socks: use own buffer instead of data->state.buffer

Closes #12788
This commit is contained in:
Stefan Eissing 2024-01-25 14:56:57 +01:00 коммит произвёл Daniel Stenberg
Родитель bc604619de
Коммит 65c7e4f92b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 5CC908FDB71E12C2
1 изменённых файлов: 19 добавлений и 8 удалений

Просмотреть файл

@ -71,9 +71,18 @@ enum connect_t {
CONNECT_DONE /* 17 connected fine to the remote or the SOCKS proxy */ CONNECT_DONE /* 17 connected fine to the remote or the SOCKS proxy */
}; };
#define CURL_SOCKS_BUF_SIZE (8*1024)
/* make sure we configure it not too low */
#if CURL_SOCKS_BUF_SIZE < 600
#error CURL_SOCKS_BUF_SIZE must be at least 600
#endif
struct socks_state { struct socks_state {
enum connect_t state; enum connect_t state;
ssize_t outstanding; /* send this many bytes more */ ssize_t outstanding; /* send this many bytes more */
unsigned char buffer[CURL_SOCKS_BUF_SIZE];
unsigned char *outp; /* send from this pointer */ unsigned char *outp; /* send from this pointer */
const char *hostname; const char *hostname;
@ -278,14 +287,11 @@ static CURLproxycode do_SOCKS4(struct Curl_cfilter *cf,
struct connectdata *conn = cf->conn; struct connectdata *conn = cf->conn;
const bool protocol4a = const bool protocol4a =
(conn->socks_proxy.proxytype == CURLPROXY_SOCKS4A) ? TRUE : FALSE; (conn->socks_proxy.proxytype == CURLPROXY_SOCKS4A) ? TRUE : FALSE;
unsigned char *socksreq = (unsigned char *)data->state.buffer; unsigned char *socksreq = sx->buffer;
CURLcode result; CURLcode result;
CURLproxycode presult; CURLproxycode presult;
struct Curl_dns_entry *dns = NULL; struct Curl_dns_entry *dns = NULL;
/* make sure that the buffer is at least 600 bytes */
DEBUGASSERT(READBUFFER_MIN >= 600);
switch(sx->state) { switch(sx->state) {
case CONNECT_SOCKS_INIT: case CONNECT_SOCKS_INIT:
/* SOCKS4 can only do IPv4, insist! */ /* SOCKS4 can only do IPv4, insist! */
@ -431,7 +437,7 @@ CONNECT_REQ_INIT:
/* append hostname */ /* append hostname */
hostnamelen = strlen(sx->hostname) + 1; /* length including NUL */ hostnamelen = strlen(sx->hostname) + 1; /* length including NUL */
if((hostnamelen <= 255) && if((hostnamelen <= 255) &&
(packetsize + hostnamelen < data->set.buffer_size)) (packetsize + hostnamelen < sizeof(sx->buffer)))
strcpy((char *)socksreq + packetsize, sx->hostname); strcpy((char *)socksreq + packetsize, sx->hostname);
else { else {
failf(data, "SOCKS4: too long host name"); failf(data, "SOCKS4: too long host name");
@ -440,6 +446,7 @@ CONNECT_REQ_INIT:
packetsize += hostnamelen; packetsize += hostnamelen;
} }
sx->outp = socksreq; sx->outp = socksreq;
DEBUGASSERT(packetsize <= sizeof(sx->buffer));
sx->outstanding = packetsize; sx->outstanding = packetsize;
sxstate(sx, data, CONNECT_REQ_SENDING); sxstate(sx, data, CONNECT_REQ_SENDING);
} }
@ -571,14 +578,14 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf,
o X'00' succeeded o X'00' succeeded
*/ */
struct connectdata *conn = cf->conn; struct connectdata *conn = cf->conn;
unsigned char *socksreq = (unsigned char *)data->state.buffer; unsigned char *socksreq = sx->buffer;
int idx; size_t idx;
CURLcode result; CURLcode result;
CURLproxycode presult; CURLproxycode presult;
bool socks5_resolve_local = bool socks5_resolve_local =
(conn->socks_proxy.proxytype == CURLPROXY_SOCKS5) ? TRUE : FALSE; (conn->socks_proxy.proxytype == CURLPROXY_SOCKS5) ? TRUE : FALSE;
const size_t hostname_len = strlen(sx->hostname); const size_t hostname_len = strlen(sx->hostname);
ssize_t len = 0; size_t len = 0;
const unsigned char auth = data->set.socks5auth; const unsigned char auth = data->set.socks5auth;
bool allow_gssapi = FALSE; bool allow_gssapi = FALSE;
struct Curl_dns_entry *dns = NULL; struct Curl_dns_entry *dns = NULL;
@ -621,6 +628,7 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf,
socksreq[1] = (unsigned char) (idx - 2); socksreq[1] = (unsigned char) (idx - 2);
sx->outp = socksreq; sx->outp = socksreq;
DEBUGASSERT(idx <= sizeof(sx->buffer));
sx->outstanding = idx; sx->outstanding = idx;
presult = socks_state_send(cf, sx, data, CURLPX_SEND_CONNECT, presult = socks_state_send(cf, sx, data, CURLPX_SEND_CONNECT,
"initial SOCKS5 request"); "initial SOCKS5 request");
@ -747,6 +755,7 @@ CONNECT_AUTH_INIT:
} }
len += proxy_password_len; len += proxy_password_len;
sxstate(sx, data, CONNECT_AUTH_SEND); sxstate(sx, data, CONNECT_AUTH_SEND);
DEBUGASSERT(len <= sizeof(sx->buffer));
sx->outstanding = len; sx->outstanding = len;
sx->outp = socksreq; sx->outp = socksreq;
} }
@ -941,6 +950,7 @@ CONNECT_REQ_SEND:
} }
#endif #endif
sx->outp = socksreq; sx->outp = socksreq;
DEBUGASSERT(len <= sizeof(sx->buffer));
sx->outstanding = len; sx->outstanding = len;
sxstate(sx, data, CONNECT_REQ_SENDING); sxstate(sx, data, CONNECT_REQ_SENDING);
FALLTHROUGH(); FALLTHROUGH();
@ -1040,6 +1050,7 @@ CONNECT_REQ_SEND:
/* decrypt_gssapi_blockread already read the whole packet */ /* decrypt_gssapi_blockread already read the whole packet */
#endif #endif
if(len > 10) { if(len > 10) {
DEBUGASSERT(len <= sizeof(sx->buffer));
sx->outstanding = len - 10; /* get the rest */ sx->outstanding = len - 10; /* get the rest */
sx->outp = &socksreq[10]; sx->outp = &socksreq[10];
sxstate(sx, data, CONNECT_REQ_READ_MORE); sxstate(sx, data, CONNECT_REQ_READ_MORE);