Les communications entre un client et un serveur jabber peuvent être chiffrées au moyen de SSL ou TLS. Traditionnellement les communications en clair ou avec TLS se font sur le port 5222 et celles chiffrées par SSL sur le port 5223.
J'ai dû un peu bidouiller la classe class.jabber.php que j'utilise dans Couac pour la rendre compatible avec les serveurs utilisant SSL, en particulier pour permettre de se connecter à un compte GTalk. Ces modifications figurent je crois dans la dernière version de la librairie, mais comme le site de celle-ci est inaccessible depuis un bon moment, je les détaille ici.
Pour choisir le type de connexion (en clair ou chiffrée par SSL), il faut
préfixer l'adresse du serveur par tcp ou ssl :
tcp://jabber.org ou ssl://jabber.org (pour le
chiffrage par TLS, si j'ai bien compris, on se connecte en TCP puis si le
client et le serveur supportent ce chiffrage, on le démarre en envoyant au
serveur un starttls).
Un problème classique lorsqu'on utilise des connexions chiffrées est celui des certificats auto-signés : les serveurs qui n'ont pas les moyens de se faire certifier par un tiers de confiance signent eux-même leur certificat. C'est une "faille" de sécurité qui par défaut provoque l'arrêt de la connexion. Pour passer outre, il faut autoriser SSL à utiliser des certificats auto-signés. Cela s'effectue en lui passant un paramètre. fsockopen ne permettant pas (plus ?) de passer des paramètres, je l'ai remplacé par stream_socket_client. Cette fonction peut recevoir un contexte comprenant entre autres les valeurs suivantes :
verify_peer: à mettre à faux pour ne pas vérifier le certificatallow_self_signed: à mettre à vrai pour autoriser les certificats auto-signés
Au final, le code complet est:
function OpenSocket($server, $port, $transport = 'tcp')
{
if (function_exists("dns_get_record"))
{
$record = dns_get_record("_xmpp-client._tcp.$server", DNS_SRV);
if (!empty($record))
{
$server = $record[0]["target"];
}
}
$context = stream_context_create();
if ($transport == 'ssl')
{
stream_context_set_option($context, 'ssl', 'allow_self_signed', true);
stream_context_set_option($context, 'ssl', 'verify_peer', false);
}
$errno = 0;
$errstr = '';
$socket = stream_socket_client($transport . '://'.$server.":".$port, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context));
// ...
}
Au passage, j'ai découvert la fonction dns_get_record et les enregistrements SRV dans le DNS qui permettent d'associer des IP à des services pour un nom de domaine.
Tout ça pour dire que Couac permet à présent de se connecter à GTalk. Il suffit, dans les propriétés du compte, de positionner le port à 5223 et le transport à SSL.