rpm  5.2.1
rpmio/rpmku.c
Go to the documentation of this file.
00001 
00005 #include "system.h"
00006 
00007 #define _RPMIOB_INTERNAL
00008 #include <rpmiotypes.h>
00009 #include <rpmio.h>
00010 #if defined(HAVE_KEYUTILS_H)
00011 #include <rpmmacro.h>
00012 #include <argv.h>
00013 #include <keyutils.h>
00014 #define _RPMPGP_INTERNAL
00015 #include <rpmpgp.h>
00016 #endif
00017 #include <rpmku.h>
00018 
00019 #include "debug.h"
00020 
00021 /*@access pgpDigParams@ */
00022 /*@access rpmiob @*/
00023 
00024 #if defined(HAVE_KEYUTILS_H)
00025 /*@unchecked@*/
00026 rpmint32_t _kuKeyring;
00027 
00028 /*@unchecked@*/
00029 static int _kuCache = 1;
00030 
00031 typedef struct _kuItem_s {
00032 /*@observer@*/
00033     const char *name;
00034     key_serial_t val;
00035 } * _kuItem;
00036 
00037 /* NB: the following table must be sorted lexically for bsearch(3). */
00038 /*@unchecked@*/ /*@observer@*/
00039 static struct _kuItem_s kuTable[] = {
00040     { "group",          KEY_SPEC_GROUP_KEYRING },
00041     { "process",        KEY_SPEC_PROCESS_KEYRING },
00042     { "session",        KEY_SPEC_SESSION_KEYRING },
00043     { "thread",         KEY_SPEC_THREAD_KEYRING },
00044     { "user",           KEY_SPEC_USER_KEYRING },
00045     { "user_session",   KEY_SPEC_USER_SESSION_KEYRING },
00046 #ifdef  NOTYET  /* XXX is this useful? */
00047   { "???",              KEY_SPEC_REQKEY_AUTH_KEY },
00048 #endif
00049 };
00050 
00051 /*@unchecked@*/
00052 static size_t nkuTable = sizeof(kuTable) / sizeof(kuTable[0]);
00053 
00054 static int
00055 kuCmp(const void * a, const void * b)
00056         /*@*/
00057 {
00058     return strcmp(((_kuItem)a)->name, ((_kuItem)b)->name);
00059 }
00060 
00061 static key_serial_t
00062 kuValue(const char * name)
00063         /*@*/
00064 {
00065     _kuItem k = NULL;
00066 
00067     if (name != NULL && *name != '\0') {
00068         _kuItem tmp = memset(alloca(sizeof(*tmp)), 0, sizeof(*tmp));
00069 /*@-temptrans@*/
00070         tmp->name = name;
00071 /*@=temptrans@*/
00072         k = (_kuItem)bsearch(tmp, kuTable, nkuTable, sizeof(kuTable[0]), kuCmp);
00073     }
00074     return (k != NULL ? k->val :  0);
00075 }
00076 #endif
00077 
00078 /*@-globs -internalglobs -mods @*/
00079 char * _GetPass(const char * prompt)
00080 {
00081     char * pw;
00082 
00083 /*@-unrecog@*/
00084     pw = getpass( prompt ? prompt : "" );
00085 /*@=unrecog@*/
00086 
00087 #if defined(HAVE_KEYUTILS_H)
00088     if (_kuKeyring == 0) {
00089         const char * _keyutils_keyring
00090                 = rpmExpand("%{?_keyutils_keyring}", NULL);
00091         _kuKeyring = (rpmuint32_t) kuValue(_keyutils_keyring);
00092         if (_kuKeyring == 0)
00093             _kuKeyring = KEY_SPEC_PROCESS_KEYRING;
00094         _keyutils_keyring = _free(_keyutils_keyring);
00095     }
00096 
00097     if (pw && *pw) {
00098         key_serial_t keyring = (key_serial_t) _kuKeyring;
00099         size_t npw = strlen(pw);
00100         (void) add_key("user", "rpm:passwd", pw, npw, keyring);
00101         (void) memset(pw, 0, npw);      /* burn the password */
00102         pw = "@u user rpm:passwd";
00103     }
00104 #endif
00105 
00106 assert(pw != NULL);
00107 /*@-observertrans -statictrans@*/
00108     return pw;
00109 /*@=observertrans =statictrans@*/
00110 }
00111 /*@=globs =internalglobs =mods @*/
00112 
00113 char * _RequestPass(/*@unused@*/ const char * prompt)
00114 {
00115 /*@only@*/ /*@relnull@*/
00116     static char * password = NULL;
00117 #if defined(HAVE_KEYUTILS_H)
00118     const char * foo = "user rpm:yyyy spoon";
00119     ARGV_t av = NULL;
00120     int xx = argvSplit(&av, foo, NULL);
00121     key_serial_t dest = 0;
00122     key_serial_t key = 0;
00123 
00124     if (password != NULL) {
00125         free(password);
00126         password = NULL;
00127     }
00128 assert(av != NULL);
00129 assert(av[0] != NULL);
00130 assert(av[1] != NULL);
00131 assert(av[2] != NULL);
00132     key = request_key(av[0], av[1], av[2], dest);
00133 
00134 /*@-nullstate@*/        /* XXX *password may be null. */
00135     xx = keyctl_read_alloc(key, (void *)&password);
00136 /*@=nullstate@*/
00137 assert(password != NULL);
00138 #endif
00139 
00140 /*@-statictrans@*/
00141     return password;
00142 /*@=statictrans@*/
00143 }
00144 
00145 /*@-redecl@*/
00146 char * (*Getpass) (const char * prompt) = _GetPass;
00147 /*@=redecl@*/
00148 
00149 rpmRC rpmkuFindPubkey(pgpDigParams sigp, /*@out@*/ rpmiob * iobp)
00150 {
00151     if (iobp != NULL)
00152         *iobp = NULL;
00153 
00154 #if defined(HAVE_KEYUTILS_H)
00155     if (_kuCache) {
00156 /*@observer@*/
00157         static const char krprefix[] = "rpm:gpg:pubkey:";
00158         key_serial_t keyring = (key_serial_t) _kuKeyring;
00159         char krfp[32];
00160         char * krn = alloca(strlen(krprefix) + sizeof("12345678"));
00161         long key;
00162         int xx;
00163 
00164         (void) snprintf(krfp, sizeof(krfp), "%08X", pgpGrab(sigp->signid+4, 4));
00165         krfp[sizeof(krfp)-1] = '\0';
00166         *krn = '\0';
00167         (void) stpcpy( stpcpy(krn, krprefix), krfp);
00168 
00169         key = keyctl_search(keyring, "user", krn, 0);
00170         xx = keyctl_read(key, NULL, 0);
00171         if (xx > 0) {
00172             rpmiob iob = rpmiobNew(xx);
00173             xx = keyctl_read(key, (char *)iob->b, iob->blen);
00174             if (xx > 0) {
00175 #ifdef  NOTYET
00176                 pubkeysource = xstrdup(krn);
00177                 _kuCache = 0;   /* XXX don't bother caching. */
00178 #endif
00179             } else
00180                 iob = rpmiobFree(iob);
00181 
00182             if (iob != NULL && iobp != NULL) {
00183                 *iobp = iob;
00184                 return RPMRC_OK;
00185             } else {
00186                 iob = rpmiobFree(iob);
00187                 return RPMRC_NOTFOUND;
00188             }
00189         } else
00190             return RPMRC_NOTFOUND;
00191     } else
00192 #endif
00193     return RPMRC_NOTFOUND;
00194 }
00195 
00196 rpmRC rpmkuStorePubkey(pgpDigParams sigp, /*@only@*/ rpmiob iob)
00197 {
00198 #if defined(HAVE_KEYUTILS_H)
00199     if (_kuCache) {
00200 /*@observer@*/
00201         static const char krprefix[] = "rpm:gpg:pubkey:";
00202         key_serial_t keyring = (key_serial_t) _kuKeyring;
00203         char krfp[32];
00204         char * krn = alloca(strlen(krprefix) + sizeof("12345678"));
00205 
00206         (void) snprintf(krfp, sizeof(krfp), "%08X", pgpGrab(sigp->signid+4, 4));
00207         krfp[sizeof(krfp)-1] = '\0';
00208         *krn = '\0';
00209         (void) stpcpy( stpcpy(krn, krprefix), krfp);
00210 /*@-moduncon -noeffectuncon @*/
00211         (void) add_key("user", krn, iob->b, iob->blen, keyring);
00212 /*@=moduncon =noeffectuncon @*/
00213     }
00214 #endif
00215     iob = rpmiobFree(iob);
00216     return RPMRC_OK;
00217 }
00218 
00219 const char * rpmkuPassPhrase(const char * passPhrase)
00220 {
00221     const char * pw;
00222 
00223 #if defined(HAVE_KEYUTILS_H)
00224     if (passPhrase && !strcmp(passPhrase, "@u user rpm:passwd")) {
00225         key_serial_t keyring = (key_serial_t) _kuKeyring;
00226         long key;
00227         int xx;
00228 
00229 /*@-moduncon@*/
00230         key = keyctl_search(keyring, "user", "rpm:passwd", 0);
00231         pw = NULL;
00232         xx = keyctl_read_alloc(key, (void **)&pw);
00233 /*@=moduncon@*/
00234         if (xx < 0)
00235             pw = NULL;
00236     } else
00237 #endif
00238         pw = xstrdup(passPhrase);
00239     return pw;
00240 }