<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
		<id>https://wiki-ima.plil.fr/mediawiki//api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jbreuvar</id>
		<title>Wiki d'activités IMA - Contributions de l’utilisateur [fr]</title>
		<link rel="self" type="application/atom+xml" href="https://wiki-ima.plil.fr/mediawiki//api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jbreuvar"/>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php/Sp%C3%A9cial:Contributions/Jbreuvar"/>
		<updated>2026-05-13T22:25:11Z</updated>
		<subtitle>Contributions de l’utilisateur</subtitle>
		<generator>MediaWiki 1.29.2</generator>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=62002</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=62002"/>
				<updated>2023-06-14T18:48:23Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* Contrôle TP Lisa-Marie */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== SMTPout : Processus de stockage du mail ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test en envoyant un mail à un utilisateur qui n'est pas dans la carte utilisateur carte.txt : le mail ne se stocke pas.&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPout en stockant plusieurs mails simultanément :&lt;br /&gt;
**Pour cela, écrire une script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
   for((i=1; i&amp;lt;=50; i++))&lt;br /&gt;
     do&lt;br /&gt;
       echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
       nc -i1 -q0 -C 193.48.57.164 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
Voir le fichier test1.txt&lt;br /&gt;
 HELO lisa&lt;br /&gt;
 MAIL FROM: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
 RCPT TO: &amp;lt;lisadubois@lamentable.site&amp;gt;&lt;br /&gt;
 DATA&lt;br /&gt;
 SUBJECT Bonjour&lt;br /&gt;
 Hi&lt;br /&gt;
 Hola&lt;br /&gt;
 .&lt;br /&gt;
 QUIT&lt;br /&gt;
