YooGoo

 
 
Bienvenue sur YooGoo
 
 

 
 
News

Description du Projet
Avancement du Projet
L'équipe
Photos du Projet et du reste
 
 

 
 
Téléchargement

Le Client
Le Serveur
Les Sources Serveur
Les Sources Client
Cahiers des Charges
Soutenance 1
Soutenance 2
Soutenance 3
Soutenance Finale
 
 

 
 
Contacts

Franck Tetzlaff CV Tessari Marco CV Bouhelier Stéphane CV Pouiller Jérôme CV
 
 

 
 

\includegraphics{YooGoo-Line.eps}
Rapport de troisième soutenance

BOUHELIER Stéphane alias Folkensama (Spé C1)
POUILLER Jérôme alias Hargos (Spé C1)
TESSARI Marco alias Zapata (Spé C1)
TETZLAFF Franck alias Danao (Spé C1)

EPITA - Avril 2002


Table des matières

Introduction

Description

Dans le cadre pédagogique d'Epita, nous travaillons sur un projet nommé YooGoo qui à pour but de créer un outil de communication sur internet. L'étymologie du mot "YooGoo" se perd dans les méandres des cerveaux dégénérés de quatre épitéens... Le projet est articulé autour du protocole, il à pour but d'établir les règles de communication, il nécessite une architecture client / serveur. A partir du protocole, il est possible de concevoir un logiciel capable d'interagir avec les autres logiciels YooGoo. YooGoo se veut sécurisé, il existe donc une couche de cryptage qui permet la confidentialité des communications. Cette particularité rend le sniffing (écoute des trames réseau) impraticable sur YooGoo. YooGoo se veut simple d'utilisation, lors de sa conception nous avons tiré partie de notre expérience des chats pour faire un protocole clair, avec des commandes simples et aux noms explicites. Le protocole est suffisamment intuitif pour que l'on puisse se connecter sur un serveur YooGoo à l'aide d'un simple client texte. Toutes les commandes retournent un message d'information suffisamment explicite pour que l'utilisateur sache où est l'erreur. Néanmoins, l'utilisation d'un client texte étant peu attrayante, nous avons aussi créé un client graphique. Celui-ci est suffisamment intuitif pour être utilisé sans avoir besoin de lire l'aide. Mais, il est suffisamment puissant par tirer pleinement parti des fonctions du serveur YooGoo. Nous voulons aussi un client entièrement personnalisable, car YooGoo se veut capable de s'adapter. YooGoo est en priorité basé sur des salons de discussion (appelés aussi canaux). Il permet l'administration des canaux grâce à un système de hiérarchie totalement invisible pour l'utilisateur normal. YooGoo gère aussi une liste de contacts qui permet de savoir qui est connecté en même temps que soi sur YooGoo. Nous avons aussi ajouté la possibilité à l'utilisateur de s'inscrire sur YooGoo et d'y avoir un profile. Tout ceci est géré par une puissante base de données. Nous avons aussi pensé à l'administration du serveur en incluant de puissantes commandes d'administration. L'administrateur a ainsi la possibilité de loguer tous les événements du serveur. Il est ainsi possible d'en tirer des statistiques sur l'utilisation du serveur.
YooGoo se veut sécurisé, simple d'utilisation et capable de s'adapter.

État du projet

Lors de la dernière soutenance, nous avions terminé la base de données et la gestion des connections sur le serveur. La conception du protocole était faite depuis la première soutenance et nous avions commencé à l'implémenter. Pour cette soutenance, nous avons fini d'implémenter le protocole. Cette implémentation nous a obligés à faire quelques modifications sur le protocole. Le protocole d'aujourd'hui a subit beaucoup d'améliorations et d'ajout depuis la première soutenance. Parmis ces ajouts, on trouve les commandes d'administration du serveur et la gestion de la contact list. Pour aider l'administrateur, nous avons aussi ajouté des logs et la gestion d'un fichier de configuration. Le serveur a aussi subit une grosse séance de debugging. A l'heure actuelle, le serveur est en Final Bêta Test. Nous avons implémenté toutes les fonctions décrites dans le cahier des charges. Nous en avons même rajoutées quelques-unes. Nous ne devrions plus avoir à toucher au code du serveur jusqu'à la soutenance finale, à moins que l'on ne découvre un bug.
Lors des autres soutenances nous avions montré un client en mode texte qui suffisait pour executer des commandes sur le serveur. Mais il est prévu un client graphique avec une interface graphique, et de multiples fonctionnalité qui permettront de simplifier l'utilisation de YooGoo.Nous nous sommes pour l'instant occupé du travail graphique. Ce dernier doit être terminé ou bien avancé pour cette soutenance. Comme les travaux graphiques demandent un temps énorme en recherche et en poffinage, cette organisation nous permettra dans la dernière soutenance de nous consacrer intégralement au code. De plus les projets de l'année dernière nous ont servis de leçon en matière de graphisme. En effet avec le graphisme et le multimédia en général, il est difficile de savoir s'arrêter car il est toujours possible de mieux faire. Pour la dernière soutenance il ne sera uniquement question de la création de la skin de base comme pour WinAmp. Celle-ci ne devrait pas nous prendre énormément de temps.

