how to authenticate to proxy with wininet.dll?

1

I have this code for connect a process to proxy, but it returns false: The code works if I do not enter username and password in SetConnectionProxy() and send only the two options PROXY flags and PROXY name. When I add the INTERNET_PER_CONN_OPTION set username and set password, it returns false. I do not know anything about wininet.

Please, help me. Thanks.

{

    private static string progressName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name; //extrae el nombre de la aplicación

    [DllImport("wininet.dll", SetLastError = true, CharSet = CharSet.Auto)]
    private static extern IntPtr InternetOpen(
        string lpszAgent, int dwAccessType, string lpszProxyName,
        string lpszProxyBypass, int dwFlags);

    [DllImport("wininet.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool InternetCloseHandle(IntPtr hInternet);

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    private struct INTERNET_PER_CONN_OPTION_LIST
    {
        public int Size;

        // The connection to be set. NULL means LAN.
        public System.IntPtr Connection;

        public int OptionCount;
        public int OptionError;

        // List of INTERNET_PER_CONN_OPTIONs.
        public System.IntPtr pOptions;
    }
    private enum INTERNET_OPTION
    {
        // Sets or retrieves an INTERNET_PER_CONN_OPTION_LIST structure that specifies
        // a list of options for a particular connection.
        INTERNET_OPTION_PER_CONNECTION_OPTION = 75,

        // Notify the system that the registry settings have been changed so that
        // it verifies the settings on the next call to InternetConnect.
        INTERNET_OPTION_SETTINGS_CHANGED = 39,

        // Causes the proxy data to be reread from the registry for a handle.
        INTERNET_OPTION_REFRESH = 37

    }

    private enum INTERNET_PER_CONN_OptionEnum
    {
        INTERNET_PER_CONN_FLAGS = 1,
        INTERNET_PER_CONN_PROXY_SERVER = 2,
        INTERNET_PER_CONN_PROXY_BYPASS = 3,
        INTERNET_PER_CONN_AUTOCONFIG_URL = 4,
        INTERNET_PER_CONN_AUTODISCOVERY_FLAGS = 5,
        INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL = 6,
        INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS = 7,
        INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_TIME = 8,
        INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_URL = 9,
        INTERNET_PER_CONN_FLAGS_UI = 10,
        INTERNET_OPTION_PROXY_USERNAME = 43,
        INTERNET_OPTION_PROXY_PASSWORD = 44
}
    private const int INTERNET_OPEN_TYPE_DIRECT = 1;  // direct to net
    private const int INTERNET_OPEN_TYPE_PRECONFIG = 0; // read registry
                                                        /// <summary>
                                                        /// Constants used in INTERNET_PER_CONN_OPTON struct.
                                                        /// </summary>
    private enum INTERNET_OPTION_PER_CONN_FLAGS
    {
        PROXY_TYPE_DIRECT = 0x00000001,   // direct to net
        PROXY_TYPE_PROXY = 0x00000002,   // via named proxy
        PROXY_TYPE_AUTO_PROXY_URL = 0x00000004,   // autoproxy URL
        PROXY_TYPE_AUTO_DETECT = 0x00000008   // use autoproxy detection
    }

    /// <summary>
    /// Used in INTERNET_PER_CONN_OPTION.
    /// When create a instance of OptionUnion, only one filed will be used.
    /// The StructLayout and FieldOffset attributes could help to decrease the struct size.
    /// </summary>
    [StructLayout(LayoutKind.Explicit)]
    private struct INTERNET_PER_CONN_OPTION_OptionUnion
    {
        // A value in INTERNET_OPTION_PER_CONN_FLAGS.
        [FieldOffset(0)]
        public int dwValue;
        [FieldOffset(0)]
        public System.IntPtr pszValue;
        [FieldOffset(0)]
        public System.Runtime.InteropServices.ComTypes.FILETIME ftValue;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct INTERNET_PER_CONN_OPTION
    {
        // A value in INTERNET_PER_CONN_OptionEnum.
        public int dwOption;
        public INTERNET_PER_CONN_OPTION_OptionUnion Value;
    }
    /// <summary>
    /// Sets an Internet option.
    /// </summary>
    [DllImport("wininet.dll", CharSet = CharSet.Ansi, SetLastError = true)]
    private static extern bool InternetSetOption(
        IntPtr hInternet,
        INTERNET_OPTION dwOption,
        IntPtr lpBuffer,
        int lpdwBufferLength);

    /// <summary>
    /// Queries an Internet option on the specified handle. The Handle will be always 0.
    /// </summary>
    [DllImport("wininet.dll", CharSet = CharSet.Ansi, SetLastError = true,
        EntryPoint = "InternetQueryOption")]
    private extern static bool InternetQueryOptionList(
        IntPtr Handle,
        INTERNET_OPTION OptionFlag,
        ref INTERNET_PER_CONN_OPTION_LIST OptionList,
        ref int size);

    /// <summary>
    /// Set the proxy server for LAN connection.
    /// </summary>
    public static bool SetConnectionProxy(string proxyServer, string username, string password)
    {

        IntPtr hInternet = InternetOpen(progressName, INTERNET_OPEN_TYPE_DIRECT, null, null, 0);

        // Create 4 options.
        int opciones = 4;

        INTERNET_PER_CONN_OPTION[] Options = new INTERNET_PER_CONN_OPTION[opciones];

        // Set PROXY flags.
        Options[0] = new INTERNET_PER_CONN_OPTION();
        Options[0].dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_FLAGS;
        Options[0].Value.dwValue = (int)INTERNET_OPTION_PER_CONN_FLAGS.PROXY_TYPE_PROXY;

        // Set proxy name.
        Options[1] = new INTERNET_PER_CONN_OPTION();
        Options[1].dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_PROXY_SERVER;
        Options[1].Value.pszValue = Marshal.StringToHGlobalAnsi(proxyServer);

        //Set username.
        Options[2] = new INTERNET_PER_CONN_OPTION();
        Options[2].dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_OPTION_PROXY_USERNAME;
        Options[2].Value.pszValue = Marshal.StringToCoTaskMemAuto(username);

        // Set password.
        Options[3] = new INTERNET_PER_CONN_OPTION();
        Options[3].dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_OPTION_PROXY_PASSWORD;
        Options[3].Value.pszValue = Marshal.StringToCoTaskMemAuto(password);

        // Allocate a block of memory of the options.
        System.IntPtr buffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(Options[0]) + Marshal.SizeOf(Options[1]) + Marshal.SizeOf(Options[2]) + Marshal.SizeOf(Options[3]));

        System.IntPtr current = buffer;

        // Marshal data from a managed object to an unmanaged block of memory.
        for (int i = 0; i < Options.Length; i++)
        {
            Marshal.StructureToPtr(Options[i], current, false);
            current = (System.IntPtr)((int)current + Marshal.SizeOf(Options[i]));
        }

        // Initialize a INTERNET_PER_CONN_OPTION_LIST instance.
        INTERNET_PER_CONN_OPTION_LIST option_list = new INTERNET_PER_CONN_OPTION_LIST();

        // Point to the allocated memory.
        option_list.pOptions = buffer;

        // Return the unmanaged size of an object in bytes.
        option_list.Size = Marshal.SizeOf(option_list);

        // IntPtr.Zero means LAN connection.
        option_list.Connection = IntPtr.Zero;

        option_list.OptionCount = Options.Length;
        option_list.OptionError = 0;
        int size = Marshal.SizeOf(option_list);

        // Allocate memory for the INTERNET_PER_CONN_OPTION_LIST instance.
        IntPtr intptrStruct = Marshal.AllocCoTaskMem(size);

        // Marshal data from a managed object to an unmanaged block of memory.
        Marshal.StructureToPtr(option_list, intptrStruct, true);

        // Set internet settings.
        bool bReturn = InternetSetOption(hInternet, INTERNET_OPTION.INTERNET_OPTION_PER_CONNECTION_OPTION, intptrStruct, size);

        // Free the allocated memory.
        Marshal.FreeCoTaskMem(buffer);
        Marshal.FreeCoTaskMem(intptrStruct);
        InternetCloseHandle(hInternet); //

        // Throw an exception if this operation failed.
        if (!bReturn)
        {
            throw new ApplicationException(" Set Internet Option Failed!");
        }

        return bReturn;
    }       

}
c#
proxy
wininet
asked on Stack Overflow Feb 15, 2018 by José Carbonell • edited Feb 15, 2018 by José Carbonell

1 Answer

1

After a long time I found the answer and it was much simpler than it seemed. It was as simple as putting the original function, without username or password, of SetConnectionProxy () and then, in the first navigation, insert the user and password of the proxy in the url: http: // user: password @ url, and I have done like this:

The connection to the proxy first:

public static bool SetConnectionProxy(string proxyServer)

   {

        IntPtr hInternet = InternetOpen(miniYo, INTERNET_OPEN_TYPE_DIRECT, null, null, 0);
        INTERNET_PER_CONN_OPTION[] Options = new INTERNET_PER_CONN_OPTION[2];

        // Set PROXY flags.
        Options[0] = new INTERNET_PER_CONN_OPTION();
        Options[0].dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_FLAGS;
        Options[0].Value.dwValue = (int)INTERNET_OPTION_PER_CONN_FLAGS.PROXY_TYPE_PROXY;

        // Set proxy name.
        Options[1] = new INTERNET_PER_CONN_OPTION();
        Options[1].dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_PROXY_SERVER;
        Options[1].Value.pszValue = Marshal.StringToHGlobalAnsi(proxyServer);

        // Allocate a block of memory of the options.
        System.IntPtr buffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(Options[0]) + Marshal.SizeOf(Options[1]));
        System.IntPtr current = buffer;

        // Marshal data from a managed object to an unmanaged block of memory.
        for (int i = 0; i < Options.Length; i++)
        {
            Marshal.StructureToPtr(Options[i], current, false);
            current = (System.IntPtr)((int)current + Marshal.SizeOf(Options[i]));
        }

        // Initialize a INTERNET_PER_CONN_OPTION_LIST instance.
        INTERNET_PER_CONN_OPTION_LIST option_list = new INTERNET_PER_CONN_OPTION_LIST();

        // Point to the allocated memory.
        option_list.pOptions = buffer;

        // Return the unmanaged size of an object in bytes.
        option_list.Size = Marshal.SizeOf(option_list);

        // IntPtr.Zero means LAN connection.
        option_list.Connection = IntPtr.Zero;

        option_list.OptionCount = Options.Length;
        option_list.OptionError = 0;
        int size = Marshal.SizeOf(option_list);

        // Allocate memory for the INTERNET_PER_CONN_OPTION_LIST instance.
        IntPtr intptrStruct = Marshal.AllocCoTaskMem(size);

        // Marshal data from a managed object to an unmanaged block of memory.
        Marshal.StructureToPtr(option_list, intptrStruct, true);

        // Set internet settings.
        bool bReturn = InternetSetOption(hInternet, INTERNET_OPTION.INTERNET_OPTION_PER_CONNECTION_OPTION, intptrStruct, size);

        // Free the allocated memory.
        Marshal.FreeCoTaskMem(buffer);
        Marshal.FreeCoTaskMem(intptrStruct);
        InternetCloseHandle(hInternet); //¿Esto lo cierra?

        // Throw an exception if this operation failed.
        if (!bReturn)
        {
            throw new ApplicationException(" Set Internet Option Failed!");
        }

        return bReturn;
    }

}

The first navigation with the user and the password, after:

UriBuilder uriSite = new UriBuilder(string);
            uriSite.UserName = usuario;
            uriSite.Password = contraseña;
            webBrowser.Navigate(uriSite.Uri);

I regret to say that I did not feel helped by the community

answered on Stack Overflow Feb 20, 2018 by José Carbonell

User contributions licensed under CC BY-SA 3.0