&lt;br /&gt;
Le test de charge est OK pour un stockage de 50 mails simultanés, le serveur est solide.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit que lorsqu'on envoie un mail depuis notre boîte mail polytech-lille.net, les messages ne s'envoient pas, ne se stockent pas&lt;br /&gt;
**En exécutant la commande strace -f, on remarque que notre boîte mail envoie la commande :&lt;br /&gt;
***EHLO au lieu de HELO&lt;br /&gt;
***MAIL FROM:&amp;lt;lisadubois@lamentable.site&amp;gt; au lieu de MAIL FROM: &amp;lt;lisadubois@lamentable.site&amp;gt;&lt;br /&gt;
***RCPT TO:&amp;lt;lisadubois@lamentable.site&amp;gt; au lieu de RCPT TO: &amp;lt;lisadubois@lamentable.site&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  struct commandes cmd_smtp[]={&lt;br /&gt;
  {&amp;quot;'''EHLO'''&amp;quot;,gestion_HELO},&lt;br /&gt;
  {&amp;quot;MAIL&amp;quot;,gestion_MAIL},&lt;br /&gt;
  {&amp;quot;RCPT&amp;quot;,gestion_RCPT},&lt;br /&gt;
  {&amp;quot;DATA&amp;quot;,gestion_DATA},&lt;br /&gt;
  {&amp;quot;QUIT&amp;quot;,gestion_QUIT},&lt;br /&gt;
  {&amp;quot;&amp;quot;,NULL}&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  static int gestion_MAIL(char *ligne,FILE *client,struct courriel *donnees){&lt;br /&gt;
  char cmd[MAX_LIGNE];&lt;br /&gt;
  char tag[MAX_LIGNE];&lt;br /&gt;
  char arg[MAX_LIGNE];&lt;br /&gt;
  char suite[MAX_LIGNE];&lt;br /&gt;
  int statut=sscanf(ligne,&amp;quot;'''%4s %5s%s %s'''&amp;quot;,cmd,tag,arg,suite);&lt;br /&gt;
&lt;br /&gt;
  static int gestion_RCPT(char *ligne,FILE *client,struct courriel *donnees){&lt;br /&gt;
  char cmd[MAX_LIGNE];&lt;br /&gt;
  char tag[MAX_LIGNE];&lt;br /&gt;
  char arg[MAX_LIGNE];&lt;br /&gt;
  char suite[MAX_LIGNE];&lt;br /&gt;
  int statut=sscanf(ligne,&amp;quot;'''%4s %3s%s %s'''&amp;quot;,cmd,tag,arg,suite);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== Gérer une file d'attente ==&lt;br /&gt;
&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&lt;br /&gt;
To do...&lt;br /&gt;
&lt;br /&gt;
== Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;br /&gt;
&lt;br /&gt;
==Contrôle TP Lisa-Marie==&lt;br /&gt;
Ajout dans cmd_smtp[] d’une ligne avec la commande HELP&lt;br /&gt;
Ajout pour chacune des commandes, un troisième champ avec une petite description de la commande.&lt;br /&gt;
 &lt;br /&gt;
struct commandes cmd_smtp[]={&lt;br /&gt;
 {“EHLO”,gestion_HELO,”Entamer la connexion”},&lt;br /&gt;
 {“MAIL”,gestion_MAIL,”Expediteur”},&lt;br /&gt;
 {“RCPT”,gestion_RCPT,”Recepteur”},&lt;br /&gt;
 {“DATA”,gestion_DATA,”corps du mail”},&lt;br /&gt;
 {“QUIT”,gestion_QUIT,”fin de connexion”},&lt;br /&gt;
 {“HELP”,gestion_HELP,”aide”},&lt;br /&gt;
 {“”,NULL}&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans smtp_private.h : &lt;br /&gt;
ajout de define pour rajouter les codes de succès et d’erreur attendu : &lt;br /&gt;
 #define SUCCES_HELP_CODE	211&lt;br /&gt;
 #define SUCCES_HELP_TEXTE ERREUR_SYNTAXE&lt;br /&gt;
&lt;br /&gt;
 #define ERREUR_HELP_CODE	502&lt;br /&gt;
 #define ERREUR_HELP_TEXTE ERREUR_SYNTAXE&lt;br /&gt;
&lt;br /&gt;
et voici la fonction principale ci dessous gestion_HELP : (avec la boucle permettant d'afficher dans le client chaque éléments du tableau&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
static int gestion_HELP(char *ligne,FILE *client,struct courriel *donnees){&lt;br /&gt;
 char cmd[MAX_LIGNE];&lt;br /&gt;
 char suite[MAX_LIGNE];&lt;br /&gt;
 int statut=sscanf(ligne,&amp;quot;%4s %s&amp;quot;,cmd,suite);&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 if(statut!=1){&lt;br /&gt;
   if(fprintf(client,&amp;quot;%03d %s \r\n&amp;quot;,ERREUR_HELP_CODE,ERREUR_HELP_TEXTE)&amp;lt;0) return GESTION_STOP;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 struct commandes *p=cmd_smtp;&lt;br /&gt;
 while(p-&amp;gt;traitement!=NULL){&lt;br /&gt;
     fprintf(client,&amp;quot;%03d-Commande %s : %s\n&amp;quot;,SUCCES_HELP_CODE,p-&amp;gt;texte,p-&amp;gt;aide);&lt;br /&gt;
     p++;&lt;br /&gt;
 }&lt;br /&gt;
 if(fprintf(client,&amp;quot;%03d %s\r\n&amp;quot;,SUCCES_HELP_CODE,SUCCES_HELP_TEXTE)&amp;lt;0) return GESTION_STOP;&lt;br /&gt;
 return GESTION_STOP;&lt;br /&gt;
 }&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=62001</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=62001"/>
				<updated>2023-06-14T18:45:23Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* Contrôle TP Lisa-Marie */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== SMTPout : Processus de stockage du mail ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test en envoyant un mail à un utilisateur qui n'est pas dans la carte utilisateur carte.txt : le mail ne se stocke pas.&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPout en stockant plusieurs mails simultanément :&lt;br /&gt;
**Pour cela, écrire une script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
   for((i=1; i&amp;lt;=50; i++))&lt;br /&gt;
     do&lt;br /&gt;
       echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
       nc -i1 -q0 -C 193.48.57.164 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
Voir le fichier test1.txt&lt;br /&gt;
 HELO lisa&lt;br /&gt;
 MAIL FROM: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
 RCPT TO: &amp;lt;lisadubois@lamentable.site&amp;gt;&lt;br /&gt;
 DATA&lt;br /&gt;
 SUBJECT Bonjour&lt;br /&gt;
 Hi&lt;br /&gt;
 Hola&lt;br /&gt;
 .&lt;br /&gt;
 QUIT&lt;br /&gt;
&lt;br /&gt;
Le test de charge est OK pour un stockage de 50 mails simultanés, le serveur est solide.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit que lorsqu'on envoie un mail depuis notre boîte mail polytech-lille.net, les messages ne s'envoient pas, ne se stockent pas&lt;br /&gt;
**En exécutant la commande strace -f, on remarque que notre boîte mail envoie la commande :&lt;br /&gt;
***EHLO au lieu de HELO&lt;br /&gt;
***MAIL FROM:&amp;lt;lisadubois@lamentable.site&amp;gt; au lieu de MAIL FROM: &amp;lt;lisadubois@lamentable.site&amp;gt;&lt;br /&gt;
***RCPT TO:&amp;lt;lisadubois@lamentable.site&amp;gt; au lieu de RCPT TO: &amp;lt;lisadubois@lamentable.site&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  struct commandes cmd_smtp[]={&lt;br /&gt;
  {&amp;quot;'''EHLO'''&amp;quot;,gestion_HELO},&lt;br /&gt;
  {&amp;quot;MAIL&amp;quot;,gestion_MAIL},&lt;br /&gt;
  {&amp;quot;RCPT&amp;quot;,gestion_RCPT},&lt;br /&gt;
  {&amp;quot;DATA&amp;quot;,gestion_DATA},&lt;br /&gt;
  {&amp;quot;QUIT&amp;quot;,gestion_QUIT},&lt;br /&gt;
  {&amp;quot;&amp;quot;,NULL}&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  static int gestion_MAIL(char *ligne,FILE *client,struct courriel *donnees){&lt;br /&gt;
  char cmd[MAX_LIGNE];&lt;br /&gt;
  char tag[MAX_LIGNE];&lt;br /&gt;
  char arg[MAX_LIGNE];&lt;br /&gt;
  char suite[MAX_LIGNE];&lt;br /&gt;
  int statut=sscanf(ligne,&amp;quot;'''%4s %5s%s %s'''&amp;quot;,cmd,tag,arg,suite);&lt;br /&gt;
&lt;br /&gt;
  static int gestion_RCPT(char *ligne,FILE *client,struct courriel *donnees){&lt;br /&gt;
  char cmd[MAX_LIGNE];&lt;br /&gt;
  char tag[MAX_LIGNE];&lt;br /&gt;
  char arg[MAX_LIGNE];&lt;br /&gt;
  char suite[MAX_LIGNE];&lt;br /&gt;
  int statut=sscanf(ligne,&amp;quot;'''%4s %3s%s %s'''&amp;quot;,cmd,tag,arg,suite);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== Gérer une file d'attente ==&lt;br /&gt;
&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&lt;br /&gt;
To do...&lt;br /&gt;
&lt;br /&gt;
== Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;br /&gt;
&lt;br /&gt;
==Contrôle TP Lisa-Marie==&lt;br /&gt;
Ajout dans cmd_smtp[] d’une ligne avec la commande HELP&lt;br /&gt;
Ajout pour chacune des commandes, un troisième champ avec une petite description de la commande.&lt;br /&gt;
 &lt;br /&gt;
struct commandes cmd_smtp[]={&lt;br /&gt;
 {“EHLO”,gestion_HELO,”Entamer la connexion”},&lt;br /&gt;
 {“MAIL”,gestion_MAIL,”Expediteur”},&lt;br /&gt;
 {“RCPT”,gestion_RCPT,”Recepteur”},&lt;br /&gt;
 {“DATA”,gestion_DATA,”corps du mail”},&lt;br /&gt;
 {“QUIT”,gestion_QUIT,”fin de connexion”},&lt;br /&gt;
 {“HELP”,gestion_HELP,”aide”},&lt;br /&gt;
 {“”,NULL}&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans smtp_private.h : &lt;br /&gt;
ajout de define pour rajouter les codes de succès et d’erreur attendu : &lt;br /&gt;
 #define SUCCES_HELP_CODE	211&lt;br /&gt;
 #define SUCCES_HELP_TEXTE ERREUR_SYNTAXE&lt;br /&gt;
&lt;br /&gt;
 #define ERREUR_HELP_CODE	502&lt;br /&gt;
 #define ERREUR_HELP_TEXTE ERREUR_SYNTAXE&lt;br /&gt;
&lt;br /&gt;
et voici la fonction principale ci dessous gestion_HELP : (avec la boucle permettant d'afficher dans le client chaque éléments du tableau&amp;quot;&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=62000</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=62000"/>
				<updated>2023-06-14T18:44:52Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* Activer la connexion chiffrée avec le serveur */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== SMTPout : Processus de stockage du mail ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test en envoyant un mail à un utilisateur qui n'est pas dans la carte utilisateur carte.txt : le mail ne se stocke pas.&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPout en stockant plusieurs mails simultanément :&lt;br /&gt;
**Pour cela, écrire une script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
   for((i=1; i&amp;lt;=50; i++))&lt;br /&gt;
     do&lt;br /&gt;
       echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
       nc -i1 -q0 -C 193.48.57.164 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
Voir le fichier test1.txt&lt;br /&gt;
 HELO lisa&lt;br /&gt;
 MAIL FROM: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
 RCPT TO: &amp;lt;lisadubois@lamentable.site&amp;gt;&lt;br /&gt;
 DATA&lt;br /&gt;
 SUBJECT Bonjour&lt;br /&gt;
 Hi&lt;br /&gt;
 Hola&lt;br /&gt;
 .&lt;br /&gt;
 QUIT&lt;br /&gt;
&lt;br /&gt;
Le test de charge est OK pour un stockage de 50 mails simultanés, le serveur est solide.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit que lorsqu'on envoie un mail depuis notre boîte mail polytech-lille.net, les messages ne s'envoient pas, ne se stockent pas&lt;br /&gt;
**En exécutant la commande strace -f, on remarque que notre boîte mail envoie la commande :&lt;br /&gt;
***EHLO au lieu de HELO&lt;br /&gt;
***MAIL FROM:&amp;lt;lisadubois@lamentable.site&amp;gt; au lieu de MAIL FROM: &amp;lt;lisadubois@lamentable.site&amp;gt;&lt;br /&gt;
***RCPT TO:&amp;lt;lisadubois@lamentable.site&amp;gt; au lieu de RCPT TO: &amp;lt;lisadubois@lamentable.site&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  struct commandes cmd_smtp[]={&lt;br /&gt;
  {&amp;quot;'''EHLO'''&amp;quot;,gestion_HELO},&lt;br /&gt;
  {&amp;quot;MAIL&amp;quot;,gestion_MAIL},&lt;br /&gt;
  {&amp;quot;RCPT&amp;quot;,gestion_RCPT},&lt;br /&gt;
  {&amp;quot;DATA&amp;quot;,gestion_DATA},&lt;br /&gt;
  {&amp;quot;QUIT&amp;quot;,gestion_QUIT},&lt;br /&gt;
  {&amp;quot;&amp;quot;,NULL}&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  static int gestion_MAIL(char *ligne,FILE *client,struct courriel *donnees){&lt;br /&gt;
  char cmd[MAX_LIGNE];&lt;br /&gt;
  char tag[MAX_LIGNE];&lt;br /&gt;
  char arg[MAX_LIGNE];&lt;br /&gt;
  char suite[MAX_LIGNE];&lt;br /&gt;
  int statut=sscanf(ligne,&amp;quot;'''%4s %5s%s %s'''&amp;quot;,cmd,tag,arg,suite);&lt;br /&gt;
&lt;br /&gt;
  static int gestion_RCPT(char *ligne,FILE *client,struct courriel *donnees){&lt;br /&gt;
  char cmd[MAX_LIGNE];&lt;br /&gt;
  char tag[MAX_LIGNE];&lt;br /&gt;
  char arg[MAX_LIGNE];&lt;br /&gt;
  char suite[MAX_LIGNE];&lt;br /&gt;
  int statut=sscanf(ligne,&amp;quot;'''%4s %3s%s %s'''&amp;quot;,cmd,tag,arg,suite);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== Gérer une file d'attente ==&lt;br /&gt;
&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&lt;br /&gt;
To do...&lt;br /&gt;
&lt;br /&gt;
== Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;br /&gt;
&lt;br /&gt;
==Contrôle TP Lisa-Marie==&lt;br /&gt;
Ajout dans cmd_smtp[] d’une ligne avec la commande HELP&lt;br /&gt;
Ajout pour chacune des commandes, un troisième champ avec une petite description de la commande.&lt;br /&gt;
struct commandes cmd_smtp[]={&lt;br /&gt;
{“EHLO”,gestion_HELO,”Entamer la connexion”},&lt;br /&gt;
{“MAIL”,gestion_MAIL,”Expediteur”},&lt;br /&gt;
{“RCPT”,gestion_RCPT,”Recepteur”},&lt;br /&gt;
{“DATA”,gestion_DATA,”corps du mail”},&lt;br /&gt;
{“QUIT”,gestion_QUIT,”fin de connexion”},&lt;br /&gt;
{“HELP”,gestion_HELP,”aide”},&lt;br /&gt;
{“”,NULL}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans smtp_private.h : &lt;br /&gt;
ajout de define pour rajouter les codes de succès et d’erreur attendu : &lt;br /&gt;
#define SUCCES_HELP_CODE	211&lt;br /&gt;
#define SUCCES_HELP_TEXTE ERREUR_SYNTAXE&lt;br /&gt;
&lt;br /&gt;
#define ERREUR_HELP_CODE	502&lt;br /&gt;
#define ERREUR_HELP_TEXTE ERREUR_SYNTAXE&lt;br /&gt;
&lt;br /&gt;
et voici la fonction principale ci dessous gestion_HELP : (avec la boucle permettant d'afficher dans le client chaque éléments du tableau&amp;quot;&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61992</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61992"/>
				<updated>2023-06-14T17:11:49Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* Activer la connexion chiffrée avec le serveur */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== SMTPout : Processus de stockage du mail ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test en envoyant un mail à un utilisateur qui n'est pas dans la carte utilisateur carte.txt : le mail ne se stocke pas.&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPout en stockant plusieurs mails simultanément :&lt;br /&gt;
**Pour cela, écrire une script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
   for((i=1; i&amp;lt;=50; i++))&lt;br /&gt;
     do&lt;br /&gt;
       echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
       nc -i1 -q0 -C 193.48.57.164 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
Voir le fichier test1.txt&lt;br /&gt;
 HELO lisa&lt;br /&gt;
 MAIL FROM: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
 RCPT TO: &amp;lt;lisadubois@lamentable.site&amp;gt;&lt;br /&gt;
 DATA&lt;br /&gt;
 SUBJECT Bonjour&lt;br /&gt;
 Hi&lt;br /&gt;
 Hola&lt;br /&gt;
 .&lt;br /&gt;
 QUIT&lt;br /&gt;
&lt;br /&gt;
Le test de charge est OK pour un stockage de 50 mails simultanés, le serveur est solide.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit que lorsqu'on envoie un mail depuis notre boîte mail polytech-lille.net, les messages ne s'envoient pas, ne se stockent pas&lt;br /&gt;
**En exécutant la commande strace -f, on remarque que notre boîte mail envoie la commande :&lt;br /&gt;
***EHLO au lieu de HELO&lt;br /&gt;
***MAIL FROM:&amp;lt;lisadubois@lamentable.site&amp;gt; au lieu de MAIL FROM: &amp;lt;lisadubois@lamentable.site&amp;gt;&lt;br /&gt;
***RCPT TO:&amp;lt;lisadubois@lamentable.site&amp;gt; au lieu de RCPT TO: &amp;lt;lisadubois@lamentable.site&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  struct commandes cmd_smtp[]={&lt;br /&gt;
  {&amp;quot;'''EHLO'''&amp;quot;,gestion_HELO},&lt;br /&gt;
  {&amp;quot;MAIL&amp;quot;,gestion_MAIL},&lt;br /&gt;
  {&amp;quot;RCPT&amp;quot;,gestion_RCPT},&lt;br /&gt;
  {&amp;quot;DATA&amp;quot;,gestion_DATA},&lt;br /&gt;
  {&amp;quot;QUIT&amp;quot;,gestion_QUIT},&lt;br /&gt;
  {&amp;quot;&amp;quot;,NULL}&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  static int gestion_MAIL(char *ligne,FILE *client,struct courriel *donnees){&lt;br /&gt;
  char cmd[MAX_LIGNE];&lt;br /&gt;
  char tag[MAX_LIGNE];&lt;br /&gt;
  char arg[MAX_LIGNE];&lt;br /&gt;
  char suite[MAX_LIGNE];&lt;br /&gt;
  int statut=sscanf(ligne,&amp;quot;'''%4s %5s%s %s'''&amp;quot;,cmd,tag,arg,suite);&lt;br /&gt;
&lt;br /&gt;
  static int gestion_RCPT(char *ligne,FILE *client,struct courriel *donnees){&lt;br /&gt;
  char cmd[MAX_LIGNE];&lt;br /&gt;
  char tag[MAX_LIGNE];&lt;br /&gt;
  char arg[MAX_LIGNE];&lt;br /&gt;
  char suite[MAX_LIGNE];&lt;br /&gt;
  int statut=sscanf(ligne,&amp;quot;'''%4s %3s%s %s'''&amp;quot;,cmd,tag,arg,suite);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== Gérer une file d'attente ==&lt;br /&gt;
&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&lt;br /&gt;
To do...&lt;br /&gt;
&lt;br /&gt;
== Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=Fichier:LisaJerome.zip&amp;diff=61991</id>
		<title>Fichier:LisaJerome.zip</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=Fichier:LisaJerome.zip&amp;diff=61991"/>
				<updated>2023-06-14T17:11:22Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : Jbreuvar a téléversé une nouvelle version de Fichier:LisaJerome.zip&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dernière version avec script shell pour test de charge du serveur SMTPin&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61989</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61989"/>
				<updated>2023-06-14T17:10:37Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* Gérer une file d'attente */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== SMTPout : Processus de stockage du mail ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test en envoyant un mail à un utilisateur qui n'est pas dans la carte utilisateur carte.txt : le mail ne se stocke pas.&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPout en stockant plusieurs mails simultanément :&lt;br /&gt;
**Pour cela, écrire une script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
   for((i=1; i&amp;lt;=50; i++))&lt;br /&gt;
     do&lt;br /&gt;
       echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
       nc -i1 -q0 -C 193.48.57.164 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
Voir le fichier test1.txt&lt;br /&gt;
 HELO lisa&lt;br /&gt;
 MAIL FROM: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
 RCPT TO: &amp;lt;lisadubois@lamentable.site&amp;gt;&lt;br /&gt;
 DATA&lt;br /&gt;
 SUBJECT Bonjour&lt;br /&gt;
 Hi&lt;br /&gt;
 Hola&lt;br /&gt;
 .&lt;br /&gt;
 QUIT&lt;br /&gt;
&lt;br /&gt;
Le test de charge est OK pour un stockage de 50 mails simultanés, le serveur est solide.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit que lorsqu'on envoie un mail depuis notre boîte mail polytech-lille.net, les messages ne s'envoient pas, ne se stockent pas&lt;br /&gt;
**En exécutant la commande strace -f, on remarque que notre boîte mail envoie la commande :&lt;br /&gt;
***EHLO au lieu de HELO&lt;br /&gt;
***MAIL FROM:&amp;lt;lisadubois@lamentable.site&amp;gt; au lieu de MAIL FROM: &amp;lt;lisadubois@lamentable.site&amp;gt;&lt;br /&gt;
***RCPT TO:&amp;lt;lisadubois@lamentable.site&amp;gt; au lieu de RCPT TO: &amp;lt;lisadubois@lamentable.site&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  struct commandes cmd_smtp[]={&lt;br /&gt;
  {&amp;quot;'''EHLO'''&amp;quot;,gestion_HELO},&lt;br /&gt;
  {&amp;quot;MAIL&amp;quot;,gestion_MAIL},&lt;br /&gt;
  {&amp;quot;RCPT&amp;quot;,gestion_RCPT},&lt;br /&gt;
  {&amp;quot;DATA&amp;quot;,gestion_DATA},&lt;br /&gt;
  {&amp;quot;QUIT&amp;quot;,gestion_QUIT},&lt;br /&gt;
  {&amp;quot;&amp;quot;,NULL}&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  static int gestion_MAIL(char *ligne,FILE *client,struct courriel *donnees){&lt;br /&gt;
  char cmd[MAX_LIGNE];&lt;br /&gt;
  char tag[MAX_LIGNE];&lt;br /&gt;
  char arg[MAX_LIGNE];&lt;br /&gt;
  char suite[MAX_LIGNE];&lt;br /&gt;
  int statut=sscanf(ligne,&amp;quot;'''%4s %5s%s %s'''&amp;quot;,cmd,tag,arg,suite);&lt;br /&gt;
&lt;br /&gt;
  static int gestion_RCPT(char *ligne,FILE *client,struct courriel *donnees){&lt;br /&gt;
  char cmd[MAX_LIGNE];&lt;br /&gt;
  char tag[MAX_LIGNE];&lt;br /&gt;
  char arg[MAX_LIGNE];&lt;br /&gt;
  char suite[MAX_LIGNE];&lt;br /&gt;
  int statut=sscanf(ligne,&amp;quot;'''%4s %3s%s %s'''&amp;quot;,cmd,tag,arg,suite);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== Gérer une file d'attente ==&lt;br /&gt;
&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&lt;br /&gt;
To do...&lt;br /&gt;
&lt;br /&gt;
== Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61984</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61984"/>
				<updated>2023-06-14T17:01:34Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* Tester les limites de SMTPout */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== SMTPout : Processus de stockage du mail ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test en envoyant un mail à un utilisateur qui n'est pas dans la carte utilisateur carte.txt : le mail ne se stocke pas.&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPout en stockant plusieurs mails simultanément :&lt;br /&gt;
**Pour cela, écrire une script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
   for((i=1; i&amp;lt;=50; i++))&lt;br /&gt;
     do&lt;br /&gt;
       echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
       nc -i1 -q0 -C 193.48.57.164 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
Voir le fichier test1.txt&lt;br /&gt;
 HELO lisa&lt;br /&gt;
 MAIL FROM: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
 RCPT TO: &amp;lt;lisadubois@lamentable.site&amp;gt;&lt;br /&gt;
 DATA&lt;br /&gt;
 SUBJECT Bonjour&lt;br /&gt;
 Hi&lt;br /&gt;
 Hola&lt;br /&gt;
 .&lt;br /&gt;
 QUIT&lt;br /&gt;
&lt;br /&gt;
Le test de charge est OK pour un stockage de 50 mails simultanés, le serveur est solide.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit que lorsqu'on envoie un mail depuis notre boîte mail polytech-lille.net, les messages ne s'envoient pas, ne se stockent pas&lt;br /&gt;
**En exécutant la commande strace -f, on remarque que notre boîte mail envoie la commande :&lt;br /&gt;
***EHLO au lieu de HELO&lt;br /&gt;
***MAIL FROM:&amp;lt;lisadubois@lamentable.site&amp;gt; au lieu de MAIL FROM: &amp;lt;lisadubois@lamentable.site&amp;gt;&lt;br /&gt;
***RCPT TO:&amp;lt;lisadubois@lamentable.site&amp;gt; au lieu de RCPT TO: &amp;lt;lisadubois@lamentable.site&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  struct commandes cmd_smtp[]={&lt;br /&gt;
  {&amp;quot;'''EHLO'''&amp;quot;,gestion_HELO},&lt;br /&gt;
  {&amp;quot;MAIL&amp;quot;,gestion_MAIL},&lt;br /&gt;
  {&amp;quot;RCPT&amp;quot;,gestion_RCPT},&lt;br /&gt;
  {&amp;quot;DATA&amp;quot;,gestion_DATA},&lt;br /&gt;
  {&amp;quot;QUIT&amp;quot;,gestion_QUIT},&lt;br /&gt;
  {&amp;quot;&amp;quot;,NULL}&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
  static int gestion_MAIL(char *ligne,FILE *client,struct courriel *donnees){&lt;br /&gt;
  char cmd[MAX_LIGNE];&lt;br /&gt;
  char tag[MAX_LIGNE];&lt;br /&gt;
  char arg[MAX_LIGNE];&lt;br /&gt;
  char suite[MAX_LIGNE];&lt;br /&gt;
  int statut=sscanf(ligne,&amp;quot;'''%4s %5s%s %s'''&amp;quot;,cmd,tag,arg,suite);&lt;br /&gt;
&lt;br /&gt;
  static int gestion_RCPT(char *ligne,FILE *client,struct courriel *donnees){&lt;br /&gt;
  char cmd[MAX_LIGNE];&lt;br /&gt;
  char tag[MAX_LIGNE];&lt;br /&gt;
  char arg[MAX_LIGNE];&lt;br /&gt;
  char suite[MAX_LIGNE];&lt;br /&gt;
  int statut=sscanf(ligne,&amp;quot;'''%4s %3s%s %s'''&amp;quot;,cmd,tag,arg,suite);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== Gérer une file d'attente ==&lt;br /&gt;
&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&lt;br /&gt;
&lt;br /&gt;
Voir aussi comment je passe en IPV6 ? au lieu d'IPV4 ?&lt;br /&gt;
&lt;br /&gt;
== Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61983</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61983"/>
				<updated>2023-06-14T17:00:38Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* Tester les limites de SMTPout */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== SMTPout : Processus de stockage du mail ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test en envoyant un mail à un utilisateur qui n'est pas dans la carte utilisateur carte.txt : le mail ne se stocke pas.&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPout en stockant plusieurs mails simultanément :&lt;br /&gt;
**Pour cela, écrire une script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
   for((i=1; i&amp;lt;=50; i++))&lt;br /&gt;
     do&lt;br /&gt;
       echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
       nc -i1 -q0 -C 193.48.57.164 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
Voir le fichier test1.txt&lt;br /&gt;
 HELO lisa&lt;br /&gt;
 MAIL FROM: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
 RCPT TO: &amp;lt;lisadubois@lamentable.site&amp;gt;&lt;br /&gt;
 DATA&lt;br /&gt;
 SUBJECT Bonjour&lt;br /&gt;
 Hi&lt;br /&gt;
 Hola&lt;br /&gt;
 .&lt;br /&gt;
 QUIT&lt;br /&gt;
&lt;br /&gt;
Le test de charge est OK pour un stockage de 50 mails simultanés, le serveur est solide.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit que lorsqu'on envoie un mail depuis notre boîte mail polytech-lille.net, les messages ne s'envoient pas, ne se stockent pas&lt;br /&gt;
**En exécutant la commande strace -f, on remarque que notre boîte mail envoie la commande :&lt;br /&gt;
***EHLO au lieu de HELO&lt;br /&gt;
***MAIL FROM:&amp;lt;lisadubois@lamentable.site&amp;gt; au lieu de MAIL FROM: &amp;lt;lisadubois@lamentable.site&amp;gt;&lt;br /&gt;
***RCPT TO:&amp;lt;lisadubois@lamentable.site&amp;gt; au lieu de RCPT TO: &amp;lt;lisadubois@lamentable.site&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  struct commandes cmd_smtp[]={&lt;br /&gt;
  {&amp;quot;'''EHLO'''&amp;quot;,gestion_HELO},&lt;br /&gt;
  {&amp;quot;MAIL&amp;quot;,gestion_MAIL},&lt;br /&gt;
  {&amp;quot;RCPT&amp;quot;,gestion_RCPT},&lt;br /&gt;
  {&amp;quot;DATA&amp;quot;,gestion_DATA},&lt;br /&gt;
  {&amp;quot;QUIT&amp;quot;,gestion_QUIT},&lt;br /&gt;
  {&amp;quot;&amp;quot;,NULL}&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  static int gestion_MAIL(char *ligne,FILE *client,struct courriel *donnees){&lt;br /&gt;
  char cmd[MAX_LIGNE];&lt;br /&gt;
  char tag[MAX_LIGNE];&lt;br /&gt;
  char arg[MAX_LIGNE];&lt;br /&gt;
  char suite[MAX_LIGNE];&lt;br /&gt;
  int statut=sscanf(ligne,&amp;quot;'''%4s %5s%s %s'''&amp;quot;,cmd,tag,arg,suite);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  static int gestion_RCPT(char *ligne,FILE *client,struct courriel *donnees){&lt;br /&gt;
  char cmd[MAX_LIGNE];&lt;br /&gt;
  char tag[MAX_LIGNE];&lt;br /&gt;
  char arg[MAX_LIGNE];&lt;br /&gt;
  char suite[MAX_LIGNE];&lt;br /&gt;
  int statut=sscanf(ligne,&amp;quot;'''%4s %3s%s %s'''&amp;quot;,cmd,tag,arg,suite);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== Gérer une file d'attente ==&lt;br /&gt;
&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&lt;br /&gt;
&lt;br /&gt;
Voir aussi comment je passe en IPV6 ? au lieu d'IPV4 ?&lt;br /&gt;
&lt;br /&gt;
== Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=Fichier:LisaJerome.zip&amp;diff=61971</id>
		<title>Fichier:LisaJerome.zip</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=Fichier:LisaJerome.zip&amp;diff=61971"/>
				<updated>2023-06-14T15:35:51Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : Jbreuvar a téléversé une nouvelle version de Fichier:LisaJerome.zip&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dernière version avec script shell pour test de charge du serveur SMTPin&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61969</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61969"/>
				<updated>2023-06-14T15:35:20Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* Tester les limites de SMTPout */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== SMTPout : Processus de stockage du mail ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test en envoyant un mail à un utilisateur qui n'est pas dans la carte utilisateur carte.txt : le mail ne se stocke pas.&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPout en stockant plusieurs mails simultanément :&lt;br /&gt;
**Pour cela, écrire une script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
   for((i=1; i&amp;lt;=50; i++))&lt;br /&gt;
     do&lt;br /&gt;
       echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
       nc -i1 -q0 -C 193.48.57.164 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
Voir le fichier test1.txt&lt;br /&gt;
 HELO lisa&lt;br /&gt;
 MAIL FROM: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
 RCPT TO: &amp;lt;lisadubois@lamentable.site&amp;gt;&lt;br /&gt;
 DATA&lt;br /&gt;
 SUBJECT Bonjour&lt;br /&gt;
 Hi&lt;br /&gt;
 Hola&lt;br /&gt;
 .&lt;br /&gt;
 QUIT&lt;br /&gt;
&lt;br /&gt;
Le test de charge est OK pour un stockage de 50 mails simultanés, le serveur est solide.&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit que lorsqu'on envoie un mail depuis notre adresse mail gmail ou polytech-lille.net, les messages ne s'envoient pas, ne se stockent pas&lt;br /&gt;
**En exécutant la commande strace -f on remarque que notre boîte mail envoie les commandes SMTP RCPT TO:&amp;lt;lisadubois@lamentable.site&amp;gt; au lieu de RCPT TO:&amp;lt;lisadubois@lamentable.site&amp;gt;. Il faut donc supprimer les espaces des commandes SMTP dans smtp.c :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== Gérer une file d'attente ==&lt;br /&gt;
&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&lt;br /&gt;
&lt;br /&gt;
Voir aussi comment je passe en IPV6 ? au lieu d'IPV4 ?&lt;br /&gt;
&lt;br /&gt;
== Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61940</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61940"/>
				<updated>2023-06-14T14:52:55Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* Tester les limites de SMTPout */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== SMTPout : Processus de stockage du mail ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test en envoyant un mail à un utilisateur qui n'est pas dans la carte utilisateur carte.txt : le mail ne se stocke pas.&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPout en stockant plusieurs mails simultanément :&lt;br /&gt;
**Pour cela, écrire une script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
   for((i=1; i&amp;lt;=50; i++))&lt;br /&gt;
     do&lt;br /&gt;
       echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
       nc -i1 -q0 -C 193.48.57.164 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
Voir le fichier test1.txt&lt;br /&gt;
 HELO lisa&lt;br /&gt;
 MAIL FROM: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
 RCPT TO: &amp;lt;lisadubois@lamentable.site&amp;gt;&lt;br /&gt;
 DATA&lt;br /&gt;
 SUBJECT Bonjour&lt;br /&gt;
 Hi&lt;br /&gt;
 Hola&lt;br /&gt;
 .&lt;br /&gt;
 QUIT&lt;br /&gt;
&lt;br /&gt;
Le test de charge est OK pour un stockage de 50 mails simultanés, le serveur est solide.&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit que lorsqu'on envoie un mail depuis notre adresse mail gmail ou polytech-lille.net, les messages ne s'envoient pas, ne se stockent pas&lt;br /&gt;
**En exécutant la commande strace -f on remarque que notre boîte mail envoie les commandes SMTP RCPT TO:&amp;lt;lisadubois@lamentable.site&amp;gt; au lieu de RCPT TO:&amp;lt;lisadubois@lamentable.site&amp;gt;. Il faut donc supprimer les espaces des commandes SMTP dans smtp.c :&lt;br /&gt;
&lt;br /&gt;
== Gérer une file d'attente ==&lt;br /&gt;
&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&lt;br /&gt;
&lt;br /&gt;
Voir aussi comment je passe en IPV6 ? au lieu d'IPV4 ?&lt;br /&gt;
&lt;br /&gt;
== Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61866</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61866"/>
				<updated>2023-06-14T13:09:36Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* Gérer une file d'attente */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== SMTPout : Processus de stockage du mail ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test en envoyant un mail à un utilisateur qui n'est pas dans la carte utilisateur carte.txt : le mail ne se stocke pas&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPout en stockant plusieurs mails simultanément :&lt;br /&gt;
**Pour cela, écrire une script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
   for((i=1; i&amp;lt;=50; i++))&lt;br /&gt;
     do&lt;br /&gt;
       echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
       nc -i1 -q0 -C 193.48.57.164 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
Voir le fichier test1.txt&lt;br /&gt;
 HELO lisa&lt;br /&gt;
 MAIL FROM: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
 RCPT TO: &amp;lt;lisadubois@lamentable.site&amp;gt;&lt;br /&gt;
 DATA&lt;br /&gt;
 SUBJECT Bonjour&lt;br /&gt;
 Hi&lt;br /&gt;
 Hola&lt;br /&gt;
 .&lt;br /&gt;
 QUIT&lt;br /&gt;
&lt;br /&gt;
Le test de charge est OK pour un stockage de 50 mails simultanés, le serveur est solide.&lt;br /&gt;
&lt;br /&gt;
== Gérer une file d'attente ==&lt;br /&gt;
&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&lt;br /&gt;
&lt;br /&gt;
Voir aussi comment je passe en IPV6 ? au lieu d'IPV4 ?&lt;br /&gt;
&lt;br /&gt;
== Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61864</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61864"/>
				<updated>2023-06-14T13:09:25Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* Tester les limites de SMTPout */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== SMTPout : Processus de stockage du mail ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test en envoyant un mail à un utilisateur qui n'est pas dans la carte utilisateur carte.txt : le mail ne se stocke pas&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPout en stockant plusieurs mails simultanément :&lt;br /&gt;
**Pour cela, écrire une script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
   for((i=1; i&amp;lt;=50; i++))&lt;br /&gt;
     do&lt;br /&gt;
       echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
       nc -i1 -q0 -C 193.48.57.164 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
Voir le fichier test1.txt&lt;br /&gt;
 HELO lisa&lt;br /&gt;
 MAIL FROM: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
 RCPT TO: &amp;lt;lisadubois@lamentable.site&amp;gt;&lt;br /&gt;
 DATA&lt;br /&gt;
 SUBJECT Bonjour&lt;br /&gt;
 Hi&lt;br /&gt;
 Hola&lt;br /&gt;
 .&lt;br /&gt;
 QUIT&lt;br /&gt;
&lt;br /&gt;
Le test de charge est OK pour un stockage de 50 mails simultanés, le serveur est solide.&lt;br /&gt;
&lt;br /&gt;
== Gérer une file d'attente ==&lt;br /&gt;
&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&lt;br /&gt;
&lt;br /&gt;
== Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61858</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61858"/>
				<updated>2023-06-14T13:07:39Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* Tester les limites de SMTPout */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== SMTPout : Processus de stockage du mail ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test en envoyant un mail à un utilisateur qui n'est pas dans la carte utilisateur carte.txt : le mail ne se stocke pas&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPout en stockant plusieurs mails simultanément :&lt;br /&gt;
**Pour cela, écrire une script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
   for((i=1; i&amp;lt;=50; i++))&lt;br /&gt;
     do&lt;br /&gt;
       echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
       nc -i1 -q0 -C 193.48.57.164 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
Voir le fichier test1.txt&lt;br /&gt;
 HELO lisa&lt;br /&gt;
 MAIL FROM: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
 RCPT TO: &amp;lt;lisadubois@lamentable.site&amp;gt;&lt;br /&gt;
 DATA&lt;br /&gt;
 SUBJECT Bonjour&lt;br /&gt;
 Hi&lt;br /&gt;
 Hola&lt;br /&gt;
 .&lt;br /&gt;
 QUIT&lt;br /&gt;
&lt;br /&gt;
On &lt;br /&gt;
&lt;br /&gt;
Le test de charge est OK pour un stockage de 50 mails simultanés, le serveur est solide.&lt;br /&gt;
&lt;br /&gt;
Voir aussi comment je passe en IPV6 ? au lieu d'IPV4 ?&lt;br /&gt;
&lt;br /&gt;
== Gérer une file d'attente ==&lt;br /&gt;
&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&lt;br /&gt;
&lt;br /&gt;
== Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61838</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61838"/>
				<updated>2023-06-14T12:38:34Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* Tester les limites de SMTPin */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== SMTPout : Processus de stockage du mail ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
Voir aussi comment je passe en IPV6 ? au lieu d'IPV4 ?&lt;br /&gt;
&lt;br /&gt;
== Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61803</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61803"/>
				<updated>2023-06-14T08:54:00Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* To do */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== SMTPout : Processus de stockage du mail ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
Voir aussi comment je passe en IPV6 ? au lieu d'IPV4 ?&lt;br /&gt;
&lt;br /&gt;
== Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61802</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61802"/>
				<updated>2023-06-14T08:53:45Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 8) Activer la connexion chiffrée avec le serveur */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== SMTPout : Processus de stockage du mail ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
Voir aussi comment je passe en IPV6 ? au lieu d'IPV4 ?&lt;br /&gt;
&lt;br /&gt;
== To do ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61801</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61801"/>
				<updated>2023-06-14T08:53:33Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 7) Tester les limites de SMTPout */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== SMTPout : Processus de stockage du mail ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
Voir aussi comment je passe en IPV6 ? au lieu d'IPV4 ?&lt;br /&gt;
&lt;br /&gt;
== 8) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
== To do ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61800</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61800"/>
				<updated>2023-06-14T08:53:08Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 7) Tester les limites de SMTPout */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== SMTPout : Processus de stockage du mail ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== 7) Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
Voir aussi comment je passe en IPV6 ? au lieu d'IPV4 ?&lt;br /&gt;
&lt;br /&gt;
== 8) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
== To do ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61799</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61799"/>
				<updated>2023-06-14T08:52:47Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 6) Debug SMTPout -&amp;gt; recevoir les mails */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== SMTPout : Processus de stockage du mail ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== 7) Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
== 8) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
== To do ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61798</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61798"/>
				<updated>2023-06-14T08:52:39Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 5) Tester les limites de SMTPin */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== SMTPout : Processus de stockage du mail ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== 7) Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
== 8) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
== To do ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61797</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61797"/>
				<updated>2023-06-14T08:52:28Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 4) Debug SMTPin -&amp;gt; envoyer les mails */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== SMTPout : Processus de stockage du mail ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== 7) Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
== 8) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
== To do ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61796</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61796"/>
				<updated>2023-06-14T08:52:11Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== SMTPout : Processus de stockage du mail ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== 7) Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
== 8) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
== To do ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61795</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61795"/>
				<updated>2023-06-14T08:51:54Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 2) Modifications SMTPout */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== SMTPout : Processus de stockage du mail ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== 7) Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
== 8) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
== To do ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61794</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61794"/>
				<updated>2023-06-14T08:50:15Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 1) Debug SMTPin */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== 2) Modifications SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== 7) Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
== 8) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
== To do ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61793</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61793"/>
				<updated>2023-06-14T08:49:46Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 8) Activer la connexion chiffrée avec le serveur */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== 1) Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== 2) Modifications SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== 7) Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
