aboutsummaryrefslogtreecommitdiff
path: root/lib/vssh/libssh2.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/vssh/libssh2.c')
-rw-r--r--lib/vssh/libssh2.c328
1 files changed, 165 insertions, 163 deletions
diff --git a/lib/vssh/libssh2.c b/lib/vssh/libssh2.c
index f539b393b..e9dfef950 100644
--- a/lib/vssh/libssh2.c
+++ b/lib/vssh/libssh2.c
@@ -138,7 +138,7 @@ const struct Curl_handler Curl_handler_scp = {
ZERO_NULL, /* domore_getsock */
ssh_getsock, /* perform_getsock */
scp_disconnect, /* disconnect */
- ZERO_NULL, /* readwrite */
+ ZERO_NULL, /* write_resp */
ZERO_NULL, /* connection_check */
ssh_attach, /* attach */
PORT_SSH, /* defport */
@@ -167,7 +167,7 @@ const struct Curl_handler Curl_handler_sftp = {
ZERO_NULL, /* domore_getsock */
ssh_getsock, /* perform_getsock */
sftp_disconnect, /* disconnect */
- ZERO_NULL, /* readwrite */
+ ZERO_NULL, /* write_resp */
ZERO_NULL, /* connection_check */
ssh_attach, /* attach */
PORT_SSH, /* defport */
@@ -589,10 +589,9 @@ static CURLcode ssh_knownhost(struct Curl_easy *data)
switch(rc) {
default: /* unknown return codes will equal reject */
- /* FALLTHROUGH */
case CURLKHSTAT_REJECT:
state(data, SSH_SESSION_FREE);
- /* FALLTHROUGH */
+ FALLTHROUGH();
case CURLKHSTAT_DEFER:
/* DEFER means bail out but keep the SSH_HOSTKEY state */
result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
@@ -601,9 +600,8 @@ static CURLcode ssh_knownhost(struct Curl_easy *data)
/* remove old host+key that doesn't match */
if(host)
libssh2_knownhost_del(sshc->kh, host);
- /* FALLTHROUGH */
+ FALLTHROUGH();
case CURLKHSTAT_FINE:
- /* FALLTHROUGH */
case CURLKHSTAT_FINE_ADD_TO_FILE:
/* proceed */
if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
@@ -997,7 +995,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
}
state(data, SSH_S_STARTUP);
- /* FALLTHROUGH */
+ FALLTHROUGH();
case SSH_S_STARTUP:
rc = session_startup(sshc->ssh_session, sock);
@@ -1016,7 +1014,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
state(data, SSH_HOSTKEY);
- /* FALLTHROUGH */
+ FALLTHROUGH();
case SSH_HOSTKEY:
/*
* Before we authenticate we should check the hostkey's fingerprint
@@ -1537,139 +1535,137 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
state(data, SSH_SFTP_NEXT_QUOTE);
break;
}
- {
- /*
- * the arguments following the command must be separated from the
- * command with a space so we can check for it unconditionally
- */
- cp = strchr(cmd, ' ');
- if(!cp) {
- failf(data, "Syntax error command '%s', missing parameter",
- cmd);
+
+ /*
+ * the arguments following the command must be separated from the
+ * command with a space so we can check for it unconditionally
+ */
+ cp = strchr(cmd, ' ');
+ if(!cp) {
+ failf(data, "Syntax error command '%s', missing parameter",
+ cmd);
+ state(data, SSH_SFTP_CLOSE);
+ sshc->nextstate = SSH_NO_STATE;
+ sshc->actualcode = CURLE_QUOTE_ERROR;
+ break;
+ }
+
+ /*
+ * also, every command takes at least one argument so we get that
+ * first argument right now
+ */
+ result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir);
+ if(result) {
+ if(result == CURLE_OUT_OF_MEMORY)
+ failf(data, "Out of memory");
+ else
+ failf(data, "Syntax error: Bad first parameter to '%s'", cmd);
+ state(data, SSH_SFTP_CLOSE);
+ sshc->nextstate = SSH_NO_STATE;
+ sshc->actualcode = result;
+ break;
+ }
+
+ /*
+ * SFTP is a binary protocol, so we don't send text commands
+ * to the server. Instead, we scan for commands used by
+ * OpenSSH's sftp program and call the appropriate libssh2
+ * functions.
+ */
+ if(strncasecompare(cmd, "chgrp ", 6) ||
+ strncasecompare(cmd, "chmod ", 6) ||
+ strncasecompare(cmd, "chown ", 6) ||
+ strncasecompare(cmd, "atime ", 6) ||
+ strncasecompare(cmd, "mtime ", 6)) {
+ /* attribute change */
+
+ /* sshc->quote_path1 contains the mode to set */
+ /* get the destination */
+ result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
+ if(result) {
+ if(result == CURLE_OUT_OF_MEMORY)
+ failf(data, "Out of memory");
+ else
+ failf(data, "Syntax error in %s: Bad second parameter", cmd);
+ Curl_safefree(sshc->quote_path1);
state(data, SSH_SFTP_CLOSE);
sshc->nextstate = SSH_NO_STATE;
- sshc->actualcode = CURLE_QUOTE_ERROR;
+ sshc->actualcode = result;
break;
}
-
- /*
- * also, every command takes at least one argument so we get that
- * first argument right now
- */
- result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir);
+ memset(&sshp->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
+ state(data, SSH_SFTP_QUOTE_STAT);
+ break;
+ }
+ if(strncasecompare(cmd, "ln ", 3) ||
+ strncasecompare(cmd, "symlink ", 8)) {
+ /* symbolic linking */
+ /* sshc->quote_path1 is the source */
+ /* get the destination */
+ result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
if(result) {
if(result == CURLE_OUT_OF_MEMORY)
failf(data, "Out of memory");
else
- failf(data, "Syntax error: Bad first parameter to '%s'", cmd);
+ failf(data,
+ "Syntax error in ln/symlink: Bad second parameter");
+ Curl_safefree(sshc->quote_path1);
state(data, SSH_SFTP_CLOSE);
sshc->nextstate = SSH_NO_STATE;
sshc->actualcode = result;
break;
}
-
- /*
- * SFTP is a binary protocol, so we don't send text commands
- * to the server. Instead, we scan for commands used by
- * OpenSSH's sftp program and call the appropriate libssh2
- * functions.
- */
- if(strncasecompare(cmd, "chgrp ", 6) ||
- strncasecompare(cmd, "chmod ", 6) ||
- strncasecompare(cmd, "chown ", 6) ||
- strncasecompare(cmd, "atime ", 6) ||
- strncasecompare(cmd, "mtime ", 6)) {
- /* attribute change */
-
- /* sshc->quote_path1 contains the mode to set */
- /* get the destination */
- result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
- if(result) {
- if(result == CURLE_OUT_OF_MEMORY)
- failf(data, "Out of memory");
- else
- failf(data, "Syntax error in %s: Bad second parameter", cmd);
- Curl_safefree(sshc->quote_path1);
- state(data, SSH_SFTP_CLOSE);
- sshc->nextstate = SSH_NO_STATE;
- sshc->actualcode = result;
- break;
- }
- memset(&sshp->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
- state(data, SSH_SFTP_QUOTE_STAT);
- break;
- }
- if(strncasecompare(cmd, "ln ", 3) ||
- strncasecompare(cmd, "symlink ", 8)) {
- /* symbolic linking */
- /* sshc->quote_path1 is the source */
- /* get the destination */
- result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
- if(result) {
- if(result == CURLE_OUT_OF_MEMORY)
- failf(data, "Out of memory");
- else
- failf(data,
- "Syntax error in ln/symlink: Bad second parameter");
- Curl_safefree(sshc->quote_path1);
- state(data, SSH_SFTP_CLOSE);
- sshc->nextstate = SSH_NO_STATE;
- sshc->actualcode = result;
- break;
- }
- state(data, SSH_SFTP_QUOTE_SYMLINK);
- break;
- }
- else if(strncasecompare(cmd, "mkdir ", 6)) {
- /* create dir */
- state(data, SSH_SFTP_QUOTE_MKDIR);
- break;
- }
- else if(strncasecompare(cmd, "rename ", 7)) {
- /* rename file */
- /* first param is the source path */
- /* second param is the dest. path */
- result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
- if(result) {
- if(result == CURLE_OUT_OF_MEMORY)
- failf(data, "Out of memory");
- else
- failf(data, "Syntax error in rename: Bad second parameter");
- Curl_safefree(sshc->quote_path1);
- state(data, SSH_SFTP_CLOSE);
- sshc->nextstate = SSH_NO_STATE;
- sshc->actualcode = result;
- break;
- }
- state(data, SSH_SFTP_QUOTE_RENAME);
- break;
- }
- else if(strncasecompare(cmd, "rmdir ", 6)) {
- /* delete dir */
- state(data, SSH_SFTP_QUOTE_RMDIR);
- break;
- }
- else if(strncasecompare(cmd, "rm ", 3)) {
- state(data, SSH_SFTP_QUOTE_UNLINK);
+ state(data, SSH_SFTP_QUOTE_SYMLINK);
+ break;
+ }
+ else if(strncasecompare(cmd, "mkdir ", 6)) {
+ /* create dir */
+ state(data, SSH_SFTP_QUOTE_MKDIR);
+ break;
+ }
+ else if(strncasecompare(cmd, "rename ", 7)) {
+ /* rename file */
+ /* first param is the source path */
+ /* second param is the dest. path */
+ result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
+ if(result) {
+ if(result == CURLE_OUT_OF_MEMORY)
+ failf(data, "Out of memory");
+ else
+ failf(data, "Syntax error in rename: Bad second parameter");
+ Curl_safefree(sshc->quote_path1);
+ state(data, SSH_SFTP_CLOSE);
+ sshc->nextstate = SSH_NO_STATE;
+ sshc->actualcode = result;
break;
}
+ state(data, SSH_SFTP_QUOTE_RENAME);
+ break;
+ }
+ else if(strncasecompare(cmd, "rmdir ", 6)) {
+ /* delete dir */
+ state(data, SSH_SFTP_QUOTE_RMDIR);
+ break;
+ }
+ else if(strncasecompare(cmd, "rm ", 3)) {
+ state(data, SSH_SFTP_QUOTE_UNLINK);
+ break;
+ }
#ifdef HAS_STATVFS_SUPPORT
- else if(strncasecompare(cmd, "statvfs ", 8)) {
- state(data, SSH_SFTP_QUOTE_STATVFS);
- break;
- }
-#endif
-
- failf(data, "Unknown SFTP command");
- Curl_safefree(sshc->quote_path1);
- Curl_safefree(sshc->quote_path2);
- state(data, SSH_SFTP_CLOSE);
- sshc->nextstate = SSH_NO_STATE;
- sshc->actualcode = CURLE_QUOTE_ERROR;
+ else if(strncasecompare(cmd, "statvfs ", 8)) {
+ state(data, SSH_SFTP_QUOTE_STATVFS);
break;
}
+#endif
+
+ failf(data, "Unknown SFTP command");
+ Curl_safefree(sshc->quote_path1);
+ Curl_safefree(sshc->quote_path2);
+ state(data, SSH_SFTP_CLOSE);
+ sshc->nextstate = SSH_NO_STATE;
+ sshc->actualcode = CURLE_QUOTE_ERROR;
+ break;
}
- break;
case SSH_SFTP_NEXT_QUOTE:
Curl_safefree(sshc->quote_path1);
@@ -1962,13 +1958,23 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
break;
}
else if(rc == 0) {
+ #ifdef _MSC_VER
+ #define CURL_LIBSSH2_VFS_SIZE_MASK "I64u"
+ #else
+ #define CURL_LIBSSH2_VFS_SIZE_MASK "llu"
+ #endif
char *tmp = aprintf("statvfs:\n"
- "f_bsize: %llu\n" "f_frsize: %llu\n"
- "f_blocks: %llu\n" "f_bfree: %llu\n"
- "f_bavail: %llu\n" "f_files: %llu\n"
- "f_ffree: %llu\n" "f_favail: %llu\n"
- "f_fsid: %llu\n" "f_flag: %llu\n"
- "f_namemax: %llu\n",
+ "f_bsize: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
+ "f_frsize: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
+ "f_blocks: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
+ "f_bfree: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
+ "f_bavail: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
+ "f_files: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
+ "f_ffree: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
+ "f_favail: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
+ "f_fsid: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
+ "f_flag: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
+ "f_namemax: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n",
statvfs.f_bsize, statvfs.f_frsize,
statvfs.f_blocks, statvfs.f_bfree,
statvfs.f_bavail, statvfs.f_files,
@@ -2152,14 +2158,15 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
}
/* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
do {
+ char scratch[4*1024];
size_t readthisamountnow =
- (data->state.resume_from - passed > data->set.buffer_size) ?
- (size_t)data->set.buffer_size :
- curlx_sotouz(data->state.resume_from - passed);
+ (data->state.resume_from - passed >
+ (curl_off_t)sizeof(scratch)) ?
+ sizeof(scratch) : curlx_sotouz(data->state.resume_from - passed);
size_t actuallyread;
Curl_set_in_callback(data, true);
- actuallyread = data->state.fread_func(data->state.buffer, 1,
+ actuallyread = data->state.fread_func(scratch, 1,
readthisamountnow,
data->state.in);
Curl_set_in_callback(data, false);
@@ -2205,7 +2212,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
/* we want to use the _sending_ function even when the socket turns
out readable as the underlying libssh2 sftp send function will deal
with both accordingly */
- conn->cselect_bits = CURL_CSELECT_OUT;
+ data->state.select_bits = CURL_CSELECT_OUT;
/* since we don't really wait for anything at this point, we want the
state machine to move on as soon as possible so we set a very short
@@ -2341,14 +2348,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
state(data, SSH_STOP);
break;
}
- /* since this counts what we send to the client, we include the
- newline in this counter */
- data->req.bytecount += readdir_len + 1;
- /* output debug output if that is requested */
- Curl_debug(data, CURLINFO_DATA_IN, sshp->readdir_filename,
- readdir_len);
- Curl_debug(data, CURLINFO_DATA_IN, (char *)"\n", 1);
}
else {
result = Curl_dyn_add(&sshp->readdir, sshp->readdir_longentry);
@@ -2427,13 +2427,6 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
Curl_dyn_ptr(&sshp->readdir),
Curl_dyn_len(&sshp->readdir));
- if(!result) {
- /* output debug output if that is requested */
- Curl_debug(data, CURLINFO_DATA_IN,
- Curl_dyn_ptr(&sshp->readdir),
- Curl_dyn_len(&sshp->readdir));
- data->req.bytecount += Curl_dyn_len(&sshp->readdir);
- }
if(result) {
Curl_dyn_free(&sshp->readdir);
state(data, SSH_STOP);
@@ -2608,7 +2601,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
/* we want to use the _receiving_ function even when the socket turns
out writableable as the underlying libssh2 recv function will deal
with both accordingly */
- conn->cselect_bits = CURL_CSELECT_IN;
+ data->state.select_bits = CURL_CSELECT_IN;
if(result) {
/* this should never occur; the close state should be entered
@@ -2763,7 +2756,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
/* we want to use the _sending_ function even when the socket turns
out readable as the underlying libssh2 scp send function will deal
with both accordingly */
- conn->cselect_bits = CURL_CSELECT_OUT;
+ data->state.select_bits = CURL_CSELECT_OUT;
state(data, SSH_STOP);
}
@@ -2825,7 +2818,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
/* we want to use the _receiving_ function even when the socket turns
out writableable as the underlying libssh2 recv function will deal
with both accordingly */
- conn->cselect_bits = CURL_CSELECT_IN;
+ data->state.select_bits = CURL_CSELECT_IN;
if(result) {
state(data, SSH_SCP_CHANNEL_FREE);
@@ -3030,7 +3023,6 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
break;
case SSH_QUIT:
- /* fallthrough, just stop! */
default:
/* internal error */
sshc->nextstate = SSH_NO_STATE;
@@ -3299,6 +3291,27 @@ static CURLcode ssh_connect(struct Curl_easy *data, bool *done)
#ifndef CURL_DISABLE_PROXY
if(conn->http_proxy.proxytype == CURLPROXY_HTTPS) {
/*
+ Setup libssh2 callbacks to make it read/write TLS from the socket.
+
+ ssize_t
+ recvcb(libssh2_socket_t sock, void *buffer, size_t length,
+ int flags, void **abstract);
+
+ ssize_t
+ sendcb(libssh2_socket_t sock, const void *buffer, size_t length,
+ int flags, void **abstract);
+
+ */
+#if LIBSSH2_VERSION_NUM >= 0x010b01
+ infof(data, "Uses HTTPS proxy");
+ libssh2_session_callback_set2(sshc->ssh_session,
+ LIBSSH2_CALLBACK_RECV,
+ (libssh2_cb_generic *)ssh_tls_recv);
+ libssh2_session_callback_set2(sshc->ssh_session,
+ LIBSSH2_CALLBACK_SEND,
+ (libssh2_cb_generic *)ssh_tls_send);
+#else
+ /*
* This crazy union dance is here to avoid assigning a void pointer a
* function pointer as it is invalid C. The problem is of course that
* libssh2 has such an API...
@@ -3318,22 +3331,11 @@ static CURLcode ssh_connect(struct Curl_easy *data, bool *done)
sshsend.sendptr = ssh_tls_send;
infof(data, "Uses HTTPS proxy");
- /*
- Setup libssh2 callbacks to make it read/write TLS from the socket.
-
- ssize_t
- recvcb(libssh2_socket_t sock, void *buffer, size_t length,
- int flags, void **abstract);
-
- ssize_t
- sendcb(libssh2_socket_t sock, const void *buffer, size_t length,
- int flags, void **abstract);
-
- */
libssh2_session_callback_set(sshc->ssh_session,
LIBSSH2_CALLBACK_RECV, sshrecv.recvp);
libssh2_session_callback_set(sshc->ssh_session,
LIBSSH2_CALLBACK_SEND, sshsend.sendp);
+#endif
/* Store the underlying TLS recv/send function pointers to be used when
reading from the proxy */