X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=mutt_ssl.c;h=8739a801606552f62f9d17cc380d7285d7460576;hp=1f847a4cff168add261449f5d7f11907a6119624;hb=170b2f011c6e3616b24ae69bd181c4915ba6eb67;hpb=6833ce8bdca2d64e14485118f2a4417b7e1cb1b1 diff --git a/mutt_ssl.c b/mutt_ssl.c index 1f847a4..8739a80 100644 --- a/mutt_ssl.c +++ b/mutt_ssl.c @@ -68,13 +68,15 @@ sslsockdata; /* local prototypes */ int ssl_init (void); static int add_entropy (const char *file); -static int ssl_check_certificate (sslsockdata * data); static int ssl_socket_read (CONNECTION* conn, char* buf, size_t len); static int ssl_socket_write (CONNECTION* conn, const char* buf, size_t len); static int ssl_socket_open (CONNECTION * conn); static int ssl_socket_close (CONNECTION * conn); static int tls_close (CONNECTION* conn); -int ssl_negotiate (sslsockdata*); +static int ssl_check_certificate (sslsockdata * data); +static void ssl_get_client_cert(sslsockdata *ssldata, CONNECTION *conn); +static int ssl_passwd_cb(char *buf, int size, int rwflag, void *userdata); +static int ssl_negotiate (sslsockdata*); /* mutt_ssl_starttls: Negotiate TLS over an already opened connection. * TODO: Merge this code better with ssl_socket_open. */ @@ -94,6 +96,8 @@ int mutt_ssl_starttls (CONNECTION* conn) goto bail_ssldata; } + ssl_get_client_cert(ssldata, conn); + if (! (ssldata->ssl = SSL_new (ssldata->ctx))) { dprint (1, (debugfile, "mutt_ssl_starttls: Error allocating SSL\n")); @@ -279,6 +283,8 @@ static int ssl_socket_open (CONNECTION * conn) SSL_CTX_set_options(data->ctx, SSL_OP_NO_SSLv3); } + ssl_get_client_cert(data, conn); + data->ssl = SSL_new (data->ctx); SSL_set_fd (data->ssl, conn->fd); @@ -296,7 +302,7 @@ static int ssl_socket_open (CONNECTION * conn) /* ssl_negotiate: After SSL state has been initialised, attempt to negotiate * SSL over the wire, including certificate checks. */ -int ssl_negotiate (sslsockdata* ssldata) +static int ssl_negotiate (sslsockdata* ssldata) { int err; const char* errmsg; @@ -315,7 +321,7 @@ int ssl_negotiate (sslsockdata* ssldata) errmsg = _("I/O error"); break; case SSL_ERROR_SSL: - errmsg = _("unspecified protocol error"); + errmsg = ERR_error_string (ERR_get_error (), NULL); break; default: errmsg = _("unknown error"); @@ -403,7 +409,7 @@ static void x509_fingerprint (char *s, int l, X509 * cert) if (!X509_digest (cert, EVP_md5 (), md, &n)) { - snprintf (s, l, _("[unable to calculate]")); + snprintf (s, l, "%s", _("[unable to calculate]")); } else { @@ -411,7 +417,7 @@ static void x509_fingerprint (char *s, int l, X509 * cert) { char ch[8]; snprintf (ch, 8, "%02X%s", md[j], (j % 2 ? " " : "")); - strncat (s, ch, l); + safe_strcat (s, l, ch); } } } @@ -598,7 +604,7 @@ static int ssl_check_certificate (sslsockdata * data) } row++; - snprintf (menu->dialog[row++], SHORT_STRING, _("This certificate is valid")); + snprintf (menu->dialog[row++], SHORT_STRING, "%s", _("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"), @@ -623,9 +629,9 @@ static int ssl_check_certificate (sslsockdata * data) helpstr[0] = '\0'; mutt_make_help (buf, sizeof (buf), _("Exit "), MENU_GENERIC, OP_EXIT); - strncat (helpstr, buf, sizeof (helpstr)); + safe_strcat (helpstr, sizeof (helpstr), buf); mutt_make_help (buf, sizeof (buf), _("Help"), MENU_GENERIC, OP_HELP); - strncat (helpstr, buf, sizeof (helpstr)); + safe_strcat (helpstr, sizeof (helpstr), buf); menu->help = helpstr; done = 0; @@ -667,3 +673,31 @@ static int ssl_check_certificate (sslsockdata * data) 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); +}