Programmation réticulaire
Transcription
Programmation réticulaire
Programmation réticulaire Client-serveur Christian Queinnec Professeur émérite de l’UPMC Paracamplus by C.Queinnec Programmation réticulaire 1/139 I Cours dispensé à l’INSTA I en octobre 2015 by C.Queinnec Programmation réticulaire 2/139 Plan I Historique de l’invocation à distance I Mécanismes de RPC I Interfaces et génération I Rappels HTML I HTTP I Ressources I Génération de pages I Caractères I Sécurité by C.Queinnec Programmation réticulaire 3/139 Visions Deux visions s’opposent: I service I I I I point d’entrée d’un traitement « fonction » invocable à distance Ce cours s’intéresse surtout aux services vus du client ressource I concept ayant plusieurs représentations ou apparences possibles by C.Queinnec Programmation réticulaire 4/139 Partie 1 Historique by C.Queinnec Programmation réticulaire 5/139 L’invocation à distance 1982: The network is the computer: NFS, RPC, XDR. Courier (Mesa) [Xerox PARC] I ASN.1 & RPC+IDL I Corba, DCOM I Java, RMI I XML, XMLRPC, SOAP, WS-* I JSON, Ajax by C.Queinnec Programmation réticulaire 6/139 L’invocation I valeurs → endroits connus I saut vers appelé I résultats → endroits connus I reprise appelant by C.Queinnec Programmation réticulaire 7/139 L’invocation à distance I valeurs → endroits connus I saut vers appelé I résultats → endroits connus I reprise appelant C’est pareil, mais . . . I Non immédiateté des transferts d’information I Risque d’erreur dans la propagation I Copie des données I Coût des transmissions I Niveau de sécurité différent by C.Queinnec Programmation réticulaire 8/139 Partie 2 Remote Procedure Call by C.Queinnec Programmation réticulaire 9/139 XDR (l’ancêtre) en quelques mots I Tout est transmis par mots de 4 octets I L’ordre des octets est fixé I Types de données C (entiers, flottants, caractères simples, répétitions, structures, tableaux) Plutôt nommé « sérialisation » maintenant suite à Java. by C.Queinnec Programmation réticulaire 10/139 L’essence du RPC Code original: z = f(x, y); et bibliothèque originale: function f (x, y) { return ...; } by C.Queinnec Programmation réticulaire 11/139 Transformation côté client Principe: simplifier le client au maximum au détriment du serveur. Simple et seul changement de bibliothèque: function f (x, y) { return decode(invoke("f", encode(x), encode(y))); } encode envoie, invoke exécute, decode reçoit. by C.Queinnec Programmation réticulaire 12/139 Transformation côté serveur Bibliothèque originale: function f (x, y) { return ...; } function invoke (fnName, x, y) { if ( fnName == "f" ) { return encode(f(decode(x), decode(y))); } else if ... by C.Queinnec Programmation réticulaire 13/139 code bibliothèque code bibliothèque2 relais proxy by C.Queinnec serveur bibliothèque génération? Programmation réticulaire 14/139 Corba et autres intergiciels I I Afin de pallier l’absence de pointeurs, introduction de « fournisseur de services » distants et partagés. Indépendance vis-à-vis des langages de programmation: IDL (Interface Definition Language). fs.service(argument,...) orb.invoke(fs,"service",arguments) ORB ORB orb.invoke(fs,"service",arguments) by C.Queinnec Programmation réticulaire 15/139 ASN.1 I Un langage de description de données (et de signatures de fonctions). I Types de base: entier, flottant, booléen, caractère. I Composeurs de types: enregistrement, répétition, union. ASN.1 utilisé dans les normes Implantation d’ASN.1 (BER, DER, etc.) utilisée pour les certificats X509 by C.Queinnec Programmation réticulaire 16/139 Java et RMI I RMI = RPC en et pour Java I IDL ≈ interface (idl2java, java2idl) I service associé d’annuaire JNDI Sérialisation ayant de nombreuses propriétés supplémentaires: I particularisable I resynchronisable I lien vers classes I gestion des versions des classes by C.Queinnec Programmation réticulaire 17/139 XML et SOAP XML: un langage parenthésé décrivant des arbres régis par une grammaire (DTD, XML schéma, RelaxNG). Pourquoi donc ne pas échanger en XML ? 1998: XMLRPC, 1999: SOAP, 2005: JBI (XML + pièces jointes) <f><x>3.14</x> <y>2</y> </f> <fresult>-1.0</fresult> by C.Queinnec Programmation réticulaire 18/139 JSON En fait, on n’a besoin que de manipuler des données assimilables par Javascript et donc des atomes (nombres, chaînes), des tableaux et des tables associatives (des dictionnaires). { callee: "f", arguments: { x: 3.14, y: 2 }, "argument-values": [ 3.14, 2 ] } Beaucoup plus compact qu’XML, couplable avec JSONP by C.Queinnec Programmation réticulaire 19/139 Partie 3 Interfaces et générations by C.Queinnec Programmation réticulaire 20/139 De l’importance des interfaces I L’interface est primordiale. Elle décrit les services que peut rendre un « fournisseur de services ». Techniquement c’est un ensemble de types décrivant les signatures des services et les données échangées. I Il existe plusieurs types d’IDL: l’IDL de Corba, l’IDL de COM (extension de celui de DCE), les interfaces de Java, etc. I Historiquement fondé sur C, ils incorporent maintenant des exceptions ainsi que des annotations sémantiques ou de qualité de services. by C.Queinnec Programmation réticulaire 21/139 Génération d’encodeur/décodeur Soit le type de la fonction originale f: double function f (real x, int y); Côté client, on peut la remplacer par: double function f (real x, int y) { Requete _requete = allouer_Requete("f "); encode_real(x, _requete); encode_int(y, _requete); send_request_then_wait_for_answer(_requete); return decode_double(_requete); } f f by C.Queinnec real int Programmation réticulaire 22/139 Côté serveur: void function receive_Requete (Requete requete) { if ( requete.fnName == "f " ) { receive_Requete_f (requete); } else if ... void function receive_Requete_f (Requete _requete) { real x = decode_real(_requete); int y = decode_int(_requete); double _d = f (x, y); encode_double(_d, _requete); answer(_requete); } f connexion (socket) client double client by C.Queinnec f real int Programmation réticulaire 23/139 Génération de serveur On veut procurer les deux services suivants (avec rpcgen): double function f (real x, int y); real function g (); double function f (real x, int y) { return ...; } real function g () { return ...; } by C.Queinnec Programmation réticulaire 24/139 Voici le programme serveur engendré: void function main () { make_server_listen(); while ( (Requete requete = get_next_Requete()) ) { serve(requete.service_name, requete); } } void function serve (string service_name, Requete requete) { if ( service_name == "f " ) { handle_Requete_f (requete); } else if ( service_name == "g" ) { handle_Requete_g(requete); } else { requete.status = NoSuchService; } answer(requete); } by C.Queinnec Programmation réticulaire 25/139 void function handle_Requete_f (Requete _requete) { real x = decode_real(_requete); int y = decode_int(_requete); double _d = f (x, y); encode_double(_d, _requete); } void function handle_Requete_g (Requete _requete) { real _r = g(); encode_real(_r, _requete); } double function f (real x, int y) { return ...; } real function g () { return ...; } by C.Queinnec Programmation réticulaire 26/139 Publicité/introspection struct struct_Service { string name; struct_Type result; int argument_length; struct_Type[] argument; // string comment; }; struct struct_Services { int number; struct_Service service[2]; } les_services { // ou en WSDL 2, { { "f", DOUBLE, 2, {REAL, INT} }, { "g", REAL, 0, {} } } }; void function handle_Requete_services (Requete reque encode_struct_Services(les_services, requete); } by C.Queinnec Programmation réticulaire 27/139 Qualité des types I Type → vérification de types I Type → encodeur/décodeur (ORB) I Type → serveur (rpcgen, ORB) I Type → publicité (UDDI Universal Description, Discovery, and Integration), JNDI, JINI, LDAP, UPnP, JBI I Type → introspection (XML SOAP) I Type → invocation dynamique by C.Queinnec Programmation réticulaire 28/139 Les grands points de choix IDL serveur client fs.service(arg...) éventuellement retour binaire(XDR, RMI) textuel(XML, SOAP,JSON) sérialisation exécution [fs,service,args,émetteur] recherche UDDI JNDI Corba désérialisation transport synchrone (HTTP, connexion) asynchrone (SMTP) by C.Queinnec Programmation réticulaire 29/139 Choix formalisme Comment décrire les services ? I interface en Java (compilateurs idl2java, java2idl) I description en IDL (compilateurs de codeur/décodeur vers langages de programmation à la Corba) descripteur XML (WSDL) (compilation/interprétation des descripteurs) I I en WSDL, description additionnelle pour le transport I annotations dans code Java, C# pour engendrer le précédent descripteur I utilisation des capacités réflexives pour ne même plus annoter Soucis sur certains types de données. by C.Queinnec Programmation réticulaire 30/139 Choix sérialisation I Comment coder/empaqueter l’information ? I I I I binaire: efficace, difficilement déployable, couplage client/serveur, peu évolutif textuel: verbeux, universel, déployable (print/read), assez évolutif, relayable, vérifiable (grammaires) Soucis pour pointeurs, fonctions, . . . sans oublier l’émetteur! Autres considérations: I I I I sécurité, signature, chiffrement intégrité (résistance aux pannes), resynchronisation, gestion des versions client/serveur, auto-description qualité de service, priorité, relais, by C.Queinnec Programmation réticulaire 31/139 Choix recherche Où se trouve un fournisseur de services ? I ports bien connus I sites bien connus (DNS) I annuaire caché dans les ORB (Corba) I annuaire UDDI, JNDI, JINI, LDAP, UPnP, JBI Dans tous les cas, un fournisseur de services s’enregistre sous un nom dans un annuaire par lequel il pourra être retrouvé, il spécifie aussi comment on doit lui parler. by C.Queinnec Programmation réticulaire 32/139 Choix de couplages Du côté du langage du serveur, on peut souhaiter voir: I un objet Request lié au cadre employé (Axis par ex.) I un DOM (ou un SAX dégraissé) I un POJO (Plain Old Java Object) Idem côté client. by C.Queinnec Programmation réticulaire 33/139 Choix transport I synchrone (HTTP, FTP, connexion) ou asynchrone (SMTP, RSS) I avec retour ou pas I au plus, au moins une fois by C.Queinnec Programmation réticulaire 34/139 Partie 4 Rappels d’HTML by C.Queinnec Programmation réticulaire 35/139 HTML (rappels) I Langage de mise en page (ou plutôt en écran) de textes I avec (un peu) structuration de données (cf. XML) I langage parenthésé à balises I balises spécialisées pour interactions côté client I séparation du style du rendu Note: HTML 2, 3, 4, XHTML, HTML5, etc. Note: CSS 1, 2, 3 by C.Queinnec Programmation réticulaire 36/139 Taxonomie de quelques balises html, head, body, h1, h2, . . . , h6, p, ul, ol, li, dl, dt, dd, a, table, tr, th, td, div, span, frame, frameset, iframe, meta pre (cas délicat!) address, base, blockquote, caption, code, cite, img, link map, area, applet, param, bgsound, embed, object form, button, input, select, option, textarea tt, em, b, i, u, font, hr, big, small, strong, strike, blink, br, center by C.Queinnec Programmation réticulaire 37/139 Formulaires Des balises existent mettant en place des « widgets » de saisie d’information au sein d’un (ou plusieurs) formulaire(s) (pour form): I champ de texte (sur une ou plusieurs lignes), I champ sans écho (pour mot de passe), I boutons radio, I case à cocher, I menu, I bouton d’envoi de fichier, I bouton caché, I boutons d’envoi, de ré-initialisation. by C.Queinnec Programmation réticulaire 38/139 Syntaxe d’un formulaire par l’exemple <form name=’nom du formulaire’ method=’GET ou POST’ enctype=’application/x-www-form-urlencoded ou multipart/form-data’ action=’url’ > Votre nom: <input type=’textfield’ name=’t1’ value=’votre nom’ size=20 maxlength=30> Votre <strong>raison</strong> de vivre: <textarea name=’t2’ rows=4 cols=40> ecrire ici </textarea> Votre mot de passe: <input type=’password’ name=’t3’ size=10> Votre sexe: Homme:<input type=’radio’ name=’t4’ value=’male’ checked> Femme:<input type=’radio’ name=’t4’ value=’femelle’> Votre etat: fatigue: <input type=’checkbox’ name=’t5’ value=’fatigue’> serein: <input type=’checkbox’ name=’t6’ value=’serein’> <input type=’file’ name=’t7’ size=50 maxlength=80> <select name=’t8’><option><em>a</em> <option selected>B</select> <input type=’hidden’ name=’t9’ value=des caracteres’> <input type=’submit’ name=’doit’ value=’Envoyer’> <input type=’reset’ value=’Re-initialiser’> </form> by C.Queinnec Programmation réticulaire 39/139 by C.Queinnec Programmation réticulaire 40/139 Caractéristiques communes I Tous les widgets demandant de l’information ont un nom, I ils peuvent avoir une valeur par défaut, I ainsi que quelques paramètres pour fignoler leur apparence. La syntaxe n’est pas très uniforme (notamment les balises textarea et select). by C.Queinnec Programmation réticulaire 41/139 Ce qui se passe 1. Quand un navigateur reçoit un formulaire, il interprète le source HTML et affiche le texte et les widgets. 2. Il joue ensuite le rôle d’un éditeur de texte pour les widgets de texte (balises textfield ou textarea ou password) (en Netscape, Mozilla c’est un petit Emacs). 3. Il s’occupe également des coches, des choix dans les menus déroulants etc. 4. En local, il sait remettre le formulaire dans son état initial (avec le bouton de ré-initialisation). 5. Enfin, quand le bouton d’envoi est pressé, il sait envoyer les informations recueillies. Le serveur n’est donc pas sollicité pendant toute la durée où l’utilisateur remplit le formulaire. by C.Queinnec Programmation réticulaire 42/139 Partie 5 HTTP by C.Queinnec Programmation réticulaire 43/139 HTTP I Protocole d’échange d’information textuel Hypertext Transfer Protocol I dans la lignée de smtp, ftp I HTTP/1.1 spécifié en 1997 by C.Queinnec Programmation réticulaire 44/139 URI, URL, URN URI signifie Universal Resource Identifier. Une URI est un nom qui désigne une ressource (de nature quelconque). Une URI répond à une syntaxe précise permettant d’être: I communicable (imprimable) I extensible I complète (permet de tout nommmer) URL signifie Universal Resource Locator. C’est une URI spécialisée pour le nommage de ressources devant être accédée par des protocoles Internet. by C.Queinnec Programmation réticulaire 45/139 URN URN signifie Universal Resource Name. Une URN vise à donner un nom unique et persistant à une ressource indépendamment des façons par lesquelles elle peut être accédée. Les URN doivent aussi étendre les schémas de nommage universels tels que ISBN, ISO, etc. URN, Clarification UR? by C.Queinnec Programmation réticulaire 46/139 URI URI = scheme : path Le sens de la chaîne path dépend du schéma de nommage employé. Tout ce qui n’est pas ASCII (alphabet 7bits) est encodé avec (%hh). Le % est réservé à ces encodages. Le blanc doit toujours être encodé (à cause du courrier). Les /, ., .. ont des sens suggérés (de parcours d’arbre) # délimite un fragment de la ressource nommée (ce qui suit n’est pas envoyé au serveur). ? délimite le début de paramètres additionnels. by C.Queinnec Programmation réticulaire 47/139 URI relative URI = path Une URI relative (sans :) se complète à l’aide d’une URI complète existante (par exemple, celle du document qui contient cette uri). Le schéma est nécessairement le même. by C.Queinnec Programmation réticulaire 48/139 URI relative: exemples Si la chaîne path est hiérarchique alors, grosso-modo, on interprète l’uri relative un peu comme un nom relatif dans une hiérarchie de fichiers. /a/b/c /a//b/c d ../d /d //d by C.Queinnec → → → → /a/b/d /a/d /d /a//d dangereux! Programmation réticulaire 49/139 Schémas d’URI I http Hypertext Transfer Protocol I ftp File Transfer protocol I gopher Gopher protocol I mailto Electronic mail address I news Usenet news I telnet, rlogin and tn3270 Reference to interactive sessions Et d’autres encore: I wais Wide Area Information Servers I file Local file access by C.Queinnec Programmation réticulaire 50/139 URL scheme://user:passwordhost:port/url-pathscheme://userhos scheme://host:port/url-path scheme://host/url-path Le serveur est un FQDN (Fully Qualified Domain Name) ou un numéro IP. Le port est un naturel décimal. by C.Queinnec Programmation réticulaire 51/139 URL pour ftp ftp://user:passwordhost:port/url-path;type=typecodeftp:/ Le type est optionnel (synthétisé par défaut par le client). Il correspond au type de transfert (texte, binaire) souhaité. Exemples: ftp://[email protected]/%2Fetc/motd ftp://[email protected]/etc/motd correspond à: ftp host.dom, USER myname, mot de passe, CWD /etc (resp. CWD etc), GET motd. by C.Queinnec Programmation réticulaire 52/139 Quelques autres URLs mailto:[email protected] nntp://news.ext.jussieu.fr/gnu.emacs.sources/12 telnet:[email protected] file://maya.infop6.jussieu.fr/usr/bin/date file:///etc/hostname by C.Queinnec Programmation réticulaire 53/139 URL pour HTTP http://host:port/path?querystring http://host:port/path http://host:port Une référence est parfois suffixée comme suit: http://www.infop6.jussieu.fr/evaluation/spip/rubrique.ph Notez que le fragment (préfixé par #) ne fait pas partie de l’URL. La ressource spécifiée par l’URL est récupérée depuis le réseau et le navigateur en extrait le fragment mentionné (ou le rend directement apparent sur l’écran). by C.Queinnec Programmation réticulaire 54/139 Messages HTTP start line CR LF name:value CR LF autant que de parametres HTTP CR LF message body Pour les requêtes, la première ligne est: method SP uri SP HTTP/1.version La méthode peut être: GET ou HEAD (obligatoirement implantées par le serveur) ou encore OPTIONS, POST, PUT, DELETE, TRACE, CONNECT ou encore autre chose. Le second champ peut être une URL complète ou juste un chemin d’accès (dans ce dernier cas, le paramètre HTTP Host est recommandé). by C.Queinnec Programmation réticulaire 55/139 Pour les réponses, la première ligne est: HTTP/1.version SP code SP paraphrase Le code s’exprime en 3 chiffres, la paraphrase est humainement lisible. I 1xx en cours de traitement I 2xx succès I 3xx redirection I 4xx erreur client I 5xx erreur serveur by C.Queinnec Programmation réticulaire 56/139 Paramètres HTTP Le nom du paramètre n’est pas sensible à la casse. Il peut y avoir des blancs superflus juste après le : et avant le CR LF. L’ordre des paramètres n’est pas important mais le plus souvent du plus général au plus particulier. Il est possible de donner plusieurs fois un même paramètre (ordre signifiant donc). Foo: a Bar: c Foo: b by C.Queinnec Foo: a, b Bar: c Programmation réticulaire 57/139 Classification des paramètres I décrivant des généralités I décrivant la connexion I décrivant le serveur (ou le client) I I I I I I Accept: Accept-Charset: Accept-Encoding: Accept-Language: User-Agent: Server: Transfer-Encoding: From: Host: If-Modified-Since: Retry-After: Referer: décrivant une ressource dans le message I I Connection: Max-Forwards: (et méthode OPTIONS) décrivant le message (la requête ou la réponse) I I Date: Content-Type: Location: Age: ETag: If-None-Match: Allow: Content-Encoding: Content-Length: Content-MD5: Content-Language: Expires: Last-Modified: suggérant des règles de transmission I Pragma: Cache-Control: by C.Queinnec Programmation réticulaire 58/139 Entité dans corps de message Le type MIME (pour Multipurpose Internet Mail Extensions) classifie les sortes d’entité. Originellement fait pour passer des fichiers par courrier électronique (7bits, 100K). Syntaxiquement: catégorie/nature text/plain text/html text/rtf image/gif image/png audio/ video/ application/postscript application/x-dvi application/rtf application/vnd.ms-excel by C.Queinnec Programmation réticulaire 59/139 Ce type est utilisé dans le paramètre HTTP Content-Type et peut être accompagné d’options comme: Content-Type: text/html; charset=ISO-8859-1 Fichier .mime.types pour associer des applications (ou actions) à ces types. Cf. aussi KDE, Gnome, etc. by C.Queinnec Programmation réticulaire 60/139 Méthodes I Les méthodes GET ou HEAD (obligatoirement implantées par le serveur) doivent être idempotentes c’est-à-dire sans effet de bord. I Les méthodes POST, PUT, DELETE ne sont pas idempotentes. L’uri de POST indique le processus qui traitera la requête, l’uri de PUT désigne le nom de la ressource à créer. I La méthode TRACE permet d’inspecter la connexion à la manière d’un ping ou d’un traceroute. I Remarque: pas de DIR en HTTP! by C.Queinnec Programmation réticulaire 61/139 Quelques exemples GET / HTTP/1.0 GET http://www.infop6.jussieu.fr/licence/ HTTP/1.0 If-Modified-Since: Sun, 06 Nov 1994 08:49:37 GMT by C.Queinnec Programmation réticulaire 62/139 GET /licence/2001/licence/public/module.php?id=6 HTT Accept-Language: fr, en Pragma: no-cache Accept: image/gif, image/x-xbitmap, image/jpeg, imag Accept-Charset: iso-8859-1,*,utf-8 Host: www.infop6.jussieu.fr Accept-Encoding: gzip User-Agent: Mozilla/4.78 [en] (X11; U; Linux 2.4.8-3 Proxy-Connection: Keep-Alive If-Modified-Since: Mon, 31 Dec 2001 14:14:29 GMT; le Referer: http://www.infop6.jussieu.fr/licence/2001/l by C.Queinnec Programmation réticulaire 63/139 Envoi des informations au serveur I Les informations recueillies (coches, choix, textes, fichiers) sont conditionnées pour être envoyées au serveur (spécifié par l’URL de l’attribut action de la balise form). I Attention, souvent les navigateurs n’envoient de l’information que si elle a été saisie ou modifiée. I L’encodage par défaut est application/x-www-form-urlencoded. Les valeurs sont conditionnées sous la forme d’une chaîne (avec les conventions d’encodage propres aux URL (+, %xy, &): nom=valeur&nom=valeur&nom=valeur by C.Queinnec Programmation réticulaire 64/139 Côté serveur <form method=’GET’ action=’url’> Nom:<input type=’text’ size=10 name=’n’> <input type=’submit’ name=’do’ value=’Envoyer’> </form> ’n’ ’do’ H ’Moi’ ’Envoyer’ Nom: Moi GET url?do=Envoyer&n=Moi HTTP/1.0 Envoyer Côté client by C.Queinnec Programmation réticulaire 65/139 Côté serveur <form method=’POST’ action=’url’> Nom:<input type=’text’ size=10 name=’n’> <input type=’submit’ name=’do’ value=’Envoyer’> </form> Nom: Moi Envoyer ’n’ ’do’ H ’Moi’ ’Envoyer’ POST url HTTP/1.0 Content−Type: application/x−www−form−url−encoded Content−Length: 16 do=Envoyer&n=Moi Côté client by C.Queinnec Programmation réticulaire 66/139 Cette chaîne peut être envoyée à l’URL sous la forme d’une requête HTTP de type GET: GET url?nom=valeur&nom=valeur&nom=valeur ...autres parametres de requete ou de type POST: POST url Content-Type: application/x-www-form-urlencoded Content-Length: 32 ...autres parametres de requete nom=valeur&nom=valeur&nom=valeur by C.Queinnec Programmation réticulaire 67/139 Enfin existe encore l’encodage multipart/form-data POST url Content-Type: multipart/form-data; boundary=0xKhTmLbOuNdArY ...autres parametres de requete --0xKhTmLbOuNdArY Content-Disposition: form-data; name="n" Moi --0xKhTmLbOuNdArY Content-Disposition: form-data; name="do" Envoyer --0xKhTmLbOuNdArY-- by C.Queinnec Programmation réticulaire 68/139 Les transports de type POST sont les plus sûrs (parce qu’ils sont insensibles à la taille des données (ce qui n’est pas le cas de GET) et permettent de spécifier l’alphabet utilisé (pour les lettres accentuées)), l’encodage multipart/form-data sait envoyer des fichiers ce que ne sait pas faire application/x-www-form-urlencoded mais impose le recours à une bibliothèque pour l’extraction des paramètres. by C.Queinnec Programmation réticulaire 69/139 Côté serveur Le serveur doit pouvoir fournir à une application les couples nom-valeur quelque soit l’encodage et le conditionnement (type MIME) queryString = GETparameters requestMethod "q1" pathInfo "q2" POST uri?q1=v1&q2=v2 HTTP/1.1 Parm1: valeur1 Parm2: valeur2 "var1" "var2" H "v1" "v2" RemoteHost RemotePort ServerPort ServerProtocol ServerHost var1=val1&var2=val2 POSTparameters H HTTPparameters "val1" "Parm1" "val2" "Parm2" H "valeur1" "valeur2" Directive Status: 200 super! pour indiquer le code. by C.Queinnec Programmation réticulaire 70/139 Pages dynamiques L’interprétation de l’URL est à la discrétion du serveur. La décoder suivant le système de fichiers du serveur est une option simple mais ce n’est pas la seule. On peut synthétiser la réponse et ainsi avoir des pages dynamiques. Un jeu de convention pour transporter des paramètres (ou des fichiers) et lancer, côté serveur, les traitements appropriés. Limitation de la taille d’une URL, visibilité des paramètres, non idempotence des requêtes GET. by C.Queinnec Programmation réticulaire 71/139 by C.Queinnec Programmation réticulaire 72/139 Informations La requête comporte de nombreux points où passer de l’information: I l’URI, I la chaîne des paramètres de requête (ou query-string), I les paramètres HTTP, I le corps du message. by C.Queinnec Programmation réticulaire 73/139 Toute bibliothèque raisonnable permet d’obtenir toutes ces informations: I l’uri (ou ses divers constituants (protocole, hôte, port, chemin (chemin telquel, inteprété par rapport au système de fichiers), I les paramètres de requête (tous (en table de hachage) ou un par un) I les paramètres HTTP (tous ou un par un) I le corps du message (comme un flux ou si c’est une requête POST, comme une suite de paramètres de requête (tous ou un par un) Attention, pour tous les paramètres de tout type, un nom mène à une suite (ordonnée) de valeurs (des chaînes) (souvent une seule mais pas toujours). Certains paramètres HTTP influencent le décodage des autres parties du message. by C.Queinnec Programmation réticulaire 74/139 les grandes étapes d’un serveur 1. décodage url (de la gauche vers la droite) 2. décodage de la chaîne de requête et des paramètres http 3. recherche fichier/programme I I droits d’accès, réécriture, paramétrage, 4. détermination type mime du résultat I I I suffixe du fichier, règles locales (.htaccess) analyse du début de la réponse 5. génération du corps de la réponse 6. en HTTP/1.0, fermeture de la connexion by C.Queinnec Programmation réticulaire 75/139 Codes d’HTTP I I I I I I I I I I I I I I I I I 200 OK 201 Created (+ Location pour URI canonique) 202 Accepted (+ Location pour URI de contrôle) 204 No Content (la représentation est vide) 301 Moved Permanently (+ Location) 303 See Other (+ Location pour le contenu de la réponse) 304 Not Modified 307 Temporary Redirect (+ Location pour re-soumettre la requête) 400 Bad Request 404 Not Found 405 Method Not Allowed 406 Not Acceptable (pas de représentation acceptable) 409 Conflict 410 Gone 415 Unsupported Media Type 500 Internal Server Error 503 Service Unavailable by C.Queinnec Programmation réticulaire 76/139 Interface CGI Lancer des programmes extérieurs en leur donnant les informations de la requête cf. standard Les premières lignes sont analysées et rendues sous la forme de variables d’environnement: I I I I I I I I I I I I I I SERVER_SOFTWARE SERVER_NAME GATEWAY_INTERFACE SERVER_PROTOCOL SERVER_PORT REQUEST_METHOD PATH_INFO PATH_TRANSLATED SCRIPT_NAME QUERY_STRING REMOTE_HOST REMOTE_ADDR CONTENT_TYPE CONTENT_LENGTH by C.Queinnec Programmation réticulaire 77/139 Les paramètres HTTP sont analysés et rendus sous forme de variables d’environnement préfixés par HTTP_. I HTTP_ACCEPT I HTTP_USER_AGENT Le corps du message est fourni dans le flux d’entrée standard du programme. La longueur de ce flux se trouve dans la variable CONTENT_LENGTH, sa nature dans CONTENT_TYPE. Le serveur analyse la sortie standard du programme. Les première lignes doivent être des paramètres HTTP (au minimum Content-Type) éventuellement précédé du code HTTP de retour (sinon il sera positionné à 200 si tout se passe bien par le serveur) puis une ligne vide puis le corps du message. by C.Queinnec Programmation réticulaire 78/139 Exemples de CGI Rendre la date: #! /bin/sh echo ’Content-Type: text/plain’ echo date Autre exemple de script CGI, aussi en shell: #! /usr/bin/tail +1 Content-Type: text/html <html><head><title>Page statique</title></head> <body>Ceci est une page statique.</body></html> by C.Queinnec Programmation réticulaire 79/139 Pour voir ce que l’interface CGI a placé dans l’environnement: #! /bin/sh echo ’Content-Type: text/html’ echo echo ’<html><head><title>Environnement CGI</title>’ echo ’</head><body><pre>’ printenv echo ’</pre></body></html>’ CGI est lent mais simple! Voir aussi FastCGI. Principal langage pour CGI: Perl (et mod_perl) by C.Queinnec Programmation réticulaire 80/139 Maintenir un état côté serveur HTTP est un protocole sans état. Pour maintenir un état il faut être capable de déterminer si deux requêtes viennent du même utilisateur. I bouton caché I cookie I réécriture d’URL I session SSL by C.Queinnec Programmation réticulaire 81/139 Bouton caché Si la réponse du serveur est un formulaire: <----------------- reponse serveur <form ...> <input type=’hidden’ name=’n’ value=’v’> </form> -----------------> nouvelle requete client n=v Problèmes: I ne fonctionne que pour les formulaires I modifiable par l’utilisateur by C.Queinnec Programmation réticulaire 82/139 Cookies But: tracer les utilisateurs en stockant de l’information dans le client. <------------- 200 OK Set-Cookie: NGUserID=3e17099b-28471-1016452371-1; expires=Wednesday, 30-Dec-2037 16:00:00 GMT; path=/; domain=.hi-media.com -------------> GET www.hi-media.com/url Cookie: NGUserID=3e17099b-28471-1016452371-1 Limitation en taille et nombre (20 cookies de 4Ko). Attention à la comparaison de noms d’hôtes. Sans date de péremption, un cookie meurt quand on quitte son navigateur. by C.Queinnec Programmation réticulaire 83/139 Documentation simple sur cookie Pour des cookies plus modernes: <------------- 200 OK Set-Cookie: NGUserID=3e170; Max-Age=300; Path=/; Domain=.hi-media.com; secure; Comment="Le cookie moderne!"; Version=1 -------------> GET www.hi-media.com/url Cookie: $Version="1"; NGUserID=3e170; other=42 RFC nouveau cookie Principe: ne jamais faire confiance à l’information venant du client! by C.Queinnec Programmation réticulaire 84/139 Réécriture d’URL <------------------ reponse serveur href=’http://hote:port/path/info’ <------------------ transforme en href=’http://hote:port/path/info?SESSIONID=xxxx’ href=’http://hote:port/path/info;SESSIONID=xxxx’ href=’http://hote:port/path/info/xxxx’ href=’http://hote:port/xxxx/path/info’ href=’http://hotexxxx:port/path/info’ by C.Queinnec Programmation réticulaire 85/139 Réécriture d’URL (problèmes) I toutes les pages sont dynamiques puisque toutes les urls doivent être réécrites. I nécessité de coopération entre toutes les pages pour adopter un schéma commun d’encodage I l’information est modifiable par l’utilisateur by C.Queinnec Programmation réticulaire 86/139 Autres techniques Nouveau, pour traquer le client: utilisation des champs HTTP Last-Modified ou ETags. Cookies croisés by C.Queinnec Programmation réticulaire 87/139 Authentification Accès à une zone protégée: ------------> GET url <------------ 401 unauthorized WWW-Authenticate: Basic realm="Secret P6" ------------> GET url Authorization: Basic base64("user:password") <------------ 200 page (en clair) ------------> GET url/sousurl Authorization: Basic base64("user:password") <------------ 200 page (en clair) by C.Queinnec Programmation réticulaire 88/139 I liberté du client pour la demande de nom/mot de passe. I liberté du serveur de la vérification nom/mot de passe (fichier, base n?dbm, base de données, etc.) I Pas de déconnexion prévue. I Autre méthode: Digest (avec défi ou nonce). by C.Queinnec Programmation réticulaire 89/139 HTTPS I Forcer l’usager à utiliser une communication chiffrée (SSL, TLS) par le protocole HTTPS. I Comment est négocié un canal chiffré non observable (il y a des variantes): by C.Queinnec Programmation réticulaire 90/139 ClientHello ----------------> <----------------- ServerHello <----------------- Certificat <----------------- ServerKeyExchange? <----------------- CertificateRequest? <----------------- ServerHelloDone Certificate? ---------------> ClientKeyExchange ----------> ChangeCypherSpec -----------> Finished -----chiffre-------> <----------------- ChangeCypherSpec <---chiffre------- Finished Sur le canal chiffré passe de multiples requêtes (en HTTP/1.1). Tant que le canal reste ouvert, l’interlocuteur n’a pas changé. Enfin on peut utiliser de l’authentification via HTTPS. by C.Queinnec Programmation réticulaire 91/139 Les besoins fondamentaux I Discrétion (ne pas être lu par autrui) I Intégrité (l’information n’a pas été altérée) I Authentification (être sûr de l’auteur) I Non-répudiation (l’auteur ne peut nier sa qualité) by C.Queinnec Programmation réticulaire 92/139 Principes du chiffrement 1. Soit t un texte clair 2. soit C un algorithme de chiffrement 3. alors au lieu de transmettre t, on transmet m = C(t) 4. Si le destinataire connaît C −1 , 5. il calcule C −1 (m) = C −1 (C(t)) = t by C.Queinnec Programmation réticulaire 93/139 Desiderata Il est très difficile de fabriquer une bonne fonction C mais plus facile si l’on suit le cours Cryptographie+Compression dans la spécialité STL de master! I C(t) doit se calculer vite (sans limite de taille pour t) I C −1 (m) doit se calculer vite I Trouver t à partir de m doit être difficile I Trouver C −1 à partir de C doit être difficile by C.Queinnec Programmation réticulaire 94/139 Solution Une solution: C doit être un algorithme paramétré public. Le paramètre se nomme la clé k, l’algorithme de chiffrement est donc Ck . Les seules informations à propager sont les clés. Les algorithmes secrets largement disséminés ont souvent été ratés (CSS pour Content Scrambling System pour le chiffrement des DVD). by C.Queinnec Programmation réticulaire 95/139 Types d’algorithmes I clé symétrique: (Ck )−1 = Ck−1 La même clé sert à chiffrer et déchiffrer. I clés asymétriques: Ck−1 = Ck 0 une clé permet de chiffrer, une autre de déchiffrer. L’algorithme peut être étudié mathématiquement. L’attaque la plus simple est d’essayer toutes les clés: pour parer cette attaque, il suffit qu’il y ait beaucoup de clés ! by C.Queinnec Programmation réticulaire 96/139 Problèmes des clés symétriques I comment échanger la clé avant de s’en servir ? I le nombre de clés augmente quadratiquement en le nombre d’utilisateurs souhaitant s’échanger des informations (puisqu’il faut autant de paires de clés que de couples d’utilisateurs souhaitant échanger de l’information). by C.Queinnec Programmation réticulaire 97/139 Intérêts des algorithmes à clé symétrique I bien connus I I I I I I I 1977: DES (Data Encryption Standard) triple DES Blowfish (non breveté, utilisé dans ssh) IDEA (utilisé dans PGP) RC2, RC4, RC5 Rijndael AES rapides by C.Queinnec Programmation réticulaire 98/139 Système à clé publique I I on rend publique l’une des clés asymétriques trouver l’autre clé doit rester difficile I I 1976: concept établi (publié) par Diffie-Hellman (fonction difficilement inversible) 1977: première implantation publiée par Rivest-Shamir-Adleman by C.Queinnec Programmation réticulaire 99/139 Principes de RSA et Diffie-Hellman 0 0 I Puisque (t k )k mod(n) = (t k )k mod(n) I alors m = t k mod(n) et t = mk mod(n) I on peut rendre public n et k I sans pour autant rendre simple de trouver k 0 . 0 Inconvénient: plus lent que les algorithmes à clé symétrique. by C.Queinnec Programmation réticulaire 100/139 Avantages I le nombre de clés est linéaire en le nombre d’utilisateurs I on peut assurer (en même temps) chiffrement, authentification et non-répudiation. by C.Queinnec Programmation réticulaire 101/139 Comment partager un secret ? Méthode de Diffie-Hellman: I publics: p grand nombre premier, g élément générateur de Zp I Alice a un nombre fétiche (clé privée) a ∈ Zp I Bob a un nombre fétiche (clé privée) b ∈ Zp I Alice transmet à Bob: g a mod(p) I Bob transmet à Alice: g b mod(p) I Le secret commun est g a b = g b = g ab mod(p) a amélioré par MTI (Matsumoto, Takashima, Imai) et Needham-Schroeder. by C.Queinnec Programmation réticulaire 102/139 Discrétion I Alice veut transmettre t à Bob I Alice va chercher la clé publique de Bob: Pub[Bob] I Alice crypte t avec la clé publique de Bob I Alice transmet à Bob: m = Pub[Bob](t) I Bob décrypte avec sa clé privée et obtient t = Priv[Bob](m). by C.Queinnec Programmation réticulaire 103/139 Authentification et non-répudiation I Alice veut transmettre t à Bob I Alice crypte t avec sa clé privée I Alice transmet à Bob: Priv[Alice](t) + +Alice I Bob voit que cela vient d’Alice et va chercher la clé publique d’Alice I Bob décrypte avec la clé publique d’Alice et obtient t. by C.Queinnec Programmation réticulaire 104/139 Tout à la fois (essai 1) I Alice veut transmettre t à Bob I Alice va chercher la clé publique de Bob I Alice crypte t avec la clé publique de Bob I Alice crypte Pub[Bob](t) avec sa clé privée I Alice transmet Priv[Alice](Pub[Bob](t)) + +Alice I Bob voit que cela vient d’Alice et va chercher la clé publique d’Alice I Bob décrypte avec la clé publique d’Alice et obtient Pub[Bob](t) I Bob décrypte avec sa clé privée et obtient t by C.Queinnec Programmation réticulaire 105/139 Que peut faire X s’il intercepte le message ? I I Il voit que le message vient d’Alice, Il peut l’intercepter et le renvoyer comme si X était Alice (man in the middle) I I il décode avec la clé publique d’Alice et réencode avec sa clé privée il renvoie à Bob Priv[X ](Pub[Bob](t)) + +X I Il peut le stocker pour le renvoyer plus tard I il peut l’altérer pour encombrer le destinataire I etc. by C.Queinnec Programmation réticulaire 106/139 Tout à la fois (essai 2) assurant aussi authentification et non-répudiation: I I I I I I I I I Alice veut transmettre t à Bob Alice crypte t avec sa clé privée Alice va chercher la clé publique de Bob Alice crypte Priv[Alice](t) + +Alice avec la clé publique de Bob Alice transmet Pub[Bob](Priv[Alice](t) + +Alice) X ne peut rien faire du message car il lui manque la clé privée de Bob (il ne sait même plus que cela vient d’Alice) Bob décrypte avec sa clé privée et obtient Priv[Alice](t) + +Alice Bob voit que cela vient d’Alice et va chercher la clé publique d’Alice Bob décrypte avec la clé publique d’Alice et obtient t by C.Queinnec Programmation réticulaire 107/139 Intégrité L’intégrité seule est possible grâce à des fonctions de hash (Message Digest, footprint, fingerprint) particulières. I On calcule le résumé d du message t: soit d = H(t) I On envoie t + +d I Le destinataire sépare t de d, I Le destinataire recalcule le résumé d 0 = H(t) I le message a été altéré si d 6= d 0 Il faut que la fonction H soit publique. Attention, ce n’est pas une protection du message mais il suffit de protéger le résumé: c’est la signature électronique. by C.Queinnec Programmation réticulaire 108/139 Signature I Alice calcule le résumé d du message t: soit d = H(t) I Alice crypte le résumé (avec C) I Alice envoie t + +s avec s = C(d) I Bob sépare t de s I Bob recalcule le résumé d 0 = H(t) I le message t a été altéré si d 0 6= C −1 (s) Nécessité d’un secret partagé entre Alice et Bob: C by C.Queinnec Programmation réticulaire 109/139 Désiderata sur la fonction H I Un bit change dans t, d change beaucoup. I Étant donné d, il est difficile de créer t tel que d = H(t) Algorithmes existant: I MD2 (Message Digest) (résumé de 128 bits) I MD5 (résumé de 128 bits) utilisé dans SSL et Authenticode, en voie de disgrâce I SHA-1 (pour Secure Hash) (résumé de 160 bits) I SHA-256, SHA-384, SHA-512 (dans la lignée d’AES) Intérêts: rapides à calculer, aucune restriction légale, peuvent aussi servir à l’authentification. by C.Queinnec Programmation réticulaire 110/139 Authentification HMAC pour Hash Message Authentication Code. Au lieu d’utiliser une fonction H unique et publique, on utilise une fonction paramétrable Halice non moins publique où seule une clé (alice) est à échanger. L’astuce est que l’on peut réutiliser les algorithmes existant pour réaliser Halice . I Alice va utiliser la clé Ka que Bob connait I Alice doit transmettre t I Alice calcule s = H((Ka XOR 0x5c) + +H((Ka XOR 0x36) + +t)) I Alice transmet t + +”H” + +s I Bob recalcule et compare. by C.Queinnec Programmation réticulaire 111/139 S/MIME Illustration en S/MIME (pour Secure MIME). To: \ldots From: \ldots Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg=sha1; boundary="------------msDD9" --------------msDD9 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable Bonjour, ceci est un message! --------------msDD9 Content-Type: application/x-pkcs7-signature; name="smime Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: Signature cryptographique S/MIME MIIJuAYJKoZIhvcNAQcCoIIJqTCCCaUCAQExCzAJBgUrDgMCGgUAMAsG by C.Queinnec Programmation réticulaire 112/139 PGP et consorts Illustration avec OpenPGP: To: \ldots From: \ldots -----BEGIN PGP SIGNED MESSAGE----Hash: SHA1 Bonjour, ceci est un message! -----BEGIN PGP SIGNATURE----Version: GnuPG v1.0.6 (GNU/Linux) Comment: Processed by Mailcrypt 3.5.6 and Gnu Privacy Guard <http://www.gnupg.org/> iD8DBQE8zDR2NvFKaFH6L20RArGOAKDNO1V0WK8PVOvf0NJtYIT8IJdn C8Vc/r4T1mIZyOfRA+TeJaY= =4yIb -----END PGP SIGNATURE----- Nouvelle forme: by C.Queinnec Programmation réticulaire 113/139 Exemple de signatures: Signature de logiciels On peut signer des logiciels ce qui garantit leur intégrité (après archivage et transmission) et leur auteur (ou provenance). I fichiers jar Java I binaires ActiveX I archives .rpm by C.Queinnec Programmation réticulaire 114/139 Messagerie Deux techniques pour la messagerie semblables mais incompatibles: I S/MIME I PGP (pour Pretty Good Privacy). Voir comparaisons ainsi que GnuPG. On peut crypter les messages ou seulement les signer (authentifier leur auteur). Elles reposent l’une et l’autre sur des certificats. by C.Queinnec Programmation réticulaire 115/139 Certificats basiques Un fichier contenant (entre autres): I un nom (un Distinguished Name X.500 (comme pour LDAP)) cn=fr,ou=upmc,ou=ufr922,cn=Christian Queinnec I une clé publique (et son type d’algorithme) I un intervalle de validité temporelle. I Souvent des couples supplémentaires nom=valeur. souvent associés à des serveurs de clés (requêtes nom vers certificat). Des formats textuels existent pour les représenter comme X509 v3. Pour qu’ils soient sûrs, leur intégrité est contrôlée. by C.Queinnec Programmation réticulaire 116/139 Intégrité de certificats I Le contenu du certificat est cc = "nom" + +Pub[nom] + +autre I On le signe avec la clé privée: s = Priv[nom](H(cc)) I Le certificat est: "nom" + +Pub[nom] + +autre + +s I Quand on le reçoit, on sépare clé publique: Pub[nom] et signature s I On calcule le résumé de H(cc) I Si H(cc) 6= Pub[nom](s), le certificat a été altéré I Si le certificat est valide, alors probablement celui qui l’a créé connaissait la clé privée associée à la clé publique qui s’y trouve. Aucun rapport avec le nom bien sûr (sauf que le nom est probablement celui avec lequel le certificat a été créé). by C.Queinnec Programmation réticulaire 117/139 Problème des certificats Le grand problème est l’établissement du lien entre individu (ou rôle), certificat et nom présent dans le certificat. Deux types de solutions où le certificat est lui-même authentifié par autre chose: I réseau de confiance (Web of trust) I autorités de certification by C.Queinnec Programmation réticulaire 118/139 Contreseing de certificats I Si c est un certificat quelconque, I si Alice a un certificat c 0 I elle peut bâtir cc = c + +c 0 + +Priv[c 0 ](H(c + +c 0 )) I À la réception, Bob peux vérifier que c et c 0 sont valides, I et qu’Alice a mis son contreseing sur le certificat c. Le reste est une affaire de confiance dans le jugement d’Alice. Le certificat peut également être contresigné par le signataire ce qui prouve qu’il connait sa clé privée (mais pas qu’il est Bob). by C.Queinnec Programmation réticulaire 119/139 Réseau de confiance Web of Trust I j’ai confiance en moi, I je peux publier (sur un serveur de clés) que j’ai confiance en certains certificats (je garantis que ce sont bien les certificats d’individus que je connais), I transitivement, j’ai confiance dans les certificats dans lesquels ceux en qui j’ai confiance ont confiance. by C.Queinnec Programmation réticulaire 120/139 Autorité de certification I À tout certificat est ajouté des informations: I I I I nom de l’autorité de certification certificat de l’autorité de certification URL pour CPS Certification Practices Statement URL pour CRL Certification Revokation List (et OCSP pour vérification) I j’ai confiance dans un certificat si j’ai confiance dans l’autorité de certification. I j’ai confiance dans la clé auto-signée originelle de RSA Data Security inc. On parle de PKI pour Public Key Infrastructure. by C.Queinnec Programmation réticulaire 121/139 Exemple de certificat Certificate: Data: Version: 3 (0x2) Serial Number: 484087 (0x762f7) Signature Algorithm: md5WithRSAEncryption Issuer: C=ZA, ST=Western Cape, L=Cape Town, O=Th OU=Certificate Services, CN=Personal Freemail RSA 2000.8.30 Validity Not Before: Jan 1 01:00:00 2002 GMT Not After : Mar 4 18:10:47 2010 GMT Subject: C=FR/O=UPMC/OU=UFR 922/CN=Christian Que Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (1024 bit) Modulus (1024 bit): d7:9d:e8:6d:e0:d8:17:d2:84:55:54:3a: .........:e8:45 Exponent: 65537 (0x10001) X509v3 extensions: by C.Queinnec Programmation réticulaire 122/139 Retour sur la signature La technique de S/MIME et PGP: I Soit t à signer (éventuellement HMACisé pour l’intégrité) I Le tout est t + +certificat(Alice) + +Priv[Alice](H(t)) I que l’on peut transmettre crypté avec la clé publique de Bob. by C.Queinnec Programmation réticulaire 123/139 SSL Secure Socket Layer: Connexion (surtout TCP) sécurisée (chiffrée, authentifiée (par certificats), intègre, compressée) paramétrable. Quasiment compatible de l’interface des connecteurs de TCP/IP. TLS 1.0 à peu près égal à SSL 3.0 Protocole modulaire et extensible (les algorithmes d’intégrité, d’authentification, de chiffrement sont des paramètes négociés). Couches d’authentification entre machines puis entre processus. by C.Queinnec Programmation réticulaire 124/139 SSL: initialisation Protocole d’initialisation: I Alice -> Bob: hello ++ certificat(Alice) I Bob: vérifie certificat(Alice) . . . I Bob -> Alice: certificat(Bob) ++ nonce I Alice: vérifie certificat(Bob) . . . I Alice -> Bob: Priv[Alice](Pub[Bob](masterSecret,nonce)) I Alice: clé de session engendrée par masterSecret,nonce I Bob: clé de session engendrée par masterSecret,nonce I Entre Alice et Bob: même clé symétrique de session (3DES, Blowfish) by C.Queinnec Programmation réticulaire 125/139 Session Demander au conteneur de gérer lui-même, par tous les moyens à sa disposition, le suivi des usagers. session_start(); $_SESSION[’cle’] = ’valeur’; //Changement d’identifiant de session session_regenerate_id(); session_destroy(); unset($_SESSION); L’objet session est une table associative permettant d’insérer des attributs. by C.Queinnec Programmation réticulaire 126/139 Redirection Parmi les codes de retour 3xx: 301 Moved permanently ou 302 Found permettent les redirections permanentes ou temporaires. ------------> GET url <------------ 301 Moved permanently Location: nouvelle-url ------------> GET nouvelle-url <------------ 200 page by C.Queinnec Programmation réticulaire 127/139 Authentification côté client ------------> GET dom/url <------------ 302 Moved temporarily Location: authurl?oldUrl=dom/url ------------> GET authurl?oldUrl=dom/url <------------ 200 formulaire a remplir ------------> POST checkurl et information oldUrl=dom/url <------------ 302 Moved temporarily Location: dom/url Set-Cookie: Clef=912436tal; Domain=dom; Path=url ------------> GET dom/url Cookie: Clef=912436tal by C.Queinnec Programmation réticulaire 128/139 SSO (single sign on) CAS, OpenId 307 CAS,OpenID auth form 307+cookie checkCookie getProfileInfo by C.Queinnec Programmation réticulaire 129/139 Cache (un peu) Champ HTTP Expires et mécanisme de validation. ------------> GET dom/url <------------ 200 OK Date: Last-Modified: Expires: Cache-Control: maxage= ETag: opaque +user tracking ------------> GET dom/url If-Modified-Since: If-None-Match: opaque <------------ 304 Not modified by C.Queinnec Programmation réticulaire 130/139 ------------> PUT dom/url par exemple If-Match: opaque <------------ 412 Precondition failed Et inversement pour ne rien retenir: ------------> GET dom/url <------------ 200 OK Pragma: no-cache en http 1.0 Cache-Control: no-cache en http 1.1 maintenant Cache-Control: no-store en http 1.1 maintenant by C.Queinnec Programmation réticulaire 131/139 Conclusions I Ne jamais faire confiance à l’information provenant de l’utilisateur. C’est le premier commandement de l’Open Web Application Security Project I Utiliser une information de session correspondant à une clé d’indexation en base côté serveur. I Utiliser des clés non forgeables. I Changer souvent de clés (datées). Invalider les anciennes clés. by C.Queinnec Programmation réticulaire 132/139 Partie 6 Ressources by C.Queinnec Programmation réticulaire 133/139 Ressources I Pourquoi ne pas s’appuyer plus sur HTTP ? Thèse de Roy Fielding (2000) Architectural Styles and the Desing of Network-Based Software Architectures I Plus de sémantique dans l’URL: toute ressource manipulable a une URI propre I Pas d’enveloppes (aller ou retour): l’URL est l’enveloppe d’émission. I Outre GET, usage des commandes HEAD, POST, PUT, DELETE I Pour l’instant pas d’équivalent à WSDL. Les grands exemples d’architecture REST: Amazon, Google, . . . mais aussi Atom, Ruby on Rails by C.Queinnec Programmation réticulaire 134/139 Exemple: Amazon S3 Serveur programmatique de stockage I GET /bucket liste les objets contenus dans une aire I GET /bucket/object renvoie l’objet I HEAD /bucket/object ne renvoie que les méta-données concernant l’objet I PUT /bucket/object + body crée/modifie l’objet I POST /bucket + body crée un objet anonyme et renvoie son URI (via Location) I DELETE /bucket/object supprime l’objet I DELETE /bucket supprime l’aire I ... by C.Queinnec Programmation réticulaire 135/139 Principes REST I Nommage I I I Représentations de ressources I I I Toute URI désigne une unique ressource. mais une même ressource peut (temporairement ou non) avoir plusieurs noms. Par exemple /software/1.0.3.tgz ou /software/latest.tgz dans l’URI dans les entêtes HTTP: Accept, Accept-Language, Accept-Encoding etc. Conséquences d’HTTP: pas d’état, sémantique des commandes fixée CRUD = POST, GET, PUT, DELETE by C.Queinnec Programmation réticulaire 136/139 Représentations I I Représentations diverses pour les images, les sons, les textes Représentation pour les données (graphes, arbres): I I I XML JSON YAML by C.Queinnec Programmation réticulaire 137/139 Architecture d’une application REST I L’URI est analysée pour déterminer la ressource concernée. I pour S3: /{bucket}/{object} I la commande est déterminée (GET, PUT, POST, DELETE) I Si retour il y a, la représentation de la ressource ou de l’anomalie est déterminée I les méta-données décrivant la représentation accompagnent celle-ci. by C.Queinnec Programmation réticulaire 138/139 Commandes REST I GET pour obtenir une ressource, ne doit rien modifier, être idempotente I PUT pour créer (ou remplacer) une ressource dont l’URI est spécifiée par le client I POST pour créer une nouvelle ressource dont l’URI sera engendrée par le serveur I DELETE pour supprimer une ressource. Tout pour du CRUD! by C.Queinnec Programmation réticulaire 139/139 Architecture usuelle La forme usuelle est d’avoir une arborescence de contrôleurs/actions: (patronURL × variablesPatronURL) → ressource ressource → (method → représentation) Par exemple (en omettant l’accès à la requête pour obtenir les paramètres HTTP additionnels): GET /person/{nom}/{prenom} -> fun(nom prenom) ressource PUT /person/{id}/age/{age} -> fun(id age) ressource Multiples variantes différemment Curryfiées ou empaquetées by C.Queinnec Programmation réticulaire 140/139 Soucis I actions binaires: I I I I I exprimer qu’une personne va à une réunion ? transactionnel décrire un virement bancaire ? sécurité Les URI doivent-elles être évidentes ou opaques ? I résistance au changement: /person/23eab89c vis-à-vis de //www.systeme-lip6.fr/Christian.Queinnec/index.ht (maintenant //lip6.fr/Christian.Queinnec/ by C.Queinnec Programmation réticulaire 141/139 Comparaisons I SOAP est indépendant du transport donc d’HTTP I I I I propre modèle de sécurité propre retour des erreurs propre stratégie de cache ou d’idempotence WSDL définit finement les formats des données échangées En revanche, Rest est plutôt orienté vers l’échange de documents (XML, micro-formats, PDF, JSON, etc.). Avec XML, notion de pièces jointes (comme en JBI Java Business Integration). Rest utilise des substantifs, les services utilisent plutôt des verbes. by C.Queinnec Programmation réticulaire 142/139 Patrons I Javascript: Angular, Ember, Backbone, React, Express, Vanilla (cf. aussi MicroJS) I Java: Servlet, JSP, Struts, Cocoon, JSF (Java Server Faces) I Perl: Catalyst, Jifty, Mason I Xduce, Ocsigen by C.Queinnec Programmation réticulaire 143/139 Partie 7 Génération de pages by C.Queinnec Programmation réticulaire 144/139 Génération de pages Plusieurs techniques possibles (côté serveur ou client): I métissage I macro-génération by C.Queinnec Programmation réticulaire 145/139 Écrire un programme (dans le langage X) qui engendre de l’HTML revient à mélanger des chaînes HTML statiques avec quelques parties calculées par des expressions du langage X. # en Perl print "<p>Bonjour "; print $prenom, " ", $nom; print ",</p> <div> Comment allez-vous ? <br> ... "; # En Perl avec le module CGI: print p("Bonjour $prenom $nom,"), "<div> "; my @words = ["comment", "allez", "vous"]; print join(" ", @words), " ?", br, "..."; by C.Queinnec Programmation réticulaire 146/139 int main () /* En C */ { printf("<p>Bonjour %s %s,</p>\n" "<div> Comment allez-vous ? <br>\n" "... ", prenom, nom); } ;;; En Hop (BODY (P "Bonjour " nom prenom ",") (DIV "Comment allez-vous ? " (BR) "...") ) by C.Queinnec Programmation réticulaire 147/139 S’il y a peu de parties variantes, si le langage a des chaînes sur une seule ligne, des expressions pour imprimer verbeuses, le code devient vite illisible. L’idée (éculée): écrire dans le langage majoritaire et inclure des îlots dans un autre langage. I C et cpp (pour les macros) I notation backquote en Lisp/Scheme I programmation littéraire (Pascal + TEX) I Java et javadoc (ou iContract): commentaires structurés I X et SQL (par exemple, jsql = Java + SQL) I Attention! LINQ (Language Integrated Query) étend C# 3.0 et ne le métisse pas! by C.Queinnec Programmation réticulaire 148/139 Métissage avec HTML I JSP = HTML et Java (Java Server Page) ou taglib I Perl + HTML: HTML::Embperl, Mason, Apache::ASP, HTML::Template, Template Toolkit I PHP = HTML et une sorte de Perl (Personal Home Page) I Shervlet = HTML + sh <!-- en PHP --> <p>Bonjour <?php echo $prenom ?>, <?php echo $nom ?> <div> Comment allez-vous ? <br> ... by C.Queinnec Programmation réticulaire 149/139 Métissage par compilation Une technique simple passe par un compilateur traduisant le langage X+HTML en X. Par exemple, une JSP est compilée en une servlet (une classe Java). Shervlet = sh+HTML <html><head><title> shervlet </title></head><body> Il est <?sh date ?> en ce moment<br> dit <?sh uname -a ?></body></html> <html><head><title> shervlet </title></head><body> <?sh if [ "$REMOTE_HOST" = ’1.2.3.4’ ] ; then ?> Salut vieille branche, <?sh ;else ?> Bonjour, <?sh fi ?> </body></html> by C.Queinnec Programmation réticulaire 150/139 <html><head><title> shervlet </title></head><body> Il est <?sh date ?> en ce moment<br> dit <?sh uname -a ?></body></html> se compile en: #! /bin/sh echo -n "<html><head><title> shervlet </title></h Il est " date echo -n " en ce moment<br> dit " uname -a echo -n "</body></html> " by C.Queinnec Programmation réticulaire 151/139 Caractères Jeux de caractères: ASCII (7bits), latin1 = ISO-8859-1, latin9 = ISO-8859-15, Unicode et ISO/IEC 10646. En Unicode, tous les caractères ont un nom canonique comme « U+03BC GREEK SMALL LETTER MU » et un numéro (20 à 22 bits suffisent). Les jeux de caractères n’ont rien à voir avec les langues (grec, cyrillique, français de France ou du Québec) codés comme fr_FR, fr_CA ou GR. En jargon, locale régissant, nombres, argent, date, ordre alphabétique, etc. (cf. variables LC_DATE, LC_ALL, etc.) by C.Queinnec Programmation réticulaire 152/139 Glyphes Unicode n’est pas concerné par les descriptions graphiques qui se nomment des glyphes. 2673: RECYCLING SYMBOL FOR TYPE-1 PLASTICS polyethylene terephthalate 2674: RECYCLING SYMBOL FOR TYPE-2 PLASTICS high density polyethylene by C.Queinnec Programmation réticulaire 153/139 Relations entre caractères Certains caractères ont des rapport entre eux: I appartenance à un alphabet national I correspondance minuscule/majuscule I reconnaissance chiffre/lettre/ponctuation I ordre des caractères I ordre contigü pour les chiffres I composition de caractères (comme « U+00E0 LATIN SMALL LETTER A WITH GRAVE » est composé de « U+0061 LATIN SMALL LETTER A » et « U+0300 COMBINING GRAVE ACCENT ») I équivalence de symboles (Ohm et Oméga) I règles de césure by C.Queinnec Programmation réticulaire 154/139 Codages I I I I UCS-2: chaque caractère unicode est codé en deux octets. Les bigrammes 1111 1... .... .... sont réservés (et notamment FEFF pour lutter contre les représentations gros- ou petit-boutiennes). En Javascript \uxyzt désigne un caractère unicode. Java (et d’autres) est par défaut en ISO-8859-1 mais \uxyzt désigne un caractère unicode. UTF-8 (même style de schéma pour UTF-16): 0abcdefg 110abcde 10fghijk 1110abcd 10efghij 10klmnop -> abcdefg -> abcdefghijk -> abcdefghijklmnop Ainsi A é e 65 233 8364 0100 0001 1100 0011 1010 1001 1110 0010 1000 0010 1010 1100 by C.Queinnec Programmation réticulaire 155/139 Codage ISO-8859-1 ISO-8859-1 est un jeu de 256 caractères pour l’Europe de l’ouest, ISO-8859-2 pour l’Europe de l’est, etc. by C.Queinnec Programmation réticulaire 156/139 Codage ISO-8859-15 L’ISO-8859-15 est aussi connu sous le nom de « Latin9 » (ou encore « Latin0 »). C’est celui qu’il faut utiliser de préférence à l’ISO-8859-1 (dit « Latin1 »). by C.Queinnec Programmation réticulaire 157/139 Le grand jeu 1. octets (un (ou plusieurs) octet(s) pour un caractère) 2. caractères (une abstraction en mémoire de l’application) 3. glyphes (suivant polices) octets UTF8 quoted− printable échappement \uxyzt octets Unicode +plan ISO−8859−x polices glyphes by C.Queinnec glyphes Programmation réticulaire 158/139 Comment le dire ? En Emacs, première ligne -*- coding: utf-8 -*En XML, attribut encoding <?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> en HTTP: Content-Type: text/html; charset=UTF-8 by C.Queinnec Programmation réticulaire 159/139 Principes sécuritaires D’après Open Web Application Security Project: I Minimiser la surface attaquable I Choix sûrs par défaut I Moindre privilège I Défense en profondeur I Rattrapage d’erreur sûr I Séparation des rôles I Pas de sécurité par obscurité I Simplicité I Automatisation des tests de correction de vulnérabilité by C.Queinnec Programmation réticulaire 160/139 Partie 8 MVC by C.Queinnec Programmation réticulaire 161/139 Model-View-Control Depuis Smalltalk 80, la technique du MVC. Les visualisateurs sont souvent des moteurs incrémentiels. Le modèle peut être testé indépendamment des E/S. Contrôleur action Modèle événement err page by C.Queinnec eu r Visualisateur Programmation réticulaire 162/139 Conversations I Imposer/suggérer parcours dans les pages I I I I formulaire des impôts annuaire UPMC TME solitaire Résister aux boutons Back et Clone by C.Queinnec Programmation réticulaire 163/139 Automate Grande matrice: événement(requête) × état → état × page(réponse) I CGI::Application, Struts, JSF, etc. Les questions: I comment représenter l’état ? I où stocker l’état ? L’objet « session » identifie un visiteur, est stocké côté serveur et est équivalent à une table associative. Il est maintenu par bouton caché, cookie ou réécriture d’URL. by C.Queinnec Programmation réticulaire 164/139 Cookies, Sessions et conversation SumServlet (I) A number please? 123 SumServlet (II) 123 B + 201 SumServlet (III) 123 + 201 C 324 SUBMIT! SUM? D A E F SumServlet (III) + 123 21 144 SumServlet (I) A number please? 100 G SUBMIT! SumServlet (II) SumServlet (III) 100 + 66 H + 100 66 166 SUM? by C.Queinnec Programmation réticulaire 165/139 Stockage de l’état I Une première idée: dans le cookie! événement(requête 3 cookie 3 état) → page(réponse 3 cookie 3 état) I Une moins mauvaise idée: dans la session: événement(requête) × état(session@serveur) → état(session@serveur) × page(réponse) I La meilleure idée: dans l’URL: événement(requête URL) × (URL → continuation)@serveur → (URL’ → continuation)@serveur × page(réponse by C.Queinnec Programmation réticulaire URL’) 166/139 Objet session L’objet session impose une gestion de mémoire partagée en cas de multiples serveurs. Néfaste pour l’extensibilité ou passage à l’échelle! Répartiteur de charges (HAproxy, Pound, etc.). client httpd webapp client httpd webapp httpd webapp base des objets Session répartiteur de charges base des objets Session by C.Queinnec affinité de Session Programmation réticulaire 167/139 Matrice Sur l’application précédente et en supposant que l’on sache distinguer les deux entrées de nombres. On pourrait aussi ne mémoriser que n1 + n2. état × entrée initial 1N(n1) final(n1, n2) n1 1N(n1) -?-?- n2 — final(n1, n2) -?- Ne passe guère à l’échelle (ou alors Esterel ?). by C.Queinnec Programmation réticulaire 168/139 Portée des données Stocker une donnée dans une servlet (ou JSP) est associé à une portée: I requête I session I application I illimitée by C.Queinnec Programmation réticulaire 169/139 Validation Les données venant du client sont transmises comme des chaînes de caractères sous la forme n = v, comment assurer qu’elles sont conformes aux besoins (ce n’est pas un problème pour les services Web) ? I I Identifier pour chaque page (ou état ?) les données d’entrée et leur nature On leur associe un validateur (regexp, date, numéro de téléphone, etc.) I I I outre la validation côté serveur, on peut émettre en plus un validateur en Javascript côté client =⇒ un mécanisme de notification d’erreur au client by C.Queinnec Programmation réticulaire 170/139 Xduce, Ocsigen I L’application toute entière est exprimé en un unique programme I Vérification statique (typage des entrées, du XML de sortie) by C.Queinnec Programmation réticulaire 171/139 Partie 9 Conclusions by C.Queinnec Programmation réticulaire 172/139 Conclusions I Un très (trop) grand nombre de cadres de réalisation I Séparation des métiers et des outils I Importance grandissante des vérifications statiques by C.Queinnec Programmation réticulaire 173/139