Summary: | [PATCH] SASL Authentication fails if another client of sasl is loaded | ||
---|---|---|---|
Product: | [Frameworks and Libraries] kio | Reporter: | Andreas Roth <aroth> |
Component: | smtp | Assignee: | Allen Winter <winter> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | mueller, winter |
Priority: | NOR | ||
Version: | unspecified | ||
Target Milestone: | --- | ||
Platform: | Ubuntu | ||
OS: | Linux | ||
Latest Commit: | Version Fixed In: | ||
Sentry Crash Report: | |||
Attachments: | Fix callbacks for SMTP and POP3 kioslave |
Description
Andreas Roth
2007-06-09 13:35:29 UTC
Created attachment 20815 [details]
Fix callbacks for SMTP and POP3 kioslave
The patch fixes the SASL callbacks for the SMTP and POP3 kioslaves. It simply
specifies the callbacks for every connection (in sasl_client_new) instead of
using the callbacks specified through sasl_client_init.
SVN commit 674951 by winterz: Fix bug "SASL Authentication fails if another client of sasl is loaded" Patch by Andreas. Thanks! BUGS: 146582 M +21 -9 pop3/pop3.cc M +23 -10 smtp/command.cc --- branches/KDE/3.5/kdebase/kioslave/pop3/pop3.cc #674950:674951 @@ -87,6 +87,18 @@ { SASL_CB_CANON_USER, NULL, NULL }, { SASL_CB_LIST_END, NULL, NULL } }; + +static sasl_callback_t client_callbacks[] = { + { SASL_CB_ECHOPROMPT, NULL, NULL }, + { SASL_CB_NOECHOPROMPT, NULL, NULL }, + { SASL_CB_GETREALM, NULL, NULL }, + { SASL_CB_USER, NULL, NULL }, + { SASL_CB_AUTHNAME, NULL, NULL }, + { SASL_CB_PASS, NULL, NULL }, + { SASL_CB_GETOPT, NULL, NULL }, + { SASL_CB_CANON_USER, NULL, NULL }, + { SASL_CB_LIST_END, NULL, NULL } +}; #endif int kdemain(int argc, char **argv) @@ -451,7 +463,7 @@ return true; #else return false; -#endif +#endif } #define SASLERROR closeConnection(); \ @@ -474,7 +486,7 @@ result = sasl_client_new( "pop", m_sServer.latin1(), - 0, 0, NULL, 0, &conn ); + 0, 0, client_callbacks, 0, &conn ); if ( result != SASL_OK ) { POP3_DEBUG << "sasl_client_new failed with: " << result << endl; @@ -505,7 +517,7 @@ } do { - result = sasl_client_start(conn, sasl_list.join(" ").latin1(), + result = sasl_client_start(conn, sasl_list.join(" ").latin1(), &client_interact, &out, &outlen, &mechusing); if (result == SASL_INTERACT) @@ -521,9 +533,9 @@ sasl_dispose( &conn ); return -1; } - + POP3_DEBUG << "Preferred authentication method is " << mechusing << "." << endl; - + QByteArray challenge, tmp; QString firstCommand = "AUTH " + QString::fromLatin1( mechusing ); @@ -534,7 +546,7 @@ firstCommand += " "; firstCommand += QString::fromLatin1( tmp.data(), tmp.size() ); } - + challenge.resize( 2049 ); resp = command( firstCommand.latin1(), challenge.data(), 2049 ); while( resp == Cont ) { @@ -610,7 +622,7 @@ bool POP3Protocol::loginPASS( KIO::AuthInfo &ai ) { char buf[512]; - + if (m_sUser.isEmpty() || m_sPass.isEmpty()) { // Prompt for usernames if (!openPassDlg(ai)) { @@ -761,7 +773,7 @@ switch ( retval ) { case 0: return true; case -1: return false; - default: + default: m_try_apop = false; } } else if ( m_try_sasl ) { @@ -770,7 +782,7 @@ switch ( retval ) { case 0: return true; case -1: return false; - default: + default: m_try_sasl = false; } } else { --- branches/KDE/3.5/kdebase/kioslave/smtp/command.cc #674950:674951 @@ -47,6 +47,19 @@ namespace KioSMTP { +#ifdef HAVE_LIBSASL2 +static sasl_callback_t client_callbacks[] = { + { SASL_CB_ECHOPROMPT, NULL, NULL }, + { SASL_CB_NOECHOPROMPT, NULL, NULL }, + { SASL_CB_GETREALM, NULL, NULL }, + { SASL_CB_USER, NULL, NULL }, + { SASL_CB_AUTHNAME, NULL, NULL }, + { SASL_CB_PASS, NULL, NULL }, + { SASL_CB_CANON_USER, NULL, NULL }, + { SASL_CB_LIST_END, NULL, NULL } +}; +#endif + // // Command (base class) // @@ -144,7 +157,7 @@ // // STARTTLS - rfc 3207 - // + // QCString StartTLSCommand::nextCommandLine( TransactionState * ) { mComplete = true; @@ -195,16 +208,16 @@ mAi( &ai ), mFirstTime( true ) { -#ifdef HAVE_LIBSASL2 +#ifdef HAVE_LIBSASL2 int result; mMechusing = 0; conn = 0; client_interact = 0; mOut = 0; mOutlen = 0; mOneStep = false; - + result = sasl_client_new( "smtp", aFQDN.latin1(), - 0, 0, NULL, 0, &conn ); + 0, 0, client_callbacks, 0, &conn ); if ( result != SASL_OK ) { SASLERROR return; @@ -232,13 +245,13 @@ AuthCommand::~AuthCommand() { -#ifdef HAVE_LIBSASL2 +#ifdef HAVE_LIBSASL2 if ( conn ) { kdDebug(7112) << "dispose sasl connection" << endl; sasl_dispose( &conn ); conn = 0; } -#endif +#endif } bool AuthCommand::saslInteract( void *in ) @@ -309,7 +322,7 @@ mUngetSASLResponse = 0; } else if ( mFirstTime ) { QString firstCommand = "AUTH " + QString::fromLatin1( mMechusing ); - + tmp.setRawData( mOut, mOutlen ); KCodecs::base64Encode( tmp, challenge ); tmp.resetRawData( mOut, mOutlen ); @@ -318,7 +331,7 @@ firstCommand += QString::fromLatin1( challenge.data(), challenge.size() ); } cmd = firstCommand.latin1(); - + if ( mOneStep ) mComplete = true; } else { // kdDebug(7112) << "SS: '" << mLastChallenge << "'" << endl; @@ -344,7 +357,7 @@ tmp.setRawData( mOut, mOutlen ); cmd = KCodecs::base64Encode( tmp ); tmp.resetRawData( mOut, mOutlen ); - + // kdDebug(7112) << "CC: '" << cmd << "'" << endl; mComplete = ( result == SASL_OK ); } @@ -424,7 +437,7 @@ ts->addRejectedRecipient( mAddr, r.errorMessage() ); return false; - } + } // // DATA (only initial processing!) this patch seems to break kio_pop3 completely. which other kioslave was using libsasl? the description doesn't make sense to me, because kioslaves are loaded into the same process one after the other - there is only one existing at the same time, hence the problem can't happen as described. Your right, each kio slave is loaded into a different process. But there are other libraries which are using libsasl. Most notable the libnss-ldap, which is loaded when LDAP authentication is enabled. On my machine the kio slaves, which are using libsasl, does not work for users who are authenticated using LDAP. The ldap library itself uses SASL authentication (or even only initialize the libsasl) with different callbacks and the callbacks from the next user (the kio slave) will be ignored. This patch moves the initialization of the callbacks from the global libsasl init to the connection specific initialization. In KDE there are four (AFAIK) kio slaves which are using libsasl: smtp, pop3, imap and sieve (the later two are in kdepim). If you need further details, feel free to ask. I can not see where libnss-ldap is doing a sasl initialisation, but in any case your description is wrong: the ioslaves are not supposed to use the hooks at all, given that they use the iterative client API. There is however a bug in the sasl libs that the getopt hook is invoked anyway, which causes the crashes with your patch. anyway, all sorted out now. libnss-ldap does not itself initialize the sasl library, but it uses the openldap libraries, which i suppose initialize the sasl library. I check on a fresh installed Kubuntu 7.04 machine, that when the kio slave tries to initialize the sasl library, another one already did this before. But this only happens for users with use ldap based accounts. If i try the same with a local account, the library was not initialized before the kio slaves tried. > There is however a bug in the sasl libs that the getopt hook is invoked anyway, which causes the crashes with your patch.
anyway, all sorted out now.
Would you mind sharing the sasl patch, please?
Ah, thanks. I read it, as if you patched cyrus sasl as well. |