== 8) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
== To do ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61792</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61792"/>
				<updated>2023-06-14T08:49:34Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* To do */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== 1) Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== 2) Modifications SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== 7) Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
== 8) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61791</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61791"/>
				<updated>2023-06-14T08:46:41Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 6) Debug SMTPout -&amp;gt; recevoir les mails */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== To do ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*ne doivent être stockés que les courriels à destination d’un utilisateur local ;&amp;lt;br&amp;gt; --à tester&lt;br /&gt;
&lt;br /&gt;
== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== 1) Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== 2) Modifications SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== 7) Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
== 8) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61790</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61790"/>
				<updated>2023-06-14T08:45:30Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 8) Tester les limites de SMTPout */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== To do ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*ne doivent être stockés que les courriels à destination d’un utilisateur local ;&amp;lt;br&amp;gt; --à tester&lt;br /&gt;
&lt;br /&gt;
== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== 1) Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== 2) Modifications SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
    }&lt;br /&gt;
  adresse[j]='\0';&lt;br /&gt;
  char *id=scanCarteUtilisateur(adresse);&lt;br /&gt;
  free(adresse);&lt;br /&gt;
  return id;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== 7) Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
== 8) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61789</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61789"/>
				<updated>2023-06-14T08:45:21Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 8) Activer la connexion chiffrée avec le serveur */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== To do ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*ne doivent être stockés que les courriels à destination d’un utilisateur local ;&amp;lt;br&amp;gt; --à tester&lt;br /&gt;
