support in ~/ and SSH_DIR/ in filenames instead of %s/
Get rid of snprintf to fixed sized buffers in setting options. Instead make locations starting with ~/ relative to the users initial working directory (as libssh does not look into the home directory but only at the initial home directory). and starting with SSH_DIR/ relative to the configured ssh directory.
Этот коммит содержится в:
родитель
0f77578ee2
Коммит
f643c34ee8
@ -236,6 +236,41 @@ static int ssh_options_set_algo(ssh_options opt, int algo, const char *list) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *dir_expand_dup(ssh_options opt, const char *value, int allowsshdir) {
|
||||
char *n;
|
||||
|
||||
if (value[0] == '~' && value[1] == '/') {
|
||||
const char *homedir = ssh_get_user_home_dir();
|
||||
size_t lv = strlen(value + 1), lh = strlen(homedir);
|
||||
|
||||
n = malloc(lv + lh + 1);
|
||||
if (n == NULL)
|
||||
return NULL;
|
||||
memcpy(n, homedir, lh);
|
||||
memcpy(n + lh + 1, value + 1, lv + 1);
|
||||
return n;
|
||||
}
|
||||
if (allowsshdir && strncmp(value, "SSH_DIR/", 8) == 0) {
|
||||
size_t lv, ls;
|
||||
if (opt->ssh_dir == NULL) {
|
||||
if (ssh_options_set(opt, SSH_OPTIONS_SSH_DIR, NULL) < 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
value += 7;
|
||||
lv = strlen(value);
|
||||
ls = strlen(opt->ssh_dir);
|
||||
|
||||
n = malloc(lv + ls + 1);
|
||||
if (n == NULL)
|
||||
return NULL;
|
||||
memcpy(n, opt->ssh_dir, ls);
|
||||
memcpy(n + ls + 1, value, lv + 1);
|
||||
return n;
|
||||
}
|
||||
return strdup(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function can set all possible ssh options.
|
||||
*
|
||||
@ -390,7 +425,6 @@ static int ssh_options_set_algo(ssh_options opt, int algo, const char *list) {
|
||||
*/
|
||||
int ssh_options_set(ssh_options opt, enum ssh_options_e type,
|
||||
const void *value) {
|
||||
char buf[1024] = {0};
|
||||
char *p, *q;
|
||||
int i;
|
||||
|
||||
@ -484,16 +518,16 @@ int ssh_options_set(ssh_options opt, enum ssh_options_e type,
|
||||
break;
|
||||
case SSH_OPTIONS_SSH_DIR:
|
||||
if (value == NULL) {
|
||||
snprintf(buf, sizeof(buf), "%s/.ssh/", ssh_get_user_home_dir());
|
||||
opt->ssh_dir = strdup(buf);
|
||||
SAFE_FREE(opt->ssh_dir);
|
||||
/* TODO: why ~/.ssh/ instead of ~/.ssh ? */
|
||||
|
||||
opt->ssh_dir = dir_expand_dup(opt, "~/.ssh/", 0);
|
||||
if (opt->ssh_dir == NULL) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
/* do we really want it this way? */
|
||||
snprintf(buf, sizeof(buf), value, ssh_get_user_home_dir());
|
||||
SAFE_FREE(opt->ssh_dir);
|
||||
opt->ssh_dir = strdup(buf);
|
||||
opt->ssh_dir = dir_expand_dup(opt, value, 0);
|
||||
if (opt->ssh_dir == NULL) {
|
||||
return -1;
|
||||
}
|
||||
@ -504,28 +538,23 @@ int ssh_options_set(ssh_options opt, enum ssh_options_e type,
|
||||
if (value == NULL) {
|
||||
return -1;
|
||||
}
|
||||
snprintf(buf, sizeof(buf), value, ssh_get_user_home_dir());
|
||||
SAFE_FREE(opt->identity);
|
||||
opt->identity = strdup(buf);
|
||||
opt->identity = dir_expand_dup(opt, value, 1);
|
||||
if (opt->identity == NULL) {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case SSH_OPTIONS_KNOWNHOSTS:
|
||||
if (value == NULL) {
|
||||
if (ssh_options_set(opt, SSH_OPTIONS_SSH_DIR, NULL) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/known_hosts", opt->ssh_dir);
|
||||
opt->known_hosts_file = strdup(buf);
|
||||
SAFE_FREE(opt->known_hosts_file);
|
||||
opt->known_hosts_file = dir_expand_dup(opt,
|
||||
"SSH_DIR/known_hosts", 1);
|
||||
if (opt->known_hosts_file == NULL) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf), value, ssh_get_user_home_dir());
|
||||
SAFE_FREE(opt->known_hosts_file);
|
||||
opt->known_hosts_file = strdup(buf);
|
||||
opt->known_hosts_file = dir_expand_dup(opt, value, 1);
|
||||
if (opt->known_hosts_file == NULL) {
|
||||
return -1;
|
||||
}
|
||||
@ -1287,25 +1316,25 @@ int ssh_options_set_auth_callback(ssh_options opt, ssh_auth_callback cb,
|
||||
* @see ssh_options_set_host()
|
||||
*/
|
||||
int ssh_options_parse_config(ssh_options opt, const char *filename) {
|
||||
char buffer[1024] = {0};
|
||||
char *expanded_filename;
|
||||
int r;
|
||||
|
||||
if (opt == NULL || opt->host == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (opt->ssh_dir == NULL) {
|
||||
if (ssh_options_default_ssh_dir(opt) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* set default filename */
|
||||
if (filename == NULL) {
|
||||
snprintf(buffer, 1024, "%s/config", opt->ssh_dir);
|
||||
filename = buffer;
|
||||
expanded_filename = dir_expand_dup(opt, "SSH_DIR/config", 1);
|
||||
} else {
|
||||
expanded_filename = dir_expand_dup(opt, filename, 1);
|
||||
}
|
||||
if (expanded_filename == NULL)
|
||||
return -1;
|
||||
|
||||
return ssh_config_parse_file(opt, filename);
|
||||
r = ssh_config_parse_file(opt, filename);
|
||||
free(expanded_filename);
|
||||
return r;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user