diff options
author | james <james@e7ae566f-a301-0410-adde-c780ea21d3b5> | 2005-12-08 23:10:22 +0000 |
---|---|---|
committer | james <james@e7ae566f-a301-0410-adde-c780ea21d3b5> | 2005-12-08 23:10:22 +0000 |
commit | df5722cc68307206c5edcc94fd7ae333d3212b59 (patch) | |
tree | 6cf9b42be4660ac58cb61c76276f28f140b44b25 | |
parent | Inline file capability now works for (diff) | |
download | openvpn-df5722cc68307206c5edcc94fd7ae333d3212b59.tar.xz |
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.am | 3 | ||||
-rwxr-xr-x | ieproxy.c | 137 | ||||
-rwxr-xr-x | ieproxy.h | 24 | ||||
-rwxr-xr-x | makefile.w32 | 4 | ||||
-rw-r--r-- | options.c | 78 | ||||
-rw-r--r-- | proxy.c | 54 | ||||
-rw-r--r-- | proxy.h | 2 | ||||
-rw-r--r-- | syshead.h | 2 |
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 \ @@ -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]) @@ -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; @@ -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 @@ -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 |