Merge lp:~smoser/software-properties/trunk.lp1667725-https-signing-key into lp:software-properties

Proposed by Scott Moser
Status: Merged
Merged at revision: 1050
Proposed branch: lp:~smoser/software-properties/trunk.lp1667725-https-signing-key
Merge into: lp:software-properties
Diff against target: 138 lines (+41/-8)
3 files modified
debian/changelog (+7/-0)
softwareproperties/ppa.py (+29/-8)
tests/test_lp.py (+5/-0)
To merge this branch: bzr merge lp:~smoser/software-properties/trunk.lp1667725-https-signing-key
Reviewer Review Type Date Requested Status
Colin Watson Approve
Review via email: mp+351824@code.launchpad.net

Commit message

Get PPA key signing data from launchpad https rather than keyserver.

Previously adding of a PPA would read the signing key fingerprint from
launchpad and then read the signing key data from keyserver.ubuntu.com
over https.

This changes that to use the newly added getSigningKeyData operation
from launchpad. And uses the launchpad 'devel' api version.
The primary benefit of this is a reduction in the number
of external services that 'add-apt-repository' relies upon.
That means less external services that may be down, and also less
holes poked in egress networking to allow add-apt-repository to work.

There are also 3 other changes/improvements that we found along the way:
 a.) make python2 (pycurl) path follow http redirects.
 b.) use 'mangle_ppa_shortcut' in other paths.
 c.) mangle_ppa_shortcut can now support input with or without 'ppa:' as
     a prefix.

To post a comment you must log in.
1051. By Scott Moser

remove staging, launchpad marked released.

1052. By Scott Moser