Qui a fait quoi?

Puisque nous sommes en avance par rapport au planning du cahier des charges, les tâches de chacun ont été modifiées. Hargos et Zapata se sont consacrés uniquement à la finalisation du serveur, tandis que Danao et Folken ont travaillé sur le client. Voici ce que chacun à fait :
Danao
s'est occupé de l'interface graphique du client, il a du apprendre à manier les composant et les objets windows.
Folkensama
a travaillé sur la mise en forme des messages, le traiement des couleurs et des images sur le client
Hargos
a implementé le protocole, travaillé sur les fonctions d'administrations, les logs et le fichier de configuration.
Zapata
a travaillé sur le protocole et implémenté la gestion d'une la liste de contacts.

Le serveur achevé

L'utilisateur

Définition.

Un serveur de chat à pour but de permettre à plusieurs utilisateurs de dialoguer entre eux. Chaque utilisateur à la possibilité d'échanger des messages avec les autres. De plus pour permettre aux utilisateurs de se regrouper, certaines informations peuvent être publiées aux autres, et éventuellement, enregistrées sur le serveur.
Chaque utilisateur est représenté en mémoire sur le serveur par un objet. On parlera alors d'un objet utilisateur (ou user). Celui ci regroupe toutes les informations relatives à un utilisateur. Celles ci peuvent être d'ordre technique comme le socket, le tampon d'envoi (voir la partie réseaux du rapport de deuxième soutenance), tout comme des informations sur les utilisateurs comme la ville où il habite, sa date de naissance. L'objet utilisateur contient aussi deux files, une pour les messages qu'il a reçus qui attendent d'être traités, l'autre la liste des canaux auquel il est connecté.
Pour mettre de l'ordre dans tous ces objets utilisateurs, ils sont classés dans une base de données. Souvent il sera nécessaire de retrouver l'objet utilisateur correspondant à un nom. Il existe donc cinq arbres de classement, en fonction du nom, de la ville, de la date de naissance et enfin une liste des connectés triés par nom. La structure interne est un arbre (de type AVL, pour plus d'informations sur le fonctionnement voir le rapport de deuxième soutenance).

Deux types d'utilisateur.

Non-enregistré

Un utilisateur qui se connecte ponctuellement sur YooGoo, peut ne pas vouloir fournir d'informations le concernant. Il est alors un peu comme un invité. Aucunes des informations qu'il fournit ne sont conservées sur le serveur. A peine il sera déconnecté que son profil n'existera plus, il est obligé d'envoyer les informations à chaque fois. Un utilisateur à tout de même accès à toutes les fonctions de YooGoo.

Enregistré

Un utilisateur régulier de YooGoo aura fortement intérêt à s'enregistrer. Toutes les informations qu'il fournit sont alors enregistrées sur le serveur. Ainsi à chaque connexion il retrouve toutes les informations qu'il a pu rentrer dans ses précédentes sessions.

Enregistrement

La commande REG PASSWORD permet d'enregistré le pseudo sous lequel on est connecté. Par la suite cet utilisateur devra taper son mot de passe à la connexion pour pouvoir accéder au serveur. Ainsi on est sur que ce soit toujours la même personne qui utilise ce nom. Pour se désenregistré on utilise la commande UNREG (sans paramètre). Chaque enregistrement crée une entrée dans une base de données d'utilisateur. Lorsqu'on se désinscrit l'entrée est supprimée, et il ne reste plus de trace de l'utilisateur.

Base de données des utilisateurs.

Le profil d'un utilisateur est conservé dans un fichier (par défaut "user.yoo"). Quand l'utilisateur s'enregistre, on lui attribue une ligne dans le fichier (la dernière). Ainsi à chaque fois qu'on aura besoin d'accéder à ses informations on ira directement à cette ligne du fichier. Ceci est d'autant plus facile que chaque ligne du fichier à la même taille.
Cette ligne contient toutes les informations du profil d'un utilisateur. Chaque champ est séparé par un caractère spécial. Les champs ne doivent donc pas contenir ce caractère. Les différents champs du profil sont (dans l'ordre): pseudo, genre, date de naissance, ville, mot de passe, nom, prénom, adresse, code postal, langue, pays, téléphone n°1, téléphone n°2, e-mail n°1, e-mail n°2, photo, description. Dans le fichier la taille de chaque champ est prédéfinit. Si la valeur fournit ne fait pas la bonne taille, les trous sont comblés par des espaces.
Lors d'un désenregistrement on supprime la ligne de l'utilisateur du fichier. Pour cela, on copie la dernière ligne du fichier, on la met à la place de celle à supprimer, puis on réduit la taille du fichier de la taille d'une ligne. Il ne faut pas oublier de mettre à jour la ligne de l'utilisateur qui a été déplacé.
Au démarrage du serveur, le fichier base de données est parcouru, et on crée en mémoire un objet pour chaque utilisateur enregistré. Ceci permet de pouvoir effectuer des opérations sur les utilisateurs enregistrés même si ceux ci ne sont pas connectés.

Informations.

