Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "remoting/jingle_glue/xmpp_signal_strategy.h" | 5 #include "remoting/jingle_glue/xmpp_signal_strategy.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | |
| 7 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/string_util.h" | |
| 8 #include "jingle/notifier/base/gaia_token_pre_xmpp_auth.h" | 10 #include "jingle/notifier/base/gaia_token_pre_xmpp_auth.h" |
| 9 #include "remoting/jingle_glue/jingle_thread.h" | 11 #include "remoting/jingle_glue/jingle_thread.h" |
| 10 #include "remoting/jingle_glue/xmpp_socket_adapter.h" | 12 #include "remoting/jingle_glue/xmpp_socket_adapter.h" |
| 11 #include "third_party/libjingle/source/talk/base/asyncsocket.h" | 13 #include "third_party/libjingle/source/talk/base/asyncsocket.h" |
| 12 #include "third_party/libjingle/source/talk/xmpp/prexmppauth.h" | 14 #include "third_party/libjingle/source/talk/xmpp/prexmppauth.h" |
| 13 #include "third_party/libjingle/source/talk/xmpp/saslcookiemechanism.h" | 15 #include "third_party/libjingle/source/talk/xmpp/saslcookiemechanism.h" |
| 14 | 16 |
| 15 namespace { | 17 namespace { |
| 16 | 18 |
| 17 const char kDefaultResourceName[] = "chromoting"; | 19 const char kDefaultResourceName[] = "chromoting"; |
| 18 | 20 |
| 19 // Use 58 seconds keep-alive interval, in case routers terminate | 21 // Use 58 seconds keep-alive interval, in case routers terminate |
| 20 // connections that are idle for more than a minute. | 22 // connections that are idle for more than a minute. |
| 21 const int kKeepAliveIntervalSeconds = 50; | 23 const int kKeepAliveIntervalSeconds = 50; |
| 22 | 24 |
| 25 void DisconnectXmppClient(buzz::XmppClient* client) { | |
| 26 client->Disconnect(); | |
| 27 } | |
| 28 | |
| 23 } // namespace | 29 } // namespace |
| 24 | 30 |
| 25 namespace remoting { | 31 namespace remoting { |
| 26 | 32 |
| 27 XmppSignalStrategy::XmppSignalStrategy(JingleThread* jingle_thread, | 33 XmppSignalStrategy::XmppSignalStrategy(JingleThread* jingle_thread, |
| 28 const std::string& username, | 34 const std::string& username, |
| 29 const std::string& auth_token, | 35 const std::string& auth_token, |
| 30 const std::string& auth_token_service) | 36 const std::string& auth_token_service) |
| 31 : thread_(jingle_thread), | 37 : thread_(jingle_thread), |
| 32 username_(username), | 38 username_(username), |
| 33 auth_token_(auth_token), | 39 auth_token_(auth_token), |
| 34 auth_token_service_(auth_token_service), | 40 auth_token_service_(auth_token_service), |
| 35 resource_name_(kDefaultResourceName), | 41 resource_name_(kDefaultResourceName), |
| 36 xmpp_client_(NULL), | 42 xmpp_client_(NULL), |
| 37 state_(DISCONNECTED) { | 43 state_(DISCONNECTED), |
| 44 error_(NO_ERROR) { | |
| 38 } | 45 } |
| 39 | 46 |
| 40 XmppSignalStrategy::~XmppSignalStrategy() { | 47 XmppSignalStrategy::~XmppSignalStrategy() { |
| 41 DCHECK_EQ(listeners_.size(), 0U); | |
| 42 Disconnect(); | 48 Disconnect(); |
| 43 } | 49 } |
| 44 | 50 |
| 45 void XmppSignalStrategy::Connect() { | 51 void XmppSignalStrategy::Connect() { |
| 46 DCHECK(CalledOnValidThread()); | 52 DCHECK(CalledOnValidThread()); |
| 47 | 53 |
| 48 // Disconnect first if we are currently connected. | 54 // Disconnect first if we are currently connected. |
| 49 Disconnect(); | 55 Disconnect(); |
| 50 | 56 |
| 51 buzz::XmppClientSettings settings; | 57 buzz::XmppClientSettings settings; |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 82 // in response to Disconnect() call above. | 88 // in response to Disconnect() call above. |
| 83 DCHECK(xmpp_client_ == NULL); | 89 DCHECK(xmpp_client_ == NULL); |
| 84 } | 90 } |
| 85 } | 91 } |
| 86 | 92 |
| 87 SignalStrategy::State XmppSignalStrategy::GetState() const { | 93 SignalStrategy::State XmppSignalStrategy::GetState() const { |
| 88 DCHECK(CalledOnValidThread()); | 94 DCHECK(CalledOnValidThread()); |
| 89 return state_; | 95 return state_; |
| 90 } | 96 } |
| 91 | 97 |
| 98 SignalStrategy::Error XmppSignalStrategy::GetError() const { | |
| 99 DCHECK(CalledOnValidThread()); | |
| 100 return error_; | |
| 101 } | |
| 102 | |
| 92 std::string XmppSignalStrategy::GetLocalJid() const { | 103 std::string XmppSignalStrategy::GetLocalJid() const { |
| 93 DCHECK(CalledOnValidThread()); | 104 DCHECK(CalledOnValidThread()); |
| 94 return xmpp_client_->jid().Str(); | 105 return xmpp_client_->jid().Str(); |
| 95 } | 106 } |
| 96 | 107 |
| 97 void XmppSignalStrategy::AddListener(Listener* listener) { | 108 void XmppSignalStrategy::AddListener(Listener* listener) { |
| 98 DCHECK(CalledOnValidThread()); | 109 DCHECK(CalledOnValidThread()); |
| 99 listeners_.AddObserver(listener); | 110 listeners_.AddObserver(listener); |
| 100 } | 111 } |
| 101 | 112 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 147 } | 158 } |
| 148 | 159 |
| 149 void XmppSignalStrategy::SetResourceName(const std::string &resource_name) { | 160 void XmppSignalStrategy::SetResourceName(const std::string &resource_name) { |
| 150 DCHECK(CalledOnValidThread()); | 161 DCHECK(CalledOnValidThread()); |
| 151 resource_name_ = resource_name; | 162 resource_name_ = resource_name; |
| 152 } | 163 } |
| 153 | 164 |
| 154 void XmppSignalStrategy::OnConnectionStateChanged( | 165 void XmppSignalStrategy::OnConnectionStateChanged( |
| 155 buzz::XmppEngine::State state) { | 166 buzz::XmppEngine::State state) { |
| 156 DCHECK(CalledOnValidThread()); | 167 DCHECK(CalledOnValidThread()); |
| 168 | |
| 157 if (state == buzz::XmppEngine::STATE_OPEN) { | 169 if (state == buzz::XmppEngine::STATE_OPEN) { |
| 170 // Verify that the JID that we've received matches the username | |
| 171 // that we have. If it doesn't, then the OAuth token was probably | |
| 172 // issued for a different account, so we treat is a an auth error. | |
|
simonmorris
2012/05/11 22:59:03
Maybe add a TODO to handle unusual cases where the
Sergey Ulanov
2012/05/11 23:33:42
Done.
| |
| 173 if (!StartsWithASCII(GetLocalJid(), username_, false)) { | |
| 174 LOG(ERROR) << "Received JID that is different from the expected value."; | |
| 175 error_ = AUTHENTICATION_FAILED; | |
| 176 xmpp_client_->SignalStateChange.disconnect(this); | |
| 177 MessageLoop::current()->PostTask( | |
| 178 FROM_HERE, base::Bind(&DisconnectXmppClient, xmpp_client_)); | |
| 179 xmpp_client_ = NULL; | |
| 180 SetState(DISCONNECTED); | |
| 181 return; | |
| 182 } | |
| 183 | |
| 158 keep_alive_timer_.Start( | 184 keep_alive_timer_.Start( |
| 159 FROM_HERE, base::TimeDelta::FromSeconds(kKeepAliveIntervalSeconds), | 185 FROM_HERE, base::TimeDelta::FromSeconds(kKeepAliveIntervalSeconds), |
| 160 this, &XmppSignalStrategy::SendKeepAlive); | 186 this, &XmppSignalStrategy::SendKeepAlive); |
| 161 SetState(CONNECTED); | 187 SetState(CONNECTED); |
| 162 } else if (state == buzz::XmppEngine::STATE_CLOSED) { | 188 } else if (state == buzz::XmppEngine::STATE_CLOSED) { |
| 163 // Make sure we dump errors to the log. | 189 // Make sure we dump errors to the log. |
| 164 int subcode; | 190 int subcode; |
| 165 buzz::XmppEngine::Error error = xmpp_client_->GetError(&subcode); | 191 buzz::XmppEngine::Error error = xmpp_client_->GetError(&subcode); |
| 166 LOG(INFO) << "XMPP connection was closed: error=" << error | 192 LOG(INFO) << "XMPP connection was closed: error=" << error |
| 167 << ", subcode=" << subcode; | 193 << ", subcode=" << subcode; |
| 168 | 194 |
| 169 keep_alive_timer_.Stop(); | 195 keep_alive_timer_.Stop(); |
| 170 | 196 |
| 171 // Client is destroyed by the TaskRunner after the client is | 197 // Client is destroyed by the TaskRunner after the client is |
| 172 // closed. Reset the pointer so we don't try to use it later. | 198 // closed. Reset the pointer so we don't try to use it later. |
| 173 xmpp_client_ = NULL; | 199 xmpp_client_ = NULL; |
| 200 | |
| 201 switch (error) { | |
| 202 case buzz::XmppEngine::ERROR_UNAUTHORIZED: | |
| 203 case buzz::XmppEngine::ERROR_AUTH: | |
| 204 case buzz::XmppEngine::ERROR_MISSING_USERNAME: | |
| 205 error_ = AUTHENTICATION_FAILED; | |
| 206 break; | |
| 207 | |
| 208 default: | |
| 209 error_ = NETWORK_ERROR; | |
| 210 } | |
| 211 | |
| 174 SetState(DISCONNECTED); | 212 SetState(DISCONNECTED); |
| 175 } | 213 } |
| 176 } | 214 } |
| 177 | 215 |
| 178 void XmppSignalStrategy::SetState(State new_state) { | 216 void XmppSignalStrategy::SetState(State new_state) { |
| 179 if (state_ != new_state) { | 217 if (state_ != new_state) { |
| 180 state_ = new_state; | 218 state_ = new_state; |
| 181 FOR_EACH_OBSERVER(Listener, listeners_, | 219 FOR_EACH_OBSERVER(Listener, listeners_, |
| 182 OnSignalStrategyStateChange(new_state)); | 220 OnSignalStrategyStateChange(new_state)); |
| 183 } | 221 } |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 194 std::string mechanism = notifier::GaiaTokenPreXmppAuth::kDefaultAuthMechanism; | 232 std::string mechanism = notifier::GaiaTokenPreXmppAuth::kDefaultAuthMechanism; |
| 195 if (settings.token_service() == "oauth2") { | 233 if (settings.token_service() == "oauth2") { |
| 196 mechanism = "X-OAUTH2"; | 234 mechanism = "X-OAUTH2"; |
| 197 } | 235 } |
| 198 | 236 |
| 199 return new notifier::GaiaTokenPreXmppAuth( | 237 return new notifier::GaiaTokenPreXmppAuth( |
| 200 jid.Str(), settings.auth_cookie(), settings.token_service(), mechanism); | 238 jid.Str(), settings.auth_cookie(), settings.token_service(), mechanism); |
| 201 } | 239 } |
| 202 | 240 |
| 203 } // namespace remoting | 241 } // namespace remoting |
| OLD | NEW |