Example #1
0
Proxy* WinHttpIO::getautoproxy()
{
    Proxy* proxy = new Proxy();
    proxy->setProxyType(Proxy::NONE);

    WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieProxyConfig = { 0 };

    if (WinHttpGetIEProxyConfigForCurrentUser(&ieProxyConfig) == TRUE)
    {
        if (ieProxyConfig.lpszProxy)
        {
            string proxyURL;
            proxy->setProxyType(Proxy::CUSTOM);
            int len = wcslen(ieProxyConfig.lpszProxy);
            proxyURL.assign((const char*)ieProxyConfig.lpszProxy, len * sizeof(wchar_t) + 1);

            // only save one proxy
            for (int i = 0; i < len; i++)
            {
                wchar_t* character = (wchar_t*)(proxyURL.data() + i * sizeof(wchar_t));

                if (*character == ' ' || *character == ';')
                {
                    proxyURL.resize(i*sizeof(wchar_t));
                    len = i;
                    break;
                }
            }

            // remove protocol prefix, if any
            for (int i = len - 1; i >= 0; i--)
            {
                wchar_t* character = (wchar_t*)(proxyURL.data() + i * sizeof(wchar_t));

                if (*character == '/')
                {
                    proxyURL = proxyURL.substr((i + 1) * sizeof(wchar_t));
                    break;
                }
            }

            proxy->setProxyURL(&proxyURL);
        }
        else if (ieProxyConfig.lpszAutoConfigUrl || ieProxyConfig.fAutoDetect == TRUE)
        {
            WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions;

            if (ieProxyConfig.lpszAutoConfigUrl)
            {
                autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
                autoProxyOptions.lpszAutoConfigUrl = ieProxyConfig.lpszAutoConfigUrl;
                autoProxyOptions.dwAutoDetectFlags = 0;
            }
            else
            {
                autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
                autoProxyOptions.lpszAutoConfigUrl = NULL;
                autoProxyOptions.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
            }

            autoProxyOptions.fAutoLogonIfChallenged = TRUE;
            autoProxyOptions.lpvReserved = NULL;
            autoProxyOptions.dwReserved = 0;

            WINHTTP_PROXY_INFO proxyInfo;

            if (WinHttpGetProxyForUrl(hSession, L"https://g.api.mega.co.nz/", &autoProxyOptions, &proxyInfo))
            {
                if (proxyInfo.lpszProxy)
                {
                    string proxyURL;
                    proxy->setProxyType(Proxy::CUSTOM);
                    proxyURL.assign((const char*)proxyInfo.lpszProxy, wcslen(proxyInfo.lpszProxy) * sizeof(wchar_t));
                    proxy->setProxyURL(&proxyURL);
                }
            }
        }
    }

    if (ieProxyConfig.lpszProxy)
    {
        GlobalFree(ieProxyConfig.lpszProxy);
    }

    if (ieProxyConfig.lpszProxyBypass)
    {
        GlobalFree(ieProxyConfig.lpszProxyBypass);
    }

    if (ieProxyConfig.lpszAutoConfigUrl)
    {
        GlobalFree(ieProxyConfig.lpszAutoConfigUrl);
    }

    return proxy;
}
/*!
 * @brief Prepare a winHTTP request with the given context.
 * @param ctx Pointer to the HTTP transport context to prepare the request from.
 * @param isGet Indication of whether this request is a GET request, otherwise POST is used.
 * @param direction String representing the direction of the communications (for debug).
 * @return An Internet request handle.
 */
