Retrouvez cet article dans : Misc 17
1 Avant de commencer
Le but de cet article est de traiter des différentes façons de gérer l'authentification d'un client et d'un serveur basés sur le paradigme ONC/RPC (RFC1832). Nous verrons les différents mécanismes utilisables et leurs limitations avant de regarder de plus près RPCSEC_GSS (RFC2203) qui est une évolution naturelle de ONC/RPC en matière de sécurité grâce à l'introduction du formalisme de la GSS-API. Nous supposerons que le lecteur est déjà familier avec le formalisme des ONC/RPC et qu'il a connaissance des grands principes de la GSS-API (Global Security Service Application Programming Interface, utilisée dans la dernière partie). Quelques rappels liminaires sont fournis pour introduire les notions, mais il ne s'agit en aucun cas d'une référence. Les références situées à la fin de l'article vous permettront de disposer des documents nécessaires sur ces sujets.1.1 Le protocole ONC/RPC
ONC/RPC a principalement été créé dans le but de fournir une couche de base au protocole NFS. Actuellement, il sert de base à de nombreux protocoles du monde Unix, NFS bien sûr, mais aussi NIS, NIS+ ou RPCBIND. Un client/serveur ONC/RPC suppose que le serveur est accessible pour différentes fonctions, identifiées par un triplet (numéro de programme, numéro de version, numéro de fonction). Par exemple, la fonction READDIR du protocole NFSv3 est identifiée par le triplet (100003, 3, 16). L'utilisation d'une fonction est générique : le client renseigne une structure décrivant les arguments de la fonction, l'envoie au serveur qui effectue le travail et retourne une structure décrivant le résultat de l'opération. Dans la suite de l'article, nous appellerons " requête " le message envoyé par le client sur le serveur et qui contient les arguments, la " réponse " sera le message retourné par le serveur sur le client et contenant le résultat. Un message RPC est composé de deux parties : un en-tête et un corps de message. La structure de l'en-tête est bien connue et décrite dans les spécifications de ONC/RPC, le corps du message dépend du protocole qui utilise RPC pour gérer ces messages. Pour garantir la portabilité des messages entre différentes architectures (BigEndian et LittleEndian) un format de représentation externe de données a été choisi pour ONC/RPC : le format XDR. Le corps du message est encodé/décodé depuis le format propre à l'architecture vers le format XDR.2. Les différents types d'authentification disponibles dans ONC/RPC
2.1 En-tête d'un appel RPC
L'en-tête du message est tout particulièrement intéressant. Il contient l'identifiant de la fonction appelée ainsi que des informations relatives à l'émetteur du message. Dans le cadre de la gestion de l'authentification, il est très intéressant car c'est ici que l'on trouve les credentials du message. Dans tout ce qui suit, le terme " credentials " désignera une structure de données opaque utilisée pour identifier un acteur au sein d'un mécanisme d'authentification. L'en-tête RPC est défini dans le fichierL'essentiel des informations relatives à l'authentification passe dans la requête, il est donc utile d'en savoir un peu plus sur la structurerm_xidest l'identifiant de la requête. Il est principalement utilisé par le client pour s'assurer que le serveur ne lui retourne pas un message destiné à un autre client, ainsi que pour la gestion des requêtes dupliquées et/ou réémises (par exemple un trafic NFS important avec UDP comme couche de transport engendrera des requêtes dupliquées ;rm_directionqui indique le sens du message (requête ou réponse) ;ruest une union discriminée par le champrm_direction. Dans le cas d'une requête, ce champ prendra la forme d'une structurecall_body, et elle sera une structurereply_bodydans le cas d'une réponse.
cb_rpcvers indique le numéro de version des ONC/RPC, valeur fixée dans les spécifications du protocole. Ce champ contiendra toujours la valeur 2 ;ÂChaque mécanisme d'authentification fonctionne de façon similaire : on lit danscb_vers,cb_prog,cb_procforment le triplet (version, programme, fonction) qui identifie totalement la fonction ;cb_credest un champ opaque qui contient les informations destinées à l'authentification, à savoir les trois informations suivantes :
oa_flavorest le type d'authentification utilisé ;oa_baseest le début d'un buffer opaque contenant les informations nécessaires pour l'authentification. C'est une information opaque qui n'a de sens que du point de vue interne au mécanisme sous-jacent. Nous verrons dans chaque cas comment l'utiliser ;oa_lengthest la longueur du buffer précédent ;cb_verfest un vérificateur, il est utilisé dans certains mécanismes d'authentification.
2.2 Le plus simple c'est de ne rien faire : authentification AUTH_NONE
Pour commencer, on utilise l'authentification2.2.1 Trace réseau
Les informations suivantes sont extraites des traces réseaux réalisées entre deux machines sous SunOS, réalisées avec l'utilitaire Snoop. Le message qui correspond est une consultation de page NIS, sans aucune authentification :RPC: ----- SUN RPC Header -----
RPC:
RPC: Transaction id = 1082628167
-> le champ rm_xid
RPC: Type = 0 (Call)
-> le champ rm_direction (ici il s'agit d'une requête)
RPC: RPC version = 2
-> call_body::cb_rpcvers (possède toujours la valeur 2)
RPC: Program = 100004 (NIS), version = 2, procedure = 3
-> call_body::cb_prog, call_body::cb_vers, call_body::cb_proc
RPC: Credentials: Flavor = 0 (None), len = 0 bytes
-> Les credentials, ici de taille vide, on remarque que cb_cred::oa_flavor = 0 = AUTH_NONE
RPC: Verifier : Flavor = 0 (None), len = 0 bytes
-> le vérificateur, de taille vide également
RPC:
2.3 Un peu plus compliqué, mais pas très robuste : authentification AUTH_UNIX
L'authentification de typestruct authunix_parms
{
u_long aup_time ;
char *aup_machname ;
__uid_t aup_uid ;
__gid_t aup_gid ;
u_int aup_len ;
__gid_t *aup_gids ;
} ;
aup_timeest un horodateur, il est généralement non utilisé ;aup_machnameest une chaîne de caractères contenant le nom de la machine cliente, limitée à 255 caractères (soit la valeur de la constanteMAX_MACHINE_NAMEdansauth_unix.h). Ce champ n'est pas utilisé en général, il est considéré comme préférable d'obtenir l'adresse IP de l'appelant (parsvc_getcaller) puis de rechercher le nom de machine correspondant. En effet, il est facile de falsifier ce champ et de prétendre provenir d'une autre machine (simplement en manipulant la structure), alors que trompersvc_getcallerrevient à duper l'appel standard C getpeername, ce qui est moins simple (bien que très faisable) ;aup_uidest le user id de la personne qui tourne le client ;aup_gidest le group id de la personne qui tourne le client ;aup_gidsest un tableau de group ids listant les groupes secondaires auxquels la personne qui tourne le client appartient. Ce tableau est limité à 16 éléments (c'est la constanteNGRPSdéfinie dans le fichier auth_unix.h qui indique cette valeur). Ce nombre peut être plus faible sur d'autres OS. En particulier, certaines versions de SunOS limitaient ce nombre à 8 ou 10.
2.3.1 Trace réseau
RPC: ----- SUN RPC Header -----          RPC:          RPC: Transaction id = 2809524949          RPC: Type = 0 (Call)          RPC: RPC version = 2          RPC: Program = 100003 (NFS), version = 3, procedure = 1          RPC: Credentials: Flavor = 1 (Unix), len = 32 bytes -> cb_cred::oa_flavor = AUTH_UNIX          RPC:    Time = 28-May-04 06:55:22                  -> cb_cred::oa_base::authunix_parms::aup_time          RPC:    Hostname = sanguku                         -> cb_cred::oa_base::authunix_parms::aup_machname          RPC:    Uid = 1234, Gid = 5678                     -> cb_cred::oa_base::authunix_parms::aup_uid, cb_cred::oa_base::authunix_parms::aup_gid          RPC:    Groups = 5678                              -> cb_cred::oa_base::authunix_parms::aup_gids (ici l'utilisateur n'appartient qu'à un seul groupe)          RPC: Verifier  : Flavor = 0 (None), len = 0 bytes -> pas de vérificateur dans ce type d'authentification          RPC:
2.4 Authentification avec la méthode de Diffie-Hellman : l'authentification AUTH_DH
La méthode d'authentification de Diffie-Hellman (ou2.4.1 Petit rappel : clef publique et privée selon l'algorithme Diffie-Hellman
La méthode de Diffie-Hellman repose sur l'utilisation des clefs publiques et privées. On ne rentrera pas dans le détail de la génération de ces clefs (cela fait l'objet d'un autre article de ce dossier). Les clefs utilisées dans AUTH_DH ont une longueur fixe de 192 octets. On considère dans ce qui suit que :- chaque acteur peut, à partir de sa clef privée et de la clef publique de l'autre, créer une clef commune (qui est la même pour chaque acteur) ;
- l'opération qui consiste à casser une telle clef (qui se ramène souvent à résoudre un logarithme discret) est supposée longue au regard des durées des échanges entre les acteurs.
2.4.2 Les credentials RPC avec AUTH_DH
Un utilisateur est identifié sous la forme d'une chaîne de caractères (de longueur inférieure à 255) au lieu d'un entier repérant son uid. Cette chaîne est appelée network name ou netname. On considère que les netnames sont uniques pour chaque client sur le réseau (lequel réseau peut être Internet en entier), et il est de la responsabilité de l'OS de correctement générer des netnames en conformité avec la façon dont il désigne les utilisateurs. Lors du premier appel, le client engendre une clef de conversation. Ensuite, il crée une structure de 128 octets, définissant une fenêtre de temps, regroupant une date epoch et une durée. Cette structure est encodée avec la clef de conversation. Ensuite, il chiffre la clef de conversation avec la clef commune de l'algorithme de Diffie-Hellman. Le client envoie alors, dans les credentials RPC, au format XDR, l'ensemble suivant : à un flag (ou namekind) indiquant que le nom qui suit est un netname et pas un nickname généré par le serveur (cette notion sera définie plus loin) ;- son netname complet ;
- les 128 octets représentant la fenêtre de temps chiffrée avec la clef de conversation ;
- la clef de conversation chiffrée avec la clef commune Diffie-Hellman.
- flag namekind indiquant qu'on utilise un nickname et plus un netname complet ;
- le nickname sur 64 bits ;
- une fenêtre de temps de 128 octets chiffrée avec la clef de conversation.
2.4.3 Faiblesse de AUTH_DH
Il y a un sujet que nous avons scrupuleusement évité : la méthode utilisée par les acteurs pour obtenir la clef publique de leur interlocuteur. Traditionnellement, les acteurs sont désignés par leurs netnames. Un fichier local ou une table NIS définit les associations entre les netnames et les clefs publiques correspondantes. Cette consultation n'est pas sécurisée puisque l'on ne dispose pas encore des informations indispensables à l'authentification (en l'occurrence les clefs publiques). De plus, la longueur de la clef (192 octets) est considérée, de nos jours, comme une valeur trop faible pour fournir une robustesse suffisante. L'authentification2.4.4 Trace réseau
La trace qui suit est obtenue si vous utilisez le service NIS+ de Solaris. Ici, on essaye de joindre le daemonRPC: ----- SUN RPC Header -----
RPC:
RPC: Transaction id = 1874964582
RPC: Type = 0 (Call)
RPC: RPC version = 2
RPC: Program = 100300 (NIS+), version = 3, procedure = 1
RPC: Credentials: Flavor = 3 (DES), len = 48 bytes
-> cb_cred::oa_flavor = AUTH_DH = AUTH_DES
RPC: Name kind = 0 (fullname)
-> Appel initial pas de nickname encore négocié
RPC: Network name = unix.78451@sanguku.mydomain
-> qualification par le network name complet (car name kind = 0)
RPC: Conversation key = 0x85DC96471A3B9964 (DES encrypted)
-> la clef de conversation chiffrée
RPC: Window = 0x459674CD (DES encrypted)
-> fenêtre de validité du message
RPC: Verifier : Flavor = 3 (DES), len = 12 bytes
-> Le vérificateur
RPC: Timestamp = 0x14526973ABCD55CC (DES encrypted)
RPC: Window = 0xA4509B65 (DES encrypted)
Dans le vérificateur de la réponse du client, on trouve le nickname :
 RPC: ----- SUN RPC Header -----          RPC:          RPC: Transaction id = 1874964582          RPC: Type = 1 (Reply)          RPC:  Status = 0 (Accepted)          RPC: Verifier      : Flavor = 3 (DES), len = 12 bytes          RPC:    Timestamp = 0x568741D6B5A8C431 (DES encrypted)          RPC:     Nickname = 0x40000000         -> le reply contient le nickname pour cette session          RPC: Accept status = 0 ( Success)Ensuite, les messages du client utilisent le nickname obtenu :
 RPC: ----- SUN RPC Header -----
RPC:
RPC: Transaction id = 1874952746
RPC: Type = 0 (Call)
RPC: RPC version = 2
RPC: Program = 100300 (NIS+), version = 3, procedure = 5
RPC: Credentials: Flavor = 3 (DES), len = 8 bytes
-> les credentials ne contiennent pas le nom complet et sont plus courts
RPC: Name kind = 1 (nickname)
-> On utilise le nickname que l'on a obtenu lors du premier appel
RPC: Nickname = 0x40000000
RPC: Verifier : Flavor = 3 (DES), len = 12 bytes
RPC: Timestamp = 0x5671BCAD678900AA (DES encrypted)
RPC: Window = 0x00000000 (DES encrypted)
2.5 Authentification avec Kerberos 4Â : AUTH_KERB
Dans ce qui suit, nous supposons que le lecteur est familier avec les notions relatives à Kerberos, en particulier les mécanismes basés sur une tierce personne de confiance. Nous ne rentrerons donc dans aucun détail relatif à Kerberos. L'utilisation de Kerberos 4 dans2.6 Utilisation de Kerberos 5 et limitation de ONC/RPC
Si vous avez bien suivi ce qui précède, on procède toujours de la même façon quand il s'agit de gérer une authentification dans ONC/RPC. Le credential et le vérificateur sont des buffers opaques sur lesquels on plaque une structure spécifique au type d'authentification de façon à en déduire les informations utiles à l'authentification. A priori, on pourrait plaquer n'importe quelle structure sur le credential et le vérificateur pour faire des échanges d'informations entre le client et le serveur. Malheureusement il y a une limite forte : la taille du credential est limitée à 400 octets. Ce n'est pas gênant pour y mettre une clef Diffie-Hellman de 192 octets ou un ticket Kerberos 4, mais avec d'autres protocoles, comme Kerberos 5, la place vient à manquer. Or, pour des raisons évidentes de compatibilité avec l'existant, il est inenvisageable d'agrandir le champ3. Contourner la limite de taille du credential : définition de RPCSEC_GSS
RPCSEC_GSS s'appuie sur le formalisme de la GSS-API. Autant dire les choses comme elles sont : c'est un formalisme assez lourd mais qui apporte des avantages conséquents, le principal étant de gérer de façon portable différents mécanismes de sécurité, sans adhérence ou presque avec les spécificités du mécanisme. L'emploi de la GSS-API garantit ainsi que des protocoles tels que Kerberos 5 qui ne sont pas supportés, comme on l'a vu, par ONC/RPC, le seront dans RPCSEC_GSS, mais il permet aussi de garantir que les futurs mécanismes, supportant la GSS-API, seront supportés par RPCSEC_GSS. On peut toutefois utiliser RPCSEC_GSS sans connaître la GSS-API dans la mesure où son formalisme est très proche, du point de vue du développeur, de celui de ONC/RPC. Le fonctionnement interne, en revanche, est très différent. On notera cependant que RPCSEC_GSS est totalement compatible avec ONC/RPC : un serveur basé sur RPCSEC_GSS peut également implémenter tous les types d'authentification de ONC/RPC.3.1 Rappel : La GSS-API en deux mots
La GSS-API , ou Generic Security Service Application Programming Interface est un modèle de programmation destiné à être implémenté comme une sur-couche d'un mécanisme de sécurité existant. La GSS-API standardise les structures, les fonctions à utiliser et la façon de les mettre en œuvre. Grâce à cette API générique, il est possible de gérer de l'authentification entre un client et un serveur en minimisant les adhérences avec le mécanisme de sécurité sous-jacent, ce qui apporte un gain de portabilité et de maintenabilité de l'application particulièrement appréciable. Dans la suite nous verrons comment la GSS-API est utilisée dans ONC/RPC pour faire RPCSEC_GSS. Nous n'allons pas entrer dans les détails concernant la GSS-API, je vous renvoie plutôt aux documents indiqués à la fin de cet article, sachez simplement que :- l'acquisition d'un credential au sens du mécanisme de sécurité se fait au travers de la fonction
gss_acquire_cred, ou bien le credential est hérité de l'environnement (par exemple lancé depuis un shell qui dispose d'un ticket Kerberos) ; - le client et le serveur, qui disposent chacun de credentials GSS-API, vont partir dans une boucle de négociation, dans le but d'établir un contexte commun. Cette boucle peut présenter une ou plusieurs itérations, selon le type de mécanisme de sécurité sous-jacent. Dans celle-ci, le client appelle la fonction
gss_init_sec_context, ce qui lui donne une " proposition de contexte " qu'il envoie au serveur. Le serveur reçoit cette information, la fait traiter par la fonctiongss_accept_sec_context, et retourne le résultat au client. On repart alors sur une éventuelle autre itération jusqu'à converger sur l'établissement du contexte commun final ; - si le mécanisme sous-jacent le permet, la GSS-API fournit les outils nécessaires pour chiffrer/déchiffrer des messages (les fonction
gss_wrapetgss_unwrap) ainsi que les fonctions pour créer une signature du message utile à la vérification de l'intégrité de celui-ci (gss_get_micetgss_verify_mic).
3.2 RPCSEC_GSS
ou comment les traditions viennent au secours des concepteurs de protocole On a vu que se limiter à l'emploi de l'en-tête du message ONC/RPC pour contenir les informations relatives à l'authentification ne suffisait pas, par manque de place. S'il est impossible d'utiliser la place disponible dans l'en-tête d'un message, le seul moyen restant consiste à mettre ces informations dans le corps du message. Le problème est que l'on ne doit pas venir marcher sur les plates-bandes des données de nature applicative qui sont dans le corps du message. La situation ressemble fort à une impasse. Heureusement, les architectes de RPCSEC_GSS ont trouvé un contournement, en s'appuyant sur un comportement traditionnel des produits utilisant les ONC/RPC. Mais avant de voir comment, faisons une petite digression. Quand un produit dispose d'un protocole basé sur les ONC/RPC, il définit un jeu de fonctions disposant d'arguments et de résultats au format bien connu et identifié de façon unique par un numéro. L'ensemble des couples (numéro de fonction, fonction de service associée) forme l'épine dorsale du traitement des requêtes dans un client ou un serveur RPC. Il est d'usage de toujours avoir une fonction dont le numéro est 0, dont le nom est en général3.3 Disponibilité de RPCSEC_GSS
RPCSEC_GSS est généralement disponible pour tout mécanisme de gestion de la sécurité qui supporte la GSS-API. Actuellement, on trouve la GSS-API pour Kerberos 5 ainsi que pour les protocoles SPKM-3 (RFC2025) et LIPKEY (w) (pour utilisation dans une implémentation de NFSv4). On trouve aussi sur certains OS, dont Solaris, des implémentations de la GSS-API et de RPCSEC_GSS au dessus de Diffie-Hellman avec des clefs de plus grande longueur (640 octets ou 1024 octets). Une authentification via RPCSEC_GSS est caractérisée par3.4 La boucle de négociation GSS-API, vue au travers de RPCSEC_GSS
RPCSEC_GSS présente, du point de vue de l'application cliente, une très grande similarité avec ONC/RPC. En gros, une application qui utilise les appels ONC/RPC utilisera RPCSEC_GSS de la même façon : création d'une structure CLIENTgc_v: La version de RPCSEC_GSS utilisée (en pratique, toujours la valeur 1, ce champ existe pour permettre de futures extensions de protocole) ;gc_proc: la procédure de contrôle. Peut prendre les valeurs suivantes :RPCSEC_GSS_DATA: le message n'est pas un paquet de négociation ;RPCSEC_GSS_INIT: le message est une initialisation de négociation ;RPCSEC_GSS_CONTINUE_INIT: le message est une phase intermédiaire de négociation ;RPCSEC_GSS_DESTROY: le message indique la destruction d'un contexte précédemment négocié.
gc_seq: numéro de séquence. Cette valeur sert à calculer une somme de contrôle à l'aide du contexte négocié entre les acteurs. La somme résultante est placée dans le vérificateur de la réponse à une requête. Ce moyen garantit que la réponse corresponde bien à l'acteur concerné et qu'il ne s'agisse pas d'une réponse falsifiée.gc_svc: nature du service de RPCSEC_GSS utilisé :RPCSEC_GSS_SVC_NONE: on authentifie, mais on ne vérifie pas l'intégrité des messages ;RPCSEC_GSS_SVC_INTEGRITY: authentification plus vérification de l'intégrité du message par calcul d'une MIC (somme de contrôle) gérée par la GSS-API ;PCSEC_GSS_SVC_PRIVACY: authentification et échange de messages chiffrés.
- gc_ctx : contexte GSS-API propre au dialogue client serveur.
- 1. le client initie un contexte de sécurité en appelant
gss_init_sec_context.
Il forme un message avec l'étiquettegc_proc = RPCSEC_GSS_INITpuis stocke l'amorce de contexte dans le corps du message RPC comme une donnée utilisateur. Le message est envoyé en surchargeant la fonction.
- 2. Le serveur reçoit ce paquet, voit l'étiquette
gc_proc = RPCSEC_GSS_INITet sait qu'il s'agit d'un appel à la fonction 0 surchargée.
Il décode le contexte et l'utilise comme argument pourgss_accept_sec_context. Il retourne le résultat (toujours dans le corps du message de la fonction 0) dans la réponse au client. Si le contexte est négocié avec succès, on pourra l'utiliser ultérieurement, sinon une autre passe est nécessaire.
- 3. Si une autre passe est nécessaire, le client emploie à nouveau
gss_init_sec_contexten utilisant la réponse du serveur et envoie le résultat avec une étiquetteRPCSEC_GSS_CONTINUE_INIT.
Et ainsi de suite jusqu'à établissement du contexte ou échec dans la négociation.Par la suite, le serveur pourra utiliser normalement les fonctions de son protocole, mais le champ gc_proc vaudra
3.5 Différents types de services de RPCSEC_GSS
Comme cela a été évoqué plus haut, RPCSEC_GSS supporte trois types de services différents :- Le premier,
RPCSEC_GSS_SVC_NONEindique que l'on utilise la GSS-API uniquement pour gérer l'authentification entre le client et le serveur. Ensuite, des messages similaires à ceux de ONC/RPC sont utilisés. Cela suppose que les appels RPC sont faits sur un protocole de transport comme TCP, orienté connexion. - Le service
RPCSEC_GSS_SVC_INTEGRITYintègre au message la notion d'intégrité. Il permet de vérifier si le message est bien identique au niveau du client et du serveur, mais aussi de vérifier que le message vient bien de celui avec lequel on a négocié un contexte. En effet, le calcul de la somme de contrôle (ou MIC) dépend du contexte qui n'est connu que du client et du serveur. Ce service repose sur les fonctionsgss_get_micetgss_verify_micde la GSS-API. - Le service
RPCSEC_GSS_SVC_PRIVACYpermet de déchiffrer le message en totalité, en se basant sur les fonctionsgss_wrap/gss_unwrapde la GSS-API. Seuls les acteurs ayant connaissance du contexte négocié sont à même de décoder son contenu.
struct rpc_gss_integ_data {
opaque <> databody_integ ;
opaque <> checksum;}
Le champ struct rpc_gss_data {
uint32 seq_num ;
proc_req_arg arg ;}
Le récepteur du message calculera la somme de contrôle sur la structure struct rpc_gss_priv_data {
opaque <> databody_priv ;}
Ensuite, on déchiffre le champ 3.6 Trace réseau
Voici le type de trace réseau que l'on obtient avec RPCSEC_GSS. Le service qui est appelé ici est celui d'une programme de test, qui ne couvre aucune fonction particulière à part celle d'utiliser RPCSEC_GSS. Le numéro de programme utilisé est 88888888. Lors de la création du contexte d'authentification, on a vu qu'un appel à la procédure 0, avec RPC: ----- SUN RPC Header -----
RPC:
RPC: Transaction id = 8569412567
RPC: Type = 0 (Call)
RPC: RPC version = 2
RPC: Program = 88888888 (?), version = 1, procedure = 0
RPC: Credentials: Flavor = 6 (RPCSEC_GSS), len = 20 bytes
RPC: version = 1
RPC: gss control procedure = 1 (RPCSEC_GSS_INIT)
--> surcharge de RPC_NULL par RPCSEC_GSS_INIT
RPC: sequence num = 0
RPC: service = 1 (none)
--> utilisation de RPCSEC_GSS_SVC_NONE
RPC: handle: length = 0, data = []
RPC: Verifier : Flavor = 0 (None), len = 0 bytes
RPC:
RPC: RPCSEC_GSS_INIT args:
RPC: gss_token: length = 502 bytes
RPC: (on trouve ensuite le message de négociation créé avec gss_init_sec_context)
Le serveur retourne, dans la réponse, le message de négociation, retraité par ses soins avec  RPC: ----- SUN RPC Header -----
RPC:
RPC: Transaction id = 8569412567
RPC: Type = 1 (Reply)
RPC: Status = 0 (Accepted)
RPC: Verifier : Flavor = 6 (RPCSEC_GSS), len = 37 bytes
.....
RPC: RPCSEC_GSS_INIT result:
RPC: handle: length = 4, data = [00000003]
--> le serveur a négocié un contexte, il retourne un identifiant qui indexe ce contexte
RPC: gss_major status = 0
--> gss_major = gss_minor = 0, la négociation est un succès, le contexte négocié est dans le corps de la réponse
RPC: gss_minor status = 0
RPC: sequence window = 128
RPC: gss token: length = 106 bytes
RPC: ..... les données contenues dans le gss token,
résultat de la négociation .....
Par la suite, les appels du client ont la forme suivante :
RPC: ----- SUN RPC Header -----
RPC:
RPC: Transaction id = 8569412678
RPC: Type = 0 (Call)
RPC: RPC version = 2
RPC: Program = 88888888 (?), version = 1, procedure = 1
RPC: Credentials: Flavor = 6 (RPCSEC_GSS), len = 24
bytes
RPC: version = 1
RPC: gss control procedure = 1 (RPCSEC_GSS_DATA)
--> un appel normal, pas une fonction de contrôle
RPC: sequence num = 2
RPC: service = 1 (none)
RPC: handle: length = 4, data = [00000003]
--> le client rappelle au serveur l'identifiant du contexte négocié pour permettre au serveur de le retrouver
RPC: Verifier : Flavor = 6 (None), len = 37 bytes
RPC: ...... somme de contrôle du numéro de séquence .....
--> le serveur calculera la cohérence entre seq_num et cette MIC avec les informations de contexte, pour authentifier le message
RPC:
RPC: ...... ensuite on trouve les informations relatives à la procédure 1 du protocole program = 88888888, vers = 1
5. Conclusion en forme de résumé
L'authentification est un besoin qui a été pris en compte dans les RPC dès la définition du protocole. Par la suite, des mécanismes de plus en plus complexes ont été ajoutés au standard au fur et à mesure que les technologies et les besoins évoluaient, jusqu'à faire apparaître des limitations structurelles dans le protocole. Ces limitations ont été à l'origine de RPCSEC_GSS, protocole plus évolué et ne rencontrant pas les limitations de ONC/RPC, tout en restant compatible avec ce dernier. Le support, la GSS-API en interne de RPCSEC_GSS, garantit le futur du protocole dans la mesure où il utilise une API standard présente désormais dans les protocoles de sécurité actuels (Kerberos 5, mais aussi SPKM et LIPKEY). Quand l'IETF a posé les définitions de NFSv4, la sécurité et l'authentification à différentes échelles (du LAN au WAN) sont apparues comme un besoin prioritaire. RPCSEC_GSS est né de ce besoin, pour pallier les défauts de ONC/RPC en la matière. Les ONC/RPC avaient vu le jour pour servir de couche de transport aux protocoles NFSv2 et NFSv3. Ainsi, de même que NFS avait " porté " ONC/RPC, NFSv4 doit porter RPCSEC_GSS car toute implémentation de ce protocole doit explicitement s'appuyer sur ce nouveau standard de RPC. De plus, RPCSEC_GSS est formellement très proche de ONC/RPC, tant au niveau du codage des clients que de celui des serveurs, une similarité qui facilite le portage des applicatifs existants dans ce nouveau protocole tout en assurant son évolutivité avec les protocoles de sécurité futurs puisque les adhérences se limitent à la GSS-API dont les spécifications sont fixées une fois pour toutes. De même que NFSv4, RPCSEC_GSS est un standard émergent, en train de gagner du terrain petit à petit. Si la sécurité n'est pas un besoin critique de vos outils, RPCSEC_GSS ne présente que peu d'intérêt et amène un certain surcoût. Dans le cas contraire, c'est la solution naturelle à adopter, pour sa généricité, sa portabilité et son évolutivité. Références :RFC1831: Remote Procedure Call Version 2ÂRFC1832: XDR: External Data Representation StandardRFC2203: RPCSEC_GSS Protocol SpecificationRFC2478: The simple and Protected GSS-API Negociation MechanismRFC2623: NFS Version 2 and Version 3 Security Issues and the NFS Protocol's Use of RPCSEC_GSS and Kerberos V5RFC3530 : Network File System (NFS) version 4 ProtocolRFC1509: Generic Security Service API: C-bindingsRFC1510: The Kerberos Network Authentication Service (V5)RFC1964: The Kerberos Version 5 GSS_API MechanismRFC2078: Generic Security Service Application Programming Interface, Version 2RFC2025: The Simple Public-Key GSS-API Mechanism (SPKM)RFC2847: A Low Infrastructure Public Key Mechanism Using SPKM- Premiers pas avec la GSS-API, Linux Magazine numéro 52.
- Article Authentification : clé de voûte de la confiance, ManuX, Misc 15.
Retrouvez cet article dans : Misc 17





Donnez votre avis
Vous devez avoir ouvert une session pour écrire un commentaire.