%        File: applicatifs-TCPIP.tex
%
\documentclass[a4paper]{article}
\usepackage{pstricks,pst-node,pst-tree}
\usepackage{fancybox}

\usepackage[utf8]{inputenc}
\usepackage{fullpage}

\usepackage{listings}
\usepackage[francais]{babel}
\lstset{extendedchars=true,language=C,basicstyle=\small}

\usepackage{fancyhdr}
\pagestyle{fancy}

\rhead{Travaux pratiques}
\lhead{Votre nom :}
\lfoot{IRC2}
\rfoot{2006---2007}
\headheight 12pt
\renewcommand{\headrulewidth}{0pt}
\renewcommand{\footrulewidth}{0.4pt}

\newenvironment{question}[1][2cm]{\noindent\doublebox\bgroup\begin{tabular}{ll}\noindent\vrule depth #1 width 0cm&\begin{minipage}{\textwidth}\noindent\textbf{Question :}}{\end{minipage}\end{tabular}\egroup}

\title{Protocoles applicatifs\\TCP/IP}
\author{}
\date{22 mars 2007}
\begin{document}

\maketitle
\thispagestyle{fancy}

\section{Présentation}

  Un certain nombre d'applications et protocoles associés font partie intégrante de tout environnement TCP/IP :
\begin{itemize}
\item transfert de fichiers (FTP)
\item connexion à distance (telnet)
\item connexion sécurisée à distance (ssh)
\item transfert de courrier électronique (SMTP)
\item partage de fichiers en réseau (NFS)
\item environnements graphiques réseau (X11)
\item récupération de courrier électronique (POP, IMAP, etc.)
\item etc.
\end{itemize}

  Nous allons détailler certains de ces protocoles.

\begin{question}
Le fichier \verb!/etc/services! contient la liste des correspondances par défaut entre les ports et les protocoles
associés. Quels sont les ports associés à SMTP, HTTP, POP3, IMAP, et FTP ?
\end{question}

\section{Courrier électronique}


Le transfert (l'envoi) de courrier électronique est pris en charge par le protocole SMTP.

Ce protocole est décrit dans les RFC 821 et 822. Voir \verb!http://rfc.net/! pour consulter ces RFC.

Deux types d'application sont utilisés pour le transport de mail : le MUA (Mail user agent) comme OutLook, Thunderbird, Mutt,
etc. et le MTA (Mail Transfert Agent), comme Exchange, Postfix, Exim, Sendmail, etc.

\begin{itemize}
\item MUA
\begin{itemize}
\item Composition
\item Mise en forme, codage
\item Décodage
\item Lecture
\end{itemize}

\item MTA
\begin{itemize}
\item Transfert, routage
\item Filtrage (spam, virus, dossier\ldots)
\item Stockage
\end{itemize}

Le cheminement classique d'un mail est le suivant :
\vskip 0.5cm
\begin{psmatrix}[rowsep=0.8cm,colsep=1.3cm]
       \psframebox{MUA} & \psframebox{MTA} & \psframebox{MTA} & \psframebox{MTA} & \psframebox{MTA} & \psframebox{MUA}
       %Links
       %   \psset{shortput=tablr}
       \ncline{->}{1,1}{1,2}\naput{SMTP}
       \ncline{->}{1,2}{1,3}\naput{SMTP}
       \ncline[linestyle=dotted]{->}{1,3}{1,4}\naput{SMTP}
       \ncline{->}{1,4}{1,5}\naput{SMTP}
       \ncline{->}{1,5}{1,6}\naput{IMAP,POP}
\end{psmatrix}
\end{itemize}
\newpage

Un message est composé de deux entités/fichiers :
\begin{itemize}
\item l'enveloppe, utilisée par le MTA uniquement, qui contient le destinataire (le vrai !), la longueur du mail, etc.
\item le mail en lui même, qui est rempli par les MUA et complétés par les MTA traversés.
\end{itemize}

Le mail (en dehors de l'enveloppe, donc) est lui-même composé de deux parties : l'entête (les \textit{Headers}) et
le corps du message.

Les headers sont des lignes comportants un ``:'' comme :
\begin{itemize}
\item To:
\item Cc:
\item From:
\item Date:
\item Subject:
\item Bcc:
\item \ldots
\end{itemize}

Parmi ces headers, seuls trois sont essentiels (définis comme tels dans la RFC). La liste des headers est terminée par
une ligne vide. Ce qui suit cette ligne est donc le corps du message qui est terminé par un point tout seul sur une ligne.
La plupart des MUA proposent leur propre éditeur qui cache une grande partie du protocole (notamment le point final).

Sur la page suivante, vous trouverez un exemple d'envoi de mail à l'aide de l'utilitaire \textbf{telnet} qui permet de
se connecter à une machine distante sur un port donné, puis de ``discuter'' directement avec un serveur distant.

\newpage
\paragraph{Exemple de communication SMTP}

\begin{verbatim}
=> dindinx@coruscant:/tmp$ telnet mail.dindinx.net 25
   Trying 82.233.39.60...
   Connected to mail.dindinx.net.
   Escape character is '^]'.
   220 mail.dindinx.net ESMTP Exim 4.50 Tue, 26 Sep 2006 11:12:00 +0200
=> HELO dindinx.org
   250 mail.dindinx.net Hello dindinx.org [192.168.0.252]
=> EHLO dindinx.org
   250-mail.dindinx.net Hello dindinx.org [192.168.0.252]
   250-SIZE 52428800
   250-PIPELINING
   250 HELP
=> MAIL FROM:<david@dindinx.org>
   250 OK
=> RCPT TO:<david@dindinx.net>
   250 Accepted
=> DATA
   354 Enter message, ending with "." on a line by itself
=> Subject: Je Joue avec SMTP
=> From: moi@cpe.fr
=> To: lui@labas.com
=> 
=> Coucou,
=> 
=> Comment va ?
=> 
=> .
   250 OK id=1GS902-0005hx-Hl
=> QUIT
   221 mail.dindinx.net closing connection
   Connection closed by foreign host.
\end{verbatim}

\paragraph{Mail correspondant}

\begin{verbatim}
From dindinx  Tue Sep 26 11:23:28 2006                                                                                         
Return-path: david@dindinx.org                                                                                                 
Envelope-to: david@dindinx.net                                                                                                 
Delivery-date: Tue, 26 Sep 2006 11:14:44 +0200                                                                                 
Received: from yavin [192.168.0.251]                                                                                           
        by coruscant with POP3 (fetchmail-6.3.4)                                                                               
        for <dindinx@localhost> (single-drop); Tue, 26 Sep 2006 11:23:28 +0200 (CEST)                                          
Received: from [192.168.0.252] (helo=dindinx.org)                                                                              
        by mail.dindinx.net with esmtp (Exim 4.50)                                                                             
        id 1GS902-0005hx-Hl                                                                                                    
        for david@dindinx.net; Tue, 26 Sep 2006 11:14:44 +0200                                                                 
Subject: Je Joue avec SMTP                                                                                                     
From: moi@cpe.fr                                                                                                               
To: lui@labas.com                                                                                                              
Message-Id: <E1GS902-0005hx-Hl@mail.dindinx.net>                                                                               
Date: Tue, 26 Sep 2006 11:14:18 +0200                                                                                          
                                                                                                                               
Coucou,                                                                                                                        

Comment va ?
 
\end{verbatim}
\newpage

\begin{question}[0cm]
Lisez les RFC 821 et 822 et utilisez l'utilitaire telnet pour m'envoyer un mail. N'hésitez pas à le personnaliser.
\end{question}

\section{Récupération de courrier}

Vous savez maintenant comment envoyer un mail. Nous allons maintenant voir comment récuperer vos mails depuis une
machine distante.

\subsection{POP3}

Le protocole POP3 permet de récupérer des mails stockés sur un serveur distant. Il s'agit donc d'un transfert allant dans le
sens inverse de SMTP. Ce protocole assez simpliste est décrit par la RFC 1939.

Une transaction POP3 est toujours du même type : on commence par s'identifier (login et mot de passe), puis on peut avoir des
statistiques sur le nombre de mails présents et leur taille, récupérer un mail par son numéro ou encore supprimer un mail de
la même façon.

Afin de se fixer les idées voici un exemple de communication typique.

\begin{verbatim}
=> dindinx@coruscant:~$ telnet yavin 110
   Trying 192.168.0.251...
   Connected to yavin.
   Escape character is '^]'.
   +OK
=> USER bragui
   +OK
=> PASS bragui
   +OK
=> STAT
   +OK 3 50429
=> LIST
   +OK
   1 8162
   2 41823
   3 444
   .
=> TOP 1
   -ERR
=> RETR 3
   +OK
   Return-path: <david@dindinx.org>
   Envelope-to: bragui@dindinx.net
   Delivery-date: Wed, 27 Sep 2006 10:55:26 +0200
   Received: from [192.168.0.1] (ident=dindinx)
           by mail.dindinx.net with smtp (Exim 4.50)
           id 1GSVBn-0006ZC-L9
           for bragui@dindinx.net; Wed, 27 Sep 2006 10:55:26 +0200
   From: David
   To: Bragui
   Suject: Test pour les étudiants
   Message-Id: <E1GSVBn-0006ZC-L9@mail.dindinx.net>
   Date: Wed, 27 Sep 2006 10:55:16 +0200
   
   Coucou.
   .
=> DELE 3
   +OK
=> STAT
   +OK 2 49985
=> LIST
   +OK
   1 8162
   2 41823
   .
=> QUIT
   +OK
   Connection closed by foreign host.
dindinx@coruscant:~$
\end{verbatim}

\begin{question}[6cm]
Lisez la RFC 1939 en détail et expliquez brièvement les commandes de l'état transaction.
\end{question}

\subsection{IMAP4}

Le protocole POP3 étant assez limité (pas de gestion de dossiers, pas de gestion des accès concurrents, pas de possibilités
de récupérer seulement une partie d'un mail, etc.) le protocole IMAP4 a été mis au point pour lever la plupart de ces
limitations. Le protocol IMAP4 est décrit par la RFC 3501. Malheureusement, ce protocole est affreusement compliqué.

Nous ne détaillerons pas plus ce protocole.

\section{Transfert de fichiers}

Le protocole FTP est spécialement dédié aux transferts de fichiers. Il est défini par la RFC 959.

FTP est un protocole à authentification, qui permet assez simplement de se connecter à un serveur de fichiers distants,
d'y explorer l'arborescence et de récupérer ou stoquer des fichiers.

Les commandes principales sont :
\begin{itemize}
\item \textbf{USER} qui permet de s'identifier (anonymous si l'on ne dispose pas de compte sur le serveur)
\item \textbf{PASS} pour indiquer son mot de passe (qui n'a aucun sens particulier en cas de connexion anonyme)
\item \textbf{PWD} permet d'afficher le chemin courant
\item \textbf{CWD} permet de changer le chemin courant
\item \textbf{STAT} permet d'avoir des informations sur le serveur ou sur un chemin indiqué en paramètre
\item \textbf{HELP} permet de connaître l'ensemble des commandes supportées par le serveur
\item \textbf{FEAT} permet de connaître l'ensemble des fonctionnalités optionnelles supportées par le serveur.
\end{itemize}

Cependant pour pouvoir déposer un fichier ou en récupérer un autre, on est obligé d'ouvrir un autre canal de transfert
que celui utilisé pour taper les commandes et avoir les réponses du serveur. On dit que l'on a un canal de commandes (qui
est sur le port 21 et qui reste connecté) et un canal de données (qui est sur un autre port et qui n'existe que le temps du
transfert d'un seul fichier ou du listage d'un répertoire.

Il existe deux façons d'ouvrir ce deuxième canal (de données donc) :
\begin{itemize}
\item \textbf{PASV} qui demande au serveur d'ouvrir ce canal pour nous et de nous transmettre le numéro du port correspondant.
\item \textbf{PORT} qui indique au serveur que l'on a ouvert un port de notre côté et qu'il peut s'y connecter pour envoyer
                    les données.
\end{itemize}

Une fois que le canal de données est ouvert, on peut utiliser les commandes suivantes :
\begin{itemize}
\item \textbf{LIST} pour récupérer le listage du répertoire courant dans le canal de données (équivalent à ce que fait
                    \textbf{STAT .} dans le canal de commandes)
\item \textbf{RETR} qui permet de récupérer le contenu d'un fichier.
\item \textbf{STOR} qui permet de déposer un fichier sur le serveur.
\end{itemize}

L'exemple de communication suivant montre l'utilisation des deux canaux. Dans la partie droite, vous pouvez voir comment
les canaux de données sont créés pour chaque commande qui en demande un.

\begin{tabular}{l|l}
\begin{minipage}{0.5\textwidth}
{\tiny
\begin{verbatim}
=> dindinx@beranger:~$ telnet ftp.gimp.org 21
   Trying 128.32.112.248...
   Connected to ftp.gimp.org.
   Escape character is '^]'.
   220 Welcome to the GIMP.ORG FTP service.
=> USER anonymous
   331 Please specify the password.
=> PASS gnap
   230 Login successful.
=> PWD
   257 "/"
=> CWD /pub/gimp/v0.99
   250 Directory successfully changed.
=> STAT
   211-FTP server status:
        Connected to 134.214.49.229
        Logged in as ftp
        TYPE: ASCII
        No session bandwidth limit
        Session timeout in seconds is 120
        Control connection is plain text
        Data connections will be plain text
        At session startup, client count was 22
        vsFTPd 2.0.3 - secure, fast, stable
   211 End of status
=> HELP
   214-The following commands are recognized.
    ABOR ACCT ALLO APPE CDUP CWD  DELE EPRT EPSV FEAT HELP LIST MDTM MKD
    MODE NLST NOOP OPTS PASS PASV PORT PWD  QUIT REIN REST RETR RMD  RNFR
    RNTO SITE SIZE SMNT STAT STOR STOU STRU SYST TYPE USER XCUP XCWD XMKD
    XPWD XRMD
   214 Help OK.
=> FEAT
   211-Features:
    EPRT
    EPSV
    MDTM
    PASV
    REST STREAM
    SIZE
    TVFS
   211 End
=> STAT .
   213-Status follows:
   drwxrwsr-x    4 ftp      ftp          1024 Jun 05  1998 .
   drwxrwsr-x   21 ftp      ftp          1024 May 14  2005 ..
   lrwxrwxrwx    1 ftp      ftp             6 Oct 02  1999 .message -> README
   -rw-rw-r--    1 ftp      ftp           420 May 17  1998 README
   drwxrwsr-x   22 ftp      ftp          1024 May 17  1998 old
   drwxrwsr-x    2 ftp      ftp          1024 Nov 15  2004 v0.99.31
   213 End of status
=> PASV
   227 Entering Passive Mode (128,32,112,248,198,69)










=> LIST
   150 Here comes the directory listing.
   226 Directory send OK.



=> PASV
   227 Entering Passive Mode (128,32,112,248,225,127)









=> RETR README
   150 Opening BINARY mode data connection for README (420 bytes).
   226 File send OK.














=> QUIT
   221 Goodbye.
   Connection closed by foreign host.
\end{verbatim}
}
\end{minipage}
&
\begin{minipage}{0.5\textwidth}
{\tiny
\begin{verbatim}


















































dindinx@beranger:~$ bc                       
bc 1.06
Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
198*256+69
50757
quit
dindinx@beranger:~$ telnet ftp.gimp.org 50757
Trying 128.32.112.248...
Connected to ftp.gimp.org.
Escape character is '^]'.
-rw-rw-r--    1 ftp      ftp           420 May 17  1998 README
drwxrwsr-x   22 ftp      ftp          1024 May 17  1998 old
drwxrwsr-x    2 ftp      ftp          1024 Nov 15  2004 v0.99.31
Connection closed by foreign host.
dindinx@beranger:~$ bc                       
bc 1.06
Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
225*256+127
57727
quit
dindinx@beranger:~$ telnet ftp.gimp.org 57727
Trying 128.32.112.248...
Connected to ftp.gimp.org.
Escape character is '^]'.
This is version 0.99.31 of the GNU Image Manipulation Program.

This version is no longer distributed along with the Gtk toolkit;
you'll have to grab and install it separately.  Please install Gtk
before configuring the GIMP for compilation. This GIMP requires
GTK 1.0.1 or later.

gimp-data-extras contains a bunch of optional extra data files for GIMP.

See the files README and NOTES in the archive for more details.
Connection closed by foreign host.

\end{verbatim}
}
\end{minipage}
\end{tabular}

\begin{question}
Réalisez le même genre de capture d'écran pour récupérer un autre fichier sur un autre serveur ftp.
\end{question}

\section{Consultation d'un serveur Web}

Comme vous le savez probablement, pour récupérer une page d'un serveur web, on utilise le protocole HTTP. Ce protocole
existe sous deux versions : 
\begin{itemize}
\item HTTP 1.0 décrit par la RFC 1945.
\item HTTP 1.1 décrit par la RFC 2616.
\end{itemize}

Contrairement aux autres procotoles applicatifs que nous avons vus, HTTP ne nécessite aucune identification (pas de
login ou de mot de passe pour se connecter à un serveur). Et la plupart du temps une transaction se résume à la séquence
suivante :
\begin{itemize}
\item connexion,
\item requête,
\item réception de la réponse,
\item déconnexion.
\end{itemize}

Une requête commence systématiquement par la commande que l'on souhaite réaliser, cette commande (toujours en majuscule)
peut être :
\begin{itemize}
\item \textbf{GET} : la plus utilisée, permet de récupérer un document,
\item \textbf{HEAD} : permet de ne récupérer que l'entête (les headers) associée à un document,
\item \textbf{POST} : envoie des données à destination d'un document (le plus souvent un programme de traitement de
                      formulaires)
\item \textbf{PUT} : permet de déposer un document (peu utilisé car dangereux)
\item \textbf{DELETE}
\item \textbf{LINK}
\item \textbf{UNLINK}
\end{itemize}

Puis, suivant la commande et sur la même ligne, on trouve les paramètres de la commande. Pour \textbf{GET} et \textbf{POST}
(qui seront les seules commandes auxquelles nous nous intéresserons), les paramètres sont le nom complet du document que
l'on souhaite récupérer (chemin compris) suivit du protocole que l'on accepte, ce qui donne par exemple :
\begin{verbatim}
GET / HTTP/1.0
\end{verbatim}

ou

\begin{verbatim}
POST /validate.php HTTP/1.1
\end{verbatim}

vient ensuite une liste de lignes d'entêtes qui permettent de préciser la requète. Comme dans le cas d'envoi de mails, les
lignes d'entêtes sont du genre :
\begin{verbatim}
Attribut: valeur
\end{verbatim}

Parmi les \textit{attributs} les plus utilisés on trouve :
\begin{itemize}
\item \textbf{User-Agent:} qui permet d'indiquer le nom du navigateur que l'on utilise, le serveur HTTP peut alors décider
                           d'envoyer un document adapté.
\item \textbf{Accept:} qui permet d'indiquer les types de document que l'on accepte, par exemple \texttt{text/html}
\item \textbf{Host:} qui permet d'indiquer le nom du serveur auquel on se connecte (au cas où un même serveur héberge plusieurs
                     noms de domaine).
\item \textbf{Connection:} qui permet de définir le type de connexion, par exemple la valeur \texttt{Keep-Alive} permet de
                           maintenir la connexion entre deux GET (ou POST) ce qui permet d'être plus rapide. De plus, certains
                           serveurs réagissent différemment si le même document est demandé plusieurs fois pendant la même
                           connexion.
\item \textbf{Accept-Encoding:}
\item \textbf{Accept-Charset:}
\item etc. (voir les sections 4.5 et 5.3 de la RFC2616)
\end{itemize}

Les lignes d'entêtes non reconnues par le serveur seront simplement ignorées, on peut donc en ajouter à loisir.
La fin de la requète est signifiée par une ligne vide, ce qui provoque l'envoi de la requète.

La réponse arrive sous une forme un peu équivalente :
\begin{itemize}
\item Une première ligne indique l'état de la réponse avec éventuellement un message d'erreur (voir la section 9 de la
      RFC 1945 ou la section 10 de la RFC 2616)
\item Un certain nombre de lignes d'entête, au même format que précédemment.
\item Une ligne vide
\item Le contenu du document souhaité (même s'il y a eu une erreur)
\end{itemize}

Exemple :

\begin{verbatim}
=> $ telnet dindinx.net 80
   Trying 213.30.188.200...
   Connected to dindinx.net.
   Escape character is '^]'.
=> GET /bla.html HTTP/1.0
=> 
   HTTP/1.1 404 Not Found
   Date: Tue, 03 Oct 2006 09:13:08 GMT
   Server: Apache/2.0.54 (Debian GNU/Linux) PHP/4.3.10-16
   Content-Length: 316
   Connection: close
   Content-Type: text/html; charset=iso-8859-1
   
   <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
   <html><head>
   <title>404 Not Found</title>
   </head><body>
   <h1>Not Found</h1>
   <p>The requested URL /bla.html was not found on this server.</p>
   <hr>
   <address>Apache/2.0.54 (Debian GNU/Linux) PHP/4.3.10-16 Server at
                                cobalt.accelance.net Port 80</address>
   </body></html>
   Connection closed by foreign host.
\end{verbatim}
\newpage
autre exemple :

\begin{verbatim}
=> $ telnet dindinx.net 80
   Trying 213.30.188.200...
   Connected to dindinx.net.
   Escape character is '^]'.
=> GET /files/hanoi.c HTTP/1.0
=> Host: dindinx.net
=> User-Agent: telnet
=> Accept: */*
=> 
   HTTP/1.1 200 OK
   Date: Tue, 03 Oct 2006 09:18:59 GMT
   Server: Apache/2.0.54 (Debian GNU/Linux) PHP/4.3.10-16
   Last-Modified: Mon, 04 Sep 2006 21:22:18 GMT
   ETag: "7fbb-a5-5630d680"
   Accept-Ranges: bytes
   Content-Length: 165
   Connection: close
   Content-Type: text/x-csrc
   
   i;main(){while(++i<16)printf("%d-->%d\n",(i&i-1)%3,((i|i-1)+1)%3);}
   //main(i,v)char**v;{for(i=1;i<1<<atoi(v[1]);i++)printf("%d-->%d\n",(i&i-1)%3,
   //((i|i-1)+1)%3);}
   Connection closed by foreign host.
\end{verbatim}

\begin{question}
Que se passe-t-il si on oublie l'entête Host dans l'exemple précédent ? Pourquoi ?
\end{question}

\begin{question}[15cm]
Essayez la commande GET du protocole HTTP pour récupérer le contenu de différentes pages sur le web. Que donne la page de
Google ? Pourquoi ? En vous aidant de l'option \textbf{-d} de l'utilitaire \textbf{wget} récupérez la véritable page
d'index et mettez-vous à la place d'un navigateur web graphique afin de savoir quelles sont toutes les commandes GET
nécessaires pour dessiner la page d'accueil de Google.

\end{question}

\end{document}


