IMA4 2021/2022 EC4 : Différence entre versions
(→Etape4) |
(→Etape finale) |
||
(50 révisions intermédiaires par le même utilisateur non affichées) | |||
Ligne 37 : | Ligne 37 : | ||
Suite à une mauvaise compréhension du sujet de ma part, j'ai recommencé le projet avec le code fourni. | Suite à une mauvaise compréhension du sujet de ma part, j'ai recommencé le projet avec le code fourni. | ||
− | ==Erreurs corrigés | + | ==Erreurs corrigés== |
smtp.c:184:23: warning: format not a string literal and no format arguments [-Wformat-security] | smtp.c:184:23: warning: format not a string literal and no format arguments [-Wformat-security] | ||
Ligne 55 : | Ligne 55 : | ||
La fonction fprintf ne reconnaissait pas le dernier argument en paramètre. Ajout d'un %s : fprintf(FILE *,"%s",char *) | La fonction fprintf ne reconnaissait pas le dernier argument en paramètre. Ajout d'un %s : fprintf(FILE *,"%s",char *) | ||
− | smtp_private.h : ACCUEIL_CODE = 250 => ACCUEIL_CODE 220 | + | Dans smtp_private.h : ACCUEIL_CODE = 250 => ACCUEIL_CODE 220 |
smtp.c : Affichage de la première réponse serveur distant dans retourGénérique | smtp.c : Affichage de la première réponse serveur distant dans retourGénérique | ||
Ligne 61 : | Ligne 61 : | ||
==Script pour netcat== | ==Script pour netcat== | ||
− | Automatisation des tests avec les commandes : <br/> | + | * Automatisation des tests avec les commandes : <br/> |
$ function slowcat(){ while read; do sleep .05; echo "$REPLY"; done; } <br/> | $ function slowcat(){ while read; do sleep .05; echo "$REPLY"; done; } <br/> | ||
$ cat txt | slowcat | nc localhost [port] <br/> | $ cat txt | slowcat | nc localhost [port] <br/> | ||
− | Et le fichier "txt": <br/> | + | * Et le fichier "txt": <br/> |
HELO localhost <br/> | HELO localhost <br/> | ||
Ligne 71 : | Ligne 71 : | ||
RCPT TO: <konstantin.patrikeev@polytech-lille.net><br/> | RCPT TO: <konstantin.patrikeev@polytech-lille.net><br/> | ||
DATA<br/> | DATA<br/> | ||
− | From: [ | + | From: [TEST] <patrikeev@gmail.com><br/> |
To: <konstantin.patrikeev@polytech-lille.net><br/> | To: <konstantin.patrikeev@polytech-lille.net><br/> | ||
Date: Fri, 27 Oct 2017 06:14:11 +0000<br/> | Date: Fri, 27 Oct 2017 06:14:11 +0000<br/> | ||
Ligne 90 : | Ligne 90 : | ||
Lors de cette étape, j'ai réussi à m'envoyer un mail sur le serveur mail woody.escaut.net de polytech. Le test doit obligatoirement se faire à partir de l'adresse d'un nom de domaine internet sinon le serveur SMTP ne répondra pas. | Lors de cette étape, j'ai réussi à m'envoyer un mail sur le serveur mail woody.escaut.net de polytech. Le test doit obligatoirement se faire à partir de l'adresse d'un nom de domaine internet sinon le serveur SMTP ne répondra pas. | ||
− | Dans la partie précédentes, le | + | Dans la partie précédentes, le SMTPin arrivait à établir une connexion avec le serveur mail 193.48.57.36 en effectuant le test à polytech. |
Cependant il n'allait pas plus loins dans l'envoi des requetes HELO, MAIL, RCPT, DATA et QUIT. | Cependant il n'allait pas plus loins dans l'envoi des requetes HELO, MAIL, RCPT, DATA et QUIT. | ||
Ligne 110 : | Ligne 110 : | ||
- De plus, pour automatiser les tests, un fichier txt est disponible dans le répertoire EtapeN du projet avec un fichier README.txt qui explique comment s'en servir. | - De plus, pour automatiser les tests, un fichier txt est disponible dans le répertoire EtapeN du projet avec un fichier README.txt qui explique comment s'en servir. | ||
− | == Documents Rendus | + | = Etape 5 = |
+ | |||
+ | Pour cette partie, nous nous focalisons sur les fichiers du répertoire src/SMTout et nous réalisons les tests en local. Un repertoire /tmp est déjà créé à la racine. | ||
+ | |||
+ | Le but est de pouvoir stocker les donnés des mails reçus dans un dossier (/tmp par défault) en triant les mails par destinataire. | ||
+ | |||
+ | Plusieurs erreurs on été corrigés dans out.c. Il manquait notamment des fonctions pour créer des répertoires. | ||
+ | Nous avons choisit d'utiliser la fonction system (remplacée ensuite) qui nous permet de lancer des commandes linux (pour utiliser mkdir). | ||
+ | |||
+ | Pour l'instant, le code a été simplifié en enlevant la partie sur les cartes utilisateur et nous avons pris l'adresse de destination comme id pour différencier les utilisateurs. | ||
+ | |||
+ | Voici les passages modifiés dans out.c : | ||
+ | |||
+ | * Fonction main ligne 240 | ||
+ | |||
+ | - Repertoire de mails racine stocké dans racine | ||
+ | - if (strlen(config.dossier) > 0 ) { strcpy(racine, config.dossier); | ||
+ | - } else { strcpy(racine, MAILDIR_DFLTBASE); | ||
+ | - } | ||
+ | |||
+ | * Fonction Gestion Courriel ligne 178 | ||
+ | |||
+ | - // Creation du repertoire /id | ||
+ | - sprintf(command,"mkdir -m 700 %s/%s",racine,id); | ||
+ | - system(command); | ||
+ | |||
+ | - // Creation du repertoire /id/tmp | ||
+ | - sprintf(command,"mkdir -m 700 %s/%s/%s",racine,id, MAILDIR_TMP); | ||
+ | - system(command); | ||
+ | |||
+ | - // creation d'un fichier de stockage mail | ||
+ | - #ifdef DEVERMINE | ||
+ | - printf("Stockage mail (racine) : %s/%/%s/%ld_%010d_%010ld\n",dossier,id,MAILDIR_TMP,time(NULL),pid,messages); | ||
+ | - #endif | ||
+ | - sprintf(fichier,"%s/%s/%s/%ld_%010d_%010ld",racine,id,MAILDIR_TMP,time(NULL),pid,messages); | ||
+ | - FILE *f=fopen(fichier,"w+"); | ||
+ | |||
+ | |||
+ | Une fonction void affichesmtp_config(struct smtp_config config) a également été implémentée dans args.c pour l'affichage des parmètres de configuration du serveur | ||
+ | |||
+ | - void affichesmtp_config(struct smtp_config config){ | ||
+ | printf (" AFFICHE CONFIG \n"); | ||
+ | printf(" journal : %s\n", config.journal); | ||
+ | printf(" niveau : %d\n", config.niveau); | ||
+ | printf(" port : %s\n", config.port); | ||
+ | printf(" dossier : %s\n", config.dossier); | ||
+ | printf(" carte : %s\n", config.carte); | ||
+ | printf(" local : %x\n", config.local); | ||
+ | } | ||
+ | |||
+ | =Etape 6= | ||
+ | |||
+ | Pour cette étape, le but est de réaliser des tests sur la syntaxe des commande reçues par nos serveurs SMTP. | ||
+ | |||
+ | Pour cela, nous avons réalisé une fonction "analyse" dans smtp.c : | ||
+ | |||
+ | -int analyse_adresse(char str[MAX_ADRESSE_COURRIEL], FILE * client){ | ||
+ | if (str[0]!='<'){ | ||
+ | fprintf(client,"%s","L'adresse doit être entre chevrons </>\n"); return -1; | ||
+ | } | ||
+ | int arobase_flag = -1; | ||
+ | for (int i=0; str[i]!='\0'; i++){ | ||
+ | if(str[i]=='@'){ | ||
+ | arobase_flag = 1; | ||
+ | } | ||
+ | if ( ((str[i+1])=='\0')&&(str[i]!='>') ){ | ||
+ | fprintf(client,"%s","L'adresse doit être entre chevrons </>\n"); return -1; | ||
+ | } | ||
+ | } | ||
+ | if (arobase_flag != 1){ | ||
+ | fprintf(client,"%s", "Il manque un '@' dans le mail\n"); return -1; | ||
+ | } | ||
+ | return 1; | ||
+ | } | ||
+ | |||
+ | La vérification de l'identification de HELO est déjà implémentée dans le code de base. Donc cette fonction a pour but de vérifier la syntaxe des adresse mails passés en paramètre à MAIL FROM: et RCPT TO: . | ||
+ | |||
+ | Cette fonction ne vérifie pas encore la présence ou non d'un espacement ' ' entre ':' et l'adresse mail en paramètre. | ||
+ | |||
+ | =Etape finale= | ||
+ | |||
+ | Pour cette dernière étape, la fonction analyse_adresse a été ajoutée aux fonctions gestion_MAIL et gestion_RCPT pour vérifier la syntaxe mail en argument. | ||
+ | |||
+ | Pour le serveur de réception SMTPout, dans out.c, l'option -d permet maintenant de créer un dossier à la racine du système pour y stocker les mails: | ||
+ | |||
+ | - // Repertoire de mails racine stocké dans la variable racine // creation du dossier racine si programme lancé en sudo (ligne 249) | ||
+ | - if (strlen(config.dossier) > 0 ) { strcpy(racine, config.dossier); char command[MAX_TAILLE_ADRESSE]; | ||
+ | strcpy(command, "sudo mkdir "); strcat(command, racine); | ||
+ | system(command); | ||
+ | - } else { strcpy(racine, MAILDIR_DFLTBASE); | ||
+ | - } | ||
+ | |||
+ | Cette option ne fonctionne qu'en mode sudo et ne prend pas en charge la création d'une arborescence même si cette dernière aurait pu être implémentée en utilisant "mkdir -R et -p" pour créer des répertoires récursivement et en ajoutant les répertoires parents manquants. | ||
+ | |||
+ | * fonction int mkdir( const char * path, mode_t mode ) de la bibliothèeque <sys/stat.h.h> | ||
+ | |||
+ | Pour éviter l'utilisation de la fonction system pour la création des répertoires, nous avons utilisé la fonction mkdir. | ||
+ | Le mode 755 (user = r+w+x, group = r+x et other = r+x) permet de définir les droits d'accès à ces dossiers. | ||
+ | |||
+ | - if (strlen(config.dossier) > 0 ) { strcpy(racine, config.dossier); | ||
+ | //char command[MAX_TAILLE_ADRESSE]; | ||
+ | /*strcpy(command, "sudo mkdir "); strcat(command, racine); // Il est plus conventionnel d'utiliser la fonction C ci dessous | ||
+ | system(command);*/ | ||
+ | result = mkdir( racine, MKDIR_MODE ); | ||
+ | - } else { strcpy(racine, MAILDIR_DFLTBASE); | ||
+ | - } | ||
+ | |||
+ | |||
+ | |||
+ | * Carte utilisateur | ||
+ | |||
+ | Jusqu'ici, notre serveur enregistrait les mails dans des répertoires en fonction des adresses mails de destination. | ||
+ | Les fonctions chargeCarteUtilisateurs, scanCarteUtilisateur et stockeInit permettent respectivement de d charger les id utilisateur, de scanner les ids trouvés et d'initialiser la structure adrVersID. | ||
+ | |||
+ | - L'option -u [fichier] est nécessaire pour renseigner le fichier de configuration. Les tests on été effectué avec un fichier "aliases" dans le repertoir SMTPout. En voici le contenu: | ||
+ | |||
+ | - rex : Xavier.Redon@plil.fr,xavier@polytech-lille.fr, rex@plil.fr | ||
+ | - tv: Thomas.Vantroys@univ-lille.fr | ||
+ | |||
+ | |||
+ | * La fonction analyse informe l'utilisateur sur la nécessité d'avoir un espace entre MAIL FROM: / RCPT TO: et l'adresse qui suit <adresse@domaine.net> | ||
+ | |||
+ | = Documents Rendus = | ||
Lien du répertoire git : https://archives.plil.fr/kpatrike/EC_Messagerie.git | Lien du répertoire git : https://archives.plil.fr/kpatrike/EC_Messagerie.git |
Version actuelle datée du 7 septembre 2022 à 13:38
Sommaire
Objectif
Terminer le projet système réseau SE2a4 2021/2022 à partir d'un source incomplet.
Le sujet du projet est ici : https://rex.plil.fr/Enseignement/Systeme/Tutorat.IMA2a4.Messagerie/
Le source incomplet est disponible en ligne Fichier:PSR-ReX-v6.zip.
Vous devez documenter vos avancées sur cette page Wiki.
Travail réalisé
Etape1:
- args.c : traitement des arguments courts et longs - libcom : Fonctions Initialisation, Connexion, BoucleServeur et résolution de nom de domaine - MTAint/tcpint.c : Code source pour le test de la communication TCP avec notre serveur fonctionne avec nc [ipv4_serveur] [port]
L'étape suivante sera d'implémenter les threads pour gérer plusieurs communications en même temps.
Etape2:
- MTAint: gestion_stmp : fonction de traitement et de stockage des informations avec des commandes HELO, MAIL, RCPT, DATA, QUIT dans une structure client réorganisation des fichiers : Test(test connection tcp, répertoire MTAint Etape1) , implémentation de la bibliothèque SMTP
L'implémentation des threads nous donne des erreurs. Librarire Threads non implémentée pour l'instant.
Etape2_finale:
MTAint: Implémentation des threads réalisée à l'aide d'une structure {void * arg, void * f(*f)(void *). Conflits de librairies résolus, nouvelle fonction serverLoop2 pour les threads et changement de void * gestionsmtp(int) en void * gestionsmtp(void *) pour être pris en charge par un thread
La prochaine étape est d'envoyer les donnés sur le port 25 et de recevoir un mail.
Etape3
Suite à une mauvaise compréhension du sujet de ma part, j'ai recommencé le projet avec le code fourni.
Erreurs corrigés
smtp.c:184:23: warning: format not a string literal and no format arguments [-Wformat-security]
184 | if(fprintf(dialogue,envoi)<0) return -1; |
smtp.c: In function ‘dialogue_DATA’: smtp.c:211:1: warning: format not a string literal and no format arguments [-Wformat-security]
211 | if(fprintf(dialogue,corps)<0) return -1; | ^~
smtp.c: In function ‘afficheCourriel’: smtp.c:239:3: warning: format not a string literal and no format arguments [-Wformat-security]
239 | if(complet) fprintf(sortie,donnees->corps); | ^~
La fonction fprintf ne reconnaissait pas le dernier argument en paramètre. Ajout d'un %s : fprintf(FILE *,"%s",char *)
Dans smtp_private.h : ACCUEIL_CODE = 250 => ACCUEIL_CODE 220
smtp.c : Affichage de la première réponse serveur distant dans retourGénérique
Script pour netcat
- Automatisation des tests avec les commandes :
$ function slowcat(){ while read; do sleep .05; echo "$REPLY"; done; }
$ cat txt | slowcat | nc localhost [port]
- Et le fichier "txt":
HELO localhost
MAIL FROM: <patrikeev@gmail.com>
RCPT TO: <konstantin.patrikeev@polytech-lille.net>
DATA
From: [TEST] <patrikeev@gmail.com>
To: <konstantin.patrikeev@polytech-lille.net>
Date: Fri, 27 Oct 2017 06:14:11 +0000
Subject: Test Message
Hi there! This is supposed to be a real email...
Have a good day!
-- System
.
QUIT
Etape4
Lors de cette étape, j'ai réussi à m'envoyer un mail sur le serveur mail woody.escaut.net de polytech. Le test doit obligatoirement se faire à partir de l'adresse d'un nom de domaine internet sinon le serveur SMTP ne répondra pas.
Dans la partie précédentes, le SMTPin arrivait à établir une connexion avec le serveur mail 193.48.57.36 en effectuant le test à polytech.
Cependant il n'allait pas plus loins dans l'envoi des requetes HELO, MAIL, RCPT, DATA et QUIT.
2 erreurs on étés corrigées:
- int statut=sscanf(ligne,"%3d",&code); // au lieur de "%4d" dans scmtpin:ligne181
- #define ACCUEIL_CODE 220 // au lieu de 250 pour la reconnaissance du code d'accueil
Ainsi le programme n'arrivait pas à :
1. Reconnaître le bon code d'accueil 220 dans la fonction retour_generique
- static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille) // smtp.c:ligne 170
2. Identifier correctement ce code dans le message de réponse du serveur. sscanf prenait une chaîne de caractères %4s au lieur d'un entier %3d (Les codes sont donnés sur 3 chiffres)
- De plus, pour automatiser les tests, un fichier txt est disponible dans le répertoire EtapeN du projet avec un fichier README.txt qui explique comment s'en servir.
Etape 5
Pour cette partie, nous nous focalisons sur les fichiers du répertoire src/SMTout et nous réalisons les tests en local. Un repertoire /tmp est déjà créé à la racine.
Le but est de pouvoir stocker les donnés des mails reçus dans un dossier (/tmp par défault) en triant les mails par destinataire.
Plusieurs erreurs on été corrigés dans out.c. Il manquait notamment des fonctions pour créer des répertoires. Nous avons choisit d'utiliser la fonction system (remplacée ensuite) qui nous permet de lancer des commandes linux (pour utiliser mkdir).
Pour l'instant, le code a été simplifié en enlevant la partie sur les cartes utilisateur et nous avons pris l'adresse de destination comme id pour différencier les utilisateurs.
Voici les passages modifiés dans out.c :
- Fonction main ligne 240
- Repertoire de mails racine stocké dans racine - if (strlen(config.dossier) > 0 ) { strcpy(racine, config.dossier); - } else { strcpy(racine, MAILDIR_DFLTBASE); - }
- Fonction Gestion Courriel ligne 178
- // Creation du repertoire /id - sprintf(command,"mkdir -m 700 %s/%s",racine,id); - system(command);
- // Creation du repertoire /id/tmp - sprintf(command,"mkdir -m 700 %s/%s/%s",racine,id, MAILDIR_TMP); - system(command);
- // creation d'un fichier de stockage mail - #ifdef DEVERMINE - printf("Stockage mail (racine) : %s/%/%s/%ld_%010d_%010ld\n",dossier,id,MAILDIR_TMP,time(NULL),pid,messages); - #endif - sprintf(fichier,"%s/%s/%s/%ld_%010d_%010ld",racine,id,MAILDIR_TMP,time(NULL),pid,messages); - FILE *f=fopen(fichier,"w+");
Une fonction void affichesmtp_config(struct smtp_config config) a également été implémentée dans args.c pour l'affichage des parmètres de configuration du serveur
- void affichesmtp_config(struct smtp_config config){ printf (" AFFICHE CONFIG \n"); printf(" journal : %s\n", config.journal); printf(" niveau : %d\n", config.niveau); printf(" port : %s\n", config.port); printf(" dossier : %s\n", config.dossier); printf(" carte : %s\n", config.carte); printf(" local : %x\n", config.local); }
Etape 6
Pour cette étape, le but est de réaliser des tests sur la syntaxe des commande reçues par nos serveurs SMTP.
Pour cela, nous avons réalisé une fonction "analyse" dans smtp.c :
-int analyse_adresse(char str[MAX_ADRESSE_COURRIEL], FILE * client){ if (str[0]!='<'){ fprintf(client,"%s","L'adresse doit être entre chevrons </>\n"); return -1; } int arobase_flag = -1; for (int i=0; str[i]!='\0'; i++){ if(str[i]=='@'){ arobase_flag = 1; } if ( ((str[i+1])=='\0')&&(str[i]!='>') ){ fprintf(client,"%s","L'adresse doit être entre chevrons </>\n"); return -1; } } if (arobase_flag != 1){ fprintf(client,"%s", "Il manque un '@' dans le mail\n"); return -1; } return 1;
}
La vérification de l'identification de HELO est déjà implémentée dans le code de base. Donc cette fonction a pour but de vérifier la syntaxe des adresse mails passés en paramètre à MAIL FROM: et RCPT TO: .
Cette fonction ne vérifie pas encore la présence ou non d'un espacement ' ' entre ':' et l'adresse mail en paramètre.
Etape finale
Pour cette dernière étape, la fonction analyse_adresse a été ajoutée aux fonctions gestion_MAIL et gestion_RCPT pour vérifier la syntaxe mail en argument.
Pour le serveur de réception SMTPout, dans out.c, l'option -d permet maintenant de créer un dossier à la racine du système pour y stocker les mails:
- // Repertoire de mails racine stocké dans la variable racine // creation du dossier racine si programme lancé en sudo (ligne 249) - if (strlen(config.dossier) > 0 ) { strcpy(racine, config.dossier); char command[MAX_TAILLE_ADRESSE]; strcpy(command, "sudo mkdir "); strcat(command, racine); system(command); - } else { strcpy(racine, MAILDIR_DFLTBASE); - }
Cette option ne fonctionne qu'en mode sudo et ne prend pas en charge la création d'une arborescence même si cette dernière aurait pu être implémentée en utilisant "mkdir -R et -p" pour créer des répertoires récursivement et en ajoutant les répertoires parents manquants.
- fonction int mkdir( const char * path, mode_t mode ) de la bibliothèeque <sys/stat.h.h>
Pour éviter l'utilisation de la fonction system pour la création des répertoires, nous avons utilisé la fonction mkdir. Le mode 755 (user = r+w+x, group = r+x et other = r+x) permet de définir les droits d'accès à ces dossiers.
- if (strlen(config.dossier) > 0 ) { strcpy(racine, config.dossier); //char command[MAX_TAILLE_ADRESSE]; /*strcpy(command, "sudo mkdir "); strcat(command, racine); // Il est plus conventionnel d'utiliser la fonction C ci dessous system(command);*/ result = mkdir( racine, MKDIR_MODE ); - } else { strcpy(racine, MAILDIR_DFLTBASE); - }
- Carte utilisateur
Jusqu'ici, notre serveur enregistrait les mails dans des répertoires en fonction des adresses mails de destination. Les fonctions chargeCarteUtilisateurs, scanCarteUtilisateur et stockeInit permettent respectivement de d charger les id utilisateur, de scanner les ids trouvés et d'initialiser la structure adrVersID.
- L'option -u [fichier] est nécessaire pour renseigner le fichier de configuration. Les tests on été effectué avec un fichier "aliases" dans le repertoir SMTPout. En voici le contenu:
- rex : Xavier.Redon@plil.fr,xavier@polytech-lille.fr, rex@plil.fr - tv: Thomas.Vantroys@univ-lille.fr
- La fonction analyse informe l'utilisateur sur la nécessité d'avoir un espace entre MAIL FROM: / RCPT TO: et l'adresse qui suit <adresse@domaine.net>
Documents Rendus
Lien du répertoire git : https://archives.plil.fr/kpatrike/EC_Messagerie.git