static HINTERNET get_request_winhttp(HttpTransportContext *ctx, BOOL isGet, const char *direction)
{
	HINTERNET hReq = NULL;
	DWORD flags = WINHTTP_FLAG_BYPASS_PROXY_CACHE;

	if (ctx->ssl)
	{
		flags |= WINHTTP_FLAG_SECURE;
		dprintf("[%s] Setting secure flag..", direction);
	}

	vdprintf("[%s] opening request on connection %x to %S", direction, ctx->connection, ctx->uri);
	hReq = WinHttpOpenRequest(ctx->connection, isGet ? L"GET" : L"POST", ctx->uri, NULL, NULL, NULL, flags);

	if (hReq == NULL)
	{
		dprintf("[%s] Failed WinHttpOpenRequest: %u", direction, GetLastError());
		SetLastError(ERROR_NOT_FOUND);
		return NULL;
	}

	// if no proxy is set, we should look to see if we can (and should) use the system
	// proxy settings for the given user.
	if (!ctx->proxy)
	{
		if (!ctx->proxy_configured)
		{
			WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieConfig = { 0 };
			if (WinHttpGetIEProxyConfigForCurrentUser(&ieConfig))
			{
				dprintf("[PROXY] Got IE configuration");
				dprintf("[PROXY] AutoDetect: %s", ieConfig.fAutoDetect ? "yes" : "no");
				dprintf("[PROXY] Auto URL: %S", ieConfig.lpszAutoConfigUrl);
				dprintf("[PROXY] Proxy: %S", ieConfig.lpszProxy);
				dprintf("[PROXY] Proxy Bypass: %S", ieConfig.lpszProxyBypass);

				if (ieConfig.lpszAutoConfigUrl || ieConfig.fAutoDetect)
				{
					WINHTTP_AUTOPROXY_OPTIONS autoProxyOpts = { 0 };
					WINHTTP_PROXY_INFO proxyInfo = { 0 };

					if (ieConfig.fAutoDetect)
					{
						dprintf("[PROXY] IE config set to autodetect with DNS or DHCP");

						autoProxyOpts.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
						autoProxyOpts.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
						autoProxyOpts.lpszAutoConfigUrl = 0;
					}
					else if (ieConfig.lpszAutoConfigUrl)
					{
						dprintf("[PROXY] IE config set to autodetect with URL %S", ieConfig.lpszAutoConfigUrl);

						autoProxyOpts.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
						autoProxyOpts.dwAutoDetectFlags = 0;
						autoProxyOpts.lpszAutoConfigUrl = ieConfig.lpszAutoConfigUrl;
					}
					autoProxyOpts.fAutoLogonIfChallenged = TRUE;

					if (WinHttpGetProxyForUrl(ctx->internet, ctx->url, &autoProxyOpts, &proxyInfo))
					{
						ctx->proxy_for_url = malloc(sizeof(WINHTTP_PROXY_INFO));
						memcpy(ctx->proxy_for_url, &proxyInfo, sizeof(WINHTTP_PROXY_INFO));
					}
				}
				else if (ieConfig.lpszProxy)
				{
					WINHTTP_PROXY_INFO* proxyInfo = (WINHTTP_PROXY_INFO*)calloc(1, sizeof(WINHTTP_PROXY_INFO));
					ctx->proxy_for_url = proxyInfo;

					dprintf("[PROXY] IE config set to proxy %S with bypass %S", ieConfig.lpszProxy, ieConfig.lpszProxyBypass);

					proxyInfo->dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
					proxyInfo->lpszProxy = ieConfig.lpszProxy;
					proxyInfo->lpszProxyBypass = ieConfig.lpszProxyBypass;

					// stop the cleanup code from removing these as we're using them behind the scenes and they will
					// be freed later instead.
					ieConfig.lpszProxy = NULL;
					ieConfig.lpszProxyBypass = NULL;;
				}

				if (ieConfig.lpszAutoConfigUrl)
				{
					GlobalFree(ieConfig.lpszAutoConfigUrl);
				}
				if (ieConfig.lpszProxy)
				{
					GlobalFree(ieConfig.lpszProxy);
				}
				if (ieConfig.lpszProxyBypass)
				{
					GlobalFree(ieConfig.lpszProxyBypass);
				}
			}

			// mark as "configured" so we don't attempt to do this horrible PoS mess again.
			ctx->proxy_configured = TRUE;
		}

		if (ctx->proxy_for_url &&
			!WinHttpSetOption(hReq, WINHTTP_OPTION_PROXY, ctx->proxy_for_url, sizeof(WINHTTP_PROXY_INFO)))
		{
			dprintf("[%s] Unable to set proxy options: %u", GetLastError());
		}
	}
	else
	{
		if (ctx->proxy_user)
		{
			dprintf("[%s] Setting proxy username to %S", direction, ctx->proxy_user);
			if (!WinHttpSetOption(hReq, WINHTTP_OPTION_PROXY_USERNAME, ctx->proxy_user, (DWORD)(wcslen(ctx->proxy_user))));
			{
				dprintf("[%s] Failed to set username %u", direction, GetLastError());
			}
		}
		if (ctx->proxy_pass)
		{
			dprintf("[%s] Setting proxy password to %S", direction, ctx->proxy_pass);
			if (!WinHttpSetOption(hReq, WINHTTP_OPTION_PROXY_PASSWORD, ctx->proxy_pass, (DWORD)(wcslen(ctx->proxy_pass))));
			{
				dprintf("[%s] Failed to set password %u", direction, GetLastError());
			}
		}
	}

	if (ctx->ssl)
	{
		flags = SECURITY_FLAG_IGNORE_UNKNOWN_CA
			| SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
			| SECURITY_FLAG_IGNORE_CERT_CN_INVALID
			| SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE;
		if (!WinHttpSetOption(hReq, WINHTTP_OPTION_SECURITY_FLAGS, &flags, sizeof(flags)))
		{
			dprintf("[%s] failed to set the security flags on the request", direction);
		}
	}

	return hReq;
}
DWORD
ProxyResolver::GetProxyForAutoSettings(
    _In_ HINTERNET hSession,
    _In_z_ PCWSTR pwszUrl,
    _In_opt_z_ PCWSTR pwszAutoConfigUrl,
    _Outptr_result_maybenull_ PWSTR *ppwszProxy,
    _Outptr_result_maybenull_ PWSTR *ppwszProxyBypass
)
/*++

Routine Description:

    Uses Auto detection or AutoConfigURL to run WinHttpGetProxyForUrl.

    Additionally provides autologon by calling once without autologon, which is
    most performant, and then with autologon if logon fails.

Arguments:

    hSession - The WinHttp session to use for the proxy resolution.

    pwszUrl - The URL to get the proxy for.

    pwszAutoConfig - The autoconfig URL or NULL for Autodetection.

    ppwszProxy - Upon success, the proxy string found for pwszUrl or NULL if
                 no proxy should be used for this URL.
                 Use GlobalFree to free.

    ppwszProxyBypass - Upon success, the proxy bypass string found for pwszUrl
                       or NULL if there is no proxy bypass for the
                       configuration type.
                       Use GlobalFree to free.
Return Value:

    WIN32 Error codes.  The caller should use IsRecoverableAutoProxyError to
        decide whether execution can continue.

--*/
{
    DWORD dwError = ERROR_SUCCESS;
    WINHTTP_AUTOPROXY_OPTIONS waoOptions = {};
    WINHTTP_PROXY_INFO wpiProxyInfo = {};

    *ppwszProxy = NULL;
    *ppwszProxyBypass = NULL;

    if (pwszAutoConfigUrl)
    {
        waoOptions.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
        waoOptions.lpszAutoConfigUrl = pwszAutoConfigUrl;
    }
    else
    {
        waoOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
        waoOptions.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
    }

    //
    // First call with no autologon.  Autologon prevents the
    // session (in proc) or autoproxy service (out of proc) from caching
    // the proxy script.  This causes repetitive network traffic, so it is
    // best not to do autologon unless it is required according to the
    // result of WinHttpGetProxyForUrl.
    // This applies to both WinHttpGetProxyForUrl and WinhttpGetProxyForUrlEx.
    //

    if (m_fExtendedAPI)
    {
        m_hEvent = CreateEventEx(NULL,
                                 NULL,
                                 0,
                                 EVENT_ALL_ACCESS);
        if (m_hEvent == NULL)
        {
            dwError = GetLastError();
            goto quit;
        }

        dwError = GetProxyForUrlEx(hSession,
                                   pwszUrl,
                                   &waoOptions);

        if (dwError != ERROR_WINHTTP_LOGIN_FAILURE)
        {
            //
            // Unless we need to retry with auto-logon exit the function with the
            // result, on success the proxy list will be stored in m_wprProxyResult
            // by GetProxyCallBack.
            //

            goto quit;
        }

        //
        // Enable autologon if challenged.
        //

        waoOptions.fAutoLogonIfChallenged = TRUE;
        dwError = GetProxyForUrlEx(hSession,
                                   pwszUrl,
                                   &waoOptions);

        goto quit;
    }

    if (!WinHttpGetProxyForUrl(hSession,
                               pwszUrl,
                               &waoOptions,
                               &wpiProxyInfo))
    {
        dwError = GetLastError();

        if (dwError != ERROR_WINHTTP_LOGIN_FAILURE)
        {
            goto quit;
        }

        //
        // Enable autologon if challenged.
        //

        dwError = ERROR_SUCCESS;
        waoOptions.fAutoLogonIfChallenged = TRUE;
        if (!WinHttpGetProxyForUrl(hSession,
                                   pwszUrl,
                                   &waoOptions,
                                   &wpiProxyInfo))
        {
            dwError = GetLastError();
            goto quit;
        }
    }

    *ppwszProxy = wpiProxyInfo.lpszProxy;
    wpiProxyInfo.lpszProxy = NULL;

    *ppwszProxyBypass = wpiProxyInfo.lpszProxyBypass;
    wpiProxyInfo.lpszProxyBypass = NULL;

quit:

    if (wpiProxyInfo.lpszProxy)
    {
        GlobalFree(wpiProxyInfo.lpszProxy);
        wpiProxyInfo.lpszProxy = NULL;
    }

    if (wpiProxyInfo.lpszProxyBypass)
    {
        GlobalFree(wpiProxyInfo.lpszProxyBypass);
        wpiProxyInfo.lpszProxyBypass = NULL;
    }

    return dwError;
}
Example #4
0
// Detect any proxy configuration settings automatically.
//
static void windows_detect_autoproxy_settings() {
    if (log_flags.proxy_debug) {
        post_sysmon_msg("[proxy] automatic proxy check in progress");
    }

    HINTERNET                 hWinHttp = NULL;
    WINHTTP_AUTOPROXY_OPTIONS autoproxy_options;
    WINHTTP_PROXY_INFO        proxy_info;
    PARSED_URL purl;
    std::wstring              network_test_url;
    size_t                    pos;


    memset(&autoproxy_options, 0, sizeof(autoproxy_options));
    memset(&proxy_info, 0, sizeof(proxy_info));

    autoproxy_options.dwFlags =
        WINHTTP_AUTOPROXY_AUTO_DETECT;
    autoproxy_options.dwAutoDetectFlags =
        WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
    autoproxy_options.fAutoLogonIfChallenged = TRUE;

    network_test_url = boinc_ascii_to_wide(nvc_config.network_test_url).c_str();

    hWinHttp = WinHttpOpen(
        L"BOINC client",
        WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
        WINHTTP_NO_PROXY_NAME,
        WINHTTP_NO_PROXY_BYPASS,
        NULL
    );

    char msg[1024], buf[1024];
    safe_strcpy(msg, "[proxy] ");

    if (WinHttpGetProxyForUrl(hWinHttp, network_test_url.c_str(), &autoproxy_options, &proxy_info)) {

        // Apparently there are some conditions where WinHttpGetProxyForUrl can return
        //   success but where proxy_info.lpszProxy is null.  Maybe related to UPNP?
        //
        // For the time being check to see if proxy_info.lpszProxy is non-null.
        //
        if (proxy_info.lpszProxy) {
            std::string proxy(boinc_wide_to_ascii(std::wstring(proxy_info.lpszProxy)));
            std::string new_proxy;

            if (log_flags.proxy_debug) {
                safe_strcat(msg, "proxy list: ");
                safe_strcat(msg, proxy.c_str());
            }

            if (!proxy.empty()) {
                // Trim string if more than one proxy is defined
                // proxy list is defined as:
                //   ([<scheme>=][<scheme>"://"]<server>[":"<port>])

                // Find and erase first delimeter type.
                pos = proxy.find(';');
                if (pos != -1 ) {
                    new_proxy = proxy.erase(pos);
                    proxy = new_proxy;
                }

                // Find and erase second delimeter type.
                pos = proxy.find(' ');
                if (pos != -1 ) {
                    new_proxy = proxy.erase(pos);
                    proxy = new_proxy;
                }

                // Parse the remaining url
                parse_url(proxy.c_str(), purl);

                // Store the results for future use.
                if (0 != strcmp(working_proxy_info.autodetect_server_name, purl.host)) {
                    // Reset clients connection error detection path
                    net_status.need_physical_connection = false;

                    working_proxy_info.autodetect_protocol = purl.protocol;
                    safe_strcpy(working_proxy_info.autodetect_server_name, purl.host);
                    working_proxy_info.autodetect_port = purl.port;
                }

                if (log_flags.proxy_debug) {
                    snprintf(buf, sizeof(buf), "proxy detected %s:%d", purl.host, purl.port);
                    safe_strcat(msg, buf);
                }
            }
        }

        // Clean up
        if (proxy_info.lpszProxy) GlobalFree(proxy_info.lpszProxy);
        if (proxy_info.lpszProxyBypass) GlobalFree(proxy_info.lpszProxyBypass);
    } else {
        // We can get here if the user is switching from a network that
        // requires a proxy to one that does not require a proxy.
        working_proxy_info.autodetect_protocol = 0;
        safe_strcpy(working_proxy_info.autodetect_server_name, "");
        working_proxy_info.autodetect_port = 0;
        if (log_flags.proxy_debug) {
            safe_strcat(msg, "no automatic proxy detected");
        }
    }
    if (hWinHttp) WinHttpCloseHandle(hWinHttp);
    if (log_flags.proxy_debug) {
        post_sysmon_msg(msg);
    }
}
    /* "c:\src\ip\pymfc\pymfclib\_pymfclib_winhttp.pyx":95 */
    ((struct __pyx_obj_17_pymfclib_winhttp_WinHTTPSession *)__pyx_v_self)->hInternet = NULL;
    goto __pyx_L2;
  }
  __pyx_L2:;

  Py_DECREF(__pyx_v_self);
}

