Beispiel #1
0
        private int GetProxiesForUrl(string targetUrl, ref WINHTTP_AUTOPROXY_OPTIONS options, out string proxies)
        {
            // argument checks
            Debug.Assert(string.IsNullOrEmpty(targetUrl) == false);

            int win32Error          = ERROR_SUCCESS;
            WINHTTP_PROXY_INFO info = new WINHTTP_PROXY_INFO();

            // call Win32 WinHttpGetProxyForUrl and convnert the results to managed string
            RuntimeHelpers.PrepareConstrainedRegions();
            try {
                if (WinHttpGetProxyForUrl(this.session, targetUrl, ref options, out info))
                {
                    proxies = Marshal.PtrToStringUni(info.lpszProxy);
                }
                else
                {
                    win32Error = GetLastWin32Error();
                    proxies    = null;
                }
            } finally {
                Marshal.FreeHGlobal(info.lpszProxyBypass);
                Marshal.FreeHGlobal(info.lpszProxy);
            }

            return(win32Error);
        }
Beispiel #2
0
                public Native(WINHTTP_AUTOPROXY_OPTIONS managed)
                {
                    Flags           = managed.Flags;
                    AutoDetectFlags = managed.AutoDetectFlags;
                    AutoConfigUrl   = managed.AutoConfigUrl is not null?Marshal.StringToCoTaskMemUni(managed.AutoConfigUrl) : IntPtr.Zero;

                    Reserved1             = managed.Reserved1;
                    Reserved2             = managed.Reserved2;
                    AutoLoginIfChallenged = managed.AutoLoginIfChallenged ? 1 : 0;
                }
Beispiel #3
0
        private int GetProxiesForUrl(string targetUrl, out string proxies)
        {
            // argument checks
            Debug.Assert(string.IsNullOrEmpty(targetUrl) == false);

            // prepare options
            WINHTTP_AUTOPROXY_OPTIONS options = new WINHTTP_AUTOPROXY_OPTIONS();

            Debug.Assert(options.dwFlags == 0);
            Debug.Assert(options.dwAutoDetectFlags == 0);
            Debug.Assert(options.lpszAutoConfigUrl == null);

            if (this.useAutoDetection)
            {
                // use auto detection
                options.dwFlags          |= WINHTTP_AUTOPROXY_AUTO_DETECT;
                options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
            }

            if (string.IsNullOrEmpty(this.autoConfigUrl) == false)
            {
                // use auto config file
                options.dwFlags          |= WINHTTP_AUTOPROXY_CONFIG_URL;
                options.lpszAutoConfigUrl = this.autoConfigUrl;
            }

            // first, try to get proxies without authentication
            options.fAutoLogonIfChallenged = false;
            int win32Error = GetProxiesForUrl(targetUrl, ref options, out proxies);

            if (win32Error == ERROR_WINHTTP_LOGIN_FAILURE)
            {
                // It seems that you need authentication to download the PAC file.
                // Retry with the auto logon flag.
                // This flag should be used only after the download fails with ERROR_WINHTTP_LOGIN_FAILURE
                // because authentication has a bit of overhead.
                // See https://msdn.microsoft.com/en-us/library/windows/desktop/aa383153.aspx
                options.fAutoLogonIfChallenged = true;
                win32Error = GetProxiesForUrl(targetUrl, ref options, out proxies);
            }
            if (win32Error != ERROR_SUCCESS)
            {
                LogWin32Error("WinHttpGetProxyForUrl");
            }

            return(win32Error);
        }
Beispiel #4
0
 public static extern bool WinHttpGetProxyForUrl(
     IntPtr hSession,
     string lpcwszUrl,
     ref WINHTTP_AUTOPROXY_OPTIONS pAutoProxyOptions,
     ref WINHTTP_PROXY_INFO pProxyInfo);
 public static extern bool WinHttpGetProxyForUrl(
     SafeWinHttpHandle sessionHandle, string url,
     ref WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions,
     out WINHTTP_PROXY_INFO proxyInfo);
Beispiel #6
0
 public static extern bool WinHttpGetProxyForUrl(
     SafeWinHttpHandle sessionHandle, string url,
     ref WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions,
     out WINHTTP_PROXY_INFO proxyInfo);
Beispiel #7
0
 static extern bool WinHttpGetProxyForUrl( 
     IntPtr hSession,
     string lpcwszUrl,
     ref WINHTTP_AUTOPROXY_OPTIONS pAutoProxyOptions,
     ref WINHTTP_PROXY_INFO pProxyInfo
     );
