⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mutt_ssl.c

📁 mutt-1.5.12 源代码。linux 下邮件接受的工具。
💻 C
📖 第 1 页 / 共 2 页
字号:
  int rc;  rc = ssl_socket_close (conn);  conn->conn_read = raw_socket_read;  conn->conn_write = raw_socket_write;  conn->conn_close = raw_socket_close;  return rc;}static char *x509_get_part (char *line, const char *ndx){  static char ret[SHORT_STRING];  char *c, *c2;  strfcpy (ret, _("Unknown"), sizeof (ret));  c = strstr (line, ndx);  if (c)  {    c += strlen (ndx);    c2 = strchr (c, '/');    if (c2)      *c2 = '\0';    strfcpy (ret, c, sizeof (ret));    if (c2)      *c2 = '/';  }  return ret;}static void x509_fingerprint (char *s, int l, X509 * cert){  unsigned char md[EVP_MAX_MD_SIZE];  unsigned int n;  int j;  if (!X509_digest (cert, EVP_md5 (), md, &n))  {    snprintf (s, l, _("[unable to calculate]"));  }  else  {    for (j = 0; j < (int) n; j++)    {      char ch[8];      snprintf (ch, 8, "%02X%s", md[j], (j % 2 ? " " : ""));      safe_strcat (s, l, ch);    }  }}static char *asn1time_to_string (ASN1_UTCTIME *tm){  static char buf[64];  BIO *bio;  strfcpy (buf, _("[invalid date]"), sizeof (buf));    bio = BIO_new (BIO_s_mem());  if (bio)  {    if (ASN1_TIME_print (bio, tm))      (void) BIO_read (bio, buf, sizeof (buf));    BIO_free (bio);  }  return buf;}static int check_certificate_by_signer (X509 *peercert){  X509_STORE_CTX xsc;  X509_STORE *ctx;  int pass = 0;  ctx = X509_STORE_new ();  if (ctx == NULL) return 0;  if (option (OPTSSLSYSTEMCERTS))  {    if (X509_STORE_set_default_paths (ctx))      pass++;    else      dprint (2, (debugfile, "X509_STORE_set_default_paths failed\n"));  }  if (X509_STORE_load_locations (ctx, SslCertFile, NULL))    pass++;  else    dprint (2, (debugfile, "X509_STORE_load_locations_failed\n"));  if (pass == 0)  {    /* nothing to do */    X509_STORE_free (ctx);    return 0;  }  X509_STORE_CTX_init (&xsc, ctx, peercert, NULL);  pass = (X509_verify_cert (&xsc) > 0);#ifdef DEBUG  if (! pass)  {    char buf[SHORT_STRING];    int err;    err = X509_STORE_CTX_get_error (&xsc);    snprintf (buf, sizeof (buf), "%s (%d)", 	X509_verify_cert_error_string(err), err);    dprint (2, (debugfile, "X509_verify_cert: %s\n", buf));  }#endif  X509_STORE_CTX_cleanup (&xsc);  X509_STORE_free (ctx);  return pass;}static int compare_certificates (X509 *cert, X509 *peercert,  unsigned char *peermd, unsigned int peermdlen){  unsigned char md[EVP_MAX_MD_SIZE];  unsigned int mdlen;    /* Avoid CPU-intensive digest calculation if the certificates are    * not even remotely equal.    */  if (X509_subject_name_cmp (cert, peercert) != 0 ||      X509_issuer_name_cmp (cert, peercert) != 0)    return -1;    if (!X509_digest (cert, EVP_sha1(), md, &mdlen) || peermdlen != mdlen)    return -1;    if (memcmp(peermd, md, mdlen) != 0)    return -1;  return 0;}static int check_certificate_cache (X509 *peercert){  unsigned char peermd[EVP_MAX_MD_SIZE];  unsigned int peermdlen;  X509 *cert;  LIST *scert;  if (!X509_digest (peercert, EVP_sha1(), peermd, &peermdlen))  {    return 0;  }    for (scert = SslSessionCerts; scert; scert = scert->next)  {    cert = *(X509**)scert->data;    if (!compare_certificates (cert, peercert, peermd, peermdlen))    {      return 1;    }  }    return 0;}static int check_certificate_by_digest (X509 *peercert){  unsigned char peermd[EVP_MAX_MD_SIZE];  unsigned int peermdlen;  X509 *cert = NULL;  int pass = 0;  FILE *fp;  /* expiration check */  if (X509_cmp_current_time (X509_get_notBefore (peercert)) >= 0)  {    dprint (2, (debugfile, "Server certificate is not yet valid\n"));    mutt_error (_("Server certificate is not yet valid"));    mutt_sleep (2);    return 0;  }  if (X509_cmp_current_time (X509_get_notAfter (peercert)) <= 0)  {    dprint (2, (debugfile, "Server certificate has expired"));    mutt_error (_("Server certificate has expired"));    mutt_sleep (2);    return 0;  }  if ((fp = fopen (SslCertFile, "rt")) == NULL)    return 0;  if (!X509_digest (peercert, EVP_sha1(), peermd, &peermdlen))  {    fclose (fp);    return 0;  }  while ((cert = READ_X509_KEY (fp, &cert)) != NULL)  {    pass = compare_certificates (cert, peercert, peermd, peermdlen) ? 0 : 1;        if (pass)      break;  }  X509_free (cert);  fclose (fp);  return pass;}static int ssl_check_certificate (sslsockdata * data){  char *part[] =  {"/CN=", "/Email=", "/O=", "/OU=", "/L=", "/ST=", "/C="};  char helpstr[SHORT_STRING];  char buf[SHORT_STRING];  MUTTMENU *menu;  int done, row, i;  FILE *fp;  char *name = NULL, *c;  /* check session cache first */  if (check_certificate_cache (data->cert))  {    dprint (1, (debugfile, "ssl_check_certificate: using cached certificate\n"));    return 1;  }  if (check_certificate_by_signer (data->cert))  {    dprint (1, (debugfile, "ssl_check_certificate: signer check passed\n"));    return 1;  }  /* automatic check from user's database */  if (SslCertFile && check_certificate_by_digest (data->cert))  {    dprint (1, (debugfile, "ssl_check_certificate: digest check passed\n"));    return 1;  }  /* interactive check from user */  menu = mutt_new_menu ();  menu->max = 19;  menu->dialog = (char **) safe_calloc (1, menu->max * sizeof (char *));  for (i = 0; i < menu->max; i++)    menu->dialog[i] = (char *) safe_calloc (1, SHORT_STRING * sizeof (char));  row = 0;  strfcpy (menu->dialog[row], _("This certificate belongs to:"), SHORT_STRING);  row++;  name = X509_NAME_oneline (X509_get_subject_name (data->cert),			    buf, sizeof (buf));  for (i = 0; i < 5; i++)  {    c = x509_get_part (name, part[i]);    snprintf (menu->dialog[row++], SHORT_STRING, "   %s", c);  }  row++;  strfcpy (menu->dialog[row], _("This certificate was issued by:"), SHORT_STRING);  row++;  name = X509_NAME_oneline (X509_get_issuer_name (data->cert),			    buf, sizeof (buf));  for (i = 0; i < 5; i++)  {    c = x509_get_part (name, part[i]);    snprintf (menu->dialog[row++], SHORT_STRING, "   %s", c);  }  row++;  snprintf (menu->dialog[row++], SHORT_STRING, _("This certificate is valid"));  snprintf (menu->dialog[row++], SHORT_STRING, _("   from %s"),       asn1time_to_string (X509_get_notBefore (data->cert)));  snprintf (menu->dialog[row++], SHORT_STRING, _("     to %s"),       asn1time_to_string (X509_get_notAfter (data->cert)));  row++;  buf[0] = '\0';  x509_fingerprint (buf, sizeof (buf), data->cert);  snprintf (menu->dialog[row++], SHORT_STRING, _("Fingerprint: %s"), buf);  menu->title = _("SSL Certificate check");  if (SslCertFile && X509_cmp_current_time (X509_get_notAfter (data->cert)) >= 0      && X509_cmp_current_time (X509_get_notBefore (data->cert)) < 0)  {    menu->prompt = _("(r)eject, accept (o)nce, (a)ccept always");    menu->keys = _("roa");  }  else  {    menu->prompt = _("(r)eject, accept (o)nce");    menu->keys = _("ro");  }    helpstr[0] = '\0';  mutt_make_help (buf, sizeof (buf), _("Exit  "), MENU_GENERIC, OP_EXIT);  safe_strcat (helpstr, sizeof (helpstr), buf);  mutt_make_help (buf, sizeof (buf), _("Help"), MENU_GENERIC, OP_HELP);  safe_strcat (helpstr, sizeof (helpstr), buf);  menu->help = helpstr;  done = 0;  set_option(OPTUNBUFFEREDINPUT);  while (!done)  {    switch (mutt_menuLoop (menu))    {      case -1:			/* abort */      case OP_MAX + 1:		/* reject */      case OP_EXIT:        done = 1;        break;      case OP_MAX + 3:		/* accept always */        done = 0;        if ((fp = fopen (SslCertFile, "a")))	{	  if (PEM_write_X509 (fp, data->cert))	    done = 1;	  fclose (fp);	}	if (!done)        {	  mutt_error (_("Warning: Couldn't save certificate"));	  mutt_sleep (2);	}	else        {	  mutt_message (_("Certificate saved"));	  mutt_sleep (0);	}        /* fall through */      case OP_MAX + 2:		/* accept once */        done = 2;        /* keep a handle on accepted certificates in case we want to         * open up another connection to the same server in this session */        SslSessionCerts = mutt_add_list_n (SslSessionCerts, &data->cert,                                           sizeof (X509 **));        break;    }  }  unset_option(OPTUNBUFFEREDINPUT);  mutt_menuDestroy (&menu);  return (done == 2);}static void ssl_get_client_cert(sslsockdata *ssldata, CONNECTION *conn){  if (SslClientCert)  {    dprint (2, (debugfile, "Using client certificate %s\n", SslClientCert));    SSL_CTX_set_default_passwd_cb_userdata(ssldata->ctx, &conn->account);    SSL_CTX_set_default_passwd_cb(ssldata->ctx, ssl_passwd_cb);    SSL_CTX_use_certificate_file(ssldata->ctx, SslClientCert, SSL_FILETYPE_PEM);    SSL_CTX_use_PrivateKey_file(ssldata->ctx, SslClientCert, SSL_FILETYPE_PEM);  }}static int ssl_passwd_cb(char *buf, int size, int rwflag, void *userdata){  ACCOUNT *account = (ACCOUNT*)userdata;  if (mutt_account_getuser (account))    return 0;  dprint (2, (debugfile, "ssl_passwd_cb: getting password for %s@%s:%u\n",	      account->user, account->host, account->port));    if (mutt_account_getpass (account))    return 0;  return snprintf(buf, size, "%s", account->pass);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -