-const char gateway_rcs[] = "$Id: gateway.c,v 1.102 2017/07/01 17:08:25 ler762 Exp $";
/*********************************************************************
*
* File : $Source: /cvsroot/ijbswa/current/gateway.c,v $
* or SOCKS5 proxy).
*
* Copyright : Written by and Copyright (C) 2001-2017 the
- * Privoxy team. http://www.privoxy.org/
+ * Privoxy team. https://www.privoxy.org/
*
* Based on the Internet Junkbuster originally written
* by and Copyright (C) 1997 Anonymous Coders and
#include <netdb.h>
#endif /* def __BEOS__ */
-#ifdef __OS2__
-#include <utils.h>
-#endif /* def __OS2__ */
-
#include "project.h"
#include "jcc.h"
#include "errlog.h"
#endif /* HAVE_POLL */
#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
-const char gateway_h_rcs[] = GATEWAY_H_VERSION;
-
-static jb_socket socks4_connect(const struct forward_spec * fwd,
- const char * target_host,
+static jb_socket socks4_connect(const struct forward_spec *fwd,
+ const char *target_host,
int target_port,
struct client_state *csp);
static const char socks_userid[] = "anonymous";
#ifdef FEATURE_CONNECTION_SHARING
+#ifndef FEATURE_CONNECTION_KEEP_ALIVE
+#error Using FEATURE_CONNECTION_SHARING without FEATURE_CONNECTION_KEEP_ALIVE is impossible
+#endif
#define MAX_REUSABLE_CONNECTIONS 100
return;
}
+ assert(slot < SZ(reusable_connection));
assert(NULL != connection->host);
reusable_connection[slot].host = strdup_or_die(connection->host);
reusable_connection[slot].sfd = connection->sfd;
* Returns : JB_INVALID_SOCKET => failure, else it is the socket file descriptor.
*
*********************************************************************/
-jb_socket forwarded_connect(const struct forward_spec * fwd,
+jb_socket forwarded_connect(const struct forward_spec *fwd,
struct http_request *http,
struct client_state *csp)
{
- const char * dest_host;
+ const char *dest_host;
int dest_port;
jb_socket sfd = JB_INVALID_SOCKET;
}
-#ifdef FUZZ_SOCKS
+#ifdef FUZZ
/*********************************************************************
*
* Function : socks_fuzz
* Returns : JB_INVALID_SOCKET => failure, else a socket file descriptor.
*
*********************************************************************/
-static jb_socket socks4_connect(const struct forward_spec * fwd,
- const char * target_host,
+static jb_socket socks4_connect(const struct forward_spec *fwd,
+ const char *target_host,
int target_port,
struct client_state *csp)
{
c->dstip[2] = (unsigned char)((web_server_addr >> 8) & 0xff);
c->dstip[3] = (unsigned char)((web_server_addr ) & 0xff);
-#ifdef FUZZ_SOCKS
+#ifdef FUZZ
sfd = 0;
#else
/* pass the request to the socks server */
return(JB_INVALID_SOCKET);
}
-#ifdef FUZZ_SOCKS
+#ifdef FUZZ
sfd = 0;
if (!err && read_socket(sfd, sbuf, 2) != 2)
#else
client_pos = 0;
cbuf[client_pos++] = '\x05'; /* Version */
- cbuf[client_pos++] = '\x01'; /* One authentication method supported */
+
+ if (fwd->auth_username && fwd->auth_password)
+ {
+ cbuf[client_pos++] = '\x02'; /* Two authentication methods supported */
+ cbuf[client_pos++] = '\x02'; /* Username/password */
+ }
+ else
+ {
+ cbuf[client_pos++] = '\x01'; /* One authentication method supported */
+ }
cbuf[client_pos++] = '\x00'; /* The no authentication authentication method */
if (write_socket(sfd, cbuf, client_pos))
err = 1;
}
- if (!err && (sbuf[1] != '\x00'))
+ if (!err && (sbuf[1] == '\x02'))
+ {
+ /* check cbuf overflow */
+ size_t auth_len = strlen(fwd->auth_username) + strlen(fwd->auth_password) + 3;
+ if (auth_len > sizeof(cbuf))
+ {
+ errstr = "SOCKS5 username and/or password too long";
+ err = 1;
+ }
+
+ if (!err)
+ {
+ client_pos = 0;
+ cbuf[client_pos++] = '\x01'; /* Version */
+ cbuf[client_pos++] = (char)strlen(fwd->auth_username);
+
+ memcpy(cbuf + client_pos, fwd->auth_username, strlen(fwd->auth_username));
+ client_pos += strlen(fwd->auth_username);
+ cbuf[client_pos++] = (char)strlen(fwd->auth_password);
+ memcpy(cbuf + client_pos, fwd->auth_password, strlen(fwd->auth_password));
+ client_pos += strlen(fwd->auth_password);
+
+ if (write_socket(sfd, cbuf, client_pos))
+ {
+ errstr = "SOCKS5 negotiation auth write failed";
+ csp->error_message = strdup(errstr);
+ log_error(LOG_LEVEL_CONNECT, "%s", errstr);
+ close_socket(sfd);
+ return(JB_INVALID_SOCKET);
+ }
+
+ if (read_socket(sfd, sbuf, sizeof(sbuf)) != 2)
+ {
+ errstr = "SOCKS5 negotiation auth read failed";
+ err = 1;
+ }
+ }
+
+ if (!err && (sbuf[1] != '\x00'))
+ {
+ errstr = "SOCKS5 authentication failed";
+ err = 1;
+ }
+ }
+ else if (!err && (sbuf[1] != '\x00'))
{
errstr = "SOCKS5 negotiation protocol error";
err = 1;
cbuf[client_pos++] = (char)((target_port >> 8) & 0xff);
cbuf[client_pos++] = (char)((target_port ) & 0xff);
-#ifndef FUZZ_SOCKS
+#ifndef FUZZ
if (write_socket(sfd, cbuf, client_pos))
{
errstr = "SOCKS5 negotiation write failed";