Les utilisateurs ont donc la possibilité d'envoyer des informations leur concernant afin de les rendre disponibles aux autres utilisateurs. Chaque utilisateur, enregistré ou pas, à un mini profil contenant son pseudo, sa ville, sa date de naissance et son genre. Un utilisateur enregistré a, quant à lui, un profil complet avec nom, prénom, adresse etc.
Pour modifier les valeurs des champs de son profil, on utilise les fonctions CHNICK, CHGENDER,... et ainsi de suite pour tous les champs du profil. Ces fonctions testent les arguments passés en paramètre pour voir s'il est acceptable. Si aucune valeur est passé en paramètre à la fonction, on efface le contenu du champ.
Le profil complet n'existe pas en mémoire. Il faut donc pour les fonctions qui modifient ces valeurs écrire directement dans le fichier. On accède au fichier à la ligne de l'utilisateur, on va jusqu'au champ que l'on veut modifier en comptant le nombre de caractères délimiteurs rencontrés et on modifie le champ (toujours en complétant la taille du champ avec des espaces). Ainsi la base de données est toujours à jour.
Les valeurs du mini profil sont aussi stockées en mémoire car on y accède beaucoup plus souvent. Nous avons vu que les objets utilisateurs sont triés dans des arbres selon leur pseudo, leur ville, leur age et leur genre. Lors d'une modification d'une de ces valeurs il ne faut pas oublier de mettre à jour les arbres, pour cela on supprime l'ancien utilisateur et on ajoute le nouveau.
Toutes ces informations sont accessibles aux autres utilisateurs grâce à deux fonctions. La première est ASV USER qui renvoie RPL_ASV NICK STATUS GENRE VILLE. On obtient aussi tout le mini profil. Cette fonction est utilisable aussi bien sur les utilisateurs enregistrés que sur ceux non enregistrés. La seule restriction est qu'ils doivent être connectés. La deuxième fonction est WHO USER. Elle renvoie plusieurs réponses RPL_WHO. La fonction ne renvoie que les champs qui ont une valeur non nulle. Les différentes réponses sont :
  • RPL_WHO n°1 = Pseudo + genre + age + ville
  • RPL_WHO n°2 = Nom + Prénom + Adresse + Code Postal + Langue + Pays
  • RPL_WHO n°3 = Téléphone 1 + Téléphone 2 + Mail 1 + Mail 2
  • RPL_WHO n°4 = Photo + Description
La fin de la transmission est marquée par le message RPL_ENDWHO. La valeur du champ est précédée par un identifiant par exemple :
        Rpl_who NOM= Angeline SEXE= FEMALE AGE= 19821006 VILLE= Paris
La commande WHO ne marche que sur les utilisateurs enregistrés, connectés ou non.
Mais le plus grand intérêt du profil est de pouvoir effectué des recherches dessus. Il existe une fonction de recherche qui renvoie la liste des utilisateurs correspondant aux critères que l'on a définit. Il est donc possible de faire une recherche multicritère. La fonction de recherche se prototype ainsi :
Search [Nick=Pseudo] [Age=Age][Birth=Date_Naissance] [Town=Ville]
       [Sex={Male|Female}][Status={OnLine|OffLine}]
Pour chaque argument passé en paramètre à la fonction, on regarde où est le '$=$', on regarde quel est l'identifiant qui le précède et on affecte la valeur de ce champ à un objet utilisateur temporaire. On recherche ensuite s'il y a un utilisateur qui correspond exactement, sinon on recherche la liste des utilisateurs qui ressemble à l'utilisateur recherché. Ceci est possible grâce aux différents arbres de la base de données. On renvoie alors une réponse RPL_SEARCH PSEUDO pour chaque utilisateur trouvé.

Liste de contacts.

Principes.

La liste de contact est une liste de personne que l'on connaît et qui ont des droits spéciaux. Il y a deux types de personnes que l'on rajoute dans sa liste, des personnes que l'on aime bien avec qui on va partager certaines informations. D'autres qu'on essaye d'éviter, on pourra alors leur interdire certaines choses.
La liste de contact contient en fait deux listes. La liste de contacts à proprement parler, qui associe à des noms des droits. Mais aussi une liste de personne dont on est ami. Cette liste permet de savoir à qui il faut envoyer des informations lorsqu'il y à des changements.
Les listes des utilisateurs enregistrées sont sauvegardées, tout comme le profil. Mais vu qu'on ne connaît pas par avance le nombre de contacts que l'utilisateur va avoir, on ne peut avoir une ligne de taille fixe par utilisateur. Il y a donc un fichier par personne. Ce fichier contient une première ligne avec la première liste, une suite de noms et d'entiers séparés par un caractère spécial. A chaque connexion d'un utilisateur enregistré on charge sa liste en mémoire. Il faut alors faire attention car il peut avoir eu des changements alors qu'il était déconnecté, par exemple quelqu'un l'a supprimé de sa liste, il faut donc mettre à jour la liste des personnes dont on est ami pour cesser de le prévenir lors de changements. Lors de la déconnexion on sauvegarde les listes dans le fichier.

Les différentes fonctions.

