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