git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@850 e7ae566f-a301-0410-adde-c780ea21d3b5
| ... | ... |
@@ -3,7 +3,7 @@ Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net> |
| 3 | 3 |
|
| 4 | 4 |
$Id$ |
| 5 | 5 |
|
| 6 |
-2005.11.xx -- Version 2.1-beta8 |
|
| 6 |
+2005.12.xx -- Version 2.1-beta8 |
|
| 7 | 7 |
|
| 8 | 8 |
* --remap-usr1 will now also remap signals thrown during |
| 9 | 9 |
initialization. |
| ... | ... |
@@ -17,6 +17,8 @@ $Id$ |
| 17 | 17 |
* Fixed typo in manage.c where inline function declaration |
| 18 | 18 |
was declared without the "static" keyword (David Stipp). |
| 19 | 19 |
* Patch to support --topology subnet on Mac OS X (Mathias Sundman). |
| 20 |
+* Added --auto-proxy directive to auto-detect HTTP or SOCKS |
|
| 21 |
+ proxy settings (currently Windows only). |
|
| 20 | 22 |
|
| 21 | 23 |
2005.11.12 -- Version 2.1-beta7 |
| 22 | 24 |
|
| ... | ... |
@@ -29,7 +31,8 @@ $Id$ |
| 29 | 29 |
but actually would only accept /29 or less. |
| 30 | 30 |
* Extend byte counters to 64 bits (M. van Cuijk). |
| 31 | 31 |
* PKCS#11 fixes (Alon Bar-Lev). |
| 32 |
- |
|
| 32 |
+* Removed redundant base64 code. |
|
| 33 |
+ |
|
| 33 | 34 |
2005.11.02 -- Version 2.0.5 |
| 34 | 35 |
|
| 35 | 36 |
* Fixed bug in Linux get_default_gateway function |
| ... | ... |
@@ -127,8 +127,7 @@ EXTRA_DIST = \ |
| 127 | 127 |
plugin \ |
| 128 | 128 |
management \ |
| 129 | 129 |
pkcs11-headers \ |
| 130 |
- cryptoki-win32.h \ |
|
| 131 |
- ieproxy.c ieproxy.h |
|
| 130 |
+ cryptoki-win32.h |
|
| 132 | 131 |
|
| 133 | 132 |
dist-hook: |
| 134 | 133 |
cd $(distdir) && for i in $(EXTRA_DIST) ; do find $$i -name .svn -type d -prune -exec rm -rf '{}' ';' ; rm -f `find $$i -type f | grep -E '(^|\/)\.?\#|\~$$|\.s?o$$'` ; done
|
| ... | ... |
@@ -39,7 +39,7 @@ |
| 39 | 39 |
|
| 40 | 40 |
#include "syshead.h" |
| 41 | 41 |
|
| 42 |
-#if NTLM |
|
| 42 |
+#ifdef ENABLE_HTTP_PROXY |
|
| 43 | 43 |
|
| 44 | 44 |
#include "base64.h" |
| 45 | 45 |
|
| ... | ... |
@@ -48,16 +48,6 @@ |
| 48 | 48 |
static char base64_chars[] = |
| 49 | 49 |
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
| 50 | 50 |
|
| 51 |
-static int |
|
| 52 |
-pos(char c) |
|
| 53 |
-{
|
|
| 54 |
- char *p; |
|
| 55 |
- for (p = base64_chars; *p; p++) |
|
| 56 |
- if (*p == c) |
|
| 57 |
- return p - base64_chars; |
|
| 58 |
- return -1; |
|
| 59 |
-} |
|
| 60 |
- |
|
| 61 | 51 |
int |
| 62 | 52 |
base64_encode(const void *data, int size, char **str) |
| 63 | 53 |
{
|
| ... | ... |
@@ -96,6 +86,18 @@ base64_encode(const void *data, int size, char **str) |
| 96 | 96 |
return strlen(s); |
| 97 | 97 |
} |
| 98 | 98 |
|
| 99 |
+#if NTLM |
|
| 100 |
+ |
|
| 101 |
+static int |
|
| 102 |
+pos(char c) |
|
| 103 |
+{
|
|
| 104 |
+ char *p; |
|
| 105 |
+ for (p = base64_chars; *p; p++) |
|
| 106 |
+ if (*p == c) |
|
| 107 |
+ return p - base64_chars; |
|
| 108 |
+ return -1; |
|
| 109 |
+} |
|
| 110 |
+ |
|
| 99 | 111 |
#define DECODE_ERROR 0xffffffff |
| 100 | 112 |
|
| 101 | 113 |
static unsigned int |
| ... | ... |
@@ -141,6 +143,8 @@ base64_decode(const char *str, void *data) |
| 141 | 141 |
return q - (unsigned char *) data; |
| 142 | 142 |
} |
| 143 | 143 |
|
| 144 |
+#endif /* NTLM */ |
|
| 145 |
+ |
|
| 144 | 146 |
#else |
| 145 | 147 |
static void dummy(void) {}
|
| 146 | 148 |
#endif |
| ... | ... |
@@ -31,12 +31,10 @@ |
| 31 | 31 |
* SUCH DAMAGE. |
| 32 | 32 |
*/ |
| 33 | 33 |
|
| 34 |
-/* $KTH: base64.h,v 1.2 1999/12/02 16:58:45 joda Exp $ */ |
|
| 35 |
- |
|
| 36 | 34 |
#ifndef _BASE64_H_ |
| 37 | 35 |
#define _BASE64_H_ |
| 38 | 36 |
|
| 39 |
-#if NTLM |
|
| 37 |
+#ifdef ENABLE_HTTP_PROXY |
|
| 40 | 38 |
|
| 41 | 39 |
int base64_encode(const void *data, int size, char **str); |
| 42 | 40 |
int base64_decode(const char *str, void *data); |
| ... | ... |
@@ -621,6 +621,18 @@ buf_parse (struct buffer *buf, const int delim, char *line, const int size) |
| 621 | 621 |
} |
| 622 | 622 |
|
| 623 | 623 |
/* |
| 624 |
+ * Print a string which might be NULL |
|
| 625 |
+ */ |
|
| 626 |
+const char * |
|
| 627 |
+np (const char *str) |
|
| 628 |
+{
|
|
| 629 |
+ if (str) |
|
| 630 |
+ return str; |
|
| 631 |
+ else |
|
| 632 |
+ return "[NULL]"; |
|
| 633 |
+} |
|
| 634 |
+ |
|
| 635 |
+/* |
|
| 624 | 636 |
* Classify and mutate strings based on character types. |
| 625 | 637 |
*/ |
| 626 | 638 |
|
| ... | ... |
@@ -553,8 +553,9 @@ xor (uint8_t *dest, const uint8_t *src, int len) |
| 553 | 553 |
} |
| 554 | 554 |
|
| 555 | 555 |
/* |
| 556 |
- * Classify and mutate strings based on character types. |
|
| 556 |
+ * Print a string which might be NULL |
|
| 557 | 557 |
*/ |
| 558 |
+const char *np (const char *str); |
|
| 558 | 559 |
|
| 559 | 560 |
/*#define CHARACTER_CLASS_DEBUG*/ |
| 560 | 561 |
|
| ... | ... |
@@ -102,6 +102,12 @@ init_remote_list (struct context *c) |
| 102 | 102 |
void |
| 103 | 103 |
context_init_1 (struct context *c) |
| 104 | 104 |
{
|
| 105 |
+#ifdef ENABLE_HTTP_PROXY |
|
| 106 |
+ bool did_http = false; |
|
| 107 |
+#else |
|
| 108 |
+ const bool did_http = false; |
|
| 109 |
+#endif |
|
| 110 |
+ |
|
| 105 | 111 |
context_clear_1 (c); |
| 106 | 112 |
|
| 107 | 113 |
packet_id_persist_init (&c->c1.pid_persist); |
| ... | ... |
@@ -145,20 +151,24 @@ context_init_1 (struct context *c) |
| 145 | 145 |
#endif |
| 146 | 146 |
|
| 147 | 147 |
#ifdef ENABLE_HTTP_PROXY |
| 148 |
- if (c->options.http_proxy_options) |
|
| 148 |
+ if (c->options.http_proxy_options || c->options.auto_proxy_info) |
|
| 149 | 149 |
{
|
| 150 | 150 |
/* Possible HTTP proxy user/pass input */ |
| 151 | 151 |
c->c1.http_proxy = new_http_proxy (c->options.http_proxy_options, |
| 152 |
+ c->options.auto_proxy_info, |
|
| 152 | 153 |
&c->gc); |
| 154 |
+ if (c->c1.http_proxy) |
|
| 155 |
+ did_http = true; |
|
| 153 | 156 |
} |
| 154 | 157 |
#endif |
| 155 | 158 |
|
| 156 | 159 |
#ifdef ENABLE_SOCKS |
| 157 |
- if (c->options.socks_proxy_server) |
|
| 160 |
+ if (!did_http && (c->options.socks_proxy_server || c->options.auto_proxy_info)) |
|
| 158 | 161 |
{
|
| 159 | 162 |
c->c1.socks_proxy = new_socks_proxy (c->options.socks_proxy_server, |
| 160 | 163 |
c->options.socks_proxy_port, |
| 161 | 164 |
c->options.socks_proxy_retry, |
| 165 |
+ c->options.auto_proxy_info, |
|
| 162 | 166 |
&c->gc); |
| 163 | 167 |
} |
| 164 | 168 |
#endif |
| ... | ... |
@@ -78,7 +78,6 @@ HEADERS = \ |
| 78 | 78 |
fragment.h \ |
| 79 | 79 |
gremlin.h \ |
| 80 | 80 |
helper.h \ |
| 81 |
- ieproxy.h \ |
|
| 82 | 81 |
init.h \ |
| 83 | 82 |
integer.h \ |
| 84 | 83 |
interval.h \ |
| ... | ... |
@@ -137,7 +136,6 @@ OBJS = base64.o \ |
| 137 | 137 |
fragment.o \ |
| 138 | 138 |
gremlin.o \ |
| 139 | 139 |
helper.o \ |
| 140 |
- ieproxy.o \ |
|
| 141 | 140 |
init.o \ |
| 142 | 141 |
interval.o \ |
| 143 | 142 |
list.o \ |
| ... | ... |
@@ -101,6 +101,7 @@ openvpn \- secure IP tunnel daemon. |
| 101 | 101 |
[\ \fB\-\-auth\-user\-pass\-verify\fR\ \fIscript\fR\ ] |
| 102 | 102 |
[\ \fB\-\-auth\-user\-pass\fR\ \fIup\fR\ ] |
| 103 | 103 |
[\ \fB\-\-auth\fR\ \fIalg\fR\ ] |
| 104 |
+[\ \fB\-\-auto\-proxy\fR\ ] |
|
| 104 | 105 |
[\ \fB\-\-bcast\-buffers\fR\ \fIn\fR\ ] |
| 105 | 106 |
[\ \fB\-\-ca\fR\ \fIfile\fR\ ] |
| 106 | 107 |
[\ \fB\-\-ccd\-exclusive\fR\ ] |
| ... | ... |
@@ -597,7 +598,19 @@ as the |
| 597 | 597 |
number of retries of connection attempt (default=infinite). |
| 598 | 598 |
.\"********************************************************* |
| 599 | 599 |
.TP |
| 600 |
-.B --http-proxy server port [authfile] [auth-method] |
|
| 600 |
+.B --auto-proxy |
|
| 601 |
+Try to sense HTTP or SOCKS proxy settings automatically. |
|
| 602 |
+If no settings are present, a direct connection will be attempted. |
|
| 603 |
+If both HTTP and SOCKS settings are present, HTTP will be preferred. |
|
| 604 |
+If the HTTP proxy server requires a password, it will be queried from |
|
| 605 |
+stdin or the management interface. If the underlying OS doesn't support an API for |
|
| 606 |
+returning proxy settings, a direct connection will be attempted. |
|
| 607 |
+Currently, only Windows clients support this option via the |
|
| 608 |
+InternetQueryOption API. |
|
| 609 |
+This option exists in OpenVPN 2.1 or higher. |
|
| 610 |
+.\"********************************************************* |
|
| 611 |
+.TP |
|
| 612 |
+.B --http-proxy server port [authfile|'auto'] [auth-method] |
|
| 601 | 613 |
Connect to remote host through an HTTP proxy at address |
| 602 | 614 |
.B server |
| 603 | 615 |
and port |
| ... | ... |
@@ -608,7 +621,15 @@ is a file containing a username and password on 2 lines, or |
| 608 | 608 |
"stdin" to prompt from console. |
| 609 | 609 |
|
| 610 | 610 |
.B auth-method |
| 611 |
-should be one of "none", "basic", or "ntlm". |
|
| 611 |
+should be one of "none", "basic", or "ntlm". |
|
| 612 |
+ |
|
| 613 |
+The |
|
| 614 |
+.B auto |
|
| 615 |
+flag causes OpenVPN to automatically determine the |
|
| 616 |
+.B auth-method |
|
| 617 |
+and query stdin or the management interface for |
|
| 618 |
+username/password credentials, if required. This flag |
|
| 619 |
+exists on OpenVPN 2.1 or higher. |
|
| 612 | 620 |
.\"********************************************************* |
| 613 | 621 |
.TP |
| 614 | 622 |
.B --http-proxy-retry |
| ... | ... |
@@ -857,6 +878,8 @@ of the TAP-Win32 driver. When used on *nix, requires that the tun |
| 857 | 857 |
driver supports an |
| 858 | 858 |
.BR ifconfig (8) |
| 859 | 859 |
command which sets a subnet instead of a remote endpoint IP address. |
| 860 |
+ |
|
| 861 |
+This option exists in OpenVPN 2.1 or higher. |
|
| 860 | 862 |
.\"********************************************************* |
| 861 | 863 |
.TP |
| 862 | 864 |
.B --tun-ipv6 |
| ... | ... |
@@ -1175,8 +1198,7 @@ bypasses the tunnel |
| 1175 | 1175 |
(Available on Windows clients, may not be available |
| 1176 | 1176 |
on non-Windows clients). |
| 1177 | 1177 |
|
| 1178 |
-Using the def1 flag is highly recommended, and is currently |
|
| 1179 |
-planned to become the default by OpenVPN 2.1. |
|
| 1178 |
+Using the def1 flag is highly recommended. |
|
| 1180 | 1179 |
.\"********************************************************* |
| 1181 | 1180 |
.TP |
| 1182 | 1181 |
.B --link-mtu n |
| ... | ... |
@@ -97,12 +97,18 @@ static const char usage_message[] = |
| 97 | 97 |
" between connection retries (default=%d).\n" |
| 98 | 98 |
"--connect-timeout n : For --proto tcp-client, connection timeout (in seconds).\n" |
| 99 | 99 |
"--connect-retry-max n : Maximum connection attempt retries, default infinite.\n" |
| 100 |
+#ifdef GENERAL_PROXY_SUPPORT |
|
| 101 |
+ "--auto-proxy : Try to sense proxy settings (or lack thereof) automatically.\n" |
|
| 102 |
+#endif |
|
| 100 | 103 |
#ifdef ENABLE_HTTP_PROXY |
| 101 |
- "--http-proxy s p [up] [auth] : Connect to remote host through an HTTP proxy at\n" |
|
| 102 |
- " address s and port p. If proxy authentication is required,\n" |
|
| 104 |
+ "--http-proxy s p [up] [auth] : Connect to remote host\n" |
|
| 105 |
+ " through an HTTP proxy at address s and port p.\n" |
|
| 106 |
+ " If proxy authentication is required,\n" |
|
| 103 | 107 |
" up is a file containing username/password on 2 lines, or\n" |
| 104 | 108 |
" 'stdin' to prompt from console. Add auth='ntlm' if\n" |
| 105 | 109 |
" the proxy requires NTLM authentication.\n" |
| 110 |
+ "--http-proxy s p 'auto': Like the above directive, but automatically determine\n" |
|
| 111 |
+ " auth method and query for username/password if needed.\n" |
|
| 106 | 112 |
"--http-proxy-retry : Retry indefinitely on HTTP proxy errors.\n" |
| 107 | 113 |
"--http-proxy-timeout n : Proxy timeout in seconds, default=5.\n" |
| 108 | 114 |
"--http-proxy-option type [parm] : Set extended HTTP proxy options.\n" |
| ... | ... |
@@ -1537,8 +1543,8 @@ options_postprocess (struct options *options, bool first_time) |
| 1537 | 1537 |
msg (M_USAGE, "--remote MUST be used in TCP Client mode"); |
| 1538 | 1538 |
|
| 1539 | 1539 |
#ifdef ENABLE_HTTP_PROXY |
| 1540 |
- if (options->http_proxy_options && options->proto != PROTO_TCPv4_CLIENT) |
|
| 1541 |
- msg (M_USAGE, "--http-proxy MUST be used in TCP Client mode (i.e. --proto tcp-client)"); |
|
| 1540 |
+ if ((options->http_proxy_options || options->auto_proxy_info) && options->proto != PROTO_TCPv4_CLIENT) |
|
| 1541 |
+ msg (M_USAGE, "--http-proxy or --auto-proxy MUST be used in TCP Client mode (i.e. --proto tcp-client)"); |
|
| 1542 | 1542 |
#endif |
| 1543 | 1543 |
|
| 1544 | 1544 |
#if defined(ENABLE_HTTP_PROXY) && defined(ENABLE_SOCKS) |
| ... | ... |
@@ -3675,67 +3681,78 @@ add_option (struct options *options, |
| 3675 | 3675 |
} |
| 3676 | 3676 |
options->proto = proto; |
| 3677 | 3677 |
} |
| 3678 |
-#ifdef ENABLE_HTTP_PROXY |
|
| 3679 |
- else if (streq (p[0], "http-proxy") && p[1]) |
|
| 3678 |
+#ifdef GENERAL_PROXY_SUPPORT |
|
| 3679 |
+ else if (streq (p[0], "auto-proxy")) |
|
| 3680 | 3680 |
{
|
| 3681 |
- struct http_proxy_options *ho; |
|
| 3681 |
+ char *error = NULL; |
|
| 3682 | 3682 |
|
| 3683 | 3683 |
VERIFY_PERMISSION (OPT_P_GENERAL); |
| 3684 |
+ options->auto_proxy_info = get_proxy_settings (&error, &options->gc); |
|
| 3685 |
+ if (error) |
|
| 3686 |
+ msg (M_WARN, "PROXY: %s", error); |
|
| 3687 |
+ } |
|
| 3688 |
+ else if (streq (p[0], "show-proxy-settings")) |
|
| 3689 |
+ {
|
|
| 3690 |
+ struct auto_proxy_info *pi; |
|
| 3691 |
+ char *error = NULL; |
|
| 3684 | 3692 |
|
| 3685 |
- if (streq (p[1], "auto")) |
|
| 3693 |
+ VERIFY_PERMISSION (OPT_P_GENERAL); |
|
| 3694 |
+ pi = get_proxy_settings (&error, &options->gc); |
|
| 3695 |
+ if (pi) |
|
| 3686 | 3696 |
{
|
| 3687 |
- struct http_proxy_options hpo; |
|
| 3688 |
- bool status; |
|
| 3689 |
- char *error = NULL; |
|
| 3690 |
- |
|
| 3691 |
- p[4] = p[3]; |
|
| 3692 |
- p[3] = p[2]; |
|
| 3693 |
- p[1] = p[2] = NULL; |
|
| 3694 |
- CLEAR (hpo); |
|
| 3695 |
- |
|
| 3696 |
- status = get_http_proxy_settings (&hpo, &error, &options->gc); |
|
| 3697 |
- if (status) |
|
| 3698 |
- {
|
|
| 3699 |
- ho = init_http_options_if_undefined (options); |
|
| 3700 |
- ho->server = hpo.server; |
|
| 3701 |
- ho->port = hpo.port; |
|
| 3702 |
- } |
|
| 3703 |
- else |
|
| 3704 |
- {
|
|
| 3705 |
- if (error) |
|
| 3706 |
- msg (M_WARN, "http-proxy auto error: %s", error); |
|
| 3707 |
- goto err; |
|
| 3708 |
- } |
|
| 3697 |
+ msg (M_INFO|M_NOPREFIX, "HTTP Server: %s", np(pi->http.server)); |
|
| 3698 |
+ msg (M_INFO|M_NOPREFIX, "HTTP Port: %d", pi->http.port); |
|
| 3699 |
+ msg (M_INFO|M_NOPREFIX, "SOCKS Server: %s", np(pi->socks.server)); |
|
| 3700 |
+ msg (M_INFO|M_NOPREFIX, "SOCKS Port: %d", pi->socks.port); |
|
| 3709 | 3701 |
} |
| 3710 |
- else |
|
| 3711 |
- {
|
|
| 3712 |
- int port; |
|
| 3713 |
- if (!p[2]) |
|
| 3714 |
- {
|
|
| 3715 |
- msg (msglevel, "http-proxy port number not defined"); |
|
| 3716 |
- goto err; |
|
| 3717 |
- } |
|
| 3718 |
- port = atoi (p[2]); |
|
| 3719 |
- if (!legal_ipv4_port (port)) |
|
| 3720 |
- {
|
|
| 3721 |
- msg (msglevel, "Bad http-proxy port number: %s", p[2]); |
|
| 3722 |
- goto err; |
|
| 3723 |
- } |
|
| 3702 |
+ if (error) |
|
| 3703 |
+ msg (msglevel, "Proxy error: %s", error); |
|
| 3704 |
+#ifdef WIN32 |
|
| 3705 |
+ show_win_proxy_settings (M_INFO|M_NOPREFIX); |
|
| 3706 |
+#endif |
|
| 3707 |
+ openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */ |
|
| 3708 |
+ } |
|
| 3709 |
+#endif /* GENERAL_PROXY_SUPPORT */ |
|
| 3710 |
+#ifdef ENABLE_HTTP_PROXY |
|
| 3711 |
+ else if (streq (p[0], "http-proxy") && p[1]) |
|
| 3712 |
+ {
|
|
| 3713 |
+ struct http_proxy_options *ho; |
|
| 3724 | 3714 |
|
| 3725 |
- ho = init_http_options_if_undefined (options); |
|
| 3715 |
+ VERIFY_PERMISSION (OPT_P_GENERAL); |
|
| 3726 | 3716 |
|
| 3727 |
- ho->server = p[1]; |
|
| 3728 |
- ho->port = port; |
|
| 3729 |
- } |
|
| 3717 |
+ {
|
|
| 3718 |
+ int port; |
|
| 3719 |
+ if (!p[2]) |
|
| 3720 |
+ {
|
|
| 3721 |
+ msg (msglevel, "http-proxy port number not defined"); |
|
| 3722 |
+ goto err; |
|
| 3723 |
+ } |
|
| 3724 |
+ port = atoi (p[2]); |
|
| 3725 |
+ if (!legal_ipv4_port (port)) |
|
| 3726 |
+ {
|
|
| 3727 |
+ msg (msglevel, "Bad http-proxy port number: %s", p[2]); |
|
| 3728 |
+ goto err; |
|
| 3729 |
+ } |
|
| 3730 |
+ |
|
| 3731 |
+ ho = init_http_options_if_undefined (options); |
|
| 3732 |
+ |
|
| 3733 |
+ ho->server = p[1]; |
|
| 3734 |
+ ho->port = port; |
|
| 3735 |
+ } |
|
| 3730 | 3736 |
|
| 3731 | 3737 |
if (p[3]) |
| 3732 | 3738 |
{
|
| 3733 |
- ho->auth_method_string = "basic"; |
|
| 3734 |
- ho->auth_file = p[3]; |
|
| 3735 |
- |
|
| 3736 |
- if (p[4]) |
|
| 3739 |
+ if (streq (p[3], "auto")) |
|
| 3740 |
+ ho->auth_retry = true; |
|
| 3741 |
+ else |
|
| 3737 | 3742 |
{
|
| 3738 |
- ho->auth_method_string = p[4]; |
|
| 3743 |
+ ho->auth_method_string = "basic"; |
|
| 3744 |
+ ho->auth_file = p[3]; |
|
| 3745 |
+ |
|
| 3746 |
+ if (p[4]) |
|
| 3747 |
+ {
|
|
| 3748 |
+ ho->auth_method_string = p[4]; |
|
| 3749 |
+ } |
|
| 3739 | 3750 |
} |
| 3740 | 3751 |
} |
| 3741 | 3752 |
else |
| ... | ... |
@@ -3778,29 +3795,6 @@ add_option (struct options *options, |
| 3778 | 3778 |
msg (msglevel, "Bad http-proxy-option or missing parameter: '%s'", p[1]); |
| 3779 | 3779 |
} |
| 3780 | 3780 |
} |
| 3781 |
- else if (streq (p[0], "show-http-proxy-settings")) |
|
| 3782 |
- {
|
|
| 3783 |
- struct http_proxy_options po; |
|
| 3784 |
- bool status; |
|
| 3785 |
- char *error = NULL; |
|
| 3786 |
- |
|
| 3787 |
- VERIFY_PERMISSION (OPT_P_GENERAL); |
|
| 3788 |
- CLEAR (po); |
|
| 3789 |
- status = get_http_proxy_settings (&po, &error, &options->gc); |
|
| 3790 |
- if (status) |
|
| 3791 |
- {
|
|
| 3792 |
- msg (M_INFO|M_NOPREFIX, "Server: %s", po.server); |
|
| 3793 |
- msg (M_INFO|M_NOPREFIX, "Port: %d", po.port); |
|
| 3794 |
- } |
|
| 3795 |
- else |
|
| 3796 |
- {
|
|
| 3797 |
- if (error) |
|
| 3798 |
- msg (msglevel, "Proxy error: %s", error); |
|
| 3799 |
- else |
|
| 3800 |
- msg (msglevel, "Proxy settings are undefined"); |
|
| 3801 |
- } |
|
| 3802 |
- openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */ |
|
| 3803 |
- } |
|
| 3804 | 3781 |
#endif |
| 3805 | 3782 |
#ifdef ENABLE_SOCKS |
| 3806 | 3783 |
else if (streq (p[0], "socks-proxy") && p[1]) |
| ... | ... |
@@ -250,6 +250,10 @@ struct options |
| 250 | 250 |
struct route_option_list *routes; |
| 251 | 251 |
bool route_nopull; |
| 252 | 252 |
|
| 253 |
+#ifdef GENERAL_PROXY_SUPPORT |
|
| 254 |
+ struct auto_proxy_info *auto_proxy_info; |
|
| 255 |
+#endif |
|
| 256 |
+ |
|
| 253 | 257 |
#ifdef ENABLE_HTTP_PROXY |
| 254 | 258 |
struct http_proxy_options *http_proxy_options; |
| 255 | 259 |
#endif |
| ... | ... |
@@ -28,8 +28,6 @@ |
| 28 | 28 |
#include "config.h" |
| 29 | 29 |
#endif |
| 30 | 30 |
|
| 31 |
-#ifdef ENABLE_HTTP_PROXY |
|
| 32 |
- |
|
| 33 | 31 |
#include "syshead.h" |
| 34 | 32 |
|
| 35 | 33 |
#include "common.h" |
| ... | ... |
@@ -38,6 +36,7 @@ |
| 38 | 38 |
#include "socket.h" |
| 39 | 39 |
#include "fdmisc.h" |
| 40 | 40 |
#include "proxy.h" |
| 41 |
+#include "base64.h" |
|
| 41 | 42 |
#include "ntlm.h" |
| 42 | 43 |
|
| 43 | 44 |
#ifdef WIN32 |
| ... | ... |
@@ -46,55 +45,7 @@ |
| 46 | 46 |
|
| 47 | 47 |
#include "memdbg.h" |
| 48 | 48 |
|
| 49 |
-#ifdef WIN32 |
|
| 50 |
- |
|
| 51 |
-bool |
|
| 52 |
-get_http_proxy_settings (struct http_proxy_options *p, char **err, struct gc_arena *gc) |
|
| 53 |
-{
|
|
| 54 |
- bool ret = false; |
|
| 55 |
- const char *result; |
|
| 56 |
- |
|
| 57 |
- p->server = NULL; |
|
| 58 |
- p->port = 0; |
|
| 59 |
- getIeHttpProxyError = NULL; |
|
| 60 |
- if (err) |
|
| 61 |
- *err = NULL; |
|
| 62 |
- |
|
| 63 |
- result = getIeHttpProxy (); |
|
| 64 |
- if (result) |
|
| 65 |
- {
|
|
| 66 |
- char addr_str[128]; |
|
| 67 |
- char port_str[16]; |
|
| 68 |
- struct buffer in; |
|
| 69 |
- buf_set_read (&in, (const uint8_t *)result, strlen (result)); |
|
| 70 |
- if (buf_parse (&in, ':', addr_str, sizeof (addr_str)) |
|
| 71 |
- && buf_parse (&in, ':', port_str, sizeof (port_str))) |
|
| 72 |
- {
|
|
| 73 |
- p->server = string_alloc (addr_str, gc); |
|
| 74 |
- p->port = atoi (port_str); |
|
| 75 |
- ret = true; |
|
| 76 |
- } |
|
| 77 |
- free ((void *)result); |
|
| 78 |
- } |
|
| 79 |
- else if (getIeHttpProxyError) |
|
| 80 |
- {
|
|
| 81 |
- if (err) |
|
| 82 |
- *err = string_alloc (getIeHttpProxyError, gc); |
|
| 83 |
- } |
|
| 84 |
- return ret; |
|
| 85 |
-} |
|
| 86 |
- |
|
| 87 |
-#else |
|
| 88 |
- |
|
| 89 |
-bool |
|
| 90 |
-get_http_proxy_settings (struct http_proxy_options *p, char **err, struct gc_arena *gc) |
|
| 91 |
-{
|
|
| 92 |
- if (err) |
|
| 93 |
- *err = string_alloc ("HTTP proxy detection not supported on this OS", gc);
|
|
| 94 |
- return false; |
|
| 95 |
-} |
|
| 96 |
- |
|
| 97 |
-#endif |
|
| 49 |
+#ifdef ENABLE_HTTP_PROXY |
|
| 98 | 50 |
|
| 99 | 51 |
/* cached proxy username/password */ |
| 100 | 52 |
static struct user_pass static_proxy_user_pass; |
| ... | ... |
@@ -246,42 +197,12 @@ send_crlf (socket_descriptor_t sd) |
| 246 | 246 |
uint8_t * |
| 247 | 247 |
make_base64_string2 (const uint8_t *str, int src_len, struct gc_arena *gc) |
| 248 | 248 |
{
|
| 249 |
- static const char base64_table[] = |
|
| 250 |
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
|
| 251 |
- |
|
| 252 |
- uint8_t *buf; |
|
| 253 |
- const uint8_t *src; |
|
| 254 |
- uint8_t *dst; |
|
| 255 |
- int bits, data, dst_len; |
|
| 256 |
- |
|
| 257 |
- /* make base64 string */ |
|
| 258 |
- dst_len = (src_len + 2) / 3 * 4; |
|
| 259 |
- buf = gc_malloc (dst_len + 1, false, gc); |
|
| 260 |
- bits = data = 0; |
|
| 261 |
- src = str; |
|
| 262 |
- dst = buf; |
|
| 263 |
- while (dst_len--) |
|
| 264 |
- {
|
|
| 265 |
- if (bits < 6) |
|
| 266 |
- {
|
|
| 267 |
- data = (data << 8) | *src; |
|
| 268 |
- bits += 8; |
|
| 269 |
- src++; |
|
| 270 |
- } |
|
| 271 |
- *dst++ = base64_table[0x3F & (data >> (bits - 6))]; |
|
| 272 |
- bits -= 6; |
|
| 273 |
- } |
|
| 274 |
- *dst = '\0'; |
|
| 275 |
- |
|
| 276 |
- /* fix-up tail padding */ |
|
| 277 |
- switch (src_len % 3) |
|
| 278 |
- {
|
|
| 279 |
- case 1: |
|
| 280 |
- *--dst = '='; |
|
| 281 |
- case 2: |
|
| 282 |
- *--dst = '='; |
|
| 283 |
- } |
|
| 284 |
- return buf; |
|
| 249 |
+ uint8_t *ret = NULL; |
|
| 250 |
+ char *b64out = NULL; |
|
| 251 |
+ ASSERT (base64_encode ((const void *)str, src_len, &b64out) >= 0); |
|
| 252 |
+ ret = (uint8_t *) string_alloc (b64out, gc); |
|
| 253 |
+ free (b64out); |
|
| 254 |
+ return ret; |
|
| 285 | 255 |
} |
| 286 | 256 |
|
| 287 | 257 |
uint8_t * |
| ... | ... |
@@ -300,18 +221,67 @@ username_password_as_base64 (const struct http_proxy_info *p, |
| 300 | 300 |
return (const char *)make_base64_string ((const uint8_t*)BSTR (&out), gc); |
| 301 | 301 |
} |
| 302 | 302 |
|
| 303 |
+static void |
|
| 304 |
+get_user_pass_http (struct http_proxy_info *p, const bool force) |
|
| 305 |
+{
|
|
| 306 |
+ if (!static_proxy_user_pass.defined || force) |
|
| 307 |
+ {
|
|
| 308 |
+ get_user_pass (&static_proxy_user_pass, |
|
| 309 |
+ p->options.auth_file, |
|
| 310 |
+ "HTTP Proxy", |
|
| 311 |
+ GET_USER_PASS_MANAGEMENT); |
|
| 312 |
+ p->up = static_proxy_user_pass; |
|
| 313 |
+ } |
|
| 314 |
+} |
|
| 315 |
+ |
|
| 303 | 316 |
struct http_proxy_info * |
| 304 | 317 |
new_http_proxy (const struct http_proxy_options *o, |
| 318 |
+ struct auto_proxy_info *auto_proxy_info, |
|
| 305 | 319 |
struct gc_arena *gc) |
| 306 | 320 |
{
|
| 307 | 321 |
struct http_proxy_info *p; |
| 308 |
- ALLOC_OBJ_CLEAR_GC (p, struct http_proxy_info, gc); |
|
| 322 |
+ struct http_proxy_options opt; |
|
| 323 |
+ |
|
| 324 |
+ if (auto_proxy_info) |
|
| 325 |
+ {
|
|
| 326 |
+ if (o && o->server) |
|
| 327 |
+ {
|
|
| 328 |
+ /* if --http-proxy explicitly given, disable auto-proxy */ |
|
| 329 |
+ auto_proxy_info = NULL; |
|
| 330 |
+ } |
|
| 331 |
+ else |
|
| 332 |
+ {
|
|
| 333 |
+ /* if no --http-proxy explicitly given and no auto settings, fail */ |
|
| 334 |
+ if (!auto_proxy_info->http.server) |
|
| 335 |
+ return NULL; |
|
| 309 | 336 |
|
| 310 |
- if (!o->server) |
|
| 337 |
+ if (o) |
|
| 338 |
+ {
|
|
| 339 |
+ opt = *o; |
|
| 340 |
+ } |
|
| 341 |
+ else |
|
| 342 |
+ {
|
|
| 343 |
+ CLEAR (opt); |
|
| 344 |
+ |
|
| 345 |
+ /* These settings are only used for --auto-proxy */ |
|
| 346 |
+ opt.timeout = 5; |
|
| 347 |
+ opt.http_version = "1.0"; |
|
| 348 |
+ } |
|
| 349 |
+ |
|
| 350 |
+ opt.server = auto_proxy_info->http.server; |
|
| 351 |
+ opt.port = auto_proxy_info->http.port; |
|
| 352 |
+ opt.auth_retry = true; |
|
| 353 |
+ |
|
| 354 |
+ o = &opt; |
|
| 355 |
+ } |
|
| 356 |
+ } |
|
| 357 |
+ |
|
| 358 |
+ if (!o || !o->server) |
|
| 311 | 359 |
msg (M_FATAL, "HTTP_PROXY: server not specified"); |
| 312 | 360 |
|
| 313 | 361 |
ASSERT (legal_ipv4_port (o->port)); |
| 314 | 362 |
|
| 363 |
+ ALLOC_OBJ_CLEAR_GC (p, struct http_proxy_info, gc); |
|
| 315 | 364 |
p->options = *o; |
| 316 | 365 |
|
| 317 | 366 |
/* parse authentication method */ |
| ... | ... |
@@ -332,11 +302,7 @@ new_http_proxy (const struct http_proxy_options *o, |
| 332 | 332 |
/* only basic and NTLM authentication supported so far */ |
| 333 | 333 |
if (p->auth_method == HTTP_AUTH_BASIC || p->auth_method == HTTP_AUTH_NTLM) |
| 334 | 334 |
{
|
| 335 |
- get_user_pass (&static_proxy_user_pass, |
|
| 336 |
- o->auth_file, |
|
| 337 |
- "HTTP Proxy", |
|
| 338 |
- GET_USER_PASS_MANAGEMENT); |
|
| 339 |
- p->up = static_proxy_user_pass; |
|
| 335 |
+ get_user_pass_http (p, true); |
|
| 340 | 336 |
} |
| 341 | 337 |
|
| 342 | 338 |
#if !NTLM |
| ... | ... |
@@ -348,7 +314,7 @@ new_http_proxy (const struct http_proxy_options *o, |
| 348 | 348 |
return p; |
| 349 | 349 |
} |
| 350 | 350 |
|
| 351 |
-void |
|
| 351 |
+bool |
|
| 352 | 352 |
establish_http_proxy_passthru (struct http_proxy_info *p, |
| 353 | 353 |
socket_descriptor_t sd, /* already open to proxy */ |
| 354 | 354 |
const char *host, /* openvpn server remote */ |
| ... | ... |
@@ -362,6 +328,12 @@ establish_http_proxy_passthru (struct http_proxy_info *p, |
| 362 | 362 |
char get[80]; |
| 363 | 363 |
int status; |
| 364 | 364 |
int nparms; |
| 365 |
+ bool ret = false; |
|
| 366 |
+ |
|
| 367 |
+ /* get user/pass if not previously given or if --auto-proxy is being used */ |
|
| 368 |
+ if (p->auth_method == HTTP_AUTH_BASIC |
|
| 369 |
+ || p->auth_method == HTTP_AUTH_NTLM) |
|
| 370 |
+ get_user_pass_http (p, false); |
|
| 365 | 371 |
|
| 366 | 372 |
/* format HTTP CONNECT message */ |
| 367 | 373 |
openvpn_snprintf (buf, sizeof(buf), "CONNECT %s:%d HTTP/%s", |
| ... | ... |
@@ -519,7 +491,21 @@ establish_http_proxy_passthru (struct http_proxy_info *p, |
| 519 | 519 |
ASSERT (0); /* No NTLM support */ |
| 520 | 520 |
#endif |
| 521 | 521 |
} |
| 522 |
- else goto error; |
|
| 522 |
+ else if (p->auth_method == HTTP_AUTH_NONE && p->options.auth_retry) |
|
| 523 |
+ {
|
|
| 524 |
+ /* |
|
| 525 |
+ * Proxy needs authentication, but we don't have a user/pass. |
|
| 526 |
+ * Now we will change p->auth_method and return true so that |
|
| 527 |
+ * our caller knows to call us again on a newly opened socket. |
|
| 528 |
+ * JYFIXME: This code needs to check proxy error output and set |
|
| 529 |
+ * JYFIXME: p->auth_method = HTTP_AUTH_NTLM if necessary. |
|
| 530 |
+ */ |
|
| 531 |
+ p->auth_method = HTTP_AUTH_BASIC; |
|
| 532 |
+ ret = true; |
|
| 533 |
+ goto done; |
|
| 534 |
+ } |
|
| 535 |
+ else |
|
| 536 |
+ goto error; |
|
| 523 | 537 |
} |
| 524 | 538 |
|
| 525 | 539 |
|
| ... | ... |
@@ -527,7 +513,7 @@ establish_http_proxy_passthru (struct http_proxy_info *p, |
| 527 | 527 |
if (nparms < 1 || status != 200) |
| 528 | 528 |
{
|
| 529 | 529 |
msg (D_LINK_ERRORS, "HTTP proxy returned bad status"); |
| 530 |
-#if 0 |
|
| 530 |
+#if 0 |
|
| 531 | 531 |
/* DEBUGGING -- show a multi-line HTTP error response */ |
| 532 | 532 |
while (true) |
| 533 | 533 |
{
|
| ... | ... |
@@ -556,17 +542,221 @@ establish_http_proxy_passthru (struct http_proxy_info *p, |
| 556 | 556 |
msg (M_INFO, "HTTP PROXY: lookahead: %s", format_hex (BPTR (lookahead), BLEN (lookahead), 0)); |
| 557 | 557 |
#endif |
| 558 | 558 |
|
| 559 |
+ done: |
|
| 559 | 560 |
gc_free (&gc); |
| 560 |
- return; |
|
| 561 |
+ return ret; |
|
| 561 | 562 |
|
| 562 | 563 |
error: |
| 563 | 564 |
/* on error, should we exit or restart? */ |
| 564 | 565 |
if (!*signal_received) |
| 565 | 566 |
*signal_received = (p->options.retry ? SIGUSR1 : SIGTERM); /* SOFT-SIGUSR1 -- HTTP proxy error */ |
| 566 | 567 |
gc_free (&gc); |
| 567 |
- return; |
|
| 568 |
+ return ret; |
|
| 568 | 569 |
} |
| 569 | 570 |
|
| 570 | 571 |
#else |
| 571 | 572 |
static void dummy(void) {}
|
| 572 | 573 |
#endif /* ENABLE_HTTP_PROXY */ |
| 574 |
+ |
|
| 575 |
+#ifdef GENERAL_PROXY_SUPPORT |
|
| 576 |
+ |
|
| 577 |
+#ifdef WIN32 |
|
| 578 |
+ |
|
| 579 |
+#if 0 |
|
| 580 |
+char * |
|
| 581 |
+get_windows_internet_string (const DWORD dwOption, struct gc_arena *gc) |
|
| 582 |
+{
|
|
| 583 |
+ DWORD size = 0; |
|
| 584 |
+ char *ret = NULL; |
|
| 585 |
+ |
|
| 586 |
+ /* Initially, get size of return buffer */ |
|
| 587 |
+ InternetQueryOption (NULL, dwOption, NULL, &size); |
|
| 588 |
+ if (size) |
|
| 589 |
+ {
|
|
| 590 |
+ /* Now get actual info */ |
|
| 591 |
+ ret = (INTERNET_PROXY_INFO *) gc_malloc (size, false, gc); |
|
| 592 |
+ if (!InternetQueryOption (NULL, dwOption, (LPVOID) ret, &size)) |
|
| 593 |
+ ret = NULL; |
|
| 594 |
+ } |
|
| 595 |
+ return ret; |
|
| 596 |
+} |
|
| 597 |
+#endif |
|
| 598 |
+ |
|
| 599 |
+static INTERNET_PROXY_INFO * |
|
| 600 |
+get_windows_proxy_settings (struct gc_arena *gc) |
|
| 601 |
+{
|
|
| 602 |
+ DWORD size = 0; |
|
| 603 |
+ INTERNET_PROXY_INFO *ret = NULL; |
|
| 604 |
+ |
|
| 605 |
+ /* Initially, get size of return buffer */ |
|
| 606 |
+ InternetQueryOption (NULL, INTERNET_OPTION_PROXY, NULL, &size); |
|
| 607 |
+ if (size) |
|
| 608 |
+ {
|
|
| 609 |
+ /* Now get actual info */ |
|
| 610 |
+ ret = (INTERNET_PROXY_INFO *) gc_malloc (size, false, gc); |
|
| 611 |
+ if (!InternetQueryOption (NULL, INTERNET_OPTION_PROXY, (LPVOID) ret, &size)) |
|
| 612 |
+ ret = NULL; |
|
| 613 |
+ } |
|
| 614 |
+ return ret; |
|
| 615 |
+} |
|
| 616 |
+ |
|
| 617 |
+static const char * |
|
| 618 |
+parse_windows_proxy_setting (const char *str, struct auto_proxy_info_entry *e, struct gc_arena *gc) |
|
| 619 |
+{
|
|
| 620 |
+ char buf[128]; |
|
| 621 |
+ const char *ret = NULL; |
|
| 622 |
+ struct buffer in; |
|
| 623 |
+ |
|
| 624 |
+ CLEAR (*e); |
|
| 625 |
+ |
|
| 626 |
+ buf_set_read (&in, (const uint8_t *)str, strlen (str)); |
|
| 627 |
+ |
|
| 628 |
+ if (strchr (str, '=') != NULL) |
|
| 629 |
+ {
|
|
| 630 |
+ if (buf_parse (&in, '=', buf, sizeof (buf))) |
|
| 631 |
+ ret = string_alloc (buf, gc); |
|
| 632 |
+ } |
|
| 633 |
+ |
|
| 634 |
+ if (buf_parse (&in, ':', buf, sizeof (buf))) |
|
| 635 |
+ e->server = string_alloc (buf, gc); |
|
| 636 |
+ |
|
| 637 |
+ if (e->server && buf_parse (&in, '\0', buf, sizeof (buf))) |
|
| 638 |
+ e->port = atoi (buf); |
|
| 639 |
+ |
|
| 640 |
+ return ret; |
|
| 641 |
+} |
|
| 642 |
+ |
|
| 643 |
+static void |
|
| 644 |
+parse_windows_proxy_setting_list (const char *str, const char *type, struct auto_proxy_info_entry *e, struct gc_arena *gc) |
|
| 645 |
+{
|
|
| 646 |
+ struct gc_arena gc_local = gc_new (); |
|
| 647 |
+ struct auto_proxy_info_entry el; |
|
| 648 |
+ |
|
| 649 |
+ CLEAR (*e); |
|
| 650 |
+ if (type) |
|
| 651 |
+ {
|
|
| 652 |
+ char buf[128]; |
|
| 653 |
+ struct buffer in; |
|
| 654 |
+ |
|
| 655 |
+ buf_set_read (&in, (const uint8_t *)str, strlen (str)); |
|
| 656 |
+ if (strchr (str, '=') != NULL) |
|
| 657 |
+ {
|
|
| 658 |
+ while (buf_parse (&in, ' ', buf, sizeof (buf))) |
|
| 659 |
+ {
|
|
| 660 |
+ const char *t = parse_windows_proxy_setting (buf, &el, &gc_local); |
|
| 661 |
+ if (t && !strcmp (t, type)) |
|
| 662 |
+ goto found; |
|
| 663 |
+ } |
|
| 664 |
+ } |
|
| 665 |
+ } |
|
| 666 |
+ else |
|
| 667 |
+ {
|
|
| 668 |
+ if (!parse_windows_proxy_setting (str, &el, &gc_local)) |
|
| 669 |
+ goto found; |
|
| 670 |
+ } |
|
| 671 |
+ goto done; |
|
| 672 |
+ |
|
| 673 |
+ found: |
|
| 674 |
+ if (el.server && el.port > 0) |
|
| 675 |
+ {
|
|
| 676 |
+ e->server = string_alloc (el.server, gc); |
|
| 677 |
+ e->port = el.port; |
|
| 678 |
+ } |
|
| 679 |
+ |
|
| 680 |
+ done: |
|
| 681 |
+ gc_free (&gc_local); |
|
| 682 |
+} |
|
| 683 |
+ |
|
| 684 |
+static const char * |
|
| 685 |
+win_proxy_access_type (const DWORD dwAccessType) |
|
| 686 |
+{
|
|
| 687 |
+ switch (dwAccessType) |
|
| 688 |
+ {
|
|
| 689 |
+ case INTERNET_OPEN_TYPE_DIRECT: |
|
| 690 |
+ return "INTERNET_OPEN_TYPE_DIRECT"; |
|
| 691 |
+ case INTERNET_OPEN_TYPE_PROXY: |
|
| 692 |
+ return "INTERNET_OPEN_TYPE_PROXY"; |
|
| 693 |
+ default: |
|
| 694 |
+ return "[UNKNOWN]"; |
|
| 695 |
+ } |
|
| 696 |
+} |
|
| 697 |
+ |
|
| 698 |
+void |
|
| 699 |
+show_win_proxy_settings (const int msglevel) |
|
| 700 |
+{
|
|
| 701 |
+ INTERNET_PROXY_INFO *info; |
|
| 702 |
+ struct gc_arena gc = gc_new (); |
|
| 703 |
+ |
|
| 704 |
+ info = get_windows_proxy_settings (&gc); |
|
| 705 |
+ msg (msglevel, "PROXY INFO: %s %s", |
|
| 706 |
+ win_proxy_access_type (info->dwAccessType), |
|
| 707 |
+ info->lpszProxy ? info->lpszProxy : "[NULL]"); |
|
| 708 |
+ |
|
| 709 |
+ gc_free (&gc); |
|
| 710 |
+} |
|
| 711 |
+ |
|
| 712 |
+struct auto_proxy_info * |
|
| 713 |
+get_proxy_settings (char **err, struct gc_arena *gc) |
|
| 714 |
+{
|
|
| 715 |
+ struct gc_arena gc_local = gc_new (); |
|
| 716 |
+ INTERNET_PROXY_INFO *info; |
|
| 717 |
+ struct auto_proxy_info *pi; |
|
| 718 |
+ |
|
| 719 |
+ ALLOC_OBJ_CLEAR_GC (pi, struct auto_proxy_info, gc); |
|
| 720 |
+ |
|
| 721 |
+ if (err) |
|
| 722 |
+ *err = NULL; |
|
| 723 |
+ |
|
| 724 |
+ info = get_windows_proxy_settings (&gc_local); |
|
| 725 |
+ |
|
| 726 |
+ if (!info) |
|
| 727 |
+ {
|
|
| 728 |
+ if (err) |
|
| 729 |
+ *err = "PROXY: failed to obtain windows proxy info"; |
|
| 730 |
+ goto done; |
|
| 731 |
+ } |
|
| 732 |
+ |
|
| 733 |
+ switch (info->dwAccessType) |
|
| 734 |
+ {
|
|
| 735 |
+ case INTERNET_OPEN_TYPE_DIRECT: |
|
| 736 |
+ break; |
|
| 737 |
+ case INTERNET_OPEN_TYPE_PROXY: |
|
| 738 |
+ if (!info->lpszProxy) |
|
| 739 |
+ break; |
|
| 740 |
+ parse_windows_proxy_setting_list (info->lpszProxy, NULL, &pi->http, gc); |
|
| 741 |
+ if (!pi->http.server) |
|
| 742 |
+ parse_windows_proxy_setting_list (info->lpszProxy, "http", &pi->http, gc); |
|
| 743 |
+ parse_windows_proxy_setting_list (info->lpszProxy, "socks", &pi->socks, gc); |
|
| 744 |
+ break; |
|
| 745 |
+ default: |
|
| 746 |
+ if (err) |
|
| 747 |
+ *err = "PROXY: unknown proxy type"; |
|
| 748 |
+ break; |
|
| 749 |
+ } |
|
| 750 |
+ |
|
| 751 |
+ done: |
|
| 752 |
+ gc_free (&gc_local); |
|
| 753 |
+ return pi; |
|
| 754 |
+} |
|
| 755 |
+ |
|
| 756 |
+#else |
|
| 757 |
+ |
|
| 758 |
+struct auto_proxy_info * |
|
| 759 |
+get_proxy_settings (char **err, struct gc_arena *gc) |
|
| 760 |
+{
|
|
| 761 |
+#if 1 |
|
| 762 |
+ if (err) |
|
| 763 |
+ *err = string_alloc ("PROXY: automatic detection not supported on this OS", gc);
|
|
| 764 |
+ return NULL; |
|
| 765 |
+#else /* JYFIXME, test --auto-proxy feature */ |
|
| 766 |
+ struct auto_proxy_info *pi; |
|
| 767 |
+ ALLOC_OBJ_CLEAR_GC (pi, struct auto_proxy_info, gc); |
|
| 768 |
+ pi->http.server = "10.10.0.2"; |
|
| 769 |
+ pi->http.port = 4000; |
|
| 770 |
+ return pi; |
|
| 771 |
+#endif |
|
| 772 |
+} |
|
| 773 |
+ |
|
| 774 |
+#endif |
|
| 775 |
+ |
|
| 776 |
+#endif /* GENERAL_PROXY_SUPPORT */ |
| ... | ... |
@@ -25,11 +25,35 @@ |
| 25 | 25 |
#ifndef PROXY_H |
| 26 | 26 |
#define PROXY_H |
| 27 | 27 |
|
| 28 |
-#ifdef ENABLE_HTTP_PROXY |
|
| 29 |
- |
|
| 30 | 28 |
#include "buffer.h" |
| 31 | 29 |
#include "misc.h" |
| 32 | 30 |
|
| 31 |
+#ifdef GENERAL_PROXY_SUPPORT |
|
| 32 |
+ |
|
| 33 |
+/* |
|
| 34 |
+ * Return value for get_proxy_settings to automatically |
|
| 35 |
+ * determine proxy information. |
|
| 36 |
+ */ |
|
| 37 |
+struct auto_proxy_info_entry {
|
|
| 38 |
+ char *server; |
|
| 39 |
+ int port; |
|
| 40 |
+}; |
|
| 41 |
+ |
|
| 42 |
+struct auto_proxy_info {
|
|
| 43 |
+ struct auto_proxy_info_entry http; |
|
| 44 |
+ struct auto_proxy_info_entry socks; |
|
| 45 |
+}; |
|
| 46 |
+ |
|
| 47 |
+struct auto_proxy_info *get_proxy_settings (char **err, struct gc_arena *gc); |
|
| 48 |
+ |
|
| 49 |
+#ifdef WIN32 |
|
| 50 |
+void show_win_proxy_settings (const int msglevel); |
|
| 51 |
+#endif /* WIN32 */ |
|
| 52 |
+ |
|
| 53 |
+#endif /* GENERAL_PROXY_SUPPORT */ |
|
| 54 |
+ |
|
| 55 |
+#ifdef ENABLE_HTTP_PROXY |
|
| 56 |
+ |
|
| 33 | 57 |
/* HTTP CONNECT authentication methods */ |
| 34 | 58 |
#define HTTP_AUTH_NONE 0 |
| 35 | 59 |
#define HTTP_AUTH_BASIC 1 |
| ... | ... |
@@ -41,6 +65,7 @@ struct http_proxy_options {
|
| 41 | 41 |
int port; |
| 42 | 42 |
bool retry; |
| 43 | 43 |
int timeout; |
| 44 |
+ bool auth_retry; |
|
| 44 | 45 |
const char *auth_method_string; |
| 45 | 46 |
const char *auth_file; |
| 46 | 47 |
const char *http_version; |
| ... | ... |
@@ -55,9 +80,10 @@ struct http_proxy_info {
|
| 55 | 55 |
}; |
| 56 | 56 |
|
| 57 | 57 |
struct http_proxy_info *new_http_proxy (const struct http_proxy_options *o, |
| 58 |
+ struct auto_proxy_info *auto_proxy_info, |
|
| 58 | 59 |
struct gc_arena *gc); |
| 59 | 60 |
|
| 60 |
-void establish_http_proxy_passthru (struct http_proxy_info *p, |
|
| 61 |
+bool establish_http_proxy_passthru (struct http_proxy_info *p, |
|
| 61 | 62 |
socket_descriptor_t sd, /* already open to proxy */ |
| 62 | 63 |
const char *host, /* openvpn server remote */ |
| 63 | 64 |
const int port, /* openvpn server port */ |
| ... | ... |
@@ -67,7 +93,6 @@ void establish_http_proxy_passthru (struct http_proxy_info *p, |
| 67 | 67 |
uint8_t *make_base64_string2 (const uint8_t *str, int str_len, struct gc_arena *gc); |
| 68 | 68 |
uint8_t *make_base64_string (const uint8_t *str, struct gc_arena *gc); |
| 69 | 69 |
|
| 70 |
-bool get_http_proxy_settings (struct http_proxy_options *p, char **err, struct gc_arena *gc); |
|
| 70 |
+#endif /* ENABLE_HTTP_PROXY */ |
|
| 71 | 71 |
|
| 72 |
-#endif |
|
| 73 |
-#endif |
|
| 72 |
+#endif /* PROXY_H */ |
| ... | ... |
@@ -1307,44 +1307,57 @@ link_socket_init_phase2 (struct link_socket *sock, |
| 1307 | 1307 |
} |
| 1308 | 1308 |
else if (sock->info.proto == PROTO_TCPv4_CLIENT) |
| 1309 | 1309 |
{
|
| 1310 |
- socket_connect (&sock->sd, |
|
| 1311 |
- &sock->info.lsa->local, |
|
| 1312 |
- sock->bind_local, |
|
| 1313 |
- &sock->info.lsa->actual.dest, |
|
| 1314 |
- sock->remote_list, |
|
| 1315 |
- remote_dynamic, |
|
| 1316 |
- &remote_changed, |
|
| 1317 |
- sock->connect_retry_seconds, |
|
| 1318 |
- sock->connect_timeout, |
|
| 1319 |
- sock->connect_retry_max, |
|
| 1320 |
- signal_received); |
|
| 1321 |
- |
|
| 1322 |
- if (*signal_received) |
|
| 1323 |
- goto done; |
|
| 1324 | 1310 |
|
| 1325 |
- if (false) |
|
| 1326 |
- ; |
|
| 1311 |
+#ifdef GENERAL_PROXY_SUPPORT |
|
| 1312 |
+ bool proxy_retry = false; |
|
| 1313 |
+#else |
|
| 1314 |
+ const bool proxy_retry = false; |
|
| 1315 |
+#endif |
|
| 1316 |
+ do {
|
|
| 1317 |
+ socket_connect (&sock->sd, |
|
| 1318 |
+ &sock->info.lsa->local, |
|
| 1319 |
+ sock->bind_local, |
|
| 1320 |
+ &sock->info.lsa->actual.dest, |
|
| 1321 |
+ sock->remote_list, |
|
| 1322 |
+ remote_dynamic, |
|
| 1323 |
+ &remote_changed, |
|
| 1324 |
+ sock->connect_retry_seconds, |
|
| 1325 |
+ sock->connect_timeout, |
|
| 1326 |
+ sock->connect_retry_max, |
|
| 1327 |
+ signal_received); |
|
| 1328 |
+ |
|
| 1329 |
+ if (*signal_received) |
|
| 1330 |
+ goto done; |
|
| 1331 |
+ |
|
| 1332 |
+ if (false) |
|
| 1333 |
+ ; |
|
| 1327 | 1334 |
#ifdef ENABLE_HTTP_PROXY |
| 1328 |
- else if (sock->http_proxy) |
|
| 1329 |
- {
|
|
| 1330 |
- establish_http_proxy_passthru (sock->http_proxy, |
|
| 1331 |
- sock->sd, |
|
| 1332 |
- sock->proxy_dest_host, |
|
| 1333 |
- sock->proxy_dest_port, |
|
| 1334 |
- &sock->stream_buf.residual, |
|
| 1335 |
- signal_received); |
|
| 1336 |
- } |
|
| 1335 |
+ else if (sock->http_proxy) |
|
| 1336 |
+ {
|
|
| 1337 |
+ proxy_retry = establish_http_proxy_passthru (sock->http_proxy, |
|
| 1338 |
+ sock->sd, |
|
| 1339 |
+ sock->proxy_dest_host, |
|
| 1340 |
+ sock->proxy_dest_port, |
|
| 1341 |
+ &sock->stream_buf.residual, |
|
| 1342 |
+ signal_received); |
|
| 1343 |
+ } |
|
| 1337 | 1344 |
#endif |
| 1338 | 1345 |
#ifdef ENABLE_SOCKS |
| 1339 |
- else if (sock->socks_proxy) |
|
| 1340 |
- {
|
|
| 1341 |
- establish_socks_proxy_passthru (sock->socks_proxy, |
|
| 1342 |
- sock->sd, |
|
| 1343 |
- sock->proxy_dest_host, |
|
| 1344 |
- sock->proxy_dest_port, |
|
| 1345 |
- signal_received); |
|
| 1346 |
- } |
|
| 1346 |
+ else if (sock->socks_proxy) |
|
| 1347 |
+ {
|
|
| 1348 |
+ establish_socks_proxy_passthru (sock->socks_proxy, |
|
| 1349 |
+ sock->sd, |
|
| 1350 |
+ sock->proxy_dest_host, |
|
| 1351 |
+ sock->proxy_dest_port, |
|
| 1352 |
+ signal_received); |
|
| 1353 |
+ } |
|
| 1347 | 1354 |
#endif |
| 1355 |
+ if (proxy_retry) |
|
| 1356 |
+ {
|
|
| 1357 |
+ openvpn_close_socket (sock->sd); |
|
| 1358 |
+ sock->sd = create_socket_tcp (); |
|
| 1359 |
+ } |
|
| 1360 |
+ } while (proxy_retry); |
|
| 1348 | 1361 |
} |
| 1349 | 1362 |
#ifdef ENABLE_SOCKS |
| 1350 | 1363 |
else if (sock->info.proto == PROTO_UDPv4 && sock->socks_proxy) |
| ... | ... |
@@ -1386,7 +1399,7 @@ link_socket_init_phase2 (struct link_socket *sock, |
| 1386 | 1386 |
goto done; |
| 1387 | 1387 |
} |
| 1388 | 1388 |
#endif |
| 1389 |
- |
|
| 1389 |
+ |
|
| 1390 | 1390 |
if (*signal_received) |
| 1391 | 1391 |
goto done; |
| 1392 | 1392 |
|
| ... | ... |
@@ -60,10 +60,25 @@ struct socks_proxy_info * |
| 60 | 60 |
new_socks_proxy (const char *server, |
| 61 | 61 |
int port, |
| 62 | 62 |
bool retry, |
| 63 |
+ struct auto_proxy_info *auto_proxy_info, |
|
| 63 | 64 |
struct gc_arena *gc) |
| 64 | 65 |
{
|
| 65 | 66 |
struct socks_proxy_info *p; |
| 67 |
+ |
|
| 68 |
+ if (auto_proxy_info) |
|
| 69 |
+ {
|
|
| 70 |
+ if (!server) |
|
| 71 |
+ {
|
|
| 72 |
+ if (!auto_proxy_info->socks.server) |
|
| 73 |
+ return NULL; |
|
| 74 |
+ |
|
| 75 |
+ server = auto_proxy_info->socks.server; |
|
| 76 |
+ port = auto_proxy_info->socks.port; |
|
| 77 |
+ } |
|
| 78 |
+ } |
|
| 79 |
+ |
|
| 66 | 80 |
ALLOC_OBJ_CLEAR_GC (p, struct socks_proxy_info, gc); |
| 81 |
+ |
|
| 67 | 82 |
ASSERT (server); |
| 68 | 83 |
ASSERT (legal_ipv4_port (port)); |
| 69 | 84 |
|
| ... | ... |
@@ -50,6 +50,7 @@ void socks_adjust_frame_parameters (struct frame *frame, int proto); |
| 50 | 50 |
struct socks_proxy_info *new_socks_proxy (const char *server, |
| 51 | 51 |
int port, |
| 52 | 52 |
bool retry, |
| 53 |
+ struct auto_proxy_info *auto_proxy_info, |
|
| 53 | 54 |
struct gc_arena *gc); |
| 54 | 55 |
|
| 55 | 56 |
void establish_socks_proxy_passthru (struct socks_proxy_info *p, |
| ... | ... |
@@ -266,6 +266,7 @@ |
| 266 | 266 |
|
| 267 | 267 |
#ifdef WIN32 |
| 268 | 268 |
#include <iphlpapi.h> |
| 269 |
+#include <WinInet.h> |
|
| 269 | 270 |
#endif |
| 270 | 271 |
|
| 271 | 272 |
#ifdef HAVE_SYS_MMAN_H |
| ... | ... |
@@ -436,6 +437,13 @@ socket_defined (const socket_descriptor_t sd) |
| 436 | 436 |
#endif |
| 437 | 437 |
|
| 438 | 438 |
/* |
| 439 |
+ * Should we include code common to all proxy methods? |
|
| 440 |
+ */ |
|
| 441 |
+#if defined(ENABLE_HTTP_PROXY) || defined(ENABLE_SOCKS) |
|
| 442 |
+#define GENERAL_PROXY_SUPPORT |
|
| 443 |
+#endif |
|
| 444 |
+ |
|
| 445 |
+/* |
|
| 439 | 446 |
* Do we have PKCS11 capability? |
| 440 | 447 |
*/ |
| 441 | 448 |
#if defined(USE_PKCS11) && defined(USE_CRYPTO) && defined(USE_SSL) |