mirror of
https://git.libssh.org/projects/libssh.git
synced 2025-11-29 01:03:57 +03:00
options: Add a bind option to set the config directory
This adds the SSH_BIND_OPTIONS_CONFIG_DIR which allows to set the directory used to expand the escape character "%d" when passing a path to ssh_bind_options_parse_file(). Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
committed by
Andreas Schneider
parent
fd25beff68
commit
68385a2e98
@@ -47,6 +47,7 @@ struct ssh_bind_struct {
|
|||||||
int blocking;
|
int blocking;
|
||||||
int toaccept;
|
int toaccept;
|
||||||
bool config_processed;
|
bool config_processed;
|
||||||
|
char *config_dir;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ssh_poll_handle_struct *ssh_bind_get_poll(struct ssh_bind_struct
|
struct ssh_poll_handle_struct *ssh_bind_get_poll(struct ssh_bind_struct
|
||||||
|
|||||||
@@ -51,7 +51,8 @@ enum ssh_bind_options_e {
|
|||||||
SSH_BIND_OPTIONS_CIPHERS_C_S,
|
SSH_BIND_OPTIONS_CIPHERS_C_S,
|
||||||
SSH_BIND_OPTIONS_CIPHERS_S_C,
|
SSH_BIND_OPTIONS_CIPHERS_S_C,
|
||||||
SSH_BIND_OPTIONS_HMAC_C_S,
|
SSH_BIND_OPTIONS_HMAC_C_S,
|
||||||
SSH_BIND_OPTIONS_HMAC_S_C
|
SSH_BIND_OPTIONS_HMAC_S_C,
|
||||||
|
SSH_BIND_OPTIONS_CONFIG_DIR,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct ssh_bind_struct* ssh_bind;
|
typedef struct ssh_bind_struct* ssh_bind;
|
||||||
|
|||||||
@@ -393,6 +393,7 @@ void ssh_bind_free(ssh_bind sshbind){
|
|||||||
/* options */
|
/* options */
|
||||||
SAFE_FREE(sshbind->banner);
|
SAFE_FREE(sshbind->banner);
|
||||||
SAFE_FREE(sshbind->bindaddr);
|
SAFE_FREE(sshbind->bindaddr);
|
||||||
|
SAFE_FREE(sshbind->config_dir);
|
||||||
|
|
||||||
SAFE_FREE(sshbind->dsakey);
|
SAFE_FREE(sshbind->dsakey);
|
||||||
SAFE_FREE(sshbind->rsakey);
|
SAFE_FREE(sshbind->rsakey);
|
||||||
|
|||||||
104
src/options.c
104
src/options.c
@@ -1602,6 +1602,11 @@ static int ssh_bind_set_algo(ssh_bind sshbind,
|
|||||||
* Set the Message Authentication Code algorithm server
|
* Set the Message Authentication Code algorithm server
|
||||||
* to client (const char *, comma-separated list).
|
* to client (const char *, comma-separated list).
|
||||||
*
|
*
|
||||||
|
* - SSH_BIND_OPTIONS_CONFIG_DIR:
|
||||||
|
* Set the directory (const char *, format string)
|
||||||
|
* to be used when the "%d" scape is used when providing
|
||||||
|
* paths of configuration files to
|
||||||
|
* ssh_bind_options_parse_config().
|
||||||
*
|
*
|
||||||
* @param value The value to set. This is a generic pointer and the
|
* @param value The value to set. This is a generic pointer and the
|
||||||
* datatype which should be used is described at the
|
* datatype which should be used is described at the
|
||||||
@@ -1887,6 +1892,22 @@ int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SSH_BIND_OPTIONS_CONFIG_DIR:
|
||||||
|
v = value;
|
||||||
|
SAFE_FREE(sshbind->config_dir);
|
||||||
|
if (v == NULL) {
|
||||||
|
break;
|
||||||
|
} else if (v[0] == '\0') {
|
||||||
|
ssh_set_error_invalid(sshbind);
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
sshbind->config_dir = ssh_path_expand_tilde(v);
|
||||||
|
if (sshbind->config_dir == NULL) {
|
||||||
|
ssh_set_error_oom(sshbind);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ssh_set_error(sshbind, SSH_REQUEST_DENIED, "Unknown ssh option %d", type);
|
ssh_set_error(sshbind, SSH_REQUEST_DENIED, "Unknown ssh option %d", type);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1896,6 +1917,80 @@ int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *ssh_bind_options_expand_escape(ssh_bind sshbind, const char *s)
|
||||||
|
{
|
||||||
|
char buf[MAX_BUF_SIZE];
|
||||||
|
char *r, *x = NULL;
|
||||||
|
const char *p;
|
||||||
|
size_t i, l;
|
||||||
|
|
||||||
|
r = ssh_path_expand_tilde(s);
|
||||||
|
if (r == NULL) {
|
||||||
|
ssh_set_error_oom(sshbind);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(r) > MAX_BUF_SIZE) {
|
||||||
|
ssh_set_error(sshbind, SSH_FATAL, "string to expand too long");
|
||||||
|
free(r);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = r;
|
||||||
|
buf[0] = '\0';
|
||||||
|
|
||||||
|
for (i = 0; *p != '\0'; p++) {
|
||||||
|
if (*p != '%') {
|
||||||
|
buf[i] = *p;
|
||||||
|
i++;
|
||||||
|
if (i >= MAX_BUF_SIZE) {
|
||||||
|
free(r);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
buf[i] = '\0';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
p++;
|
||||||
|
if (*p == '\0') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (*p) {
|
||||||
|
case 'd':
|
||||||
|
x = strdup(sshbind->config_dir);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ssh_set_error(sshbind, SSH_FATAL,
|
||||||
|
"Wrong escape sequence detected");
|
||||||
|
free(r);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x == NULL) {
|
||||||
|
ssh_set_error_oom(sshbind);
|
||||||
|
free(r);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
i += strlen(x);
|
||||||
|
if (i >= MAX_BUF_SIZE) {
|
||||||
|
ssh_set_error(sshbind, SSH_FATAL,
|
||||||
|
"String too long");
|
||||||
|
free(x);
|
||||||
|
free(r);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
l = strlen(buf);
|
||||||
|
strncpy(buf + l, x, sizeof(buf) - l - 1);
|
||||||
|
buf[i] = '\0';
|
||||||
|
SAFE_FREE(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(r);
|
||||||
|
return strdup(buf);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Parse a ssh bind options configuration file.
|
* @brief Parse a ssh bind options configuration file.
|
||||||
*
|
*
|
||||||
@@ -1914,6 +2009,7 @@ int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type,
|
|||||||
int ssh_bind_options_parse_config(ssh_bind sshbind, const char *filename)
|
int ssh_bind_options_parse_config(ssh_bind sshbind, const char *filename)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
char *expanded_filename;
|
||||||
|
|
||||||
if (sshbind == NULL) {
|
if (sshbind == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1931,8 +2027,14 @@ int ssh_bind_options_parse_config(ssh_bind sshbind, const char *filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (filename != NULL) {
|
if (filename != NULL) {
|
||||||
|
expanded_filename = ssh_bind_options_expand_escape(sshbind, filename);
|
||||||
|
if (expanded_filename == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Apply the user provided configuration */
|
/* Apply the user provided configuration */
|
||||||
rc = ssh_bind_config_parse_file(sshbind, filename);
|
rc = ssh_bind_config_parse_file(sshbind, expanded_filename);
|
||||||
|
free(expanded_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
|||||||
@@ -1301,6 +1301,7 @@ static void torture_bind_options_parse_config(void **state)
|
|||||||
{
|
{
|
||||||
struct bind_st *test_state;
|
struct bind_st *test_state;
|
||||||
ssh_bind bind;
|
ssh_bind bind;
|
||||||
|
char *cwd = NULL;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
assert_non_null(state);
|
assert_non_null(state);
|
||||||
@@ -1309,11 +1310,53 @@ static void torture_bind_options_parse_config(void **state)
|
|||||||
assert_non_null(test_state->bind);
|
assert_non_null(test_state->bind);
|
||||||
bind = test_state->bind;
|
bind = test_state->bind;
|
||||||
|
|
||||||
rc = ssh_bind_options_parse_config(bind, LIBSSH_CUSTOM_BIND_CONFIG_FILE);
|
cwd = torture_get_current_working_dir();
|
||||||
|
assert_non_null(cwd);
|
||||||
|
|
||||||
|
rc = ssh_bind_options_set(bind,
|
||||||
|
SSH_BIND_OPTIONS_CONFIG_DIR,
|
||||||
|
(const char *)cwd);
|
||||||
|
assert_int_equal(rc, 0);
|
||||||
|
assert_non_null(bind->config_dir);
|
||||||
|
assert_string_equal(bind->config_dir, cwd);
|
||||||
|
|
||||||
|
rc = ssh_bind_options_parse_config(bind, "%d/"LIBSSH_CUSTOM_BIND_CONFIG_FILE);
|
||||||
assert_int_equal(rc, 0);
|
assert_int_equal(rc, 0);
|
||||||
assert_int_equal(bind->bindport, 42);
|
assert_int_equal(bind->bindport, 42);
|
||||||
|
|
||||||
|
SAFE_FREE(cwd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void torture_bind_options_config_dir(void **state)
|
||||||
|
{
|
||||||
|
struct bind_st *test_state;
|
||||||
|
ssh_bind bind;
|
||||||
|
const char *new_dir = "/new/dir/";
|
||||||
|
const char *replacement_dir = "/replacement/dir/";
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
assert_non_null(state);
|
||||||
|
test_state = *((struct bind_st **)state);
|
||||||
|
assert_non_null(test_state);
|
||||||
|
assert_non_null(test_state->bind);
|
||||||
|
bind = test_state->bind;
|
||||||
|
|
||||||
|
rc = ssh_bind_options_set(bind,
|
||||||
|
SSH_BIND_OPTIONS_CONFIG_DIR,
|
||||||
|
new_dir);
|
||||||
|
assert_int_equal(rc, 0);
|
||||||
|
assert_non_null(bind->config_dir);
|
||||||
|
assert_string_equal(bind->config_dir, new_dir);
|
||||||
|
|
||||||
|
rc = ssh_bind_options_set(bind,
|
||||||
|
SSH_BIND_OPTIONS_CONFIG_DIR,
|
||||||
|
replacement_dir);
|
||||||
|
assert_int_equal(rc, 0);
|
||||||
|
assert_non_null(bind->config_dir);
|
||||||
|
assert_string_equal(bind->config_dir, replacement_dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* WITH_SERVER */
|
#endif /* WITH_SERVER */
|
||||||
|
|
||||||
|
|
||||||
@@ -1381,6 +1424,8 @@ int torture_run_tests(void) {
|
|||||||
sshbind_setup, sshbind_teardown),
|
sshbind_setup, sshbind_teardown),
|
||||||
cmocka_unit_test_setup_teardown(torture_bind_options_parse_config,
|
cmocka_unit_test_setup_teardown(torture_bind_options_parse_config,
|
||||||
sshbind_setup, sshbind_teardown),
|
sshbind_setup, sshbind_teardown),
|
||||||
|
cmocka_unit_test_setup_teardown(torture_bind_options_config_dir,
|
||||||
|
sshbind_setup, sshbind_teardown),
|
||||||
};
|
};
|
||||||
#endif /* WITH_SERVER */
|
#endif /* WITH_SERVER */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user