diff options
Diffstat (limited to 'lib/vssh')
-rw-r--r-- | lib/vssh/libssh.c | 157 | ||||
-rw-r--r-- | lib/vssh/libssh2.c | 88 | ||||
-rw-r--r-- | lib/vssh/ssh.h | 3 | ||||
-rw-r--r-- | lib/vssh/wolfssh.c | 10 |
4 files changed, 153 insertions, 105 deletions
diff --git a/lib/vssh/libssh.c b/lib/vssh/libssh.c index 08896ab..d146d15 100644 --- a/lib/vssh/libssh.c +++ b/lib/vssh/libssh.c @@ -159,6 +159,7 @@ const struct Curl_handler Curl_handler_scp = { scp_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_SSH, /* defport */ CURLPROTO_SCP, /* protocol */ CURLPROTO_SCP, /* family */ @@ -185,6 +186,7 @@ const struct Curl_handler Curl_handler_sftp = { sftp_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_SSH, /* defport */ CURLPROTO_SFTP, /* protocol */ CURLPROTO_SFTP, /* family */ @@ -549,49 +551,48 @@ cleanup: return rc; } -#define MOVE_TO_ERROR_STATE(_r) { \ - state(data, SSH_SESSION_DISCONNECT); \ - sshc->actualcode = _r; \ - rc = SSH_ERROR; \ - break; \ -} +#define MOVE_TO_ERROR_STATE(_r) do { \ + state(data, SSH_SESSION_DISCONNECT); \ + sshc->actualcode = _r; \ + rc = SSH_ERROR; \ + } while(0) -#define MOVE_TO_SFTP_CLOSE_STATE() { \ - state(data, SSH_SFTP_CLOSE); \ - sshc->actualcode = sftp_error_to_CURLE(sftp_get_error(sshc->sftp_session)); \ - rc = SSH_ERROR; \ - break; \ -} +#define MOVE_TO_SFTP_CLOSE_STATE() do { \ + state(data, SSH_SFTP_CLOSE); \ + sshc->actualcode = \ + sftp_error_to_CURLE(sftp_get_error(sshc->sftp_session)); \ + rc = SSH_ERROR; \ + } while(0) -#define MOVE_TO_LAST_AUTH \ - if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { \ - rc = SSH_OK; \ - state(data, SSH_AUTH_PASS_INIT); \ - break; \ - } \ - else { \ - MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); \ - } +#define MOVE_TO_LAST_AUTH do { \ + if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { \ + rc = SSH_OK; \ + state(data, SSH_AUTH_PASS_INIT); \ + } \ + else { \ + MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); \ + } \ + } while(0) -#define MOVE_TO_TERTIARY_AUTH \ - if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { \ - rc = SSH_OK; \ - state(data, SSH_AUTH_KEY_INIT); \ - break; \ - } \ - else { \ - MOVE_TO_LAST_AUTH; \ - } +#define MOVE_TO_TERTIARY_AUTH do { \ + if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { \ + rc = SSH_OK; \ + state(data, SSH_AUTH_KEY_INIT); \ + } \ + else { \ + MOVE_TO_LAST_AUTH; \ + } \ + } while(0) -#define MOVE_TO_SECONDARY_AUTH \ - if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { \ - rc = SSH_OK; \ - state(data, SSH_AUTH_GSSAPI); \ - break; \ - } \ - else { \ - MOVE_TO_TERTIARY_AUTH; \ - } +#define MOVE_TO_SECONDARY_AUTH do { \ + if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { \ + rc = SSH_OK; \ + state(data, SSH_AUTH_GSSAPI); \ + } \ + else { \ + MOVE_TO_TERTIARY_AUTH; \ + } \ + } while(0) static int myssh_auth_interactive(struct connectdata *conn) @@ -629,7 +630,7 @@ restart: rc = SSH_OK; else if(rc == SSH_AUTH_INFO) { nprompts = ssh_userauth_kbdint_getnprompts(sshc->ssh_session); - if(nprompts != 0) + if(nprompts) return SSH_ERROR; sshc->kbd_state = 2; @@ -704,6 +705,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) if(rc != SSH_OK) { failf(data, "Failure establishing ssh session"); MOVE_TO_ERROR_STATE(CURLE_FAILED_INIT); + break; } state(data, SSH_HOSTKEY); @@ -714,6 +716,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) rc = myssh_is_known(data); if(rc != SSH_OK) { MOVE_TO_ERROR_STATE(CURLE_PEER_FAILED_VERIFICATION); + break; } state(data, SSH_AUTHLIST); @@ -735,6 +738,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } else if(rc == SSH_AUTH_ERROR) { MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); + break; } sshc->auth_methods = ssh_userauth_list(sshc->ssh_session, NULL); @@ -753,6 +757,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } else { /* unsupported authentication method */ MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); + break; } break; @@ -760,6 +765,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) case SSH_AUTH_PKEY_INIT: if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY)) { MOVE_TO_SECONDARY_AUTH; + break; } /* Two choices, (1) private key was given on CMD, @@ -775,6 +781,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) if(rc != SSH_OK) { MOVE_TO_SECONDARY_AUTH; + break; } } @@ -833,6 +840,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) case SSH_AUTH_GSSAPI: if(!(data->set.ssh_auth_types & CURLSSH_AUTH_GSSAPI)) { MOVE_TO_TERTIARY_AUTH; + break; } rc = ssh_userauth_gssapi(sshc->ssh_session); @@ -879,6 +887,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD)) { /* Host key authentication is intentionally not implemented */ MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); + break; } state(data, SSH_AUTH_PASS); /* FALLTHROUGH */ @@ -951,8 +960,9 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) * Get the "home" directory */ sshc->homedir = sftp_canonicalize_path(sshc->sftp_session, "."); - if(sshc->homedir == NULL) { + if(!sshc->homedir) { MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT); + break; } data->state.most_recent_ftp_entrypath = sshc->homedir; @@ -1025,7 +1035,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) case SSH_SFTP_QUOTE_SETSTAT: rc = sftp_setstat(sshc->sftp_session, sshc->quote_path2, sshc->quote_attrs); - if(rc != 0 && !sshc->acceptfail) { + if(rc && !sshc->acceptfail) { Curl_safefree(sshc->quote_path1); Curl_safefree(sshc->quote_path2); failf(data, "Attempt to set SFTP stats failed: %s", @@ -1044,7 +1054,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) case SSH_SFTP_QUOTE_SYMLINK: rc = sftp_symlink(sshc->sftp_session, sshc->quote_path2, sshc->quote_path1); - if(rc != 0 && !sshc->acceptfail) { + if(rc && !sshc->acceptfail) { Curl_safefree(sshc->quote_path1); Curl_safefree(sshc->quote_path2); failf(data, "symlink command failed: %s", @@ -1060,7 +1070,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) case SSH_SFTP_QUOTE_MKDIR: rc = sftp_mkdir(sshc->sftp_session, sshc->quote_path1, (mode_t)data->set.new_directory_perms); - if(rc != 0 && !sshc->acceptfail) { + if(rc && !sshc->acceptfail) { Curl_safefree(sshc->quote_path1); failf(data, "mkdir command failed: %s", ssh_get_error(sshc->ssh_session)); @@ -1075,7 +1085,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) case SSH_SFTP_QUOTE_RENAME: rc = sftp_rename(sshc->sftp_session, sshc->quote_path1, sshc->quote_path2); - if(rc != 0 && !sshc->acceptfail) { + if(rc && !sshc->acceptfail) { Curl_safefree(sshc->quote_path1); Curl_safefree(sshc->quote_path2); failf(data, "rename command failed: %s", @@ -1090,7 +1100,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) case SSH_SFTP_QUOTE_RMDIR: rc = sftp_rmdir(sshc->sftp_session, sshc->quote_path1); - if(rc != 0 && !sshc->acceptfail) { + if(rc && !sshc->acceptfail) { Curl_safefree(sshc->quote_path1); failf(data, "rmdir command failed: %s", ssh_get_error(sshc->ssh_session)); @@ -1104,7 +1114,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) case SSH_SFTP_QUOTE_UNLINK: rc = sftp_unlink(sshc->sftp_session, sshc->quote_path1); - if(rc != 0 && !sshc->acceptfail) { + if(rc && !sshc->acceptfail) { Curl_safefree(sshc->quote_path1); failf(data, "rm command failed: %s", ssh_get_error(sshc->ssh_session)); @@ -1179,7 +1189,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) sftp_attributes attrs; attrs = sftp_stat(sshc->sftp_session, protop->path); - if(attrs != 0) { + if(attrs) { data->info.filetime = attrs->mtime; sftp_attributes_free(attrs); } @@ -1203,16 +1213,17 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) { int flags; - if(data->state.resume_from != 0) { + if(data->state.resume_from) { sftp_attributes attrs; if(data->state.resume_from < 0) { attrs = sftp_stat(sshc->sftp_session, protop->path); - if(attrs != 0) { + if(attrs) { curl_off_t size = attrs->size; if(size < 0) { failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size); MOVE_TO_ERROR_STATE(CURLE_BAD_DOWNLOAD_RESUME); + break; } data->state.resume_from = attrs->size; @@ -1224,7 +1235,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } } - if(data->set.ftp_append) + if(data->set.remote_append) /* Try to open for append, but create if nonexisting */ flags = O_WRONLY|O_CREAT|O_APPEND; else if(data->state.resume_from > 0) @@ -1254,6 +1265,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } else { MOVE_TO_SFTP_CLOSE_STATE(); + break; } } @@ -1292,8 +1304,11 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) CURL_READFUNC_ABORT return code still aborts */ failf(data, "Failed to read data"); MOVE_TO_ERROR_STATE(CURLE_FTP_COULDNT_USE_REST); + break; } } while(passed < data->state.resume_from); + if(rc) + break; } /* now, decrease the size of the read */ @@ -1304,8 +1319,9 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } rc = sftp_seek64(sshc->sftp_file, data->state.resume_from); - if(rc != 0) { + if(rc) { MOVE_TO_SFTP_CLOSE_STATE(); + break; } } if(data->state.infilesize > 0) { @@ -1375,6 +1391,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) (err != SSH_FX_FAILURE) && (err != SSH_FX_PERMISSION_DENIED)) { MOVE_TO_SFTP_CLOSE_STATE(); + break; } rc = 0; /* clear rc and continue */ } @@ -1398,6 +1415,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) failf(data, "Could not open directory for reading: %s", ssh_get_error(sshc->ssh_session)); MOVE_TO_SFTP_CLOSE_STATE(); + break; } state(data, SSH_SFTP_READDIR); break; @@ -1413,11 +1431,11 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) sshc->readdir_longentry = sshc->readdir_attrs->longname; sshc->readdir_len = strlen(sshc->readdir_filename); - if(data->set.ftp_list_only) { + if(data->set.list_only) { char *tmpLine; tmpLine = aprintf("%s\n", sshc->readdir_filename); - if(tmpLine == NULL) { + if(!tmpLine) { state(data, SSH_SFTP_CLOSE); sshc->actualcode = CURLE_OUT_OF_MEMORY; break; @@ -1453,16 +1471,15 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) if((sshc->readdir_attrs->flags & SSH_FILEXFER_ATTR_PERMISSIONS) && ((sshc->readdir_attrs->permissions & S_IFMT) == S_IFLNK)) { - sshc->readdir_linkPath = malloc(PATH_MAX + 1); - if(sshc->readdir_linkPath == NULL) { + sshc->readdir_linkPath = aprintf("%s%s", protop->path, + sshc->readdir_filename); + + if(!sshc->readdir_linkPath) { state(data, SSH_SFTP_CLOSE); sshc->actualcode = CURLE_OUT_OF_MEMORY; break; } - msnprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", protop->path, - sshc->readdir_filename); - state(data, SSH_SFTP_READDIR_LINK); break; } @@ -1492,12 +1509,13 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) failf(data, "Could not read symlink for reading: %s", ssh_get_error(sshc->ssh_session)); MOVE_TO_SFTP_CLOSE_STATE(); + break; } - if(sshc->readdir_link_attrs->name == NULL) { + if(!sshc->readdir_link_attrs->name) { sshc->readdir_tmp = sftp_readlink(sshc->sftp_session, sshc->readdir_linkPath); - if(sshc->readdir_filename == NULL) + if(!sshc->readdir_filename) sshc->readdir_len = 0; else sshc->readdir_len = strlen(sshc->readdir_tmp); @@ -1587,6 +1605,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) ssh_get_error(sshc->ssh_session)); MOVE_TO_SFTP_CLOSE_STATE(); + break; } state(data, SSH_SFTP_DOWNLOAD_STAT); @@ -1662,8 +1681,9 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } rc = sftp_seek64(sshc->sftp_file, from); - if(rc != 0) { + if(rc) { MOVE_TO_SFTP_CLOSE_STATE(); + break; } } data->req.size = size; @@ -1700,8 +1720,9 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) size - data->state.resume_from); rc = sftp_seek64(sshc->sftp_file, data->state.resume_from); - if(rc != 0) { + if(rc) { MOVE_TO_SFTP_CLOSE_STATE(); + break; } } } @@ -1796,6 +1817,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) failf(data, "SCP requires a known file size for upload"); sshc->actualcode = CURLE_UPLOAD_FAILED; MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED); + break; } sshc->scp_session = @@ -1823,6 +1845,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) err_msg = ssh_get_error(sshc->ssh_session); failf(data, "%s", err_msg); MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED); + break; } rc = ssh_scp_push_file(sshc->scp_session, protop->path, @@ -1832,6 +1855,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) err_msg = ssh_get_error(sshc->ssh_session); failf(data, "%s", err_msg); MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED); + break; } /* upload data */ @@ -1860,6 +1884,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) err_msg = ssh_get_error(sshc->ssh_session); failf(data, "%s", err_msg); MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT); + break; } state(data, SSH_SCP_DOWNLOAD); /* FALLTHROUGH */ @@ -2164,7 +2189,7 @@ static CURLcode myssh_connect(struct Curl_easy *data, bool *done) ssh = &conn->proto.sshc; ssh->ssh_session = ssh_new(); - if(ssh->ssh_session == NULL) { + if(!ssh->ssh_session) { failf(data, "Failure initialising ssh session"); return CURLE_FAILED_INIT; } @@ -2662,7 +2687,7 @@ static void sftp_quote(struct Curl_easy *data) * command with a space so we can check for it unconditionally */ cp = strchr(cmd, ' '); - if(cp == NULL) { + if(!cp) { failf(data, "Syntax error in SFTP command. Supply parameter(s)!"); state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; @@ -2811,7 +2836,7 @@ static void sftp_quote_stat(struct Curl_easy *data) if(sshc->quote_attrs) sftp_attributes_free(sshc->quote_attrs); sshc->quote_attrs = sftp_stat(sshc->sftp_session, sshc->quote_path2); - if(sshc->quote_attrs == NULL) { + if(!sshc->quote_attrs) { Curl_safefree(sshc->quote_path1); Curl_safefree(sshc->quote_path2); failf(data, "Attempt to get SFTP stats failed: %d", diff --git a/lib/vssh/libssh2.c b/lib/vssh/libssh2.c index 3130dcc..8a6345b 100644 --- a/lib/vssh/libssh2.c +++ b/lib/vssh/libssh2.c @@ -121,6 +121,7 @@ static int ssh_getsock(struct Curl_easy *data, struct connectdata *conn, curl_socket_t *sock); static CURLcode ssh_setup_connection(struct Curl_easy *data, struct connectdata *conn); +static void ssh_attach(struct Curl_easy *data, struct connectdata *conn); /* * SCP protocol handler. @@ -142,6 +143,7 @@ const struct Curl_handler Curl_handler_scp = { scp_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ssh_attach, PORT_SSH, /* defport */ CURLPROTO_SCP, /* protocol */ CURLPROTO_SCP, /* family */ @@ -170,6 +172,7 @@ const struct Curl_handler Curl_handler_sftp = { sftp_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ssh_attach, PORT_SSH, /* defport */ CURLPROTO_SFTP, /* protocol */ CURLPROTO_SFTP, /* family */ @@ -184,7 +187,7 @@ kbd_callback(const char *name, int name_len, const char *instruction, LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses, void **abstract) { - struct connectdata *conn = (struct connectdata *)*abstract; + struct Curl_easy *data = (struct Curl_easy *)*abstract; #ifdef CURL_LIBSSH2_DEBUG fprintf(stderr, "name=%s\n", name); @@ -199,11 +202,11 @@ kbd_callback(const char *name, int name_len, const char *instruction, (void)instruction_len; #endif /* CURL_LIBSSH2_DEBUG */ if(num_prompts == 1) { + struct connectdata *conn = data->conn; responses[0].text = strdup(conn->passwd); responses[0].length = curlx_uztoui(strlen(conn->passwd)); } (void)prompts; - (void)abstract; } /* kbd_callback */ static CURLcode sftp_libssh2_error_to_CURLE(unsigned long err) @@ -956,7 +959,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) out_of_memory = TRUE; } - if(out_of_memory || sshc->rsa == NULL) { + if(out_of_memory || !sshc->rsa) { Curl_safefree(sshc->rsa); Curl_safefree(sshc->rsa_pub); state(data, SSH_SESSION_FREE); @@ -1359,7 +1362,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) * command with a space so we can check for it unconditionally */ cp = strchr(cmd, ' '); - if(cp == NULL) { + if(!cp) { failf(data, "Syntax error command '%s'. Missing parameter!", cmd); state(data, SSH_SFTP_CLOSE); @@ -1534,7 +1537,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) if(rc == LIBSSH2_ERROR_EAGAIN) { break; } - if(rc != 0 && !sshc->acceptfail) { /* get those attributes */ + if(rc && !sshc->acceptfail) { /* get those attributes */ sftperr = libssh2_sftp_last_error(sshc->sftp_session); Curl_safefree(sshc->quote_path1); Curl_safefree(sshc->quote_path2); @@ -1633,7 +1636,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) if(rc == LIBSSH2_ERROR_EAGAIN) { break; } - if(rc != 0 && !sshc->acceptfail) { + if(rc && !sshc->acceptfail) { sftperr = libssh2_sftp_last_error(sshc->sftp_session); Curl_safefree(sshc->quote_path1); Curl_safefree(sshc->quote_path2); @@ -1656,7 +1659,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) if(rc == LIBSSH2_ERROR_EAGAIN) { break; } - if(rc != 0 && !sshc->acceptfail) { + if(rc && !sshc->acceptfail) { sftperr = libssh2_sftp_last_error(sshc->sftp_session); Curl_safefree(sshc->quote_path1); Curl_safefree(sshc->quote_path2); @@ -1677,7 +1680,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) if(rc == LIBSSH2_ERROR_EAGAIN) { break; } - if(rc != 0 && !sshc->acceptfail) { + if(rc && !sshc->acceptfail) { sftperr = libssh2_sftp_last_error(sshc->sftp_session); Curl_safefree(sshc->quote_path1); failf(data, "mkdir command failed: %s", @@ -1702,7 +1705,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) if(rc == LIBSSH2_ERROR_EAGAIN) { break; } - if(rc != 0 && !sshc->acceptfail) { + if(rc && !sshc->acceptfail) { sftperr = libssh2_sftp_last_error(sshc->sftp_session); Curl_safefree(sshc->quote_path1); Curl_safefree(sshc->quote_path2); @@ -1722,7 +1725,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) if(rc == LIBSSH2_ERROR_EAGAIN) { break; } - if(rc != 0 && !sshc->acceptfail) { + if(rc && !sshc->acceptfail) { sftperr = libssh2_sftp_last_error(sshc->sftp_session); Curl_safefree(sshc->quote_path1); failf(data, "rmdir command failed: %s", @@ -1741,7 +1744,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) if(rc == LIBSSH2_ERROR_EAGAIN) { break; } - if(rc != 0 && !sshc->acceptfail) { + if(rc && !sshc->acceptfail) { sftperr = libssh2_sftp_last_error(sshc->sftp_session); Curl_safefree(sshc->quote_path1); failf(data, "rm command failed: %s", sftp_libssh2_strerror(sftperr)); @@ -1764,7 +1767,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) if(rc == LIBSSH2_ERROR_EAGAIN) { break; } - if(rc != 0 && !sshc->acceptfail) { + if(rc && !sshc->acceptfail) { sftperr = libssh2_sftp_last_error(sshc->sftp_session); Curl_safefree(sshc->quote_path1); failf(data, "statvfs command failed: %s", @@ -1857,7 +1860,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) * same name as the last directory in the path. */ - if(data->state.resume_from != 0) { + if(data->state.resume_from) { LIBSSH2_SFTP_ATTRIBUTES attrs; if(data->state.resume_from < 0) { rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshp->path, @@ -1880,7 +1883,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) } } - if(data->set.ftp_append) + if(data->set.remote_append) /* Try to open for append, but create if nonexisting */ flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND; else if(data->state.resume_from > 0) @@ -2143,7 +2146,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) readdir_len = (size_t) rc; sshp->readdir_filename[readdir_len] = '\0'; - if(data->set.ftp_list_only) { + if(data->set.list_only) { result = Curl_client_write(data, CLIENTWRITE_BODY, sshp->readdir_filename, readdir_len); @@ -2931,7 +2934,7 @@ static CURLcode ssh_multi_statemach(struct Curl_easy *data, bool *done) static CURLcode ssh_block_statemach(struct Curl_easy *data, struct connectdata *conn, - bool duringconnect) + bool disconnect) { struct ssh_conn *sshc = &conn->proto.sshc; CURLcode result = CURLE_OK; @@ -2945,17 +2948,19 @@ static CURLcode ssh_block_statemach(struct Curl_easy *data, if(result) break; - if(Curl_pgrsUpdate(data)) - return CURLE_ABORTED_BY_CALLBACK; + if(!disconnect) { + if(Curl_pgrsUpdate(data)) + return CURLE_ABORTED_BY_CALLBACK; - result = Curl_speedcheck(data, now); - if(result) - break; + result = Curl_speedcheck(data, now); + if(result) + break; - left = Curl_timeleft(data, NULL, duringconnect); - if(left < 0) { - failf(data, "Operation timed out"); - return CURLE_OPERATION_TIMEDOUT; + left = Curl_timeleft(data, NULL, FALSE); + if(left < 0) { + failf(data, "Operation timed out"); + return CURLE_OPERATION_TIMEDOUT; + } } if(block) { @@ -3054,17 +3059,15 @@ static CURLcode ssh_connect(struct Curl_easy *data, bool *done) #ifdef CURL_LIBSSH2_DEBUG curl_socket_t sock; #endif - struct SSHPROTO *sshp = data->req.p.ssh; struct ssh_conn *sshc; CURLcode result; struct connectdata *conn = data->conn; /* initialize per-handle data if not already */ - if(!sshp) { + if(!data->req.p.ssh) { result = ssh_setup_connection(data, conn); if(result) return result; - sshp = data->req.p.ssh; } /* We default to persistent connections. We set this already in this connect @@ -3086,7 +3089,7 @@ static CURLcode ssh_connect(struct Curl_easy *data, bool *done) sshc->ssh_session = libssh2_session_init_ex(my_libssh2_malloc, my_libssh2_free, my_libssh2_realloc, data); - if(sshc->ssh_session == NULL) { + if(!sshc->ssh_session) { failf(data, "Failure initialising ssh session"); return CURLE_FAILED_INIT; } @@ -3159,6 +3162,7 @@ static CURLcode ssh_connect(struct Curl_easy *data, bool *done) sshc->kh = libssh2_knownhost_init(sshc->ssh_session); if(!sshc->kh) { libssh2_session_free(sshc->ssh_session); + sshc->ssh_session = NULL; return CURLE_FAILED_INIT; } @@ -3279,10 +3283,8 @@ static CURLcode scp_disconnect(struct Curl_easy *data, if(sshc->ssh_session) { /* only if there's a session still around to use! */ - state(data, SSH_SESSION_DISCONNECT); - - result = ssh_block_statemach(data, conn, FALSE); + result = ssh_block_statemach(data, conn, TRUE); } return result; @@ -3296,10 +3298,9 @@ static CURLcode ssh_done(struct Curl_easy *data, CURLcode status) struct SSHPROTO *sshp = data->req.p.ssh; struct connectdata *conn = data->conn; - if(!status) { + if(!status) /* run the state-machine */ result = ssh_block_statemach(data, conn, FALSE); - } else result = status; @@ -3439,7 +3440,7 @@ static CURLcode sftp_disconnect(struct Curl_easy *data, if(sshc->ssh_session) { /* only if there's a session still around to use! */ state(data, SSH_SFTP_SHUTDOWN); - result = ssh_block_statemach(data, conn, FALSE); + result = ssh_block_statemach(data, conn, TRUE); } DEBUGF(infof(data, "SSH DISCONNECT is done\n")); @@ -3606,4 +3607,21 @@ size_t Curl_ssh_version(char *buffer, size_t buflen) return msnprintf(buffer, buflen, "libssh2/%s", LIBSSH2_VERSION); } +/* The SSH session is associated with the *CONNECTION* but the callback user + * pointer is an easy handle pointer. This function allows us to reassign the + * user pointer to the *CURRENT* (new) easy handle. + */ +static void ssh_attach(struct Curl_easy *data, struct connectdata *conn) +{ + DEBUGASSERT(data); + DEBUGASSERT(conn); + if(conn->handler->protocol & PROTO_FAMILY_SSH) { + struct ssh_conn *sshc = &conn->proto.sshc; + if(sshc->ssh_session) { + /* only re-attach if the session already exists */ + void **abstract = libssh2_session_abstract(sshc->ssh_session); + *abstract = data; + } + } +} #endif /* USE_LIBSSH2 */ diff --git a/lib/vssh/ssh.h b/lib/vssh/ssh.h index 52e1ee6..505b078 100644 --- a/lib/vssh/ssh.h +++ b/lib/vssh/ssh.h @@ -263,9 +263,12 @@ extern const struct Curl_handler Curl_handler_sftp; CURLcode Curl_ssh_init(void); void Curl_ssh_cleanup(void); size_t Curl_ssh_version(char *buffer, size_t buflen); +void Curl_ssh_attach(struct Curl_easy *data, + struct connectdata *conn); #else /* for non-SSH builds */ #define Curl_ssh_cleanup() +#define Curl_ssh_attach(x,y) #endif #endif /* HEADER_CURL_SSH_H */ diff --git a/lib/vssh/wolfssh.c b/lib/vssh/wolfssh.c index 6020180..9f3266a 100644 --- a/lib/vssh/wolfssh.c +++ b/lib/vssh/wolfssh.c @@ -91,6 +91,7 @@ const struct Curl_handler Curl_handler_scp = { wscp_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_SSH, /* defport */ CURLPROTO_SCP, /* protocol */ PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION @@ -119,6 +120,7 @@ const struct Curl_handler Curl_handler_sftp = { wsftp_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_SSH, /* defport */ CURLPROTO_SFTP, /* protocol */ CURLPROTO_SFTP, /* family */ @@ -388,7 +390,7 @@ static CURLcode wssh_connect(struct Curl_easy *data, bool *done) } sshc->ssh_session = wolfSSH_new(sshc->ctx); - if(sshc->ssh_session == NULL) { + if(!sshc->ssh_session) { failf(data, "No wolfSSH session"); goto error; } @@ -585,7 +587,7 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, bool *block) } } - if(data->set.ftp_append) + if(data->set.remote_append) /* Try to open for append, but create if nonexisting */ flags = WOLFSSH_FXF_WRITE|WOLFSSH_FXF_CREAT|WOLFSSH_FXF_APPEND; else if(data->state.resume_from > 0) @@ -859,9 +861,9 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, bool *block) result = CURLE_OK; while(name) { char *line = aprintf("%s\n", - data->set.ftp_list_only ? + data->set.list_only ? name->fName : name->lName); - if(line == NULL) { + if(!line) { state(data, SSH_SFTP_CLOSE); sshc->actualcode = CURLE_OUT_OF_MEMORY; break; |