Beispiel #8
0
        // Determine dynamic proxy url, either automagically, or by downloading and running specified script
        static IWebProxy DetermineAutoProxyForUrl(string targetUrl, string proxyScriptUrl, ref int errorCode)
        {
            if(hSession == IntPtr.Zero)
            {
                OpenWinHttpSession();
            }

            WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions = new WINHTTP_AUTOPROXY_OPTIONS();
            WINHTTP_PROXY_INFO proxyInfo = new WINHTTP_PROXY_INFO();
            proxyInfo.pwszProxy = proxyInfo.pwszProxyBypass = IntPtr.Zero;

            if (!String.IsNullOrEmpty(proxyScriptUrl))
            {
                // The proxy script URL is already known.
                // Therefore, auto-detection is not required.
                autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;

                // Set the proxy auto configuration URL.
                autoProxyOptions.lpszAutoConfigUrl = proxyScriptUrl;
                autoProxyOptions.dwAutoDetectFlags = 0;
            }
            else
            {  // must determine location of script
                autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
                autoProxyOptions.dwAutoDetectFlags = (WINHTTP_AUTO_DETECT_TYPE_DHCP|WINHTTP_AUTO_DETECT_TYPE_DNS_A);
            }

            // If obtaining the PAC script requires NTLM/Negotiate
            // authentication, automatically supply the domain credentials of the client.
            autoProxyOptions.fAutoLoginIfChallenged = true;

            //Get proxy
            bool result = WinHttpGetProxyForUrl(hSession, targetUrl, ref autoProxyOptions, ref proxyInfo);

            // that failed - retrieve and safely store last Win32 error
            if(!result)
            {
                errorCode = Marshal.GetLastWin32Error();
            }

            string proxyUrl = "";

            // get returned string, if any
            if(proxyInfo.pwszProxy != IntPtr.Zero)
            {
                // get string from IntPtr in structure
                proxyUrl = Marshal.PtrToStringUni(proxyInfo.pwszProxy);
                Marshal.FreeHGlobal(proxyInfo.pwszProxy); // free Win32 string

                // split returned proxies into array
                string [] theUrls = proxyUrl.Split(';');

                // use only first one, get rid of "PROXY " prefix and whitespace
                proxyUrl = theUrls[0].Replace("PROXY ", "").Trim();
            }
            if(proxyInfo.pwszProxyBypass != IntPtr.Zero) Marshal.FreeHGlobal(proxyInfo.pwszProxyBypass);

            return String.IsNullOrEmpty(proxyUrl) ? null : new WebProxy(proxyUrl);
        }
        public Task <WebProxy> CreateProxyAsync(Uri destination)
        {
            var ieProxy = new WINHTTP_CURRENT_USER_IE_PROXY_CONFIG();

            var success = WinHttpGetIEProxyConfigForCurrentUser(out ieProxy);

            if (success && ieProxy.Proxy != IntPtr.Zero)
            {
                var proxyUrl   = Marshal.PtrToStringUni(ieProxy.Proxy);
                var bypassList = Marshal.PtrToStringUni(ieProxy.ProxyBypass)?.Split(';', ' ', '\t', '\r', '\n');
                return(Task.FromResult(new WebProxy(new Uri($"http://{proxyUrl}"), bypassList?.Contains("<local>") ?? false, bypassList)));
            }

            var session = WinHttpOpen(null, WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY, WINHTTP_NO_PROXY_NAME,
                                      WINHTTP_NO_PROXY_BYPASS, 0);

            if (session.IsInvalid)
            {
                WriteLog.To.Sync.W(Tag,
                                   $"Unable to open WinHttp session to query for proxy (error code: {Marshal.GetLastWin32Error()})");
                return(Task.FromResult <WebProxy>(null));
            }

            var options = new WINHTTP_AUTOPROXY_OPTIONS
            {
                AutoConfigUrl         = null,
                AutoDetectFlags       = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A,
                AutoLoginIfChallenged = false,
                Flags     = WINHTTP_AUTOPROXY_AUTO_DETECT,
                Reserved1 = IntPtr.Zero,
                Reserved2 = 0
            };

            var info = new WINHTTP_PROXY_INFO
            {
                AccessType  = 0,
                Proxy       = IntPtr.Zero,
                ProxyBypass = IntPtr.Zero
            };

            success = WinHttpGetProxyForUrl(session, destination.AbsoluteUri, ref options, out info);
            session.Close();
            if (!success)
            {
                var lastErr = Marshal.GetLastWin32Error();
                if (lastErr != ERROR_WINHTTP_AUTODETECTION_FAILED)
                {
                    WriteLog.To.Sync.W(Tag,
                                       $"Call to WinHttpGetProxyForUrl failed (error code: {lastErr})");
                }
                else
                {
                    WriteLog.To.Sync.W(Tag, "Call to WinHttpGetProxyForUrl failed (possible direct connection)...");
                }

                return(Task.FromResult <WebProxy>(null));
            }

            var url    = Marshal.PtrToStringUni(info.Proxy);
            var bypass = Marshal.PtrToStringUni(info.ProxyBypass)?.Split(';', ' ', '\t', '\r', '\n');

            return(Task.FromResult(new WebProxy(new Uri($"http://{url}"), bypass?.Contains("<local>") ?? false, bypass)));
        }
