[prev in list] [next in list] [prev in thread] [next in thread] 

List:       rpm-cvs
Subject:    [CVS] RPM: rpm-5_4: rpm/tools/ rpmkey.c
From:       "Jeff Johnson" <jbj () rpm5 ! org>
Date:       2016-03-29 16:42:05
Message-ID: 20160329164205.6DFA05F011 () rpm5 ! org
[Download RAW message or body]

  RPM Package Manager, CVS Repository
  http://rpm5.org/cvs/
  ____________________________________________________________________________

  Server: rpm5.org                         Name:   Jeff Johnson
  Root:   /v/rpm/cvs                       Email:  jbj@rpm5.org
  Module: rpm                              Date:   29-Mar-2016 18:42:05
  Branch: rpm-5_4                          Handle: 2016032916420500

  Modified files:           (Branch: rpm-5_4)
    rpm/tools               rpmkey.c

  Log:
    - sanity.

  Summary:
    Revision    Changes     Path
    1.5.2.4     +455 -207   rpm/tools/rpmkey.c
  ____________________________________________________________________________

  patch -p0 <<'@@ .'
  Index: rpm/tools/rpmkey.c
  ============================================================================
  $ cvs diff -u -r1.5.2.3 -r1.5.2.4 rpmkey.c
  --- rpm/tools/rpmkey.c	2 May 2015 06:02:52 -0000	1.5.2.3
  +++ rpm/tools/rpmkey.c	29 Mar 2016 16:42:05 -0000	1.5.2.4
  @@ -4,7 +4,6 @@
   
   #include "system.h"
   
  -#include <rpmio.h>
   #include <poptIO.h>
   
   #include <keyutils.h>
  @@ -17,9 +16,14 @@
   static gid_t mygid, *mygroups;
   static int myngroups;
   
  +#ifdef	NOTYET
  +static int verbose;
  +#endif
  +
   /*
    * handle an error
    */
  +__attribute__ ((noreturn))
   static inline void rpmkeyError(const char *msg)
   {
       perror(msg);
  @@ -29,15 +33,16 @@
   /*
    * display command format information
    */
  +__attribute__ ((noreturn))
   static void rpmkeyFormat(void)
   {
   #ifdef	NOTYET
  -    const struct command *cmd;
  +    const struct poptOption *cmd;
   
       fprintf(stderr, "Format:\n");
   
  -    for (cmd = commands; cmd->action; cmd++)
  -	fprintf(stderr, "  keyctl %s %s\n", cmd->name, cmd->format);
  +    for (cmd = _rpmkeyCommandTable; cmd->longName; cmd++)
  +	fprintf(stderr, "  keyctl %s %s\n", cmd->longName, cmd->argDescrip);
   #endif
   
       fprintf(stderr, "\n");
  @@ -59,6 +64,34 @@
   }
   
   /*
  + * Load the groups list and grab the process's UID and GID.
  + */
  +static inline void grab_creds(void)
  +{
  +    static int inited;
  +
  +    if (inited)
  +	return;
  +    inited = 1;
  +
  +    /* grab my UID, GID and groups */
  +    myuid = geteuid();
  +    mygid = getegid();
  +    myngroups = getgroups(0, NULL);
  +
  +    if (myuid == (uid_t)-1 || mygid == (gid_t)-1 || myngroups == -1)
  +	rpmkeyError("Unable to get UID/GID/#Groups\n");
  +
  +    mygroups = calloc(myngroups, sizeof(gid_t));
  +    if (!mygroups)
  +	rpmkeyError("calloc");
  +
  +    myngroups = getgroups(myngroups, mygroups);
  +    if (myngroups < 0)
  +	rpmkeyError("Unable to get Groups\n");
  +}
  +
  +/*
    * convert the permissions mask to a string representing the permissions we
    * have actually been granted
    */
  @@ -68,6 +101,8 @@
       gid_t *pg;
       int loop;
   
  +    grab_creds();
  +
       perms = (perm & KEY_POS_ALL) >> 24;
   
       if (uid == myuid) {
  @@ -75,7 +110,7 @@
   	goto write_mask;
       }
   
  -    if (gid != (gid_t) - 1) {
  +    if (gid != (gid_t)-1) {
   	if (gid == mygid) {
   	    perms |= (perm & KEY_GRP_ALL) >> 8;
   	    goto write_mask;
  @@ -94,52 +129,38 @@
   
     write_mask:
       sprintf(pretty, "--%c%c%c%c%c%c",
  -	    perms & KEY_OTH_SETATTR ? 'a' : '-',
  -	    perms & KEY_OTH_LINK ? 'l' : '-',
  -	    perms & KEY_OTH_SEARCH ? 's' : '-',
  -	    perms & KEY_OTH_WRITE ? 'w' : '-',
  -	    perms & KEY_OTH_READ ? 'r' : '-',
  -	    perms & KEY_OTH_VIEW ? 'v' : '-');
  +	    (perms & KEY_OTH_SETATTR) ? 'a' : '-',
  +	    (perms & KEY_OTH_LINK) ? 'l' : '-',
  +	    (perms & KEY_OTH_SEARCH) ? 's' : '-',
  +	    (perms & KEY_OTH_WRITE) ? 'w' : '-',
  +	    (perms & KEY_OTH_READ) ? 'r' : '-',
  +	    (perms & KEY_OTH_VIEW) ? 'v' : '-');
   }
   
   /*
    * recursively display a key/keyring tree
    */
  -static int dump_key_tree_aux(key_serial_t key, int depth, int more)
  +static int dump_key_tree_aux(key_serial_t key, int depth, int more,
  +			     int hex_key_IDs)
   {
       static char dumpindent[64];
       key_serial_t *pk;
       key_perm_t perm;
  -    size_t ringlen, desclen;
  +    size_t ringlen;
       void *payload;
       char *desc, type[255], pretty_mask[9];
       int uid, gid, ret, n, dpos, rdepth, kcount = 0;
   
  -    if (depth > 8)
  +    if (depth > 8 * 4)
   	return 0;
   
  -    /* find out how big this key's description is */
  -    ret = keyctl_describe(key, NULL, 0);
  -    if (ret < 0) {
  -	printf("%d: key inaccessible (%m)\n", key);
  -	return 0;
  -    }
  -    desclen = ret + 1;
  -
  -    desc = xmalloc(desclen);
  -
       /* read the description */
  -    ret = keyctl_describe(key, desc, desclen);
  +    ret = keyctl_describe_alloc(key, &desc);
       if (ret < 0) {
   	printf("%d: key inaccessible (%m)\n", key);
  -	free(desc);
   	return 0;
       }
   
  -    desclen = (size_t) ret < desclen ? (size_t) ret : desclen;
  -
  -    desc[desclen] = 0;
  -
       /* parse */
       type[0] = 0;
       uid = 0;
  @@ -157,11 +178,20 @@
       /* and print */
       calc_perms(pretty_mask, perm, uid, gid);
   
  -    printf("%9d %s  %5d %5d  %s%s%s: %s\n",
  -	   key,
  -	   pretty_mask,
  -	   uid, gid,
  -	   dumpindent, depth > 0 ? "\\_ " : "", type, desc + dpos);
  +    if (hex_key_IDs)
  +	printf("0x%08x %s  %5d %5d  %s%s%s: %s\n",
  +	       key,
  +	       pretty_mask,
  +	       uid, gid,
  +	       dumpindent, depth > 0 ? "\\_ " : "", type, desc + dpos);
  +    else
  +	printf("%10d %s  %5d %5d  %s%s%s: %s\n",
  +	       key,
  +	       pretty_mask,
  +	       uid, gid,
  +	       dumpindent, depth > 0 ? "\\_ " : "", type, desc + dpos);
  +
  +    free(desc);
   
       /* if it's a keyring then we're going to want to recursively
        * display it if we can */
  @@ -176,6 +206,8 @@
   
   	/* read its contents */
   	payload = xmalloc(ringlen);
  +	if (!payload)
  +	    rpmkeyError("malloc");
   
   	ret = keyctl_read(key, payload, ringlen);
   	if (ret < 0)
  @@ -210,7 +242,8 @@
   		kcount += dump_key_tree_aux(key,
   					    rdepth,
   					    ringlen - 4 >=
  -					    sizeof(key_serial_t));
  +					    sizeof(key_serial_t),
  +					    hex_key_IDs);
   	    }
   
   	} while (ringlen -= 4, ringlen >= sizeof(key_serial_t));
  @@ -218,23 +251,28 @@
   	free(payload);
       }
   
  -    free(desc);
       return kcount;
   }
   
   /*
    * recursively list a keyring's contents
    */
  -static int dump_key_tree(key_serial_t keyring, const char *name)
  +static int dump_key_tree(key_serial_t keyring, const char *name,
  +			 int hex_key_IDs)
   {
       printf("%s\n", name);
  -    return dump_key_tree_aux(keyring, 0, 0);
  +
  +    keyring = keyctl_get_keyring_ID(keyring, 0);
  +    if (keyring == -1)
  +	rpmkeyError("Unable to dump key");
  +
  +    return dump_key_tree_aux(keyring, 0, 0, hex_key_IDs);
   }
   
   /*
    * parse a key identifier
    */
  -static key_serial_t get_key_id(const char *arg)
  +static key_serial_t get_key_id(char *arg)
   {
       key_serial_t id;
       char *end;
  @@ -260,6 +298,36 @@
   	exit(2);
       }
   
  +    /* handle a lookup-by-name request "%<type>:<desc>", eg: "%keyring:_ses" */
  +    if (arg[0] == '%') {
  +	char *type;
  +
  +	arg++;
  +	if (!*arg)
  +	    goto incorrect_key_by_name_spec;
  +
  +	if (*arg == ':') {
  +	    type = "keyring";
  +	    arg++;
  +	} else {
  +	    type = arg;
  +	    arg = strchr(arg, ':');
  +	    if (!arg)
  +		goto incorrect_key_by_name_spec;
  +	    *(arg++) = '\0';
  +	}
  +
  +	if (!*arg)
  +	    goto incorrect_key_by_name_spec;
  +
  +	id = find_key_by_type_and_desc(type, arg, 0);
  +	if (id == -1) {
  +	    fprintf(stderr, "Can't find '%s:%s'\n", type, arg);
  +	    exit(1);
  +	}
  +	return id;
  +    }
  +
       /* handle a numeric key ID */
       id = strtoul(arg, &end, 0);
       if (*end) {
  @@ -268,14 +336,18 @@
       }
   
       return id;
  +
  +  incorrect_key_by_name_spec:
  +    fprintf(stderr, "Incorrect key-by-name spec\n");
  +    exit(2);
   }
   
   /*
    * grab data from stdin
    */
  -static char *grab_stdin(void)
  +static char *grab_stdin(size_t * _size)
   {
  -    static char input[65536 + 1];
  +    static char input[1024 * 1024 + 1];
       size_t n;
       int tmp;
   
  @@ -298,19 +370,43 @@
       }
   
       input[n] = '\0';
  +    *_size = n;
   
       return input;
   }
   
   /*
  + * Display version information
  + */
  +static int rpmkeyVersion(int argc, char *argv[])
  +{
  +    printf("keyctl from %s (Built %s)\n",
  +	   keyutils_version_string, keyutils_build_string);
  +    return 0;
  +}
  +
  +/*
    * show the parent process's session keyring
    */
   static int rpmkeyShow(int argc, char *argv[])
   {
  -    if (argc != 1)
  +    key_serial_t keyring = KEY_SPEC_SESSION_KEYRING;
  +    int hex_key_IDs = 0;
  +
  +    if (argc >= 2 && strcmp(argv[1], "-x") == 0) {
  +	hex_key_IDs = 1;
  +	argc--;
  +	argv++;
  +    }
  +
  +    if (argc > 2)
   	rpmkeyFormat();
   
  -    dump_key_tree(KEY_SPEC_SESSION_KEYRING, "Session Keyring");
  +    if (argc == 2)
  +	keyring = get_key_id(argv[1]);
  +
  +    dump_key_tree(keyring, argc == 2 ? "Keyring" : "Session Keyring",
  +		  hex_key_IDs);
       return 0;
   }
   
  @@ -341,19 +437,26 @@
    */
   static int rpmkeyPAdd(int argc, char *argv[])
   {
  -    char *args[6];
  +    key_serial_t dest;
  +    size_t datalen;
  +    void *data;
  +    int ret;
  +
   
       if (argc != 4)
   	rpmkeyFormat();
   
  -    args[0] = argv[0];
  -    args[1] = argv[1];
  -    args[2] = argv[2];
  -    args[3] = grab_stdin();
  -    args[4] = argv[3];
  -    args[5] = NULL;
  +    dest = get_key_id(argv[3]);
  +
  +    data = grab_stdin(&datalen);
   
  -    return rpmkeyAdd(5, args);
  +    ret = add_key(argv[1], argv[2], data, datalen, dest);
  +    if (ret < 0)
  +	rpmkeyError("add_key");
  +
  +    /* print the resulting key ID */
  +    printf("%d\n", ret);
  +    return 0;
   }
   
   /*
  @@ -411,6 +514,7 @@
   static int rpmkeyPRequest2(int argc, char *argv[])
   {
       char *args[6];
  +    size_t datalen;
   
       if (argc != 3 && argc != 4)
   	rpmkeyFormat();
  @@ -418,7 +522,7 @@
       args[0] = argv[0];
       args[1] = argv[1];
       args[2] = argv[2];
  -    args[3] = grab_stdin();
  +    args[3] = grab_stdin(&datalen);
       args[4] = argv[3];
       args[5] = NULL;
   
  @@ -448,17 +552,20 @@
    */
   static int rpmkeyPUpdate(int argc, char *argv[])
   {
  -    char *args[4];
  +    key_serial_t key;
  +    size_t datalen;
  +    void *data;
   
       if (argc != 2)
   	rpmkeyFormat();
   
  -    args[0] = argv[0];
  -    args[1] = argv[1];
  -    args[2] = grab_stdin();
  -    args[3] = NULL;
  +    key = get_key_id(argv[1]);
  +    data = grab_stdin(&datalen);
  +
  +    if (keyctl_update(key, data, datalen) < 0)
  +	rpmkeyError("keyctl_update");
   
  -    return rpmkeyUpdate(3, args);
  +    return 0;
   }
   
   /*
  @@ -538,20 +645,39 @@
   }
   
   /*
  - * unlink a key from a keyrign
  + * Attempt to unlink a key matching the ID
  + */
  +static int rpmkeyUnlink_func(key_serial_t parent, key_serial_t key,
  +				  char *desc, int desc_len, void *data)
  +{
  +    key_serial_t *target = data;
  +
  +    if (key == *target)
  +	return keyctl_unlink(key, parent) < 0 ? 0 : 1;
  +    return 0;
  +}
  +
  +/*
  + * Unlink a key from a keyring or from the session keyring tree.
    */
   static int rpmkeyUnlink(int argc, char *argv[])
   {
       key_serial_t keyring, key;
  +    int n;
   
  -    if (argc != 3)
  +    if (argc != 2 && argc != 3)
   	rpmkeyFormat();
   
       key = get_key_id(argv[1]);
  -    keyring = get_key_id(argv[2]);
   
  -    if (keyctl_unlink(key, keyring) < 0)
  -	rpmkeyError("keyctl_unlink");
  +    if (argc == 3) {
  +	keyring = get_key_id(argv[2]);
  +	if (keyctl_unlink(key, keyring) < 0)
  +	    rpmkeyError("keyctl_unlink");
  +    } else {
  +	n = recursive_session_key_scan(rpmkeyUnlink_func, &key);
  +	printf("%d links removed\n", n);
  +    }
   
       return 0;
   }
  @@ -608,7 +734,7 @@
       }
   
       /* hexdump the contents */
  -    printf("%u bytes of data in key:\n", ret);
  +    printf("%u bytes of data in key:\n", (unsigned)ret);
   
       sep = 0;
       col = 0;
  @@ -733,7 +859,7 @@
       if (count == 1)
   	printf("1 key in keyring:\n");
       else
  -	printf("%u keys in keyring:\n", count);
  +	printf("%u keys in keyring:\n", (unsigned)count);
   
       pk = keylist;
       do {
  @@ -851,33 +977,33 @@
   	   " %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c"
   	   " %5d %5d %*.*s: %s\n",
   	   key,
  -	   perm & KEY_POS_SETATTR ? 'a' : '-',
  -	   perm & KEY_POS_LINK ? 'l' : '-',
  -	   perm & KEY_POS_SEARCH ? 's' : '-',
  -	   perm & KEY_POS_WRITE ? 'w' : '-',
  -	   perm & KEY_POS_READ ? 'r' : '-',
  -	   perm & KEY_POS_VIEW ? 'v' : '-',
  -
  -	   perm & KEY_USR_SETATTR ? 'a' : '-',
  -	   perm & KEY_USR_LINK ? 'l' : '-',
  -	   perm & KEY_USR_SEARCH ? 's' : '-',
  -	   perm & KEY_USR_WRITE ? 'w' : '-',
  -	   perm & KEY_USR_READ ? 'r' : '-',
  -	   perm & KEY_USR_VIEW ? 'v' : '-',
  -
  -	   perm & KEY_GRP_SETATTR ? 'a' : '-',
  -	   perm & KEY_GRP_LINK ? 'l' : '-',
  -	   perm & KEY_GRP_SEARCH ? 's' : '-',
  -	   perm & KEY_GRP_WRITE ? 'w' : '-',
  -	   perm & KEY_GRP_READ ? 'r' : '-',
  -	   perm & KEY_GRP_VIEW ? 'v' : '-',
  -
  -	   perm & KEY_OTH_SETATTR ? 'a' : '-',
  -	   perm & KEY_OTH_LINK ? 'l' : '-',
  -	   perm & KEY_OTH_SEARCH ? 's' : '-',
  -	   perm & KEY_OTH_WRITE ? 'w' : '-',
  -	   perm & KEY_OTH_READ ? 'r' : '-',
  -	   perm & KEY_OTH_VIEW ? 'v' : '-',
  +	   (perm & KEY_POS_SETATTR) ? 'a' : '-',
  +	   (perm & KEY_POS_LINK) ? 'l' : '-',
  +	   (perm & KEY_POS_SEARCH) ? 's' : '-',
  +	   (perm & KEY_POS_WRITE) ? 'w' : '-',
  +	   (perm & KEY_POS_READ) ? 'r' : '-',
  +	   (perm & KEY_POS_VIEW) ? 'v' : '-',
  +
  +	   (perm & KEY_USR_SETATTR) ? 'a' : '-',
  +	   (perm & KEY_USR_LINK) ? 'l' : '-',
  +	   (perm & KEY_USR_SEARCH) ? 's' : '-',
  +	   (perm & KEY_USR_WRITE) ? 'w' : '-',
  +	   (perm & KEY_USR_READ) ? 'r' : '-',
  +	   (perm & KEY_USR_VIEW) ? 'v' : '-',
  +
  +	   (perm & KEY_GRP_SETATTR) ? 'a' : '-',
  +	   (perm & KEY_GRP_LINK) ? 'l' : '-',
  +	   (perm & KEY_GRP_SEARCH) ? 's' : '-',
  +	   (perm & KEY_GRP_WRITE) ? 'w' : '-',
  +	   (perm & KEY_GRP_READ) ? 'r' : '-',
  +	   (perm & KEY_GRP_VIEW) ? 'v' : '-',
  +
  +	   (perm & KEY_OTH_SETATTR) ? 'a' : '-',
  +	   (perm & KEY_OTH_LINK) ? 'l' : '-',
  +	   (perm & KEY_OTH_SEARCH) ? 's' : '-',
  +	   (perm & KEY_OTH_WRITE) ? 'w' : '-',
  +	   (perm & KEY_OTH_READ) ? 'r' : '-',
  +	   (perm & KEY_OTH_VIEW) ? 'v' : '-',
   	   uid, gid, tlen, tlen, buffer, buffer + dpos);
   
       return 0;
  @@ -1037,7 +1163,7 @@
       execvp(argv[0], argv);
       rpmkeyError(argv[0]);
   
  -    /*@notreached@ */
  +    /*@notreached@*/
       return -1;
   }
   
  @@ -1065,18 +1191,21 @@
    */
   static int rpmkeyPInstantiate(int argc, char *argv[])
   {
  -    char *args[5];
  +    key_serial_t key, dest;
  +    size_t datalen;
  +    void *data;
   
       if (argc != 3)
   	rpmkeyFormat();
   
  -    args[0] = argv[0];
  -    args[1] = argv[1];
  -    args[2] = grab_stdin();
  -    args[3] = argv[2];
  -    args[4] = NULL;
  +    key = get_key_id(argv[1]);
  +    dest = get_key_id(argv[2]);
  +    data = grab_stdin(&datalen);
  +
  +    if (keyctl_instantiate(key, data, datalen, dest) < 0)
  +	rpmkeyError("keyctl_instantiate");
   
  -    return rpmkeyInstantiate(4, args);
  +    return 0;
   }
   
   /*
  @@ -1270,19 +1399,19 @@
   }
   
   struct purge_data {
  -    const char	*type;
  -    const char	*desc;
  -    size_t	desc_len;
  -    size_t	type_len;
  -    char	prefix_match;
  -    char	case_indep;
  +    const char *type;
  +    const char *desc;
  +    size_t desc_len;
  +    size_t type_len;
  +    char prefix_match;
  +    char case_indep;
   };
   
   /*
    * Attempt to unlink a key matching the type
    */
   static int rpmkeyPurge_type_func(key_serial_t parent, key_serial_t key,
  -				      char *raw, int raw_len, void *data)
  +				char *raw, int raw_len, void *data)
   {
       const struct purge_data *purge = data;
       char *p, *type;
  @@ -1306,7 +1435,7 @@
    * Attempt to unlink a key matching the type and description literally
    */
   static int rpmkeyPurge_literal_func(key_serial_t parent, key_serial_t key,
  -					 char *raw, int raw_len, void *data)
  +				char *raw, int raw_len, void *data)
   {
       const struct purge_data *purge = data;
       size_t tlen;
  @@ -1350,7 +1479,7 @@
   	    return 0;
       }
   
  -    printf("%*.*s '%s'\n", (int)tlen, (int)tlen, type, desc);
  +    printf("%*.*s '%s'\n", (int) tlen, (int) tlen, type, desc);
   
       return keyctl_unlink(key, parent) < 0 ? 0 : 1;
   }
  @@ -1359,7 +1488,7 @@
    * Attempt to unlink a key matching the type and description literally
    */
   static int rpmkeyPurge_search_func(key_serial_t parent, key_serial_t keyring,
  -					char *raw, int raw_len, void *data)
  +				char *raw, int raw_len, void *data)
   {
       const struct purge_data *purge = data;
       key_serial_t key;
  @@ -1384,8 +1513,8 @@
   {
       recursive_key_scanner_t func;
       struct purge_data purge = {
  -	.prefix_match	= 0,
  -	.case_indep	= 0,
  +	.prefix_match = 0,
  +	.case_indep = 0,
       };
       int n = 0, search_mode = 0;
   
  @@ -1407,10 +1536,10 @@
       if (argc < 1)
   	rpmkeyFormat();
   
  -    purge.type	= argv[0];
  -    purge.desc	= argv[1];
  -    purge.type_len	= strlen(purge.type);
  -    purge.desc_len	= purge.desc ? strlen(purge.desc) : 0;
  +    purge.type = argv[0];
  +    purge.desc = argv[1];
  +    purge.type_len = strlen(purge.type);
  +    purge.desc_len = purge.desc ? strlen(purge.desc) : 0;
   
       if (search_mode == 1) {
   	if (argc != 2 || purge.prefix_match || purge.case_indep)
  @@ -1437,79 +1566,159 @@
   }
   #endif	/* REFERENCE */
   
  +/*
  + * Invalidate a key
  + */
  +static int rpmkeyInvalidate(int argc, char *argv[])
  +{
  +    key_serial_t key;
  +
  +    if (argc != 2)
  +	rpmkeyFormat();
  +
  +    key = get_key_id(argv[1]);
  +
  +    if (keyctl_invalidate(key) < 0)
  +	rpmkeyError("keyctl_invalidate");
  +
  +    return 0;
  +}
  +
  +/*
  + * Get the per-UID persistent keyring
  + */
  +static int rpmkeyGetPersistent(int argc, char *argv[])
  +{
  +    key_serial_t dest, ret;
  +    uid_t uid = -1;
  +    char *q;
  +
  +    if (argc != 2 && argc != 3)
  +	rpmkeyFormat();
  +
  +    dest = get_key_id(argv[1]);
  +
  +    if (argc > 2) {
  +	uid = strtoul(argv[2], &q, 0);
  +	if (*q) {
  +	    fprintf(stderr, "Unparsable uid: '%s'\n", argv[2]);
  +	    exit(2);
  +	}
  +    }
  +
  +    ret = keyctl_get_persistent(uid, dest);
  +    if (ret < 0)
  +	rpmkeyError("keyctl_get_persistent");
  +
  +    /* print the resulting key ID */
  +    printf("%d\n", ret);
  +    return 0;
  +}
  +
   /*==============================================================*/
   
  -static struct poptOption optionsTable[] = {
  +#define	ARGMINMAX(_min, _max)	(int)(((_min) << 8) | ((_max) & 0xff))
  +
  +struct poptOption _rpmkeyCommandTable[] = {
     { "debug", 'd', POPT_ARG_VAL | POPT_ARGFLAG_DOC_HIDDEN, &_debug, 1,
        NULL, NULL},
   
  -  { "add", '\0', POPT_ARG_MAINCALL, rpmkeyAdd, 0,
  -     N_("Add a key to a keyring"), N_("<type> <desc> <data> <keyring>")},
  -  { "chgrp", '\0', POPT_ARG_MAINCALL, rpmkeyChgrp, 0,
  -     N_("Change the access controls on a key"), N_("<key> <gid>")},
  -  { "chown", '\0', POPT_ARG_MAINCALL, rpmkeyChown, 0,
  -     N_("Change the access controls on a key"), N_("<key> <uid>")},
  -  { "clear", '\0', POPT_ARG_MAINCALL, rpmkeyClear, 0,
  -     N_("Clear a keyring"), N_("<keyring>")},
  -  { "describe", '\0', POPT_ARG_MAINCALL, rpmkeyDescribe, 0,
  -     N_("Describe a key"), N_("<keyring>")},
  -  { "instantiate", '\0', POPT_ARG_MAINCALL, rpmkeyInstantiate, 0,
  -     N_("Instantiate a key"), N_("<key> <data> <keyring>")},
  -  { "link", '\0', POPT_ARG_MAINCALL, rpmkeyLink, 0,
  -     N_("Link a key to a keyring"), N_("<key> <keyring>")},
  -  { "list", '\0', POPT_ARG_MAINCALL, rpmkeyList, 0,
  -     N_("List a keyring"), N_("<keyring>")},
  -  { "negate", '\0', POPT_ARG_MAINCALL, rpmkeyNegate, 0,
  -     N_("Instantiate a key"), N_("<key> <timeout> <keyring>")},
  -  { "new_session", '\0', POPT_ARG_MAINCALL, rpmkeyNewSession, 0,
  -     N_("Install a new session keyring"), N_("<key>")},
  -  { "newring", '\0', POPT_ARG_MAINCALL, rpmkeyNewring, 0,
  -     N_("Create a keyring"), N_("<name> <keyring>")},
  -  { "padd", '\0', POPT_ARG_MAINCALL, rpmkeyPAdd, 0,
  -     N_("Add a key to a keyring"), N_("<type> <desc> <keyring>")},
  -  { "pinstantiate", '\0', POPT_ARG_MAINCALL, rpmkeyPInstantiate, 0,
  -     N_("Instantiate a key"), N_("<key> <keyring>")},
  -  { "pipe", '\0', POPT_ARG_MAINCALL, rpmkeyPipe, 0,
  -     N_("Read a key"), N_("<key>")},
  -  { "prequest2", '\0', POPT_ARG_MAINCALL, rpmkeyPRequest2, 0,
  -     N_("Request a key"), N_("<type> <desc> [<dest_keyring>]")},
  -  { "print", '\0', POPT_ARG_MAINCALL, rpmkeyPrint, 0,
  -     N_("Read a key"), N_("<key>")},
  -  { "pupdate", '\0', POPT_ARG_MAINCALL, rpmkeyPUpdate, 0,
  -     N_("Update a key"), N_("<key>")},
  -/* XXX purge */
  -  { "rdescribe", '\0', POPT_ARG_MAINCALL, rpmkeyRDescribe, 0,
  -     N_("Describe a key"), N_("<keyring> [sep]")},
  -  { "read", '\0', POPT_ARG_MAINCALL, rpmkeyRead, 0,
  -     N_("Read a key"), N_("<key>")},
  -/* XXX reap */
  -/* XXX reject */
  -  { "request", '\0', POPT_ARG_MAINCALL, rpmkeyRequest, 0,
  -     N_("Request a key"), N_("<type> <desc> [<dest_keyring>]")},
  -  { "request2", '\0', POPT_ARG_MAINCALL, rpmkeyRequest2, 0,
  -     N_("Request a key"), N_("<type> <desc> <info> [<dest_keyring>]")},
  -  { "revoke", '\0', POPT_ARG_MAINCALL, rpmkeyRevoke, 0,
  -     N_("Revoke a key"), N_("<key>")},
  -  { "rlist", '\0', POPT_ARG_MAINCALL, rpmkeyRList, 0,
  -     N_("List a keyring"), N_("<keyring>")},
  -  { "search", '\0', POPT_ARG_MAINCALL, rpmkeySearch, 0,
  -     N_("Search a keyring"),
  -     N_("<keyring> <type> <desc> [<dest_keyring>]")},
  -  { "security", '\0', POPT_ARG_MAINCALL, rpmkeySecurity, 0,
  -     N_("Retrieve a key's security context"), N_("<key>")},
  -  { "session", '\0', POPT_ARG_MAINCALL, rpmkeySession, 0,
  -     N_("Start a new session with fresh keyrings"),
  -     N_("[{-|<name>} [<prog> <arg1> <arg2> ...]]")},
  -  { "setperm", '\0', POPT_ARG_MAINCALL, rpmkeySetperm, 0,
  -     N_("Set the permissions mask on a key"), N_("<key> <mask>")},
  -  { "show", '\0', POPT_ARG_MAINCALL, rpmkeyShow, 0,
  -     N_("Show process keyrings"), NULL},
  -  { "timeout", '\0', POPT_ARG_MAINCALL, rpmkeyTimeout, 0,
  -     N_("Set the expiry time on a key"), N_("<key> <timeout>")},
  -  { "unlink", '\0', POPT_ARG_MAINCALL, rpmkeyUnlink, 0,
  -     N_("Unlink a key from a keyring"), N_("<key> <keyring>")},
  -  { "update", '\0', POPT_ARG_MAINCALL, rpmkeyUpdate, 0,
  -     N_("Update a key"), N_("<key> <data>")},
  +  { "add", '\0', POPT_ARG_MAINCALL,	rpmkeyAdd, ARGMINMAX(5, 5),
  +     N_("Add key to <kr>"), N_("<type> <desc> <data> <kr>") },
  +  { "chgrp", '\0', POPT_ARG_MAINCALL,	rpmkeyChgrp, ARGMINMAX(3, 3),
  +     N_("Change <gid> on <key>"), N_("<key> <gid>") },
  +  { "chown", '\0', POPT_ARG_MAINCALL,	rpmkeyChown, ARGMINMAX(3, 3),
  +     N_("Change <uid> on <key>"), N_("<key> <uid>") },
  +  { "clear", '\0', POPT_ARG_MAINCALL,	rpmkeyClear, ARGMINMAX(2, 2),
  +     N_("Clear <kr>"), N_("<kr>") },
  +  { "describe", '\0', POPT_ARG_MAINCALL,	rpmkeyDescribe, ARGMINMAX(2, 2),
  +     N_("Describe <kr>"), N_("<kr>") },
  +  { "instantiate", '\0', POPT_ARG_MAINCALL,	rpmkeyInstantiate, ARGMINMAX(4, 4),
  +     N_("Instantiate <key> in <kr>"), N_("<key> <data> <kr>") },
  +  { "invalidate", '\0', POPT_ARG_MAINCALL,	rpmkeyInvalidate, ARGMINMAX(2, 2),
  +     N_("Invalidate <key>"), N_("<key>") },
  +  { "get_persistent", '\0', POPT_ARG_MAINCALL,	rpmkeyGetPersistent, ARGMINMAX(2, 3),
  +     N_("Get a persistent <kr>"), N_("<kr> [<uid>]") },
  +  { "link", '\0', POPT_ARG_MAINCALL,	rpmkeyLink, ARGMINMAX(3, 3),
  +     N_("Link <key> into <kr>"), N_("<key> <kr>") },
  +  { "list", '\0', POPT_ARG_MAINCALL,	rpmkeyList, ARGMINMAX(2, 2),
  +     N_("List <kr>"), N_("<kr>") },
  +  { "negate", '\0', POPT_ARG_MAINCALL,	rpmkeyNegate, ARGMINMAX(4, 4),
  +     N_("Negate <key> in <kr>"), N_("<key> <timeout> <kr>") },
  +  { "new_session", '\0', POPT_ARG_MAINCALL,	rpmkeyNewSession, ARGMINMAX(1, 1),
  +     N_("Install new session <kr>"), NULL },
  +  { "newring", '\0', POPT_ARG_MAINCALL,	rpmkeyNewring, ARGMINMAX(3, 3),
  +     N_("Create <kr>"), N_("<name> <kr>") },
  +  { "padd", '\0', POPT_ARG_MAINCALL,	rpmkeyPAdd, ARGMINMAX(4, 4),
  +     N_("Add key to <kr>"), N_("<type> <desc> <kr>") },
  +  { "pinstantiate", '\0', POPT_ARG_MAINCALL,	rpmkeyPInstantiate, ARGMINMAX(3, 3),
  +     N_("Instantiate <key> in <kr>"), N_("<key> <kr>") },
  +  { "pipe", '\0', POPT_ARG_MAINCALL,	rpmkeyPipe, ARGMINMAX(2, 2),
  +     N_("Read <key>"), N_("<key>") },
  +  { "prequest2", '\0', POPT_ARG_MAINCALL,	rpmkeyPRequest2, ARGMINMAX(3, 4),
  +     N_("Request <key>"), N_("<type> <desc> [<destkr>]") },
  +  { "print", '\0', POPT_ARG_MAINCALL,	rpmkeyPrint, ARGMINMAX(2, 2),
  +     N_("Print <key>"), N_("<key>") },
  +  { "pupdate", '\0', POPT_ARG_MAINCALL,	rpmkeyPUpdate, ARGMINMAX(2, 2),
  +     N_("Update <key>"), N_("<key>") },
  +#ifdef	NOTYET
  +	/* XXX FIXME: variable args and flags */
  +  { "purge", '\0', POPT_ARG_MAINCALL,	rpmkeyPurge, ARGMINMAX(0, 0),
  +     N_("Purge all keys of <type>"), N_("<type>") },
  +	/* XXX FIXME: variable args and flags */
  +  { "purge", '\0', POPT_ARG_MAINCALL,	NULL, ARGMINMAX(0, 0),
  +     N_(" Purge <key>"), N_("[-p] [-i] <type> <desc>") },
  +	/* XXX FIXME: variable args and flags */
  +  { "purge", '\0', POPT_ARG_MAINCALL,	NULL, ARGMINMAX(0, 0),
  +     N_("Purge <key>"), N_("-s <type> <desc>") },
  +#endif
  +  { "rdescribe", '\0', POPT_ARG_MAINCALL,	rpmkeyRDescribe, ARGMINMAX(2, 3),
  +     N_("Describe <kr>"), N_("<kr> [sep]") },
  +  { "read", '\0', POPT_ARG_MAINCALL,	rpmkeyRead, ARGMINMAX(2, 2),
  +     N_("Read <key>"), N_("<key>") },
  +#ifdef	NOTYET
  +  { "reap", '\0', POPT_ARG_MAINCALL,	rpmkeyReap, ARGMINMAX(1, 2),
  +     N_("Reap"), N_("[-v]") },
  +  { "reject", '\0', POPT_ARG_MAINCALL,	rpmkeyReject, ARGMINMAX(5, 5),
  +     N_("Reject"), N_("<key> <timeout> <error> <kr>") },
  +#endif
  +  { "request", '\0', POPT_ARG_MAINCALL,	rpmkeyRequest, ARGMINMAX(3, 4),
  +     N_("Request key"), N_("<type> <desc> [<destkr>]") },
  +  { "request2", '\0', POPT_ARG_MAINCALL,	rpmkeyRequest2, ARGMINMAX(0, 0),
  +     N_("Request <key>"), N_("<type> <desc> <info> [<destkr>]") },
  +  { "revoke", '\0', POPT_ARG_MAINCALL,	rpmkeyRevoke, ARGMINMAX(4, 5),
  +     N_("Revoke <key>"), N_("<key>") },
  +  { "rlist", '\0', POPT_ARG_MAINCALL,	rpmkeyRList, ARGMINMAX(2, 2),
  +     N_("List <kr>"), N_("<kr>") },
  +  { "search", '\0', POPT_ARG_MAINCALL,	rpmkeySearch, ARGMINMAX(4, 5),
  +     N_("Search <kr>"), N_("<kr> <type> <desc> [<destkr>]") },
  +  { "security", '\0', POPT_ARG_MAINCALL,	rpmkeySecurity, ARGMINMAX(2, 2),
  +     N_("Retrieve <key> security"), N_("<key>") },
  +	/* XXX FIXME: variable args and flags */
  +  { "session", '\0', POPT_ARG_MAINCALL,	rpmkeySession, ARGMINMAX(0, 0),
  +     N_("Start new session"), NULL },
  +#ifdef	NOTYET
  +	/* XXX FIXME: variable args and flags */
  +  { "session", '\0', POPT_ARG_MAINCALL,	NULL, ARGMINMAX(0, 0),
  +     N_("Start new session"),
  +     N_("- [<prog> <arg1> <arg2> ...]") },
  +	/* XXX FIXME: variable args and flags */
  +  { "session", '\0', POPT_ARG_MAINCALL,	NULL, ARGMINMAX(0, 0),
  +     N_("Start new session"),
  +     N_("<name> [<prog> <arg1> <arg2> ...]") },
  +#endif
  +  { "setperm", '\0', POPT_ARG_MAINCALL,	rpmkeySetperm, ARGMINMAX(3, 3),
  +     N_("Set <mask> on <kr>"), N_("<key> <mask>") },
  +  { "show", '\0', POPT_ARG_MAINCALL,	rpmkeyShow, ARGMINMAX(1, 3),
  +     N_("Show process <kr>"), N_("[-x] [<kr>]") },
  +  { "timeout", '\0', POPT_ARG_MAINCALL,	rpmkeyTimeout, ARGMINMAX(3, 3),
  +     N_("Set <timeout> on <key>"), N_("<key> <timeout>") },
  +  { "unlink", '\0', POPT_ARG_MAINCALL,	rpmkeyUnlink, ARGMINMAX(2, 3),
  +     N_("Unlink <key> from <kr>"), N_("<key> [<kr>]") },
  +  { "update", '\0', POPT_ARG_MAINCALL,	rpmkeyUpdate, ARGMINMAX(3, 3),
  +     N_("Update <key> with <data>"), N_("<key> <data>") },
  +  { "version", '\0', POPT_ARG_MAINCALL,	rpmkeyVersion, ARGMINMAX(1, 1),
  +     N_("Display keyutils version"), NULL },
   
    { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmioAllPoptTable, 0,
   	N_("Common options for all rpmio executables:"),
  @@ -1519,14 +1728,17 @@
       POPT_AUTOHELP
   
     { NULL, (char) -1, POPT_ARG_INCLUDE_TABLE, NULL, 0,
  -        N_("\
  +	N_("\
   Format:\n\
  +  keyctl --version \n\
     keyctl add <type> <desc> <data> <keyring>\n\
     keyctl chgrp <key> <gid>\n\
     keyctl chown <key> <uid>\n\
     keyctl clear <keyring>\n\
     keyctl describe <keyring>\n\
     keyctl instantiate <key> <data> <keyring>\n\
  +  keyctl invalidate <key>\n\
  +  keyctl get_persistent <keyring> [<uid>]\n\
     keyctl link <key> <keyring>\n\
     keyctl list <keyring>\n\
     keyctl negate <key> <timeout> <keyring>\n\
  @@ -1538,8 +1750,13 @@
     keyctl prequest2 <type> <desc> [<dest_keyring>]\n\
     keyctl print <key>\n\
     keyctl pupdate <key>\n\
  +  keyctl purge <type>\n\
  +  keyctl purge [-p] [-i] <type> <desc>\n\
  +  keyctl purge -s <type> <desc>\n\
     keyctl rdescribe <keyring> [sep]\n\
     keyctl read <key>\n\
  +  keyctl reap [-v]\n\
  +  keyctl reject <key> <timeout> <error> <keyring>\n\
     keyctl request <type> <desc> [<dest_keyring>]\n\
     keyctl request2 <type> <desc> <info> [<dest_keyring>]\n\
     keyctl revoke <key>\n\
  @@ -1550,9 +1767,9 @@
     keyctl session - [<prog> <arg1> <arg2> ...]\n\
     keyctl session <name> [<prog> <arg1> <arg2> ...]\n\
     keyctl setperm <key> <mask>\n\
  -  keyctl show \n\
  +  keyctl show [-x] [<keyring>]\n\
     keyctl timeout <key> <timeout>\n\
  -  keyctl unlink <key> <keyring>\n\
  +  keyctl unlink <key> [<keyring>]\n\
     keyctl update <key> <data>\n\
   \n\
   Key/keyring ID:\n\
  @@ -1572,31 +1789,62 @@
       POPT_TABLEEND
   };
   
  -int
  -main(int argc, char *argv[])
  +static int cmd_run(int argc, char *argv[])
   {
  -    poptContext optCon = rpmioInit(argc, argv, optionsTable);
  -    int ec = 0;
  +    const struct poptOption * c;
  +    const char * cmd;
  +    int rc = 1;
  +
  +    if (argv == NULL || argv[0] == NULL)	/* XXX segfault avoidance */
  +	goto exit;
  +    cmd = argv[0];
  +    for (c = _rpmkeyCommandTable; c->longName != NULL; c++) {
  +	int (*func) (int argc, char *argv[]) = NULL;
   
  -    if (optCon == NULL)
  -	exit(EXIT_FAILURE);
  +	if (strcmp(cmd, c->longName))
  +	    continue;
   
  -    /* grab my UID, GID and groups */
  -    myuid = geteuid();
  -    mygid = getegid();
  -    myngroups = getgroups(0, NULL);
  +	func = c->arg;
  +	rc = (*func) (argc, argv);
  +	break;
  +    }
   
  -    if (myuid == (uid_t) - 1 || mygid == (uid_t) - 1 || myngroups == -1)
  -	rpmkeyError("Unable to get UID/GID/#Groups\n");
  +exit:
  +    return rc;
  +}
   
  -    mygroups = calloc(myngroups, sizeof(gid_t));
  -    if (!mygroups)
  -	rpmkeyError("calloc");
  +/*
  + * execute the appropriate subcommand
  + */
  +int main(int argc, char *argv[])
  +{
  +    char * arg0 = argv[0];
  +    poptContext con = rpmioInit(argc, argv, _rpmkeyCommandTable);
  +    char ** av = NULL;
  +    int ac;
  +    int ec;
  +    int xx;
   
  -    myngroups = getgroups(myngroups, mygroups);
  -    if (myngroups < 0)
  -	rpmkeyError("Unable to get Groups\n");
  +    while ((xx = poptGetNextOpt(con)) > 0)
  +    switch (xx) {
  +    default:
  +	fprintf(stderr, _("%s: option table misconfigured (%d)\n"),
  +		arg0, xx);
  +	ec = EXIT_FAILURE;
  +	goto exit;
  +	break;
  +    }
  +
  +    av = (char **) poptGetArgs(con);
  +    for (ac = 0; av[ac] != NULL; ac++)
  +	;
   
  -    optCon = rpmioFini(optCon);
  +    ec = cmd_run(ac, av);
  +    if (ec)
  +	goto exit;
  +
  +exit:
  +    con = rpmioFini(con);
       return ec;
  +
   }
  @@ .
______________________________________________________________________
RPM Package Manager                                    http://rpm5.org
CVS Sources Repository                                rpm-cvs@rpm5.org
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic