OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/browser/sync/profile_sync_service.h" | 5 #include "chrome/browser/sync/profile_sync_service.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <map> | 8 #include <map> |
9 #include <ostream> | 9 #include <ostream> |
10 #include <set> | 10 #include <set> |
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 types, | 368 types, |
369 credentials, | 369 credentials, |
370 delete_sync_data_folder); | 370 delete_sync_data_folder); |
371 } | 371 } |
372 | 372 |
373 void ProfileSyncService::CreateBackend() { | 373 void ProfileSyncService::CreateBackend() { |
374 backend_.reset(new SyncBackendHost(profile_)); | 374 backend_.reset(new SyncBackendHost(profile_)); |
375 } | 375 } |
376 | 376 |
377 bool ProfileSyncService::IsEncryptedDatatypeEnabled() const { | 377 bool ProfileSyncService::IsEncryptedDatatypeEnabled() const { |
| 378 if (HasPendingEncryptedTypes()) |
| 379 return true; |
378 syncable::ModelTypeSet preferred_types; | 380 syncable::ModelTypeSet preferred_types; |
379 GetPreferredDataTypes(&preferred_types); | 381 GetPreferredDataTypes(&preferred_types); |
380 syncable::ModelTypeSet encrypted_types; | 382 syncable::ModelTypeSet encrypted_types; |
381 GetEncryptedDataTypes(&encrypted_types); | 383 GetEncryptedDataTypes(&encrypted_types); |
382 syncable::ModelTypeBitSet preferred_types_bitset = | 384 syncable::ModelTypeBitSet preferred_types_bitset = |
383 syncable::ModelTypeBitSetFromSet(preferred_types); | 385 syncable::ModelTypeBitSetFromSet(preferred_types); |
384 syncable::ModelTypeBitSet encrypted_types_bitset = | 386 syncable::ModelTypeBitSet encrypted_types_bitset = |
385 syncable::ModelTypeBitSetFromSet(encrypted_types); | 387 syncable::ModelTypeBitSetFromSet(encrypted_types); |
386 DCHECK(encrypted_types.count(syncable::PASSWORDS)); | 388 DCHECK(encrypted_types.count(syncable::PASSWORDS)); |
387 return (preferred_types_bitset & encrypted_types_bitset).any(); | 389 return (preferred_types_bitset & encrypted_types_bitset).any(); |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
735 if (unrecoverable_error_detected_) { | 737 if (unrecoverable_error_detected_) { |
736 // When unrecoverable error is detected we post a task to shutdown the | 738 // When unrecoverable error is detected we post a task to shutdown the |
737 // backend. The task might not have executed yet. | 739 // backend. The task might not have executed yet. |
738 return; | 740 return; |
739 } | 741 } |
740 | 742 |
741 VLOG(1) << "Passphrase required with reason: " | 743 VLOG(1) << "Passphrase required with reason: " |
742 << sync_api::PassphraseRequiredReasonToString(reason); | 744 << sync_api::PassphraseRequiredReasonToString(reason); |
743 passphrase_required_reason_ = reason; | 745 passphrase_required_reason_ = reason; |
744 | 746 |
| 747 // Store any passphrases we have into temps and clear out the originals so |
| 748 // we don't hold on to the passphrases any longer than we have to. We |
| 749 // then use the passphrases if they're present (after OnPassphraseAccepted). |
| 750 std::string gaia_password = gaia_password_; |
| 751 std::string cached_passphrase = cached_passphrase_.value; |
| 752 bool is_explicit = cached_passphrase_.is_explicit; |
| 753 bool is_creation = cached_passphrase_.is_creation; |
| 754 gaia_password_ = std::string(); |
| 755 cached_passphrase_ = CachedPassphrase(); |
| 756 |
745 // We will skip the passphrase prompt and suppress the warning if the | 757 // We will skip the passphrase prompt and suppress the warning if the |
746 // passphrase is needed for decryption but the user is not syncing an | 758 // passphrase is needed for decryption but the user is not syncing an |
747 // encrypted data type on this machine. Otherwise we look for one. | 759 // encrypted data type on this machine. Otherwise we look for one. |
748 if (!IsEncryptedDatatypeEnabled() && IsPassphraseRequiredForDecryption()) { | 760 if (!IsEncryptedDatatypeEnabled() && IsPassphraseRequiredForDecryption()) { |
749 VLOG(1) << "Not decrypting and no encrypted datatypes enabled" | 761 VLOG(1) << "Decrypting and no encrypted datatypes enabled" |
750 << ", accepted passphrase."; | 762 << ", accepted passphrase."; |
751 OnPassphraseAccepted(); | 763 OnPassphraseAccepted(); |
752 } | 764 } |
753 | 765 |
754 // First try supplying gaia password as the passphrase. | 766 // First try supplying gaia password as the passphrase. |
755 if (!gaia_password_.empty()) { | 767 if (!gaia_password.empty()) { |
756 VLOG(1) << "Attempting gaia passphrase."; | 768 VLOG(1) << "Attempting gaia passphrase."; |
757 SetPassphrase(gaia_password_, false, true); | 769 // SetPassphrase will set gaia_password_ if the syncer isn't ready. |
758 gaia_password_ = std::string(); | 770 SetPassphrase(gaia_password, false, true); |
759 return; | 771 return; |
760 } | 772 } |
761 | 773 |
762 // If the above failed then try the custom passphrase the user might have | 774 // If the above failed then try the custom passphrase the user might have |
763 // entered in setup. | 775 // entered in setup. |
764 if (!cached_passphrase_.value.empty()) { | 776 if (!cached_passphrase.empty()) { |
765 VLOG(1) << "Attempting cached passphrase."; | 777 VLOG(1) << "Attempting cached passphrase."; |
766 SetPassphrase(cached_passphrase_.value, | 778 // SetPassphrase will set cached_passphrase_ if the syncer isn't ready. |
767 cached_passphrase_.is_explicit, | 779 SetPassphrase(cached_passphrase, is_explicit, is_creation); |
768 cached_passphrase_.is_creation); | |
769 cached_passphrase_ = CachedPassphrase(); | |
770 return; | 780 return; |
771 } | 781 } |
772 | 782 |
773 // Prompt the user for a password. | 783 // Prompt the user for a password. |
774 if (WizardIsVisible() && IsEncryptedDatatypeEnabled() && | 784 if (WizardIsVisible() && IsEncryptedDatatypeEnabled() && |
775 IsPassphraseRequiredForDecryption()) { | 785 IsPassphraseRequiredForDecryption()) { |
776 VLOG(1) << "Prompting user for passphrase."; | 786 VLOG(1) << "Prompting user for passphrase."; |
777 wizard_.Step(SyncSetupWizard::ENTER_PASSPHRASE); | 787 wizard_.Step(SyncSetupWizard::ENTER_PASSPHRASE); |
778 } | 788 } |
779 | 789 |
780 NotifyObservers(); | 790 NotifyObservers(); |
781 } | 791 } |
782 | 792 |
783 void ProfileSyncService::OnPassphraseAccepted() { | 793 void ProfileSyncService::OnPassphraseAccepted() { |
784 VLOG(1) << "Received OnPassphraseAccepted."; | 794 VLOG(1) << "Received OnPassphraseAccepted."; |
| 795 // Don't hold on to a passphrase in raw form longer than needed. |
| 796 gaia_password_ = std::string(); |
| 797 cached_passphrase_ = CachedPassphrase(); |
| 798 |
785 // Make sure the data types that depend on the passphrase are started at | 799 // Make sure the data types that depend on the passphrase are started at |
786 // this time. | 800 // this time. |
787 syncable::ModelTypeSet types; | 801 syncable::ModelTypeSet types; |
788 GetPreferredDataTypes(&types); | 802 GetPreferredDataTypes(&types); |
789 | 803 |
790 // Reset passphrase_required_reason_ before configuring the DataTypeManager | 804 // Reset passphrase_required_reason_ before configuring the DataTypeManager |
791 // since we know we no longer require the passphrase. | 805 // since we know we no longer require the passphrase. |
792 passphrase_required_reason_ = sync_api::REASON_PASSPHRASE_NOT_REQUIRED; | 806 passphrase_required_reason_ = sync_api::REASON_PASSPHRASE_NOT_REQUIRED; |
793 | 807 |
794 if (data_type_manager_.get()) { | 808 if (data_type_manager_.get()) { |
795 // Unblock the data type manager if necessary. | 809 // Unblock the data type manager if necessary. |
796 // This will always trigger a SYNC_CONFIGURE_DONE on completion, which will | 810 // This will always trigger a SYNC_CONFIGURE_DONE on completion, which will |
797 // step the UI wizard into DONE state (even if no datatypes have changed). | 811 // step the UI wizard into DONE state (even if no datatypes have changed). |
798 data_type_manager_->Configure(types, | 812 data_type_manager_->Configure(types, |
799 sync_api::CONFIGURE_REASON_RECONFIGURATION); | 813 sync_api::CONFIGURE_REASON_RECONFIGURATION); |
800 } | 814 } |
801 | 815 |
802 NotifyObservers(); | 816 NotifyObservers(); |
803 } | 817 } |
804 | 818 |
805 void ProfileSyncService::OnEncryptionComplete( | 819 void ProfileSyncService::OnEncryptionComplete( |
806 const syncable::ModelTypeSet& encrypted_types) { | 820 const syncable::ModelTypeSet& encrypted_types) { |
| 821 if (!pending_types_for_encryption_.empty()) { |
| 822 // The user had chosen to encrypt datatypes. This is the last thing to |
| 823 // complete, so now that we're done notify the UI. |
| 824 wizard_.Step(SyncSetupWizard::DONE); |
| 825 } |
| 826 pending_types_for_encryption_.clear(); |
807 NotifyObservers(); | 827 NotifyObservers(); |
808 } | 828 } |
809 | 829 |
810 void ProfileSyncService::OnMigrationNeededForTypes( | 830 void ProfileSyncService::OnMigrationNeededForTypes( |
811 const syncable::ModelTypeSet& types) { | 831 const syncable::ModelTypeSet& types) { |
812 DCHECK(backend_initialized_); | 832 DCHECK(backend_initialized_); |
813 DCHECK(data_type_manager_.get()); | 833 DCHECK(data_type_manager_.get()); |
814 | 834 |
815 // Migrator must be valid, because we don't sync until it is created and this | 835 // Migrator must be valid, because we don't sync until it is created and this |
816 // callback originates from a sync cycle. | 836 // callback originates from a sync cycle. |
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1214 if (!backend_.get()) | 1234 if (!backend_.get()) |
1215 return; | 1235 return; |
1216 backend_->DeactivateDataType(data_type_controller, change_processor); | 1236 backend_->DeactivateDataType(data_type_controller, change_processor); |
1217 } | 1237 } |
1218 | 1238 |
1219 void ProfileSyncService::SetPassphrase(const std::string& passphrase, | 1239 void ProfileSyncService::SetPassphrase(const std::string& passphrase, |
1220 bool is_explicit, | 1240 bool is_explicit, |
1221 bool is_creation) { | 1241 bool is_creation) { |
1222 if (ShouldPushChanges() || IsPassphraseRequired()) { | 1242 if (ShouldPushChanges() || IsPassphraseRequired()) { |
1223 VLOG(1) << "Setting " << (is_explicit ? "explicit" : "implicit") | 1243 VLOG(1) << "Setting " << (is_explicit ? "explicit" : "implicit") |
1224 << " passphrase " << (is_creation ? " for creation" : ""); | 1244 << " passphrase" << (is_creation ? " for creation" : ""); |
1225 backend_->SetPassphrase(passphrase, is_explicit); | 1245 backend_->SetPassphrase(passphrase, is_explicit); |
1226 } else { | 1246 } else { |
1227 if (is_explicit) { | 1247 if (is_explicit) { |
1228 cached_passphrase_.value = passphrase; | 1248 cached_passphrase_.value = passphrase; |
1229 cached_passphrase_.is_explicit = is_explicit; | 1249 cached_passphrase_.is_explicit = is_explicit; |
1230 cached_passphrase_.is_creation = is_creation; | 1250 cached_passphrase_.is_creation = is_creation; |
1231 } else { | 1251 } else { |
1232 gaia_password_ = passphrase; | 1252 gaia_password_ = passphrase; |
1233 } | 1253 } |
1234 } | 1254 } |
1235 } | 1255 } |
1236 | 1256 |
1237 void ProfileSyncService::EncryptDataTypes( | 1257 void ProfileSyncService::set_pending_types_for_encryption( |
1238 const syncable::ModelTypeSet& encrypted_types) { | 1258 const syncable::ModelTypeSet& encrypted_types) { |
1239 if (HasSyncSetupCompleted()) { | 1259 if (encrypted_types.empty()) { |
1240 backend_->EncryptDataTypes(encrypted_types); | 1260 // We can't unencrypt types. |
| 1261 VLOG(1) << "No datatypes set for encryption, dropping encryption request."; |
1241 pending_types_for_encryption_.clear(); | 1262 pending_types_for_encryption_.clear(); |
1242 } else { | 1263 return; |
1243 pending_types_for_encryption_ = encrypted_types; | |
1244 } | 1264 } |
| 1265 // Setting the pending types for encryption doesn't actually trigger |
| 1266 // encryption. The actual encryption will occur after the datatype manager |
| 1267 // is reconfigured. |
| 1268 pending_types_for_encryption_ = encrypted_types; |
1245 } | 1269 } |
1246 | 1270 |
1247 // This would open a transaction to get the encrypted types. Do not call this | 1271 // This will open a transaction to get the encrypted types. Do not call this |
1248 // if you already have a transaction open. | 1272 // if you already have a transaction open. |
1249 void ProfileSyncService::GetEncryptedDataTypes( | 1273 void ProfileSyncService::GetEncryptedDataTypes( |
1250 syncable::ModelTypeSet* encrypted_types) const { | 1274 syncable::ModelTypeSet* encrypted_types) const { |
1251 CHECK(encrypted_types); | 1275 CHECK(encrypted_types); |
1252 if (backend_.get()) { | 1276 if (backend_.get()) { |
1253 *encrypted_types = backend_->GetEncryptedDataTypes(); | 1277 *encrypted_types = backend_->GetEncryptedDataTypes(); |
1254 DCHECK(encrypted_types->count(syncable::PASSWORDS)); | 1278 DCHECK(encrypted_types->count(syncable::PASSWORDS)); |
1255 } else { | 1279 } else { |
1256 // Either we are in an unrecoverable error or the sync is not yet done | 1280 // Either we are in an unrecoverable error or the sync is not yet done |
1257 // initializing. In either case just return the password type. During | 1281 // initializing. In either case just return the password type. During |
1258 // sync initialization the UI might need to know what our encrypted | 1282 // sync initialization the UI might need to know what our encrypted |
1259 // types are. | 1283 // types are. |
1260 (*encrypted_types).insert(syncable::PASSWORDS); | 1284 (*encrypted_types).insert(syncable::PASSWORDS); |
1261 } | 1285 } |
1262 } | 1286 } |
1263 | 1287 |
| 1288 bool ProfileSyncService::HasPendingEncryptedTypes() const { |
| 1289 return !pending_types_for_encryption_.empty(); |
| 1290 } |
| 1291 |
1264 void ProfileSyncService::Observe(int type, | 1292 void ProfileSyncService::Observe(int type, |
1265 const NotificationSource& source, | 1293 const NotificationSource& source, |
1266 const NotificationDetails& details) { | 1294 const NotificationDetails& details) { |
1267 switch (type) { | 1295 switch (type) { |
1268 case chrome::NOTIFICATION_SYNC_CONFIGURE_START: { | 1296 case chrome::NOTIFICATION_SYNC_CONFIGURE_START: { |
1269 NotifyObservers(); | 1297 NotifyObservers(); |
1270 // TODO(sync): Maybe toast? | 1298 // TODO(sync): Maybe toast? |
1271 break; | 1299 break; |
1272 } | 1300 } |
1273 case chrome::NOTIFICATION_SYNC_CONFIGURE_DONE: { | 1301 case chrome::NOTIFICATION_SYNC_CONFIGURE_DONE: { |
1274 DataTypeManager::ConfigureResultWithErrorLocation* result_with_location = | 1302 DataTypeManager::ConfigureResultWithErrorLocation* result_with_location = |
1275 Details<DataTypeManager::ConfigureResultWithErrorLocation>( | 1303 Details<DataTypeManager::ConfigureResultWithErrorLocation>( |
1276 details).ptr(); | 1304 details).ptr(); |
1277 | 1305 |
1278 DataTypeManager::ConfigureResult result = result_with_location->result; | 1306 DataTypeManager::ConfigureResult result = result_with_location->result; |
1279 VLOG(1) << "PSS SYNC_CONFIGURE_DONE called with result: " << result; | 1307 VLOG(1) << "PSS SYNC_CONFIGURE_DONE called with result: " << result; |
1280 if (result == DataTypeManager::ABORTED && | 1308 if (result == DataTypeManager::ABORTED && |
1281 expect_sync_configuration_aborted_) { | 1309 expect_sync_configuration_aborted_) { |
1282 VLOG(0) << "ProfileSyncService::Observe Sync Configure aborted"; | 1310 VLOG(0) << "ProfileSyncService::Observe Sync Configure aborted"; |
1283 expect_sync_configuration_aborted_ = false; | 1311 expect_sync_configuration_aborted_ = false; |
1284 return; | 1312 return; |
1285 } | 1313 } |
1286 // Clear out the gaia password if it is already there. | |
1287 gaia_password_ = std::string(); | |
1288 if (result != DataTypeManager::OK) { | 1314 if (result != DataTypeManager::OK) { |
1289 VLOG(0) << "ProfileSyncService::Observe: Unrecoverable error detected"; | 1315 VLOG(0) << "ProfileSyncService::Observe: Unrecoverable error detected"; |
1290 std::string message = StringPrintf("Sync Configuration failed with %d", | 1316 std::string message = StringPrintf("Sync Configuration failed with %d", |
1291 result); | 1317 result); |
1292 OnUnrecoverableError(*(result_with_location->location), message); | 1318 OnUnrecoverableError(*(result_with_location->location), message); |
1293 cached_passphrase_ = CachedPassphrase(); | 1319 cached_passphrase_ = CachedPassphrase(); |
1294 return; | 1320 return; |
1295 } | 1321 } |
1296 | 1322 |
1297 // If the user had entered a custom passphrase use it now. | |
1298 if (!cached_passphrase_.value.empty()) { | |
1299 // Don't hold on to the passphrase in raw form longer than needed. | |
1300 SetPassphrase(cached_passphrase_.value, | |
1301 cached_passphrase_.is_explicit, | |
1302 cached_passphrase_.is_creation); | |
1303 cached_passphrase_ = CachedPassphrase(); | |
1304 } | |
1305 | |
1306 // We should never get in a state where we have no encrypted datatypes | 1323 // We should never get in a state where we have no encrypted datatypes |
1307 // enabled, and yet we still think we require a passphrase for decryption. | 1324 // enabled, and yet we still think we require a passphrase for decryption. |
1308 DCHECK(!(IsPassphraseRequiredForDecryption() && | 1325 DCHECK(!(IsPassphraseRequiredForDecryption() && |
1309 !IsEncryptedDatatypeEnabled())); | 1326 !IsEncryptedDatatypeEnabled())); |
1310 | 1327 |
1311 // TODO(sync): Less wizard, more toast. | |
1312 wizard_.Step(SyncSetupWizard::DONE); | |
1313 NotifyObservers(); | |
1314 | |
1315 // In the old world, this would be a no-op. With new syncer thread, | 1328 // In the old world, this would be a no-op. With new syncer thread, |
1316 // this is the point where it is safe to switch from config-mode to | 1329 // this is the point where it is safe to switch from config-mode to |
1317 // normal operation. | 1330 // normal operation. |
1318 backend_->StartSyncingWithServer(); | 1331 backend_->StartSyncingWithServer(); |
1319 | 1332 |
1320 if (!pending_types_for_encryption_.empty()) { | 1333 if (pending_types_for_encryption_.empty()) { |
1321 EncryptDataTypes(pending_types_for_encryption_); | 1334 wizard_.Step(SyncSetupWizard::DONE); |
1322 pending_types_for_encryption_.clear(); | 1335 NotifyObservers(); |
| 1336 } else { |
| 1337 // Will clear pending_types_for_encryption_ on success (via |
| 1338 // OnEncryptionComplete). Has no effect if pending_types_for_encryption_ |
| 1339 // matches the encrypted types (and will clear |
| 1340 // pending_types_for_encryption_). |
| 1341 backend_->EncryptDataTypes(pending_types_for_encryption_); |
1323 } | 1342 } |
1324 break; | 1343 break; |
1325 } | 1344 } |
1326 case chrome::NOTIFICATION_PREF_CHANGED: { | 1345 case chrome::NOTIFICATION_PREF_CHANGED: { |
1327 std::string* pref_name = Details<std::string>(details).ptr(); | 1346 std::string* pref_name = Details<std::string>(details).ptr(); |
1328 if (*pref_name == prefs::kSyncManaged) { | 1347 if (*pref_name == prefs::kSyncManaged) { |
1329 NotifyObservers(); | 1348 NotifyObservers(); |
1330 if (*pref_sync_managed_) { | 1349 if (*pref_sync_managed_) { |
1331 DisableForUser(); | 1350 DisableForUser(); |
1332 } else if (HasSyncSetupCompleted() && AreCredentialsAvailable()) { | 1351 } else if (HasSyncSetupCompleted() && AreCredentialsAvailable()) { |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1427 // is initialized, all enabled data types are consistent with one | 1446 // is initialized, all enabled data types are consistent with one |
1428 // another, and no unrecoverable error has transpired. | 1447 // another, and no unrecoverable error has transpired. |
1429 if (unrecoverable_error_detected_) | 1448 if (unrecoverable_error_detected_) |
1430 return false; | 1449 return false; |
1431 | 1450 |
1432 if (!data_type_manager_.get()) | 1451 if (!data_type_manager_.get()) |
1433 return false; | 1452 return false; |
1434 | 1453 |
1435 return data_type_manager_->state() == DataTypeManager::CONFIGURED; | 1454 return data_type_manager_->state() == DataTypeManager::CONFIGURED; |
1436 } | 1455 } |
OLD | NEW |