troubadix 25.10.8__tar.gz → 25.10.10__tar.gz
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-25.10.8 → troubadix-25.10.10}/PKG-INFO +1 -1
- {troubadix-25.10.8 → troubadix-25.10.10}/pyproject.toml +1 -1
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_encoding.py +74 -11
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/standalone_plugins/test_deprecate_vts.py +52 -1
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/__version__.py +1 -1
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/codespell/codespell.exclude +7 -0
- troubadix-25.10.10/troubadix/plugins/encoding.py +78 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/http_links_in_tags.py +4 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/standalone_plugins/deprecate_vts.py +82 -17
- troubadix-25.10.8/troubadix/plugins/encoding.py +0 -62
- {troubadix-25.10.8 → troubadix-25.10.10}/LICENSE +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/README.md +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/__init__.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/helper/__init__.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/helper/test_date_format.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/helper/test_if_block_parser.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/helper/test_linguistic_exception_handler.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/helper/test_patterns.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/helper/test_remove_comments.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/helper/test_text_utils.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/manual_tests/comment_removal_diff.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/__init__.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/fail.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/fail2.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_badwords.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_copyright_text.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_copyright_year.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_creation_date.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_cve_format.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_cvss_format.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_dependencies.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_dependency_category_order.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_deprecated_dependency.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_deprecated_functions.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_double_end_points.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_duplicate_oid.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_duplicated_script_tags.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_files/fail_bad_new_line.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_files/fail_badwords.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_files/fail_name_and_copyright_newline.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_files/fail_name_newline.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_files/fail_permissions.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_files/fail_spelling.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_files/nasl/21.04/fail.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_files/nasl/21.04/fail_badwords.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_files/nasl/21.04/fail_name_and_copyright_newline.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_files/nasl/21.04/fail_name_newline.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_files/nasl/21.04/fail_solution_template.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_files/nasl/21.04/runner/fail.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_files/nasl/21.04/runner/fail2.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_files/nasl/21.04/runner/test.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_files/nasl/21.04/runner/test_valid_oid.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_files/nasl/21.04/test.inc +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_files/nasl/21.04/test.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_files/nasl/warning.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_files/ok_permissions.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_files/test_oid.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_forking_nasl_functions.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_get_kb_on_services.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_grammar.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_http_links_in_tags.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_if_statement_syntax.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_illegal_characters.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_log_messages.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_malformed_dependencies.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_misplaced_compare_in_if.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_missing_desc_exit.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_missing_tag_solution.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_multiple_re_parameters.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_newlines.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_overlong_description_lines.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_overlong_script_tags.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_prod_svc_detect_in_vulnvt.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_qod.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_reporting_consistency.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_script_add_preference_type.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_script_calls_empty_values.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_script_calls_recommended.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_script_category.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_script_copyright.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_script_family.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_script_tag_form.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_script_tag_whitespaces.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_script_tags_mandatory.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_script_version_and_last_modification_tags.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_script_xref_form.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_script_xref_url.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_security_messages.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_set_get_kb_calls.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_severity_date.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_severity_format.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_severity_origin.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_solution_text.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_solution_type.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_spaces_before_dots.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_spaces_in_filename.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_spelling.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_tabs.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_todo_tbd.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_trailing_spaces_tabs.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_using_display.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_valid_oid.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_valid_script_tag_names.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_variable_redefinition_in_foreach.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_vt_file_permissions.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/plugins/test_vt_placement.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/standalone_plugins/__init__.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/standalone_plugins/changed_packages/__init__.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/standalone_plugins/changed_packages/markers/__init__.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/standalone_plugins/changed_packages/markers/test_added_epoch.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/standalone_plugins/changed_packages/markers/test_added_release.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/standalone_plugins/changed_packages/markers/test_added_udeb.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/standalone_plugins/changed_packages/markers/test_changed_update.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/standalone_plugins/changed_packages/markers/test_dropped_architecture.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/standalone_plugins/changed_packages/test_changed_packages.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/standalone_plugins/changed_packages/test_package.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/standalone_plugins/nasl/21.04/21_script.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/standalone_plugins/nasl/22.04/22_script.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/standalone_plugins/nasl/common/bar.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/standalone_plugins/nasl/common/foo.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/standalone_plugins/nasl/common/foobar.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/standalone_plugins/nasl/common/gsf/enterprise_script.nasl +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/standalone_plugins/test_changed_creation_date.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/standalone_plugins/test_changed_cves.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/standalone_plugins/test_changed_oid.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/standalone_plugins/test_dependency_graph.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/standalone_plugins/test_file_extensions.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/standalone_plugins/test_last_modification.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/standalone_plugins/test_no_solution.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/standalone_plugins/test_version_updated.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/test_argparser.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/test_helper.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/test_naslinter.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/test_reporter.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/test_results.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/tests/test_runner.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/__init__.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/argparser.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/codespell/codespell.additions +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/codespell/codespell.ignore +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/helper/__init__.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/helper/date_format.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/helper/helper.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/helper/if_block_parser.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/helper/linguistic_exception_handler.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/helper/patterns.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/helper/remove_comments.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/helper/text_utils.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugin.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/__init__.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/badwords.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/copyright_text.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/copyright_year.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/creation_date.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/cve_format.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/cvss_format.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/dependencies.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/dependency_category_order.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/deprecated_dependency.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/deprecated_functions.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/double_end_points.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/duplicate_oid.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/duplicated_script_tags.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/forking_nasl_functions.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/get_kb_on_services.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/grammar.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/if_statement_syntax.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/illegal_characters.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/log_messages.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/malformed_dependencies.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/misplaced_compare_in_if.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/missing_desc_exit.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/missing_tag_solution.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/multiple_re_parameters.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/newlines.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/overlong_description_lines.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/overlong_script_tags.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/prod_svc_detect_in_vulnvt.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/qod.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/reporting_consistency.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/script_add_preference_type.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/script_calls_empty_values.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/script_calls_recommended.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/script_category.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/script_copyright.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/script_family.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/script_tag_form.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/script_tag_whitespaces.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/script_tags_mandatory.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/script_version_and_last_modification_tags.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/script_xref_form.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/script_xref_url.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/security_messages.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/set_get_kb_calls.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/severity_date.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/severity_format.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/severity_origin.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/solution_text.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/solution_type.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/spaces_before_dots.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/spaces_in_filename.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/spelling.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/tabs.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/todo_tbd.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/trailing_spaces_tabs.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/using_display.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/valid_oid.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/valid_script_tag_names.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/variable_assigned_in_if.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/variable_redefinition_in_foreach.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/vt_file_permissions.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/plugins/vt_placement.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/reporter.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/results.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/runner.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/standalone_plugins/__init__.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/standalone_plugins/allowed_rev_diff.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/standalone_plugins/changed_creation_date.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/standalone_plugins/changed_cves.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/standalone_plugins/changed_oid.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/standalone_plugins/changed_packages/changed_packages.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/standalone_plugins/changed_packages/marker/__init__.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/standalone_plugins/changed_packages/marker/added_epoch.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/standalone_plugins/changed_packages/marker/added_release.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/standalone_plugins/changed_packages/marker/added_udeb.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/standalone_plugins/changed_packages/marker/changed_update.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/standalone_plugins/changed_packages/marker/dropped_architecture.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/standalone_plugins/changed_packages/marker/marker.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/standalone_plugins/changed_packages/package.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/standalone_plugins/common.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/standalone_plugins/dependency_graph/__init__.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/standalone_plugins/dependency_graph/checks.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/standalone_plugins/dependency_graph/cli.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/standalone_plugins/dependency_graph/dependency_graph.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/standalone_plugins/dependency_graph/models.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/standalone_plugins/file_extensions.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/standalone_plugins/last_modification.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/standalone_plugins/no_solution.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/standalone_plugins/util.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/standalone_plugins/version_updated.py +0 -0
- {troubadix-25.10.8 → troubadix-25.10.10}/troubadix/troubadix.py +0 -0
|
@@ -44,6 +44,69 @@ class CheckEncodingTestCase(PluginTestCase):
|
|
|
44
44
|
|
|
45
45
|
self.assertEqual(len(results), 0)
|
|
46
46
|
|
|
47
|
+
def test_ok_iso_8859_1(self):
|
|
48
|
+
"""Test that all valid ISO-8859-1 characters pass encoding validation.
|
|
49
|
+
|
|
50
|
+
This covers the issue reported in JIRA VTOPS-281 where characters like 'ä' and '®'
|
|
51
|
+
should be valid when files are properly encoded as ISO-8859-1.
|
|
52
|
+
"""
|
|
53
|
+
with self.create_directory() as tempdir:
|
|
54
|
+
path = tempdir / "file.nasl"
|
|
55
|
+
|
|
56
|
+
# All valid ISO-8859-1 characters (0-255)
|
|
57
|
+
# ASCII printable characters (32-126) + Latin-1 supplement (160-255)
|
|
58
|
+
latin1_chars = "".join(
|
|
59
|
+
[chr(i) for i in list(range(32, 127)) + list(range(160, 256))]
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
path.write_text(
|
|
63
|
+
latin1_chars,
|
|
64
|
+
encoding="iso-8859-1",
|
|
65
|
+
)
|
|
66
|
+
content = path.read_text(encoding=CURRENT_ENCODING)
|
|
67
|
+
fake_context = self.create_file_plugin_context(
|
|
68
|
+
nasl_file=path, file_content=content, lines=content.splitlines()
|
|
69
|
+
)
|
|
70
|
+
plugin = CheckEncoding(fake_context)
|
|
71
|
+
|
|
72
|
+
results = list(plugin.run())
|
|
73
|
+
|
|
74
|
+
self.assertEqual(len(results), 0)
|
|
75
|
+
|
|
76
|
+
def test_specific_latin1_chars_utf8_encoding_fails(self):
|
|
77
|
+
"""Test that specific Latin-1 characters fail when saved as UTF-8.
|
|
78
|
+
|
|
79
|
+
This specifically tests the JIRA VTOPS-281 reported issue where 'ä' and '®'
|
|
80
|
+
cause encoding problems when saved as UTF-8 but read as ISO-8859-1.
|
|
81
|
+
"""
|
|
82
|
+
with self.create_directory() as tempdir:
|
|
83
|
+
path = tempdir / "file.nasl"
|
|
84
|
+
|
|
85
|
+
# Specific characters that were problematic: ä (U+00E4) and ® (U+00AE)
|
|
86
|
+
path.write_text(
|
|
87
|
+
"This contains ä and ® characters",
|
|
88
|
+
encoding="utf-8",
|
|
89
|
+
)
|
|
90
|
+
content = path.read_text(encoding=CURRENT_ENCODING)
|
|
91
|
+
fake_context = self.create_file_plugin_context(
|
|
92
|
+
nasl_file=path, file_content=content, lines=content.splitlines()
|
|
93
|
+
)
|
|
94
|
+
plugin = CheckEncoding(fake_context)
|
|
95
|
+
|
|
96
|
+
results = list(plugin.run())
|
|
97
|
+
|
|
98
|
+
self.assertEqual(len(results), 2)
|
|
99
|
+
self.assertIsInstance(results[0], LinterError)
|
|
100
|
+
self.assertEqual(
|
|
101
|
+
"Detected encoding 'UTF-8' is not Latin-1 compatible.",
|
|
102
|
+
results[0].message,
|
|
103
|
+
)
|
|
104
|
+
self.assertIsInstance(results[1], LinterError)
|
|
105
|
+
self.assertEqual(
|
|
106
|
+
"Likely UTF-8 multibyte sequence found in line 1",
|
|
107
|
+
results[1].message,
|
|
108
|
+
)
|
|
109
|
+
|
|
47
110
|
def test_some_invalid_characters(self):
|
|
48
111
|
with self.create_directory() as tempdir:
|
|
49
112
|
path = tempdir / "file.nasl"
|
|
@@ -61,22 +124,18 @@ class CheckEncodingTestCase(PluginTestCase):
|
|
|
61
124
|
|
|
62
125
|
results = list(plugin.run())
|
|
63
126
|
|
|
64
|
-
self.assertEqual(len(results),
|
|
127
|
+
self.assertEqual(len(results), 2)
|
|
65
128
|
|
|
66
129
|
self.assertIsInstance(results[0], LinterError)
|
|
67
130
|
self.assertEqual(
|
|
68
|
-
"
|
|
69
|
-
"Allowed encodings are ascii, latin_1.",
|
|
131
|
+
"Detected encoding 'UTF-8' is not Latin-1 compatible.",
|
|
70
132
|
results[0].message,
|
|
71
133
|
)
|
|
134
|
+
self.assertIsInstance(results[1], LinterError)
|
|
72
135
|
self.assertEqual(
|
|
73
|
-
"
|
|
136
|
+
"Likely UTF-8 multibyte sequence found in line 1",
|
|
74
137
|
results[1].message,
|
|
75
138
|
)
|
|
76
|
-
self.assertEqual(
|
|
77
|
-
"Found invalid character in line: 2",
|
|
78
|
-
results[2].message,
|
|
79
|
-
)
|
|
80
139
|
|
|
81
140
|
def test_invisible_whitespace(self):
|
|
82
141
|
with self.create_directory() as tempdir:
|
|
@@ -95,10 +154,14 @@ class CheckEncodingTestCase(PluginTestCase):
|
|
|
95
154
|
|
|
96
155
|
results = list(plugin.run())
|
|
97
156
|
|
|
98
|
-
self.assertEqual(len(results),
|
|
157
|
+
self.assertEqual(len(results), 2)
|
|
99
158
|
self.assertIsInstance(results[0], LinterError)
|
|
100
159
|
self.assertEqual(
|
|
101
|
-
"
|
|
102
|
-
"Allowed encodings are ascii, latin_1.",
|
|
160
|
+
"Detected encoding 'UTF-8' is not Latin-1 compatible.",
|
|
103
161
|
results[0].message,
|
|
104
162
|
)
|
|
163
|
+
self.assertIsInstance(results[1], LinterError)
|
|
164
|
+
self.assertEqual(
|
|
165
|
+
"Likely UTF-8 multibyte sequence found in line 1",
|
|
166
|
+
results[1].message,
|
|
167
|
+
)
|
|
@@ -12,6 +12,7 @@ from troubadix.standalone_plugins.deprecate_vts import (
|
|
|
12
12
|
_get_summary,
|
|
13
13
|
deprecate,
|
|
14
14
|
get_files_from_path,
|
|
15
|
+
load_transition_oid_mapping,
|
|
15
16
|
parse_args,
|
|
16
17
|
parse_files,
|
|
17
18
|
update_summary,
|
|
@@ -153,10 +154,60 @@ class DeprecateVTsTestCase(unittest.TestCase):
|
|
|
153
154
|
self.assertNotIn(result, "script_dependencies")
|
|
154
155
|
self.assertNotIn(result, 'include("revisions-lib.inc");')
|
|
155
156
|
assert (
|
|
156
|
-
"Note: This VT has been deprecated and replaced by "
|
|
157
|
+
"\n\n Note: This VT has been deprecated and replaced by "
|
|
157
158
|
"a Notus scanner based one."
|
|
158
159
|
) in result
|
|
159
160
|
|
|
161
|
+
def test_deprecate_with_oid_mapping(self):
|
|
162
|
+
with TemporaryDirectory() as out_dir, TemporaryDirectory() as in_dir:
|
|
163
|
+
# Create a temporary transition file with OID mapping
|
|
164
|
+
transition_file = in_dir / "transition.py"
|
|
165
|
+
transition_file.write_text(
|
|
166
|
+
'mapping = {"1.3.6.1.4.1.25623.1.0.910673": "1.3.6.1.4.1.25623.1.0.999999"}',
|
|
167
|
+
encoding="utf8",
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
# Load the OID mapping
|
|
171
|
+
oid_mapping = load_transition_oid_mapping(transition_file)
|
|
172
|
+
|
|
173
|
+
testfile1 = in_dir / "testfile1.nasl"
|
|
174
|
+
testfile1.write_text(NASL_CONTENT, encoding="utf8")
|
|
175
|
+
|
|
176
|
+
testfile2 = out_dir / "testfile1.nasl"
|
|
177
|
+
testfile2.touch()
|
|
178
|
+
|
|
179
|
+
to_deprecate = [
|
|
180
|
+
DeprecatedFile(
|
|
181
|
+
name="testfile1.nasl",
|
|
182
|
+
full_path=testfile1,
|
|
183
|
+
content=NASL_CONTENT,
|
|
184
|
+
)
|
|
185
|
+
]
|
|
186
|
+
deprecate(out_dir, to_deprecate, "NOTUS", oid_mapping)
|
|
187
|
+
|
|
188
|
+
result = testfile2.read_text(encoding="utf8")
|
|
189
|
+
# Check that the replacement OID is included in the summary
|
|
190
|
+
self.assertIn(
|
|
191
|
+
"The replacement VT has OID 1.3.6.1.4.1.25623.1.0.999999.",
|
|
192
|
+
result,
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
def test_load_transition_oid_mapping(self):
|
|
196
|
+
with TemporaryDirectory() as tempdir:
|
|
197
|
+
transition_file = tempdir / "transition.py"
|
|
198
|
+
transition_file.write_text(
|
|
199
|
+
'mapping = {"1.3.6.1.4.1.25623.1.0.910673": "1.3.6.1.4.1.25623.1.0.999999",'
|
|
200
|
+
'"another_oid": "replacement_oid"}',
|
|
201
|
+
encoding="utf8",
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
result = load_transition_oid_mapping(transition_file)
|
|
205
|
+
expected = {
|
|
206
|
+
"1.3.6.1.4.1.25623.1.0.910673": "1.3.6.1.4.1.25623.1.0.999999",
|
|
207
|
+
"another_oid": "replacement_oid",
|
|
208
|
+
}
|
|
209
|
+
self.assertEqual(result, expected)
|
|
210
|
+
|
|
160
211
|
def test_deprecate_kb_item(self):
|
|
161
212
|
with TemporaryDirectory() as out_dir, TemporaryDirectory() as in_dir:
|
|
162
213
|
testfile1 = in_dir / "testfile1.nasl"
|
|
@@ -273,6 +273,7 @@ CPE = "cpe:/a:mapp:webtrekk:";
|
|
|
273
273
|
CPE = "cpe:/a:netsparker:wass";
|
|
274
274
|
CPE = "cpe:/a:tawk:tawk.to_live_chat";
|
|
275
275
|
CPE: cpe:/a:tawk:tawk.to_live_chat:0.8.0
|
|
276
|
+
cpe =~ "^cpe:/o:fujifilm:apeos_2150_(n|nd|nda)_firmware") {
|
|
276
277
|
cpe =~ "^cpe:/o:hp:laserjet_pro_420[1-3](cdn|dn|dw|dne|dwe)_firmware") {
|
|
277
278
|
CPU' could have occured because a retry loop continually finds the same
|
|
278
279
|
crafted IFF ILBM file. NOTE: some of these details are obtained from
|
|
@@ -398,7 +399,9 @@ drbd: Avoid Clang warning about pointless switch statment (bsc#1051510).
|
|
|
398
399
|
eliptic curve parameters were not sufficiently validated during
|
|
399
400
|
} else if( banner =~ "^220 (RICOH|LANIER|SAVIN|Gestetner|NRG) (Aficio |Pro)?([A-Z]+)? [^ ]+ (\([^)]+\) )?FTP server" ) {
|
|
400
401
|
} else if("diese Vorgabe muss manuell ueberprueft werden" >< tolower(status)) {
|
|
402
|
+
} else if (prod =~ "^BMX\s*NOE\s*0100$") {
|
|
401
403
|
else if (prod =~ "^BMX\s*NOE\s*0100$" || prod =~ "^BMX\s*NOE\s*0100H$") {
|
|
404
|
+
} else if (prod =~ "^BMX\s*NOE\s*0110$") {
|
|
402
405
|
else if (prod =~ "^BMX\s*NOE\s*0110$" || prod =~ "^BMX\s*NOE\s*0110H$") {
|
|
403
406
|
else if( svc == "agobot.fo" )
|
|
404
407
|
Enable log information of starting/stoping services. (bsc#1144923,
|
|
@@ -415,6 +418,7 @@ examined with fuzzing by Tim Blazytko, Cornelius Aschermann, Sergej
|
|
|
415
418
|
execute arbitrary code via a crafted Upack PE file.
|
|
416
419
|
executuon (bsc#966437).
|
|
417
420
|
EXP=CustomIE.dll
|
|
421
|
+
expected_value = '1. The output should contain "iif "lo" accept" and contain "iif != "lo" ip saddr 127.0.0.0/8 drop" and contain "iif != "lo" ip6 saddr ::1 drop"
|
|
418
422
|
EXP=expext.dll
|
|
419
423
|
expressions that are not properly handled by a stap script that
|
|
420
424
|
* extended EAP-SIM/AKA fast re-authentication to allow use with FILS
|
|
@@ -442,6 +446,7 @@ files. If a user were tricked into opening a specially-crafted CAF file, a
|
|
|
442
446
|
files packed with UPack.
|
|
443
447
|
files to potentially execute code and it is tracked by the Mitre CVE
|
|
444
448
|
file_xml = '\t\t<file_item' + status + ' xmlns="http://oval.mitre.org/XMLSchema/' +
|
|
449
|
+
firebird:x:109:117:Firebird Database Administator,,,:/var/lib/firebird:/usr/sbin/nologin
|
|
445
450
|
Fixed a bug where Podman could not run containers usin... [Please see the references for more information on the vulnerabilities]");
|
|
446
451
|
Fixed an issue with version missmatch (bsc#1162224).
|
|
447
452
|
Fixed a regression in regards to the 'edge' comand line flag
|
|
@@ -582,6 +587,7 @@ if (prod =~ "^BMX\s*NOE\s*0110$" || prod =~ "^BMX\s*NOE\s*0110H$") {
|
|
|
582
587
|
if (prod =~ "^BMX\s*NOE\s*0110" && version_is_less(version: version, test_version: "6.5")) {
|
|
583
588
|
if (prod =~ "^BMX\s*NOE\s*0110" && version_is_less(version: version, test_version: "6.70")) {
|
|
584
589
|
if (prod =~ "^BMX\s*NOE\s*0200") {
|
|
590
|
+
if (!prod || (prod !~ "^BMX\s*P34" && prod !~ "^BMX\s*(NOC\s*0401|NGD\s*0100|NOR\s*0200H|NOE\s*01[01]0)"))
|
|
585
591
|
if (!prod || (prod !~ "^BMX\s*P34" && prod !~ "^BMX\s*NOE\s*01[01]0"))
|
|
586
592
|
if (!prod || (prod !~ "^BMX\s*P34" && prod !~ "^BMX\s*NOE\s*0(1[01]|20)0"))
|
|
587
593
|
if (!prod || (prod !~ "^BMX\s*P34" && prod !~ "^BMX\s*NOR\s*0200H" && prod !~ "^BMX\s*NOE\s*0100" &&
|
|
@@ -752,6 +758,7 @@ ML^Q8<TQ^+LTL*)6UG-,[V6-;N*W*79^&[ND/.DM''*U8D?Q:.'+%RB;S$!.'
|
|
|
752
758
|
MM]7>[YM~GC^@?_WK0@W/F>UDL^Q8<TQ^+LTL*)6UG-,[V6-;N*W*79^&[ND/
|
|
753
759
|
MN*W*79^&[ND/.DM''*U8D?Q:.'+%RB;S$!.'6['*(;8>~A:>&GO>&&M7/36X
|
|
754
760
|
model = "TE Unknown Model";
|
|
761
|
+
mod = eregmatch(pattern: "([-A-Za-z0-9]+) -?\s*.*([Cc]ard|[Cc]ontroller) \[v", string: recv);
|
|
755
762
|
mod = eregmatch(pattern: "Huawei (TE[0-9]0)", string: banner);
|
|
756
763
|
mod = eregmatch(pattern: "(RICOH|LANIER|SAVIN|Gestetner|NRG) ((Aficio |Pro)?([A-Z]+)? [^ ]+)", string: banner);
|
|
757
764
|
mod = eregmatch(pattern: "^(RICOH|LANIER|SAVIN|Gestetner|NRG) ((Aficio )?[^ ]+ [^ :]*)(:[^:]+:Ver.([.0-9]+))?", string: banner);
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Copyright (C) 2022 Greenbone AG
|
|
2
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
3
|
+
|
|
4
|
+
from typing import Iterator
|
|
5
|
+
|
|
6
|
+
import magic
|
|
7
|
+
|
|
8
|
+
from troubadix.plugin import (
|
|
9
|
+
FilePlugin,
|
|
10
|
+
LinterError,
|
|
11
|
+
LinterResult,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
# OpenVAS decodes NASL files using ISO-8859-1 (Latin-1).
|
|
15
|
+
# Files saved in other encodings (like UTF-8)
|
|
16
|
+
# will be misinterpreted and cause errors or garbled text.
|
|
17
|
+
# US-ASCII is also allowed since it's a subset of ISO-8859-1.
|
|
18
|
+
ALLOWED_ENCODINGS = ["iso-8859-1", "us-ascii"]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class CheckEncoding(FilePlugin):
|
|
22
|
+
"""
|
|
23
|
+
Check if the encoding of the NASL file is ISO-8859-1 (Latin-1) encoded.
|
|
24
|
+
Finds UTF-8 multibyte sequences that are composed of individually valid Latin-1 bytes,
|
|
25
|
+
but result in garbled text.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
name = "check_encoding"
|
|
29
|
+
|
|
30
|
+
def run(self) -> Iterator[LinterResult]:
|
|
31
|
+
with open(self.context.nasl_file, "rb") as f:
|
|
32
|
+
raw = f.read()
|
|
33
|
+
|
|
34
|
+
# Use magic to detect encoding
|
|
35
|
+
detected_encoding = magic.Magic(mime_encoding=True).from_buffer(raw)
|
|
36
|
+
|
|
37
|
+
if detected_encoding not in ALLOWED_ENCODINGS:
|
|
38
|
+
yield LinterError(
|
|
39
|
+
f"Detected encoding '{detected_encoding.upper()}' is not Latin-1 compatible.",
|
|
40
|
+
file=self.context.nasl_file,
|
|
41
|
+
plugin=self.name,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
def has_utf8_multibyte(data: bytes) -> bool:
|
|
45
|
+
"""
|
|
46
|
+
Function to detect UTF-8 multibyte sequences by checking the first two bytes.
|
|
47
|
+
UTF-8 multibyte sequences start with a lead byte followed by continuation bytes.
|
|
48
|
+
|
|
49
|
+
Lead byte ranges:
|
|
50
|
+
- 2-byte: 0xC2–0xDF (110xxxxx, excluding 0xC0–0xC1 to avoid overlongs)
|
|
51
|
+
- 3-byte: 0xE0–0xEF (1110xxxx)
|
|
52
|
+
- 4-byte: 0xF0–0xF4 (11110xxx)
|
|
53
|
+
These ranges are continuous, so we can check 0xC2–0xF4 as a single range.
|
|
54
|
+
11000010 C2 -- F4 11110111
|
|
55
|
+
|
|
56
|
+
Continuation bytes: 0x80–0xBF (10yyyyyy)
|
|
57
|
+
10000000 80 -- BF 10111111
|
|
58
|
+
|
|
59
|
+
Lead and continuation byte values are either not valid Latin-1 or special symbols
|
|
60
|
+
that are unlikely to be following each other in normal use.
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
for i in range(len(data) - 1):
|
|
64
|
+
first = data[i]
|
|
65
|
+
second = data[i + 1]
|
|
66
|
+
if 0xC2 <= first <= 0xF4 and 0x80 <= second <= 0xBF:
|
|
67
|
+
return True
|
|
68
|
+
return False
|
|
69
|
+
|
|
70
|
+
lines = raw.split(b"\n")
|
|
71
|
+
for i, line_bytes in enumerate(lines, start=1):
|
|
72
|
+
if has_utf8_multibyte(line_bytes):
|
|
73
|
+
yield LinterError(
|
|
74
|
+
f"Likely UTF-8 multibyte sequence found in line {i}",
|
|
75
|
+
file=self.context.nasl_file,
|
|
76
|
+
plugin=self.name,
|
|
77
|
+
line=i,
|
|
78
|
+
)
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
2
|
# SPDX-FileCopyrightText: 2024 Greenbone AG
|
|
3
3
|
|
|
4
|
+
import importlib.util
|
|
5
|
+
import logging
|
|
4
6
|
import re
|
|
5
7
|
from argparse import ArgumentParser, Namespace
|
|
6
8
|
from dataclasses import dataclass
|
|
7
9
|
from enum import Enum
|
|
8
10
|
from pathlib import Path
|
|
9
|
-
from typing import Iterable
|
|
11
|
+
from typing import Iterable
|
|
10
12
|
|
|
11
13
|
from pontos.terminal.terminal import ConsoleTerminal
|
|
12
14
|
|
|
@@ -19,6 +21,8 @@ from troubadix.helper.patterns import (
|
|
|
19
21
|
)
|
|
20
22
|
from troubadix.troubadix import from_file
|
|
21
23
|
|
|
24
|
+
logger = logging.getLogger(__name__)
|
|
25
|
+
|
|
22
26
|
|
|
23
27
|
class Deprecations(Enum):
|
|
24
28
|
NOTUS = "and replaced by a Notus scanner based one."
|
|
@@ -37,7 +41,21 @@ class DeprecatedFile:
|
|
|
37
41
|
KB_ITEMS_PATTERN = re.compile(r"set_kb_item\(.+\);")
|
|
38
42
|
|
|
39
43
|
|
|
40
|
-
def
|
|
44
|
+
def load_transition_oid_mapping(transition_file: Path) -> dict[str, str]:
|
|
45
|
+
spec = importlib.util.spec_from_file_location(
|
|
46
|
+
"transition_layer", transition_file
|
|
47
|
+
)
|
|
48
|
+
transition_layer = importlib.util.module_from_spec(spec)
|
|
49
|
+
spec.loader.exec_module(transition_layer)
|
|
50
|
+
|
|
51
|
+
return transition_layer.mapping
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def update_summary(
|
|
55
|
+
file: DeprecatedFile,
|
|
56
|
+
deprecation_reason: str,
|
|
57
|
+
replacement_oid: str | None = None,
|
|
58
|
+
) -> str:
|
|
41
59
|
"""Update the summary of the nasl script by adding the information
|
|
42
60
|
that the script has been deprecated, and if possible, the oid of
|
|
43
61
|
the new notus script replacing it.
|
|
@@ -46,21 +64,22 @@ def update_summary(file: DeprecatedFile, deprecation_reason: str) -> str:
|
|
|
46
64
|
file: DeprecatedFile object containing the content of the VT
|
|
47
65
|
deprecation_reason: The reason this VT is being deprecated,
|
|
48
66
|
from a list of options.
|
|
67
|
+
replacement_oid: The OID of the script that replaces this deprecated one.
|
|
49
68
|
|
|
50
69
|
Returns:
|
|
51
70
|
The updated content of the file
|
|
52
71
|
"""
|
|
53
72
|
old_summary = _get_summary(file.content)
|
|
54
73
|
if not old_summary:
|
|
55
|
-
|
|
74
|
+
logger.warning(f"No summary in: {file.name}")
|
|
56
75
|
return file.content
|
|
57
76
|
|
|
58
|
-
deprecate_text =
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
77
|
+
deprecate_text = f"Note: This VT has been deprecated {Deprecations[deprecation_reason].value}"
|
|
78
|
+
|
|
79
|
+
if replacement_oid:
|
|
80
|
+
deprecate_text += f" The replacement VT has OID {replacement_oid}."
|
|
62
81
|
|
|
63
|
-
new_summary = old_summary + "\n" + deprecate_text
|
|
82
|
+
new_summary = old_summary + "\n\n " + deprecate_text
|
|
64
83
|
file.content = file.content.replace(old_summary, new_summary)
|
|
65
84
|
|
|
66
85
|
return file.content
|
|
@@ -71,8 +90,7 @@ def _finalize_content(content: str) -> str:
|
|
|
71
90
|
deprecated tag and removing the extra content."""
|
|
72
91
|
content_to_keep = content.split("exit(0);")[0]
|
|
73
92
|
return content_to_keep + (
|
|
74
|
-
'script_tag(name:"deprecated", value:TRUE)
|
|
75
|
-
"\n\n exit(0);\n}\n\nexit(66);\n"
|
|
93
|
+
'script_tag(name:"deprecated", value:TRUE);\n\n exit(0);\n}\n\nexit(66);\n'
|
|
76
94
|
)
|
|
77
95
|
|
|
78
96
|
|
|
@@ -111,7 +129,7 @@ def parse_files(files: list) -> list[DeprecatedFile]:
|
|
|
111
129
|
return to_deprecate
|
|
112
130
|
|
|
113
131
|
|
|
114
|
-
def _get_summary(content: str) ->
|
|
132
|
+
def _get_summary(content: str) -> str | None:
|
|
115
133
|
"""Extract the summary from the nasl script"""
|
|
116
134
|
pattern = get_script_tag_pattern(ScriptTag.SUMMARY)
|
|
117
135
|
if match_summary := re.search(pattern, content):
|
|
@@ -120,10 +138,34 @@ def _get_summary(content: str) -> Optional[str]:
|
|
|
120
138
|
return None
|
|
121
139
|
|
|
122
140
|
|
|
141
|
+
def find_replacement_oid(
|
|
142
|
+
file: DeprecatedFile,
|
|
143
|
+
oid_mapping: dict[str, str] | None = None,
|
|
144
|
+
) -> str | None:
|
|
145
|
+
# Get replacement OID if available
|
|
146
|
+
if not oid_mapping:
|
|
147
|
+
return None
|
|
148
|
+
|
|
149
|
+
oid_match = re.search(
|
|
150
|
+
get_special_script_tag_pattern(SpecialScriptTag.OID),
|
|
151
|
+
file.content,
|
|
152
|
+
)
|
|
153
|
+
if not oid_match:
|
|
154
|
+
raise ValueError(
|
|
155
|
+
f"No OID found in {file.name}. Cannot map to replacement OID."
|
|
156
|
+
)
|
|
157
|
+
oid = oid_match.group("value")
|
|
158
|
+
replacement_oid = oid_mapping.get(oid)
|
|
159
|
+
if not replacement_oid:
|
|
160
|
+
raise ValueError(f"No replacement OID found for {oid} in {file.name}.")
|
|
161
|
+
return replacement_oid
|
|
162
|
+
|
|
163
|
+
|
|
123
164
|
def deprecate(
|
|
124
165
|
output_path: Path,
|
|
125
166
|
to_deprecate: list[DeprecatedFile],
|
|
126
167
|
deprecation_reason: str,
|
|
168
|
+
oid_mapping: dict[str, str] | None = None,
|
|
127
169
|
) -> None:
|
|
128
170
|
"""Deprecate the selected VTs by removing unnecessary keys, updating the
|
|
129
171
|
summary, and adding the deprecated tag.
|
|
@@ -134,16 +176,19 @@ def deprecate(
|
|
|
134
176
|
to_deprecate: the list of files to be deprecated
|
|
135
177
|
deprecation_reason: The reason this VT is being deprecated,
|
|
136
178
|
from a list of options.
|
|
179
|
+
oid_mapping: Optional mapping of file paths to replacement OIDs
|
|
137
180
|
"""
|
|
138
181
|
output_path.mkdir(parents=True, exist_ok=True)
|
|
139
182
|
for file in to_deprecate:
|
|
140
183
|
if re.findall(KB_ITEMS_PATTERN, file.content):
|
|
141
|
-
|
|
142
|
-
f"Unable to deprecate {file.name}. There are still KB keys "
|
|
143
|
-
f"remaining."
|
|
184
|
+
logger.warning(
|
|
185
|
+
f"Unable to deprecate {file.name}. There are still KB keys remaining."
|
|
144
186
|
)
|
|
145
187
|
continue
|
|
146
|
-
|
|
188
|
+
|
|
189
|
+
replacement_oid = find_replacement_oid(file, oid_mapping)
|
|
190
|
+
|
|
191
|
+
file.content = update_summary(file, deprecation_reason, replacement_oid)
|
|
147
192
|
file.content = _finalize_content(file.content)
|
|
148
193
|
|
|
149
194
|
# Drop any unnecessary script tags like script_dependencies(),
|
|
@@ -229,6 +274,17 @@ def parse_args(args: Iterable[str] = None) -> Namespace:
|
|
|
229
274
|
"to be deprecated, separated by new lines."
|
|
230
275
|
),
|
|
231
276
|
)
|
|
277
|
+
|
|
278
|
+
parser.add_argument(
|
|
279
|
+
"--transition-file",
|
|
280
|
+
metavar="<transition_file>",
|
|
281
|
+
default=None,
|
|
282
|
+
type=file_type_existing,
|
|
283
|
+
help=(
|
|
284
|
+
"Path to a file containing a list of oid mappings."
|
|
285
|
+
"Found in notus/generator/nasl/transition_layer."
|
|
286
|
+
),
|
|
287
|
+
)
|
|
232
288
|
return parser.parse_args(args)
|
|
233
289
|
|
|
234
290
|
|
|
@@ -245,8 +301,17 @@ def main():
|
|
|
245
301
|
elif args.file:
|
|
246
302
|
files = args.file
|
|
247
303
|
|
|
248
|
-
|
|
249
|
-
|
|
304
|
+
# Load OID mapping if provided
|
|
305
|
+
oid_mapping = None
|
|
306
|
+
if args.transition_file:
|
|
307
|
+
oid_mapping = load_transition_oid_mapping(args.transition_file)
|
|
308
|
+
|
|
309
|
+
deprecate(
|
|
310
|
+
args.output_path,
|
|
311
|
+
parse_files(files),
|
|
312
|
+
args.deprecation_reason,
|
|
313
|
+
oid_mapping,
|
|
314
|
+
)
|
|
250
315
|
|
|
251
316
|
|
|
252
317
|
if __name__ == "__main__":
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
# Copyright (C) 2022 Greenbone AG
|
|
2
|
-
#
|
|
3
|
-
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
|
-
#
|
|
5
|
-
# This program is free software: you can redistribute it and/or modify
|
|
6
|
-
# it under the terms of the GNU General Public License as published by
|
|
7
|
-
# the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
# (at your option) any later version.
|
|
9
|
-
#
|
|
10
|
-
# This program is distributed in the hope that it will be useful,
|
|
11
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
# GNU General Public License for more details.
|
|
14
|
-
#
|
|
15
|
-
# You should have received a copy of the GNU General Public License
|
|
16
|
-
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
-
|
|
18
|
-
import re
|
|
19
|
-
from pathlib import Path
|
|
20
|
-
from typing import Iterable, Iterator
|
|
21
|
-
|
|
22
|
-
import charset_normalizer
|
|
23
|
-
|
|
24
|
-
from troubadix.plugin import LineContentPlugin, LinterError, LinterResult
|
|
25
|
-
|
|
26
|
-
# Only the ASCII and extended ASCII for now... # https://www.ascii-code.com/
|
|
27
|
-
# CHAR_SET = r"[^\x00-\xFF]"
|
|
28
|
-
# Temporary only check for chars in between 7f-9f, like in the old Feed-QA...
|
|
29
|
-
INVALID_CHAR_PATTERN = re.compile(r"[\x7F-\x9F]")
|
|
30
|
-
|
|
31
|
-
ALLOWED_ENCODINGS = ["ascii", "latin_1"]
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
class CheckEncoding(LineContentPlugin):
|
|
35
|
-
name = "check_encoding"
|
|
36
|
-
|
|
37
|
-
def check_lines(
|
|
38
|
-
self,
|
|
39
|
-
nasl_file: Path,
|
|
40
|
-
lines: Iterable[str],
|
|
41
|
-
) -> Iterator[LinterResult]:
|
|
42
|
-
match = charset_normalizer.from_path(
|
|
43
|
-
nasl_file, threshold=0.4, cp_isolation=ALLOWED_ENCODINGS
|
|
44
|
-
).best()
|
|
45
|
-
|
|
46
|
-
if not match:
|
|
47
|
-
yield LinterError(
|
|
48
|
-
f"VT uses a wrong encoding. "
|
|
49
|
-
f"Allowed encodings are {', '.join(ALLOWED_ENCODINGS)}.",
|
|
50
|
-
file=nasl_file,
|
|
51
|
-
plugin=self.name,
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
for index, line in enumerate(lines, 1):
|
|
55
|
-
encoding = INVALID_CHAR_PATTERN.search(line)
|
|
56
|
-
if encoding:
|
|
57
|
-
yield LinterError(
|
|
58
|
-
f"Found invalid character in line: {index}",
|
|
59
|
-
file=nasl_file,
|
|
60
|
-
plugin=self.name,
|
|
61
|
-
line=index,
|
|
62
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|