diff --git a/keyutils/__init__.py b/keyutils/__init__.py index 8b5e896..bd5d255 100644 --- a/keyutils/__init__.py +++ b/keyutils/__init__.py @@ -177,6 +177,10 @@ def move(key, from_ringid, to_ringid, flags=0): return _keyutils.move(key, from_ringid, to_ringid, flags) +def capabilities() -> bytes: + return _keyutils.capabilities() + + def describe_key(keyId): return _keyutils.describe_key(keyId) diff --git a/keyutils/_keyutils.pyx b/keyutils/_keyutils.pyx index 0ce7818..bcd9761 100644 --- a/keyutils/_keyutils.pyx +++ b/keyutils/_keyutils.pyx @@ -76,6 +76,18 @@ class constants: KEYCTL_MOVE_EXCL = ckeyutils.KEYCTL_MOVE_EXCL + KEYCTL_CAPS0_CAPABILITIES = ckeyutils.KEYCTL_CAPS0_CAPABILITIES + KEYCTL_CAPS0_PERSISTENT_KEYRINGS = ckeyutils.KEYCTL_CAPS0_PERSISTENT_KEYRINGS + KEYCTL_CAPS0_DIFFIE_HELLMAN = ckeyutils.KEYCTL_CAPS0_DIFFIE_HELLMAN + KEYCTL_CAPS0_PUBLIC_KEY = ckeyutils.KEYCTL_CAPS0_PUBLIC_KEY + KEYCTL_CAPS0_BIG_KEY = ckeyutils.KEYCTL_CAPS0_BIG_KEY + KEYCTL_CAPS0_INVALIDATE = ckeyutils.KEYCTL_CAPS0_INVALIDATE + KEYCTL_CAPS0_RESTRICT_KEYRING = ckeyutils.KEYCTL_CAPS0_RESTRICT_KEYRING + KEYCTL_CAPS0_MOVE = ckeyutils.KEYCTL_CAPS0_MOVE + # KEYCTL_CAPS1_NS_KEYRING_NAME = ckeyutils.KEYCTL_CAPS1_NS_KEYRING_NAME + # KEYCTL_CAPS1_NS_KEY_TAG = ckeyutils.KEYCTL_CAPS1_NS_KEY_TAG + # KEYCTL_CAPS1_NOTIFICATIONS = ckeyutils.KEYCTL_CAPS1_NOTIFICATIONS + def _throw_err(int rc): if rc < 0: PyErr_SetFromErrno(error) @@ -396,6 +408,19 @@ def move(int key, int from_ringid, int to_ringid, unsigned int flags): return None +def capabilities(): + cdef int rc + cdef int buflen = 4 + cdef unsigned char *buffer = stdlib.malloc(buflen) + cdef bytes obj + with nogil: + rc = ckeyutils.capabilities(buffer, buflen) + _throw_err(rc) + # TODO: check we aren't leaving buffer allocated + obj = PyBytes_FromStringAndSize( buffer, buflen) + return obj + + def describe_key(int key): cdef int size cdef char *ptr diff --git a/keyutils/ckeyutils.pxd b/keyutils/ckeyutils.pxd index d8af24b..83caf98 100644 --- a/keyutils/ckeyutils.pxd +++ b/keyutils/ckeyutils.pxd @@ -67,6 +67,19 @@ cdef extern from "keyutils.h" nogil: # keyctl_move flags int KEYCTL_MOVE_EXCL "KEYCTL_MOVE_EXCL" + # keyctl_capabilities output fields + int KEYCTL_CAPS0_CAPABILITIES "KEYCTL_CAPS0_CAPABILITIES" + int KEYCTL_CAPS0_PERSISTENT_KEYRINGS "KEYCTL_CAPS0_PERSISTENT_KEYRINGS" + int KEYCTL_CAPS0_DIFFIE_HELLMAN "KEYCTL_CAPS0_DIFFIE_HELLMAN" + int KEYCTL_CAPS0_PUBLIC_KEY "KEYCTL_CAPS0_PUBLIC_KEY" + int KEYCTL_CAPS0_BIG_KEY "KEYCTL_CAPS0_BIG_KEY" + int KEYCTL_CAPS0_INVALIDATE "KEYCTL_CAPS0_INVALIDATE" + int KEYCTL_CAPS0_RESTRICT_KEYRING "KEYCTL_CAPS0_RESTRICT_KEYRING" + int KEYCTL_CAPS0_MOVE "KEYCTL_CAPS0_MOVE" + # int KEYCTL_CAPS1_NS_KEYRING_NAME "KEYCTL_CAPS1_NS_KEYRING_NAME" + # int KEYCTL_CAPS1_NS_KEY_TAG "KEYCTL_CAPS1_NS_KEY_TAG" + # int KEYCTL_CAPS1_NOTIFICATIONS "KEYCTL_CAPS1_NOTIFICATIONS" + int add_key "add_key"(char *key_type, char *description, void *payload, int plen, int keyring) int request_key "request_key"(char *key_type, char *description, char *callout_info, int keyring) key_serial_t get_keyring_id "keyctl_get_keyring_ID"(key_serial_t key, int create) @@ -96,6 +109,7 @@ cdef extern from "keyutils.h" nogil: int pkey_sign "keyctl_pkey_sign"(key_serial_t key, const char* info, const void *data, size_t data_len, void *sig, size_t sig_len) int pkey_verify "keyctl_pkey_verify"(key_serial_t key, const char* info, const void *data, size_t data_len, void *sig, size_t sig_len) int move "keyctl_move"(key_serial_t key, key_serial_t from_ringid, key_serial_t to_ringid, unsigned int flags) + int capabilities "keyctl_capabilities"(unsigned char *buffer, size_t buflen) int describe_alloc "keyctl_describe_alloc"(int key, char **bufptr) int read_alloc "keyctl_read_alloc"(int key, void ** bufptr) int get_security_alloc "keyctl_get_security_alloc"(key_serial_t key, char **bufptr) diff --git a/test/keyutils_test.py b/test/keyutils_test.py index 2c15ede..25628bf 100644 --- a/test/keyutils_test.py +++ b/test/keyutils_test.py @@ -235,6 +235,11 @@ def test_move_exclusive(self, ring): keyutils.move(key, r_from, r_to, keyutils.KEYCTL_MOVE_EXCL) assert e.value.args[1] == 'File exists' + def test_capabilities(self): + caps = keyutils.capabilities() + assert caps + assert not caps.startswith(b'\x00') # the first byte will contain the results, and it should contain _something_ + def test_get_keyring_id(): keyring = keyutils.get_keyring_id(keyutils.KEY_SPEC_THREAD_KEYRING, False) assert keyring is not None and keyring != 0