request_key
Section: System Calls (2)
Updated: 5 février 2023
Index
Return to Main Contents
NOM
request_key - Demander une clé au gestionnaire de clés du noyau
BIBLIOTHÈQUE
Utilitaires de gestion de clefs Linux (libkeyutils, -lkeyutils)
SYNOPSIS
#include <keyutils.h>
key_serial_t request_key(const char *type, const char *description,
const char *_Nullable callout_info,
key_serial_t dest_keyring);
DESCRIPTION
request_key() essaie de trouver une clé d'un type donné, qui
correspond à la description (au nom) spécifiée. Si aucune clé n'a pu être
trouvée, la clé peut être créée. Si la clé a été trouvée ou créée,
request_key() la rattache au trousseau dont l'identifiant est indiqué
dans dest_keyring et il renvoie le numéro de série de la clé.
request_key() cherche une clé correspondant aux critères d'abord
récursivement à l'intérieur des trousseaux attachés au processus appelant,
dans l'ordre suivant : trousseau spécifique au thread, trousseau spécifique
au processus, et enfin le trousseau de session.
Si request_key() est appelé depuis un programme lui-même appelé par
request_key() au nom d'un autre processus afin de générer une clé, alors
les trousseaux de cet autre processus seront ensuite parcourus en utilisant
les identifiants d’utilisateur, de groupe, du groupe supplémentaire et le
contexte de sécurité de ce processus.
La recherche dans l'arborescence d'un trousseau est de type parcours en
largeur : une correspondance est d'abord recherchée avec toutes les clés
d'un trousseau avant de chercher dans les trousseaux trouvés dans ce
trousseau. Seules les clés et seuls les trousseaux pour lesquels le
processus a l'autorisation search peuvent être examinés.
Si aucune clé n'est trouvée et si callout est NULL, l'appel échoue avec
l'erreur ENOKEY.
Si aucune clé n'est trouvée et si callout n'est pas NULL, le noyau essaie
d'appeler un programme de l'espace utilisateur pour instancier la clé. Les
détails sont donnés ci-dessous.
Le numéro de série dest_keyring peut être celui d'un trousseau valable
sur lequel l'appelant possède les droits en écriture ou il peut s'agir d'un
des identifiants de trousseau spécial suivants :
- KEY_SPEC_THREAD_KEYRING
-
Cela indique le trousseau spécifique au thread de l'appelant (voir
thread-keyring(7)).
- KEY_SPEC_PROCESS_KEYRING
-
Cela indique le trousseau spécifique au processus de l'appelant (voir
process-keyring(7)).
- KEY_SPEC_SESSION_KEYRING
-
Cela indique le trousseau spécifique à la session de l'appelant (voir
session-keyring(7)).
- KEY_SPEC_USER_KEYRING
-
Cela indique le trousseau spécifique à l'UID de l'appelant (voir
user-keyring(7)).
- KEY_SPEC_USER_SESSION_KEYRING
-
Cela indique le trousseau spécifique à la session de l'UID de l'appelant
(voir user-session-keyring(7)).
Quand dest_keyring est indiqué comme 0 et qu'aucune construction de
clé n'ait été effectuée, aucune édition de liens supplémentaire n'est
effectuée.
Sinon, si dest_keyring est 0 et si une nouvelle clé est construite, la
nouvelle clé sera attachée au trousseau par défaut. Plus précisément, quand
le noyau essaie de déterminer le trousseau auquel rattacher la clé
nouvellement créée, il essaie les trousseaux les uns à la suite des autres,
en commençant par celui défini par l'opération KEYCTL_SET_REQKEY_KEYRING
de keyctl(2), puis en continuant dans l'ordre ci-dessous jusqu'à ce qu'il
trouve le premier trousseau existant :
- •
-
Le trousseau du demandeur (KEY_REQKEY_DEFL_REQUESTOR_KEYRING depuis Linux
2.6.29).
- •
-
Le trousseau spécifique au thread (KEY_REQKEY_DEFL_THREAD_KEYRING ; voir
thread-keyring(7)).
- •
-
Le trousseau spécifique au processus (KEY_REQKEY_DEFL_PROCESS_KEYRING ;
voir process-keyring(7)).
- •
-
Le trousseau spécifique à la session (KEY_REQKEY_DEFL_SESSION_KEYRING ;
voir session-keyring(7)).
- •
-
Le trousseau de la session associé à l'identifiant utilisateur du processus
(KEY_REQKEY_DEFL_USER_SESSION_KEYRING ; voir
user-session-keyring(7)). Ce trousseau est censé toujours exister.
- •
-
Le trousseau spécifique à l'identifiant utilisateur
(KEY_REQKEY_DEFL_USER_KEYRING ; voir user-keyring(7)). Ce trousseau
est toujours censé exister.
Si l'opération KEYCTL_SET_REQKEY_KEYRING de keyctl(2) indique
KEY_REQKEY_DEFL_DEFAULT (ou si aucune opération
KEYCTL_SET_REQKEY_KEYRING n'est effectuée), le noyau cherche un trousseau
à partir du début de la liste.
Demander l'instanciation d'une clé dans l'espace utilisateur
Si le noyau ne peut pas trouver de clé correspondant à type et à
description et si callout n'est pas NULL, le noyau essaie d'appeler un
programme de l'espace utilisateur pour instancier une clé au type et à la
description donnés. Dans ce cas, les étapes suivantes sont suivies :
- (1)
-
Le noyau crée une clé non instanciée, U, du type et de la description
demandés.
- (2)
-
Le noyau crée une clé d'autorisation, V, qui se rapporte à la clé U, et
enregistre les faits que l'appelant de request_key() est :
-
- (2.1)
-
le contexte dans lequel la clé U doit être instanciée et sécurisée et
- (2.2)
-
le contexte à partir duquel les requêtes associées à la clé peuvent être
honorées.
-
La clé d'autorisation est construite comme suit :
-
- •
-
Le type de clé est « .request_key_auth ».
- •
-
Les identifiants utilisateur et de groupe de la clé sont les mêmes que ceux
du système de fichiers correspondant du processus à l'origine de la demande.
- •
-
La clé accorde le droit de visibilité, lecture et de recherche au
détenteur de la clé ainsi que celui de visibilité à l'utilisateur de la
clé.
- •
-
La description (son nom) de la clé est la chaîne hexadécimale représentant
l'identifiant de la clé à instancier dans le programme à l'origine de la
demande.
- •
-
La charge utile de la clé est récupérée à partir des données indiquées dans
callout_info.
- •
-
En interne, le noyau enregistre aussi l'identifiant de processus de la
request_key() appelée.
- (3)
-
Le noyau crée un processus qui exécute un service de l'espace utilisateur
tel que request-key(8) avec un nouveau trousseau de session contenant un
lien vers la clé d'autorisation, V.
-
Ce programme est fourni avec les options suivantes en ligne de commande :
-
- [0]
-
La chaîne « /sbin/request-key ».
- [1]
-
« create » (indiquant qu'une clé doit être créée).
- [2]
-
L'identifiant de la clé à instancier.
- [3]
-
L'identifiant utilisateur du système de fichiers de l'appelant de
request_key().
- [4]
-
L'identifiant de groupe du système de fichiers de l'appelant de
request_key().
- [5]
-
L'identifiant du trousseau du thread de l’appelant de request_key(). Il
peut être zéro si le trousseau n'a pas été créé.
- [6]
-
L'identifiant du trousseau du processus de l'appelant de
request_key(). Il peut être zéro si le trousseau n'a pas été créé.
- [7]
-
L'identifiant du trousseau de session de l'appelant de request_key().
-
Note : chacune des options de la ligne de commande étant un identifiant
de clé est encodé en décimal (contrairement aux identifiants de clé
affichés dans /proc/keys, affichés en valeurs hexadécimales).
- (4)
-
Le programme généré dans l'étape précédente :
-
- •
-
Assume l'autorité pour instancier la clé U en utilisant l'opération
KEYCTL_ASSUME_AUTHORITY de keyctl(2) (généralement à l'aide de la
fonction keyctl_assume_authority(3)).
- •
-
Obtient les données de l'appel à partir de la charge utile de la clé
d'autorisation V (en utilisant l'opération KEYCTL_READ de keyctl(2)
(ou plus généralement, la fonction keyctl_read(3)) avec une valeur
d'identifiant de clé de KEY_SPEC_REQKEY_AUTH_KEY).
- •
-
Instancie la clé (ou exécute un autre programme pour faire cette tâche), en
indiquant la charge utile et le trousseau de destination (on peut accéder à
celui indiqué par le demandeur lors de l'appel request_key() en utilisant
l'identifiant de clé spécial KEY_SPEC_REQUESTOR_KEYRING). L'instanciation
est effectuée en utilisant l'opération KEYCTL_INSTANTIATE de keyctl(2)
(ou plus généralement, la fonction keyctl_instantiate(3)). À ce moment,
l'appel request_key() se termine et le programme à l'origine de la
demande peut continuer son exécution.
Si ces étapes ne réussissent pas, une erreur ENOKEY sera renvoyée à
l'appelant de request_key() et une clé temporaire et instanciée de
manière négative sera installée sur le trousseau indiqué par
dest_keyring. Elle expirera après quelques secondes mais elle permettra
aux appels suivants à request_key() d'échouer jusqu'à ce qu'elles
réussissent. Le but de cette clé instanciée négativement est d'empêcher des
processus (potentiellement différents) d'effectuer des demandes répétées
(qui requièrent des appels request-key(8) coûteux) pour une clé qui ne
peut pas être instanciée positivement (pour l'instant).
Une fois que la clé a été instanciée, la clé d'autorisation
(KEY_SPEC_REQKEY_AUTH_KEY) est révoquée et le trousseau de destination
(KEY_SPEC_REQUESTOR_KEYRING) n'est plus accessible au programme
request-key(8).
Si une clé est créée, qu'elle soit valable ou instanciée négativement, elle
remplacera toute autre clé possédant le même type et la même description
dans le trousseau indiqué dans dest_keyring.
VALEUR RENVOYÉE
En cas de succès, request_key() renvoie le numéro de série de la clé
trouvée ou créée. En cas d'erreur, la valeur -1 est renvoyée et errno
est positionné pour indiquer l'erreur.
ERREURS
- EACCES
-
Le trousseau n'était pas disponible pour pouvoir être modifié par
l'utilisateur.
- EDQUOT
-
Le quota de clés de cet utilisateur serait dépassé si la clé était créée ou
ajoutée au trousseau.
- EFAULT
-
Le type, la description ou la callout_info pointe en dehors de
l'espace d'adressage accessible au processus.
- EINTR
-
La requête a été interrompue par un signal ; voir signal(7).
- EINVAL
-
La longueur de la chaîne (y compris l'octet NULL final) spécifié dans
type ou description a dépassé la limite (respectivement 32 et
4096 octets).
- EINVAL
-
La taille de la clé (octet NULL final inclus) indiquée dans callout_info
dépassait la taille de la page du système.
- EKEYEXPIRED
-
Une clé expirée a été trouvée, mais aucun remplacement n'a pu être obtenu.
- EKEYREJECTED
-
La tentative de générer une nouvelle clé a été rejetée.
- EKEYREVOKED
-
Une clé révoquée a été trouvée, mais aucun remplacement n'a pu être obtenu.
- ENOKEY
-
Aucune clé correspondante n'a été trouvée.
- ENOMEM
-
Il n'y a pas assez de mémoire pour créer une clé.
- EPERM
-
Le paramètre type commençait par un point ('.').
VERSIONS
Cet appel système est apparu pour la première fois dans Linux 2.6.10. La
possibilité d'instancier des clés à la demande a été ajoutée dans Linux
2.6.13.
STANDARDS
Cet appel système est une extension Linux non standard.
EXEMPLES
Le programme ci-dessous montre l'utilisation de request_key(). Les
paramètres type, description et callout_info pour l'appel système
sont récupérés à partir des valeurs fournies dans les options de la ligne de
commande. L'appel indique le trousseau de session en tant que trousseau
cible.
Pour montrer ce programme, on crée d'abord une entrée adéquate dans
/etc/request-key.conf.
$ sudo sh
# echo 'création utilisateur mtk:* * /bin/keyctl instantiate %k %c %S' \
> /etc/request-key.conf
# exit
Cette entrée indique que lorsqu'une nouvelle clé « utilisateur » avec le
préfixe « mtk: » doit être instanciée, la tâche doit être effectuée par
l'opération instantiate de la commande keyctl(1). Les paramètres
fournis à l'opération instantiate sont : l'identifiant de la clé non
instanciée (%k), les données de l'appel fournies à l'appel
request_key() (%c) et le trousseau de session (%S) du demandeur (à
savoir l'appelant de request_key()). Consulter request-key.conf(5)
pour les détails de ces spécificateurs %.
Puis on lance le programme et on vérifie que le contenu de /proc/keys
pour vérifier que la clé demandée a été instanciée :
$ ./t_request_key user mtk:key1 "Payload data"
$ grep '2dddaf50' /proc/keys
2dddaf50 I--Q--- 1 perm 3f010000 1000 1000 user mtk:key1: 12
Pour un autre exemple d'utilisation de ce programme, voir keyctl(2).
Source du programme
/* t_request_key.c */
#include <keyutils.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
key_serial_t key;
if (argc != 4) {
fprintf(stderr, "Utilisation : %s type description données-appel\n",
argv[0]);
exit(EXIT_FAILURE);
}
key = request_key(argv[1], argv[2], argv[3],
KEY_SPEC_SESSION_KEYRING);
if (key == -1) {
perror("request_key");
exit(EXIT_FAILURE);
}
printf("L'identifiant de la clé est %jx\n", (uintmax_t) key);
exit(EXIT_SUCCESS);
}
VOIR AUSSI
keyctl(1), add_key(2), keyctl(2), keyctl(3), capabilities(7),
keyrings(7), keyutils(7), persistent-keyring(7),
process-keyring(7), session-keyring(7), thread-keyring(7),
user-keyring(7), user-session-keyring(7), request-key(8)
Les fichiers Documentation/security/keys/core.rst et
Documentation/keys/request-key.rst des sources du noyau (ou, avant
Linux 4.13, Documentation/security/keys.txt et
Documentation/security/keys-request-key.txt).
TRADUCTION
La traduction française de cette page de manuel a été créée par
Christophe Blaess <https://www.blaess.fr/christophe/>,
Stéphan Rafin <stephan.rafin@laposte.net>,
Thierry Vignaud <tvignaud@mandriva.com>,
François Micaux,
Alain Portal <aportal@univ-montp2.fr>,
Jean-Philippe Guérard <fevrier@tigreraye.org>,
Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>,
Julien Cristau <jcristau@debian.org>,
Thomas Huriaux <thomas.huriaux@gmail.com>,
Nicolas François <nicolas.francois@centraliens.net>,
Florentin Duneau <fduneau@gmail.com>,
Simon Paillard <simon.paillard@resel.enst-bretagne.fr>,
Denis Barbier <barbier@debian.org>,
David Prévot <david@tilapin.org>
et
Jean-Philippe MENGUAL <jpmengual@debian.org>
Cette traduction est une documentation libre ; veuillez vous reporter à la
GNU General Public License version 3
concernant les conditions de copie et
de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.
Si vous découvrez un bogue dans la traduction de cette page de manuel,
veuillez envoyer un message à
Index
- NOM
-
- BIBLIOTHÈQUE
-
- SYNOPSIS
-
- DESCRIPTION
-
- Demander l'instanciation d'une clé dans l'espace utilisateur
-
- VALEUR RENVOYÉE
-
- ERREURS
-
- VERSIONS
-
- STANDARDS
-
- EXEMPLES
-
- Source du programme
-
- VOIR AUSSI
-
- TRADUCTION
-
This document was created by
man2html,
using the manual pages.
Time: 20:39:58 GMT, May 22, 2024