addon-sdk/source/python-lib/cuddlefish/preflight.py

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rwxr-xr-x

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

mercurial