| OLD | NEW | 
|---|
| 1 # coding: utf-8 | 1 # coding: utf-8 | 
| 2 | 2 | 
| 3 # This Source Code Form is subject to the terms of the Mozilla Public | 3 # This Source Code Form is subject to the terms of the Mozilla Public | 
| 4 # License, v. 2.0. If a copy of the MPL was not distributed with this | 4 # License, v. 2.0. If a copy of the MPL was not distributed with this | 
| 5 # file, You can obtain one at http://mozilla.org/MPL/2.0/. | 5 # file, You can obtain one at http://mozilla.org/MPL/2.0/. | 
| 6 | 6 | 
| 7 import os | 7 import os | 
| 8 import re | 8 import re | 
| 9 import json | 9 import json | 
| 10 import ConfigParser | 10 import ConfigParser | 
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 82     author=get_optional('general', 'author'), | 82     author=get_optional('general', 'author'), | 
| 83     homepage=get_optional('general', 'homepage'), | 83     homepage=get_optional('general', 'homepage'), | 
| 84     updateURL=get_optional('general', 'updateURL'), | 84     updateURL=get_optional('general', 'updateURL'), | 
| 85     allowedDomains=allowedDomains, | 85     allowedDomains=allowedDomains, | 
| 86     allowAllDomains=allowAllDomains, | 86     allowAllDomains=allowAllDomains, | 
| 87     allowSecurePages=allowSecurePages, | 87     allowSecurePages=allowSecurePages, | 
| 88     startScripts=(get_optional('contentScripts', 'document_start') or '').split(
     ), | 88     startScripts=(get_optional('contentScripts', 'document_start') or '').split(
     ), | 
