summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreric <eric@openbsd.org>2018-09-20 11:42:28 +0000
committereric <eric@openbsd.org>2018-09-20 11:42:28 +0000
commit43ddfbdb2dafc46cc9d4b54b7369d8155d41cb80 (patch)
tree8ed70bb98164a65501cf4174dc3f395c94088d3c
parentfix indentation (diff)
downloadwireguard-openbsd-43ddfbdb2dafc46cc9d4b54b7369d8155d41cb80.tar.xz
wireguard-openbsd-43ddfbdb2dafc46cc9d4b54b7369d8155d41cb80.zip
properly handle credentials and fix auth in smtp(1)
ok gilles@
-rw-r--r--usr.sbin/smtpd/smtp.h5
-rw-r--r--usr.sbin/smtpd/smtp_client.c69
-rw-r--r--usr.sbin/smtpd/smtpc.c12
3 files changed, 55 insertions, 31 deletions
diff --git a/usr.sbin/smtpd/smtp.h b/usr.sbin/smtpd/smtp.h
index 16fa459cfe4..a5eded2ff1e 100644
--- a/usr.sbin/smtpd/smtp.h
+++ b/usr.sbin/smtpd/smtp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtp.h,v 1.1 2018/04/26 13:57:13 eric Exp $ */
+/* $OpenBSD: smtp.h,v 1.2 2018/09/20 11:42:28 eric Exp $ */
/*
* Copyright (c) 2018 Eric Faurot <eric@openbsd.org>
@@ -51,7 +51,8 @@ struct smtp_params {
/* SMTP options */
int lmtp; /* use LMTP protocol */
const char *helo; /* string to use with HELO */
- const char *auth; /* credentials for AUTH */
+ const char *auth_user; /* for AUTH */
+ const char *auth_pass; /* for AUTH */
};
struct smtp_rcpt {
diff --git a/usr.sbin/smtpd/smtp_client.c b/usr.sbin/smtpd/smtp_client.c
index e1f75437dfb..f2113af2ab4 100644
--- a/usr.sbin/smtpd/smtp_client.c
+++ b/usr.sbin/smtpd/smtp_client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtp_client.c,v 1.7 2018/09/01 12:03:31 miko Exp $ */
+/* $OpenBSD: smtp_client.c,v 1.8 2018/09/20 11:42:28 eric Exp $ */
/*
* Copyright (c) 2018 Eric Faurot <eric@openbsd.org>
@@ -251,7 +251,8 @@ smtp_client_state(struct smtp_client *proto, int newstate)
{
struct smtp_rcpt *rcpt;
char ibuf[LINE_MAX], obuf[LINE_MAX];
- int oldstate, offset;
+ size_t n;
+ int oldstate;
if (proto->reply)
proto->reply[0] = '\0';
@@ -297,7 +298,7 @@ smtp_client_state(struct smtp_client *proto, int newstate)
break;
case STATE_AUTH:
- if (!proto->params.auth)
+ if (!proto->params.auth_user)
smtp_client_state(proto, STATE_READY);
else if ((proto->flags & FLAG_TLS) == 0)
smtp_client_cancel(proto, FAIL_IMPL,
@@ -315,7 +316,32 @@ smtp_client_state(struct smtp_client *proto, int newstate)
break;
case STATE_AUTH_PLAIN:
- smtp_client_sendcmd(proto, "AUTH PLAIN %s", proto->params.auth);
+ (void)strlcpy(ibuf, "-", sizeof(ibuf));
+ (void)strlcat(ibuf, proto->params.auth_user, sizeof(ibuf));
+ if (strlcat(ibuf, ":", sizeof(ibuf)) >= sizeof(ibuf)) {
+ errno = EMSGSIZE;
+ smtp_client_cancel(proto, FAIL_INTERNAL,
+ "credentials too large");
+ break;
+ }
+ n = strlcat(ibuf, proto->params.auth_pass, sizeof(ibuf));
+ if (n >= sizeof(ibuf)) {
+ errno = EMSGSIZE;
+ smtp_client_cancel(proto, FAIL_INTERNAL,
+ "credentials too large");
+ break;
+ }
+ *strchr(ibuf, ':') = '\0';
+ ibuf[0] = '\0';
+ if (base64_encode(ibuf, n, obuf, sizeof(obuf)) == -1) {
+ errno = EMSGSIZE;
+ smtp_client_cancel(proto, FAIL_INTERNAL,
+ "credentials too large");
+ break;
+ }
+ smtp_client_sendcmd(proto, "AUTH PLAIN %s", obuf);
+ explicit_bzero(ibuf, sizeof ibuf);
+ explicit_bzero(obuf, sizeof obuf);
break;
case STATE_AUTH_LOGIN:
@@ -323,39 +349,28 @@ smtp_client_state(struct smtp_client *proto, int newstate)
break;
case STATE_AUTH_LOGIN_USER:
- memset(ibuf, 0, sizeof ibuf);
- if (base64_decode(proto->params.auth, (unsigned char *)ibuf,
- sizeof(ibuf)-1) == -1) {
- errno = EOVERFLOW;
+ if (base64_encode(proto->params.auth_user,
+ strlen(proto->params.auth_user), obuf,
+ sizeof(obuf)) == -1) {
+ errno = EMSGSIZE;
smtp_client_cancel(proto, FAIL_INTERNAL,
- "Credentials too large");
+ "credentials too large");
break;
}
-
- memset(obuf, 0, sizeof obuf);
- base64_encode((unsigned char *)ibuf + 1, strlen(ibuf + 1),
- obuf, sizeof obuf);
smtp_client_sendcmd(proto, "%s", obuf);
- explicit_bzero(ibuf, sizeof ibuf);
explicit_bzero(obuf, sizeof obuf);
break;
case STATE_AUTH_LOGIN_PASS:
- memset(ibuf, 0, sizeof ibuf);
- if (base64_decode(proto->params.auth, (unsigned char *)ibuf,
- sizeof(ibuf)-1) == -1) {
- errno = EOVERFLOW;
+ if (base64_encode(proto->params.auth_pass,
+ strlen(proto->params.auth_pass), obuf,
+ sizeof(obuf)) == -1) {
+ errno = EMSGSIZE;
smtp_client_cancel(proto, FAIL_INTERNAL,
- "Credentials too large");
+ "credentials too large");
break;
}
-
- offset = strlen(ibuf+1)+2;
- memset(obuf, 0, sizeof obuf);
- base64_encode((unsigned char *)ibuf + offset,
- strlen(ibuf + offset), obuf, sizeof obuf);
smtp_client_sendcmd(proto, "%s", obuf);
- explicit_bzero(ibuf, sizeof ibuf);
explicit_bzero(obuf, sizeof obuf);
break;
@@ -452,7 +467,7 @@ smtp_client_response(struct smtp_client *proto, const char *line)
* Otherwise, fallback to using HELO.
*/
if ((proto->params.tls_req == TLS_FORCE) ||
- (proto->params.auth))
+ (proto->params.auth_user))
smtp_client_cancel(proto, FAIL_RESP, line);
else
smtp_client_state(proto, STATE_HELO);
@@ -478,7 +493,7 @@ smtp_client_response(struct smtp_client *proto, const char *line)
case STATE_STARTTLS:
if (line[0] != '2') {
if ((proto->params.tls_req == TLS_FORCE) ||
- (proto->params.auth)) {
+ (proto->params.auth_user)) {
smtp_client_cancel(proto, FAIL_RESP, line);
break;
}
diff --git a/usr.sbin/smtpd/smtpc.c b/usr.sbin/smtpd/smtpc.c
index 8bbd1f43d87..d6bb2c8321e 100644
--- a/usr.sbin/smtpd/smtpc.c
+++ b/usr.sbin/smtpd/smtpc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpc.c,v 1.3 2018/05/21 21:25:37 krw Exp $ */
+/* $OpenBSD: smtpc.c,v 1.4 2018/09/20 11:42:28 eric Exp $ */
/*
* Copyright (c) 2018 Eric Faurot <eric@openbsd.org>
@@ -204,7 +204,15 @@ parse_server(char *server)
if (port && port[0] == '\0')
port = NULL;
- params.auth = creds;
+ if (creds) {
+ p = strchr(creds, ':');
+ if (p == NULL)
+ fatalx("invalid credentials");
+ *p = '\0';
+
+ params.auth_user = creds;
+ params.auth_pass = p + 1;
+ }
params.tls_req = TLS_YES;
if (!strcmp(scheme, "lmtp")) {