1
0
mirror of https://github.com/moparisthebest/curl synced 2024-08-13 17:03:50 -04:00

libssh2: handle the SSH protocols done over HTTPS proxy

Reported-by: Robin Douine
Fixes #4295
Closes #6021
This commit is contained in:
Daniel Stenberg 2020-09-28 14:02:27 +02:00
parent 82d66f1582
commit edfb6168e9
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2

View File

@ -3039,6 +3039,42 @@ static CURLcode ssh_setup_connection(struct connectdata *conn)
static Curl_recv scp_recv, sftp_recv;
static Curl_send scp_send, sftp_send;
static ssize_t ssh_tls_recv(libssh2_socket_t sock, void *buffer,
size_t length, int flags, void **abstract)
{
struct connectdata *conn = (struct connectdata *)*abstract;
ssize_t nread;
CURLcode result;
(void)flags;
result = Curl_read(conn, sock, buffer, length, &nread);
if(result == CURLE_AGAIN)
return -EAGAIN; /* magic return code for libssh2 */
else if(result)
return -1; /* generic error */
if(conn->data->set.verbose)
Curl_debug(conn->data, CURLINFO_DATA_IN, (char *)buffer, (size_t)nread);
return nread;
}
static ssize_t ssh_tls_send(libssh2_socket_t sock, const void *buffer,
size_t length, int flags, void **abstract)
{
struct connectdata *conn = (struct connectdata *)*abstract;
ssize_t nwrite;
CURLcode result;
(void)flags;
result = Curl_write(conn, sock, buffer, length, &nwrite);
if(result == CURLE_AGAIN)
return -EAGAIN; /* magic return code for libssh2 */
else if(result)
return -1; /* error */
if(conn->data->set.verbose)
Curl_debug(conn->data, CURLINFO_DATA_OUT, (char *)buffer, (size_t)nwrite);
return nwrite;
}
/*
* Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
* do protocol-specific actions at connect-time.
@ -3060,14 +3096,6 @@ static CURLcode ssh_connect(struct connectdata *conn, bool *done)
function to make the re-use checks properly be able to check this bit. */
connkeep(conn, "SSH default");
if(conn->handler->protocol & CURLPROTO_SCP) {
conn->recv[FIRSTSOCKET] = scp_recv;
conn->send[FIRSTSOCKET] = scp_send;
}
else {
conn->recv[FIRSTSOCKET] = sftp_recv;
conn->send[FIRSTSOCKET] = sftp_send;
}
ssh = &conn->proto.sshc;
#ifdef CURL_LIBSSH2_DEBUG
@ -3088,6 +3116,53 @@ static CURLcode ssh_connect(struct connectdata *conn, bool *done)
return CURLE_FAILED_INIT;
}
if(conn->http_proxy.proxytype == CURLPROXY_HTTPS) {
/*
* 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...
*/
union receive {
void *recvp;
ssize_t (*recvptr)(libssh2_socket_t, void *, size_t, int, void **);
};
union transfer {
void *sendp;
ssize_t (*sendptr)(libssh2_socket_t, const void *, size_t, int, void **);
};
union receive sshrecv;
union transfer sshsend;
sshrecv.recvptr = ssh_tls_recv;
sshsend.sendptr = ssh_tls_send;
infof(data, "Uses HTTPS proxy!\n");
/*
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(ssh->ssh_session,
LIBSSH2_CALLBACK_RECV, sshrecv.recvp);
libssh2_session_callback_set(ssh->ssh_session,
LIBSSH2_CALLBACK_SEND, sshsend.sendp);
}
else if(conn->handler->protocol & CURLPROTO_SCP) {
conn->recv[FIRSTSOCKET] = scp_recv;
conn->send[FIRSTSOCKET] = scp_send;
}
else {
conn->recv[FIRSTSOCKET] = sftp_recv;
conn->send[FIRSTSOCKET] = sftp_send;
}
if(data->set.ssh_compression) {
#if LIBSSH2_VERSION_NUM >= 0x010208
if(libssh2_session_flag(ssh->ssh_session, LIBSSH2_FLAG_COMPRESS, 1) < 0)