Skip to content

Commit 6975200

Browse files
Add (open)SUSE product check
Currently just validating that the provided cpeid by rpm provides matches the one registered by the installed .prod file.
1 parent a65b622 commit 6975200

4 files changed

Lines changed: 90 additions & 0 deletions

File tree

rpmlint/checks/ProductCheck.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import re
2+
import stat
3+
import subprocess
4+
5+
from xml.dom.minidom import parse
6+
from urllib.parse import unquote
7+
8+
from rpmlint.checks.AbstractCheck import AbstractFilesCheck
9+
10+
11+
class ProductCheck(AbstractFilesCheck):
12+
"""
13+
Validate that product files are correct. currently only cpeid.
14+
"""
15+
16+
def __init__(self, config, output):
17+
super().__init__(config, output, r'/etc/products.d/.*\.prod$')
18+
19+
def check_file(self, pkg, filename):
20+
cpeid_provider_found = None
21+
cpeid_xml_found = None
22+
for provide in pkg.provides:
23+
if provide.name == 'product-cpeid()' and len(provide.version) > 1:
24+
if cpeid_provider_found:
25+
self.output.add_info('E', pkg, 'product-cpeid-multiple-provider', 'multiple product-cpeid() provider, this is not specified yet', filename)
26+
return
27+
cpeid_provider_found = unquote(provide.version[1])
28+
29+
if not cpeid_provider_found:
30+
self.output.add_info('E', pkg, 'product-cpeid-no-provider', 'no product-cpeid() provider', filename)
31+
return
32+
33+
lf = pkg.dir_name() + filename
34+
35+
try:
36+
xml = parse(lf)
37+
except xml.parsers.expat.ExpatError:
38+
self.output.add_info('E', pkg, 'product-parsing-exception', 'Failed to parse: ', lf)
39+
return
40+
41+
cpeids = xml.getElementsByTagName('cpeid')
42+
if len(cpeids) != 1:
43+
self.output.add_info('E', pkg, 'product-cpeid-unavailable', 'cpeid must be defined as singleton in prod file', lf)
44+
return
45+
46+
cpeid_xml_found = cpeids[0].firstChild.data
47+
48+
if not cpeid_xml_found:
49+
self.output.add_info('E', pkg, 'product-cpeid-no-prod-definition', 'no cpeid defined in prod file', lf)
50+
return
51+
52+
if cpeid_xml_found != cpeid_provider_found:
53+
self.output.add_info('E', pkg, 'product-cpeid-provider-mismatch', 'cpeid defined different in prod file to rpm provides', lf)
54+
55+
56+
for file in pkg.files:
57+
if file != "/etc/os-release":
58+
continue
59+
60+
# Found base system
61+
with open(pkg.dir_name() + '/etc/os-release', encoding='utf8') as f:
62+
cpe_name = None
63+
for line in f:
64+
if line.startswith("CPE_NAME="):
65+
cpe_name = line[10:].strip().strip('"').strip("'")
66+
67+
if not cpe_name:
68+
self.output.add_info('E', pkg, 'product-cpe_name-missing', 'no CPE_NAME defined in /etc/os-release file')
69+
return
70+
71+
if cpe_name != cpeid_xml_found and cpe_name.startswith("cpe:2.3:"):
72+
# convert to 2.2 style for now for comparing
73+
cpe_name = "cpe:/" + cpe_name.removeprefix("cpe:2.3:")
74+
while True:
75+
new_cpe_name = cpe_name.removesuffix(":*")
76+
if new_cpe_name == cpe_name:
77+
break
78+
cpe_name = new_cpe_name
79+
80+
if cpe_name != cpeid_xml_found:
81+
self.output.add_info('E', pkg, 'product-cpe_name-mismatch', 'CPE_NAME defined in /etc/os-release file is not matching', cpe_name, " vs ", cpeid_xml_found)
82+
83+
84+

rpmlint/configdefaults.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Checks = [
2020
"MixedOwnershipCheck",
2121
"PkgConfigCheck",
2222
"PostCheck",
23+
"ProductCheck",
2324
"PythonCheck",
2425
"SignatureCheck",
2526
"SourceCheck",
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
product-parsing-exception="""
2+
The package provides an invalid product definition
3+
"""
4+

test/test_lint.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
'MixedOwnershipCheck',
5151
'PkgConfigCheck',
5252
'PostCheck',
53+
'ProductCheck',
5354
'PythonCheck',
5455
'SignatureCheck',
5556
'SourceCheck',

0 commit comments

Comments
 (0)