rpm 5.2.1

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

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 }