summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2005-12-08 23:10:22 +0000
committerjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2005-12-08 23:10:22 +0000
commitdf5722cc68307206c5edcc94fd7ae333d3212b59 (patch)
tree6cf9b42be4660ac58cb61c76276f28f140b44b25
parentc959fc742eb10c516261765718a761536b0b8f4a (diff)
downloadopenvpn-df5722cc68307206c5edcc94fd7ae333d3212b59.tar.gz
openvpn-df5722cc68307206c5edcc94fd7ae333d3212b59.tar.xz
openvpn-df5722cc68307206c5edcc94fd7ae333d3212b59.zip
First attempt at automatic proxy detection,
Windows-only at this point. Proxy settings are taken from IE. git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@846 e7ae566f-a301-0410-adde-c780ea21d3b5
-rw-r--r--Makefile.am3
-rwxr-xr-xieproxy.c137
-rwxr-xr-xieproxy.h24
-rwxr-xr-xmakefile.w324
-rw-r--r--options.c78
-rw-r--r--proxy.c54
-rw-r--r--proxy.h2
-rw-r--r--syshead.h2
8 files changed, 291 insertions, 13 deletions
diff --git a/Makefile.am b/Makefile.am
index 424b167..ebfa22d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -127,7 +127,8 @@ EXTRA_DIST = \
plugin \
management \
pkcs11-headers \
- cryptoki-win32.h
+ cryptoki-win32.h \
+ ieproxy.c ieproxy.h
dist-hook:
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
diff --git a/ieproxy.c b/ieproxy.c
new file mode 100755
index 0000000..42b067b
--- /dev/null
+++ b/ieproxy.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2004 Ewan Bhamrah Harley <code@ewan.info>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <WinInet.h>
+#include <malloc.h>
+
+LPCTSTR getIeHttpProxyError=NULL;
+
+/* getIeHttpProxy fetches the current IE proxy settings for http */
+
+LPCTSTR getIeHttpProxy()
+{
+ DWORD psize=0;
+ INTERNET_PROXY_INFO *pinfo;
+ LPTSTR proxyString;
+ LPTSTR p;
+ LPTSTR q;
+ unsigned int len;
+
+ /* first see how big a buffer we need for the IPO structure */
+ InternetQueryOption(NULL, INTERNET_OPTION_PROXY, NULL, &psize);
+ if(!psize)
+ {
+ getIeHttpProxyError="InternetQueryOption failed to return buffer size";
+ return(NULL);
+ }
+
+ /* allocate memory for IPO */
+ pinfo = malloc (psize*sizeof(TCHAR));
+ if (pinfo == NULL)
+ {
+ getIeHttpProxyError="malloc failed (1)";
+ return(NULL);
+ }
+
+ /* now run the real query */
+ if(!InternetQueryOption(NULL, INTERNET_OPTION_PROXY, (LPVOID) pinfo, &psize))
+ {
+ getIeHttpProxyError="InternetQueryOption() failed to find proxy info";
+ free(pinfo);
+ return(NULL);
+ }
+
+
+ /* see what sort of result we got */
+
+ if(pinfo->dwAccessType == INTERNET_OPEN_TYPE_DIRECT)
+ {
+ /* No proxy configured */
+ free(pinfo);
+ return("");
+ }
+ else if(pinfo->dwAccessType == INTERNET_OPEN_TYPE_PROXY)
+ {
+ /* we have a proxy - now parse result string */
+ /* if result string does NOT contain an '=' sign then */
+ /* there is a single proxy for all protocols */
+ for (p=(LPTSTR)pinfo->lpszProxy; *p && *p != '='; p++);
+ if(!*p)
+ {
+ /* single proxy */
+ /* allocate a new string to return */
+ len = 1+strlen(pinfo->lpszProxy);
+ proxyString = malloc (len*sizeof(TCHAR));
+ if (proxyString == NULL)
+ {
+ getIeHttpProxyError="malloc failed (2)";
+ free(pinfo);
+ return(NULL);
+ }
+ strncpy(proxyString, pinfo->lpszProxy,len);
+ proxyString[len]=0;
+ free(pinfo);
+ return(proxyString);
+ }
+ else
+ {
+ /* multiple space seperated proxies defined in the form */
+ /* protocol=proxyhost[:port] */
+ /* we want the one marked "http=", if any. */
+ p=(LPTSTR)pinfo->lpszProxy;
+ while(*p && strncmp(p, "http=", 5))
+ {
+ for(; *p && *p != ' '; p++);
+ if(*p) p++;
+ }
+ if(*p)
+ {
+ /* found the proxy */
+ p+=5;
+ for(q=p; *q && *q != ' '; q++);
+ /* allocate a buffer for the proxy information */
+ len=1+(q-p);
+ proxyString=malloc(len*sizeof(TCHAR));
+ if(proxyString==NULL)
+ {
+ getIeHttpProxyError="malloc failed (3)";
+ free(pinfo);
+ return(NULL);
+ }
+ strncpy(proxyString, p, len);
+ proxyString[len]=0;
+ free(pinfo);
+ return(proxyString);
+ }
+ else
+ {
+ /* No http proxy in list */
+ free(pinfo);
+ return("");
+ }
+ }
+ }
+ else
+ {
+ /* InternetQueryOption returned a proxy type we don't know about*/
+ getIeHttpProxyError="Unknown Proxy Type";
+ free(pinfo);
+ return(NULL);
+ }
+}
diff --git a/ieproxy.h b/ieproxy.h
new file mode 100755
index 0000000..0786c05
--- /dev/null
+++ b/ieproxy.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2004 Ewan Bhamrah Harley <code@ewan.info>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __GETIEHTTPPROXY__
+#define __GETIEHTTPPROXY__
+extern LPTSTR getIeHttpProxyError;
+LPCTSTR getIeHttpProxy();
+#endif
diff --git a/makefile.w32 b/makefile.w32
index 4184504..c612512 100755
--- a/makefile.w32
+++ b/makefile.w32
@@ -49,7 +49,7 @@ INCLUDE_DIRS = -I${OPENSSL}/include -I${LZO}/include
INCLUDE_DIRS_DMALLOC = ${INCLUDE_DIRS} -I${DMALLOC}
-LIBS = -llzo2 -lcrypt32 -lws2_32 -lgdi32 -liphlpapi -lwinmm
+LIBS = -llzo2 -lcrypt32 -lWinInet -lws2_32 -lgdi32 -liphlpapi -lwinmm
LIBS_DMALLOC = ${LIBS} -ldmalloc
@@ -78,6 +78,7 @@ HEADERS = \
fragment.h \
gremlin.h \
helper.h \
+ ieproxy.h \
init.h \
integer.h \
interval.h \
@@ -136,6 +137,7 @@ OBJS = base64.o \
fragment.o \
gremlin.o \
helper.o \
+ ieproxy.o \
init.o \
interval.o \
list.o \
diff --git a/options.c b/options.c
index 9e38da6..ebe61d0 100644
--- a/options.c
+++ b/options.c
@@ -969,7 +969,7 @@ show_remote_list (const struct remote_list *l)
}
#endif
-#if defined(ENABLE_HTTP_PROXY) && defined (ENABLE_DEBUG)
+#if defined(ENABLE_HTTP_PROXY) && defined(ENABLE_DEBUG)
static void
show_http_proxy_options (const struct http_proxy_options *o)
{
@@ -3676,23 +3676,58 @@ add_option (struct options *options,
options->proto = proto;
}
#ifdef ENABLE_HTTP_PROXY
- else if (streq (p[0], "http-proxy") && p[1] && p[2])
+ else if (streq (p[0], "http-proxy") && p[1])
{
- int port;
struct http_proxy_options *ho;
VERIFY_PERMISSION (OPT_P_GENERAL);
- port = atoi (p[2]);
- if (!legal_ipv4_port (port))
+
+ if (streq (p[1], "auto"))
{
- msg (msglevel, "Bad http-proxy port number: %s", p[2]);
- goto err;
+ struct http_proxy_options hpo;
+ bool status;
+ char *error = NULL;
+
+ p[4] = p[3];
+ p[3] = p[2];
+ p[1] = p[2] = NULL;
+ CLEAR (hpo);
+
+ status = get_http_proxy_settings (&hpo, &error, &options->gc);
+ if (status)
+ {
+ ho = init_http_options_if_undefined (options);
+ ho->server = hpo.server;
+ ho->port = hpo.port;
+ }
+ else
+ {
+ if (error)
+ msg (M_WARN, "http-proxy auto error: %s", error);
+ goto err;
+ }
}
+ else
+ {
+ int port;
+ if (!p[2])
+ {
+ msg (msglevel, "http-proxy port number not defined");
+ goto err;
+ }
+ port = atoi (p[2]);
+ if (!legal_ipv4_port (port))
+ {
+ msg (msglevel, "Bad http-proxy port number: %s", p[2]);
+ goto err;
+ }
- ho = init_http_options_if_undefined (options);
+ ho = init_http_options_if_undefined (options);
+
+ ho->server = p[1];
+ ho->port = port;
+ }
- ho->server = p[1];
- ho->port = port;
if (p[3])
{
ho->auth_method_string = "basic";
@@ -3743,6 +3778,29 @@ add_option (struct options *options,
msg (msglevel, "Bad http-proxy-option or missing parameter: '%s'", p[1]);
}
}
+ else if (streq (p[0], "show-http-proxy-settings"))
+ {
+ struct http_proxy_options po;
+ bool status;
+ char *error = NULL;
+
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ CLEAR (po);
+ status = get_http_proxy_settings (&po, &error, &options->gc);
+ if (status)
+ {
+ msg (M_INFO|M_NOPREFIX, "Server: %s", po.server);
+ msg (M_INFO|M_NOPREFIX, "Port: %d", po.port);
+ }
+ else
+ {
+ if (error)
+ msg (msglevel, "Proxy error: %s", error);
+ else
+ msg (msglevel, "Proxy settings are undefined");
+ }
+ openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
+ }
#endif
#ifdef ENABLE_SOCKS
else if (streq (p[0], "socks-proxy") && p[1])
diff --git a/proxy.c b/proxy.c
index 0911733..0cfd51c 100644
--- a/proxy.c
+++ b/proxy.c
@@ -40,8 +40,62 @@
#include "proxy.h"
#include "ntlm.h"
+#ifdef WIN32
+#include "ieproxy.h"
+#endif
+
#include "memdbg.h"
+#ifdef WIN32
+
+bool
+get_http_proxy_settings (struct http_proxy_options *p, char **err, struct gc_arena *gc)
+{
+ bool ret = false;
+ const char *result;
+
+ p->server = NULL;
+ p->port = 0;
+ getIeHttpProxyError = NULL;
+ if (err)
+ *err = NULL;
+
+ result = getIeHttpProxy ();
+ if (result)
+ {
+ char addr_str[128];
+ char port_str[16];
+ struct buffer in;
+ buf_set_read (&in, (const uint8_t *)result, strlen (result));
+ if (buf_parse (&in, ':', addr_str, sizeof (addr_str))
+ && buf_parse (&in, ':', port_str, sizeof (port_str)))
+ {
+ p->server = string_alloc (addr_str, gc);
+ p->port = atoi (port_str);
+ ret = true;
+ }
+ free ((void *)result);
+ }
+ else if (getIeHttpProxyError)
+ {
+ if (err)
+ *err = string_alloc (getIeHttpProxyError, gc);
+ }
+ return ret;
+}
+
+#else
+
+bool
+get_http_proxy_settings (struct http_proxy_options *p, char **err, struct gc_arena *gc)
+{
+ if (err)
+ *err = string_alloc ("HTTP proxy detection not supported on this OS", gc);
+ return false;
+}
+
+#endif
+
/* cached proxy username/password */
static struct user_pass static_proxy_user_pass;
diff --git a/proxy.h b/proxy.h
index 9a31826..5e7178c 100644
--- a/proxy.h
+++ b/proxy.h
@@ -67,5 +67,7 @@ void establish_http_proxy_passthru (struct http_proxy_info *p,
uint8_t *make_base64_string2 (const uint8_t *str, int str_len, struct gc_arena *gc);
uint8_t *make_base64_string (const uint8_t *str, struct gc_arena *gc);
+bool get_http_proxy_settings (struct http_proxy_options *p, char **err, struct gc_arena *gc);
+
#endif
#endif
diff --git a/syshead.h b/syshead.h
index d25b82c..6426241 100644
--- a/syshead.h
+++ b/syshead.h
@@ -429,7 +429,7 @@ socket_defined (const socket_descriptor_t sd)
/*
* Should we include NTLM proxy functionality
*/
-#if defined(USE_CRYPTO) && defined (ENABLE_HTTP_PROXY)
+#if defined(USE_CRYPTO) && defined(ENABLE_HTTP_PROXY)
#define NTLM 1
#else
#define NTLM 0