From d55192fc95cad5c26cd1e13f819f9b2e4e7bed00 Mon Sep 17 00:00:00 2001 From: Gilles Chehade Date: Sat, 20 Dec 2008 00:18:04 +0000 Subject: - import first bricks of SMTP AUTH support. currently only AUTH PLAIN is supported, AUTH LOGIN will follow soon. AUTH will only work if a listen directive has "enable auth" keywords, AND session is safe (ssmtp or starttls). --- usr.sbin/smtpd/lka.c | 6 +++++- usr.sbin/smtpd/mfa.c | 4 +++- usr.sbin/smtpd/parse.y | 24 +++++++++++++++++------- usr.sbin/smtpd/smtp_session.c | 29 +++++++++++++++++------------ usr.sbin/smtpd/smtpd.h | 43 ++++++++++++++++++++++++------------------- 5 files changed, 66 insertions(+), 40 deletions(-) diff --git a/usr.sbin/smtpd/lka.c b/usr.sbin/smtpd/lka.c index 7a16f1ad938..9b34a508771 100644 --- a/usr.sbin/smtpd/lka.c +++ b/usr.sbin/smtpd/lka.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lka.c,v 1.7 2008/12/13 23:19:33 jacekm Exp $ */ +/* $OpenBSD: lka.c,v 1.8 2008/12/20 00:18:03 gilles Exp $ */ /* * Copyright (c) 2008 Pierre-Yves Ritschard @@ -188,6 +188,10 @@ lka_dispatch_mfa(int sig, short event, void *p) if (lka_verify_rcpt(env, &ss->u.path, &ss->ss)) ss->code = 250; + else if (ss->flags & F_MESSAGE_AUTHENTICATED) { + log_debug("accepting for authenticated user"); + ss->code = 250; + } imsg_compose(ibuf, IMSG_LKA_RCPT, 0, 0, -1, ss, sizeof(*ss)); diff --git a/usr.sbin/smtpd/mfa.c b/usr.sbin/smtpd/mfa.c index a6e53fa3ebd..08d78c2ee1e 100644 --- a/usr.sbin/smtpd/mfa.c +++ b/usr.sbin/smtpd/mfa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mfa.c,v 1.3 2008/12/13 23:19:34 jacekm Exp $ */ +/* $OpenBSD: mfa.c,v 1.4 2008/12/20 00:18:03 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade @@ -163,6 +163,8 @@ mfa_dispatch_smtp(int sig, short event, void *p) ss.u.path = mr->path; ss.ss = mr->ss; + ss.flags = mr->flags; + imsg_compose(env->sc_ibufs[PROC_LKA], IMSG_LKA_RCPT, 0, 0, -1, &ss, sizeof(ss)); break; diff --git a/usr.sbin/smtpd/parse.y b/usr.sbin/smtpd/parse.y index 370a950aa5e..d7a06caf63c 100644 --- a/usr.sbin/smtpd/parse.y +++ b/usr.sbin/smtpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.19 2008/12/18 22:13:57 gilles Exp $ */ +/* $OpenBSD: parse.y,v 1.20 2008/12/20 00:18:03 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade @@ -117,11 +117,11 @@ typedef struct { %token DNS DB TFILE EXTERNAL DOMAIN CONFIG SOURCE %token RELAY VIA DELIVER TO MAILDIR MBOX HOSTNAME %token ACCEPT REJECT INCLUDE NETWORK ERROR MDA FROM FOR -%token ARROW +%token ARROW ENABLE AUTH %token STRING %token NUMBER %type map -%type quantifier decision port ssmtp from +%type quantifier decision port ssmtp from auth %type condition %type interval %type mapref @@ -225,10 +225,14 @@ ssmtp : SSMTP { $$ = 1; } | /* empty */ { $$ = 0; } ; +auth : ENABLE AUTH { $$ = 1; } + | /* empty */ { $$ = 0; } + ; + main : QUEUE INTERVAL interval { conf->sc_qintval = $3; } - | ssmtp LISTEN ON STRING port certname { + | ssmtp LISTEN ON STRING port certname auth { char *cert; u_int8_t flags; @@ -241,9 +245,13 @@ main : QUEUE INTERVAL interval { cert = ($6 != NULL) ? $6 : $4; flags = 0; + + if ($7) + flags |= F_AUTH; + if (ssl_load_certfile(conf, cert) < 0) { log_warnx("warning: could not load cert: %s, " - "no SSL/TLS support", cert); + "no SSL/TLS/AUTH support", cert); if ($1 || $6 != NULL) { yyerror("cannot load certificate: %s", cert); @@ -254,9 +262,9 @@ main : QUEUE INTERVAL interval { } else { if ($1) - flags = F_SSMTP; + flags |= F_SSMTP; else - flags = F_STARTTLS; + flags |= F_STARTTLS; } if (! interface($4, &conf->sc_listeners, @@ -784,12 +792,14 @@ lookup(char *s) static const struct keywords keywords[] = { { "accept", ACCEPT }, { "all", ALL }, + { "auth", AUTH }, { "certificate", CERTIFICATE }, { "config", CONFIG }, { "db", DB }, { "deliver", DELIVER }, { "dns", DNS }, { "domain", DOMAIN }, + { "enable", ENABLE }, { "external", EXTERNAL }, { "file", TFILE }, { "for", FOR }, diff --git a/usr.sbin/smtpd/smtp_session.c b/usr.sbin/smtpd/smtp_session.c index 4298da03e0b..f1b038c94ed 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.31 2008/12/18 23:57:17 jacekm Exp $ */ +/* $OpenBSD: smtp_session.c,v 1.32 2008/12/20 00:18:03 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade @@ -296,10 +296,9 @@ session_rfc5321_ehlo_handler(struct session *s, char *args) session_respond(s, "250-STARTTLS"); /* only advertise auth if session is secure */ - /* - if (s->s_flags & F_SECURE) + if ((s->s_l->flags & F_AUTH) && (s->s_flags & F_SECURE)) session_respond(s, "250-AUTH %s", "PLAIN"); - */ + session_respond(s, "250 HELP"); return 1; @@ -392,6 +391,12 @@ session_rfc5321_rcpt_handler(struct session *s, char *args) s->s_state = S_RCPTREQUEST; mr.ss = s->s_ss; + + if (s->s_flags & F_AUTHENTICATED) { + s->s_msg.flags |= F_MESSAGE_AUTHENTICATED; + mr.flags |= F_MESSAGE_AUTHENTICATED; + } + imsg_compose(s->s_env->sc_ibufs[PROC_MFA], IMSG_MFA_RCPT, 0, 0, -1, &mr, sizeof(mr)); bufferevent_disable(s->s_bev, EV_READ); @@ -494,15 +499,15 @@ session_command(struct session *s, char *cmd, char *args) } /* RFC 4954 - AUTH */ - /* - for (i = 0; i < (int)(sizeof(rfc4954_cmdtab) / sizeof(struct session_cmd)); ++i) - if (strcasecmp(rfc4954_cmdtab[i].name, cmd) == 0) - break; - if (i < (int)(sizeof(rfc4954_cmdtab) / sizeof(struct session_cmd))) { - if (rfc4954_cmdtab[i].func(s, args)) - return; + if ((s->s_l->flags & F_AUTH) && (s->s_flags & F_SECURE)) { + for (i = 0; i < (int)(sizeof(rfc4954_cmdtab) / sizeof(struct session_cmd)); ++i) + if (strcasecmp(rfc4954_cmdtab[i].name, cmd) == 0) + break; + if (i < (int)(sizeof(rfc4954_cmdtab) / sizeof(struct session_cmd))) { + if (rfc4954_cmdtab[i].func(s, args)) + return; + } } - */ rfc5321: /* RFC 5321 - SMTP */ diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h index 663ce549ec7..5c4cccf55ce 100644 --- a/usr.sbin/smtpd/smtpd.h +++ b/usr.sbin/smtpd/smtpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.h,v 1.32 2008/12/19 00:39:05 gilles Exp $ */ +/* $OpenBSD: smtpd.h,v 1.33 2008/12/20 00:18:03 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade @@ -71,6 +71,7 @@ #define F_STARTTLS 0x01 #define F_SSMTP 0x02 +#define F_AUTH 0x04 #define F_SSL (F_SSMTP|F_STARTTLS) @@ -369,23 +370,6 @@ struct alias { }; TAILQ_HEAD(aliaseslist, alias); -struct submit_status { - u_int64_t id; - int code; - union submit_path { - struct path path; - char msgid[MAXPATHLEN]; - char errormsg[MAX_LINE_SIZE]; - } u; - struct sockaddr_storage ss; -}; - -struct message_recipient { - u_int64_t id; - struct sockaddr_storage ss; - struct path path; -}; - enum message_type { T_MDA_MESSAGE = 0x1, T_MTA_MESSAGE = 0x2, @@ -407,7 +391,8 @@ enum message_flags { F_MESSAGE_RESOLVED = 0x1, F_MESSAGE_EXPIRED = 0x2, F_MESSAGE_SCHEDULED = 0x4, - F_MESSAGE_PROCESSING = 0x8 + F_MESSAGE_PROCESSING = 0x8, + F_MESSAGE_AUTHENTICATED = 0x10 }; struct message { @@ -615,6 +600,26 @@ struct smtpd { SPLAY_HEAD(mdaproctree, mdaproc) mdaproc_queue; }; +struct submit_status { + u_int64_t id; + int code; + union submit_path { + struct path path; + char msgid[MAXPATHLEN]; + char errormsg[MAX_LINE_SIZE]; + } u; + enum message_flags flags; + struct sockaddr_storage ss; +}; + +struct message_recipient { + u_int64_t id; + struct sockaddr_storage ss; + enum message_flags flags; + struct path path; +}; + + /* aliases.c */ int aliases_exist(struct smtpd *, char *); int aliases_get(struct smtpd *, struct aliaseslist *, char *); -- cgit v1.2.3