keyctl(2)

NOM
keyctl - Manipuler la gestion des clés du noyau

BIBLIOTHÈQUE
Bibliothèque C standard (libc, -lc)

SYNOPSIS
#include <linux/keyctl.h>  /* Définition des constantes KEY* */
#include <sys/syscall.h>   /* Définition des constantes SYS_* */
#include <unistd.h>

long syscall(SYS_keyctl, int op, ...);

DESCRIPTION
keyctl() permet aux programmes de l'espace utilisateur de manipuler des clés.

L'opération qu'effectue keyctl() dépend de la valeur du paramètre op. Chacune de ces opérations fait partie de l'enveloppe de la bibliothèque libkeyutils (fournie par le paquet keyutils) en tant que fonctions individuelles (voir keyctl(3)) pour permettre au compilateur de vérifier les types.

Les valeurs autorisées pour op sont :

KEYCTL_GET_KEYRING_ID(2const)
KEYCTL_JOIN_SESSION_KEYRING(2const)
KEYCTL_UPDATE(2const)
KEYCTL_REVOKE(2const)
KEYCTL_CHOWN(2const)
KEYCTL_SETPERM(2const)
KEYCTL_DESCRIBE(2const)
KEYCTL_CLEAR(2const)
KEYCTL_LINK(2const)
KEYCTL_UNLINK(2const)
KEYCTL_SEARCH(2const)
KEYCTL_READ(2const)
KEYCTL_INSTANTIATE(2const)
KEYCTL_INSTANTIATE_IOV(2const)
KEYCTL_NEGATE(2const)
KEYCTL_REJECT(2const)
KEYCTL_SET_REQKEY_KEYRING(2const)
KEYCTL_SET_TIMEOUT(2const)
KEYCTL_ASSUME_AUTHORITY(2const)
KEYCTL_GET_SECURITY(2const)
KEYCTL_SESSION_TO_PARENT(2const)
KEYCTL_INVALIDATE(2const)
KEYCTL_GET_PERSISTENT(2const)
KEYCTL_DH_COMPUTE(2const)
KEYCTL_RESTRICT_KEYRING(2const)

VALEUR RENVOYÉE
Pour qu'un appel réussisse, le code de retour dépend de l'opération.

En cas d'erreur, la valeur de retour est -1 et errno est définie pour préciser l'erreur.

ERREURS

EACCES
    L'opération demandée n'était pas autorisée.

EDQUOT
    Le quota de clés de l'utilisateur appelant serait dépassé si la clé était créée ou ajoutée au trousseau.

