summaryrefslogtreecommitdiffstats
path: root/qmail-smtpd.c
diff options
context:
space:
mode:
Diffstat (limited to 'qmail-smtpd.c')
-rw-r--r--qmail-smtpd.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/qmail-smtpd.c b/qmail-smtpd.c
index d0395fc..1c26031 100644
--- a/qmail-smtpd.c
+++ b/qmail-smtpd.c
@@ -211,6 +211,9 @@ int err_authabrt() { out("501 auth exchange canceled (#5.0.0)\r\n"); return -1;
211int err_input() { out("501 malformed auth input (#5.5.4)\r\n"); return -1; } 211int err_input() { out("501 malformed auth input (#5.5.4)\r\n"); return -1; }
212int err_wantstarttls() { out("530 Must issue a STARTTLS command first (#5.7.0)\r\n"); return -1; }; 212int err_wantstarttls() { out("530 Must issue a STARTTLS command first (#5.7.0)\r\n"); return -1; };
213void err_authfail() { out("535 authentication failed (#5.7.1)\r\n"); do_hard_errors(); } 213void err_authfail() { out("535 authentication failed (#5.7.1)\r\n"); do_hard_errors(); }
214void err_authfail_reason(char *r) { out("535 "); out(r); out(" (#5.7.1)\r\n"); do_hard_errors(); }
215void err_authfail_disabled() { out("535 login disabled for this user (#5.7.1)\r\n"); do_hard_errors(); }
216void err_authfail_temp() { out("454 temporary failure (#4.3.0)\r\n"); do_hard_errors(); }
214void err_nomailbox() { out("554 sorry, no mailbox here by that name (#5.1.1)\r\n"); do_hard_errors(); } 217void err_nomailbox() { out("554 sorry, no mailbox here by that name (#5.1.1)\r\n"); do_hard_errors(); }
215void err_maxrcpt() { out("450 too many recipients (#4.7.1)\r\n"); do_hard_errors(); } 218void err_maxrcpt() { out("450 too many recipients (#4.7.1)\r\n"); do_hard_errors(); }
216 219
@@ -1054,7 +1057,7 @@ int authenticate(void)
1054 int pi[2]; 1057 int pi[2];
1055 int piauth[2], i, len; 1058 int piauth[2], i, len;
1056 char *arg; 1059 char *arg;
1057 static stralloc authout = {0}, authparams = {0}; 1060 static stralloc authout = {0}, authparams = {0}, authreason = {0};
1058 1061
1059 if (!stralloc_0(&user)) die_nomem(); 1062 if (!stralloc_0(&user)) die_nomem();
1060 if (!stralloc_0(&pass)) die_nomem(); 1063 if (!stralloc_0(&pass)) die_nomem();
@@ -1105,12 +1108,17 @@ int authenticate(void)
1105 len = authout.len; 1108 len = authout.len;
1106 arg = authout.s; 1109 arg = authout.s;
1107 if (!stralloc_copys(&authparams, "")) die_nomem(); 1110 if (!stralloc_copys(&authparams, "")) die_nomem();
1111 if (!stralloc_copys(&authreason, "")) die_nomem();
1108 while (len) { 1112 while (len) {
1109 if (*arg == '\0') { 1113 if (*arg == '\0') {
1110 if (case_starts(authparams.s, "USER=") && (authparams.len - 5) > 0) { 1114 if (case_starts(authparams.s, "USER=") && (authparams.len - 5) > 0) {
1111 if (!stralloc_copyb(&user, authparams.s + 5, authparams.len - 5)) die_nomem(); 1115 if (!stralloc_copyb(&user, authparams.s + 5, authparams.len - 5)) die_nomem();
1112 if (!stralloc_0(&user)) die_nomem(); 1116 if (!stralloc_0(&user)) die_nomem();
1113 } 1117 }
1118 else if (case_starts(authparams.s, "REASON=") && (authparams.len - 7) > 0) {
1119 if (!stralloc_copyb(&authreason, authparams.s + 7, authparams.len - 7)) die_nomem();
1120 if (!stralloc_0(&authreason)) die_nomem();
1121 }
1114 if (!stralloc_copys(&authparams, "")) die_nomem(); 1122 if (!stralloc_copys(&authparams, "")) die_nomem();
1115 } 1123 }
1116 else 1124 else
@@ -1128,7 +1136,20 @@ int authenticate(void)
1128 byte_zero(ssauth2buf,sizeof ssauth2buf); 1136 byte_zero(ssauth2buf,sizeof ssauth2buf);
1129 if (wait_pid(&wstat,child) == -1) return err_child(); 1137 if (wait_pid(&wstat,child) == -1) return err_child();
1130 if (wait_crashed(wstat)) return err_child(); 1138 if (wait_crashed(wstat)) return err_child();
1131 if (wait_exitcode(wstat)) { sleep(AUTHSLEEP); return 1; } /* no */ 1139 if (wait_exitcode(wstat)) {
1140 sleep(AUTHSLEEP);
1141 if (authreason.len > 0) { err_authfail_reason(authreason.s); return -1; }
1142 switch(wait_exitcode(wstat))
1143 {
1144 case 110: /* login disabled */
1145 err_authfail_disabled();
1146 return -1;
1147 case 111: /* temp fail */
1148 err_authfail_temp();
1149 return -1;
1150 }
1151 return 1; /* invalid login */
1152 }
1132 return 0; /* yes */ 1153 return 0; /* yes */
1133} 1154}
1134 1155
@@ -1234,12 +1255,12 @@ struct authcmd {
1234 char *text; 1255 char *text;
1235 int (*fun)(); 1256 int (*fun)();
1236} authcmds[] = { 1257} authcmds[] = {
1237 { "login",auth_login } 1258 { "login", auth_login },
1238, { "plain",auth_plain } 1259 { "plain", auth_plain },
1239#ifdef CRAM_MD5 1260#ifdef CRAM_MD5
1240, { "cram-md5",auth_cram } 1261 { "cram-md5", auth_cram },
1241#endif 1262#endif
1242, { 0,err_noauth } 1263 { 0, err_noauth },
1243}; 1264};
1244 1265
1245void smtp_auth(arg) 1266void smtp_auth(arg)