summaryrefslogtreecommitdiffstats
path: root/smtp-tls.c
diff options
context:
space:
mode:
authorPawel Salek <pawsa@fedorapeople.org>2010-03-05 21:22:15 +0100
committerPawel Salek <pawsa@fedorapeople.org>2010-03-05 21:22:15 +0100
commit0cc409a44cac5ac29d0bd18fa13a4e9f2b2f2b96 (patch)
tree5a54b7a2e3f0d767cbf587212c95897b8310a28b /smtp-tls.c
parent5d3cf8a33ced580af0d3e30b8fbd3cf9a5aa315a (diff)
downloadlibesmtp-0cc409a44cac5ac29d0bd18fa13a4e9f2b2f2b96.tar.gz
libesmtp-0cc409a44cac5ac29d0bd18fa13a4e9f2b2f2b96.tar.xz
libesmtp-0cc409a44cac5ac29d0bd18fa13a4e9f2b2f2b96.zip
Implement submission to smtps service.
* examples/mail-file.c: allow testing submission to smtps service. * libesmtp-private.h: add negotiate_ssl() prototype. * libesmtp.h: add Starttls_OVER_SSL to starttls_option enum. * protocol.h: enable SSL on connection whenever selected. * smtp-tls.c: share negotiate_ssl().
Diffstat (limited to 'smtp-tls.c')
-rw-r--r--smtp-tls.c86
1 files changed, 52 insertions, 34 deletions
diff --git a/smtp-tls.c b/smtp-tls.c
index a42e8f5..f51cfad 100644
--- a/smtp-tls.c
+++ b/smtp-tls.c
@@ -419,9 +419,11 @@ select_starttls (smtp_session_t session)
storage to record this for future sessions. */
/* if (...)
session->starttls_enabled = Starttls_REQUIRED; */
- if (!(session->extensions & EXT_STARTTLS))
+ if (session->starttls_enabled == Starttls_DISABLED)
return 0;
- if (!session->starttls_enabled)
+ if ( (session->starttls_enabled == Starttls_ENABLED ||
+ session->starttls_enabled == Starttls_REQUIRED) &&
+ !(session->extensions & EXT_STARTTLS))
return 0;
#ifdef USE_PTHREADS
pthread_mutex_lock (&starttls_mutex);
@@ -589,9 +591,10 @@ check_acceptable_security (smtp_session_t session, SSL *ssl)
if (!ok)
{
/* Matching by subjectAltName failed, try commonName */
- X509_NAME_get_text_by_NID (X509_get_subject_name (cert),
- NID_commonName, buf, sizeof buf);
- if (!match_domain (session->host, buf) != 0)
+ int l = X509_NAME_get_text_by_NID (X509_get_subject_name (cert),
+ NID_commonName, buf, sizeof buf);
+ if (l != strlen(buf) ||
+ !match_domain (session->host, buf) != 0)
{
if (session->event_cb != NULL)
(*session->event_cb) (session, SMTP_EV_WRONG_PEER_CERTIFICATE,
@@ -605,35 +608,14 @@ check_acceptable_security (smtp_session_t session, SSL *ssl)
return ok;
}
-void
-cmd_starttls (siobuf_t conn, smtp_session_t session)
-{
- sio_write (conn, "STARTTLS\r\n", -1);
- session->cmd_state = -1;
-}
-
-void
-rsp_starttls (siobuf_t conn, smtp_session_t session)
+int
+negotiate_ssl (siobuf_t conn, smtp_session_t session)
{
- int code;
SSL *ssl;
X509 *cert;
char buf[256];
- code = read_smtp_response (conn, session, &session->mta_status, NULL);
- if (code < 0)
- {
- session->rsp_state = S_quit;
- return;
- }
-
- if (code != 2)
- {
- if (code != 4 && code != 5)
- set_error (SMTP_ERR_INVALID_RESPONSE_STATUS);
- session->rsp_state = S_quit;
- }
- else if (sio_set_tlsclient_ssl (conn, (ssl = starttls_create_ssl (session))))
+ if (sio_set_tlsclient_ssl (conn, (ssl = starttls_create_ssl (session))))
{
session->using_tls = 1;
@@ -643,7 +625,7 @@ rsp_starttls (siobuf_t conn, smtp_session_t session)
destroy_auth_mechanisms (session);
if (!check_acceptable_security (session, ssl))
- session->rsp_state = S_quit;
+ return -1;
else
{
if (session->event_cb != NULL)
@@ -663,16 +645,52 @@ rsp_starttls (siobuf_t conn, smtp_session_t session)
if (session->auth_context != NULL)
auth_set_external_id (session->auth_context, buf);
}
-
- /* Next state is EHLO */
- session->rsp_state = S_ehlo;
+
}
+ return 0;
+ } else
+ return -2;
+}
+
+void
+cmd_starttls (siobuf_t conn, smtp_session_t session)
+{
+ sio_write (conn, "STARTTLS\r\n", -1);
+ session->cmd_state = -1;
+}
+
+void
+rsp_starttls (siobuf_t conn, smtp_session_t session)
+{
+ int code;
+
+ code = read_smtp_response (conn, session, &session->mta_status, NULL);
+ if (code < 0)
+ {
+ session->rsp_state = S_quit;
+ return;
}
- else
+
+ if (code != 2)
{
+ if (code != 4 && code != 5)
+ set_error (SMTP_ERR_INVALID_RESPONSE_STATUS);
+ session->rsp_state = S_quit;
+ }
+ else {
+ switch (negotiate_ssl (conn, session) ) {
+ case 0:
+ /* Next state is EHLO */
+ session->rsp_state = S_ehlo;
+ break;
+ case -1:
+ session->rsp_state = S_quit;
+ break;
+ default: /* -2 */
set_error (SMTP_ERR_CLIENT_ERROR);
session->rsp_state = -1;
}
+ }
}
#else