La fonction permettant de gérer toute la liste de contacts est :
    contactlist add|get|del|change|accept|denie|status
Voici le détail de chaque sous fonction :
ADD USER [DROIT]
:
ajoute un utilisateur à la liste de contacts. Si droit n'est pas indiqué c'est la valeur par défaut qui sera donné comme droit. Si c'est un droit "mauvais" on envoie à l'utilisateur ajouté soit CL_BLACKLISTEDBY (l'utilisateur à été mit en liste noire) soit CL_IGNOREDBY (l'utilisateur est ignoré) soit CL_MUTEBY (l'utilisateur ne peut plus parler avec la personne). Si le droit est "ami" , on envoie alors une requête d'ajout à l'utilisateur concerné, sauf si celui ci a aussi donné un droit "ami" à l'appelant.
DEL USER
:
supprime un utilisateur de la liste de contacts. Si l'utilisateur était un ami il est prévenu par CL_REMOVEDBY. Si l'utilisateur supprimé était un ami, on supprime le nom de l'appelant dans la liste des utilisateurs dont il est ami.
CHANGE USER [DROIT]
:
change les droit d'un utilisateur de la liste de contacts. Il faut faire attention aux cas où un "ennemi" devient un "ami" ou vice-versa. Si pas de droit la valeur par défaut est mise.
GET [USER]
:
permet de recevoir la liste de contacts d'un utilisateur. Sans paramètre la fonction renvoie la liste de contact de l'appelant. Sinon il faut que l'utilisateur ait les bons droits chez l'utilisateur dont il désire avoir la liste de contacts.
Renvoie RPL_CL PSEUDO DROIT (avec dix couples (pseudo, droit)maximum par réponse).
ACCEPT USER
:
permet d'accepter la demande d'ajout d'un ami.
DENIE USER
:
refuse la demande d'ajout d'un ami.
STATUS
:
renvoie le statut de tous les utilisateurs amis présents sur la liste de contacts.

Les droits.

Comme nous l'avons vu, il est possible de donné des droits "ami" comme des droits "mauvais" aux utilisateurs présents dans la liste de contacts ?
Les différents droits sont :
CL_BLACKLIST
:
L'utilisateur cible est mis sur liste noire. Il n'a plus accès aux informations de l'utilisateur appelant (la fonction WHO et ASV lui sont inaccessibles). Il lui est impossible de parler avec l'utilisateur appelant. Si l'utilisateur cible essaye d'ajouter l'appelant à sa liste de contact, il obtiendra un refus automatiquement. De plus l'appelant ne reçoit plus les messages de la cible même lorsqu'il est connecté sur le même canal.
CL_NOREP
:
L'utilisateur appelant ne donne plus accès à ces informations (WHO et ASV inaccessibles). Un ajout sur la liste de contacts sera automatiquement refusé.
CL_MUTE
:
L'utilisateur appelant ne reçoit plus aucun message de la part de la cible, ni directement ni des canaux.
CL_NOINOF
:
L'utilisateur cache ces informations (WHO et ASV inaccessibles).
CL_ASVONLY
:
Le WHO est inaccessible à la cible.
CL_AMI1
:
L'utilisateur cible est un ami. La cible prévient de ses changements de statut, de ses connections et déconnections.
CL_AMI2
:
L'utilisateur cible est un ami. La cible prévient de ses changements de statut, de ses connections et déconnections. La cible peut avoir accès à la liste de contacts de l'appelant.

Le Statut.

Le statut permet d'indiquer dans quel état on est. Souvent certains utilisateurs restent connecté toute la journée, mais ils ne sont pas forcement devant leur ordinateur. Pour prévenir les autres dans un tel cas, il suffit de mettre sont statut sur AWAY, pour indiquer que l'on est partit. Comme état il existe :
  • ONLINE, on est connecté et devant son ordinateur.
  • CHAT, on est disponible pour discuter.
  • AWAY, on n'est pas devant son écran.
  • DND, Do Not Disturb, on ne veut pas être dérangé.
  • OCCUPIED, on est occupé.
  • BRB, Be right Back, on revient tout de suite.
  • OFFLINE, non connecté.
A chaque changement de statut il faut prévenir toutes les personnes qui sont nos amis. Il faut aussi prévenir tous les utilisateurs qui sont connectés au même canal, ceci peut permettre à un client YooGoo de suivre l'évolution du statut des utilisateurs connectés sur un canal. Il faut aussi prévenir ses amis lorsqu'on se connecte et quand on se déconnecte. A la connexion il faut aussi recevoir les statuts de tous les utilisateurs amis présents dans la liste de contacts. Ceci ce fait grâce à la fonction contactlist status. Cela est optionnel, donc ce n'est pas le serveur qui s'en occupe, c'est le client qui doit envoyer cette commande pour gérer une liste d'amis.

Communication avec les autres.

Que serait un serveur de chat sans commande pour dialoguer entre utilisateurs ? Dans YooGoo il existe deux façons de parler entre utilisateur, soit en passant par des canaux, soit en communiquant directement avec un utilisateur.
Pour une discussion directe il y a deux possibilités, soit en passant par le serveur, soit en connexion directe entre les deux personnes. Pour une connexion directe c'est la commande QUERY USER PORT qui sera utilisée. La commande query envoie à l'utilisateur cible l'adresse IP et le port où il doit se connecter pour parler avec l'autre utilisateur. C'est alors aux client de s'occuper d'établir la connexion et de communiquer. Le serveur ne s'occupe que de fournir l'adresse où se connecter. L'inconvénient de cette méthode est d'une part que chaque utilisateur connaît l'IP de l'autre, ce qui dans certains cas peut être dangereux (selon la personne avec qui on parle), d'autre part, on ne passe plus par le serveur, donc la communication n'est pas forcement cryptée. L'avantage est que le trafic sur le réseau est beaucoup plus moins important et plus rapide.
Si on communique en passant par le serveur, c'est la commande MSGUSER USER MSG qui sera utilisé. C'est le serveur qui s'occupe d'envoyer le message d'un utilisateur à l'autre. Le message est comme tous les autres crypté. De plus on à pas besoin de connaître l'IP de l'autre. Un autre grand avantage de cette méthode est que si l'utilisateur avec qui on parle est enregistré, on peut aussi lui envoyer des messages même s'il n'est pas connecté. Lors de sa prochaine connexion il recevra tous les messages qu'on lui a envoyés. Ceci est extrêmement pratique car souvent on ne peut pas être connecté en même temps, et il est difficile de croiser tout le monde.
L'autre possibilité de discussion est en passant par des canaux. Plusieurs personnes sont regroupées dans une même salle virtuelle, chaque message envoyé est reçut par tous les autres utilisateurs du canal. Les canaux sont vus plus en détails dans la partie suivante.

Les canaux

Qu'est-ce qu'un canal, un salon et un chatroom?

Le principal but de YooGoo est d'accueillir ses utilisateurs sur des canaux. Un canal peut aussi être appelé Chatroom ou salon. Un salon est un "lieu" (ici, virtuel) où les utilisateurs discutent entre eux. Chaque phrase de chaque utilisateur est retransmise à tous les autres utilisateurs connectés sur le même salon.

Gestion des canaux par la base de donnée.

Chaque canal est symbolisé par un objet que nous verrons en détail un peu plus loin. Nous utilisons la base de données codée pour la seconde soutenance pour gère les canaux. Les canaux sont triés dans la base de données selon leurs noms. Effectivement, les canaux sont repérés par un nom unique. La base de données nous permet de faire la conversion entre le nom et l'adresse de l'objet de façon très rapide (cf. rapport de soutenance numéro 2 : le fonctionnement interne de la base de données).
Par exemple lorsqu'un utilisateur envoie la commande:
           MsgChan Epita "Bonjour Tous le monde"
(commande permettant d'envoyer le message "Bonjour tous le monde" sur le canal "Epita").
La première opération à faire sera de retrouver l'adresse du canal Epita. Ensuite, nous pourrons traiter le reste de la commande.

Principes de l'objet Canal.

L'objet canal correspond grosso modo à une liste chaînée d'utilisateurs. Effectivement, toutes les fonctions basiques d'un canal peuvent se faire sur une liste chaînée. Lorsqu'un utilisateur envoie un message à un canal (MSGCHAN CANAL MESSAGE), on vérifie que l'utilisateur qui envoie le message est bien connecté au canal. Il suffit de faire une recherche dans la liste. Ensuite, on parcourt la liste des connectés sur le canal et on envoie un message à chaque utilisateur de la liste. Le message renvoyé à la structure suivante:
        msgChan Canal Pseudo_de_l_expéditeur Message
Lorsqu'un utilisateur joint le canal (JOIN CANAL [PASSWORD] (Nous verrons l'argument PASSWORD plus tard)), il suffit de l'ajouter dans la liste. De même lorsqu'il il part d'un canal (PART CANAL), il suffit de faire une suppression. Lorsqu'un utilisateur arrive ou part du canal, un message informe les autres utilisateurs de l'évènement. Lorsqu'un utilisateur essaye de joindre un canal qui n'est pas trouve dans la base de données (donc, il n'existe pas) celui-ci est automatiquement créé. Pour cela on crée un objet canal vide et on l'ajoute dans la base de données. De même, lorsque le dernier utilisateur d'un canal s'en va, ce dernier est automatiquement détruit. Ceci pourra être modifié en changeant l'option KEEP que nous verrons plus loin.
L'utilisateur aura aussi besoin de savoir qui est connecté avec lui sur le canal. La fonction GETCONNECTED renvoie la liste des utilisateurs d'un canal. Pour cette fonction, nous n'en pouvions pas renvoyer tous les utilisateurs d'un seul coup. Nous sommes effectivement limite par la taille du buffer d'envoi. Nous envoyons donc le résultat par petits morceaux. Un message RPL_GETCONNECTED est envoyé pour chaque utilisateur. La fin de la liste est signalée par le message RPL_ENDGETCONNECTEDS. GETCONNECTEDS renvoie aussi le statut et le grade des utilisateurs. Nous verrons tout a l'heure la hiérarchie sur les canaux. Ces information seront utile au client pour faire la liste des connectés.
Par exemple :
            <- getconnecteds Epita
            -> Rpl_GetConnecteds Epita Danao ONLINE ChanRoot
            -> Rpl_GetConnecteds Epita Zapata AWAY User
            -> Rpl_GetConnecteds Epita Folken DND User
            -> Rpl_GetConnecteds Epita Hargos ONLINE Op
            -> Rpl_EndGetConnecteds
            -> 0 Inf_Ok