EINVAL
    la taille de la chaîne (y compris l'octet NULL final) indiquée dans arg3 (le type de clé) ou dans arg4 (la description de la clé) dépassait les limites (respectivement 32 et 4096 octets).

EKEYEXPIRED
    Une clé expirée a été trouvée ou spécifiée.

EKEYREJECTED
    Une clé rejetée a été trouvée ou spécifiée.

EKEYREVOKED
    Une clé révoquée a été trouvée ou spécifiée.

ENOKEY
    Aucune clé correspondante n'a été trouvée, ou une clé non valable a été spécifiée.

ENOMEM
    Une des routines de l'allocation mémoire du noyau a échoué lors de l'exécution de l'appel système.

ENOTDIR
    Une clé de type trousseau était attendue mais l'identifiant d'une clé de type différent a été fourni.

VERSIONS
Une enveloppe est fournie dans la bibliothèque libkeyutils. (Le paquet accompagnant fournit le fichier d'en-tête <keyutils.h>.) Cependant, plutôt que d'utiliser cet appel système directement, vous voudrez probablement utiliser les fonctions de la bibliothèque mentionnées dans les descriptions des opérations individuelles ci-dessus.

STANDARDS
Linux.

HISTORIQUE
Linux 2.6.10.

EXEMPLES
Le programme ci-dessous fournit un sous-ensemble de fonctions du programme request-key(8) fourni par le paquet keyutils. Pour information, le programme enregistre diverses informations dans un fichier journal.

Comme indiqué dans request_key(2), le programme request-key(8) est appelé avec les paramètres de la ligne de commande qui décrivent une clé à instancier. Le programme exemple récupère et enregistre ces arguments. Le programme endosse l'autorité d'instancier la clé demandée, puis il instancie cette clé.

La session d'interpréteur suivante montre l'utilisation de ce programme. Dans la session, nous compilons le programme, puis nous l'utilisons pour remplacer temporairement le programme request-key(8) standard (remarquez que la désactivation temporaire du programme standard request-key(8) peut ne pas être sure sur certains systèmes). Tant que notre programme exemple est installé, nous utilisons le programme exemple présent dans request_key(2) pour demander une clé.

    $ cc -o key_instantiate key_instantiate.c -lkeyutils;
    $ sudo mv /sbin/request-key /sbin/request-key.backup;
    $ sudo cp key_instantiate /sbin/request-key;
    $ ./t_request_key user mykey somepayloaddata;
    Key ID is 20d035bf
    $ sudo mv /sbin/request-key.backup /sbin/request-key;

En regardant le fichier journal créé par ce programme, on peut voir les paramètres de la ligne de commande fournis à notre programme exemple :

    $ cat /tmp/key_instantiate.log;
    Time: Mon Nov  7 13:06:47 2016

    Command line arguments:
      argv[0]:            /sbin/request-key
      operation:          create
      key_to_instantiate: 20d035bf
      UID:                1000
      GID:                1000
      thread_keyring:     0
      process_keyring:    0
      session_keyring:    256e6a6

    Key description:      user;1000;1000;3f010000;mykey
    Auth key payload:     somepayloaddata
    Destination keyring:  256e6a6
    Auth key description: .request_key_auth;1000;1000;0b010000;20d035bf

Les dernières lignes de la sortie ci-dessus montrent que le programme exemple a pu récupérer :

-   la description de la clé à instanciée, qui incluait le nom de la clé (mykey) ;

-   la charge utile de la clé d'autorisation, qui consistait dans des données (somepayloaddata) passées à request_key(2) ;

-   le trousseau de destination indiqué dans l'appel à request_key(2) ;

-   la description de la clé d'autorisation où on peut voir que le nom de la clé correspond à l'identifiant de celle à instancier (20d035bf).

Le programme exemple dans request_key(2) indiquait le trousseau de destination en tant que KEY_SPEC_SESSION_KEYRING. En examinant le contenu de /proc/keys, on peut voir que cela a été transcrit dans l'identifiant du trousseau de destination (0256e6a6) affiché dans le fichier journal ci-dessus ; on peut aussi voir la clé nouvellement créée dont le nom est mykey et l'identifiant est 20d035bf.

    $ cat /proc/keys | egrep 'mykey|256e6a6';
    0256e6a6 I--Q---  194 perm 3f030000  1000  1000 keyring  _ses: 3
    20d035bf I--Q---    1 perm 3f010000  1000  1000 user     mykey: 16

  Source du programme
    /* key_instantiate.c */

    #include <errno.h>
    #include <keyutils.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <time.h>

    #ifndef KEY_SPEC_REQUESTOR_KEYRING
    #define KEY_SPEC_REQUESTOR_KEYRING      (-8)
    #endif

    int
    main(int argc, char *argv[])
    {
        int           akp_size;       /* Size of auth_key_payload */
        int           auth_key;
        char          dbuf[256];
        char          auth_key_payload[256];
        char          *operation;
        FILE          *fp;
        gid_t         gid;
        uid_t         uid;
        time_t        t;
        key_serial_t  key_to_instantiate, dest_keyring;
        key_serial_t  thread_keyring, process_keyring, session_keyring;

        if (argc != 8) {
            fprintf(stderr, "Usage: %s op key uid gid thread_keyring "
                            "process_keyring session_keyring\n", argv[0]);
            exit(EXIT_FAILURE);
        }

        fp = fopen("/tmp/key_instantiate.log", "w");
        if (fp == NULL)
            exit(EXIT_FAILURE);

        setbuf(fp, NULL);

        t = time(NULL);
        fprintf(fp, "Time: %s\n", ctime(&t));

        /*
         * The kernel passes a fixed set of arguments to the program
         * that it execs; fetch them.
         */
        operation = argv[1];
        key_to_instantiate = atoi(argv[2]);
        uid = atoi(argv[3]);
        gid = atoi(argv[4]);
        thread_keyring = atoi(argv[5]);
        process_keyring = atoi(argv[6]);
        session_keyring = atoi(argv[7]);

        fprintf(fp, "Command line arguments:\n");
        fprintf(fp, "  argv[0]:            %s\n", argv[0]);
        fprintf(fp, "  operation:          %s\n", operation);
        fprintf(fp, "  key_to_instantiate: %jx\n",
                (uintmax_t) key_to_instantiate);
        fprintf(fp, "  UID:                %jd\n", (intmax_t) uid);
        fprintf(fp, "  GID:                %jd\n", (intmax_t) gid);
        fprintf(fp, "  thread_keyring:     %jx\n",
                (uintmax_t) thread_keyring);
        fprintf(fp, "  process_keyring:    %jx\n",
                (uintmax_t) process_keyring);
        fprintf(fp, "  session_keyring:    %jx\n",
                (uintmax_t) session_keyring);
        fprintf(fp, "\n");

        /*
         * Assume the authority to instantiate the key named in argv[2].
         */
        if (keyctl(KEYCTL_ASSUME_AUTHORITY, key_to_instantiate) == -1) {
            fprintf(fp, "KEYCTL_ASSUME_AUTHORITY failed: %s\n",
                    strerror(errno));
            exit(EXIT_FAILURE);
        }

        /*
         * Fetch the description of the key that is to be instantiated.
         */
        if (keyctl(KEYCTL_DESCRIBE, key_to_instantiate,
                   dbuf, sizeof(dbuf)) == -1) {
            fprintf(fp, "KEYCTL_DESCRIBE failed: %s\n", strerror(errno));
            exit(EXIT_FAILURE);
        }

        fprintf(fp, "Key description:      %s\n", dbuf);

        /*
         * Fetch the payload of the authorization key, which is
         * actually the callout data given to request_key().
         */
        akp_size = keyctl(KEYCTL_READ, KEY_SPEC_REQKEY_AUTH_KEY,
                          auth_key_payload, sizeof(auth_key_payload));
        if (akp_size == -1) {
            fprintf(fp, "KEYCTL_READ failed: %s\n", strerror(errno));
            exit(EXIT_FAILURE);
        }

        auth_key_payload[akp_size] = '\0';
        fprintf(fp, "Auth key payload:     %s\n", auth_key_payload);

        /*
         * For interest, get the ID of the authorization key and
         * display it.
         */
        auth_key = keyctl(KEYCTL_GET_KEYRING_ID,
                          KEY_SPEC_REQKEY_AUTH_KEY);
        if (auth_key == -1) {
            fprintf(fp, "KEYCTL_GET_KEYRING_ID failed: %s\n",
                    strerror(errno));
            exit(EXIT_FAILURE);
        }

        fprintf(fp, "Auth key ID:          %jx\n", (uintmax_t) auth_key);

        /*
         * Fetch key ID for the request_key(2) destination keyring.
         */
        dest_keyring = keyctl(KEYCTL_GET_KEYRING_ID,
                              KEY_SPEC_REQUESTOR_KEYRING);
        if (dest_keyring == -1) {
            fprintf(fp, "KEYCTL_GET_KEYRING_ID failed: %s\n",
                    strerror(errno));
            exit(EXIT_FAILURE);
        }

        fprintf(fp, "Destination keyring:  %jx\n", (uintmax_t) dest_keyring);

        /*
         * Fetch the description of the authorization key.  This
         * allows us to see the key type, UID, GID, permissions,
         * and description (name) of the key.  Among other things,
         * we will see that the name of the key is a hexadecimal
         * string representing the ID of the key to be instantiated.
         */
        if (keyctl(KEYCTL_DESCRIBE, KEY_SPEC_REQKEY_AUTH_KEY,
                   dbuf, sizeof(dbuf)) == -1)
        {
            fprintf(fp, "KEYCTL_DESCRIBE failed: %s\n", strerror(errno));
            exit(EXIT_FAILURE);
        }

        fprintf(fp, "Auth key description: %s\n", dbuf);

        /*
         * Instantiate the key using the callout data that was supplied
         * in the payload of the authorization key.
         */
        if (keyctl(KEYCTL_INSTANTIATE, key_to_instantiate,
                   auth_key_payload, akp_size + 1, dest_keyring) == -1)
        {
            fprintf(fp, "KEYCTL_INSTANTIATE failed: %s\n",
                    strerror(errno));
            exit(EXIT_FAILURE);
        }

        exit(EXIT_SUCCESS);
    }

VOIR AUSSI
keyctl(1), add_key(2), request_key(2), keyctl(3), recursive_key_scan(3), recursive_session_key_scan(3), capabilities(7), credentials(7), keyrings(7), keyutils(7), persistent-keyring(7), process-keyring(7), session-keyring(7), thread-keyring(7), user-keyring(7), user_namespaces(7), user-session-keyring(7), request-key(8)

Les fichiers sources du noyau Documentation/security/keys/ (ou avant Linux 4.13, dans le fichier Documentation/security/keys.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 (https://www.gnu.org/licenses/gpl-3.0.html) 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 à debian-l10n-french@lists.debian.org.