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 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 types, | 369 types, |
370 credentials, | 370 credentials, |
371 delete_sync_data_folder); | 371 delete_sync_data_folder); |
372 } | 372 } |
373 | 373 |
374 void ProfileSyncService::CreateBackend() { | 374 void ProfileSyncService::CreateBackend() { |
375 backend_.reset(new SyncBackendHost(profile_)); | 375 backend_.reset(new SyncBackendHost(profile_)); |
376 } | 376 } |
377 | 377 |
378 bool ProfileSyncService::IsEncryptedDatatypeEnabled() const { | 378 bool ProfileSyncService::IsEncryptedDatatypeEnabled() const { |
| 379 if (HasPendingEncryptedTypes()) |
| 380 return true; |
379 syncable::ModelTypeSet preferred_types; | 381 syncable::ModelTypeSet preferred_types; |
380 GetPreferredDataTypes(&preferred_types); | 382 GetPreferredDataTypes(&preferred_types); |
381 syncable::ModelTypeSet encrypted_types; | 383 syncable::ModelTypeSet encrypted_types; |
382 GetEncryptedDataTypes(&encrypted_types); | 384 GetEncryptedDataTypes(&encrypted_types); |
383 syncable::ModelTypeBitSet preferred_types_bitset = | 385 syncable::ModelTypeBitSet preferred_types_bitset = |
384 syncable::ModelTypeBitSetFromSet(preferred_types); | 386 syncable::ModelTypeBitSetFromSet(preferred_types); |
385 syncable::ModelTypeBitSet encrypted_types_bitset = | 387 syncable::ModelTypeBitSet encrypted_types_bitset = |
386 syncable::ModelTypeBitSetFromSet(encrypted_types); | 388 syncable::ModelTypeBitSetFromSet(encrypted_types); |
387 DCHECK(encrypted_types.count(syncable::PASSWORDS)); | 389 DCHECK(encrypted_types.count(syncable::PASSWORDS)); |
388 return (preferred_types_bitset & encrypted_types_bitset).any(); | 390 return (preferred_types_bitset & encrypted_types_bitset).any(); |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
684 if (unrecoverable_error_detected_) { | 686 if (unrecoverable_error_detected_) { |
685 // When unrecoverable error is detected we post a task to shutdown the | 687 // When unrecoverable error is detected we post a task to shutdown the |
686 // backend. The task might not have executed yet. | 688 // backend. The task might not have executed yet. |
687 return; | 689 return; |
688 } | 690 } |
689 | 691 |
690 VLOG(1) << "Passphrase required with reason: " | 692 VLOG(1) << "Passphrase required with reason: " |
691 << sync_api::PassphraseRequiredReasonToString(reason); | 693 << sync_api::PassphraseRequiredReasonToString(reason); |
692 passphrase_required_reason_ = reason; | 694 passphrase_required_reason_ = reason; |
693 | 695 |
| 696 // Store any passphrases we have into temps and clear out the originals so |
| 697 // we don't hold on to the passphrases any longer than we have to. We |
| 698 // then use the passphrases if they're present (after OnPassphraseAccepted). |
| 699 std::string gaia_password = gaia_password_; |
| 700 std::string cached_passphrase = cached_passphrase_.value; |
| 701 bool is_explicit = cached_passphrase_.is_explicit; |
| 702 bool is_creation = cached_passphrase_.is_creation; |
| 703 gaia_password_ = std::string(); |
| 704 cached_passphrase_ = CachedPassphrase(); |
| 705 |
694 // We will skip the passphrase prompt and suppress the warning if the | 706 // We will skip the passphrase prompt and suppress the warning if the |
695 // passphrase is needed for decryption but the user is not syncing an | 707 // passphrase is needed for decryption but the user is not syncing an |
696 // encrypted data type on this machine. Otherwise we look for one. | 708 // encrypted data type on this machine. Otherwise we look for one. |
697 if (!IsEncryptedDatatypeEnabled() && IsPassphraseRequiredForDecryption()) { | 709 if (!IsEncryptedDatatypeEnabled() && IsPassphraseRequiredForDecryption()) { |
698 VLOG(1) << "Not decrypting and no encrypted datatypes enabled" | 710 VLOG(1) << "Decrypting and no encrypted datatypes enabled" |
699 << ", accepted passphrase."; | 711 << ", accepted passphrase."; |
700 OnPassphraseAccepted(); | 712 OnPassphraseAccepted(); |
701 } | 713 } |
702 | 714 |
703 // First try supplying gaia password as the passphrase. | 715 // First try supplying gaia password as the passphrase. |
704 if (!gaia_password_.empty()) { | 716 if (!gaia_password.empty()) { |
705 VLOG(1) << "Attempting gaia passphrase."; | 717 VLOG(1) << "Attempting gaia passphrase."; |
706 SetPassphrase(gaia_password_, false, true); | 718 // SetPassphrase will set gaia_password_ if the syncer isn't ready. |
707 gaia_password_ = std::string(); | 719 SetPassphrase(gaia_password, false, true); |
708 return; | 720 return; |
709 } | 721 } |
710 | 722 |
711 // If the above failed then try the custom passphrase the user might have | 723 // If the above failed then try the custom passphrase the user might have |
712 // entered in setup. | 724 // entered in setup. |
713 if (!cached_passphrase_.value.empty()) { | 725 if (!cached_passphrase.empty()) { |
714 VLOG(1) << "Attempting cached passphrase."; | 726 VLOG(1) << "Attempting cached passphrase."; |
715 SetPassphrase(cached_passphrase_.value, | 727 // SetPassphrase will set cached_passphrase_ if the syncer isn't ready. |
716 cached_passphrase_.is_explicit, | 728 SetPassphrase(cached_passphrase, is_explicit, is_creation); |
717 cached_passphrase_.is_creation); | |
718 cached_passphrase_ = CachedPassphrase(); | |
719 return; | 729 return; |
720 } | 730 } |
721 | 731 |
722 // Prompt the user for a password. | 732 // Prompt the user for a password. |
723 if (WizardIsVisible() && IsEncryptedDatatypeEnabled() && | 733 if (WizardIsVisible() && IsEncryptedDatatypeEnabled() && |
724 IsPassphraseRequiredForDecryption()) { | 734 IsPassphraseRequiredForDecryption()) { |
725 VLOG(1) << "Prompting user for passphrase."; | 735 VLOG(1) << "Prompting user for passphrase."; |
726 wizard_.Step(SyncSetupWizard::ENTER_PASSPHRASE); | 736 wizard_.Step(SyncSetupWizard::ENTER_PASSPHRASE); |
727 } | 737 } |
728 | 738 |
729 NotifyObservers(); | 739 NotifyObservers(); |
730 } | 740 } |
731 | 741 |
732 void ProfileSyncService::OnPassphraseAccepted() { | 742 void ProfileSyncService::OnPassphraseAccepted() { |
733 VLOG(1) << "Received OnPassphraseAccepted."; | 743 VLOG(1) << "Received OnPassphraseAccepted."; |
| 744 // Don't hold on to a passphrase in raw form longer than needed. |
| 745 gaia_password_ = std::string(); |
| 746 cached_passphrase_ = CachedPassphrase(); |
| 747 |
734 // Make sure the data types that depend on the passphrase are started at | 748 // Make sure the data types that depend on the passphrase are started at |
735 // this time. | 749 // this time. |
736 syncable::ModelTypeSet types; | 750 syncable::ModelTypeSet types; |
737 GetPreferredDataTypes(&types); | 751 GetPreferredDataTypes(&types); |
738 | 752 |
739 // Reset passphrase_required_reason_ before configuring the DataTypeManager | 753 // Reset passphrase_required_reason_ before configuring the DataTypeManager |
740 // since we know we no longer require the passphrase. | 754 // since we know we no longer require the passphrase. |
741 passphrase_required_reason_ = sync_api::REASON_PASSPHRASE_NOT_REQUIRED; | 755 passphrase_required_reason_ = sync_api::REASON_PASSPHRASE_NOT_REQUIRED; |
742 | 756 |
743 if (data_type_manager_.get()) { | 757 if (data_type_manager_.get()) { |
744 // Unblock the data type manager if necessary. | 758 // Unblock the data type manager if necessary. |
745 // This will always trigger a SYNC_CONFIGURE_DONE on completion, which will | 759 // This will always trigger a SYNC_CONFIGURE_DONE on completion, which will |
746 // step the UI wizard into DONE state (even if no datatypes have changed). | 760 // step the UI wizard into DONE state (even if no datatypes have changed). |
747 data_type_manager_->Configure(types, | 761 data_type_manager_->Configure(types, |
748 sync_api::CONFIGURE_REASON_RECONFIGURATION); | 762 sync_api::CONFIGURE_REASON_RECONFIGURATION); |
749 } | 763 } |
750 | 764 |
751 NotifyObservers(); | 765 NotifyObservers(); |
752 } | 766 } |
753 | 767 |
754 void ProfileSyncService::OnEncryptionComplete( | 768 void ProfileSyncService::OnEncryptionComplete( |
755 const syncable::ModelTypeSet& encrypted_types) { | 769 const syncable::ModelTypeSet& encrypted_types) { |
| 770 if (!pending_types_for_encryption_.empty()) { |
| 771 // The user had chosen to encrypt datatypes. This is the last thing to |
| 772 // complete, so now that we're done notify the UI. |
| 773 wizard_.Step(SyncSetupWizard::DONE); |
| 774 } |
| 775 pending_types_for_encryption_.clear(); |
756 NotifyObservers(); | 776 NotifyObservers(); |
757 } | 777 } |
758 | 778 |
759 void ProfileSyncService::OnMigrationNeededForTypes( | 779 void ProfileSyncService::OnMigrationNeededForTypes( |
760 const syncable::ModelTypeSet& types) { | 780 const syncable::ModelTypeSet& types) { |
761 DCHECK(backend_initialized_); | 781 DCHECK(backend_initialized_); |
762 DCHECK(data_type_manager_.get()); | 782 DCHECK(data_type_manager_.get()); |
763 | 783 |
764 // Migrator must be valid, because we don't sync until it is created and this | 784 // Migrator must be valid, because we don't sync until it is created and this |
765 // callback originates from a sync cycle. | 785 // callback originates from a sync cycle. |
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1175 if (!backend_.get()) | 1195 if (!backend_.get()) |
1176 return; | 1196 return; |
1177 backend_->DeactivateDataType(data_type_controller, change_processor); | 1197 backend_->DeactivateDataType(data_type_controller, change_processor); |
1178 } | 1198 } |
1179 | 1199 |
1180 void ProfileSyncService::SetPassphrase(const std::string& passphrase, | 1200 void ProfileSyncService::SetPassphrase(const std::string& passphrase, |
1181 bool is_explicit, | 1201 bool is_explicit, |
1182 bool is_creation) { | 1202 bool is_creation) { |
1183 if (ShouldPushChanges() || IsPassphraseRequired()) { | 1203 if (ShouldPushChanges() || IsPassphraseRequired()) { |
1184 VLOG(1) << "Setting " << (is_explicit ? "explicit" : "implicit") | 1204 VLOG(1) << "Setting " << (is_explicit ? "explicit" : "implicit") |
1185 << " passphrase " << (is_creation ? " for creation" : ""); | 1205 << " passphrase" << (is_creation ? " for creation" : ""); |
1186 backend_->SetPassphrase(passphrase, is_explicit); | 1206 backend_->SetPassphrase(passphrase, is_explicit); |
1187 } else { | 1207 } else { |
1188 if (is_explicit) { | 1208 if (is_explicit) { |
1189 cached_passphrase_.value = passphrase; | 1209 cached_passphrase_.value = passphrase; |
1190 cached_passphrase_.is_explicit = is_explicit; | 1210 cached_passphrase_.is_explicit = is_explicit; |
1191 cached_passphrase_.is_creation = is_creation; | 1211 cached_passphrase_.is_creation = is_creation; |
1192 } else { | 1212 } else { |
1193 gaia_password_ = passphrase; | 1213 gaia_password_ = passphrase; |
1194 } | 1214 } |
1195 } | 1215 } |
1196 } | 1216 } |
1197 | 1217 |
1198 void ProfileSyncService::EncryptDataTypes( | 1218 void ProfileSyncService::set_pending_types_for_encryption( |
1199 const syncable::ModelTypeSet& encrypted_types) { | 1219 const syncable::ModelTypeSet& encrypted_types) { |
1200 if (HasSyncSetupCompleted()) { | 1220 if (encrypted_types.empty()) { |
1201 backend_->EncryptDataTypes(encrypted_types); | 1221 // We can't unencrypt types. |
| 1222 VLOG(1) << "No datatypes set for encryption, dropping encryption request."; |
1202 pending_types_for_encryption_.clear(); | 1223 pending_types_for_encryption_.clear(); |
1203 } else { | 1224 return; |
1204 pending_types_for_encryption_ = encrypted_types; | |
1205 } | 1225 } |
| 1226 // Setting the pending types for encryption doesn't actually trigger |
| 1227 // encryption. The actual encryption will occur after the datatype manager |
| 1228 // is reconfigured. |
| 1229 pending_types_for_encryption_ = encrypted_types; |
1206 } | 1230 } |
1207 | 1231 |
1208 // This would open a transaction to get the encrypted types. Do not call this | 1232 // This will open a transaction to get the encrypted types. Do not call this |
1209 // if you already have a transaction open. | 1233 // if you already have a transaction open. |
1210 void ProfileSyncService::GetEncryptedDataTypes( | 1234 void ProfileSyncService::GetEncryptedDataTypes( |
1211 syncable::ModelTypeSet* encrypted_types) const { | 1235 syncable::ModelTypeSet* encrypted_types) const { |
1212 CHECK(encrypted_types); | 1236 CHECK(encrypted_types); |
1213 if (backend_.get()) { | 1237 if (backend_.get()) { |
1214 *encrypted_types = backend_->GetEncryptedDataTypes(); | 1238 *encrypted_types = backend_->GetEncryptedDataTypes(); |
1215 DCHECK(encrypted_types->count(syncable::PASSWORDS)); | 1239 DCHECK(encrypted_types->count(syncable::PASSWORDS)); |
1216 } else { | 1240 } else { |
1217 // Either we are in an unrecoverable error or the sync is not yet done | 1241 // Either we are in an unrecoverable error or the sync is not yet done |
1218 // initializing. In either case just return the password type. During | 1242 // initializing. In either case just return the password type. During |
1219 // sync initialization the UI might need to know what our encrypted | 1243 // sync initialization the UI might need to know what our encrypted |
1220 // types are. | 1244 // types are. |
1221 (*encrypted_types).insert(syncable::PASSWORDS); | 1245 (*encrypted_types).insert(syncable::PASSWORDS); |
1222 } | 1246 } |
1223 } | 1247 } |
1224 | 1248 |
| 1249 bool ProfileSyncService::HasPendingEncryptedTypes() const { |
| 1250 return !pending_types_for_encryption_.empty(); |
| 1251 } |
| 1252 |
1225 void ProfileSyncService::Observe(int type, | 1253 void ProfileSyncService::Observe(int type, |
1226 const NotificationSource& source, | 1254 const NotificationSource& source, |
1227 const NotificationDetails& details) { | 1255 const NotificationDetails& details) { |
1228 switch (type) { | 1256 switch (type) { |
1229 case chrome::NOTIFICATION_SYNC_CONFIGURE_START: { | 1257 case chrome::NOTIFICATION_SYNC_CONFIGURE_START: { |
1230 NotifyObservers(); | 1258 NotifyObservers(); |
1231 // TODO(sync): Maybe toast? | 1259 // TODO(sync): Maybe toast? |
1232 break; | 1260 break; |
1233 } | 1261 } |
1234 case chrome::NOTIFICATION_SYNC_CONFIGURE_DONE: { | 1262 case chrome::NOTIFICATION_SYNC_CONFIGURE_DONE: { |
1235 DataTypeManager::ConfigureResult* result = | 1263 DataTypeManager::ConfigureResult* result = |
1236 Details<DataTypeManager::ConfigureResult>(details).ptr(); | 1264 Details<DataTypeManager::ConfigureResult>(details).ptr(); |
1237 | 1265 |
1238 DataTypeManager::ConfigureStatus status = result->status; | 1266 DataTypeManager::ConfigureStatus status = result->status; |
1239 VLOG(1) << "PSS SYNC_CONFIGURE_DONE called with status: " << status; | 1267 VLOG(1) << "PSS SYNC_CONFIGURE_DONE called with status: " << status; |
1240 if (status == DataTypeManager::ABORTED && | 1268 if (status == DataTypeManager::ABORTED && |
1241 expect_sync_configuration_aborted_) { | 1269 expect_sync_configuration_aborted_) { |
1242 VLOG(0) << "ProfileSyncService::Observe Sync Configure aborted"; | 1270 VLOG(0) << "ProfileSyncService::Observe Sync Configure aborted"; |
1243 expect_sync_configuration_aborted_ = false; | 1271 expect_sync_configuration_aborted_ = false; |
1244 return; | 1272 return; |
1245 } | 1273 } |
1246 // Clear out the gaia password if it is already there. | |
1247 gaia_password_ = std::string(); | |
1248 if (status != DataTypeManager::OK) { | 1274 if (status != DataTypeManager::OK) { |
1249 VLOG(0) << "ProfileSyncService::Observe: Unrecoverable error detected"; | 1275 VLOG(0) << "ProfileSyncService::Observe: Unrecoverable error detected"; |
1250 std::string message = | 1276 std::string message = |
1251 "Sync Configuration failed while configuring " + | 1277 "Sync Configuration failed while configuring " + |
1252 syncable::ModelTypeSetToString(result->failed_types) + | 1278 syncable::ModelTypeSetToString(result->failed_types) + |
1253 ": " + DataTypeManager::ConfigureStatusToString(status); | 1279 ": " + DataTypeManager::ConfigureStatusToString(status); |
1254 OnUnrecoverableError(result->location, message); | 1280 OnUnrecoverableError(result->location, message); |
1255 cached_passphrase_ = CachedPassphrase(); | 1281 cached_passphrase_ = CachedPassphrase(); |
1256 return; | 1282 return; |
1257 } | 1283 } |
1258 | 1284 |
1259 // If the user had entered a custom passphrase use it now. | |
1260 if (!cached_passphrase_.value.empty()) { | |
1261 // Don't hold on to the passphrase in raw form longer than needed. | |
1262 SetPassphrase(cached_passphrase_.value, | |
1263 cached_passphrase_.is_explicit, | |
1264 cached_passphrase_.is_creation); | |
1265 cached_passphrase_ = CachedPassphrase(); | |
1266 } | |
1267 | |
1268 // We should never get in a state where we have no encrypted datatypes | 1285 // We should never get in a state where we have no encrypted datatypes |
1269 // enabled, and yet we still think we require a passphrase for decryption. | 1286 // enabled, and yet we still think we require a passphrase for decryption. |
1270 DCHECK(!(IsPassphraseRequiredForDecryption() && | 1287 DCHECK(!(IsPassphraseRequiredForDecryption() && |
1271 !IsEncryptedDatatypeEnabled())); | 1288 !IsEncryptedDatatypeEnabled())); |
1272 | 1289 |
1273 // TODO(sync): Less wizard, more toast. | |
1274 wizard_.Step(SyncSetupWizard::DONE); | |
1275 NotifyObservers(); | |
1276 | |
1277 // In the old world, this would be a no-op. With new syncer thread, | 1290 // In the old world, this would be a no-op. With new syncer thread, |
1278 // this is the point where it is safe to switch from config-mode to | 1291 // this is the point where it is safe to switch from config-mode to |
1279 // normal operation. | 1292 // normal operation. |
1280 backend_->StartSyncingWithServer(); | 1293 backend_->StartSyncingWithServer(); |
1281 | 1294 |
1282 if (!pending_types_for_encryption_.empty()) { | 1295 if (pending_types_for_encryption_.empty()) { |
1283 EncryptDataTypes(pending_types_for_encryption_); | 1296 wizard_.Step(SyncSetupWizard::DONE); |
1284 pending_types_for_encryption_.clear(); | 1297 NotifyObservers(); |
| 1298 } else { |
| 1299 // Will clear pending_types_for_encryption_ on success (via |
| 1300 // OnEncryptionComplete). Has no effect if pending_types_for_encryption_ |
| 1301 // matches the encrypted types (and will clear |
| 1302 // pending_types_for_encryption_). |
| 1303 backend_->EncryptDataTypes(pending_types_for_encryption_); |
1285 } | 1304 } |
1286 break; | 1305 break; |
1287 } | 1306 } |
1288 case chrome::NOTIFICATION_PREF_CHANGED: { | 1307 case chrome::NOTIFICATION_PREF_CHANGED: { |
1289 std::string* pref_name = Details<std::string>(details).ptr(); | 1308 std::string* pref_name = Details<std::string>(details).ptr(); |
1290 if (*pref_name == prefs::kSyncManaged) { | 1309 if (*pref_name == prefs::kSyncManaged) { |
1291 NotifyObservers(); | 1310 NotifyObservers(); |
1292 if (*pref_sync_managed_) { | 1311 if (*pref_sync_managed_) { |
1293 DisableForUser(); | 1312 DisableForUser(); |
1294 } else if (HasSyncSetupCompleted() && AreCredentialsAvailable()) { | 1313 } else if (HasSyncSetupCompleted() && AreCredentialsAvailable()) { |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1384 // is initialized, all enabled data types are consistent with one | 1403 // is initialized, all enabled data types are consistent with one |
1385 // another, and no unrecoverable error has transpired. | 1404 // another, and no unrecoverable error has transpired. |
1386 if (unrecoverable_error_detected_) | 1405 if (unrecoverable_error_detected_) |
1387 return false; | 1406 return false; |
1388 | 1407 |
1389 if (!data_type_manager_.get()) | 1408 if (!data_type_manager_.get()) |
1390 return false; | 1409 return false; |
1391 | 1410 |
1392 return data_type_manager_->state() == DataTypeManager::CONFIGURED; | 1411 return data_type_manager_->state() == DataTypeManager::CONFIGURED; |
1393 } | 1412 } |
OLD | NEW |