Parlons XMPP - épisode 9 - copie de fichiers et Jingle

goffi 04/11/2015, 13:53 technique planet-libre parlons_xmpp jabber-xmpp Libre

(pour lire les épisodes précédents, suivez l'étiquette correspondante)

Bien que déjà répété un certain nombre de fois, je le redis : XMPP fait bien plus que de la messagerie instantanée. Une des fonctionnalités qui est apparue rapidement est la copie de fichiers, voyons cela de plus près

Le problème : XMPP étant du XML, il n'est pas vraiment adapté aux données purement binaires comme des fichiers. La solution est de passer par l'extérieur, c'est à dire une autre connexion non XML, et d'utiliser le flux XML pour la gérer, on parle de connexion « out-band ». Malheureusement, parfois il n'est pas possible d'établir cette connexion, alors on passe tout par le flux XML : c'est lent, peu efficace, mais ça fonctionne presque toujours, on parle de connexion « in-band » (qu'on pourrait traduire par « interne »).
Il y a aussi des cas où il est plus simple et efficace de rester « in-band », enfin surtout un : si on envoie très peu de données, comme une petite image (un avatar par exemple).

Comme souvent dans le monde XMPP, plusieurs solutions ont été proposées, expérimentées, parfois adoptées puis dépréciées, jusqu'à ce qu'on trouve et garde celle qui semble convenir le mieux, et qui est a priori la meilleure techniquement.
Commençons par la solution courante, appelée « Stream Initiation » (initiation de flux), elle est définie par la XEP-0095, et la copie de fichier l'utilise via la XEP-0096.

La copie de fichiers est la seule application qui utilise la XEP-0095. Nous avons 2 personnes en jeu : celle qui veut envoyer le fichier, qu'on appellera « l'expéditeur » (« sender » en anglais) et celui qui veut le recevoir, qu'on appellera « le destinataire » (« receiver » en anglais).

La XEP-0096 défini ce qu'on appelle un « profil » pour l'initiation de flux, le profil « transfert de fichier ». Elle sert principalement à transmettre les métadonnées du fichier : une description, sa taille, son nom, sa date de dernière modification, et un « hash », c'est à dire une somme de contrôle pour vérifier que le fichier a été correctement copié. C'est l'algorithme MD5 qui est utilisé ici, pourtant connu pour avoir des failles, même si elles ne sont pas dramatiques dans le cadre d'un transfert de fichier (l'expéditeur étant déjà validé par ailleurs).

Il est également possible d'indiquer une fourchette (« range ») à copier, c'est à dire un point de départ (« offset ») dans le fichier et une longueur (« length »), pratique si un transfert a été interrompu en plein milieu, par une coupure de courant par exemple.

Le reste, c'est la XEP-0095 qui s'en occupe, il s'agit juste de négocier la méthode à utiliser, le destinataire accepte ou non le flux, et choisi une des méthodes. Il y a 2 méthodes principales : la première est le transfert en interne (« In-Band Bytestreams », XEP-0047) qui se contente de transcoder les données en base64.

La deuxième (la XEP-0065, « SOCKS5 Bytestreams ») est plus intéressante, elle utilise SOCKS v5 pour établir une connexion externe (« out-band ») et tenter une connexion directe ou via un « proxy » qui est un élément externe relayant les données. L'utilisation d'un proxy est moins efficace qu'une connexion directe bien entendu (les données passent par un 3ᵉ point), mais est parfois nécessaire si une connexion directe est impossible à cause d'un pare-feu ou d'un NAT par exemple. XMPP permet, grâce à disco (la XEP-0030) de savoir automatiquement si votre serveur propose un proxy.
C'est donc la XEP-0065 qui est à l'origine du nom « proxy65 » couramment utilisé.
Petit détail qui a son importance : dans le cas du transfert direct, la connexion se fait du destinataire vers l'expéditeur (qui a ouvert un port pour l'occasion), aussi la connexion peut échouer dans beaucoup de cas (par exemple l'expéditeur est derrière un NAT). Une méthode a été faite pour améliorer la situation, mais elle n'a jamais été standardisée, vous pouvez la trouver ici : http://delta.affinix.com/specs/stream.html.

Voilà pour la méthode actuelle. Elle pose de nombreux problèmes : c'est uniquement l'expéditeur qui doit proposer et le destinataire accepte ou refuse, il n'y a pas de vraie méthode de secours (appelée « fallback » en anglais), c.-à-d. de méthode pour passer de SOCKS5 (ou « s5b ») au transfert « in-band » (ou « ibb »), et il y a souvent des difficultés pour établir une connexion directe comme expliqué au paragraphe précédent. Bref, ça n'est pas satisfaisant. Mais le problème est assez complexe, il n'est pas si simple de faire une connexion directe, c'est à dire pair à pair (ou « peer to peer » en anglais).

Heureusement, une nouvelle méthode est apparue, et elle est beaucoup plus souple et efficace : Jingle. Mais cet article étant déjà long, j'en parlerai la prochaine fois.

J'en profite pour annoncer que je vais commencer une série d'articles pour expliquer l'architecture et ce qu'on peut faire concrètement avec « Salut à Toi ».

Je vous rappelle aussi que nous avons une campagne de financement participatif en cours pour porter « Salut à Toi » sur Android et faire une version de bureau, et que nous avons bien besoin de soutien ! http://www.arizuka.com/fr/projects/libervia
Merci :)

Vous voulez du (micro)blogage, de la décentralisation et du chiffrement sur Android ?

goffi 22/10/2015, 13:23 jabber-xmpp GNU-Linux projet Libre planet-libre SàT

Salut à vous !

 
Aujourd'hui nous lançons une petite campagne de financement participatif pour le développement d'une version Android de Libervia/Salut à Toi.
 
Nous souhaitons ici développer une application native, avec toutes les fonctionnalités avancées dont nous disposons déjà, telles que le (micro)blogage, le chiffrement de bout en bout via OTR (et il est possible que nous ajoutions OMEMO/Axolotl, une nouvelle méthode permettant de chiffrer les messages hors ligne ou dans une discussion de groupe), le partage de fichiers, ou des choses plus exotiques comme une télécommande universelle.
 