static PyObject *__pyx_f_17_pymfclib_winhttp_14WinHTTPSession_getProxyForUrl(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyObject *__pyx_f_17_pymfclib_winhttp_14WinHTTPSession_getProxyForUrl(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_url = 0;
  PyObject *__pyx_v_configurl = 0;
  WINHTTP_AUTOPROXY_OPTIONS __pyx_v_autoopt;
  WINHTTP_PROXY_INFO __pyx_v_proxyinfo;
  struct __pyx_obj_17_pymfclib_winhttp_ProxyInfo *__pyx_v_ret;
  PyObject *__pyx_r;
  int __pyx_1;
  __pyx_t_17_pymfclib_winhttp_PYMFC_WCHAR *__pyx_2;
  BOOL __pyx_3;
  PyObject *__pyx_4 = 0;
  static char *__pyx_argnames[] = {"url","configurl",0};
  if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "OO", __pyx_argnames, &__pyx_v_url, &__pyx_v_configurl)) return 0;
  Py_INCREF(__pyx_v_self);
  Py_INCREF(__pyx_v_url);
  Py_INCREF(__pyx_v_configurl);
  __pyx_v_ret = ((struct __pyx_obj_17_pymfclib_winhttp_ProxyInfo *)Py_None); Py_INCREF(Py_None);

  /* "c:\src\ip\pymfc\pymfclib\_pymfclib_winhttp.pyx":102 */
  memset((&__pyx_v_autoopt),0,(sizeof(__pyx_v_autoopt)));

  /* "c:\src\ip\pymfc\pymfclib\_pymfclib_winhttp.pyx":103 */
  memset((&__pyx_v_proxyinfo),0,(sizeof(__pyx_v_proxyinfo)));

  /* "c:\src\ip\pymfc\pymfclib\_pymfclib_winhttp.pyx":105 */
  __pyx_1 = PyObject_IsTrue(__pyx_v_configurl); if (__pyx_1 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; goto __pyx_L1;}
  if (__pyx_1) {

    /* "c:\src\ip\pymfc\pymfclib\_pymfclib_winhttp.pyx":106 */
    __pyx_v_autoopt.dwFlags = (WINHTTP_AUTOPROXY_AUTO_DETECT | WINHTTP_AUTOPROXY_CONFIG_URL);

    /* "c:\src\ip\pymfc\pymfclib\_pymfclib_winhttp.pyx":107 */
    __pyx_2 = PyUnicode_AsUnicode(__pyx_v_configurl); if (__pyx_2 == NULL) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; goto __pyx_L1;}
    __pyx_v_autoopt.lpszAutoConfigUrl = __pyx_2;
    goto __pyx_L2;
  }
  /*else*/ {
    __pyx_v_autoopt.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
  }
  __pyx_L2:;

  /* "c:\src\ip\pymfc\pymfclib\_pymfclib_winhttp.pyx":111 */
  __pyx_v_autoopt.dwAutoDetectFlags = (WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A);

  /* "c:\src\ip\pymfc\pymfclib\_pymfclib_winhttp.pyx":112 */
  __pyx_v_autoopt.fAutoLogonIfChallenged = 1;

  /* "c:\src\ip\pymfc\pymfclib\_pymfclib_winhttp.pyx":114 */
  __pyx_2 = PyUnicode_AsUnicode(__pyx_v_url); if (__pyx_2 == NULL) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; goto __pyx_L1;}
  __pyx_3 = WinHttpGetProxyForUrl(((struct __pyx_obj_17_pymfclib_winhttp_WinHTTPSession *)__pyx_v_self)->hInternet,__pyx_2,(&__pyx_v_autoopt),(&__pyx_v_proxyinfo));
  if (__pyx_3) {

    /* "c:\src\ip\pymfc\pymfclib\_pymfclib_winhttp.pyx":115 */
    __pyx_4 = PyObject_CallObject(((PyObject *)__pyx_ptype_17_pymfclib_winhttp_ProxyInfo), 0); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; goto __pyx_L1;}
    Py_DECREF(((PyObject *)__pyx_v_ret));
    __pyx_v_ret = ((struct __pyx_obj_17_pymfclib_winhttp_ProxyInfo *)__pyx_4);
    __pyx_4 = 0;

    /* "c:\src\ip\pymfc\pymfclib\_pymfclib_winhttp.pyx":116 */
    __pyx_4 = PyInt_FromLong((__pyx_v_proxyinfo.dwAccessType == WINHTTP_ACCESS_TYPE_NO_PROXY)); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; goto __pyx_L1;}
    Py_DECREF(__pyx_v_ret->noproxy);
    __pyx_v_ret->noproxy = __pyx_4;
    __pyx_4 = 0;

    /* "c:\src\ip\pymfc\pymfclib\_pymfclib_winhttp.pyx":118 */
    /*try:*/ {

      /* "c:\src\ip\pymfc\pymfclib\_pymfclib_winhttp.pyx":119 */
      __pyx_1 = (__pyx_v_proxyinfo.lpszProxy != 0);
      if (__pyx_1) {
        __pyx_4 = _fromWideChar(__pyx_v_proxyinfo.lpszProxy); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; goto __pyx_L5;}
        Py_DECREF(__pyx_v_ret->proxy);
        __pyx_v_ret->proxy = __pyx_4;
        __pyx_4 = 0;
        goto __pyx_L7;
      }
      __pyx_L7:;

      /* "c:\src\ip\pymfc\pymfclib\_pymfclib_winhttp.pyx":121 */
      __pyx_1 = (__pyx_v_proxyinfo.lpszProxyBypass != 0);
      if (__pyx_1) {
        __pyx_4 = _fromWideChar(__pyx_v_proxyinfo.lpszProxyBypass); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 122; goto __pyx_L5;}
        Py_DECREF(__pyx_v_ret->proxybypass);
        __pyx_v_ret->proxybypass = __pyx_4;
        __pyx_4 = 0;
        goto __pyx_L8;
      }
      __pyx_L8:;
    }
    /*finally:*/ {
      int __pyx_why;
      PyObject *__pyx_exc_type, *__pyx_exc_value, *__pyx_exc_tb;
      int __pyx_exc_lineno;
      __pyx_why = 0; goto __pyx_L6;
      __pyx_L5: {
        __pyx_why = 4;
        Py_XDECREF(__pyx_4); __pyx_4 = 0;
        PyErr_Fetch(&__pyx_exc_type, &__pyx_exc_value, &__pyx_exc_tb);
        __pyx_exc_lineno = __pyx_lineno;
        goto __pyx_L6;
      }
      __pyx_L6:;

      /* "c:\src\ip\pymfc\pymfclib\_pymfclib_winhttp.pyx":124 */
      __pyx_1 = (__pyx_v_proxyinfo.lpszProxy != 0);
      if (__pyx_1) {
        GlobalFree(__pyx_v_proxyinfo.lpszProxy);
        goto __pyx_L10;
      }
      __pyx_L10:;

      /* "c:\src\ip\pymfc\pymfclib\_pymfclib_winhttp.pyx":126 */
      __pyx_1 = (__pyx_v_proxyinfo.lpszProxyBypass != 0);
      if (__pyx_1) {
        GlobalFree(__pyx_v_proxyinfo.lpszProxyBypass);
        goto __pyx_L11;
      }
      __pyx_L11:;
      switch (__pyx_why) {
        case 4: {
          PyErr_Restore(__pyx_exc_type, __pyx_exc_value, __pyx_exc_tb);
          __pyx_lineno = __pyx_exc_lineno;
          __pyx_exc_type = 0;
          __pyx_exc_value = 0;
          __pyx_exc_tb = 0;
          goto __pyx_L1;
        }
      }
    }

    /* "c:\src\ip\pymfc\pymfclib\_pymfclib_winhttp.pyx":128 */
    Py_INCREF(((PyObject *)__pyx_v_ret));
    __pyx_r = ((PyObject *)__pyx_v_ret);
    goto __pyx_L0;
    goto __pyx_L3;
  }
  __pyx_L3:;

  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1:;
  Py_XDECREF(__pyx_4);
  __Pyx_AddTraceback("_pymfclib_winhttp.WinHTTPSession.getProxyForUrl");
  __pyx_r = 0;
  __pyx_L0:;
  Py_DECREF(__pyx_v_ret);
  Py_DECREF(__pyx_v_self);
  Py_DECREF(__pyx_v_url);
  Py_DECREF(__pyx_v_configurl);
  return __pyx_r;
}
Example #6
0
	// This method will return true if we should keep attempting to use a proxy
	// or false if the auto proxy determination was to use a direct connection.
	static bool GetAutoProxiesForURL(string& url, vector<SharedProxy>& proxies)
	{
		bool shouldUseProxy = true;
		WINHTTP_PROXY_INFO autoProxyInfo;
		ZeroMemory(&autoProxyInfo, sizeof(WINHTTP_PROXY_INFO)); 
		
		WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions;
		ZeroMemory(&autoProxyOptions, sizeof(WINHTTP_AUTOPROXY_OPTIONS)); 
		
		// This type of auto-detection might take several seconds, so
		// if the user specified  an autoconfiguration URL don't do it.
		// TODO: Maybe we should use this as a fallback later, but it's *very* expensive.
		if (autoConfigURL.empty() && useProxyAutoConfig)
		{
			autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
			autoProxyOptions.dwAutoDetectFlags = 
				WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
		}

		if (!autoConfigURL.empty())
		{
			autoProxyOptions.dwFlags |= WINHTTP_AUTOPROXY_CONFIG_URL;
			autoProxyOptions.lpszAutoConfigUrl = autoConfigURL.c_str();
		}
		
		// From Chromium:
		// Per http://msdn.microsoft.com/en-us/library/aa383153(VS.85).aspx, it is
		// necessary to first try resolving with fAutoLogonIfChallenged set to false.
		// Otherwise, we fail over to trying it with a value of true.  This way we
		// get good performance in the case where WinHTTP uses an out-of-process
		// resolver.  This is important for Vista and Win2k3.
		wstring wideURL = UTF8ToWide(url);
		autoProxyOptions.fAutoLogonIfChallenged = FALSE;
		BOOL ok = WinHttpGetProxyForUrl(
			httpSession.GetHandle(), wideURL.c_str(), &autoProxyOptions, &autoProxyInfo);

		if (!ok && ERROR_WINHTTP_LOGIN_FAILURE == GetLastError())
		{
			autoProxyOptions.fAutoLogonIfChallenged = TRUE;
			ok = WinHttpGetProxyForUrl(
				httpSession.GetHandle(), wideURL.c_str(), &autoProxyOptions, &autoProxyInfo);
		}
		
		if (ok && autoProxyInfo.dwAccessType == WINHTTP_ACCESS_TYPE_NAMED_PROXY &&
			 autoProxyInfo.lpszProxy)
		{
			// Only the first proxy in the list will get a copy of the bypass list.
			std::string bypassList;
			if (autoProxyInfo.lpszProxyBypass)
			{
				std::wstring bypassW = autoProxyInfo.lpszProxyBypass;
				bypassList = string(bypassW.begin(), bypassW.end());
			}

			std::wstring proxyListW = autoProxyInfo.lpszProxy;
			string proxyList = string(proxyListW.begin(), proxyListW.end());
			ParseProxyList(proxyList, bypassList, proxies);
		}
		else if (ok && autoProxyInfo.dwAccessType == WINHTTP_ACCESS_TYPE_NO_PROXY)
		{
			// The only case in which we do not continue to try using a proxy.
			// In this case the auto proxy setup told us to use a direct connection.
			shouldUseProxy = false;
		}
		else
		{
			// Auto proxy failed, so try another method
			string error = "Could not get proxy for url=";
			error.append(url);
			error.append(": ");
			error.append(ErrorCodeToString(GetLastError()));
			Logger::Get("Proxy")->Error(error);
		}
		
		// Always cleanup
		if (autoProxyInfo.lpszProxy)
			GlobalFree(autoProxyInfo.lpszProxy);
		if (autoProxyInfo.lpszProxyBypass)
			GlobalFree(autoProxyInfo.lpszProxyBypass);
		
		return shouldUseProxy;
	}
