Re: Why is SASL authentication have to be so difficult? Round 2
On Mon, 6 Dec 2004, Robert Lubbers wrote: * OK cyrus.domain.com Cyrus IMAP4 v2.2.9 server ready . login cyrususer secret . NO Login failed: can't request info until later in exchange . logout * BYE LOGOUT received . OK Completed Ken pointed something out to me about this yesterday, notably, that imap has code e.g. r = sasl_getprop(imapd_saslconn, SASL_USERNAME, (const void **) canon_user); while pop does not. And I don't know the history. This is one reason I'd rather have a real database of bugs, but making bugzilla manageable for this is somewhat hard. The commit log on 1.398.2.81 is don't canonify a userid twice So we switch from (effectively) calling auth_canonifyid from canonify_userid before doing sasl stuff, to this sasl_getprop after. Reversing that change would be as follows, you'll almost certainly need to apply it by hand. hand. Index: imapd.c === RCS file: /afs/andrew.cmu.edu/system/cvs/src/cyrus/imap/imapd.c,v retrieving revision 1.398.2.81 retrieving revision 1.398.2.80 diff -u -r1.398.2.81 -r1.398.2.80 --- imapd.c 29 May 2003 20:18:58 - 1.398.2.81 +++ imapd.c 29 May 2003 14:50:45 - 1.398.2.80 @@ -38,7 +38,7 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: imapd.c,v 1.398.2.81 2003/05/29 20:18:58 rjs3 Exp $ */ +/* $Id: imapd.c,v 1.398.2.80 2003/05/29 14:50:45 ken3 Exp $ */ #include config.h @@ -1561,7 +1561,8 @@ char c; struct buf passwdbuf; char *passwd; -const char *reply = NULL; +char *canon_user; +const char *reply = 0; int plaintextloginpause; int r; @@ -1571,10 +1572,20 @@ return; } +canon_user = canonify_userid(user, NULL, NULL); + +if (!canon_user) { + syslog(LOG_NOTICE, badlogin: %s plaintext %s invalid user, + imapd_clienthost, beautify_string(user)); + prot_printf(imapd_out, %s NO %s\r\n, tag, + error_message(IMAP_INVALID_USER)); + return; +} + /* possibly disallow login */ if ((imapd_starttls_done == 0) (config_getswitch(IMAPOPT_ALLOWPLAINTEXT) == 0) - !is_userid_anonymous(user)) { + strcmp(canon_user, anonymous) != 0) { eatline(imapd_in, ' '); prot_printf(imapd_out, %s NO Login only available under a layer\r\n, tag); @@ -1596,7 +1607,7 @@ passwd = passwdbuf.s; -if (is_userid_anonymous(user)) { +if (!strcmp(canon_user, anonymous)) { if (config_getswitch(IMAPOPT_ALLOWANONYMOUSLOGIN)) { passwd = beautify_string(passwd); if (strlen(passwd) 500) passwd[500] = '\0'; @@ -1615,21 +1626,22 @@ } } else if ((r = sasl_checkpass(imapd_saslconn, -user, -strlen(user), +canon_user, +strlen(canon_user), passwd, strlen(passwd))) != SASL_OK) { syslog(LOG_NOTICE, badlogin: %s plaintext %s %s, - imapd_clienthost, user, sasl_errdetail(imapd_saslconn)); + imapd_clienthost, canon_user, sasl_errdetail(imapd_saslconn)); sleep(3); - if ((reply = sasl_errstring(r, NULL, NULL)) != NULL) { + if (reply) { + prot_printf(imapd_out, %s NO Login failed: %s\r\n, tag, reply); + } else if ((reply = sasl_errstring(r, NULL, NULL)) != NULL) { prot_printf(imapd_out, %s NO Login failed: %s\r\n, tag, reply); } else { prot_printf(imapd_out, %s NO Login failed: %d\r\n, tag, r); } - snmp_increment_args(AUTHENTICATION_NO, 1, VARIABLE_AUTH, 0 /* hash_simple(LOGIN) */, VARIABLE_LISTEND); @@ -1637,26 +1649,6 @@ return; } else { - const char *canon_user; - - r = sasl_getprop(imapd_saslconn, SASL_USERNAME, - (const void **) canon_user); - - if(r != SASL_OK) { - if ((reply = sasl_errstring(r, NULL, NULL)) != NULL) { - prot_printf(imapd_out, %s NO Login failed: %s\r\n, - tag, reply); - } else { - prot_printf(imapd_out, %s NO Login failed: %d\r\n, tag, r); - } - - snmp_increment_args(AUTHENTICATION_NO, 1, -VARIABLE_AUTH, 0 /* hash_simple(LOGIN) */, -VARIABLE_LISTEND); - freebuf(passwdbuf); - return; - } - imapd_userid = xstrdup(canon_user); snmp_increment_args(AUTHENTICATION_YES, 1, VARIABLE_AUTH, 0 /*hash_simple(LOGIN) */, @@ -1761,6 +1753,7 @@ */ sasl_result = sasl_getprop(imapd_saslconn, SASL_USERNAME, (const void **) canon_user); +imapd_userid = xstrdup(canon_user); if (sasl_result != SASL_OK) { prot_printf(imapd_out, %s NO weird SASL error %d SASL_USERNAME\r\n, tag, sasl_result); @@ -1769,7 +1762,6 @@ reset_saslconn(imapd_saslconn); return; } -imapd_userid = xstrdup(canon_user); proc_register(imapd, imapd_clienthost, imapd_userid, (char *)0); --- Cyrus Home Page: http://asg.web.cmu.edu/cyrus Cyrus Wiki/FAQ:
Re: Why is SASL authentication have to be so difficult? Round 2
On Tue, 7 Dec 2004, Derrick J Brashear wrote: On Mon, 6 Dec 2004, Robert Lubbers wrote: * OK cyrus.domain.com Cyrus IMAP4 v2.2.9 server ready . login cyrususer secret . NO Login failed: can't request info until later in exchange . logout * BYE LOGOUT received . OK Completed Ken pointed something out to me about this yesterday, notably, that imap has code e.g. r = sasl_getprop(imapd_saslconn, SASL_USERNAME, (const void **) canon_user); while pop does not. And I don't know the history. This is one reason I'd rather have a real database of bugs, but making bugzilla manageable for this is somewhat hard. The commit log on 1.398.2.81 is don't canonify a userid twice Derrick, There was a long discussion about this on cyrus-sasl and cyrus-devel lists awhile back: http://asg.web.cmu.edu/archive/message.php?mailbox=archive.cyrus-saslsearchterm=saslpasswd2%20and%20virtdomainsmsg=3683 -Igor So we switch from (effectively) calling auth_canonifyid from canonify_userid before doing sasl stuff, to this sasl_getprop after. Reversing that change would be as follows, you'll almost certainly need to apply it by hand. hand. Index: imapd.c === RCS file: /afs/andrew.cmu.edu/system/cvs/src/cyrus/imap/imapd.c,v retrieving revision 1.398.2.81 retrieving revision 1.398.2.80 diff -u -r1.398.2.81 -r1.398.2.80 --- imapd.c 29 May 2003 20:18:58 - 1.398.2.81 +++ imapd.c 29 May 2003 14:50:45 - 1.398.2.80 @@ -38,7 +38,7 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: imapd.c,v 1.398.2.81 2003/05/29 20:18:58 rjs3 Exp $ */ +/* $Id: imapd.c,v 1.398.2.80 2003/05/29 14:50:45 ken3 Exp $ */ #include config.h @@ -1561,7 +1561,8 @@ char c; struct buf passwdbuf; char *passwd; -const char *reply = NULL; +char *canon_user; +const char *reply = 0; int plaintextloginpause; int r; @@ -1571,10 +1572,20 @@ return; } +canon_user = canonify_userid(user, NULL, NULL); + +if (!canon_user) { + syslog(LOG_NOTICE, badlogin: %s plaintext %s invalid user, + imapd_clienthost, beautify_string(user)); + prot_printf(imapd_out, %s NO %s\r\n, tag, + error_message(IMAP_INVALID_USER)); + return; +} + /* possibly disallow login */ if ((imapd_starttls_done == 0) (config_getswitch(IMAPOPT_ALLOWPLAINTEXT) == 0) - !is_userid_anonymous(user)) { + strcmp(canon_user, anonymous) != 0) { eatline(imapd_in, ' '); prot_printf(imapd_out, %s NO Login only available under a layer\r\n, tag); @@ -1596,7 +1607,7 @@ passwd = passwdbuf.s; -if (is_userid_anonymous(user)) { +if (!strcmp(canon_user, anonymous)) { if (config_getswitch(IMAPOPT_ALLOWANONYMOUSLOGIN)) { passwd = beautify_string(passwd); if (strlen(passwd) 500) passwd[500] = '\0'; @@ -1615,21 +1626,22 @@ } } else if ((r = sasl_checkpass(imapd_saslconn, -user, -strlen(user), +canon_user, +strlen(canon_user), passwd, strlen(passwd))) != SASL_OK) { syslog(LOG_NOTICE, badlogin: %s plaintext %s %s, - imapd_clienthost, user, sasl_errdetail(imapd_saslconn)); + imapd_clienthost, canon_user, sasl_errdetail(imapd_saslconn)); sleep(3); - if ((reply = sasl_errstring(r, NULL, NULL)) != NULL) { + if (reply) { + prot_printf(imapd_out, %s NO Login failed: %s\r\n, tag, reply); + } else if ((reply = sasl_errstring(r, NULL, NULL)) != NULL) { prot_printf(imapd_out, %s NO Login failed: %s\r\n, tag, reply); } else { prot_printf(imapd_out, %s NO Login failed: %d\r\n, tag, r); } - snmp_increment_args(AUTHENTICATION_NO, 1, VARIABLE_AUTH, 0 /* hash_simple(LOGIN) */, VARIABLE_LISTEND); @@ -1637,26 +1649,6 @@ return; } else { - const char *canon_user; - - r = sasl_getprop(imapd_saslconn, SASL_USERNAME, - (const void **) canon_user); - - if(r != SASL_OK) { - if ((reply = sasl_errstring(r, NULL, NULL)) != NULL) { - prot_printf(imapd_out, %s NO Login failed: %s\r\n, - tag, reply); - } else { - prot_printf(imapd_out, %s NO Login failed: %d\r\n, tag, r); - } - - snmp_increment_args(AUTHENTICATION_NO, 1, -VARIABLE_AUTH, 0 /* hash_simple(LOGIN) */, -VARIABLE_LISTEND); - freebuf(passwdbuf); - return; - } - imapd_userid = xstrdup(canon_user); snmp_increment_args(AUTHENTICATION_YES, 1, VARIABLE_AUTH, 0 /*hash_simple(LOGIN) */, @@ -1761,6 +1753,7 @@ */ sasl_result = sasl_getprop(imapd_saslconn, SASL_USERNAME, (const void **) canon_user); +imapd_userid = xstrdup(canon_user); if (sasl_result != SASL_OK) { prot_printf(imapd_out, %s NO weird SASL error %d SASL_USERNAME\r\n, tag, sasl_result); @@ -1769,7 +1762,6 @@
Re: Why is SASL authentication have to be so difficult? Round 2
The commit log on 1.398.2.81 is don't canonify a userid twice Derrick, There was a long discussion about this on cyrus-sasl and cyrus-devel lists awhile back: http://asg.web.cmu.edu/archive/message.php?mailbox=archive.cyrus-saslsearchterm=saslpasswd2%20and%20virtdomainsmsg=3683 this isn't quite the same thing. further investigation shows that auxprop verify password mech works differently from all the others, including the saslauthd mech he cares about. it canonifies, and all the others don't. --- Cyrus Home Page: http://asg.web.cmu.edu/cyrus Cyrus Wiki/FAQ: http://cyruswiki.andrew.cmu.edu List Archives/Info: http://asg.web.cmu.edu/cyrus/mailing-list.html
Re: Why is SASL authentication have to be so difficult? Round 2
But it looks like I also miss the scope; sasl_check_pass canonifies (which means auxprop_verify_password canonifies twice from sasl_check_pass, and from sasl_user_exists is the only verify_password backend which canonifies... sigh) anyway, i think there is something more subtle doing on here maybe? --- Cyrus Home Page: http://asg.web.cmu.edu/cyrus Cyrus Wiki/FAQ: http://cyruswiki.andrew.cmu.edu List Archives/Info: http://asg.web.cmu.edu/cyrus/mailing-list.html
Re: Why is SASL authentication have to be so difficult? Round 2
On Tue, 7 Dec 2004, Derrick J Brashear wrote: The commit log on 1.398.2.81 is don't canonify a userid twice Derrick, There was a long discussion about this on cyrus-sasl and cyrus-devel lists awhile back: http://asg.web.cmu.edu/archive/message.php?mailbox=archive.cyrus-saslsearchterm=saslpasswd2%20and%20virtdomainsmsg=3683 this isn't quite the same thing. further investigation shows that auxprop verify password mech works differently from all the others, including the saslauthd mech he cares about. it canonifies, and all the others don't. I was just trying to point out the history of that particular patch. -- Igor --- Cyrus Home Page: http://asg.web.cmu.edu/cyrus Cyrus Wiki/FAQ: http://cyruswiki.andrew.cmu.edu List Archives/Info: http://asg.web.cmu.edu/cyrus/mailing-list.html
Re: Why is SASL authentication have to be so difficult? Round 2
On Tue, 7 Dec 2004, Igor Brezac wrote: There was a long discussion about this on cyrus-sasl and cyrus-devel lists awhile back: http://asg.web.cmu.edu/archive/message.php?mailbox=archive.cyrus-saslsearchterm=saslpasswd2%20and%20virtdomainsmsg=3683 this isn't quite the same thing. further investigation shows that auxprop verify password mech works differently from all the others, including the saslauthd mech he cares about. it canonifies, and all the others don't. I was just trying to point out the history of that particular patch. Oh. Sorry. Duh. --- Cyrus Home Page: http://asg.web.cmu.edu/cyrus Cyrus Wiki/FAQ: http://cyruswiki.andrew.cmu.edu List Archives/Info: http://asg.web.cmu.edu/cyrus/mailing-list.html
Re: Why is SASL authentication have to be so difficult? Round 2
Robert Lubbers wrote: I am still working on getting this IMAP server authenticating against my Windows domain PDC, and I did manage to get the POP server authenticating, which is a giant step forward. But both the IMAP component and the cyradm component are complaining: They both give me the same error message: What version of SASL are you using? I can't reproduce this error using the current versions of Cyrus and SASL. cyrus-servertelnet localhost 143 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. * OK cyrus.domain.com Cyrus IMAP4 v2.2.9 server ready . login cyrususer secret . NO Login failed: can't request info until later in exchange . logout * BYE LOGOUT received . OK Completed whereas the POP3 server doesn't complain at all: cyrus-server telnet localhost 110 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. +OK cyrus-server.domain.com Cyrus POP3 v2.2.9 server ready [EMAIL PROTECTED] user cyrususer +OK Name is a valid mailbox pass intisol +OK Mailbox locked and ready The wild thing is that the /var/log/secure fuile shows a valid authentication for either one: For POP3 Dec 6 10:59:51 cyrus-server saslauthd[1841]: rel_accept_lock : released accept lock Dec 6 10:59:51 cyrus-server saslauthd[1842]: get_accept_lock : acquired accept lock Dec 6 10:59:51 cyrus-server pam_winbind[1841]: user 'cyrususer' granted acces Dec 6 10:59:51 cyrus-server pam_winbind[1841]: user 'cyrususer' granted acces Dec 6 10:59:51 cyrus-server saslauthd[1841]: do_auth : auth success: [user=cyrususer] [service=pop] [realm=] [mech=pam] Dec 6 10:59:51 cyrus-server saslauthd[1841]: do_request : response: 0 Whereas for IMAP: Dec 6 11:03:24 cyrus-server saslauthd[1842]: rel_accept_lock : released accept lock Dec 6 11:03:24 cyrus-server saslauthd[1837]: get_accept_lock : acquired accept lock Dec 6 11:03:24 cyrus-server pam_winbind[1842]: user 'cyrususer' granted acces Dec 6 11:03:24 cyrus-server pam_winbind[1842]: user 'cyrususer' granted acces Dec 6 11:03:24 cyrus-server saslauthd[1842]: do_auth : auth success: [user=cyrususer] [service=imap] [realm=] [mech=pam] Dec 6 11:03:24 cyrus-server saslauthd[1842]: do_request : response: OK' See? No difference. For cyradm: cyrus-servercyradm --user cyrusadmin --auth login localhost IMAP Password: Login failed: can't request info until later in exchange at /usr/lib/perl5/site_perl/5.8.0/i386-linux-thread-multi/Cyrus/IMAP/Admin.pm line 118 cyradm: cannot authenticate to server with login as cyrus Yet this is a user that exists in /etc/sasldb2: cyrus-server sasldblistusers2 [EMAIL PROTECTED]: userPassword [EMAIL PROTECTED]: userPassword [EMAIL PROTECTED]: cmusaslsecretOTP [EMAIL PROTECTED]: cmusaslsecretOTP Just for the sake of completeness, here is the contents of my /usr/local/lib/sasl directory: cyrus-server ls -l /usr/local/lib/sasl2 total 600 -rwxr-xr-x1 root root 711 Dec 6 10:02 libanonymous.la lrwxrwxrwx1 root root 22 Dec 6 10:02 libanonymous.so - libanonymous.so.2.0.20 lrwxrwxrwx1 root root 22 Dec 6 10:02 libanonymous.so.2 - libanonymous.so.2.0.20 -rwxr-xr-x1 root root89354 Dec 6 10:02 libanonymous.so.2.0.20 -rwxr-xr-x1 root root 695 Dec 6 10:02 liblogin.la lrwxrwxrwx1 root root 18 Dec 6 10:02 liblogin.so - liblogin.so.2.0.20 lrwxrwxrwx1 root root 18 Dec 6 10:02 liblogin.so.2 - liblogin.so.2.0.20 -rwxr-xr-x1 root root88558 Dec 6 10:02 liblogin.so.2.0.20 -rwxr-xr-x1 root root 684 Dec 6 10:02 libotp.la lrwxrwxrwx1 root root 16 Dec 6 10:02 libotp.so - libotp.so.2.0.20 lrwxrwxrwx1 root root 16 Dec 6 10:02 libotp.so.2 - libotp.so.2.0.20 -rwxr-xr-x1 root root 155138 Dec 6 10:02 libotp.so.2.0.20 -rwxr-xr-x1 root root 695 Dec 6 10:02 libplain.la lrwxrwxrwx1 root root 18 Dec 6 10:02 libplain.so - libplain.so.2.0.20 lrwxrwxrwx1 root root 18 Dec 6 10:02 libplain.so.2 - libplain.so.2.0.20 -rwxr-xr-x1 root root88316 Dec 6 10:02 libplain.so.2.0.20 -rwxr-xr-x1 root root 716 Dec 6 10:02 libsasldb.la lrwxrwxrwx1 root root 19 Dec 6 10:02 libsasldb.so - libsasldb.so.2.0.20 lrwxrwxrwx1 root root 19 Dec 6 10:02 libsasldb.so.2 - libsasldb.so.2.0.20 -rwxr-xr-x1 root root 145666 Dec 6 10:02 libsasldb.so.2.0.20 I have a sym link from /usr/local/lib/sals2 to /usr/local/lib/sasl, /usr/lib/sasl2, and /usr/lib/sasl. Here is my /etc/imapd.conf: postmaster: postmaster configdirectory: /var/imap partition-default: /var/spool/imap admins: noctest admin allowanonymouslogin: no allowplaintext: yes sasl_mech_list: PLAIN servername: cyrus-server.domain.com autocreatequota: 4 reject8bit: no quotawarn: 90 timeout: 30 poptimeout: 10
Re: Why is SASL authentication have to be so difficult? Round 2
On Tue, 7 Dec 2004, Derrick J Brashear wrote: But it looks like I also miss the scope; sasl_check_pass canonifies (which means auxprop_verify_password canonifies twice from sasl_check_pass, and from sasl_user_exists is the only verify_password backend which canonifies... sigh) anyway, i think there is something more subtle doing on here maybe? I have not looked at the code in awhile, but it looks like double canonification occurs twice in cmd_login() as well - imapd_canon_user() and sasl_checkpass(). -- Igor --- Cyrus Home Page: http://asg.web.cmu.edu/cyrus Cyrus Wiki/FAQ: http://cyruswiki.andrew.cmu.edu List Archives/Info: http://asg.web.cmu.edu/cyrus/mailing-list.html