Beispiel #10
0
 public static Native ConvertToUnmanaged(WINHTTP_AUTOPROXY_OPTIONS managed) => new(managed);
Beispiel #11
0
      /// <summary>get the address(s) of proxy servers from Control Panel / Internet Options</summary>
      /// <param name="serverURL">the url of the web-server with which the RC will interact</param>
      private string GetDynamicProxy(string serverURL, NameValueCollection outgoingHeaders)
      {
         var byteArray = new byte[10000];
         var chrArray = new char[20000];
         Encoding encoding = Encoding.UTF8;

         //Open http session
         IntPtr hSession = WinHttpOpen("Test App", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, _winhttpNoProxyName,
                                       _winhttpNoProxyBypass, 0);
         var wao = new WINHTTP_AUTOPROXY_OPTIONS();
         var wpi = new WINHTTP_PROXY_INFO();
         wao.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
         wao.dwAutoDetectFlags = 0;
         wao.fAutoLoginIfChallenged = true;
         // Get the proxy config file (pac).
         wao.lpszAutoConfigUrl =
            (String)
            Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\Currentversion\\Internet Settings").GetValue(
               "AutoConfigURL");
         wao.dwAutoDetectFlags = (WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A);

         if (wao.lpszAutoConfigUrl != null)
            wao.lpszAutoConfigUrl = wao.lpszAutoConfigUrl.Trim();

         bool result = WinHttpGetProxyForUrl(hSession, serverURL, ref wao, ref wpi);

         // If we didn't succeed to read the pac file maybe its an ins file
         if (!result && !string.IsNullOrEmpty(wao.lpszAutoConfigUrl))
         {
            try
            {
               int usedLen;
               int charLen = 0;
               Decoder decoder = encoding.GetDecoder();

               // Get the content of the file
               var requesterURLCon = (HttpWebRequest)WebRequest.Create(wao.lpszAutoConfigUrl);
               requesterURLCon.AllowAutoRedirect = true;
               requesterURLCon.Method = "GET";
               requesterURLCon.Credentials = CredentialCache.DefaultCredentials;
               if (outgoingHeaders.Count > 0 && Logger.Instance.LogLevel == Logger.LogLevels.Basic)
                  requesterURLCon.Headers.Add(outgoingHeaders.GetKey(0), outgoingHeaders.GetValues(0)[0]);

               // read the answer
               WebResponse webResponse = requesterURLCon.GetResponse();
               var inpStreamReader = new StreamReader(webResponse.GetResponseStream(), encoding);
               Stream stream = inpStreamReader.BaseStream;
#if !PocketPC
               stream = new BufferedStream(stream);
#endif
               while ((usedLen = stream.Read(byteArray, 0, byteArray.Length)) > 0)
               {
                  // Make sure we have enough space for the growing message
                  if (charLen + usedLen > chrArray.Length)
                  {
                     var newArray = new char[chrArray.Length + 10000];
                     chrArray.CopyTo(newArray, 0);
                     chrArray = newArray;
                  }
                  charLen += decoder.GetChars(byteArray, 0, usedLen, chrArray, charLen);
               }
               var answer = new String(chrArray, 0, charLen);
               Logger.Instance.WriteServerToLog("pac file" + answer);

               // Get the pac file from the correct entry in the ins file
               int startIndex = answer.IndexOf("AutoConfigJSURL");
               Logger.Instance.WriteServerToLog("pac file" + startIndex);
               if (startIndex != -1)
               {
                  int endIndex = answer.IndexOf(".pac", startIndex);
                  Logger.Instance.WriteServerToLog("pac file" + endIndex);
                  string str = answer.Substring(startIndex + 16, endIndex - startIndex - 16 + 4);
                  Logger.Instance.WriteServerToLog("str" + str);
                  wao.lpszAutoConfigUrl = str;
                  WinHttpGetProxyForUrl(hSession, serverURL, ref wao, ref wpi);
               }
            }
            catch (System.Exception ex)
            {
               Logger.Instance.WriteExceptionToLog(ex, string.Format("PAC file \"{0}\" was not found!", wao.lpszAutoConfigUrl));
            }
         }

         //Close http session
         WinHttpCloseHandle(hSession);

         if (wpi.dwAccessType == WINHTTP_ACCESS_TYPE_NO_PROXY)
            return "DIRECT";
         return wpi.lpszProxy;
      }
