Parse the 'pub' line from the pgp output.
136{
137 struct PgpUid *uid = NULL;
138 int field = 0;
139 bool is_uid = false;
140 bool is_pub = false;
141 bool is_fpr = false;
142 char *pend = NULL;
143 char *p = NULL;
146 char tstr[11] = { 0 };
147
148 *is_subkey = false;
149 if (*buf == '\0')
150 return NULL;
151
152
153
154
156 if (k)
157 memcpy(&tmp, k, sizeof(tmp));
158
160
162 for (p = buf; p; p = pend)
163 {
164 pend = strchr(p, ':');
165 if (pend)
166 *pend++ = 0;
167 field++;
168 if ((*p == '\0') && (field != 1) && (field != 10))
169 continue;
170
171 if (is_fpr && (field != 10))
172 continue;
173
174 switch (field)
175 {
176 case 1:
177 {
179
181 is_pub = true;
183 *is_subkey = true;
185 ;
187 *is_subkey = true;
189 is_uid = true;
191 is_fpr = true;
192 else
193 return NULL;
194
195 if (!(is_uid || is_fpr || (*is_subkey && c_pgp_ignore_subkeys)))
196 memset(&tmp, 0, sizeof(tmp));
197
198 break;
199 }
200 case 2:
201 {
203
204 switch (*p)
205 {
206 case 'd':
208 break;
209 case 'e':
211 break;
212 case 'f':
213 trust = 3;
214 break;
215 case 'm':
216 trust = 2;
217 break;
218 case 'n':
219 trust = 1;
220 break;
221 case 'r':
223 break;
224 case 'u':
225 trust = 3;
226 break;
227 default:
228 break;
229 }
230
231 if (!is_uid && !(*is_subkey && c_pgp_ignore_subkeys))
233
234 break;
235 }
236 case 3:
237 {
239
240 if (!(*is_subkey && c_pgp_ignore_subkeys) && !mutt_str_atos_full(p, &tmp.
keylen))
241 {
242 goto bail;
243 }
244 break;
245 }
246 case 4:
247 {
249
250 if (!(*is_subkey && c_pgp_ignore_subkeys))
251 {
252 int x = 0;
253 if (!mutt_str_atoi_full(p, &x))
254 goto bail;
257 }
258 break;
259 }
260 case 5:
261 {
263
264 if (!(*is_subkey && c_pgp_ignore_subkeys))
266 break;
267 }
268 case 6:
269 {
271
272 if (strchr(p, '-'))
273 {
274 struct tm time = { 0 };
275
276 time.tm_sec = 0;
277 time.tm_min = 0;
278 time.tm_hour = 12;
279 strncpy(tstr, p, 11);
280 tstr[4] = '\0';
281 tstr[7] = '\0';
282 if (!mutt_str_atoi_full(tstr, &time.tm_year))
283 {
284 p = tstr;
285 goto bail;
286 }
287 time.tm_year -= 1900;
288 if (!mutt_str_atoi_full(tstr + 5, &time.tm_mon))
289 {
290 p = tstr + 5;
291 goto bail;
292 }
293 time.tm_mon -= 1;
294 if (!mutt_str_atoi_full(tstr + 8, &time.tm_mday))
295 {
296 p = tstr + 8;
297 goto bail;
298 }
300 }
301 else
302 {
303 unsigned long long secs = 0;
304
306 goto bail;
308 }
309 break;
310 }
311 case 7:
312 break;
313 case 8:
314 break;
315 case 9:
316 break;
317 case 10:
318 {
319
320
321
322
323
324 if (!(pend && (*p || is_pub)))
325 break;
326
327 if (is_fpr)
328 {
329
332 break;
333 }
334
335
336 if (!is_uid && (*is_subkey && c_pgp_ignore_subkeys))
337 break;
338
340
348
349 if (strstr(p, "ENCR"))
351 if (strstr(p, "SIGN"))
353
354 break;
355 }
356 case 11:
357 break;
358 case 12:
360
361 while (*p)
362 {
363 switch (*p++)
364 {
365 case 'D':
367 break;
368
369 case 'e':
371 break;
372
373 case 's':
375 break;
376
377 default:
378 break;
379 }
380 }
381
382 if (!is_uid && (!*is_subkey || !c_pgp_ignore_subkeys ||
385 {
387 }
388
389 break;
390
391 default:
392 break;
393 }
394 }
395
396
397 if (!(is_uid || is_fpr || (*is_subkey && c_pgp_ignore_subkeys)))
399 if (!k)
400 return NULL;
401 memcpy(k, &tmp, sizeof(*k));
402
403
405 {
408 }
409
410 return k;
411
412bail:
414 return NULL;
415}
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.
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.
#define MUTT_MEM_CALLOC(n, type)
time_t mutt_date_make_time(struct tm *t, bool local)
Convert struct tm to time_t.
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.
@ KEYFLAG_REVOKED
Key is revoked.
@ KEYFLAG_PREFER_SIGNING
Key's owner prefers signing.
@ KEYFLAG_NONE
No flags are set.
@ KEYFLAG_PREFER_ENCRYPTION
Key's owner prefers encryption.
@ KEYFLAG_CANSIGN
Key is suitable for signing.
@ KEYFLAG_EXPIRED
Key is expired.
@ KEYFLAG_CANENCRYPT
Key is suitable for encryption.
@ KEYFLAG_DISABLED
Key is marked disabled.
const char * pgp_pkalgbytype(unsigned char type)
Get the name of the algorithm from its ID.
struct ConfigSubset * sub
Inherited config items.
Information about a PGP key.
struct PgpUid * address
User IDs.
char * fingerprint
Key fingerprint.
time_t gen_time
Key generation time.
const char * algorithm
Algorithm name.
int numalg
Algorithm number.
struct PgpKeyInfo * parent
Parent key.
int flags
Flags for this UID.
char * addr
Email address.
struct PgpUid * next
Linked list.