troubadix 24.7.1__py3-none-any.whl → 24.7.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
troubadix/__version__.py CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  # THIS IS AN AUTOGENERATED FILE. DO NOT TOUCH!
4
4
 
5
- __version__ = "24.7.1"
5
+ __version__ = "24.7.3"
@@ -0,0 +1,251 @@
1
+ # SPDX-License-Identifier: GPL-3.0-or-later
2
+ # SPDX-FileCopyrightText: 2024 Greenbone AG
3
+
4
+ import re
5
+ from argparse import ArgumentParser, Namespace
6
+ from dataclasses import dataclass
7
+ from enum import Enum
8
+ from pathlib import Path
9
+ from typing import Iterable, Optional
10
+
11
+ from troubadix.argparser import file_type, directory_type
12
+ from troubadix.helper.patterns import (
13
+ get_special_script_tag_pattern,
14
+ get_script_tag_pattern,
15
+ ScriptTag,
16
+ SpecialScriptTag,
17
+ )
18
+
19
+
20
+ class Deprecations(Enum):
21
+ NOTUS = "and replaced by a Notus scanner based one."
22
+ MERGED = "because it has been merged into a different VT."
23
+ DEFUNCT = "and is therefore no longer functional."
24
+ DUPLICATE = "as a duplicate."
25
+
26
+
27
+ @dataclass
28
+ class DeprecatedFile:
29
+ name: str
30
+ full_path: Path
31
+ content: str
32
+
33
+
34
+ KB_ITEMS_PATTERN = re.compile(r"set_kb_item\(.+\);")
35
+
36
+
37
+ def update_summary(file: DeprecatedFile, deprecation_reason: str) -> str:
38
+ """Update the summary of the nasl script by adding the information
39
+ that the script has been deprecated, and if possible, the oid of
40
+ the new notus script replacing it.
41
+
42
+ Args:
43
+ file: DeprecatedFile object containing the content of the VT
44
+ deprecation_reason: The reason this VT is being deprecated,
45
+ from a list of options.
46
+
47
+ Returns:
48
+ The updated content of the file
49
+ """
50
+ old_summary = _get_summary(file.content)
51
+ if not old_summary:
52
+ print(f"No summary in: {file.name}")
53
+ return file.content
54
+
55
+ deprecate_text = (
56
+ f"Note: This VT has been deprecated "
57
+ f"{Deprecations[deprecation_reason].value}"
58
+ )
59
+
60
+ new_summary = old_summary + "\n" + deprecate_text
61
+ file.content = file.content.replace(old_summary, new_summary)
62
+
63
+ return file.content
64
+
65
+
66
+ def _finalize_content(content: str) -> str:
67
+ """Update the content field of the nasl script by adding the
68
+ deprecated tag and removing the extra content."""
69
+ content_to_keep = content.split("exit(0);")[0]
70
+ return content_to_keep + (
71
+ 'script_tag(name:"deprecated", value:TRUE);'
72
+ "\n\nexit(0);\n}\n\nexit(66);\n"
73
+ )
74
+
75
+
76
+ def get_files_from_path(dir_path: Path = None) -> list:
77
+ """Get a list of files from the input path provided
78
+
79
+ Args:
80
+ dir_path (optional): The path to the directory with the files to
81
+ be deprecated
82
+ """
83
+ return [file for file in dir_path.glob("**/*")]
84
+
85
+
86
+ def filter_files(
87
+ files: list, filename_prefix: str = None
88
+ ) -> list[DeprecatedFile]:
89
+ """Filter the files based on a provided prefix and convert them into
90
+ DeprecatedFile objects
91
+
92
+ Args:
93
+ files: a list of files to deprecate, should be .nasl VTs
94
+ filename_prefix: an optional prefix to filter only specific files
95
+
96
+ Returns:
97
+ List of DeprecatedFile objects
98
+
99
+ """
100
+ to_deprecate = []
101
+ if filename_prefix:
102
+ filename_filter = re.compile(rf"{filename_prefix}")
103
+ files[:] = [
104
+ file for file in files if re.match(filename_filter, file.name)
105
+ ]
106
+
107
+ for file in files:
108
+ with file.open("r", encoding="latin-1") as fh:
109
+ to_deprecate.append(
110
+ DeprecatedFile(
111
+ file.name,
112
+ file.absolute(),
113
+ fh.read(),
114
+ )
115
+ )
116
+ return to_deprecate
117
+
118
+
119
+ def _get_summary(content: str) -> Optional[str]:
120
+ """Extract the summary from the nasl script"""
121
+ pattern = get_script_tag_pattern(ScriptTag.SUMMARY)
122
+ if match_summary := re.search(pattern, content):
123
+ value = match_summary.group().split('value:"')[1]
124
+ return value.replace('");', "")
125
+ return None
126
+
127
+
128
+ def deprecate(
129
+ output_path: Path,
130
+ to_deprecate: list[DeprecatedFile],
131
+ deprecation_reason: str,
132
+ ) -> None:
133
+ """Deprecate the selected VTs by removing unnecessary keys, updating the
134
+ summary, and adding the deprecated tag.
135
+
136
+ Args:
137
+ output_path: the directory where the deprecated VTs should be written
138
+ to, i.e. "attic"
139
+ to_deprecate: the list of files to be deprecated
140
+ deprecation_reason: The reason this VT is being deprecated,
141
+ from a list of options.
142
+ """
143
+ output_path.mkdir(parents=True, exist_ok=True)
144
+ for file in to_deprecate:
145
+ if re.findall(KB_ITEMS_PATTERN, file.content):
146
+ print(
147
+ f"Unable to deprecate {file.name}. There are still KB keys "
148
+ f"remaining."
149
+ )
150
+ continue
151
+ file.content = update_summary(file, deprecation_reason)
152
+ file.content = _finalize_content(file.content)
153
+
154
+ # Drop any unnecessary script tags like script_dependencies(),
155
+ # script_require_udp_ports() or script_mandatory_keys()
156
+ tags_to_remove = list()
157
+
158
+ if dependencies := re.search(
159
+ get_special_script_tag_pattern(SpecialScriptTag.DEPENDENCIES),
160
+ file.content,
161
+ ):
162
+ tags_to_remove.append(dependencies.group())
163
+
164
+ if udp := re.search(
165
+ get_special_script_tag_pattern(SpecialScriptTag.REQUIRE_UDP_PORTS),
166
+ file.content,
167
+ ):
168
+ tags_to_remove.append(udp.group())
169
+
170
+ if man_keys := re.search(
171
+ get_special_script_tag_pattern(SpecialScriptTag.MANDATORY_KEYS),
172
+ file.content,
173
+ ):
174
+ tags_to_remove.append(man_keys.group())
175
+
176
+ for tag in tags_to_remove:
177
+ file.content = file.content.replace(" " + tag + "\n", "")
178
+
179
+ file.full_path.rename(output_path / file.name)
180
+
181
+ with open(output_path / file.name, "w", encoding="latin-1") as f:
182
+ f.write(file.content)
183
+ f.truncate()
184
+
185
+
186
+ def parse_args(args: Iterable[str] = None) -> Namespace:
187
+ parser = ArgumentParser(description="Deprecate VTs")
188
+ parser.add_argument(
189
+ "-o",
190
+ "--output-path",
191
+ metavar="<output_path>",
192
+ type=directory_type,
193
+ required=True,
194
+ help="Path where the deprecated files should be written to.",
195
+ )
196
+ parser.add_argument(
197
+ "-p",
198
+ "--filename-prefix",
199
+ metavar="<filename_prefix>",
200
+ nargs="?",
201
+ default=None,
202
+ type=str,
203
+ help="The prefix of the files you would like to deprecate,"
204
+ "for example 'gb_rhsa_2021' to filter on the year",
205
+ )
206
+ parser.add_argument(
207
+ "-r",
208
+ "--deprecation-reason",
209
+ metavar="<deprecation_reason>",
210
+ choices=[reason.name for reason in Deprecations],
211
+ type=str,
212
+ help="The reason the VT is being deprecated. Options are 'notus':"
213
+ "The VT has been replaced by a new Notus VT. 'Merged': the VT has"
214
+ "been merged with another still active VT, 'duplicate': The VT has"
215
+ "a still active duplicate, 'defunct': The VT is no longer "
216
+ "functional.",
217
+ )
218
+ group = parser.add_mutually_exclusive_group(required=True)
219
+ group.add_argument(
220
+ "-f",
221
+ "--files",
222
+ metavar="<files>",
223
+ nargs="+",
224
+ default=None,
225
+ type=file_type,
226
+ help="Files to deprecate",
227
+ )
228
+ group.add_argument(
229
+ "-i",
230
+ "--input-path",
231
+ metavar="<input_path>",
232
+ default=None,
233
+ type=directory_type,
234
+ help="Path to the existing nasl script directory",
235
+ )
236
+ return parser.parse_args(args)
237
+
238
+
239
+ def main():
240
+ args = parse_args()
241
+ input_path = args.input_path if args.input_path else None
242
+ filename_prefix = args.filename_prefix
243
+
244
+ files = args.files or get_files_from_path(input_path)
245
+ filtered_files = filter_files(files, filename_prefix)
246
+
247
+ deprecate(args.output_path, filtered_files, args.deprecation_reason)
248
+
249
+
250
+ if __name__ == "__main__":
251
+ main()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: troubadix
3
- Version: 24.7.1
3
+ Version: 24.7.3
4
4
  Summary: A linting and QA check tool for NASL files
