Le protocole FTP: File Transfert Protocol


Une contribution de gogo


Informations :
  • - Pour obtenir la liste des commandes du serveur FTP il suffit de lui envoyer la commande " HELP " même si vous n'êtes pas encore identifié. Si vous utilisez le client FTP du DOS il faudra taper " LITERAL HELP " pour que ce ne soit pas l'aide de la commande FTP qui soit affichée mais l'aide du serveur FTP.
  • - Il est important d'attendre les réponses même lorsque la réponse importe peu, sinon au moment où la réponse nous importera nous aurons le risque de recevoir les réponses des précédentes requêtes.
  • - Le protocole FTP s'utilise de façon standard sur le port 21 du serveur en mode TCP. Il est possible d'installer un serveur FTP sur un port quelconque. Par contre le FTP ne fonctionne que sur du TCP, que ce soit pour le port de contrôle ou les ports data.
  • - Un serveur FTP est toujours en attente sur un port fixe, dit port de contrôle, qui sert à recevoir la connexion et toutes les commandes, et utilise un autre port, soit au hasard soit dans une plage de ports fixée, pour les transferts de données (une command LIST déclenche un transfert de données ! ).
  • - Le port de transfert de données est spécifié soit par le client qui indique au serveur son N° et attend sa connexion (mode standard), soit par le serveur qui indique au client le N° du port auquel il doit se connecter (mode passif, déclenché par la commande PASV). Cette notion est extrêmement importante pour les gens qui ont des firewall.
  • - Si le client a un firewall, le mode standard ne fonctionnera pas car le serveur n'arrivera jamais à se connecter au client pour transférer les données, et le premier LIST donnera l'impression que l'application est " plantée ".
  • - Si le serveur a un firewall, il faut configurer celui ci pour qu'il laisse passer le port du serveur (21) et une plage de ports pour les transferts si le serveur accepte le mode passif.
  • - Le serveur doit avoir une plage de ports (entre X et Y) pour les transferts même s'il n'a qu'un seul client, car chaque commande LIST utilise un port de données, et un port de données ne peut plus être utilisé pendant presque une minute dans certains cas. Donc pour éviter tout problème à chaque fois que le client ou le serveur se mettent en attente, ils changent de port sans essayer de réutiliser le port précédent.


Légende : < Réception d'une information sur le port de contrôle
> Envoi d'une information sur le port de contrôle
< Réception d'une information sur le port de données


Connexion au serveur FTP:
< 220 ProFTPD 1.2.6 Server (ProFTPD: Serveur ) [ftpperso2-1.free.fr]
Le premier nombre est toujours le résultat qui doit être interprété par un programme. Les codes sont tous référencés dans les RFC : page http://www.eisti.fr/res/res/rfc959/959-4.htm (trouvé sur le site des RFC français http://abcdrfc.free.fr/)
> USER gogo.manu
Il est nécessaire de s'identifier au début pour avoir accès au reste des fonctions.

< 331 Password required for gogo.manu.
> PASS ****
Si la commande PASS échoue, il faut recommencer depuis la commande USER dans tous les cas.

< 230-User gogo.manu logged in.
< 230 Quotas on: using 105426317.00 of 104857600.00 bytes
Les codes 230 ici donnent des informations que l'on peut ignorer, mais qu'il faut attendre. Le signe moins après le 230 de la première ligne indique que ce n'est pas la dernière ligne du bloc " 230 " Attention ! Dans certains cas le 230 n'est indiqué que sur la première et la dernière ligne, cela dépend du serveur FTP. Faites bien vos tests sur plusieurs serveurs différents.

> SYST
< 215 UNIX Type: L8
Ce n'est pas vital, cela sert seulement à savoir quel est le système du serveur. Si le système est Unix en principe les minuscules et majuscules sont différenciées. Mais il ne faut pas trop s'y fier car il arrive de voir une réponse " Unix " même sur un serveur " windows ".

