diff --git a/indimail-mta-x/indimail-env.9 b/indimail-mta-x/indimail-env.9 index 017e014ab..f0155d53d 100644 --- a/indimail-mta-x/indimail-env.9 +++ b/indimail-mta-x/indimail-env.9 @@ -54,7 +54,10 @@ bouncing the mail after discovring that the account doesn't exist .TP \fIAUTH_SMTP\fR If set, \fBqmail-remote\fR(8) will use authenticated SMTP with the remote -host before starting delivery. +host before starting delivery. Supported values are LOGIN, PLAIN, XOAUTH2, +CRAM-MD5, CRAM-RIPEMD, CRAM-SHA1, CRAM-SHA224, CRAM-SHA256, CRAM-SHA384, +CRAM-SHA512, DIGEST-MD5, SCRAM-SHA1, SCRAM-SHA-1-PLUS, SCRAM-SHA256, +SCRAM-SHA-256-PLUS .TP \fIBADEXT\fR @@ -247,7 +250,9 @@ Used by various indimail-virtual programs and \fBqmail-smtpd\fR(8) when domain component is missing in addresses. .TP -\fIDISABLE_AUTH_LOGIN\fR, \fIDISABLE_AUTH_PLAIN\fR, \fIDISABLE_CRAM_MD5\fR, \fIDISABLE_CRAM_RIPEMD\fR, +\fIDISABLE_AUTH_LOGIN\fR, \fIDISABLE_AUTH_PLAIN\fR, \fIDISABLE_AUTH_OAUTH2\fR, +.TP +\fIDISABLE_CRAM_MD5\fR, \fIDISABLE_CRAM_RIPEMD\fR, .TP \fIDISABLE_CRAM_SHA1\fR, \fIDISABLE_CRAM_SHA224\fR, \fIDISABLE_CRAM_SHA256\fR, \fIDSABLE_CRAM_SHA384\fR, .TP diff --git a/indimail-mta-x/qmail-remote.9 b/indimail-mta-x/qmail-remote.9 index 15ae46e31..441f3b41d 100644 --- a/indimail-mta-x/qmail-remote.9 +++ b/indimail-mta-x/qmail-remote.9 @@ -96,7 +96,7 @@ or \fISYSCONF/control/smtproutes\fR control file. This is described in detail in the section \fBCONTROL FILES\fR. \fBqmail-remote\fR uses libgsasl to use GNU Simple Authentication and Security Layer detailed here https://www.gnu.org/software/gsasl. \fBqmail-remote\fR supports LOGIN, -PLAIN, CRAM-MD5, CRAM-SHA1, CRAM-SHA224, CRAM-SHA256, CRAM-SHA384, +PLAIN, XOAUTH2, CRAM-MD5, CRAM-SHA1, CRAM-SHA224, CRAM-SHA256, CRAM-SHA384, CRAM-RIPEMD, DIGEST-MD5 authentication using built-in functions and SCRAM-SHA-1, SCRAM-SHA-256, SCRAM-SHA-1-PLUS, SCRAM-SHA-256-PLUS authentication provided by libgsasl. Note that DIGEST-MD5 has been moved to @@ -176,25 +176,31 @@ no supported AUTH method found, continuing without authentication. Z Connected to .I host -but authentication was rejected (AUTH PLAIN). +but unable to base64encode (plain). .TP 5 Z Connected to .I host -but unable to base64encode (plain). +but unable to base64encode (challenge). + +.TP 5 +Z +Connected to +.I host +but unable to base64encode (username+digest). .TP 5 Z Connected to .I host -but authentication was rejected (plain)." +but unable to base64encode (oauth2). .TP 5 Z Connected to .I host -but authentication was rejected (AUTH LOGIN). +but unable to base64encode (oauth2 error). .TP 5 Z @@ -202,6 +208,12 @@ Connected to .I host but unable to base64encode user. +.TP 5 +Z +Connected to +.I host +but unable to base64encode password. + .TP 5 Z Connected to @@ -224,8 +236,8 @@ but authentication was rejected (password). Z Connected to .I host -but authentication was rejected (AUTH LOGIN, PLAIN, CRAM-MD5, CRAM-SHA1, -CRAM-SHA224, CRAM-SHA256, CRAM-SHA384, CRAM-SHA512, CRAM-RIPEMD, +but authentication was rejected (AUTH LOGIN, PLAIN, XOAUTH2, CRAM-MD5, +CRAM-SHA1, CRAM-SHA224, CRAM-SHA256, CRAM-SHA384, CRAM-SHA512, CRAM-RIPEMD, DIGEST-MD5, SCRAM-SHA-1, SCRAM-SHA-256, SCRAM-SHA-1-PLUS, SCRAM-SHA-256-PLUS) @@ -577,7 +589,7 @@ Here \fIaddr\fR is an address; \fBqmail-remote\fR will use for authenticated SMTP. If there are several assignments for the same \fIaddr\fR address, -\fBqmail-remote\R will use the first one. +\fBqmail-remote\fR will use the first one. \fIaddr\fR is interpreted without regard to case. @@ -614,11 +626,11 @@ You can create \fISYSCONF/control/remote_auth.cdb\fR from \fBAUTH_SMTP\fR can have the values SCRAM-SHA-256-PLUS, SCRAM-SHA-256, SCRAM-SHA-1-PLUS, SCRAM-SHA-1, DIGEST-MD5, CRAM-RIPEMD, CRAM-SHA512, -CRAM-SHA384, CRAM-SHA256, CRAM-SHA224, CRAM-SHA1, CRAM-MD5, LOGIN or PLAIN -to use the desired authentication method. AUTH_SMTP can also be an empty -string to let qmail-remote choose an authentication method in the order -listed above. If no method from the above list is found supported by the -remote server, qmail-remote will continue without using authentication. +CRAM-SHA384, CRAM-SHA256, CRAM-SHA224, CRAM-SHA1, CRAM-MD5, LOGIN, PLAIN, +XOAUTH2 to use the desired authentication method. AUTH_SMTP can also be an +empty string to let qmail-remote choose an authentication method in the +order listed above. If no method from the above list is found supported by +the remote server, qmail-remote will continue without using authentication. Remember that authenticated smtp gets disabled if username and password have not been configured in \fBsmtproutes\fR control file or the \fBSMTPROUTE\fR / \fBX-SMTPROUTES\fR environment variable. @@ -629,7 +641,7 @@ characters for SCRAM-SHA-1 and 64 characters for SCRAM-SHA-256) with the user’s PBKDF2-prepared password. The salted password value can be derived by using the --mkpasswd parameter for the gsasl(1) utility. indimail has vpasswd(1) / vmoduser(1), which use gsasl_scram_secrets_from_password(3) -API to set passwords for AUTH PLAIN, LOGIN, CRAM-MD5, CRAM-SHA1, +API to set passwords for AUTH PLAIN, LOGIN, XOAUTH2, CRAM-MD5, CRAM-SHA1, CRAM-SHA224, CRAM-SHA256, CRAM-SHA384, CRAM-SHA512, CRAM-RIPEMD, DIGEST-MD5, SCRAM-SHA-1, SCRAM-SHA-256 methods. The hex-encoded salted password can be used to avoid storing a clear-text credential in the @@ -644,6 +656,7 @@ following environment variables. .EX DISABLE_AUTH_LOGIN DISABLE_AUTH_PLAIN + DISABLE_AUTH_OAUTH2 DISABLE_CRAM_MD5 DISABLE_CRAM_SHA1 DISABLE_CRAM_SHA224 @@ -658,9 +671,9 @@ following environment variables. DISABLE_SCRAM_SHA256_PLUS .EE -If you set the environment variable \fBSECURE_AUTH\fR, AUTH LOGIN and -AUTH PLAIN gets disabled, unless qmail-remote has opened a TLS session wth -the remote host. See the control file \fIclientcert.pem\fR. +If you set the environment variable \fBSECURE_AUTH\fR, AUTH LOGIN, AUTH +PLAIN and AUTH XOUTH2 gets disabled, unless qmail-remote has opened a TLS +session with the remote host. See the control file \fIclientcert.pem\fR. If all connections to the \fIrelay\fR server fail for a \fImax_tolerance\fR seconds, further connections to the same server are avoided for a period of diff --git a/indimail-mta-x/qmail-remote.c b/indimail-mta-x/qmail-remote.c index 75c244cbc..34baf9e13 100644 --- a/indimail-mta-x/qmail-remote.c +++ b/indimail-mta-x/qmail-remote.c @@ -1,6 +1,6 @@ /*- * RCS log at bottom - * $Id: qmail-remote.c,v 1.174 2024-05-12 00:20:03+05:30 mbhangui Exp mbhangui $ + * $Id: qmail-remote.c,v 1.175 2024-07-16 00:17:36+05:30 Cprogrammer Exp mbhangui $ */ #include #include @@ -1471,22 +1471,25 @@ decode_smtpauth_err(int code, const char *s1, const char *s2) switch(code) { case 432: - quit(code, 1, "ZConnected to ", " but a password transition is needed ", "(", s1, s2, ") (#4.7.12).", NULL); + quit(code, 1, "ZConnected to ", " but a password transition is needed (", s1, s2, ") (#4.7.12).", NULL); break; case 454: - quit(code, 1, "ZConnected to ", " but got temporary authentication failure ", s1, s2, ") (#4.7.0).", NULL); - break; - case 534: - quit(code, 1, "DConnected to ", " but authentication mechanism is too weak ", s1, s2, ") (#5.7.9).", NULL); - break; - case 535: - quit(code, 1, "DConnected to ", " but authentication credentials invalid ", s1, s2, ") (#5.7.8).", NULL); + quit(code, 1, "ZConnected to ", " but got temporary authentication failure (", s1, s2, ") (#4.7.0).", NULL); break; case 500: - quit(code, 1, "DConnected to ", " but authentication Exchange line is too long ", s1, s2, ") (#5.5.6).", NULL); + quit(code, 1, "DConnected to ", " but authentication Exchange line is too long (", s1, s2, ") (#5.5.6).", NULL); break; case 530: - quit(code, 1, "DConnected to ", " but authentication required ", s1, s2, ") (#5.7.0).", NULL); + quit(code, 1, "DConnected to ", " but authentication required (", s1, s2, ") (#5.7.0).", NULL); + break; + case 534: + quit(code, 1, "DConnected to ", " but authentication mechanism is too weak (", s1, s2, ") (#5.7.9).", NULL); + break; + case 535: + if (slop.len) + quit(code, 1, "DConnected to ", " but authentication credentials invalid (", s1, s2, ") oauth2 error [", slop.s, "]", ") (#5.7.8).", NULL); + else + quit(code, 1, "DConnected to ", " but authentication credentials invalid (", s1, s2, ") (#5.7.8).", NULL); break; case 538: quit(code, 1, "DConnected to ", " but encryption required for requested authentication mechanism ", s1, s2, ") (#5.7.11).", NULL); @@ -1593,8 +1596,10 @@ auth_digest_md5(int use_size) if (substdio_put(&smtpto, "\r\n", 2) == -1 || substdio_flush(&smtpto) == -1) temp_write(); - if ((code = smtpcode()) != 235) + if ((code = smtpcode()) != 235) { + slop.len = 0; decode_smtpauth_err(code, "AUTH ", "DIGEST-MD5"); + } mailfrom_xtext(use_size); } @@ -1714,11 +1719,13 @@ auth_cram(int type, int use_size) if (b64encode(&slop, &auth)) quit(-1, -1, "ZConnected to ", " but unable to base64encode username+digest", NULL); if (substdio_put(&smtpto, auth.s, auth.len) == -1 || - substdio_put(&smtpto, "\r\n", 2) == -1) + substdio_put(&smtpto, "\r\n", 2) == -1 || + substdio_flush(&smtpto) == -1) temp_write(); - substdio_flush(&smtpto); - if ((code = smtpcode()) != 235) + if ((code = smtpcode()) != 235) { + slop.len = 0; decode_smtpauth_err(code, "AUTH ", get_authmethod(type)); + } mailfrom_xtext(use_size); } @@ -1743,9 +1750,11 @@ auth_plain(int use_size) if (substdio_put(&smtpto, auth.s, auth.len) == -1 || substdio_put(&smtpto, "\r\n", 2) == -1 || substdio_flush(&smtpto) == -1) - temp_nomem(); - if ((code = smtpcode()) != 235) + temp_write(); + if ((code = smtpcode()) != 235) { + slop.len = 0; decode_smtpauth_err(code, "AUTH ", "PLAIN"); + } mailfrom_xtext(use_size); } @@ -1767,22 +1776,57 @@ auth_login(int use_size) if (substdio_put(&smtpto, auth.s, auth.len) == -1 || substdio_put(&smtpto, "\r\n", 2) == -1 || substdio_flush(&smtpto) == -1) - temp_nomem(); + temp_write(); if ((code = smtpcode()) != 334) quit(code, 1, "ZConnected to ", " but authentication was rejected (username)", NULL); if (!stralloc_copys(&auth, "")) temp_nomem(); if (b64encode(&pass, &auth)) - quit(-1, -1, "ZConnected to ", " but unable to base64encode pass", NULL); + quit(-1, -1, "ZConnected to ", " but unable to base64encode password", NULL); if (substdio_put(&smtpto, auth.s, auth.len) == -1 || substdio_put(&smtpto, "\r\n", 2) == -1 || substdio_flush(&smtpto) == -1) - temp_nomem(); - if ((code = smtpcode()) != 235) + temp_write(); + if ((code = smtpcode()) != 235) { + slop.len = 0; decode_smtpauth_err(code, "AUTH ", "LOGIN"); + } + mailfrom_xtext(use_size); +} + +#ifdef AUTH_XOAUTH2 +void +auth_xoauth2(int use_size) +{ + int code; + + if (!stralloc_copyb(&plain, "user=", 5) || + !stralloc_cat(&plain, &user) || + !stralloc_catb(&plain, "\001auth=Bearer ", 13) || + !stralloc_cat(&plain, &pass) || + !stralloc_catb(&plain, "\001\001", 2)) + temp_nomem(); + if (b64encode(&plain, &auth)) + quit(-1, -1, "ZConnected to ", " but unable to base64encode (oauth2)", NULL); + if (substdio_put(&smtpto, "AUTH XOAUTH2 ", 13) == -1 || + substdio_put(&smtpto, auth.s, auth.len) == -1 || + substdio_put(&smtpto, "\r\n", 2) == -1 || + substdio_flush(&smtpto) == -1) + temp_write(); + if ((code = smtpcode()) != 235) { + if (substdio_put(&smtpto, "\r\n", 2) == -1 || + substdio_flush(&smtpto) == -1) + temp_write(); + if (b64decode((unsigned char *) smtptext.s + 4, smtptext.len - 5, &slop)) + quit(-1, -1, "ZConnected to ", " but unable to base64decode oauth2 error", NULL); + slop.len--; + code = smtpcode(); + decode_smtpauth_err(code, "AUTH ", "XOAUTH2"); + } mailfrom_xtext(use_size); } +#endif #if defined(HASLIBGSASL) && defined(TLS) static void @@ -2061,8 +2105,14 @@ smtp_auth(const char *type, int use_size) int i = 0, login_supp = 0, plain_supp = 0, cram_md5_supp = 0, cram_sha1_supp = 0, cram_sha224_supp, cram_sha256_supp = 0, cram_sha384_supp, cram_sha512_supp = 0, cram_rmd_supp = 0, digest_md5_supp = 0; +#ifdef AUTH_XOAUTH2 + int xoauth2_supp = 0; +#endif const char *ptr, *no_auth_login, *no_auth_plain, *no_cram_md5, *no_cram_sha1, *no_cram_sha224, *no_cram_sha256, *no_cram_sha384, *no_cram_sha512, *no_cram_ripemd, *no_digest_md5; +#ifdef AUTH_XOAUTH2 + const char *no_auth_xoauth2; +#endif #ifdef TLS int secure_auth; #endif @@ -2127,14 +2177,27 @@ smtp_auth(const char *type, int use_size) if (case_starts(ptr, "PLAIN")) plain_supp = 1; } +#ifdef AUTH_XOAUTH2 + else + if (*ptr == 'X') { + if (case_starts(ptr, "XOAUTH2")) + xoauth2_supp = 1; + } +#endif } #ifdef TLS secure_auth = env_get("SECURE_AUTH") ? 1 : 0; no_auth_login = secure_auth && !ssl ? "" : env_get("DISABLE_AUTH_LOGIN"); no_auth_plain = secure_auth && !ssl ? "" : env_get("DISABLE_AUTH_PLAIN"); +#ifdef AUTH_XOAUTH2 + no_auth_xoauth2 = secure_auth && !ssl ? "" : env_get("DISABLE_AUTH_OAUTH2"); +#endif #else no_auth_login = env_get("DISABLE_AUTH_LOGIN"); no_auth_plain = env_get("DISABLE_AUTH_PLAIN"); +#ifdef AUTH_XOAUTH2 + no_auth_xoauth2 = env_get("DISABLE_AUTH_OAUTH2"); +#endif #endif no_cram_md5 = env_get("DISABLE_CRAM_MD5"); no_cram_sha1 = env_get("DISABLE_CRAM_SHA1"); @@ -2209,6 +2272,12 @@ smtp_auth(const char *type, int use_size) auth_login(use_size); return; } +#ifdef AUTH_XOAUTH2 + if (!no_auth_xoauth2 && xoauth2_supp) { + auth_xoauth2(use_size); + return; + } +#endif } else #if defined(HASLIBGSASL) && defined(TLS) if (scram_sha256_plus_supp && !case_diffs(type, "SCRAM-SHA-256-PLUS")) { @@ -2236,6 +2305,12 @@ smtp_auth(const char *type, int use_size) auth_plain(use_size); return; } else +#ifdef AUTH_XOAUTH2 + if (xoauth2_supp && !case_diffs(type, "XOAUTH2")) { + auth_xoauth2(use_size); + return; + } else +#endif if (cram_md5_supp && !case_diffs(type, "CRAM-MD5")) { auth_cram(AUTH_CRAM_MD5, use_size); return; @@ -3741,13 +3816,16 @@ main(int argc, char **argv) void getversion_qmail_remote_c() { - const char *x = "$Id: qmail-remote.c,v 1.174 2024-05-12 00:20:03+05:30 mbhangui Exp mbhangui $"; + const char *x = "$Id: qmail-remote.c,v 1.175 2024-07-16 00:17:36+05:30 Cprogrammer Exp mbhangui $"; x = sccsidqrdigestmd5h; x++; } /* * $Log: qmail-remote.c,v $ + * Revision 1.175 2024-07-16 00:17:36+05:30 Cprogrammer + * added XOAUTH2 auth method + * * Revision 1.174 2024-05-12 00:20:03+05:30 mbhangui * fix function prototypes * diff --git a/indimail-mta-x/qmail-smtpd.9 b/indimail-mta-x/qmail-smtpd.9 index ef23f3d4a..676e74ed8 100644 --- a/indimail-mta-x/qmail-smtpd.9 +++ b/indimail-mta-x/qmail-smtpd.9 @@ -89,7 +89,7 @@ You can disable HELP by setteing environment variable \fBDISABLE_HELP\fR. \fBqmail-smtpd\fR includes a \'MAIL FROM:\' parameter parser and obeys \'AUTH\' and \'SIZE\' advertisements. -\fBqmail-smtpd\fR can accept LOGIN, PLAIN, CRAM-MD5, CRAM-SHA1, +\fBqmail-smtpd\fR can accept LOGIN, PLAIN, XOAUTH2, CRAM-MD5, CRAM-SHA1, CRAM-SHA224, CRAM-SHA256, CRAM-SHA384, CRAM-RIPEMD, DIGEST-MD5, SCRAM-SHA-1, SCRAM-SHA-1-PLUS, SCRAM-SHA-256, SCRAM-SHA-256-PLUS AUTH types. For auth types other than the SCRAM methods, it invokes @@ -104,17 +104,18 @@ read end. \fIsubprogram\fR should read file descriptor 3 and should in turn return 0 to \fBqmail-smtpd\fR, effectively setting the environment variables TCPREMOTEINFO and AUTHINFO (any supplied value replaced with the authenticated username). One can specifically disable the AUTH methods by -setting DISABLE_AUTH_LOGIN, DISABLE_AUTH_PLAIN, DISABLE_CRAM_MD5, -DISABLE_CRAM_SHA1, DISABLE_CRAM_SHA224, DISABLE_CRAM_SHA256, -DISABLE_CRAM_SHA384, DISABLE_CRAM_SHA512, DISABLE_CRAM_RIPEMD, -DISABLE_DIGEST_MD5, DISABLE_SCRAM_SHA1, DISABLE_SCRAM_SHA1_PLUS, -DISABLE_SCRAM_SHA256, DISABLE_SCRAM_SHA256_PLUS, environment variable. If -you set the environment variable \fBSECURE_AUTH\fR, AUTH LOGIN and AUTH -PLAIN gets disabled unless STARTTLS is issued or you run qmail-smtpd under -SSL (e.g. port 465). You may set \fBFORCE_TLS\fR environment variable to -deny authentication, if the client does not provide the STARTTLS command. -The \fIfalsepgm\fR argument is the name of a program that always fails, -such as \fB/bin/false\fR. +setting DISABLE_AUTH_LOGIN, DISABLE_AUTH_PLAIN, DISABLE_AUTH_OAUTH2, +DISABLE_CRAM_MD5, DISABLE_CRAM_SHA1, DISABLE_CRAM_SHA224, +DISABLE_CRAM_SHA256, DISABLE_CRAM_SHA384, DISABLE_CRAM_SHA512, +DISABLE_CRAM_RIPEMD, DISABLE_DIGEST_MD5, DISABLE_SCRAM_SHA1, +DISABLE_SCRAM_SHA1_PLUS, DISABLE_SCRAM_SHA256, DISABLE_SCRAM_SHA256_PLUS, +environment variable. If +you set the environment variable \fBSECURE_AUTH\fR, AUTH LOGIN, AUTH PLAIN, +AUTH XOAUTH2 gets disabled unless STARTTLS is issued or you run qmail-smtpd +under SSL (e.g. port 465). You may set \fBFORCE_TLS\fR environment variable +to deny authentication, if the client does not provide the STARTTLS +command. The \fIfalsepgm\fR argument is the name of a program that always +fails, such as \fB/bin/false\fR. qmail-smtpd supports SASL - Simple Authentication and Security Layer framework with the GNU SASL library. For SCRAM authentication types, diff --git a/indimail-mta-x/smtpd.c b/indimail-mta-x/smtpd.c index acf235486..e1a8c8a94 100644 --- a/indimail-mta-x/smtpd.c +++ b/indimail-mta-x/smtpd.c @@ -1,6 +1,6 @@ /* * RCS log at bottom - * $Id: smtpd.c,v 1.327 2024-05-16 18:31:07+05:30 Cprogrammer Exp mbhangui $ + * $Id: smtpd.c,v 1.328 2024-07-16 00:17:49+05:30 Cprogrammer Exp mbhangui $ */ #include #include @@ -125,6 +125,9 @@ static int auth_cram_sha384(); static int auth_cram_sha512(); static int auth_cram_ripemd(); static int auth_digest_md5(); +#ifdef AUTH_XOAUTH2 +static int auth_xoauth2(const char *); +#endif #ifdef HASLIBGSASL static int auth_scram_sha1(); static int auth_scram_sha1_plus(); @@ -158,7 +161,7 @@ static SSL *ssl = NULL; static struct strerr *se; #endif static int tr_success = 0, penalty = 5; -static c_char *revision = "$Revision: 1.327 $"; +static c_char *revision = "$Revision: 1.328 $"; static c_char *protocol = "SMTP"; static stralloc proto = { 0 }; static stralloc Revision = { 0 }; @@ -412,6 +415,9 @@ struct authcmd { {"cram-sha512", auth_cram_sha512}, {"cram-ripemd", auth_cram_ripemd}, {"digest-md5", auth_digest_md5}, +#ifdef AUTH_XOAUTH2 + {"xoauth2", auth_xoauth2}, +#endif #ifdef HASLIBGSASL {"scram-sha-1", auth_scram_sha1}, {"scram-sha-1-plus", auth_scram_sha1_plus}, @@ -3045,6 +3051,9 @@ smtp_ehlo(const char *arg) *no_cram_sha1, *no_cram_sha224, *no_cram_sha256, *no_cram_sha384, *no_cram_sha512, *no_cram_ripemd, *no_digest_md5; +#ifdef AUTH_XOAUTH2 + const char *no_auth_xoauth2; +#endif #ifdef HASLIBGSASL char *no_scram_sha1, *no_scram_sha256, *no_scram_sha512; #endif @@ -3052,9 +3061,15 @@ smtp_ehlo(const char *arg) #ifdef TLS no_auth_login = secure_auth && !ssl ? "" : env_get("DISABLE_AUTH_LOGIN"); no_auth_plain = secure_auth && !ssl ? "" : env_get("DISABLE_AUTH_PLAIN"); +#ifdef AUTH_XOAUTH2 + no_auth_xoauth2 = secure_auth && !ssl ? "" : env_get("DISABLE_OAUTH2"); +#endif #else no_auth_login = env_get("DISABLE_AUTH_LOGIN"); no_auth_plain = env_get("DISABLE_AUTH_PLAIN"); +#ifdef AUTH_XOAUTH2 + no_auth_xoauth2 = env_get("DISABLE_AUTH_OAUTH2"); +#endif #endif no_cram_md5 = env_get("DISABLE_CRAM_MD5"); no_cram_sha1 = env_get("DISABLE_CRAM_SHA1"); @@ -3072,29 +3087,33 @@ smtp_ehlo(const char *arg) no_scram_sha256_plus = env_get("DISABLE_SCRAM_SHA256_PLUS"); no_scram_sha512_plus = env_get("DISABLE_SCRAM_SHA512_PLUS"); #endif -#ifdef HASLIBGSASL - flags1 = !no_auth_login && !no_auth_plain && !no_cram_md5 && - !no_cram_sha1 && !no_cram_sha256 && !no_cram_sha512 && - !no_cram_ripemd && !no_digest_md5 && !no_scram_sha1 && - !no_scram_sha256 && !no_scram_sha512 && !no_scram_sha1_plus && - !no_scram_sha256_plus && !no_scram_sha512_plus; - flags2 = !no_auth_login || !no_auth_plain || !no_cram_md5 || - !no_cram_sha1 || !no_cram_sha256 || !no_cram_sha512 || !no_cram_ripemd - || !no_scram_sha1 || !no_scram_sha256 || !no_scram_sha512 || - !no_scram_sha1_plus || !no_scram_sha256_plus || !no_scram_sha512_plus; -#else flags1 = !no_auth_login && !no_auth_plain && !no_cram_md5 && !no_cram_sha1 && !no_cram_sha256 && !no_cram_sha512 && !no_cram_ripemd && !no_digest_md5; flags2 = !no_auth_login || !no_auth_plain || !no_cram_md5 || !no_cram_sha1 || !no_cram_sha256 || !no_cram_sha512 || !no_cram_ripemd; +#ifdef HASLIBGSASL + flags1 = flags1 && !no_scram_sha1 && !no_scram_sha256 && + !no_scram_sha512 && !no_scram_sha1_plus && !no_scram_sha256_plus && + !no_scram_sha512_plus; + flags2 = flags2 || !no_scram_sha1 || !no_scram_sha256 || !no_scram_sha512 || + !no_scram_sha1_plus || !no_scram_sha256_plus || !no_scram_sha512_plus; +#endif +#ifdef AUTH_XOAUTH2 + flags1 = flags1 && !no_auth_xoauth2; + flags2 = flags2 || !no_auth_xoauth2; #endif if (flags1) { /*- all auth methods enabled */ + out("250-AUTH LOGIN PLAIN", NULL); +#ifdef AUTH_XOAUTH2 + out(" XOAUTH2", NULL); +#endif + out(" CRAM-MD5 CRAM-SHA1 CRAM-SHA224 CRAM-SHA256 CRAM-SHA384 CRAM-SHA512 CRAM-RIPEMD DIGEST-MD5", NULL); #ifdef HASLIBGSASL #if 0 - out("250-AUTH LOGIN PLAIN CRAM-MD5 CRAM-SHA1 CRAM-SHA224 CRAM-SHA256 CRAM-SHA384 CRAM-SHA512 CRAM-RIPEMD DIGEST-MD5 SCRAM-SHA-1 SCRAM-SHA-256 SCRAM-SHA-512", NULL); + out(" SCRAM-SHA-1 SCRAM-SHA-256 SCRAM-SHA-512", NULL); #else - out("250-AUTH LOGIN PLAIN CRAM-MD5 CRAM-SHA1 CRAM-SHA224 CRAM-SHA256 CRAM-SHA384 CRAM-SHA512 CRAM-RIPEMD DIGEST-MD5 SCRAM-SHA-1 SCRAM-SHA-256", NULL); + out(" SCRAM-SHA-1 SCRAM-SHA-256", NULL); #endif #ifdef TLS if (ssl) @@ -3106,10 +3125,14 @@ smtp_ehlo(const char *arg) #endif out("\r\n", NULL); if (old_client_bug) { + out("250-AUTH=LOGIN PLAIN", NULL); +#ifdef AUTH_XOAUTH2 + out(" XOAUTH2", NULL); +#endif #if 0 - out("250-AUTH=LOGIN PLAIN CRAM-MD5 CRAM-SHA1 CRAM-SHA224 CRAM-SHA256 CRAM-SHA384 CRAM-SHA512 CRAM-RIPEMD DIGEST-MD5 SCRAM-SHA-1 SCRAM-SHA-256 SCRAM-SHA-512", NULL); + out(" CRAM-MD5 CRAM-SHA1 CRAM-SHA224 CRAM-SHA256 CRAM-SHA384 CRAM-SHA512 CRAM-RIPEMD DIGEST-MD5 SCRAM-SHA-1 SCRAM-SHA-256 SCRAM-SHA-512", NULL); #else - out("250-AUTH=LOGIN PLAIN CRAM-MD5 CRAM-SHA1 CRAM-SHA224 CRAM-SHA256 CRAM-SHA384 CRAM-SHA512 CRAM-RIPEMD DIGEST-MD5 SCRAM-SHA-1 SCRAM-SHA-256", NULL); + out(" CRAM-MD5 CRAM-SHA1 CRAM-SHA224 CRAM-SHA256 CRAM-SHA384 CRAM-SHA512 CRAM-RIPEMD DIGEST-MD5 SCRAM-SHA-1 SCRAM-SHA-256", NULL); #endif #ifdef TLS if (ssl) @@ -3121,10 +3144,19 @@ smtp_ehlo(const char *arg) #endif out("\r\n", NULL); } -#else - out("250-AUTH LOGIN PLAIN CRAM-MD5 CRAM-SHA1 CRAM-SHA224 CRAM-SHA256 CRAM-SHA384 CRAM-SHA512 CRAM-RIPEMD DIGEST-MD5\r\n", NULL); - if (old_client_bug) - out("250-AUTH=LOGIN PLAIN CRAM-MD5 CRAM-SHA1 CRAM-SHA224 CRAM-SHA256 CRAM-SHA384 CRAM-SHA512 CRAM-RIPEMD DIGEST-MD5\r\n", NULL); +#else /*- non GSASL */ + out("250-AUTH LOGIN PLAIN", NULL); +#ifdef AUTH_XOAUTH2 + out(" XOAUTH2", NULL); +#endif + out(" CRAM-MD5 CRAM-SHA1 CRAM-SHA224 CRAM-SHA256 CRAM-SHA384 CRAM-SHA512 CRAM-RIPEMD DIGEST-MD5\r\n", NULL); + if (old_client_bug) { + out("250-AUTH=LOGIN PLAIN", NULL); +#ifdef AUTH_XOAUTH2 + out(" XOAUTH2", NULL); +#endif + out(" CRAM-MD5 CRAM-SHA1 CRAM-SHA224 CRAM-SHA256 CRAM-SHA384 CRAM-SHA512 CRAM-RIPEMD DIGEST-MD5\r\n", NULL); + } #endif /*- #ifdef HAVELIBGSASL */ } else /*- few auth methods disabled */ if (flags2) { @@ -3135,6 +3167,10 @@ smtp_ehlo(const char *arg) out(" LOGIN", NULL); if (!no_auth_plain) out(" PLAIN", NULL); +#ifdef AUTH_XOAUTH2 + if (!no_auth_xoauth2) + out(" XOAUTH2", NULL); +#endif if (!no_cram_md5) out(" CRAM-MD5", NULL); if (!no_cram_sha1) @@ -3173,6 +3209,10 @@ smtp_ehlo(const char *arg) out(flag++ == 0 ? "250-AUTH=" : " ", "LOGIN", NULL); if (!no_auth_plain) out(flag++ == 0 ? "250-AUTH=" : " ", "PLAIN", NULL); +#ifdef AUTH_XOAUTH2 + if (!no_auth_xoauth2) + out(flag++ == 0 ? "250-AUTH=" : " ", "XOAUTH2", NULL); +#endif if (!no_cram_md5) { out(flag++ == 0 ? "250-AUTH=" : " ", "CRAM-MD5", NULL); } @@ -5146,15 +5186,14 @@ authenticate(int method) close(pe[1]); #endif substdio_fdbuf(&ssup, safewrite, pi[1], upbuf, sizeof upbuf); - if (substdio_put(&ssup, user.s, user.len) == -1 || - substdio_put(&ssup, pass.s, pass.len) == -1 || - substdio_put(&ssup, resp.s, resp.len) == -1) - return err_write(); strnum[0] = method; - strnum[1] = 0; - if (!stralloc_copyb(&authmethod, strnum, 2)) + if (!stralloc_copyb(&authmethod, strnum, 1) || + !stralloc_0(&authmethod)) die_nomem(); - if (substdio_put(&ssup, authmethod.s, authmethod.len) == -1 || + if (substdio_put(&ssup, user.s, user.len) == -1 || + substdio_put(&ssup, pass.s, pass.len) == -1 || + substdio_put(&ssup, resp.s, resp.len) == -1 || + substdio_put(&ssup, authmethod.s, authmethod.len) == -1 || substdio_flush(&ssup) == -1) return err_write(); close(pi[1]); @@ -6271,11 +6310,62 @@ auth_digest_md5() return (r); } +#ifdef AUTH_XOAUTH2 +static int +auth_xoauth2(const char *arg) +{ + int r, i; + char *p1, *p2; + + /* + * printf("user=%s\001auth=Bearer %s\001\001", user, token); + */ +#ifdef TLS + if (secure_auth && !ssl) + return err_noauthallowed(); +#endif + if (*arg) { + if ((r = b64decode((const unsigned char *) arg, str_len(arg), &slop)) == 1) + return err_input(); + } else { + out("334 \r\n", NULL); + flush(); + if (authgetl() < 0) + return -1; + if ((r = b64decode((const unsigned char *) authin.s, authin.len, &slop)) == 1) + return err_input(); + } + if (r == -1 || !stralloc_0(&slop)) + die_nomem(); + if (str_diffn(slop.s, "user=", 5)) + return err_input(); + if (!(p1 = str_str(slop.s, "\001auth=Bearer "))) + return err_input(); + if (!(p2 = str_str(p1 + 13, "\001\001"))) + return err_input(); + for (i = 0, p2 = slop.s + 5;*p2 && *p2 != '\01'; p2++, i++); + if (!stralloc_copyb(&user, slop.s + 5, i) || + !stralloc_0(&user)) + die_nomem(); + for (i = 0, p2 = p1 + 13;*p2 && *p2 != '\01'; p2++, i++); + if (!stralloc_copyb(&pass, p1 + 13, i) || + !stralloc_0(&pass)) + die_nomem(); + if (!user.len || !pass.len) + return err_input(); + r = authenticate(AUTH_XOAUTH2); + if (!r || r == 3) + authd = AUTH_XOAUTH2; + return (r); +} +#endif + void smtp_auth(const char *arg) { int i, j; - char *cmd; + char *cmd, *scope; + char ch[2]; switch (setup_state) { @@ -6351,6 +6441,19 @@ smtp_auth(const char *arg) err_authfailure(user.len ? user.s : 0, j); if (penalty > 0) sleep(penalty); +#ifdef AUTH_XOAUTH2 + if (case_equals(authcmds[i].text, "xoauth2")) { + scope = env_get("XOAUTH2_SCOPE"); + if (!stralloc_copyb(&slop, "{\"status\":\"401\",\"schemes\":bearer mac\",\"scope\":\"", 47) || + !stralloc_cats(&slop, scope ? scope : "https://github.com/indimail/indimail-mta/") || + !stralloc_catb(&slop, "\"}", 2)) + die_nomem(); + if (b64encode(&slop, &resp) < 0 || !stralloc_0(&resp)) + die_nomem(); + out("334 ", resp.s, "\r\n", NULL); + substdio_get(&ssin, ch, 2); + } +#endif out("535 authorization failure (#5.7.8)\r\n", NULL); flush(); break; @@ -7381,6 +7484,9 @@ addrrelay() /* * $Log: smtpd.c,v $ + * Revision 1.328 2024-07-16 00:17:49+05:30 Cprogrammer + * added XOAUTH2 auth method + * * Revision 1.327 2024-05-16 18:31:07+05:30 Cprogrammer * fixed missing wsp * @@ -7822,7 +7928,7 @@ addrrelay() const char * getversion_smtpd_c() { - const char *x = "$Id: smtpd.c,v 1.327 2024-05-16 18:31:07+05:30 Cprogrammer Exp mbhangui $"; + const char *x = "$Id: smtpd.c,v 1.328 2024-07-16 00:17:49+05:30 Cprogrammer Exp mbhangui $"; x++; return revision + 11; diff --git a/indimail-mta-x/svctool.9 b/indimail-mta-x/svctool.9 index d6e87a11a..0ca9f2814 100644 --- a/indimail-mta-x/svctool.9 +++ b/indimail-mta-x/svctool.9 @@ -207,7 +207,7 @@ Known values for OPTION are: cugmail - Allow only local valid senders to use SMTP. antispoof - Turn on antispoofing code authsmtp - Enable Authenticated SMTP - secureauth - Disable AUTH PLAIN, LOGIN methods over un-encrypted channel + secureauth - Disable AUTH PLAIN, LOGIN, XOAUTH2 methods over un-encrypted channel forceauthsmtp - Enforce Authenticated SMTP before accepting MAIL FROM enablecram - Enable the pw_passwd field of indimail table to be used for CRAM authenticated smtp methods diff --git a/indimail-mta-x/sys-checkpwd.8 b/indimail-mta-x/sys-checkpwd.8 index 40938bd16..4a5ade0a6 100644 --- a/indimail-mta-x/sys-checkpwd.8 +++ b/indimail-mta-x/sys-checkpwd.8 @@ -1,3 +1,4 @@ +.\" vim: tw=75 .TH sys-checkpwd 8 .SH NAME sys-checkpwd \- indimail-mta checkpassword program for authentication @@ -7,9 +8,9 @@ sys-checkpwd \- indimail-mta checkpassword program for authentication .SH DESCRIPTION \fBsys-checkpwd\fR supports authentication for ESMTP AUTH option in -\fBqmail-smtpd(8)\fR, allowing the LOGIN, PLAIN, and CRAM-MD5, CRAM-SHA1, -CRAM-SHA224, CRAM-SHA256, CRAM-SHA384, CRAM-SHA512, CRAM-RIPEMD, DIGEST-MD5 -AUTH types. \fBsys-checkpwd\fR looks up userids in the systems +\fBqmail-smtpd(8)\fR, allowing the LOGIN, PLAIN, XOAUTH2, and CRAM-MD5, +CRAM-SHA1, CRAM-SHA224, CRAM-SHA256, CRAM-SHA384, CRAM-SHA512, CRAM-RIPEMD, +DIGEST-MD5 AUTH types. \fBsys-checkpwd\fR looks up userids in the systems authentication database (/etc/passwd or /etc/shadow). \fBsys-checkpwd\fR needs to be setuid root to function. \fBsys-checkpwd\fR drops all root privileges after reading the shadow(5) file, switches to the real uid of @@ -29,9 +30,9 @@ to descriptor 4 and the data which was earlier read on descriptor 3 is written back on descriptor 4. The alternate program is invoked when sys-checkpwd doesn't support authentication for the supplied login name. .PP -For LOGIN, PLAIN AUTH types, the information supplied on descriptor 3 is a -login name terminated by \\0 and password terminated by \\0. -\fBsys-checkpwd\fR encrypts the password using cyrpt(3) routine and +For LOGIN, PLAIN, XOAUTH2 AUTH types, the information supplied on +descriptor 3 is a login name terminated by \\0 and password terminated +by \\0. \fBsys-checkpwd\fR encrypts the password using crypt(3) routine and compares it against the value present in the passwd database. The encrypted password can be in DES, MD5, SHA-256 or SHA-512 hash. .PP @@ -51,9 +52,9 @@ temporary problem checking the password, \fBsys-checkpwd\fR exits 111. hostname is simply used to form the CRAM-MD5, CRAM-SHA1, CRAM-SHA224, CRAM-SHA256, CRAM-SHA384, CRAM-RIPEMD, DIGEST-MD5 challenge. \fBqmail-smtpd\fR invokes \fBsys-checkpwd\fR, feeding it the username and -password, in the case of LOGIN or PLAIN, or the username, challenge, and -response, in the case of CRAM-MD5, CRAM-SHA1, CRAM-RIPEMD, DIGEST-MD5. If -the user checks out, \fBsys-checkpwd\fR exits with a status of 0 for the +password, in the case of LOGIN, PLAIN, XOAUTH2 or the username, challenge, +and response, in the case of CRAM-MD5, CRAM-SHA1, CRAM-RIPEMD, DIGEST-MD5. +If the user checks out, \fBsys-checkpwd\fR exits with a status of 0 for the user to be authenticated. Otherwise, subprogram should exit with a non-zero status, or call an alternate checkpassword program. The last subprogram can usually be /usr/bin/false (or /bin/false, depending on your flavor of OS). diff --git a/indimail-mta-x/sys-checkpwd.c b/indimail-mta-x/sys-checkpwd.c index cfaaa5554..4ed8eb951 100644 --- a/indimail-mta-x/sys-checkpwd.c +++ b/indimail-mta-x/sys-checkpwd.c @@ -1,8 +1,10 @@ /* - * $Id: sys-checkpwd.c,v 1.22 2024-05-09 22:03:17+05:30 mbhangui Exp mbhangui $ + * $Id: sys-checkpwd.c,v 1.23 2024-07-16 00:18:31+05:30 Cprogrammer Exp mbhangui $ * * Test method * printf "login\0pass\0\0\x01\0" >/tmp/input + * or + * printf "login\0challenge\0response\0\x01\0" >/tmp/input * as root run * env DEBUG=1 DEBUG_LOGIN=1 sys-checkpwd /bin/false < /tmp/input 3<&0 */ @@ -120,7 +122,7 @@ runcmmd(const char *cmmd) } static void -pipe_exec(char **argv, char *tmpbuf, int len, int restore) +pipe_exec(char **argv, char *buffer, int len, int restore) { int pipe_fd[2]; char strnum[FMT_ULONG]; @@ -138,8 +140,8 @@ pipe_exec(char **argv, char *tmpbuf, int len, int restore) if (pipe_fd[1] != 3 && pipe_fd[1] != 4) close(pipe_fd[1]); if (restore > 0) - tmpbuf[restore] = '@'; - if (write(4, tmpbuf, len) != len) + buffer[restore] = '@'; + if (write(4, buffer, len) != len) strerr_die2sys(111, FATAL, "write: "); close(4); execv(argv[1], argv + 1); @@ -149,7 +151,7 @@ pipe_exec(char **argv, char *tmpbuf, int len, int restore) int main(int argc, char **argv) { - char *ptr, *tmpbuf, *login, *response, *challenge, *stored; + char *ptr, *authstr, *login, *response, *challenge, *stored; char strnum[FMT_ULONG]; static stralloc buf = {0}; int i, count, offset, status, save = -1, use_pwgr, authlen = 512, @@ -166,7 +168,7 @@ main(int argc, char **argv) _exit(2); use_pwgr = env_get("USE_QPWGR") ? 1 : 0; debug = env_get("DEBUG") ? 1 : 0; - if (!(tmpbuf = alloc((authlen + 1) * sizeof(char)))) { + if (!(authstr = alloc((authlen + 1) * sizeof(char)))) { print_error("out of memory"); strnum[fmt_uint(strnum, (unsigned int) authlen + 1)] = 0; strerr_warn3("alloc-", strnum, ": ", &strerr_sys); @@ -175,7 +177,7 @@ main(int argc, char **argv) enable_cram = env_get("ENABLE_CRAM") ? 1 : 0; for (offset = 0;;) { do { - count = read(3, tmpbuf + offset, authlen + 1 - offset); + count = read(3, authstr + offset, authlen + 1 - offset); #ifdef ERESTART } while(count == -1 && (errno == EINTR || errno == ERESTART)); #else @@ -192,22 +194,22 @@ main(int argc, char **argv) _exit(2); } count = 0; - login = tmpbuf + count; /*- username */ - for (;tmpbuf[count] && count < offset;count++); - if (count == offset || (count + 1) == offset) + login = authstr + count; /*- username */ + for (; authstr[count] && count < offset; count++); + if (count == offset || (count + 1) == offset) /*- early termination */ _exit(2); + count++; - challenge = tmpbuf + count; /*- challenge for CRAM methods (or plain text password for LOGIN/PLAIN) */ - for (;tmpbuf[count] && count < offset;count++); + challenge = authstr + count; /*- challenge for CRAM methods (or plain text password for LOGIN/PLAIN/XOAUTH2) */ + for (; authstr[count] && count < offset; count++); if (count == offset || (count + 1) == offset) _exit(2); + count++; - response = tmpbuf + count; /*- response (CRAM methods, etc) */ - for (; tmpbuf[count] && count < offset; count++); - if (count == offset || (count + 1) == offset) - auth_method = 0; - else - auth_method = tmpbuf[count + 1]; + response = authstr + count; /*- response (CRAM methods, etc) */ + for (; authstr[count] && count < offset; count++); + + auth_method = authstr[offset - 2]; if (env_get("STRIP_DOMAIN")) { /*- set this for roundcubemail */ i = str_chr(login, '@'); @@ -218,7 +220,7 @@ main(int argc, char **argv) } if (!(pw = (use_pwgr ? qgetpwnam : getpwnam) (login))) { if (errno != ETXTBSY) - pipe_exec(argv, tmpbuf, offset, save); + pipe_exec(argv, authstr, offset, save); else { print_error("getpwnam"); strerr_die2sys(111, FATAL, "getpwnam: "); @@ -232,7 +234,7 @@ main(int argc, char **argv) #ifdef HASUSERPW if (!(upw = getuserpw(login))) { if (errno != ETXTBSY) - pipe_exec(argv, tmpbuf, offset, save); + pipe_exec(argv, authstr, offset, save); else { print_error("getuserpw"); strerr_die2sys(111, FATAL, "getuserpw: "); @@ -246,7 +248,7 @@ main(int argc, char **argv) #ifdef HASGETSPNAM if (!(spw = getspnam(login))) { if (errno != ETXTBSY) - pipe_exec(argv, tmpbuf, offset, save); + pipe_exec(argv, authstr, offset, save); else { print_error("getspnam"); strerr_die2sys(111, FATAL, "getspnam: "); @@ -263,10 +265,10 @@ main(int argc, char **argv) i = str_rchr(argv[0], '/'); ptr = (char *) get_authmethod(auth_method); subprintf(subfderr, - "%s: uid=%u, login=%s, challenge=%s, response=%s, encrypted=%s, CRAM=%s AUTH=%s", + "%s: uid=%u, login=%s, challenge=%s, response=%s, encrypted=%s, CRAM=%s AUTH=%s-%d", argv[0][i] ? argv[0] + i + 1 : argv[0], getuid(), login, challenge, response, stored ? stored : "null", - enable_cram ? "Yes" : "No", ptr); + enable_cram ? "Yes" : "No", ptr, auth_method); #ifdef HASUSERPW subprintf(subfderr, ", USERPW=YES"); #else @@ -300,11 +302,11 @@ main(int argc, char **argv) substdio_flush(subfderr); } if (!stored) - pipe_exec(argv, tmpbuf, offset, save); + pipe_exec(argv, authstr, offset, save); if (pw_comp((unsigned char *) login, (unsigned char *) stored, (unsigned char *) (*response ? challenge : 0), (unsigned char *) (*response ? response : challenge), auth_method)) - pipe_exec(argv, tmpbuf, offset, save); /*- never returns */ + pipe_exec(argv, authstr, offset, save); /*- never returns */ status = 0; if ((ptr = (char *) env_get("POSTAUTH"))) { if (!access(ptr, X_OK)) { @@ -325,7 +327,7 @@ main(int argc, char **argv) void getversion_sys_checkpwd_c() { - const char *x = "$Id: sys-checkpwd.c,v 1.22 2024-05-09 22:03:17+05:30 mbhangui Exp mbhangui $"; + const char *x = "$Id: sys-checkpwd.c,v 1.23 2024-07-16 00:18:31+05:30 Cprogrammer Exp mbhangui $"; x = sccsidmakeargsh; x++; @@ -334,6 +336,9 @@ getversion_sys_checkpwd_c() /* * $Log: sys-checkpwd.c,v $ + * Revision 1.23 2024-07-16 00:18:31+05:30 Cprogrammer + * changed variable name tmpbuf to authstr + * * Revision 1.22 2024-05-09 22:03:17+05:30 mbhangui * fix discarded-qualifier compiler warnings * diff --git a/indimail-mta-x/tests/test-indimail-mta b/indimail-mta-x/tests/test-indimail-mta index 19dde4846..bad1e048f 100755 --- a/indimail-mta-x/tests/test-indimail-mta +++ b/indimail-mta-x/tests/test-indimail-mta @@ -1,6 +1,6 @@ #!/bin/sh # -# $Id: test-indimail-mta,v 1.79 2024-05-21 20:59:25+05:30 Cprogrammer Exp mbhangui $ +# $Id: test-indimail-mta,v 1.80 2024-07-16 00:19:03+05:30 Cprogrammer Exp mbhangui $ # start=$(date +'%s') user=$(whoami) @@ -1185,6 +1185,7 @@ create_authsmtp() echo "pass=\`echo \$var | cut -d ' ' -f2\`" echo "exec 4>$tmpdir/authsmtp.\$\$ 3<$tmpdir/authsmtp.\$\$" echo "/bin/rm -f $tmpdir/authsmtp.\$\$" + echo "echo \"authsmtp: user=\$user, pass=\$pass\" 1>&2" /bin/echo "echo \$var | tr [\" \"] [\"\\0\"] 1>&4" echo "if [ \"\$user\" = \"$user@$HOSTNAME\" -a \"\$pass\" = \"abcd12345678\" ] ; then" echo " exit 0" @@ -1328,7 +1329,7 @@ start_tcpserver_smtp_unix() MAKE_SEEKABLE=1 \ DKIMVERIFY="" \ $tcpserver $smtp_socket $qmail_smtpd $HOSTNAME \ - $testdir/bin/authsmtp $sbindir/sys-checkpwd /bin/false + $sys_pwd $testdir/bin/authsmtp /bin/false ) > $logdir/smtpd/smtpd.log 2>&1 & smtp_pid=$(/bin/ps -ef|grep $smtp_socket|grep qmail-smtpd|awk '{print $2}') @@ -2804,7 +2805,7 @@ test_qmail_remote_auth() { t1=$(date +"%s.%4N") case $1 in - "CRAM-MD5") + "CRAM-MD5"|"CRAM-SHA1"|"CRAM-SHA224"|"CRAM-SHA256"|"CRAM-SHA384"|"CRAM-SHA512"|"CRAM-RIPEMD"|"DIGEST-MD5") u=$user pass=$(sudo grep $user /etc/shadow|cut -d: -f2) ;; @@ -2837,7 +2838,7 @@ test_qmail_remote_auth() t2=$(date +"%s.%4N") secs=$(echo $t1 $t2 $sleep_secs | awk '{printf("%0.4f\n", $2-$1-$3)}') tcount=$(expr $tcount + 1) - printf "\r testing qmail-remote AUTH %-8s qmail-remote send+receive succeeded %31s [%.4f sec]\n" "$1" " " $secs + printf "\r testing qmail-remote AUTH %-11s qmail-remote send+receive succeeded %28s [%.4f sec]\n" "$1" " " $secs print_pct /bin/rm -f $testdir/tmpdir.$$ $tmpdir/mail.txt else @@ -2882,7 +2883,7 @@ test_qmail_remote_auth() failed=1 exit 1 fi - if [ " $1" = " CRAM-MD5" ] ; then + if [ " $1" = " DIGEST-MD5" ] ; then if [ $batv_status -eq 0 -a "$addr" = "$user@$HOSTNAME" ] ; then t2=$(date +"%s.%4N") secs=$(echo $t1 $t2 $sleep_secs | awk '{printf("%0.4f\n", $2-$1-$3)}') @@ -6373,7 +6374,22 @@ do_without_svscan() test_qmail_remote_auth "PLAIN" test_qmail_remote_auth "LOGIN" + test_qmail_remote_auth "XOAUTH2" + ( + printf "#!/bin/sh\n" + echo "exec $sys_pwd \$*" + ) > $testdir/bin/authsmtp + chmod +x $testdir/bin/authsmtp test_qmail_remote_auth "CRAM-MD5" + test_qmail_remote_auth "CRAM-SHA1" + test_qmail_remote_auth "CRAM-SHA224" + test_qmail_remote_auth "CRAM-SHA256" + test_qmail_remote_auth "CRAM-SHA384" + test_qmail_remote_auth "CRAM-SHA512" + test_qmail_remote_auth "CRAM-RIPEMD" + test_qmail_remote_auth "DIGEST-MD5" + /bin/rm -f $testdir/bin/authsmtp + create_authsmtp test_qmail_remote_routing test_qmail_remote_auth_cdb test_qmail_remote_starttls @@ -9034,7 +9050,7 @@ fi if [ -f $testdir/qtotal.count ] ; then total_tests=$(cat $testdir/qtotal.count) else - total_tests=314 + total_tests=322 fi failed=0 do_setup @@ -9089,6 +9105,9 @@ exit 0 # # $Log: test-indimail-mta,v $ +# Revision 1.80 2024-07-16 00:19:03+05:30 Cprogrammer +# added test for CRAM, XOAUTH2 auth methods +# # Revision 1.79 2024-05-21 20:59:25+05:30 Cprogrammer # fixed display of time taken #