5
5
  Home-page: https://github.com/greenbone/troubadix
6
6
  License: GPL-3.0-or-later
@@ -1,5 +1,5 @@
1
1
  troubadix/__init__.py,sha256=K7sIXXDrC7YRb7BvIpdQ6ZfG_QkT0qUH_wAlHROVRfM,716
2
- troubadix/__version__.py,sha256=mL2tC0y5b_pjx_tasGY6xoDz7aN4XEWC-5G3mdeIoTA,103
2
+ troubadix/__version__.py,sha256=W7cqBfyqbLP9pEZlIH-kS8GRqdzbsgDZY7oYAswusxY,103
3
3
  troubadix/argparser.py,sha256=r9IkiYkd_8BqFGUEkhpawnW5DHo4hIciHd0dptToBjk,6999
4
4
  troubadix/codespell/codespell.additions,sha256=9hUrzjJF4Q8T5rVLx8CQa01oICvmsjzE6sCPjVRDOEU,418
5
5
  troubadix/codespell/codespell.exclude,sha256=qALEzLglEbPwcTRwGcobM_MTJzZyJekYRdJY3ws5yeM,138030
@@ -86,13 +86,14 @@ troubadix/standalone_plugins/changed_packages/marker/dropped_architecture.py,sha
86
86
  troubadix/standalone_plugins/changed_packages/marker/marker.py,sha256=7uZXR2Ds_8soB_2wugCkOSz_3hoX03KMh2NAW0G5Dzg,1278
