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 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
361 types, | 361 types, |
362 credentials, | 362 credentials, |
363 delete_sync_data_folder); | 363 delete_sync_data_folder); |
364 } | 364 } |
365 | 365 |
366 void ProfileSyncService::CreateBackend() { | 366 void ProfileSyncService::CreateBackend() { |
367 backend_.reset(new SyncBackendHost(profile_)); | 367 backend_.reset(new SyncBackendHost(profile_)); |
368 } | 368 } |
369 | 369 |
370 bool ProfileSyncService::IsEncryptedDatatypeEnabled() const { | 370 bool ProfileSyncService::IsEncryptedDatatypeEnabled() const { |
371 if (!pending_types_for_encryption_.empty()) | |
372 return true; | |
371 syncable::ModelTypeSet preferred_types; | 373 syncable::ModelTypeSet preferred_types; |
372 GetPreferredDataTypes(&preferred_types); | 374 GetPreferredDataTypes(&preferred_types); |
373 syncable::ModelTypeSet encrypted_types; | 375 syncable::ModelTypeSet encrypted_types; |
374 GetEncryptedDataTypes(&encrypted_types); | 376 GetEncryptedDataTypes(&encrypted_types); |
375 syncable::ModelTypeBitSet preferred_types_bitset = | 377 syncable::ModelTypeBitSet preferred_types_bitset = |
376 syncable::ModelTypeBitSetFromSet(preferred_types); | 378 syncable::ModelTypeBitSetFromSet(preferred_types); |
377 syncable::ModelTypeBitSet encrypted_types_bitset = | 379 syncable::ModelTypeBitSet encrypted_types_bitset = |
378 syncable::ModelTypeBitSetFromSet(encrypted_types); | 380 syncable::ModelTypeBitSetFromSet(encrypted_types); |
379 DCHECK(encrypted_types.count(syncable::PASSWORDS)); | 381 DCHECK(encrypted_types.count(syncable::PASSWORDS)); |
380 return (preferred_types_bitset & encrypted_types_bitset).any(); | 382 return (preferred_types_bitset & encrypted_types_bitset).any(); |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
679 } | 681 } |
680 | 682 |
681 VLOG(1) << "Passphrase required with reason: " | 683 VLOG(1) << "Passphrase required with reason: " |
682 << sync_api::PassphraseRequiredReasonToString(reason); | 684 << sync_api::PassphraseRequiredReasonToString(reason); |
683 passphrase_required_reason_ = reason; | 685 passphrase_required_reason_ = reason; |
684 | 686 |
685 // We will skip the passphrase prompt and suppress the warning if the | 687 // We will skip the passphrase prompt and suppress the warning if the |
686 // passphrase is needed for decryption but the user is not syncing an | 688 // passphrase is needed for decryption but the user is not syncing an |
687 // encrypted data type on this machine. Otherwise we look for one. | 689 // encrypted data type on this machine. Otherwise we look for one. |
688 if (!IsEncryptedDatatypeEnabled() && IsPassphraseRequiredForDecryption()) { | 690 if (!IsEncryptedDatatypeEnabled() && IsPassphraseRequiredForDecryption()) { |
689 VLOG(1) << "Not decrypting and no encrypted datatypes enabled" | 691 VLOG(1) << "Decrypting and no encrypted datatypes enabled" |
690 << ", accepted passphrase."; | 692 << ", accepted passphrase."; |
691 OnPassphraseAccepted(); | 693 OnPassphraseAccepted(); |
692 } | 694 } |
693 | 695 |
694 // First try supplying gaia password as the passphrase. | 696 // First try supplying gaia password as the passphrase. |
695 if (!gaia_password_.empty()) { | 697 if (!gaia_password_.empty()) { |
696 VLOG(1) << "Attempting gaia passphrase."; | 698 VLOG(1) << "Attempting gaia passphrase."; |
697 SetPassphrase(gaia_password_, false, true); | 699 std::string pass = gaia_password_; |
698 gaia_password_ = std::string(); | 700 gaia_password_ = std::string(); |
701 // May set gaia_password_ if the syncer isn't ready. | |
702 SetPassphrase(pass, false, true); | |
699 return; | 703 return; |
700 } | 704 } |
701 | 705 |
702 // If the above failed then try the custom passphrase the user might have | 706 // If the above failed then try the custom passphrase the user might have |
703 // entered in setup. | 707 // entered in setup. |
704 if (!cached_passphrase_.value.empty()) { | 708 if (!cached_passphrase_.value.empty()) { |
705 VLOG(1) << "Attempting cached passphrase."; | 709 VLOG(1) << "Attempting cached passphrase."; |
706 SetPassphrase(cached_passphrase_.value, | 710 std::string pass = cached_passphrase_.value; |
707 cached_passphrase_.is_explicit, | 711 bool is_explicit = cached_passphrase_.is_explicit; |
708 cached_passphrase_.is_creation); | 712 bool is_creation = cached_passphrase_.is_creation; |
709 cached_passphrase_ = CachedPassphrase(); | 713 cached_passphrase_ = CachedPassphrase(); |
714 // May set cached_passphrase_ is the syncer isn't ready. | |
715 SetPassphrase(pass, is_explicit, is_creation); | |
710 return; | 716 return; |
711 } | 717 } |
712 | 718 |
713 // Prompt the user for a password. | 719 // Prompt the user for a password. |
714 if (WizardIsVisible() && IsEncryptedDatatypeEnabled() && | 720 if (WizardIsVisible() && IsEncryptedDatatypeEnabled() && |
715 IsPassphraseRequiredForDecryption()) { | 721 IsPassphraseRequiredForDecryption()) { |
716 VLOG(1) << "Prompting user for passphrase."; | 722 VLOG(1) << "Prompting user for passphrase."; |
717 wizard_.Step(SyncSetupWizard::ENTER_PASSPHRASE); | 723 wizard_.Step(SyncSetupWizard::ENTER_PASSPHRASE); |
718 } | 724 } |
719 | 725 |
720 NotifyObservers(); | 726 NotifyObservers(); |
721 } | 727 } |
722 | 728 |
723 void ProfileSyncService::OnPassphraseAccepted() { | 729 void ProfileSyncService::OnPassphraseAccepted() { |
724 VLOG(1) << "Received OnPassphraseAccepted."; | 730 VLOG(1) << "Received OnPassphraseAccepted."; |
731 // Don't hold on to a passphrase in raw form longer than needed. | |
732 gaia_password_ = std::string(); | |
733 cached_passphrase_ = CachedPassphrase(); | |
734 | |
725 // Make sure the data types that depend on the passphrase are started at | 735 // Make sure the data types that depend on the passphrase are started at |
726 // this time. | 736 // this time. |
727 syncable::ModelTypeSet types; | 737 syncable::ModelTypeSet types; |
728 GetPreferredDataTypes(&types); | 738 GetPreferredDataTypes(&types); |
729 | 739 |
730 // Reset passphrase_required_reason_ before configuring the DataTypeManager | 740 // Reset passphrase_required_reason_ before configuring the DataTypeManager |
731 // since we know we no longer require the passphrase. | 741 // since we know we no longer require the passphrase. |
732 passphrase_required_reason_ = sync_api::REASON_PASSPHRASE_NOT_REQUIRED; | 742 passphrase_required_reason_ = sync_api::REASON_PASSPHRASE_NOT_REQUIRED; |
733 | 743 |
734 if (data_type_manager_.get()) { | 744 if (data_type_manager_.get()) { |
735 // Unblock the data type manager if necessary. | 745 // Unblock the data type manager if necessary. |
736 // This will always trigger a SYNC_CONFIGURE_DONE on completion, which will | 746 // This will always trigger a SYNC_CONFIGURE_DONE on completion, which will |
737 // step the UI wizard into DONE state (even if no datatypes have changed). | 747 // step the UI wizard into DONE state (even if no datatypes have changed). |
738 data_type_manager_->Configure(types, | 748 data_type_manager_->Configure(types, |
739 sync_api::CONFIGURE_REASON_RECONFIGURATION); | 749 sync_api::CONFIGURE_REASON_RECONFIGURATION); |
740 } | 750 } |
741 | 751 |
742 NotifyObservers(); | 752 NotifyObservers(); |
743 } | 753 } |
744 | 754 |
745 void ProfileSyncService::OnEncryptionComplete( | 755 void ProfileSyncService::OnEncryptionComplete( |
746 const syncable::ModelTypeSet& encrypted_types) { | 756 const syncable::ModelTypeSet& encrypted_types) { |
757 if (!pending_types_for_encryption_.empty()) { | |
758 // The user had chosen to encrypt datatypes. This is the last thing to | |
759 // complete, so now that we're done notify the UI. | |
760 wizard_.Step(SyncSetupWizard::DONE); | |
Nicolas Zea
2011/08/02 21:18:26
This works because encryption only occurs in the S
| |
761 } | |
762 pending_types_for_encryption_.clear(); | |
747 NotifyObservers(); | 763 NotifyObservers(); |
748 } | 764 } |
749 | 765 |
750 void ProfileSyncService::OnMigrationNeededForTypes( | 766 void ProfileSyncService::OnMigrationNeededForTypes( |
751 const syncable::ModelTypeSet& types) { | 767 const syncable::ModelTypeSet& types) { |
752 DCHECK(backend_initialized_); | 768 DCHECK(backend_initialized_); |
753 DCHECK(data_type_manager_.get()); | 769 DCHECK(data_type_manager_.get()); |
754 | 770 |
755 // Migrator must be valid, because we don't sync until it is created and this | 771 // Migrator must be valid, because we don't sync until it is created and this |
756 // callback originates from a sync cycle. | 772 // callback originates from a sync cycle. |
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1160 if (!backend_.get()) | 1176 if (!backend_.get()) |
1161 return; | 1177 return; |
1162 backend_->DeactivateDataType(data_type_controller, change_processor); | 1178 backend_->DeactivateDataType(data_type_controller, change_processor); |
1163 } | 1179 } |
1164 | 1180 |
1165 void ProfileSyncService::SetPassphrase(const std::string& passphrase, | 1181 void ProfileSyncService::SetPassphrase(const std::string& passphrase, |
1166 bool is_explicit, | 1182 bool is_explicit, |
1167 bool is_creation) { | 1183 bool is_creation) { |
1168 if (ShouldPushChanges() || IsPassphraseRequired()) { | 1184 if (ShouldPushChanges() || IsPassphraseRequired()) { |
1169 VLOG(1) << "Setting " << (is_explicit ? "explicit" : "implicit") | 1185 VLOG(1) << "Setting " << (is_explicit ? "explicit" : "implicit") |
1170 << " passphrase " << (is_creation ? " for creation" : ""); | 1186 << " passphrase" << (is_creation ? " for creation" : ""); |
1171 backend_->SetPassphrase(passphrase, is_explicit); | 1187 backend_->SetPassphrase(passphrase, is_explicit); |
1172 } else { | 1188 } else { |
1173 if (is_explicit) { | 1189 if (is_explicit) { |
1174 cached_passphrase_.value = passphrase; | 1190 cached_passphrase_.value = passphrase; |
1175 cached_passphrase_.is_explicit = is_explicit; | 1191 cached_passphrase_.is_explicit = is_explicit; |
1176 cached_passphrase_.is_creation = is_creation; | 1192 cached_passphrase_.is_creation = is_creation; |
1177 } else { | 1193 } else { |
1178 gaia_password_ = passphrase; | 1194 gaia_password_ = passphrase; |
1179 } | 1195 } |
1180 } | 1196 } |
1181 } | 1197 } |
1182 | 1198 |
1183 void ProfileSyncService::EncryptDataTypes( | 1199 void ProfileSyncService::EncryptDataTypes( |
1184 const syncable::ModelTypeSet& encrypted_types) { | 1200 const syncable::ModelTypeSet& encrypted_types) { |
1185 if (HasSyncSetupCompleted()) { | 1201 if (encrypted_types.empty()) { |
1186 backend_->EncryptDataTypes(encrypted_types); | 1202 // We can't unencrypt types. |
1203 VLOG(1) << "No datatypes set for encryption, dropping encryption request."; | |
1187 pending_types_for_encryption_.clear(); | 1204 pending_types_for_encryption_.clear(); |
Nicolas Zea
2011/08/02 21:18:26
This call will be combined with a configuredatatyp
| |
1188 } else { | 1205 return; |
1189 pending_types_for_encryption_ = encrypted_types; | |
1190 } | 1206 } |
1207 // We require that every call to EncryptDatatypes be coupled with a | |
1208 // ConfigureDataTypeManager. The actual call to encrypt the datatypes happens | |
1209 // after SYNC_CONFIGURE_DONE, to ensure we've downloaded any new datatypes | |
1210 // before beginning encryption. | |
1211 // TODO(zea): This is very brittle and relies on ConfigureDataTypes being | |
1212 // called after the encryptdatatypes in sync_setup_flow.cc. Fix this. | |
1213 pending_types_for_encryption_ = encrypted_types; | |
1191 } | 1214 } |
1192 | 1215 |
1193 // This would open a transaction to get the encrypted types. Do not call this | 1216 // This will open a transaction to get the encrypted types. Do not call this |
1194 // if you already have a transaction open. | 1217 // if you already have a transaction open. |
1195 void ProfileSyncService::GetEncryptedDataTypes( | 1218 void ProfileSyncService::GetEncryptedDataTypes( |
1196 syncable::ModelTypeSet* encrypted_types) const { | 1219 syncable::ModelTypeSet* encrypted_types) const { |
1197 CHECK(encrypted_types); | 1220 CHECK(encrypted_types); |
1198 if (backend_.get()) { | 1221 if (backend_.get()) { |
1199 *encrypted_types = backend_->GetEncryptedDataTypes(); | 1222 *encrypted_types = backend_->GetEncryptedDataTypes(); |
1200 DCHECK(encrypted_types->count(syncable::PASSWORDS)); | 1223 DCHECK(encrypted_types->count(syncable::PASSWORDS)); |
1201 } else { | 1224 } else { |
1202 // Either we are in an unrecoverable error or the sync is not yet done | 1225 // Either we are in an unrecoverable error or the sync is not yet done |
1203 // initializing. In either case just return the password type. During | 1226 // initializing. In either case just return the password type. During |
(...skipping 17 matching lines...) Expand all Loading... | |
1221 Details<DataTypeManager::ConfigureResult>(details).ptr(); | 1244 Details<DataTypeManager::ConfigureResult>(details).ptr(); |
1222 | 1245 |
1223 DataTypeManager::ConfigureStatus status = result->status; | 1246 DataTypeManager::ConfigureStatus status = result->status; |
1224 VLOG(1) << "PSS SYNC_CONFIGURE_DONE called with status: " << status; | 1247 VLOG(1) << "PSS SYNC_CONFIGURE_DONE called with status: " << status; |
1225 if (status == DataTypeManager::ABORTED && | 1248 if (status == DataTypeManager::ABORTED && |
1226 expect_sync_configuration_aborted_) { | 1249 expect_sync_configuration_aborted_) { |
1227 VLOG(0) << "ProfileSyncService::Observe Sync Configure aborted"; | 1250 VLOG(0) << "ProfileSyncService::Observe Sync Configure aborted"; |
1228 expect_sync_configuration_aborted_ = false; | 1251 expect_sync_configuration_aborted_ = false; |
1229 return; | 1252 return; |
1230 } | 1253 } |
1231 // Clear out the gaia password if it is already there. | |
1232 gaia_password_ = std::string(); | |
1233 if (status != DataTypeManager::OK) { | 1254 if (status != DataTypeManager::OK) { |
1234 VLOG(0) << "ProfileSyncService::Observe: Unrecoverable error detected"; | 1255 VLOG(0) << "ProfileSyncService::Observe: Unrecoverable error detected"; |
1235 std::string message = | 1256 std::string message = |
1236 "Sync Configuration failed while configuring " + | 1257 "Sync Configuration failed while configuring " + |
1237 syncable::ModelTypeSetToString(result->failed_types) + | 1258 syncable::ModelTypeSetToString(result->failed_types) + |
1238 ": " + DataTypeManager::ConfigureStatusToString(status); | 1259 ": " + DataTypeManager::ConfigureStatusToString(status); |
1239 OnUnrecoverableError(result->location, message); | 1260 OnUnrecoverableError(result->location, message); |
1240 cached_passphrase_ = CachedPassphrase(); | 1261 cached_passphrase_ = CachedPassphrase(); |
1241 return; | 1262 return; |
1242 } | 1263 } |
1243 | 1264 |
1244 // If the user had entered a custom passphrase use it now. | |
Nicolas Zea
2011/08/02 21:18:26
This all now happens in OnPassphraseRequired and O
| |
1245 if (!cached_passphrase_.value.empty()) { | |
1246 // Don't hold on to the passphrase in raw form longer than needed. | |
1247 SetPassphrase(cached_passphrase_.value, | |
1248 cached_passphrase_.is_explicit, | |
1249 cached_passphrase_.is_creation); | |
1250 cached_passphrase_ = CachedPassphrase(); | |
1251 } | |
1252 | |
1253 // We should never get in a state where we have no encrypted datatypes | 1265 // We should never get in a state where we have no encrypted datatypes |
1254 // enabled, and yet we still think we require a passphrase for decryption. | 1266 // enabled, and yet we still think we require a passphrase for decryption. |
1255 DCHECK(!(IsPassphraseRequiredForDecryption() && | 1267 DCHECK(!(IsPassphraseRequiredForDecryption() && |
1256 !IsEncryptedDatatypeEnabled())); | 1268 !IsEncryptedDatatypeEnabled())); |
1257 | 1269 |
1258 // TODO(sync): Less wizard, more toast. | 1270 if (!gaia_password_.empty()) { |
1259 wizard_.Step(SyncSetupWizard::DONE); | 1271 // If we haven't yet attempted to set the gaia passphrase use it now. |
1260 NotifyObservers(); | 1272 SetPassphrase(gaia_password_, false, true); |
1273 gaia_password_ = std::string(); | |
1274 } else if (!cached_passphrase_.value.empty()) { | |
1275 // If the user had entered a custom passphrase use it now. | |
1276 SetPassphrase(cached_passphrase_.value, | |
1277 cached_passphrase_.is_explicit, | |
1278 cached_passphrase_.is_creation); | |
1279 cached_passphrase_ = CachedPassphrase(); | |
1280 } | |
1281 | |
1261 | 1282 |
1262 // In the old world, this would be a no-op. With new syncer thread, | 1283 // In the old world, this would be a no-op. With new syncer thread, |
1263 // this is the point where it is safe to switch from config-mode to | 1284 // this is the point where it is safe to switch from config-mode to |
1264 // normal operation. | 1285 // normal operation. |
1265 backend_->StartSyncingWithServer(); | 1286 backend_->StartSyncingWithServer(); |
1266 | 1287 |
1267 if (!pending_types_for_encryption_.empty()) { | 1288 if (pending_types_for_encryption_.empty()) { |
1268 EncryptDataTypes(pending_types_for_encryption_); | 1289 // TODO(sync): Less wizard, more toast. |
1269 pending_types_for_encryption_.clear(); | 1290 wizard_.Step(SyncSetupWizard::DONE); |
1291 NotifyObservers(); | |
1292 } else { | |
1293 // Will clear pending_types_for_encryption_ on success. Has no effect | |
1294 // if pending_types_for_encryption_ matches the encrypted types. | |
1295 backend_->EncryptDataTypes(pending_types_for_encryption_); | |
1270 } | 1296 } |
1271 break; | 1297 break; |
1272 } | 1298 } |
1273 case chrome::NOTIFICATION_PREF_CHANGED: { | 1299 case chrome::NOTIFICATION_PREF_CHANGED: { |
1274 std::string* pref_name = Details<std::string>(details).ptr(); | 1300 std::string* pref_name = Details<std::string>(details).ptr(); |
1275 if (*pref_name == prefs::kSyncManaged) { | 1301 if (*pref_name == prefs::kSyncManaged) { |
1276 NotifyObservers(); | 1302 NotifyObservers(); |
1277 if (*pref_sync_managed_) { | 1303 if (*pref_sync_managed_) { |
1278 DisableForUser(); | 1304 DisableForUser(); |
1279 } else if (HasSyncSetupCompleted() && AreCredentialsAvailable()) { | 1305 } else if (HasSyncSetupCompleted() && AreCredentialsAvailable()) { |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1369 // is initialized, all enabled data types are consistent with one | 1395 // is initialized, all enabled data types are consistent with one |
1370 // another, and no unrecoverable error has transpired. | 1396 // another, and no unrecoverable error has transpired. |
1371 if (unrecoverable_error_detected_) | 1397 if (unrecoverable_error_detected_) |
1372 return false; | 1398 return false; |
1373 | 1399 |
1374 if (!data_type_manager_.get()) | 1400 if (!data_type_manager_.get()) |
1375 return false; | 1401 return false; |
1376 | 1402 |
1377 return data_type_manager_->state() == DataTypeManager::CONFIGURED; | 1403 return data_type_manager_->state() == DataTypeManager::CONFIGURED; |
1378 } | 1404 } |
OLD | NEW |