#1 Version 1.1 : Ajout du chiffrement Playfair, en option en plus des autres méthodes

Открыто
tunui хочет смерджить 3 коммит(ов) из tunui/Passerelle:tunui_ajout_playfair в master
  1. +2
    -0
      src/.gitignore
  2. +8
    -4
      src/Makefile
  3. +248
    -0
      src/chiffre.c
  4. +46
    -0
      src/chiffre.h
  5. +279
    -244
      src/pass.c
  6. +35
    -11
      src/pass.h

+ 2
- 0
src/.gitignore Просмотреть файл

@@ -0,0 +1,2 @@
pass
*.o

+ 8
- 4
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

+ 248
- 0
src/chiffre.c Просмотреть файл

@@ -0,0 +1,248 @@
/* chiffre.c : Système simple de chiffrement d'octets inspiré de la méthode PlayFair */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>

#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

+ 46
- 0
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

+ 279
- 244
src/pass.c Просмотреть файл

@@ -1,7 +1,9 @@
/* notre passerelle TCP IPv4 */
/* Notre passerrelle TCP IPv4 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
@@ -9,315 +11,348 @@
#include <fcntl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <signal.h>
#include <sys/wait.h>
#include <netdb.h>
#include <pthread.h>

#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<f) {
*d++ ^= *c++; /* equiv. *d ^= *c; d++; c++; */
if (c==fc) c=(long long *)BCLE;
}
return; /* pour l'instant ne fait rien !! */
}
// exemple : makeip4(127,0,0,1);
uint32_t addresse;
char *p;
p = (char *) &addresse;
*p++ = (unsigned char) a;
*p++ = (unsigned char) b;
*p++ = (unsigned char) c;
*p = (unsigned char) d;

int initCle(void)
{
int fd;
if ((fd = open(NFCLE,O_RDONLY)) == -1) return -1;
if (read(fd,BCLE, LCLE) != LCLE) return -1;
close(fd);
return 0;
return addresse;
}

void fchiffre(char * b, int l, int ori) /* travaille avec CLE de 64 bits */
/* Fonction qui lit taille octets à la fois */
int readNbc(int fd, char *buffer, int taille)
{
long long *d, *f;
d=(long long*)b;
f=(long long*)(b+l);
/* le chiffrement avec xor */
while (d<f) *d++ ^= CLE;
#ifdef TRACECH
if (ori==0) { /* le thread L -> 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;
}

+ 35
- 11
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 <netdb.h>

/* 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

Загрузка…
Отмена
Сохранить