1
1

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.
Этот коммит содержится в:
Bernhard R. Link 2009-09-24 20:36:49 +02:00 коммит произвёл Aris Adamantiadis
родитель 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;
}
/** @} */