Skip to content

Commit fdbaf70

Browse files
committed
Key alias support [RHELDST-35396]
For PQC signed RPMs (not only), Errata tool API will provide a string called "key alias" on `sig_key` field in format "name1,name2,...". In order support this following changes are now implemented: * For Errata source: ** replace `,` with `+` in string provided from `sig_key` field, this is later provided to Koji source as a signing key argument. * For Koji source: ** keep backwards compatible behavior for parsing `signing_key` argument ** replace `+` with `,` for each value in `signing_key` (later used for path to RPM file) ** extract signing key ID from RPM headers every time as we don't know whether caller passed alias or actual key ID, as the alias can be formed as one name only ("sig_key":"alias_name")
1 parent 8c6d46b commit fdbaf70

File tree

11 files changed

+329
-44
lines changed

11 files changed

+329
-44
lines changed

src/pushsource/_impl/backend/errata_source/errata_source.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,11 @@ def _filter_rpms_by_arch(self, erratum, rpm_filenames):
415415
def _rpm_push_items_from_build(self, erratum, build_nvr, build_info):
416416
rpms = build_info.get("rpms") or {}
417417
signing_key = build_info.get("sig_key") or None
418+
if signing_key:
419+
# Errata Tool API may return key alias in sig_key field in format "name1,name2,...", but
420+
# we need to convert "," into "+" otherwise it would be used as multiple keys for Koji
421+
# source which would result in incorrect processing.
422+
signing_key = signing_key.replace(",", "+")
418423
sha256sums = (build_info.get("checksums") or {}).get("sha256") or {}
419424
md5sums = (build_info.get("checksums") or {}).get("md5") or {}
420425

src/pushsource/_impl/backend/koji_source.py

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@
1010
import koji
1111
from more_executors import Executors
1212
from more_executors.futures import f_map
13+
try:
14+
from kobo import rpmlib
15+
except Exception as ex: # pragma: no cover, pylint: disable=broad-except
16+
# If kobo.rpmlib is unavailable, let's not immediately crash.
17+
# We will hold this exception and re-raise it only if there's an
18+
# attempt to use the related functionality.
19+
from .. import broken_rpmlib as rpmlib
20+
21+
rpmlib.CAUSE = ex
1322

