* If someone does it'd probably be trivial to write mutt_nss_get_ssf().
* I have a feeling more SSL code could be shared between those two files,
* but I haven't looked into it yet, since I still don't know the APIs. */
-#if defined(USE_SSL) && !defined(USE_NSS)
- if (conn->account.flags & M_ACCT_SSL)
+#if defined(USE_SSL)
+ if (conn->ssf)
{
#ifdef USE_SASL2 /* I'm not sure this actually has an effect, at least with SASLv2 */
dprint (2, (debugfile, "External SSF: %d\n", conn->ssf));
return -1;
}
#ifdef USE_SASL2
- dprint (2, (debugfile, "External authentication name: %s\n","NULL"));
- if (sasl_setprop (*saslconn, SASL_AUTH_EXTERNAL, NULL) != SASL_OK)
+ dprint (2, (debugfile, "External authentication name: %s\n", conn->account.user));
+ if (sasl_setprop (*saslconn, SASL_AUTH_EXTERNAL, conn->account.user) != SASL_OK)
{
dprint (1, (debugfile, "mutt_sasl_client_new: Error setting external properties\n"));
return -1;
/* 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. */
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"));
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);
/* 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;
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");
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);
+}