Skip to content

Commit 3e45943

Browse files
committed
Add support for AUTH PLAIN
1 parent 7f88bbe commit 3e45943

2 files changed

Lines changed: 54 additions & 24 deletions

File tree

dma.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ struct mx_hostentry {
166166
struct smtp_auth_mechanisms {
167167
int cram_md5;
168168
int login;
169+
int plain;
169170
};
170171

171172
struct smtp_features {

net.c

Lines changed: 53 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -281,44 +281,67 @@ smtp_login(int fd, char *login, char* password, const struct smtp_features* feat
281281
}
282282
}
283283

284-
// LOGIN
285-
if (features->auth.login) {
284+
// LOGIN or PLAIN
285+
if (features->auth.login || features->auth.plain) {
286286
if ((config.features & INSECURE) != 0 ||
287287
(config.features & SECURETRANSFER) != 0) {
288288
/* Send AUTH command according to RFC 2554 */
289-
send_remote_command(fd, "AUTH LOGIN");
289+
const char *auth_mechanism = features->auth.login ? "LOGIN" : "PLAIN";
290+
send_remote_command(fd, "AUTH %s", auth_mechanism);
290291
if (read_remote(fd, 0, NULL) != 3) {
291292
syslog(LOG_NOTICE, "remote delivery deferred:"
292-
" AUTH login not available: %s",
293-
neterr);
293+
" AUTH %s not available: %s",
294+
auth_mechanism, neterr);
294295
return (1);
295296
}
296297

297-
len = base64_encode(login, strlen(login), &temp);
298-
if (len < 0) {
298+
if (features->auth.login) {
299+
// LOGIN mechanism
300+
len = base64_encode(login, strlen(login), &temp);
301+
if (len < 0) {
299302
encerr:
300-
syslog(LOG_ERR, "can not encode auth reply: %m");
301-
return (1);
302-
}
303+
syslog(LOG_ERR, "can not encode auth reply: %m");
304+
return (1);
305+
}
303306

304-
send_remote_command(fd, "%s", temp);
305-
free(temp);
306-
res = read_remote(fd, 0, NULL);
307-
if (res != 3) {
308-
syslog(LOG_NOTICE, "remote delivery %s: AUTH login failed: %s",
309-
res == 5 ? "failed" : "deferred", neterr);
310-
return (res == 5 ? -1 : 1);
311-
}
307+
send_remote_command(fd, "%s", temp);
308+
free(temp);
309+
res = read_remote(fd, 0, NULL);
310+
if (res != 3) {
311+
syslog(LOG_NOTICE, "remote delivery %s: AUTH LOGIN failed: %s",
312+
res == 5 ? "failed" : "deferred", neterr);
313+
return (res == 5 ? -1 : 1);
314+
}
315+
316+
len = base64_encode(password, strlen(password), &temp);
317+
if (len < 0)
318+
goto encerr;
319+
320+
send_remote_command(fd, "%s", temp);
321+
free(temp);
322+
} else if (features->auth.plain) {
323+
// PLAIN mechanism
324+
size_t buflen = strlen(login) + strlen(password) + 3;
325+
char *plainbuf = malloc(buflen);
326+
if (plainbuf == NULL) {
327+
syslog(LOG_ERR, "remote delivery deferred: unable to allocate memory");
328+
return (1);
329+
}
330+
331+
snprintf(plainbuf, buflen, "%c%s%c%s", '\0', login, '\0', password);
312332

313-
len = base64_encode(password, strlen(password), &temp);
314-
if (len < 0)
315-
goto encerr;
333+
len = base64_encode(plainbuf, buflen, &temp);
334+
free(plainbuf);
335+
if (len < 0)
336+
goto encerr;
337+
338+
send_remote_command(fd, "%s", temp);
339+
free(temp);
340+
}
316341

317-
send_remote_command(fd, "%s", temp);
318-
free(temp);
319342
res = read_remote(fd, 0, NULL);
320343
if (res != 2) {
321-
syslog(LOG_NOTICE, "remote delivery %s: Authentication failed: %s",
344+
syslog(LOG_NOTICE, "remote delivery %s: AUTH PLAIN failed: %s",
322345
res == 5 ? "failed" : "deferred", neterr);
323346
return (res == 5 ? -1 : 1);
324347
}
@@ -381,6 +404,9 @@ static void parse_auth_line(char* line, struct smtp_auth_mechanisms* auth) {
381404
else if (strcmp(method, "LOGIN") == 0)
382405
auth->login = 1;
383406

407+
else if (strcmp(method, "PLAIN") == 0)
408+
auth->plain = 1;
409+
384410
method = strtok(NULL, " ");
385411
}
386412
}
@@ -469,6 +495,9 @@ int perform_server_greeting(int fd, struct smtp_features* features) {
469495
if (features->auth.login) {
470496
syslog(LOG_DEBUG, " Server supports LOGIN authentication");
471497
}
498+
if (features->auth.plain) {
499+
syslog(LOG_DEBUG, " Server supports PLAIN authentication");
500+
}
472501

473502
return 0;
474503
}

0 commit comments

Comments
 (0)