| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/proximity_auth/messenger_impl.h" | 5 #include "components/proximity_auth/messenger_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/json/json_reader.h" | 8 #include "base/json/json_reader.h" |
| 9 #include "base/json/json_writer.h" | 9 #include "base/json/json_writer.h" |
| 10 #include "base/location.h" | |
| 11 #include "base/thread_task_runner_handle.h" | |
| 12 #include "base/values.h" | 10 #include "base/values.h" |
| 13 #include "components/proximity_auth/connection.h" | 11 #include "components/proximity_auth/connection.h" |
| 14 #include "components/proximity_auth/cryptauth/base64url.h" | 12 #include "components/proximity_auth/cryptauth/base64url.h" |
| 15 #include "components/proximity_auth/logging/logging.h" | 13 #include "components/proximity_auth/logging/logging.h" |
| 16 #include "components/proximity_auth/messenger_observer.h" | 14 #include "components/proximity_auth/messenger_observer.h" |
| 17 #include "components/proximity_auth/remote_status_update.h" | 15 #include "components/proximity_auth/remote_status_update.h" |
| 18 #include "components/proximity_auth/secure_context.h" | 16 #include "components/proximity_auth/secure_context.h" |
| 19 #include "components/proximity_auth/wire_message.h" | 17 #include "components/proximity_auth/wire_message.h" |
| 20 | 18 |
| 21 namespace proximity_auth { | 19 namespace proximity_auth { |
| 22 namespace { | 20 namespace { |
| 23 | 21 |
| 24 // The key names of JSON fields for messages sent between the devices. | 22 // The key names of JSON fields for messages sent between the devices. |
| 25 const char kTypeKey[] = "type"; | 23 const char kTypeKey[] = "type"; |
| 26 const char kNameKey[] = "name"; | 24 const char kNameKey[] = "name"; |
| 27 const char kDataKey[] = "data"; | 25 const char kDataKey[] = "data"; |
| 28 const char kEncryptedDataKey[] = "encrypted_data"; | 26 const char kEncryptedDataKey[] = "encrypted_data"; |
| 29 | 27 |
| 30 // The types of messages that can be sent and received. | 28 // The types of messages that can be sent and received. |
| 31 const char kMessageTypeLocalEvent[] = "event"; | 29 const char kMessageTypeLocalEvent[] = "event"; |
| 32 const char kMessageTypeRemoteStatusUpdate[] = "status_update"; | 30 const char kMessageTypeRemoteStatusUpdate[] = "status_update"; |
| 33 const char kMessageTypeDecryptRequest[] = "decrypt_request"; | 31 const char kMessageTypeDecryptRequest[] = "decrypt_request"; |
| 34 const char kMessageTypeDecryptResponse[] = "decrypt_response"; | 32 const char kMessageTypeDecryptResponse[] = "decrypt_response"; |
| 35 const char kMessageTypeUnlockRequest[] = "unlock_request"; | 33 const char kMessageTypeUnlockRequest[] = "unlock_request"; |
| 36 const char kMessageTypeUnlockResponse[] = "unlock_response"; | 34 const char kMessageTypeUnlockResponse[] = "unlock_response"; |
| 37 | 35 |
| 38 // The name for an unlock event originating from the local device. | 36 // The name for an unlock event originating from the local device. |
| 39 const char kUnlockEventName[] = "easy_unlock"; | 37 const char kUnlockEventName[] = "easy_unlock"; |
| 40 | 38 |
| 41 // Messages sent and received from the iOS app when polling for it's lock screen | |
| 42 // status. | |
| 43 // TODO(tengs): Unify the iOS status update protocol with the existing Android | |
| 44 // protocol, so we don't have this special case. | |
| 45 const char kPollScreenState[] = "PollScreenState"; | |
| 46 const char kScreenUnlocked[] = "Screen Unlocked"; | |
| 47 const char kScreenLocked[] = "Screen Locked"; | |
| 48 const int kIOSPollingIntervalSeconds = 5; | |
| 49 | |
| 50 // Serializes the |value| to a JSON string and returns the result. | 39 // Serializes the |value| to a JSON string and returns the result. |
| 51 std::string SerializeValueToJson(const base::Value& value) { | 40 std::string SerializeValueToJson(const base::Value& value) { |
| 52 std::string json; | 41 std::string json; |
| 53 base::JSONWriter::Write(value, &json); | 42 base::JSONWriter::Write(value, &json); |
| 54 return json; | 43 return json; |
| 55 } | 44 } |
| 56 | 45 |
| 57 // Returns the message type represented by the |message|. This is a convenience | 46 // Returns the message type represented by the |message|. This is a convenience |
| 58 // wrapper that should only be called when the |message| is known to specify its | 47 // wrapper that should only be called when the |message| is known to specify its |
| 59 // message type, i.e. this should not be called for untrusted input. | 48 // message type, i.e. this should not be called for untrusted input. |
| 60 std::string GetMessageType(const base::DictionaryValue& message) { | 49 std::string GetMessageType(const base::DictionaryValue& message) { |
| 61 std::string type; | 50 std::string type; |
| 62 message.GetString(kTypeKey, &type); | 51 message.GetString(kTypeKey, &type); |
| 63 return type; | 52 return type; |
| 64 } | 53 } |
| 65 | 54 |
| 66 } // namespace | 55 } // namespace |
| 67 | 56 |
| 68 MessengerImpl::MessengerImpl(scoped_ptr<Connection> connection, | 57 MessengerImpl::MessengerImpl(scoped_ptr<Connection> connection, |
| 69 scoped_ptr<SecureContext> secure_context) | 58 scoped_ptr<SecureContext> secure_context) |
| 70 : connection_(connection.Pass()), | 59 : connection_(connection.Pass()), |
| 71 secure_context_(secure_context.Pass()), | 60 secure_context_(secure_context.Pass()), |
| 72 weak_ptr_factory_(this) { | 61 weak_ptr_factory_(this) { |
| 73 DCHECK(connection_->IsConnected()); | 62 DCHECK(connection_->IsConnected()); |
| 74 connection_->AddObserver(this); | 63 connection_->AddObserver(this); |
| 75 | |
| 76 // TODO(tengs): We need CryptAuth to report if the phone runs iOS or Android, | |
| 77 // rather than relying on this heuristic. | |
| 78 if (connection_->remote_device().bluetooth_type == RemoteDevice::BLUETOOTH_LE) | |
| 79 PollScreenStateForIOS(); | |
| 80 } | 64 } |
| 81 | 65 |
| 82 MessengerImpl::~MessengerImpl() { | 66 MessengerImpl::~MessengerImpl() { |
| 83 if (connection_) | 67 if (connection_) |
| 84 connection_->RemoveObserver(this); | 68 connection_->RemoveObserver(this); |
| 85 } | 69 } |
| 86 | 70 |
| 87 void MessengerImpl::AddObserver(MessengerObserver* observer) { | 71 void MessengerImpl::AddObserver(MessengerObserver* observer) { |
| 88 observers_.AddObserver(observer); | 72 observers_.AddObserver(observer); |
| 89 } | 73 } |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 } | 236 } |
| 253 FOR_EACH_OBSERVER(MessengerObserver, observers_, | 237 FOR_EACH_OBSERVER(MessengerObserver, observers_, |
| 254 OnDecryptResponse(response.Pass())); | 238 OnDecryptResponse(response.Pass())); |
| 255 } | 239 } |
| 256 | 240 |
| 257 void MessengerImpl::HandleUnlockResponseMessage( | 241 void MessengerImpl::HandleUnlockResponseMessage( |
| 258 const base::DictionaryValue& message) { | 242 const base::DictionaryValue& message) { |
| 259 FOR_EACH_OBSERVER(MessengerObserver, observers_, OnUnlockResponse(true)); | 243 FOR_EACH_OBSERVER(MessengerObserver, observers_, OnUnlockResponse(true)); |
| 260 } | 244 } |
| 261 | 245 |
| 262 void MessengerImpl::PollScreenStateForIOS() { | |
| 263 if (!connection_->IsConnected()) | |
| 264 return; | |
| 265 | |
| 266 // Sends message requesting screen state. | |
| 267 connection_->SendMessage(make_scoped_ptr(new WireMessage(kPollScreenState))); | |
| 268 | |
| 269 // Schedules the next message in |kPollingIntervalSeconds|. | |
| 270 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | |
| 271 FROM_HERE, base::Bind(&MessengerImpl::PollScreenStateForIOS, | |
| 272 weak_ptr_factory_.GetWeakPtr()), | |
| 273 base::TimeDelta::FromSeconds(kIOSPollingIntervalSeconds)); | |
| 274 } | |
| 275 | |
| 276 void MessengerImpl::OnConnectionStatusChanged(Connection* connection, | 246 void MessengerImpl::OnConnectionStatusChanged(Connection* connection, |
| 277 Connection::Status old_status, | 247 Connection::Status old_status, |
| 278 Connection::Status new_status) { | 248 Connection::Status new_status) { |
| 279 DCHECK_EQ(connection, connection_.get()); | 249 DCHECK_EQ(connection, connection_.get()); |
| 280 if (new_status == Connection::DISCONNECTED) { | 250 if (new_status == Connection::DISCONNECTED) { |
| 281 PA_LOG(INFO) << "Secure channel disconnected..."; | 251 PA_LOG(INFO) << "Secure channel disconnected..."; |
| 282 connection_->RemoveObserver(this); | 252 connection_->RemoveObserver(this); |
| 253 connection_.reset(); |
| 283 FOR_EACH_OBSERVER(MessengerObserver, observers_, OnDisconnected()); | 254 FOR_EACH_OBSERVER(MessengerObserver, observers_, OnDisconnected()); |
| 284 // TODO(isherman): Determine whether it's also necessary/appropriate to fire | 255 // TODO(isherman): Determine whether it's also necessary/appropriate to fire |
| 285 // this notification from the destructor. | 256 // this notification from the destructor. |
| 286 } | 257 } |
| 287 } | 258 } |
| 288 | 259 |
| 289 void MessengerImpl::OnMessageReceived(const Connection& connection, | 260 void MessengerImpl::OnMessageReceived(const Connection& connection, |
| 290 const WireMessage& wire_message) { | 261 const WireMessage& wire_message) { |
| 291 // TODO(tengs): Unify the iOS status update protocol with the existing Android | |
| 292 // protocol, so we don't have this special case. | |
| 293 std::string payload = wire_message.payload(); | |
| 294 if (payload == kScreenUnlocked || payload == kScreenLocked) { | |
| 295 RemoteStatusUpdate update; | |
| 296 update.user_presence = | |
| 297 (payload == kScreenUnlocked ? USER_PRESENT : USER_ABSENT); | |
| 298 update.secure_screen_lock_state = SECURE_SCREEN_LOCK_ENABLED; | |
| 299 update.trust_agent_state = TRUST_AGENT_ENABLED; | |
| 300 FOR_EACH_OBSERVER(MessengerObserver, observers_, | |
| 301 OnRemoteStatusUpdate(update)); | |
| 302 return; | |
| 303 } | |
| 304 | |
| 305 secure_context_->Decode(wire_message.payload(), | 262 secure_context_->Decode(wire_message.payload(), |
| 306 base::Bind(&MessengerImpl::OnMessageDecoded, | 263 base::Bind(&MessengerImpl::OnMessageDecoded, |
| 307 weak_ptr_factory_.GetWeakPtr())); | 264 weak_ptr_factory_.GetWeakPtr())); |
| 308 } | 265 } |
| 309 | 266 |
| 310 void MessengerImpl::OnSendCompleted(const Connection& connection, | 267 void MessengerImpl::OnSendCompleted(const Connection& connection, |
| 311 const WireMessage& wire_message, | 268 const WireMessage& wire_message, |
| 312 bool success) { | 269 bool success) { |
| 313 if (!pending_message_) { | 270 if (!pending_message_) { |
| 314 PA_LOG(ERROR) << "Unexpected message sent."; | 271 PA_LOG(ERROR) << "Unexpected message sent."; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 336 } else { | 293 } else { |
| 337 PA_LOG(ERROR) << "Message of unknown type '" << pending_message_->type | 294 PA_LOG(ERROR) << "Message of unknown type '" << pending_message_->type |
| 338 << "' sent."; | 295 << "' sent."; |
| 339 } | 296 } |
| 340 | 297 |
| 341 pending_message_.reset(); | 298 pending_message_.reset(); |
| 342 ProcessMessageQueue(); | 299 ProcessMessageQueue(); |
| 343 } | 300 } |
| 344 | 301 |
| 345 } // namespace proximity_auth | 302 } // namespace proximity_auth |
| OLD | NEW |