Commit initial
This commit is contained in:
commit
5f5c8a7eaf
|
@ -0,0 +1,64 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#define MAXHOSTLEN 64
|
||||
#define MAXPORTLEN 6
|
||||
#define MAXBUFFERLEN 1024
|
||||
int main(int argc, char* argv[]){
|
||||
int descSock; // Descripteur de la socket
|
||||
int ecode; // Retour des fonctions
|
||||
struct addrinfo *res; // Résultat de la focntion getaddrinfo
|
||||
struct addrinfo hints = { // Cette structure permet de contrôler l'exécution de la fonction getaddrinfo
|
||||
0,
|
||||
AF_INET, //seule les adresses IPv4 seront présentées par la fonctiongetaddrinfo
|
||||
SOCK_STREAM,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
char serverName[MAXHOSTLEN]; // Nom de la machine serveur
|
||||
char serverPort[MAXPORTLEN]; // Numéro de port
|
||||
char buffer[MAXBUFFERLEN]; // buffer stockant les messages échangés entre le client et le serveur
|
||||
//On teste les valeurs rentrées par l'utilisateur
|
||||
if (argc != 3){ perror("Mauvaise utilisation de la commande: <nom serveur> <numero de port>\n"); exit(1);}
|
||||
if (strlen(argv[1]) >= MAXHOSTLEN){ perror("Le nom de la machine serveur est trop long\n"); exit(2);}
|
||||
if (strlen(argv[2]) >= MAXPORTLEN){ perror("Le numero de port du serveur est trop long\n"); exit(2);}
|
||||
strncpy(serverName, argv[1], MAXHOSTLEN);
|
||||
serverName[MAXHOSTLEN-1] = '\0';
|
||||
strncpy(serverPort, argv[2], MAXPORTLEN);
|
||||
serverPort[MAXPORTLEN-1] = '\0';
|
||||
//Création de la socket IPv4/TCP
|
||||
descSock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (descSock == -1) {
|
||||
perror("Erreur creation socket");
|
||||
exit(4);
|
||||
}
|
||||
//Récupération des informations sur le serveur
|
||||
ecode = getaddrinfo(serverName,serverPort,&hints,&res);
|
||||
if (ecode){
|
||||
fprintf(stderr,"getaddrinfo: %s\n", gai_strerror(ecode));
|
||||
exit(3);
|
||||
}
|
||||
//Connexion au serveur
|
||||
ecode = connect(descSock, res->ai_addr, res->ai_addrlen);
|
||||
if (ecode == -1) {
|
||||
close(descSock);
|
||||
freeaddrinfo(res);
|
||||
perror("Erreur connect");
|
||||
exit(5);
|
||||
}
|
||||
freeaddrinfo(res);
|
||||
//Echange de donneés avec le serveur
|
||||
ecode = read(descSock, buffer, MAXBUFFERLEN);
|
||||
if (ecode == -1) {perror("Problème de lecture\n"); exit(6);}
|
||||
buffer[ecode] = '\0';
|
||||
printf("MESSAGE RECU DU SERVEUR: \"%s\".\n",buffer);
|
||||
//Fermeture de la socket
|
||||
close(descSock);
|
||||
}
|
||||
|
|
@ -0,0 +1,336 @@
|
|||
// Bibliothéques
|
||||
// ==============================================
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
// Constantes
|
||||
// ==============================================
|
||||
|
||||
#define SERVADDR "127.0.0.1" // Définition de l'adresse IP d'écoute
|
||||
#define SERVPORT "4444" // Définition du port d'écoute, si 0 port choisi dynamiquement
|
||||
#define LISTENLEN 2 // Taille du tampon de demandes de connexions, MAX 2
|
||||
#define MAXBUFFERLEN 1024
|
||||
#define MAXHOSTLEN 64
|
||||
#define MAXPORTLEN 6
|
||||
|
||||
|
||||
// PROCEDURES
|
||||
// ==============================================
|
||||
|
||||
void decoupeLogin( char *entreeUtilisateur, char *login, char *server );
|
||||
void waitingForUser(int *socket,char *buffer,int *n);
|
||||
void waitingForServer(int *socket,char *buffer,int *n);
|
||||
|
||||
|
||||
// MAIN
|
||||
// ==============================================
|
||||
|
||||
int main( int argc, char *argv[] ) {
|
||||
|
||||
// Variables [ SERVEUR ] >> [ PROXY ] - [ PROXY ] >> [ SERVEUR ]
|
||||
// ==============================================
|
||||
|
||||
int sockServeur; // Descripteur pour le socket
|
||||
int fncRet; // Stock le retour des fonctions
|
||||
struct addrinfo *resBIS; // Résultat de la focntion getaddrinfo
|
||||
struct addrinfo hintsBIS = {0, AF_INET, SOCK_STREAM, 0, 0, NULL, NULL, NULL}; // Filtra pour le getaddrinfo
|
||||
char bufferFTP[MAXBUFFERLEN];
|
||||
|
||||
// Variables [ CLIENT ] >> [ PROXY ] - [ PROXY ] >> [ CLIENT ]
|
||||
// ==============================================
|
||||
|
||||
char serverAddr[MAXHOSTLEN]; // Adresse du serveur
|
||||
char serverPort[MAXPORTLEN]; // Port du server
|
||||
char buffer[MAXBUFFERLEN]; // Tampon pour écrire sur le socket
|
||||
char bufferRcv[MAXBUFFERLEN]; // Tampon pour écrire sur le socket
|
||||
int descSockRDV; // Descripteur de socket de rendez-vous
|
||||
int ecode; // Code retour des fonctions
|
||||
int descSockCOM; // Descripteur de socket de communication
|
||||
int n = 0;
|
||||
int lenRCV = 0;
|
||||
|
||||
|
||||
struct addrinfo hints; // Filtre pour la fonction get_addr_info
|
||||
struct addrinfo *res; // Resultat get_addr_info
|
||||
struct sockaddr_storage myinfo; // Informations sur la connexion de RDV
|
||||
struct sockaddr_storage from; // Informations sur le client connecté
|
||||
|
||||
|
||||
char entreeUtilisateur[40]; // login@server
|
||||
char login[20]; // Isoler le login
|
||||
char serveur[20]; // Isoler le serveur
|
||||
|
||||
|
||||
socklen_t len = sizeof( struct sockaddr_storage ); // Variable utilisée pour stocker les longueurs des structures de socket
|
||||
|
||||
pid_t pid;
|
||||
|
||||
// Initialisation de la socket de RDV IPv4/TCP
|
||||
|
||||
descSockRDV = socket( AF_INET, SOCK_STREAM, 0 );
|
||||
|
||||
// Mise à zéro de la variable hints,entreeUtilisateur,loggin..
|
||||
|
||||
memset( &hints, 0, sizeof( hints ) );
|
||||
memset( entreeUtilisateur, 0, sizeof( entreeUtilisateur ) );
|
||||
memset( login, 0, sizeof( login ) );
|
||||
memset( serveur, 0, sizeof( serveur ) );
|
||||
memset( buffer, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferRcv, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferFTP, 0, sizeof( MAXBUFFERLEN ) );
|
||||
|
||||
// Initailisation de la variable hints
|
||||
|
||||
hints.ai_flags = AI_PASSIVE; // mode serveur, nous allons utiliser la fonction bind
|
||||
hints.ai_socktype = SOCK_STREAM; // TCP
|
||||
hints.ai_family = AF_INET; // IPv4
|
||||
|
||||
// Récupération des informations du serveur > Machine locale
|
||||
|
||||
ecode = getaddrinfo( SERVADDR, SERVPORT, &hints, &res );
|
||||
|
||||
// Publication de la socket
|
||||
|
||||
ecode = bind( descSockRDV, res->ai_addr, res->ai_addrlen );
|
||||
|
||||
ecode = listen( descSockRDV, LISTENLEN );
|
||||
|
||||
// Attente connexion du client
|
||||
// Lorsque demande de connexion, creation d'un processus fils et d'un socket de communication avec le client, MAX 2 attentes
|
||||
|
||||
while( 1 == 1 ) {
|
||||
|
||||
descSockCOM = accept( descSockRDV, ( struct sockaddr * ) &from, &len );
|
||||
|
||||
if( ( pid= fork() ) == 0) {
|
||||
|
||||
close( descSockRDV ); // On ferme le socketRDV on s'occupe seulement de gérer le socket actuel
|
||||
|
||||
strcpy( buffer, "220 Bienvenue sur le proxyFTP de aurehacks\r\n" ); // Echange de données avec le client connecté
|
||||
|
||||
send( descSockCOM, buffer, strlen( buffer ), 0 ); // Ecriture sur le socket
|
||||
|
||||
while(1 == 1) { // Gestion des commandes
|
||||
|
||||
waitingForUser(&descSockCOM,bufferRcv,&n);
|
||||
|
||||
// Gestion de l'authentification
|
||||
// ==============================================
|
||||
|
||||
if( strstr( bufferRcv,"USER") ) {
|
||||
|
||||
memset( buffer, 0, sizeof( MAXBUFFERLEN ) );
|
||||
|
||||
decoupeLogin(bufferRcv,login,serveur); // On isole le loggin ainsi que l'IP/URL du serveur
|
||||
|
||||
strcat(buffer,login); // On formate le login
|
||||
|
||||
sockServeur = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
getaddrinfo(serveur,"21",&hints,&res);
|
||||
|
||||
connect(sockServeur, res->ai_addr, res->ai_addrlen);
|
||||
|
||||
|
||||
|
||||
// [1] Message de Bienvenue
|
||||
// ==============================================
|
||||
|
||||
waitingForServer(&sockServeur,bufferFTP,&n);
|
||||
|
||||
// ==============================================
|
||||
|
||||
|
||||
|
||||
// [2] Envoi de "USER login"
|
||||
// ==============================================
|
||||
|
||||
send( sockServeur, buffer, strlen( buffer ), 0 );
|
||||
send( sockServeur, "\r\n", 2, 0 );
|
||||
|
||||
waitingForServer(&sockServeur,bufferFTP,&n);
|
||||
|
||||
// ==============================================
|
||||
|
||||
|
||||
// [3] Réception du "331 password required" et transmission au client
|
||||
// ==============================================
|
||||
|
||||
strcpy( bufferFTP, "331 required password\r\n" ); // Cas special SINON ON EN DIRECT send( descSockCOM, strcat(bufferFTP,"\r\n"), strlen( bufferFTP ), 0 );
|
||||
|
||||
send( descSockCOM, bufferFTP, strlen( bufferFTP ), 0 );
|
||||
|
||||
waitingForUser(&descSockCOM,bufferRcv,&n);
|
||||
|
||||
// ==============================================
|
||||
|
||||
|
||||
|
||||
// [4] Réception du "PASS mdp" (mot de passe du client) et transmission au serveur
|
||||
// ==============================================
|
||||
|
||||
send( sockServeur, bufferRcv, strlen( bufferRcv ), 0 );
|
||||
send( sockServeur, "\r\n", 2, 0 );
|
||||
|
||||
waitingForServer(&sockServeur,bufferFTP,&n);
|
||||
|
||||
// ==============================================
|
||||
|
||||
|
||||
|
||||
|
||||
// [5] Réception du "220 logged in" et transmission au client
|
||||
// ==============================================
|
||||
|
||||
strcpy( bufferFTP, "220 Logged IN !\r\n" ); // Cas special SINON ON EN DIRECT send( descSockCOM, strcat(bufferFTP,"\r\n"), strlen( bufferFTP ), 0 );
|
||||
|
||||
send( descSockCOM, bufferFTP, strlen( bufferFTP ), 0 );
|
||||
|
||||
waitingForUser(&descSockCOM,bufferRcv,&n);
|
||||
|
||||
// ==============================================
|
||||
|
||||
|
||||
// On clean les buffers
|
||||
|
||||
memset( buffer, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferRcv, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferFTP, 0, sizeof( MAXBUFFERLEN ) );
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Gestion du mode actif
|
||||
// ==============================================
|
||||
|
||||
if( strncmp( bufferRcv,"PORT", 4 ) ) {
|
||||
|
||||
n = 0;
|
||||
|
||||
// On clean les buffers
|
||||
|
||||
memset( buffer, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferRcv, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferFTP, 0, sizeof( MAXBUFFERLEN ) );
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Gestion du mode passif
|
||||
// ==============================================
|
||||
|
||||
if( strncmp( bufferRcv,"PASSV", 5 ) ) {
|
||||
|
||||
n = 0;
|
||||
|
||||
// On clean les buffers
|
||||
|
||||
memset( buffer, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferRcv, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferFTP, 0, sizeof( MAXBUFFERLEN ) );
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Gestion de la fermeture de session
|
||||
// ==============================================
|
||||
|
||||
|
||||
if( strncmp( bufferRcv,"QUIT", 4 ) ) {
|
||||
|
||||
break; // On quitte la boucle lorsque que l'on reçoit la commande "QUIT"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
freeaddrinfo(res);
|
||||
|
||||
close( descSockCOM );
|
||||
close( sockServeur );
|
||||
|
||||
// Fin du fils
|
||||
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
close( descSockRDV );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// decoupeLogin
|
||||
// ==============================================
|
||||
|
||||
void decoupeLogin( char *entreeUtilisateur, char *login, char *server ) {
|
||||
|
||||
int i,j = 0;
|
||||
|
||||
for( i=0; i<strlen( entreeUtilisateur ); i++) {
|
||||
|
||||
if( entreeUtilisateur[i] != '@' )
|
||||
login[i] = entreeUtilisateur[i];
|
||||
|
||||
if( entreeUtilisateur[i] == '@' ) {
|
||||
|
||||
i++;
|
||||
|
||||
while( entreeUtilisateur[i] != '\0' ) {
|
||||
|
||||
server[j] = entreeUtilisateur[i];
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void waitingForUser(int *socket,char *buffer,int *n) {
|
||||
|
||||
*n = 0;
|
||||
|
||||
while(1 == 1) { // Gestion du buffer
|
||||
|
||||
recv( *socket, buffer+( *n ), 1, 0 );
|
||||
|
||||
if( buffer[*n] == '\n' && buffer[( *n )-1] == '\r') {
|
||||
|
||||
buffer[*n] = '\0';
|
||||
buffer[( *n )-1] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
( *n )++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void waitingForServer(int *socket,char *buffer,int *n) {
|
||||
|
||||
*n = 0;
|
||||
|
||||
while(1 == 1) { // Gestion du buffer
|
||||
|
||||
recv( *socket, buffer+( *n ), 1, 0 );
|
||||
|
||||
if( buffer[*n] == '\n' && buffer[( *n )-1] == '\r') {
|
||||
|
||||
buffer[*n] = '\0';
|
||||
buffer[( *n )-1] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
( *n )++;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#define SERVADDR "127.0.0.1" // Définition de l'adresse IP d'écoute
|
||||
#define SERVPORT "0" // Définition du port d'écoute, si 0 port choisi dynamiquement
|
||||
#define LISTENLEN 1 // Taille du tampon de demande de connexion
|
||||
#define MAXBUFFERLEN 1024
|
||||
#define MAXHOSTLEN 64
|
||||
#define MAXPORTLEN 6
|
||||
|
||||
|
||||
int main(){
|
||||
int ecode; // Code retour des fonctions
|
||||
char serverAddr[MAXHOSTLEN]; // Adresse du serveur
|
||||
char serverPort[MAXPORTLEN]; // Port du server
|
||||
int descSockRDV; // Descripteur de socket de rendez-vous
|
||||
int descSockCOM; // Descripteur de socket de communication
|
||||
struct addrinfo hints; // Contrôle la fonction getaddrinfo
|
||||
struct addrinfo *res; // Contient le résultat de la fonction getaddrinfo
|
||||
struct sockaddr_storage myinfo; // Informations sur la connexion de RDV
|
||||
struct sockaddr_storage from; // Informations sur le client connecté
|
||||
socklen_t len; // Variable utilisée pour stocker les
|
||||
// longueurs des structures de socket
|
||||
char buffer[MAXBUFFERLEN]; // Tampon de communication entre le client et le serveur
|
||||
// Initialisation de la socket de RDV IPv4/TCP
|
||||
descSockRDV = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (descSockRDV == -1) {
|
||||
perror("Erreur création socket RDV\n");
|
||||
exit(2);
|
||||
}
|
||||
// Publication de la socket au niveau du système
|
||||
// Assignation d'une adresse IP et un numéro de port
|
||||
// Mise à zéro de hints
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
// Initailisation de hints
|
||||
hints.ai_flags = AI_PASSIVE; // mode serveur, nous allons utiliser la fonction bind
|
||||
hints.ai_socktype = SOCK_STREAM; // TCP
|
||||
hints.ai_family = AF_INET; // seules les adresses IPv4 seront présentées par
|
||||
// la fonction getaddrinfo
|
||||
|
||||
// Récupération des informations du serveur
|
||||
ecode = getaddrinfo(SERVADDR, SERVPORT, &hints, &res);
|
||||
if (ecode) {
|
||||
fprintf(stderr,"getaddrinfo: %s\n", gai_strerror(ecode));
|
||||
exit(1);
|
||||
}
|
||||
// Publication de la socket
|
||||
ecode = bind(descSockRDV, res->ai_addr, res->ai_addrlen);
|
||||
if (ecode == -1) {
|
||||
perror("Erreur liaison de la socket de RDV");
|
||||
exit(3);
|
||||
}
|
||||
// Nous n'avons plus besoin de cette liste chainée addrinfo
|
||||
freeaddrinfo(res);
|
||||
// Récuppération du nom de la machine et du numéro de port pour affichage à l'écran
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
len=sizeof(struct sockaddr_storage);
|
||||
ecode=getsockname(descSockRDV, (struct sockaddr *) &myinfo, &len);
|
||||
if (ecode == -1)
|
||||
{
|
||||
perror("SERVEUR: getsockname");
|
||||
exit(4);
|
||||
}
|
||||
ecode = getnameinfo((struct sockaddr*)&myinfo, sizeof(myinfo), serverAddr,MAXHOSTLEN,
|
||||
serverPort, MAXPORTLEN, NI_NUMERICHOST | NI_NUMERICSERV);
|
||||
if (ecode != 0) {
|
||||
fprintf(stderr, "error in getnameinfo: %s\n", gai_strerror(ecode));
|
||||
exit(4);
|
||||
}
|
||||
printf("L'adresse d'ecoute est: %s\n", serverAddr);
|
||||
printf("Le port d'ecoute est: %s\n", serverPort);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Definition de la taille du tampon contenant les demandes de connexion
|
||||
ecode = listen(descSockRDV, LISTENLEN);
|
||||
if (ecode == -1) {
|
||||
perror("Erreur initialisation buffer d'écoute");
|
||||
exit(5);
|
||||
}
|
||||
while( 1 ){
|
||||
|
||||
|
||||
|
||||
len = sizeof(struct sockaddr_storage);
|
||||
// Attente connexion du client
|
||||
// Lorsque demande de connexion, creation d'une socket de communication avec le client
|
||||
descSockCOM = accept(descSockRDV, (struct sockaddr *) &from, &len);
|
||||
if (descSockCOM == -1){
|
||||
perror("Erreur accept\n");
|
||||
exit(6);
|
||||
}
|
||||
// Echange de données avec le client connecté
|
||||
strcpy(buffer, "BLABLABLA\n");
|
||||
|
||||
write(descSockCOM, buffer, strlen(buffer));
|
||||
//Fermeture de la connexion
|
||||
close(descSockCOM);
|
||||
|
||||
}
|
||||
close(descSockRDV);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,215 @@
|
|||
#include "proxy_ftp.h"
|
||||
|
||||
// DECLARATIONS
|
||||
static pthread_t userServer;
|
||||
static short unsigned int userServerState = 1;
|
||||
static char remoteAssignedPort[maxPortLen] = {'\0'};
|
||||
|
||||
/* headers */
|
||||
static void* testClient(char* host, char* port);
|
||||
static void* testServer();
|
||||
static void* testClientFTP();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*****************/
|
||||
/* CORPS DU PROG */
|
||||
/*****************/
|
||||
int main(int argc, char* argv[]){
|
||||
|
||||
/* client */
|
||||
if( argc > 2 && strcmp(argv[1],"c") == 0 )
|
||||
testClient("localhost", argv[2]);
|
||||
|
||||
/* server */
|
||||
else if( argc > 1 && strcmp(argv[1], "s") == 0 )
|
||||
testServer();
|
||||
|
||||
/* clientFTP */
|
||||
else if( argc > 1 && strcmp(argv[1], "f") == 0 )
|
||||
testClientFTP();
|
||||
|
||||
/* client + server (multithread) */
|
||||
else if( argc > 1 && strcmp(argv[1], "both") == 0 ){
|
||||
|
||||
pthread_create(&userServer, NULL, &testServer, (void*) NULL);
|
||||
|
||||
// on attends d'avoir le port
|
||||
while( strlen(remoteAssignedPort) == 0 );
|
||||
|
||||
// on lance le client en boucle
|
||||
while( strlen(remoteAssignedPort) != 0 )
|
||||
testClient("localhost", remoteAssignedPort);
|
||||
|
||||
pthread_join(userServer, (void*) NULL);
|
||||
pthread_exit((void*) userServer);
|
||||
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void* testClientFTP(){
|
||||
CLIENT_FTPREQUEST(FTP_HOST, FTP_PORT);
|
||||
return;
|
||||
|
||||
// char request[maxBuffLen];
|
||||
// char* response;
|
||||
|
||||
// while( 1 ){
|
||||
// // on vide les buffers
|
||||
// memset(&request, '\0', sizeof(request));
|
||||
// memset(&response, '\0', sizeof(response));
|
||||
|
||||
// printf("> ");
|
||||
// read_stdin(request, maxBuffLen);
|
||||
// // on supprime le dernier retour chariot
|
||||
// // request[strlen(request)-1] == '\0';
|
||||
|
||||
|
||||
|
||||
// CLIENT_REQUEST(FTP_HOST, FTP_PORT, request, &response);
|
||||
|
||||
// if( strlen(response) > 0 )
|
||||
// printf("%s\n", response);
|
||||
|
||||
// response = NULL;
|
||||
// }
|
||||
|
||||
// return;
|
||||
}
|
||||
|
||||
|
||||
static void* testClient(char* host, char* port){
|
||||
char request[maxBuffLen];
|
||||
char* response;
|
||||
|
||||
// on vide les buffers
|
||||
memset(&request, '\0', sizeof(request));
|
||||
memset(&response, '\0', sizeof(response));
|
||||
|
||||
printf("> ");
|
||||
read_stdin(request, maxBuffLen);
|
||||
// on supprime le dernier retour chariot
|
||||
// request[strlen(request)-1] == '\0';
|
||||
|
||||
|
||||
|
||||
// CLIENT_REQUEST(remoteHost, remotePort, "GET / HTTP/1.0\r\n\r\n", &response);
|
||||
CLIENT_REQUEST(host, port, request, &response);
|
||||
|
||||
if( strlen(response) > 0 )
|
||||
printf("%s\n", response);
|
||||
|
||||
response = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void* testServer(){
|
||||
int SOCKET; // contiendra la connection en cours
|
||||
char BUFFER[maxBuffLen]; // contiendra le BUFFER
|
||||
struct sockaddr_storage clientInfo; // contiendra les infos client
|
||||
char repeat; // sert à sortir de la boucle
|
||||
int nbReceived, nbSend; // contiendra les nb reçu && envoyé
|
||||
socklen_t len = sizeof(struct sockaddr_storage);
|
||||
|
||||
// retour de @DROP_SERVER
|
||||
char* serverPort; // contiendra le port
|
||||
int LISTENSOCK; // contiendra la socket d'écoute
|
||||
|
||||
|
||||
/* [0] On lance @DROP_SERVER
|
||||
==========================================================*/
|
||||
DROP_SERVER(remoteHost, &serverPort, &LISTENSOCK);
|
||||
|
||||
printf("Port: %s\n", serverPort);
|
||||
strcpy(remoteAssignedPort, serverPort);// PORT GLOBAL
|
||||
|
||||
while( userServerState ){
|
||||
|
||||
/* [1] Attente d'une demande de connection, puis création d'une socket
|
||||
============================================================================*/
|
||||
SOCKET = accept(LISTENSOCK, (struct sockaddr *) &clientInfo, &len);
|
||||
|
||||
if( DEBUGMOD ) printf("SOCKET: %d\n", SOCKET);
|
||||
|
||||
/* [2] On récupère les données reçues
|
||||
============================================================================*/
|
||||
nbReceived = read(SOCKET, BUFFER, sizeof(BUFFER)-1);
|
||||
|
||||
if( DEBUGMOD ) printf("Recu: %d\n", nbReceived);
|
||||
if( DEBUGMOD ) printf("Message: %s\n", BUFFER);
|
||||
|
||||
/* [3] Redirection vers le serveur FTP
|
||||
============================================================================*/
|
||||
// on redirige la réponse vers le serveur FTP distant
|
||||
char* ftp_response;
|
||||
CLIENT_REQUEST(FTP_HOST, FTP_PORT, BUFFER, &ftp_response);
|
||||
// printf("===FTP===\n%s\n", ftp_response);
|
||||
|
||||
/* [4] On analyse et renvoie la réponse à l'utilisateur
|
||||
============================================================================*/
|
||||
// formatBuffer(ftp_response);
|
||||
// MANAGE_RESPONSE(&SOCKET, ftp_response);
|
||||
|
||||
// on réponds au client
|
||||
formatBuffer(ftp_response);
|
||||
write(SOCKET, ftp_response, strlen(ftp_response)-1);
|
||||
|
||||
|
||||
/* [5] On ferme la SOCKET et vide les buffers
|
||||
============================================================================*/
|
||||
close(SOCKET);
|
||||
memset(&BUFFER, '\0', sizeof(BUFFER)); // on vide le buffer
|
||||
ftp_response = NULL;
|
||||
|
||||
|
||||
}
|
||||
|
||||
close(LISTENSOCK);
|
||||
strcpy(remoteAssignedPort, "\0");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* DROP_SERVER
|
||||
* INIT_CLIENT
|
||||
*
|
||||
* while(){
|
||||
* accept();
|
||||
* send
|
||||
* }
|
||||
*
|
||||
* EXIT_CLIENT
|
||||
* HALT_SERVER
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
|
@ -0,0 +1,39 @@
|
|||
/* global */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
|
||||
/* sys */
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
/* socket */
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h> // getaddrinfo, getnameinfo
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/* basis */
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
|
||||
/* debug */
|
||||
// #define DEBUGMOD FALSE // <Boolean> TRUE = débugmode activé
|
||||
#define DEBUGMOD TRUE // <Boolean> TRUE = débugmode activé
|
||||
|
||||
/* vars */
|
||||
#define remoteHost "localhost"
|
||||
#define remotePort "80"
|
||||
#define maxBuffLen 4096
|
||||
#define maxListLen 2
|
||||
#define maxHostLen 64
|
||||
#define maxPortLen 6
|
||||
|
||||
#define FTP_HOST "31.170.164.47"
|
||||
#define FTP_PORT "21"
|
||||
|
||||
/* local dependencies */
|
||||
#include "dep/utility.c"
|
||||
#include "dep/client.c"
|
||||
#include "dep/server.c"
|
Binary file not shown.
|
@ -0,0 +1,64 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#define MAXHOSTLEN 64
|
||||
#define MAXPORTLEN 6
|
||||
#define MAXBUFFERLEN 1024
|
||||
int main(int argc, char* argv[]){
|
||||
int descSock; // Descripteur de la socket
|
||||
int ecode; // Retour des fonctions
|
||||
struct addrinfo *res; // Résultat de la focntion getaddrinfo
|
||||
struct addrinfo hints = { // Cette structure permet de contrôler l'exécution de la fonction getaddrinfo
|
||||
0,
|
||||
AF_INET, //seule les adresses IPv4 seront présentées par la fonctiongetaddrinfo
|
||||
SOCK_STREAM,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
char serverName[MAXHOSTLEN]; // Nom de la machine serveur
|
||||
char serverPort[MAXPORTLEN]; // Numéro de port
|
||||
char buffer[MAXBUFFERLEN]; // buffer stockant les messages échangés entre le client et le serveur
|
||||
//On teste les valeurs rentrées par l'utilisateur
|
||||
if (argc != 3){ perror("Mauvaise utilisation de la commande: <nom serveur> <numero de port>\n"); exit(1);}
|
||||
if (strlen(argv[1]) >= MAXHOSTLEN){ perror("Le nom de la machine serveur est trop long\n"); exit(2);}
|
||||
if (strlen(argv[2]) >= MAXPORTLEN){ perror("Le numero de port du serveur est trop long\n"); exit(2);}
|
||||
strncpy(serverName, argv[1], MAXHOSTLEN);
|
||||
serverName[MAXHOSTLEN-1] = '\0';
|
||||
strncpy(serverPort, argv[2], MAXPORTLEN);
|
||||
serverPort[MAXPORTLEN-1] = '\0';
|
||||
//Création de la socket IPv4/TCP
|
||||
descSock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (descSock == -1) {
|
||||
perror("Erreur creation socket");
|
||||
exit(4);
|
||||
}
|
||||
//Récupération des informations sur le serveur
|
||||
ecode = getaddrinfo(serverName,serverPort,&hints,&res);
|
||||
if (ecode){
|
||||
fprintf(stderr,"getaddrinfo: %s\n", gai_strerror(ecode));
|
||||
exit(3);
|
||||
}
|
||||
//Connexion au serveur
|
||||
ecode = connect(descSock, res->ai_addr, res->ai_addrlen);
|
||||
if (ecode == -1) {
|
||||
close(descSock);
|
||||
freeaddrinfo(res);
|
||||
perror("Erreur connect");
|
||||
exit(5);
|
||||
}
|
||||
freeaddrinfo(res);
|
||||
//Echange de donneés avec le serveur
|
||||
ecode = read(descSock, buffer, MAXBUFFERLEN);
|
||||
if (ecode == -1) {perror("Problème de lecture\n"); exit(6);}
|
||||
buffer[ecode] = '\0';
|
||||
printf("MESSAGE RECU DU SERVEUR: \"%s\".\n",buffer);
|
||||
//Fermeture de la socket
|
||||
close(descSock);
|
||||
}
|
||||
|
|
@ -0,0 +1,336 @@
|
|||
// Bibliothéques
|
||||
// ==============================================
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
// Constantes
|
||||
// ==============================================
|
||||
|
||||
#define SERVADDR "127.0.0.1" // Définition de l'adresse IP d'écoute
|
||||
#define SERVPORT "4444" // Définition du port d'écoute, si 0 port choisi dynamiquement
|
||||
#define LISTENLEN 2 // Taille du tampon de demandes de connexions, MAX 2
|
||||
#define MAXBUFFERLEN 1024
|
||||
#define MAXHOSTLEN 64
|
||||
#define MAXPORTLEN 6
|
||||
|
||||
|
||||
// PROCEDURES
|
||||
// ==============================================
|
||||
|
||||
void decoupeLogin( char *entreeUtilisateur, char *login, char *server );
|
||||
void waitingForUser(int *socket,char *buffer,int *n);
|
||||
void waitingForServer(int *socket,char *buffer,int *n);
|
||||
|
||||
|
||||
// MAIN
|
||||
// ==============================================
|
||||
|
||||
int main( int argc, char *argv[] ) {
|
||||
|
||||
// Variables [ SERVEUR ] >> [ PROXY ] - [ PROXY ] >> [ SERVEUR ]
|
||||
// ==============================================
|
||||
|
||||
int sockServeur; // Descripteur pour le socket
|
||||
int fncRet; // Stock le retour des fonctions
|
||||
struct addrinfo *resBIS; // Résultat de la focntion getaddrinfo
|
||||
struct addrinfo hintsBIS = {0, AF_INET, SOCK_STREAM, 0, 0, NULL, NULL, NULL}; // Filtra pour le getaddrinfo
|
||||
char bufferFTP[MAXBUFFERLEN];
|
||||
|
||||
// Variables [ CLIENT ] >> [ PROXY ] - [ PROXY ] >> [ CLIENT ]
|
||||
// ==============================================
|
||||
|
||||
char serverAddr[MAXHOSTLEN]; // Adresse du serveur
|
||||
char serverPort[MAXPORTLEN]; // Port du server
|
||||
char buffer[MAXBUFFERLEN]; // Tampon pour écrire sur le socket
|
||||
char bufferRcv[MAXBUFFERLEN]; // Tampon pour écrire sur le socket
|
||||
int descSockRDV; // Descripteur de socket de rendez-vous
|
||||
int ecode; // Code retour des fonctions
|
||||
int descSockCOM; // Descripteur de socket de communication
|
||||
int n = 0;
|
||||
int lenRCV = 0;
|
||||
|
||||
|
||||
struct addrinfo hints; // Filtre pour la fonction get_addr_info
|
||||
struct addrinfo *res; // Resultat get_addr_info
|
||||
struct sockaddr_storage myinfo; // Informations sur la connexion de RDV
|
||||
struct sockaddr_storage from; // Informations sur le client connecté
|
||||
|
||||
|
||||
char entreeUtilisateur[40]; // login@server
|
||||
char login[20]; // Isoler le login
|
||||
char serveur[20]; // Isoler le serveur
|
||||
|
||||
|
||||
socklen_t len = sizeof( struct sockaddr_storage ); // Variable utilisée pour stocker les longueurs des structures de socket
|
||||
|
||||
pid_t pid;
|
||||
|
||||
// Initialisation de la socket de RDV IPv4/TCP
|
||||
|
||||
descSockRDV = socket( AF_INET, SOCK_STREAM, 0 );
|
||||
|
||||
// Mise à zéro de la variable hints,entreeUtilisateur,loggin..
|
||||
|
||||
memset( &hints, 0, sizeof( hints ) );
|
||||
memset( entreeUtilisateur, 0, sizeof( entreeUtilisateur ) );
|
||||
memset( login, 0, sizeof( login ) );
|
||||
memset( serveur, 0, sizeof( serveur ) );
|
||||
memset( buffer, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferRcv, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferFTP, 0, sizeof( MAXBUFFERLEN ) );
|
||||
|
||||
// Initailisation de la variable hints
|
||||
|
||||
hints.ai_flags = AI_PASSIVE; // mode serveur, nous allons utiliser la fonction bind
|
||||
hints.ai_socktype = SOCK_STREAM; // TCP
|
||||
hints.ai_family = AF_INET; // IPv4
|
||||
|
||||
// Récupération des informations du serveur > Machine locale
|
||||
|
||||
ecode = getaddrinfo( SERVADDR, SERVPORT, &hints, &res );
|
||||
|
||||
// Publication de la socket
|
||||
|
||||
ecode = bind( descSockRDV, res->ai_addr, res->ai_addrlen );
|
||||
|
||||
ecode = listen( descSockRDV, LISTENLEN );
|
||||
|
||||
// Attente connexion du client
|
||||
// Lorsque demande de connexion, creation d'un processus fils et d'un socket de communication avec le client, MAX 2 attentes
|
||||
|
||||
while( 1 == 1 ) {
|
||||
|
||||
descSockCOM = accept( descSockRDV, ( struct sockaddr * ) &from, &len );
|
||||
|
||||
if( ( pid= fork() ) == 0) {
|
||||
|
||||
close( descSockRDV ); // On ferme le socketRDV on s'occupe seulement de gérer le socket actuel
|
||||
|
||||
strcpy( buffer, "220 Bienvenue sur le proxyFTP de aurehacks\r\n" ); // Echange de données avec le client connecté
|
||||
|
||||
send( descSockCOM, buffer, strlen( buffer ), 0 ); // Ecriture sur le socket
|
||||
|
||||
while(1 == 1) { // Gestion des commandes
|
||||
|
||||
waitingForUser(&descSockCOM,bufferRcv,&n);
|
||||
|
||||
// Gestion de l'authentification
|
||||
// ==============================================
|
||||
|
||||
if( strstr( bufferRcv,"USER") ) {
|
||||
|
||||
memset( buffer, 0, sizeof( MAXBUFFERLEN ) );
|
||||
|
||||
decoupeLogin(bufferRcv,login,serveur); // On isole le loggin ainsi que l'IP/URL du serveur
|
||||
|
||||
strcat(buffer,login); // On formate le login
|
||||
|
||||
sockServeur = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
getaddrinfo(serveur,"21",&hints,&res);
|
||||
|
||||
connect(sockServeur, res->ai_addr, res->ai_addrlen);
|
||||
|
||||
|
||||
|
||||
// [1] Message de Bienvenue
|
||||
// ==============================================
|
||||
|
||||
waitingForServer(&sockServeur,bufferFTP,&n);
|
||||
|
||||
// ==============================================
|
||||
|
||||
|
||||
|
||||
// [2] Envoi de "USER login"
|
||||
// ==============================================
|
||||
|
||||
send( sockServeur, buffer, strlen( buffer ), 0 );
|
||||
send( sockServeur, "\r\n", 2, 0 );
|
||||
|
||||
waitingForServer(&sockServeur,bufferFTP,&n);
|
||||
|
||||
// ==============================================
|
||||
|
||||
|
||||
// [3] Réception du "331 password required" et transmission au client
|
||||
// ==============================================
|
||||
|
||||
strcpy( bufferFTP, "331 required password\r\n" ); // Cas special SINON ON EN DIRECT send( descSockCOM, strcat(bufferFTP,"\r\n"), strlen( bufferFTP ), 0 );
|
||||
|
||||
send( descSockCOM, bufferFTP, strlen( bufferFTP ), 0 );
|
||||
|
||||
waitingForUser(&descSockCOM,bufferRcv,&n);
|
||||
|
||||
// ==============================================
|
||||
|
||||
|
||||
|
||||
// [4] Réception du "PASS mdp" (mot de passe du client) et transmission au serveur
|
||||
// ==============================================
|
||||
|
||||
send( sockServeur, bufferRcv, strlen( bufferRcv ), 0 );
|
||||
send( sockServeur, "\r\n", 2, 0 );
|
||||
|
||||
waitingForServer(&sockServeur,bufferFTP,&n);
|
||||
|
||||
// ==============================================
|
||||
|
||||
|
||||
|
||||
|
||||
// [5] Réception du "220 logged in" et transmission au client
|
||||
// ==============================================
|
||||
|
||||
strcpy( bufferFTP, "220 Logged IN !\r\n" ); // Cas special SINON ON EN DIRECT send( descSockCOM, strcat(bufferFTP,"\r\n"), strlen( bufferFTP ), 0 );
|
||||
|
||||
send( descSockCOM, bufferFTP, strlen( bufferFTP ), 0 );
|
||||
|
||||
waitingForUser(&descSockCOM,bufferRcv,&n);
|
||||
|
||||
// ==============================================
|
||||
|
||||
|
||||
// On clean les buffers
|
||||
|
||||
memset( buffer, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferRcv, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferFTP, 0, sizeof( MAXBUFFERLEN ) );
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Gestion du mode actif
|
||||
// ==============================================
|
||||
|
||||
if( strncmp( bufferRcv,"PORT", 4 ) ) {
|
||||
|
||||
n = 0;
|
||||
|
||||
// On clean les buffers
|
||||
|
||||
memset( buffer, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferRcv, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferFTP, 0, sizeof( MAXBUFFERLEN ) );
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Gestion du mode passif
|
||||
// ==============================================
|
||||
|
||||
if( strncmp( bufferRcv,"PASSV", 5 ) ) {
|
||||
|
||||
n = 0;
|
||||
|
||||
// On clean les buffers
|
||||
|
||||
memset( buffer, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferRcv, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferFTP, 0, sizeof( MAXBUFFERLEN ) );
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Gestion de la fermeture de session
|
||||
// ==============================================
|
||||
|
||||
|
||||
if( strncmp( bufferRcv,"QUIT", 4 ) ) {
|
||||
|
||||
break; // On quitte la boucle lorsque que l'on reçoit la commande "QUIT"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
freeaddrinfo(res);
|
||||
|
||||
close( descSockCOM );
|
||||
close( sockServeur );
|
||||
|
||||
// Fin du fils
|
||||
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
close( descSockRDV );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// decoupeLogin
|
||||
// ==============================================
|
||||
|
||||
void decoupeLogin( char *entreeUtilisateur, char *login, char *server ) {
|
||||
|
||||
int i,j = 0;
|
||||
|
||||
for( i=0; i<strlen( entreeUtilisateur ); i++) {
|
||||
|
||||
if( entreeUtilisateur[i] != '@' )
|
||||
login[i] = entreeUtilisateur[i];
|
||||
|
||||
if( entreeUtilisateur[i] == '@' ) {
|
||||
|
||||
i++;
|
||||
|
||||
while( entreeUtilisateur[i] != '\0' ) {
|
||||
|
||||
server[j] = entreeUtilisateur[i];
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void waitingForUser(int *socket,char *buffer,int *n) {
|
||||
|
||||
*n = 0;
|
||||
|
||||
while(1 == 1) { // Gestion du buffer
|
||||
|
||||
recv( *socket, buffer+( *n ), 1, 0 );
|
||||
|
||||
if( buffer[*n] == '\n' && buffer[( *n )-1] == '\r') {
|
||||
|
||||
buffer[*n] = '\0';
|
||||
buffer[( *n )-1] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
( *n )++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void waitingForServer(int *socket,char *buffer,int *n) {
|
||||
|
||||
*n = 0;
|
||||
|
||||
while(1 == 1) { // Gestion du buffer
|
||||
|
||||
recv( *socket, buffer+( *n ), 1, 0 );
|
||||
|
||||
if( buffer[*n] == '\n' && buffer[( *n )-1] == '\r') {
|
||||
|
||||
buffer[*n] = '\0';
|
||||
buffer[( *n )-1] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
( *n )++;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#define SERVADDR "127.0.0.1" // Définition de l'adresse IP d'écoute
|
||||
#define SERVPORT "0" // Définition du port d'écoute, si 0 port choisi dynamiquement
|
||||
#define LISTENLEN 1 // Taille du tampon de demande de connexion
|
||||
#define MAXBUFFERLEN 1024
|
||||
#define MAXHOSTLEN 64
|
||||
#define MAXPORTLEN 6
|
||||
|
||||
|
||||
int main(){
|
||||
int ecode; // Code retour des fonctions
|
||||
char serverAddr[MAXHOSTLEN]; // Adresse du serveur
|
||||
char serverPort[MAXPORTLEN]; // Port du server
|
||||
int descSockRDV; // Descripteur de socket de rendez-vous
|
||||
int descSockCOM; // Descripteur de socket de communication
|
||||
struct addrinfo hints; // Contrôle la fonction getaddrinfo
|
||||
struct addrinfo *res; // Contient le résultat de la fonction getaddrinfo
|
||||
struct sockaddr_storage myinfo; // Informations sur la connexion de RDV
|
||||
struct sockaddr_storage from; // Informations sur le client connecté
|
||||
socklen_t len; // Variable utilisée pour stocker les
|
||||
// longueurs des structures de socket
|
||||
char buffer[MAXBUFFERLEN]; // Tampon de communication entre le client et le serveur
|
||||
// Initialisation de la socket de RDV IPv4/TCP
|
||||
descSockRDV = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (descSockRDV == -1) {
|
||||
perror("Erreur création socket RDV\n");
|
||||
exit(2);
|
||||
}
|
||||
// Publication de la socket au niveau du système
|
||||
// Assignation d'une adresse IP et un numéro de port
|
||||
// Mise à zéro de hints
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
// Initailisation de hints
|
||||
hints.ai_flags = AI_PASSIVE; // mode serveur, nous allons utiliser la fonction bind
|
||||
hints.ai_socktype = SOCK_STREAM; // TCP
|
||||
hints.ai_family = AF_INET; // seules les adresses IPv4 seront présentées par
|
||||
// la fonction getaddrinfo
|
||||
|
||||
// Récupération des informations du serveur
|
||||
ecode = getaddrinfo(SERVADDR, SERVPORT, &hints, &res);
|
||||
if (ecode) {
|
||||
fprintf(stderr,"getaddrinfo: %s\n", gai_strerror(ecode));
|
||||
exit(1);
|
||||
}
|
||||
// Publication de la socket
|
||||
ecode = bind(descSockRDV, res->ai_addr, res->ai_addrlen);
|
||||
if (ecode == -1) {
|
||||
perror("Erreur liaison de la socket de RDV");
|
||||
exit(3);
|
||||
}
|
||||
// Nous n'avons plus besoin de cette liste chainée addrinfo
|
||||
freeaddrinfo(res);
|
||||
// Récuppération du nom de la machine et du numéro de port pour affichage à l'écran
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
len=sizeof(struct sockaddr_storage);
|
||||
ecode=getsockname(descSockRDV, (struct sockaddr *) &myinfo, &len);
|
||||
if (ecode == -1)
|
||||
{
|
||||
perror("SERVEUR: getsockname");
|
||||
exit(4);
|
||||
}
|
||||
ecode = getnameinfo((struct sockaddr*)&myinfo, sizeof(myinfo), serverAddr,MAXHOSTLEN,
|
||||
serverPort, MAXPORTLEN, NI_NUMERICHOST | NI_NUMERICSERV);
|
||||
if (ecode != 0) {
|
||||
fprintf(stderr, "error in getnameinfo: %s\n", gai_strerror(ecode));
|
||||
exit(4);
|
||||
}
|
||||
printf("L'adresse d'ecoute est: %s\n", serverAddr);
|
||||
printf("Le port d'ecoute est: %s\n", serverPort);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Definition de la taille du tampon contenant les demandes de connexion
|
||||
ecode = listen(descSockRDV, LISTENLEN);
|
||||
if (ecode == -1) {
|
||||
perror("Erreur initialisation buffer d'écoute");
|
||||
exit(5);
|
||||
}
|
||||
while( 1 ){
|
||||
|
||||
|
||||
|
||||
len = sizeof(struct sockaddr_storage);
|
||||
// Attente connexion du client
|
||||
// Lorsque demande de connexion, creation d'une socket de communication avec le client
|
||||
descSockCOM = accept(descSockRDV, (struct sockaddr *) &from, &len);
|
||||
if (descSockCOM == -1){
|
||||
perror("Erreur accept\n");
|
||||
exit(6);
|
||||
}
|
||||
// Echange de données avec le client connecté
|
||||
strcpy(buffer, "BLABLABLA\n");
|
||||
|
||||
write(descSockCOM, buffer, strlen(buffer));
|
||||
//Fermeture de la connexion
|
||||
close(descSockCOM);
|
||||
|
||||
}
|
||||
close(descSockRDV);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,215 @@
|
|||
#include "proxy_ftp.h"
|
||||
|
||||
// DECLARATIONS
|
||||
static pthread_t userServer;
|
||||
static short unsigned int userServerState = 1;
|
||||
static char remoteAssignedPort[maxPortLen] = {'\0'};
|
||||
|
||||
/* headers */
|
||||
static void* testClient(char* host, char* port);
|
||||
static void* testServer();
|
||||
static void* testClientFTP();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*****************/
|
||||
/* CORPS DU PROG */
|
||||
/*****************/
|
||||
int main(int argc, char* argv[]){
|
||||
|
||||
/* client */
|
||||
if( argc > 2 && strcmp(argv[1],"c") == 0 )
|
||||
testClient("localhost", argv[2]);
|
||||
|
||||
/* server */
|
||||
else if( argc > 1 && strcmp(argv[1], "s") == 0 )
|
||||
testServer();
|
||||
|
||||
/* clientFTP */
|
||||
else if( argc > 1 && strcmp(argv[1], "f") == 0 )
|
||||
testClientFTP();
|
||||
|
||||
/* client + server (multithread) */
|
||||
else if( argc > 1 && strcmp(argv[1], "both") == 0 ){
|
||||
|
||||
pthread_create(&userServer, NULL, &testServer, (void*) NULL);
|
||||
|
||||
// on attends d'avoir le port
|
||||
while( strlen(remoteAssignedPort) == 0 );
|
||||
|
||||
// on lance le client en boucle
|
||||
while( strlen(remoteAssignedPort) != 0 )
|
||||
testClient("localhost", remoteAssignedPort);
|
||||
|
||||
pthread_join(userServer, (void*) NULL);
|
||||
pthread_exit((void*) userServer);
|
||||
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void* testClientFTP(){
|
||||
CLIENT_FTPREQUEST(FTP_HOST, FTP_PORT);
|
||||
return;
|
||||
|
||||
// char request[maxBuffLen];
|
||||
// char* response;
|
||||
|
||||
// while( 1 ){
|
||||
// // on vide les buffers
|
||||
// memset(&request, '\0', sizeof(request));
|
||||
// memset(&response, '\0', sizeof(response));
|
||||
|
||||
// printf("> ");
|
||||
// read_stdin(request, maxBuffLen);
|
||||
// // on supprime le dernier retour chariot
|
||||
// // request[strlen(request)-1] == '\0';
|
||||
|
||||
|
||||
|
||||
// CLIENT_REQUEST(FTP_HOST, FTP_PORT, request, &response);
|
||||
|
||||
// if( strlen(response) > 0 )
|
||||
// printf("%s\n", response);
|
||||
|
||||
// response = NULL;
|
||||
// }
|
||||
|
||||
// return;
|
||||
}
|
||||
|
||||
|
||||
static void* testClient(char* host, char* port){
|
||||
char request[maxBuffLen];
|
||||
char* response;
|
||||
|
||||
// on vide les buffers
|
||||
memset(&request, '\0', sizeof(request));
|
||||
memset(&response, '\0', sizeof(response));
|
||||
|
||||
printf("> ");
|
||||
read_stdin(request, maxBuffLen);
|
||||
// on supprime le dernier retour chariot
|
||||
// request[strlen(request)-1] == '\0';
|
||||
|
||||
|
||||
|
||||
// CLIENT_REQUEST(remoteHost, remotePort, "GET / HTTP/1.0\r\n\r\n", &response);
|
||||
CLIENT_REQUEST(host, port, request, &response);
|
||||
|
||||
if( strlen(response) > 0 )
|
||||
printf("%s\n", response);
|
||||
|
||||
response = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void* testServer(){
|
||||
int SOCKET; // contiendra la connection en cours
|
||||
char BUFFER[maxBuffLen]; // contiendra le BUFFER
|
||||
struct sockaddr_storage clientInfo; // contiendra les infos client
|
||||
char repeat; // sert à sortir de la boucle
|
||||
int nbReceived, nbSend; // contiendra les nb reçu && envoyé
|
||||
socklen_t len = sizeof(struct sockaddr_storage);
|
||||
|
||||
// retour de @DROP_SERVER
|
||||
char* serverPort; // contiendra le port
|
||||
int LISTENSOCK; // contiendra la socket d'écoute
|
||||
|
||||
|
||||
/* [0] On lance @DROP_SERVER
|
||||
==========================================================*/
|
||||
DROP_SERVER(remoteHost, &serverPort, &LISTENSOCK);
|
||||
|
||||
printf("Port: %s\n", serverPort);
|
||||
strcpy(remoteAssignedPort, serverPort);// PORT GLOBAL
|
||||
|
||||
while( userServerState ){
|
||||
|
||||
/* [1] Attente d'une demande de connection, puis création d'une socket
|
||||
============================================================================*/
|
||||
SOCKET = accept(LISTENSOCK, (struct sockaddr *) &clientInfo, &len);
|
||||
|
||||
if( DEBUGMOD ) printf("SOCKET: %d\n", SOCKET);
|
||||
|
||||
/* [2] On récupère les données reçues
|
||||
============================================================================*/
|
||||
nbReceived = read(SOCKET, BUFFER, sizeof(BUFFER)-1);
|
||||
|
||||
if( DEBUGMOD ) printf("Recu: %d\n", nbReceived);
|
||||
if( DEBUGMOD ) printf("Message: %s\n", BUFFER);
|
||||
|
||||
/* [3] Redirection vers le serveur FTP
|
||||
============================================================================*/
|
||||
// on redirige la réponse vers le serveur FTP distant
|
||||
char* ftp_response;
|
||||
CLIENT_REQUEST(FTP_HOST, FTP_PORT, BUFFER, &ftp_response);
|
||||
// printf("===FTP===\n%s\n", ftp_response);
|
||||
|
||||
/* [4] On analyse et renvoie la réponse à l'utilisateur
|
||||
============================================================================*/
|
||||
// formatBuffer(ftp_response);
|
||||
// MANAGE_RESPONSE(&SOCKET, ftp_response);
|
||||
|
||||
// on réponds au client
|
||||
formatBuffer(ftp_response);
|
||||
write(SOCKET, ftp_response, strlen(ftp_response)-1);
|
||||
|
||||
|
||||
/* [5] On ferme la SOCKET et vide les buffers
|
||||
============================================================================*/
|
||||
close(SOCKET);
|
||||
memset(&BUFFER, '\0', sizeof(BUFFER)); // on vide le buffer
|
||||
ftp_response = NULL;
|
||||
|
||||
|
||||
}
|
||||
|
||||
close(LISTENSOCK);
|
||||
strcpy(remoteAssignedPort, "\0");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* DROP_SERVER
|
||||
* INIT_CLIENT
|
||||
*
|
||||
* while(){
|
||||
* accept();
|
||||
* send
|
||||
* }
|
||||
*
|
||||
* EXIT_CLIENT
|
||||
* HALT_SERVER
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
|
@ -0,0 +1,39 @@
|
|||
/* global */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
|
||||
/* sys */
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
/* socket */
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h> // getaddrinfo, getnameinfo
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/* basis */
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
|
||||
/* debug */
|
||||
// #define DEBUGMOD FALSE // <Boolean> TRUE = débugmode activé
|
||||
#define DEBUGMOD TRUE // <Boolean> TRUE = débugmode activé
|
||||
|
||||
/* vars */
|
||||
#define remoteHost "localhost"
|
||||
#define remotePort "80"
|
||||
#define maxBuffLen 4096
|
||||
#define maxListLen 2
|
||||
#define maxHostLen 64
|
||||
#define maxPortLen 6
|
||||
|
||||
#define FTP_HOST "31.170.164.47"
|
||||
#define FTP_PORT "21"
|
||||
|
||||
/* local dependencies */
|
||||
#include "dep/utility.c"
|
||||
#include "dep/client.c"
|
||||
#include "dep/server.c"
|
Binary file not shown.
|
@ -0,0 +1,64 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#define MAXHOSTLEN 64
|
||||
#define MAXPORTLEN 6
|
||||
#define MAXBUFFERLEN 1024
|
||||
int main(int argc, char* argv[]){
|
||||
int descSock; // Descripteur de la socket
|
||||
int ecode; // Retour des fonctions
|
||||
struct addrinfo *res; // Résultat de la focntion getaddrinfo
|
||||
struct addrinfo hints = { // Cette structure permet de contrôler l'exécution de la fonction getaddrinfo
|
||||
0,
|
||||
AF_INET, //seule les adresses IPv4 seront présentées par la fonctiongetaddrinfo
|
||||
SOCK_STREAM,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
char serverName[MAXHOSTLEN]; // Nom de la machine serveur
|
||||
char serverPort[MAXPORTLEN]; // Numéro de port
|
||||
char buffer[MAXBUFFERLEN]; // buffer stockant les messages échangés entre le client et le serveur
|
||||
//On teste les valeurs rentrées par l'utilisateur
|
||||
if (argc != 3){ perror("Mauvaise utilisation de la commande: <nom serveur> <numero de port>\n"); exit(1);}
|
||||
if (strlen(argv[1]) >= MAXHOSTLEN){ perror("Le nom de la machine serveur est trop long\n"); exit(2);}
|
||||
if (strlen(argv[2]) >= MAXPORTLEN){ perror("Le numero de port du serveur est trop long\n"); exit(2);}
|
||||
strncpy(serverName, argv[1], MAXHOSTLEN);
|
||||
serverName[MAXHOSTLEN-1] = '\0';
|
||||
strncpy(serverPort, argv[2], MAXPORTLEN);
|
||||
serverPort[MAXPORTLEN-1] = '\0';
|
||||
//Création de la socket IPv4/TCP
|
||||
descSock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (descSock == -1) {
|
||||
perror("Erreur creation socket");
|
||||
exit(4);
|
||||
}
|
||||
//Récupération des informations sur le serveur
|
||||
ecode = getaddrinfo(serverName,serverPort,&hints,&res);
|
||||
if (ecode){
|
||||
fprintf(stderr,"getaddrinfo: %s\n", gai_strerror(ecode));
|
||||
exit(3);
|
||||
}
|
||||
//Connexion au serveur
|
||||
ecode = connect(descSock, res->ai_addr, res->ai_addrlen);
|
||||
if (ecode == -1) {
|
||||
close(descSock);
|
||||
freeaddrinfo(res);
|
||||
perror("Erreur connect");
|
||||
exit(5);
|
||||
}
|
||||
freeaddrinfo(res);
|
||||
//Echange de donneés avec le serveur
|
||||
ecode = read(descSock, buffer, MAXBUFFERLEN);
|
||||
if (ecode == -1) {perror("Problème de lecture\n"); exit(6);}
|
||||
buffer[ecode] = '\0';
|
||||
printf("MESSAGE RECU DU SERVEUR: \"%s\".\n",buffer);
|
||||
//Fermeture de la socket
|
||||
close(descSock);
|
||||
}
|
||||
|
|
@ -0,0 +1,336 @@
|
|||
// Bibliothéques
|
||||
// ==============================================
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
// Constantes
|
||||
// ==============================================
|
||||
|
||||
#define SERVADDR "127.0.0.1" // Définition de l'adresse IP d'écoute
|
||||
#define SERVPORT "4444" // Définition du port d'écoute, si 0 port choisi dynamiquement
|
||||
#define LISTENLEN 2 // Taille du tampon de demandes de connexions, MAX 2
|
||||
#define MAXBUFFERLEN 1024
|
||||
#define MAXHOSTLEN 64
|
||||
#define MAXPORTLEN 6
|
||||
|
||||
|
||||
// PROCEDURES
|
||||
// ==============================================
|
||||
|
||||
void decoupeLogin( char *entreeUtilisateur, char *login, char *server );
|
||||
void waitingForUser(int *socket,char *buffer,int *n);
|
||||
void waitingForServer(int *socket,char *buffer,int *n);
|
||||
|
||||
|
||||
// MAIN
|
||||
// ==============================================
|
||||
|
||||
int main( int argc, char *argv[] ) {
|
||||
|
||||
// Variables [ SERVEUR ] >> [ PROXY ] - [ PROXY ] >> [ SERVEUR ]
|
||||
// ==============================================
|
||||
|
||||
int sockServeur; // Descripteur pour le socket
|
||||
int fncRet; // Stock le retour des fonctions
|
||||
struct addrinfo *resBIS; // Résultat de la focntion getaddrinfo
|
||||
struct addrinfo hintsBIS = {0, AF_INET, SOCK_STREAM, 0, 0, NULL, NULL, NULL}; // Filtra pour le getaddrinfo
|
||||
char bufferFTP[MAXBUFFERLEN];
|
||||
|
||||
// Variables [ CLIENT ] >> [ PROXY ] - [ PROXY ] >> [ CLIENT ]
|
||||
// ==============================================
|
||||
|
||||
char serverAddr[MAXHOSTLEN]; // Adresse du serveur
|
||||
char serverPort[MAXPORTLEN]; // Port du server
|
||||
char buffer[MAXBUFFERLEN]; // Tampon pour écrire sur le socket
|
||||
char bufferRcv[MAXBUFFERLEN]; // Tampon pour écrire sur le socket
|
||||
int descSockRDV; // Descripteur de socket de rendez-vous
|
||||
int ecode; // Code retour des fonctions
|
||||
int descSockCOM; // Descripteur de socket de communication
|
||||
int n = 0;
|
||||
int lenRCV = 0;
|
||||
|
||||
|
||||
struct addrinfo hints; // Filtre pour la fonction get_addr_info
|
||||
struct addrinfo *res; // Resultat get_addr_info
|
||||
struct sockaddr_storage myinfo; // Informations sur la connexion de RDV
|
||||
struct sockaddr_storage from; // Informations sur le client connecté
|
||||
|
||||
|
||||
char entreeUtilisateur[40]; // login@server
|
||||
char login[20]; // Isoler le login
|
||||
char serveur[20]; // Isoler le serveur
|
||||
|
||||
|
||||
socklen_t len = sizeof( struct sockaddr_storage ); // Variable utilisée pour stocker les longueurs des structures de socket
|
||||
|
||||
pid_t pid;
|
||||
|
||||
// Initialisation de la socket de RDV IPv4/TCP
|
||||
|
||||
descSockRDV = socket( AF_INET, SOCK_STREAM, 0 );
|
||||
|
||||
// Mise à zéro de la variable hints,entreeUtilisateur,loggin..
|
||||
|
||||
memset( &hints, 0, sizeof( hints ) );
|
||||
memset( entreeUtilisateur, 0, sizeof( entreeUtilisateur ) );
|
||||
memset( login, 0, sizeof( login ) );
|
||||
memset( serveur, 0, sizeof( serveur ) );
|
||||
memset( buffer, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferRcv, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferFTP, 0, sizeof( MAXBUFFERLEN ) );
|
||||
|
||||
// Initailisation de la variable hints
|
||||
|
||||
hints.ai_flags = AI_PASSIVE; // mode serveur, nous allons utiliser la fonction bind
|
||||
hints.ai_socktype = SOCK_STREAM; // TCP
|
||||
hints.ai_family = AF_INET; // IPv4
|
||||
|
||||
// Récupération des informations du serveur > Machine locale
|
||||
|
||||
ecode = getaddrinfo( SERVADDR, SERVPORT, &hints, &res );
|
||||
|
||||
// Publication de la socket
|
||||
|
||||
ecode = bind( descSockRDV, res->ai_addr, res->ai_addrlen );
|
||||
|
||||
ecode = listen( descSockRDV, LISTENLEN );
|
||||
|
||||
// Attente connexion du client
|
||||
// Lorsque demande de connexion, creation d'un processus fils et d'un socket de communication avec le client, MAX 2 attentes
|
||||
|
||||
while( 1 == 1 ) {
|
||||
|
||||
descSockCOM = accept( descSockRDV, ( struct sockaddr * ) &from, &len );
|
||||
|
||||
if( ( pid= fork() ) == 0) {
|
||||
|
||||
close( descSockRDV ); // On ferme le socketRDV on s'occupe seulement de gérer le socket actuel
|
||||
|
||||
strcpy( buffer, "220 Bienvenue sur le proxyFTP de aurehacks\r\n" ); // Echange de données avec le client connecté
|
||||
|
||||
send( descSockCOM, buffer, strlen( buffer ), 0 ); // Ecriture sur le socket
|
||||
|
||||
while(1 == 1) { // Gestion des commandes
|
||||
|
||||
waitingForUser(&descSockCOM,bufferRcv,&n);
|
||||
|
||||
// Gestion de l'authentification
|
||||
// ==============================================
|
||||
|
||||
if( strstr( bufferRcv,"USER") ) {
|
||||
|
||||
memset( buffer, 0, sizeof( MAXBUFFERLEN ) );
|
||||
|
||||
decoupeLogin(bufferRcv,login,serveur); // On isole le loggin ainsi que l'IP/URL du serveur
|
||||
|
||||
strcat(buffer,login); // On formate le login
|
||||
|
||||
sockServeur = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
getaddrinfo(serveur,"21",&hints,&res);
|
||||
|
||||
connect(sockServeur, res->ai_addr, res->ai_addrlen);
|
||||
|
||||
|
||||
|
||||
// [1] Message de Bienvenue
|
||||
// ==============================================
|
||||
|
||||
waitingForServer(&sockServeur,bufferFTP,&n);
|
||||
|
||||
// ==============================================
|
||||
|
||||
|
||||
|
||||
// [2] Envoi de "USER login"
|
||||
// ==============================================
|
||||
|
||||
send( sockServeur, buffer, strlen( buffer ), 0 );
|
||||
send( sockServeur, "\r\n", 2, 0 );
|
||||
|
||||
waitingForServer(&sockServeur,bufferFTP,&n);
|
||||
|
||||
// ==============================================
|
||||
|
||||
|
||||
// [3] Réception du "331 password required" et transmission au client
|
||||
// ==============================================
|
||||
|
||||
strcpy( bufferFTP, "331 required password\r\n" ); // Cas special SINON ON EN DIRECT send( descSockCOM, strcat(bufferFTP,"\r\n"), strlen( bufferFTP ), 0 );
|
||||
|
||||
send( descSockCOM, bufferFTP, strlen( bufferFTP ), 0 );
|
||||
|
||||
waitingForUser(&descSockCOM,bufferRcv,&n);
|
||||
|
||||
// ==============================================
|
||||
|
||||
|
||||
|
||||
// [4] Réception du "PASS mdp" (mot de passe du client) et transmission au serveur
|
||||
// ==============================================
|
||||
|
||||
send( sockServeur, bufferRcv, strlen( bufferRcv ), 0 );
|
||||
send( sockServeur, "\r\n", 2, 0 );
|
||||
|
||||
waitingForServer(&sockServeur,bufferFTP,&n);
|
||||
|
||||
// ==============================================
|
||||
|
||||
|
||||
|
||||
|
||||
// [5] Réception du "220 logged in" et transmission au client
|
||||
// ==============================================
|
||||
|
||||
strcpy( bufferFTP, "220 Logged IN !\r\n" ); // Cas special SINON ON EN DIRECT send( descSockCOM, strcat(bufferFTP,"\r\n"), strlen( bufferFTP ), 0 );
|
||||
|
||||
send( descSockCOM, bufferFTP, strlen( bufferFTP ), 0 );
|
||||
|
||||
waitingForUser(&descSockCOM,bufferRcv,&n);
|
||||
|
||||
// ==============================================
|
||||
|
||||
|
||||
// On clean les buffers
|
||||
|
||||
memset( buffer, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferRcv, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferFTP, 0, sizeof( MAXBUFFERLEN ) );
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Gestion du mode actif
|
||||
// ==============================================
|
||||
|
||||
if( strncmp( bufferRcv,"PORT", 4 ) ) {
|
||||
|
||||
n = 0;
|
||||
|
||||
// On clean les buffers
|
||||
|
||||
memset( buffer, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferRcv, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferFTP, 0, sizeof( MAXBUFFERLEN ) );
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Gestion du mode passif
|
||||
// ==============================================
|
||||
|
||||
if( strncmp( bufferRcv,"PASSV", 5 ) ) {
|
||||
|
||||
n = 0;
|
||||
|
||||
// On clean les buffers
|
||||
|
||||
memset( buffer, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferRcv, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferFTP, 0, sizeof( MAXBUFFERLEN ) );
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Gestion de la fermeture de session
|
||||
// ==============================================
|
||||
|
||||
|
||||
if( strncmp( bufferRcv,"QUIT", 4 ) ) {
|
||||
|
||||
break; // On quitte la boucle lorsque que l'on reçoit la commande "QUIT"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
freeaddrinfo(res);
|
||||
|
||||
close( descSockCOM );
|
||||
close( sockServeur );
|
||||
|
||||
// Fin du fils
|
||||
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
close( descSockRDV );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// decoupeLogin
|
||||
// ==============================================
|
||||
|
||||
void decoupeLogin( char *entreeUtilisateur, char *login, char *server ) {
|
||||
|
||||
int i,j = 0;
|
||||
|
||||
for( i=0; i<strlen( entreeUtilisateur ); i++) {
|
||||
|
||||
if( entreeUtilisateur[i] != '@' )
|
||||
login[i] = entreeUtilisateur[i];
|
||||
|
||||
if( entreeUtilisateur[i] == '@' ) {
|
||||
|
||||
i++;
|
||||
|
||||
while( entreeUtilisateur[i] != '\0' ) {
|
||||
|
||||
server[j] = entreeUtilisateur[i];
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void waitingForUser(int *socket,char *buffer,int *n) {
|
||||
|
||||
*n = 0;
|
||||
|
||||
while(1 == 1) { // Gestion du buffer
|
||||
|
||||
recv( *socket, buffer+( *n ), 1, 0 );
|
||||
|
||||
if( buffer[*n] == '\n' && buffer[( *n )-1] == '\r') {
|
||||
|
||||
buffer[*n] = '\0';
|
||||
buffer[( *n )-1] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
( *n )++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void waitingForServer(int *socket,char *buffer,int *n) {
|
||||
|
||||
*n = 0;
|
||||
|
||||
while(1 == 1) { // Gestion du buffer
|
||||
|
||||
recv( *socket, buffer+( *n ), 1, 0 );
|
||||
|
||||
if( buffer[*n] == '\n' && buffer[( *n )-1] == '\r') {
|
||||
|
||||
buffer[*n] = '\0';
|
||||
buffer[( *n )-1] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
( *n )++;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#define SERVADDR "127.0.0.1" // Définition de l'adresse IP d'écoute
|
||||
#define SERVPORT "0" // Définition du port d'écoute, si 0 port choisi dynamiquement
|
||||
#define LISTENLEN 1 // Taille du tampon de demande de connexion
|
||||
#define MAXBUFFERLEN 1024
|
||||
#define MAXHOSTLEN 64
|
||||
#define MAXPORTLEN 6
|
||||
|
||||
|
||||
int main(){
|
||||
int ecode; // Code retour des fonctions
|
||||
char serverAddr[MAXHOSTLEN]; // Adresse du serveur
|
||||
char serverPort[MAXPORTLEN]; // Port du server
|
||||
int descSockRDV; // Descripteur de socket de rendez-vous
|
||||
int descSockCOM; // Descripteur de socket de communication
|
||||
struct addrinfo hints; // Contrôle la fonction getaddrinfo
|
||||
struct addrinfo *res; // Contient le résultat de la fonction getaddrinfo
|
||||
struct sockaddr_storage myinfo; // Informations sur la connexion de RDV
|
||||
struct sockaddr_storage from; // Informations sur le client connecté
|
||||
socklen_t len; // Variable utilisée pour stocker les
|
||||
// longueurs des structures de socket
|
||||
char buffer[MAXBUFFERLEN]; // Tampon de communication entre le client et le serveur
|
||||
// Initialisation de la socket de RDV IPv4/TCP
|
||||
descSockRDV = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (descSockRDV == -1) {
|
||||
perror("Erreur création socket RDV\n");
|
||||
exit(2);
|
||||
}
|
||||
// Publication de la socket au niveau du système
|
||||
// Assignation d'une adresse IP et un numéro de port
|
||||
// Mise à zéro de hints
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
// Initailisation de hints
|
||||
hints.ai_flags = AI_PASSIVE; // mode serveur, nous allons utiliser la fonction bind
|
||||
hints.ai_socktype = SOCK_STREAM; // TCP
|
||||
hints.ai_family = AF_INET; // seules les adresses IPv4 seront présentées par
|
||||
// la fonction getaddrinfo
|
||||
|
||||
// Récupération des informations du serveur
|
||||
ecode = getaddrinfo(SERVADDR, SERVPORT, &hints, &res);
|
||||
if (ecode) {
|
||||
fprintf(stderr,"getaddrinfo: %s\n", gai_strerror(ecode));
|
||||
exit(1);
|
||||
}
|
||||
// Publication de la socket
|
||||
ecode = bind(descSockRDV, res->ai_addr, res->ai_addrlen);
|
||||
if (ecode == -1) {
|
||||
perror("Erreur liaison de la socket de RDV");
|
||||
exit(3);
|
||||
}
|
||||
// Nous n'avons plus besoin de cette liste chainée addrinfo
|
||||
freeaddrinfo(res);
|
||||
// Récuppération du nom de la machine et du numéro de port pour affichage à l'écran
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
len=sizeof(struct sockaddr_storage);
|
||||
ecode=getsockname(descSockRDV, (struct sockaddr *) &myinfo, &len);
|
||||
if (ecode == -1)
|
||||
{
|
||||
perror("SERVEUR: getsockname");
|
||||
exit(4);
|
||||
}
|
||||
ecode = getnameinfo((struct sockaddr*)&myinfo, sizeof(myinfo), serverAddr,MAXHOSTLEN,
|
||||
serverPort, MAXPORTLEN, NI_NUMERICHOST | NI_NUMERICSERV);
|
||||
if (ecode != 0) {
|
||||
fprintf(stderr, "error in getnameinfo: %s\n", gai_strerror(ecode));
|
||||
exit(4);
|
||||
}
|
||||
printf("L'adresse d'ecoute est: %s\n", serverAddr);
|
||||
printf("Le port d'ecoute est: %s\n", serverPort);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Definition de la taille du tampon contenant les demandes de connexion
|
||||
ecode = listen(descSockRDV, LISTENLEN);
|
||||
if (ecode == -1) {
|
||||
perror("Erreur initialisation buffer d'écoute");
|
||||
exit(5);
|
||||
}
|
||||
while( 1 ){
|
||||
|
||||
|
||||
|
||||
len = sizeof(struct sockaddr_storage);
|
||||
// Attente connexion du client
|
||||
// Lorsque demande de connexion, creation d'une socket de communication avec le client
|
||||
descSockCOM = accept(descSockRDV, (struct sockaddr *) &from, &len);
|
||||
if (descSockCOM == -1){
|
||||
perror("Erreur accept\n");
|
||||
exit(6);
|
||||
}
|
||||
// Echange de données avec le client connecté
|
||||
strcpy(buffer, "BLABLABLA\n");
|
||||
|
||||
write(descSockCOM, buffer, strlen(buffer));
|
||||
//Fermeture de la connexion
|
||||
close(descSockCOM);
|
||||
|
||||
}
|
||||
close(descSockRDV);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
|
||||
static void* action1();
|
||||
static void* action2();
|
||||
|
||||
|
||||
pthread_t thread1, thread2;
|
||||
static int bool1 = 1;
|
||||
static int bool2 = 1;
|
||||
|
||||
|
||||
|
||||
int main(int argc, char* argv []){
|
||||
|
||||
pthread_create(&thread1, NULL, &action1, (void*) NULL);
|
||||
pthread_create(&thread2, NULL, &action2, (void*) NULL);
|
||||
|
||||
printf("THREADS CREATED\n===============\n");
|
||||
|
||||
sleep(3);
|
||||
bool1 = 0;
|
||||
sleep(3);
|
||||
bool2 = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void* action1(){
|
||||
while( bool1 ){
|
||||
printf("[THREAD] 1\n");
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
pthread_exit((void*) thread1);
|
||||
}
|
||||
|
||||
static void* action2(){
|
||||
while( bool2 ){
|
||||
printf("[THREAD] 2\n");
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
pthread_exit((void*) thread2);
|
||||
}
|
|
@ -0,0 +1,215 @@
|
|||
#include "proxy_ftp.h"
|
||||
|
||||
// DECLARATIONS
|
||||
static pthread_t userServer;
|
||||
static short unsigned int userServerState = 1;
|
||||
static char remoteAssignedPort[maxPortLen] = {'\0'};
|
||||
|
||||
/* headers */
|
||||
static void* testClient(char* host, char* port);
|
||||
static void* testServer();
|
||||
static void* testClientFTP();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*****************/
|
||||
/* CORPS DU PROG */
|
||||
/*****************/
|
||||
int main(int argc, char* argv[]){
|
||||
|
||||
/* client */
|
||||
if( argc > 2 && strcmp(argv[1],"c") == 0 )
|
||||
testClient("localhost", argv[2]);
|
||||
|
||||
/* server */
|
||||
else if( argc > 1 && strcmp(argv[1], "s") == 0 )
|
||||
testServer();
|
||||
|
||||
/* clientFTP */
|
||||
else if( argc > 1 && strcmp(argv[1], "f") == 0 )
|
||||
testClientFTP();
|
||||
|
||||
/* client + server (multithread) */
|
||||
else if( argc > 1 && strcmp(argv[1], "both") == 0 ){
|
||||
|
||||
pthread_create(&userServer, NULL, &testServer, (void*) NULL);
|
||||
|
||||
// on attends d'avoir le port
|
||||
while( strlen(remoteAssignedPort) == 0 );
|
||||
|
||||
// on lance le client en boucle
|
||||
while( strlen(remoteAssignedPort) != 0 )
|
||||
testClient("localhost", remoteAssignedPort);
|
||||
|
||||
pthread_join(userServer, (void*) NULL);
|
||||
pthread_exit((void*) userServer);
|
||||
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void* testClientFTP(){
|
||||
CLIENT_FTPREQUEST(FTP_HOST, FTP_PORT);
|
||||
return;
|
||||
|
||||
// char request[maxBuffLen];
|
||||
// char* response;
|
||||
|
||||
// while( 1 ){
|
||||
// // on vide les buffers
|
||||
// memset(&request, '\0', sizeof(request));
|
||||
// memset(&response, '\0', sizeof(response));
|
||||
|
||||
// printf("> ");
|
||||
// read_stdin(request, maxBuffLen);
|
||||
// // on supprime le dernier retour chariot
|
||||
// // request[strlen(request)-1] == '\0';
|
||||
|
||||
|
||||
|
||||
// CLIENT_REQUEST(FTP_HOST, FTP_PORT, request, &response);
|
||||
|
||||
// if( strlen(response) > 0 )
|
||||
// printf("%s\n", response);
|
||||
|
||||
// response = NULL;
|
||||
// }
|
||||
|
||||
// return;
|
||||
}
|
||||
|
||||
|
||||
static void* testClient(char* host, char* port){
|
||||
char request[maxBuffLen];
|
||||
char* response;
|
||||
|
||||
// on vide les buffers
|
||||
memset(&request, '\0', sizeof(request));
|
||||
memset(&response, '\0', sizeof(response));
|
||||
|
||||
printf("> ");
|
||||
read_stdin(request, maxBuffLen);
|
||||
// on supprime le dernier retour chariot
|
||||
// request[strlen(request)-1] == '\0';
|
||||
|
||||
|
||||
|
||||
// CLIENT_REQUEST(remoteHost, remotePort, "GET / HTTP/1.0\r\n\r\n", &response);
|
||||
CLIENT_REQUEST(host, port, request, &response);
|
||||
|
||||
if( strlen(response) > 0 )
|
||||
printf("%s\n", response);
|
||||
|
||||
response = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void* testServer(){
|
||||
int SOCKET; // contiendra la connection en cours
|
||||
char BUFFER[maxBuffLen]; // contiendra le BUFFER
|
||||
struct sockaddr_storage clientInfo; // contiendra les infos client
|
||||
char repeat; // sert à sortir de la boucle
|
||||
int nbReceived, nbSend; // contiendra les nb reçu && envoyé
|
||||
socklen_t len = sizeof(struct sockaddr_storage);
|
||||
|
||||
// retour de @DROP_SERVER
|
||||
char* serverPort; // contiendra le port
|
||||
int LISTENSOCK; // contiendra la socket d'écoute
|
||||
|
||||
|
||||
/* [0] On lance @DROP_SERVER
|
||||
==========================================================*/
|
||||
DROP_SERVER(remoteHost, &serverPort, &LISTENSOCK);
|
||||
|
||||
printf("Port: %s\n", serverPort);
|
||||
strcpy(remoteAssignedPort, serverPort);// PORT GLOBAL
|
||||
|
||||
while( userServerState ){
|
||||
|
||||
/* [1] Attente d'une demande de connection, puis création d'une socket
|
||||
============================================================================*/
|
||||
SOCKET = accept(LISTENSOCK, (struct sockaddr *) &clientInfo, &len);
|
||||
|
||||
if( DEBUGMOD ) printf("SOCKET: %d\n", SOCKET);
|
||||
|
||||
/* [2] On récupère les données reçues
|
||||
============================================================================*/
|
||||
nbReceived = read(SOCKET, BUFFER, sizeof(BUFFER)-1);
|
||||
|
||||
if( DEBUGMOD ) printf("Recu: %d\n", nbReceived);
|
||||
if( DEBUGMOD ) printf("Message: %s\n", BUFFER);
|
||||
|
||||
/* [3] Redirection vers le serveur FTP
|
||||
============================================================================*/
|
||||
// on redirige la réponse vers le serveur FTP distant
|
||||
char* ftp_response;
|
||||
CLIENT_REQUEST(FTP_HOST, FTP_PORT, BUFFER, &ftp_response);
|
||||
// printf("===FTP===\n%s\n", ftp_response);
|
||||
|
||||
/* [4] On analyse et renvoie la réponse à l'utilisateur
|
||||
============================================================================*/
|
||||
// formatBuffer(ftp_response);
|
||||
// MANAGE_RESPONSE(&SOCKET, ftp_response);
|
||||
|
||||
// on réponds au client
|
||||
formatBuffer(ftp_response);
|
||||
write(SOCKET, ftp_response, strlen(ftp_response)-1);
|
||||
|
||||
|
||||
/* [5] On ferme la SOCKET et vide les buffers
|
||||
============================================================================*/
|
||||
close(SOCKET);
|
||||
memset(&BUFFER, '\0', sizeof(BUFFER)); // on vide le buffer
|
||||
ftp_response = NULL;
|
||||
|
||||
|
||||
}
|
||||
|
||||
close(LISTENSOCK);
|
||||
strcpy(remoteAssignedPort, "\0");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* DROP_SERVER
|
||||
* INIT_CLIENT
|
||||
*
|
||||
* while(){
|
||||
* accept();
|
||||
* send
|
||||
* }
|
||||
*
|
||||
* EXIT_CLIENT
|
||||
* HALT_SERVER
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
|
@ -0,0 +1,39 @@
|
|||
/* global */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
|
||||
/* sys */
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
/* socket */
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h> // getaddrinfo, getnameinfo
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/* basis */
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
|
||||
/* debug */
|
||||
// #define DEBUGMOD FALSE // <Boolean> TRUE = débugmode activé
|
||||
#define DEBUGMOD TRUE // <Boolean> TRUE = débugmode activé
|
||||
|
||||
/* vars */
|
||||
#define remoteHost "localhost"
|
||||
#define remotePort "80"
|
||||
#define maxBuffLen 4096
|
||||
#define maxListLen 2
|
||||
#define maxHostLen 64
|
||||
#define maxPortLen 6
|
||||
|
||||
#define FTP_HOST "31.170.164.47"
|
||||
#define FTP_PORT "21"
|
||||
|
||||
/* local dependencies */
|
||||
#include "dep/utility.c"
|
||||
#include "dep/client.c"
|
||||
#include "dep/server.c"
|
Binary file not shown.
|
@ -0,0 +1,55 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
|
||||
static void* action1();
|
||||
static void* action2();
|
||||
|
||||
|
||||
pthread_t thread1, thread2;
|
||||
static int bool1 = 1;
|
||||
static int bool2 = 1;
|
||||
|
||||
|
||||
|
||||
int main(int argc, char* argv []){
|
||||
|
||||
pthread_create(&thread1, NULL, &action1, (void*) NULL);
|
||||
pthread_create(&thread2, NULL, &action2, (void*) NULL);
|
||||
|
||||
printf("THREADS CREATED\n===============\n");
|
||||
|
||||
sleep(3);
|
||||
bool1 = 0;
|
||||
sleep(3);
|
||||
bool2 = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void* action1(){
|
||||
while( bool1 ){
|
||||
printf("[THREAD] 1\n");
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
pthread_exit((void*) thread1);
|
||||
}
|
||||
|
||||
static void* action2(){
|
||||
while( bool2 ){
|
||||
printf("[THREAD] 2\n");
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
pthread_exit((void*) thread2);
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,64 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#define MAXHOSTLEN 64
|
||||
#define MAXPORTLEN 6
|
||||
#define MAXBUFFERLEN 1024
|
||||
int main(int argc, char* argv[]){
|
||||
int descSock; // Descripteur de la socket
|
||||
int ecode; // Retour des fonctions
|
||||
struct addrinfo *res; // Résultat de la focntion getaddrinfo
|
||||
struct addrinfo hints = { // Cette structure permet de contrôler l'exécution de la fonction getaddrinfo
|
||||
0,
|
||||
AF_INET, //seule les adresses IPv4 seront présentées par la fonctiongetaddrinfo
|
||||
SOCK_STREAM,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
char serverName[MAXHOSTLEN]; // Nom de la machine serveur
|
||||
char serverPort[MAXPORTLEN]; // Numéro de port
|
||||
char buffer[MAXBUFFERLEN]; // buffer stockant les messages échangés entre le client et le serveur
|
||||
//On teste les valeurs rentrées par l'utilisateur
|
||||
if (argc != 3){ perror("Mauvaise utilisation de la commande: <nom serveur> <numero de port>\n"); exit(1);}
|
||||
if (strlen(argv[1]) >= MAXHOSTLEN){ perror("Le nom de la machine serveur est trop long\n"); exit(2);}
|
||||
if (strlen(argv[2]) >= MAXPORTLEN){ perror("Le numero de port du serveur est trop long\n"); exit(2);}
|
||||
strncpy(serverName, argv[1], MAXHOSTLEN);
|
||||
serverName[MAXHOSTLEN-1] = '\0';
|
||||
strncpy(serverPort, argv[2], MAXPORTLEN);
|
||||
serverPort[MAXPORTLEN-1] = '\0';
|
||||
//Création de la socket IPv4/TCP
|
||||
descSock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (descSock == -1) {
|
||||
perror("Erreur creation socket");
|
||||
exit(4);
|
||||
}
|
||||
//Récupération des informations sur le serveur
|
||||
ecode = getaddrinfo(serverName,serverPort,&hints,&res);
|
||||
if (ecode){
|
||||
fprintf(stderr,"getaddrinfo: %s\n", gai_strerror(ecode));
|
||||
exit(3);
|
||||
}
|
||||
//Connexion au serveur
|
||||
ecode = connect(descSock, res->ai_addr, res->ai_addrlen);
|
||||
if (ecode == -1) {
|
||||
close(descSock);
|
||||
freeaddrinfo(res);
|
||||
perror("Erreur connect");
|
||||
exit(5);
|
||||
}
|
||||
freeaddrinfo(res);
|
||||
//Echange de donneés avec le serveur
|
||||
ecode = read(descSock, buffer, MAXBUFFERLEN);
|
||||
if (ecode == -1) {perror("Problème de lecture\n"); exit(6);}
|
||||
buffer[ecode] = '\0';
|
||||
printf("MESSAGE RECU DU SERVEUR: \"%s\".\n",buffer);
|
||||
//Fermeture de la socket
|
||||
close(descSock);
|
||||
}
|
||||
|
|
@ -0,0 +1,336 @@
|
|||
// Bibliothéques
|
||||
// ==============================================
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
// Constantes
|
||||
// ==============================================
|
||||
|
||||
#define SERVADDR "127.0.0.1" // Définition de l'adresse IP d'écoute
|
||||
#define SERVPORT "4444" // Définition du port d'écoute, si 0 port choisi dynamiquement
|
||||
#define LISTENLEN 2 // Taille du tampon de demandes de connexions, MAX 2
|
||||
#define MAXBUFFERLEN 1024
|
||||
#define MAXHOSTLEN 64
|
||||
#define MAXPORTLEN 6
|
||||
|
||||
|
||||
// PROCEDURES
|
||||
// ==============================================
|
||||
|
||||
void decoupeLogin( char *entreeUtilisateur, char *login, char *server );
|
||||
void waitingForUser(int *socket,char *buffer,int *n);
|
||||
void waitingForServer(int *socket,char *buffer,int *n);
|
||||
|
||||
|
||||
// MAIN
|
||||
// ==============================================
|
||||
|
||||
int main( int argc, char *argv[] ) {
|
||||
|
||||
// Variables [ SERVEUR ] >> [ PROXY ] - [ PROXY ] >> [ SERVEUR ]
|
||||
// ==============================================
|
||||
|
||||
int sockServeur; // Descripteur pour le socket
|
||||
int fncRet; // Stock le retour des fonctions
|
||||
struct addrinfo *resBIS; // Résultat de la focntion getaddrinfo
|
||||
struct addrinfo hintsBIS = {0, AF_INET, SOCK_STREAM, 0, 0, NULL, NULL, NULL}; // Filtra pour le getaddrinfo
|
||||
char bufferFTP[MAXBUFFERLEN];
|
||||
|
||||
// Variables [ CLIENT ] >> [ PROXY ] - [ PROXY ] >> [ CLIENT ]
|
||||
// ==============================================
|
||||
|
||||
char serverAddr[MAXHOSTLEN]; // Adresse du serveur
|
||||
char serverPort[MAXPORTLEN]; // Port du server
|
||||
char buffer[MAXBUFFERLEN]; // Tampon pour écrire sur le socket
|
||||
char bufferRcv[MAXBUFFERLEN]; // Tampon pour écrire sur le socket
|
||||
int descSockRDV; // Descripteur de socket de rendez-vous
|
||||
int ecode; // Code retour des fonctions
|
||||
int descSockCOM; // Descripteur de socket de communication
|
||||
int n = 0;
|
||||
int lenRCV = 0;
|
||||
|
||||
|
||||
struct addrinfo hints; // Filtre pour la fonction get_addr_info
|
||||
struct addrinfo *res; // Resultat get_addr_info
|
||||
struct sockaddr_storage myinfo; // Informations sur la connexion de RDV
|
||||
struct sockaddr_storage from; // Informations sur le client connecté
|
||||
|
||||
|
||||
char entreeUtilisateur[40]; // login@server
|
||||
char login[20]; // Isoler le login
|
||||
char serveur[20]; // Isoler le serveur
|
||||
|
||||
|
||||
socklen_t len = sizeof( struct sockaddr_storage ); // Variable utilisée pour stocker les longueurs des structures de socket
|
||||
|
||||
pid_t pid;
|
||||
|
||||
// Initialisation de la socket de RDV IPv4/TCP
|
||||
|
||||
descSockRDV = socket( AF_INET, SOCK_STREAM, 0 );
|
||||
|
||||
// Mise à zéro de la variable hints,entreeUtilisateur,loggin..
|
||||
|
||||
memset( &hints, 0, sizeof( hints ) );
|
||||
memset( entreeUtilisateur, 0, sizeof( entreeUtilisateur ) );
|
||||
memset( login, 0, sizeof( login ) );
|
||||
memset( serveur, 0, sizeof( serveur ) );
|
||||
memset( buffer, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferRcv, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferFTP, 0, sizeof( MAXBUFFERLEN ) );
|
||||
|
||||
// Initailisation de la variable hints
|
||||
|
||||
hints.ai_flags = AI_PASSIVE; // mode serveur, nous allons utiliser la fonction bind
|
||||
hints.ai_socktype = SOCK_STREAM; // TCP
|
||||
hints.ai_family = AF_INET; // IPv4
|
||||
|
||||
// Récupération des informations du serveur > Machine locale
|
||||
|
||||
ecode = getaddrinfo( SERVADDR, SERVPORT, &hints, &res );
|
||||
|
||||
// Publication de la socket
|
||||
|
||||
ecode = bind( descSockRDV, res->ai_addr, res->ai_addrlen );
|
||||
|
||||
ecode = listen( descSockRDV, LISTENLEN );
|
||||
|
||||
// Attente connexion du client
|
||||
// Lorsque demande de connexion, creation d'un processus fils et d'un socket de communication avec le client, MAX 2 attentes
|
||||
|
||||
while( 1 == 1 ) {
|
||||
|
||||
descSockCOM = accept( descSockRDV, ( struct sockaddr * ) &from, &len );
|
||||
|
||||
if( ( pid= fork() ) == 0) {
|
||||
|
||||
close( descSockRDV ); // On ferme le socketRDV on s'occupe seulement de gérer le socket actuel
|
||||
|
||||
strcpy( buffer, "220 Bienvenue sur le proxyFTP de aurehacks\r\n" ); // Echange de données avec le client connecté
|
||||
|
||||
send( descSockCOM, buffer, strlen( buffer ), 0 ); // Ecriture sur le socket
|
||||
|
||||
while(1 == 1) { // Gestion des commandes
|
||||
|
||||
waitingForUser(&descSockCOM,bufferRcv,&n);
|
||||
|
||||
// Gestion de l'authentification
|
||||
// ==============================================
|
||||
|
||||
if( strstr( bufferRcv,"USER") ) {
|
||||
|
||||
memset( buffer, 0, sizeof( MAXBUFFERLEN ) );
|
||||
|
||||
decoupeLogin(bufferRcv,login,serveur); // On isole le loggin ainsi que l'IP/URL du serveur
|
||||
|
||||
strcat(buffer,login); // On formate le login
|
||||
|
||||
sockServeur = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
getaddrinfo(serveur,"21",&hints,&res);
|
||||
|
||||
connect(sockServeur, res->ai_addr, res->ai_addrlen);
|
||||
|
||||
|
||||
|
||||
// [1] Message de Bienvenue
|
||||
// ==============================================
|
||||
|
||||
waitingForServer(&sockServeur,bufferFTP,&n);
|
||||
|
||||
// ==============================================
|
||||
|
||||
|
||||
|
||||
// [2] Envoi de "USER login"
|
||||
// ==============================================
|
||||
|
||||
send( sockServeur, buffer, strlen( buffer ), 0 );
|
||||
send( sockServeur, "\r\n", 2, 0 );
|
||||
|
||||
waitingForServer(&sockServeur,bufferFTP,&n);
|
||||
|
||||
// ==============================================
|
||||
|
||||
|
||||
// [3] Réception du "331 password required" et transmission au client
|
||||
// ==============================================
|
||||
|
||||
strcpy( bufferFTP, "331 required password\r\n" ); // Cas special SINON ON EN DIRECT send( descSockCOM, strcat(bufferFTP,"\r\n"), strlen( bufferFTP ), 0 );
|
||||
|
||||
send( descSockCOM, bufferFTP, strlen( bufferFTP ), 0 );
|
||||
|
||||
waitingForUser(&descSockCOM,bufferRcv,&n);
|
||||
|
||||
// ==============================================
|
||||
|
||||
|
||||
|
||||
// [4] Réception du "PASS mdp" (mot de passe du client) et transmission au serveur
|
||||
// ==============================================
|
||||
|
||||
send( sockServeur, bufferRcv, strlen( bufferRcv ), 0 );
|
||||
send( sockServeur, "\r\n", 2, 0 );
|
||||
|
||||
waitingForServer(&sockServeur,bufferFTP,&n);
|
||||
|
||||
// ==============================================
|
||||
|
||||
|
||||
|
||||
|
||||
// [5] Réception du "220 logged in" et transmission au client
|
||||
// ==============================================
|
||||
|
||||
strcpy( bufferFTP, "220 Logged IN !\r\n" ); // Cas special SINON ON EN DIRECT send( descSockCOM, strcat(bufferFTP,"\r\n"), strlen( bufferFTP ), 0 );
|
||||
|
||||
send( descSockCOM, bufferFTP, strlen( bufferFTP ), 0 );
|
||||
|
||||
waitingForUser(&descSockCOM,bufferRcv,&n);
|
||||
|
||||
// ==============================================
|
||||
|
||||
|
||||
// On clean les buffers
|
||||
|
||||
memset( buffer, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferRcv, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferFTP, 0, sizeof( MAXBUFFERLEN ) );
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Gestion du mode actif
|
||||
// ==============================================
|
||||
|
||||
if( strncmp( bufferRcv,"PORT", 4 ) ) {
|
||||
|
||||
n = 0;
|
||||
|
||||
// On clean les buffers
|
||||
|
||||
memset( buffer, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferRcv, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferFTP, 0, sizeof( MAXBUFFERLEN ) );
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Gestion du mode passif
|
||||
// ==============================================
|
||||
|
||||
if( strncmp( bufferRcv,"PASSV", 5 ) ) {
|
||||
|
||||
n = 0;
|
||||
|
||||
// On clean les buffers
|
||||
|
||||
memset( buffer, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferRcv, 0, sizeof( MAXBUFFERLEN ) );
|
||||
memset( bufferFTP, 0, sizeof( MAXBUFFERLEN ) );
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Gestion de la fermeture de session
|
||||
// ==============================================
|
||||
|
||||
|
||||
if( strncmp( bufferRcv,"QUIT", 4 ) ) {
|
||||
|
||||
break; // On quitte la boucle lorsque que l'on reçoit la commande "QUIT"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
freeaddrinfo(res);
|
||||
|
||||
close( descSockCOM );
|
||||
close( sockServeur );
|
||||
|
||||
// Fin du fils
|
||||
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
close( descSockRDV );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// decoupeLogin
|
||||
// ==============================================
|
||||
|
||||
void decoupeLogin( char *entreeUtilisateur, char *login, char *server ) {
|
||||
|
||||
int i,j = 0;
|
||||
|
||||
for( i=0; i<strlen( entreeUtilisateur ); i++) {
|
||||
|
||||
if( entreeUtilisateur[i] != '@' )
|
||||
login[i] = entreeUtilisateur[i];
|
||||
|
||||
if( entreeUtilisateur[i] == '@' ) {
|
||||
|
||||
i++;
|
||||
|
||||
while( entreeUtilisateur[i] != '\0' ) {
|
||||
|
||||
server[j] = entreeUtilisateur[i];
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void waitingForUser(int *socket,char *buffer,int *n) {
|
||||
|
||||
*n = 0;
|
||||
|
||||
while(1 == 1) { // Gestion du buffer
|
||||
|
||||
recv( *socket, buffer+( *n ), 1, 0 );
|
||||
|
||||
if( buffer[*n] == '\n' && buffer[( *n )-1] == '\r') {
|
||||
|
||||
buffer[*n] = '\0';
|
||||
buffer[( *n )-1] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
( *n )++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void waitingForServer(int *socket,char *buffer,int *n) {
|
||||
|
||||
*n = 0;
|
||||
|
||||
while(1 == 1) { // Gestion du buffer
|
||||
|
||||
recv( *socket, buffer+( *n ), 1, 0 );
|
||||
|
||||
if( buffer[*n] == '\n' && buffer[( *n )-1] == '\r') {
|
||||
|
||||
buffer[*n] = '\0';
|
||||
buffer[( *n )-1] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
( *n )++;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#define SERVADDR "127.0.0.1" // Définition de l'adresse IP d'écoute
|
||||
#define SERVPORT "0" // Définition du port d'écoute, si 0 port choisi dynamiquement
|
||||
#define LISTENLEN 1 // Taille du tampon de demande de connexion
|
||||
#define MAXBUFFERLEN 1024
|
||||
#define MAXHOSTLEN 64
|
||||
#define MAXPORTLEN 6
|
||||
|
||||
|
||||
int main(){
|
||||
int ecode; // Code retour des fonctions
|
||||
char serverAddr[MAXHOSTLEN]; // Adresse du serveur
|
||||
char serverPort[MAXPORTLEN]; // Port du server
|
||||
int descSockRDV; // Descripteur de socket de rendez-vous
|
||||
int descSockCOM; // Descripteur de socket de communication
|
||||
struct addrinfo hints; // Contrôle la fonction getaddrinfo
|
||||
struct addrinfo *res; // Contient le résultat de la fonction getaddrinfo
|
||||
struct sockaddr_storage myinfo; // Informations sur la connexion de RDV
|
||||
struct sockaddr_storage from; // Informations sur le client connecté
|
||||
socklen_t len; // Variable utilisée pour stocker les
|
||||
// longueurs des structures de socket
|
||||
char buffer[MAXBUFFERLEN]; // Tampon de communication entre le client et le serveur
|
||||
// Initialisation de la socket de RDV IPv4/TCP
|
||||
descSockRDV = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (descSockRDV == -1) {
|
||||
perror("Erreur création socket RDV\n");
|
||||
exit(2);
|
||||
}
|
||||
// Publication de la socket au niveau du système
|
||||
// Assignation d'une adresse IP et un numéro de port
|
||||
// Mise à zéro de hints
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
// Initailisation de hints
|
||||
hints.ai_flags = AI_PASSIVE; // mode serveur, nous allons utiliser la fonction bind
|
||||
hints.ai_socktype = SOCK_STREAM; // TCP
|
||||
hints.ai_family = AF_INET; // seules les adresses IPv4 seront présentées par
|
||||
// la fonction getaddrinfo
|
||||
|
||||
// Récupération des informations du serveur
|
||||
ecode = getaddrinfo(SERVADDR, SERVPORT, &hints, &res);
|
||||
if (ecode) {
|
||||
fprintf(stderr,"getaddrinfo: %s\n", gai_strerror(ecode));
|
||||
exit(1);
|
||||
}
|
||||
// Publication de la socket
|
||||
ecode = bind(descSockRDV, res->ai_addr, res->ai_addrlen);
|
||||
if (ecode == -1) {
|
||||
perror("Erreur liaison de la socket de RDV");
|
||||
exit(3);
|
||||
}
|
||||
// Nous n'avons plus besoin de cette liste chainée addrinfo
|
||||
freeaddrinfo(res);
|
||||
// Récuppération du nom de la machine et du numéro de port pour affichage à l'écran
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
len=sizeof(struct sockaddr_storage);
|
||||
ecode=getsockname(descSockRDV, (struct sockaddr *) &myinfo, &len);
|
||||
if (ecode == -1)
|
||||
{
|
||||
perror("SERVEUR: getsockname");
|
||||
exit(4);
|
||||
}
|
||||
ecode = getnameinfo((struct sockaddr*)&myinfo, sizeof(myinfo), serverAddr,MAXHOSTLEN,
|
||||
serverPort, MAXPORTLEN, NI_NUMERICHOST | NI_NUMERICSERV);
|
||||
if (ecode != 0) {
|
||||
fprintf(stderr, "error in getnameinfo: %s\n", gai_strerror(ecode));
|
||||
exit(4);
|
||||
}
|
||||
printf("L'adresse d'ecoute est: %s\n", serverAddr);
|
||||
printf("Le port d'ecoute est: %s\n", serverPort);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Definition de la taille du tampon contenant les demandes de connexion
|
||||
ecode = listen(descSockRDV, LISTENLEN);
|
||||
if (ecode == -1) {
|
||||
perror("Erreur initialisation buffer d'écoute");
|
||||
exit(5);
|
||||
}
|
||||
while( 1 ){
|
||||
|
||||
|
||||
|
||||
len = sizeof(struct sockaddr_storage);
|
||||
// Attente connexion du client
|
||||
// Lorsque demande de connexion, creation d'une socket de communication avec le client
|
||||
descSockCOM = accept(descSockRDV, (struct sockaddr *) &from, &len);
|
||||
if (descSockCOM == -1){
|
||||
perror("Erreur accept\n");
|
||||
exit(6);
|
||||
}
|
||||
// Echange de données avec le client connecté
|
||||
strcpy(buffer, "BLABLABLA\n");
|
||||
|
||||
write(descSockCOM, buffer, strlen(buffer));
|
||||
//Fermeture de la connexion
|
||||
close(descSockCOM);
|
||||
|
||||
}
|
||||
close(descSockRDV);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,193 @@
|
|||
#include "client.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void CLIENT_REQUEST(char* serverHost, char* serverPort, char* pRequest, char** pAnswer){
|
||||
if( DEBUGMOD ) printf("====== CLIENT_REQUEST(%s, %s, %s, %s) ======\n\n", serverHost, serverPort, pRequest, *pAnswer);
|
||||
|
||||
struct addrinfo hints; // contiendra le filtre/format
|
||||
struct addrinfo* addrinfo; // contiendra les infos
|
||||
int SOCKET, CONNECT; // file_desc(s)
|
||||
char BUFFER[maxBuffLen]; // BUFFER de communication
|
||||
// char pAnswer[maxBuffLen] = {0}; // on vide la réponse (contiendra la réponse du serveur)
|
||||
|
||||
/* [1] On définit le filtre/format
|
||||
=======================================================*/
|
||||
memset(&hints, 0, sizeof(struct addrinfo)); // on vide le filtre
|
||||
hints.ai_family = AF_UNSPEC; // Allow IPv4 ou IPv6
|
||||
hints.ai_socktype = SOCK_STREAM; // TCP (SOCK_DGRAM = UDP)
|
||||
hints.ai_flags = 0; // non spécifié
|
||||
hints.ai_protocol = 0; // non spécifié
|
||||
|
||||
if( DEBUGMOD ) printf("============HINTS===========\n");
|
||||
if( DEBUGMOD ) printf( "AI_FLAGS = %d\n", hints.ai_flags ); // int
|
||||
if( DEBUGMOD ) printf( "AI_FAMILY = %d\n", hints.ai_family ); // int
|
||||
if( DEBUGMOD ) printf( "AI_SOCKTYPE = %d\n", hints.ai_socktype ); // int
|
||||
if( DEBUGMOD ) printf( "AI_PROTOCOL = %d\n", hints.ai_protocol ); // int
|
||||
if( DEBUGMOD ) printf( "AI_ADDRLEN = %d\n", hints.ai_addrlen ); // int
|
||||
if( DEBUGMOD ) printf("\n");
|
||||
|
||||
|
||||
/* [2] On récupère les infos
|
||||
=======================================================*/
|
||||
getaddrinfo(serverHost, serverPort, &hints, &addrinfo);
|
||||
|
||||
if( DEBUGMOD ) printf("=============RES============\n");
|
||||
if( DEBUGMOD ) printf( "AI_FLAGS = %d\n", addrinfo->ai_flags ); // int
|
||||
if( DEBUGMOD ) printf( "AI_FAMILY = %d\n", addrinfo->ai_family ); // int
|
||||
if( DEBUGMOD ) printf( "AI_SOCKTYPE = %d\n", addrinfo->ai_socktype ); // int
|
||||
if( DEBUGMOD ) printf( "AI_PROTOCOL = %d\n", addrinfo->ai_protocol ); // int
|
||||
if( DEBUGMOD ) printf( "AI_ADDRLEN = %d\n", addrinfo->ai_addrlen ); // int
|
||||
if( DEBUGMOD ) printf("\n");
|
||||
|
||||
/* [3] Création de la socket
|
||||
=======================================================*/
|
||||
SOCKET = socket(addrinfo->ai_family, addrinfo->ai_socktype, 0);
|
||||
|
||||
if( DEBUGMOD ) printf("SOCKET = %d\n", SOCKET);
|
||||
|
||||
// si erreur
|
||||
if( SOCKET == -1 ) return;
|
||||
|
||||
/* [4] On établit la connection
|
||||
=======================================================*/
|
||||
CONNECT = connect(
|
||||
SOCKET,
|
||||
addrinfo->ai_addr,
|
||||
addrinfo->ai_addrlen
|
||||
);
|
||||
|
||||
if( DEBUGMOD ) printf("CONNECT = %d\n", CONNECT);
|
||||
|
||||
// si erreur
|
||||
if( CONNECT == -1 ) return;
|
||||
|
||||
// on a plus besoin des infos de l'adresse
|
||||
freeaddrinfo(addrinfo);
|
||||
|
||||
|
||||
/* [5] On écrit sur la socket
|
||||
=======================================================*/
|
||||
int nbSend = swrite(&SOCKET, pRequest);
|
||||
|
||||
if( DEBUGMOD ) printf("nbSend: %d\n", nbSend);
|
||||
if( DEBUGMOD ) printf("Message: %s\n", pRequest);
|
||||
|
||||
// si pas tout envoyé
|
||||
if( strlen(pRequest) != nbSend ) return;
|
||||
|
||||
/* [6] On lit la réponse
|
||||
=======================================================*/
|
||||
// memset(BUFFER, '\0', sizeof(BUFFER)); // on vide le buffer
|
||||
int nbRecup = sread(&SOCKET, BUFFER);
|
||||
|
||||
*pAnswer = malloc( sizeof(BUFFER) );
|
||||
strcpy(*pAnswer, BUFFER);
|
||||
|
||||
if( DEBUGMOD ) printf("nbReceived: %d\n", nbRecup);
|
||||
if( DEBUGMOD ) printf("Message: %s\n", *pAnswer);
|
||||
|
||||
|
||||
/* [7] On ferme la connection
|
||||
=======================================================*/
|
||||
int closeState = close(SOCKET);
|
||||
|
||||
// if( closeState == -1 ) return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void CONNECT_CLIENT(char* serverHost, char* serverPort, int* pSocket){
|
||||
if( DEBUGMOD ) printf("====== INIT_CLIENT(%s, %s, %d) ======\n\n", serverHost, serverPort, *pSocket);
|
||||
|
||||
struct addrinfo hints; // contiendra le filtre/format
|
||||
struct addrinfo* addrinfo; // contiendra les infos
|
||||
int CONNECT; // file_desc(s)
|
||||
char BUFFER[maxBuffLen]; // BUFFER de communication
|
||||
// char pAnswer[maxBuffLen] = {0}; // on vide la réponse (contiendra la réponse du serveur)
|
||||
|
||||
/* [1] On définit le filtre/format
|
||||
=======================================================*/
|
||||
memset(&hints, 0, sizeof(struct addrinfo)); // on vide le filtre
|
||||
hints.ai_family = AF_UNSPEC; // Allow IPv4 ou IPv6
|
||||
hints.ai_socktype = SOCK_STREAM; // TCP (SOCK_DGRAM = UDP)
|
||||
hints.ai_flags = 0; // non spécifié
|
||||
hints.ai_protocol = 0; // non spécifié
|
||||
|
||||
if( DEBUGMOD ) printf("============HINTS===========\n");
|
||||
if( DEBUGMOD ) printf( "AI_FLAGS = %d\n", hints.ai_flags ); // int
|
||||
if( DEBUGMOD ) printf( "AI_FAMILY = %d\n", hints.ai_family ); // int
|
||||
if( DEBUGMOD ) printf( "AI_SOCKTYPE = %d\n", hints.ai_socktype ); // int
|
||||
if( DEBUGMOD ) printf( "AI_PROTOCOL = %d\n", hints.ai_protocol ); // int
|
||||
if( DEBUGMOD ) printf( "AI_ADDRLEN = %d\n", hints.ai_addrlen ); // int
|
||||
if( DEBUGMOD ) printf("\n");
|
||||
|
||||
|
||||
/* [2] On récupère les infos
|
||||
=======================================================*/
|
||||
getaddrinfo(serverHost, serverPort, &hints, &addrinfo);
|
||||
|
||||
if( DEBUGMOD ) printf("=============RES============\n");
|
||||
if( DEBUGMOD ) printf( "AI_FLAGS = %d\n", addrinfo->ai_flags ); // int
|
||||
if( DEBUGMOD ) printf( "AI_FAMILY = %d\n", addrinfo->ai_family ); // int
|
||||
if( DEBUGMOD ) printf( "AI_SOCKTYPE = %d\n", addrinfo->ai_socktype ); // int
|
||||
if( DEBUGMOD ) printf( "AI_PROTOCOL = %d\n", addrinfo->ai_protocol ); // int
|
||||
if( DEBUGMOD ) printf( "AI_ADDRLEN = %d\n", addrinfo->ai_addrlen ); // int
|
||||
if( DEBUGMOD ) printf("\n");
|
||||
|
||||
/* [3] Création de la socket
|
||||
=======================================================*/
|
||||
*pSocket = socket(addrinfo->ai_family, addrinfo->ai_socktype, 0);
|
||||
|
||||
if( DEBUGMOD ) printf("SOCKET = %d\n", *pSocket);
|
||||
|
||||
// si erreur
|
||||
if( *pSocket == -1 ) return;
|
||||
|
||||
/* [4] On établit la connection
|
||||
=======================================================*/
|
||||
CONNECT = connect(
|
||||
*pSocket,
|
||||
addrinfo->ai_addr,
|
||||
addrinfo->ai_addrlen
|
||||
);
|
||||
|
||||
if( DEBUGMOD ) printf("CONNECT = %d\n", CONNECT);
|
||||
|
||||
// si erreur
|
||||
if( CONNECT == -1 ) return;
|
||||
|
||||
// on a plus besoin des infos de l'adresse
|
||||
freeaddrinfo(addrinfo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CLIENT_SEND(int* pSocket, char* pRequest, char** pAnswer){
|
||||
char BUFFER[maxBuffLen] = {'\0'};
|
||||
|
||||
/* [5] On écrit sur la socket
|
||||
=======================================================*/
|
||||
int nbSend = swrite(pSocket, pRequest);
|
||||
|
||||
if( DEBUGMOD ) printf("nbSend: %d\n", nbSend);
|
||||
if( DEBUGMOD ) printf("Message: %s\n", pRequest);
|
||||
|
||||
// si pas tout envoyé
|
||||
if( strlen(pRequest) != nbSend ) return;
|
||||
|
||||
/* [6] On lit la réponse
|
||||
=======================================================*/
|
||||
int nbRecup = sread(pSocket, BUFFER);
|
||||
|
||||
*pAnswer = malloc( sizeof(BUFFER) );
|
||||
strcpy(*pAnswer, BUFFER);
|
||||
|
||||
if( DEBUGMOD ) printf("nbReceived: %d\n", nbRecup);
|
||||
if( DEBUGMOD ) printf("Message: %s\n", *pAnswer);
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/* Envoi d'une requête à un serveur et réception de la réponse
|
||||
*
|
||||
* @serverHost<char*> Nom de l'hôte distant (server)
|
||||
* @serverPort<char*> Numéro du port distant (server)
|
||||
* @pRequest<char*> Requête à envoyer au serveur
|
||||
*
|
||||
* @pAnswer<char**> Pointeur sur le <char*> à remplir => contiendra la réponse du serveur
|
||||
*
|
||||
*/
|
||||
void CLIENT_REQUEST(char* serverHost, char* serverPort, char* pRequest, char** pAnswer);
|
||||
|
||||
|
||||
|
||||
void CONNECT_CLIENT(char* serverHost, char* serverPort, int* pSocket);
|
||||
|
||||
|
||||
void CLIENT_SEND(int* pSocket, char* pRequest, char** pAnswer);
|
|
@ -0,0 +1,283 @@
|
|||
#include "server.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void DROP_SERVER(char* serverHost, char** givenPort, int* listenSocket){
|
||||
if( DEBUGMOD ) printf("====== DROP_SERVER(%s, %s, %d) ======\n\n", serverHost, *givenPort, *listenSocket);
|
||||
|
||||
// FONCTIONNEMENT
|
||||
struct addrinfo hints; // contiendra le filtre/format
|
||||
struct addrinfo* addrinfo; // contiendra les infos du serveur
|
||||
int SOCKET, BIND, LISTEN; // file_desc(s)
|
||||
|
||||
// INFOS
|
||||
struct sockaddr_storage serverInfo; // contiendra les informations du server
|
||||
socklen_t sockaddr_len = sizeof(struct sockaddr_storage);
|
||||
char infoHost[maxHostLen]; // contiendra l'adresse du server
|
||||
char infoPort[maxPortLen]; // contiendra le port du server
|
||||
|
||||
/* [1] On définit le filtre/format
|
||||
=======================================================*/
|
||||
memset(&hints, 0, sizeof(struct addrinfo)); // on vide le filtre
|
||||
hints.ai_family = AF_UNSPEC; // Allow IPv4 ou IPv6
|
||||
hints.ai_socktype = SOCK_STREAM; // TCP (SOCK_DGRAM = UDP)
|
||||
hints.ai_flags = AI_PASSIVE; // mode SERVER
|
||||
hints.ai_protocol = 0; // non spécifié
|
||||
|
||||
if( DEBUGMOD ) printf("============HINTS===========\n");
|
||||
if( DEBUGMOD ) printf( "AI_FLAGS = %d\n", hints.ai_flags ); // int
|
||||
if( DEBUGMOD ) printf( "AI_FAMILY = %d\n", hints.ai_family ); // int
|
||||
if( DEBUGMOD ) printf( "AI_SOCKTYPE = %d\n", hints.ai_socktype ); // int
|
||||
if( DEBUGMOD ) printf( "AI_PROTOCOL = %d\n", hints.ai_protocol ); // int
|
||||
if( DEBUGMOD ) printf( "AI_ADDRLEN = %d\n", hints.ai_addrlen ); // int
|
||||
if( DEBUGMOD ) printf("\n");
|
||||
|
||||
|
||||
/* [2] On récupère les infos
|
||||
=======================================================*/
|
||||
if( strlen(*givenPort) == 0 ) // si pas défini, port dynamique
|
||||
getaddrinfo(serverHost, 0, &hints, &addrinfo);
|
||||
else // sinon manuel
|
||||
getaddrinfo(serverHost, *givenPort, &hints, &addrinfo);
|
||||
// Remarque: port=0 donc va être défini dynamiquement
|
||||
|
||||
if( DEBUGMOD ) printf("=============RES============\n");
|
||||
if( DEBUGMOD ) printf( "AI_FLAGS = %d\n", addrinfo->ai_flags ); // int
|
||||
if( DEBUGMOD ) printf( "AI_FAMILY = %d\n", addrinfo->ai_family ); // int
|
||||
if( DEBUGMOD ) printf( "AI_SOCKTYPE = %d\n", addrinfo->ai_socktype ); // int
|
||||
if( DEBUGMOD ) printf( "AI_PROTOCOL = %d\n", addrinfo->ai_protocol ); // int
|
||||
if( DEBUGMOD ) printf( "AI_ADDRLEN = %d\n", addrinfo->ai_addrlen ); // int
|
||||
if( DEBUGMOD ) printf("\n");
|
||||
|
||||
/* [3] Création de la socket
|
||||
=======================================================*/
|
||||
|
||||
SOCKET = socket(addrinfo->ai_family, addrinfo->ai_socktype, 0);
|
||||
|
||||
if( DEBUGMOD ) printf("SOCKET = %d\n", SOCKET);
|
||||
|
||||
// si erreur
|
||||
if( SOCKET == -1 ) return;
|
||||
|
||||
/* [4] On publie la SOCKET
|
||||
=======================================================*/
|
||||
BIND = bind(
|
||||
SOCKET,
|
||||
addrinfo->ai_addr,
|
||||
addrinfo->ai_addrlen
|
||||
);
|
||||
|
||||
if( DEBUGMOD ) printf("BIND = %d\n", BIND);
|
||||
|
||||
// si erreur
|
||||
if( BIND == -1 ) return;
|
||||
|
||||
/* [5] On récupère les informations du serveur (host/port)
|
||||
=======================================================*/
|
||||
int getInfo = getsockname(SOCKET, (struct sockaddr *) &serverInfo, &sockaddr_len);
|
||||
|
||||
if( getInfo == -1 ) return;
|
||||
|
||||
getInfo = getnameinfo( // on récupère le host et le port
|
||||
(struct sockaddr *) &serverInfo,
|
||||
sizeof(serverInfo),
|
||||
infoHost, maxHostLen,
|
||||
infoPort, maxPortLen,
|
||||
NI_NUMERICHOST | NI_NUMERICSERV
|
||||
);
|
||||
|
||||
if( getInfo == -1 ) return;
|
||||
|
||||
if( DEBUGMOD ) printf("Server host: %s\n", infoHost);
|
||||
if( DEBUGMOD ) printf("Server port: %s\n", infoPort);
|
||||
|
||||
|
||||
// on a plus besoin des infos de l'adresse
|
||||
freeaddrinfo(addrinfo);
|
||||
|
||||
|
||||
/* [6] On met la socket sur écoute
|
||||
=======================================================*/
|
||||
LISTEN = listen(SOCKET, maxListLen);
|
||||
|
||||
if( DEBUGMOD ) printf("LISTEN = %d\n", LISTEN);
|
||||
|
||||
// si erreur
|
||||
if( LISTEN == -1 ) return;
|
||||
|
||||
/* [7] On envoie les données par référence
|
||||
=======================================================*/
|
||||
// port
|
||||
*givenPort = malloc( sizeof(infoPort) );
|
||||
strcpy(*givenPort, infoPort);
|
||||
|
||||
// socket d'écoute
|
||||
*listenSocket = SOCKET;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// CMD: CLIENT (SRV) PROXY (CLT) FTP
|
||||
// DTA: CLIENT (CLT) PROXY (CLT) FTP
|
||||
//
|
||||
//
|
||||
//
|
||||
// [1] Ecoute sur port p de localhost
|
||||
// [2-n] Si commande, envoi à FTP
|
||||
// Puis Reception de FTP, envoi à CLIENT
|
||||
|
||||
|
||||
void MANAGE_REQUEST(int* SOCKET, char* pRequest){
|
||||
if( DEBUGMOD ) printf("====== MANAGE_REQUEST(%d, %s) ======\n\n", *SOCKET, pRequest);
|
||||
|
||||
char answer[maxBuffLen]; // contiendra la réponse
|
||||
int nbSend; // contiendra le nombre de données envoyées
|
||||
char rCommand[10]; // contiendra les commandes (1ère partie)
|
||||
char rContent[maxBuffLen]; // contiendra le contenu associé à la commande (2ème partie)
|
||||
|
||||
// on vide les buffers
|
||||
memset(&rCommand, '\0', sizeof(rCommand));
|
||||
memset(&rContent, '\0', sizeof(rContent));
|
||||
memset(&answer, '\0', sizeof(answer));
|
||||
|
||||
|
||||
/* [1] On découpe la requête en 2 parties
|
||||
================================================*/
|
||||
splitFtpRequest(pRequest, rCommand, rContent);
|
||||
// strcpy(answer, strcat(rCommand, rContent) );
|
||||
|
||||
/* [2] Selection en fonction de @rCommand
|
||||
================================================*/
|
||||
|
||||
/* (1) Erreur de syntaxe
|
||||
--------------------------------------------*/
|
||||
if( strcmp(rCommand, "ERROR") == 0 )
|
||||
strcpy(answer, "666 Tu t'es chié!!\n");
|
||||
|
||||
/* (2) Connection (username)
|
||||
--------------------------------------------*/
|
||||
else if( strcmp(rCommand, "USER") == 0 )
|
||||
strcpy(answer, "331 C'est donc ça ton blase!\n");
|
||||
|
||||
|
||||
/* (n) Commande inconnue
|
||||
--------------------------------------------*/
|
||||
else
|
||||
strcpy(answer, "??? Connè pô!\n");
|
||||
|
||||
|
||||
/* [3] Envoi de la réponse
|
||||
================================================*/
|
||||
formatBuffer(answer);
|
||||
nbSend = write(*SOCKET, answer, strlen(answer));
|
||||
|
||||
/* [4] Fermeture de la SOCKET
|
||||
================================================*/
|
||||
// close(*SOCKET);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MANAGE_RESPONSE(int* SOCKET, char** pAnswer){
|
||||
if( DEBUGMOD ) printf("====== MANAGE_RESPONSE(%d, %s) ======\n\n", *SOCKET, *pAnswer);
|
||||
|
||||
char answer[maxBuffLen]; // contiendra la réponse
|
||||
char ftpCode[4]; // contiendra le code FTP (1ère partie)
|
||||
char ftpText[maxBuffLen]; // contiendra le texte associé à la commande (2ème partie)
|
||||
|
||||
// on vide les buffers
|
||||
memset(&ftpCode, '\0', sizeof(ftpCode));
|
||||
memset(&ftpText, '\0', sizeof(ftpText));
|
||||
memset(&answer, '\0', sizeof(answer));
|
||||
|
||||
|
||||
/* [1] On découpe la requête en 2 parties
|
||||
================================================*/
|
||||
splitFtpResponse(*pAnswer, ftpCode, ftpText);
|
||||
|
||||
/* [2] Selection en fonction de @ftpCode
|
||||
================================================*/
|
||||
|
||||
// /* (1) Demande d'username
|
||||
// --------------------------------------------*/
|
||||
// if( strcmp(ftpCode, "220") == 0 )
|
||||
// strcpy(answer, USER_MSG);
|
||||
|
||||
|
||||
/* (2) Demande d'username
|
||||
--------------------------------------------*/
|
||||
if( strcmp(ftpCode, "220") == 0 )
|
||||
strcpy(answer, WLCM_MSG);
|
||||
|
||||
|
||||
/* (3) username OK -> demande MDP
|
||||
--------------------------------------------*/
|
||||
else if( strcmp(ftpCode, "331") == 0 )
|
||||
strcpy(answer, USER_MSG);
|
||||
|
||||
/* (3) Bon mdp -> connection
|
||||
--------------------------------------------*/
|
||||
else if( strcmp(ftpCode, "230") == 0 )
|
||||
strcpy(answer, PASS_BON_MSG);
|
||||
|
||||
|
||||
|
||||
/* (4) Mauvais mdp -> connection
|
||||
--------------------------------------------*/
|
||||
else if( strcmp(ftpCode, "530") == 0 )
|
||||
strcpy(answer, PASS_BAD_MSG);
|
||||
|
||||
/* (5) Info SYST
|
||||
--------------------------------------------*/
|
||||
// else if( strcmp(ftpCode, "215") == 0 )
|
||||
// strcpy(answer, "bla\n");
|
||||
|
||||
/* (6) LOGOUT => EXIT
|
||||
--------------------------------------------*/
|
||||
else if( strcmp(ftpCode, "221") == 0 )
|
||||
strcpy(answer, EXIT_MSG);
|
||||
|
||||
|
||||
|
||||
/* (n) Commande inconnue
|
||||
--------------------------------------------*/
|
||||
else
|
||||
strcpy(answer, *pAnswer);
|
||||
|
||||
|
||||
/* [3] Retour de la réponse
|
||||
================================================*/
|
||||
strcpy(*pAnswer, answer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int WAIT_CLIENT(int* pSocket, char* pBuffer){
|
||||
memset(pBuffer, 0, maxBuffLen); // on vide le buffer
|
||||
|
||||
int nbRead = 0;
|
||||
|
||||
do{
|
||||
nbRead = sread(pSocket, pBuffer);
|
||||
|
||||
// si on est déconnecté, on ferme la SOCKET
|
||||
if( nbRead == -1 ){
|
||||
printf("Client déconnecté!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
}while( pBuffer[nbRead-1] != '\n' && pBuffer[nbRead-2] != '\r' );
|
||||
|
||||
|
||||
// on retourne -1 si erreur, SINON 0
|
||||
return nbRead;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/* Créé et met un serveur sur écoute
|
||||
*
|
||||
* @serverHost<char*> Nom de l'hôte local (localhost)
|
||||
*
|
||||
* @givenPort<char**> Pointeur sur le <char*> à remplir => contiendra le port donné par le système
|
||||
* @listenSocket<int*> Pointeur sur le <int> à remplir => contiendra un pointeur sur la socket d'écoute
|
||||
*
|
||||
*/
|
||||
void DROP_SERVER(char* serverHost, char** givenPort, int* listenSocket);
|
||||
|
||||
|
||||
|
||||
/* Gestion de la réponse au client
|
||||
*
|
||||
* @SOCKET<int*> Pointeur sur la SOCKET concernée
|
||||
* @pRequest<char*> Requête reçue et à traiter
|
||||
*
|
||||
*/
|
||||
void MANAGE_REQUEST(int* SOCKET, char* pRequest);
|
||||
|
||||
|
||||
|
||||
|
||||
void MANAGE_RESPONSE(int* SOCKET, char** pAnswer);
|
||||
|
||||
|
||||
|
||||
|
||||
int WAIT_CLIENT(int* pSocket, char* pBuffer);
|
|
@ -0,0 +1,151 @@
|
|||
#include "utility.h"
|
||||
|
||||
void splitFtpRequest(char* pRequest, char* pCommand, char* pContent){
|
||||
/* [1] Vérification du format
|
||||
===========================================*/
|
||||
int firstSpaceIndex = indexOf(pRequest, ' ');
|
||||
|
||||
if( firstSpaceIndex != 3 && firstSpaceIndex != 4){ // contient aucun espace en position 3 ou 4, on quitte
|
||||
strcpy(pCommand, "ERROR");
|
||||
strcpy(pContent, "");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* [2] Séparation des 2 parties
|
||||
===========================================*/
|
||||
int i;
|
||||
|
||||
for( i = 0 ; i < strlen(pRequest) || pRequest[i] != '\0' ; i++ ){
|
||||
|
||||
if( i < firstSpaceIndex ) // première partie (pCommand)
|
||||
strcpy( pCommand, strcat(pCommand, (char[2]) { (char) pRequest[i], '\0' }) );
|
||||
if( i > firstSpaceIndex ) // seconde partie (pContent)
|
||||
strcpy( pContent, strcat(pContent, (char[2]) { (char) pRequest[i], '\0' }) );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void splitFtpResponse(char* pAnswer, char* ftpCode, char* ftpText){
|
||||
/* [1] Vérification du format
|
||||
===========================================*/
|
||||
int codeLength = 3; // taille du code
|
||||
|
||||
/* [2] Séparation des 2 parties
|
||||
===========================================*/
|
||||
int i;
|
||||
|
||||
for( i = 0 ; i < strlen(pAnswer) || pAnswer[i] != '\0' ; i++ ){
|
||||
|
||||
if( i < codeLength ) // première partie (ftpCode)
|
||||
strcpy( ftpCode, strcat(ftpCode, (char[2]) { (char) pAnswer[i], '\0' }) );
|
||||
if( i > codeLength ) // seconde partie (ftpText)
|
||||
strcpy( ftpText, strcat(ftpText, (char[2]) { (char) pAnswer[i], '\0' }) );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int indexOf(char* haystack, char needle){
|
||||
int i;
|
||||
|
||||
for( i = 0 ; i < strlen(haystack) || haystack[i] != '\0' ; i++ )
|
||||
if( haystack[i] == needle ) // si on trouve le caractère
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
void formatBuffer(char* pBuffer){
|
||||
if( DEBUGMOD ) printf( "BUFLEN (bef): %lu\n", strlen(pBuffer) );
|
||||
if( DEBUGMOD ) printf( "BUFFER: (%s)\n", pBuffer );
|
||||
|
||||
/* [1] On retire les "\n" et "\r" de la fin de la chaine
|
||||
============================================================*/
|
||||
int i;
|
||||
|
||||
for( i = strlen(pBuffer)-1 ; i >= 0 || pBuffer[i] != '\0' ; i-- )
|
||||
if( pBuffer[i] == '\n' || pBuffer[i] == '\r' ) // si c'est un retour chariot
|
||||
pBuffer[i] = '\0'; // on efface
|
||||
else
|
||||
break;
|
||||
|
||||
// on ferme ensuite la chaîne
|
||||
pBuffer[i] = '\0';
|
||||
|
||||
/* [2] On ajoute "\r\n" à la fin
|
||||
============================================================*/
|
||||
strcpy(pBuffer, strcat(pBuffer, "\r\n"));
|
||||
|
||||
if( DEBUGMOD ) printf( "BUFLEN (aft): %lu\n", strlen(pBuffer) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void read_stdin(char* pBuffer, unsigned long pLength){
|
||||
fgets(pBuffer, pLength, stdin); // on lit l'entrée standard
|
||||
|
||||
int i;
|
||||
// on supprimes les retours à la ligne de la fin
|
||||
for( i = strlen(pBuffer)-1 ; i >= 0 || pBuffer[i] != '\0' ; i-- )
|
||||
if( pBuffer[i] == '\n' || pBuffer[i] == '\r' ) // si c'est un retour chariot
|
||||
pBuffer[i] = '\0'; // on efface
|
||||
else
|
||||
break;
|
||||
|
||||
strcpy(pBuffer, strcat(pBuffer, "\r\n"));
|
||||
}
|
||||
|
||||
|
||||
int swrite(int* pSocket, char* pBuffer){
|
||||
if( *pSocket == -1 ) return -1; // si SOCKET fermée, on retourne une erreur
|
||||
|
||||
return write(*pSocket, pBuffer, strlen(pBuffer), MSG_DONTROUTE);
|
||||
}
|
||||
|
||||
|
||||
int sread(int* pSocket, char* pBuffer){
|
||||
if( *pSocket == -1 ) return -1; // si SOCKET fermée, on retourne une erreur
|
||||
|
||||
|
||||
// on vide le buffer avant de lire
|
||||
memset(pBuffer, '\0', maxBuffLen);
|
||||
int nbRead = read(*pSocket, pBuffer, maxBuffLen);
|
||||
|
||||
|
||||
// si on est déconnecté, on ferme la SOCKET
|
||||
if( nbRead == 0 ){
|
||||
close(*pSocket);
|
||||
return -1; // on retourne une erreur
|
||||
}
|
||||
|
||||
return nbRead;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void xPrint(char* pPattern, char* pBuffer){
|
||||
char tmpBuffer[maxBuffLen];
|
||||
strcpy(tmpBuffer, pBuffer);
|
||||
|
||||
|
||||
int i;
|
||||
|
||||
// on supprimes les retours à la ligne de la fin
|
||||
for( i = strlen(tmpBuffer)-1 ; i >= 0 || tmpBuffer[i] != '\0' ; i-- )
|
||||
if( tmpBuffer[i] == '\n' || tmpBuffer[i] == '\r' ) // si c'est un retour chariot
|
||||
tmpBuffer[i] = '\0'; // on efface
|
||||
else
|
||||
break;
|
||||
|
||||
printf(pPattern, tmpBuffer);
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/* Découpe la requête FTP en 2 parties
|
||||
*
|
||||
* @pRequest<char*> La requête en question
|
||||
*
|
||||
* @pCommand<char*> Remplissage: commande (1ère partie)
|
||||
* @pContant<char*> Remplissage: contenu (2ème partie)
|
||||
*
|
||||
*
|
||||
*/
|
||||
void splitFtpRequest(char* pRequest, char* pCommand, char* pContent);
|
||||
|
||||
/* Découpe la réponse FTP en 2 parties
|
||||
*
|
||||
* @pAnswer<char*> La réponse en question
|
||||
*
|
||||
* @ftpCode<char*> Remplissage: code FTP (1ère partie)
|
||||
* @ftpText<char*> Remplissage: text associé (2ème partie)
|
||||
*
|
||||
*
|
||||
*/
|
||||
void splitFtpResponse(char* pAnswer, char* ftpCode, char* ftpText);
|
||||
|
||||
|
||||
/* Retourne le rang d'un caractère dans une string
|
||||
*
|
||||
* @haystack<char*> La chaîne dans laquelle rechercher
|
||||
* @needle<char> Le caractère recherché
|
||||
*
|
||||
* @return position<int> Retourne l'index de @needle dans @haystack ou -1 si ne trouve pas
|
||||
*
|
||||
*/
|
||||
int indexOf(char* haystack, char needle);
|
||||
|
||||
|
||||
|
||||
/* Formatte un buffer pour être envoyé
|
||||
*
|
||||
* @pBuffer<char*> Buffer en question
|
||||
*
|
||||
*/
|
||||
void formatBuffer(char *pBuffer);
|
||||
|
||||
|
||||
void read_stdin(char* pBuffer, unsigned long pLength);
|
||||
|
||||
|
||||
|
||||
/* read/write socket */
|
||||
int swrite(int* pSocket, char* pBuffer);
|
||||
int sread(int* pSocket, char* pBuffer);
|
||||
|
||||
|
||||
|
||||
|
||||
void xPrint(char* pPattern, char* pBuffer);
|
|
@ -0,0 +1,146 @@
|
|||
#include "proxy_ftp.h"
|
||||
|
||||
// DECLARATIONS
|
||||
static pthread_t userServer;
|
||||
static short unsigned int userServerState = 1;
|
||||
static char remoteAssignedPort[maxPortLen] = {'\0'};
|
||||
|
||||
/* headers */
|
||||
static void* testServer();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*****************/
|
||||
/* CORPS DU PROG */
|
||||
/*****************/
|
||||
int main(int argc, char* argv[]){
|
||||
|
||||
testServer();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void* testServer(){
|
||||
int USER_SOCKET; // contiendra le BUS DE COMMANDE utilisateur
|
||||
int FTP_SOCKET; // contiendra le BUS DE COMMANDE FTP
|
||||
int DUSER_SOCKET; // contiendra le BUS DE DONNES utilisateur
|
||||
int DFTP_SOCKET; // contiendra le BUS DE DONNEES FTP
|
||||
|
||||
char BUFFER[maxBuffLen]; // contiendra le BUFFER
|
||||
struct sockaddr_storage clientInfo; // contiendra les infos client
|
||||
char repeat; // sert à sortir de la boucle
|
||||
int nbReceived, nbSend; // contiendra les nb reçu && envoyé
|
||||
socklen_t len = sizeof(struct sockaddr_storage);
|
||||
|
||||
// retour de @DROP_SERVER
|
||||
char* serverPort; // contiendra le port
|
||||
int LISTENSOCK; // contiendra la socket d'écoute
|
||||
char* ftp_response;
|
||||
|
||||
/* [0] On lance @DROP_SERVER
|
||||
==========================================================*/
|
||||
serverPort = malloc(4*sizeof(char));
|
||||
strcpy(serverPort, "4444");
|
||||
DROP_SERVER(remoteHost, &serverPort, &LISTENSOCK);
|
||||
CONNECT_CLIENT(FTP_HOST, FTP_PORT, &FTP_SOCKET);
|
||||
|
||||
printf("Port: %s\n", serverPort);
|
||||
strcpy(remoteAssignedPort, serverPort);// PORT GLOBAL
|
||||
|
||||
/* [1] Attente d'une demande de connection, puis création d'une socket
|
||||
============================================================================*/
|
||||
USER_SOCKET = accept(LISTENSOCK, (struct sockaddr *) &clientInfo, &len);
|
||||
|
||||
/* [2] On envoie la séquence d'initialisation
|
||||
============================================================================*/
|
||||
strcpy(BUFFER, "");
|
||||
CLIENT_SEND(&FTP_SOCKET, BUFFER, &ftp_response);
|
||||
MANAGE_RESPONSE(&USER_SOCKET, &ftp_response);
|
||||
swrite(&USER_SOCKET, ftp_response);
|
||||
|
||||
xPrint("P->F: %s\n\n", BUFFER);
|
||||
xPrint("F->P: %s\n", ftp_response);
|
||||
|
||||
/* BOUCLE DE COMMANDES */
|
||||
while( USER_SOCKET != -1 && FTP_SOCKET != -1 ){
|
||||
|
||||
/* [3] On récupère les données reçues (+attente)
|
||||
============================================================================*/
|
||||
if( WAIT_CLIENT(&USER_SOCKET, BUFFER) == -1 ) break;
|
||||
xPrint("C->P: %s\n", BUFFER);
|
||||
|
||||
if( DEBUGMOD ) printf("Recu: %d\n", nbReceived);
|
||||
if( DEBUGMOD ) printf("C->P: %s\n", BUFFER);
|
||||
|
||||
|
||||
/* [4] Redirection vers le serveur FTP
|
||||
============================================================================*/
|
||||
CLIENT_SEND(&FTP_SOCKET, BUFFER, &ftp_response);
|
||||
// printf("U22: %d\n", USER_SOCKET);
|
||||
xPrint("P->F: %s\n\n", BUFFER);
|
||||
xPrint("F->P: %s\n", ftp_response);
|
||||
|
||||
|
||||
/* [5] On analyse et renvoie la réponse à l'utilisateur
|
||||
============================================================================*/
|
||||
// on analyse
|
||||
MANAGE_RESPONSE(&USER_SOCKET, &ftp_response);
|
||||
|
||||
// on réponds au client
|
||||
if( swrite(&USER_SOCKET, ftp_response) == -1 ) break;
|
||||
printf("P->C: %s\n", ftp_response);
|
||||
|
||||
|
||||
|
||||
/* [6] On vide les buffers
|
||||
============================================================================*/
|
||||
memset(BUFFER, '\0', sizeof(BUFFER)); // on vide le buffer
|
||||
ftp_response = NULL;
|
||||
}
|
||||
|
||||
close(USER_SOCKET);
|
||||
close(FTP_SOCKET);
|
||||
close(LISTENSOCK);
|
||||
strcpy(remoteAssignedPort, "\0");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* DROP_SERVER
|
||||
* INIT_CLIENT
|
||||
*
|
||||
* while(){
|
||||
* accept();
|
||||
* client_send()
|
||||
* }
|
||||
*
|
||||
* EXIT_CLIENT
|
||||
* HALT_SERVER
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
|
@ -0,0 +1,84 @@
|
|||
/* global */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
|
||||
/* sys */
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
/* socket */
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h> // getaddrinfo, getnameinfo
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/* basis */
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
|
||||
/* debug */
|
||||
#define DEBUGMOD FALSE // <Boolean> TRUE = débugmode activé
|
||||
// #define DEBUGMOD TRUE // <Boolean> TRUE = débugmode activé
|
||||
|
||||
/* vars */
|
||||
#define remoteHost "localhost"
|
||||
#define remotePort "80"
|
||||
#define maxBuffLen 4096
|
||||
#define maxListLen 2
|
||||
#define maxHostLen 64
|
||||
#define maxPortLen 6
|
||||
|
||||
#define FTP_HOST "31.170.164.47"
|
||||
// #define FTP_HOST "localhost"
|
||||
#define FTP_PORT "21"
|
||||
// u712664263
|
||||
|
||||
|
||||
/* MESSAGES */
|
||||
// 220-\n
|
||||
// 220- +----------------------------+\n
|
||||
// 220- | Bienvenue sur PROXY FCP!!! |\n
|
||||
// 220- +----------------------------+\n
|
||||
// 220-\n
|
||||
// 220-\n
|
||||
// 220- (FCP=File Club Protocol)\n
|
||||
// 220-\n
|
||||
// 220-\n
|
||||
// 220- Qui est tu ?!\n
|
||||
// 220-\n
|
||||
// 220\n
|
||||
#define WLCM_MSG "220-\n220- +----------------------------+\n220- | Bienvenue sur PROXY FCP!!! |\n220- +----------------------------+\n220-\n220-\n220- (FCP=File Club Protocol)\n220-\n220-\n220- Qui est tu ?!\n220-\n220\n"
|
||||
|
||||
#define CON_MSG "220 Connecté au serveur\n"
|
||||
#define USER_MSG "331 Tu connais la procédure.. Donne moi le mot de passe ?\n"
|
||||
// 230- Bienvenue au FILE CLUB!\n\n
|
||||
// 230- Les règles du File Club sont:\n
|
||||
// 230- ====================================\n
|
||||
// 230- 1. Il est interdit de parler du File Club.\n
|
||||
// 230- 2. Il est interdit de parler du File Club.\n
|
||||
// 230- 3. Si quelqu'un dit stop ou s'évanouit, le transfert s'arrête.\n
|
||||
// 230- 4. Seulement deux fichiers par transfert.\n
|
||||
// 230- 5. Un transfert à la fois.\n
|
||||
// 230- 6. Pas de '.log', pas de '.txt'.\n
|
||||
// 230- 7. Le transfert dure aussi longtemps qu'il doit durer.\n
|
||||
// 230- 8. Si c'est votre premier soir au File Club, vous devez transférer.\n
|
||||
// 230\n
|
||||
#define PASS_BON_MSG "230- Bienvenue au FILE CLUB!\n230-\n230- Les règles du File Club sont:\n230- ====================================\n230- 1. Il est interdit de parler du File Club.\n230- 2. Il est interdit de parler du File Club.\n230- 3. Si quelqu'un dit stop ou s'évanouit, le transfert s'arrête.\n230- 4. Seulement deux fichiers par transfert.\n230- 5. Un transfert à la fois.\n230- 6. Pas de '.log', pas de '.txt'.\n230- 7. Le transfert dure aussi longtemps qu'il doit durer.\n230- 8. Si c'est votre premier soir au File Club, vous devez transférer.\n230\n"
|
||||
#define PASS_BAD_MSG "530- Mauvais mot de passe! Dégage!\n530\n"
|
||||
// 221-\n
|
||||
// 221- Fermeture des portes!\n
|
||||
// 221- Tout le monde dehors!!\n
|
||||
// 221- Et n'oublie pas la PREMIERE REGLE!!\n
|
||||
// 221\n
|
||||
#define EXIT_MSG "221-\n221- Fermeture des portes!\n221- Tout le monde dehors!!\n221- Et n'oublie pas la PREMIERE REGLE!!\n221\n"
|
||||
|
||||
|
||||
|
||||
//Je suis le canal biliaire irrité de Jack.
|
||||
|
||||
/* local dependencies */
|
||||
#include "dep/utility.c"
|
||||
#include "dep/client.c"
|
||||
#include "dep/server.c"
|
|
@ -0,0 +1,55 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
|
||||
static void* action1();
|
||||
static void* action2();
|
||||
|
||||
|
||||
pthread_t thread1, thread2;
|
||||
static int bool1 = 1;
|
||||
static int bool2 = 1;
|
||||
|
||||
|
||||
|
||||
int main(int argc, char* argv []){
|
||||
|
||||
pthread_create(&thread1, NULL, &action1, (void*) NULL);
|
||||
pthread_create(&thread2, NULL, &action2, (void*) NULL);
|
||||
|
||||
printf("THREADS CREATED\n===============\n");
|
||||
|
||||
sleep(3);
|
||||
bool1 = 0;
|
||||
sleep(3);
|
||||
bool2 = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void* action1(){
|
||||
while( bool1 ){
|
||||
printf("[THREAD] 1\n");
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
pthread_exit((void*) thread1);
|
||||
}
|
||||
|
||||
static void* action2(){
|
||||
while( bool2 ){
|
||||
printf("[THREAD] 2\n");
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
pthread_exit((void*) thread2);
|
||||
}
|
Binary file not shown.
Loading…
Reference in New Issue