ADD_KEY(2) Вызовы системы управления ключами Linux ADD_KEY(2)

ИМЯ

add_key - добавить ключ в систему управления ключами ядра

ОБЗОР

#include <sys/types.h>
#include <keyutils.h>
key_serial_t add_key(const char *type, const char *description,
                     const void *payload, size_t plen,
                     key_serial_t keyring);

В glibc нет обёрточной функции для данного системного вызова; смотрите ЗАМЕЧАНИЯ.

ОПИСАНИЕ

Вызов add_key() создаёт или обновляет ключ заданного типа type с описанием description, конструирует его с полезными данными payload и длиной plen, присоединяет его к заданной связке ключей keyring и возвращает его серийный номер.

Ключ может быть отклонён, если его данные представлены в неправильном формате или возникла другая ошибка.

Если в указываемой связке ключей keyring уже есть ключ с таким же type и description то, если тип ключа это поддерживает, ключ будет обновлён, а не создан заново; если нет, то будет создан новый ключ (с другим идентификатором) и он вытеснит ссылку на существующий ключ из связки.

Связка ключей keyring может задаваться серийным номером действующей связки ключей, для которой у вызывающего есть права на запись. Или же это может быть один из следующих специальных идентификаторов связок ключей:

Связка ключей вызывающей нити (thread-keyring(7)).
Связка ключей вызывающего процесса (process-keyring(7)).
Связка ключей сеанса вызывающего (session-keyring(7)).
Связка ключей по UID вызывающего (user-keyring(7)).
Связка ключей по UID сеанса вызывающего (user-session-keyring(7)).

Типы ключей

Значение type ключа представляет собой строку, которой определяется тип ключа. Внутри ядра определено несколько типов ключей, которые доступны в ядре кода управления ключами. В пользовательском пространстве в аргументе type при вызове add_key() можно использовать следующие значения:

"keyring"
Связки ключей — это специальные типы ключей, которые могут содержать ссылки на цепочки других ключей любого типа. Если данный интерфейс используется для создания связки ключей, то значение payload должно быть равно NULL, а plen должно быть равно нулю.
"user"
Тип ключа общего назначения, чьи полезные данные можно читать и обновлять из пользовательских программ. Ключ полностью хранится в памяти ядра. Полезные данные ключей этого типа представляют собой данные произвольной структуры (blob) размером до 32767 байт.
"logon" (начиная с Linux 3.3)
Данный тип ключа подобен "user", но не позволяет читать ключ. Этот тип подходит для хранения полезных данных, которые вам не нужно читать из пользовательского пространства.

Для данного типа ключа значение description должно уточняться префиксом «service», который в description отделяется символом «:» от остальных символов.

"big_key" (начиная с Linux 3.13)
Данный тип ключа подобен "user", но может содержать полезные данные размером до 1 МиБ. Если полезной нагрузки много, то её можно хранить зашифрованной в tmpfs (может вытесняться из памяти), а не в памяти ядра.

Дополнительную информацию об этих типах ключей смотрите в keyrings(7).

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

При успешном выполнении add_key() возвращается серийный номер созданного или изменённого ключа. При ошибке возвращается -1, а в errno содержится код ошибки.

ОШИБКИ

Изменение связки ключей пользователю недоступно.
Квота на ключи для данного пользователя была бы превышена, если бы этот ключ создался или был бы прицеплен в связку ключей.
Значение одного или нескольких полей из type, description и payload указывают вне доступного адресного пространства процесса.
Размер строки (включая конечный байт null), указанной в type или description, превышает ограничение (32 байта и 4096 байт, соответственно).
Некорректное значение полезных данных.
Значение type равно "logon", но значение description не начинается строкой-префиксом в виде "service:".
Срок службы связки ключей истёк.
Связка ключей отозвана.
Связка ключей не существует.
Недостаточно памяти для создания ключа.
Значение type начинается с точки ('.'). Типы ключей, начинающиеся с точки, зарезервированы для использования в реализации.
Значение type равно "keyring" и description начинается с точки ('.'). Связки ключей с описаниями (именами), которые начинаются с точки, зарезервированы для использования реализацией.

ВЕРСИИ

Этот системный вызов впервые появился в Linux 2.6.10.

СООТВЕТСТВИЕ СТАНДАРТАМ

Этот системный вызов является нестандартным расширением Linux.

ЗАМЕЧАНИЯ

В glibc нет обёрточной функции для этого системного вызова. Такая функция предоставляется пакетом libkeyutils. Для работы с функцией подключите библиотеку с помощью -lkeyutils.

ПРИМЕР

Программа, представленная ниже, создаёт ключ с типом, описанием и полезными данными, указанными в аргументах командной строки, и и цепляет этот ключ в связку ключей сеанса. Пример работы программы:

$ ./a.out user mykey "Some payload"
ID ключа = 64a4dca
$ grep '64a4dca' /proc/keys
064a4dca I--Q---    1 perm 3f010000  1000  1000 user    mykey: 12

Исходный код программы

#include <sys/types.h>
#include <keyutils.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
main(int argc, char *argv[])
{

    key_serial_t key;

    if (argc != 4) {

        fprintf(stderr, "Использование: %s тип описание полезные_данные\n",

                argv[0]);

        exit(EXIT_FAILURE);

    }

    key = add_key(argv[1], argv[2], argv[3], strlen(argv[3]),

                KEY_SPEC_SESSION_KEYRING);

    if (key == -1) {

        perror("add_key");

        exit(EXIT_FAILURE);

    }

    printf("ID ключа = %lx\n", (long) key);

    exit(EXIT_SUCCESS);
}

СМОТРИТЕ ТАКЖЕ

keyctl(1), keyctl(2), request_key(2), keyctl(3), keyrings(7), keyutils(7), persistent-keyring(7), process-keyring(7), session-keyring(7), thread-keyring(7), user-keyring(7), user-session-keyring(7)

Файлы исходного кода ядра Documentation/security/keys/core.rst и Documentation/keys/request-key.rst (или, до Linux 4.13, файлы Documentation/security/keys.txt и Documentation/security/keys-request-key.txt).

2019-03-06 Linux