📄 pgpkey.c
字号:
f = pgp_compare_trust; break; } qsort (KeyTable, i, sizeof (pgp_uid_t *), f); helpstr[0] = 0; mutt_make_help (buf, sizeof (buf), _("Exit "), MENU_PGP, OP_EXIT); strcat (helpstr, buf); /* __STRCAT_CHECKED__ */ mutt_make_help (buf, sizeof (buf), _("Select "), MENU_PGP, OP_GENERIC_SELECT_ENTRY); strcat (helpstr, buf); /* __STRCAT_CHECKED__ */ mutt_make_help (buf, sizeof (buf), _("Check key "), MENU_PGP, OP_VERIFY_KEY); strcat (helpstr, buf); /* __STRCAT_CHECKED__ */ mutt_make_help (buf, sizeof (buf), _("Help"), MENU_PGP, OP_HELP); strcat (helpstr, buf); /* __STRCAT_CHECKED__ */ menu = mutt_new_menu (); menu->max = i; menu->make_entry = pgp_entry; menu->menu = MENU_PGP; menu->help = helpstr; menu->data = KeyTable; if (p) snprintf (buf, sizeof (buf), _("PGP keys matching <%s>."), p->mailbox); else snprintf (buf, sizeof (buf), _("PGP keys matching \"%s\"."), s); menu->title = buf; kp = NULL; mutt_clear_error (); while (!done) { switch (mutt_menuLoop (menu)) { case OP_VERIFY_KEY: mutt_mktemp (tempfile); if ((devnull = fopen ("/dev/null", "w")) == NULL) /* __FOPEN_CHECKED__ */ { mutt_perror _("Can't open /dev/null"); break; } if ((fp = safe_fopen (tempfile, "w")) == NULL) { fclose (devnull); mutt_perror _("Can't create temporary file"); break; } mutt_message _("Invoking PGP..."); snprintf (tmpbuf, sizeof (tmpbuf), "0x%s", pgp_keyid (pgp_principal_key (KeyTable[menu->current]->parent))); if ((thepid = pgp_invoke_verify_key (NULL, NULL, NULL, -1, fileno (fp), fileno (devnull), tmpbuf)) == -1) { mutt_perror _("Can't create filter"); unlink (tempfile); fclose (fp); fclose (devnull); } mutt_wait_filter (thepid); fclose (fp); fclose (devnull); mutt_clear_error (); snprintf (cmd, sizeof (cmd), _("Key ID: 0x%s"), pgp_keyid (pgp_principal_key (KeyTable[menu->current]->parent))); mutt_do_pager (cmd, tempfile, 0, NULL); menu->redraw = REDRAW_FULL; break; case OP_VIEW_ID: mutt_message ("%s", KeyTable[menu->current]->addr); break; case OP_GENERIC_SELECT_ENTRY: /* XXX make error reporting more verbose */ if (option (OPTPGPCHECKTRUST)) if (!pgp_key_is_valid (KeyTable[menu->current]->parent)) { mutt_error _("This key can't be used: expired/disabled/revoked."); break; } if (option (OPTPGPCHECKTRUST) && (!pgp_id_is_valid (KeyTable[menu->current]) || !pgp_id_is_strong (KeyTable[menu->current]))) { char *s = ""; char buff[LONG_STRING]; if (KeyTable[menu->current]->flags & KEYFLAG_CANTUSE) s = N_("ID is expired/disabled/revoked."); else switch (KeyTable[menu->current]->trust & 0x03) { case 0: s = N_("ID has undefined validity."); break; case 1: s = N_("ID is not valid."); break; case 2: s = N_("ID is only marginally valid."); break; } snprintf (buff, sizeof (buff), _("%s Do you really want to use the key?"), _(s)); if (mutt_yesorno (buff, M_NO) != M_YES) { mutt_clear_error (); break; } }# if 0 kp = pgp_principal_key (KeyTable[menu->current]->parent);# else kp = KeyTable[menu->current]->parent;# endif done = 1; break; case OP_EXIT: kp = NULL; done = 1; break; } } mutt_menuDestroy (&menu); FREE (&KeyTable); set_option (OPTNEEDREDRAW); return (kp);}pgp_key_t pgp_ask_for_key (char *tag, char *whatfor, short abilities, pgp_ring_t keyring){ pgp_key_t key; char resp[SHORT_STRING]; struct pgp_cache *l = NULL; mutt_clear_error (); resp[0] = 0; if (whatfor) { for (l = id_defaults; l; l = l->next) if (!mutt_strcasecmp (whatfor, l->what)) { strfcpy (resp, NONULL (l->dflt), sizeof (resp)); break; } } FOREVER { resp[0] = 0; if (mutt_get_field (tag, resp, sizeof (resp), M_CLEAR) != 0) return NULL; if (whatfor) { if (l) mutt_str_replace (&l->dflt, resp); else { l = safe_malloc (sizeof (struct pgp_cache)); l->next = id_defaults; id_defaults = l; l->what = safe_strdup (whatfor); l->dflt = safe_strdup (resp); } } if ((key = pgp_getkeybystr (resp, abilities, keyring))) return key; BEEP (); } /* not reached */}/* generate a public key attachment */BODY *pgp_make_key_attachment (char *tempf){ BODY *att; char buff[LONG_STRING]; char tempfb[_POSIX_PATH_MAX], tmp[STRING]; FILE *tempfp; FILE *devnull; struct stat sb; pid_t thepid; pgp_key_t key; unset_option (OPTPGPCHECKTRUST); key = pgp_ask_for_key (_("Please enter the key ID: "), NULL, 0, PGP_PUBRING); if (!key) return NULL; snprintf (tmp, sizeof (tmp), "0x%s", pgp_keyid (pgp_principal_key (key))); pgp_free_key (&key); if (!tempf) { mutt_mktemp (tempfb); tempf = tempfb; } if ((tempfp = safe_fopen (tempf, tempf == tempfb ? "w" : "a")) == NULL) { mutt_perror _("Can't create temporary file"); return NULL; } if ((devnull = fopen ("/dev/null", "w")) == NULL) /* __FOPEN_CHECKED__ */ { mutt_perror _("Can't open /dev/null"); fclose (tempfp); if (tempf == tempfb) unlink (tempf); return NULL; } mutt_message _("Invoking pgp..."); if ((thepid = pgp_invoke_export (NULL, NULL, NULL, -1, fileno (tempfp), fileno (devnull), tmp)) == -1) { mutt_perror _("Can't create filter"); unlink (tempf); fclose (tempfp); fclose (devnull); return NULL; } mutt_wait_filter (thepid); fclose (tempfp); fclose (devnull); att = mutt_new_body (); att->filename = safe_strdup (tempf); att->unlink = 1; att->use_disp = 0; att->type = TYPEAPPLICATION; att->subtype = safe_strdup ("pgp-keys"); snprintf (buff, sizeof (buff), _("PGP Key %s."), tmp); att->description = safe_strdup (buff); mutt_update_encoding (att); stat (tempf, &sb); att->length = sb.st_size; return att;}static LIST *pgp_add_string_to_hints (LIST *hints, const char *str){ char *scratch; char *t; if ((scratch = safe_strdup (str)) == NULL) return hints; for (t = strtok (scratch, " ,.:\"()<>\n"); t; t = strtok (NULL, " ,.:\"()<>\n")) { if (strlen (t) > 3) hints = mutt_add_list (hints, t); } FREE (&scratch); return hints;}static pgp_key_t *pgp_get_lastp (pgp_key_t p){ for (; p; p = p->next) if (!p->next) return &p->next; return NULL;}pgp_key_t pgp_getkeybyaddr (ADDRESS * a, short abilities, pgp_ring_t keyring){ ADDRESS *r, *p; LIST *hints = NULL; int weak = 0; int invalid = 0; int multi = 0; int this_key_has_strong; int this_key_has_weak; int this_key_has_invalid; int match; pgp_key_t keys, k, kn; pgp_key_t the_valid_key = NULL; pgp_key_t matches = NULL; pgp_key_t *last = &matches; pgp_uid_t *q; if (a && a->mailbox) hints = pgp_add_string_to_hints (hints, a->mailbox); if (a && a->personal) hints = pgp_add_string_to_hints (hints, a->personal); mutt_message (_("Looking for keys matching \"%s\"..."), a->mailbox); keys = pgp_get_candidates (keyring, hints); mutt_free_list (&hints); if (!keys) return NULL; dprint (5, (debugfile, "pgp_getkeybyaddr: looking for %s <%s>.", a->personal, a->mailbox)); for (k = keys; k; k = kn) { kn = k->next; dprint (5, (debugfile, " looking at key: %s\n", pgp_keyid (k))); if (abilities && !(k->flags & abilities)) { dprint (5, (debugfile, " insufficient abilities: Has %x, want %x\n", k->flags, abilities)); continue; } this_key_has_weak = 0; /* weak but valid match */ this_key_has_invalid = 0; /* invalid match */ this_key_has_strong = 0; /* strong and valid match */ match = 0; /* any match */ for (q = k->address; q; q = q->next) { r = rfc822_parse_adrlist (NULL, q->addr); for (p = r; p; p = p->next) { int validity = pgp_id_matches_addr (a, p, q); if (validity & PGP_KV_MATCH) /* something matches */ match = 1; /* is this key a strong candidate? */ if ((validity & PGP_KV_VALID) && (validity & PGP_KV_STRONGID) && (validity & PGP_KV_ADDR)) { if (the_valid_key && the_valid_key != k) multi = 1; the_valid_key = k; this_key_has_strong = 1; } else if ((validity & PGP_KV_MATCH) && !(validity & PGP_KV_VALID)) this_key_has_invalid = 1; else if ((validity & PGP_KV_MATCH) && (!(validity & PGP_KV_STRONGID) || !(validity & PGP_KV_ADDR))) this_key_has_weak = 1; } rfc822_free_address (&r); } if (match && !this_key_has_strong && this_key_has_invalid) invalid = 1; if (match && !this_key_has_strong && this_key_has_weak) weak = 1; if (match) { *last = pgp_principal_key (k); kn = pgp_remove_key (&keys, *last); last = pgp_get_lastp (k); } } pgp_free_key (&keys); if (matches) { if (the_valid_key && !multi /* && !weak && !(invalid && option (OPTPGPSHOWUNUSABLE)) */) { /* * There was precisely one strong match on a valid ID. * * Proceed without asking the user. */ pgp_remove_key (&matches, the_valid_key); pgp_free_key (&matches); k = the_valid_key; } else { /* * Else: Ask the user. */ if ((k = pgp_select_key (matches, a, NULL))) pgp_remove_key (&matches, k); pgp_free_key (&matches); } return k; } return NULL;}pgp_key_t pgp_getkeybystr (char *p, short abilities, pgp_ring_t keyring){ LIST *hints = NULL; pgp_key_t keys; pgp_key_t matches = NULL; pgp_key_t *last = &matches; pgp_key_t k, kn; pgp_uid_t *a; short match; mutt_message (_("Looking for keys matching \"%s\"..."), p); hints = pgp_add_string_to_hints (hints, p); keys = pgp_get_candidates (keyring, hints); mutt_free_list (&hints); if (!keys) return NULL; for (k = keys; k; k = kn) { kn = k->next; if (abilities && !(k->flags & abilities)) continue; match = 0; for (a = k->address; a; a = a->next) { dprint (5, (debugfile, "pgp_getkeybystr: matching \"%s\" against key %s, \"%s\": ", p, pgp_keyid (k), a->addr)); if (!*p || mutt_strcasecmp (p, pgp_keyid (k)) == 0 || (!mutt_strncasecmp (p, "0x", 2) && !mutt_strcasecmp (p + 2, pgp_keyid (k))) || (option (OPTPGPLONGIDS) && !mutt_strncasecmp (p, "0x", 2) && !mutt_strcasecmp (p + 2, k->keyid + 8)) || mutt_stristr (a->addr, p)) { dprint (5, (debugfile, "match.\n")); match = 1; break; } } if (match) { *last = pgp_principal_key (k); kn = pgp_remove_key (&keys, *last); last = pgp_get_lastp (k); } } pgp_free_key (&keys); if (matches) { if ((k = pgp_select_key (matches, NULL, p))) pgp_remove_key (&matches, k); pgp_free_key (&matches); return k; } return NULL;}#endif /* CRYPT_BACKEND_CLASSIC_PGP */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -