> 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

Reply via email to