87
87
  troubadix/standalone_plugins/changed_packages/package.py,sha256=Pcr2tcwiPTzD3jB0iteqA7-TajL-dl5Onh1dvC_H9xk,2743
88
88
  troubadix/standalone_plugins/common.py,sha256=PkScV-lisNY4WyrzwjV3dK1DF26hJv5JXTcREblJ0v0,1028
89
+ troubadix/standalone_plugins/deprecate_vts.py,sha256=gbvG8znQliwZ5XdHqnu-hSk36L33SDqZZhKQcvyGOSI,7661
89
90
  troubadix/standalone_plugins/file_extensions.py,sha256=3lEf73573RaTWgWZgiw8FFICKwc9FfFe8IKrufGofNM,2327
90
91
  troubadix/standalone_plugins/last_modification.py,sha256=oYzQq7xV3YzSvi6ZtuHuupXsJwBtO93tKfbwaIeqiJI,4616
91
92
  troubadix/standalone_plugins/no_solution.py,sha256=81r20kP8otRob2NTaCea-sgVRIM6ARvhddFdibsG6Ao,8877
92
93
  troubadix/standalone_plugins/version_updated.py,sha256=dIGj81rbluyNjINn9kA1yPY2hUo6fqbNa-kg0Zi9Clc,4263
93
94
  troubadix/troubadix.py,sha256=L3Iacrq2uQx8wrmsD4nCFjJDeRDMRWtgSgHLWdP8gJE,6045
94
- troubadix-24.7.1.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
95
- troubadix-24.7.1.dist-info/METADATA,sha256=ZteAYoz8rPORdONVkWbsFOGJBcFIWU32C9doR1NQfyY,3965
96
- troubadix-24.7.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
97
- troubadix-24.7.1.dist-info/entry_points.txt,sha256=oKf82stzVeO3JT7sayXgJm0MUS1aSP5VbSUfZ8HGVCU,665
98
- troubadix-24.7.1.dist-info/RECORD,,
95
+ troubadix-24.7.3.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
96
+ troubadix-24.7.3.dist-info/METADATA,sha256=k16fMjdhgIqxgS1CU5QonSY0VwFqqZ6xmK0_DTxCZks,3965
97
+ troubadix-24.7.3.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
98
+ troubadix-24.7.3.dist-info/entry_points.txt,sha256=LplOk4nzKrS4B8Jz0SPkQLPlIDesdraCO8Vp_eoycpc,737
99
+ troubadix-24.7.3.dist-info/RECORD,,
@@ -4,6 +4,7 @@ troubadix-allowed-rev-diff=troubadix.standalone_plugins.allowed_rev_diff:main
4
4
  troubadix-changed-cves=troubadix.standalone_plugins.changed_cves:main
5
5
  troubadix-changed-oid=troubadix.standalone_plugins.changed_oid:main
6
6
  troubadix-changed-packages=troubadix.standalone_plugins.changed_packages.changed_packages:main
7
+ troubadix-deprecate-vts=troubadix.standalone_plugins.deprecate_vts:main
7
8
  troubadix-file-extensions=troubadix.standalone_plugins.file_extensions:main
8
9
  troubadix-last-modification=troubadix.standalone_plugins.last_modification:main
9
10
  troubadix-no-solution=troubadix.standalone_plugins.no_solution:main