aboutsummaryrefslogtreecommitdiff
path: root/libssh
diff options
context:
space:
mode:
Diffstat (limited to 'libssh')
-rw-r--r--libssh/auth.c18
-rw-r--r--libssh/client.c8
-rw-r--r--libssh/keyfiles.c30
-rw-r--r--libssh/options.c147
4 files changed, 101 insertions, 102 deletions
diff --git a/libssh/auth.c b/libssh/auth.c
index 53baa85c..2a56645a 100644
--- a/libssh/auth.c
+++ b/libssh/auth.c
@@ -1032,16 +1032,11 @@ int ssh_userauth_autopubkey(ssh_session session, const char *passphrase) {
for (it = ssh_list_get_iterator(session->identity);
it != NULL;
it = it->next) {
- char *privkey_file = NULL;
+ const char *privkey_file = it->data;
int privkey_open = 0;
privkey = NULL;
- privkey_file = dir_expand_dup(session, it->data, 1);
- if (privkey_file == NULL) {
- continue;
- }
-
ssh_log(session, SSH_LOG_PROTOCOL, "Trying to read privatekey %s", privkey_file);
rc = ssh_try_publickey_from_file(session, privkey_file, &pubkey_string, &type);
@@ -1054,7 +1049,6 @@ int ssh_userauth_autopubkey(ssh_session session, const char *passphrase) {
ssh_log(session, SSH_LOG_RARE,
"Reading private key %s failed (bad passphrase ?)",
privkey_file);
- SAFE_FREE(privkey_file);
leave_function();
return SSH_AUTH_ERROR;
}
@@ -1062,7 +1056,6 @@ int ssh_userauth_autopubkey(ssh_session session, const char *passphrase) {
pubkey = publickey_from_privatekey(privkey);
if (pubkey == NULL) {
- SAFE_FREE(privkey_file);
privatekey_free(privkey);
ssh_set_error_oom(session);
leave_function();
@@ -1073,7 +1066,6 @@ int ssh_userauth_autopubkey(ssh_session session, const char *passphrase) {
type = pubkey->type;
publickey_free(pubkey);
if (pubkey_string == NULL) {
- SAFE_FREE(privkey_file);
ssh_set_error_oom(session);
leave_function();
return SSH_AUTH_ERROR;
@@ -1082,7 +1074,6 @@ int ssh_userauth_autopubkey(ssh_session session, const char *passphrase) {
len = strlen(privkey_file) + 5;
publickey_file = malloc(len);
if (publickey_file == NULL) {
- SAFE_FREE(privkey_file);
ssh_set_error_oom(session);
leave_function();
return SSH_AUTH_ERROR;
@@ -1095,13 +1086,11 @@ int ssh_userauth_autopubkey(ssh_session session, const char *passphrase) {
}
SAFE_FREE(publickey_file);
} else if (rc < 0) {
- SAFE_FREE(privkey_file);
continue;
}
rc = ssh_userauth_offer_pubkey(session, NULL, type, pubkey_string);
if (rc == SSH_AUTH_ERROR){
- SAFE_FREE(privkey_file);
string_free(pubkey_string);
ssh_log(session, SSH_LOG_RARE, "Publickey authentication error");
leave_function();
@@ -1109,7 +1098,6 @@ int ssh_userauth_autopubkey(ssh_session session, const char *passphrase) {
} else {
if (rc != SSH_AUTH_SUCCESS){
ssh_log(session, SSH_LOG_PROTOCOL, "Publickey refused by server");
- SAFE_FREE(privkey_file);
string_free(pubkey_string);
continue;
}
@@ -1124,7 +1112,6 @@ int ssh_userauth_autopubkey(ssh_session session, const char *passphrase) {
ssh_log(session, SSH_LOG_RARE,
"Reading private key %s failed (bad passphrase ?)",
privkey_file);
- SAFE_FREE(privkey_file);
string_free(pubkey_string);
continue; /* continue the loop with other pubkey */
}
@@ -1132,7 +1119,6 @@ int ssh_userauth_autopubkey(ssh_session session, const char *passphrase) {
rc = ssh_userauth_pubkey(session, NULL, pubkey_string, privkey);
if (rc == SSH_AUTH_ERROR) {
- SAFE_FREE(privkey_file);
string_free(pubkey_string);
privatekey_free(privkey);
leave_function();
@@ -1141,7 +1127,6 @@ int ssh_userauth_autopubkey(ssh_session session, const char *passphrase) {
if (rc != SSH_AUTH_SUCCESS){
ssh_log(session, SSH_LOG_RARE,
"The server accepted the public key but refused the signature");
- SAFE_FREE(privkey_file);
string_free(pubkey_string);
privatekey_free(privkey);
continue;
@@ -1151,7 +1136,6 @@ int ssh_userauth_autopubkey(ssh_session session, const char *passphrase) {
/* auth success */
ssh_log(session, SSH_LOG_PROTOCOL,
"Successfully authenticated using %s", privkey_file);
- SAFE_FREE(privkey_file);
string_free(pubkey_string);
privatekey_free(privkey);
diff --git a/libssh/client.c b/libssh/client.c
index e75ff494..875cc4af 100644
--- a/libssh/client.c
+++ b/libssh/client.c
@@ -690,6 +690,14 @@ int ssh_connect(ssh_session session) {
leave_function();
return SSH_ERROR;
}
+
+ ret = ssh_options_apply(session);
+ if (ret < 0) {
+ ssh_set_error(session, SSH_FATAL, "Couldn't apply options");
+ leave_function();
+ return SSH_ERROR;
+ }
+
session->session_state=SSH_SESSION_STATE_CONNECTING;
ssh_socket_set_callbacks(session->socket,&session->socket_callbacks);
session->socket_callbacks.connected=socket_callback_connected;
diff --git a/libssh/keyfiles.c b/libssh/keyfiles.c
index 8f63729c..79b3bfe8 100644
--- a/libssh/keyfiles.c
+++ b/libssh/keyfiles.c
@@ -1157,8 +1157,6 @@ int ssh_try_publickey_from_file(ssh_session session, const char *keyfile,
ssh_string try_publickey_from_file(ssh_session session, struct ssh_keys_struct keytab,
char **privkeyfile, int *type) {
- char *public;
- char *private;
const char *priv;
const char *pub;
char *new;
@@ -1179,21 +1177,15 @@ ssh_string try_publickey_from_file(ssh_session session, struct ssh_keys_struct k
}
}
- /* are them readable ? */
- public=dir_expand_dup(session,pub,1);
- private=dir_expand_dup(session,priv,1);
- //snprintf(public, sizeof(public), "%s/%s", session->sshdir, pub);
- //snprintf(private, sizeof(private), "%s/%s", session->sshdir, priv);
-
- ssh_log(session, SSH_LOG_PACKET, "Trying to open publickey %s", public);
- if (!ssh_file_readaccess_ok(public)) {
- ssh_log(session, SSH_LOG_PACKET, "Failed to open publickey %s", public);
+ ssh_log(session, SSH_LOG_PACKET, "Trying to open publickey %s", pub);
+ if (!ssh_file_readaccess_ok(pub)) {
+ ssh_log(session, SSH_LOG_PACKET, "Failed to open publickey %s", pub);
goto error;
}
- ssh_log(session, SSH_LOG_PACKET, "Trying to open privatekey %s", private);
- if (!ssh_file_readaccess_ok(private)) {
- ssh_log(session, SSH_LOG_PACKET, "Failed to open privatekey %s", private);
+ ssh_log(session, SSH_LOG_PACKET, "Trying to open privatekey %s", priv);
+ if (!ssh_file_readaccess_ok(priv)) {
+ ssh_log(session, SSH_LOG_PACKET, "Failed to open privatekey %s", priv);
goto error;
}
@@ -1203,26 +1195,24 @@ ssh_string try_publickey_from_file(ssh_session session, struct ssh_keys_struct k
* We are sure both the private and public key file is readable. We return
* the public as a string, and the private filename as an argument
*/
- pubkey = publickey_from_file(session, public, type);
+ pubkey = publickey_from_file(session, pub, type);
if (pubkey == NULL) {
ssh_log(session, SSH_LOG_PACKET,
"Wasn't able to open public key file %s: %s",
- public,
+ pub,
ssh_get_error(session));
goto error;
}
- new = realloc(*privkeyfile, strlen(private) + 1);
+ new = realloc(*privkeyfile, strlen(priv) + 1);
if (new == NULL) {
string_free(pubkey);
goto error;
}
- strcpy(new, private);
+ strcpy(new, priv);
*privkeyfile = new;
error:
- SAFE_FREE(public);
- SAFE_FREE(private);
return pubkey;
}
diff --git a/libssh/options.c b/libssh/options.c
index 97e6f7ae..160b87c2 100644
--- a/libssh/options.c
+++ b/libssh/options.c
@@ -167,58 +167,6 @@ int ssh_options_set_algo(ssh_session session, int algo,
return 0;
}
-char *dir_expand_dup(ssh_session session, const char *value, int allowsshdir) {
- char *new;
-
- if (value[0] == '~' && value[1] == '/') {
- char *homedir = ssh_get_user_home_dir();
- size_t lv, lh;
-
- if (homedir == NULL) {
- return NULL;
- }
- lv = strlen(value + 1);
- lh = strlen(homedir);
-
- new = malloc(lv + lh + 1);
- if (new == NULL) {
- ssh_set_error_oom(session);
- SAFE_FREE(homedir);
- return NULL;
- }
- memcpy(new, homedir, lh);
- SAFE_FREE(homedir);
- memcpy(new + lh, value + 1, lv + 1);
- return new;
- }
- if (allowsshdir && strncmp(value, "SSH_DIR/", 8) == 0) {
- size_t lv, ls;
- if (session->sshdir == NULL) {
- if (ssh_options_set(session, SSH_OPTIONS_SSH_DIR, NULL) < 0)
- return NULL;
- }
-
- value += 7;
- lv = strlen(value);
- ls = strlen(session->sshdir);
-
- new = malloc(lv + ls + 1);
- if (new == NULL) {
- ssh_set_error_oom(session);
- return NULL;
- }
- memcpy(new, session->sshdir, ls);
- memcpy(new + ls, value, lv + 1);
- return new;
- }
- new = strdup(value);
- if (new == NULL) {
- ssh_set_error_oom(session);
- return NULL;
- }
- return new;
-}
-
/**
* @brief This function can set all possible ssh options.
*
@@ -476,15 +424,14 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
case SSH_OPTIONS_SSH_DIR:
if (value == NULL) {
SAFE_FREE(session->sshdir);
- /* TODO: why ~/.ssh/ instead of ~/.ssh ? */
- session->sshdir = dir_expand_dup(session, "~/.ssh/", 0);
+ session->sshdir = ssh_path_expand_tilde("~/.ssh/");
if (session->sshdir == NULL) {
return -1;
}
} else {
SAFE_FREE(session->sshdir);
- session->sshdir = dir_expand_dup(session, value, 0);
+ session->sshdir = ssh_path_expand_tilde(value);
if (session->sshdir == NULL) {
return -1;
}
@@ -496,27 +443,28 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
ssh_set_error_invalid(session, __FUNCTION__);
return -1;
}
- q = dir_expand_dup(session, value, 1);
+ q = strdup(value);
if (q == NULL) {
- return -1;
+ return -1;
}
rc = ssh_list_prepend(session->identity, q);
if (rc < 0) {
- SAFE_FREE(q);
return -1;
}
break;
case SSH_OPTIONS_KNOWNHOSTS:
if (value == NULL) {
SAFE_FREE(session->knownhosts);
- session->knownhosts = dir_expand_dup(session,
- "SSH_DIR/known_hosts", 1);
+ if (session->sshdir == NULL) {
+ return -1;
+ }
+ session->knownhosts = ssh_path_expand_escape(session, "%d/known_hosts");
if (session->knownhosts == NULL) {
return -1;
}
} else {
SAFE_FREE(session->knownhosts);
- session->knownhosts = dir_expand_dup(session, value, 1);
+ session->knownhosts = strdup(value);
if (session->knownhosts == NULL) {
return -1;
}
@@ -637,7 +585,12 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
ssh_set_error_invalid(session, __FUNCTION__);
return -1;
} else {
- session->ProxyCommand = strdup(value);
+ SAFE_FREE(session->ProxyCommand);
+ q = strdup(value);
+ if (q == NULL) {
+ return -1;
+ }
+ session->ProxyCommand = q;
}
break;
default:
@@ -864,20 +817,84 @@ int ssh_options_parse_config(ssh_session session, const char *filename) {
return -1;
}
+ if (session->sshdir == NULL) {
+ r = ssh_options_set(session, SSH_OPTIONS_SSH_DIR, NULL);
+ if (r < 0) {
+ ssh_set_error_oom(session);
+ return -1;
+ }
+ }
+
/* set default filename */
if (filename == NULL) {
- expanded_filename = dir_expand_dup(session, "SSH_DIR/config", 1);
+ expanded_filename = ssh_path_expand_escape(session, "%d/config");
} else {
- expanded_filename = dir_expand_dup(session, filename, 1);
+ expanded_filename = ssh_path_expand_escape(session, filename);
}
- if (expanded_filename == NULL)
+ if (expanded_filename == NULL) {
return -1;
+ }
r = ssh_config_parse_file(session, expanded_filename);
+ if (r < 0) {
+ goto out;
+ }
+ if (filename == NULL) {
+ r = ssh_config_parse_file(session, "/etc/ssh/ssh_config");
+ }
+
+out:
free(expanded_filename);
return r;
}
+int ssh_options_apply(ssh_session session) {
+ struct ssh_iterator *it;
+ char *tmp;
+ int rc;
+
+ if (session->sshdir == NULL) {
+ rc = ssh_options_set(session, SSH_OPTIONS_SSH_DIR, NULL);
+ if (rc < 0) {
+ return -1;
+ }
+ }
+
+ if (session->knownhosts == NULL) {
+ tmp = ssh_path_expand_escape(session, "%d/known_hosts");
+ } else {
+ tmp = ssh_path_expand_escape(session, session->knownhosts);
+ }
+ if (tmp == NULL) {
+ return -1;
+ }
+ free(session->knownhosts);
+ session->knownhosts = tmp;
+
+ if (session->ProxyCommand != NULL) {
+ tmp = ssh_path_expand_escape(session, session->ProxyCommand);
+ if (tmp == NULL) {
+ return -1;
+ }
+ free(session->ProxyCommand);
+ session->ProxyCommand = tmp;
+ }
+
+ for (it = ssh_list_get_iterator(session->identity);
+ it != NULL;
+ it = it->next) {
+ char *id = (char *) it->data;
+ tmp = ssh_path_expand_escape(session, id);
+ if (tmp == NULL) {
+ return -1;
+ }
+ free(id);
+ it->data = tmp;
+ }
+
+ return 0;
+}
+
/* @} */
#ifdef WITH_SERVER