&lt;br /&gt;
== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== 1) Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== 2) Modifications SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
    }&lt;br /&gt;
  adresse[j]='\0';&lt;br /&gt;
  char *id=scanCarteUtilisateur(adresse);&lt;br /&gt;
  free(adresse);&lt;br /&gt;
  return id;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== 8) Tester les limites de SMTPout ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 8) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61788</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61788"/>
				<updated>2023-06-14T08:44:56Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 7) Activer la connexion chiffrée avec le serveur */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== To do ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*ne doivent être stockés que les courriels à destination d’un utilisateur local ;&amp;lt;br&amp;gt; --à tester&lt;br /&gt;
&lt;br /&gt;
== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== 1) Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== 2) Modifications SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
    }&lt;br /&gt;
  adresse[j]='\0';&lt;br /&gt;
  char *id=scanCarteUtilisateur(adresse);&lt;br /&gt;
  free(adresse);&lt;br /&gt;
  return id;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== 8) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61787</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61787"/>
				<updated>2023-06-14T08:44:13Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* A faire */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== To do ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*ne doivent être stockés que les courriels à destination d’un utilisateur local ;&amp;lt;br&amp;gt; --à tester&lt;br /&gt;
&lt;br /&gt;
== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== 1) Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== 2) Modifications SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
    }&lt;br /&gt;
  adresse[j]='\0';&lt;br /&gt;
  char *id=scanCarteUtilisateur(adresse);&lt;br /&gt;
  free(adresse);&lt;br /&gt;
  return id;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== 7) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61786</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61786"/>
				<updated>2023-06-14T08:42:52Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 6) Debug SMTPout -&amp;gt; recevoir les mails */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A faire ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent ne pas être chiffrées, les communications non chiffrés sont reçues sur le port 25 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*ne doivent être stockés que les courriels à destination d’un utilisateur local ;&amp;lt;br&amp;gt;&lt;br /&gt;
*le processus de remise stocke le message dans le sous-répertoire Maildir/tmp puis le déplace dans le sous-répertoire Maildir/new, déplacement doit être fait par la primitive rename ;&amp;lt;br&amp;gt;&lt;br /&gt;
*pour assurer un nom unique aux fichiers de stockage, utilisez la date en seconde (fonction time), le PID et un compteur commun à tous les flux d’exécution (utilisation de sémaphores indispensable).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== 1) Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== 2) Modifications SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
    }&lt;br /&gt;
  adresse[j]='\0';&lt;br /&gt;
  char *id=scanCarteUtilisateur(adresse);&lt;br /&gt;
  free(adresse);&lt;br /&gt;
  return id;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== 7) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61785</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61785"/>
				<updated>2023-06-14T08:42:29Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 6) Debug SMTPout -&amp;gt; recevoir les mails */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A faire ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent ne pas être chiffrées, les communications non chiffrés sont reçues sur le port 25 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*ne doivent être stockés que les courriels à destination d’un utilisateur local ;&amp;lt;br&amp;gt;&lt;br /&gt;
