From 25c8d16bf56d20d78de4fe2b59c01ca51aaf0fc3 Mon Sep 17 00:00:00 2001 From: yflory Date: Tue, 13 Sep 2016 17:43:56 +0200 Subject: [PATCH] Use a new version-prefixed hash parser --- www/code/main.js | 19 ++++++----- www/common/cryptpad-common.js | 60 ++++++++++++++++++++++++++++++++--- www/pad/main.js | 21 ++++++------ www/poll/main.js | 40 ++++++++++++----------- www/slide/main.js | 7 ++-- 5 files changed, 104 insertions(+), 43 deletions(-) diff --git a/www/code/main.js b/www/code/main.js index 554215681..764ff6698 100644 --- a/www/code/main.js +++ b/www/code/main.js @@ -25,6 +25,8 @@ define([ spinner: Cryptpad.spinner(document.body), }; + Cryptpad.styleAlerts(); + module.spinner.show(); var ifrw = module.ifrw = $('#pad-iframe')[0].contentWindow; @@ -240,12 +242,13 @@ define([ }; var suggestName = function () { - var hash = window.location.hash.slice(1, 9); + var parsed = Cryptpad.parsePadUrl(window.location.href); + var name = Cryptpad.getDefaultName(parsed, []); - if (document.title === hash) { - return getHeadingText() || hash; + if (document.title.slice(0, name.length) === name) { + return getHeadingText() || document.title; } else { - return document.title || getHeadingText() || hash; + return document.title || getHeadingText() || name; } }; @@ -375,7 +378,8 @@ define([ console.error(err); return; } - document.title = window.location.hash.slice(1,9); + var parsed = Cryptpad.parsePadUrl(href); + document.title = Cryptpad.getDefaultName(parsed, []); }); }); }); @@ -439,14 +443,14 @@ define([ configureTheme(); }); - window.location.hash = info.channel + secret.key; + window.location.hash = Cryptpad.getHashFromKeys(info.channel, secret.key); Cryptpad.getPadTitle(function (err, title) { if (err) { console.log("Unable to get pad title"); console.error(err); return; } - document.title = title || window.location.hash.slice(1,9); + document.title = title || info.channel.slice(0, 8); Cryptpad.rememberPad(title, function (err, data) { if (err) { console.log("Unable to set pad title"); @@ -622,7 +626,6 @@ define([ Cryptpad.alert(Messages.disconnectAlert); }; - Cryptpad.styleAlerts(); var realtime = module.realtime = Realtime.start(config); editor.on('change', onLocal); diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index e635223c1..1e1a67069 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -100,7 +100,7 @@ define([ // don't do anything funny unless you're on a cryptpad subdomain if (!/cryptpad.fr$/i.test(hostname)) { return; } - if (hash.length >= 56) { + if (hash.length >= 25) { // you're on the right domain return; } @@ -116,15 +116,67 @@ define([ window.location.hostname = 'old.cryptpad.fr'; }; + var hexToBase64 = common.hexToBase64 = function (hex) { + var hexArray = hex + .replace(/\r|\n/g, "") + .replace(/([\da-fA-F]{2}) ?/g, "0x$1 ") + .replace(/ +$/, "") + .split(" "); + var byteString = String.fromCharCode.apply(null, hexArray); + return window.btoa(byteString).replace(/\//g, '-').slice(0,-2); + }; + + var base64ToHex = common.base64ToHex = function (b64String) { + var hexArray = []; + atob(b64String.replace(/-/g, '/') + "==").split("").forEach(function(e){ + var h = e.charCodeAt(0).toString(16); + if (h.length === 1) { h = "0"+h; } + hexArray.push(h); + }); + return hexArray.join(""); + }; + + var getHashFromKeys = common.getHashFromKeys = function (chanKey, cryptKey) { + return '/1/' + hexToBase64(chanKey) + '/' + cryptKey.replace(/\//g, '-'); + }; + var getSecrets = common.getSecrets = function () { var secret = {}; if (!/#/.test(window.location.href)) { secret.key = Crypto.genKey(); } else { var hash = window.location.hash.slice(1); + if (hash.length === 0) { + secret.key = Crypto.genKey(); + return secret; + } common.redirect(hash); - secret.channel = hash.slice(0, 32); - secret.key = hash.slice(32); + // old hash system : #{hexChanKey}{cryptKey} + // new hash system : #/{hashVersion}/{b64ChanKey}/{cryptKey} + if (hash.slice(0,1) !== '/' && hash.length >= 56) { + // Old hash + secret.channel = hash.slice(0, 32); + secret.key = hash.slice(32); + } + else { + // New hash + var hashArray = hash.split('/'); + if (hashArray.length < 4) { + common.alert("Unable to parse the key"); + throw new Error("Unable to parse the key"); + } + var version = hashArray[1]; + if (version === "1") { + secret.channel = base64ToHex(hashArray[2]); + secret.key = hashArray[3].replace(/-/g, '/'); //TODO replace / by - + if (secret.channel.length !== 32 || secret.key.length !== 24) { + common.alert("The channel key and/or the encryption key is invalid"); + console.log("Channel key length : " + secret.channel.length + " != 32"); + console.log("Encryption key length : " + secret.key.length + " != 24"); + throw new Error("The channel key and/or the encryption key is invalid"); + } + } + } } return secret; }; @@ -203,7 +255,7 @@ define([ }; // Create untitled documents when no name is given - var getDefaultName = function (parsed, recentPads) { + var getDefaultName = common.getDefaultName = function (parsed, recentPads) { var type = parsed.type; var untitledIndex = 1; var name = (Messages.type)[type] + ' - ' + new Date().toString().split(' ').slice(0,4).join(' '); diff --git a/www/pad/main.js b/www/pad/main.js index c2f62b91f..fac663e51 100644 --- a/www/pad/main.js +++ b/www/pad/main.js @@ -21,13 +21,14 @@ define([ ], function (Config, Messages, Crypto, realtimeInput, Hyperjson, Toolbar, Cursor, JsonOT, TypingTest, JSONSortify, TextPatcher, Cryptpad, Visible, Notify) { - var $ = window.jQuery; var saveAs = window.saveAs; var ifrw = $('#pad-iframe')[0].contentWindow; var Ckeditor; // to be initialized later... var DiffDom = window.diffDOM; + Cryptpad.styleAlerts(); + var stringify = function (obj) { return JSONSortify(obj); }; @@ -439,12 +440,13 @@ define([ }; var suggestName = module.suggestName = function () { - var hash = window.location.hash.slice(1, 9); + var parsed = Cryptpad.parsePadUrl(window.location.href); + var name = Cryptpad.getDefaultName(parsed, []); - if (document.title === hash) { - return getHeadingText() || hash; + if (document.title.slice(0, name.length) === name) { + return getHeadingText() || document.title; } else { - return document.title || getHeadingText() || hash; + return document.title || getHeadingText() || name; } }; @@ -535,14 +537,15 @@ define([ Cryptpad.confirm(Messages.forgetPrompt, function (yes) { if (!yes) { return; } Cryptpad.forgetPad(href, function (err, data) { - document.title = window.location.hash.slice(1,9); + var parsed = Cryptpad.parsePadUrl(href); + document.title = Cryptpad.getDefaultName(parsed, []); }); }); }); $rightside.append($forgetPad); // set the hash - window.location.hash = info.channel + secret.key; + window.location.hash = Cryptpad.getHashFromKeys(info.channel, secret.key); Cryptpad.getPadTitle(function (err, title) { if (err) { @@ -550,7 +553,7 @@ define([ console.log("Couldn't get pad title"); return; } - document.title = title || window.location.hash.slice(1, 9); + document.title = title || info.channel.slice(0, 8); Cryptpad.rememberPad(title, function (err, data) { if (err) { console.log("Couldn't remember pad"); @@ -558,8 +561,6 @@ define([ } }); }); - - Cryptpad.styleAlerts(); }; // this should only ever get called once, when the chain syncs diff --git a/www/poll/main.js b/www/poll/main.js index 9ae642e13..9636beb4a 100644 --- a/www/poll/main.js +++ b/www/poll/main.js @@ -649,17 +649,6 @@ define([ setEditable(false); }); - Cryptpad.getPadTitle(function (err, title) { - title = document.title = title || window.location.hash.slice(1, 9); - - Cryptpad.rememberPad(title, function (err, data) { - if (err) { - console.log("unable to remember pad"); - console.log(err); - return; - } - }); - }); var $toolbar = $('#toolbar'); @@ -669,12 +658,15 @@ define([ return $('