rpm  5.2.1
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@*/
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 
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 }