*le processus de remise stocke le message dans le sous-répertoire Maildir/tmp puis le déplace dans le sous-répertoire Maildir/new, déplacement doit être fait par la primitive rename ;&amp;lt;br&amp;gt;&lt;br /&gt;
*pour assurer un nom unique aux fichiers de stockage, utilisez la date en seconde (fonction time), le PID et un compteur commun à tous les flux d’exécution (utilisation de sémaphores indispensable).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== 1) Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== 2) Modifications SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if('''strcasecmp(adresses[i].adresse,courriel)== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; remplacer '''strlen(adresse)''' par '''strlen(destinataire)''' dans la boucle for():&lt;br /&gt;
  char *adresseVersUtilisateur(char *destinataire){&lt;br /&gt;
  char *adresse=malloc(strlen(destinataire));&lt;br /&gt;
  int i,j=0;;&lt;br /&gt;
  unsigned char mode=0;&lt;br /&gt;
  for(i=0;i&amp;lt;'''strlen(destinataire)''';i++){&lt;br /&gt;
    if(destinataire[i]=='&amp;gt;') break;&lt;br /&gt;
    if(mode==1) adresse[j++]=destinataire[i];&lt;br /&gt;
    if(destinataire[i]=='&amp;lt;') mode=1;&lt;br /&gt;
    }&lt;br /&gt;
  adresse[j]='\0';&lt;br /&gt;
  char *id=scanCarteUtilisateur(adresse);&lt;br /&gt;
  free(adresse);&lt;br /&gt;
  return id;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== 7) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61784</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61784"/>
				<updated>2023-06-14T08:34:56Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 5) Tester les limites de SMTPin */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A faire ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent ne pas être chiffrées, les communications non chiffrés sont reçues sur le port 25 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*ne doivent être stockés que les courriels à destination d’un utilisateur local ;&amp;lt;br&amp;gt;&lt;br /&gt;
*le processus de remise stocke le message dans le sous-répertoire Maildir/tmp puis le déplace dans le sous-répertoire Maildir/new, déplacement doit être fait par la primitive rename ;&amp;lt;br&amp;gt;&lt;br /&gt;
*pour assurer un nom unique aux fichiers de stockage, utilisez la date en seconde (fonction time), le PID et un compteur commun à tous les flux d’exécution (utilisation de sémaphores indispensable).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== 1) Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== 2) Modifications SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: &amp;lt;goudale@lamentable.site&amp;gt;&lt;br /&gt;
  RCPT TO: &amp;lt;jerome.breuvart@polytech-lille.net&amp;gt;&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if(strcasecmp(adresses[i].adresse,courriel)'''== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== 7) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61783</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61783"/>
				<updated>2023-06-14T08:31:06Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 6) Debug SMTPout -&amp;gt; recevoir les mails */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A faire ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent ne pas être chiffrées, les communications non chiffrés sont reçues sur le port 25 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*ne doivent être stockés que les courriels à destination d’un utilisateur local ;&amp;lt;br&amp;gt;&lt;br /&gt;
*le processus de remise stocke le message dans le sous-répertoire Maildir/tmp puis le déplace dans le sous-répertoire Maildir/new, déplacement doit être fait par la primitive rename ;&amp;lt;br&amp;gt;&lt;br /&gt;
*pour assurer un nom unique aux fichiers de stockage, utilisez la date en seconde (fonction time), le PID et un compteur commun à tous les flux d’exécution (utilisation de sémaphores indispensable).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== 1) Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== 2) Modifications SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: goudale@lamentable.site&lt;br /&gt;
  RCPT TO: jerome.breuvart@polytech-lille.net&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'aperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
*On s'aperçoit aussi que le serveur ne crée pas la structure de répertoire MAILDIR, il faut donc la créer : (exemple :/tmp/lisadubois/ créer 3 dossiers &amp;quot;tmp&amp;quot;, &amp;quot;cur&amp;quot; et &amp;quot;new&amp;quot;)&lt;br /&gt;
*out.c -&amp;gt; adresseVersUtilisateur() -&amp;gt; on s'aperçoit aussi qu'il est impératif que le destinataire soit passé entre chevrons dans la commande SMTP RCPT TO (exemple : RCPT TO: &amp;lt;jeromebreuvart@lamentable.site&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if(strcasecmp(adresses[i].adresse,courriel)'''== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maintenant, ça fonctionne, on peut retrouver les mails dans le répertoire new de chaque utilisateur.&lt;br /&gt;
&lt;br /&gt;
== 7) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61782</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61782"/>
				<updated>2023-06-14T08:18:43Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 6) Debug SMTPout -&amp;gt; recevoir les mails */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A faire ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent ne pas être chiffrées, les communications non chiffrés sont reçues sur le port 25 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*ne doivent être stockés que les courriels à destination d’un utilisateur local ;&amp;lt;br&amp;gt;&lt;br /&gt;
*le processus de remise stocke le message dans le sous-répertoire Maildir/tmp puis le déplace dans le sous-répertoire Maildir/new, déplacement doit être fait par la primitive rename ;&amp;lt;br&amp;gt;&lt;br /&gt;
*pour assurer un nom unique aux fichiers de stockage, utilisez la date en seconde (fonction time), le PID et un compteur commun à tous les flux d’exécution (utilisation de sémaphores indispensable).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== 1) Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== 2) Modifications SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: goudale@lamentable.site&lt;br /&gt;
  RCPT TO: jerome.breuvart@polytech-lille.net&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'apperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
Répertoires : /tmp/lisadubois/tmp/ et /tmp/jeromebreuvart/tmp/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On s'apperçoit que tous les mails se stockent dans /tmp/lisadubois/tmp/ même s'ils sont à destination de jeromebreuvart --&amp;gt; to debug &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if(strcasecmp(adresses[i].adresse,courriel)'''== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
IL FAUT UTILISER LES CHEVRONS POUR RCPT TO&lt;br /&gt;
&lt;br /&gt;
Debug SMTPout car il envoie les mails à Lisa au lieu de moi ???&lt;br /&gt;
&lt;br /&gt;
== 7) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61781</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61781"/>
				<updated>2023-06-14T07:31:00Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 2) Modifications SMTPout */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A faire ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent ne pas être chiffrées, les communications non chiffrés sont reçues sur le port 25 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*ne doivent être stockés que les courriels à destination d’un utilisateur local ;&amp;lt;br&amp;gt;&lt;br /&gt;
*le processus de remise stocke le message dans le sous-répertoire Maildir/tmp puis le déplace dans le sous-répertoire Maildir/new, déplacement doit être fait par la primitive rename ;&amp;lt;br&amp;gt;&lt;br /&gt;
*pour assurer un nom unique aux fichiers de stockage, utilisez la date en seconde (fonction time), le PID et un compteur commun à tous les flux d’exécution (utilisation de sémaphores indispensable).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== 1) Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== 2) Modifications SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: goudale@lamentable.site&lt;br /&gt;
  RCPT TO: jerome.breuvart@polytech-lille.net&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'apperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
Répertoires : /tmp/lisadubois/tmp/ et /tmp/jeromebreuvart/tmp/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On s'apperçoit que tous les mails se stockent dans /tmp/lisadubois/tmp/ même s'ils sont à destination de jeromebreuvart --&amp;gt; to debug &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if(strcasecmp(adresses[i].adresse,courriel)'''== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Debug SMTPout car il envoie les mails à Lisa au lieu de moi ???&lt;br /&gt;
&lt;br /&gt;
== 7) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61780</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61780"/>
				<updated>2023-06-14T07:30:49Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 1) Debug SMTPin */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A faire ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent ne pas être chiffrées, les communications non chiffrés sont reçues sur le port 25 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*ne doivent être stockés que les courriels à destination d’un utilisateur local ;&amp;lt;br&amp;gt;&lt;br /&gt;
*le processus de remise stocke le message dans le sous-répertoire Maildir/tmp puis le déplace dans le sous-répertoire Maildir/new, déplacement doit être fait par la primitive rename ;&amp;lt;br&amp;gt;&lt;br /&gt;
*pour assurer un nom unique aux fichiers de stockage, utilisez la date en seconde (fonction time), le PID et un compteur commun à tous les flux d’exécution (utilisation de sémaphores indispensable).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== 1) Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; -&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== 2) Modifications SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; =&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: goudale@lamentable.site&lt;br /&gt;
  RCPT TO: jerome.breuvart@polytech-lille.net&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'apperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
Répertoires : /tmp/lisadubois/tmp/ et /tmp/jeromebreuvart/tmp/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On s'apperçoit que tous les mails se stockent dans /tmp/lisadubois/tmp/ même s'ils sont à destination de jeromebreuvart --&amp;gt; to debug &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if(strcasecmp(adresses[i].adresse,courriel)'''== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Debug SMTPout car il envoie les mails à Lisa au lieu de moi ???&lt;br /&gt;
&lt;br /&gt;
== 7) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61779</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61779"/>
				<updated>2023-06-14T07:30:26Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 6) Debug SMTPout -&amp;gt; recevoir les mails */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A faire ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent ne pas être chiffrées, les communications non chiffrés sont reçues sur le port 25 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*ne doivent être stockés que les courriels à destination d’un utilisateur local ;&amp;lt;br&amp;gt;&lt;br /&gt;
*le processus de remise stocke le message dans le sous-répertoire Maildir/tmp puis le déplace dans le sous-répertoire Maildir/new, déplacement doit être fait par la primitive rename ;&amp;lt;br&amp;gt;&lt;br /&gt;
*pour assurer un nom unique aux fichiers de stockage, utilisez la date en seconde (fonction time), le PID et un compteur commun à tous les flux d’exécution (utilisation de sémaphores indispensable).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== 1) Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; =&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== 2) Modifications SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; =&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: goudale@lamentable.site&lt;br /&gt;
  RCPT TO: jerome.breuvart@polytech-lille.net&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'apperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
Répertoires : /tmp/lisadubois/tmp/ et /tmp/jeromebreuvart/tmp/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On s'apperçoit que tous les mails se stockent dans /tmp/lisadubois/tmp/ même s'ils sont à destination de jeromebreuvart --&amp;gt; to debug &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; *scanCarteUtilisateur() -&amp;gt; La fonction strcasecmp() compare les deux chaînes s1 et s2 et renvoie un entier négatif, nul, ou positif, si la chaîne s1 est respectivement inférieure, égale ou supérieure à s2.&lt;br /&gt;
&lt;br /&gt;
  char *scanCarteUtilisateur(char *courriel){&lt;br /&gt;
  int i=0;&lt;br /&gt;
  while(adresses[i].id!=NULL){&lt;br /&gt;
    if(strcasecmp(adresses[i].adresse,courriel)'''== 0''') return adresses[i].id;&lt;br /&gt;
    i++;&lt;br /&gt;
    }&lt;br /&gt;
  #ifdef DEVERMINE&lt;br /&gt;
  printf(&amp;quot;Fin fction *scanCarteUt\n&amp;quot;);&lt;br /&gt;
  #endif&lt;br /&gt;
  return NULL;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Debug SMTPout car il envoie les mails à Lisa au lieu de moi ???&lt;br /&gt;
&lt;br /&gt;
== 7) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61770</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61770"/>
				<updated>2023-06-13T20:05:59Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 5) Tester les limites de SMTPin */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A faire ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent ne pas être chiffrées, les communications non chiffrés sont reçues sur le port 25 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*ne doivent être stockés que les courriels à destination d’un utilisateur local ;&amp;lt;br&amp;gt;&lt;br /&gt;
*le processus de remise stocke le message dans le sous-répertoire Maildir/tmp puis le déplace dans le sous-répertoire Maildir/new, déplacement doit être fait par la primitive rename ;&amp;lt;br&amp;gt;&lt;br /&gt;
*pour assurer un nom unique aux fichiers de stockage, utilisez la date en seconde (fonction time), le PID et un compteur commun à tous les flux d’exécution (utilisation de sémaphores indispensable).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== 1) Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; =&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== 2) Modifications SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; =&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: goudale@lamentable.site&lt;br /&gt;
  RCPT TO: jerome.breuvart@polytech-lille.net&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'apperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
