From 2256714107042adb6e2cf1b0cb9b055b8aeb289f Mon Sep 17 00:00:00 2001 From: Edward Lee Date: Mon, 14 Jun 2010 15:16:53 -0700 Subject: [PATCH] Bug 568677 - Failure to get CryptoMeta assumes it's missing [r=mconnor] Explicitly check the status code to make sure we stop syncing on non-404 crypto meta failures. Add tests to check correct behavior of 404 and non-404 errors during syncStartup. --- services/sync/modules/constants.js | 1 + services/sync/modules/engines.js | 6 ++ .../sync/tests/unit/test_syncengine_sync.js | 88 +++++++++++++++++++ 3 files changed, 95 insertions(+) diff --git a/services/sync/modules/constants.js b/services/sync/modules/constants.js index b1e446d1dae..127795669d3 100644 --- a/services/sync/modules/constants.js +++ b/services/sync/modules/constants.js @@ -121,6 +121,7 @@ NO_SYNC_NODE_FOUND: "error.sync.reason.no_node_found", ENGINE_UPLOAD_FAIL: "error.engine.reason.record_upload_fail", ENGINE_DOWNLOAD_FAIL: "error.engine.reason.record_download_fail", ENGINE_UNKNOWN_FAIL: "error.engine.reason.unknown_fail", +ENGINE_METARECORD_DOWNLOAD_FAIL: "error.engine.reason.metarecord_download_fail", ENGINE_METARECORD_UPLOAD_FAIL: "error.engine.reason.metarecord_upload_fail", // Ways that a sync can be disabled (messages only to be printed in debug log) diff --git a/services/sync/modules/engines.js b/services/sync/modules/engines.js index 201ee73c5df..e8f7bef0337 100644 --- a/services/sync/modules/engines.js +++ b/services/sync/modules/engines.js @@ -363,6 +363,12 @@ SyncEngine.prototype = { meta = null; } } + // Don't proceed if we failed to get the crypto meta for reasons not 404 + else if (CryptoMetas.response.status != 404) { + let resp = CryptoMetas.response; + resp.failureCode = ENGINE_METARECORD_DOWNLOAD_FAIL; + throw resp; + } // Determine if we need to wipe on outdated versions let metaGlobal = Records.get(this.metaURL); diff --git a/services/sync/tests/unit/test_syncengine_sync.js b/services/sync/tests/unit/test_syncengine_sync.js index 342f4711977..b2414ff2a63 100644 --- a/services/sync/tests/unit/test_syncengine_sync.js +++ b/services/sync/tests/unit/test_syncengine_sync.js @@ -230,6 +230,94 @@ function test_syncStartup_emptyOrOutdatedGlobalsResetsSync() { } } +function test_syncStartup_metaGet404() { + _("SyncEngine._syncStartup resets sync and wipes server data if the symmetric key is missing 404"); + + Svc.Prefs.set("clusterURL", "http://localhost:8080/"); + + // A symmetric key with an incorrect HMAC + let crypto_steam = new ServerWBO("steam"); + + // A proper global record with matching version and syncID + let engine = makeSteamEngine(); + let global = new ServerWBO("global", + {engines: {steam: {version: engine.version, + syncID: engine.syncID}}}); + + // Some server side data that's going to be wiped + let collection = new ServerCollection(); + collection.wbos.flying = new ServerWBO( + "flying", encryptPayload({id: "flying", + denomination: "LNER Class A3 4472"})); + collection.wbos.scotsman = new ServerWBO( + "scotsman", encryptPayload({id: "scotsman", + denomination: "Flying Scotsman"})); + + let server = sync_httpd_setup({ + "/1.0/foo/storage/crypto/steam": crypto_steam.handler(), + "/1.0/foo/storage/steam": collection.handler() + }); + createAndUploadKeypair(); + + try { + + _("Confirm initial environment"); + do_check_false(!!crypto_steam.payload); + do_check_true(!!collection.wbos.flying.payload); + do_check_true(!!collection.wbos.scotsman.payload); + + engine.lastSync = Date.now() / 1000; + engine._syncStartup(); + + _("Sync was reset and server data was wiped"); + do_check_eq(engine.lastSync, 0); + do_check_eq(collection.wbos.flying.payload, undefined); + do_check_eq(collection.wbos.scotsman.payload, undefined); + + _("New bulk key was uploaded"); + key = crypto_steam.data.keyring["http://localhost:8080/1.0/foo/storage/keys/pubkey"]; + do_check_eq(key.wrapped, "fake-symmetric-key-0"); + do_check_eq(key.hmac, "fake-symmetric-key-0 "); + + } finally { + server.stop(function() {}); + Svc.Prefs.resetBranch(""); + Records.clearCache(); + CryptoMetas.clearCache(); + syncTesting = new SyncTestingInfrastructure(makeSteamEngine); + } +} + +function test_syncStartup_failedMetaGet() { + _("SyncEngine._syncStartup non-404 failures for getting cryptometa should stop sync"); + + Svc.Prefs.set("clusterURL", "http://localhost:8080/"); + let server = httpd_setup({ + "/1.0/foo/storage/crypto/steam": function(request, response) { + response.setStatusLine(request.httpVersion, 405, "Method Not Allowed"); + response.bodyOutputStream.write("Fail!", 5); + } + }); + + let engine = makeSteamEngine(); + try { + + _("Getting the cryptometa will fail and should set the appropriate failure"); + let error; + try { + engine._syncStartup(); + } catch (ex) { + error = ex; + } + do_check_eq(error.failureCode, ENGINE_METARECORD_DOWNLOAD_FAIL); + + } finally { + server.stop(function() {}); + Svc.Prefs.resetBranch(""); + Records.clearCache(); + syncTesting = new SyncTestingInfrastructure(makeSteamEngine); + } +} function test_syncStartup_serverHasNewerVersion() { _("SyncEngine._syncStartup ");