mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-28 06:13:31 +01:00
add HttpProxyAuthenticator config option too
svn:r4272
This commit is contained in:
parent
918c5a9115
commit
f0e309e5bd
@ -133,6 +133,7 @@ static config_var_t config_vars[] = {
|
||||
VAR("Group", STRING, Group, NULL),
|
||||
VAR("HashedControlPassword",STRING, HashedControlPassword, NULL),
|
||||
VAR("HttpProxy", STRING, HttpProxy, NULL),
|
||||
VAR("HttpProxyAuthenticator",STRING, HttpProxyAuthenticator,NULL),
|
||||
VAR("HttpsProxy", STRING, HttpsProxy, NULL),
|
||||
VAR("HttpsProxyAuthenticator",STRING,HttpsProxyAuthenticator,NULL),
|
||||
VAR("HiddenServiceOptions",LINELIST_V, RendConfigLines, NULL),
|
||||
@ -1527,6 +1528,13 @@ options_validate(or_options_t *options)
|
||||
}
|
||||
}
|
||||
|
||||
if (options->HttpProxyAuthenticator) {
|
||||
if (strlen(options->HttpProxyAuthenticator) >= 48) {
|
||||
log(LOG_WARN, "HttpProxyAuthenticator is too long (>= 48 chars).");
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (options->HttpsProxy) { /* parse it now */
|
||||
if (parse_addr_port(options->HttpsProxy, NULL,
|
||||
&options->HttpsProxyAddr, &options->HttpsProxyPort) < 0) {
|
||||
|
@ -1559,6 +1559,28 @@ int connection_send_destroy(uint16_t circ_id, connection_t *conn) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Alloocates a base64'ed authenticator for use in http or https
|
||||
* auth, based on the input string <b>authenticator</b>. Returns it
|
||||
* if success, else returns NULL. */
|
||||
char *
|
||||
alloc_http_authenticator(const char *authenticator) {
|
||||
/* an authenticator in Basic authentication
|
||||
* is just the string "username:password" */
|
||||
const int authenticator_length = strlen(authenticator);
|
||||
/* The base64_encode function needs a minimum buffer length
|
||||
* of 66 bytes. */
|
||||
const int base64_authenticator_length = (authenticator_length/48+1)*66;
|
||||
char *base64_authenticator = tor_malloc(base64_authenticator_length);
|
||||
if (base64_encode(base64_authenticator, base64_authenticator_length,
|
||||
authenticator, authenticator_length) < 0) {
|
||||
tor_free(base64_authenticator); /* free and set to null */
|
||||
} else {
|
||||
/* remove extra \n at end of encoding */
|
||||
base64_authenticator[strlen(base64_authenticator) - 1] = 0;
|
||||
}
|
||||
return base64_authenticator;
|
||||
}
|
||||
|
||||
/** Process new bytes that have arrived on conn-\>inbuf.
|
||||
*
|
||||
* This function just passes conn to the connection-specific
|
||||
|
@ -169,27 +169,18 @@ int connection_or_finished_connecting(connection_t *conn)
|
||||
char buf[1024];
|
||||
char addrbuf[INET_NTOA_BUF_LEN];
|
||||
struct in_addr in;
|
||||
char *base64_authenticator=NULL;
|
||||
const char *authenticator = get_options()->HttpsProxyAuthenticator;
|
||||
|
||||
in.s_addr = htonl(conn->addr);
|
||||
tor_inet_ntoa(&in, addrbuf, sizeof(addrbuf));
|
||||
|
||||
if (authenticator) {
|
||||
/* an authenticator in Basic authentication
|
||||
* is just the string "username:password" */
|
||||
const int authenticator_length = strlen(authenticator);
|
||||
/* The base64_encode function needs a minimum buffer length
|
||||
* of 66 bytes. */
|
||||
const int base64_authenticator_length = (authenticator_length/48+1)*66;
|
||||
char *base64_authenticator = tor_malloc(base64_authenticator_length);
|
||||
if (base64_encode(base64_authenticator, base64_authenticator_length,
|
||||
authenticator, authenticator_length) < 0) {
|
||||
log_fn(LOG_WARN, "Encoding authenticator failed");
|
||||
base64_authenticator[0] = 0;
|
||||
} else {
|
||||
/* remove extra \n at end of encoding */
|
||||
base64_authenticator[strlen(base64_authenticator) - 1] = 0;
|
||||
base64_authenticator = alloc_http_authenticator(authenticator);
|
||||
if (!base64_authenticator)
|
||||
log_fn(LOG_WARN, "Encoding https authenticator failed");
|
||||
}
|
||||
if (base64_authenticator) {
|
||||
tor_snprintf(buf, sizeof(buf), "CONNECT %s:%d HTTP/1.1\r\n"
|
||||
"Proxy-Authorization: Basic %s\r\n\r\n", addrbuf,
|
||||
conn->port, base64_authenticator);
|
||||
|
@ -363,7 +363,8 @@ directory_send_command(connection_t *conn, const char *platform,
|
||||
int purpose, const char *resource,
|
||||
const char *payload, size_t payload_len) {
|
||||
char tmp[8192];
|
||||
char proxystring[128];
|
||||
char proxystring[256];
|
||||
char proxyauthstring[256];
|
||||
char hoststring[128];
|
||||
char url[128];
|
||||
const char *httpcommand = NULL;
|
||||
@ -371,15 +372,35 @@ directory_send_command(connection_t *conn, const char *platform,
|
||||
tor_assert(conn);
|
||||
tor_assert(conn->type == CONN_TYPE_DIR);
|
||||
|
||||
/* come up with a string for which Host: we want */
|
||||
if (conn->port == 80) {
|
||||
strlcpy(hoststring, conn->address, sizeof(hoststring));
|
||||
} else {
|
||||
tor_snprintf(hoststring, sizeof(hoststring),"%s:%d",conn->address, conn->port);
|
||||
}
|
||||
|
||||
/* come up with some proxy lines, if we're using one. */
|
||||
if (get_options()->HttpProxy) {
|
||||
char *base64_authenticator=NULL;
|
||||
const char *authenticator = get_options()->HttpProxyAuthenticator;
|
||||
|
||||
tor_snprintf(proxystring, sizeof(proxystring),"http://%s", hoststring);
|
||||
if (authenticator) {
|
||||
base64_authenticator = alloc_http_authenticator(authenticator);
|
||||
if (!base64_authenticator)
|
||||
log_fn(LOG_WARN, "Encoding http authenticator failed");
|
||||
}
|
||||
if (base64_authenticator) {
|
||||
tor_snprintf(proxyauthstring, sizeof(proxyauthstring),
|
||||
"\r\nProxy-Authorization: Basic %s",
|
||||
base64_authenticator);
|
||||
tor_free(base64_authenticator);
|
||||
} else {
|
||||
proxyauthstring[0] = 0;
|
||||
}
|
||||
} else {
|
||||
proxystring[0] = 0;
|
||||
proxyauthstring[0] = 0;
|
||||
}
|
||||
|
||||
switch (purpose) {
|
||||
@ -424,12 +445,13 @@ directory_send_command(connection_t *conn, const char *platform,
|
||||
break;
|
||||
}
|
||||
|
||||
tor_snprintf(tmp, sizeof(tmp), "%s %s%s HTTP/1.0\r\nContent-Length: %lu\r\nHost: %s\r\n\r\n",
|
||||
tor_snprintf(tmp, sizeof(tmp), "%s %s%s HTTP/1.0\r\nContent-Length: %lu\r\nHost: %s%s\r\n\r\n",
|
||||
httpcommand,
|
||||
proxystring,
|
||||
url,
|
||||
payload ? (unsigned long)payload_len : 0,
|
||||
hoststring);
|
||||
hoststring,
|
||||
proxyauthstring);
|
||||
connection_write_to_buf(tmp, strlen(tmp), conn);
|
||||
|
||||
if (payload) {
|
||||
|
@ -1059,11 +1059,12 @@ typedef struct {
|
||||
char *HttpProxy; /**< hostname[:port] to use as http proxy, if any */
|
||||
uint32_t HttpProxyAddr; /**< Parsed IPv4 addr for http proxy, if any */
|
||||
uint16_t HttpProxyPort; /**< Parsed port for http proxy, if any */
|
||||
char *HttpProxyAuthenticator; /**< username:password string, if any */
|
||||
|
||||
char *HttpsProxy; /**< hostname[:port] to use as https proxy, if any */
|
||||
uint32_t HttpsProxyAddr; /**< Parsed IPv4 addr for https proxy, if any */
|
||||
uint16_t HttpsProxyPort; /**< Parsed port for https proxy, if any */
|
||||
char *HttpsProxyAuthenticator; /** username:password string, if any */
|
||||
char *HttpsProxyAuthenticator; /**< username:password string, if any */
|
||||
|
||||
struct config_line_t *DirServers; /**< List of configuration lines
|
||||
* for directory servers. */
|
||||
@ -1075,7 +1076,7 @@ typedef struct {
|
||||
smartlist_t *RedirectExitList; /**< List of exit_redirect_t */
|
||||
int _MonthlyAccountingStart; /**< Deprecated: day of month when accounting
|
||||
* interval starts */
|
||||
char *AccountingStart; /** How long is the accounting interval, and when
|
||||
char *AccountingStart; /**< How long is the accounting interval, and when
|
||||
* does it start? */
|
||||
uint64_t AccountingMax; /**< How many bytes do we allow per accounting
|
||||
* interval before hibernation? 0 for "never
|
||||
@ -1317,6 +1318,7 @@ int connection_state_is_open(connection_t *conn);
|
||||
int connection_state_is_connecting(connection_t *conn);
|
||||
|
||||
int connection_send_destroy(uint16_t circ_id, connection_t *conn);
|
||||
char *alloc_http_authenticator(const char *authenticator);
|
||||
|
||||
void assert_connection_ok(connection_t *conn, time_t now);
|
||||
int connection_or_nonopen_was_started_here(connection_t *conn);
|
||||
|
Loading…
Reference in New Issue
Block a user