Get PPA key signing data from launchpad https rather than keyserver.
(LP: #1667725)

Revision history for this message
Colin Watson (cjwatson) :
review: Approve
Revision history for this message
Scott Moser (smoser) wrote :

Addressed your other comments.

Thank you.

1053. By Scott Moser

debian/changelog: fix version

1054. By Scott Moser

address cjwatson's other comments.

1055. By Scott Moser

improve docstring, fix a bug in use of 'path', treat response as json.

cjwatson pointed out the response is json so we have to treat it as such.
just use the 'accept_json' and we're good.

1056. By Scott Moser

fix bug in calling of _recv_key (thanks cjwatson)

1057. By Scott Moser

use mangle_ppa_shortcut consistently.

this fixes a bug/issue in the python2 path with
  python -m softwareproperties.ppa ppa:~smoser/ppa

The issue was that launchpad would return a 301 and pycurl would
not follow the redirect.
  https://launchpad.net/api/devel/~smoser/+archive/ppa
would get a 301 to
  https://launchpad.net/api/devel/~smoser/+archive/ubuntu/ppa

1058. By Scott Moser

In python2 (pycurl) path follow redirects.

the pycurl path was not following redirects which made it inconsistent
behavior with python3 path. now they both act the same in this regard.

1059. By Scott Moser

Fix tests, support mangle_ppa_shortcut without a leading 'ppa:'

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2018-07-26 08:56:14 +0000
3+++ debian/changelog 2018-08-03 14:40:33 +0000
4@@ -1,3 +1,10 @@
5+software-properties (0.96.26) UNRELEASED; urgency=medium
6+
7+ * Get PPA key signing data from launchpad https rather than keyserver.
8+ (LP: #1667725)
9+
10+ -- Scott Moser <smoser@ubuntu.com> Mon, 30 Jul 2018 21:44:24 -0400
11+
12 software-properties (0.96.25) cosmic; urgency=medium
13
14 * Port the KDE frontend to a pure Qt frontend that Lubuntu can use as well.
15
16=== modified file 'softwareproperties/ppa.py'
17--- softwareproperties/ppa.py 2018-07-16 17:34:17 +0000
18+++ softwareproperties/ppa.py 2018-08-03 14:40:33 +0000
19@@ -49,7 +49,7 @@
20
21 SKS_KEYSERVER = 'https://keyserver.ubuntu.com/pks/lookup?op=get&options=mr&exact=on&search=0x%s'
22 # maintained until 2015
23-LAUNCHPAD_PPA_API = 'https://launchpad.net/api/1.0/%s/+archive/%s'
24+LAUNCHPAD_PPA_API = 'https://launchpad.net/api/devel/%s/+archive/%s'
25 LAUNCHPAD_USER_API = 'https://launchpad.net/api/1.0/%s'
26 LAUNCHPAD_USER_PPAS_API = 'https://launchpad.net/api/1.0/%s/ppas'
27 LAUNCHPAD_DISTRIBUTION_API = 'https://launchpad.net/api/1.0/%s'
28@@ -170,6 +170,7 @@
29 curl = pycurl.Curl()
30 curl.setopt(pycurl.SSL_VERIFYPEER, 1)
31 curl.setopt(pycurl.SSL_VERIFYHOST, 2)
32+ curl.setopt(pycurl.FOLLOWLOCATION, 1)
33 curl.setopt(pycurl.WRITEFUNCTION, callback.body_callback)
34 if LAUNCHPAD_PPA_CERT:
35 curl.setopt(pycurl.CAINFO, LAUNCHPAD_PPA_CERT)
36@@ -200,7 +201,10 @@
37
38
39 def mangle_ppa_shortcut(shortcut):
40- ppa_shortcut = shortcut.split(":")[1]
41+ if ":" in shortcut:
42+ ppa_shortcut = shortcut.split(":")[1]
43+ else:
44+ ppa_shortcut = shortcut
45 if ppa_shortcut.startswith("/"):
46 ppa_shortcut = ppa_shortcut.lstrip("/")
47 user = ppa_shortcut.split("/")[0]
48@@ -237,7 +241,8 @@
49 cmd = "gpg -q --homedir %s --no-default-keyring --no-options --import --import-options %s" % (self._homedir, args)
50 return subprocess.Popen(cmd.split(), stdin=subprocess.PIPE, stdout=subprocess.PIPE)
51
52- def _recv_key(self, signing_key_fingerprint):
53+ def _recv_key(self, ppa_info):
54+ signing_key_fingerprint = ppa_info["signing_key_fingerprint"]
55 try:
56 # double check that the signing key is a v4 fingerprint (160bit)
57 if not verify_keyid_is_v4(signing_key_fingerprint):
58@@ -248,8 +253,7 @@
59 print("Error: signing key fingerprint does not exist")
60 return False
61
62- return get_info_from_https(SKS_KEYSERVER % signing_key_fingerprint,
63- accept_json=False, retry_delays=(1, 2))
64+ return get_ppa_signing_key_data(ppa_info)
65
66 def _minimize_key(self, key):
67 p = self.gpg_cmd("import-minimal,import-export")
68@@ -292,7 +296,7 @@
69 ppa_path = self.ppa_path
70
71 try:
72- ppa_info = get_ppa_info(ppa_path)
73+ ppa_info = get_ppa_info(mangle_ppa_shortcut(ppa_path))
74 except PPAException as e:
75 print(e.value)
76 return False
77@@ -303,7 +307,7 @@
78 return False
79
80 # download the armored_key
81- armored_key = self._recv_key(signing_key_fingerprint)
82+ armored_key = self._recv_key(ppa_info)
83 if not armored_key:
84 return False
85
86@@ -394,6 +398,23 @@
87 (LAUNCHPAD_PPA_API % (user, ppa)))
88
89
90+def get_ppa_signing_key_data(info=None):
91+ """Return signing key data in armored ascii format for the provided ppa.
92+
93+ If 'info' is a dictionary, it is assumed to be the result
94+ of 'get_ppa_info(ppa)'. If it is a string, it is assumed to
95+ be a ppa_path.
96+
97+ Return value is a text string."""
98+ if isinstance(info, dict):
99+ link = info["self_link"]
100+ else:
101+ link = get_ppa_info(mangle_ppa_shortcut(info))["self_link"]
102+
103+ return get_info_from_https(link + "?ws.op=getSigningKeyData",
104+ accept_json=True, retry_delays=(1, 2, 3))
105+
106+
107 class PPAShortcutHandler(object):
108 def __init__(self, shortcut):
109 super(PPAShortcutHandler, self).__init__()
110@@ -450,5 +471,5 @@
111
112 if __name__ == "__main__":
113 import sys
114- ppa = sys.argv[1].split(":")[1]
115+ ppa = mangle_ppa_shortcut(sys.argv[1])
116 print(get_ppa_info(ppa))
117
118=== modified file 'tests/test_lp.py'
119--- tests/test_lp.py 2018-03-30 14:14:39 +0000
120+++ tests/test_lp.py 2018-08-03 14:40:33 +0000
121@@ -25,6 +25,7 @@
122 'distribution_link': 'https://launchpad.net/api/1.0/ubuntu',
123 'owner_link': 'https://launchpad.net/api/1.0/~mvo',
124 'reference': '~mvo/ubuntu/ppa',
125+ 'self_link': 'https://launchpad.net/api/devel/~mvo/+archive/ubuntu/ppa',
126 }
127
128 MOCK_KEY="""
129@@ -96,6 +97,10 @@
130 self.assertEqual("~gottcode/ubuntu/gcppa",
131 mangle_ppa_shortcut("ppa:/gottcode/gcppa"))
132
133+ def test_mangle_ppa_supports_no_ppa_colon_prefix(self):
134+ """mangle_ppa should also support input without 'ppa:'."""
135+ self.assertEqual("~mvo/ubuntu/ppa", mangle_ppa_shortcut("~mvo/ppa"))
136+
137
138 class AddPPASigningKeyTestCase(unittest.TestCase):
139

Subscribers

People subscribed via source and target branches

to status/vote changes: