aboutsummaryrefslogtreecommitdiff
path: root/libssh
diff options
context:
space:
mode:
authorBernhard R. Link <brlink@debian.org>2009-09-24 20:36:49 +0200
committerAris Adamantiadis <aris@0xbadc0de.be>2009-09-26 12:23:30 +0200
commitf643c34ee85f0542cbb8d9dc63703f61cc142238 (patch)
tree2af1ffe80fc1a8079098379f73865b58bdf35828 /libssh
parent0f77578ee2095311ebe71785be4ee7dad135728a (diff)
downloadlibssh-f643c34ee85f0542cbb8d9dc63703f61cc142238.tar.gz
libssh-f643c34ee85f0542cbb8d9dc63703f61cc142238.tar.xz
libssh-f643c34ee85f0542cbb8d9dc63703f61cc142238.zip
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.
Diffstat (limited to 'libssh')
-rw-r--r--libssh/options.c81
1 files changed, 55 insertions, 26 deletions
diff --git a/libssh/options.c b/libssh/options.c
index 3a6ec61..95bc0a2 100644
--- a/libssh/options.c
+++ b/libssh/options.c
@@ -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;
}
/** @} */