| 89     endScripts=(get_optional('contentScripts', 'document_end') or '').split(), | 89     endScripts=(get_optional('contentScripts', 'document_end') or '').split(), | 
| 90     menus=parse_section('menus', 2), | 90     menus=parse_section('menus', 2), | 
| 91     toolbarItems=parse_section('toolbar_items'), | 91     toolbarItems=parse_section('toolbar_items'), | 
| 92     popovers=parse_section('popovers') | 92     popovers=parse_section('popovers'), | 
|  | 93     developerIdentifier=params.get('developerIdentifier') | 
| 93   ).encode('utf-8') | 94   ).encode('utf-8') | 
| 94 | 95 | 
| 95 def createBackgroundPage(params): | 96 def createBackgroundPage(params): | 
| 96   template = getTemplate('background.html.tmpl', autoEscape=True) | 97   template = getTemplate('background.html.tmpl', autoEscape=True) | 
| 97   return template.render( | 98   return template.render( | 
| 98     backgroundScripts=params['metadata'].get( | 99     backgroundScripts=params['metadata'].get( | 
| 99       'general', 'backgroundScripts' | 100       'general', 'backgroundScripts' | 
| 100     ).split() | 101     ).split() | 
| 101   ).encode('utf-8') | 102   ).encode('utf-8') | 
| 102 | 103 | 
| 103 def createInfoModule(params): | 104 def createInfoModule(params): | 
| 104   template = getTemplate('safariInfo.js.tmpl') | 105   template = getTemplate('safariInfo.js.tmpl') | 
| 105   return template.render(params).encode('utf-8') | 106   return template.render(params).encode('utf-8') | 
| 106 | 107 | 
| 107 def fixAbsoluteUrls(files): | 108 def fixAbsoluteUrls(files): | 
| 108   for filename, content in files.iteritems(): | 109   for filename, content in files.iteritems(): | 
| 109     if os.path.splitext(filename)[1].lower() == '.html': | 110     if os.path.splitext(filename)[1].lower() == '.html': | 
| 110       files[filename] = re.sub( | 111       files[filename] = re.sub( | 
| 111         r'(<[^<>]*?\b(?:href|src)\s*=\s*["\']?)\/+', | 112         r'(<[^<>]*?\b(?:href|src)\s*=\s*["\']?)\/+', | 
| 112         r'\1' + '/'.join(['..'] * filename.count('/') + ['']), | 113         r'\1' + '/'.join(['..'] * filename.count('/') + ['']), | 
| 113         content, re.S | re.I | 114         content, re.S | re.I | 
| 114       ) | 115       ) | 
| 115 | 116 | 
| 116 def createSignedXarArchive(outFile, files, keyFile): | 117 def get_certificates_and_key(keyfile): | 
|  | 118   import M2Crypto | 
|  | 119 | 
|  | 120   certs = [] | 
|  | 121   bio = M2Crypto.BIO.openfile(keyfile) | 
|  | 122 | 
|  | 123   try: | 
|  | 124     key = M2Crypto.RSA.load_key_bio(bio) | 
|  | 125     bio.reset() | 
|  | 126     while True: | 
|  | 127       try: | 
|  | 128         certs.append(M2Crypto.X509.load_cert_bio(bio)) | 
|  | 129       except M2Crypto.X509.X509Error: | 
|  | 130         break | 
|  | 131   finally: | 
|  | 132     bio.close() | 
|  | 133 | 
|  | 134   return certs, key | 
|  | 135 | 
|  | 136 def get_developer_identifier(certs): | 
|  | 137   for cert in certs: | 
|  | 138     subject = cert.get_subject() | 
|  | 139     for entry in subject.get_entries_by_nid(subject.nid['CN']): | 
|  | 140       m = re.match(r'Safari Developer: \((.*?)\)', entry.get_data().as_text()) | 
|  | 141       if m: | 
|  | 142         return m.group(1) | 
|  | 143 | 
|  | 144   raise Exception('No Safari developer certificate found in chain') | 
|  | 145 | 
|  | 146 def createSignedXarArchive(outFile, files, certs, key): | 
| 117   import subprocess | 147   import subprocess | 
| 118   import tempfile | 148   import tempfile | 
| 119   import shutil | 149   import shutil | 
| 120   import M2Crypto | 150   import M2Crypto | 
| 121 | 151 | 
| 122   # write files to temporary directory and create a xar archive | 152   # write files to temporary directory and create a xar archive | 
| 123   dirname = tempfile.mkdtemp() | 153   dirname = tempfile.mkdtemp() | 
| 124   try: | 154   try: | 
| 125     for filename, contents in files.iteritems(): | 155     for filename, contents in files.iteritems(): | 
| 126       path = os.path.join(dirname, filename) | 156       path = os.path.join(dirname, filename) | 
| 127 | 157 | 
| 128       try: | 158       try: | 
| 129         os.makedirs(os.path.dirname(path)) | 159         os.makedirs(os.path.dirname(path)) | 
| 130       except OSError: | 160       except OSError: | 
| 131         pass | 161         pass | 
| 132 | 162 | 
| 133       with open(path, 'wb') as file: | 163       with open(path, 'wb') as file: | 
| 134         file.write(contents) | 164         file.write(contents) | 
| 135 | 165 | 
| 136     subprocess.check_output( | 166     subprocess.check_output( | 
| 137       ['xar', '-czf', os.path.abspath(outFile), '--distribution'] + os.listdir(d
     irname), | 167       ['xar', '-czf', os.path.abspath(outFile), '--distribution'] + os.listdir(d
     irname), | 
| 138       cwd=dirname | 168       cwd=dirname | 
| 139     ) | 169     ) | 
| 140   finally: | 170   finally: | 
| 141     shutil.rmtree(dirname) | 171     shutil.rmtree(dirname) | 
| 142 | 172 | 
| 143   certificate_filenames = [] | 173   certificate_filenames = [] | 
| 144   try: | 174   try: | 
| 145     # load key and certificates from the all-in-one key file | 175     # write each certificate in DER format to a separate | 
| 146     # and write each certificate in DER format to a seperate |  | 
| 147     # temporary file, that they can be passed to xar | 176     # temporary file, that they can be passed to xar | 
| 148     bio = M2Crypto.BIO.openfile(keyFile) | 177     for cert in certs: | 
| 149     try: | 178       fd, filename = tempfile.mkstemp() | 
| 150       key = M2Crypto.RSA.load_key_bio(bio) | 179       try: | 
| 151 | 180         certificate_filenames.append(filename) | 
| 152       bio.reset() | 181         os.write(fd, cert.as_der()) | 
| 153       while True: | 182       finally: | 
| 154         try: | 183         os.close(fd) | 
| 155           cert = M2Crypto.X509.load_cert_bio(bio) |  | 
| 156         except M2Crypto.X509.X509Error: |  | 
| 157           break |  | 
| 158 |  | 
| 159         fd, filename = tempfile.mkstemp() |  | 
| 160         try: |  | 
| 161           certificate_filenames.append(filename) |  | 
| 162           os.write(fd, cert.as_der()) |  | 
| 163         finally: |  | 
| 164           os.close(fd) |  | 
| 165     finally: |  | 
| 166       bio.close() |  | 
| 167 | 184 | 
| 168     # add certificates and placeholder signature | 185     # add certificates and placeholder signature | 
| 169     # to the xar archive, and get data to sign | 186     # to the xar archive, and get data to sign | 
| 170     fd, digestinfo_filename = tempfile.mkstemp() | 187     fd, digestinfo_filename = tempfile.mkstemp() | 
| 171     os.close(fd) | 188     os.close(fd) | 
| 172     try: | 189     try: | 
| 173       subprocess.check_call( | 190       subprocess.check_call( | 
| 174         [ | 191         [ | 
| 175           'xar', '--sign', '-f', outFile, | 192           'xar', '--sign', '-f', outFile, | 
| 176           '--digestinfo-to-sign', digestinfo_filename, | 193           '--digestinfo-to-sign', digestinfo_filename, | 
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 234 | 251 | 
| 235   if metadata.has_section('preprocess'): | 252   if metadata.has_section('preprocess'): | 
| 236     files.preprocess( | 253     files.preprocess( | 
| 237       [f for f, _ in metadata.items('preprocess')], | 254       [f for f, _ in metadata.items('preprocess')], | 
| 238       {'needsExt': True} | 255       {'needsExt': True} | 
| 239     ) | 256     ) | 
| 240 | 257 | 
| 241   if metadata.has_section('import_locales'): | 258   if metadata.has_section('import_locales'): | 
| 242     importGeckoLocales(params, files) | 259     importGeckoLocales(params, files) | 
| 243 | 260 | 
|  | 261   if keyFile: | 
|  | 262     certs, key = get_certificates_and_key(keyFile) | 
|  | 263     params['developerIdentifier'] = get_developer_identifier(certs) | 
|  | 264 | 
| 244   files['lib/info.js'] = createInfoModule(params) | 265   files['lib/info.js'] = createInfoModule(params) | 
| 245   files['background.html'] = createBackgroundPage(params) | 266   files['background.html'] = createBackgroundPage(params) | 
| 246   files['Info.plist'] = createManifest(params, files) | 267   files['Info.plist'] = createManifest(params, files) | 
| 247 | 268 | 
| 248   fixAbsoluteUrls(files) | 269   fixAbsoluteUrls(files) | 
| 249 | 270 | 
| 250   dirname = metadata.get('general', 'basename') + '.safariextension' | 271   dirname = metadata.get('general', 'basename') + '.safariextension' | 
| 251   for filename in files.keys(): | 272   for filename in files.keys(): | 
| 252     files[os.path.join(dirname, filename)] = files.pop(filename) | 273     files[os.path.join(dirname, filename)] = files.pop(filename) | 
| 253 | 274 | 
| 254   if not devenv and keyFile: | 275   if not devenv and keyFile: | 
| 255     createSignedXarArchive(outFile, files, keyFile) | 276     createSignedXarArchive(outFile, files, certs, key) | 
| 256   else: | 277   else: | 
| 257     files.zip(outFile) | 278     files.zip(outFile) | 
| OLD | NEW | 
|---|