| 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_(OK) { |
| 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. |
| 173 // |
| 174 // TODO(sergeyu): Some user accounts may not have associated |
| 175 // e-mail address. The check below will fail for such |
| 176 // accounts. Make sure we can handle this case proprely. |
| 177 if (!StartsWithASCII(GetLocalJid(), username_, false)) { |
| 178 LOG(ERROR) << "Received JID that is different from the expected value."; |
| 179 error_ = AUTHENTICATION_FAILED; |
| 180 xmpp_client_->SignalStateChange.disconnect(this); |
| 181 MessageLoop::current()->PostTask( |
| 182 FROM_HERE, base::Bind(&DisconnectXmppClient, xmpp_client_)); |
| 183 xmpp_client_ = NULL; |
| 184 SetState(DISCONNECTED); |
| 185 return; |
| 186 } |
| 187 |
| 158 keep_alive_timer_.Start( | 188 keep_alive_timer_.Start( |
| 159 FROM_HERE, base::TimeDelta::FromSeconds(kKeepAliveIntervalSeconds), | 189 FROM_HERE, base::TimeDelta::FromSeconds(kKeepAliveIntervalSeconds), |
| 160 this, &XmppSignalStrategy::SendKeepAlive); | 190 this, &XmppSignalStrategy::SendKeepAlive); |
| 161 SetState(CONNECTED); | 191 SetState(CONNECTED); |
| 162 } else if (state == buzz::XmppEngine::STATE_CLOSED) { | 192 } else if (state == buzz::XmppEngine::STATE_CLOSED) { |
| 163 // Make sure we dump errors to the log. | 193 // Make sure we dump errors to the log. |
| 164 int subcode; | 194 int subcode; |
| 165 buzz::XmppEngine::Error error = xmpp_client_->GetError(&subcode); | 195 buzz::XmppEngine::Error error = xmpp_client_->GetError(&subcode); |
| 166 LOG(INFO) << "XMPP connection was closed: error=" << error | 196 LOG(INFO) << "XMPP connection was closed: error=" << error |
| 167 << ", subcode=" << subcode; | 197 << ", subcode=" << subcode; |
| 168 | 198 |
| 169 keep_alive_timer_.Stop(); | 199 keep_alive_timer_.Stop(); |
| 170 | 200 |
| 171 // Client is destroyed by the TaskRunner after the client is | 201 // Client is destroyed by the TaskRunner after the client is |
| 172 // closed. Reset the pointer so we don't try to use it later. | 202 // closed. Reset the pointer so we don't try to use it later. |
| 173 xmpp_client_ = NULL; | 203 xmpp_client_ = NULL; |
| 204 |
| 205 switch (error) { |
| 206 case buzz::XmppEngine::ERROR_UNAUTHORIZED: |
| 207 case buzz::XmppEngine::ERROR_AUTH: |
| 208 case buzz::XmppEngine::ERROR_MISSING_USERNAME: |
| 209 error_ = AUTHENTICATION_FAILED; |
| 210 break; |
| 211 |
| 212 default: |
| 213 error_ = NETWORK_ERROR; |
| 214 } |
| 215 |
| 174 SetState(DISCONNECTED); | 216 SetState(DISCONNECTED); |
| 175 } | 217 } |
| 176 } | 218 } |
| 177 | 219 |
| 178 void XmppSignalStrategy::SetState(State new_state) { | 220 void XmppSignalStrategy::SetState(State new_state) { |
| 179 if (state_ != new_state) { | 221 if (state_ != new_state) { |
| 180 state_ = new_state; | 222 state_ = new_state; |
| 181 FOR_EACH_OBSERVER(Listener, listeners_, | 223 FOR_EACH_OBSERVER(Listener, listeners_, |
| 182 OnSignalStrategyStateChange(new_state)); | 224 OnSignalStrategyStateChange(new_state)); |
| 183 } | 225 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 194 std::string mechanism = notifier::GaiaTokenPreXmppAuth::kDefaultAuthMechanism; | 236 std::string mechanism = notifier::GaiaTokenPreXmppAuth::kDefaultAuthMechanism; |
| 195 if (settings.token_service() == "oauth2") { | 237 if (settings.token_service() == "oauth2") { |
| 196 mechanism = "X-OAUTH2"; | 238 mechanism = "X-OAUTH2"; |
| 197 } | 239 } |
| 198 | 240 |
| 199 return new notifier::GaiaTokenPreXmppAuth( | 241 return new notifier::GaiaTokenPreXmppAuth( |
| 200 jid.Str(), settings.auth_cookie(), settings.token_service(), mechanism); | 242 jid.Str(), settings.auth_cookie(), settings.token_service(), mechanism); |
| 201 } | 243 } |
| 202 | 244 |
| 203 } // namespace remoting | 245 } // namespace remoting |
| OLD | NEW |