aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGilles Chehade <gilles@poolp.org>2018-12-20 20:42:44 +0100
committerGilles Chehade <gilles@poolp.org>2018-12-20 20:42:44 +0100
commit6ff5d981ef950ce43909eb8b623729118cd89ffc (patch)
tree4684188f49102d54609c010be98fc448a53690ef
parentsync (diff)
downloadOpenSMTPD-6ff5d981ef950ce43909eb8b623729118cd89ffc.tar.xz
OpenSMTPD-6ff5d981ef950ce43909eb8b623729118cd89ffc.zip
sync
-rw-r--r--smtpd/mta_session.c114
-rw-r--r--smtpd/smtp_session.c22
-rw-r--r--smtpd/ssl.c4
3 files changed, 128 insertions, 12 deletions
diff --git a/smtpd/mta_session.c b/smtpd/mta_session.c
index 644cac17..755ac86d 100644
--- a/smtpd/mta_session.c
+++ b/smtpd/mta_session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mta_session.c,v 1.113 2018/10/31 15:13:21 gilles Exp $ */
+/* $OpenBSD: mta_session.c,v 1.114 2018/12/17 11:14:56 eric Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -150,6 +150,10 @@ static void mta_response(struct mta_session *, char *);
static const char * mta_strstate(int);
static void mta_start_tls(struct mta_session *);
static int mta_verify_certificate(struct mta_session *);
+static void mta_cert_init(struct mta_session *);
+static void mta_cert_init_cb(void *, int, const char *, const void *, size_t);
+static void mta_cert_verify(struct mta_session *);
+static void mta_cert_verify_cb(void *, int);
static void mta_tls_verified(struct mta_session *);
static struct mta_session *mta_tree_pop(struct tree *, uint64_t);
static const char * dsn_strret(enum dsn_ret);
@@ -937,7 +941,7 @@ mta_response(struct mta_session *s, char *line)
return;
}
- mta_start_tls(s);
+ mta_cert_init(s);
break;
case MTA_AUTH_PLAIN:
@@ -1149,7 +1153,7 @@ mta_io(struct io *io, int evt, void *arg)
if (s->use_smtps) {
io_set_write(io);
- mta_start_tls(s);
+ mta_cert_init(s);
}
else {
mta_enter_state(s, MTA_BANNER);
@@ -1162,12 +1166,7 @@ mta_io(struct io *io, int evt, void *arg)
s->id, ssl_to_text(io_ssl(s->io)));
s->flags |= MTA_TLS;
- if (mta_verify_certificate(s)) {
- io_pause(s->io, IO_IN);
- break;
- }
-
- mta_tls_verified(s);
+ mta_cert_verify(s);
break;
case IO_DATAIN:
@@ -1656,6 +1655,103 @@ mta_verify_certificate(struct mta_session *s)
}
static void
+mta_cert_init(struct mta_session *s)
+{
+ const char *name;
+ int fallback;
+
+ if (s->relay->pki_name) {
+ name = s->relay->pki_name;
+ fallback = 0;
+ }
+ else {
+ name = s->helo;
+ fallback = 1;
+ }
+
+ if (cert_init(name, fallback, mta_cert_init_cb, s)) {
+ tree_xset(&wait_ssl_init, s->id, s);
+ s->flags |= MTA_WAIT;
+ }
+}
+
+static void
+mta_cert_init_cb(void *arg, int status, const char *name, const void *cert,
+ size_t cert_len)
+{
+ struct mta_session *s = arg;
+ void *ssl;
+ char *xname = NULL, *xcert = NULL;
+
+ if (s->flags & MTA_WAIT)
+ mta_tree_pop(&wait_ssl_init, s->id);
+
+ if (status == CA_FAIL && s->relay->pki_name) {
+ log_info("%016"PRIx64" mta closing reason=ca-failure", s->id);
+ mta_free(s);
+ return;
+ }
+
+ if (name)
+ xname = xstrdup(name);
+ if (cert)
+ xcert = xmemdup(cert, cert_len);
+ ssl = ssl_mta_init(xname, xcert, cert_len, env->sc_tls_ciphers);
+ free(xname);
+ free(xcert);
+ if (ssl == NULL)
+ fatal("mta: ssl_mta_init");
+ io_start_tls(s->io, ssl);
+}
+
+static void
+mta_cert_verify(struct mta_session *s)
+{
+ const char *name;
+ int fallback;
+
+ if (s->relay->ca_name) {
+ name = s->relay->ca_name;
+ fallback = 0;
+ }
+ else {
+ name = s->helo;
+ fallback = 1;
+ }
+
+ if (cert_verify(io_ssl(s->io), name, fallback, mta_cert_verify_cb, s)) {
+ tree_xset(&wait_ssl_verify, s->id, s);
+ io_pause(s->io, IO_IN);
+ s->flags |= MTA_WAIT;
+ }
+}
+
+static void
+mta_cert_verify_cb(void *arg, int status)
+{
+ struct mta_session *s = arg;
+ int resume = 0;
+
+ if (s->flags & MTA_WAIT) {
+ mta_tree_pop(&wait_ssl_verify, s->id);
+ resume = 1;
+ }
+
+ if (status == CERT_OK)
+ s->flags |= MTA_TLS_VERIFIED;
+ else if (s->relay->flags & RELAY_TLS_VERIFY) {
+ errno = 0;
+ mta_error(s, "SSL certificate check failed");
+ mta_free(s);
+ return;
+ }
+
+ mta_tls_verified(s);
+ if (resume)
+ io_resume(s->io, IO_IN);
+}
+
+static void
mta_tls_verified(struct mta_session *s)
{
X509 *x;
diff --git a/smtpd/smtp_session.c b/smtpd/smtp_session.c
index 6928a5ce..80d6ab5c 100644
--- a/smtpd/smtp_session.c
+++ b/smtpd/smtp_session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtp_session.c,v 1.375 2018/12/14 09:18:03 eric Exp $ */
+/* $OpenBSD: smtp_session.c,v 1.376 2018/12/20 17:57:44 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -1314,18 +1314,26 @@ smtp_command(struct smtp_session *s, char *line)
* ANY
*/
case CMD_QUIT:
+ if (!smtp_check_noparam(s, args))
+ break;
smtp_filter_phase(FILTER_QUIT, s, NULL);
break;
case CMD_NOOP:
+ if (!smtp_check_noparam(s, args))
+ break;
smtp_filter_phase(FILTER_NOOP, s, NULL);
break;
case CMD_HELP:
+ if (!smtp_check_noparam(s, args))
+ break;
smtp_proceed_help(s, NULL);
break;
case CMD_WIZ:
+ if (!smtp_check_noparam(s, args))
+ break;
smtp_proceed_wiz(s, NULL);
break;
@@ -1340,6 +1348,9 @@ smtp_command(struct smtp_session *s, char *line)
static int
smtp_check_rset(struct smtp_session *s, const char *args)
{
+ if (!smtp_check_noparam(s, args))
+ return 0;
+
if (s->helo[0] == '\0') {
smtp_reply(s, "503 %s %s: Command not allowed at this point.",
esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
@@ -1547,6 +1558,9 @@ smtp_check_rcpt_to(struct smtp_session *s, const char *args)
static int
smtp_check_data(struct smtp_session *s, const char *args)
{
+ if (!smtp_check_noparam(s, args))
+ return 0;
+
if (s->tx == NULL) {
smtp_reply(s, "503 %s %s: Command not allowed at this point.",
esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
@@ -1567,6 +1581,12 @@ smtp_check_data(struct smtp_session *s, const char *args)
static int
smtp_check_noparam(struct smtp_session *s, const char *args)
{
+ if (args != NULL) {
+ smtp_reply(s, "500 %s %s: command does not accept arguments.",
+ esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS),
+ esc_description(ESC_INVALID_COMMAND_ARGUMENTS));
+ return 0;
+ }
return 1;
}
diff --git a/smtpd/ssl.c b/smtpd/ssl.c
index cd29f5cf..7cbee563 100644
--- a/smtpd/ssl.c
+++ b/smtpd/ssl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl.c,v 1.89 2017/05/17 14:00:06 deraadt Exp $ */
+/* $OpenBSD: ssl.c,v 1.90 2018/12/20 19:40:13 gilles Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -328,7 +328,7 @@ ssl_to_text(const SSL *ssl)
{
static char buf[256];
- (void)snprintf(buf, sizeof buf, "version=%s, cipher=%s, bits=%d",
+ (void)snprintf(buf, sizeof buf, "%s:%s:%d",
SSL_get_version(ssl),
SSL_get_cipher_name(ssl),
SSL_get_cipher_bits(ssl, NULL));