static bool NetlibInitHttpsConnection(struct NetlibConnection *nlc, struct NetlibUser *nlu, NETLIBOPENCONNECTION *nloc) { //rfc2817 NETLIBHTTPREQUEST nlhrSend = {0}, *nlhrReply; char szUrl[512]; nlhrSend.cbSize = sizeof(nlhrSend); nlhrSend.requestType = REQUEST_CONNECT; nlhrSend.flags = NLHRF_GENERATEHOST | NLHRF_DUMPPROXY | NLHRF_SMARTAUTHHEADER | NLHRF_HTTP11 | NLHRF_NOPROXY | NLHRF_REDIRECT; if (nlc->dnsThroughProxy) { mir_snprintf(szUrl, SIZEOF(szUrl), "%s:%u", nloc->szHost, nloc->wPort); } else { DWORD ip = DnsLookup(nlu, nloc->szHost); if (ip == 0) return false; mir_snprintf(szUrl, SIZEOF(szUrl), "%s:%u", inet_ntoa(*(PIN_ADDR)&ip), nloc->wPort); } nlhrSend.szUrl = szUrl; nlc->usingHttpGateway = true; if (NetlibHttpSendRequest((WPARAM)nlc, (LPARAM)&nlhrSend) == SOCKET_ERROR) { nlc->usingHttpGateway = false; return 0; } nlhrReply = NetlibHttpRecv(nlc, MSG_DUMPPROXY | MSG_RAW, MSG_DUMPPROXY | MSG_RAW, true); nlc->usingHttpGateway = false; if (nlhrReply == NULL) return false; if (nlhrReply->resultCode < 200 || nlhrReply->resultCode >= 300) { if (nlhrReply->resultCode == 403 && nlc->dnsThroughProxy) { NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); nlc->dnsThroughProxy = 0; return NetlibInitHttpsConnection(nlc, nlu, nloc); } NetlibHttpSetLastErrorUsingHttpResult(nlhrReply->resultCode); NetlibLogf(nlu,"%s %d: %s request failed (%u %s)",__FILE__,__LINE__,nlu->settings.proxyType==PROXYTYPE_HTTP?"HTTP":"HTTPS",nlhrReply->resultCode,nlhrReply->szResultDescr); NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); return 0; } NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); //connected return true; }
bool NetlibDoConnect(NetlibConnection *nlc) { NETLIBOPENCONNECTION *nloc = &nlc->nloc; NetlibUser *nlu = nlc->nlu; nlc->sinProxy.sin_family = AF_INET; mir_free(nlc->szProxyServer); nlc->szProxyServer = NULL; bool usingProxy = false, forceHttps = false; if (nlu->settings.useProxy) { if (nlu->settings.proxyType == PROXYTYPE_IE) { usingProxy = NetlibGetIeProxyConn(nlc, false); } else { if (nlu->settings.szProxyServer && nlu->settings.szProxyServer[0]) { nlc->szProxyServer = mir_strdup(nlu->settings.szProxyServer); nlc->wProxyPort = nlu->settings.wProxyPort; nlc->proxyType = nlu->settings.proxyType; usingProxy = true; } } } retry: if (usingProxy) { NetlibLogf(nlu,"(%p) Resolving proxy %s:%d for %s:%d ....", nlc, nlc->szProxyServer, nlc->wProxyPort, nloc->szHost, nloc->wPort); nlc->sinProxy.sin_port = htons(nlc->wProxyPort); nlc->sinProxy.sin_addr.S_un.S_addr = DnsLookup(nlu, nlc->szProxyServer); if (nlc->sinProxy.sin_addr.S_un.S_addr == 0) { usingProxy = false; nlc->proxyType = 0; } } if (!usingProxy) { NetlibLogf(nlu,"(%p) Connecting to server %s:%d....", nlc, nloc->szHost, nloc->wPort); nlc->sinProxy.sin_port = htons(nloc->wPort); nlc->sinProxy.sin_addr.S_un.S_addr = DnsLookup(nlu, nloc->szHost); } else NetlibLogf(nlu,"(%p) Connecting to proxy %s:%d for %s:%d ....", nlc, nlc->szProxyServer, nlc->wProxyPort, nloc->szHost, nloc->wPort); if (nlc->sinProxy.sin_addr.S_un.S_addr == 0) return false; if (my_connect(nlc, nloc) == SOCKET_ERROR) { if (usingProxy && (nlc->proxyType == PROXYTYPE_HTTPS || nlc->proxyType == PROXYTYPE_HTTP)) { usingProxy = false; if (!NetlibHttpFallbackToDirect(nlc, nlu, nloc)) { NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "connect", WSAGetLastError()); return false; } } else { if (nlu->settings.useProxy && !usingProxy && nlu->settings.proxyType == PROXYTYPE_IE && !forceHttps) { forceHttps = true; usingProxy = NetlibGetIeProxyConn(nlc, true); if (usingProxy) goto retry; } NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "connect", WSAGetLastError()); return false; } } if (usingProxy && !((nloc->flags & (NLOCF_HTTP | NLOCF_SSL)) == NLOCF_HTTP && (nlc->proxyType == PROXYTYPE_HTTP || nlc->proxyType == PROXYTYPE_HTTPS))) { if (!WaitUntilWritable(nlc->s, 30000)) return false; switch (nlc->proxyType) { case PROXYTYPE_SOCKS4: if (!NetlibInitSocks4Connection(nlc, nlu, nloc)) return false; break; case PROXYTYPE_SOCKS5: if (!NetlibInitSocks5Connection(nlc, nlu, nloc)) return false; break; case PROXYTYPE_HTTPS: nlc->proxyAuthNeeded = true; if (!NetlibInitHttpsConnection(nlc, nlu, nloc)) { usingProxy = false; if (!NetlibHttpFallbackToDirect(nlc, nlu, nloc)) return false; } break; case PROXYTYPE_HTTP: nlc->proxyAuthNeeded = true; if (!(nlu->user.flags & NUF_HTTPGATEWAY || nloc->flags & NLOCF_HTTPGATEWAY) || nloc->flags & NLOCF_SSL) { //NLOCF_HTTP not specified and no HTTP gateway available: try HTTPS if (!NetlibInitHttpsConnection(nlc, nlu, nloc)) { //can't do HTTPS: try direct usingProxy = false; if (!NetlibHttpFallbackToDirect(nlc, nlu, nloc)) return false; } } else { if (!NetlibInitHttpConnection(nlc, nlu, nloc)) return false; } break; default: SetLastError(ERROR_INVALID_PARAMETER); FreePartiallyInitedConnection(nlc); return false; } } else if (nloc->flags & NLOCF_HTTPGATEWAY) { if (!NetlibInitHttpConnection(nlc, nlu, nloc)) return false; nlc->usingDirectHttpGateway = true; } NetlibLogf(nlu,"(%d) Connected to %s:%d", nlc->s, nloc->szHost, nloc->wPort); if (NLOCF_SSL & nloc->flags) { return NetlibStartSsl((WPARAM)nlc, 0) != 0; } return true; }
bool NetlibDoConnect(NetlibConnection *nlc) { NETLIBOPENCONNECTION *nloc = &nlc->nloc; NetlibUser *nlu = nlc->nlu; mir_free(nlc->szProxyServer); nlc->szProxyServer = NULL; bool usingProxy = false, forceHttps = false; if (nlu->settings.useProxy) { if (nlu->settings.proxyType == PROXYTYPE_IE) usingProxy = NetlibGetIeProxyConn(nlc, false); else { if (nlu->settings.szProxyServer && nlu->settings.szProxyServer[0]) { nlc->szProxyServer = mir_strdup(nlu->settings.szProxyServer); nlc->wProxyPort = nlu->settings.wProxyPort; nlc->proxyType = nlu->settings.proxyType; usingProxy = true; } } } while (!my_connect(nlc, nloc)) { // Fallback to direct only when using HTTP proxy, as this is what used by companies // If other type of proxy used it's an indication of security nutcase, leave him alone if (usingProxy && (nlc->proxyType == PROXYTYPE_HTTPS || nlc->proxyType == PROXYTYPE_HTTP)) { usingProxy = false; nlc->proxyType = 0; NetlibLogf(nlu,"Fallback to direct connection"); continue; } if (nlu->settings.useProxy && !usingProxy && nlu->settings.proxyType == PROXYTYPE_IE && !forceHttps) { forceHttps = true; usingProxy = NetlibGetIeProxyConn(nlc, true); if (usingProxy) continue; } NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "connect", WSAGetLastError()); return false; } if (usingProxy && !((nloc->flags & (NLOCF_HTTP | NLOCF_SSL)) == NLOCF_HTTP && (nlc->proxyType == PROXYTYPE_HTTP || nlc->proxyType == PROXYTYPE_HTTPS))) { if (!WaitUntilWritable(nlc->s, 30000)) return false; switch (nlc->proxyType) { case PROXYTYPE_SOCKS4: if (!NetlibInitSocks4Connection(nlc, nlu, nloc)) return false; break; case PROXYTYPE_SOCKS5: if (!NetlibInitSocks5Connection(nlc, nlu, nloc)) return false; break; case PROXYTYPE_HTTPS: nlc->proxyAuthNeeded = true; if (!NetlibInitHttpsConnection(nlc, nlu, nloc)) { usingProxy = false; if (!NetlibHttpFallbackToDirect(nlc, nlu, nloc)) return false; } break; case PROXYTYPE_HTTP: nlc->proxyAuthNeeded = true; if (!(nlu->user.flags & NUF_HTTPGATEWAY || nloc->flags & NLOCF_HTTPGATEWAY) || nloc->flags & NLOCF_SSL) { //NLOCF_HTTP not specified and no HTTP gateway available: try HTTPS if (!NetlibInitHttpsConnection(nlc, nlu, nloc)) { //can't do HTTPS: try direct usingProxy = false; if (!NetlibHttpFallbackToDirect(nlc, nlu, nloc)) return false; } } else if (!NetlibInitHttpConnection(nlc, nlu, nloc)) return false; break; default: SetLastError(ERROR_INVALID_PARAMETER); FreePartiallyInitedConnection(nlc); return false; } } else if (nloc->flags & NLOCF_HTTPGATEWAY) { if (!NetlibInitHttpConnection(nlc, nlu, nloc)) return false; nlc->usingDirectHttpGateway = true; } NetlibLogf(nlu, "(%d) Connected to %s:%d", nlc->s, nloc->szHost, nloc->wPort); if (NLOCF_SSL & nloc->flags) return NetlibStartSsl((WPARAM)nlc, 0) != 0; return true; }