Domanda

Devo creare un utente ejabberd da uno script PHP. Devo anche essere in grado di aggiungere il nuovo utente a un elenco condiviso predefinito.

Devo semplicemente chiamare ejabberdctl usando exec() o c'è un modo migliore?

È stato utile?

Soluzione

ejabberdctl è di gran lunga il più semplice in questo caso specifico. Le altre opzioni sono:

  • Implementa un client XMPP completo in PHP (!)

  • Implementa un modulo in Erlang che inoltra le richieste: il PHP < - > la comunicazione di Erlang dovrebbe avvenire attraverso un socket e sarebbero coinvolti molti marshalling (!)

Altri suggerimenti

Ecco la mia soluzione finale:

Grazie a il consiglio di jldupont che ejabberdctl sarebbe stato il soluzione più semplice, ho superato gli ostacoli che ho incontrato e ho una soluzione funzionante.

Per impostazione predefinita, l'utente di apache non ha i privilegi giusti per eseguire correttamente sudo (e per una buona ragione). Quindi, affinché funzioni, devi chiamarlo con /etc/sudoers. Ma ... www-data richiede una password, che presenta 2 problemi:

  1. L'utente apache non ha una password.
  2. Anche se lo facesse, non c'è modo di accedervi da PHP.

Soluzione (per Ubuntu) - aggiungi questa riga alla fine di <=>:

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

Il percorso del file sudoers e di ejabberdctl può variare per altre distribuzioni Linux. Ciò consente all'utente di apache (<=>) di eseguire solo <=> con privilegi elevati e senza richiedere una password.

Tutto ciò che rimane è il codice 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>';
    }
?>

Sicurezza

È importante notare che ciò presenta un rischio per la sicurezza significativo anche se si sta eseguendo un solo comando da <=>. Se usi questo approccio, devi assicurarti di proteggere il codice PHP dietro una sorta di autenticazione in modo che non solo chiunque possa farlo eseguire. Oltre agli ovvi rischi per la sicurezza, potrebbe aprire il tuo server a un attacco Denial of Service.

Mi sono trovato su questa domanda nel 2016, ci sono modi molto più semplici per implementarla rispetto alla risposta accettata e alla più votata.

  1. Usa una libreria XMPP PHP, la più comune è:

https://github.com/fabiang/xmpp

  1. Sebbene questa libreria non supporti l'aggiunta immediata di un utente, puoi estenderla molto facilmente

ecco la classe che ho scritto per aggiungere un utente:

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. È necessario abilitare la registrazione in banda nel file ejabberd.cfg, poiché è negato per impostazione predefinita:
  

{access, register, [{allow, all}]}.

Finalmente ecco un codice di esempio per l'utilizzo di questa 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();
    }

La chiamata alla libreria fallirà se il server non ha un certificato SSL valido. Inserire un certificato valido o sostituire questa parte in SocketClient.php con lo snippet di seguito

// 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 vuoi un modo pulito e sicuro di farlo usando PHP all'interno del protocollo XMPP, ti consiglio di lavorare con questo script di esempio register_user.php . Questo è un esempio che si trova nella Jaxl Libreria PHP.

Scarica la libreria Jaxl e usa come segue:

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 $

Il modo più semplice per farlo è usare mod_xmlrpc - che ti permette di eseguire i comandi ejabberdctl usando xmlrpc. Questo è facile da usare con una libreria come:

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 );

Ho risolto il problema con mod_register_web [ 1 , 2 ]. Non richiede tonnellate di codice e, credo, è abbastanza sicuro. mod_register_web fornisce alla pagina html un semplice modulo POST per registrare un nuovo utente.

Abilita il modulo in listener http separato (nel mio caso, porta 5281). Rendi questa porta disponibile solo per richieste locali con & Quot; ip & Quot; parametro.

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: {}

Esempio di richiesta:

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

La richiesta può essere eseguita dal codice php con la libreria appropriata (che era già nel mio framework).

curl -XPOST 127.0.0.1:5281/api/register -d '{" user ": " lucky ", " host < !> quot;:!!! <> quot; data.com <> quot;, <> quot; la password <> quot;:!!! <> quot; test <> quot;} '

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top