Hiérarchie et Droits sur les Canaux.

Les fonctions précédente permettent d'avoir un objet canal de base. YooGoo permet une gestion avancée des canaux en ajoutant des droits à certains utilisateurs. Pour un utilisateur novice, cette partie administrative est totalement transparente. Son client lui affiche la liste des canaux, il fait un double click sur l'un d'entre eux pour le joindre puis, il peut discuter. Il existe quatre grades sur YooGoo. Tout d'abord l'utilisateur normal sans droit particulier. Il peut créé un canal (c'est à dire joindre un canal qui n'existe pas). A ce moment, il est considère fondateur du canal et obtient tous les droits sur le canal. Il peut nommer une autre personne comme fondateur du canal pour par exemple l'administrer à deux ou bien avoir un utilisateurs avec pouvoir de secours en cas de problèmes. Ces utilisateurs sont appelés ChanRoots. Il est possible sur des gros canaux d'avoir besoin de sous fifre pour gérer le canal. Mais, il peut être dangereux de leurs donner tous les droits. Ces utilisateur avec des droits moins importants que le ChanRoot sont des Opérateurs (on dira "Op" (prononcer Opé) dans la pratique). Chanroot peut décider des droits des Op. Enfin, tout en haut de l'échelle se trouve Root, c'est à dire l'administrateur du serveur. Il a le droits de tout faire, il n'a aucune barrière. Nous parlerons plus longuement de ses fonctions dans la partie "Fonctions d'administrations" . Signalons enfin, qu'un utilisateur peut être bannis d'un canal. Lorsqu'un utilisateur se joint à un canal, on vérifie tout d'abord qu'il n'est pas banni, si c'est le cas, sa demande est refusée et il ne peut se joindre au canal.
Pour gérer les grades sur les canaux, nous utilisons trois listes chaînées de Pseudonymes (ou NickName, en anglais). Nous ne pouvions dans ce cas utiliser des listes de pointeurs sur user (comme pour les connectés) car ces listes doivent encore être opérationnelle lorsque l'utilisateur n'est plus connecté. Vu que les Pseudo(Nîmes) sont protégé par mot de passe, on est sur de l'identité d'un utilisateur. Il n'est donc pas possible de devenir ChanRoot sur un canal en usurpant l'identité de celui-ci. Les fonctions suivantes permettent l'ajout et la suppression dans les listes des ChanRoot/Op/bannis :
  • CHANROOT CANAL PSEUDO (nomme un ChanRoot)
  • DECHANROOT CANAL PSEUDO (supprime un utilisateur de la liste des ChanRoot)
  • OP CANAL PSEUDO (nomme un Op)
  • DEOP CANAL PSEUDO (supprime un utilisateur de la liste des Op)
  • BAN CANAL PSEUDO (bannit un utilisateur)
  • DEBAN CANAL PSEUDO (supprime un utilisateur de la liste des Bannis)
