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; }