├── .gitignore ├── .travis.yml ├── AUTHORS ├── CHANGES ├── README.md ├── crxmake ├── __init__.py └── crxmake.py ├── examples └── app │ ├── _locales │ └── en │ │ └── messages.json │ ├── manifest.json │ └── scripts │ └── background.js ├── legacy └── m2crypto-0.20.2-enable-rsa-pubout.patch ├── scripts └── crxmake ├── setup.py └── test ├── __init__.py └── test_crxmake.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *~ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "2.7" 4 | # command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors 5 | install: "pip install . --use-mirrors" 6 | # command to run tests, e.g. python setup.py test 7 | script: nosetests 8 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | @bellbind - maintainer 2 | @mekarpeles -------------------------------------------------------------------------------- /CHANGES: -------------------------------------------------------------------------------- 1 | v0.0.2, Tue 04, March 2014 -- Refactor 2 | - renamed zip var to zf to avoid clobering zip builtin 3 | - created functions for public key, private key creation and signing 4 | - added .travis.yml and test case placeholder 5 | - setup.py for easy installation 6 | - added swig as os level dependency within README 7 | - added file injection (inject files from memory into zip dynamically) 8 | 9 | v0.0.1, Fri 02, Jul 2010 -- Initial Release. (bellbind) 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # crxmake-python 2 | 3 | Python script for building google chrome extension crx package. 4 | It is inspired by rubygems' crxmake. 5 | 6 | ## Ubuntu Installation 7 | 8 | sudo apt-get install swig 9 | sudo pip install crxmake 10 | 11 | ## Usage: 12 | 13 | crxmake.py PACKAGE_BASE_DIR 14 | 15 | ## Example 16 | 17 | An example extension named 'app' is provided in the examples/ 18 | directory for testing purposes: 19 | 20 | $ crxmake.py examples/app 21 | $ ls examples/app 22 | $ app app.crx app.pem 23 | 24 | ## Requires: 25 | 26 | - python 2 27 | - swig 28 | - M2Crypto (available via pip, requires swig) 29 | - "openssl" command: because current M2Crypto lacks func for rsa pubout DER 30 | 31 | ## Legacy Dependencies 32 | 33 | ### Appendix: m2crypto-0.20.2-enable-rsa-pubout.patch 34 | 35 | "svn diff" output for appending the feature for rsa pubout DER. 36 | 37 | Howto build m2crypto with it: 38 | 39 | svn co http://svn.osafoundation.org/m2crypto/tags/0.20.2 m2crypto-0.20.2 40 | cd m2crypto-0.20.2 41 | patch -p0 < ../legacy/m2crypto-0.20.2-enable-rsa-pubout.patch 42 | python setup.py build 43 | 44 | (I hope someone send it to M2Crypto maintainer ^^) 45 | 46 | ## Resources: 47 | 48 | - "M2Crypto":http://chandlerproject.org/bin/view/Projects/MeTooCrypto 49 | - "crxmake":http://github.com/Constellation/crxmake 50 | - "Packing Chrome extensions in Python":http://grack.com/blog/2009/11/09/packing-chrome-extensions-in-python/ 51 | -------------------------------------------------------------------------------- /crxmake/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- mode: python coding: utf-8 -*- 3 | 4 | """crxmake packages chrome extensions as .crx from python""" 5 | 6 | __version__ = "0.0.2" 7 | __author__ = [ 8 | "bellbind " 9 | ] 10 | __license__ = "see LICENSE" 11 | __contributors__ = "see AUTHORS" 12 | 13 | from crxmake import package, cli 14 | -------------------------------------------------------------------------------- /crxmake/crxmake.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- mode: python coding: utf-8 -*- 3 | 4 | """ 5 | crxmake 6 | ~~~~~~~ 7 | 8 | building google chrome extension crx with commandline 9 | it is inspired by rubygem's crxmake 10 | requires: M2Crypto module (and "openssl" commandline) 11 | 12 | :copyright: (c) 2010 bellbind 13 | :license: pending, see LICENSE for more details. 14 | """ 15 | 16 | import os 17 | import sys 18 | import io 19 | import argparse 20 | import tempfile 21 | import dircache 22 | import hashlib 23 | import struct 24 | import subprocess 25 | import zipfile 26 | import M2Crypto.EVP 27 | import M2Crypto.RSA 28 | import M2Crypto.BIO 29 | 30 | MAGIC = "Cr24" 31 | VERSION = struct.pack(">> rm_trailing_slash('foo/bar/') 38 | 'foo/bar' 39 | """ 40 | return d[:-1] if d.endswith(os.path.sep) else d 41 | 42 | def package(basedir, files=None, magic=MAGIC, version=VERSION): 43 | """Create a chrome extension .crx package of a base directory 44 | 45 | params: 46 | basedir - the base directory where the application is located 47 | files - a dict of {filepath: filecontents} to inject before 48 | packing. Useful for dynamically injecting configs or 49 | keys within projects. Filenames are relative to basedir. 50 | i.e. 'scripts/config.js' 51 | """ 52 | if not os.path.isdir(basedir): 53 | raise IOError("Non-existant directory <%s>" % basedir) 54 | crxd = rm_trailing_slash(basedir) 55 | 56 | try: 57 | zipdata = zipdir(crxd, inject=files) 58 | except IOError as e: 59 | raise e 60 | pem, key = create_privatekey(crxd) 61 | sig = sign(zipdata, pem) 62 | der = create_publickey(crxd, key) 63 | 64 | der_len = struct.pack("