Parse the 'pub' line from the pgp output.
131{
132 struct PgpUid *uid = NULL;
133 int field = 0;
134 bool is_uid = false;
135 bool is_pub = false;
136 bool is_fpr = false;
137 char *pend = NULL, *p = NULL;
141 char tstr[11] = { 0 };
142
143 *is_subkey = false;
144 if (*buf == '\0')
145 return NULL;
146
147
148
149
150 if (k)
151 memcpy(&tmp, k, sizeof(tmp));
152 else
153 memset(&tmp, 0, sizeof(tmp));
154
156
158 for (p = buf; p; p = pend)
159 {
160 pend = strchr(p, ':');
161 if (pend)
162 *pend++ = 0;
163 field++;
164 if ((*p == '\0') && (field != 1) && (field != 10))
165 continue;
166
167 if (is_fpr && (field != 10))
168 continue;
169
170 switch (field)
171 {
172 case 1:
173 {
175
177 is_pub = true;
179 *is_subkey = true;
181 ;
183 *is_subkey = true;
185 is_uid = true;
187 is_fpr = true;
188 else
189 return NULL;
190
191 if (!(is_uid || is_fpr || (*is_subkey && c_pgp_ignore_subkeys)))
192 memset(&tmp, 0, sizeof(tmp));
193
194 break;
195 }
196 case 2:
197 {
199
200 switch (*p)
201 {
202 case 'd':
204 break;
205 case 'e':
207 break;
208 case 'f':
209 trust = 3;
210 break;
211 case 'm':
212 trust = 2;
213 break;
214 case 'n':
215 trust = 1;
216 break;
217 case 'r':
219 break;
220 case 'u':
221 trust = 3;
222 break;
223 }
224
225 if (!is_uid && !(*is_subkey && c_pgp_ignore_subkeys))
227
228 break;
229 }
230 case 3:
231 {
233
234 if (!(*is_subkey && c_pgp_ignore_subkeys) && !mutt_str_atos_full(p, &tmp.keylen))
235 {
236 goto bail;
237 }
238 break;
239 }
240 case 4:
241 {
243
244 if (!(*is_subkey && c_pgp_ignore_subkeys))
245 {
246 int x = 0;
247 if (!mutt_str_atoi_full(p, &x))
248 goto bail;
249 tmp.numalg = x;
251 }
252 break;
253 }
254 case 5:
255 {
257
258 if (!(*is_subkey && c_pgp_ignore_subkeys))
260 break;
261 }
262 case 6:
263 {
265
266 if (strchr(p, '-'))
267 {
268 struct tm time;
269
270 time.tm_sec = 0;
271 time.tm_min = 0;
272 time.tm_hour = 12;
273 strncpy(tstr, p, 11);
274 tstr[4] = '\0';
275 tstr[7] = '\0';
276 if (!mutt_str_atoi_full(tstr, &time.tm_year))
277 {
278 p = tstr;
279 goto bail;
280 }
281 time.tm_year -= 1900;
282 if (!mutt_str_atoi_full(tstr + 5, &time.tm_mon))
283 {
284 p = tstr + 5;
285 goto bail;
286 }
287 time.tm_mon -= 1;
288 if (!mutt_str_atoi_full(tstr + 8, &time.tm_mday))
289 {
290 p = tstr + 8;
291 goto bail;
292 }
294 }
295 else
296 {
297 unsigned long long secs;
298
300 goto bail;
301 tmp.gen_time = (time_t) secs;
302 }
303 break;
304 }
305 case 7:
306 break;
307 case 8:
308 break;
309 case 9:
310 break;
311 case 10:
312 {
313
314
315
316
317
318 if (!(pend && (*p || is_pub)))
319 break;
320
321 if (is_fpr)
322 {
323
324 if (!tmp.fingerprint)
326 break;
327 }
328
329
330 if (!is_uid && (*is_subkey && c_pgp_ignore_subkeys))
331 break;
332
334
340 uid->
next = tmp.address;
341 tmp.address = uid;
342
343 if (strstr(p, "ENCR"))
345 if (strstr(p, "SIGN"))
347
348 break;
349 }
350 case 11:
351 break;
352 case 12:
354
355 while (*p)
356 {
357 switch (*p++)
358 {
359 case 'D':
361 break;
362
363 case 'e':
365 break;
366
367 case 's':
369 break;
370 }
371 }
372
373 if (!is_uid && (!*is_subkey || !c_pgp_ignore_subkeys ||
376 {
377 tmp.flags |= flags;
378 }
379
380 break;
381
382 default:
383 break;
384 }
385 }
386
387
388 if (!(is_uid || is_fpr || (*is_subkey && c_pgp_ignore_subkeys)))
390 if (!k)
391 return NULL;
392 memcpy(k, &tmp, sizeof(*k));
393
394
395 if (tmp.address)
396 {
399 }
400
401 return k;
402
403bail:
405 return NULL;
406}
const char * mutt_str_atoull(const char *str, unsigned long long *dst)
Convert ASCII string to an unsigned long long.
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
time_t mutt_date_make_time(struct tm *t, bool local)
Convert struct tm to time_t
static void fix_uid(char *uid)
Decode backslash-escaped user ids (in place)
#define mutt_debug(LEVEL,...)
@ LL_DEBUG2
Log at debug level 2.
@ LL_DEBUG1
Log at debug level 1.
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
char * mutt_str_dup(const char *str)
Copy a string, safely.
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
#define KEYFLAG_EXPIRED
Key is expired.
uint16_t KeyFlags
Flags describing PGP/SMIME keys, e.g. KEYFLAG_CANSIGN.
#define KEYFLAG_CANENCRYPT
Key is suitable for encryption.
#define KEYFLAG_NO_FLAGS
No flags are set.
#define KEYFLAG_PREFER_SIGNING
Key's owner prefers signing.
#define KEYFLAG_DISABLED
Key is marked disabled.
#define KEYFLAG_REVOKED
Key is revoked.
#define KEYFLAG_PREFER_ENCRYPTION
Key's owner prefers encryption.
#define KEYFLAG_CANSIGN
Key is suitable for signing.
const char * pgp_pkalgbytype(unsigned char type)
Get the name of the algorithm from its ID.
Container for Accounts, Notifications.
struct ConfigSubset * sub
Inherited config items.
Information about a PGP key.
struct PgpKeyInfo * parent
Parent key.
struct PgpUid * next
Linked list.