mirror of https://github.com/BOINC/boinc.git
parent
5352813307
commit
e73260c863
|
@ -10988,3 +10988,31 @@ David Mar 26 2004
|
|||
forum.inc
|
||||
user/
|
||||
host_edit_action.php
|
||||
|
||||
Eric H Mar 26 2004
|
||||
- added support for SOCKS4 and SOCKS5 proxy servers
|
||||
- added a new PROXY layer between HTTP_OP and NET_XFER. This layer takes care
|
||||
of the state transitions involved in negotiating with a SOCKS server. Since
|
||||
the HTTP_OP is dependant on the completion of the proxy operation, I made
|
||||
the layers synchronous (PROXY:poll() is called in HTTP_OP::poll() rather
|
||||
than CLIENT_STATE::do_something()). Support for editing SOCKS proxy server
|
||||
information still needs to be completed in the Windows GUI.
|
||||
- Possible future projects: add IPv6 support, GSSAPI support, test on SOCKS4 server
|
||||
|
||||
client/
|
||||
Makefile.am
|
||||
client_messages.C
|
||||
client_state.C,h
|
||||
cs_cmdline.C
|
||||
cs_statefile.C
|
||||
gui_rpc_server.C
|
||||
http.C,h
|
||||
log_flags.C,h
|
||||
message.h
|
||||
net_xfer.C,h
|
||||
pers_file_xfer.C
|
||||
proxy.C,h (added)
|
||||
scheduler_op.C
|
||||
lib/
|
||||
error_numbers.h
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ boinc_client_SOURCES = \
|
|||
net_xfer.C \
|
||||
pers_file_xfer.C \
|
||||
prefs.C \
|
||||
proxy.C \
|
||||
scheduler_op.C \
|
||||
ss_logic.C \
|
||||
time_stats.C \
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -34,6 +34,7 @@ const char* ClientMessages::v_format_kind(int kind) const
|
|||
case DEBUG_FILE_XFER: return "DEBUG_FILE_XFER ";
|
||||
case DEBUG_SCHED_OP: return "DEBUG_SCHED_OP ";
|
||||
case DEBUG_HTTP: return "DEBUG_HTTP ";
|
||||
case DEBUG_PROXY: return "DEBUG_PROXY ";
|
||||
case DEBUG_TIME: return "DEBUG_TIME ";
|
||||
case DEBUG_NET_XFER: return "DEBUG_NET_XFER ";
|
||||
case DEBUG_MEASUREMENT: return "DEBUG_MEASUREMENT";
|
||||
|
@ -50,6 +51,7 @@ bool ClientMessages::v_message_wanted(int kind) const
|
|||
case DEBUG_FILE_XFER: return log_flags.file_xfer_debug;
|
||||
case DEBUG_SCHED_OP: return log_flags.sched_op_debug;
|
||||
case DEBUG_HTTP: return log_flags.http_debug;
|
||||
case DEBUG_PROXY: return log_flags.proxy_debug;
|
||||
case DEBUG_TIME: return log_flags.time_debug;
|
||||
case DEBUG_NET_XFER: return log_flags.net_xfer_debug;
|
||||
case DEBUG_MEASUREMENT: return log_flags.measurement_debug;
|
||||
|
|
|
@ -81,14 +81,9 @@ CLIENT_STATE::CLIENT_STATE() {
|
|||
app_started = 0;
|
||||
exit_before_upload = false;
|
||||
user_idle = true;
|
||||
use_http_proxy = false;
|
||||
use_socks_proxy = false;
|
||||
pi.clear();
|
||||
show_projects = false;
|
||||
strcpy(detach_project_url, "");
|
||||
strcpy(proxy_server_name, "");
|
||||
proxy_server_port = 80;
|
||||
strcpy(socks_user_name, "");
|
||||
strcpy(socks_user_passwd, "");
|
||||
strcpy(host_venue, "");
|
||||
user_run_request = USER_RUN_REQUEST_AUTO;
|
||||
started_by_screensaver = false;
|
||||
|
|
|
@ -79,6 +79,7 @@ public:
|
|||
GUI_RPC_CONN_SET gui_rpcs;
|
||||
LANGUAGE language;
|
||||
TIME_STATS time_stats;
|
||||
PROXY_INFO pi;
|
||||
|
||||
int core_client_major_version;
|
||||
int core_client_minor_version;
|
||||
|
@ -90,18 +91,12 @@ public:
|
|||
bool return_results_immediately;
|
||||
bool show_projects;
|
||||
bool requested_exit;
|
||||
bool use_http_proxy;
|
||||
bool use_socks_proxy;
|
||||
int proxy_server_port;
|
||||
char detach_project_url[256];
|
||||
// stores URL for -detach_project option
|
||||
char reset_project_url[256];
|
||||
// stores URL for -reset_project option
|
||||
char update_prefs_url[256];
|
||||
// stores URL for -update_prefs option
|
||||
char proxy_server_name[256];
|
||||
char socks_user_name[256];
|
||||
char socks_user_passwd[256];
|
||||
char host_venue[256]; // venue, as reported by project that sent us
|
||||
// most recent global prefs
|
||||
bool exit_before_upload;
|
||||
|
|
|
@ -163,24 +163,37 @@ void CLIENT_STATE::parse_env_vars() {
|
|||
|
||||
if ((p = getenv("HTTP_PROXY"))) {
|
||||
if (strlen(p) > 0) {
|
||||
use_http_proxy = true;
|
||||
parse_url(p, proxy_server_name, proxy_server_port, temp);
|
||||
pi.use_http_proxy = true;
|
||||
parse_url(p, pi.http_server_name, pi.http_server_port, temp);
|
||||
}
|
||||
}
|
||||
|
||||
if ((p = getenv("SOCKS_SERVER"))) {
|
||||
pi.socks_version =
|
||||
getenv("SOCKS5_SERVER")?SOCKS_VERSION_5:
|
||||
getenv("SOCKS4_SERVER")?SOCKS_VERSION_4:
|
||||
getenv("SOCKS_SERVER")?SOCKS_VERSION_5:
|
||||
SOCKS_VERSION_5;
|
||||
|
||||
if ((p = getenv("SOCKS4_SERVER"))) {
|
||||
if (strlen(p) > 0) {
|
||||
use_socks_proxy = true;
|
||||
parse_url(p, proxy_server_name, proxy_server_port, temp);
|
||||
pi.use_socks_proxy = true;
|
||||
parse_url(p, pi.socks_server_name, pi.socks_server_port, temp);
|
||||
}
|
||||
}
|
||||
|
||||
if ((p = getenv("SOCKS_USER"))) {
|
||||
safe_strcpy(socks_user_name, p);
|
||||
if ((p = getenv("SOCKS_SERVER")) || (p = getenv("SOCKS5_SERVER"))) {
|
||||
if (strlen(p) > 0) {
|
||||
pi.use_socks_proxy = true;
|
||||
parse_url(p, pi.socks_server_name, pi.socks_server_port, temp);
|
||||
}
|
||||
}
|
||||
|
||||
if ((p = getenv("SOCKS_PASSWD"))) {
|
||||
safe_strcpy(socks_user_passwd, p);
|
||||
if ((p = getenv("SOCKS5_USER")) || (p = getenv("SOCKS_USER"))) {
|
||||
safe_strcpy(pi.socks5_user_name, p);
|
||||
}
|
||||
|
||||
if ((p = getenv("SOCKS5_PASSWD"))) {
|
||||
safe_strcpy(pi.socks5_user_passwd, p);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -148,14 +148,9 @@ int CLIENT_STATE::parse_state_file() {
|
|||
// after core client update
|
||||
} else if (parse_int(buf, "<core_client_major_version>", old_major_version)) {
|
||||
} else if (parse_int(buf, "<core_client_minor_version>", old_minor_version)) {
|
||||
} else if (match_tag(buf, "<use_http_proxy/>")) {
|
||||
use_http_proxy = true;
|
||||
} else if (match_tag(buf, "<use_socks_proxy/>")) {
|
||||
use_socks_proxy = true;
|
||||
} else if (parse_str(buf, "<proxy_server_name>", proxy_server_name, sizeof(proxy_server_name))) {
|
||||
} else if (parse_int(buf, "<proxy_server_port>", proxy_server_port)) {
|
||||
} else if (parse_str(buf, "<socks_user_name>", socks_user_name, sizeof(socks_user_name))) {
|
||||
} else if (parse_str(buf, "<socks_user_passwd>", socks_user_passwd, sizeof(socks_user_passwd))) {
|
||||
} else if (match_tag(buf, "<proxy_info>")) {
|
||||
retval = pi.parse(f);
|
||||
if (retval) goto done;
|
||||
// } else if (parse_int(buf, "<user_run_request/>")) {
|
||||
} else if (parse_str(buf, "<host_venue>", host_venue, sizeof(host_venue))) {
|
||||
} else {
|
||||
|
@ -261,20 +256,7 @@ int CLIENT_STATE::write_state(FILE* f) {
|
|||
|
||||
// save proxy info
|
||||
//
|
||||
fprintf(f,
|
||||
"%s"
|
||||
"%s"
|
||||
"<proxy_server_name>%s</proxy_server_name>\n"
|
||||
"<proxy_server_port>%d</proxy_server_port>\n"
|
||||
"<socks_user_name>%s</socks_user_name>\n"
|
||||
"<socks_user_passwd>%s</socks_user_passwd>\n",
|
||||
use_http_proxy?"<use_http_proxy/>\n":"",
|
||||
use_socks_proxy?"<use_socks_proxy/>\n":"",
|
||||
proxy_server_name,
|
||||
proxy_server_port,
|
||||
socks_user_name,
|
||||
socks_user_passwd
|
||||
);
|
||||
pi.write(f);
|
||||
#if 0
|
||||
fprintf(f, "<user_run_request>%d</user_run_request>\n", user_run_request);
|
||||
#endif
|
||||
|
|
|
@ -150,18 +150,28 @@ static void handle_run_benchmarks(char* buf, FILE* fout) {
|
|||
}
|
||||
|
||||
static void handle_set_proxy_settings(char* buf, FILE* fout) {
|
||||
string proxy_server_name;
|
||||
int proxy_server_port;
|
||||
if (!parse_str(buf, "<proxy_server_name>", proxy_server_name)) {
|
||||
fprintf(fout, "<error>Proxy server name missing</error>\n");
|
||||
string socks_proxy_server_name,http_proxy_server_name;
|
||||
int socks_proxy_server_port,http_proxy_server_port;
|
||||
if (!parse_str(buf, "<socks_proxy_server_name>", socks_proxy_server_name)) {
|
||||
fprintf(fout, "<error>SOCKS proxy server name missing</error>\n");
|
||||
return;
|
||||
}
|
||||
if (!parse_int(buf, "<proxy_server_port>", proxy_server_port)) {
|
||||
fprintf(fout, "<error>Proxy server port missing</error>\n");
|
||||
if (!parse_int(buf, "<socks_proxy_server_port>", socks_proxy_server_port)) {
|
||||
fprintf(fout, "<error>SOCKS proxy server port missing</error>\n");
|
||||
return;
|
||||
}
|
||||
safe_strcpy(gstate.proxy_server_name, proxy_server_name.c_str());
|
||||
gstate.proxy_server_port = proxy_server_port;
|
||||
if (!parse_str(buf, "<http_proxy_server_name>", http_proxy_server_name)) {
|
||||
fprintf(fout, "<error>HTTP proxy server name missing</error>\n");
|
||||
return;
|
||||
}
|
||||
if (!parse_int(buf, "<http_proxy_server_port>", http_proxy_server_port)) {
|
||||
fprintf(fout, "<error>HTTP proxy server port missing</error>\n");
|
||||
return;
|
||||
}
|
||||
safe_strcpy(gstate.pi.socks_server_name, socks_proxy_server_name.c_str());
|
||||
gstate.pi.socks_server_port = socks_proxy_server_port;
|
||||
safe_strcpy(gstate.pi.http_server_name, http_proxy_server_name.c_str());
|
||||
gstate.pi.http_server_port = http_proxy_server_port;
|
||||
fprintf(fout, "<success/>\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -247,9 +247,6 @@ HTTP_OP::HTTP_OP() {
|
|||
http_op_state = HTTP_STATE_IDLE;
|
||||
http_op_type = HTTP_OP_NONE;
|
||||
http_op_retval = 0;
|
||||
use_http_proxy = false;
|
||||
proxy_server_port = 0;
|
||||
strcpy(proxy_server_name, "");
|
||||
}
|
||||
|
||||
HTTP_OP::~HTTP_OP() {
|
||||
|
@ -260,10 +257,11 @@ HTTP_OP::~HTTP_OP() {
|
|||
int HTTP_OP::init_head(const char* url) {
|
||||
char proxy_buf[256];
|
||||
parse_url(url, url_hostname, port, filename);
|
||||
NET_XFER::init(use_http_proxy?proxy_server_name:url_hostname, use_http_proxy?proxy_server_port:port, HTTP_BLOCKSIZE);
|
||||
PROXY::init(url_hostname, port);
|
||||
NET_XFER::init(get_proxy_server_name(url_hostname),get_proxy_port(port), HTTP_BLOCKSIZE);
|
||||
http_op_type = HTTP_OP_HEAD;
|
||||
http_op_state = HTTP_STATE_CONNECTING;
|
||||
if (use_http_proxy) {
|
||||
if (pi.use_http_proxy) {
|
||||
sprintf(proxy_buf, "http://%s:%d/%s", url_hostname, port, filename);
|
||||
} else {
|
||||
sprintf(proxy_buf, "/%s", filename);
|
||||
|
@ -282,14 +280,15 @@ int HTTP_OP::init_get(const char* url, char* out, bool del_old_file, double off)
|
|||
}
|
||||
file_offset = off;
|
||||
parse_url(url, url_hostname, port, filename);
|
||||
NET_XFER::init(use_http_proxy?proxy_server_name:url_hostname, use_http_proxy?proxy_server_port:port, HTTP_BLOCKSIZE);
|
||||
PROXY::init(url_hostname, port);
|
||||
NET_XFER::init(get_proxy_server_name(url_hostname),get_proxy_port(port), HTTP_BLOCKSIZE);
|
||||
safe_strcpy(outfile, out);
|
||||
if (off != 0){
|
||||
bytes_xferred = off;
|
||||
}
|
||||
http_op_type = HTTP_OP_GET;
|
||||
http_op_state = HTTP_STATE_CONNECTING;
|
||||
if (use_http_proxy) {
|
||||
if (pi.use_http_proxy) {
|
||||
sprintf(proxy_buf, "http://%s:%d/%s", url_hostname, port, filename);
|
||||
} else {
|
||||
sprintf(proxy_buf, "/%s", filename);
|
||||
|
@ -308,7 +307,8 @@ int HTTP_OP::init_post(const char* url, char* in, char* out) {
|
|||
ScopeMessages scope_messages(log_messages, ClientMessages::DEBUG_HTTP);
|
||||
|
||||
parse_url(url, url_hostname, port, filename);
|
||||
NET_XFER::init(use_http_proxy?proxy_server_name:url_hostname, use_http_proxy?proxy_server_port:port, HTTP_BLOCKSIZE);
|
||||
PROXY::init(url_hostname, port);
|
||||
NET_XFER::init(get_proxy_server_name(url_hostname),get_proxy_port(port), HTTP_BLOCKSIZE);
|
||||
safe_strcpy(infile, in);
|
||||
safe_strcpy(outfile, out);
|
||||
retval = file_size(infile, size);
|
||||
|
@ -316,7 +316,7 @@ int HTTP_OP::init_post(const char* url, char* in, char* out) {
|
|||
content_length = (int)size;
|
||||
http_op_type = HTTP_OP_POST;
|
||||
http_op_state = HTTP_STATE_CONNECTING;
|
||||
if (use_http_proxy) {
|
||||
if (pi.use_http_proxy) {
|
||||
sprintf(proxy_buf, "http://%s:%d/%s", url_hostname, port, filename);
|
||||
} else {
|
||||
sprintf(proxy_buf, "/%s", filename);
|
||||
|
@ -338,7 +338,8 @@ int HTTP_OP::init_post2(
|
|||
char proxy_buf[256];
|
||||
|
||||
parse_url(url, url_hostname, port, filename);
|
||||
NET_XFER::init(use_http_proxy?proxy_server_name:url_hostname, use_http_proxy?proxy_server_port:port, HTTP_BLOCKSIZE);
|
||||
PROXY::init(url_hostname, port);
|
||||
NET_XFER::init(get_proxy_server_name(url_hostname),get_proxy_port(port), HTTP_BLOCKSIZE);
|
||||
req1 = r1;
|
||||
if (in) {
|
||||
safe_strcpy(infile, in);
|
||||
|
@ -353,7 +354,7 @@ int HTTP_OP::init_post2(
|
|||
content_length += strlen(req1);
|
||||
http_op_type = HTTP_OP_POST2;
|
||||
http_op_state = HTTP_STATE_CONNECTING;
|
||||
if (use_http_proxy) {
|
||||
if (pi.use_http_proxy) {
|
||||
sprintf(proxy_buf, "http://%s:%d/%s", url_hostname, port, filename);
|
||||
} else {
|
||||
sprintf(proxy_buf, "/%s", filename);
|
||||
|
@ -403,11 +404,50 @@ bool HTTP_OP_SET::poll() {
|
|||
break;
|
||||
}
|
||||
if (htp->is_connected) {
|
||||
htp->http_op_state = HTTP_STATE_REQUEST_HEADER;
|
||||
htp->http_op_state = HTTP_STATE_SOCKS_CONNECT;
|
||||
htp->want_upload = true;
|
||||
action = true;
|
||||
}
|
||||
break;
|
||||
case HTTP_STATE_SOCKS_CONNECT:
|
||||
// Since the HTTP layer is synchronous with the proxy layer, we
|
||||
// call proxy_poll() here instead of in do_something()
|
||||
htp->proxy_poll();
|
||||
|
||||
// After negotiation with the proxy is complete, advance to
|
||||
// the next step of the HTTP layer
|
||||
if (htp->proxy_negotiated()) {
|
||||
if (htp->proxy_retval) {
|
||||
htp->http_op_state = HTTP_STATE_DONE;
|
||||
htp->http_op_retval = htp->proxy_retval;
|
||||
switch (htp->proxy_retval) {
|
||||
case ERR_SOCKS_UNKNOWN_FAILURE:
|
||||
msg_printf(NULL, MSG_ERROR, "An unknown SOCKS server error occurred\n");
|
||||
break;
|
||||
case ERR_SOCKS_REQUEST_FAILED:
|
||||
msg_printf(NULL, MSG_ERROR, "The SOCKS server denied access for this computer\n");
|
||||
break;
|
||||
case ERR_SOCKS_BAD_USER_PASS:
|
||||
msg_printf(NULL, MSG_ERROR, "Incorrect SOCKS user name and/or password\n");
|
||||
break;
|
||||
case ERR_SOCKS_UNKNOWN_SERVER_VERSION:
|
||||
msg_printf(NULL, MSG_ERROR, "The SOCKS server is using an unknown version\n");
|
||||
break;
|
||||
case ERR_SOCKS_UNSUPPORTED:
|
||||
msg_printf(NULL, MSG_ERROR, "The SOCKS server is using unsupported features unknown to BOINC\n");
|
||||
break;
|
||||
case ERR_SOCKS_CANT_REACH_HOST:
|
||||
msg_printf(NULL, MSG_ERROR, "The SOCKS server is unable to contact the host\n");
|
||||
break;
|
||||
case ERR_SOCKS_CONN_REFUSED:
|
||||
msg_printf(NULL, MSG_ERROR, "The connection from the SOCKS server to the host was refused\n");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
htp->http_op_state = HTTP_STATE_REQUEST_HEADER;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HTTP_STATE_REQUEST_HEADER:
|
||||
if (htp->io_ready) {
|
||||
action = true;
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#ifndef _HTTP_
|
||||
#define _HTTP_
|
||||
|
||||
#include "net_xfer.h"
|
||||
#include "proxy.h"
|
||||
|
||||
// official HTTP status codes
|
||||
#define HTTP_STATUS_OK 200
|
||||
|
@ -54,7 +54,7 @@ struct HTTP_REPLY_HEADER {
|
|||
// of a string and a file w/offset,
|
||||
// and the reply goes into a memory buffer
|
||||
|
||||
class HTTP_OP : public NET_XFER {
|
||||
class HTTP_OP : public PROXY {
|
||||
public:
|
||||
HTTP_OP();
|
||||
~HTTP_OP();
|
||||
|
@ -75,9 +75,6 @@ public:
|
|||
int http_op_type;
|
||||
int http_op_retval;
|
||||
// zero if success, or a BOINC error code, or an HTTP status code
|
||||
bool use_http_proxy;
|
||||
int proxy_server_port;
|
||||
char proxy_server_name[256];
|
||||
|
||||
int init_head(const char* url);
|
||||
int init_get(const char* url, char* outfile, bool del_old_file, double offset=0);
|
||||
|
@ -102,13 +99,14 @@ public:
|
|||
|
||||
#define HTTP_STATE_IDLE 0
|
||||
#define HTTP_STATE_CONNECTING 1
|
||||
#define HTTP_STATE_REQUEST_HEADER 2
|
||||
#define HTTP_STATE_REQUEST_BODY1 3
|
||||
#define HTTP_STATE_SOCKS_CONNECT 2
|
||||
#define HTTP_STATE_REQUEST_HEADER 3
|
||||
#define HTTP_STATE_REQUEST_BODY1 4
|
||||
// sending the string part of a POST2 operation
|
||||
#define HTTP_STATE_REQUEST_BODY 4
|
||||
#define HTTP_STATE_REPLY_HEADER 5
|
||||
#define HTTP_STATE_REPLY_BODY 6
|
||||
#define HTTP_STATE_DONE 7
|
||||
#define HTTP_STATE_REQUEST_BODY 5
|
||||
#define HTTP_STATE_REPLY_HEADER 6
|
||||
#define HTTP_STATE_REPLY_BODY 7
|
||||
#define HTTP_STATE_DONE 8
|
||||
|
||||
extern void parse_url(const char* url, char* host, int &port, char* file);
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ LOG_FLAGS::LOG_FLAGS() {
|
|||
file_xfer_debug = false;
|
||||
sched_op_debug = false;
|
||||
http_debug = false;
|
||||
proxy_debug = false;
|
||||
time_debug = false;
|
||||
net_xfer_debug = false;
|
||||
measurement_debug = false;
|
||||
|
@ -92,6 +93,9 @@ int LOG_FLAGS::parse(FILE* in) {
|
|||
} else if (match_tag(buf, "<http_debug/>")) {
|
||||
http_debug = true;
|
||||
continue;
|
||||
} else if (match_tag(buf, "<proxy_debug/>")) {
|
||||
proxy_debug = true;
|
||||
continue;
|
||||
} else if (match_tag(buf, "<time_debug/>")) {
|
||||
time_debug = true;
|
||||
continue;
|
||||
|
|
|
@ -45,6 +45,7 @@ public:
|
|||
bool file_xfer_debug;
|
||||
bool sched_op_debug;
|
||||
bool http_debug;
|
||||
bool proxy_debug;
|
||||
bool time_debug; // print message on sleep
|
||||
bool net_xfer_debug;
|
||||
bool measurement_debug; // host measurement notices
|
||||
|
|
|
@ -46,6 +46,7 @@ public:
|
|||
DEBUG_FILE_XFER,
|
||||
DEBUG_SCHED_OP,
|
||||
DEBUG_HTTP,
|
||||
DEBUG_PROXY,
|
||||
DEBUG_TIME, // print message on sleep
|
||||
DEBUG_NET_XFER,
|
||||
DEBUG_MEASUREMENT, // host measurement notices
|
||||
|
|
|
@ -99,6 +99,10 @@ int get_socket_error(int fd) {
|
|||
return n;
|
||||
}
|
||||
|
||||
int NET_XFER::get_ip_addr(int &ip_addr) {
|
||||
return get_ip_addr(hostname,ip_addr);
|
||||
}
|
||||
|
||||
int NET_XFER::get_ip_addr(char *hostname, int &ip_addr) {
|
||||
hostent* hep;
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ public:
|
|||
int file_read_buf_offset, file_read_buf_len;
|
||||
|
||||
void init(char* host, int port, int blocksize);
|
||||
int get_ip_addr(int &ip_addr);
|
||||
int get_ip_addr(char *hostname, int &ip_addr);
|
||||
int open_server();
|
||||
void close_socket();
|
||||
|
|
|
@ -117,11 +117,7 @@ int PERS_FILE_XFER::start_xfer() {
|
|||
// download or upload for the persistent file transfer
|
||||
//
|
||||
file_xfer = new FILE_XFER;
|
||||
if (gstate.use_http_proxy) {
|
||||
file_xfer->use_http_proxy = true;
|
||||
safe_strcpy(file_xfer->proxy_server_name, gstate.proxy_server_name);
|
||||
file_xfer->proxy_server_port = gstate.proxy_server_port;
|
||||
}
|
||||
file_xfer->set_proxy(&gstate.pi);
|
||||
if (is_upload) {
|
||||
if (gstate.exit_before_upload) {
|
||||
exit(0);
|
||||
|
|
|
@ -0,0 +1,483 @@
|
|||
// The contents of this file are subject to the BOINC Public License
|
||||
// Version 1.0 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://boinc.berkeley.edu/license_1.0.txt
|
||||
//
|
||||
// Software distributed under the License is distributed on an "AS IS"
|
||||
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing rights and limitations
|
||||
// under the License.
|
||||
//
|
||||
// The Original Code is the Berkeley Open Infrastructure for Network Computing.
|
||||
//
|
||||
// The Initial Developer of the Original Code is the SETI@home project.
|
||||
// Portions created by the SETI@home project are Copyright (C) 2002
|
||||
// University of California at Berkeley. All Rights Reserved.
|
||||
//
|
||||
// Contributor(s):
|
||||
//
|
||||
|
||||
#include "cpp.h"
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "winsock.h"
|
||||
#endif
|
||||
#if HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#if HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#if HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "error_numbers.h"
|
||||
#include "filesys.h"
|
||||
#include "util.h"
|
||||
#include "message.h"
|
||||
#include "parse.h"
|
||||
|
||||
#include "proxy.h"
|
||||
|
||||
// Read the contents of the socket into buf
|
||||
//
|
||||
static int proxy_read_reply(int socket, char* buf, int len) {
|
||||
int i, n;
|
||||
for (i=0; i<len-1; i++) {
|
||||
n = recv(socket, buf+i, 1, 0);
|
||||
if (n != 1) break;
|
||||
}
|
||||
buf[i] = 0;
|
||||
return i;
|
||||
}
|
||||
|
||||
// Make sure we send the full contents of each message. Messages
|
||||
// are relatively short, so it's safe
|
||||
//
|
||||
/*static int proxy_atomic_send(int socket, char *buf, int size) {
|
||||
int ret, len;
|
||||
|
||||
ret = 0;
|
||||
while (size > 0) {
|
||||
len = send(socket, buf+ret, size, 0);
|
||||
if ( len == -1 && errno != ) fatal("atomic_out() failed to send(), %d\n", socks_errno());
|
||||
ret += len;
|
||||
size -= len;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
*/
|
||||
|
||||
void print_buf( char *buf, int n ) {
|
||||
for (int i=0;i<n;i++) printf( "%d ",buf[i] );
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
int PROXY_INFO::parse(FILE* in) {
|
||||
char buf[256];
|
||||
|
||||
memset(this, 0, sizeof(PROXY_INFO));
|
||||
while (fgets(buf, 256, in)) {
|
||||
if (match_tag(buf, "</proxy_info>")) return 0;
|
||||
else if (match_tag(buf, "<use_http_proxy/>")) use_http_proxy = true;
|
||||
else if (match_tag(buf, "<use_socks_proxy/>")) use_socks_proxy = true;
|
||||
else if (parse_int(buf, "<socks_version>", socks_version)) continue;
|
||||
else if (parse_str(buf, "<socks_server_name>", socks_server_name, sizeof(socks_server_name))) continue;
|
||||
else if (parse_int(buf, "<socks_server_port>", socks_server_port)) continue;
|
||||
else if (parse_str(buf, "<http_server_name>", http_server_name, sizeof(http_server_name))) continue;
|
||||
else if (parse_int(buf, "<http_server_port>", http_server_port)) continue;
|
||||
else if (parse_str(buf, "<socks5_user_name>", socks5_user_name, sizeof(socks5_user_name))) continue;
|
||||
else if (parse_str(buf, "<socks5_user_passwd>", socks5_user_passwd, sizeof(socks5_user_passwd))) continue;
|
||||
else msg_printf(NULL, MSG_ERROR, "PROXY_INFO::parse(): unrecognized: %s\n", buf);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PROXY_INFO::write(FILE* out) {
|
||||
fprintf(out,
|
||||
"<proxy_info>\n"
|
||||
"%s"
|
||||
"%s"
|
||||
" <socks_version>%d</socks_version>\n"
|
||||
" <socks_server_name>%s</socks_server_name>\n"
|
||||
" <socks_server_port>%d</socks_server_port>\n"
|
||||
" <http_server_name>%s</http_server_name>\n"
|
||||
" <http_server_port>%d</http_server_port>\n"
|
||||
" <socks5_user_name>%s</socks5_user_name>\n"
|
||||
" <socks5_user_passwd>%s</socks5_user_passwd>\n"
|
||||
"</proxy_info>\n",
|
||||
use_http_proxy?" <use_http_proxy/>\n":"",
|
||||
use_socks_proxy?" <use_socks_proxy/>\n":"",
|
||||
socks_version,
|
||||
socks_server_name,
|
||||
socks_server_port,
|
||||
http_server_name,
|
||||
http_server_port,
|
||||
socks5_user_name,
|
||||
socks5_user_passwd
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PROXY_INFO::clear() {
|
||||
use_http_proxy = false;
|
||||
use_socks_proxy = false;
|
||||
strcpy(socks_server_name, "");
|
||||
strcpy(http_server_name, "");
|
||||
socks_server_port = 80;
|
||||
http_server_port = 80;
|
||||
strcpy(socks5_user_name, "");
|
||||
strcpy(socks5_user_passwd, "");
|
||||
socks_version = 0;
|
||||
}
|
||||
|
||||
PROXY::PROXY() {
|
||||
strcpy(proxy_data,"");
|
||||
proxy_state = PROXY_STATE_CONNECTING;
|
||||
proxy_retval = 0;
|
||||
}
|
||||
|
||||
void PROXY::init(char *dst_host, int port) {
|
||||
strcpy(dest_serv_name, dst_host);
|
||||
dest_serv_port = port;
|
||||
proxy_state = PROXY_STATE_CONNECTING;
|
||||
}
|
||||
|
||||
PROXY::~PROXY() {
|
||||
}
|
||||
|
||||
int PROXY::set_proxy(PROXY_INFO *new_pi) {
|
||||
pi.use_http_proxy = new_pi->use_http_proxy;
|
||||
strcpy(pi.http_server_name, new_pi->http_server_name);
|
||||
pi.http_server_port = new_pi->http_server_port;
|
||||
|
||||
pi.use_socks_proxy = new_pi->use_socks_proxy;
|
||||
strcpy(pi.socks5_user_name, new_pi->socks5_user_name);
|
||||
strcpy(pi.socks5_user_passwd, new_pi->socks5_user_passwd);
|
||||
strcpy(pi.socks_server_name, new_pi->socks_server_name);
|
||||
pi.socks_server_port = new_pi->socks_server_port;
|
||||
pi.socks_version = new_pi->socks_version;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *PROXY::get_proxy_server_name(char *regular_server) {
|
||||
if (pi.use_socks_proxy) return pi.socks_server_name;
|
||||
else if (pi.use_http_proxy) return pi.http_server_name;
|
||||
else return regular_server;
|
||||
}
|
||||
|
||||
int PROXY::get_proxy_port(int regular_port) {
|
||||
if (pi.use_socks_proxy) return pi.socks_server_port;
|
||||
else if (pi.use_http_proxy) return pi.http_server_port;
|
||||
else return regular_port;
|
||||
}
|
||||
|
||||
int PROXY::proxy_failed(int failure_code) {
|
||||
proxy_state = PROXY_STATE_DONE;
|
||||
proxy_retval = failure_code;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Initialize proxy_data with a socks4 or socks5 connection request
|
||||
// see http://www.socks.nec.com/rfc/rfc1928.txt
|
||||
// see http://www.socks.nec.com/protocol/socks4.protocol
|
||||
// TODO: add support for GSSAPI authentication, IPv6 addresses, name -> IP resolution
|
||||
// One current problem is that the client may not fully read/write messages
|
||||
// to the server if buffers are full. proxy_atomic_send is an attempt to
|
||||
// compensate, it should be fully implemented and tested if this becomes a
|
||||
// significant issue. I'm not too worried though, since the messages are
|
||||
// always very small, and unlikely to cause space concerns (Eric Heien 3/26/04)
|
||||
|
||||
// Check available methods on the socks server
|
||||
//
|
||||
int PROXY::socks_prepare_method_req(char *buf) {
|
||||
int nbytes = 0;
|
||||
char *marker = buf;
|
||||
|
||||
if (pi.socks_version != SOCKS_VERSION_5) return ERR_SOCKS_UNKNOWN_FAILURE;
|
||||
|
||||
nbytes = 3;
|
||||
*marker++ = SOCKS_VERSION_5;
|
||||
if (*pi.socks5_user_name && *pi.socks5_user_passwd) {
|
||||
*marker++ = 2; // 2 possible methods
|
||||
*marker++ = SOCKS_AUTH_USER_PASS; // user/pass
|
||||
nbytes++;
|
||||
} else {
|
||||
*marker++ = 1; // 1 possible method:
|
||||
}
|
||||
*marker++ = SOCKS_AUTH_NONE_NEEDED; // no authentication
|
||||
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
int PROXY::socks_prepare_user_pass(char *buf) {
|
||||
int nbytes;
|
||||
char *marker = buf;
|
||||
|
||||
if (pi.socks_version != SOCKS_VERSION_5) return ERR_SOCKS_UNKNOWN_FAILURE;
|
||||
|
||||
// Send user and password
|
||||
*marker++ = SOCKS5_USER_SUBNEG_VERSION_1;
|
||||
*marker++ = strlen(pi.socks5_user_name);
|
||||
strncpy(marker, pi.socks5_user_name, strlen(pi.socks5_user_name));
|
||||
marker += strlen(pi.socks5_user_name);
|
||||
*marker++ = strlen(pi.socks5_user_passwd);
|
||||
strncpy(marker, pi.socks5_user_passwd, strlen(pi.socks5_user_passwd));
|
||||
nbytes = 1+1+strlen(pi.socks5_user_name)+1+strlen(pi.socks5_user_passwd);
|
||||
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
int PROXY::socks_prepare_connect_req(char *buf, int ns_port, int ip_addr, char *domain_name) {
|
||||
int nbytes;
|
||||
char *marker = buf, *p;
|
||||
|
||||
if (pi.socks_version == SOCKS_VERSION_4) {
|
||||
*marker++ = SOCKS_VERSION_4;
|
||||
*marker++ = 1; // Request connection
|
||||
p = (char*)&ns_port; // to this port
|
||||
for (int i=0;i<2;i++) *marker++ = *p++;
|
||||
p = (char*)&ip_addr; // at this IP address
|
||||
for (int i=0;i<4;i++) *marker++ = *p++;
|
||||
strncpy(marker, pi.socks5_user_name, strlen(pi.socks5_user_name));
|
||||
nbytes = 1+1+2+4+strlen(pi.socks5_user_name);
|
||||
} else if (pi.socks_version == SOCKS_VERSION_5) {
|
||||
if (strlen(domain_name) > 255) return ERR_SOCKS_UNKNOWN_FAILURE;
|
||||
|
||||
*marker++ = SOCKS_VERSION_5;
|
||||
*marker++ = 1; // request connection
|
||||
*marker++ = 0; // reserved
|
||||
nbytes = 3;
|
||||
|
||||
if (strlen(domain_name) > 0) {
|
||||
nbytes += 2+strlen(domain_name);
|
||||
*marker++ = SOCKS5_ADDR_TYPE_DOMAIN_NAME;
|
||||
*marker++ = strlen(domain_name);
|
||||
p = domain_name;
|
||||
for (unsigned int i=0;i<strlen(domain_name);i++) *marker++ = *p++;
|
||||
} else {
|
||||
nbytes += 1+4;
|
||||
*marker++ = SOCKS5_ADDR_TYPE_IPV4;
|
||||
p = (char*)&ip_addr;
|
||||
for (int i=0;i<4;i++) *marker++ = *p++;
|
||||
}
|
||||
p = (char*)&ns_port;
|
||||
for (int i=0;i<2;i++) *marker++ = *p++;
|
||||
nbytes += 2;
|
||||
} else {
|
||||
return ERR_SOCKS_UNKNOWN_FAILURE;
|
||||
}
|
||||
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
int PROXY::socks_parse_method_ack(char *buf) {
|
||||
// This parsing only makes sense in SOCKS version 5
|
||||
if (pi.socks_version != SOCKS_VERSION_5) return ERR_SOCKS_UNKNOWN_FAILURE;
|
||||
|
||||
// The buffer should start with the version 5 identifier
|
||||
if (buf[0] != SOCKS_VERSION_5) return ERR_SOCKS_UNKNOWN_SERVER_VERSION;
|
||||
|
||||
// Depending on the method, move to a different state or return an error
|
||||
switch (buf[1]) {
|
||||
case SOCKS_AUTH_NONE_NEEDED:
|
||||
proxy_state = PROXY_STATE_SOCKS_SEND_CONNECT_REQ;
|
||||
break;
|
||||
case SOCKS_AUTH_USER_PASS:
|
||||
proxy_state = PROXY_STATE_SOCKS_SEND_USER_PASS;
|
||||
break;
|
||||
case SOCKS_AUTH_GSSAPI:
|
||||
case SOCKS_AUTH_NONE_ACCEPTABLE:
|
||||
default:
|
||||
return ERR_SOCKS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PROXY::socks_parse_user_pass_ack(char *buf) {
|
||||
// This parsing only makes sense in SOCKS version 5
|
||||
if (pi.socks_version != SOCKS_VERSION_5) return ERR_SOCKS_UNKNOWN_FAILURE;
|
||||
|
||||
// The buffer should start with the subnegotiation version identifier
|
||||
if (buf[0] != SOCKS5_USER_SUBNEG_VERSION_1) return ERR_SOCKS_UNKNOWN_SERVER_VERSION;
|
||||
|
||||
// 0 indicates success, otherwise we assume a bad user/password
|
||||
if (buf[1] != 0) return ERR_SOCKS_BAD_USER_PASS;
|
||||
|
||||
proxy_state = PROXY_STATE_SOCKS_SEND_CONNECT_REQ;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PROXY::socks_parse_connect_ack(char *buf) {
|
||||
switch (pi.socks_version) {
|
||||
case SOCKS_VERSION_4:
|
||||
if (buf[0] != 0) return ERR_SOCKS_UNKNOWN_FAILURE;
|
||||
|
||||
switch (buf[1]) {
|
||||
case SOCKS4_REQ_GRANTED:
|
||||
proxy_state = PROXY_STATE_DONE;
|
||||
proxy_retval = 0;
|
||||
break;
|
||||
case SOCKS4_REQ_REJECTED:
|
||||
return ERR_SOCKS_REQUEST_FAILED;
|
||||
case SOCKS4_REQ_NO_IDENTD:
|
||||
return ERR_SOCKS_REQUEST_FAILED;
|
||||
case SOCKS4_REQ_BAD_USER_PASS:
|
||||
return ERR_SOCKS_BAD_USER_PASS;
|
||||
default:
|
||||
return ERR_SOCKS_UNKNOWN_FAILURE;
|
||||
}
|
||||
break;
|
||||
case SOCKS_VERSION_5:
|
||||
if (buf[0] != SOCKS_VERSION_5) return ERR_SOCKS_UNKNOWN_FAILURE;
|
||||
switch (buf[1]) {
|
||||
case SOCKS5_CONNECTION_SUCCEEDED:
|
||||
proxy_state = PROXY_STATE_DONE;
|
||||
proxy_retval = 0;
|
||||
break;
|
||||
case SOCKS5_ERR_SERVER_FAILURE:
|
||||
return ERR_SOCKS_UNKNOWN_FAILURE;
|
||||
case SOCKS5_ERR_NOT_ALLOWED:
|
||||
return ERR_SOCKS_REQUEST_FAILED;
|
||||
case SOCKS5_ERR_NETWORK_UNREACHABLE:
|
||||
return ERR_SOCKS_CANT_REACH_HOST;
|
||||
case SOCKS5_ERR_HOST_UNREACHABLE:
|
||||
return ERR_SOCKS_CANT_REACH_HOST;
|
||||
case SOCKS5_ERR_CONNECTION_REFUSED:
|
||||
return ERR_SOCKS_CONN_REFUSED;
|
||||
case SOCKS5_ERR_TTL_EXPIRED:
|
||||
return ERR_SOCKS_UNKNOWN_FAILURE;
|
||||
case SOCKS5_ERR_COMMAND_UNSUPPORTED:
|
||||
return ERR_SOCKS_UNKNOWN_FAILURE;
|
||||
case SOCKS5_ERR_ADDR_TYPE_UNSUPPORTED:
|
||||
return ERR_SOCKS_UNKNOWN_FAILURE;
|
||||
default:
|
||||
return ERR_SOCKS_UNKNOWN_FAILURE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return ERR_SOCKS_UNKNOWN_FAILURE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool PROXY::proxy_negotiated() {
|
||||
return (proxy_state == PROXY_STATE_DONE);
|
||||
}
|
||||
|
||||
bool PROXY::proxy_poll() {
|
||||
int n, retval, ip_addr, nbytes;
|
||||
bool action = false;
|
||||
char buf[256];
|
||||
|
||||
ScopeMessages scope_messages(log_messages, ClientMessages::DEBUG_PROXY);
|
||||
|
||||
switch(proxy_state) {
|
||||
case PROXY_STATE_CONNECTING:
|
||||
if (pi.use_socks_proxy) {
|
||||
if (pi.socks_version == SOCKS_VERSION_4) {
|
||||
scope_messages.printf("PROXY::proxy_poll(): attempting SOCKS4 connect\n");
|
||||
proxy_state = PROXY_STATE_SOCKS_SEND_CONNECT_REQ;
|
||||
} else if (pi.socks_version == SOCKS_VERSION_5) {
|
||||
scope_messages.printf("PROXY::proxy_poll(): attempting SOCKS5 connect\n");
|
||||
proxy_state = PROXY_STATE_SOCKS_SEND_METHOD_REQ;
|
||||
} else {
|
||||
scope_messages.printf("PROXY::proxy_poll(): SOCKS proxy ignored - unknown version: %d\n", pi.socks_version);
|
||||
proxy_state = PROXY_STATE_DONE;
|
||||
}
|
||||
} else {
|
||||
scope_messages.printf("PROXY::proxy_poll(): SOCKS proxy ignored - user pref\n");
|
||||
proxy_state = PROXY_STATE_DONE;
|
||||
}
|
||||
|
||||
action = true;
|
||||
break;
|
||||
case PROXY_STATE_SOCKS_SEND_METHOD_REQ:
|
||||
nbytes = socks_prepare_method_req(proxy_data);
|
||||
scope_messages.printf("PROXY::proxy_poll(): sending method request\n");
|
||||
if (nbytes <= 0) {
|
||||
proxy_failed(ERR_SOCKS_UNKNOWN_FAILURE);
|
||||
} else {
|
||||
n = send(socket, proxy_data, nbytes, 0);
|
||||
|
||||
if (n != nbytes) proxy_failed(ERR_SOCKS_UNKNOWN_FAILURE);
|
||||
else proxy_state = PROXY_STATE_SOCKS_PARSE_METHOD_ACK;
|
||||
}
|
||||
action = true;
|
||||
break;
|
||||
case PROXY_STATE_SOCKS_PARSE_METHOD_ACK:
|
||||
if (io_ready) {
|
||||
nbytes = proxy_read_reply(socket, buf, 256);
|
||||
if (nbytes == 0) break;
|
||||
scope_messages.printf("PROXY::proxy_poll(): parsing method request ack\n");
|
||||
retval = socks_parse_method_ack(buf);
|
||||
if (retval) proxy_failed (retval);
|
||||
action = true;
|
||||
}
|
||||
break;
|
||||
case PROXY_STATE_SOCKS_SEND_USER_PASS:
|
||||
scope_messages.printf("PROXY::proxy_poll(): sending user/pass\n");
|
||||
nbytes = socks_prepare_user_pass(proxy_data);
|
||||
if (nbytes <= 0) {
|
||||
proxy_failed(ERR_SOCKS_UNKNOWN_FAILURE);
|
||||
} else {
|
||||
n = send(socket, proxy_data, nbytes, 0);
|
||||
if (n != nbytes) proxy_failed(ERR_SOCKS_UNKNOWN_FAILURE);
|
||||
else proxy_state = PROXY_STATE_SOCKS_PARSE_USER_PASS_ACK;
|
||||
}
|
||||
action = true;
|
||||
break;
|
||||
case PROXY_STATE_SOCKS_PARSE_USER_PASS_ACK:
|
||||
if (io_ready) {
|
||||
action = true;
|
||||
nbytes = proxy_read_reply(socket, buf, 256);
|
||||
if (nbytes == 0) break;
|
||||
scope_messages.printf("PROXY::proxy_poll(): parsing user/pass ack\n");
|
||||
retval = socks_parse_user_pass_ack(buf);
|
||||
if (retval) proxy_failed(retval);
|
||||
}
|
||||
break;
|
||||
case PROXY_STATE_SOCKS_SEND_CONNECT_REQ:
|
||||
retval = get_ip_addr(ip_addr);
|
||||
if (retval) {
|
||||
proxy_failed(retval);
|
||||
break;
|
||||
}
|
||||
scope_messages.printf("PROXY::proxy_poll(): sending connect request\n");
|
||||
nbytes = socks_prepare_connect_req(proxy_data, htons(dest_serv_port), ip_addr, dest_serv_name);
|
||||
if (nbytes <= 0) {
|
||||
proxy_failed(ERR_SOCKS_UNKNOWN_FAILURE);
|
||||
} else {
|
||||
n = send(socket, proxy_data, nbytes, 0);
|
||||
if (n != nbytes) proxy_failed(ERR_SOCKS_UNKNOWN_FAILURE);
|
||||
else proxy_state = PROXY_STATE_SOCKS_PARSE_CONNECT_ACK;
|
||||
}
|
||||
action = true;
|
||||
break;
|
||||
case PROXY_STATE_SOCKS_PARSE_CONNECT_ACK:
|
||||
if (io_ready) {
|
||||
action = true;
|
||||
nbytes = proxy_read_reply(socket, buf, 256);
|
||||
if (nbytes == 0) break;
|
||||
scope_messages.printf("PROXY::proxy_poll(): parsing connect ack\n");
|
||||
retval = socks_parse_connect_ack(buf);
|
||||
if (retval) {
|
||||
proxy_failed(retval);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return action;
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
// The contents of this file are subject to the BOINC Public License
|
||||
// Version 1.0 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://boinc.berkeley.edu/license_1.0.txt
|
||||
//
|
||||
// Software distributed under the License is distributed on an "AS IS"
|
||||
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing rights and limitations
|
||||
// under the License.
|
||||
//
|
||||
// The Original Code is the Berkeley Open Infrastructure for Network Computing.
|
||||
//
|
||||
// The Initial Developer of the Original Code is the SETI@home project.
|
||||
// Portions created by the SETI@home project are Copyright (C) 2002
|
||||
// University of California at Berkeley. All Rights Reserved.
|
||||
//
|
||||
// Contributor(s):
|
||||
//
|
||||
|
||||
#ifndef _PROXY_
|
||||
#define _PROXY_
|
||||
|
||||
#include "net_xfer.h"
|
||||
|
||||
struct PROXY_INFO {
|
||||
bool use_http_proxy;
|
||||
bool use_socks_proxy;
|
||||
int socks_version;
|
||||
char socks_server_name[256];
|
||||
char http_server_name[256];
|
||||
int socks_server_port;
|
||||
int http_server_port;
|
||||
char socks5_user_name[256];
|
||||
char socks5_user_passwd[256];
|
||||
|
||||
int parse(FILE*);
|
||||
int write(FILE*);
|
||||
void clear();
|
||||
};
|
||||
|
||||
class PROXY : public NET_XFER {
|
||||
public:
|
||||
PROXY();
|
||||
~PROXY();
|
||||
|
||||
PROXY_INFO pi;
|
||||
char proxy_data[256];
|
||||
int proxy_state;
|
||||
int proxy_retval;
|
||||
char dest_serv_name[256];
|
||||
int dest_serv_port;
|
||||
|
||||
void init(char *dst_host, int port);
|
||||
bool proxy_poll();
|
||||
bool proxy_negotiated();
|
||||
int proxy_failed(int failure_code);
|
||||
char *get_proxy_server_name(char *regular_server);
|
||||
int get_proxy_port(int regular_port);
|
||||
int set_proxy(PROXY_INFO *new_pd);
|
||||
int socks_prepare_method_req(char *buf);
|
||||
int socks_prepare_user_pass(char *buf);
|
||||
int socks_prepare_connect_req(char *buf, int ns_port, int ip_addr, char *domain_name);
|
||||
int socks_parse_method_ack(char *buf);
|
||||
int socks_parse_user_pass_ack(char *buf);
|
||||
int socks_parse_connect_ack(char *buf);
|
||||
};
|
||||
|
||||
void print_buf(char *buf, int n);
|
||||
|
||||
#define PROXY_STATE_CONNECTING 0
|
||||
#define PROXY_STATE_SOCKS_SEND_METHOD_REQ 1
|
||||
#define PROXY_STATE_SOCKS_PARSE_METHOD_ACK 2
|
||||
#define PROXY_STATE_SOCKS_SEND_USER_PASS 3
|
||||
#define PROXY_STATE_SOCKS_PARSE_USER_PASS_ACK 4
|
||||
#define PROXY_STATE_SOCKS_SEND_CONNECT_REQ 5
|
||||
#define PROXY_STATE_SOCKS_PARSE_CONNECT_ACK 6
|
||||
#define PROXY_STATE_DONE 7
|
||||
|
||||
// SOCKS #defines
|
||||
#define SOCKS_VERSION_4 0x04
|
||||
#define SOCKS_VERSION_5 0x05
|
||||
|
||||
#define SOCKS_AUTH_NONE_NEEDED 0x00
|
||||
#define SOCKS_AUTH_GSSAPI 0x01
|
||||
#define SOCKS_AUTH_USER_PASS 0x02
|
||||
#define SOCKS_AUTH_NONE_ACCEPTABLE 0xFF
|
||||
|
||||
#define SOCKS4_REQ_GRANTED 90
|
||||
#define SOCKS4_REQ_REJECTED 91
|
||||
#define SOCKS4_REQ_NO_IDENTD 92
|
||||
#define SOCKS4_REQ_BAD_USER_PASS 93
|
||||
|
||||
#define SOCKS5_ADDR_TYPE_IPV4 0x01
|
||||
#define SOCKS5_ADDR_TYPE_DOMAIN_NAME 0x03
|
||||
#define SOCKS5_ADDR_TYPE_IPV6 0x04
|
||||
|
||||
#define SOCKS5_CONNECTION_SUCCEEDED 0x00
|
||||
#define SOCKS5_ERR_SERVER_FAILURE 0x01
|
||||
#define SOCKS5_ERR_NOT_ALLOWED 0x02
|
||||
#define SOCKS5_ERR_NETWORK_UNREACHABLE 0x03
|
||||
#define SOCKS5_ERR_HOST_UNREACHABLE 0x04
|
||||
#define SOCKS5_ERR_CONNECTION_REFUSED 0x05
|
||||
#define SOCKS5_ERR_TTL_EXPIRED 0x06
|
||||
#define SOCKS5_ERR_COMMAND_UNSUPPORTED 0x07
|
||||
#define SOCKS5_ERR_ADDR_TYPE_UNSUPPORTED 0x08
|
||||
|
||||
#define SOCKS5_USER_SUBNEG_VERSION_1 1
|
||||
|
||||
#endif
|
|
@ -215,11 +215,7 @@ int SCHEDULER_OP::start_rpc() {
|
|||
|
||||
scope_messages.printf_file(SCHED_OP_REQUEST_FILE, "req:");
|
||||
|
||||
if (gstate.use_http_proxy) {
|
||||
http_op.use_http_proxy = true;
|
||||
safe_strcpy(http_op.proxy_server_name, gstate.proxy_server_name);
|
||||
http_op.proxy_server_port = gstate.proxy_server_port;
|
||||
}
|
||||
http_op.set_proxy(&gstate.pi);
|
||||
retval = http_op.init_post(
|
||||
scheduler_url, SCHED_OP_REQUEST_FILE,
|
||||
SCHED_OP_RESULT_FILE
|
||||
|
@ -241,11 +237,7 @@ int SCHEDULER_OP::init_master_fetch(PROJECT* p) {
|
|||
|
||||
project = p;
|
||||
scope_messages.printf("SCHEDULER_OP::init_master_fetch(): Fetching master file for %s\n", project->master_url);
|
||||
if (gstate.use_http_proxy) {
|
||||
http_op.use_http_proxy = true;
|
||||
safe_strcpy(http_op.proxy_server_name, gstate.proxy_server_name);
|
||||
http_op.proxy_server_port = gstate.proxy_server_port;
|
||||
}
|
||||
http_op.set_proxy(&gstate.pi);
|
||||
retval = http_op.init_get(project->master_url, MASTER_FILE_NAME, true);
|
||||
if (retval) return retval;
|
||||
retval = http_ops->insert(&http_op);
|
||||
|
|
|
@ -117,3 +117,11 @@
|
|||
#define ERR_SEMCTL -166
|
||||
#define ERR_SEMOP -167
|
||||
#define ERR_FTOK -168
|
||||
#define ERR_SOCKS_UNKNOWN_FAILURE -169
|
||||
#define ERR_SOCKS_REQUEST_FAILED -170
|
||||
#define ERR_SOCKS_BAD_USER_PASS -171
|
||||
#define ERR_SOCKS_UNKNOWN_SERVER_VERSION -172
|
||||
#define ERR_SOCKS_UNSUPPORTED -173
|
||||
#define ERR_SOCKS_CANT_REACH_HOST -174
|
||||
#define ERR_SOCKS_CONN_REFUSED -175
|
||||
|
||||
|
|
Loading…
Reference in New Issue