PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/toolkit/components/url-classifier/tests/unit/test_streamupdater.js

http://github.com/zpao/v8monkey
JavaScript | 461 lines | 339 code | 96 blank | 26 comment | 5 complexity | 1e55bf99bb4dd4d7c5fa53b45e1d892b MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-3.0, AGPL-1.0, LGPL-2.1, BSD-3-Clause, GPL-2.0, JSON, Apache-2.0, 0BSD
  1. var gClientKeyRaw="TESTCLIENTKEY";
  2. // no btoa() available in xpcshell, precalculated for TESTCLIENTKEY.
  3. var gClientKey = "VEVTVENMSUVOVEtFWQ==";
  4. function MAC(content, clientKey)
  5. {
  6. var hmac = Cc["@mozilla.org/security/hmac;1"].createInstance(Ci.nsICryptoHMAC);
  7. var converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
  8. createInstance(Ci.nsIScriptableUnicodeConverter);
  9. converter.charset = "UTF-8";
  10. var keyObject = Cc["@mozilla.org/security/keyobjectfactory;1"]
  11. .getService(Ci.nsIKeyObjectFactory).keyFromString(Ci.nsIKeyObject.HMAC, clientKey);
  12. hmac.init(Ci.nsICryptoHMAC.SHA1, keyObject);
  13. var data = converter.convertToByteArray(content);
  14. hmac.update(data, data.length);
  15. return hmac.finish(true);
  16. }
  17. function doTest(updates, assertions, expectError, clientKey)
  18. {
  19. if (expectError) {
  20. doUpdateTest(updates, assertions, updateError, runNextTest, clientKey);
  21. } else {
  22. doUpdateTest(updates, assertions, runNextTest, updateError, clientKey);
  23. }
  24. }
  25. function testFillDb() {
  26. var add1Urls = [ "zaz.com/a", "yxz.com/c" ];
  27. var update = "n:1000\n";
  28. update += "i:test-phish-simple\n";
  29. var update1 = buildBareUpdate(
  30. [{ "chunkNum" : 1,
  31. "urls" : add1Urls }]);
  32. update += "u:data:," + encodeURIComponent(update1) + "\n";
  33. var assertions = {
  34. "tableData" : "test-phish-simple;a:1",
  35. "urlsExist" : add1Urls
  36. };
  37. doTest([update], assertions, false);
  38. }
  39. function testSimpleForward() {
  40. var add1Urls = [ "foo.com/a", "bar.com/c" ];
  41. var add2Urls = [ "foo.com/b" ];
  42. var add3Urls = [ "bar.com/d" ];
  43. var update = "n:1000\n";
  44. update += "i:test-phish-simple\n";
  45. var update1 = buildBareUpdate(
  46. [{ "chunkNum" : 1,
  47. "urls" : add1Urls }]);
  48. update += "u:data:," + encodeURIComponent(update1) + "\n";
  49. var update2 = buildBareUpdate(
  50. [{ "chunkNum" : 2,
  51. "urls" : add2Urls }]);
  52. update += "u:data:," + encodeURIComponent(update2) + "\n";
  53. var update3 = buildBareUpdate(
  54. [{ "chunkNum" : 3,
  55. "urls" : add3Urls }]);
  56. update += "u:data:," + encodeURIComponent(update3) + "\n";
  57. var assertions = {
  58. "tableData" : "test-phish-simple;a:1-3",
  59. "urlsExist" : add1Urls.concat(add2Urls).concat(add3Urls)
  60. };
  61. doTest([update], assertions, false);
  62. }
  63. // Make sure that a nested forward (a forward within a forward) causes
  64. // the update to fail.
  65. function testNestedForward() {
  66. var add1Urls = [ "foo.com/a", "bar.com/c" ];
  67. var add2Urls = [ "foo.com/b" ];
  68. var update = "n:1000\n";
  69. update += "i:test-phish-simple\n";
  70. var update1 = buildBareUpdate(
  71. [{ "chunkNum" : 1,
  72. "urls" : add1Urls }]);
  73. update += "u:data:," + encodeURIComponent(update1) + "\n";
  74. var update2 = buildBareUpdate(
  75. [{ "chunkNum" : 2 }]);
  76. var update3 = buildBareUpdate(
  77. [{ "chunkNum" : 3,
  78. "urls" : add1Urls }]);
  79. update2 += "u:data:," + encodeURIComponent(update3) + "\n";
  80. update += "u:data:," + encodeURIComponent(update2) + "\n";
  81. var assertions = {
  82. "tableData" : "",
  83. "urlsDontExist" : add1Urls.concat(add2Urls)
  84. };
  85. doTest([update], assertions, true);
  86. }
  87. // An invalid URL forward causes the update to fail.
  88. function testInvalidUrlForward() {
  89. var add1Urls = [ "foo.com/a", "bar.com/c" ];
  90. var update = buildPhishingUpdate(
  91. [{ "chunkNum" : 1,
  92. "urls" : add1Urls }]);
  93. update += "u:asdf://blah/blah\n"; // invalid URL scheme
  94. // The first part of the update should have succeeded.
  95. var assertions = {
  96. "tableData" : "test-phish-simple;a:1",
  97. "urlsExist" : add1Urls
  98. };
  99. doTest([update], assertions, false);
  100. }
  101. // A failed network request causes the update to fail.
  102. function testErrorUrlForward() {
  103. var add1Urls = [ "foo.com/a", "bar.com/c" ];
  104. var update = buildPhishingUpdate(
  105. [{ "chunkNum" : 1,
  106. "urls" : add1Urls }]);
  107. update += "u:http://test.invalid/asdf/asdf\n"; // invalid URL scheme
  108. // The first part of the update should have succeeded
  109. var assertions = {
  110. "tableData" : "test-phish-simple;a:1",
  111. "urlsExist" : add1Urls
  112. };
  113. doTest([update], assertions, false);
  114. }
  115. function testMultipleTables() {
  116. var add1Urls = [ "foo.com/a", "bar.com/c" ];
  117. var add2Urls = [ "foo.com/b" ];
  118. var add3Urls = [ "bar.com/d" ];
  119. var update = "n:1000\n";
  120. update += "i:test-phish-simple\n";
  121. var update1 = buildBareUpdate(
  122. [{ "chunkNum" : 1,
  123. "urls" : add1Urls }]);
  124. update += "u:data:," + encodeURIComponent(update1) + "\n";
  125. var update2 = buildBareUpdate(
  126. [{ "chunkNum" : 2,
  127. "urls" : add2Urls }]);
  128. update += "u:data:," + encodeURIComponent(update2) + "\n";
  129. update += "i:test-malware-simple\n";
  130. var update3 = buildBareUpdate(
  131. [{ "chunkNum" : 3,
  132. "urls" : add3Urls }]);
  133. update += "u:data:," + encodeURIComponent(update3) + "\n";
  134. var assertions = {
  135. "tableData" : "test-malware-simple;a:3\ntest-phish-simple;a:1-2",
  136. "urlsExist" : add1Urls.concat(add2Urls),
  137. "malwareUrlsExist" : add3Urls
  138. };
  139. doTest([update], assertions, false);
  140. }
  141. // Test a simple update with a valid message authentication code.
  142. function testValidMAC() {
  143. var addUrls = [ "foo.com/a", "foo.com/b", "bar.com/c" ];
  144. var update = buildPhishingUpdate(
  145. [
  146. { "chunkNum" : 1,
  147. "urls" : addUrls
  148. }]);
  149. update = "m:" + MAC(update, gClientKeyRaw) + "\n" + update;
  150. var assertions = {
  151. "tableData" : "test-phish-simple;a:1",
  152. "urlsExist" : addUrls
  153. };
  154. doTest([update], assertions, false, gClientKey);
  155. }
  156. // Test a simple update with an invalid message authentication code.
  157. function testInvalidMAC() {
  158. var addUrls = [ "foo.com/a", "foo.com/b", "bar.com/c" ];
  159. var update = buildPhishingUpdate(
  160. [
  161. { "chunkNum" : 1,
  162. "urls" : addUrls
  163. }]);
  164. update = "m:INVALIDMAC\n" + update;
  165. var assertions = {
  166. "tableData" : "",
  167. "urlsDontExist" : addUrls
  168. };
  169. doTest([update], assertions, true, gClientKey);
  170. }
  171. // Test a simple update without a message authentication code, when it is
  172. // expecting one.
  173. function testNoMAC() {
  174. var addUrls = [ "foo.com/a", "foo.com/b", "bar.com/c" ];
  175. var update = buildPhishingUpdate(
  176. [
  177. { "chunkNum" : 1,
  178. "urls" : addUrls
  179. }]);
  180. var assertions = {
  181. "tableData" : "",
  182. "urlsDontExist" : addUrls
  183. };
  184. doTest([update], assertions, true, gClientKey);
  185. }
  186. // Test an update with a valid message authentication code, with forwards.
  187. function testValidForwardMAC() {
  188. var add1Urls = [ "foo.com/a", "bar.com/c" ];
  189. var add2Urls = [ "foo.com/b" ];
  190. var add3Urls = [ "bar.com/d" ];
  191. var update = "n:1000\n";
  192. update += "i:test-phish-simple\n";
  193. var update1 = buildBareUpdate(
  194. [{ "chunkNum" : 1,
  195. "urls" : add1Urls }]);
  196. update += "u:data:," + encodeURIComponent(update1) +
  197. "," + MAC(update1, gClientKeyRaw) + "\n";
  198. var update2 = buildBareUpdate(
  199. [{ "chunkNum" : 2,
  200. "urls" : add2Urls }]);
  201. update += "u:data:," + encodeURIComponent(update2) +
  202. "," + MAC(update2, gClientKeyRaw) + "\n";
  203. var update3 = buildBareUpdate(
  204. [{ "chunkNum" : 3,
  205. "urls" : add3Urls }]);
  206. update += "u:data:," + encodeURIComponent(update3) +
  207. "," + MAC(update3, gClientKeyRaw) + "\n";
  208. var assertions = {
  209. "tableData" : "test-phish-simple;a:1-3",
  210. "urlsExist" : add1Urls.concat(add2Urls).concat(add3Urls)
  211. };
  212. update = "m:" + MAC(update, gClientKeyRaw) + "\n" + update;
  213. doTest([update], assertions, false, gClientKey);
  214. }
  215. // Test an update with a valid message authentication code, but with
  216. // invalid MACs on the forwards.
  217. function testInvalidForwardMAC() {
  218. var add1Urls = [ "foo.com/a", "bar.com/c" ];
  219. var add2Urls = [ "foo.com/b" ];
  220. var add3Urls = [ "bar.com/d" ];
  221. var update = "n:1000\n";
  222. update += "i:test-phish-simple\n";
  223. var update1 = buildBareUpdate(
  224. [{ "chunkNum" : 1,
  225. "urls" : add1Urls }]);
  226. update += "u:data:," + encodeURIComponent(update1) +
  227. ",BADMAC\n";
  228. var update2 = buildBareUpdate(
  229. [{ "chunkNum" : 2,
  230. "urls" : add2Urls }]);
  231. update += "u:data:," + encodeURIComponent(update2) +
  232. ",BADMAC\n";
  233. var update3 = buildBareUpdate(
  234. [{ "chunkNum" : 3,
  235. "urls" : add3Urls }]);
  236. update += "u:data:," + encodeURIComponent(update3) +
  237. ",BADMAC\n";
  238. var assertions = {
  239. "tableData" : "",
  240. "urlsDontExist" : add1Urls.concat(add2Urls).concat(add3Urls)
  241. };
  242. update = "m:" + MAC(update, gClientKeyRaw) + "\n" + update;
  243. doTest([update], assertions, true, gClientKey);
  244. }
  245. // Test an update with a valid message authentication code, but no MAC
  246. // specified for sub-urls.
  247. function testNoForwardMAC() {
  248. var add1Urls = [ "foo.com/a", "bar.com/c" ];
  249. var add2Urls = [ "foo.com/b" ];
  250. var add3Urls = [ "bar.com/d" ];
  251. var update = "n:1000\n";
  252. update += "i:test-phish-simple\n";
  253. // XXX : This test presents invalid data: urls as forwards. A valid
  254. // data url requires a comma, which the code will interpret as the
  255. // separator for a MAC.
  256. // Unfortunately this means that the update will fail even if the code
  257. // isn't properly detecting a missing MAC update. I'm not sure how to
  258. // test that :/
  259. var update1 = buildBareUpdate(
  260. [{ "chunkNum" : 1,
  261. "urls" : add1Urls }]);
  262. update += "u:data:" + encodeURIComponent(update1) + "\n";
  263. var update2 = buildBareUpdate(
  264. [{ "chunkNum" : 2,
  265. "urls" : add2Urls }]);
  266. update += "u:data:" + encodeURIComponent(update2) + "\n";
  267. var update3 = buildBareUpdate(
  268. [{ "chunkNum" : 3,
  269. "urls" : add3Urls }]);
  270. update += "u:data:" + encodeURIComponent(update3) + "\n";
  271. var assertions = {
  272. "tableData" : "",
  273. "urlsDontExist" : add1Urls.concat(add2Urls).concat(add3Urls)
  274. };
  275. update = "m:" + MAC(update, gClientKeyRaw) + "\n" + update;
  276. doTest([update], assertions, true, gClientKey);
  277. }
  278. function Observer(callback) {
  279. this.observe = callback;
  280. }
  281. Observer.prototype =
  282. {
  283. QueryInterface: function(iid)
  284. {
  285. if (!iid.equals(Ci.nsISupports) &&
  286. !iid.equals(Ci.nsIObserver)) {
  287. throw Cr.NS_ERROR_NO_INTERFACE;
  288. }
  289. return this;
  290. }
  291. };
  292. var gGotRekey;
  293. gAssertions.gotRekey = function(data, cb)
  294. {
  295. do_check_eq(gGotRekey, data);
  296. cb();
  297. }
  298. // Tests a rekey request.
  299. function testRekey() {
  300. var addUrls = [ "foo.com/a", "foo.com/b", "bar.com/c" ];
  301. var update = buildPhishingUpdate(
  302. [
  303. { "chunkNum" : 1,
  304. "urls" : addUrls
  305. }]);
  306. update = "e:pleaserekey\n" + update;
  307. var assertions = {
  308. "tableData" : "",
  309. "urlsDontExist" : addUrls,
  310. "gotRekey" : true
  311. };
  312. gGotRekey = false;
  313. var observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
  314. observerService.addObserver(new Observer(function(subject, topic, data) {
  315. if (topic == "url-classifier-rekey-requested") {
  316. gGotRekey = true;
  317. }
  318. }),
  319. "url-classifier-rekey-requested",
  320. false);
  321. doTest([update], assertions, true, gClientKey);
  322. }
  323. // Tests a database reset request.
  324. function testReset() {
  325. var addUrls1 = [ "foo.com/a", "foo.com/b" ];
  326. var update1 = buildPhishingUpdate(
  327. [
  328. { "chunkNum" : 1,
  329. "urls" : addUrls1
  330. }]);
  331. var update2 = "n:1000\nr:pleasereset\n";
  332. var addUrls3 = [ "bar.com/a", "bar.com/b" ];
  333. var update3 = buildPhishingUpdate(
  334. [
  335. { "chunkNum" : 3,
  336. "urls" : addUrls3
  337. }]);
  338. var assertions = {
  339. "tableData" : "test-phish-simple;a:3",
  340. "urlsExist" : addUrls3,
  341. "urlsDontExist" : addUrls1
  342. };
  343. doTest([update1, update2, update3], assertions, false);
  344. }
  345. function run_test()
  346. {
  347. runTests([
  348. testSimpleForward,
  349. testNestedForward,
  350. testInvalidUrlForward,
  351. testErrorUrlForward,
  352. testMultipleTables,
  353. testReset,
  354. // XXX: we're currently "once MAC, always MAC",
  355. // so any test not using a MAC must go above
  356. testValidMAC,
  357. testInvalidMAC,
  358. testNoMAC,
  359. testValidForwardMAC,
  360. testInvalidForwardMAC,
  361. testNoForwardMAC,
  362. testRekey,
  363. ]);
  364. }
  365. do_test_pending();