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 <eferollo@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
This commit is contained in:
Francesco Rollo
2024-08-20 11:32:10 +02:00
committed by Jakub Jelen
parent 38932b74c0
commit edbd929fa2
5 changed files with 40 additions and 18 deletions

View File

@@ -107,6 +107,14 @@ static struct argp_option options[] = {
.doc = "Set the authorized keys file.", .doc = "Set the authorized keys file.",
.group = 0 .group = 0
}, },
{
.name = "option",
.key = 'o',
.arg = "OPTION",
.flags = 0,
.doc = "Set server configuration option [-o OptionName=Value]",
.group = 0
},
{ {
.name = "user", .name = "user",
.key = 'u', .key = 'u',
@@ -158,6 +166,9 @@ parse_opt(int key, char *arg, struct argp_state *state)
case 'a': case 'a':
strncpy(authorizedkeys, arg, DEF_STR_SIZE - 1); strncpy(authorizedkeys, arg, DEF_STR_SIZE - 1);
break; break;
case 'o':
ssh_bind_config_parse_string(sshbind, arg);
break;
case 'u': case 'u':
strncpy(username, arg, sizeof(username) - 1); strncpy(username, arg, sizeof(username) - 1);
break; break;
@@ -194,7 +205,7 @@ parse_opt(int argc, char **argv, ssh_bind sshbind)
{ {
int key; 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') { if (key == 'p') {
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, optarg); ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, optarg);
} else if (key == 'k') { } 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); ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, optarg);
} else if (key == 'a') { } else if (key == 'a') {
strncpy(authorizedkeys, optarg, DEF_STR_SIZE-1); strncpy(authorizedkeys, optarg, DEF_STR_SIZE-1);
} else if (key == 'o') {
ssh_bind_config_parse_string(sshbind, optarg);
} else if (key == 'u') { } else if (key == 'u') {
strncpy(username, optarg, sizeof(username) - 1); strncpy(username, optarg, sizeof(username) - 1);
} else if (key == 'P') { } 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" "libssh %s -- a Secure Shell protocol implementation\n"
"\n" "\n"
" -a, --authorizedkeys=FILE Set the authorized keys file.\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" " -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" " -k, --hostkey=FILE Set a host key. Can be used multiple times.\n"
" Implies no default keys.\n" " Implies no default keys.\n"

View File

@@ -66,16 +66,6 @@ enum ssh_bind_config_opcode_e {
*/ */
int ssh_bind_config_parse_file(ssh_bind sshbind, const char *filename); 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 #ifdef __cplusplus
} }
#endif #endif

View File

@@ -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, LIBSSH_API int ssh_bind_options_parse_config(ssh_bind sshbind,
const char *filename); const char *filename);
LIBSSH_API int ssh_bind_config_parse_string(ssh_bind bind, const char *input);
/** /**
* @brief Start listening to the socket. * @brief Start listening to the socket.
* *

View File

@@ -676,7 +676,9 @@ int ssh_bind_config_parse_file(ssh_bind bind, const char *filename)
return 0; 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] bind The ssh bind session
* @params[in] input Null terminated string containing the configuration * @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) { if (c == NULL) {
/* should not happen, would mean a string without trailing '\0' */ /* 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; return SSH_ERROR;
} }
line_len = c - line_start; line_len = c - line_start;
if (line_len > MAX_LINE_SIZE - 1) { if (line_len > MAX_LINE_SIZE - 1) {
SSH_LOG(SSH_LOG_WARN, ssh_set_error(bind,
"Line %u too long: %zu characters", SSH_FATAL,
line_num, "Line %u too long: %zu characters",
line_len); line_num,
line_len);
return SSH_ERROR; return SSH_ERROR;
} }
memcpy(line, line_start, line_len); memcpy(line, line_start, line_len);
line[line_len] = '\0'; line[line_len] = '\0';
SSH_LOG(SSH_LOG_DEBUG, "Line %u: %s", line_num, line); 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) { if (rv < 0) {
return SSH_ERROR; return SSH_ERROR;
} }

View File

@@ -507,3 +507,9 @@ LIBSSH_4_11_0 # Released
sshsig_verify; sshsig_verify;
} LIBSSH_4_10_0; } LIBSSH_4_10_0;
LIBSSH_AFTER_4_11_0
{
global:
ssh_bind_config_parse_string;
} LIBSSH_4_11_0;