Skip to content

Commit d1fbbf9

Browse files
committed
Verify PGP signatures on tarballs when deploying
1 parent 5206410 commit d1fbbf9

2 files changed

Lines changed: 36 additions & 5 deletions

File tree

scripts/deploy.py

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,16 @@
1010
import argparse
1111
import os
1212
import os.path
13+
import subprocess
14+
import sys
1315
import tarfile
14-
import urllib
16+
17+
try:
18+
# python3
19+
from urllib.request import urlretrieve
20+
except ImportError:
21+
# python2
22+
from urllib import urlretrieve
1523

1624
class DeployException(Exception):
1725
pass
@@ -56,6 +64,7 @@ def __init__(self):
5664
self.bundles_path = None
5765
self.should_clean = False
5866
self.config_location = None
67+
self.verify_signature = True
5968

6069
def deploy(self, tarball, extract_path):
6170
"""Download a tarball if necessary, and unpack it
@@ -65,9 +74,15 @@ def deploy(self, tarball, extract_path):
6574
"""
6675
print("Deploying %s to %s" % (tarball, extract_path))
6776

77+
name_str = os.path.basename(tarball).replace(".tar.gz", "")
78+
extracted_dir = os.path.join(extract_path, name_str)
79+
if os.path.exists(extracted_dir):
80+
raise DeployException('Cannot unpack %s: %s already exists' % (
81+
tarball, extracted_dir))
82+
6883
downloaded = False
6984
if tarball.startswith("http://") or tarball.startswith("https://"):
70-
tarball = self.download_file(tarball)
85+
tarball = self.download_and_verify(tarball)
7186
print("Downloaded file: %s" % tarball)
7287
downloaded = True
7388

@@ -78,8 +93,6 @@ def deploy(self, tarball, extract_path):
7893
if self.should_clean and downloaded:
7994
os.remove(tarball)
8095

81-
name_str = os.path.basename(tarball).replace(".tar.gz", "")
82-
extracted_dir = os.path.join(extract_path, name_str)
8396
print ("Extracted into: %s" % extracted_dir)
8497

8598
if self.config_location:
@@ -101,12 +114,24 @@ def deploy(self, tarball, extract_path):
101114
)
102115
return extracted_dir
103116

117+
def download_and_verify(self, url):
118+
tarball = self.download_file(url)
119+
120+
if self.verify_signature:
121+
sigfile = self.download_file(url + ".asc")
122+
subprocess.check_call(["gpg", "--verify", sigfile, tarball])
123+
124+
return tarball
125+
104126
def download_file(self, url):
105127
if not os.path.isdir(self.packages_path):
106128
os.mkdir(self.packages_path)
107129
local_filename = os.path.join(self.packages_path,
108130
url.split('/')[-1])
109-
urllib.urlretrieve(url, local_filename)
131+
sys.stdout.write("Downloading %s -> %s..." % (url, local_filename))
132+
sys.stdout.flush()
133+
urlretrieve(url, local_filename)
134+
print ("Done")
110135
return local_filename
111136

112137
if __name__ == "__main__":

scripts/redeploy.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,12 @@ def deploy_tarball(tar_gz_url, build_dir):
214214
deployer.should_clean = args.clean
215215
deployer.config_location = args.config
216216

217+
# we don't pgp-sign jenkins artifacts; instead we rely on HTTPS access to
218+
# the jenkins server (and the jenkins server not being compromised and/or
219+
# github not serving it compromised source). If that's not good enough for
220+
# you, don't use riot.im/develop.
221+
deployer.verify_signature = False
222+
217223
if args.tarball_uri is not None:
218224
build_dir = os.path.join(arg_extract_path, "test-%i" % (time.time()))
219225
deploy_tarball(args.tarball_uri, build_dir)

0 commit comments

Comments
 (0)