diff --git a/include/libssh/bind_config.h b/include/libssh/bind_config.h index 5f2dccce..54346d8e 100644 --- a/include/libssh/bind_config.h +++ b/include/libssh/bind_config.h @@ -52,6 +52,7 @@ enum ssh_bind_config_opcode_e { BIND_CFG_MATCH, BIND_CFG_PUBKEY_ACCEPTED_KEY_TYPES, BIND_CFG_HOSTKEY_ALGORITHMS, + BIND_CFG_REQUIRED_RSA_SIZE, BIND_CFG_MAX /* Keep this one last in the list */ }; diff --git a/include/libssh/config.h b/include/libssh/config.h index 4f8a9b6f..d285abdc 100644 --- a/include/libssh/config.h +++ b/include/libssh/config.h @@ -66,6 +66,7 @@ enum ssh_config_opcode_e { SOC_CONTROLMASTER, SOC_CONTROLPATH, SOC_CERTIFICATE, + SOC_REQUIRED_RSA_SIZE, SOC_MAX /* Keep this one last in the list */ }; diff --git a/src/bind_config.c b/src/bind_config.c index 62d068bd..cf5f34cb 100644 --- a/src/bind_config.c +++ b/src/bind_config.c @@ -104,6 +104,11 @@ ssh_bind_config_keyword_table[] = { .opcode = BIND_CFG_HOSTKEY_ALGORITHMS, .allowed_in_match = true }, + { + .name = "requiredrsasize", + .opcode = BIND_CFG_REQUIRED_RSA_SIZE, + .allowed_in_match = true + }, { .opcode = BIND_CFG_UNKNOWN, } @@ -293,6 +298,7 @@ ssh_bind_config_parse_line(ssh_bind bind, const char *p = NULL; char *s = NULL, *x = NULL; char *keyword = NULL; + long l; size_t len; int rc = 0; @@ -594,6 +600,18 @@ ssh_bind_config_parse_line(ssh_bind bind, } } break; + case BIND_CFG_REQUIRED_RSA_SIZE: + l = ssh_config_get_long(&s, -1); + if (l >= 0 && (*parser_flags & PARSING)) { + rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_RSA_MIN_SIZE, &l); + if (rc != 0) { + SSH_LOG(SSH_LOG_TRACE, + "line %d: Failed to set RequiredRSASize value '%ld'", + count, + l); + } + } + break; case BIND_CFG_NOT_ALLOWED_IN_MATCH: SSH_LOG(SSH_LOG_DEBUG, "Option not allowed in Match block: %s, line: %d", keyword, count); diff --git a/src/config.c b/src/config.c index be105222..daa65ff7 100644 --- a/src/config.c +++ b/src/config.c @@ -153,6 +153,7 @@ static struct ssh_config_keyword_table_s ssh_config_keyword_table[] = { { "tunneldevice", SOC_NA}, { "xauthlocation", SOC_NA}, { "pubkeyacceptedkeytypes", SOC_PUBKEYACCEPTEDKEYTYPES}, + { "requiredrsasize", SOC_REQUIRED_RSA_SIZE}, { NULL, SOC_UNKNOWN } }; @@ -1439,6 +1440,12 @@ ssh_config_parse_line(ssh_session session, ssh_options_set(session, SSH_OPTIONS_CERTIFICATE, p); } break; + case SOC_REQUIRED_RSA_SIZE: + l = ssh_config_get_long(&s, -1); + if (l >= 0 && *parsing) { + ssh_options_set(session, SSH_OPTIONS_RSA_MIN_SIZE, &l); + } + break; default: ssh_set_error(session, SSH_FATAL, "ERROR - unimplemented opcode: %d", opcode); diff --git a/tests/unittests/torture_bind_config.c b/tests/unittests/torture_bind_config.c index a2f9be06..514727e5 100644 --- a/tests/unittests/torture_bind_config.c +++ b/tests/unittests/torture_bind_config.c @@ -145,6 +145,9 @@ extern LIBSSH_THREAD int ssh_log_level; "KexAlgorithms "KEXALGORITHMS"\n" \ "Include "LIBSSH_TEST_BIND_CONFIG_KEXALGORITHMS2"\n" +#define LIBSSH_TEST_BIND_CONFIG_REQUIRED_RSA_SIZE "libssh_test_bind_config_required_rsa_size" +#define LIBSSH_TEST_BIND_CONFIG_REQUIRED_RSA_SIZE_STRING "RequiredRsaSize 2233\n" + #define LIBSSH_TEST_BIND_CONFIG_FULL "libssh_test_bind_config_full" #define LIBSSH_TEST_BIND_CONFIG_INCLUDE "libssh_test_bind_config_include" #define LIBSSH_TEST_BIND_CONFIG_INCLUDE_RECURSIVE "libssh_test_bind_config_include_recursive" @@ -298,6 +301,9 @@ static int setup_config_files(void **state) torture_write_file(LIBSSH_TEST_BIND_CONFIG_KEXALGORITHMS_TWICE_REC, LIBSSH_TEST_BIND_CONFIG_KEXALGORITHMS_TWICE_REC_STRING); + torture_write_file(LIBSSH_TEST_BIND_CONFIG_REQUIRED_RSA_SIZE, + LIBSSH_TEST_BIND_CONFIG_REQUIRED_RSA_SIZE_STRING); + torture_write_file(LIBSSH_TEST_BIND_CONFIG_FULL, "ListenAddress "LISTEN_ADDRESS"\n" "Port 123\n" @@ -305,7 +311,8 @@ static int setup_config_files(void **state) "LogLevel "LOGLEVEL"\n" "Ciphers "CIPHERS"\n" "MACs "MACS"\n" - "KexAlgorithms "KEXALGORITHMS"\n"); + "KexAlgorithms "KEXALGORITHMS"\n" + "RequiredRsaSize 2233\n"); torture_write_file(LIBSSH_TEST_BIND_CONFIG_INCLUDE, "Include "LIBSSH_TEST_BIND_CONFIG_LISTENADDRESS"\n" @@ -314,7 +321,8 @@ static int setup_config_files(void **state) "Include "LIBSSH_TEST_BIND_CONFIG_LOGLEVEL"\n" "Include "LIBSSH_TEST_BIND_CONFIG_CIPHERS"\n" "Include "LIBSSH_TEST_BIND_CONFIG_MACS"\n" - "Include "LIBSSH_TEST_BIND_CONFIG_KEXALGORITHMS"\n"); + "Include "LIBSSH_TEST_BIND_CONFIG_KEXALGORITHMS"\n" + "Include "LIBSSH_TEST_BIND_CONFIG_REQUIRED_RSA_SIZE"\n"); torture_write_file(LIBSSH_TEST_BIND_CONFIG_INCLUDE_RECURSIVE, "Include "LIBSSH_TEST_BIND_CONFIG_INCLUDE"\n"); @@ -1410,6 +1418,8 @@ static int assert_full_bind_config(void **state) assert_string_equal(bind->wanted_methods[SSH_KEX], KEXALGORITHMS); } + assert_int_equal(bind->rsa_min_size, 2233); + SAFE_FREE(fips_ciphers); SAFE_FREE(fips_kex); diff --git a/tests/unittests/torture_config.c b/tests/unittests/torture_config.c index 75249fe7..7cd0f2e2 100644 --- a/tests/unittests/torture_config.c +++ b/tests/unittests/torture_config.c @@ -90,7 +90,8 @@ extern LIBSSH_THREAD int ssh_log_level; "\tGSSAPIDelegateCredentials yes\n" \ "\tGSSAPIServerIdentity example.com\n" \ "\tGSSAPIClientIdentity home.sweet\n" \ - "\tUserKnownHostsFile "USER_KNOWN_HOSTS"\n" + "\tUserKnownHostsFile "USER_KNOWN_HOSTS"\n" \ + "\tRequiredRSASize 2233\n" /* authentication methods */ #define LIBSSH_TESTCONFIG_STRING8 \ @@ -629,6 +630,7 @@ static void torture_config_new(void ** state, assert_int_equal(ssh_get_log_level(), SSH_LOG_TRACE); assert_int_equal(session->common.log_verbosity, SSH_LOG_TRACE); + assert_int_equal(session->opts.rsa_min_size, 2233); } static void torture_config_new_file(void **state)