Répertoires : /tmp/lisadubois/tmp/ et /tmp/jeromebreuvart/tmp/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*On s'apperçoit que tous les mails se stockent dans /tmp/lisadubois/tmp/ même s'ils sont à destination de jeromebreuvart --&amp;gt; to debug&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Debug SMTPout car il envoie les mails à Lisa au lieu de moi ???&lt;br /&gt;
&lt;br /&gt;
== 7) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61769</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61769"/>
				<updated>2023-06-13T20:05:46Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 6) Comment exécuter SMTPout ? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A faire ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent ne pas être chiffrées, les communications non chiffrés sont reçues sur le port 25 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*ne doivent être stockés que les courriels à destination d’un utilisateur local ;&amp;lt;br&amp;gt;&lt;br /&gt;
*le processus de remise stocke le message dans le sous-répertoire Maildir/tmp puis le déplace dans le sous-répertoire Maildir/new, déplacement doit être fait par la primitive rename ;&amp;lt;br&amp;gt;&lt;br /&gt;
*pour assurer un nom unique aux fichiers de stockage, utilisez la date en seconde (fonction time), le PID et un compteur commun à tous les flux d’exécution (utilisation de sémaphores indispensable).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== 1) Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; =&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== 2) Modifications SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; =&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: goudale@lamentable.site&lt;br /&gt;
  RCPT TO: jerome.breuvart@polytech-lille.net&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Il faut appuyer 2 fois sur QUIT pour quitter le serveur -- to debug ???&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Debug SMTPout -&amp;gt; recevoir les mails ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'apperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
Répertoires : /tmp/lisadubois/tmp/ et /tmp/jeromebreuvart/tmp/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*On s'apperçoit que tous les mails se stockent dans /tmp/lisadubois/tmp/ même s'ils sont à destination de jeromebreuvart --&amp;gt; to debug&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Debug SMTPout car il envoie les mails à Lisa au lieu de moi ???&lt;br /&gt;
&lt;br /&gt;
== 7) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61766</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61766"/>
				<updated>2023-06-13T12:08:31Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 6) Comment exécuter SMTPout ? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A faire ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent ne pas être chiffrées, les communications non chiffrés sont reçues sur le port 25 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*ne doivent être stockés que les courriels à destination d’un utilisateur local ;&amp;lt;br&amp;gt;&lt;br /&gt;
*le processus de remise stocke le message dans le sous-répertoire Maildir/tmp puis le déplace dans le sous-répertoire Maildir/new, déplacement doit être fait par la primitive rename ;&amp;lt;br&amp;gt;&lt;br /&gt;
*pour assurer un nom unique aux fichiers de stockage, utilisez la date en seconde (fonction time), le PID et un compteur commun à tous les flux d’exécution (utilisation de sémaphores indispensable).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== 1) Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; =&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== 2) Modifications SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; =&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: goudale@lamentable.site&lt;br /&gt;
  RCPT TO: jerome.breuvart@polytech-lille.net&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Il faut appuyer 2 fois sur QUIT pour quitter le serveur -- to debug ???&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Comment exécuter SMTPout ? ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'apperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
Répertoires : /tmp/lisadubois/tmp/ et /tmp/jeromebreuvart/tmp/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Debug SMTPout car il envoie les mails à Lisa au lieu de moi ???&lt;br /&gt;
&lt;br /&gt;
== 7) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61765</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61765"/>
				<updated>2023-06-13T12:07:53Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 6) Comment exécuter SMTPout ? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A faire ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent ne pas être chiffrées, les communications non chiffrés sont reçues sur le port 25 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*ne doivent être stockés que les courriels à destination d’un utilisateur local ;&amp;lt;br&amp;gt;&lt;br /&gt;
*le processus de remise stocke le message dans le sous-répertoire Maildir/tmp puis le déplace dans le sous-répertoire Maildir/new, déplacement doit être fait par la primitive rename ;&amp;lt;br&amp;gt;&lt;br /&gt;
*pour assurer un nom unique aux fichiers de stockage, utilisez la date en seconde (fonction time), le PID et un compteur commun à tous les flux d’exécution (utilisation de sémaphores indispensable).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== 1) Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; =&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== 2) Modifications SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; =&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: goudale@lamentable.site&lt;br /&gt;
  RCPT TO: jerome.breuvart@polytech-lille.net&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Il faut appuyer 2 fois sur QUIT pour quitter le serveur -- to debug ???&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Comment exécuter SMTPout ? ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'apperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
