rpm 5.2.1

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

- File List
- Globals

rpmku.c
Go to the documentation of this file.
1
5 #include "system.h"
6
7 #define _RPMIOB_INTERNAL
8 #include <rpmiotypes.h>
9 #include <rpmio.h>
10 #if defined(HAVE_KEYUTILS_H)
11 #include <rpmmacro.h>
12 #include <argv.h>
13 #include <keyutils.h>
14 #define _RPMPGP_INTERNAL
15 #include <rpmpgp.h>
16 #endif
17 #include <rpmku.h>
18
19 #include "debug.h"
20
21 /*@access pgpDigParams@ */
22 /*@access rpmiob @*/
23
24 #if defined(HAVE_KEYUTILS_H)
25 /*@unchecked@*/
26 rpmint32_t _kuKeyring;
27
28 /*@unchecked@*/
29 static int _kuCache = 1;
30
31 typedef struct _kuItem_s {
32 /*@observer@*/
33 const char *name;
34 key_serial_t val;
35 } * _kuItem;
36
37 /* NB: the following table must be sorted lexically for bsearch(3). */
38 /*@unchecked@*/ /*@observer@*/
39 static struct _kuItem_s kuTable[] = {
40 { "group", KEY_SPEC_GROUP_KEYRING },
41 { "process", KEY_SPEC_PROCESS_KEYRING },
42 { "session", KEY_SPEC_SESSION_KEYRING },
43 { "thread", KEY_SPEC_THREAD_KEYRING },
44 { "user", KEY_SPEC_USER_KEYRING },
45 { "user_session", KEY_SPEC_USER_SESSION_KEYRING },
46 #ifdef NOTYET /* XXX is this useful? */
47 { "???", KEY_SPEC_REQKEY_AUTH_KEY },
48 #endif
49 };
50
51 /*@unchecked@*/
52 static size_t nkuTable = sizeof(kuTable) / sizeof(kuTable[0]);
53
54 static int
55 kuCmp(const void * a, const void * b)
56 /*@*/
57 {
58 return strcmp(((_kuItem)a)->name, ((_kuItem)b)->name);
59 }
60
61 static key_serial_t
62 kuValue(const char * name)
63 /*@*/
64 {
65 _kuItem k = NULL;
66
67 if (name != NULL && *name != '\0') {
68 _kuItem tmp = memset(alloca(sizeof(*tmp)), 0, sizeof(*tmp));
69 /*@-temptrans@*/
70 tmp->name = name;
71 /*@=temptrans@*/
72 k = (_kuItem)bsearch(tmp, kuTable, nkuTable, sizeof(kuTable[0]), kuCmp);
73 }
74 return (k != NULL ? k->val : 0);
75 }
76 #endif
77
78 /*@-globs -internalglobs -mods @*/
79 char * _GetPass(const char * prompt)
80 {
81 char * pw;
82
83 /*@-unrecog@*/
84 pw = getpass( prompt ? prompt : "" );
85 /*@=unrecog@*/
86
87 #if defined(HAVE_KEYUTILS_H)
88 if (_kuKeyring == 0) {
89 const char * _keyutils_keyring
90 = rpmExpand("%{?_keyutils_keyring}", NULL);
91 _kuKeyring = (rpmuint32_t) kuValue(_keyutils_keyring);
92 if (_kuKeyring == 0)
93 _kuKeyring = KEY_SPEC_PROCESS_KEYRING;
94 _keyutils_keyring = _free(_keyutils_keyring);
95 }
96
97 if (pw && *pw) {
98 key_serial_t keyring = (key_serial_t) _kuKeyring;
99 size_t npw = strlen(pw);
100 (void) add_key("user", "rpm:passwd", pw, npw, keyring);
101 (void) memset(pw, 0, npw); /* burn the password */
102 pw = "@u user rpm:passwd";
103 }
104 #endif
105
106 assert(pw != NULL);
107 /*@-observertrans -statictrans@*/
108 return pw;
109 /*@=observertrans =statictrans@*/
110 }
111 /*@=globs =internalglobs =mods @*/
112
113 char * _RequestPass(/*@unused@*/ const char * prompt)
114 {
115 /*@only@*/ /*@relnull@*/
116 static char * password = NULL;
117 #if defined(HAVE_KEYUTILS_H)
118 const char * foo = "user rpm:yyyy spoon";
119 ARGV_t av = NULL;
120 int xx = argvSplit(&av, foo, NULL);
121 key_serial_t dest = 0;
122 key_serial_t key = 0;
123
124 if (password != NULL) {
125 free(password);
126 password = NULL;
127 }
128 assert(av != NULL);
129 assert(av[0] != NULL);
130 assert(av[1] != NULL);
131 assert(av[2] != NULL);
132 key = request_key(av[0], av[1], av[2], dest);
133
134 /*@-nullstate@*/ /* XXX *password may be null. */
135 xx = keyctl_read_alloc(key, (void *)&password);
136 /*@=nullstate@*/
137 assert(password != NULL);
138 #endif
139
140 /*@-statictrans@*/
141 return password;
142 /*@=statictrans@*/
143 }
144
145 /*@-redecl@*/
146 char * (*Getpass) (const char * prompt) = _GetPass;
147 /*@=redecl@*/
148
149 rpmRC rpmkuFindPubkey(pgpDigParams sigp, /*@out@*/ rpmiob * iobp)
150 {
151 if (iobp != NULL)
152 *iobp = NULL;
153
154 #if defined(HAVE_KEYUTILS_H)
155 if (_kuCache) {
156 /*@observer@*/
157 static const char krprefix[] = "rpm:gpg:pubkey:";
158 key_serial_t keyring = (key_serial_t) _kuKeyring;
159 char krfp[32];
160 char * krn = alloca(strlen(krprefix) + sizeof("12345678"));
161 long key;
162 int xx;
163
164 (void) snprintf(krfp, sizeof(krfp), "%08X", pgpGrab(sigp->signid+4, 4));
165 krfp[sizeof(krfp)-1] = '\0';
166 *krn = '\0';
167 (void) stpcpy( stpcpy(krn, krprefix), krfp);
168
169 key = keyctl_search(keyring, "user", krn, 0);
170 xx = keyctl_read(key, NULL, 0);
171 if (xx > 0) {
172 rpmiob iob = rpmiobNew(xx);
173 xx = keyctl_read(key, (char *)iob->b, iob->blen);
174 if (xx > 0) {
175 #ifdef NOTYET
176 pubkeysource = xstrdup(krn);
177 _kuCache = 0; /* XXX don't bother caching. */
178 #endif
179 } else
180 iob = rpmiobFree(iob);
181
182 if (iob != NULL && iobp != NULL) {
183 *iobp = iob;
184 return RPMRC_OK;
185 } else {
186 iob = rpmiobFree(iob);
187 return RPMRC_NOTFOUND;
188 }
189 } else
190 return RPMRC_NOTFOUND;
191 } else
192 #endif
193 return RPMRC_NOTFOUND;
194 }
195
196 rpmRC rpmkuStorePubkey(pgpDigParams sigp, /*@only@*/ rpmiob iob)
197 {
198 #if defined(HAVE_KEYUTILS_H)
199 if (_kuCache) {
200 /*@observer@*/
201 static const char krprefix[] = "rpm:gpg:pubkey:";
202 key_serial_t keyring = (key_serial_t) _kuKeyring;
203 char krfp[32];
204 char * krn = alloca(strlen(krprefix) + sizeof("12345678"));
205
206 (void) snprintf(krfp, sizeof(krfp), "%08X", pgpGrab(sigp->signid+4, 4));
207 krfp[sizeof(krfp)-1] = '\0';
208 *krn = '\0';
209 (void) stpcpy( stpcpy(krn, krprefix), krfp);
210 /*@-moduncon -noeffectuncon @*/
211 (void) add_key("user", krn, iob->b, iob->blen, keyring);
212 /*@=moduncon =noeffectuncon @*/
213 }
214 #endif
215 iob = rpmiobFree(iob);
216 return RPMRC_OK;
217 }
218
219 const char * rpmkuPassPhrase(const char * passPhrase)
220 {
221 const char * pw;
222
223 #if defined(HAVE_KEYUTILS_H)
224 if (passPhrase && !strcmp(passPhrase, "@u user rpm:passwd")) {
225 key_serial_t keyring = (key_serial_t) _kuKeyring;
226 long key;
227 int xx;
228
229 /*@-moduncon@*/
230 key = keyctl_search(keyring, "user", "rpm:passwd", 0);
231 pw = NULL;
232 xx = keyctl_read_alloc(key, (void **)&pw);
233 /*@=moduncon@*/
234 if (xx < 0)
235 pw = NULL;
236 } else
237 #endif
238 pw = xstrdup(passPhrase);
239 return pw;
240 }