diff options
Diffstat (limited to 'mailutils/sendmail.c')
-rw-r--r-- | mailutils/sendmail.c | 58 |
1 files changed, 49 insertions, 9 deletions
diff --git a/mailutils/sendmail.c b/mailutils/sendmail.c index 0170f2870..32c50ba84 100644 --- a/mailutils/sendmail.c +++ b/mailutils/sendmail.c | |||
@@ -36,7 +36,9 @@ | |||
36 | //usage: "\n openssl s_client -quiet -tls1 -connect smtp.gmail.com:465" | 36 | //usage: "\n openssl s_client -quiet -tls1 -connect smtp.gmail.com:465" |
37 | //usage: "\n $SMTP_ANTISPAM_DELAY: seconds to wait after helper connect" | 37 | //usage: "\n $SMTP_ANTISPAM_DELAY: seconds to wait after helper connect" |
38 | //usage: "\n -S HOST[:PORT] Server (default $SMTPHOST or 127.0.0.1)" | 38 | //usage: "\n -S HOST[:PORT] Server (default $SMTPHOST or 127.0.0.1)" |
39 | //usage: "\n -amLOGIN Log in using AUTH LOGIN (-amCRAM-MD5 not supported)" | 39 | //usage: "\n -amLOGIN Log in using AUTH LOGIN" |
40 | //usage: "\n -amPLAIN or AUTH PLAIN" | ||
41 | //usage: "\n (-amCRAM-MD5 not supported)" | ||
40 | //usage: "\n -auUSER Username for AUTH" | 42 | //usage: "\n -auUSER Username for AUTH" |
41 | //usage: "\n -apPASS Password for AUTH" | 43 | //usage: "\n -apPASS Password for AUTH" |
42 | //usage: "\n" | 44 | //usage: "\n" |
@@ -248,6 +250,8 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) | |||
248 | OPT_S = 1 << 6, // specify connection string | 250 | OPT_S = 1 << 6, // specify connection string |
249 | OPT_a = 1 << 7, // authentication tokens | 251 | OPT_a = 1 << 7, // authentication tokens |
250 | OPT_v = 1 << 8, // verbosity | 252 | OPT_v = 1 << 8, // verbosity |
253 | //--- for -amMETHOD | ||
254 | OPT_am_plain = 1 << 9, // AUTH PLAIN | ||
251 | }; | 255 | }; |
252 | 256 | ||
253 | // init global variables | 257 | // init global variables |
@@ -286,9 +290,14 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) | |||
286 | G.user = xstrdup(a+1); | 290 | G.user = xstrdup(a+1); |
287 | if ('p' == a[0]) | 291 | if ('p' == a[0]) |
288 | G.pass = xstrdup(a+1); | 292 | G.pass = xstrdup(a+1); |
289 | // N.B. we support only AUTH LOGIN so far | 293 | if ('m' == a[0]) { |
290 | //if ('m' == a[0]) | 294 | if ((a[1] | 0x20) == 'p') // PLAIN |
291 | // G.method = xstrdup(a+1); | 295 | opts |= OPT_am_plain; |
296 | else if ((a[1] | 0x20) == 'l') // LOGIN | ||
297 | ; /* do nothing (this is the default) */ | ||
298 | else | ||
299 | bb_error_msg_and_die("unsupported AUTH method %s", a+1); | ||
300 | } | ||
292 | } | 301 | } |
293 | // N.B. list == NULL here | 302 | // N.B. list == NULL here |
294 | //bb_error_msg("OPT[%x] AU[%s], AP[%s], AM[%s], ARGV[%s]", opts, au, ap, am, *argv); | 303 | //bb_error_msg("OPT[%x] AU[%s], AP[%s], AM[%s], ARGV[%s]", opts, au, ap, am, *argv); |
@@ -348,13 +357,44 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) | |||
348 | 357 | ||
349 | // perform authentication | 358 | // perform authentication |
350 | if (opts & OPT_a) { | 359 | if (opts & OPT_a) { |
351 | smtp_check("AUTH LOGIN", 334); | 360 | // read credentials unless they are given via -a[up] options |
352 | // we must read credentials unless they are given via -a[up] options | ||
353 | if (!G.user || !G.pass) | 361 | if (!G.user || !G.pass) |
354 | get_cred_or_die(4); | 362 | get_cred_or_die(4); |
355 | encode_base64(NULL, G.user, NULL); | 363 | if (opts & OPT_am_plain) { |
356 | smtp_check("", 334); | 364 | // C: AUTH PLAIN |
357 | encode_base64(NULL, G.pass, NULL); | 365 | // S: 334 |
366 | // C: base64encoded(auth<NUL>user<NUL>pass) | ||
367 | // S: 235 2.7.0 Authentication successful | ||
368 | //Note: a shorter format is allowed: | ||
369 | // C: AUTH PLAIN base64encoded(auth<NUL>user<NUL>pass) | ||
370 | // S: 235 2.7.0 Authentication successful | ||
371 | smtp_check("AUTH PLAIN", 334); | ||
372 | { | ||
373 | unsigned user_len = strlen(G.user); | ||
374 | unsigned pass_len = strlen(G.pass); | ||
375 | unsigned sz = 1 + user_len + 1 + pass_len; | ||
376 | char plain_auth[sz + 1]; | ||
377 | // the format is: | ||
378 | // "authorization identity<NUL>username<NUL>password" | ||
379 | // authorization identity is empty. | ||
380 | plain_auth[0] = '\0'; | ||
381 | strcpy(stpcpy(plain_auth + 1, G.user) + 1, G.pass); | ||
382 | printbuf_base64(plain_auth, sz); | ||
383 | } | ||
384 | } else { | ||
385 | // C: AUTH LOGIN | ||
386 | // S: 334 VXNlcm5hbWU6 | ||
387 | // ^^^^^^^^^^^^ server says "Username:" | ||
388 | // C: base64encoded(user) | ||
389 | // S: 334 UGFzc3dvcmQ6 | ||
390 | // ^^^^^^^^^^^^ server says "Password:" | ||
391 | // C: base64encoded(pass) | ||
392 | // S: 235 2.7.0 Authentication successful | ||
393 | smtp_check("AUTH LOGIN", 334); | ||
394 | printstr_base64(G.user); | ||
395 | smtp_check("", 334); | ||
396 | printstr_base64(G.pass); | ||
397 | } | ||
358 | smtp_check("", 235); | 398 | smtp_check("", 235); |
359 | } | 399 | } |
360 | 400 | ||