Scroll to navigation

keyctl(2) System Calls Manual keyctl(2)

الاسم

keyctl - التلاعب بمرفق إدارة المفاتيح في النواة

المكتبة

مكتبة سي المعيارية (libc، -lc)

موجز

#include <linux/keyctl.h>  /* تعريف ثوابت KEY* */
#include <sys/syscall.h>   /* تعريف ثوابت SYS_* */
#include <unistd.h>
long syscall(SYS_keyctl, int op, ...);

الوصف

تسمح keyctl() لبرامج فضاء المستخدم بإجراء تلاعب بالمفاتيح.

تُحدد العملية التي تجريها keyctl() بواسطة قيمة المعامل op. تُغلف كل عملية من هذه العمليات بواسطة مكتبة libkeyutils (التي توفرها حزمة keyutils) في دوال منفردة (انظر keyctl(3)) للسماح للمصرف بالتحقق من الأنواع.

القيم المسموح بها لـ op هي:

قيمة الإرجاع

للاستدعاء الناجح، تعتمد قيمة الإرجاع على العملية.

عند الخطأ، تُعاد القيمة -1، ويُضبط errno للإشارة إلى الخطأ.

الأخطاء

العملية المطلوبة لم تكن مسموحة.
حصة المفاتيح لمستخدم المستدعِي ستُتجاوز بإنشاء مفتاح أو ربطه بحلقة المفاتيح.
حجم السلسلة (بما في ذلك بايت الإنهاء الصفري) المحدد في arg3 (نوع المفتاح) أو arg4 (وصف المفتاح) تجاوز الحد (32 بايت و 4096 بايت على التوالي).
وُجد أو حُدد مفتاح منتهي الصلاحية.
وُجد أو حُدد مفتاح مرفوض.
وُجد أو حُدد مفتاح ملغى.
لم يُعثر على مفتاح مطابق أو حُدد مفتاح غير صالح.
فشلت إحدى روتينات تخصيص ذاكرة النواة أثناء تنفيذ استدعاء النظام.
تُوقع مفتاح من نوع حلقة مفاتيح ولكن قُدم معرف مفتاح بنوع مختلف.

الإصدارات

يُوفّر غلاف في مكتبة libkeyutils. (تُوفّر الحزمة المرفقة ملف الترويسة <keyutils.h>). ومع ذلك، بدلاً من استخدام استدعاء النظام هذا مباشرةً، ربما تود استخدام دوال المكتبة المتنوعة المذكورة في أوصاف العمليات الفردية أعلاه.

المعايير

لينكس.

التاريخ

لينكس 2.6.10.

أمثلة

يوفر البرنامج أدناه مجموعة فرعية من وظائف برنامج request-key(8) الذي توفره حزمة keyutils. لأغراض إعلامية، يسجل البرنامج معلومات متنوعة في ملف سجل.

كما هو موضح في request_key(2)، يُستدعى برنامج request-key(8) بمعاملات سطر الأوامر التي تصف مفتاحاً سيُنشأ. يجلب برنامج المثال هذه المعاملات ويسجلها. يفترض البرنامج سلطة إنشاء المفتاح المطلوب، ثم ينشئ ذلك المفتاح.

توضح جلسة الصدفة التالية استخدام هذا البرنامج. في الجلسة، نصرف البرنامج ثم نستخدمه لاستبدال برنامج request-key(8) المعياري مؤقتاً. (لاحظ أن تعطيل برنامج request-key(8) المعياري مؤقتاً قد لا يكون آمناً في بعض الأنظمة). بينما يكون برنامج المثال الخاص بنا مثبتاً، نستخدم برنامج المثال الموضح في request_key(2) لطلب مفتاح.


$ 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;

بالنظر إلى ملف السجل الذي أنشأه هذا البرنامج، يمكننا رؤية معاملات سطر الأوامر المقدمة لبرنامج المثال الخاص بنا:


$ 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

تظهر الأسطر القليلة الأخيرة من المخرجات أعلاه أن برنامج المثال كان قادراً على جلب:

وصف المفتاح المُراد إنشاؤه، والذي يتضمن اسم المفتاح (mykey
حمولة مفتاح الاستيثاق، والتي تتكون من البيانات (somepayloaddata) الممرة إلى request_key(2)؛
حلقة مفاتيح الوجهة التي حُددت في استدعاء request_key(2)؛ و
وصف مفتاح الاستيثاق، حيث يمكننا رؤية أن اسم مفتاح الاستيثاق يطابق معرف المفتاح المُراد إنشاؤه (20d035bf).

حدد برنامج المثال في request_key(2) حلقة مفاتيح الوجهة بـ KEY_SPEC_SESSION_KEYRING. بفحص محتويات /proc/keys، يمكننا رؤية أن هذا قد تُرجم إلى معرف حلقة مفاتيح الوجهة (0256e6a6) الموضح في مخرجات السجل أعلاه؛ يمكننا أيضًا رؤية المفتاح المُنشأ حديثاً باسم mykey والمعرف 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

مصدر البرنامج

/* 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; /* حجم حمولة مفتاح الاستيثاق */
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, "الاستخدام: %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, "الوقت: %s\n", ctime(&t));
/*
* تُمرّر النواة مجموعة ثابتة من المعاملات إلى البرنامج
* الذي تنفذه؛ اجلبها.
*/
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 = argv[7];
fprintf(fp, "معاملات سطر الأوامر:\n");
fprintf(fp, " argv[0]: %s\n", argv[0]);
fprintf(fp, " العملية: %s\n", operation);
fprintf(fp, " المفتاح المُراد إنشاؤه: %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, " حلقة مفاتيح الخيط: %jx\n",
(uintmax_t) thread_keyring);
fprintf(fp, " حلقة مفاتيح العملية: %jx\n",
(uintmax_t) process_keyring);
fprintf(fp, " حلقة مفاتيح الجلسة: %jx\n",
(uintmax_t) session_keyring);
fprintf(fp, "\n");
/*
* افتراض سلطة إنشاء المفتاح المسمى في argv[2].
*/
if (keyctl(KEYCTL_ASSUME_AUTHORITY, key_to_instantiate) == -1) {
fprintf(fp, "فشل KEYCTL_ASSUME_AUTHORITY: %s\n",
strerror(errno));
exit(EXIT_FAILURE);
}
/*
* جلب وصف المفتاح المُراد إنشاؤه.
*/
if (keyctl(KEYCTL_DESCRIBE, key_to_instantiate,
dbuf, sizeof(dbuf)) == -1) {
fprintf(fp, "فشل KEYCTL_DESCRIBE: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
fprintf(fp, "وصف المفتاح: %s\n", dbuf);
/*
* جلب حمولة مفتاح الاستيثاق، وهي في الواقع
* بيانات النداء المقدمة إلى 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: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
auth_key_payload[akp_size] = '\0';
fprintf(fp, "حمولة مفتاح الاستيثاق: %s\n", auth_key_payload);
/*
* من باب الفضول، جلب معرف مفتاح الاستيثاق
* وعرضه.
*/
auth_key = keyctl(KEYCTL_GET_KEYRING_ID,
KEY_SPEC_REQKEY_AUTH_KEY);
if (auth_key == -1) {
fprintf(fp, "فشل KEYCTL_GET_KEYRING_ID: %s\n",
strerror(errno));
exit(EXIT_FAILURE);
}
fprintf(fp, "معرف مفتاح الاستيثاق: %jx\n", (uintmax_t) auth_key);
/*
* جلب معرف المفتاح لحلقة مفاتيح وجهة request_key(2).
*/
dest_keyring = keyctl(KEYCTL_GET_KEYRING_ID,
KEY_SPEC_REQUESTOR_KEYRING);
if (dest_keyring == -1) {
fprintf(fp, "فشل KEYCTL_GET_KEYRING_ID: %s\n",
strerror(errno));
exit(EXIT_FAILURE);
}
fprintf(fp, "حلقة مفاتيح الوجهة: %jx\n", (uintmax_t) dest_keyring);
/*
* جلب وصف مفتاح الاستيثاق. يسمح لنا هذا
* برؤية نوع المفتاح، ومعرف المستخدم، ومعرف المجموعة، والأذونات،
* ووصف (اسم) المفتاح. من بين أشياء أخرى،
* سنرى أن اسم المفتاح هو سلسلة ست عشرية
* تمثل معرف المفتاح المُراد إنشاؤه.
*/
if (keyctl(KEYCTL_DESCRIBE, KEY_SPEC_REQKEY_AUTH_KEY,
dbuf, sizeof(dbuf)) == -1)
{
fprintf(fp, "فشل KEYCTL_DESCRIBE: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
fprintf(fp, "وصف مفتاح الاستيثاق: %s\n", dbuf);
/*
* إنشاء المفتاح باستخدام بيانات النداء التي قدمت
* في حمولة مفتاح الاستيثاق.
*/
if (keyctl(KEYCTL_INSTANTIATE, key_to_instantiate,
auth_key_payload, akp_size + 1, dest_keyring) == -1)
{
fprintf(fp, "فشل KEYCTL_INSTANTIATE: %s\n",
strerror(errno));
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS); }

انظر أيضًا

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)

ملفات مصدر النواة تحت Documentation/security/keys/.

ترجمة

تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.

8 فبراير 2026 صفحات دليل لينكس 6.18