// Main entry point
int __cdecl wmain()
{
    
    HRESULT hr = S_OK;
    WS_ERROR* error = NULL;
    WS_SERVICE_PROXY* serviceProxy = NULL;
    WS_HEAP* heap = NULL;
    WS_ENDPOINT_ADDRESS address = {};
    static const WS_STRING serviceUrl = WS_STRING_VALUE(L"http://terraservice.net/TerraService2.asmx");
    WS_CHANNEL_PROPERTY channelPropertyArray[4];
    WS_ADDRESSING_VERSION addressingVersion = WS_ADDRESSING_VERSION_TRANSPORT;
    WS_ENVELOPE_VERSION envelopeVersion = WS_ENVELOPE_VERSION_SOAP_1_1;
    WCHAR* place = NULL;
    WS_HTTP_PROXY_SETTING_MODE proxySettingMode = WS_HTTP_PROXY_SETTING_MODE_CUSTOM;
    WS_CUSTOM_HTTP_PROXY customProxy = {};
    address.url = serviceUrl;
    WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions = {};
    WINHTTP_PROXY_INFO proxyInfo = {};
    HINTERNET session = NULL;
    
    channelPropertyArray[0].id = WS_CHANNEL_PROPERTY_ADDRESSING_VERSION;
    channelPropertyArray[0].value = &addressingVersion;
    channelPropertyArray[0].valueSize = sizeof(addressingVersion);
    
    channelPropertyArray[1].id = WS_CHANNEL_PROPERTY_ENVELOPE_VERSION;
    channelPropertyArray[1].value = &envelopeVersion;
    channelPropertyArray[1].valueSize = sizeof(envelopeVersion);
    
    channelPropertyArray[2].id = WS_CHANNEL_PROPERTY_HTTP_PROXY_SETTING_MODE;
    channelPropertyArray[2].value = &proxySettingMode;
    channelPropertyArray[2].valueSize = sizeof(proxySettingMode);
    
    channelPropertyArray[3].id = WS_CHANNEL_PROPERTY_CUSTOM_HTTP_PROXY;
    channelPropertyArray[3].value = &customProxy;
    channelPropertyArray[3].valueSize = sizeof(customProxy);
    
    
    // This part illustrates how to setup a HTTP header authentication security binding
    // against the HTTP proxy server in case it requires authentication.
    // declare and initialize a default windows credential
    WS_STRING_WINDOWS_INTEGRATED_AUTH_CREDENTIAL windowsCredential = {}; // zero out the struct
    windowsCredential.credential.credentialType = WS_STRING_WINDOWS_INTEGRATED_AUTH_CREDENTIAL_TYPE; // set the credential type
    // for illustration only; usernames and passwords should never be included in source files
    windowsCredential.username.chars = L"domain\\user";
    windowsCredential.username.length = (ULONG)wcslen(windowsCredential.username.chars);
    windowsCredential.password.chars = L"password";
    windowsCredential.password.length = (ULONG)wcslen(windowsCredential.password.chars);
    
    // declare and initialize properties to set the authentication scheme to Basic
    ULONG scheme = WS_HTTP_HEADER_AUTH_SCHEME_NEGOTIATE;
    ULONG target = WS_HTTP_HEADER_AUTH_TARGET_PROXY;
    WS_SECURITY_BINDING_PROPERTY httpProxyAuthBindingProperties[2] =
    {
        { WS_SECURITY_BINDING_PROPERTY_HTTP_HEADER_AUTH_SCHEME, &scheme, sizeof(scheme) },
        { WS_SECURITY_BINDING_PROPERTY_HTTP_HEADER_AUTH_TARGET, &target, sizeof(target) }
    };
    
    // declare and initialize an HTTP header authentication security binding for the HTTP proxy server
    WS_HTTP_HEADER_AUTH_SECURITY_BINDING httpProxyAuthBinding = {}; // zero out the struct
    httpProxyAuthBinding.binding.bindingType = WS_HTTP_HEADER_AUTH_SECURITY_BINDING_TYPE; // set the binding type
    httpProxyAuthBinding.binding.properties = httpProxyAuthBindingProperties;
    httpProxyAuthBinding.binding.propertyCount = WsCountOf(httpProxyAuthBindingProperties);
    httpProxyAuthBinding.clientCredential = &windowsCredential.credential;
    
    // declare and initialize the array of all security bindings
    WS_SECURITY_BINDING* securityBindings[1] = { &httpProxyAuthBinding.binding };
    
    // declare and initialize the security description
    WS_SECURITY_DESCRIPTION securityDescription = {}; // zero out the struct
    securityDescription.securityBindings = securityBindings;
    securityDescription.securityBindingCount = WsCountOf(securityBindings);
    
    // Create an error object for storing rich error information
    hr = WsCreateError(
        NULL, 
        0, 
        &error);
    if (FAILED(hr))
    {
        goto Exit;
    }
    // Create a heap to store deserialized data
    hr = WsCreateHeap(
        /*maxSize*/ 2048, 
        /*trimSize*/ 512, 
        NULL, 
        0, 
        &heap, 
        error);
    if (FAILED(hr))
    {
        goto Exit;
    }
    
    
    session = WinHttpOpen(L"NWS Example",
        WINHTTP_ACCESS_TYPE_NO_PROXY,
        WINHTTP_NO_PROXY_NAME,
        WINHTTP_NO_PROXY_BYPASS,
        WINHTTP_FLAG_ASYNC);
    if (!session)
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto Exit;
    }
    autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_RUN_INPROCESS | WINHTTP_AUTOPROXY_AUTO_DETECT;
    autoProxyOptions.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
    autoProxyOptions.fAutoLogonIfChallenged = FALSE;
    
    WinHttpGetProxyForUrl(
        session,
        serviceUrl.chars,
        &autoProxyOptions,
        &proxyInfo);
    
    if (proxyInfo.dwAccessType == WINHTTP_ACCESS_TYPE_NAMED_PROXY)
    {
        if (proxyInfo.lpszProxy)
        {
            customProxy.servers.chars = proxyInfo.lpszProxy;
            customProxy.servers.length = (ULONG)wcslen(proxyInfo.lpszProxy);
        }
        if (proxyInfo.lpszProxyBypass)
        {
            customProxy.bypass.chars = proxyInfo.lpszProxyBypass;
            customProxy.bypass.length = (ULONG)wcslen(proxyInfo.lpszProxyBypass);
        }
    }
    
    hr = WsCreateServiceProxy(
        WS_CHANNEL_TYPE_REQUEST,
        WS_HTTP_CHANNEL_BINDING,
        &securityDescription,
        NULL,
        0,
        channelPropertyArray,
        WsCountOf(channelPropertyArray),
        &serviceProxy,
        error);
    if (FAILED(hr))
    {
        goto Exit;
    }
    
    
    // Open channel to address
    hr = WsOpenServiceProxy(
        serviceProxy,
        &address,
        NULL,
        error);
    if (FAILED(hr))
    {
        goto Exit;
    }
    
    for (int i = 0; i < 100; i++)
    {
        LonLatPt point = {10.0, 10.0};
        hr = TerraServiceSoap_ConvertLonLatPtToNearestPlace(
            serviceProxy,
            &point,
            &place,
            heap,
            NULL,
            0,
            NULL,
            error);
        if (FAILED(hr))
        {
            goto Exit;
        }
    
        if (place != NULL)
        {
            wprintf(L"Place @ Lattitude=%f, Longitutde=%f is %s\n",
                point.Lon,
                point.Lat,
                place);
        }
        else
        {
            wprintf(L"Could not find any place for Lattitude=%f, Longitutde=%f\n",
                point.Lon,
                point.Lat);
        }
        fflush(stdout);
    
        hr = WsResetHeap(
            heap,
            error);
        if (FAILED(hr))
        {
            goto Exit;
        }
    }
