diff options
Diffstat (limited to 'lib/ssh.c')
-rw-r--r-- | lib/ssh.c | 118 |
1 files changed, 32 insertions, 86 deletions
@@ -108,12 +108,14 @@ have their definition hidden well */ #endif +#define sftp_libssh2_last_error(s) curlx_ultosi(libssh2_sftp_last_error(s)) + #define sftp_libssh2_realpath(s,p,t,m) \ libssh2_sftp_symlink_ex((s), (p), curlx_uztoui(strlen(p)), \ (t), (m), LIBSSH2_SFTP_REALPATH) /* Local functions: */ -static const char *sftp_libssh2_strerror(unsigned long err); +static const char *sftp_libssh2_strerror(int err); static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc); static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc); static LIBSSH2_FREE_FUNC(my_libssh2_free); @@ -767,7 +769,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) && (strstr(sshc->authlist, "publickey") != NULL)) { - char *home; + char *home = NULL; + bool rsa_pub_empty_but_ok = FALSE; sshc->rsa_pub = sshc->rsa = NULL; @@ -775,7 +778,10 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) HOME environment variable etc? */ home = curl_getenv("HOME"); - if(data->set.str[STRING_SSH_PUBLIC_KEY]) + if(data->set.str[STRING_SSH_PUBLIC_KEY] && + !*data->set.str[STRING_SSH_PUBLIC_KEY]) + rsa_pub_empty_but_ok = true; + else if(data->set.str[STRING_SSH_PUBLIC_KEY]) sshc->rsa_pub = aprintf("%s", data->set.str[STRING_SSH_PUBLIC_KEY]); else if(home) sshc->rsa_pub = aprintf("%s/.ssh/id_dsa.pub", home); @@ -783,9 +789,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) /* as a final resort, try current dir! */ sshc->rsa_pub = strdup("id_dsa.pub"); - if(sshc->rsa_pub == NULL) { + if(!rsa_pub_empty_but_ok && (sshc->rsa_pub == NULL)) { Curl_safefree(home); - home = NULL; state(conn, SSH_SESSION_FREE); sshc->actualcode = CURLE_OUT_OF_MEMORY; break; @@ -801,9 +806,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) if(sshc->rsa == NULL) { Curl_safefree(home); - home = NULL; Curl_safefree(sshc->rsa_pub); - sshc->rsa_pub = NULL; state(conn, SSH_SESSION_FREE); sshc->actualcode = CURLE_OUT_OF_MEMORY; break; @@ -814,7 +817,6 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) sshc->passphrase = ""; Curl_safefree(home); - home = NULL; infof(data, "Using ssh public key file %s\n", sshc->rsa_pub); infof(data, "Using ssh private key file %s\n", sshc->rsa); @@ -840,9 +842,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) } Curl_safefree(sshc->rsa_pub); - sshc->rsa_pub = NULL; Curl_safefree(sshc->rsa); - sshc->rsa = NULL; if(rc == 0) { sshc->authed = TRUE; @@ -1004,7 +1004,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) } else { /* Return the error type */ - err = (int)(libssh2_sftp_last_error(sshc->sftp_session)); + err = sftp_libssh2_last_error(sshc->sftp_session); result = sftp_libssh2_error_to_CURLE(err); sshc->actualcode = result?result:CURLE_SSH; DEBUGF(infof(data, "error = %d makes libcurl = %d\n", @@ -1145,7 +1145,6 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) failf(data, "Syntax error in chgrp/chmod/chown: " "Bad second parameter"); Curl_safefree(sshc->quote_path1); - sshc->quote_path1 = NULL; state(conn, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = result; @@ -1168,7 +1167,6 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) failf(data, "Syntax error in ln/symlink: Bad second parameter"); Curl_safefree(sshc->quote_path1); - sshc->quote_path1 = NULL; state(conn, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = result; @@ -1193,7 +1191,6 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) else failf(data, "Syntax error in rename: Bad second parameter"); Curl_safefree(sshc->quote_path1); - sshc->quote_path1 = NULL; state(conn, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = result; @@ -1214,9 +1211,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) failf(data, "Unknown SFTP command"); Curl_safefree(sshc->quote_path1); - sshc->quote_path1 = NULL; Curl_safefree(sshc->quote_path2); - sshc->quote_path2 = NULL; state(conn, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_QUOTE_ERROR; @@ -1229,14 +1224,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; case SSH_SFTP_NEXT_QUOTE: - if(sshc->quote_path1) { - Curl_safefree(sshc->quote_path1); - sshc->quote_path1 = NULL; - } - if(sshc->quote_path2) { - Curl_safefree(sshc->quote_path2); - sshc->quote_path2 = NULL; - } + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); sshc->quote_item = sshc->quote_item->next; @@ -1282,11 +1271,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } else if(rc != 0 && !sshc->acceptfail) { /* get those attributes */ - err = (int)(libssh2_sftp_last_error(sshc->sftp_session)); + err = sftp_libssh2_last_error(sshc->sftp_session); Curl_safefree(sshc->quote_path1); - sshc->quote_path1 = NULL; Curl_safefree(sshc->quote_path2); - sshc->quote_path2 = NULL; failf(data, "Attempt to get SFTP stats failed: %s", sftp_libssh2_strerror(err)); state(conn, SSH_SFTP_CLOSE); @@ -1303,9 +1290,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) && !sshc->acceptfail) { Curl_safefree(sshc->quote_path1); - sshc->quote_path1 = NULL; Curl_safefree(sshc->quote_path2); - sshc->quote_path2 = NULL; failf(data, "Syntax error: chgrp gid not a number"); state(conn, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; @@ -1320,9 +1305,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) if(sshc->quote_attrs.permissions == 0 && !ISDIGIT(sshc->quote_path1[0])) { Curl_safefree(sshc->quote_path1); - sshc->quote_path1 = NULL; Curl_safefree(sshc->quote_path2); - sshc->quote_path2 = NULL; failf(data, "Syntax error: chmod permissions not a number"); state(conn, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; @@ -1336,9 +1319,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) && !sshc->acceptfail) { Curl_safefree(sshc->quote_path1); - sshc->quote_path1 = NULL; Curl_safefree(sshc->quote_path2); - sshc->quote_path2 = NULL; failf(data, "Syntax error: chown uid not a number"); state(conn, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; @@ -1361,11 +1342,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } else if(rc != 0 && !sshc->acceptfail) { - err = (int)(libssh2_sftp_last_error(sshc->sftp_session)); + err = sftp_libssh2_last_error(sshc->sftp_session); Curl_safefree(sshc->quote_path1); - sshc->quote_path1 = NULL; Curl_safefree(sshc->quote_path2); - sshc->quote_path2 = NULL; failf(data, "Attempt to set SFTP stats failed: %s", sftp_libssh2_strerror(err)); state(conn, SSH_SFTP_CLOSE); @@ -1386,11 +1365,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } else if(rc != 0 && !sshc->acceptfail) { - err = (int)(libssh2_sftp_last_error(sshc->sftp_session)); + err = sftp_libssh2_last_error(sshc->sftp_session); Curl_safefree(sshc->quote_path1); - sshc->quote_path1 = NULL; Curl_safefree(sshc->quote_path2); - sshc->quote_path2 = NULL; failf(data, "symlink command failed: %s", sftp_libssh2_strerror(err)); state(conn, SSH_SFTP_CLOSE); @@ -1409,9 +1386,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } else if(rc != 0 && !sshc->acceptfail) { - err = (int)(libssh2_sftp_last_error(sshc->sftp_session)); + err = sftp_libssh2_last_error(sshc->sftp_session); Curl_safefree(sshc->quote_path1); - sshc->quote_path1 = NULL; failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err)); state(conn, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; @@ -1434,11 +1410,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } else if(rc != 0 && !sshc->acceptfail) { - err = (int)(libssh2_sftp_last_error(sshc->sftp_session)); + err = sftp_libssh2_last_error(sshc->sftp_session); Curl_safefree(sshc->quote_path1); - sshc->quote_path1 = NULL; Curl_safefree(sshc->quote_path2); - sshc->quote_path2 = NULL; failf(data, "rename command failed: %s", sftp_libssh2_strerror(err)); state(conn, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; @@ -1455,9 +1429,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } else if(rc != 0 && !sshc->acceptfail) { - err = (int)(libssh2_sftp_last_error(sshc->sftp_session)); + err = sftp_libssh2_last_error(sshc->sftp_session); Curl_safefree(sshc->quote_path1); - sshc->quote_path1 = NULL; failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err)); state(conn, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; @@ -1474,9 +1447,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } else if(rc != 0 && !sshc->acceptfail) { - err = (int)(libssh2_sftp_last_error(sshc->sftp_session)); + err = sftp_libssh2_last_error(sshc->sftp_session); Curl_safefree(sshc->quote_path1); - sshc->quote_path1 = NULL; failf(data, "rm command failed: %s", sftp_libssh2_strerror(err)); state(conn, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; @@ -1557,7 +1529,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc) /* only when there was an SFTP protocol error can we extract the sftp error! */ - err = (int)(libssh2_sftp_last_error(sshc->sftp_session)); + err = sftp_libssh2_last_error(sshc->sftp_session); else err = -1; /* not an sftp error at all */ @@ -1711,17 +1683,16 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) *sshc->slash_pos = '/'; ++sshc->slash_pos; if(rc == -1) { - unsigned int sftp_err = 0; /* * Abort if failure wasn't that the dir already exists or the * permission was denied (creation might succeed further down the * path) - retry on unspecific FAILURE also */ - sftp_err = (unsigned int)(libssh2_sftp_last_error(sshc->sftp_session)); - if((sftp_err != LIBSSH2_FX_FILE_ALREADY_EXISTS) && - (sftp_err != LIBSSH2_FX_FAILURE) && - (sftp_err != LIBSSH2_FX_PERMISSION_DENIED)) { - result = sftp_libssh2_error_to_CURLE(sftp_err); + err = sftp_libssh2_last_error(sshc->sftp_session); + if((err != LIBSSH2_FX_FILE_ALREADY_EXISTS) && + (err != LIBSSH2_FX_FAILURE) && + (err != LIBSSH2_FX_PERMISSION_DENIED)) { + result = sftp_libssh2_error_to_CURLE(err); state(conn, SSH_SFTP_CLOSE); sshc->actualcode = result?result:CURLE_SSH; break; @@ -1747,7 +1718,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } else { - err = (int)(libssh2_sftp_last_error(sshc->sftp_session)); + err = sftp_libssh2_last_error(sshc->sftp_session); failf(data, "Could not open directory for reading: %s", sftp_libssh2_strerror(err)); state(conn, SSH_SFTP_CLOSE); @@ -1763,7 +1734,6 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) } if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) { Curl_safefree(sshc->readdir_filename); - sshc->readdir_filename = NULL; state(conn, SSH_SFTP_CLOSE); sshc->actualcode = CURLE_OUT_OF_MEMORY; break; @@ -1818,9 +1788,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) sshc->readdir_line = calloc(sshc->readdir_totalLen, 1); if(!sshc->readdir_line) { Curl_safefree(sshc->readdir_filename); - sshc->readdir_filename = NULL; Curl_safefree(sshc->readdir_longentry); - sshc->readdir_longentry = NULL; state(conn, SSH_SFTP_CLOSE); sshc->actualcode = CURLE_OUT_OF_MEMORY; break; @@ -1834,9 +1802,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) sshc->readdir_linkPath = malloc(PATH_MAX + 1); if(sshc->readdir_linkPath == NULL) { Curl_safefree(sshc->readdir_filename); - sshc->readdir_filename = NULL; Curl_safefree(sshc->readdir_longentry); - sshc->readdir_longentry = NULL; state(conn, SSH_SFTP_CLOSE); sshc->actualcode = CURLE_OUT_OF_MEMORY; break; @@ -1853,23 +1819,19 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) } else if(sshc->readdir_len == 0) { Curl_safefree(sshc->readdir_filename); - sshc->readdir_filename = NULL; Curl_safefree(sshc->readdir_longentry); - sshc->readdir_longentry = NULL; state(conn, SSH_SFTP_READDIR_DONE); break; } else if(sshc->readdir_len <= 0) { - err = (int)(libssh2_sftp_last_error(sshc->sftp_session)); + err = sftp_libssh2_last_error(sshc->sftp_session); result = sftp_libssh2_error_to_CURLE(err); sshc->actualcode = result?result:CURLE_SSH; failf(data, "Could not open remote file for reading: %s :: %d", sftp_libssh2_strerror(err), libssh2_session_last_errno(sshc->ssh_session)); Curl_safefree(sshc->readdir_filename); - sshc->readdir_filename = NULL; Curl_safefree(sshc->readdir_longentry); - sshc->readdir_longentry = NULL; state(conn, SSH_SFTP_CLOSE); break; } @@ -1887,18 +1849,14 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } Curl_safefree(sshc->readdir_linkPath); - sshc->readdir_linkPath = NULL; /* get room for the filename and extra output */ sshc->readdir_totalLen += 4 + sshc->readdir_len; new_readdir_line = realloc(sshc->readdir_line, sshc->readdir_totalLen); if(!new_readdir_line) { Curl_safefree(sshc->readdir_line); - sshc->readdir_line = NULL; Curl_safefree(sshc->readdir_filename); - sshc->readdir_filename = NULL; Curl_safefree(sshc->readdir_longentry); - sshc->readdir_longentry = NULL; state(conn, SSH_SFTP_CLOSE); sshc->actualcode = CURLE_OUT_OF_MEMORY; break; @@ -1934,7 +1892,6 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) data->req.bytecount += sshc->readdir_currLen; } Curl_safefree(sshc->readdir_line); - sshc->readdir_line = NULL; if(result) { state(conn, SSH_STOP); } @@ -1950,9 +1907,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) } sshc->sftp_handle = NULL; Curl_safefree(sshc->readdir_filename); - sshc->readdir_filename = NULL; Curl_safefree(sshc->readdir_longentry); - sshc->readdir_longentry = NULL; /* no data to transfer */ Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); @@ -1975,7 +1930,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } else { - err = (int)(libssh2_sftp_last_error(sshc->sftp_session)); + err = sftp_libssh2_last_error(sshc->sftp_session); failf(data, "Could not open remote file for reading: %s", sftp_libssh2_strerror(err)); state(conn, SSH_SFTP_CLOSE); @@ -2120,10 +2075,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) } sshc->sftp_handle = NULL; } - if(sftp_scp) { + if(sftp_scp) Curl_safefree(sftp_scp->path); - sftp_scp->path = NULL; - } DEBUGF(infof(data, "SFTP DONE done\n")); @@ -2167,7 +2120,6 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) } Curl_safefree(sshc->homedir); - sshc->homedir = NULL; conn->data->state.most_recent_ftp_entrypath = NULL; state(conn, SSH_SESSION_DISCONNECT); @@ -2392,7 +2344,6 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) } Curl_safefree(sshc->homedir); - sshc->homedir = NULL; conn->data->state.most_recent_ftp_entrypath = NULL; state(conn, SSH_SESSION_FREE); @@ -2835,7 +2786,6 @@ static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection) (void) dead_connection; Curl_safefree(conn->data->state.proto.ssh); - conn->data->state.proto.ssh = NULL; if(ssh->ssh_session) { /* only if there's a session still around to use! */ @@ -2868,10 +2818,8 @@ static CURLcode ssh_done(struct connectdata *conn, CURLcode status) else result = status; - if(sftp_scp) { + if(sftp_scp) Curl_safefree(sftp_scp->path); - sftp_scp->path = NULL; - } Curl_pgrsDone(conn); conn->data->req.keepon = 0; /* clear all bits */ @@ -3003,7 +2951,6 @@ static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection) DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n")); Curl_safefree(conn->data->state.proto.ssh); - conn->data->state.proto.ssh = NULL; if(conn->proto.sshc.ssh_session) { /* only if there's a session still around to use! */ @@ -3160,12 +3107,11 @@ get_pathname(const char **cpp, char **path) fail: Curl_safefree(*path); - *path = NULL; return CURLE_QUOTE_ERROR; } -static const char *sftp_libssh2_strerror(unsigned long err) +static const char *sftp_libssh2_strerror(int err) { switch (err) { case LIBSSH2_FX_NO_SUCH_FILE: |