> Date: Wed, 28 Apr 2010 09:12:29 -0500 > From: <open...@rkmorris.us> > Very interesting timing! Just last night I was poking about about this > a bit, and I'm not so sure that the proxy approach noted so far is the > best / right way to do this. Rather, to be able to handle dynamic (not > just static) proxy configurations the WinHTTP API looks to me to be the > way to do this (see http://msdn.microsoft.com/en- > us/library/aa384097(v=VS.85).aspx for an example).
Actually the InternetQueryOption and WinHTTP API need to be used in conjunction to guarantee proxy setting coverage - or at least thats the approach we have taken in our products. > Message: 2 > Date: Wed, 28 Apr 2010 17:24:31 +0300 > From: Alon Bar-Lev <alon.bar...@gmail.com> > The IE API is user specific. > As OpenVPN runs as a service using own user or system account, IE API > is not suitable. > Using WinHTTP indeed looks better. I don't believe this is correct, depending on the handle you pass to the API you can set proxy settings on a per connection, per session or global basis. In any case, surely having a per user proxy settings is not an issue, as you are going to establish a VPN on a per user basis also? Sorry I am not in a position to help develop, but can provide you with basically what you need to use, the following should compile under MinGW, had to snip out some unneeded stuff but you get the idea: ===== // Alter system-wide web proxy settings #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <wininet.h> #include <iostream> #include <cstring> #include <string> // Define various things which don't seem // to exist in the MinGW headers #define INTERNET_OPTION_PER_CONNECTION_OPTION 75 #define INTERNET_PER_CONN_FLAGS 1 #define PROXY_TYPE_PROXY 2 #define PROXY_TYPE_DIRECT 1 #define PROXY_TYPE_AUTO_PROXY_URL 4 #define INTERNET_PER_CONN_PROXY_SERVER 2 #define INTERNET_PER_CONN_PROXY_BYPASS 3 #define INTERNET_PER_CONN_AUTOCONFIG_URL 4 typedef struct { DWORD dwOption; union { DWORD dwValue; LPTSTR pszValue; FILETIME ftValue; } Value; } INTERNET_PER_CONN_OPTION, *LPINTERNET_PER_CONN_OPTION; typedef struct { DWORD dwSize; LPTSTR pszConnection; DWORD dwOptionCount; DWORD dwOptionError; LPINTERNET_PER_CONN_OPTION pOptions; } INTERNET_PER_CONN_OPTION_LIST, *LPINTERNET_PER_CONN_OPTION_LIST; // Entry point int main(int argc, char *argv[]) { // Initialise the option list with options common to various proxy types INTERNET_PER_CONN_OPTION_LIST list; INTERNET_PER_CONN_OPTION options[3]; options[0].dwOption = INTERNET_PER_CONN_FLAGS; options[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS; std::string proxy, bypass("127.0.0.1;"); // Use a specific proxy options[0].Value.dwValue = PROXY_TYPE_PROXY | PROXY_TYPE_DIRECT; proxy.assign("http://"); proxy.append(argv[2]); options[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER; options[1].Value.pszValue = (TCHAR*) (proxy.c_str()); // Add the proxy itself to the list of things to access directly // - but don't stick the protocol or port number in the bypass list std::string addtobypass(proxy.substr(7)); std::string::size_type pos(addtobypass.find(':')); if (pos != std::string::npos) { addtobypass.assign(addtobypass.substr(0, pos)); } bypass.append("; "); bypass.append(addtobypass); list.dwOptionCount = 3; // or to use no proxy // options[0].Value.dwValue = PROXY_TYPE_DIRECT; // list.dwOptionCount = 1; // or to use a proxy autoconfiguration file // options[0].Value.dwValue = PROXY_TYPE_AUTO_PROXY_URL | PROXY_TYPE_DIRECT; // options[1].dwOption = INTERNET_PER_CONN_AUTOCONFIG_URL; // options[1].Value.pszValue = argv[2]; // list.dwOptionCount = 3; // Finalise option list options[2].Value.pszValue = (TCHAR*) (bypass.c_str()); list.dwSize = sizeof(list); list.pszConnection = NULL; list.dwOptionError = 0; list.pOptions = options; // Set the options if (InternetSetOption(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, sizeof(list)) == FALSE) { std::cerr << "Could not InternetSetOption (1): " << GetLastError() << std::endl; return 2; } // Tell Windows we've finished changing options and to apply the new ones now if (InternetSetOption(NULL, INTERNET_OPTION_REFRESH, NULL, 0) == FALSE) { std::cerr << "Could not InternetSetOption (2): " << GetLastError() << std::endl; return 2; } return 0; } ========= We use the above in conjunction with the commandline WinHTTP API wrapper: proxycfg -u This seems to do the job for us. HTH, goodluck. Kave