Répertoires : /tmp/lisadubois/tmp/ et /tmp/jeromebreuvart/tmp/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Debug SMTPout car il envoie les mails à Lisa au lieu de moi ?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Puisqu'on exécute le serveur SMTPout sur l'interface eth0 du port 25 (au lieu de l'interface locale loopback), &lt;br /&gt;
alors on ne peut pas se connecter au serveur en localhost ('''nc localhost 25''') mais depuis l'extérieur de la VM ('''nc localhost 193.48.57.164 25''').&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Créer l'architecture de répertoires MAILDIR et le fichier carte.txt à lancer en argument avec -u,&lt;br /&gt;
Tester tout ça une fois que ma VM est en ligne.&lt;br /&gt;
&lt;br /&gt;
Comment me reconnecter à ma VM ? ssh ?&lt;br /&gt;
&lt;br /&gt;
nc 193.48.57.164 25&lt;br /&gt;
RCPT TO : jean@lamentable.site&lt;br /&gt;
&lt;br /&gt;
== 7) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61764</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61764"/>
				<updated>2023-06-13T12:07:37Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 6) Comment exécuter SMTPout ? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A faire ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent ne pas être chiffrées, les communications non chiffrés sont reçues sur le port 25 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*ne doivent être stockés que les courriels à destination d’un utilisateur local ;&amp;lt;br&amp;gt;&lt;br /&gt;
*le processus de remise stocke le message dans le sous-répertoire Maildir/tmp puis le déplace dans le sous-répertoire Maildir/new, déplacement doit être fait par la primitive rename ;&amp;lt;br&amp;gt;&lt;br /&gt;
*pour assurer un nom unique aux fichiers de stockage, utilisez la date en seconde (fonction time), le PID et un compteur commun à tous les flux d’exécution (utilisation de sémaphores indispensable).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== 1) Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; =&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== 2) Modifications SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; =&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: goudale@lamentable.site&lt;br /&gt;
  RCPT TO: jerome.breuvart@polytech-lille.net&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Il faut appuyer 2 fois sur QUIT pour quitter le serveur -- to debug ???&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Comment exécuter SMTPout ? ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'apperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
Répertoires : '''/tmp/lisadubois/tmp/''' et '''/tmp/jeromebreuvart/tmp/'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Debug SMTPout car il envoie les mails à Lisa au lieu de moi ?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Puisqu'on exécute le serveur SMTPout sur l'interface eth0 du port 25 (au lieu de l'interface locale loopback), &lt;br /&gt;
alors on ne peut pas se connecter au serveur en localhost ('''nc localhost 25''') mais depuis l'extérieur de la VM ('''nc localhost 193.48.57.164 25''').&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Créer l'architecture de répertoires MAILDIR et le fichier carte.txt à lancer en argument avec -u,&lt;br /&gt;
Tester tout ça une fois que ma VM est en ligne.&lt;br /&gt;
&lt;br /&gt;
Comment me reconnecter à ma VM ? ssh ?&lt;br /&gt;
&lt;br /&gt;
nc 193.48.57.164 25&lt;br /&gt;
RCPT TO : jean@lamentable.site&lt;br /&gt;
&lt;br /&gt;
== 7) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61763</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61763"/>
				<updated>2023-06-13T12:07:01Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 6) Comment exécuter SMTPout ? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A faire ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent ne pas être chiffrées, les communications non chiffrés sont reçues sur le port 25 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*ne doivent être stockés que les courriels à destination d’un utilisateur local ;&amp;lt;br&amp;gt;&lt;br /&gt;
*le processus de remise stocke le message dans le sous-répertoire Maildir/tmp puis le déplace dans le sous-répertoire Maildir/new, déplacement doit être fait par la primitive rename ;&amp;lt;br&amp;gt;&lt;br /&gt;
*pour assurer un nom unique aux fichiers de stockage, utilisez la date en seconde (fonction time), le PID et un compteur commun à tous les flux d’exécution (utilisation de sémaphores indispensable).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== 1) Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; =&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== 2) Modifications SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; =&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: goudale@lamentable.site&lt;br /&gt;
  RCPT TO: jerome.breuvart@polytech-lille.net&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Il faut appuyer 2 fois sur QUIT pour quitter le serveur -- to debug ???&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Comment exécuter SMTPout ? ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'apperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs :&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
**Répertoires : '''/tmp/lisadubois/tmp/''' et '''/tmp/jeromebreuvart/tmp/'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Debug SMTPout car il envoie les mails à Lisa au lieu de moi ?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Puisqu'on exécute le serveur SMTPout sur l'interface eth0 du port 25 (au lieu de l'interface locale loopback), &lt;br /&gt;
alors on ne peut pas se connecter au serveur en localhost ('''nc localhost 25''') mais depuis l'extérieur de la VM ('''nc localhost 193.48.57.164 25''').&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Créer l'architecture de répertoires MAILDIR et le fichier carte.txt à lancer en argument avec -u,&lt;br /&gt;
Tester tout ça une fois que ma VM est en ligne.&lt;br /&gt;
&lt;br /&gt;
Comment me reconnecter à ma VM ? ssh ?&lt;br /&gt;
&lt;br /&gt;
nc 193.48.57.164 25&lt;br /&gt;
RCPT TO : jean@lamentable.site&lt;br /&gt;
&lt;br /&gt;
== 7) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61762</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61762"/>
				<updated>2023-06-13T12:06:41Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 6) Comment exécuter SMTPout ? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A faire ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent ne pas être chiffrées, les communications non chiffrés sont reçues sur le port 25 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*ne doivent être stockés que les courriels à destination d’un utilisateur local ;&amp;lt;br&amp;gt;&lt;br /&gt;
*le processus de remise stocke le message dans le sous-répertoire Maildir/tmp puis le déplace dans le sous-répertoire Maildir/new, déplacement doit être fait par la primitive rename ;&amp;lt;br&amp;gt;&lt;br /&gt;
*pour assurer un nom unique aux fichiers de stockage, utilisez la date en seconde (fonction time), le PID et un compteur commun à tous les flux d’exécution (utilisation de sémaphores indispensable).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== 1) Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; =&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== 2) Modifications SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; =&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: goudale@lamentable.site&lt;br /&gt;
  RCPT TO: jerome.breuvart@polytech-lille.net&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Il faut appuyer 2 fois sur QUIT pour quitter le serveur -- to debug ???&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Comment exécuter SMTPout ? ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'apperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs.&lt;br /&gt;
&lt;br /&gt;
  lisadubois : lisadubois@lamentable.site&lt;br /&gt;
  jeromebreuvart : jeromebreuvart@lamentable.site&lt;br /&gt;
&lt;br /&gt;
**Répertoires : '''/tmp/lisadubois/tmp/''' et '''/tmp/jeromebreuvart/tmp/'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Debug SMTPout car il envoie les mails à Lisa au lieu de moi ?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Puisqu'on exécute le serveur SMTPout sur l'interface eth0 du port 25 (au lieu de l'interface locale loopback), &lt;br /&gt;
alors on ne peut pas se connecter au serveur en localhost ('''nc localhost 25''') mais depuis l'extérieur de la VM ('''nc localhost 193.48.57.164 25''').&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Créer l'architecture de répertoires MAILDIR et le fichier carte.txt à lancer en argument avec -u,&lt;br /&gt;
Tester tout ça une fois que ma VM est en ligne.&lt;br /&gt;
&lt;br /&gt;
Comment me reconnecter à ma VM ? ssh ?&lt;br /&gt;
&lt;br /&gt;
nc 193.48.57.164 25&lt;br /&gt;
RCPT TO : jean@lamentable.site&lt;br /&gt;
&lt;br /&gt;
== 7) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61761</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61761"/>
				<updated>2023-06-13T11:34:28Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 5) Tester les limites de SMTPin */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A faire ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent ne pas être chiffrées, les communications non chiffrés sont reçues sur le port 25 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*ne doivent être stockés que les courriels à destination d’un utilisateur local ;&amp;lt;br&amp;gt;&lt;br /&gt;
*le processus de remise stocke le message dans le sous-répertoire Maildir/tmp puis le déplace dans le sous-répertoire Maildir/new, déplacement doit être fait par la primitive rename ;&amp;lt;br&amp;gt;&lt;br /&gt;
*pour assurer un nom unique aux fichiers de stockage, utilisez la date en seconde (fonction time), le PID et un compteur commun à tous les flux d’exécution (utilisation de sémaphores indispensable).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== 1) Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; =&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== 2) Modifications SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; =&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: goudale@lamentable.site&lt;br /&gt;
  RCPT TO: jerome.breuvart@polytech-lille.net&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Il faut appuyer 2 fois sur QUIT pour quitter le serveur -- to debug ???&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Comment exécuter SMTPout ? ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'apperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs.&lt;br /&gt;
&lt;br /&gt;
On doit aussi écrire une carte utilisateur pour que le fonctionne.&lt;br /&gt;
&lt;br /&gt;
Puisqu'on exécute le serveur SMTPout sur l'interface eth0 du port 25 (au lieu de l'interface locale loopback), &lt;br /&gt;
alors on ne peut pas se connecter au serveur en localhost ('''nc localhost 25''') mais depuis l'extérieur de la VM ('''nc localhost 193.48.57.164 25''').&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Créer l'architecture de répertoires MAILDIR et le fichier carte.txt à lancer en argument avec -u,&lt;br /&gt;
Tester tout ça une fois que ma VM est en ligne.&lt;br /&gt;
&lt;br /&gt;
Comment me reconnecter à ma VM ? ssh ?&lt;br /&gt;
&lt;br /&gt;
nc 193.48.57.164 25&lt;br /&gt;
RCPT TO : jean@lamentable.site&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 7) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61760</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61760"/>
				<updated>2023-06-13T11:34:13Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 5) Tester les limites de SMTPin */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A faire ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent ne pas être chiffrées, les communications non chiffrés sont reçues sur le port 25 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*ne doivent être stockés que les courriels à destination d’un utilisateur local ;&amp;lt;br&amp;gt;&lt;br /&gt;
*le processus de remise stocke le message dans le sous-répertoire Maildir/tmp puis le déplace dans le sous-répertoire Maildir/new, déplacement doit être fait par la primitive rename ;&amp;lt;br&amp;gt;&lt;br /&gt;
*pour assurer un nom unique aux fichiers de stockage, utilisez la date en seconde (fonction time), le PID et un compteur commun à tous les flux d’exécution (utilisation de sémaphores indispensable).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== 1) Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; =&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== 2) Modifications SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; =&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: goudale@lamentable.site&lt;br /&gt;
  RCPT TO: jerome.breuvart@polytech-lille.net&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	  nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
      done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Il faut appuyer 2 fois sur QUIT pour quitter le serveur -- to debug ???&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Comment exécuter SMTPout ? ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'apperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs.&lt;br /&gt;
&lt;br /&gt;
On doit aussi écrire une carte utilisateur pour que le fonctionne.&lt;br /&gt;
&lt;br /&gt;
Puisqu'on exécute le serveur SMTPout sur l'interface eth0 du port 25 (au lieu de l'interface locale loopback), &lt;br /&gt;
alors on ne peut pas se connecter au serveur en localhost ('''nc localhost 25''') mais depuis l'extérieur de la VM ('''nc localhost 193.48.57.164 25''').&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Créer l'architecture de répertoires MAILDIR et le fichier carte.txt à lancer en argument avec -u,&lt;br /&gt;
Tester tout ça une fois que ma VM est en ligne.&lt;br /&gt;
&lt;br /&gt;
Comment me reconnecter à ma VM ? ssh ?&lt;br /&gt;
&lt;br /&gt;
nc 193.48.57.164 25&lt;br /&gt;
RCPT TO : jean@lamentable.site&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 7) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	<entry>
		<id>https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61759</id>
		<title>PSR SE2a4 2022/2023 G2</title>
		<link rel="alternate" type="text/html" href="https://wiki-ima.plil.fr/mediawiki//index.php?title=PSR_SE2a4_2022/2023_G2&amp;diff=61759"/>
				<updated>2023-06-13T11:33:37Z</updated>
		
		<summary type="html">&lt;p&gt;Jbreuvar : /* 5) Tester les limites de SMTPin */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== A faire ==&lt;br /&gt;
*un système doit être réalisé permettant au serveur SMTP sortant de mettre en file d’attente les messages non remis à destination pour cause d’erreur transitoire du serveur SMTP cible;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent ne pas être chiffrées, les communications non chiffrés sont reçues sur le port 25 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*les communications peuvent être chiffrées par TLS, les communication chiffrées peuvent être négociées directement sur le port 465 ;&amp;lt;br&amp;gt;&lt;br /&gt;
*il doit être possible de basculer sur une communication chiffrée à partir du port 25 en utilisant les commandes EHLO et STARTTLS ;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*ne doivent être stockés que les courriels à destination d’un utilisateur local ;&amp;lt;br&amp;gt;&lt;br /&gt;
*le processus de remise stocke le message dans le sous-répertoire Maildir/tmp puis le déplace dans le sous-répertoire Maildir/new, déplacement doit être fait par la primitive rename ;&amp;lt;br&amp;gt;&lt;br /&gt;
*pour assurer un nom unique aux fichiers de stockage, utilisez la date en seconde (fonction time), le PID et un compteur commun à tous les flux d’exécution (utilisation de sémaphores indispensable).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Commandes sur la VM ==&lt;br /&gt;
&lt;br /&gt;
*Se connecter au serveur : '''ssh root@capbreton.plil.info''' (glopglop)&lt;br /&gt;
*Se connecter à la VM : '''ssh root@193.48.57.164''' (glopglopglop)&lt;br /&gt;
*Copier le projet dans la VM (à la racine) : '''scp - r LisaJerome/ root@193.48.57.164:/'''&lt;br /&gt;
*Ouvrir le terminal en mode root : &amp;quot;su -&amp;quot; et vérifier si le port 25 est déjà occupé : '''ss -tpln'''&lt;br /&gt;
*Arrêter le processus exim4 (qui utilise le port 25) : '''service exim4 stop''' (ou kill pid)&lt;br /&gt;
*Compiler le projet (à la racine du projet) : '''make clean''' + '''make debug''' pour afficher les ifdef DEVERMINE&lt;br /&gt;
&lt;br /&gt;
*SMTPin (serveur d'envoi de mail)&lt;br /&gt;
**Exécuter SMTPin sur l'interface loopback du port 25 avec strace '''strace ./SMTPin -l -j &amp;lt;logfile.txt&amp;gt;''' et s'y connecter en local '''nc localhost 25'''&lt;br /&gt;
*SMTPout (serveur de réception de mail)&lt;br /&gt;
**Exécuter SMTPout sur l'interface eth0 du port 25 '''strace ./SMTPout -i eth0 -u &amp;lt;carte.txt&amp;gt;''' et s'y connecter '''nc 193.48.57.164 25'''&lt;br /&gt;
&lt;br /&gt;
== 1) Debug SMTPin==&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;mx.c&amp;quot; ne sert à rien (il est vide d'ailleurs), la fonction &amp;quot;**chercherMX&amp;quot; est implémentée dans &amp;quot;libs/Reseau/mx.c&amp;quot;, on peut donc le supprimer.&lt;br /&gt;
&lt;br /&gt;
*&amp;quot;in.c&amp;quot; =&amp;gt; &amp;quot;gestionCourriel()&amp;quot;, une fois les enregistrements DNS de type MX (serveurs courriel) trouvés, on doit envoyer le courriel au MX qui a la priorité la plus basse, si l'envoi échoue on retente avec le MX de priorité suivante jusqu'à ce que l'envoi soit un succès. Pourtant, dans le code, si l'envoi est un succès, on continue d'envoyer le mail aux autres MX, il faut donc rajouter l'instruction else{break;} dans le code lorsque l'envoi est un succès.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  while(*p!=NULL){&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;Serveur : %s\n&amp;quot;,*p);&lt;br /&gt;
    #endif&lt;br /&gt;
    int ss=connexionServeur(*p,SMTP_PORT_DEFAULT);&lt;br /&gt;
    FILE *dialogue=fdopen(ss,&amp;quot;a+&amp;quot;);&lt;br /&gt;
    if(dialogue==NULL){&lt;br /&gt;
      perror(&amp;quot;gestionCourriel.fdopen&amp;quot;);&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
    char erreur[MAX_ERREUR];&lt;br /&gt;
    int resultat=SMTP_dialogue(dialogue,donnees,erreur,MAX_ERREUR);&lt;br /&gt;
    fclose(dialogue);&lt;br /&gt;
    if(resultat&amp;lt;0) ecritureJournal(JOURNIV_DEVERMINE,JOURNAL_MXHS,*p);&lt;br /&gt;
    // Logguer l'erreur&lt;br /&gt;
    '''else{break;}'''&lt;br /&gt;
    p++;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== 2) Modifications SMTPout ==&lt;br /&gt;
&lt;br /&gt;
*On doit stocker les courriels dans la structure de répertoire MAILDIR, composée de 3 sous-répertoires : tmp, new et cur. Le processus qui récupère les courriels place les courriels dans le répertoire tmp, le nom du fichier est généré automatiquement de manière à être unique. Une fois le message complètement reçu par le serveur de courriel (MTA), il est déplacé, par un système de link/unlink dans le répertoire new. Au passage du client de messagerie qui parcourt le répertoire new, il est à nouveau déplacé et est mis dans le répertoire cur. Le message n'a toujours pas été lu.&amp;lt;br&amp;gt;&lt;br /&gt;
*&amp;quot;outc.c&amp;quot; =&amp;gt; &amp;quot;gestionCourriel&amp;quot;, on déplace le sous-répertoire Maildir/tmp dans le sous-repertoire Maildir/new en utilisant la primitive rename&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char fichier[MAX_CHEMIN];&lt;br /&gt;
  sprintf(fichier,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_TMP,time(NULL),pid,messages);&lt;br /&gt;
  FILE *f=fopen(fichier,&amp;quot;w&amp;quot;);&lt;br /&gt;
  if(f==NULL){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_OUVERTURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  int nb=fwrite(donnees-&amp;gt;corps,donnees-&amp;gt;taille,1,f);&lt;br /&gt;
  if(nb!=1){&lt;br /&gt;
    ecritureJournal(JOURNIV_ERREUR,JOURNAL_ECRITURE,fichier);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  fclose(f);&lt;br /&gt;
  '''char fichier_new[MAX_CHEMIN];'''&lt;br /&gt;
  '''sprintf(fichier_new,&amp;quot;%s/%s/%s/%ld_%010d_%010ld&amp;quot;,dossier,id,MAILDIR_NEW,time(NULL),pid,messages);'''&lt;br /&gt;
  '''rename(fichier, fichier_new);'''&lt;br /&gt;
&lt;br /&gt;
== 3) Exécuter les 2 serveurs sur une interface différente du port réseau 25 ==&lt;br /&gt;
&lt;br /&gt;
Après avoir démarré notre VM (routable sur internet) sur le serveur capbreton.plil.info et y avoir copié le prog, on s'aperçoit qu'il n'est pas possible de lancer les 2 serveurs SMTPin et SMTPout en même temps car les 2 s'exécutent sur la même interface (loopback) du port 25. Il faut donc lancer les serveurs sur des interfaces diff (SMTPout : eth0, SMTPin : loopback).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout(args.h) =&amp;gt; ajout d'une variable &amp;quot;interface&amp;quot; à la structure &amp;quot;stmp_config&lt;br /&gt;
&lt;br /&gt;
 struct smtp_config&lt;br /&gt;
  {&lt;br /&gt;
    char journal[CONFIG_MAX_JOURNAL];&lt;br /&gt;
    int niveau;&lt;br /&gt;
    char port[CONFIG_MAX_PORT];&lt;br /&gt;
    char dossier[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    char carte[CONFIG_MAX_CHEMIN];&lt;br /&gt;
    unsigned char local;&lt;br /&gt;
    '''char interface[CONFIG_MAX_INTERFACE];'''&lt;br /&gt;
  };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (args.c) =&amp;gt; ajout d'un case i &amp;quot;interface&amp;quot; dans le switch &lt;br /&gt;
&lt;br /&gt;
 static struct option long_options[] = {&lt;br /&gt;
    {&amp;quot;local&amp;quot;,no_argument,0,'l'},&lt;br /&gt;
    '''{&amp;quot;interfaces&amp;quot;, required_argument,0, 'i'},'''&lt;br /&gt;
    {&amp;quot;port&amp;quot;,required_argument,0,'p'},&lt;br /&gt;
    {&amp;quot;journal&amp;quot;,required_argument,0,'j'},&lt;br /&gt;
    {&amp;quot;niveau&amp;quot;,required_argument,0,'n'},&lt;br /&gt;
    {&amp;quot;dossier&amp;quot;,required_argument,0,'d'},&lt;br /&gt;
    {&amp;quot;utilisateurs&amp;quot;,required_argument,0,'u'},&lt;br /&gt;
    {0,0,0,0}&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    '''int c=getopt_long(argc,argv,&amp;quot;lp:j:n:d:u:i:&amp;quot;,long_options,NULL);'''&lt;br /&gt;
    if(c&amp;lt;0) break;&lt;br /&gt;
    switch(c){&lt;br /&gt;
      case 'l':&lt;br /&gt;
        config-&amp;gt;local=1;&lt;br /&gt;
        break;&lt;br /&gt;
      '''case 'i':'''&lt;br /&gt;
      '''strncpy(config-&amp;gt;interface,optarg,sizeof(config-&amp;gt;interface)-1);'''&lt;br /&gt;
      '''break;'''&lt;br /&gt;
      case 'p':&lt;br /&gt;
        strncpy(config-&amp;gt;port,optarg,sizeof(config-&amp;gt;port)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'j':&lt;br /&gt;
        strncpy(config-&amp;gt;journal,optarg,sizeof(config-&amp;gt;journal)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'd':&lt;br /&gt;
        strncpy(config-&amp;gt;dossier,optarg,sizeof(config-&amp;gt;dossier)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'u':&lt;br /&gt;
        strncpy(config-&amp;gt;carte,optarg,sizeof(config-&amp;gt;carte)-1);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'n':&lt;br /&gt;
        config-&amp;gt;niveau=atoi(optarg);&lt;br /&gt;
        break;&lt;br /&gt;
      default:&lt;br /&gt;
        afficheSyntaxe(argv[0]);&lt;br /&gt;
        break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*SMPTout (out.c) ==&amp;gt; main function =&amp;gt; récupérer l'interface passée en paramètre&lt;br /&gt;
&lt;br /&gt;
  char *interface=NULL;&lt;br /&gt;
  struct smtp_config config;&lt;br /&gt;
  analyseArguments(argc,argv,&amp;amp;config);&lt;br /&gt;
  if(config.journal[0]!='\0') creationJournal(config.journal);&lt;br /&gt;
  niveauJournal(config.niveau);&lt;br /&gt;
  ecritureJournal(JOURNIV_INFO,JOURNAL_DEBUT);&lt;br /&gt;
  if(config.port[0]=='\0') strcpy(config.port,SMTP_PORT_DEFAULT);&lt;br /&gt;
  if(config.local==1) interface=SMTP_LOCAL_INTERFACE;&lt;br /&gt;
  '''if(config.interface!=NULL) interface=config.interface;'''&lt;br /&gt;
&lt;br /&gt;
== 4) Debug SMTPin -&amp;gt; envoyer les mails ==&lt;br /&gt;
&lt;br /&gt;
Malgré le fait qu'on ait trouvé le serveur sur lequel envoyer notre mail et qu'on se soit bien connecté à celui-ci via socket grâce à la fonction &amp;quot;connexionserveur&amp;quot; dans &amp;quot;/libs/Reseau/reseau.c, on remarque que les mails ne s'envoient pas. On debug donc l'envoi du message.&lt;br /&gt;
&lt;br /&gt;
*libs/SMTP/smtp.c -&amp;gt; ajout DEBUG :&lt;br /&gt;
&lt;br /&gt;
  static int retour_generique(FILE *dialogue,int succes,char *erreur,int taille){&lt;br /&gt;
    char ligne[MAX_LIGNE];&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;SMTP -&amp;gt; retour generique\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    if(fgets(ligne,MAX_LIGNE,dialogue)==NULL) return -1;&lt;br /&gt;
    ligne[MAX_LIGNE-1]='\0';&lt;br /&gt;
    int code;&lt;br /&gt;
    int statut=sscanf(ligne,&amp;quot;%d&amp;quot;,&amp;amp;code);&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;statut =%d\n&amp;quot;, statut);'''&lt;br /&gt;
      '''printf(&amp;quot;succes =%d\n&amp;quot;, succes);'''&lt;br /&gt;
      '''printf(&amp;quot;code =%d\n&amp;quot;, code);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(statut==1 &amp;amp;&amp;amp; code!=succes){&lt;br /&gt;
      strncpy(erreur,ligne,taille-1);&lt;br /&gt;
    #ifdef DEVERMINE&lt;br /&gt;
      printf(&amp;quot;retour_generique ERROR\n&amp;quot;);&lt;br /&gt;
    #endif&lt;br /&gt;
    }&lt;br /&gt;
  return (statut==1 &amp;amp;&amp;amp; code==succes)?0:-1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Ce qui nous donne les informations de debug suivantes:&lt;br /&gt;
&lt;br /&gt;
  #0 [50/woody.escaut.net]&lt;br /&gt;
  Serveur : woody.escaut.net&lt;br /&gt;
  SMTP -&amp;gt; dialogue_connexion&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =220&lt;br /&gt;
  SMTP -&amp;gt; dialogue_HELO&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_MAIL&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_RCPT&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =250&lt;br /&gt;
  SMTP -&amp;gt; dialogue_DATA&lt;br /&gt;
    SMTP -&amp;gt; retour generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =250&lt;br /&gt;
    code =354&lt;br /&gt;
  SMTP -&amp;gt; dialogue_QUIT&lt;br /&gt;
    SMTP -&amp;gt; retour_generique&lt;br /&gt;
    statut =1&lt;br /&gt;
    succes =221&lt;br /&gt;
    code =250&lt;br /&gt;
&lt;br /&gt;
On remarque donc que la fonction &amp;quot;dialogue_connexion&amp;quot; attend un code de succès 220 au lieu de 250, &amp;quot;dialogue_DATA&amp;quot; 354 au lieu de 250 et &amp;quot;dialogue_QUIT&amp;quot; 250 au lieu de 221.&lt;br /&gt;
&lt;br /&gt;
*On modifie alors les valeurs des variables globales définies dans &amp;quot;smtp_private.h&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  #define ACCUEIL_CODE            '''220'''&lt;br /&gt;
  ...&lt;br /&gt;
  #define SUCCES_DATA_CODE        250&lt;br /&gt;
  #define SUCCES_DATA_TEXTE       &amp;quot;Accepted&amp;quot;&lt;br /&gt;
  #define SUCCES_QUIT_CODE        '''250'''&lt;br /&gt;
  #define SUCCES_QUIT_TEXTE       &amp;quot;Bye!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*ainsi que les noms des variables globales dans &amp;quot;smtp.c&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  static int dialogue_DATA(FILE *dialogue,char *corps,char *erreur,int taille){&lt;br /&gt;
    '''#ifdef DEVERMINE'''&lt;br /&gt;
      '''printf(&amp;quot;SMTP -&amp;gt; dialogue_DATA\n&amp;quot;);'''&lt;br /&gt;
    '''#endif'''&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;DATA\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,corps)&amp;lt;0) return -1;&lt;br /&gt;
    if(fprintf(dialogue,&amp;quot;.\r\n&amp;quot;)&amp;lt;0) return -1;&lt;br /&gt;
    return retour_generique(dialogue,'''CONTINUE_DATA_CODE''',erreur,taille);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Je réussis désormais à envoyer des mails sur @polytech_lille.net mais pas sur @gmail.com (le prob se situe au niveau des MX).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
