diff options
author | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-16 20:54:02 +0000 |
---|---|---|
committer | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-16 20:54:02 +0000 |
commit | dd7981da8ce9ae81b77c43c308cab8b664b63276 (patch) | |
tree | d06cb20f9a9f0cd762aaf0e7206b0cf8faa0dcd5 | |
parent | ce08079cf7f61aa56f11dd502690e4318b1db035 (diff) | |
download | chromium_src-dd7981da8ce9ae81b77c43c308cab8b664b63276.zip chromium_src-dd7981da8ce9ae81b77c43c308cab8b664b63276.tar.gz chromium_src-dd7981da8ce9ae81b77c43c308cab8b664b63276.tar.bz2 |
Split up PreXmppAuth and SaslHandler.
Created a X-GOOGLE-TOKEN-only SaslHandler class for use by sync.
BUG=38034
TEST=manual
Review URL: http://codereview.chromium.org/904006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@41761 0039d316-1c4b-4281-b951-d872f2087c98
9 files changed, 122 insertions, 84 deletions
diff --git a/chrome/browser/sync/notifier/communicator/single_login_attempt.cc b/chrome/browser/sync/notifier/communicator/single_login_attempt.cc index 86e04aa..80c438b 100644 --- a/chrome/browser/sync/notifier/communicator/single_login_attempt.cc +++ b/chrome/browser/sync/notifier/communicator/single_login_attempt.cc @@ -2,7 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <algorithm> #include <string> +#include <vector> #include "chrome/browser/sync/notifier/communicator/single_login_attempt.h" @@ -23,6 +25,8 @@ #include "talk/base/winsock_initializer.h" #include "talk/xmllite/xmlelement.h" #include "talk/xmpp/prexmppauth.h" +#include "talk/xmpp/saslcookiemechanism.h" +#include "talk/xmpp/saslhandler.h" #include "talk/xmpp/xmppclient.h" #include "talk/xmpp/xmppclientsettings.h" #include "talk/xmpp/xmppconstants.h" @@ -62,6 +66,44 @@ static void GetClientErrorInformation( } } +namespace { + +const char kGaiaAuthMechanism[] = "X-GOOGLE-TOKEN"; + +// This class looks for the X-GOOGLE-TOKEN auth mechanism and uses +// that instead of the default auth mechanism (PLAIN). +class GaiaOnlySaslHandler : public buzz::SaslHandler { + public: + GaiaOnlySaslHandler( + const std::string& username, + const std::string& token, + const std::string& token_service) + : username_(username), + token_(token), + token_service_(token_service) {} + + virtual std::string ChooseBestSaslMechanism( + const std::vector<std::string> & mechanisms, bool encrypted) { + return (std::find(mechanisms.begin(), + mechanisms.end(), kGaiaAuthMechanism) != + mechanisms.end()) ? kGaiaAuthMechanism : ""; + } + + virtual buzz::SaslMechanism* CreateSaslMechanism( + const std::string& mechanism) { + return + (mechanism == kGaiaAuthMechanism) ? + new buzz::SaslCookieMechanism( + kGaiaAuthMechanism, username_, token_, token_service_) + : NULL; + } + + private: + std::string username_, token_, token_service_; +}; + +} // namespace + SingleLoginAttempt::SingleLoginAttempt(talk_base::Task* parent, LoginSettings* login_settings, bool successful_connection) @@ -204,7 +246,8 @@ void SingleLoginAttempt::DoLogin( // Start connecting. client_->Connect(client_settings, login_settings_->lang(), CreateSocket(client_settings), - CreatePreXmppAuth(client_settings)); + CreatePreXmppAuth(client_settings), + CreateSaslHandler(client_settings)); client_->Start(); } @@ -259,6 +302,13 @@ buzz::PreXmppAuth* SingleLoginAttempt::CreatePreXmppAuth( return auth; } +buzz::SaslHandler* SingleLoginAttempt::CreateSaslHandler( + const buzz::XmppClientSettings& xcs) { + buzz::Jid jid(xcs.user(), xcs.host(), buzz::STR_EMPTY); + return new GaiaOnlySaslHandler( + jid.Str(), xcs.auth_cookie(), xcs.token_service()); +} + void SingleLoginAttempt::OnFreshAuthCookie(const std::string& auth_cookie) { // Remember this is a fresh cookie. cookie_refreshed_ = true; diff --git a/chrome/browser/sync/notifier/communicator/single_login_attempt.h b/chrome/browser/sync/notifier/communicator/single_login_attempt.h index 735a781..c798a27 100644 --- a/chrome/browser/sync/notifier/communicator/single_login_attempt.h +++ b/chrome/browser/sync/notifier/communicator/single_login_attempt.h @@ -17,6 +17,7 @@ namespace buzz { class AsyncSocket; class CaptchaChallenge; class PreXmppAuth; +class SaslHandler; class XmppClient; class XmppClientSettings; class XmppClientSettings; @@ -96,6 +97,8 @@ class SingleLoginAttempt : public talk_base::Task, public sigslot::has_slots<> { void DoLogin(const ConnectionSettings& connection_settings); buzz::AsyncSocket* CreateSocket(const buzz::XmppClientSettings& xcs); buzz::PreXmppAuth* CreatePreXmppAuth(const buzz::XmppClientSettings& xcs); + static buzz::SaslHandler* CreateSaslHandler( + const buzz::XmppClientSettings& xcs); // Cleans up any xmpp client state to get ready for a new one. void ClearClient(); diff --git a/chrome/browser/sync/notifier/communicator/xmpp_connection_generator.cc b/chrome/browser/sync/notifier/communicator/xmpp_connection_generator.cc index 6221f2e..2f28a59 100644 --- a/chrome/browser/sync/notifier/communicator/xmpp_connection_generator.cc +++ b/chrome/browser/sync/notifier/communicator/xmpp_connection_generator.cc @@ -21,7 +21,7 @@ #include "chrome/browser/sync/notifier/communicator/connection_settings.h" #include "chrome/browser/sync/notifier/communicator/product_info.h" #include "talk/base/autodetectproxy.h" -#include "talk/base/httpcommon.h" +#include "talk/base/httpcommon-inl.h" #include "talk/base/task.h" #include "talk/base/thread.h" #include "talk/xmpp/prexmppauth.h" diff --git a/chrome/browser/sync/notifier/gaia_auth/gaiaauth.cc b/chrome/browser/sync/notifier/gaia_auth/gaiaauth.cc index d87ea4e..1558b06 100644 --- a/chrome/browser/sync/notifier/gaia_auth/gaiaauth.cc +++ b/chrome/browser/sync/notifier/gaia_auth/gaiaauth.cc @@ -365,71 +365,6 @@ void GaiaAuth::OnAuthDone() { SignalAuthDone(); } -std::string GaiaAuth::ChooseBestSaslMechanism( - const std::vector<std::string> & mechanisms, bool encrypted) { - if (!done_) - return ""; - - std::vector<std::string>::const_iterator it; - - // A token is the weakest auth - 15s, service-limited, so prefer it. - it = std::find(mechanisms.begin(), mechanisms.end(), "X-GOOGLE-TOKEN"); - if (it != mechanisms.end()) - return "X-GOOGLE-TOKEN"; - - // A cookie is the next weakest - 14 days. - it = std::find(mechanisms.begin(), mechanisms.end(), "X-GOOGLE-COOKIE"); - if (it != mechanisms.end()) - return "X-GOOGLE-COOKIE"; - - // Never pass @google.com passwords without encryption!! - if (!encrypted && - buzz::Jid(worker_task_->GetUsername()).domain() == "google.com") { - return ""; - } - - // As a last resort, use plain authentication. - if (buzz::Jid(worker_task_->GetUsername()).domain() != "google.com") { - it = std::find(mechanisms.begin(), mechanisms.end(), "PLAIN"); - if (it != mechanisms.end()) - return "PLAIN"; - } - - // No good mechanism found. - return ""; -} - -buzz::SaslMechanism* GaiaAuth::CreateSaslMechanism( - const std::string& mechanism) { - if (!done_) { - return NULL; - } - - if (mechanism == "X-GOOGLE-TOKEN") { - return new buzz::SaslCookieMechanism( - mechanism, - worker_task_->GetUsername(), - worker_task_->GetToken(), - worker_task_->GetTokenService()); - } - - if (mechanism == "X-GOOGLE-COOKIE") { - return new buzz::SaslCookieMechanism( - "X-GOOGLE-COOKIE", - worker_task_->GetUsername(), - worker_task_->GetSID(), - worker_task_->GetTokenService()); - } - - if (mechanism == "PLAIN") { - return new buzz::SaslPlainMechanism(buzz::Jid(worker_task_->GetUsername()), - worker_task_->GetPassword()); - } - - // Oh well - none of the above. - return NULL; -} - std::string GaiaAuth::CreateAuthenticatedUrl( const std::string & continue_url, const std::string & service) { if (!done_ || worker_task_->GetToken().empty()) diff --git a/chrome/browser/sync/notifier/gaia_auth/gaiaauth.h b/chrome/browser/sync/notifier/gaia_auth/gaiaauth.h index e489f36..0de7632 100644 --- a/chrome/browser/sync/notifier/gaia_auth/gaiaauth.h +++ b/chrome/browser/sync/notifier/gaia_auth/gaiaauth.h @@ -85,11 +85,6 @@ class GaiaAuth : public PreXmppAuth { token_service_ = token_service; } - virtual std::string ChooseBestSaslMechanism( - const std::vector<std::string>& mechanisms, bool encrypted); - virtual buzz::SaslMechanism* CreateSaslMechanism( - const std::string& mechanism); - std::string CreateAuthenticatedUrl(const std::string& continue_url, const std::string& service); diff --git a/third_party/libjingle/files/talk/xmpp/prexmppauth.h b/third_party/libjingle/files/talk/xmpp/prexmppauth.h index f94bd3d..d8fdbc6 100644 --- a/third_party/libjingle/files/talk/xmpp/prexmppauth.h +++ b/third_party/libjingle/files/talk/xmpp/prexmppauth.h @@ -30,7 +30,6 @@ #include "talk/base/cryptstring.h" #include "talk/base/sigslot.h" -#include "talk/xmpp/saslhandler.h" namespace talk_base { class SocketAddress; @@ -61,7 +60,7 @@ class CaptchaChallenge { std::string captcha_image_url_; }; -class PreXmppAuth : public SaslHandler { +class PreXmppAuth { public: virtual ~PreXmppAuth() {} diff --git a/third_party/libjingle/files/talk/xmpp/xmppclient.cc b/third_party/libjingle/files/talk/xmpp/xmppclient.cc index 41cb77d..ec68215 100644 --- a/third_party/libjingle/files/talk/xmpp/xmppclient.cc +++ b/third_party/libjingle/files/talk/xmpp/xmppclient.cc @@ -30,6 +30,7 @@ #include "talk/xmpp/xmppconstants.h" #include "talk/base/sigslot.h" #include "talk/xmpp/saslplainmechanism.h" +#include "talk/xmpp/saslhandler.h" #include "talk/xmpp/prexmppauth.h" #include "talk/base/scoped_ptr.h" #include "talk/xmpp/plainsaslhandler.h" @@ -66,6 +67,7 @@ public: scoped_ptr<AsyncSocket> socket_; scoped_ptr<XmppEngine> engine_; scoped_ptr<PreXmppAuth> pre_auth_; + scoped_ptr<SaslHandler> sasl_handler_; talk_base::CryptString pass_; std::string auth_cookie_; talk_base::SocketAddress server_; @@ -90,7 +92,11 @@ public: }; XmppReturnStatus -XmppClient::Connect(const XmppClientSettings & settings, const std::string & lang, AsyncSocket * socket, PreXmppAuth * pre_auth) { +XmppClient::Connect(const XmppClientSettings & settings, + const std::string & lang, + AsyncSocket * socket, + PreXmppAuth * pre_auth, + SaslHandler * sasl_handler) { if (socket == NULL) return XMPP_RETURN_BADARGUMENT; if (d_->socket_.get() != NULL) @@ -137,6 +143,7 @@ XmppClient::Connect(const XmppClientSettings & settings, const std::string & lan d_->proxy_port_ = settings.proxy_port(); d_->allow_plain_ = settings.allow_plain(); d_->pre_auth_.reset(pre_auth); + d_->sasl_handler_.reset(sasl_handler); return XMPP_RETURN_OK; } @@ -198,6 +205,14 @@ ForgetPassword(std::string & to_erase) { int XmppClient::ProcessStart() { + if (d_->sasl_handler_.get()) { + d_->engine_->SetSaslHandler(d_->sasl_handler_.release()); + } + else { + d_->engine_->SetSaslHandler(new PlainSaslHandler( + d_->engine_->GetUser(), d_->pass_, d_->allow_plain_)); + } + if (d_->pre_auth_.get()) { d_->pre_auth_->SignalAuthDone.connect(this, &XmppClient::OnAuthDone); d_->pre_auth_->StartPreXmppAuth( @@ -206,8 +221,6 @@ XmppClient::ProcessStart() { return STATE_PRE_XMPP_LOGIN; } else { - d_->engine_->SetSaslHandler(new PlainSaslHandler( - d_->engine_->GetUser(), d_->pass_, d_->allow_plain_)); d_->pass_.Clear(); // done with this; return STATE_START_XMPP_LOGIN; } @@ -250,8 +263,6 @@ XmppClient::ProcessCookieLogin() { // Save auth cookie as a result d_->auth_cookie_ = d_->pre_auth_->GetAuthCookie(); - // transfer ownership of pre_auth_ to engine - d_->engine_->SetSaslHandler(d_->pre_auth_.release()); return STATE_START_XMPP_LOGIN; } diff --git a/third_party/libjingle/files/talk/xmpp/xmppclient.h b/third_party/libjingle/files/talk/xmpp/xmppclient.h index 1ca6fec..013d468c 100644 --- a/third_party/libjingle/files/talk/xmpp/xmppclient.h +++ b/third_party/libjingle/files/talk/xmpp/xmppclient.h @@ -40,6 +40,7 @@ namespace buzz { class XmppTask; class PreXmppAuth; +class SaslHandler; class CaptchaChallenge; // Just some non-colliding number. Could have picked "1". @@ -77,7 +78,8 @@ public: XmppReturnStatus Connect(const XmppClientSettings & settings, const std::string & lang, AsyncSocket * socket, - PreXmppAuth * preauth); + PreXmppAuth * preauth, + SaslHandler * sasl_handler); virtual talk_base::Task* GetParent(int code); virtual int ProcessStart(); diff --git a/third_party/libjingle/mods-since-v0_4_0.diff b/third_party/libjingle/mods-since-v0_4_0.diff index 94eb14d..307439e4 100644 --- a/third_party/libjingle/mods-since-v0_4_0.diff +++ b/third_party/libjingle/mods-since-v0_4_0.diff @@ -1317,6 +1317,13 @@ diff -r libjingle-0.4.0/talk/xmpp/jid.cc libjingle/files/talk/xmpp/jid.cc < #include "talk/xmpp/constants.h" --- > #include "talk/xmpp/xmppconstants.h" +diff -r libjingle-0.4.0/talk/xmpp/prexmppauth.h libjingle/files/talk/xmpp/prexmppauth.h +33d32 +< #include "talk/xmpp/saslhandler.h" +64c63 +< class PreXmppAuth : public SaslHandler { +--- +> class PreXmppAuth { diff -r libjingle-0.4.0/talk/xmpp/saslcookiemechanism.h libjingle/files/talk/xmpp/saslcookiemechanism.h 33c33 < #include "talk/xmpp/constants.h" @@ -1363,19 +1370,55 @@ diff -r libjingle-0.4.0/talk/xmpp/xmppclient.cc libjingle/files/talk/xmpp/xmppcl < #include "talk/xmpp/constants.h" --- > #include "talk/xmpp/xmppconstants.h" -261a262,263 +32a33 +> #include "talk/xmpp/saslhandler.h" +68a70 +> scoped_ptr<SaslHandler> sasl_handler_; +93c95,99 +< XmppClient::Connect(const XmppClientSettings & settings, const std::string & lang, AsyncSocket * socket, PreXmppAuth * pre_auth) { +--- +> XmppClient::Connect(const XmppClientSettings & settings, +> const std::string & lang, +> AsyncSocket * socket, +> PreXmppAuth * pre_auth, +> SaslHandler * sasl_handler) { +139a146 +> d_->sasl_handler_.reset(sasl_handler); +200a208,215 +> if (d_->sasl_handler_.get()) { +> d_->engine_->SetSaslHandler(d_->sasl_handler_.release()); +> } +> else { +> d_->engine_->SetSaslHandler(new PlainSaslHandler( +> d_->engine_->GetUser(), d_->pass_, d_->allow_plain_)); +> } +> +209,210d223 +< d_->engine_->SetSaslHandler(new PlainSaslHandler( +< d_->engine_->GetUser(), d_->pass_, d_->allow_plain_)); +253,254d265 +< // transfer ownership of pre_auth_ to engine +< d_->engine_->SetSaslHandler(d_->pre_auth_.release()); +261a273,274 > d_->pre_engine_error_ = XmppEngine::ERROR_SOCKET; > d_->pre_engine_subcode_ = d_->socket_->GetError(); -347c349 +347c360 < //#ifdef _DEBUG --- > //#if !defined(NDEBUG) -375c377 +375c388 < //#ifdef _DEBUG --- > //#if !defined(NDEBUG) diff -r libjingle-0.4.0/talk/xmpp/xmppclient.h libjingle/files/talk/xmpp/xmppclient.h -141c141 +42a43 +> class SaslHandler; +80c81,82 +< PreXmppAuth * preauth); +--- +> PreXmppAuth * preauth, +> SaslHandler * sasl_handler); +141c143 < std::string XmppClient::GetStateName(int state) const { --- > std::string GetStateName(int state) const { |