mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 08:08:50 -05:00
- Hans-Jurgen May pointed out that trying SCP or SFTP over a SOCKS proxy
crashed libcurl. This is now addressed by making sure we use "plain send" internally when doing the socks handshake instead of the Curl_write() function which is designed to use the "target" protocol. That's then SCP or SFTP in this case. I also took the opportunity and cleaned up some ssh- related #ifdefs in the code for readability.
This commit is contained in:
parent
2594124825
commit
422fd933f5
8
CHANGES
8
CHANGES
@ -6,6 +6,14 @@
|
|||||||
|
|
||||||
Changelog
|
Changelog
|
||||||
|
|
||||||
|
Daniel Stenberg (20 Jun 2008)
|
||||||
|
- Hans-Jurgen May pointed out that trying SCP or SFTP over a SOCKS proxy
|
||||||
|
crashed libcurl. This is now addressed by making sure we use "plain send"
|
||||||
|
internally when doing the socks handshake instead of the Curl_write()
|
||||||
|
function which is designed to use the "target" protocol. That's then SCP or
|
||||||
|
SFTP in this case. I also took the opportunity and cleaned up some ssh-
|
||||||
|
related #ifdefs in the code for readability.
|
||||||
|
|
||||||
Daniel Stenberg (19 Jun 2008)
|
Daniel Stenberg (19 Jun 2008)
|
||||||
- Christopher Palow fixed a curl_multi_socket() issue which previously caused
|
- Christopher Palow fixed a curl_multi_socket() issue which previously caused
|
||||||
libcurl to not tell the app properly when a socket was closed (when the name
|
libcurl to not tell the app properly when a socket was closed (when the name
|
||||||
|
@ -22,6 +22,7 @@ This release includes the following bugfixes:
|
|||||||
o Fixed the multi interface connection re-use with NSS-built libcurl
|
o Fixed the multi interface connection re-use with NSS-built libcurl
|
||||||
o connection re-use when using the multi interface with pipelining enabled
|
o connection re-use when using the multi interface with pipelining enabled
|
||||||
o curl_multi_socket() socket callback fix for close/re-create sockets case
|
o curl_multi_socket() socket callback fix for close/re-create sockets case
|
||||||
|
o SCP or SFTP over socks proxy crashed
|
||||||
|
|
||||||
This release includes the following known bugs:
|
This release includes the following known bugs:
|
||||||
|
|
||||||
@ -39,6 +40,6 @@ This release would not have looked like this without help, code, reports and
|
|||||||
advice from friends like these:
|
advice from friends like these:
|
||||||
|
|
||||||
Lenny Rachitsky, Axel Tillequin, Arnaud Ebalard, Yang Tse, Dan Fandrich,
|
Lenny Rachitsky, Axel Tillequin, Arnaud Ebalard, Yang Tse, Dan Fandrich,
|
||||||
Rob Crittenden, Dengminwen, Christopher Palow
|
Rob Crittenden, Dengminwen, Christopher Palow, Hans-Jürgen May
|
||||||
|
|
||||||
Thanks! (and sorry if I forgot to mention someone)
|
Thanks! (and sorry if I forgot to mention someone)
|
||||||
|
35
lib/sendf.c
35
lib/sendf.c
@ -356,16 +356,12 @@ CURLcode Curl_write(struct connectdata *conn,
|
|||||||
int num = (sockfd == conn->sock[SECONDARYSOCKET]);
|
int num = (sockfd == conn->sock[SECONDARYSOCKET]);
|
||||||
|
|
||||||
if(conn->ssl[num].state == ssl_connection_complete)
|
if(conn->ssl[num].state == ssl_connection_complete)
|
||||||
/* only TRUE if SSL enabled */
|
|
||||||
bytes_written = Curl_ssl_send(conn, num, mem, len);
|
bytes_written = Curl_ssl_send(conn, num, mem, len);
|
||||||
#ifdef USE_LIBSSH2
|
else if(Curl_ssh_enabled(conn, PROT_SCP))
|
||||||
else if(conn->protocol & PROT_SCP)
|
|
||||||
bytes_written = Curl_scp_send(conn, num, mem, len);
|
bytes_written = Curl_scp_send(conn, num, mem, len);
|
||||||
else if(conn->protocol & PROT_SFTP)
|
else if(Curl_ssh_enabled(conn, PROT_SFTP))
|
||||||
bytes_written = Curl_sftp_send(conn, num, mem, len);
|
bytes_written = Curl_sftp_send(conn, num, mem, len);
|
||||||
#endif /* !USE_LIBSSH2 */
|
|
||||||
else if(conn->sec_complete)
|
else if(conn->sec_complete)
|
||||||
/* only TRUE if krb enabled */
|
|
||||||
bytes_written = Curl_sec_send(conn, num, mem, len);
|
bytes_written = Curl_sec_send(conn, num, mem, len);
|
||||||
else
|
else
|
||||||
bytes_written = send_plain(conn, num, mem, len);
|
bytes_written = send_plain(conn, num, mem, len);
|
||||||
@ -376,6 +372,29 @@ CURLcode Curl_write(struct connectdata *conn,
|
|||||||
return retcode;
|
return retcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Curl_write_plain() is an internal write function that sends data to the
|
||||||
|
* server using plain sockets only. Otherwise meant to have the exact same
|
||||||
|
* proto as Curl_write()
|
||||||
|
*/
|
||||||
|
CURLcode Curl_write_plain(struct connectdata *conn,
|
||||||
|
curl_socket_t sockfd,
|
||||||
|
const void *mem,
|
||||||
|
size_t len,
|
||||||
|
ssize_t *written)
|
||||||
|
{
|
||||||
|
ssize_t bytes_written;
|
||||||
|
CURLcode retcode;
|
||||||
|
int num = (sockfd == conn->sock[SECONDARYSOCKET]);
|
||||||
|
|
||||||
|
bytes_written = send_plain(conn, num, mem, len);
|
||||||
|
|
||||||
|
*written = bytes_written;
|
||||||
|
retcode = (-1 != bytes_written)?CURLE_OK:CURLE_SEND_ERROR;
|
||||||
|
|
||||||
|
return retcode;
|
||||||
|
}
|
||||||
|
|
||||||
static CURLcode pausewrite(struct SessionHandle *data,
|
static CURLcode pausewrite(struct SessionHandle *data,
|
||||||
int type, /* what type of data */
|
int type, /* what type of data */
|
||||||
char *ptr,
|
char *ptr,
|
||||||
@ -574,8 +593,7 @@ int Curl_read(struct connectdata *conn, /* connection data */
|
|||||||
return -1; /* -1 from Curl_ssl_recv() means EWOULDBLOCK */
|
return -1; /* -1 from Curl_ssl_recv() means EWOULDBLOCK */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef USE_LIBSSH2
|
else if(Curl_ssh_enabled(conn, (PROT_SCP|PROT_SFTP))) {
|
||||||
else if(conn->protocol & (PROT_SCP|PROT_SFTP)) {
|
|
||||||
if(conn->protocol & PROT_SCP)
|
if(conn->protocol & PROT_SCP)
|
||||||
nread = Curl_scp_recv(conn, num, buffertofill, bytesfromsocket);
|
nread = Curl_scp_recv(conn, num, buffertofill, bytesfromsocket);
|
||||||
else if(conn->protocol & PROT_SFTP)
|
else if(conn->protocol & PROT_SFTP)
|
||||||
@ -589,7 +607,6 @@ int Curl_read(struct connectdata *conn, /* connection data */
|
|||||||
/* since it is negative and not EGAIN, it was a protocol-layer error */
|
/* since it is negative and not EGAIN, it was a protocol-layer error */
|
||||||
return CURLE_RECV_ERROR;
|
return CURLE_RECV_ERROR;
|
||||||
}
|
}
|
||||||
#endif /* !USE_LIBSSH2 */
|
|
||||||
else {
|
else {
|
||||||
if(conn->sec_complete)
|
if(conn->sec_complete)
|
||||||
nread = Curl_sec_read(conn, sockfd, buffertofill,
|
nread = Curl_sec_read(conn, sockfd, buffertofill,
|
||||||
|
10
lib/sendf.h
10
lib/sendf.h
@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@ -62,12 +62,18 @@ void Curl_read_rewind(struct connectdata *conn,
|
|||||||
int Curl_read(struct connectdata *conn, curl_socket_t sockfd,
|
int Curl_read(struct connectdata *conn, curl_socket_t sockfd,
|
||||||
char *buf, size_t buffersize,
|
char *buf, size_t buffersize,
|
||||||
ssize_t *n);
|
ssize_t *n);
|
||||||
/* internal write-function, does plain socket, SSL and krb4 */
|
/* internal write-function, does plain socket, SSL, SCP, SFTP and krb4 */
|
||||||
CURLcode Curl_write(struct connectdata *conn,
|
CURLcode Curl_write(struct connectdata *conn,
|
||||||
curl_socket_t sockfd,
|
curl_socket_t sockfd,
|
||||||
const void *mem, size_t len,
|
const void *mem, size_t len,
|
||||||
ssize_t *written);
|
ssize_t *written);
|
||||||
|
|
||||||
|
/* internal write-function, does plain sockets ONLY */
|
||||||
|
CURLcode Curl_write_plain(struct connectdata *conn,
|
||||||
|
curl_socket_t sockfd,
|
||||||
|
const void *mem, size_t len,
|
||||||
|
ssize_t *written);
|
||||||
|
|
||||||
/* the function used to output verbose information */
|
/* the function used to output verbose information */
|
||||||
int Curl_debug(struct SessionHandle *handle, curl_infotype type,
|
int Curl_debug(struct SessionHandle *handle, curl_infotype type,
|
||||||
char *data, size_t size,
|
char *data, size_t size,
|
||||||
|
12
lib/socks.c
12
lib/socks.c
@ -242,7 +242,8 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Send request */
|
/* Send request */
|
||||||
code = Curl_write(conn, sock, (char *)socksreq, packetsize + hostnamelen,
|
code = Curl_write_plain(conn, sock, (char *)socksreq,
|
||||||
|
packetsize + hostnamelen,
|
||||||
&written);
|
&written);
|
||||||
if((code != CURLE_OK) || (written != packetsize + hostnamelen)) {
|
if((code != CURLE_OK) || (written != packetsize + hostnamelen)) {
|
||||||
failf(data, "Failed to send SOCKS4 connect request.");
|
failf(data, "Failed to send SOCKS4 connect request.");
|
||||||
@ -251,7 +252,8 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
|
|||||||
if (protocol4a && hostnamelen == 0) {
|
if (protocol4a && hostnamelen == 0) {
|
||||||
/* SOCKS4a with very long hostname - send that name separately */
|
/* SOCKS4a with very long hostname - send that name separately */
|
||||||
hostnamelen = (ssize_t)strlen(hostname) + 1;
|
hostnamelen = (ssize_t)strlen(hostname) + 1;
|
||||||
code = Curl_write(conn, sock, (char *)hostname, hostnamelen, &written);
|
code = Curl_write_plain(conn, sock, (char *)hostname, hostnamelen,
|
||||||
|
&written);
|
||||||
if((code != CURLE_OK) || (written != hostnamelen)) {
|
if((code != CURLE_OK) || (written != hostnamelen)) {
|
||||||
failf(data, "Failed to send SOCKS4 connect request.");
|
failf(data, "Failed to send SOCKS4 connect request.");
|
||||||
return CURLE_COULDNT_CONNECT;
|
return CURLE_COULDNT_CONNECT;
|
||||||
@ -432,7 +434,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
|
|||||||
|
|
||||||
Curl_nonblock(sock, FALSE);
|
Curl_nonblock(sock, FALSE);
|
||||||
|
|
||||||
code = Curl_write(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]),
|
code = Curl_write_plain(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]),
|
||||||
&written);
|
&written);
|
||||||
if((code != CURLE_OK) || (written != (2 + (int)socksreq[1]))) {
|
if((code != CURLE_OK) || (written != (2 + (int)socksreq[1]))) {
|
||||||
failf(data, "Unable to send initial SOCKS5 request.");
|
failf(data, "Unable to send initial SOCKS5 request.");
|
||||||
@ -502,7 +504,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
|
|||||||
memcpy(socksreq + len, proxy_password, (int) pwlen);
|
memcpy(socksreq + len, proxy_password, (int) pwlen);
|
||||||
len += pwlen;
|
len += pwlen;
|
||||||
|
|
||||||
code = Curl_write(conn, sock, (char *)socksreq, len, &written);
|
code = Curl_write_plain(conn, sock, (char *)socksreq, len, &written);
|
||||||
if((code != CURLE_OK) || (len != written)) {
|
if((code != CURLE_OK) || (len != written)) {
|
||||||
failf(data, "Failed to send SOCKS5 sub-negotiation request.");
|
failf(data, "Failed to send SOCKS5 sub-negotiation request.");
|
||||||
return CURLE_COULDNT_CONNECT;
|
return CURLE_COULDNT_CONNECT;
|
||||||
@ -613,7 +615,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
|
|||||||
*((unsigned short*)&socksreq[8]) = htons((unsigned short)remote_port);
|
*((unsigned short*)&socksreq[8]) = htons((unsigned short)remote_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
code = Curl_write(conn, sock, (char *)socksreq, packetsize, &written);
|
code = Curl_write_plain(conn, sock, (char *)socksreq, packetsize, &written);
|
||||||
if((code != CURLE_OK) || (written != packetsize)) {
|
if((code != CURLE_OK) || (written != packetsize)) {
|
||||||
failf(data, "Failed to send SOCKS5 connect request.");
|
failf(data, "Failed to send SOCKS5 connect request.");
|
||||||
return CURLE_COULDNT_CONNECT;
|
return CURLE_COULDNT_CONNECT;
|
||||||
|
13
lib/ssh.h
13
lib/ssh.h
@ -8,7 +8,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@ -37,6 +37,17 @@ ssize_t Curl_sftp_send(struct connectdata *conn, int sockindex,
|
|||||||
const void *mem, size_t len);
|
const void *mem, size_t len);
|
||||||
ssize_t Curl_sftp_recv(struct connectdata *conn, int sockindex,
|
ssize_t Curl_sftp_recv(struct connectdata *conn, int sockindex,
|
||||||
char *mem, size_t len);
|
char *mem, size_t len);
|
||||||
|
bool Curl_ssh_enabled(struct connectdata *conn,
|
||||||
|
int prot);
|
||||||
|
|
||||||
|
#define Curl_ssh_enabled(conn,prot) (conn->protocol & prot)
|
||||||
|
|
||||||
|
#else /* USE_LIBSSH2 */
|
||||||
|
#define Curl_ssh_enabled(x,y) 0
|
||||||
|
#define Curl_scp_send(a,b,c,d) 0
|
||||||
|
#define Curl_sftp_send(a,b,c,d) 0
|
||||||
|
#define Curl_scp_recv(a,b,c,d) 0
|
||||||
|
#define Curl_sftp_recv(a,b,c,d) 0
|
||||||
|
|
||||||
#endif /* USE_LIBSSH2 */
|
#endif /* USE_LIBSSH2 */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user