Pergunta

Eu preciso criar um usuário ejabberd a partir de um script PHP. Eu também preciso ser capaz de adicionar o novo usuário para uma lista compartilhada predefinidos.

Eu deveria chamar ejabberdctl usando exec() ou há uma maneira melhor?

Foi útil?

Solução

ejabberdctl é de longe o mais fácil neste caso específico. As outras opções são:

  • Implementar um XMPP cliente completo em PHP (!)

  • Implementar um módulo em Erlang que proxies os pedidos: - (!) Do PHP <> comunicação Erlang teria de ser através de uma tomada e lotes de empacotamento estaria envolvido

Outras dicas

Aqui está a minha solução final:

Graças à conselho de jldupont que ejabberdctl seria a solução mais fácil , eu pressionou através dos obstáculos eu corri para dentro e ter uma solução de trabalho.

Por padrão, o usuário do apache não tem os privilégios corretos para ejabberdctl executar com êxito (e com razão). Então, para que ele funcione, você tem que chamá-lo com sudo. Mas ... sudo requer uma senha, que apresenta 2 problemas:

  1. O usuário apache não tem uma senha.
  2. Mesmo se o fizesse, não há nenhuma maneira de inseri-lo a partir de PHP.

Solution (para Ubuntu) - adicione esta linha no final do /etc/sudoers:

www-data ALL= (ejabberd) NOPASSWD: /usr/sbin/ejabberdctl

O caminho para o arquivo sudoers e ejabberdctl pode variar para outras distribuições Linux. Isso permite que o usuário do apache (www-data) para executar apenas ejabberdctl com privilégios elevados e sem a necessidade de uma senha.

Tudo o que resta é o código PHP:

<?php
    $username = 'tester';
    $password = 'testerspassword';
    $node = 'myserver.com';
    exec('sudo -u ejabberd /usr/sbin/ejabberdctl register '.$username.' '.$node.' '.$password.' 2>&1',$output,$status);
    if($output == 0)
    {
        // Success!
    }
    else
    {
        // Failure, $output has the details
        echo '<pre>';
        foreach($output as $o)
        {
            echo $o."\n";
        }
        echo '</pre>';
    }
?>

Segurança

É importante notar que este não apresentar um risco de segurança significativo, mesmo que você só está permitindo que um comando a ser executado por www-data. Se você usar essa abordagem, você precisa ter certeza de que você proteger o código PHP para trás algum tipo de autenticação para que não qualquer pessoa pode fazê-lo executar. Além riscos de segurança óbvia, poderia abrir seu servidor até um ataque de negação de serviço.

deparei-me com esta questão em 2016, existem maneiras muito mais fácil de implementar isso do que a resposta aceita eo mais votado um.

  1. Use uma biblioteca XMPP PHP, o mais comum é:

https://github.com/fabiang/xmpp

  1. Embora esta biblioteca não suporta a adição de um usuário fora da caixa, você pode muito facilmente estendê-lo

aqui é a classe que escrevi para adicionar um usuário:

use Fabiang\Xmpp\Util\XML;

/**
 * Register new user
 * @param string $username
 * @param string $password
 * @param string $email
 * @package XMPP\Protocol
 * @category XMPP
 */
class Register implements ProtocolImplementationInterface
{  
    protected $username;
    protected $password;
    protected $email;

    /**
     * Constructor.
     *
     * @param string $username
     * @param string $password
     * @param string $email
     */
    public function __construct($username, $password, $email)
    {
        $this->username = $username;
        $this->password = $password;
        $this->email = $email;
    }

    /**
     * Build XML message
     * @return type
     */
    public function toString()
    {
        $query = "<iq type='set' id='%s'><query xmlns='jabber:iq:register'><username>%s</username><password>%s</password><email>%s</email></query></iq>";        
        return XML::quoteMessage($query, XML::generateId(), (string) $this->username, (string) $this->password, (string) $this->email);
    }
}
  1. Você deve habilitar o registro em banda no arquivo ejabberd.cfg, como é negado por padrão:

{acesso, cadastre-se, [{permitem, todos}]}.

Finalmente aqui está um código de exemplo para usar essa classe:

private function registerChatUser($name, $password, $email)
    {       
        $address = 'tcp://yourserverip:5222';
        $adminUsername = 'youradmin';
        $adminPassword = 'youradminpassword';

        $options = new Options($address);
        $options->setUsername($adminUsername)->setPassword($adminPassword);

        $client = new Client($options);         
        $client->connect();             

        $register = new Register($name, $password, $email);                 
        $client->send($register);   

        $client->disconnect();
    }

A chamada biblioteca falhará se o servidor não tem um certificado SSL válido. Ou colocar um certificado válido, ou substituir esta parte em SocketClient.php com o abaixo trecho

// call stream_socket_client with custom error handler enabled
$handler = new ErrorHandler(
    function ($address, $timeout, $flags) {
        $options = [
            'ssl' => [
                'allow_self_signed' => true,
                'verify_peer_name' => false,
            ],
        ];
        $context = stream_context_create($options);
        return stream_socket_client($address, $errno, $errstr, $timeout, $flags, $context);
    },
    $this->address,
    $timeout,
    $flags
);

Se você quiser uma maneira limpa e segura de fazer isso usando o PHP no protocolo XMPP, vou recomendar trabalhar com este exemplo de script register_user.php . Este é um exemplo que pode ser encontrado no interior Jaxl PHP Library.

Fazer download da biblioteca Jaxl e uso da seguinte forma:

JAXL $ php examples/register_user.php localhost
Choose a username and password to register with this server
username:test_user
password:test_pass
registration successful
shutting down...
JAXL $

A maneira mais fácil de fazer isso é usando mod_xmlrpc - que lhe permite executar os comandos ejabberdctl usando xmlrpc. Isso é fácil de usar com uma biblioteca, tais como:

https://github.com/gamenet/php-jabber-rpc

/* Add user to Jabber */
use \GameNet\Jabber\RpcClient;
use \GameNet\Jabber\Mixins\UserTrait;
$rpc = new RpcClient([
        'server' => 'jabber.org:4560',
        'host' => 'myhost.org',
        'debug' => false,
    ]);

$result=$rpc->createUser( $username, $password );

Eu já resolveu o problema com mod_register_web [ 1 , 2 ]. Ele não requer toneladas de código e, penso eu, é bastante seguro. mod_register_web fornece página html com formulário POST simples de registrar novo usuário.

Ativar módulo sob ouvinte http separado (no meu caso, a porta 5281). Faça esta porta disponível apenas para solicitações locais com o parâmetro "ip".

listen:
  port: 5280
  module: ejabberd_http
  web_admin: true
  http_bind: true
  ## register: true

ip: "127.0.0.1"   # Only local requests allowed for user registration
  port: 5281
  module: ejabberd_http
  register: true

modules:
  mod_register_web: {}

Request exemplo:

curl -XPOST 127.0.0.1:5281/register/new -d 'username=lucky&host=vHost&password=test&password2=test'

Request pode ser executado a partir do código php com biblioteca adequada (que já estava no meu quadro).

onda -XPOST 127.0.0.1:5281/api/register -d '{ "user": "sorte", "host": "data.com", "password": "teste"}'

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top