[C/Reseau] proxy FTP (simple) en C

proxy FTP (simple) en C [C/Reseau] - C - Programmation

Marsh Posté le 02-12-2012 à 01:51:31    

Salut à tous :)

 

j'aimerais réaliser un proxy FTP actif / passif en C.

 

Je n'ai rencontré aucun problème sur les connexions de contrôle pour relayer les commandes et le réponses FTP mais bloque sur les connexions de données......

 

Pour l'instant, je souhaite seulement récupérer le résultat de la commande ls de la façon suivante :

  • communication avec le serveur FTP en mode passif ;
  • communication avec le client en mode actif et transmission du retour de la commande ls.


Ma démarche pour la commande ls

 

Le proxy détecte ls (et donc PORT ....) puis :

  • envoie la commande PASV au serveur ;
  • reçoit l'adresse IP et le port à calculer auxquels il se connecte pour créer la socket de données ;
  • envoie la commande LIST au serveur ;
  • lit  la socket de données dans buffer et la ferme.


Maintenant que j'ai le retour de ls dans buffer, il faut que je l'envoie au client en mode actif et je coince....
C'est le proxy qui doit mettre en oeuvre la connexion de transfert de données, j'ai l'adresse IP du client et le port à utiliser pour le transfert des données mais je n'ai pas d'idée de comment le faire. J'ai essayé plusieurs "trucs" en vain.

 

Voici la partie de mon code "intéressante" :

 

proxy.c

 
Code :
  1. /*
  2. ....
  3. */
  4. int clientSockRDV;  // Descripteur de socket de rendez-vous avec le client
  5. int clientSockCOM;  // Descripteur de socket de communication avec le client
  6. int servSock;   // Descripteur de socket de communication avec le serveur ftp
  7. int servSockDonnees;  // Descripteur de socket pour le mode PASSIF et la commande LIST
  8. /*
  9. ...
  10. */
  11. printf("=========================================\n" );
  12.   printf("========= commande ls detectee ==========\n" );
  13.   printf("========= passage en mode passif ========\n" );
  14.   printf("=========================================\n" );
  15.   // passer en mode passif : envoi au serveur de la commande PASV
  16.   sendToServer(servSock, "PASV\r\n" );
  17.   // reception serveur : 227 (mode passif)
  18.   recvFromServer(servSock, &buffer);
  19.   // calcul du port et conversion en chaine
  20.   sprintf(port, "%d", calculPort(buffer));
  21.   // connexion à l'adresse SERVEUR sur le port PORT via une socket
  22.   hints.ai_flags    = 0;
  23.   hints.ai_family   = AF_INET;
  24.   hints.ai_socktype = SOCK_STREAM;
  25.   hints.ai_protocol = 0;
  26.   hints.ai_addrlen  = 0;
  27.   hints.ai_canonname= NULL;
  28.   hints.ai_addr   = NULL;
  29.   hints.ai_next   = NULL;
  30.   // creation de la socket de donnees SERVSOCKDONNEES
  31.   servSockDonnees = socket(AF_INET, SOCK_STREAM, 0);
  32.   if (servSockDonnees == -1) { fatal("socket", "erreur creation socket", -1); }
  33.   // récupération des informations sur le serveur
  34.   ecode = getaddrinfo(serveur, port, &hints, &res);
  35.   if (ecode) { fatal("getaddrinfo", gai_strerror(ecode), -1); }
  36.   // connexion au serveur
  37.   ecode = connect(servSockDonnees, res->ai_addr, res->ai_addrlen);
  38.   if (ecode == -1)
  39.   {
  40.    close(servSockDonnees);
  41.    freeaddrinfo(res);
  42.    fatal("connect", "erreur connect", -1);
  43.   }
  44.   freeaddrinfo(res);
  45.   // envoi au serveur de la commande LIST
  46.   sendToServer(servSock, "LIST\r\n" );
  47.   // reception serveur (150 opening ascii)
  48.   recvFromServer(servSock, &buffer);
  49.   sendToClient(clientSockCOM, buffer);
  50.   // reception serveur (liste des fichiers)
  51.   recvFromServer(servSockDonnees, &buffer);
  52.   /********************************************************************
  53.    ********************************************************************
  54.    ********************************************************************
  55.    * ICI : j'ai le retour de ls dans buffer mais ne sais pas comment
  56.    * intenter la connexion de données du proxy vers le client
  57.    ********************************************************************
  58.    ********************************************************************
  59.    ********************************************************************/
  60.   // fermeture de la socket servSockDonnees
  61.   close(servSockDonnees);


Message édité par champidead le 02-12-2012 à 01:56:36
Reply

Marsh Posté le 02-12-2012 à 01:51:31   

Reply

Marsh Posté le 03-12-2012 à 01:04:58    

Bonjour,
 
Je comprends mal le problème, tu dis que tu as le port et l'adresse du client et que tu as aussi les données. Ton proxy se retrouve donc "à la place" du serveur FTP et doit ouvrir une connexion vers le client et envoyer les infos à l'identique soit:
 
1. Ouverture de la connexion (comme tu l'as déjà fait pour te connecter au serveur avec socket + connect)
2. Envoi des données (avec un code à priori analogue à ce que tu as déjà dans tes fonctions sendToServer/sendToClient)
 
Est-ce que cela répond au moins un peu à tes question ou bien il y a quelque chose que je ne saisis pas?
 
Bon courage!

Reply

Marsh Posté le 05-12-2012 à 20:14:20    

Bonjour _werz, excuse-moi pour la réponse tardive.

 

J'ai finalement réussi.

 

Mon explication était correcte et j'avais bien saisis le "truc". Toutefois, j'avais mal analysé le jeu de retour et d'envoi des commandes FTP.

 

Client ==== PORT 127,0,0,1,254,123  ====>  Proxy  ==== PORT 127,0,0,1,254,123  ====> Serveur
Client <=== 200 PORT successful =====  Proxy <=== 200 PORT successful ===== Serveur
Client =========== LIST ============>  Proxy ==== LIST ================> Serveur

 

J'avais oublié le message PORT command successful. Après tout s'est déroulé correctement, j'ai envoyé au client la réponse du serveur "150 opening ascii" puis j'ai envoyé la liste des fichiers via la socket des données.
Finalement, j'ai envoyé au au client la réponse du server "226 transfert complete" puis fermer les socket de données.

 

:)


Message édité par champidead le 05-12-2012 à 20:19:44
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed