diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 0000000..c6b51a4 --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,2 @@ +pass +*.o diff --git a/src/Makefile b/src/Makefile index 2816c0f..60d202c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,7 +1,11 @@ -pass : pass.c pass.h - cc -Wall -D_REENTRANT -o pass pass.c -pthread +pass: pass.o chiffre.o + cc -o pass pass.o chiffre.o -pthread -clean: - rm -f pass +pass.o: pass.c pass.h + cc -c -Wall -D_REENTRANT pass.c +chiffre.o: chiffre.c chiffre.h + cc -c -Wall -D_REENTRANT chiffre.c +clean: + rm -f pass *.o diff --git a/src/chiffre.c b/src/chiffre.c new file mode 100644 index 0000000..b26bc96 --- /dev/null +++ b/src/chiffre.c @@ -0,0 +1,248 @@ +/* chiffre.c : Système simple de chiffrement d'octets inspiré de la méthode PlayFair */ + +#include +#include +#include +#include +#include + +#include "chiffre.h" + + +#ifdef XOR_SIMPLE +static long long CLE = 0xABCD1276FA8745EC; // clé simple de 64 bits + +/* Fonction de chiffrement avec xOR, en utilisant une clé fixe de 64 bits. */ +void chiffre_xor_simple(char *buf, int l) +{ + long long *debut, *fin; + debut = (long long*) buf; + fin = (long long*) (buf + l); + + /* Le chiffrement avec xOR */ + while (debut < fin) *debut++ ^= CLE; + +#ifdef TRACE_CH + if (ori == 0) { // le thread local -> distant + if (Chiff == 1) printf("Chiffrement l=%d vers %d !\n", l, ntohs(PORTD)); + else printf("Déchiffrement l=%d depuis %d !\n", l, ntohs(PORTL)); + } else { // le fils principal distant -> local + if (Chiff == 1) printf("Déchiffrement l=%d depuis %d !\n", l, ntohs(PORTD)); + else printf("Chiffrement l=%d vers %d !\n", l, ntohs(PORTL)); + } +#endif +} +#endif + +#ifdef XOR_FICHIER +static char *NFCLE = "/tmp/clepass"; // nom du fichier utilisé pour la clé +static char BCLE[LCLE]; // buffer contenant la clé + +/* Gestion des clés à partir d'un fichier externe. */ +int init_cle_xor_fichier(void) +{ + int fd; + + if ((fd = open(NFCLE, O_RDONLY)) == -1) return -1; + if (read(fd, BCLE, LCLE) != LCLE) return -1; + close(fd); + return 0; +} + +/* Fonction de chiffrement avec xOR, en utilisant une clé externe provenant d'un fichier. */ +void chiffre_xor_fichier(char *buf, int l) +{ + long long *debut, *fin, *cle, *fin_cle; + debut = (long long *) buf; + fin = (long long *) (buf + l); + cle = (long long *) BCLE; + fin_cle = (long long *)(BCLE + LCLE); + + /* Le chiffrement avec xOR */ + while (debut < fin) { + *debut++ ^= *cle++; // équivalent à *debut ^= *cle; debut++; cle++; + if (cle == fin_cle) cle = (long long *) BCLE; + } + +#ifdef TRACE_CH + if (ori == 0) { // le thread local -> distant + if (Chiff == 1) printf("Chiffrement l=%d vers %d !\n", l, ntohs(PORTD)); + else printf("Déchiffrement l=%d depuis %d !\n", l, ntohs(PORTL)); + } else { // le fils principal distant -> local + if (Chiff == 1) printf("Déchiffrement l=%d depuis %d !\n", l, ntohs(PORTD)); + else printf("Chiffrement l=%d vers %d !\n", l, ntohs(PORTL)); + } +#endif +} +#endif + +#ifdef PLAYFAIR +static char table_chiffre[NBO]; /* table des octets à chiffrer */ +static char table_bool[NBO] = {0}; /* table pour noter le remplissage des octets */ + +#ifdef DEBUG +/* Fonction qui affiche la table de chiffrement. */ +static void Trace(void) +{ + int i, j; + unsigned char c; + + fprintf(stderr, "Table de chiffrement:\n"); + + for (i = 0; i < LCM; i++) { + for (j = 0; j < LCM; j++) { + c = (unsigned char) table_chiffre[(i * LCM) + j]; + if ((c >= ' ') && (c <= '~')) fprintf(stderr, " %c ", c); + else fprintf(stderr, "%.2x ", c); + } + fprintf(stderr, "\n"); + } + + fprintf(stderr, "\n"); +} +#endif + +void init_table_chiffre(char *cle) /* on passe la clé en parametre */ +{ + /* initialisation de la table */ + int i, I = 0, j; + char c; + + for (i = 0; i < (int) strlen(cle); i++) { + c = cle[i]; + if (table_bool[(int) c]) continue; + table_chiffre[I++] = c; + table_bool[(int) c] = 1; + } + + /* + for (i = 0; i < NBO; i++) { + if (buf2[i]) continue; + buf[I++] = (char) i; + buf2[i] = 1; + } + */ + + for (j = 0; j < SAUT; j++) { + for (i = j; i < NBO; i += SAUT) { + if (table_bool[i]) continue; + table_chiffre[I++] = i; + table_bool[i] = 1; + } + } + +#ifdef DEBUG + Trace(); + for (i = 0; i < NBO; i++) { + if (table_bool[i]) continue; + fprintf(stderr, "Valeur %d non affectée !!\n", i); + } +#endif + +} + +/* Fonction qui définit les coordonnées d'un caractère à partir de sa position dans la table */ +static void coordCar(char C, int *l, int *c) +{ + int i; + + for (i = 0; i < NBO; i++) if (table_bool[i] == C) break; + + *c = i % LCM; + *l = i / LCM; +} + +/* Fonction qui retourne le caractère de la ligne l, colonne c */ +static char carLC(int l, int c) +{ + return(table_bool[(l * LCM) + c]); +} + +/* fonction qui chiffre directement dans le buffer des données à chiffrer */ +void chiffre_playfair(char *B, int T) // B adresse du buf, T le nb d'octets +{ + int i, l1, c1, l2, c2; + + for (i = 0; i < T; i += 2) { + if (i == T - 1) { /* cas particulier du dernier octet */ + coordCar(B[i], &l1, &c1); + l1 += 2; /* on descend de 2 lignes */ + if (l1 >= LCM) l1 -= LCM; + B[i] = carLC(l1, c1); + } else { /* cas du couple */ + coordCar(B[i], &l1, &c1); + coordCar(B[i + 1], &l2, &c2); + if (l1 == l2) { /* sur la même ligne */ + /* on décale vers le haut */ + l1--; + if (l1 < 0) l1 += LCM; + B[i] = carLC(l1, c1); + B[i + 1] = carLC(l1, c2); + } else if (c1 == c2) { /* sur la même colonne */ + /* on décale vers la droite */ + c1++; + if (c1 >= LCM) c1 -= LCM; + B[i] = carLC(l1, c1); + B[i + 1] = carLC(l2, c1); + } else { /* on a un rectangle */ + /* schéma + c1 c2 + + l1 x b + + + l2 a y + + On fait la permutation x, y => a, b + **************************************/ + B[i] = carLC(l2, c1); + B[i + 1] = carLC(l1, c2); + } + } + } +} + +/* Fonction inverse de chiffre_playfair, puisque cette fonction n'est pas involutive */ +void dechiffre_playfair(char *B, int T) // B adresse du buf, T le nb d'octets +{ + int i, l1, c1, l2, c2; + + for (i = 0; i < T; i += 2) { + if (i == T - 1) { /* cas particulier du dernier octet */ + coordCar(B[i], &l1, &c1); + l1 -= 2; /* on monte de 2 lignes */ + if (l1 < 0) l1 += LCM; + B[i] = carLC(l1, c1); + } else { /* cas du couple */ + coordCar(B[i], &l1, &c1); + coordCar(B[i + 1], &l2, &c2); + if (l1 == l2) { /* sur la même ligne */ + /* on décale vers le bas */ + l1++; + if (l1 >= LCM) l1 -= LCM; + B[i] = carLC(l1, c1); + B[i + 1] = carLC(l1, c2); + } else if (c1 == c2) { /* sur la même colonne */ + /* on décale vers la gauche */ + c1--; + if (c1 < 0) c1 += LCM; + B[i] = carLC(l1, c1); + B[i + 1] = carLC(l2, c1); + } else { /* on a un rectangle */ + /* schéma + c1 c2 + + l1 x b + + + l2 a y + + On fait la permutation x, y => a, b + **************************************/ + B[i] = carLC(l2, c1); + B[i + 1] = carLC(l1, c2); + } + } + } +} +#endif diff --git a/src/chiffre.h b/src/chiffre.h new file mode 100644 index 0000000..4be5b1a --- /dev/null +++ b/src/chiffre.h @@ -0,0 +1,46 @@ +/* chiffre.h : paramètres de chiffrement */ + +#ifndef CHIFFRE_H +#define CHIFFRE_H + +/* ********* + * OPTIONS * + * *********/ + +#define DEBUG // Pour afficher notamment la table de chiffrement + +/* Options pour choisir la méthode de chiffrement */ +// #define XOR_SIMPLE +// #define XOR_FICHIER +#define PLAYFAIR + +/* ******** */ + + +#ifdef XOR_SIMPLE +/* Fonction de chiffrement avec xOR, en utilisant une clé fixe de 64 bits. */ +extern void chiffre_xor_simple(char *buf, int l); +#endif + +#ifdef XOR_FICHIER +#define LCLE 8192 // longueur de la clé : 8ko = 65536 bits, ATTENTION, doit être un multiple de 8*n +/* Fonction qui initialise la clé à partir d'un fichier externe. */ +extern int init_cle_xor(void); +/* Fonction de chiffrement avec xOR, en utilisant une clé externe provenant d'un fichier. */ +extern void chiffre_xor_fichier(char *buf, int l); +#endif + +#ifdef PLAYFAIR +#define CLE_PLAYFAIR "e2l" +#define SAUT 29 // valeur du saut pour remplir le reste de la table +#define NBO 256 // nb d'octets +#define LCM 6 // Longueur du côté de la matrice + +/* Fonction qui initialise la table de chiffrement. */ +extern void init_table_chiffre(char *cle); +/* Fonction qui chiffre directement dans le buffer des données à chiffrer */ +extern void chiffre_playfair(char *B, int T); // B adresse du buf, T le nb d'octets +/* Fonction inverse de chiffre_playfair, puisque cette fonction n'est pas involutive */ +extern void dechiffre_playfair(char *B, int T); // B adresse du buf, T le nb d'octets +#endif +#endif diff --git a/src/pass.c b/src/pass.c index 25895c9..1635782 100644 --- a/src/pass.c +++ b/src/pass.c @@ -1,7 +1,9 @@ -/* notre passerelle TCP IPv4 */ +/* Notre passerrelle TCP IPv4 */ + #include #include #include +#include #include #include #include @@ -9,315 +11,348 @@ #include #include #include +#include #include #include -#include #include +#include "chiffre.h" #include "pass.h" -/* les variables globales */ -int RUN=1; /* Indice qui permet de stopper en le mettant a zero */ -int Chiff=0; /* =0 rien; =1 chiff. distant =-1 chiff. local */ -in_port_t PORTL, PORTD; /* au format du reseau !! */ -uint32_t ADDRD; /* adressse distante au format du reseau */ -long long CLE = 0xABCD1276FA8745EC; +/* Variables globales */ + +static int RUN = 1; // booléen pour la boucle d'acceptation +static int Chiff = 0; // valeur pour l'option de chiffrement, -1 pour local, 1 pour distant, 0 pour rien +static in_port_t PORTL, PORTD; // ports distant et local au format du réseau ! +static uint32_t ADDRD; // adresse distante au format réseau +static int SidLoc, SidDist; // variables globales des deux taches de transfert +/* Fonction qui agit en tant que handler pour signal() */ void interrupt(int S) { - switch(S) { - case SIGCHLD : - while (waitpid(-1,NULL,WNOHANG) != -1); - break; - case SIGINT: - case SIGTERM: - fprintf(stderr,"Arret de la passerelle !\n"); - exit(0); - default: - fprintf(stderr,"Recu signal %d !?!?\n",S); - } - return; + switch (S) { + case SIGCHLD: + while (waitpid(-1, NULL, WNOHANG) != -1); + break; + case SIGINT: + RUN = 0; + exit(EXIT_FAILURE); + break; + case SIGTERM: + fprintf(stderr, "Arret de la passerelle !\n"); + exit(0); + break; + default: + fprintf(stderr, "Reçu signal %d !?!\n", S); + break; + } } - -/* la structure sockaddr_in */ -struct sockaddr_in Sin = { AF_INET }; /* Le reste de egal à 0 !! */ - -/* fct qui fabrique un IP v4 au format reseau - exemple : makip4(127,0,0,1); */ -uint32_t makip4(int a, int b, int c, int d) +/* Fonction qui traduit une adresse IPv4 en chaîne de caractères xxx.xxx.xxx.xxx */ +char *adip(uint32_t A) { -uint32_t A; -char *p; - p = (char *)&A; - *p++ = (unsigned char)a; - *p++ = (unsigned char)b; - *p++ = (unsigned char)c; - *p = (unsigned char)d; - //return htonl(A); - return A; -} + // 255.255.255.255 par exemple = 15 char + '\0' = 16 + static char buffer[16]; -/* fct qui traduit une adresse IP V4 en chaine de caractere xxx.xxx.xxx.xxx */ -char * adip(uint32_t A) -{ -static char b[16]; - sprintf(b,"%d.%d.%d.%d", (int)((A>>24)& 0xFF), (int)((A>>16)& 0xFF), (int)((A>>8)& 0xFF), (int)(A & 0xFF)); - return b; -} + sprintf(buffer, "%d.%d.%d.%d", + (int) ((A>>24) & 0xFF), + (int) ((A>>16) & 0xFF), + (int) ((A>>8) & 0xFF), + (int) (A & 0xFF) + ); -int readNbc(int fd, char*b, int t) -{ -char * d; -int n, T=t; -#ifdef TRACESP - printf(" readNbc %d octets !\n",t); -#endif - d=b; - while(T>0) { - if ((n=read(fd,d,T)) == -1) return -1; - d+=n; - T-=n; - } - return 0; + return buffer; } -int SidLoc, SidDist; /* variables globales des 2 taches de transfert */ - -/* gestion des cles a partir d'un fichier externe */ -char *NFCLE="/tmp/clepass"; -/* ATTENTION choisir LCLE tel que = 8*n !!! */ -#define LCLE 8192 /* 8 ko => cle de 65536 bits !! */ -char BCLE[LCLE]; /* buffer contenant la cle */ - -/* on suppose dans tout le code que la fct de chiffrement est telle que -fchiffre(fchiffre(buf)) = buf !! autrement dit qu'elle est involutive ! */ -void fchiffre2(char * b, int l, int ori) /* travaille avec BCLE */ +/* Fontion qui fabrique un IPv4 au format réseau */ +uint32_t makeip4(int a, int b, int c, int d) { -long long *d, *f, *c, *fc; - d=(long long*)b; - f=(long long*)(b+l); - c=(long long *)BCLE; - fc=(long long *)(BCLE+LCLE); - /* le chiffrement avec xor */ - while (d D */ - if (Chiff==1) printf("Chiffrement l=%d vers %d !\n",l,ntohs(PORTD)); - else printf("Dechiffrement l=%d depuis %d !\n",l,ntohs(PORTL)); - } else { /* le fils D -> L */ - if (Chiff==1) printf("Dechiffrement l=%d depuis %d !\n",l,ntohs(PORTD)); - else printf("Chiffrement l=%d vers %d !\n",l,ntohs(PORTL)); - } + char *debut; + int n, T = taille; + +#ifdef TRACE_SP + printf("readNbc %d octets !\n", taille); #endif - return; /* pour l'instant ne fait rien !! */ + + debut = buffer; + while (T > 0) { + if ((n = read(fd, debut, T)) == -1) return -1; + debut += n; + T -= n; + } + return 0; } -/* la fonction du thread qui lit le port local et ecrit vers le port distant */ -void * fct_th(void * p) +/* Fonction du thread qui lit le port local et écrit vers le port distant */ +void *fct_th(void *p) { -int n; -uint16_t lb; -char buf[LBUF]; - /* on s'occupe du transfert L -> D */ + int n; + uint16_t lb; + char buf[LBUF]; + + /* On s'occupe du transfert local -> distant */ while (1) { - /* lecture cote LOCAL */ - if (Chiff == -1) { /* chiffrement cote local */ - if (read(SidLoc,&lb,2)!=2) n=-1; - else { - n = (int)ntohs(lb); - if (readNbc(SidLoc,buf,n) == -1) n=-1; - fchiffre2(buf,n,0); - } - } else - n=read(SidLoc,buf,LBUF); + /* Lecture côté local */ + if (Chiff == -1) { // chiffrement côté local + if (read(SidLoc, &lb, sizeof(lb)) != sizeof(lb)) n = -1; + else { + n = (int) ntohs(lb); + if (readNbc(SidLoc, buf, n) == -1) n = -1; +#ifdef XOR_SIMPLE + chiffre_xor_simple(buf, n); +#endif +#ifdef XOR_FICHIER + chiffre_xor_fichier(buf, n); +#endif +#ifdef PLAYFAIR + chiffre_playfair(buf, n); +#endif + } + } else n = read(SidLoc, buf, LBUF); if (n > 0) { - /* ecriture cote DISTANT */ - if (Chiff == 1) { -#ifdef TRACESP - printf(" writeNbc %d octets !\n",n); + /* Ecriture côté distant */ + if (Chiff == 1) { +#ifdef TRACE_SP + printf("writeNbc %d octets !\n", n); #endif - fchiffre2(buf,n,0); - lb = htons((uint16_t)n); - write(SidDist,&lb,2); /* on envoie le nb d'octets du paquet */ - } - write(SidDist,buf,n); +#ifdef XOR_SIMPLE + chiffre_xor_simple(buf, n); +#endif +#ifdef XOR_FICHIER + chiffre_xor_fichier(buf, n); +#endif +#ifdef PLAYFAIR + dechiffre_playfair(buf, n); +#endif + lb = htons((uint16_t) n); + write(SidDist, &lb, sizeof(lb)); // On envoie le nombre d'octets du paquet + } + write(SidDist, buf, n); } - if (n==-1) break; + if (n == -1) break; } + return NULL; } - -int liaison(int fd) /* il faut creer la passerelle pour le client */ +/* Création de la passerelle pour le client */ +int liaison(int fd) { -int sid,n ; -uint16_t lb; -struct sockaddr_in Sin = { AF_INET }; -pthread_t thid; -char buf[LBUF]; - /* on est dans le cas du client qui veut se connecter au serveur */ - /* fabrication de l'interface reseau en IP V4 */ - SidLoc = fd; /* pour que le thread l'utilise */ - if ((sid = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == -1) { - perror("socket"); return 1; + int sid, n; + uint16_t lb; + struct sockaddr_in Sin; + pthread_t thid; + char buf[LBUF]; + + /* On est dans le cas du client qui veut se connecter au serveur */ + + /* Fabrication de l'interface réseau en IPv4 */ + SidLoc = fd; // pour que le thread l'utilise + if ((sid = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { + perror("socket"); + return 1; } + + Sin.sin_family = AF_INET; Sin.sin_port = PORTD; Sin.sin_addr.s_addr = ADDRD; - /* on fait la connexion */ - if (connect(sid, (struct sockaddr*)&Sin, sizeof(Sin)) < 0) { - perror("connect"); return 2; + + /* On fait la connexion */ + if (connect(sid, (struct sockaddr *) &Sin, sizeof(Sin)) == -1) { + perror("connect"); + return 2; } - /* on masque le signal SIGPIPE */ - signal(SIGPIPE,SIG_IGN); - /* la connexion est faite ! */ - SidDist = sid; /* pour que le thread l'utilise */ - /* creation du thread qui va se charger du transfert L -> D */ - if (pthread_create(&thid,NULL,fct_th,NULL) !=0) { - fprintf(stderr,"Erreur creation thread !\n"); - close(fd); - close(sid); - return 3; + + /* On masque le signal SIGPIPE */ + signal(SIGPIPE, SIG_IGN); + + /* La connexion est faite ! */ + SidDist = sid; // pour que le thread l'utilise + + /* Création du thread qui va se charger du transfert local vers distant */ + if (pthread_create(&thid, NULL, fct_th, NULL) != 0) { + fprintf(stderr, "Erreur création thread !\n"); + close(fd); + close(sid); + return 3; } - /* on s'occupe du transfert D -> L */ + + /* On s'occupe du transfert distant -> local */ while (1) { - if (Chiff == 1) { /* chiffrement cote distant */ - if (read(sid,&lb,2)!=2) n=-1; - else { - n = (int)ntohs(lb); - if (readNbc(sid,buf,n) == -1) n=-1; - fchiffre2(buf,n,0); - } - } else n=read(sid,buf,LBUF); + if (Chiff == 1) { // chiffrement côté distant + if (read(sid, &lb, sizeof(lb)) != sizeof(lb)) n = -1; + else { + n = (int) ntohs(lb); + if (readNbc(sid, buf, n) == -1) n = -1; +#ifdef XOR_SIMPLE + chiffre_xor_simple(buf, n); +#endif +#ifdef XOR_FICHIER + chiffre_xor_fichier(buf, n); +#endif +#ifdef PLAYFAIR + dechiffre_playfair(buf, n); +#endif + } + } else n = read(sid, buf, LBUF); if (n > 0) { - if (Chiff==-1) { -#ifdef TRACESP - printf(" writeNbc %d octets !\n",n); + if (Chiff == -1) { +#ifdef TRACE_SP + printf("writeNbc %d octets !\n", n); +#endif +#ifdef XOR_SIMPLE + chiffre_xor_simple(buf, n); +#endif +#ifdef XOR_FICHIER + chiffre_xor_fichier(buf, n); +#endif +#ifdef PLAYFAIR + chiffre_playfair(buf, n); #endif - fchiffre2(buf,n,1); - lb = htons((uint16_t)n); - write(fd,&lb,2); /* on envoie le nb d'octets du paquet */ - } - write(fd,buf,n); + lb = htons((uint16_t) n); + write(fd, &lb, sizeof(lb)); + } + write(fd, buf, n); } - if (n==-1) break; + if (n == -1) break; } + close(fd); + return 0; } -void finerr(char * N, int err) +/* Message d'aide pour l'utilisateur */ +void finerr(char *N, int err) { - fprintf(stderr,"%s : version %s\n",N,Version); - fprintf(stderr,"Utilisation : %s -d|-l|-s port_local nom_ou_ip_serveur port_distant !\n",N); + fprintf(stderr, "%s : version %s\n", N, Version); + fprintf(stderr, "Utilisation : %s -d|-l|-s port_local nom_ou_ip_serveur port_distant\n", N); exit(err); } int main(int N, char *P[]) { -int sid, newsid, err; /* socket id = file descriptor */ -struct sockaddr_in Srec; -struct hostent *h; -pid_t pid; -long lg; - - signal(SIGCHLD,interrupt); - signal(SIGINT,interrupt); - signal(SIGTERM,interrupt); - if (initCle()) { - fprintf(stderr,"Erreur lecture ficher cle %s !!\n", NFCLE); - return 1; + int sid, new_sid, err; // socket id = file descriptor + struct sockaddr_in Sin, Srec; + struct hostent *host; + pid_t pid; + long lg; + + /* Récupération des éventuels signaux qu'on pourrait recevoir, et appel de la fonction interrupt() */ + signal(SIGCHLD, interrupt); + signal(SIGINT, interrupt); + signal(SIGTERM, interrupt); + +#ifdef XOR_FICHIER + if (init_cle_xor_fichier()) { + fprintf(stderr, "Erreur lecture fichier clé : '%s' !\n", NFCLE); + return 1; } - /* verification que l'on a bien 4 parametres et seult 4 ! */ - if (N != 5) finerr(P[0],1); - /* verification du 1er parametres */ - if (P[1][0] != '-') finerr(P[0],2); - if (strlen(P[1]) != 2) finerr(P[0],2); - switch(P[1][1]) { - case 'l': - Chiff = -1; - break; - case 'd': - Chiff = 1; - break; - case 's': - Chiff = 0; - break; - default : - finerr(P[0],2); +#endif +#ifdef PLAYFAIR + init_table_chiffre(CLE_PLAYFAIR); +#endif + + /* Vérification que l'on a bien 4 paramètres et seulement 4 */ + if (N != 5) finerr(P[0], 1); + + /* Vérification du 1er paramètre */ + if (P[1][0] != '-') finerr(P[0], 1); + if (strlen(P[1]) != 2) finerr(P[0], 2); + switch (P[1][1]) { + case 'l': + Chiff = -1; + break; + case 'd': + Chiff = 1; + break; + case 's': + Chiff = 0; + break; + default: + finerr(P[0], 2); + break; } - PORTL = htons(atoi(P[2])); - PORTD = htons(atoi(P[4])); - if ((h=gethostbyname(P[3])) == NULL) { - fprintf(stderr,"Erreur gethostbyname no %d !\n",h_errno); - return 2; + + PORTL = htons(atoi(P[2])); + PORTD = htons(atoi(P[4])); + + /* Récuperation de l'adresse */ + if ((host = gethostbyname(P[3])) == NULL) { + fprintf(stderr, "Erreur gethostbyname no %d !\n", h_errno); + return 2; } - bcopy((void*)(h->h_addr),(void*)(&ADDRD),h->h_length); + bcopy((void*) (host->h_addr), (void*) (&ADDRD), host->h_length); - /* fabrication de l'interface reseau en IP V4 */ - if ((sid = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == -1) { - perror("socket"); return 5; + /* Fabrication de l'interface réseau en IPv4 */ + if ((sid = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { + perror("socket"); + return 5; } - /* initialiser la structure sockaddr_in pour dire quel port on veut */ + + Sin.sin_family = AF_INET; Sin.sin_port = PORTL; - /* Sin.sin_addr.s_addr = makip4(127,0,0,1); */ - Sin.sin_addr.s_addr = makip4(0,0,0,0); - /* puis faire un bind() pour s'attacher a ce port */ - if (bind(sid,(struct sockaddr *)&Sin,sizeof(Sin)) == -1) { - perror("bind"); return 3; + Sin.sin_addr.s_addr = makeip4(0, 0, 0, 0); + // Sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + /* Puis faire un bind() pour s'attacher à ce port */ + /* La fonction bind est une fonction unique, aveugle à la structure qui va envoyer les données. Elle ne se soucie + * pas de savoir si on va communiquer en IPv4 ou IPv6 par exemple. + * La fonction bind prend donc en fait une structure générique, sockaddr. Dans cette structure elle lit sa_family, + * qui lui indique qu'il s'agit d'IPv4. */ + /* Pour faire la conversion des struct on fait un cast. */ + if (bind(sid, (struct sockaddr *) &Sin, sizeof(Sin)) == -1) { + perror("bind"); + return 3; } - /* on definit le nombre d'ecoutes simultannees */ + /* On définit le nombre d'écoutes simultanées */ if (listen(sid, NBCLI) == -1) { - perror("listen"); return 4; + perror("listen"); + return 4; } - while(RUN) { /* on attend le clients locaux pour transmettre les donnees */ - lg = sizeof(Sin); - if ((newsid=accept(sid,(struct sockaddr *)&Srec, (socklen_t*)&lg))<0){ - perror("accept"); - } else { - /* message pour informer qui se connecte */ + + /* On laisse le serveur accepter des connexions + * A chaque connexion établie, le serveur crée un fils pour gérer celle-ci. */ + while (RUN) { // on attend les clients locaux pour transmettre les données + lg = sizeof(Sin); + if ((new_sid = accept(sid, (struct sockaddr *) &Srec, (socklen_t *) &lg)) < 0) { + perror("accept"); + } else { #ifdef TRACE_1 - printf("Connexion de %s !\n",adip(ntohl(Srec.sin_addr.s_addr))); + printf("Connexion de %s !\n", adip(ntohl(Srec.sin_addr.s_addr))); #endif - /* creation du processus dedie au client */ - if ((pid = fork()) == -1) { - perror("fork"); - write(newsid,"Erreur passerelle !\n",18); - } else { - if (pid==0) { /* code du fils */ - err=liaison(newsid);/* creation passerelle privee pour client */ - if (err) printf("Erreur liaison %d !\n",err); - return err; - } - /* suite du pere : ie passerelle principale */ - } - close(newsid); - } + + /* Création d'un processus dédié au client */ + if ((pid = fork()) == -1) { + perror("fork"); + write(new_sid, "Erreur passerelle !\n", 21); + } else { + if (pid == 0) { // code du fils + err = liaison(new_sid); // Création de la passerelle privée pour le client + if (err) fprintf(stderr, "Erreur liaison %d !\n", err); + return err; + } + } + close(new_sid); // On ferme le file descriptor qu'on vient de créer puisque c'est le fils qui s'en occupe + } } - return 0; /* fin OK */ -} + return 0; +} diff --git a/src/pass.h b/src/pass.h index 2311708..42b82a0 100644 --- a/src/pass.h +++ b/src/pass.h @@ -1,16 +1,40 @@ -/* pass.h : parametres du programme pass.c */ +/* pass.h : paramètres du programme pass.c */ -#define Version "1.00" +#ifndef PASS_H +#define PASS_H -#define EOT '\04' /* caractere fin de transmission */ +#define Version "1.1" -#define NBCLI 10 /* nb de client pouvant utiliser la passerelle */ +#define EOT '\04' +#define LBUF 512 // ATTENTION: doit être un multiple de la longueur de la clé ! +#define NBCLI 10 // nombre de clients pouvant utiliser la passerelle -#define LBUF 512 /* ATTENTION doit etre un multiple de la longueur de la cle !*/ +/* Les différents niveaux de trace pour débugger le code */ +#define TRACE_1 // suivi de la connexion des clients +#define TRACE_CH // pour suivre les opérations de chiffrement +#define TRACE_SP // pour suivre les opérations de structure de paquet -/* les differents niveaux de traces pour debugger le code */ -/* les options de compilation conditionnelle : -#define TRACE_1 suivit de la connexion des clients -#define TRACECH pour suivre les operations de chiffrement -#define TRACESP pour suivre les operations de structure de paquets -******************************************* */ +#include + +/* Fonction qui traduit une adresse IPv4 en chaîne de caractères xxx.xxx.xxx.xxx */ +extern char *adip(uint32_t A); + +/* Fontion qui fabrique un IPv4 au format réseau */ +extern uint32_t makeip4(int a, int b, int c, int d); + +/* Fonction qui agit en tant que handler pour signal() */ +extern void interrupt(int S); + +/* Fonction qui lit taille octets à la fois */ +extern int readNbc(int fd, char *buffer, int taille); + +/* Fonction du thread qui lit le port local et écrit vers le port distant */ +extern void *fct_th(void *p); + +/* Création de la passerelle pour le client */ +extern int liaison(int fd); + +/* Message d'aide pour l'utilisateur */ +extern void finerr(char *N, int err); + +#endif