Question

Je dois créer un utilisateur ejabberd à partir d'un script PHP. Je dois également pouvoir ajouter le nouvel utilisateur à une liste partagée prédéfinie.

Devrais-je simplement appeler ejabberdctl en utilisant exec() ou existe-t-il un meilleur moyen?

Était-ce utile?

La solution

ejabberdctl est de loin le plus simple dans ce cas particulier. Les autres options sont:

  • Implémentez un client XMPP complet en PHP (!)

  • Implémentez un module dans Erlang qui proxy les demandes: la PHP < - > Erlang doit se faire via un socket et de nombreux marshaling seraient impliqués (!)

Autres conseils

Voici ma solution finale:

Merci aux le conseil de jldupont selon lequel ejabberdctl serait le La solution la plus simple, j’ai traversé les obstacles que j’ai rencontrés et j’ai trouvé une solution efficace.

Par défaut, l'utilisateur d'Apache ne dispose pas des privilèges appropriés pour exécuter avec succès sudo (et pour une bonne raison). Donc, pour que cela fonctionne, vous devez l'appeler avec /etc/sudoers. Mais ... www-data nécessite un mot de passe, ce qui pose 2 problèmes:

  1. L'utilisateur apache n'a pas de mot de passe.
  2. Même si c'était le cas, il n'y a aucun moyen de le saisir à partir de PHP.

Solution (pour Ubuntu) - ajoutez cette ligne à la fin de <=>:

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

Le chemin d'accès au fichier sudoers et à ejabberdctl peut varier pour d'autres distributions Linux. Cela permet à l'utilisateur (<=>) d'apache de n'exécuter que <=> avec des privilèges élevés et sans mot de passe.

Il ne reste que le code 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>';
    }
?>

Sécurité

Il est important de noter que cela présente un risque de sécurité important même si vous ne permettez qu'une seule commande à être exécutée par <=>. Si vous utilisez cette approche, vous devez vous assurer de protéger le code PHP derrière une sorte d'authentification afin que personne ne puisse le faire exécuter. Au-delà des risques de sécurité évidents, cela pourrait exposer votre serveur à une attaque par déni de service.

Je suis tombé sur cette question en 2016, il existe des moyens beaucoup plus simples de la mettre en œuvre que la réponse acceptée et la plus votée.

  1. Utilisez une bibliothèque PHP XMPP, la plus courante étant:

https://github.com/fabiang/xmpp

  1. Bien que cette bibliothèque ne prenne pas en charge l'ajout immédiat d'un utilisateur, vous pouvez facilement l'étendre

voici la classe que j'ai écrite pour ajouter un utilisateur:

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. Vous devez activer l'enregistrement dans la bande dans le fichier ejabberd.cfg, car il est refusé par défaut:
  

{accès, enregistrez-vous, [{autoriser, tout}]}.

Enfin, voici un exemple de code permettant d’utiliser cette 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();
    }

L'appel de la bibliothèque échouera si le serveur ne dispose pas d'un certificat SSL valide. Placez un certificat valide ou remplacez cette partie dans SocketClient.php par l’extrait ci-dessous

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

Si vous souhaitez utiliser PHP de manière propre et sécurisée avec le protocole XMPP, je vous recommanderai d'utiliser cet exemple de script register_user.php . C’est un exemple qui se trouve dans la Jaxl bibliothèque PHP.

Téléchargez la bibliothèque Jaxl et utilisez-la comme suit:

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 $

La méthode la plus simple consiste à utiliser mod_xmlrpc, qui vous permet d’exécuter les commandes ejabberdctl à l’aide de xmlrpc. Ceci est facile à utiliser avec une bibliothèque telle que:

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

J'ai résolu le problème avec mod_register_web [ 1 , 2 ]. Cela n'exige pas des tonnes de code et, je pense, est suffisamment sécurisé. mod_register_web fournit une page HTML avec un formulaire POST simple pour enregistrer un nouvel utilisateur.

Activez le module sous un écouteur http distinct (dans mon cas, le port 5281). N'activez ce port que pour les demandes locales avec & Quot; ip & Quot; paramètre.

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

Exemple de demande:

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

La requête peut être exécutée à partir du code php avec la bibliothèque appropriée (qui était déjà dans mon framework).

curl -XPOST 127.0.0.1:5281/api/register -d '{& "utilisateur &"; & "; chanceux &", & "hôte < !> ";: &"; data.com & ", &" mot de passe & ": &" tester & "} '

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top