Beispiel #12
0
        // Determine dynamic proxy url, either automagically, or by downloading and running specified script
        static IWebProxy DetermineAutoProxyForUrl(string targetUrl, string proxyScriptUrl, ref int errorCode)
        {
            if (hSession == IntPtr.Zero)
            {
                OpenWinHttpSession();
            }

            WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions = new WINHTTP_AUTOPROXY_OPTIONS();
            WINHTTP_PROXY_INFO        proxyInfo        = new WINHTTP_PROXY_INFO();

            proxyInfo.pwszProxy = proxyInfo.pwszProxyBypass = IntPtr.Zero;

            if (!IsEmpty(proxyScriptUrl))
            {
                // The proxy script URL is already known.
                // Therefore, auto-detection is not required.
                autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;

                // Set the proxy auto configuration URL.
                autoProxyOptions.lpszAutoConfigUrl = proxyScriptUrl;
                autoProxyOptions.dwAutoDetectFlags = 0;
            }
            else
            {              // must determine location of script
                autoProxyOptions.dwFlags           = WINHTTP_AUTOPROXY_AUTO_DETECT;
                autoProxyOptions.dwAutoDetectFlags = (WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A);
            }

            // If obtaining the PAC script requires NTLM/Negotiate
            // authentication, automatically supply the domain credentials of the client.
            autoProxyOptions.fAutoLoginIfChallenged = true;

            //Get proxy
            bool result = WinHttpGetProxyForUrl(hSession, targetUrl, ref autoProxyOptions, ref proxyInfo);

            // that failed - retrieve and safely store last Win32 error
            if (!result)
            {
                errorCode = Marshal.GetLastWin32Error();
            }

            string proxyUrl = "";

            // get returned string, if any
            if (proxyInfo.pwszProxy != IntPtr.Zero)
            {
                // get string from IntPtr in structure
                proxyUrl = Marshal.PtrToStringUni(proxyInfo.pwszProxy);
                Marshal.FreeHGlobal(proxyInfo.pwszProxy);                 // free Win32 string

                // split returned proxies into array
                string [] theUrls = proxyUrl.Split(';');

                // use only first one, get rid of "PROXY " prefix and whitespace
                proxyUrl = theUrls[0].Replace("PROXY ", "").Trim();
            }
            if (proxyInfo.pwszProxyBypass != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(proxyInfo.pwszProxyBypass);
            }

            return(IsEmpty(proxyUrl) ? null : new WebProxy(proxyUrl));
        }
Beispiel #13
0
 internal static extern bool WinHttpGetProxyForUrl(SafeHINTERNET hSession, string lpcwszUrl, [In] ref WINHTTP_AUTOPROXY_OPTIONS pAutoProxyOptions, out WINHTTP_PROXY_INFO pProxyInfo);
 internal static extern bool WinHttpGetProxyForUrl(WinHttpHandle session, string url, [In] ref WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions,
                                                   out WINHTTP_PROXY_INFO proxyInfo);
Beispiel #15
0
 // TODO: [DllImportGenerator] Switch to use GeneratedDllImport once we support non-blittable structs.
 [return: MarshalAs(UnmanagedType.Bool)]public static extern bool WinHttpGetProxyForUrl(
     SafeWinHttpHandle? sessionHandle,
     string url,
     ref WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions,
     out WINHTTP_PROXY_INFO proxyInfo);