diff options
| -rw-r--r-- | qmail-smtpd.c | 33 |
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; | |||
| 211 | int err_input() { out("501 malformed auth input (#5.5.4)\r\n"); return -1; } | 211 | int err_input() { out("501 malformed auth input (#5.5.4)\r\n"); return -1; } |
| 212 | int err_wantstarttls() { out("530 Must issue a STARTTLS command first (#5.7.0)\r\n"); return -1; }; | 212 | int err_wantstarttls() { out("530 Must issue a STARTTLS command first (#5.7.0)\r\n"); return -1; }; |
| 213 | void err_authfail() { out("535 authentication failed (#5.7.1)\r\n"); do_hard_errors(); } | 213 | void err_authfail() { out("535 authentication failed (#5.7.1)\r\n"); do_hard_errors(); } |
| 214 | void err_authfail_reason(char *r) { out("535 "); out(r); out(" (#5.7.1)\r\n"); do_hard_errors(); } | ||
| 215 | void err_authfail_disabled() { out("535 login disabled for this user (#5.7.1)\r\n"); do_hard_errors(); } | ||
| 216 | void err_authfail_temp() { out("454 temporary failure (#4.3.0)\r\n"); do_hard_errors(); } | ||
| 214 | void err_nomailbox() { out("554 sorry, no mailbox here by that name (#5.1.1)\r\n"); do_hard_errors(); } | 217 | void err_nomailbox() { out("554 sorry, no mailbox here by that name (#5.1.1)\r\n"); do_hard_errors(); } |
| 215 | void err_maxrcpt() { out("450 too many recipients (#4.7.1)\r\n"); do_hard_errors(); } | 218 | void 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 | ||
| 1245 | void smtp_auth(arg) | 1266 | void smtp_auth(arg) |
