rpm 5.3.7

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     if (password == NULL)
00138         password = "";
00139 #endif
00140 
00141 /*@-statictrans@*/
00142     return password;
00143 /*@=statictrans@*/
00144 }
00145 
00146 /*@-redecl@*/
00147 char * (*Getpass) (const char * prompt) = _GetPass;
00148 /*@=redecl@*/
00149 
00150 rpmRC rpmkuFindPubkey(pgpDigParams sigp, /*@out@*/ rpmiob * iobp)
00151 {
00152     if (iobp != NULL)
00153         *iobp = NULL;
00154 
00155 #if defined(HAVE_KEYUTILS_H)
00156     if (_kuCache) {
00157 /*@observer@*/
00158         static const char krprefix[] = "rpm:gpg:pubkey:";
00159         key_serial_t keyring = (key_serial_t) _kuKeyring;
00160         char krfp[32];
00161         char * krn = alloca(strlen(krprefix) + sizeof("12345678"));
00162         long key;
00163         int xx;
00164 
00165         (void) snprintf(krfp, sizeof(krfp), "%08X", pgpGrab(sigp->signid+4, 4));
00166         krfp[sizeof(krfp)-1] = '\0';
00167         *krn = '\0';
00168         (void) stpcpy( stpcpy(krn, krprefix), krfp);
00169 
00170         key = keyctl_search(keyring, "user", krn, 0);
00171         xx = keyctl_read(key, NULL, 0);
00172         if (xx > 0) {
00173             rpmiob iob = rpmiobNew(xx);
00174             xx = keyctl_read(key, (char *)iob->b, iob->blen);
00175             if (xx > 0) {
00176 #ifdef  NOTYET
00177                 pubkeysource = xstrdup(krn);
00178                 _kuCache = 0;   /* XXX don't bother caching. */
00179 #endif
00180             } else
00181                 iob = rpmiobFree(iob);
00182 
00183             if (iob != NULL && iobp != NULL) {
00184                 *iobp = iob;
00185                 return RPMRC_OK;
00186             } else {
00187                 iob = rpmiobFree(iob);
00188                 return RPMRC_NOTFOUND;
00189             }
00190         } else
00191             return RPMRC_NOTFOUND;
00192     } else
00193 #endif
00194     return RPMRC_NOTFOUND;
00195 }
00196 
00197 rpmRC rpmkuStorePubkey(pgpDigParams sigp, /*@only@*/ rpmiob iob)
00198 {
00199 #if defined(HAVE_KEYUTILS_H)
00200     if (_kuCache) {
00201 /*@observer@*/
00202         static const char krprefix[] = "rpm:gpg:pubkey:";
00203         key_serial_t keyring = (key_serial_t) _kuKeyring;
00204         char krfp[32];
00205         char * krn = alloca(strlen(krprefix) + sizeof("12345678"));
00206 
00207         (void) snprintf(krfp, sizeof(krfp), "%08X", pgpGrab(sigp->signid+4, 4));
00208         krfp[sizeof(krfp)-1] = '\0';
00209         *krn = '\0';
00210         (void) stpcpy( stpcpy(krn, krprefix), krfp);
00211 /*@-moduncon -noeffectuncon @*/
00212         (void) add_key("user", krn, iob->b, iob->blen, keyring);
00213 /*@=moduncon =noeffectuncon @*/
00214     }
00215 #endif
00216     iob = rpmiobFree(iob);
00217     return RPMRC_OK;
00218 }
00219 
00220 const char * rpmkuPassPhrase(const char * passPhrase)
00221 {
00222     const char * pw;
00223 
00224 #if defined(HAVE_KEYUTILS_H)
00225     if (passPhrase && !strcmp(passPhrase, "@u user rpm:passwd")) {
00226         key_serial_t keyring = (key_serial_t) _kuKeyring;
00227         long key;
00228         int xx;
00229 
00230 /*@-moduncon@*/
00231         key = keyctl_search(keyring, "user", "rpm:passwd", 0);
00232         pw = NULL;
00233         xx = keyctl_read_alloc(key, (void *)&pw);
00234 /*@=moduncon@*/
00235         if (xx < 0)
00236             pw = NULL;
00237     } else
00238 #endif
00239         pw = xstrdup(passPhrase);
00240     return pw;
00241 }