Exit:
    if (FAILED(hr))
    {
        // Print out the error
        PrintError(hr, error);
    }
    if (proxyInfo.lpszProxy)
    {
        ::GlobalFree(proxyInfo.lpszProxy);
    }
    if (proxyInfo.lpszProxyBypass)
    {
        ::GlobalFree(proxyInfo.lpszProxyBypass);
    }
    if (serviceProxy != NULL)
    {
        WsCloseServiceProxy(serviceProxy, NULL, NULL);
        WsFreeServiceProxy(serviceProxy);
    }
    if (!session)
    {
        WinHttpCloseHandle(session);
    }
    if (heap != NULL)
    {
        WsFreeHeap(heap);
    }
    if (error != NULL)
    {
        WsFreeError(error);
    }
    fflush(stdout);
    return SUCCEEDED(hr) ? 0 : -1;
}
Example #8
0
static LPWSTR
QueryWindowsProxySettings(const url_scheme scheme, LPCSTR host)
{
    LPWSTR proxy = NULL;
    BOOL auto_detect = TRUE;
    LPWSTR auto_config_url = NULL;
    WINHTTP_CURRENT_USER_IE_PROXY_CONFIG proxy_config;

    if (WinHttpGetIEProxyConfigForCurrentUser(&proxy_config))
    {
        proxy = proxy_config.lpszProxy;
        auto_detect = proxy_config.fAutoDetect;
        auto_config_url = proxy_config.lpszAutoConfigUrl;
        GlobalFree(proxy_config.lpszProxyBypass);
    }

    if (auto_detect)
    {
        LPWSTR old_url = auto_config_url;
        DWORD flags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
        if (WinHttpDetectAutoProxyConfigUrl(flags, &auto_config_url))
            GlobalFree(old_url);
    }

    if (auto_config_url)
    {
        HINTERNET session = WinHttpOpen(NULL, WINHTTP_ACCESS_TYPE_NO_PROXY,
            WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
        if (session)
        {
            int size = _snwprintf(NULL, 0, L"%s://%S", UrlSchemeStr(scheme), host) + 1;
            LPWSTR url = malloc(size * sizeof(WCHAR));
            if (url)
            {
                _snwprintf(url, size, L"%s://%S", UrlSchemeStr(scheme), host);

                LPWSTR old_proxy = proxy;
                WINHTTP_PROXY_INFO proxy_info;
                WINHTTP_AUTOPROXY_OPTIONS options = {
                    .fAutoLogonIfChallenged = TRUE,
                    .dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL,
                    .lpszAutoConfigUrl = auto_config_url,
                    .dwAutoDetectFlags = 0,
                    .lpvReserved = NULL,
                    .dwReserved = 0
                };

                if (WinHttpGetProxyForUrl(session, url, &options, &proxy_info))
                {
                    GlobalFree(old_proxy);
                    GlobalFree(proxy_info.lpszProxyBypass);
                    proxy = proxy_info.lpszProxy;
                }
                free(url);
            }
            WinHttpCloseHandle(session);
        }
        GlobalFree(auto_config_url);
    }

    return proxy;
}


static VOID
ParseProxyString(LPWSTR proxy_str, url_scheme scheme,
                 LPCSTR *type, LPCWSTR *host, LPCWSTR *port)
{
    if (proxy_str == NULL)
        return;

    LPCWSTR delim = L"; ";
    LPWSTR token = wcstok(proxy_str, delim);

    LPCWSTR scheme_str = UrlSchemeStr(scheme);
    LPCWSTR socks_str = UrlSchemeStr(SOCKS_URL);

    /* Token format: [<scheme>=][<scheme>"://"]<server>[":"<port>] */
    while (token)
    {
        BOOL match = FALSE;
        LPWSTR eq = wcschr(token, '=');
        LPWSTR css = wcsstr(token, L"://");

        /*
         * If the token has a <scheme>, test for the one we're looking for.
         * If we're looking for a https proxy, socks will also do.
         * If it's a proxy without a <scheme> it's only good for https.
         */
        if (eq || css)
        {
            if (wcsbegins(token, scheme_str))
            {
                match = TRUE;
            }
            else if (scheme == HTTPS_URL && wcsbegins(token, socks_str))
            {
                match = TRUE;
                scheme = SOCKS_URL;
            }
        }
        else if (scheme == HTTPS_URL)
        {
            match = TRUE;
        }

        if (match)
        {
            LPWSTR server = token;
            if (css)
                server = css + 3;
            else if (eq)
                server = eq + 1;

            /* IPv6 addresses are surrounded by brackets */
            LPWSTR port_delim;
            if (server[0] == '[')
            {
                server += 1;
                LPWSTR end = wcschr(server, ']');
                if (end == NULL)
                    continue;
                *end++ = '\0';

                port_delim = (*end == ':' ? end : NULL);
            }
            else
            {
                port_delim = wcsrchr(server, ':');
                if (port_delim)
                    *port_delim = '\0';
            }

            *type = (scheme == HTTPS_URL ? "HTTP" : "SOCKS");
            *host = server;
            if (port_delim)
                *port = port_delim + 1;
            else
                *port = (scheme == HTTPS_URL ? L"80": L"1080");

            break;
        }
        token = wcstok(NULL, delim);
    }
}


/*
 * Respond to management interface PROXY notifications
 * Input format: REMOTE_NO,PROTOCOL,HOST
 */
void
OnProxy(connection_t *c, char *line)
{
    LPSTR proto, host;
    char *pos = strchr(line, ',');
    if (pos == NULL)
        return;

    proto = ++pos;
    pos = strchr(pos, ',');
    if (pos == NULL)
        return;

    *pos = '\0';
    host = ++pos;
    if (host[0] == '\0')
        return;

    LPCSTR type = "NONE";
    LPCWSTR addr = L"", port = L"";
    LPWSTR proxy_str = NULL;

    if (o.proxy_source == manual)
    {
        if (o.proxy_type == http && streq(proto, "TCP"))
        {
            type = "HTTP";
            addr = o.proxy_http_address;
            port = o.proxy_http_port;
        }
        else if (o.proxy_type == socks)
        {
            type = "SOCKS";
            addr = o.proxy_socks_address;
            port = o.proxy_socks_port;
        }
    }
    else if (o.proxy_source == windows)
    {
        url_scheme scheme = (streq(proto, "TCP") ? HTTPS_URL : SOCKS_URL);
        proxy_str = QueryWindowsProxySettings(scheme, host);
        ParseProxyString(proxy_str, scheme, &type, &addr, &port);
    }

    char cmd[128];
    snprintf(cmd, sizeof(cmd), "proxy %s %S %S", type, addr, port);
    cmd[sizeof(cmd) - 1] = '\0';
    ManagementCommand(c, cmd, NULL, regular);

    GlobalFree(proxy_str);
}