+ modifier fgets dans libs/SMTP.c, gérer la gestion d'une commande à deux lignes : si présence d'un tiret dans la quatrième colonne, il faut prendre en compte la commande complète&lt;br /&gt;
&lt;br /&gt;
== 5) Tester les limites de SMTPin ==&lt;br /&gt;
&lt;br /&gt;
*Tester SMTPin avec des commandes (HELO, MAIL FROM, RCPT TO, DATA et QUIT) erronées et dans le mauvais ordre.&amp;lt;br&amp;gt;&lt;br /&gt;
**SMTPin est solide, il répond aux commandes erronées SYNTAX ERROR et &amp;quot;503 Need MAIL and RCPT first&amp;quot; si mauvais ordre des commandes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Effectuer un test de charge sur le serveur SMTPin en envoyant plusieurs mails en même temps :&lt;br /&gt;
**Pour cela se connecter au serveur en chargeant un fichier texte contenant les commandes SMTP à entrer au serveur : '''nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt''', voir test1.txt :&lt;br /&gt;
  HELO jj&lt;br /&gt;
  MAIL FROM: goudale@lamentable.site&lt;br /&gt;
  RCPT TO: jerome.breuvart@polytech-lille.net&lt;br /&gt;
  DATA&lt;br /&gt;
  SUBJECT Bonjour&lt;br /&gt;
  Hi&lt;br /&gt;
  Hola&lt;br /&gt;
  .&lt;br /&gt;
  QUIT&lt;br /&gt;
&lt;br /&gt;
**Ecrire un script shell qui exécute cette commande plusieurs fois en tâche de fond (avec &amp;amp;), cela nous permet de tester les threads:&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  for((i=1; i&amp;lt;=10; i++))&lt;br /&gt;
      do&lt;br /&gt;
          echo &amp;quot;Exec $i&amp;quot;&lt;br /&gt;
	      nc -i1 -q0 -C localhost 25 &amp;lt; test1.txt &amp;amp;&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Il faut appuyer 2 fois sur QUIT pour quitter le serveur -- to debug ???&lt;br /&gt;
&lt;br /&gt;
[[Fichier:LisaJerome.zip]]&lt;br /&gt;
&lt;br /&gt;
== 6) Comment exécuter SMTPout ? ==&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; gestionCourriel() -&amp;gt; on s'aperçoit que le serveur écrit le mail dans /tmp/&amp;lt;user&amp;gt;/tmp mais il ne le crée pas, il faut donc le créer manuellement.&lt;br /&gt;
&lt;br /&gt;
*out.c -&amp;gt; stockeInit() -&amp;gt; on s'apperçoit que le serveur a besoin d'une carte des utilisateur pour fonctionner, il faut donc exécuter le serveur avec cette carte contenant nos utilisateurs.&lt;br /&gt;
&lt;br /&gt;
On doit aussi écrire une carte utilisateur pour que le fonctionne.&lt;br /&gt;
&lt;br /&gt;
Puisqu'on exécute le serveur SMTPout sur l'interface eth0 du port 25 (au lieu de l'interface locale loopback), &lt;br /&gt;
alors on ne peut pas se connecter au serveur en localhost ('''nc localhost 25''') mais depuis l'extérieur de la VM ('''nc localhost 193.48.57.164 25''').&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Créer l'architecture de répertoires MAILDIR et le fichier carte.txt à lancer en argument avec -u,&lt;br /&gt;
Tester tout ça une fois que ma VM est en ligne.&lt;br /&gt;
&lt;br /&gt;
Comment me reconnecter à ma VM ? ssh ?&lt;br /&gt;
&lt;br /&gt;
nc 193.48.57.164 25&lt;br /&gt;
RCPT TO : jean@lamentable.site&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 7) Activer la connexion chiffrée avec le serveur ==&lt;br /&gt;
&lt;br /&gt;
*Télécharger la bibliothèque libssl -&amp;gt; '''apt-get update''' puis '''apt-get install libssl-dev'''.&lt;/div&gt;</summary>
		<author><name>Jbreuvar</name></author>	</entry>

	</feed>