> REST 100
< 350 Restarting at 100. Send STORE or RETRIEVE to initiate transfer.
Le code 350 signifie que le serveur accepte de reprendre la lecture ou l'écriture de fichiers à partir d'un octet qui n'est pas le premier, indispensable pour faire des resume. Attention, certains serveurs FTP fonctionnent très mal en resume de UPLOAD (envoi du client vers eux), bien qu'ils signalent que cela fonctionne et qu'ils ne fassent aucune erreur, le fichier est incorrect car il reprend l'écriture au premier octet du fichier.

> REST 0
< 350 Restarting at 0. Send STORE or RETRIEVE to initiate transfer.
Maintenant que l'on sait que le serveur supporte ou pas les resume, nous initialisons le transfert au tout début.

[Ecoute data port 1116]
> PORT 192,168,0,7,4,92
Nous somme ici en mode " standard " (inverse de passif), c'est à dire que le client choisi un port libre en créant un socket en écoute, et indique par la commande PORT au serveur quel est le numéro de ce port.
Le format de la commande PORT, souvent mal expliquée, est :
PORT IP1, IP2, IP3, IP4, PORT1, PORT2

Admettons que mon adresse IP soit 62.212.104.150, et que mon client soit en écoute sur le port 815, cela donne :
PORT 62,212,104,150,3,47
Parce que 3*256 + 47 = 815

Donc avec PORT 192,168,0,7,4,92
Mon PC est en attente sur le port 4*256+92 = 1116
Si j'ai un firewall j'ai au préalable défini une plage de ports ouverts en réception, par exemple de 1100 à 1150.

Ici nous notons une importante erreur souvent commise et parfois fonctionnelle : L'adresse IP qui est spécifiée dans cette commande PORT est 192.168.0.7, ce qui est une adresse IP locale et en aucun cas une adresse IP internet.

Cela arrive lorsque notre PC appartient à un réseau local.

Que se passe t'il dans ce cas ?
Nous somme tout simplement en train de dire à notre serveur (free par exemple), que nous attendons son appel sur l'adresse IP 192.168.0.7 sur le port 1116… mais le serveur ne trouvera JAMAIS cette IP car pour lui aussi il s'agit d'une IP locale.

Dans ce cas il faut intégrer au logiciel client une zone de saisie pour que l'utilisateur puisse rentrer sa vraie adresse internet. Cette adresse devra être utilisée en lieu et place de l'adresse IP locale, sans quoi avec certains serveurs FTP cela ne fonctionnera pas.

Pourquoi certains ? tout simplement parce que les serveurs qui accepteront ceci ignorent tout simplement l'adresse IP que l'on envoie dans la commande PORT. Ils utilisent l'adresse IP que l'on utilise pour notre port de contrôle. Bien sûr de tels serveurs ne supportent pas le FXP (transfert de site à site géré par un port contrôle extérieur).

Donc si le serveur est puissant cette erreur de PORT ne passera pas.

< 200 PORT command successful

Le serveur a enregistré l'adresse IP et le port auxquels il doit se connecter pour envoyer ses données. Mais comme pour l'instant il n'a rien à envoyer… il ne se connecte pas encore.

> LIST -al

Nous envoyons une demande de listing. Le serveur se connecte à l'IP et au port indiqués dans la commande PORT précédente, et dès que l'on a accepté la connexion (avec .Accept par exemple), il commence à envoyer ses données sur le PORT DATA.

< 150 Opening ASCII mode data connection for file list

Nous recevons une information sur le port de contrôle signifiant que le transfert commence. Comme le serveur n'attend pas de réponse, cette information peut très bien arriver après le premier paquet du port data !!! Donc plus ou moins en même temps nous commençons à recevoir des informations sur le port data, Pour un LIST cela sera en mode texte, mais cela fonctionne de la même manière en mode binaire avec une récupération de fichier.

DIR drwxr-sr-t  14 web      site         4096 Feb 13 23:39 .
DIR drwxr-sr-t  14 web      site         4096 Feb 13 23:39 ..
DIR -rw-r--r--   1 web      site           90 Nov  5 11:11 .htaccess
DIR drwxr-sr-x   2 web      site         4096 Jan 11 04:49 BACKUP
...
DIR drwxr-sr-x   2 web      site         4096 Nov  5 11:20 msg
DIR d---rwx---   3 web      site         4096 Dec 21 01:34 mysql
DIR drwxr-sr-x   3 web      site         4096 Sep 22  2002 php
DIR drwxr-sr-x   4 web      site         4096 Mar 19 10:10 public
DIR -rw-r--r--   1 web      site      1060776 Jun 28  2002 rescue.zip
DIR drwxr-sr-x   2 web      site         4096 Sep 13  2002 sessions
DIR drwxr-sr-x   2 web      site         4096 Oct 14  2002 test
DIR -rw-r--r--   1 web      site            0 Sep 20  2002 toto
DIR drwxr-sr-x   2 web      site         4096 Aug  9  2002 wskquick
Concernant le formatage de la liste reçue, je n'ai toujours pas compris quelle était la façon de l'interpréter, car le format varie en fonction des sites.

< 226-Transfer complete.
< 226 Quotas on: using 105426317.00 of 104857600.00 bytes

Alors ici il s'agit de bien faire attention. A la fin du transfert il se passe plusieurs choses : - le serveur ferme la connexion data - le serveur envoie le code 226 sur le port contrôle.

Mais l'ordre est aléatoire car il fait les deux opérations en même temps, et l'ordre des paquets data est conservé. Donc il n'est pas rare de recevoir le code 226, qui n'indique pas que tous les paquets ont été reçus mais simplement qu'ils ont tous été envoyés (nuance), et de continuer à recevoir des paquets data pendant un moment avant la fermeture du port. Il faut donc gérer les différents cas de fin de transfert, bien que cela ne soit pas vraiment évident à gérer de premier abord. Enfin le fait d'être au courant évitera pas mal de bugs…. Car bien sûr il arrive que le 226 arrive à point nommé, juste après la fermeture du port data.

  • - en mode passif, au lieu de port, envoyer la commande " PASV " sans paramètres
  • le serveur répondra une phrase contenant les mêmes informations qu'une commande PORT,
  • il faut alors décoder l'IP et le N° de port et se connecter, puis envoyer la commande de transfert
  • sur le port de contrôle.
  • - Pour envoyer des données vous devez gérer vous même la lecture dans le fichier, l'avantage étant que cela peut très bien ne pas être un fichier mais des données provenant d'autres sources.
  • - Pour recevoir un fichier, il suffit de spécifier le répertoire et le nom du fichier distant, c'est à vous également (logique), de savoir quoi faire des données que le serveur vous envoie.
  • - Pour transférer du binaire il faut auparavant utiliser la commande " MODE " pour passer en mode binaire… et ne pas oublier de repasser en mode ascii pour faire un dir.
  • - Certains clients FTP envoient régulièrement des NOOP, LIST ou STAT pour éviter d'être déconnectés à cause de timeout. A part le NOOP, les autres commandent sont utiles parce que certains serveurs détectent cette pratique et ignorent les NOOP…
  • - Pour être sûr qu'un client fonctionnera avec votre serveur, il est impératif de supporter le mode passif, sans quoi si le client a un firewall cela ne fonctionnera pas. Supporter le mode passif implique :
    • o Avoir une plage de ports libre en réception sur le serveur (configurer le firewall)
    • o Spécifier dans l'application l'adresse IP réelle sur internet (et non l'adresse IP locale)
  • - Si vous désirez interrompre un transfert, il existe plusieurs méthodes.
    • o La méthode propre consiste à envoyer une donnée spéciale sur le port de contrôle, que je n'ai pas encore réussi à faire fonctionner, la donnée était de type binaire et non une commande ABOR toute simple. ABOR est important mais il me semble qu'il faut précéder cela d'un code spécial.
    • o La méthode sale consiste à fermer la connexion data… mais quelle sera la réaction du serveur…. ?