[RFC,27/27] containers: Sample to grant access to a key in a container
diff mbox series

Message ID 155024713756.21651.13272811997083735868.stgit@warthog.procyon.org.uk
State New
Headers show
Series
  • Containers and using authenticated filesystems
Related show

Commit Message

David Howells Feb. 15, 2019, 4:12 p.m. UTC
Provide a sample program that will grant access to the specified key for a
container named "foo-test" (as created by the test-container sample) and
then link the key into the container keyring (either given on the command
line or searches for a keyring called "_container" in the session keyring
as placed there by the test-container sample).

So, for example, this could be used to place an rxrpc key in the container
keyring for kAFS inside the container to use:

 (1) Poke kerberos to get a ticket for accessing AFS.

	# kinit
	# aklog-kafs redhat.com

 (2) Find the rxrpc key ID:

	# keyctl show
	Session Keyring
	1071328996 --alswrv      0     0  keyring: _ses
	 574060623 ---lswrv      0 65534   \_ keyring: _uid.0
	1004048468 --alswrv      0     0   \_ rxrpc: afs@redhat.com
	 918328787 --alswrv      0     0   \_ keyring: upcall
	 996275498 --alswrv      0     0   \_ keyring: _container
	 785497401 --alswrv      0     0       \_ user: foobar

     which would be 1004048468 in this example.

 (3) Invoke the sample:

	# test-cont-grant 1004048468

     The rxrpc key can now be seen in the container keyring:

	# keyctl show
	Session Keyring
	1071328996 --alswrv      0     0  keyring: _ses
	 574060623 ---lswrv      0 65534   \_ keyring: _uid.0
	1004048468 --alswrv      0     0   \_ rxrpc: afs@redhat.com
	 918328787 --alswrv      0     0   \_ keyring: upcall
	 996275498 --alswrv      0     0   \_ keyring: _container
	 785497401 --alswrv      0     0       \_ user: foobar
	1004048468 --alswrv      0     0       \_ rxrpc: afs@redhat.com

 (4) Mount the kAFS filesystem inside the container:

	> mount -t afs "%redhat.com:root.cell" /mnt

The contents of /mnt can then be used from inside the container using the
key placed into the container keyring.

Signed-off-by: David Howells <dhowells@redhat.com>
---

 samples/vfs/Makefile          |    3 +
 samples/vfs/test-cont-grant.c |   84 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 87 insertions(+)
 create mode 100644 samples/vfs/test-cont-grant.c

Patch
diff mbox series

diff --git a/samples/vfs/Makefile b/samples/vfs/Makefile
index a8e9e1142ae3..c8eea193a856 100644
--- a/samples/vfs/Makefile
+++ b/samples/vfs/Makefile
@@ -6,6 +6,7 @@  hostprogs-$(CONFIG_SAMPLE_VFS) := \
 	test-mntinfo \
 	test-statx \
 	test-container \
+	test-cont-grant \
 	test-upcall
 
 # Tell kbuild to always build the programs
@@ -22,5 +23,7 @@  HOSTCFLAGS_test-statx.o += -I$(objtree)/usr/include
 
 HOSTCFLAGS_test-container.o += -I$(objtree)/usr/include
 HOSTLDLIBS_test-container += -lkeyutils
+HOSTCFLAGS_test-cont-grant.o += -I$(objtree)/usr/include
+HOSTLDLIBS_test-cont-grant += -lkeyutils
 HOSTCFLAGS_test-upcall.o += -I$(objtree)/usr/include
 HOSTLDLIBS_test-upcall += -lkeyutils
diff --git a/samples/vfs/test-cont-grant.c b/samples/vfs/test-cont-grant.c
new file mode 100644
index 000000000000..da4a60bc71fa
--- /dev/null
+++ b/samples/vfs/test-cont-grant.c
@@ -0,0 +1,84 @@ 
+/* Link a key into a container keyring and grant perms to the container.
+ *
+ * Copyright (C) 2019 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/wait.h>
+#include <linux/mount.h>
+#include <linux/unistd.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <keyutils.h>
+
+#define KEYCTL_GRANT_PERMISSION		36	/* Grant a permit to a key */
+
+enum key_ace_subject_type {
+	KEY_ACE_SUBJ_STANDARD	= 0,	/* subject is one of key_ace_standard_subject */
+	KEY_ACE_SUBJ_CONTAINER	= 1,	/* subject is a container fd */
+	KEY_ACE_SUBJ_CONTAINER_NAME = 2, /* subject is a container name pointer */
+};
+
+enum key_ace_standard_subject {
+	KEY_ACE_EVERYONE	= 0,	/* Everyone, including owner and group */
+	KEY_ACE_GROUP		= 1,	/* The key's group */
+	KEY_ACE_OWNER		= 2,	/* The owner of the key */
+	KEY_ACE_POSSESSOR	= 3,	/* Any process that possesses of the key */
+};
+
+#define KEY_ACE_VIEW		0x00000001 /* Can describe the key */
+#define KEY_ACE_READ		0x00000002 /* Can read the key content */
+#define KEY_ACE_WRITE		0x00000004 /* Can update/modify the key content */
+#define KEY_ACE_SEARCH		0x00000008 /* Can find the key by search */
+#define KEY_ACE_LINK		0x00000010 /* Can make a link to the key */
+#define KEY_ACE_SET_SECURITY	0x00000020 /* Can set owner, group, ACL */
+#define KEY_ACE_INVAL		0x00000040 /* Can invalidate the key */
+#define KEY_ACE_REVOKE		0x00000080 /* Can revoke the key */
+#define KEY_ACE_JOIN		0x00000100 /* Can join keyring */
+#define KEY_ACE_CLEAR		0x00000200 /* Can clear keyring */
+
+int main(int argc, char *argv[])
+{
+	key_serial_t key, keyring;
+
+	if (argc == 2) {
+		printf("Find keyring '_container'...\n");
+		keyring = keyctl_search(KEY_SPEC_SESSION_KEYRING, "keyring", "_container", 0);
+		if (keyring == -1) {
+			perror("keyctl_search");
+			exit(1);
+		}
+
+		key = atoi(argv[1]);
+	} else if (argc == 3) {
+		printf("Use specified keyring...\n");
+		keyring = atoi(argv[2]);
+		key = atoi(argv[1]);
+	} else {
+		fprintf(stderr, "Format: test-cont-grant <key> [<cont-keyring>]\n");
+		exit(2);
+	}
+
+	if (keyctl(KEYCTL_GRANT_PERMISSION, key,
+		   KEY_ACE_SUBJ_CONTAINER_NAME, "foo-test",
+		   KEY_ACE_SEARCH) < 0) {
+		perror("keyctl_grant/s");
+		exit(1);
+	}
+
+	if (keyctl_link(key, keyring) < 0) {
+		perror("keyctl_link");
+		exit(1);
+	}
+
+	exit(0);
+}