From edbd929fa2895a972e79575a0040232b577f8de4 Mon Sep 17 00:00:00 2001 From: Francesco Rollo Date: Tue, 20 Aug 2024 11:32:10 +0200 Subject: [PATCH] feat(server): Add support for -o option argument in server example Allow passing server configuration options via the -o flag and expose ssh_bind_config_parse_string() as a public API. Signed-off-by: Francesco Reviewed-by: Jakub Jelen --- examples/ssh_server.c | 16 +++++++++++++++- include/libssh/bind_config.h | 10 ---------- include/libssh/server.h | 2 ++ src/bind_config.c | 24 +++++++++++++++++------- src/libssh.map | 6 ++++++ 5 files changed, 40 insertions(+), 18 deletions(-) diff --git a/examples/ssh_server.c b/examples/ssh_server.c index fb1541d9..592ce445 100644 --- a/examples/ssh_server.c +++ b/examples/ssh_server.c @@ -107,6 +107,14 @@ static struct argp_option options[] = { .doc = "Set the authorized keys file.", .group = 0 }, + { + .name = "option", + .key = 'o', + .arg = "OPTION", + .flags = 0, + .doc = "Set server configuration option [-o OptionName=Value]", + .group = 0 + }, { .name = "user", .key = 'u', @@ -158,6 +166,9 @@ parse_opt(int key, char *arg, struct argp_state *state) case 'a': strncpy(authorizedkeys, arg, DEF_STR_SIZE - 1); break; + case 'o': + ssh_bind_config_parse_string(sshbind, arg); + break; case 'u': strncpy(username, arg, sizeof(username) - 1); break; @@ -194,7 +205,7 @@ parse_opt(int argc, char **argv, ssh_bind sshbind) { int key; - while((key = getopt(argc, argv, "a:e:k:p:P:r:u:v")) != -1) { + while((key = getopt(argc, argv, "a:e:k:o:p:P:r:u:v")) != -1) { if (key == 'p') { ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, optarg); } else if (key == 'k') { @@ -205,6 +216,8 @@ parse_opt(int argc, char **argv, ssh_bind sshbind) ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, optarg); } else if (key == 'a') { strncpy(authorizedkeys, optarg, DEF_STR_SIZE-1); + } else if (key == 'o') { + ssh_bind_config_parse_string(sshbind, optarg); } else if (key == 'u') { strncpy(username, optarg, sizeof(username) - 1); } else if (key == 'P') { @@ -222,6 +235,7 @@ parse_opt(int argc, char **argv, ssh_bind sshbind) "libssh %s -- a Secure Shell protocol implementation\n" "\n" " -a, --authorizedkeys=FILE Set the authorized keys file.\n" + " -o, --option=OPTION Set server configuration option (e.g., -o OptionName=Value).\n" " -e, --ecdsakey=FILE Set the ecdsa key (deprecated alias for 'k').\n" " -k, --hostkey=FILE Set a host key. Can be used multiple times.\n" " Implies no default keys.\n" diff --git a/include/libssh/bind_config.h b/include/libssh/bind_config.h index 54346d8e..3271b5bf 100644 --- a/include/libssh/bind_config.h +++ b/include/libssh/bind_config.h @@ -66,16 +66,6 @@ enum ssh_bind_config_opcode_e { */ int ssh_bind_config_parse_file(ssh_bind sshbind, const char *filename); -/* @brief Parse configuration string and set the options to the given bind session - * - * @params[in] bind The ssh bind session - * @params[in] input Null terminated string containing the configuration - * - * @returns SSH_OK on successful parsing the configuration string, - * SSH_ERROR on error - */ -int ssh_bind_config_parse_string(ssh_bind bind, const char *input); - #ifdef __cplusplus } #endif diff --git a/include/libssh/server.h b/include/libssh/server.h index ee800567..fb420bf7 100644 --- a/include/libssh/server.h +++ b/include/libssh/server.h @@ -102,6 +102,8 @@ LIBSSH_API int ssh_bind_options_set(ssh_bind sshbind, LIBSSH_API int ssh_bind_options_parse_config(ssh_bind sshbind, const char *filename); +LIBSSH_API int ssh_bind_config_parse_string(ssh_bind bind, const char *input); + /** * @brief Start listening to the socket. * diff --git a/src/bind_config.c b/src/bind_config.c index a8bf3703..77fe8bc4 100644 --- a/src/bind_config.c +++ b/src/bind_config.c @@ -676,7 +676,9 @@ int ssh_bind_config_parse_file(ssh_bind bind, const char *filename) return 0; } -/* @brief Parse configuration string and set the options to the given bind session +/** + * @brief Parse configuration string and set the options to the given bind + * session * * @params[in] bind The ssh bind session * @params[in] input Null terminated string containing the configuration @@ -713,21 +715,29 @@ int ssh_bind_config_parse_string(ssh_bind bind, const char *input) } if (c == NULL) { /* should not happen, would mean a string without trailing '\0' */ - SSH_LOG(SSH_LOG_WARN, "No trailing '\\0' in config string"); + ssh_set_error(bind, + SSH_FATAL, + "No trailing '\\0' in config string"); return SSH_ERROR; } line_len = c - line_start; if (line_len > MAX_LINE_SIZE - 1) { - SSH_LOG(SSH_LOG_WARN, - "Line %u too long: %zu characters", - line_num, - line_len); + ssh_set_error(bind, + SSH_FATAL, + "Line %u too long: %zu characters", + line_num, + line_len); return SSH_ERROR; } memcpy(line, line_start, line_len); line[line_len] = '\0'; SSH_LOG(SSH_LOG_DEBUG, "Line %u: %s", line_num, line); - rv = ssh_bind_config_parse_line(bind, line, line_num, &parser_flags, seen, 0); + rv = ssh_bind_config_parse_line(bind, + line, + line_num, + &parser_flags, + seen, + 0); if (rv < 0) { return SSH_ERROR; } diff --git a/src/libssh.map b/src/libssh.map index 3f16299e..d0390d36 100644 --- a/src/libssh.map +++ b/src/libssh.map @@ -507,3 +507,9 @@ LIBSSH_4_11_0 # Released sshsig_verify; } LIBSSH_4_10_0; +LIBSSH_AFTER_4_11_0 +{ + global: + ssh_bind_config_parse_string; +} LIBSSH_4_11_0; +