📄 smime.c
字号:
while (fgets (buf, sizeof (buf) - 1, fp) != NULL) if (mailbox && !(mutt_strncasecmp (mailbox, buf, addr_len))) { numFields = sscanf (buf, MUTT_FORMAT(STRING) " " MUTT_FORMAT(STRING) " " MUTT_FORMAT(STRING) " " MUTT_FORMAT(STRING) " " MUTT_FORMAT(STRING) "\n", fields[0], fields[1], fields[2], fields[3], fields[4]); if (numFields < 2) continue; if (mailbox && public && (!fields[4] || *fields[4] == 'i' || *fields[4] == 'e' || *fields[4] == 'r')) continue; if (found) { if (public && *fields[4] == 'u' ) snprintf (prompt, sizeof (prompt), _("ID %s is unverified. Do you want to use it for %s ?"), fields[1], mailbox); else if (public && *fields[4] == 'v' ) snprintf (prompt, sizeof (prompt), _("Use (untrusted!) ID %s for %s ?"), fields[1], mailbox); else snprintf (prompt, sizeof (prompt), _("Use ID %s for %s ?"), fields[1], mailbox); if (may_ask == 0) choice = M_YES; if (may_ask && (choice = mutt_yesorno (prompt, M_NO)) == -1) { found = 0; ask = 0; *key = '\0'; break; } else if (choice == M_NO) { ask = 1; continue; } else if (choice == M_YES) { strfcpy (key, fields[1], sizeof (key)); ask = 0; break; } } else { if (public) key_trust_level = *fields[4]; strfcpy (key, fields[1], sizeof (key)); } found = 1; } else if(query) { numFields = sscanf (buf, MUTT_FORMAT(STRING) " " MUTT_FORMAT(STRING) " " MUTT_FORMAT(STRING) " " MUTT_FORMAT(STRING) " " MUTT_FORMAT(STRING) "\n", fields[0], fields[1], fields[2], fields[3], fields[4]); /* query = label: return certificate. */ if (numFields >= 3 && !(mutt_strncasecmp (query, fields[2], query_len))) { ask = 0; strfcpy (key, fields[1], sizeof (key)); } /* query = certificate: return intermediate certificate. */ else if (numFields >= 4 && !(mutt_strncasecmp (query, fields[1], query_len))) { ask = 0; strfcpy (key, fields[3], sizeof (key)); } } safe_fclose (&fp); if (ask) { if (public && *fields[4] == 'u' ) snprintf (prompt, sizeof (prompt), _("ID %s is unverified. Do you want to use it for %s ?"), fields[1], mailbox); else if (public && *fields[4] == 'v' ) snprintf (prompt, sizeof (prompt), _("Use (untrusted!) ID %s for %s ?"), fields[1], mailbox); else snprintf (prompt, sizeof(prompt), _("Use ID %s for %s ?"), key, mailbox); choice = mutt_yesorno (prompt, M_NO); if (choice == -1 || choice == M_NO) *key = '\0'; } else if (key_trust_level && may_ask) { if (key_trust_level == 'u' ) { snprintf (prompt, sizeof (prompt), _("ID %s is unverified. Do you want to use it for %s ?"), key, mailbox); choice = mutt_yesorno (prompt, M_NO); if (choice != M_YES) *key = '\0'; } else if (key_trust_level == 'v' ) { mutt_error (_("Warning: You have not yet decided to trust ID %s. (any key to continue)"), key); mutt_sleep (5); } } } /* Note: safe_strdup ("") returns NULL. */ return safe_strdup (key);}/* This sets the '*ToUse' variables for an upcoming decryption, where the reuquired key is different from SmimeDefaultKey.*/void _smime_getkeys (char *mailbox){ char *k = NULL; char buf[STRING]; k = smime_get_field_from_db (mailbox, NULL, 0, 1); if (!k) { snprintf(buf, sizeof(buf), _("Enter keyID for %s: "), mailbox); k = smime_ask_for_key(buf, mailbox, 0); } if (k) { /* the key used last time. */ if (*SmimeKeyToUse && !mutt_strcasecmp (k, SmimeKeyToUse + mutt_strlen (SmimeKeys)+1)) { FREE (&k); return; } else smime_void_passphrase (); snprintf (SmimeKeyToUse, sizeof (SmimeKeyToUse), "%s/%s", NONULL(SmimeKeys), k); snprintf (SmimeCertToUse, sizeof (SmimeCertToUse), "%s/%s", NONULL(SmimeCertificates), k); if (mutt_strcasecmp (k, SmimeDefaultKey)) smime_void_passphrase (); FREE (&k); return; } if (*SmimeKeyToUse) { if (!mutt_strcasecmp (SmimeDefaultKey, SmimeKeyToUse + mutt_strlen (SmimeKeys)+1)) return; smime_void_passphrase (); } snprintf (SmimeKeyToUse, sizeof (SmimeKeyToUse), "%s/%s", NONULL (SmimeKeys), NONULL (SmimeDefaultKey)); snprintf (SmimeCertToUse, sizeof (SmimeCertToUse), "%s/%s", NONULL (SmimeCertificates), NONULL (SmimeDefaultKey));}void smime_getkeys (ENVELOPE *env){ ADDRESS *t; int found = 0; if (option (OPTSDEFAULTDECRYPTKEY) && SmimeDefaultKey && *SmimeDefaultKey) { snprintf (SmimeKeyToUse, sizeof (SmimeKeyToUse), "%s/%s", NONULL (SmimeKeys), SmimeDefaultKey); snprintf (SmimeCertToUse, sizeof (SmimeCertToUse), "%s/%s", NONULL(SmimeCertificates), SmimeDefaultKey); return; } for (t = env->to; !found && t; t = t->next) if (mutt_addr_is_user (t)) { found = 1; _smime_getkeys (t->mailbox); } for (t = env->cc; !found && t; t = t->next) if (mutt_addr_is_user (t)) { found = 1; _smime_getkeys (t->mailbox); } if (!found && (t = mutt_default_from())) { _smime_getkeys (t->mailbox); rfc822_free_address (&t); }}/* This routine attempts to find the keyids of the recipients of a message. * It returns NULL if any of the keys can not be found. */char *smime_findKeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc){ char *keyID, *keylist = NULL; size_t keylist_size = 0; size_t keylist_used = 0; ADDRESS *tmp = NULL, *addr = NULL; ADDRESS **last = &tmp; ADDRESS *p, *q; int i; const char *fqdn = mutt_fqdn (1); for (i = 0; i < 3; i++) { switch (i) { case 0: p = to; break; case 1: p = cc; break; case 2: p = bcc; break; default: abort (); } *last = rfc822_cpy_adr (p); while (*last) last = &((*last)->next); } if (fqdn) rfc822_qualify (tmp, fqdn); tmp = mutt_remove_duplicates (tmp); for (p = tmp; p ; p = p->next) { char buf[LONG_STRING]; q = p; if ((keyID = smime_get_field_from_db (q->mailbox, NULL, 1, 1)) == NULL) { snprintf(buf, sizeof(buf), _("Enter keyID for %s: "), q->mailbox); keyID = smime_ask_for_key(buf, q->mailbox, 1); } if(!keyID) { mutt_message (_("No (valid) certificate found for %s."), q->mailbox); FREE (&keylist); rfc822_free_address (&tmp); rfc822_free_address (&addr); return NULL; } keylist_size += mutt_strlen (keyID) + 2; safe_realloc (&keylist, keylist_size); sprintf (keylist + keylist_used, "%s\n", keyID); /* __SPRINTF_CHECKED__ */ keylist_used = mutt_strlen (keylist); rfc822_free_address (&addr); } rfc822_free_address (&tmp); return (keylist);}static int smime_handle_cert_email (char *certificate, char *mailbox, int copy, char ***buffer, int *num){ FILE *fpout = NULL, *fperr = NULL; char tmpfname[_POSIX_PATH_MAX]; char email[STRING]; int ret = -1, count = 0; pid_t thepid; mutt_mktemp (tmpfname); if ((fperr = safe_fopen (tmpfname, "w+")) == NULL) { mutt_perror (tmpfname); return 1; } mutt_unlink (tmpfname); mutt_mktemp (tmpfname); if ((fpout = safe_fopen (tmpfname, "w+")) == NULL) { fclose (fperr); mutt_perror (tmpfname); return 1; } mutt_unlink (tmpfname); if ((thepid = smime_invoke (NULL, NULL, NULL, -1, fileno (fpout), fileno (fperr), certificate, NULL, NULL, NULL, NULL, NULL, SmimeGetCertEmailCommand))== -1) { mutt_message (_("Error: unable to create OpenSSL subprocess!")); fclose (fperr); fclose (fpout); return 1; } mutt_wait_filter (thepid); fflush (fpout); rewind (fpout); rewind (fperr); fflush (fperr); while ((fgets (email, sizeof (email), fpout))) { *(email + mutt_strlen (email)-1) = '\0'; if(mutt_strncasecmp (email, mailbox, mutt_strlen (mailbox)) == 0) ret=1; ret = ret < 0 ? 0 : ret; count++; } if (ret == -1) { mutt_endwin(NULL); mutt_copy_stream (fperr, stdout); mutt_any_key_to_continue (_("Error: unable to create OpenSSL subprocess!")); ret = 1; } else if (!ret) ret = 1; else ret = 0; if(copy && buffer && num) { (*num) = count; *buffer = safe_calloc(sizeof(char*), count); count = 0; rewind (fpout); while ((fgets (email, sizeof (email), fpout))) { *(email + mutt_strlen (email) - 1) = '\0'; (*buffer)[count] = safe_calloc(1, mutt_strlen (email) + 1); strncpy((*buffer)[count], email, mutt_strlen (email)); count++; } } else if(copy) ret = 2; fclose (fpout); fclose (fperr); return ret;}static char *smime_extract_certificate (char *infile){ FILE *fpout = NULL, *fperr = NULL; char pk7out[_POSIX_PATH_MAX], certfile[_POSIX_PATH_MAX]; char tmpfname[_POSIX_PATH_MAX]; pid_t thepid; int empty; mutt_mktemp (tmpfname); if ((fperr = safe_fopen (tmpfname, "w+")) == NULL) { mutt_perror (tmpfname); return NULL; } mutt_unlink (tmpfname); mutt_mktemp (pk7out); if ((fpout = safe_fopen (pk7out, "w+")) == NULL) { fclose (fperr); mutt_perror (pk7out); return NULL; } /* Step 1: Convert the signature to a PKCS#7 structure, as we can't extract the full set of certificates directly. */ if ((thepid = smime_invoke (NULL, NULL, NULL, -1, fileno (fpout), fileno (fperr), infile, NULL, NULL, NULL, NULL, NULL, SmimePk7outCommand))== -1) { mutt_any_key_to_continue (_("Error: unable to create OpenSSL subprocess!")); fclose (fperr); fclose (fpout); mutt_unlink (pk7out); return NULL; } mutt_wait_filter (thepid); fflush (fpout); rewind (fpout); rewind (fperr); fflush (fperr); empty = (fgetc (fpout) == EOF); if (empty) { mutt_perror (pk7out); mutt_copy_stream (fperr, stdout); fclose (fpout); fclose (fperr); mutt_unlink (pk7out); return NULL; } fclose (fpout); mutt_mktemp (certfile); if ((fpout = safe_fopen (certfile, "w+")) == NULL) { fclose (fperr); mutt_unlink (pk7out); mutt_perror (certfile); return NULL; } /* Step 2: Extract the certificates from a PKCS#7 structure. */ if ((thepid = smime_invoke (NULL, NULL, NULL, -1, fileno (fpout), fileno (fperr), pk7out, NULL, NULL, NULL, NULL, NULL, SmimeGetCertCommand))== -1) { mutt_any_key_to_continue (_("Error: unable to create OpenSSL subprocess!")); fclose (fperr); fclose (fpout); mutt_unlink (pk7out); mutt_unlink (certfile); return NULL; } mutt_wait_filter (thepid); mutt_unlink (pk7out); fflush (fpout); rewind (fpout); rewind (fperr); fflush (fperr); empty = (fgetc (fpout) == EOF); if (empty) { mutt_copy_stream (fperr, stdout); fclose (fpout); fclose (fperr); mutt_unlink (certfile); return NULL; } fclose (fpout); fclose (fperr); return safe_strdup (certfile);}static char *smime_extract_signer_certificate (char *infile){ FILE *fpout = NULL, *fperr = NULL; char pk7out[_POSIX_PATH_MAX], certfile[_POSIX_PATH_MAX]; char tmpfname[_POSIX_PATH_MAX]; pid_t thepid; int empty; mutt_mktemp (tmpfname); if ((fperr = safe_fopen (tmpfname, "w+")) == NULL) { mutt_perror (tmpfname); return NULL; } mutt_unlink (tmpfname);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -