PSR SE2a4 2022/2023 G6 : Différence entre versions

De Wiki d'activités IMA
Ligne 30 : Ligne 30 :
 
Le nouveau code reprend l'architecture globalement du code fourni, ils rassemblent juste les librairies dans une architecture descente sous src et utilise Meson.
 
Le nouveau code reprend l'architecture globalement du code fourni, ils rassemblent juste les librairies dans une architecture descente sous src et utilise Meson.
  
'''Création code''' Maildir/tmp -> réception message ('''MTAext.c''')<br/>
+
'''Création code''' <code> root@yamaha:~/SMTP/src# vim MTAint.c </code> -> réception message ('''MTAext.c''')<br/>
 
Pour générer un identifiant unique, on utilise la librairie <libuuid> : #include <uuid/uuid.h> <br/>
 
Pour générer un identifiant unique, on utilise la librairie <libuuid> : #include <uuid/uuid.h> <br/>
 
https://stackoverflow.com/questions/51053568/generating-a-random-uuid-in-c<br/>
 
https://stackoverflow.com/questions/51053568/generating-a-random-uuid-in-c<br/>
Ligne 185 : Ligne 185 :
  
 
</pre>
 
</pre>
Ici, on utilise une fonction conditionnelle pour informer que l'on n'est pas parvenu à compiler l'expression régulière et, en deuxième, qu'il n'y a pas de domaine destinataire.<br/>
+
Ici, on utilise plusieurs fonctions conditionnelles pour informer que l'on n'est pas parvenu à compiler l'expression régulière, qu'il n'y a pas de match (donc de domaine destinataire), qu'il n'y a pas de groupe (dans le domaine destinataire).<br/>

Version du 29 mars 2023 à 14:23

Infrastructure

Le serveur est disponible sur yamaha.germond.org (193.48.57.161), le DNS est hébergé sur l'infrastructure de @Bastien.Germond [1]

[1] https://github.com/BastienGermond/NixOs-config/blob/ecdf095a8ea55ed00d8b612dde74400cd11a444e/hosts/coral/data/dns/zones/germond.org.db.nix#L48

Architecture

Le projet est sous Meson ; pour compiler, on utilise la commande <meson compile -C build>

Comment récupérer un certificat avec Let's Encrypt ?

TODO

Premier pas

03/02/2023
Création VM : yamaha (IP : 193.48.57.161)
Lancement de la VM
Ouverture du projet beta
Découverte SMTPin


Réception message

10/02/2023
Réécriture du code

Le nouveau code reprend l'architecture globalement du code fourni, ils rassemblent juste les librairies dans une architecture descente sous src et utilise Meson.

Création code root@yamaha:~/SMTP/src# vim MTAint.c -> réception message (MTAext.c)
Pour générer un identifiant unique, on utilise la librairie <libuuid> : #include <uuid/uuid.h>
https://stackoverflow.com/questions/51053568/generating-a-random-uuid-in-c

int processing_mail(struct smtp_state *state){
    LOG_D("Processing mail...");
    
    uuid_t binuuid;// Unique ID in binary
    uuid_generate_random(binuuid);
    char *uuid = malloc(37);//Nb of characters for unique id
    uuid_unparse_lower(binuuid, uuid);//unique id en lettre minuscule

On définit ici un identifiant unique pour pouvoir suivre le mail envoyé (éviter toutes collisions ou perdition de données).

if(fptr == NULL){
    LOG_E("Couldn't open Maildir tmp");
    exit(1);
}

Ici, on utilise une fonction conditionnelle pour informer que l'on n'est pas parvenu à entrer dans le dossier de redirection de mail.

fprintf(fptr, "From: %s\r\n", state->sender); 
fprintf(fptr, "To: %s\r\n", state->recipient);
fprintf(fptr, "%s\r\n", state->body);
fclose(fptr);

On transforme les informations stockées dans la structure "state" en format de mail avec la source, le destinataire et le corps.

int server_process(int sfd) {
    return smtp_process(sfd, processing_mail);
}
int main(void) {
    log_init_default("-", LOG_DEBUG);

    int sock = init_server("yamaha.germond.org", "8025", NULL);

    if (sock < 0) {
        LOG_C("Failed to start server");
        return EXIT_FAILURE;
    }

    int status = loop_server(sock, server_process);

    if (status < 0) {
        LOG_E("MTAext: server closed unexpectedly");
    };

    return 0;
}

La fonction main permet d'initialiser et de lancer notre serveur <yamaha.germond.org> (récupérer l'adresse IPV4/V6) et d'informer des erreurs.

Test code MTAext.c : vérification
Le mail est composé d'une entête et d'un corps de mail
On lance la compilation du code puis l’exécutable ./build/MTAext
La connexion s'établit entre deux terminaux : celui de notre machine virtuelle

root@yamaha:~/SMTP# ./build/MTAext  
[DEBUG] Server opened on 2001:660:4401:60a0::100:0:8025
[DEBUG] loop_server: waiting for incomming connection
[DEBUG] loop_server: waiting for incomming connection
[DEBUG] loop_server: waiting for incomming connection

Et celui de la machine PC zabeth19

pifou@zabeth19:~$ telnet yamaha.germond.org 8025
Trying 2001:660:4401:60a0:216:3eff:fe63:515a...
Connected to yamaha.germond.org.
Escape character is '^]'.
250 Welcome

-> compilation/execution de réception de mails (envoyeur, receveur, corps de mail, UUID)
On envoi un mail depuis la machine zabeth19

pifou@zabeth19:~$ telnet yamaha.germond.org 8025
Trying 2001:660:4401:60a0:216:3eff:fe63:515a...
Connected to yamaha.germond.org.
Escape character is '^]'.
250 Welcome
HELO zabeth19
250 Hi!
MAIL FROM:<testreception@yamaha.germond.org>            
250 Sender recorded
RCPT TO:<receptiontest@yamaha.germond.org>
250 Target recorded
DATA 
Subject: Démonstration du bon fonctionnement de la réception

Avec ce mail nous voyons que nous arrivons à communiquer (envoyer d'une machine quelconque et recevoir sur notre serveur.

Et on le reçoit sur notre serveur root@yamaha

[DEBUG] loop_server: waiting for incomming connection
[DEBUG] smtp_process: incomming (cmd: HELO): HELO zabeth19
[DEBUG] _thread_main: process done, closing connection.
[DEBUG] smtp_process: incomming (cmd: MAIL): MAIL FROM:<testreception@yamaha.germond.org>
[DEBUG] smtp_process: incomming (cmd: RCPT): RCPT TO:<receptiontest@yamaha.germond.org>
[DEBUG] smtp_process: incomming (cmd: DATA): DATA
[DEBUG] Processing mail...
[DEBUG] Mail UUID 3a59c1ca-c52a-4af9-8b22-9e9beb1faf53
[DEBUG] Writing mails at /root/Maildir/tmp/3a59c1ca-c52a-4af9-8b22-9e9beb1faf53
[DEBUG] Move mails at /root/Maildir/new/3a59c1ca-c52a-4af9-8b22-9e9beb1faf53
[DEBUG] _thread_main: process done, closing connection.

Avec la commande <mutt>, on peut vérifier que le mail est bien parvenu jusqu'à notre serveur :

 
   1 N   Jan 01 testreception@y (0.1K) Démonstration du bon fonctionnement de la réception
   2     Jan 01 bastien@yamaha. (0.1K)
   3 O   Jan 01 bastien@yamaha. (0.1K) Test mail
   4     Jan 01 a@b.c           (0.1K)
   5     Jan 01 a@b.c           (0.1K)
   6     Jan 01 a@b.c           (0.1K)


Envoie message

Création code Maildir/tmp -> envoie message (MTAint.c)

Pour pouvoir utiliser les expressions régulières, on utilise la librairie <regex> : #include <regex.h>

 
int extract_domain_name(char *domain_name, size_t size) {
    char *regexString = "@(.+)";
    size_t maxMatches = 1;
    size_t maxGroups = 1;
    regex_t regexCompiled;
    regmatch_t groupArray[maxGroups];

On commence par créer une fonction d'extraction du nom de domaine qui prend en paramètre le nom du domaine et sa taille.
La forme char *regexString = "@(.+)"; est l'expression régulière nous permettant de récupérer le nom de domaine (tout ce qui ce situe après le "@"). Le site https://regex101.com/ nous permet de rentrer notre test string et une expression régulière et d'obtenir le match correspondant, soit, dans notre cas : @(.+).

 
if(regcomp(&regexCompiled, regexString, REG_EXTENDED)){
        LOG_D("Fail to compile regular expression.");
        return -1;
    }

if regexec(&regexCompiled, cursor, maxGroups, groupArray, 0)){
        LOG_D("There is no recipient domain.")
        return -1; // No match
    }

if(groupArray[0].rm_so == (size_t)-1){
        return -1; // No group in match
    }

Ici, on utilise plusieurs fonctions conditionnelles pour informer que l'on n'est pas parvenu à compiler l'expression régulière, qu'il n'y a pas de match (donc de domaine destinataire), qu'il n'y a pas de groupe (dans le domaine destinataire).