Pour gérer les droit des op, nous utilisons donc un entier où chaque bit correspond à une fonction que les op peuvent utiliser. Si le bit est à 0, ils n'y ont pas accès, sinon, ils peuvent utiliser la commande. ChanRoot a accès à la commande CHMOD CANAL COMMANDE {ONOFF} qui permet aux ops d'utiliser ou non $<$Commande$>$. La fonction CHMOD utilise un masque de bit pour mettre à jour la variable Droit. Si ChanRoot décide de mettre toutes les commandes sur OFF, l'OP n'a alors pas plus de droits d'un utilisateur normal. Si ChanRoot décide de mettre toutes les commandes sur ON, les OP ont alors presque autant de pouvoir que lui. Lors de la création du canal, les Ops ont par défaut tout les droits. Tous les champs sont donc à 1. Les seules commandes qui ne peuvent jamais devenir accessible aux OP sont CHANROOT (Nommer un ChanRoot), DECHANROOT (supprime un utilisateur de la liste des ChanRoot), CHMOD (Modifier les droits des Ops) et CHKEEP et CHPRIV (que nous verrons plus bas). Ainsi, pour chaque commande d'administration du serveur, on vérifie que le demandeur est ChanRoot OU (Op ET A_le_Droit).
Voici par exemple de ce qui peut se passer sur un canal Epita où Hargos est ChanRoot, Danao est Op et Lamer est un utilisateur normal:
            Hargos -> ChMod Epita Ban OFF
            Hargos <- Inf_Ok
            **** Si l'op n'ont pas le droit de bannir ***
            Danao -> ban Epita Lamer
            Danao <- Err_Privileges
            *** On modifie la variable Droit ***
            Hargos -> ChMod Epita Ban On
            Hargos <- Inf_Ok
            *** Ca marche ***
            Danao -> ban Epita Lamer
            *** Tout le canal est averti de l'évènement ***
            Danao <- ban Danao Epita Lamer
            Hargos <- ban Danao Epita Lamer
            Lamer <- ban Danao Epita Lamer
            Danao <- Inf_Ok