1423
from ..source import Source
1524
from ..model import (
@@ -181,7 +190,9 @@ def __init__(
181190
signing_key (list[str])
182191
GPG signing key ID(s). If provided, content must be signed
183192
using one of the provided keys. Include ``None`` if unsigned
184-
should also be permitted.
193+
should also be permitted.
194+
195+
Supports also key alias in the format ``name1+name2+...``
185196
186197
Keys should be listed in the order of preference.
187198
@@ -216,7 +227,7 @@ def __init__(
216227
)
217228
self._container_build = [try_int(x) for x in list_argument(container_build)]
218229
self._vmi_build = [try_int(x) for x in list_argument(vmi_build)]
219-
self._signing_key = list_argument(signing_key)
230+
self._signing_key = self._parse_signing_key(list_argument(signing_key))
220231
self._dest = list_argument(dest)
221232
self._timeout = timeout
222233
self._pathinfo = koji.PathInfo(basedir)
@@ -251,6 +262,15 @@ def _koji_session(self):
251262
tls.koji_session = koji.ClientSession(self._url, {"anon_retry": True})
252263
return tls.koji_session
253264

265+
def _parse_signing_key(self, keys):
266+
out = []
267+
for key in keys:
268+
if key:
269+
out.append(key.replace("+", ",")) # adjust alias to comma separated names of keys
270+
else:
271+
out.append(key)
272+
return out
273+
254274
def _koji_check(self):
255275
# Do a basic connection check with koji.
256276
# If this succeeds, we can be reasonably sure that the koji connection is
@@ -309,7 +329,7 @@ def _push_items_from_rpm_meta(self, rpm, meta):
309329
candidate = unsigned_path
310330

311331
wait_exist(candidate, timeout, poll_rate)
312-
332+
#import pdb; pdb.set_trace()
313333
# If signing keys requested, try them in order of preference
314334
# Some key should be present at this stage, let's try them all
315335
for key in self._signing_key:
@@ -321,7 +341,10 @@ def _push_items_from_rpm_meta(self, rpm, meta):
321341
candidate_paths.append(candidate)
322342
if os.path.exists(candidate):
323343
rpm_path = candidate
324-
rpm_signing_key = key
344+
# we may only get key alias as input, let's extract actual key ID from RPM header in all cases
345+
# as we don't know if the provided data are alias or actual key ID
346+
header = rpmlib.get_rpm_header(candidate)
347+
rpm_signing_key = rpmlib.get_keys_from_header(header)
325348
break
326349

327350
if self._signing_key:
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
advisory_id: RHSA-2020:0509-sig-key-alias
2+
cdn_file_list:
3+
sudo-1.8.25p1-4.el8_0.3:
4+
checksums:
5+
md5:
6+
sudo-1.8.25p1-4.el8_0.3.ppc64le.rpm: 0d56f302617696d3511e71e1669e62c0
7+
sudo-1.8.25p1-4.el8_0.3.src.rpm: f94ab3724b498e3faeab643fe2a67c9c
8+
sudo-1.8.25p1-4.el8_0.3.x86_64.rpm: 25e9470c4fe96034fe1d7525c04b5d8e
9+
sudo-debuginfo-1.8.25p1-4.el8_0.3.ppc64le.rpm: e242826fb38f487502cdc1f1a06991d2
10+
sudo-debuginfo-1.8.25p1-4.el8_0.3.x86_64.rpm: 91126f02975c06015880d6ea99cb2760
11+
sudo-debugsource-1.8.25p1-4.el8_0.3.ppc64le.rpm: d6da7e2e3d9efe050fef2e8d047682be
12+
sudo-debugsource-1.8.25p1-4.el8_0.3.x86_64.rpm: 6b0967941c0caf626c073dc7da0272b6
13+
sha256:
14+
sudo-1.8.25p1-4.el8_0.3.ppc64le.rpm: 31c4f73af90c6d267cc5281c59e4a93ae3557b2253d9a8e3fef55f3cafca6e54
15+
sudo-1.8.25p1-4.el8_0.3.src.rpm: 10d7724302a60d0d2ca890fc7834b8143df55ba1ce0176469ea634ac4ab7aa28
16+
sudo-1.8.25p1-4.el8_0.3.x86_64.rpm: 593f872c1869f7beb963c8df2945fc691a1d999945c8c45c6bc7e02731fa016f
17+
sudo-debuginfo-1.8.25p1-4.el8_0.3.ppc64le.rpm: 04db0c39efb31518ff79bf98d1c27256d46cdc72b967a5b2094a6efec3166df2
18+
sudo-debuginfo-1.8.25p1-4.el8_0.3.x86_64.rpm: 1b7d3a7613236ffea7c4553eb9dea69fc19557005ac3a059d7e83efc08c5b754
19+
sudo-debugsource-1.8.25p1-4.el8_0.3.ppc64le.rpm: 355cbb9dc348b17782cff57120391685d6a1f6884facc54fac4b7fb54abeffba
20+
sudo-debugsource-1.8.25p1-4.el8_0.3.x86_64.rpm: 43e318fa49e4df685ea0d5f0925a00a336236b2e20f27f9365c39a48102c2cf6
21+
rpms:
22+
sudo-1.8.25p1-4.el8_0.3.ppc64le.rpm:
23+
- rhel-8-for-ppc64le-baseos-e4s-rpms__8_DOT_0
24+
sudo-1.8.25p1-4.el8_0.3.src.rpm:
25+
- rhel-8-for-ppc64le-baseos-e4s-source-rpms__8_DOT_0
26+
- rhel-8-for-x86_64-baseos-e4s-source-rpms__8_DOT_0
27+
sudo-1.8.25p1-4.el8_0.3.x86_64.rpm:
28+
- rhel-8-for-x86_64-baseos-e4s-rpms__8_DOT_0
29+
sudo-debuginfo-1.8.25p1-4.el8_0.3.ppc64le.rpm:
30+
- rhel-8-for-ppc64le-baseos-e4s-debug-rpms__8_DOT_0
31+
sudo-debuginfo-1.8.25p1-4.el8_0.3.x86_64.rpm:
32+
- rhel-8-for-x86_64-baseos-e4s-debug-rpms__8_DOT_0
33+
sudo-debugsource-1.8.25p1-4.el8_0.3.ppc64le.rpm:
34+
- rhel-8-for-ppc64le-baseos-e4s-debug-rpms__8_DOT_0
35+
sudo-debugsource-1.8.25p1-4.el8_0.3.x86_64.rpm:
36+
- rhel-8-for-x86_64-baseos-e4s-debug-rpms__8_DOT_0
37+
sig_key: foo,bar,baz
38+
cdn_metadata:
39+
description: 'The sudo packages contain the sudo utility which allows system administrators
40+
to provide certain users with the permission to execute privileged commands, which
41+
are used for system management purposes, without having to log in as root.
42+
43+
44+
Security Fix(es):
45+
46+
47+
* sudo: Stack based buffer overflow when pwfeedback is enabled (CVE-2019-18634)
48+
49+
50+
For more details about the security issue(s), including the impact, a CVSS score,
51+
acknowledgments, and other related information, refer to the CVE page(s) listed
52+
in the References section.'
53+
54+
id: RHSA-2020:0509
55+
issued: 2020-02-13 19:00:11 UTC
56+
pkglist:
57+
- packages:
58+
- arch: ppc64le
59+
epoch: '0'
60+
filename: sudo-1.8.25p1-4.el8_0.3.ppc64le.rpm
61+
name: sudo
62+
release: 4.el8_0.3
63+
src: sudo-1.8.25p1-4.el8_0.3.src.rpm
64+
sum:
65+
- md5
66+
- 0d56f302617696d3511e71e1669e62c0
67+
- sha256
68+
- 31c4f73af90c6d267cc5281c59e4a93ae3557b2253d9a8e3fef55f3cafca6e54
69+
version: 1.8.25p1
70+
- arch: SRPMS
71+
epoch: '0'
72+
filename: sudo-1.8.25p1-4.el8_0.3.src.rpm
73+
name: sudo
74+
release: 4.el8_0.3
75+
src: sudo-1.8.25p1-4.el8_0.3.src.rpm
76+
sum:
77+
- md5
78+
- f94ab3724b498e3faeab643fe2a67c9c
79+
- sha256
80+
- 10d7724302a60d0d2ca890fc7834b8143df55ba1ce0176469ea634ac4ab7aa28
81+
version: 1.8.25p1
82+
- arch: x86_64
83+
epoch: '0'
84+
filename: sudo-1.8.25p1-4.el8_0.3.x86_64.rpm
85+
name: sudo
86+
release: 4.el8_0.3
87+
src: sudo-1.8.25p1-4.el8_0.3.src.rpm
88+
sum:
89+
- md5
90+
- 25e9470c4fe96034fe1d7525c04b5d8e
91+
- sha256
92+
- 593f872c1869f7beb963c8df2945fc691a1d999945c8c45c6bc7e02731fa016f
93+
version: 1.8.25p1
94+
- arch: ppc64le
95+
epoch: '0'
96+
filename: sudo-debuginfo-1.8.25p1-4.el8_0.3.ppc64le.rpm
97+
name: sudo-debuginfo
98+
release: 4.el8_0.3
99+
src: sudo-1.8.25p1-4.el8_0.3.src.rpm
100+
sum:
101+
- md5
102+
- e242826fb38f487502cdc1f1a06991d2
103+
- sha256
104+
- 04db0c39efb31518ff79bf98d1c27256d46cdc72b967a5b2094a6efec3166df2
105+
version: 1.8.25p1
106+
- arch: x86_64
107+
epoch: '0'
108+
filename: sudo-debuginfo-1.8.25p1-4.el8_0.3.x86_64.rpm
109+
name: sudo-debuginfo
110+
release: 4.el8_0.3
111+
src: sudo-1.8.25p1-4.el8_0.3.src.rpm
112+
sum:
113+
- md5
114+
- 91126f02975c06015880d6ea99cb2760
115+
- sha256
116+
- 1b7d3a7613236ffea7c4553eb9dea69fc19557005ac3a059d7e83efc08c5b754
117+
version: 1.8.25p1
118+
- arch: ppc64le
119+
epoch: '0'
120+
filename: sudo-debugsource-1.8.25p1-4.el8_0.3.ppc64le.rpm
121+
name: sudo-debugsource
122+
release: 4.el8_0.3
123+
src: sudo-1.8.25p1-4.el8_0.3.src.rpm
124+
reboot_suggested: true
125+
sum:
126+
- md5
127+
- d6da7e2e3d9efe050fef2e8d047682be
128+
- sha256
129+
- 355cbb9dc348b17782cff57120391685d6a1f6884facc54fac4b7fb54abeffba
130+
version: 1.8.25p1
131+
- arch: x86_64
132+
epoch: '0'
133+
filename: sudo-debugsource-1.8.25p1-4.el8_0.3.x86_64.rpm
134+
name: sudo-debugsource
135+
release: 4.el8_0.3
136+
src: sudo-1.8.25p1-4.el8_0.3.src.rpm
137+
sum:
138+
- md5
139+
- 6b0967941c0caf626c073dc7da0272b6
140+
- sha256
141+
- 43e318fa49e4df685ea0d5f0925a00a336236b2e20f27f9365c39a48102c2cf6
142+
version: 1.8.25p1
143+
pulp_user_metadata:
144+
content_types:
145+
- rpm
146+
pushcount: '3'
147+
reboot_suggested: false
148+
references:
149+
- href: https://access.redhat.com/errata/RHSA-2020:0509
150+
id: null
151+
title: RHSA-2020:0509
152+
type: self
153+
- href: https://bugzilla.redhat.com/show_bug.cgi?id=1796944
154+
id: '1796944'
155+
title: 'CVE-2019-18634 sudo: Stack based buffer overflow when pwfeedback is enabled'
156+
type: bugzilla
157+
- href: https://www.redhat.com/security/data/cve/CVE-2019-18634.html
158+
id: CVE-2019-18634
159+
title: CVE-2019-18634
160+
type: cve
161+
- href: https://access.redhat.com/security/updates/classification/#important
162+
id: classification
163+
title: important
164+
type: other
165+
release: '0'
166+
rights: Copyright 2020 Red Hat Inc
167+
severity: Important
168+
solution: 'For details on how to apply this update, which includes the changes described
169+
in this advisory, refer to:
170+
171+
172+
https://access.redhat.com/articles/11258'
173+
status: final
174+
summary: 'An update for sudo is now available for Red Hat Enterprise Linux 8.0 Update
175+
Services for SAP Solutions.
176+
177+
178+
Red Hat Product Security has rated this update as having a security impact of
179+
Important. A Common Vulnerability Scoring System (CVSS) base score, which gives
180+
a detailed severity rating, is available for each vulnerability from the CVE link(s)
181+
in the References section.'
182+
title: 'Important: sudo security update'
183+
type: security
184+
updated: 2020-02-13 19:00:11 UTC
185+
version: '3'

tests/errata/test_errata_missing_modules.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
from pytest import raises
2-
2+
from mock import patch
33
from pushsource import Source
44

55

6-
def test_errata_modules_via_koji(fake_errata_tool, fake_koji, koji_dir):
6+
@patch("pushsource._impl.backend.koji_source.rpmlib.get_keys_from_header", return_value="fd431d51")
7+
@patch("pushsource._impl.backend.koji_source.rpmlib.get_rpm_header")
8+
def test_errata_modules_via_koji(mock_get_rpm_header, mock_get_keys_from_headers, fake_errata_tool, fake_koji, koji_dir):
79
"""Errata source gives an error if ET requested modules which don't exist in koji"""
810

911
source = Source.get(

tests/errata/test_errata_module_sources.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import pytest
44

55
from pushsource import Source, ModuleMdSourcePushItem
6-
6+
from mock import patch
77

88
@pytest.fixture
99
def source_factory(fake_errata_tool, fake_koji, koji_dir):
@@ -161,8 +161,9 @@ def source_factory(fake_errata_tool, fake_koji, koji_dir):
161161

162162
yield ctor
163163

164-
165-
def test_errata_module_sources(source_factory, koji_dir):
164+
@patch("pushsource._impl.backend.koji_source.rpmlib.get_keys_from_header", return_value="fd431d51")
165+
@patch("pushsource._impl.backend.koji_source.rpmlib.get_rpm_header")
166+
def test_errata_module_sources(mock_get_rpm_header, mock_get_keys_from_headers, source_factory, koji_dir):
166167
"""Errata source can provide ModuleMdSourcePushItems, typical scenario."""
167168

168169
source = source_factory(errata="RHEA-2020:0346")
@@ -193,8 +194,9 @@ def test_errata_module_sources(source_factory, koji_dir):
193194
)
194195
]
195196

196-
197-
def test_errata_module_sources_no_ftp_paths(source_factory):
197+
@patch("pushsource._impl.backend.koji_source.rpmlib.get_keys_from_header", return_value="fd431d51")
198+
@patch("pushsource._impl.backend.koji_source.rpmlib.get_rpm_header")
199+
def test_errata_module_sources_no_ftp_paths(mock_get_rpm_header, mock_get_keys_from_headers, source_factory):
198200
"""Errata source skips ModuleMdSourcePushItems if ET does not request any
199201
FTP paths for modules."""
200202

@@ -207,8 +209,9 @@ def test_errata_module_sources_no_ftp_paths(source_factory):
207209
# Should not have found anything since ET reported no dests for modules in FTP paths
208210
assert src_items == []
209211

210-
211-
def test_errata_module_sources_no_cdn_list(source_factory, caplog):
212+
@patch("pushsource._impl.backend.koji_source.rpmlib.get_keys_from_header", return_value="fd431d51")
213+
@patch("pushsource._impl.backend.koji_source.rpmlib.get_rpm_header")
214+
def test_errata_module_sources_no_cdn_list(mock_get_rpm_header, mock_get_keys_from_headers, source_factory, caplog):
212215
"""Errata source skips ModuleMdSourcePushItems if ET does not present those
213216
modules in get_advisory_cdn_file_list."""
214217

@@ -228,8 +231,9 @@ def test_errata_module_sources_no_cdn_list(source_factory, caplog):
228231
in caplog.text
229232
)
230233