Ce développement fonctionnera également sur bureau (Gnu/Linux bien sûr, mais il devrait fonctionner sur d'autres plateformes comme Windows ou Mac OS X) avec la même interface.
 
Il existe déjà quelques clients Android (comme le très joli Movim de notre ami Edhelas, Conversations ou Xabber), mais aucun n'offre actuellement le même bouquet de fonctionnalités que Libervia/Salut à Toi, aussi ce développement sera un vrai plus.
 
D'autre part nous sommes particulièrement attentifs à l'éthique (cf notre contrat social) et nous sommes organsiés en association loi 1901 en autogestion, dans l'idée de faire une coopérative sur le long terme. Cette campagne est aussi l'occasion de tester un moyen de financement, et nous avons choisi Arizuka car ce site se concentre sur les projets de l'économie sociale et solidaire.
 
Voilà, donc maintenant on compte sur vous ! N'hésitez pas à poser vos question soit en commentaire, soit par courriel (goffi@goffi.org) soit sur notre salon de discussion XMPP: sat@chat.jabberfr.org
 
Salut à Toi: http://salut-a-toi.org
 

P.-S. : nous préparons aussi une (grosse) nouvelle version dans les semaines à venir, je ferai certainement une série d'articles pour expliquer les nouveautés et comment se servir de Libervia ou SàT en général.

Parlons XMPP - épisode 8 - PubSub et PEP

goffi 08/09/2015, 13:10 technique planet-libre parlons_xmpp jabber-xmpp Libre

(pour lire les épisodes précédents, suivez l'étiquette correspondante)

Aujourd'hui nous allons expliquer dans les grandes lignes comment fonctionnent « PubSub » et « PEP », et voir à quoi cela peut servir. Cet article va reprendre en partie ce que j'ai dit à la conférence « PubSub, microblogage et XMPP » en juillet dernier aux RMLL.

PubSub signifie « Publish/Subscribe » (Publication/Abonnement), c'est un mécanisme qui permet à une ou plusieurs personnes de publier toutes sortes d'informations sur un endroit connu (qu'on appelle un nœud) et aux personnes qui le désirent de s'abonner, c'est à dire d'avoir accès au contenu et d'être averti des modifications, le tout avec un système d'accès simple. Il s'agit du patron de conception « observateur/observable » décentralisé et appliqué à XMPP.

Le fonctionnement est expliqué dans la XEP-0060, c'est une des XEPs les plus longues de XMPP mais le principe est relativement simple à comprendre. Sans reprendre le long glossaire du document, expliquons quelques termes :

  • le service PubSub est l'entité qui gère le mécanisme de publication, d'autorisation, d'abonnement, de notification. C'est une entité XMPP et un jid y est donc associé, c'est à lui que vous faites toutes les requêtes pour un nœud donné.
  • le nœud est un espace associé à une publication. On peut associer ça à l'adresse d'un flux Atom.
  • un « item » (élément) est une publication dans un nœud. On peut associer ça à un article dans un flux Atom.
  • cet « item » contient un « payload » (charge utile), c'est à dire un contenu significatif qui dépend de la fonctionnalité utilisée. En effet la XEP-0060 décrit un mécanisme générique et souple, qui est ensuite utilisé dans des cas pratiques par d'autres extensions.

Un service PubSub est généralement un composant de votre serveur, mais ça peut-être n'importe quelle entité : votre serveur lui-même (c'est le cas avec PEP que nous allons voir ci-dessous), ou un client voire votre client lui-même (mais c'est assez rare – je n'ai jamais vu de client le faire –, car en général on utilise le service de son serveur).

Le mécanisme général est très simple et centré sur les nœuds : chaque entité (associée à un jid) à un rôle lié à ce nœud selon qu'elle l'ait créé, qu'elle soit publieur, abonné, banni ou sans lien avec le nœud. À ces rôles sont donnés des autorisations : le droit d'écrire (avec le « publish model » ou modèle de publication) et le droit en lecture (avec l'« access model » ou modèle d'accès).

Reprenons de manière un peu plus formelle. Les rôles dont nous avons parlé sont appelés « affiliations », et on peut avoir les suivantes:

  • owner (propriétaire): en général celui qui a créé le nœud
  • publisher (publieur): celui ou ceux (il peut y en avoir plusieurs) qui ont accès en écriture
  • publish-only (publication seulement): droit d'écriture mais pas de lecture, c'est un cas peu fréquent.
  • member (membre): quelqu'un qui est abonné au nœud
  • none (rien): l'entité n'a pas de lien avec le nœud
  • outcast (banni): l'entité a été explicitement interdite d'accès au nœud

La section 4.1 de la XEP-0060 fourni un tableau qui montre les autorisations selon l'affiliation. Ainsi on voit que le propriétaire peut publier ou configurer un nœud.

Les modèles d'accès (pour la lecture) définis dans la XEP-0060 sont les suivants:

  • open (ouvert, public): tout le monde peut lire le nœud
  • presence (présence – oui je traduis même pour un seul accent –) : si une entité est autorisée à voir la présence du publieur, alors elle peut accéder au nœud
  • roster (liste de contacts): si une entité est dans un groupe défini (dans la configuration du nœud) de la liste de contacts du service pubsub, elle a accès au nœud.
  • whitelist (liste blanche): des entités sont explicitement autorisées dans la configuration du nœud

Et rapidement les modèles de publication:

  • publishers (publieurs): quelqu'un qui a l'affiliation publieur peut écrire
  • subscribers (abonnés): n'importe quel abonné peut écrire
  • open (ouvert/libre): tout le monde peut écrire

Il faut bien noter une chose essentielle dans PubSub : quand la combinaison autorisation/abonnement/configuration le permet, on reçoit une notification immédiatement quand un élément est publié, modifié ou supprimé. Autrement dit on n'est plus du tout dans l'analogie avec un flux Atom – où on doit aller vérifier régulièrement qu'il n'y a rien de nouveau –, on est prévenu si nécessaire. Ceci est beaucoup plus efficace, rapide, et économe en ressources.

Voilà pour la base. La XEP défini d'autres choses qu'il n'est pas forcément pertinent d'expliquer ici, comme les métadonnées ou les inscriptions temporaires. On peut toutefois s'arrêter sur les collections, qui ne sont que mentionnées dans la XEP-0060 mais décrites en détails dans la XEP-0248. Elles permettent de faire des arbres de nœuds, et ainsi de représenter des données avec des relations entre elles. Des exemples valent parfois mieux qu'un long discours: les collections peuvent être utilisées pour représenter un système de fichiers sur un disque dur, ou un arbre généalogique.

Tout ceci est souple, générique, puissant, et relativement facile à utiliser par un client. Mais la XEP étant très longue, et l'implémentation de la partie service plus complexe, les implémentations ont mis du temps à arriver (et encore aujourd'hui elles sont très inégales). Comme PubSub peut être intéressant même sans tout le mécanisme, une version simplifiée est décrite dans la XEP-0163: « Personal Eventing Protocol » (Protocole d'évènements personels).

Cette dernière se base sur PubSub, mais définit les règles suivantes qui simplifient beaucoup :

  • 1 compte (jid) = 1 service : probablement la règle la plus importante, elle évite d'avoir à chercher un service PubSub associé à un jid, puisque le service est l'adresse canonique (« bare jid ») de l'entité. Ainsi pour la microblogage (XEP-0277), il suffit de connaître le jid de la personne – le nœud étant défini dans la XEP – pour retrouver ses publications.

  • 1 publieur par nœud : le propriétaire et le publieur sont le même, et il n'y a qu'un publieur par nœud. On se coupe ainsi de l'édition collaborative par souci de simplification, et il faudra utiliser PubSub pour ce genre d'applications.

  • accès par présence par défaut : sans rien toucher, il suffit d'avoir quelqu'un dans sa liste de contacts (et qui a accès à la présence) pour qu'il soit autorisé à voir nos publications

  • notifications filtrées sur l'intérêt exprimé : pour éviter d'être submergé de notifications, une entité/un client doit explicitement indiquer qu'il est intéressé par tel ou tel nœud

  • options par défaut au plus simple

PEP était utilisé au début pour des événements (sans grand intérêt à mon sens) comme l'humeur ou la musique en cours d'écoute, mais depuis son utilisation a évolué.

Voici, pour finir, quelques exemples d'utilisation de PubSub ou PEP:

  • enregistrement de données publiques ou semi-publiques (XEP-0222), par exemple une clef publique de chiffrement
  • enregistrement de données privées (XEP-0223), très utile pour n'importe quelle donnée de petite taille
  • les marque-pages (XEP-0048) utilisés pour les salons de discussions utilisent PEP (la XEP-0048 a été modifiée après l'apparition de PEP pour s'y adapter)
  • le microblogage bien entendu (XEP-0277), qui utilise PEP et utilise du Atom pour sa « charge utile » (« payload ») et un accès en général public. Les commentaires sont sur un nœud PubSub séparé, en général avec un modèle de publication par abonnement.
  • la XEP-0214 utilise PubSub et les collections pour faire un dépôt de fichiers
  • le futur protocole de discussions de groupe « MUC 2 » devrait se baser sur PubSub

PubSub pourrait aussi être utilisé pour placer des points sur une carte, faire un wiki, organiser des événements, ou encore gérer et surveiller une batterie de serveurs qui nous préviendraient en cas de problème.

Je reviendrai sûrement plus tard sur tout ça pour expliquer le microblogage ou d'autres extensions.

La prochaine fois, je pense vous parler de Jingle (mais pas de la partie vidéo-conférence). J'espère qu'à ce stade vous commencez à comprendre que XMPP n'est pas une technologie, mais un ensemble de technologies coordonnées et qui se réutilisent les unes les autres quand nécessaire.

J'ai un peu réduit le rythme des articles ces derniers temps car je travaille sur mon projet, et qu'une partie a été traduite en anglais avec l'aide de pas mal de monde (merci encore !), tout cela prend du temps.

Si vous venez à la fête de l'huma ce week-end, vous pourrez me trouver au village du libre, où Parinux me prête gentiment un bout de stand (merci aussi !). Je n'y serai pas en permanence, car je compte aussi profiter un peu de la fête :)

Parlons XMPP - épisode 7 - cas pratiques: SleekXMPP et SàT

goffi 06/08/2015, 10:16 technique planet-libre parlons_xmpp jabber-xmpp Libre

(pour lire les épisodes précédents, suivez l'étiquette correspondante)

Comme cela a été demandé plusieurs fois, nous allons pour cet article faire un petit cas pratique avec deux bots XMPP.

SleekXMPP

c'est SleekXMPP que nous allons tester, que je n'avais jamais utilisé avant cet article. Il s'agit d'une bibliothèque Python qui se veut simple, avec peu de dépendances, et gérant tout avec des greffons. Vous pouvez aussi utiliser le fork (amical) fait pour Poezio, Slixmpp qui a réécrit le cœur de la bibliothèque pour tout gérer en asynchrone (sans thread) via le récent asyncio (aussi il faut une version de Python >= à 3.4, alors que SleekXMPP fonctionne avec Python 2 et 3).

Sans entrer trop dans les détails, que vous trouverez sur le site officiel avec plusieurs tutoriels (http://sleekxmpp.com/), faisons un simple bot qui répond à des commandes ad-hoc (aucun lien avec Tintin, voir plutôt l'épisode 6):

Ce script est une adaptation de l'exemple donné dans le dépôt officiel (voir sa licence). Des explications sont données après le script, et il devrait fonctionner avec Python 2.6 ou supérieur ou 3.1 ou supérieur.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sleekxmpp
from sleekxmpp import jid

JID="mon_super_bot@mon_super_server.tld"
PWD="mon_super_mot_de_passe"
ADMIN=jid.JID("mon_admin@mon_super_server.tld")
CMD_ENVOI = u'envoi message'
CMD_DECO = u'déconnexion'
CMD_ADMIN = u'gros bouton rouge'


class MonSuperBot(sleekxmpp.ClientXMPP):

    def __init__(self):
        sleekxmpp.ClientXMPP.__init__(self, JID, PWD)
        self.add_event_handler("session_start", self.session_start)
        # note 1
        self.register_plugin('xep_0030')
        self.register_plugin('xep_0004')
        self.register_plugin('xep_0050')
        self.register_plugin('xep_0199', {'keepalive': True, 'frequency':15})

    def session_start(self, event):
        # note 2
        self.send_presence()
        self.get_roster()
        self['xep_0050'].add_command(node='monbot',
                                     name=u'Commandes de monbot',
                                     handler=self._handle_commands)

    def _handle_commands(self, iq, session):
        form = self['xep_0004'].makeForm('form', 'bot')
        form['instructions'] = u'Choisissez une commande'
        options = [CMD_ENVOI, CMD_DECO]

        # note 3
        if session['from'].bare == ADMIN:
            options.append(CMD_ADMIN)

        form.addField(var='command',
                      label=u'commande',
                      ftype='list-single',
                      required=True,
                      options=options
                      )

        session['payload'] = form
        session['next'] = self._handle_command_complete
        session['has_next'] = False

        return session

    def _handle_command_complete(self, payload, session):
        form = payload
        command = form['values']['command']

        if command == CMD_ENVOI:
            self.send_message(mto=session['from'],
                              mbody="Message important !",
                              mtype='headline')
        elif command == CMD_DECO:
            self.disconnect(wait=True) # note 4
        elif command == CMD_ADMIN:
            # note 5
            if session['from'].bare == ADMIN:
                session['notes'] = [('warning', 'BOOM !')]
            else:
                raise ValueError("ce n'est pas un admin !")
        return session


if __name__ == '__main__':
    xmpp = MonSuperBot()
    if xmpp.connect(): # note 6
        print(r"\o/")
        xmpp.process(block=True)
    else:
        print(":(")

Explications

Après avoir importé sleekxmpp, nous utilisons quelques constantes (n'oubliez pas bien sûr de remplacer JID et PWD par des valeurs adaptées) pour simplifier, les exemples officiels permettent de manière plus élégante de préciser jid et mot de passe en ligne de commande.

Notre bot se comportera comme un client, nous héritons donc de sleekxmpp.ClientXMPP.

au niveau de la note 1 nous implémentons les greffons qui gèrent les XEPs qui nous intéressent :

  • disco (XEP-0030) pour annoncer ad-hoc, comme expliqué dans l'épisode 3
  • les formulaires de données (x-data, XEP-0004) et les commandes « ad-hoc » (commands, XEP-0050), expliquées dans l'épisode 6
  • la XEP-0199 permet d'envoyer et de répondre à des « pings », afin de s'assurer que la connexion et les logiciels sont toujours actifs.

À la note 2 nous envoyons notre présence et demandons la liste de contacts (« roster »), ce qui est requis par les RFCs, certains serveurs pouvant refuser de répondre si ce n'est pas fait.
Ensuite nous utilisons le greffon des commandes « ad-hoc » pour ajouter le point d'entrée à nos commandes.

Ce point d'entrée appellera la méthode « _handle_commands », et nous utilisons un formulaire (comme expliqué dans la XEP-0004) pour spécifier nos commandes. La liste « options » nous sert à indiquer nos commandes dans l'ordre voulu.

Au niveau de la note 3, nous profitons de l’identification forte de XMPP pour vérifier très simplement si le demandeur utilise l'adresse (jid) de notre compte privilégié, que nous avons indiqué dans la constante « ADMIN ». Nous aurons ainsi un jeu de commandes différent si nous utilisons le compte privilégié ou un autre.
Évidemment si vous voulez profiter de l'authentification forte, il faut vous assurer que tout est en ordre au niveau des certificats et du chiffrement (ce que fait a priori SleekXMPP de base, consultez la documentation pour plus d'informations).

L'ajout de commande se fait ici par une liste à choix unique (« list-single »), mais vous pouvez demander d'autres choses comme des mots de passe ou des jids, tout est expliqué dans la XEP-0004.

Quelques précisions sur ad-hoc : à chaque « page » vous pouvez effectuer une action:

  • cancel pour annuler
  • prev pour revenir en arrière
  • execute pour lancer une commande ou continuer la session
  • next pour passer à la page suivante
  • complete pour finir la sesssion

Ces actions sont gérées par sleekXMPP à travers le dictionnaire « session », la meilleure documentation que j'ai trouvée sur le sujet est le code lui-même : dans le fichier « sleekxmpp/plugins/xep_0050/adhoc.py » présent dans les sources.

Ad-hoc permet également d'indiquer un message, une « note », pour donner l'état de votre commande, elle peut avoir un type « info », « warn » (warning: attention) ou « error » (erreur).

Dans le code nous indiquons que nous avons notre dernière « page » par « session['has_next'] = False », et qu'il faut traiter la réponse dans « _handle_command_complete ». Oui c'est un peu contre-intuitif d’avoir à la fois has_next à False, et un next, mais ce dernier correspond à la réponse et non à une nouvelle page.

Passons à ces réponses. Nous regardons ce qui est dans le formulaire pour savoir quoi faire. Dans le premier cas nous envoyons un message manchette ou « headline » (voir l'épisode 2)

Dans le deuxième cas (au niveau de la note 4) on fait une déconnexion. Alors j'ai eu un problème ici avec SleekXMPP, que j'utilise pour la première fois comme indiqué plus haut : il faudrait pour faire propre terminer la session ad-hoc avant de déconnecter, mais je n'ai pas trouvé de moyen simple de le faire, vu que la déconnexion est immédiate et qu'il faut retourner le dictionnaire session pour terminer la séquence. Peut-être que je suis passé à côté de quelque chose, n'hésitez pas préciser en commentaire si vous avez une astuce.

Passons à la note 5: je refais une vérification du jid avant de lancer la commande privilégiée. La raison est simple: le formulaire est envoyé du client au bot par le serveur sans être vérifié par ce dernier, c'est au bot à le faire. Il est interdit d'ajouter une nouvelle commande, mais comme je doute que SleekXMPP conserve le formulaire d’origine pour vérifier qu'il n'y a rien de nouveau, un attaquant pourrait ajouter la commande privilégiée sans être admin. Cette vérification permet de l'éviter.

Pour faire propre il faudrait envoyer une réponse XMPP précisant que l'action est interdite, mais pour faire simple je me suis contenté d'une exception ici.

Enfin, au niveau de la note 6 on se connecte. Pour un serveur local de test, si vous n'avez pas de serveur DNS configuré comme il faut, vous pouvez spécifier l'adresse ip ou le nom de domaine local en dur, ainsi que le port (par exemple « self.connect(('localhost', 5222)) ». Si votre certificat n'est pas valide, vous pouvez aussi utiliser « use_tls=False » (pour les tests uniquement !). La documentation de SleekXMPP vous indiquera plus clairement comment gérer correctement les certificats.

Enfin, un autre problème que j'ai eu avec SleekXMPP: il ne semble pas possible avec ma version (1.3.1) d'indiquer de ne pas utiliser de commande « exécuter » ou de spécifier son équivalence (ce qui est pourtant possible avec la XEP-0050). Il faudrait qu'elle soit absente ou équivalent à « compléter ». Vous allez ainsi avoir un bouton qui sera inutile, et provoquera même une erreur. Là encore si quelqu'un plus habitué à la bibliothèque peut indiquer en commentaire comment corriger cela. Utilisez donc le bouton « compléter » (ou « finir ») et non « exécuter » de votre client.

Voilà la capture de notre bot piloté par Gajim:

bot piloté par Gajim

Salut à Toi

Pour indiquer les ajouts faits au code, nous utilisons un bot dénommé « Sabot ». Nous gérons les sources avec Mercurial (sur https://repos.goffi.org/). Celui-ci permet d'exécuter une commande via des crochets (« hooks »), dont un qui est lancé à chaque série de commits: incoming. Nous avons donc ceci dans notre hgrc:

[hooks]
incoming.sabot = /chemin/vers/hg_sabot_hook.sh

Pour le bot, nous profitons du côté multi-interfaces de SàT: SàT a une architecture qui permet pour un même client (et donc les mêmes profils, comptes, etc) d'avoir différentes interfaces (console, ligne de commande, bureau, web, etc).

Nous avons donc créé le compte comme un compte normal grâce à Primitivus, l'interface console (nous sommes sur un serveur sans interface graphique disponible). On peut joindre le salon désiré (ici sat@chat.jabberfr.org), et le mêttre en favori (grâce à la XEP-0048), ainsi que gérer l'entrée automatique (« autojoin »). Il ne reste plus qu'à envoyer le message quand le script hg_sabot_hook.sh est appelé, ce que nous faisons à l'aide de « jp », l'interface en ligne de commande:

#!/bin/sh

#on s'assure d'abord que D-Bus est lancé
eval `/chemin/vers/dbus-launch.sh`

REPOS_BASE="http://repos.goffi.org/sat"
PROJECT_FULL="Salut à Toi"
REPOS="$REPOS_BASE/rev/$HG_NODE"
MUC="sat@chat.jabberfr.org"

hg log -r $HG_NODE --template "Commit from {author|person} on $PROJECT_FULL\n{desc}\n$REPOS" | jp message -cp sabot $MUC

(le vrai script est un tout petit peu plus long puisqu'il gère aussi les noms des autres dépôts).

L'option « -c » indique de se connecter si ça n'est pas le cas, et « -p sabot » précise qu'il faut utiliser le profil « sabot »

Le script dbus-launch.sh s'assure juste que D-Bus est bien lancé et réutilisé entre les sessions de l'utilisateur:

#!/bin/sh
DBUS_PATH="/tmp/.dbus.`whoami`"
if [ ! -e $DBUS_PATH ]; then
        dbus-launch --sh-syntax > $DBUS_PATH
        chmod 400 $DBUS_PATH
fi
cat $DBUS_PATH

Voilà pour ces cas pratiques. La prochaine fois, je parlerai soit de PubSub, soit de Jingle.

Conférences des RMLL

goffi 28/07/2015, 14:03 jabber-xmpp GNU-Linux technique projet Libre planet-libre SàT

Salut à vous,

 
j'attendais de voir les vidéos publiées, c'est désormais le cas. Notre passage aux RMLL s'est très bien passé et a été l'occasion de se faire de nouveaux contacts et d'avoir des discussions très intéressantes. J'ai particulièrement apprécié participer à la table ronde sur les nouveaux médias, et rencontrer Arno de SPIP/SeenThis (je connaissais déjà les autres participants).
 
Je n'ai pas eu l'occasion de voir beaucoup de conférences car j'étais au stand, mais je viens bien sûr vous recommander de voir celles sur XMPP ou en particulier la table ronde sur les nouveaux médias:

Toutes les interventions étaient vraiment intéressantes, y compris dans le public. Merci à ceux qui y ont participé, et à Olicat pour avoir animé.

En ce qui concerne XMPP, il y a bien sur les conférences de Libervia et Movim. Pour Libervia la qualité est vraiment mauvaise, aussi je vous recommande plutôt la version de Pas Sage En Seine, c'est la même conférence:

Libervia

Movim

Et sur un plan plus technique, la conférence « PubSub, Microblogage et XMPP » dont j'ai déjà parlé plusieurs fois:

En dehors de ça comme je l'ai dit je n'ai pas pu voir beaucoup de conférences. J'ai particulièrement aimé celle de Paul Kocialkowski sur Replicant (en anglais, il y en a aussi eu une en français que je n'ai pas pu voir, je ne sais pas si c'est le même ou pas, du coup je mets les 2):

À voir aussi celle de Gelnior (de Newebe/Cozy cloud) sur la conception graphique, je l'avais vue aux JDLL:

Enfin, autre conférence que je n'ai pas (encore) vue, mais comme on en parle dans la table ronde je la mets ici, la conférence « SPIP et sa communauté »:

 
Il y en a eu beaucoup d'autres, aussi n'hésitez pas à préciser en commentaires celles que vous conseillez.

Appel à la communauté: aidez moi à traduire la série « Parlons XMPP »

goffi 27/07/2015, 16:43 technique planet-libre parlons_xmpp jabber-xmpp Libre

Salut à vous,

la série que j'ai commencé fin juin, « Parlons XMPP » a plus de succès que ce à quoi je m'attendais (surtout en été !), et a incité plusieurs personnes à regarder un peu plus ce que peut faire ce protocole.

Du coup j'aimerais bien traduire la série en anglais (ou autre !), mais je n'ai vraiment pas le temps de le faire moi même, vu que je dois déjà travailler sur Salut à Toi, et que l'écriture des articles en français me prend beaucoup de temps.

Alors je veux tenter le coup avec une traduction collaborative, un peu comme ce que fait framasoft pour traduire des articles de l'anglais vers le français, mais dans l'autre sens.

Tous les articles sont sous licence libre (Cc By-SA), et il faut bien noter que je parle souvent de « Salut à Toi » sur lequel je travaille, même si je parle aussi d'autres projets.

Bref, je tente le coup, j'ai ouvert un framapad avec le premier article.

Si vous voulez participer ajoutez votre nom ou pseudo pour être dans les auteurs de la traduction, et vous pouvez traduire en dessous du paragraphe en français. Je demanderai une relecture par un anglophone à la fin.

En dehors des 6 articles déjà publiés, je pense continuer au rythme d'un par semaine au moins pendant l'été.

Pour aider à la traduction, c'est par ici: https://bimestriel.framapad.org/p/parlons_XMPP

Merci d'avance !

Goffi

Parlons XMPP - épisode 6 - les commandes à distance

goffi 27/07/2015, 10:46 technique planet-libre parlons_xmpp jabber-xmpp Libre

(pour lire les épisodes précédents, suivez l'étiquette correspondante)

 
Aujourd'hui nous allons parler d'une de mes fonctionnalités favorites dans XMPP : les commandes à distance. Il s'agit de la possibilité pour 2 entités XMPP d'exécuter des actions à distance de manière générique.

La première méthode, assez peu utilisée à ma connaissance, est via la XEP-0009 (oui c'est une vieille, elle date de 2001), qui donne une méthode pour utiliser XML-RPC à travers XMPP.
XML-RPC est un Système de communications inter processus, c'est à dire un moyen pour 2 entités de communiquer à distance. Vous pouvez ainsi exécuter des commandes indépendamment du langage de programmation, en ayant des données décrites (est-ce que je reçois un entier ? Une chaîne de caractères ?). Ceci est particulièrement adapté pour la communication de machines à machines, quand on sait déjà quelles méthodes sont disponibles et ce qu'elles font. Le cas type est une interface de programmation (ou API) pour permettre de contrôler quelque chose, comme un serveur par exemple.

La deuxième méthode est appelée commandes « ad-hoc » (de circonstance), et c'est la XEP-0050 qui les explique. L'idée est aussi de pouvoir exécuter de manière générique des commandes, mais cette fois sans savoir à l'avance ce qui va être disponible, et en pensant plutôt à une interaction humain/machine, bien que machine/machine soit bien sûr tout à fait possible.

Le cas typique d'utilisation est la configuration d'un service, mais ce peut être utilisé pour n'importe quoi.
Ce qui rend cette fonctionnalité particulièrement puissante, c'est qu'elle fait partie de XMPP et donc peut profiter de tous ses avantages, en particulier l'authentification forte (quand on parle à server@example.net, on sait qu'on ne parle pas à quelqu'un d'autre) et la liste de contacts (roster) avec leurs groupes. Nous avons ainsi un système de permissions simple à mettre en œuvre et efficace.

Prenons un exemple: vous êtes administrateur sur Prosody (pour mémoire, un serveur XMPP populaire) – pour cela il vous suffit de donner votre jid dans la variable « admins » dans la configuration –, et vous voulez… pouvoir administrer votre serveur. Pas besoin de s'embêter à avoir une page web dédiée avec mot de passe etc, il vous suffit d'avoir un client XMPP qui gère les commandes ad-hoc (Gajim par exemple), et d'entrer l'adresse de votre serveur.

Exemple ci-dessous avec Libervia, l'adresse libervia.org est celle du serveur, voici ce que, en tant qu'admin, je peux voir.

capture d'écran des commandes ad-hoc pour un admin avec Libervia

Le « Send Announcement to Online Users » (envoyer une annonce à tous les utilisateurs en ligne) est particulièrement utile juste avant une mise à jour.

Avec un compte lambda, voilà ce que l'on voit :
capture d'écran des commandes ad-hoc pour un utilisateur lambda avec Libervia

Malheureusement avec certains clients, l'accès est tout sauf intuitif. Je pense que l'exemple le pire est Psi : pour accéder aux commandes du serveur il faut aller dans la découverte des services (« service discovery ») soit via le menu « General » soit en cliquant droit sur votre profil, puis cliquer sur le nom de votre serveur dans la liste des services, puis enfin cliquer sur l’icône en forme de terminal, appelée « execute command » (exécuter une commande).

Dans Gajim c'est plus simple (clique droit sur votre profil puis « exécuter une commande »), dans Swift c'est dans le menu Actions => Run Server Command (Exécuter une commande serveur). Si vous voulez exécuter des commandes sur un jid arbitraire dans Gajim, il vous faut passer par le menu « Découvrir les services », comme avec Psi ; je n'ai pas l'impression que ce soit possible avec Swift.

Ci dessous une capture de Movim, ces commandes sont dans le menu « actions »:

les actions dans Movim

Même sans être administrateur, les commandes « ad-hoc » peuvent vous être utiles. Par exemple, vous avez oublié de déconnecter votre client chez vous et vous vous trouvez chez un ami. Il vous suffit de vous connecter, et de spécifier le jid complet, avec la ressource, de votre client à la maison. SàT par exemple vous permet à l'heure actuelle de changer votre statut voire de vous déconnecter. Gajim permet en plus de transférer les messages non lus ou de quitter des salons de discussions.

Accès à un client Gajim à distance

Il est facile d'imaginer à quel point cette fonctionnalité peut être utile pour l'administration ou la surveillance de serveurs, pour la robotique, la domotique, le contrôle à distance de votre ordinateur, de votre bot XMPP, etc.

Voyons un autre cas pratique que nous avons implémenté dans Salut à Toi : on couple les commandes « ad-hoc » avec D-Bus. Pour ceux qui ne connaissent pas, D-Bus est un autre système de communication inter-processus qui a été développé par Freedesktop comme un standard commun dans les bureaux libres, en s'inspirant de l'existant et en particulier du DCOP de KDE. Il est donc très largement utilisé dans les logiciels libres, et permet de piloter beaucoup de logiciels courants.
En liant D-Bus et ad-hoc, SàT permet de créer très facilement une télécommande universelle, pilotable depuis n'importe quel client XMPP compatible (y compris sur votre téléphone, ce qui est particulièrement intéressant pour une télécommande), et en prime avec gestion des permissions par groupe.

Cette fonctionnalité est montrée dans le courte vidéo ci-dessous, on autorise les membres du groupe « coloc » à piloter une instance de VLC, pratique quand on fait une séance cinéma dans la colocation :).

Nous allons ajouter également la possibilité d’exécuter des scripts ou des commandes shell, on pourra ainsi très facilement autoriser tous les administrateurs d'un serveur à le redémarrer ou à avoir son statut.

Petite note sur le fonctionnement : les commandes ad-hoc, comme à peu près tout ce qui demande de la transmission d'informations typées dans XMPP, se basent sur les « Data Forms » (formulaires de données, XEP-0004). Cette extension standardise donc les formulaires, et permet de demander des booléens, des mots de passes ou encore des listes de jids.

J'en profite aussi pour vous donner le lien vers la conférence « PubSub, microblogage et XMPP » que j'ai faite aux RMLL il y a un peu plus de 2 semaines. J'y explique en 20 min les bases de PubSub et du microblogage dans XMPP, ainsi que l'intérêt des 2 XEPs que nous avons publiées (cf ce journal sur DLFP). J'en reparlerai bien sûr dans un prochain article.

Bien qu'ayant plusieurs idées en tête, je ne suis pas encore décidé pour le prochain article, il est possible que je parle de PubSub, de copie de fichiers, de chiffrement de bout en bout, ou de tout autre chose…

Conférence « PubSub, microblogage et XMPP » en ligne

goffi 23/07/2015, 09:04 technique planet-libre SàT jabber-xmpp Libre

Un petit billet pour vous dire que ma conférence rapide (20 min) et technique sur le (micro)blogage dans XMPP, « PubSub, microblogage et XMPP » vient d'être publiée.

Nous avons beaucoup travaillé dessus cette dernière année, et je pense qu’on va voir XMPP arriver en force dans ce domaine dans les mois à venir.

À voir aussi sur https://rmll.ubicast.tv/videos/pubsub-microblogage-et-xmpp/

e-Jim 07/08/2015, 11:29

Salut Goffi,

Une petite question concernant cette conférence que je viens de visionner: les XEP 0355 et 0356 ont-ils une chance d'être implémentés assez rapidement par des serveurs? Est-ce que vous avez des contacts avec des devs des serveurs principaux dans ce sens?

Sinon, on risque de se retrouver dans la même situation que pour PEP, non?

Goffi 20/08/2015, 12:14

Oups, désolé j'étais passé à côté de ce commentaire...

Alors il y a déjà une implémentation (faite par nous) pour Prosody, et je suppose qu'elle doit marcher pour Metronome aussi vu que c'est un fork.

Nous sommes en contacts avec un des dévs principaux de Ejabberd qui s'est montré intéressé aussi, et au dernier XMPP summit l'équipe de MongooseIM (fork de Ejabberd) était également intéressée, donc tout ça est encourageant.

Maintenant ce qui change vraiment, c'est que d'une part ces 2 XEPs sont beaucoup plus faciles à implémenter qu'un serveur pubsub complet, et d'autre part une fois implémentée, nous ne serons plus bloqués pour les évolutions futures: si une nouvelle XEP sort, nous pourrons l'implémenter nous-même pour tout le monde d'un coup et en profiter directement. Donc la situation n'est pas du tout la même qu'avec PEP.


author website

Parlons XMPP - épisode 5 - les discussions de groupe (suite) et les transports

goffi 21/07/2015, 12:18 technique planet-libre parlons_xmpp jabber-xmpp Libre

(pour lire les épisodes précédents, suivez l'étiquette correspondante)

 

Autre point intéressant par rapport à IRC, XMPP conserve l'ordre des messages, par exemple si vous avez la conversation suivante :

[Morphée] tu peux avoir la pilule rouge
[Lué] OK je prends celle-là
[Morphée] ou la bleue

Avec XMPP vous êtes sûrs que c'est la pilule rouge qui a été choisie, vous évitez ainsi les confusions (et de vivre dans l'ignorance).

Comme dit précédemment, la présence est envoyée au service MUC, pas besoin de vous renommer en xxx_away pour prévenir que vous n'êtes pas là, il suffit d'utiliser l'état associé (et vous pouvez utiliser le message de statut pour compléter). Une autre information utile nous est fournie par la XEP-0085 : les notifications d'états de discussion (« Chat State Notifications »). Cette extension permet de savoir ce que fait un utilisateur par rapport à une conversation : est-ce qu'il est actif dessus ? Est-ce qu'il est parti ? Ou est-il en train de taper un message ? Ceci fonctionne aussi avec les conversations de groupes, et c'est vraiment pratique à l'usage.

Quand vous commencez à fréquenter beaucoup de salons, vous avez envie que votre client en garde la liste, ou d'y aller automatiquement à la connexion ; c'est l'extension « Bookmarks » (marque-pages, XEP-0048) qui permet cela, et vous pouvez ainsi retrouver vos salons en changeant de client (puisque la liste est gardée sur le serveur). Alors petite parenthèse là-dessus, nous sommes plusieurs à penser que cette extension a des problèmes : elle est censée gérer les urls mais personne ne l'utilise de cette façon, elle ne gère pas les étiquettes, et elle pose des problèmes de concurrence, ou si on veut l'utiliser hors standard. Nous (plusieurs développeurs dont Edhelas de Movim que vous connaissez ici) avons donc commencé à écrire une alternative, qui pourrait même être utilisée pour synchroniser les marque-pages dans les butineurs, y compris différents. Affaire à suivre.

En plus de garder la liste, il est bien sûr utile de pouvoir facilement donner un lien vers un salon. La XEP-0045 défini les URI à utiliser pour cela (ici), avec la possibilité de préciser un mot de passe ou d'inviter du monde. C'est de cette façon que l'adresse suivante est cliquable : sat@chat.jabberfr.org ; il suffit de prendre l'adresse du salon, d'en faire une url XMPP en préfixant avec « xmpp: » et d'ajouter « ?join » à la fin pour indiquer qu'on lie un salon MUC. Pour que le lien fonctionne, il faut que vous ayez associé dans votre système un client XMPP avec ces urls (comme vous associez un butineur à une url http:).

Tout n'est pas toujours parfait non plus dans XMPP, et parfois l'héritage historique, ou les évolutions, ou la trop grande souplesse, amènent à un peu de complications.
Ainsi pour MUC il existe 2 méthodes pour inviter quelqu'un : directe (XEP-0249) ou arbitrée (« mediated invitation » définie dans le XEP-0045). La seconde méthode envoie une invitation à travers le salon lui-même, elle est surtout utilisée pour les salons « réservés aux membres » qui sont rares.
Elle risque en outre de se faire bloquer (si un utilisateur n'accepte pas, par exemple, que les messages de personnes dans sa liste de contacts – « roster » –, nous verrons dans un futur article comment faire cela). L'invitation directe est envoyée au jid à inviter sans passer par le salon – d'où son nom –, c'est celle qui est à préférer.
En pratique cette situation ne pose de problèmes éventuels qu'aux développeurs de clients, et il suffit souvent d'implémenter la XEP-0249.

D'un autre côté les extensions permettent des fonctionnalités alléchantes. Ainsi le « Federated MUC » (salons MUC fédérés, XEP-0289) permet de lier des salons entre eux pour qu'ils soient les miroirs les uns des autres. Ceci permet de choisir un serveur plus proche géographiquement de vous, ou d'avoir une solution de repli en cas de problème avec le vôtre. Des discussions sont en cours actuellement pour faire un « MUC 2 » basé sur « PubSub », bref XMPP est un protocole qui est loin d'être figé.

Bon tout ça c'est bien joli, mais IRC est tout de même un protocole qui fonctionne relativement bien, et qui est très populaire, ce serait bien de pouvoir communiquer avec.
XMPP gère des passerelles (ou « gateways » ou encore « transports »), c'est un moyen de communiquer vers un réseau extérieur sans rien modifier à votre client.

La passerelle est souvent sous forme d'un composant qui vient se greffer à votre serveur, et qui traduit le réseau externe (un peu pompeusement appelé « legacy » – réseau hérité – dans le jargon XMPP). La grande force de leur fonctionnement est que le mécanisme pour s'enregistrer est standardisé, et que pour votre client c'est du XMPP classique.
Une passerelle se concentrera la plupart du temps sur un réseau en particulier, et si elle est complète tentera de traduire le maximum voire toutes les fonctionnalités du réseau en question.

C'est la XEP-0100 qui explique le fonctionnement des passerelles, et elle réutilise – comme souvent – des XEP existantes, en l’occurrence « service discovery » dont on a parlé dans l'épisode 3, la XEP-0077 qui gère les enregistrements de comptes et la XEP-0144 (« Roster Item Exchange », échange d’éléments de la liste de contacts) pour l'ajout, la modification, ou la suppression des contacts (ou des « amis » sur les réseaux d'ours en peluche ou tout le monde s'aime et s'observe).
Disco permet, comme on l'avait vu, de nommer les passerelles, voire même pour les plus courantes d'avoir un type dédié. Ainsi il est possible d'identifier une passerelle IRC grâce au couple catégorie/type « conference/irc ».

Ci-dessous, une vielle capture de SàT, tirée de la première vidéo de présentation (2011 !) qui montre un gestionnaire de passerelles. Vous remarquerez peut-être qu'il y a une passerelle vers XMPP lui-même, elle peut être utile pour regrouper différents comptes XMPP si votre client ne le gère pas d'origine.

vieille capture gestionnaire passerelles SàT

Quelques remarques sur les passerelles:

  • souvent vous devez fournir un mot de passe pour vous connecter sur votre compte sur le réseau externe. C'est pratique car vous n'aurez pas à vous souvenir de X mots de passe (une fois enregistré dans la passerelle, plus besoin d'y penser), mais ça veut dire que vous le fournissez à la fois au serveur, et à la passerelle. Il vous faut donc faire confiance aux logiciels utilisés, mais aussi aux administrateurs des serveurs concernés. Encore une fois, il vaut mieux héberger soi-même son serveur.

  • vos communications passeront donc sur le serveur externe. C'est évident, mais il est bon de rappeler que le chiffrement de XMPP ou les précautions prises par vos administrateurs n'auront plus aucun effet une fois passé sur l'autre réseau (et donc selon le réseau, il est possible qu'on enregistre vos conversations, qu'on fasse du commerce avec vos données, etc). Il est toutefois possible d'utiliser du chiffrement de bout en bout dans certains cas, mais nous y reviendrons dans un futur article.

  • les fonctionnalités disponibles sont l'intersection de ce que sait faire XMPP, ce que sait faire/à implémenté votre passerelle, et de ce que sait faire/à implémenté votre client. Dans certains cas vous pouvez tout faire comme avec votre client d'origine du réseau externe (voire plus, avec le chiffrement de bout en bout par exemple), dans d'autres non.

  • si vous utilisez une passerelle vers un réseau non standard voire hostile, il est possible que votre passerelle cesse de fonctionner du jour au lendemain si le protocole change. Utilisez des standards !

Un service souvent utilisé pour les passerelles est Spectrum 2. Pour IRC, je vous recommande particulièrement biboumi: http://biboumi.louiz.org/. C'est fait par la même équipe que Poezio dont j'ai parlé précédemment, et c'est une passerelle très complète et vraiment simple d'utilisation.

Petit détail encore lié à la décentralisation de XMPP : si votre serveur n'a pas la passerelle que vous voulez, vous pouvez parfaitement utiliser une passerelle sur un autre serveur (si celui-ci ne l'interdit pas explicitement), mais cela veut dire que vous devez faire confiance à cet autre serveur pour votre identifiant/mot de passe et pour vos conversations.

Ce fonctionnement par passerelles standardisées et côté serveur permet d'avoir des logiciels qui se concentrent sur un réseau pour pouvoir communiquer avec le mieux possible, de garder le client qu'on apprécie et auquel on est habitué, d'éviter d'avoir à se souvenir de dizaines de mots de passes, d'avoir toutes nos communications au même endroit, ou encore de laisser les administrateurs s'occuper des mises à jour pour tout le monde d'un coup. C'est un gros atout dans la manche de XMPP.

Enfin, il existe aussi des techniques pour synchroniser un salon MUC XMPP avec un canal IRC (ou autre), qui vont du simple bot qui se contente de répéter tout entre les 2 salons (le plugins « Parrot » – Perroquet – permet de faire ça très facilement avec SàT), à celui un peu plus élaboré qui va créer plusieurs connexions sur IRC pour simuler les différents occupants du salon (c'est ce que faisait le désormais abandonné xib – merci Link Mauve pour le nom –). Cette dernière option risque de poser des problèmes avec les administrateurs du serveur IRC, aussi le mieux serait d'avoir un serveur multi-protocoles (ou tout le monde sur XMPP !).

Ceci clos notre tour des MUCs. Je n'ai pas parlé des détails comme les rôles car ils sont calqués sur IRC, et vous pouvez lire la XEP si vous voulez savoir vraiment comment tout cela fonctionne à l'intérieur. J'y reviendrai peut-être dans le futur pour expliquer d'autres XEPs, ou si MUC 2 voit le jour (ce qui semble bien engagé).
La prochaine fois je pense sortir un peu de la messagerie instantanée pour parler des commandes « ad-hoc » (de circonstance).

Parlons XMPP - épisode 4 - les discussions de groupes

goffi 14/07/2015, 11:08 technique planet-libre parlons_xmpp jabber-xmpp Libre

(pour lire les épisodes précédents, suivez l'étiquette correspondante)

Dans le milieu du développement logiciel, et surtout dans le logiciel libre, les discussions de groupes sont très populaires, le plus souvent via IRC (Internet Relay Chat).
Ce vénérable protocole fait ce qu'on lui demande, et XMPP s'en est fortement inspiré. Voyons ça de plus près.

Les discussions de groupes utilisées actuellement sont appelées MUC pour « Multi-User Chat » et sont définies par la XEP-0045. Cette dernière standardise et étend la solution utilisée à l'origine, appelée « groupchat ». Comme tout ceci est calqué sur IRC, je vais expliquer au fur et à mesure les différences majeures avec lui.

Il est possible d'accéder à un salon situé sur n'importe quel serveur depuis n'importe quel serveur (encore une fois, tant que ça n'est pas explicitement interdit dans la configuration). Les salons ont un jid, comme les utilisateurs, qui est de la forme nom_salon@service. Par exemple celui de Salut à Toi est sat@chat.jabberfr.org : « sat » est le nom du salon, « chat.jabberfr.org » le service.

La ressource est utilisée pour les occupants du salon: sat@chat.jabberfr.org/goffi correspond à l'occupant appelé « goffi » sur le salon sat@chat.jabberfr.org. Ah, petit détail que j'ai oublié de vous préciser dans les précédents articles: tout est unicode en XMPP, y compris le jid. Vous pouvez donc utiliser un pseudo arabe ou russe. Mais attention : certains caractères unicodes se ressemblent fortement, aussi il peut y avoir un risque de confusion visuelle entre 2 mots qui se ressemblent graphiquement, qu'on appelle « homoglyphes » : par exemple « gοffⅰ » ressemble à « goffi » mais il utilise des caractères différents. Ce problème est mentionné dans un rapport technique unicode: http://www.unicode.org/reports/tr36/. Aussi, ne vous basez pas uniquement sur un pseudonyme pour identifier quelqu'un (surtout qu'il est possible qu'il soit réutilisé par quelqu'un d'autre entre 2 sessions).

Le pseudonyme (« nickname » ou « nick » en plus court) est lié au salon et non au service : vous pouvez vous appeler « toto » sur un salon et « titi » sur un autre, et il peut y avoir quelqu'un d'autre qui s'appelle « titi » également sur un troisième salon. Ceci est une autre grosse différence avec IRC où on a un seul pseudonyme par serveur, qui sera utilisé pour tous les salons (canaux ou « channels » chez IRC) de celui-ci.

Pour entrer ou sortir d'un salon, ou changer de pseudonyme, on envoie une présence disponible (ou pas) directement à salon@example.net/pseudo_désiré, mais ceci est normalement géré par votre client.

Il est possible d'écrire directement à tous les occupants du salon (en dessous c'est un message de type « groupchat » qui est envoyé au bare jid du salon), ou d'avoir une discussion privée avec un membre (on écrit normalement au jid complet – ou full jid – du destinataire).

Un salon peut être public ou caché (il n’apparaîtra alors pas dans la liste des salons), non anonyme ou semi-anonyme (dans le premier cas tout le monde peut voir le jid réel d'un occupant, dans le second seuls les modérateurs et administrateurs le peuvent), persistant ou temporaire, ouvert ou accessible uniquement à une liste blanche d'utilisateur ou encore protégé par un mot de passe, modéré ou pas.

Ces paramètres se règlent normalement à la création du salon, ou se modifient après coup via l'option idoine de votre client (sur Gajim : clique droit sur un onglet de salon => Gérer le salon => Configurer le salon). Selon le service utilisé, vous pouvez configurer plus ou moins de choses, par exemple limiter le nombre maximal d'occupants.

Une fonctionnalité souvent implémentée est l'historique, ou « back log » : quand vous arrivez dans un salon, le service vous envoie les X derniers messages, vous permettant ainsi de comprendre le contexte de la conversation en cours.

Aussi, si une archive publique du salon est conservée (on parle de salon « loggué »), le service doit vous avertir (c'est obligatoire dans la XEP), ce qui est un autre bon point par rapport à IRC. Il faut bien sûr garder à l'esprit que n'importe qui dans le salon peut garder une archive au risque de la publier sans votre consentement.

Bon tout ça c'est bien joli, mais une grande force d'IRC c'est sa simplicité : pas de compte à créer, il faut juste choisir un pseudo (unique), un serveur et roulez jeunesse ! Eh bien vous ne serez pas déçus, XMPP propose exactement la même chose avec les connexions dites « anonymes ». Pas d'anonymat au sens de Tor ici, mais plutôt la possibilité d'avoir un compte temporaire, avec un jid plus ou moins aléatoire, le temps de vous connecter. Ceci est disponible de base mais doit souvent être explicitement autorisé dans la configuration du serveur, et la plupart du temps les connexions anonymes sont limitées au serveur local, pas de communication avec les autres (pour éviter les pourriels).

Si vous voulez faire des conversations à la IRC de manière simple et intuitive, et si vous aimez la console, je vous recommande fortement Poezio qui est un excellent client XMPP, et qui joue la simplicité : de base, sans rien changer à la configuration, vous serez connecté anonymement sur le service MUC de Poezio. Il s'inspire de Irssi/Weechat, et reprend les commandes de ces derniers (ou plus généralement d'IRC). Ci-dessous le message au premier lancement, sans avoir touché à la configuration, on voit le jid anonyme attribué le temps de la session.

capture Poezio

Bon cet épisode est déjà suffisamment long, mais je n'ai pas fini avec les MUCs, aussi on en reparlera la prochaine fois, probablement avec les transports.

Hedy 14/07/2015, 16:14

Merci pour cette série de billets des plus intéressante :)
J'ai autrefois utilisé XMPP pour monitorer certaines infos de mes serveurs depuis mon roaster : load average, espace disque restant...
Malheureusement depuis Wheezy, mon bout de script a cessé de fonctionner pour une raison obscure et je n'ai pas réussi à remettre le nez dedans.
C'était à la fois léger et efficace :)

Goffi 14/07/2015, 16:27

Hedy: quelle bibliothèque utilisais-tu ? Quel langage ? Tu devrais demander conseil soit chez Debian, soit sur jdev (salon anglophone des développeurs XMPP, il y a aussi une liste de diffusion, tu as tous les liens sur https://xmpp.org/participate/discus...). Il y a probablement des salons francophones qui peuvent t'aider aussi, selon le langage utilisé.


author website

Hedy 14/07/2015, 16:39

Oui je me doute...
C'était un script en python que j'avais récupéré sur un blog.
Je l'ai utilisé des années, et j'ai tjrs été surpris que XMPP ne soit pas plus démocratisé à ce niveau (monitoring).

Un jour, je m'y repencherai sans doute :)

Goffi 14/07/2015, 21:31

En Python il y SleekXMPP et Twisted/Wokkel (qu'on utilise avec SàT) qui sont actifs, ça peut valoir le coup de réécrire.

Mais sinon le monitoring, il peut être plus simple/rapide d'utiliser un client en ligne de commande, ou un bot déjà existant. Nous avons un client en ligne de commande pour ça par exemple (jp), et on l'utilise sur notre salon pour voir les commits mercurial en temps réél. Pour envoyer un message il suffit de faire « echo ton_message | jp message ton_jid@domaine.tld ».


author website

Hedy 14/07/2015, 22:26

Merci pour les pistes :)
De mon côté cet après midi je suis tombé sur Jimbo : http://www.darkcoding.net/software/...

La mise en place est facile mais reste à configurer les infos remontées, et surtout éviter d'envoyer un nouveau msg toutes les 5min et privilégier à la place une mise jour du status (plus discret à mon goût)

Goffi 15/07/2015, 10:54

Ah je ne connaissais pas, bien.

Note que tu peux utiliser un « contenu étendu » dans ton message, c'est à dire un message qui transporte autre chose qu'un texte à afficher (cf https://tools.ietf.org/html/rfc6120... pour les détails). Comme ça tu peux en envoyer plus souvent, et les autres clients ignoreront le namespace qu'ils ne connaissent pas.

Une autre option est d'utiliser PEP: ton serveur est un client XMPP avec PEP, et il transmet les infos sur son état de cette façon.

Tu n'es pas le premier à me parler de monitoring serveur, je me demande si ça ne vaudrait pas le coup d'ajouter des commandes spécialisées pour ça dans SàT et jp...


author website