Set proxy username and password using Wininet in C #

This is my first question on Stack Overflow. They helped me a lot with this site.

I am working on an application in C # on .NET 2010. I am trying to set up a system proxy for HTTP requests. A proxy server is a Squid-based proxy server with "basic" authentication enabled. I was able to install IE proxy.

Now that the proxy is installed in IE, IE is asking for the username and password for the proxy, and now I'm trying to automate this functionality, and over the past week I have not been able to get it to work and search the Internet, but still there is no success.

Below is the code that I use to install IE proxy.

public static bool SetProxy(string strProxy, string username, string password, string exceptions) { InternetPerConnOptionList list = new InternetPerConnOptionList(); int optionCount = string.IsNullOrEmpty(strProxy) ? 1 : (string.IsNullOrEmpty(exceptions) ? 2 : 3); InternetConnectionOption[] options = new InternetConnectionOption[optionCount]; // USE a proxy server ... options[0].m_Option = PerConnOption.INTERNET_PER_CONN_FLAGS; options[0].m_Value.m_Int = (int)((optionCount < 2) ? PerConnFlags.PROXY_TYPE_DIRECT : (PerConnFlags.PROXY_TYPE_DIRECT | PerConnFlags.PROXY_TYPE_PROXY)); // use THIS proxy server if (optionCount > 1) { options[1].m_Option = PerConnOption.INTERNET_PER_CONN_PROXY_SERVER; options[1].m_Value.m_StringPtr = Marshal.StringToHGlobalAuto(strProxy); // except for these addresses ... if (optionCount > 2) { options[2].m_Option = PerConnOption.INTERNET_PER_CONN_PROXY_BYPASS; options[2].m_Value.m_StringPtr = Marshal.StringToHGlobalAuto(exceptions); } } // default stuff list.dwSize = Marshal.SizeOf(list); list.szConnection = IntPtr.Zero; list.dwOptionCount = options.Length; list.dwOptionError = 0; int optSize = Marshal.SizeOf(typeof(InternetConnectionOption)); // make a pointer out of all that ... IntPtr optionsPtr = Marshal.AllocCoTaskMem(optSize * options.Length); // copy the array over into that spot in memory ... for (int i = 0; i < options.Length; ++i) { IntPtr opt = new IntPtr(optionsPtr.ToInt32() + (i * optSize)); Marshal.StructureToPtr(options[i], opt, false); } list.options = optionsPtr; // and then make a pointer out of the whole list IntPtr ipcoListPtr = Marshal.AllocCoTaskMem((Int32)list.dwSize); Marshal.StructureToPtr(list, ipcoListPtr, false); // and finally, call the API method! int returnvalue = NativeMethods.InternetSetOption(IntPtr.Zero, InternetOption.INTERNET_OPTION_PER_CONNECTION_OPTION, ipcoListPtr, list.dwSize) ? -1 : 0; if (returnvalue == 0) { // get the error codes, they might be helpful returnvalue = Marshal.GetLastWin32Error(); } // FREE the data ASAP Marshal.FreeCoTaskMem(optionsPtr); Marshal.FreeCoTaskMem(ipcoListPtr); if (returnvalue > 0) { // throw the error codes, they might be helpful throw new Win32Exception(Marshal.GetLastWin32Error()); } return (returnvalue < 0); } } #region WinInet structures [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct InternetPerConnOptionList { public int dwSize; // size of the INTERNET_PER_CONN_OPTION_LIST struct public IntPtr szConnection; // connection name to set/query options public int dwOptionCount; // number of options to set/query public int dwOptionError; // on error, which option failed //[MarshalAs(UnmanagedType.)] public IntPtr options; }; [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct InternetConnectionOption { static readonly int Size; public PerConnOption m_Option; public InternetConnectionOptionValue m_Value; static InternetConnectionOption() { InternetConnectionOption.Size = Marshal.SizeOf(typeof(InternetConnectionOption)); } // Nested Types [StructLayout(LayoutKind.Explicit)] public struct InternetConnectionOptionValue { // Fields [FieldOffset(0)] public System.Runtime.InteropServices.ComTypes.FILETIME m_FileTime; [FieldOffset(0)] public int m_Int; [FieldOffset(0)] public IntPtr m_StringPtr; } } #endregion #region WinInet enums // // options manifests for Internet{Query|Set}Option // public enum InternetOption : uint { INTERNET_OPTION_PER_CONNECTION_OPTION = 75 } // // Options used in INTERNET_PER_CONN_OPTON struct // public enum PerConnOption { INTERNET_PER_CONN_FLAGS = 1, // Sets or retrieves the connection type. The Value member will contain one or more of the values from PerConnFlags INTERNET_PER_CONN_PROXY_SERVER = 2, // Sets or retrieves a string containing the proxy servers. INTERNET_PER_CONN_PROXY_BYPASS = 3, // Sets or retrieves a string containing the URLs that do not use the proxy server. INTERNET_PER_CONN_AUTOCONFIG_URL = 4//, // Sets or retrieves a string containing the URL to the automatic configuration script. } // // PER_CONN_FLAGS // [Flags] public enum PerConnFlags { 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 } #endregion internal static class NativeMethods { [DllImport("WinInet.dll", SetLastError = true, CharSet = CharSet.Auto)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool InternetSetOption(IntPtr hInternet, InternetOption dwOption, IntPtr lpBuffer, int dwBufferLength); } 

Any help in working with this functionality is appreciated.

Sincerely, Mudasir Mirza.

+4
source share
3 answers

When you install proxies for WinINET, there is no way to save a "global" username and password for all clients. You can cache this username / password only for each process. In this process, you can use the InternetSetOption API to provide a username and password. This will set a password only for WinINET, not for .NET or other HTTP stacks.

+1
source

Take a look at the WebProxy class and see if this allows you to do what you want?

use it like this (I'm going to assume that the exceptions are separated by the ';' character):

 public static void SetProxy(string proxyAddress, string userName, string password, string exceptions) { var credential = new NetworkCredential(userName, password); string[] bypassList = null; if (!string.IsNullOrEmpty(exceptions)) { bypassList = exceptions.Split(';'); } WebRequest.DefaultWebProxy = new WebProxy(proxyAddress, true, bypassList, credential); } 

to call the method:

 SetProxy("http://proxy:8080", "user", "password", "http://site1;http://site2"); 
0
source

I had a similar problem with WebBrowser when authenticating and annoying the Windows Security window. First enter the proxy server address using WinINET, and then call the navigation method with your credentials. This helps to store proxy credentials for one process:

 WebBrowser.Navigate("http://user: pass@geoip.hidemyass.com /"); 

The WinINET method sets the proxy address to perfect, however your code uses INTERNET_OPTION_PER_CONNECTION_OPTION , which is not suitable for your idea of ​​a global proxy (as @EricLaw said). Try working with INTERNET_OPTION_PROXY ( documentaion )

In addition, there are four different approaches without a direct solution. But they are very convenient.

0
source

Source: https://habr.com/ru/post/1396935/


All Articles