231-
232-
def test_errata_module_missing_sources(source_factory, fake_koji):
234+
@patch("pushsource._impl.backend.koji_source.rpmlib.get_keys_from_header", return_value="fd431d51")
235+
@patch("pushsource._impl.backend.koji_source.rpmlib.get_rpm_header")
236+
def test_errata_module_missing_sources(mock_get_rpm_header, mock_get_keys_from_headers, source_factory, fake_koji):
233237
"""Errata source gives fatal error if ET requests some FTP paths for modules,
234238
yet no module sources exist on koji build."""
235239
source = source_factory(errata="RHEA-2020:0346")

tests/errata/test_errata_modules.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import os
2-
2+
from mock import patch
33
from pushsource import (
44
Source,
55
ErratumPushItem,
@@ -10,8 +10,9 @@
1010
ModuleMdPushItem,
1111
)
1212

13-
14-
def test_errata_modules_via_koji(fake_errata_tool, fake_koji, koji_dir):
13+
@patch("pushsource._impl.backend.koji_source.rpmlib.get_keys_from_header", return_value="fd431d51")
14+
@patch("pushsource._impl.backend.koji_source.rpmlib.get_rpm_header")
15+
def test_errata_modules_via_koji(mock_get_rpm_header, mock_get_keys_from_headers, fake_errata_tool, fake_koji, koji_dir):
1516
"""Errata source containing a module yields modules & RPMs taken
1617
from koji source"""
1718

0 commit comments

Comments
 (0)