Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: packagerSafari.py

Issue 29322519: Issue 2796 - Added DeveloperIdentifier to Info.plist for Safari 9 (Closed)
Patch Set: Created July 16, 2015, 2:32 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Info.plist.tmpl ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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):
kzar 2015/07/16 15:39:53 Nit: Use camel case to match the other function na
Sebastian Noack 2015/07/16 15:50:48 I think we should move to PEP-8 for new code.
kzar 2015/07/16 15:56:35 From PEP-8: "A style guide is about consistency.
Wladimir Palant 2015/07/16 19:16:23 I agree with Sebastian - we are never going to tak
kzar 2015/07/17 08:51:18 Acknowledged.
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')
kzar 2015/07/16 15:39:53 Nit: Capitalise Safari?
Sebastian Noack 2015/07/16 15:50:48 This code where merely copied from sitescripts. Bu
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 seperate
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
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)
OLDNEW
« no previous file with comments | « Info.plist.tmpl ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld