summaryrefslogtreecommitdiff
path: root/usr.sbin/smtpd
diff options
context:
space:
mode:
authorGilles Chehade <gilles@cvs.openbsd.org>2015-12-12 20:02:32 +0000
committerGilles Chehade <gilles@cvs.openbsd.org>2015-12-12 20:02:32 +0000
commit921ca576c5940a00b46b54ae0bc24d8d1fae52d7 (patch)
treecf54e545e94d1974105ca8b9ab2edd180771a732 /usr.sbin/smtpd
parent3e352dbd304a287e139549b2b95547719a070d8c (diff)
remove CA from pki and no longer allow specifying a CA with 'pki' keyword.
introduce 'ca' keyword to allow specifying a custom CA. making CA part of pki was a bad idea and several people hit use-cases that plain couldn't work. instead of: pki foobar.org ca "/etc/mail/CA.pem" use now: ca foobar.org certificate "/etc/mail/CA.pem" ok sunil@, jung@
Diffstat (limited to 'usr.sbin/smtpd')
-rw-r--r--usr.sbin/smtpd/lka.c19
-rw-r--r--usr.sbin/smtpd/mta.c14
-rw-r--r--usr.sbin/smtpd/mta_session.c14
-rw-r--r--usr.sbin/smtpd/parse.y5
-rw-r--r--usr.sbin/smtpd/smtp_session.c28
-rw-r--r--usr.sbin/smtpd/smtpd.c11
-rw-r--r--usr.sbin/smtpd/smtpd.conf.512
-rw-r--r--usr.sbin/smtpd/ssl.c8
-rw-r--r--usr.sbin/smtpd/ssl.h8
9 files changed, 60 insertions, 59 deletions
diff --git a/usr.sbin/smtpd/lka.c b/usr.sbin/smtpd/lka.c
index 1d2093823b5..7247a4042d3 100644
--- a/usr.sbin/smtpd/lka.c
+++ b/usr.sbin/smtpd/lka.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lka.c,v 1.187 2015/12/12 14:06:08 gilles Exp $ */
+/* $OpenBSD: lka.c,v 1.188 2015/12/12 20:02:31 gilles Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -155,6 +155,7 @@ lka_imsg(struct mproc *p, struct imsg *imsg)
}
resp_ca_cert.status = CA_OK;
resp_ca_cert.cert_len = pki->pki_cert_len;
+ (void)strlcpy(resp_ca_cert.name, pki->pki_name, sizeof resp_ca_cert.name);
iov[0].iov_base = &resp_ca_cert;
iov[0].iov_len = sizeof(resp_ca_cert);
iov[1].iov_base = pki->pki_cert;
@@ -686,16 +687,20 @@ static void
lka_certificate_verify_resume(enum imsg_type type, struct ca_vrfy_req_msg *req)
{
struct ca_vrfy_resp_msg resp;
- struct pki *pki;
+ struct ca *sca;
const char *cafile;
size_t i;
resp.reqid = req->reqid;
- pki = dict_get(env->sc_pki_dict, req->name);
- cafile = CA_FILE;
- if (pki && pki->pki_ca_file)
- cafile = pki->pki_ca_file;
- if (! lka_X509_verify(req, cafile, NULL))
+ sca = dict_get(env->sc_ca_dict, req->name);
+ if (sca == NULL)
+ if (req->fallback)
+ sca = dict_get(env->sc_ca_dict, "*");
+ cafile = sca ? sca->ca_cert_file : CA_FILE;
+
+ if (sca == NULL && !req->fallback)
+ resp.status = CA_FAIL;
+ else if (! lka_X509_verify(req, cafile, NULL))
resp.status = CA_FAIL;
else
resp.status = CA_OK;
diff --git a/usr.sbin/smtpd/mta.c b/usr.sbin/smtpd/mta.c
index 3b32362098c..276a4ccf271 100644
--- a/usr.sbin/smtpd/mta.c
+++ b/usr.sbin/smtpd/mta.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mta.c,v 1.196 2015/12/01 10:48:21 gilles Exp $ */
+/* $OpenBSD: mta.c,v 1.197 2015/12/12 20:02:31 gilles Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -1648,6 +1648,9 @@ mta_relay(struct envelope *e)
key.pki_name = e->agent.mta.relay.pki_name;
if (!key.pki_name[0])
key.pki_name = NULL;
+ key.ca_name = e->agent.mta.relay.ca_name;
+ if (!key.ca_name[0])
+ key.ca_name = NULL;
key.authtable = e->agent.mta.relay.authtable;
if (!key.authtable[0])
key.authtable = NULL;
@@ -1675,6 +1678,7 @@ mta_relay(struct envelope *e)
r->backuppref = -1;
r->port = key.port;
r->pki_name = key.pki_name ? xstrdup(key.pki_name, "mta: pki_name") : NULL;
+ r->ca_name = key.ca_name ? xstrdup(key.ca_name, "mta: ca_name") : NULL;
if (key.authtable)
r->authtable = xstrdup(key.authtable, "mta: authtable");
if (key.authlabel)
@@ -1730,6 +1734,7 @@ mta_relay_unref(struct mta_relay *relay)
free(relay->authtable);
free(relay->backupname);
free(relay->pki_name);
+ free(relay->ca_name);
free(relay->helotable);
free(relay->heloname);
free(relay->secret);
@@ -1960,6 +1965,13 @@ mta_relay_cmp(const struct mta_relay *a, const struct mta_relay *b)
if (a->pki_name && ((r = strcmp(a->pki_name, b->pki_name))))
return (r);
+ if (a->ca_name == NULL && b->ca_name)
+ return (-1);
+ if (a->ca_name && b->ca_name == NULL)
+ return (1);
+ if (a->ca_name && ((r = strcmp(a->ca_name, b->ca_name))))
+ return (r);
+
if (a->backupname && ((r = strcmp(a->backupname, b->backupname))))
return (r);
diff --git a/usr.sbin/smtpd/mta_session.c b/usr.sbin/smtpd/mta_session.c
index 7856f0b4298..ee36679e531 100644
--- a/usr.sbin/smtpd/mta_session.c
+++ b/usr.sbin/smtpd/mta_session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mta_session.c,v 1.81 2015/12/12 17:16:56 gilles Exp $ */
+/* $OpenBSD: mta_session.c,v 1.82 2015/12/12 20:02:31 gilles Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -259,7 +259,6 @@ mta_session_imsg(struct mproc *p, struct imsg *imsg)
const char *name;
void *ssl;
int dnserror, status;
- char *pkiname;
switch (imsg->hdr.type) {
@@ -337,11 +336,7 @@ mta_session_imsg(struct mproc *p, struct imsg *imsg)
resp_ca_cert = xmemdup(imsg->data, sizeof *resp_ca_cert, "mta:ca_cert");
resp_ca_cert->cert = xstrdup((char *)imsg->data +
sizeof *resp_ca_cert, "mta:ca_cert");
- if (s->relay->pki_name)
- pkiname = s->relay->pki_name;
- else
- pkiname = s->helo;
- ssl = ssl_mta_init(pkiname,
+ ssl = ssl_mta_init(resp_ca_cert->name,
resp_ca_cert->cert, resp_ca_cert->cert_len, env->sc_tls_ciphers);
if (ssl == NULL)
fatal("mta: ssl_mta_init");
@@ -1572,8 +1567,9 @@ mta_verify_certificate(struct mta_session *s)
memset(cert_der, 0, sizeof(cert_der));
memset(&req_ca_vrfy, 0, sizeof req_ca_vrfy);
- if (s->relay->pki_name) {
- name = s->relay->pki_name;
+ /* Send the client certificate */
+ if (s->relay->ca_name) {
+ name = s->relay->ca_name;
req_ca_vrfy.fallback = 0;
}
else {
diff --git a/usr.sbin/smtpd/parse.y b/usr.sbin/smtpd/parse.y
index efabbf246af..58ec5d6679b 100644
--- a/usr.sbin/smtpd/parse.y
+++ b/usr.sbin/smtpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.176 2015/12/12 18:52:23 gilles Exp $ */
+/* $OpenBSD: parse.y,v 1.177 2015/12/12 20:02:31 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -394,9 +394,6 @@ opt_pki : CERTIFICATE STRING {
| KEY STRING {
pki->pki_key_file = $2;
}
- | CA STRING {
- pki->pki_ca_file = $2;
- }
| DHPARAMS STRING {
pki->pki_dhparams_file = $2;
}
diff --git a/usr.sbin/smtpd/smtp_session.c b/usr.sbin/smtpd/smtp_session.c
index 18357eb4f51..3410a9491b2 100644
--- a/usr.sbin/smtpd/smtp_session.c
+++ b/usr.sbin/smtpd/smtp_session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtp_session.c,v 1.258 2015/12/12 18:49:38 gilles Exp $ */
+/* $OpenBSD: smtp_session.c,v 1.259 2015/12/12 20:02:31 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -714,7 +714,6 @@ smtp_session_imsg(struct mproc *p, struct imsg *imsg)
struct smtp_session *s;
struct smtp_rcpt *rcpt;
void *ssl;
- char *pkiname;
char user[LOGIN_NAME_MAX];
struct msg m;
const char *line, *helo;
@@ -1040,12 +1039,7 @@ smtp_session_imsg(struct mproc *p, struct imsg *imsg)
resp_ca_cert = xmemdup(imsg->data, sizeof *resp_ca_cert, "smtp:ca_cert");
resp_ca_cert->cert = xstrdup((char *)imsg->data +
sizeof *resp_ca_cert, "smtp:ca_cert");
- if (s->listener->pki_name[0])
- pkiname = s->listener->pki_name;
- else
- pkiname = s->smtpname;
- ssl_ctx = dict_get(env->sc_ssl_dict, pkiname);
-
+ ssl_ctx = dict_get(env->sc_ssl_dict, resp_ca_cert->name);
ssl = ssl_smtp_init(ssl_ctx, smtp_sni_callback,
s->listener->flags & F_TLS_VERIFY);
io_set_read(&s->io);
@@ -2286,7 +2280,7 @@ smtp_verify_certificate(struct smtp_session *s)
struct iovec iov[2];
X509 *x;
STACK_OF(X509) *xchain;
- const char *pkiname;
+ const char *name;
unsigned char *cert_der[MAX_CERTS];
int cert_len[MAX_CERTS];
int i, cert_count, res;
@@ -2295,11 +2289,17 @@ smtp_verify_certificate(struct smtp_session *s)
memset(cert_der, 0, sizeof(cert_der));
memset(&req_ca_vrfy, 0, sizeof req_ca_vrfy);
- if (s->listener->pki_name[0])
- pkiname = s->listener->pki_name;
- else
- pkiname = s->smtpname;
- if (strlcpy(req_ca_vrfy.name, pkiname, sizeof req_ca_vrfy.name)
+ /* Send the client certificate */
+ if (s->listener->ca_name[0]) {
+ name = s->listener->ca_name;
+ req_ca_vrfy.fallback = 0;
+ }
+ else {
+ name = s->smtpname;
+ req_ca_vrfy.fallback = 1;
+ }
+
+ if (strlcpy(req_ca_vrfy.name, name, sizeof req_ca_vrfy.name)
>= sizeof req_ca_vrfy.name)
return 0;
diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c
index 94cf4843cac..0e0e37f760b 100644
--- a/usr.sbin/smtpd/smtpd.c
+++ b/usr.sbin/smtpd/smtpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.c,v 1.265 2015/12/12 11:31:29 sunil Exp $ */
+/* $OpenBSD: smtpd.c,v 1.266 2015/12/12 20:02:31 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -730,9 +730,6 @@ load_pki_tree(void)
if (! ssl_load_certificate(pki, pki->pki_cert_file))
fatalx("load_pki_tree: failed to load certificate file");
- if (pki->pki_ca_file)
- if (! ssl_load_cafile(pki, pki->pki_ca_file))
- fatalx("load_pki_tree: failed to load CA file");
if (pki->pki_dhparams_file)
if (! ssl_load_dhparams(pki, pki->pki_dhparams_file))
fatalx("load_pki_tree: failed to load dhparams file");
@@ -742,10 +739,8 @@ load_pki_tree(void)
iter_dict = NULL;
while (dict_iter(env->sc_ca_dict, &iter_dict, &k, (void **)&sca)) {
log_debug("info: loading CA information for %s", k);
- /*
- * if (! ssl_load_cafile(sca, sca->ca_cert_file))
- * fatalx("load_pki_tree: failed to load CA file");
- */
+ if (! ssl_load_cafile(sca, sca->ca_cert_file))
+ fatalx("load_pki_tree: failed to load CA file");
}
}
diff --git a/usr.sbin/smtpd/smtpd.conf.5 b/usr.sbin/smtpd/smtpd.conf.5
index 011a859b444..c59942bdb74 100644
--- a/usr.sbin/smtpd/smtpd.conf.5
+++ b/usr.sbin/smtpd/smtpd.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: smtpd.conf.5,v 1.141 2015/12/12 18:49:38 gilles Exp $
+.\" $OpenBSD: smtpd.conf.5,v 1.142 2015/12/12 20:02:31 gilles Exp $
.\"
.\" Copyright (c) 2008 Janne Johansson <jj@openbsd.org>
.\" Copyright (c) 2009 Jacek Masiulaniec <jacekm@dobremiasto.net>
@@ -570,6 +570,11 @@ bounce-warn 1h, 6h, 2d
will generate a failure report when an envelope is in the queue for more
than one hour, six hours and two days.
The default is 4h.
+.It Ic ca Ar hostname Ic ca Ar cafile
+Associate a custom CA certificate located in
+.Ar cafile
+with
+.Ar hostname .
.It Xo
.Ic ciphers Ar cipher-list
.Xc
@@ -793,11 +798,6 @@ Associate the key located in
.Ar keyfile
with
.Ar hostname .
-.It Ic pki Ar hostname Ic ca Ar cafile
-Associate a custom CA certificate
-.Ar cafile
-with
-.Ar hostname .
.It Ic pki Ar hostname Ic dhparams Ar dhfile
Associate the Diffie-Hellman parameters located in
.Ar dhfile
diff --git a/usr.sbin/smtpd/ssl.c b/usr.sbin/smtpd/ssl.c
index f9f7ce4f800..6699fb7f05b 100644
--- a/usr.sbin/smtpd/ssl.c
+++ b/usr.sbin/smtpd/ssl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl.c,v 1.83 2015/12/12 18:30:39 gilles Exp $ */
+/* $OpenBSD: ssl.c,v 1.84 2015/12/12 20:02:31 gilles Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -321,10 +321,10 @@ ssl_load_keyfile(struct pki *p, const char *pathname, const char *pkiname)
}
int
-ssl_load_cafile(struct pki *p, const char *pathname)
+ssl_load_cafile(struct ca *c, const char *pathname)
{
- p->pki_ca = ssl_load_file(pathname, &p->pki_ca_len, 0755);
- if (p->pki_ca == NULL)
+ c->ca_cert = ssl_load_file(pathname, &c->ca_cert_len, 0755);
+ if (c->ca_cert == NULL)
return 0;
return 1;
}
diff --git a/usr.sbin/smtpd/ssl.h b/usr.sbin/smtpd/ssl.h
index 30e73ac9bb6..01586f3cf63 100644
--- a/usr.sbin/smtpd/ssl.h
+++ b/usr.sbin/smtpd/ssl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl.h,v 1.17 2015/12/12 17:16:56 gilles Exp $ */
+/* $OpenBSD: ssl.h,v 1.18 2015/12/12 20:02:31 gilles Exp $ */
/*
* Copyright (c) 2013 Gilles Chehade <gilles@poolp.org>
*
@@ -21,10 +21,6 @@
struct pki {
char pki_name[HOST_NAME_MAX+1];
- char *pki_ca_file;
- char *pki_ca;
- off_t pki_ca_len;
-
char *pki_cert_file;
char *pki_cert;
off_t pki_cert_len;
@@ -63,7 +59,7 @@ void ssl_error(const char *);
int ssl_load_certificate(struct pki *, const char *);
int ssl_load_keyfile(struct pki *, const char *, const char *);
-int ssl_load_cafile(struct pki *, const char *);
+int ssl_load_cafile(struct ca *, const char *);
int ssl_load_dhparams(struct pki *, const char *);
int ssl_load_pkey(const void *, size_t, char *, off_t,
X509 **, EVP_PKEY **);