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,
&amp;):
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