Aux fonctions permettant de gérer la hiérarchie sur le canal s'ajoute les fonctions permettant de gérer les petits détails du canal. Tout d'abord, la fonction KICK CANAL NICK. Quand un utilisateur ne respecte pas les règles sur un canal, un op peut décider de "kicker" celui ci, c'est à dire, le forcer à partir du canal. Ceci n'empêchera pas l'utilisateur de revenir tout de suite après, mais, elle sert d'avertissement au bannissement (généralement accompagne d'un kick). En interne, cette commande fonctionne exactement comme la fonction part. L'objet canal possède aussi des variables pour le nom du canal, son sujet, son mot de passe et sa catégorie. ces variables peuvent être respectivement modifiée par CHCHANNAME, CHCHANTOPIC, CHCHANPASS et CHCHANCAT. Lorsque l'on change le nom d'un canal, on modifie la variable et surtout, on met a jour la base de données des canaux. Le sujet permet de donne un aperçu du sujet de discussion du canal. Le mot de passe empêche de joindre le canal si on ne possède pas le mot de passe. Si la variable est vide, cela signifie qu'il n'y a pas de mot passe. Lorsqu'un utilisateur joint un canal protégé par mot de passe, il doit passer celui ci en paramètre de la commande Join. On compare ce mot de passe avec celui du canal. Si ils sont différents, l'accès est refusé. Enfin, a la catégorie correspond un nombre qui permet de savoir sur quel sujet est le canal (A la manière catégories Yahoo : Informatique, Voyage, Informations, etc...)

Informations sur un canal.

Toutes ces informations peuvent être récupérées grâce à la commande WHAT CANAL. Cette commande renvoie diverses info sur le canal sous la forme suivante: RPL_WHAT NOM SUJET DROITS_DES_OP CATEGORIE NOMBRE_DE_CONNECTES NOMBRE_D'OP NOMBRE_DE_CHANROOT NOMBRE_DE_BANNIS.
Un utilisateur peut aussi recevoir la liste des ChanRoot/Op/bannis du canal grâce aux commande GETCHANROOTS, GETOPS, GETBANS. Ces commandes renvoient une liste de nom de la même façon que GETCONNECTEDS. C'est à dire RPL_GETOPS... RPL_ENDGETOPS... etc
Enfin, pour que les utilisateurs puissent parfaitement utiliser les canaux, il faut une commande permettant de donner la liste de ceux-ci. GETCHANS effectue cette tache. Le message renvoyé est base sur le même modèle que GETCONNECTED, GETBANS, etc... En interne, il faut cette fois parcourir l'arbre des canaux pour récupère les nom de tous les canaux.

Canal permanent, privé et invitations.

Au début de cette partie, nous avons dit que lorsque le dernier connecte sur un canal s'en allait, le canal était détruit. La variable Droits possède un bit supplémentaire permettant d'empêcher ça lorsque ce bit est a 1. CHKEEP permet de modifier la valeur de ce bit. CHKEEP n'est utilisable que pas ChanRoot. Ainsi, lorsque le dernier utilisateur s'en va, le canal et toute sa configuration sont conservés.
Lors de la fermeture du serveur la liste des canaux permanents est sauvegardée dans un fichier. Pour chaque canal on sauvegarde aussi toutes les informations qui lui sont relatives : nom, catégorie, mot de passe s'il y en a, les droits et la description. Les différentes listes sont aussi sauvegardés : les ops, les chanroots, et les bannis. Lors du lancement du serveur, le fichier est chargé et on recrée tous les canaux dans la base de donnée tel qu'ils étaient avant la fermeture du serveur.
Nous savons qu'il existe deux sortes d'utilisateurs dans YooGoo, les enregistrés et les non-enregistrés. De plus les diverses listes utilisées pour l'administration d'un canal sauvegarde les noms des utilisateurs. Ces raisons font qu'un administrateur de canal peut désirer qu'il n'y est que des utilisateurs enregistrés sur sont canal. Pour cela il existe un fanion PRIVÉ. Celui ci fonctionne comme le fanion KEEP. Il n'est utilisable que par le ChanRoot. Une fois activé, seuls les utilisateurs enregistrés pourront joindre le canal.
Nous avons vu qu'il est possible de protéger l'accès à un canal par un mot de passe. Ainsi pour permettre à quelqu'un de rejoindre le canal il faut lui donné le mot de passe. Mais cette méthode peut être dangereuse, le mot de passe peut rapidement tomber entre de mauvaises mains. Les ops et chanroot ont alors une autre méthode pour permettre à un utilisateur lambda d'accédé au canal : il peuvent l'inviter. La commande INVITE USER et DEINVITE USER permette la gestion des invités. Ces fonctions fonctionnent comme les OP/DEOP, grâce à une liste. Lorsqu'un utilisateur essaye de joindre un canal qui est protégé par un mot de passe on regarde s'il est invité. Si oui, on le supprime de la liste d'invité et il peut rejoindre le canal. Ainsi une invitation n'est valable qu'une fois. De plus la liste d'invité n'est pas sauvegardée. Ces deux points peuvent sembler fastidieux mais permettent aux ops d'avoir un maximum de contrôle des allées et venus dans leur canal. Il faut noter que l'accès au mot de passe (GETCHANPASS) est réservé aux ops et ChanRoot.

Les fonctions d'administration.

Comme nous l'avons dit plus haut, YooGoo possède une hiérarchie. Tout en haut de cette hiérarchie se trouve l'administrateur ou encore appelle Root. A l'image d'UNIX, on considère Root comme un homme de confiance absolue.

Gestion des roots.

YooGoo permet de gérer plusieurs Root sur un serveur. Nous utilisons, pour gérer les root, la même liste chaînée que pour la gestion des ChanRoot, Op (operateurs?) et Bannis. Les seules différences sont que cette liste est globale au serveur et quelle est sauvegarde dans un fichier. Pour la structure du fichier, nous utilisons une ligne par root. Comme pour les ChanRoot, l'administrateur possède les commandes "root" et "deroot" pour ajouter et supprimer des roots. Pour l'ajout d'un root dans le fichier, on écrit une ligne a la fin. Pour la suppression, nous avons décidé de réécrire tout le fichier plutôt que de faire un algorithme compliqué. Le fichier étant court et la commande rarement appelée, ça ne pose pas de problème de charge d'accès au disque. Le fichier est ensuite lu à chaque démarrage.

Privilèges.

Le premier privilège du Root est de ne jamais recevoir de message "Err_Privileges". Dans toutes les fonctions qui demandent d'être ChanRoot ou Op ou toute autre barrière, on teste si l'utilisateur est root. Si c'est le cas, On le laisse faire.
Root possède aussi la commande KILL USER. Elle permet à Root de déconnecter un utilisateur du canal. En interne, cette fonction appelle la fonction disconnect du serveur.
La commande KICKALL CANAL permet de vider un canal. Tous les utilisateurs sont " kickés " (vulgairement, jetés a coups de pied dehors) et le canal est détruit si le fanion KEEP n'est pas actif. (Cf. partie "Les canaux") Si le root met un mot de passe sur le canal avant de faire cette manip, il empêche quiconque (puisque personne ne connaît le mot de passe) de se joindre au canal. Ca peut être utile pour des canaux illégaux. En interne, on appelle la fonction kick pour chaque personne du canal.
Il peut être intéressant pour le root d'envoyer un message a tous les connectés pour par exemple signaler une maintenance. La commande ToAll $<$Message$>$ le permet. Par exemple :
    root -> ToAll "Attention : Fermeture du serveur dans 5 minutes"
    user1 <- ToAll "Attention : Fermeture du serveur dans 5 minutes"
    user2 <- ToAll "Attention : Fermeture du serveur dans 5 minutes"
    user3 <- ToAll "Attention : Fermeture du serveur dans 5 minutes"
    .....
    root <- Inf_Ok
Pour cette fonction, on parcourt l'arbre des connectes et on envoie le message a chaque utilisateur.
Enfin, la plus puissante des commandes est peut-être la commande IAM USER COMMAND. Elle permet d'exécuter une commande comme si on était cet utilisateur. Pour effectuer ceci, on appelle le parseur avec la commande et l'utilisateur en question en paramètre. Nous avons des problèmes pour renvoyer les retours de messages au root. Effectivement, une fois l'appel du parseur fait, il n'y a plus moyen de savoir si c'est une commande détournée ou non. Les messages de retours sont donc envoyés à l'utilisateur. Nous avions au début pensé à changer le pointeur du tampon d'envoi de l'utilisateur de façon à ce qu'il pointe sur le tampon d'envoi du root. Ca aurait sûrement fonctionné avec un serveur "Normal", mais Yoogoo est un serveur sécurisé. Il faut donc aussi prendre en compte les clés DES, et ce, avant d'envoyer le message à root. Bref cette solution aurait sûrement fonctionné, mais, elle était trop compliquée à mettre en oeuvre. Nous avons donc ajouté une variable de retour de type user * dans l'objet user. Dans la fonction d'envoie, si cette variable et non NULL, on rappelle la fonction d'envoie avec pour destinataire l'utilisateur pointer par cette variable et le tour est joué.

Les logs.

Le fichier de configuration.

 
 

 
 
Documentation

FAQ
Conception du Protocole
SDK en Ligne
Télécharger SDK
Cahiers des Charges
Soutenance 1
Soutenance 2
Soutenance 3
Soutenance Finale

Comment marche...
Les Canaux
Le Profile
L'administration
La Base de Données
La Cryptographie
Winsock
Le Multithreading
 
 

 
 
Liens

Epita
EpiTarget
Hallucinetik - Zone 42
poupouill.fr.st Minosis (Spé C2)
La Spé C1
La Sup C1
 
 


 
 
made in Epita Powered by ApachePHP Scripting Language

All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest © 2000 by YooGoo Team
Des remarques, des question, des choses pas claires? Hargos@ifrance.com