From 3217ead5c28a55d8eedc400957e05735e0f94db6 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 9 Mar 2022 20:53:08 +0100 Subject: [PATCH 16/39] OpenSSH Config Scanner: Record the presence of subsystem option --- .../common/actors/opensshconfigscanner/actor.py | 1 + .../libraries/readopensshconfig.py | 6 ++++++ ...test_readopensshconfig_opensshconfigscanner.py | 15 +++++++++++++++ .../system_upgrade/common/models/opensshconfig.py | 7 +++++-- 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/repos/system_upgrade/common/actors/opensshconfigscanner/actor.py b/repos/system_upgrade/common/actors/opensshconfigscanner/actor.py index df194559..4553f3e8 100644 --- a/repos/system_upgrade/common/actors/opensshconfigscanner/actor.py +++ b/repos/system_upgrade/common/actors/opensshconfigscanner/actor.py @@ -15,6 +15,7 @@ class OpenSshConfigScanner(Actor): * Protocol * Ciphers * MACs + * Subsystem sftp """ diff --git a/repos/system_upgrade/common/actors/opensshconfigscanner/libraries/readopensshconfig.py b/repos/system_upgrade/common/actors/opensshconfigscanner/libraries/readopensshconfig.py index 3b70486a..4a8df194 100644 --- a/repos/system_upgrade/common/actors/opensshconfigscanner/libraries/readopensshconfig.py +++ b/repos/system_upgrade/common/actors/opensshconfigscanner/libraries/readopensshconfig.py @@ -61,6 +61,12 @@ def parse_config(config): if not ret.macs: ret.macs = value + elif el[0].lower() == 'subsystem': + # Record only first occurence, which is effective + if el[1].lower() == 'sftp' and len(el) > 2 and not ret.subsystem_sftp: + # here we need to record all remaining items as command and arguments + ret.subsystem_sftp = ' '.join(el[2:]) + elif el[0].lower() in DEPRECATED_DIRECTIVES: # Filter out duplicit occurences of the same deprecated directive if el[0].lower() not in ret.deprecated_directives: diff --git a/repos/system_upgrade/common/actors/opensshconfigscanner/tests/test_readopensshconfig_opensshconfigscanner.py b/repos/system_upgrade/common/actors/opensshconfigscanner/tests/test_readopensshconfig_opensshconfigscanner.py index 8fa5837b..48d24b28 100644 --- a/repos/system_upgrade/common/actors/opensshconfigscanner/tests/test_readopensshconfig_opensshconfigscanner.py +++ b/repos/system_upgrade/common/actors/opensshconfigscanner/tests/test_readopensshconfig_opensshconfigscanner.py @@ -24,6 +24,8 @@ def test_parse_config(): "hostkey /etc/ssh/ssh_host_ed25519_key", "ciphers aes128-ctr", "macs hmac-md5", + "subsystem sftp internal-sftp", + "subsystem other internal-other", # this is ignored ] output = parse_config(config) @@ -34,6 +36,7 @@ def test_parse_config(): assert output.protocol == "2" assert output.ciphers == "aes128-ctr" assert output.macs == "hmac-md5" + assert output.subsystem_sftp == "internal-sftp" def test_parse_config_case(): @@ -41,6 +44,7 @@ def test_parse_config_case(): "PermitRootLogin prohibit-password", "UsePrivilegeSeparation yes", "Protocol 1", + "SubSystem sftp sftp-server", ] output = parse_config(config) @@ -49,6 +53,7 @@ def test_parse_config_case(): assert output.permit_root_login[0].value == "prohibit-password" assert output.use_privilege_separation == "yes" assert output.protocol == "1" + assert output.subsystem_sftp == "sftp-server" def test_parse_config_multiple(): @@ -58,6 +63,8 @@ def test_parse_config_multiple(): "PermitRootLogin yes", "Ciphers aes128-cbc", "Ciphers aes256-cbc", + "subsystem sftp internal-sftp", + "subsystem sftp internal-sftp2", ] output = parse_config(config) @@ -69,6 +76,7 @@ def test_parse_config_multiple(): assert output.use_privilege_separation is None assert output.protocol is None assert output.ciphers == 'aes128-cbc' + assert output.subsystem_sftp == 'internal-sftp' def test_parse_config_commented(): @@ -76,6 +84,7 @@ def test_parse_config_commented(): "#PermitRootLogin no", "#UsePrivilegeSeparation no", "#Protocol 12", + "#SubSystem sftp internal-sftp", ] output = parse_config(config) @@ -83,6 +92,7 @@ def test_parse_config_commented(): assert not output.permit_root_login assert output.use_privilege_separation is None assert output.protocol is None + assert output.subsystem_sftp is None def test_parse_config_missing_argument(): @@ -90,6 +100,8 @@ def test_parse_config_missing_argument(): "PermitRootLogin", "UsePrivilegeSeparation", "Protocol" + "SubSystem" + "SubSystem sftp" ] output = parse_config(config) @@ -97,6 +109,7 @@ def test_parse_config_missing_argument(): assert not output.permit_root_login assert output.use_privilege_separation is None assert output.protocol is None + assert output.subsystem_sftp is None def test_parse_config_match(): @@ -174,6 +187,7 @@ def test_produce_config(): use_privilege_separation="yes", protocol="1", deprecated_directives=[], + subsystem_sftp="internal-sftp", ) produce_config(fake_producer, config) @@ -183,6 +197,7 @@ def test_produce_config(): assert cfg.permit_root_login[0].value == "no" assert cfg.use_privilege_separation == "yes" assert cfg.protocol == '1' + assert cfg.subsystem_sftp == 'internal-sftp' def test_actor_execution(current_actor_context): diff --git a/repos/system_upgrade/common/models/opensshconfig.py b/repos/system_upgrade/common/models/opensshconfig.py index 934c9da3..e94c6881 100644 --- a/repos/system_upgrade/common/models/opensshconfig.py +++ b/repos/system_upgrade/common/models/opensshconfig.py @@ -34,7 +34,10 @@ class OpenSshConfig(Model): """ Value of the Ciphers directive, if present. Ciphers separated by comma. """ macs = fields.Nullable(fields.String()) """ Value of the MACs directive, if present. """ - modified = fields.Boolean(default=False) - """ True if the configuration file was modified. """ deprecated_directives = fields.List(fields.String()) """ Configuration directives that were deprecated in the new version of openssh. """ + subsystem_sftp = fields.Nullable(fields.String()) + """ The "Subsystem sftp" configuration option, if present """ + + modified = fields.Boolean(default=False) + """ True if the configuration file was modified. """ -- 2.35.3