
  Spcification (non officielle) du protocole Netsoul
  Par Patrick MARIE <mycroft@virgaria.org>
  Dernire modification: 20031029

/*
 * ----------------------------------------------------------------------------
 * "THE BEER-WARE LICENSE" (Revision 42):
 * <mycroft@virgaria.org> wrote this file. As long as you retain this notice
 * you can do whatever you want with this stuff. If we meet some day, and you
 * think this stuff is worth it, you can buy me a beer in return. Patrick MARIE
 * ----------------------------------------------------------------------------
 */

  Ce papier est munie d'une structure qui me semble la meilleure pour la
rdaction de celle ci (lire: j'cris cela comme je le sens).
Il dcrit ce que j'ai pu apprendre en lisant les diffrentes sources des
clients, et en reproduisant diffrentes parties du protocole.

  Pour ceux qui ne le savent pas, Epita/Epitech sont deux coles d'informatique
en France, situe au Kremlin bicetre (sud ouest de Paris).
(liens: http://www.epita.fr/ ; http://www.epitech.net/)

  Je ne suis pour ma part aucunement affili de prs ou de loin  ces coles,
rdigeant cette documentation pour informer les utilisateurs.


I. Sommaire

  * I. Sommaire
  * II. Prsentation
  * III. Phase d'authentification
  * IV. Commandes
  * V. Messages serveur
  * VI. Annexes 


II. Prsentation

  Les informations prsentes dans ce papier feront srement l'objet de
modifications indpendantes de ma volont. Sera indpendante de ma volont
galement la mise  jour de ce texte, car je ne serai certainement pas
motiv pour continuer de chercher ce que les mainteneurs principaux
de Netsoul-Epita (voir ci dessous) feront comme modifications dans le
futur. Les informations sont actuelles  la date de dernire mise  jour
de ce texte.

  Au moment ou j'cris ces lignes, le seul serveur Netsoul-Epita
(Netsoul-Epita nommant le nom du protocole netsoul dans Epita) se situe
sur le port TCP 4242 et  l'adresse "ns-server.epita.fr" (163.5.255.80)
(et en interne dans Epita, 10.42.1.59)

  Les commandes envoyes et reues sont toujours termines par '\n'.
  Certaines commandes envoyes par le client peuvent recevoir des "accuss de
rception", d'autres non. Tout cela sera notifi au bon moment.

  Notations: Les messages reus et envoys tant au format texte ascii, il
est facile de reprsenter dans ce texte plusieurs exemples.
  Les lignes envoyes seront dans ce document prcdes d'un 'client: ';
  Les lignes reues seront prcdes d'un 'server: '.
  Bien entendu, ces 'client: ' et 'server: ' ne font pas partis de la 
communication sur le rseau.

  Par exemple:

-- capture 1 --
client: test
-- fin capture 1 --

  correspondra en C :

  ...
  #define TEST_MESSAGE "test\n"
  ...
  write(sock, TEST_MESSAGE, strlen(TEST_MESSAGE));
  ...

  Pour les exemples "longs", on rajoutera des balises '-- capture X --' et
'-- fin capture X --' pour dlimiter ces exemples.

III. Phase d'authentification

  1/ Premier cas: utilisateur externe au PIE.

-- capture 1 --
client: telnet ns-server.epita.fr 4242
client: Connected to 163.5.255.80.
client: Escape character is '^]'.
server: salut 27 2fb93c1e8020c71ccf99f6555f70e56f 195.220.50.8 45686 1036068977
-- fin capture 1 --

  Le premier message d'authentification est de ce format:

salut <numro de socket> <hash md5 alatoire> <host client> <port client> <timestamp server>

  Le numro de socket est invariablement un unsigned int;
la chane md5 un unsigned char d'une longueur de 32 octets ('\0' final non 
compris);
l'host client est une ip lisible, donc au maximum d'une longueur de 15 octets;
('\0' final non compris);
le port client est un unsigned short;
le timestamp est un time_t.

  Le hash md5 alatoire, l'host client et le port client vont servir  
construire la chane d'authentification  envoyer par le client.


  Avant cela, le client doit demander l'autorisation de s'authentifier, et
en donner la mthode.

client: auth_ag ext_user none none
server: rep 002 -- cmd end


  A partir de ce moment, le client doit envoyer la commande 'ext_user_log',
de ce format la:

client: ext_user_log mycroft b2177622c14612a9b0e725b9c317026f none location
server: rep 002 -- cmd end

  Les paramtres sont de ce format:
ext_user_log <login user> <chane md5 de rponse> <user data> <user location>

  Le login user n'est que le login utilisateur, sur le PIE;
  La chane md5 de rponse est telle que:

  MD5("<hash md5 alatoire>-<host client>/<port client><pass socks>")

  Exemple:

  ...
  /* Les arguments sont rcupres des commandes prcdentes */
  sprintf(buffer, "%s-%s/%i%s", hashauth, client_host, client_port, password);

  /* Primitive MD5 issue de la libcrypto (openssl) */
  MD5(buffer, strlen(buffer), pass);

  /* MD5 renvoie des donnes sous format binaires, on rend la chane 
     'lisible' */
  str = malloc(sizeof(char) * (MD5_DIGEST_LENGTH * 2 + 1));
  memset(str, 0, (MD5_DIGEST_LENGTH * 2 + 1));
  for (i = 0; i < MD5_DIGEST_LENGTH; i ++)
     sprintf(str + (2 * i), "%02x", pass[i]);
  ...


  Le champs 'user data' et 'user location' permettent de dfinir deux valeurs,
en gnral le client utilise et la version, et la location du client (dans
le PIE, la salle, le rang et le numro de station)

  Ces deux champs doivent tre dans le format des urls, c'est  dire pour 
faire passer "toto tutu lala" il faudra envoyer "toto%20tutu%20%lala"

  Ces deux champs sont de longueur maximum de 64 caractres.

  Exemple:

client: ext_user_log mycroft c5b38c5022d9e1af23cfb89630010f03 paul%2Dsud%2Easso%2Eups%2Dtlse%2Efr%20 nsc%20roulez
server: rep 002 -- cmd end


  Au moment o l'ext_user_log est envoy et confirm, l'utilisateur est loggu
dans le rseau netsoul et peut envoyer des commandes.

  On associera deux commandes  la phase de connexion pour un utilisateur
externe au PIE: "attach" et le changement de status.

  'attach' permet aux utilisateurs externes de librer l'accs  d'autres
daemons interne  epita tels que les news.

client: attach
server: rep 002 -- cmd end

  En final,  la connexion, le status utilisateur est 'connexion'. Le client
doit changer ce status. (voir plus loin.)

client: state actif:1067437282

  Le serveur ne renvoie rien suite  la commande 'state'.


  2/ Second cas: utilisateur interne au PIE.

  Un utilisateur du PIE, c'est  dire l'ensemble des machines dans le parc
informatique d'epita n'a pas  subir cette phase d'authentification, comme
elle a t tablie par la connexion de l'utilisateur sur le rseau.

  Afin de rcuprer la connexion, l'utilisateur doit rcuprer les variables
d'environnement $NS_USER_LINK afin de connaitre le numro de la socket unix,
qui sera:

  ...
  int sock;
  struct sockaddr_un sua;

  sock = socket (PF_LOCAL, SOCK_STREAM, 0);

  sprintf(path, "%s/.ns/%s", getenv("HOME"), getenv("NS_USER_LINK"));
  strcpy(sua.sun_path, path);

  connect (sock, (struct sockaddr *)&sua, sizeof(sua));
  ...


IV. Commandes

  Ces commandes existent pour les clients internes et externes au PIE.

  D'une manire gnrale, les commandes utilisateurs doivent tre prcde
d'un 'user_cmd' quand on est  l'extrieur du PIE, et d'un 'cmd' quand on
est  l'intrieur du PIE.

  Exemple:

  Si l'on veut envoyer un message  'rn' (voir section IV. 2/ ), on utilisera:

  - de l'extrieur:

client: user_cmd msg_user rn msg test 

  - de l'intrieur (sur la socket unix):

client: cmd msg_user rn msg test


  1/ state

  Les clients (utilisateur) netsoul se voient attribus d'un status de la
connexion.

  Bien que n'importe quel status semble tre accept par le serveur, il est
prfrable d'en utiliser qu'un de ceux ci:

  * actif
  -> Vous tes sur votre station de travail, prs  tre joint si ncessaire;
  * away
  -> Vous n'tes pas sur votre station de travail;
  * connection
  -> Vous n'avez pas chang le status par dfaut suivant la connexion;
  * idle
  -> Vous tes sur votre station, mais n'avez pas montr signe de vie;
  * lock
  -> Vous avez lock votre station;
  * server
  -> Le client est sur un serveur d'applications;
  * none 
  -> Vous ne dsirez pas utiliser le status.

  Avec cela, il faut envoyer le timestamp de changement d'tat, sous ce format:

state <new status>:<timestamp>

  Exemples d'utilisation:

client: state actif:1036142854

state away:1036142860

  D'une manire gnrale, les commandes utilisateur

  A l'externe du PIE, cette commande peut aussi etre envoye de cette forme:

client: user_cmd state <new status> 

  Exemples d'utilisation:

client: user_cmd state none
client: user_cmd state actif

  Voir galement la section "Messages serveur".


  2/ msg

  Comme jabber ou yahoo, il est possible de faire de "l'instant messaging"
avec Netsoul.

  On peut envoyer des messages  toutes les personnes loggus  netsoul. 
L'envoie de message  des personnes non loggus est autorise, mais les
messages ne sont pas conservs par le serveur (donc perdus).

  Exemple, pour un utilisateur externe puis interne: 

client: user_cmd msg_user rn msg bonjours 
client: cmd msg_user rn msg bonjours

  Format:
(cmd|user_cmd) msg_user <login / liste login> msg <message>

  login / liste login contient soit un login (Exemple: 'rn');
    soit une liste de login (Exemple: '{rn,jumpy,:42}'), ou, entre accolades
et spares par des ',', on peut mettre soit des login soit des numros de
sockets (prefixees alors de ':').
    Cette notion de liste de login est galement utilise pour d'autre
commandes.

  message: le message doit tre du mme format que "user data" et "location",
en 'url encoded'.

  Exemple:

client: user_cmd msg_user {mycroft,:1049} msg Salut%2C%20ca%20vas%20%3F

  Voir galement la section "Messages serveur".


  3/ list_users

  list_users permet de rcuprer la liste des clients loggues sur netsoul.
Il peut viser un login en particulier ou plusieurs via une liste de login
(dcrit dans la section IV. 2/)

  Format:
list_users <login / liste login> 

  Exemple:

-- capture 1 --
client: list_users rn
server: 1419 rn 163.5.42.42 1067515354 1067516102 1 3 NetBsd_wse bocal_r1p1 wheel actif:1067516103 -
server: rep 002 -- cmd end
-- fin capture 1 --

-- capture 2 --
client: list_users dontexist
server: rep 002 -- cmd end
-- fin capture 2 --

-- capture 3 --
client: list_users {:1419,benoit_e}
server: 184 benoit_e 10.252.42.53 1067515906 1067516521 3 1 ~ kernel ept_2002 serveur:1067515855 bnsd-0.1
server: 1419 rn 163.5.42.42 1067515354 1067516718 1 3 NetBsd_wse bocal_r1p1 wheel actif:1067516719 - 
server: rep 002 -- cmd end
-- fin capture 3 --

  Voir la section IV. 2/ pour la description de 'login / liste login'.
  Voir galement la section "Messages serveur".


  4/ watch_log_user

  watch_log_user permet de mettre en place, sur le serveur, une liste de
login/connexion pour lesquelles on veut etre avertis des login/logout/
changements de status... (comme icq, aim, ...)

  Format:

(cmd|user_cmd) watch_log_user <login / liste login>

  Exemple:

client: user_cmd watch_log_user {rn,benoit_e}

  Voir la section IV. 2/ pour la description de 'login / liste login'. 
  Voir galement la section "Messages serveur".


  5/ who

  who permet d'avoir des informations sur un/des utilisateur(s) loggues
(moyen de substitution  list_users).

  Format:

(cmd|user_cmd) who <login / list login>

  Exemple:

-- capture --
client: raw user_cmd who {rn,mycroft}
server: user_cmd 525:user:1/3:mycroft@195.220.50.8:~:paul%2Dsud%2Easso%2Eups%2Dtlse%2Efr%20:ext | who 525 mycroft 195.220.50.8 106751826 5 1067518791 3 1 ~ paul%2Dsud%2Easso%2Eups%2Dtlse%2Efr%20 ext actif:1067518387 nsc%20roulez
server: user_cmd 525:user:1/3:mycroft@195.220.50.8:~:paul%2Dsud%2Easso%2Eups%2Dtlse%2Efr%20:ext | who 1419 rn 163.5.42.42 1067515354 1067518532 1 3 NetBsd_wse bocal_r1p1 wheel actif:1067518039 -
server: user_cmd 525:user:1/3:mycroft@195.220.50.8:~:paul%2Dsud%2Easso%2Eups%2Dtlse%2Efr%20:ext | who 118 mycroft 212.129.36.164 1067500202 1067518681 3 1 ~ appart%40madrid ext actif:1067500221 bns%2D0%2E9%2E2%20%5B%20bNetSoul%20rocks%20%5D
server: user_cmd 525:user:1/3:mycroft@195.220.50.8:~:paul%2Dsud%2Easso%2Eups%2Dtlse%2Efr%20:ext | who rep 002 -- cmd end
-- fin capture --

  Voir la section IV. 2/ pour la description de 'login / liste login'.
  Voir galement la section "Messages serveur".


  6/ exit

  Un client peut envoyer  tout moment la commande 'exit' afin de se delogguer
du serveur.


V. Messages serveur

  1/ Changement de status d'un utilisateur

  Le client netsoul recevra tout les messages login, logout et state d'un
utilisateur qu'il aura mis dans sa "watch_log" list.

  Exemple:

client: user_cmd watch_log_user {mycroft}
[...]
server: user_cmd 91:user:1/3:mycroft@195.220.50.8:~:paul%2Dsud%2Easso%2Eups%2Dtlse%2Efr%20:ext | login
server: user_cmd 91:user:1/3:mycroft@195.220.50.8:~:paul%2Dsud%2Easso%2Eups%2Dtlse%2Efr%20:ext | state actif:1067518230
server: user_cmd 91:user:1/3:mycroft@195.220.50.8:~:paul%2Dsud%2Easso%2Eups%2Dtlse%2Efr%20:ext | state away:1067518242
server: user_cmd 91:user:1/3:mycroft@195.220.50.8:~:paul%2Dsud%2Easso%2Eups%2Dtlse%2Efr%20:ext | logout
[...]

  Voici le format d'une notification:

user_cmd <socket>:user:<trust level>:<login>@<user host>:<workstation type>:<location>:<groupe> | <command> <command extension>

  socket: unsigned int, reprsentant le numro de la socket du client qui
          vient d'envoyer le message;
  trust level: 1/3 hors du PIE (en externe, donc), 3/1 en interne;
  login: login de l'utilisateur du client qui envoie le message;
  user host: adresse ip du client;
  workstation type: type de la machine (seulement pour le PIE, ex: NetBsd_wse);
  location: champs location de l'utilisateur (en url encoded);
  command: soit login (pour indiquer que l'utilisateur vient de se logguer),
                logout (l'utilisateur vient de se delogguer),
                state (l'utilisateur vient de changer de status).


  2/ Rception d'un message

  La rception d'un message est similaire au changement d'un status (V. 1/);
Est juste diffrent la commande, qui sera 'msg':

  Exemple:

client: user_cmd msg_user {mycroft} msg test
server: user_cmd 525:user:1/3:mycroft@195.220.50.8:~:paul%2Dsud%2Easso%2Eups%2Dtlse%2Efr%20:ext | msg test

  Le message est url-encoded, et ne peut contenir plus de 256 caractres
(aprs encodage.)

  De plus, on pourra recevoir les notifications pour les mails:

server: user_cmd 0:mail:9/9:_deamon:: | new_mail -f mycroft@virgaria.org %28test%20email%29

  La commande est 'new_mail'; Cette commande est suivie de -f, puis de l'email
source du message et finalement du titre du mail en url-encoded.


  3/ Rception d'une rponse  la commande list_users

client: list_users franco_l
server: 1043 franco_l 213.142.23.186 1067500237 1067520661 3 1 ~ rhs%2Ese epita_2003 actif:1067500198 42
server: rep 002 -- cmd end

  Le format du message reu est de la forme:

<socket> <login> <user host> <login timestamp> <last status change timestamp> <trust level low> <trust level high> <workstation type> <location> <group> <status> <user data>

  socket: unsigned int, reprsentant le numro de la socket du client qui
          vient d'envoyer le message;
  user host: adresse ip du client;
  login timestamp: heure de connexion du client sur netsoul
  last status change timestamp: heure du dernier changement d'etat;
  trust level low/high: correspondent au 1/3 et 3/1 pour les machines dans le
                        PIE et hors du PIE;
  workstation type: type de la machine;
  location: champs location de l'utilisateur (en url encoded);
  group: groupe de l'utilisateur;
  status: status de l'utilisateur;
  user date: champs userdata de l'utilisateur (en url encoded).
  

  4/ Rception d'une rponse  la commande who

  Suite  la commande who, le client reoit au moins une ligne comprenant,
sous la forme d'un message de changement de status (V. 1/), mais ayant comme
commande 'who' le message 'rep 002 -- cmd end'.

client: user_cmd who {rn}
server: user_cmd 525:user:1/3:mycroft@195.220.50.8:~:paul%2Dsud%2Easso%2Eups%2Dtlse%2Efr%20:ext | who 1419 rn 163.5.42.42 1067515354 1067522535 1 3 NetBsd_wse bocal_r1p1 wheel idle:1067522086 -
server: user_cmd 525:user:1/3:mycroft@195.220.50.8:~:paul%2Dsud%2Easso%2Eups%2Dtlse%2Efr%20:ext | who rep 002 -- cmd end

  Le format de la partie avant le '|' est dcrit dans la section V. I/
  Le format de la partie aprs le '|' est le suivant:

| who <socket> <login> <user host> <login timestamp> <last change timestamp> <trust level low> <trust level high> <workstation type> <location> <group> <status> <user data>

  Le message reu aprs le 'who' tant du mme format que celui renvoy par la
commande 'list_users', le format n'en sera pas re dcrit ici. cf section V. 3/


  5/ Rception d'un 'ping'

  Le serveur netsoul envoit rgulierement des 'ping' afin de voir si le
client est encore connect. Il associe cela  un nombre qui correspond au
nombre de seconde que le serveur attend aprs un message du client avant de
le dconnecter.
  Le client peut rpondre, par exemple, la mme ligne envoye.

  Exemple:

server: ping 600
client: ping 600


VI. Annexes

  1/ A faire

  * tenter une connexion ext  l'intrieur du PIE; il me semble que le
'protocole' d'auth etait une fois de plus diffrent. (cf mthode csecret)
  * voir les diffrentes gestions des "cmd", "user_cmd", ...  l'intrieur
du PIE.
  * extensions des clients:
06:33 !!! Not yet handled: [user_cmd 95:user:1/3:asega_a@10.253.4.11:~:%5co_:ept3 | dotnetSoul_UserCancelledTyping null ]
06:33 !!! Not yet handled: [user_cmd 95:user:1/3:asega_a@10.253.4.11:~:%5co_:ept3 | dotnetSoul_UserTyping null ]
06:33 !!! Not yet handled: [user_cmd 95:user:1/3:asega_a@10.253.4.11:~:%5co_:ept3 | dotnetSoul_UserCancelledTyping null ]

  * rcuprer les clients en commande, et voir les fonctions.

  2/ Exemple de connexion 'complet'

  3/ Change Log

