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
00022
00023
00024 #if defined(HAVE_KEYUTILS_H)
00025
00026 rpmint32_t _kuKeyring;
00027
00028
00029 static int _kuCache = 1;
00030
00031 typedef struct _kuItem_s {
00032
00033 const char *name;
00034 key_serial_t val;
00035 } * _kuItem;
00036
00037
00038
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
00047 { "???", KEY_SPEC_REQKEY_AUTH_KEY },
00048 #endif
00049 };
00050
00051
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
00070 tmp->name = name;
00071
00072 k = (_kuItem)bsearch(tmp, kuTable, nkuTable, sizeof(kuTable[0]), kuCmp);
00073 }
00074 return (k != NULL ? k->val : 0);
00075 }
00076 #endif
00077
00078
00079 char * _GetPass(const char * prompt)
00080 {
00081 char * pw;
00082
00083
00084 pw = getpass( prompt ? prompt : "" );
00085
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);
00102 pw = "@u user rpm:passwd";
00103 }
00104 #endif
00105
00106 assert(pw != NULL);
00107
00108 return pw;
00109
00110 }
00111
00112
00113 char * _RequestPass( const char * prompt)
00114 {
00115
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
00135 xx = keyctl_read_alloc(key, (void *)&password);
00136
00137 assert(password != NULL);
00138 #endif
00139
00140
00141 return password;
00142
00143 }
00144
00145
00146 char * (*Getpass) (const char * prompt) = _GetPass;
00147
00148
00149 rpmRC rpmkuFindPubkey(pgpDigParams sigp, rpmiob * iobp)
00150 {
00151 if (iobp != NULL)
00152 *iobp = NULL;
00153
00154 #if defined(HAVE_KEYUTILS_H)
00155 if (_kuCache) {
00156
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;
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, rpmiob iob)
00197 {
00198 #if defined(HAVE_KEYUTILS_H)
00199 if (_kuCache) {
00200
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
00211 (void) add_key("user", krn, iob->b, iob->blen, keyring);
00212
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
00230 key = keyctl_search(keyring, "user", "rpm:passwd", 0);
00231 pw = NULL;
00232 xx = keyctl_read_alloc(key, (void **)&pw);
00233
00234 if (xx < 0)
00235 pw = NULL;
00236 } else
00237 #endif
00238 pw = xstrdup(passPhrase);
00239 return pw;
00240 }