Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | # This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. |
michael@0 | 4 | |
michael@0 | 5 | import os, sys |
michael@0 | 6 | import base64 |
michael@0 | 7 | import simplejson as json |
michael@0 | 8 | |
michael@0 | 9 | def create_jid(): |
michael@0 | 10 | """Return 'jid1-XYZ', where 'XYZ' is a randomly-generated string. (in the |
michael@0 | 11 | previous jid0- series, the string securely identified a specific public |
michael@0 | 12 | key). To get a suitable add-on ID, append '@jetpack' to this string. |
michael@0 | 13 | """ |
michael@0 | 14 | # per https://developer.mozilla.org/en/Install_Manifests#id all XPI id |
michael@0 | 15 | # values must either be in the form of a 128-bit GUID (crazy braces |
michael@0 | 16 | # and all) or in the form of an email address (crazy @ and all). |
michael@0 | 17 | # Firefox will refuse to install an add-on with an id that doesn't |
michael@0 | 18 | # match one of these forms. The actual regexp is at: |
michael@0 | 19 | # http://mxr.mozilla.org/mozilla-central/source/toolkit/mozapps/extensions/internal/XPIProvider.jsm#130 |
michael@0 | 20 | # So the JID needs an @-suffix, and the only legal punctuation is |
michael@0 | 21 | # "-._". So we start with a base64 encoding, and replace the |
michael@0 | 22 | # punctuation (+/) with letters (AB), losing a few bits of integrity. |
michael@0 | 23 | |
michael@0 | 24 | # even better: windows has a maximum path length limitation of 256 |
michael@0 | 25 | # characters: |
michael@0 | 26 | # http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx |
michael@0 | 27 | # (unless all paths are prefixed with "\\?\", I kid you not). The |
michael@0 | 28 | # typical install will put add-on code in a directory like: |
michael@0 | 29 | # C:\Documents and Settings\<username>\Application Data\Mozilla\Firefox\Profiles\232353483.default\extensions\$JID\... |
michael@0 | 30 | # (which is 108 chars long without the $JID). |
michael@0 | 31 | # Then the unpacked XPI contains packaged resources like: |
michael@0 | 32 | # resources/$JID-api-utils-lib/main.js (35 chars plus the $JID) |
michael@0 | 33 | # |
michael@0 | 34 | # We create a random 80 bit string, base64 encode that (with |
michael@0 | 35 | # AB instead of +/ to be path-safe), then bundle it into |
michael@0 | 36 | # "jid1-XYZ@jetpack". This gives us 27 characters. The resulting |
michael@0 | 37 | # main.js will have a path length of 211 characters, leaving us 45 |
michael@0 | 38 | # characters of margin. |
michael@0 | 39 | # |
michael@0 | 40 | # 80 bits is enough to generate one billion JIDs and still maintain lower |
michael@0 | 41 | # than a one-in-a-million chance of accidental collision. (1e9 JIDs is 30 |
michael@0 | 42 | # bits, square for the "birthday-paradox" to get 60 bits, add 20 bits for |
michael@0 | 43 | # the one-in-a-million margin to get 80 bits) |
michael@0 | 44 | |
michael@0 | 45 | # if length were no issue, we'd prefer to use this: |
michael@0 | 46 | h = os.urandom(80/8) |
michael@0 | 47 | s = base64.b64encode(h, "AB").strip("=") |
michael@0 | 48 | jid = "jid1-" + s |
michael@0 | 49 | return jid |
michael@0 | 50 | |
michael@0 | 51 | def preflight_config(target_cfg, filename, stderr=sys.stderr): |
michael@0 | 52 | modified = False |
michael@0 | 53 | config = json.load(open(filename, 'r')) |
michael@0 | 54 | |
michael@0 | 55 | if "id" not in config: |
michael@0 | 56 | print >>stderr, ("No 'id' in package.json: creating a new ID for you.") |
michael@0 | 57 | jid = create_jid() |
michael@0 | 58 | config["id"] = jid |
michael@0 | 59 | modified = True |
michael@0 | 60 | |
michael@0 | 61 | if modified: |
michael@0 | 62 | i = 0 |
michael@0 | 63 | backup = filename + ".backup" |
michael@0 | 64 | while os.path.exists(backup): |
michael@0 | 65 | if i > 1000: |
michael@0 | 66 | raise ValueError("I'm having problems finding a good name" |
michael@0 | 67 | " for the backup file. Please move %s out" |
michael@0 | 68 | " of the way and try again." |
michael@0 | 69 | % (filename + ".backup")) |
michael@0 | 70 | backup = filename + ".backup-%d" % i |
michael@0 | 71 | i += 1 |
michael@0 | 72 | os.rename(filename, backup) |
michael@0 | 73 | new_json = json.dumps(config, indent=4) |
michael@0 | 74 | open(filename, 'w').write(new_json+"\n") |
michael@0 | 75 | return False, True |
michael@0 | 76 | |
michael@0 | 77 | return True, False |