|
1 | 1 | import os |
2 | | -import os.path |
3 | 2 | import platform |
4 | 3 | import re |
5 | 4 | import runpy |
6 | | -import subprocess |
7 | 5 | import sys |
8 | | -import time |
9 | | -import traceback |
10 | | -from os.path import dirname, expanduser, join |
11 | | -from subprocess import PIPE, CalledProcessError, Popen |
| 6 | +from os.path import basename, dirname, join |
12 | 7 |
|
13 | 8 |
|
14 | | -class MakeCertPem: |
15 | | - """ create openssl cert bundle from system certificates """ |
16 | | - |
17 | | - def __init__(self, openssl): |
18 | | - self.openssl = openssl |
19 | | - |
20 | | - def is_valid_cert(self, cert): |
21 | | - """ check if cert is valid according to openssl""" |
22 | | - cmd = [self.openssl, "x509", "-inform", "pem", "-checkend", "0", "-noout"] |
23 | | - # print("D: is_valid_cert %r" % cmd) |
24 | | - proc = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) |
25 | | - stdout, stderr = proc.communicate(cert) |
26 | | - # print("out: %s; err:%s; ret:%i" % (stdout, stderr, proc.returncode)) |
27 | | - return proc.returncode == 0 |
28 | | - |
29 | | - def get_certs(self): |
30 | | - """ extract System's certificates then filter them by validity |
31 | | - and return a list of text of valid certs |
32 | | - """ |
33 | | - cmd = ["security", "find-certificate", "-a", "-p", |
34 | | - "/System/Library/Keychains/SystemRootCertificates.keychain"] |
35 | | - cert_re = re.compile(b"^-----BEGIN CERTIFICATE-----$" + |
36 | | - b".+?" + |
37 | | - b"^-----END CERTIFICATE-----$", re.M | re.S) |
38 | | - try: |
39 | | - certs_str = subprocess.check_output(cmd) |
40 | | - all_certs = cert_re.findall(certs_str) |
41 | | - print("I: extracted %i certificates" % len(all_certs)) |
42 | | - valid_certs = [cert for cert in all_certs |
43 | | - if self.is_valid_cert(cert)] |
44 | | - print("I: of which %i are valid certificates" % len(valid_certs)) |
45 | | - return valid_certs |
46 | | - except OSError: |
47 | | - print("E: extracting certificates using %r" % cmd) |
48 | | - traceback.print_exc() |
49 | | - except CalledProcessError as err: |
50 | | - print(("E: extracting certificates using %r, exit=%i" % |
51 | | - (cmd, err.returncode))) |
52 | | - |
53 | | - @staticmethod |
54 | | - def write_certs(certs, dest): |
55 | | - """ write concatenated certs to dest """ |
56 | | - with open(dest, "wb") as output: |
57 | | - output.write(b"\n".join(certs)) |
58 | | - |
59 | | - def regen(self, dest): |
60 | | - """ main program """ |
61 | | - print("I: make_cert_pem %s %s" % (self.openssl, dest)) |
62 | | - certs = self.get_certs() |
63 | | - if certs is None: |
64 | | - print("E: no certificate extracted") |
65 | | - return -1 |
66 | | - else: |
67 | | - self.write_certs(certs, dest) |
68 | | - print("I: updated %s with %i certificates" % (dest, len(certs))) |
69 | | - return 0 |
70 | | - |
71 | 9 | # print("launcher.py sys.argv=", sys.argv) |
72 | 10 | bundlepath = sys.argv.pop(0) |
73 | | -app = os.path.basename(sys.argv[0]) |
| 11 | +app = basename(sys.argv[0]) |
74 | 12 |
|
75 | 13 | bundle_contents = join(bundlepath, 'Contents') |
76 | 14 | bundle_res = join(bundle_contents, 'Resources') |
@@ -107,70 +45,18 @@ def regen(self, dest): |
107 | 45 | sys.path.append(bundle_res) |
108 | 46 | print('System Path:\n','\n'.join(sys.path)) |
109 | 47 |
|
110 | | -# see https://gpodder.github.io/docs/user-manual.html#gpodder-home-folder-and-download-location |
111 | | -# To override gPodder home and/or download directory: |
112 | | -# 1. uncomment (remove the pound sign and space) at the begining of the relevant line |
113 | | -# 2. replace ~/gPodderData or ~/gPodderDownloads with the path you want for your gPodder home |
114 | | -# (you can move the original folder in the Finder first, |
115 | | -# then drag and drop to the launcher.py in TextEdit to ensure the correct path is set) |
116 | | -# uncomment the following line to override gPodder home |
117 | | -# os.environ['GPODDER_HOME'] = expanduser('~/gPodderData') |
118 | | -# uncomment the following line to override gPodder download directory |
119 | | -# os.environ['GPODDER_DOWNLOAD_DIR'] = expanduser('~/gPodderDownloads') |
120 | | - |
121 | 48 | for k, v in os.environ.items(): |
122 | 49 | print("%s=%s" % (k,v)) |
123 | 50 |
|
124 | | -def gpodder_home(): |
125 | | - # don't inadvertently create the new gPodder home, |
126 | | - # it would be prefered to the old one |
127 | | - default_path = join(os.environ['HOME'], 'Library', 'Application Support', 'gPodder') |
128 | | - cands = [ |
129 | | - os.environ.get('GPODDER_HOME'), |
130 | | - default_path, |
131 | | - join(os.environ['HOME'], 'gPodder'), |
132 | | - ] |
133 | | - for cand in cands: |
134 | | - if cand and os.path.exists(cand): |
135 | | - return cand |
136 | | - return default_path |
137 | | - |
138 | | - |
139 | | -gphome = gpodder_home() |
140 | | -os.makedirs(join(gphome, 'openssl'), exist_ok=True) |
141 | | -# generate cert.extracted.pem |
142 | | -cert_gen = join(gphome, 'openssl', 'cert.extracted.pem') |
143 | | -cert_pem = join(gphome, 'openssl', 'cert.pem') |
144 | | -regen = False |
145 | | -if not os.path.isfile(cert_gen): |
146 | | - regen = True |
147 | | -else: |
148 | | - last_modified = os.stat(cert_gen).st_mtime |
149 | | - regen = last_modified < time.time() - 3600 * 7 |
150 | | - |
151 | | -if regen: |
152 | | - print('(Re)generating', cert_pem) |
153 | | - openssl = join(bundle_bin, 'openssl') |
154 | | - MakeCertPem(openssl).regen(cert_gen) |
155 | | -else: |
156 | | - print('No regenerating', cert_gen, 'it\'s fresh enough') |
157 | | - |
158 | | -# and link to it by default. Users may want to point cert.pem to MacPorts |
159 | | -# /opt/local/etc/openssl/cert.pem, for instance. |
160 | | -if not os.path.exists(cert_pem): |
161 | | - os.symlink(os.path.basename(cert_gen), cert_pem) |
162 | | -#Set path to CA files |
163 | | -os.environ['SSL_CERT_FILE'] = cert_pem |
| 51 | +python_exe = join(bundle_contents, 'MacOS', 'python3') |
164 | 52 |
|
165 | 53 | if app == 'run-python': |
166 | | - python_exe = join(bundle_contents, 'MacOS', 'python3') |
167 | 54 | # executable is repeated as argv[0]. |
168 | 55 | # Old sys.argv[0] points to Contents/MacOS so must be removed |
169 | 56 | args = [python_exe] + sys.argv[1:] |
170 | 57 | # print("running", args) |
171 | 58 | os.execv(python_exe, args) |
172 | 59 | elif app == 'run-pip': |
173 | | - python_exe = join(bundle_contents, 'MacOS', 'python3') |
174 | 60 | pip = join(bundle_contents, 'Resources', 'bin', 'pip3') |
175 | 61 | # executable is repeated as argv[0]. |
176 | 62 | # Old sys.argv[0] points to Contents/MacOS so must be removed |
|
0 commit comments