diff options
Diffstat (limited to 'libssh')
-rw-r--r-- | libssh/auth.c | 18 | ||||
-rw-r--r-- | libssh/client.c | 8 | ||||
-rw-r--r-- | libssh/keyfiles.c | 30 | ||||
-rw-r--r-- | libssh/options.c | 147 |
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 |