static int SendHttpRequestAndData(NetlibConnection *nlc, struct ResizableCharBuffer *httpRequest, NETLIBHTTPREQUEST *nlhr, int sendContentLengthHeader) { bool sendData = (nlhr->requestType == REQUEST_POST || nlhr->requestType == REQUEST_PUT); if (sendContentLengthHeader && sendData) AppendToCharBuffer(httpRequest, "Content-Length: %d\r\n\r\n", nlhr->dataLength); else AppendToCharBuffer(httpRequest, "\r\n"); DWORD hflags = (nlhr->flags & NLHRF_DUMPASTEXT ? MSG_DUMPASTEXT : 0) | (nlhr->flags & (NLHRF_NODUMP | NLHRF_NODUMPSEND | NLHRF_NODUMPHEADERS) ? MSG_NODUMP : (nlhr->flags & NLHRF_DUMPPROXY ? MSG_DUMPPROXY : 0)) | (nlhr->flags & NLHRF_NOPROXY ? MSG_RAW : 0); int bytesSent = NLSend(nlc, httpRequest->sz, httpRequest->iEnd, hflags); if (bytesSent != SOCKET_ERROR && sendData && nlhr->dataLength) { DWORD sflags = (nlhr->flags & NLHRF_DUMPASTEXT ? MSG_DUMPASTEXT : 0) | (nlhr->flags & (NLHRF_NODUMP | NLHRF_NODUMPSEND) ? MSG_NODUMP : (nlhr->flags & NLHRF_DUMPPROXY ? MSG_DUMPPROXY : 0)) | (nlhr->flags & NLHRF_NOPROXY ? MSG_RAW : 0); int sendResult = NLSend(nlc, nlhr->pData, nlhr->dataLength, sflags); bytesSent = sendResult != SOCKET_ERROR ? bytesSent + sendResult : SOCKET_ERROR; } mir_free(httpRequest->sz); memset(httpRequest, 0, sizeof(*httpRequest)); return bytesSent; }
static int NetlibInitSocks4Connection(NetlibConnection *nlc, NetlibUser *nlu, NETLIBOPENCONNECTION *nloc) { // http://www.socks.nec.com/protocol/socks4.protocol and http://www.socks.nec.com/protocol/socks4a.protocol if (!nloc->szHost || !nloc->szHost[0]) return 0; size_t nHostLen = strlen(nloc->szHost) + 1; size_t nUserLen = nlu->settings.szProxyAuthUser ? strlen(nlu->settings.szProxyAuthUser) + 1 : 1; size_t len = 8 + nUserLen; char* pInit = (char*)alloca(len + nHostLen); pInit[0] = 4; // SOCKS4 pInit[1] = 1; //connect *(PWORD)&pInit[2] = htons(nloc->wPort); if (nUserLen <= 1) pInit[8] = 0; else memcpy(&pInit[8], nlu->settings.szProxyAuthUser, nUserLen); //if cannot resolve host, try resolving through proxy (requires SOCKS4a) DWORD ip = DnsLookup(nlu, nloc->szHost); *(PDWORD)&pInit[4] = ip ? ip : 0x01000000; if (!ip) { memcpy(&pInit[len], nloc->szHost, nHostLen); len += nHostLen; } if (NLSend(nlc, pInit, (int)len, MSG_DUMPPROXY) == SOCKET_ERROR) { NetlibLogf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"NLSend",GetLastError()); return 0; } char reply[8]; if (!RecvUntilTimeout(nlc, reply, sizeof(reply), MSG_DUMPPROXY, RECV_DEFAULT_TIMEOUT)) { NetlibLogf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"RecvUntilTimeout",GetLastError()); return 0; } switch ((BYTE)reply[1]) { case 90: return 1; case 91: SetLastError(ERROR_ACCESS_DENIED); break; case 92: SetLastError(ERROR_CONNECTION_UNAVAIL); break; case 93: SetLastError(ERROR_INVALID_ACCESS); break; default: SetLastError(ERROR_INVALID_DATA); break; } NetlibLogf(nlu,"%s %d: Proxy connection failed (%x %u)",__FILE__,__LINE__, (BYTE)reply[1], GetLastError()); return 0; }
static int NetlibInitSocks5Connection(struct NetlibConnection *nlc,struct NetlibUser *nlu,NETLIBOPENCONNECTION *nloc) { //rfc1928 BYTE buf[258]; buf[0]=5; //yep, socks5 buf[1]=1; //one auth method buf[2]=nlu->settings.useProxyAuth?2:0; if(NLSend(nlc,(char*)buf,3,MSG_DUMPPROXY)==SOCKET_ERROR) { NetlibLogf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"NLSend",GetLastError()); return 0; } //confirmation of auth method if (!RecvUntilTimeout(nlc,(char*)buf,2,MSG_DUMPPROXY,RECV_DEFAULT_TIMEOUT)) { NetlibLogf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"RecvUntilTimeout",GetLastError()); return 0; } if((buf[1]!=0 && buf[1]!=2)) { SetLastError(ERROR_INVALID_ID_AUTHORITY); NetlibLogf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"NLRecv",GetLastError()); return 0; } if(buf[1]==2) { //rfc1929 int nUserLen,nPassLen; PBYTE pAuthBuf; nUserLen=lstrlenA(nlu->settings.szProxyAuthUser); nPassLen=lstrlenA(nlu->settings.szProxyAuthPassword); pAuthBuf=(PBYTE)mir_alloc(3+nUserLen+nPassLen); pAuthBuf[0]=1; //auth version pAuthBuf[1]=nUserLen; memcpy(pAuthBuf+2,nlu->settings.szProxyAuthUser,nUserLen); pAuthBuf[2+nUserLen]=nPassLen; memcpy(pAuthBuf+3+nUserLen,nlu->settings.szProxyAuthPassword,nPassLen); if(NLSend(nlc,(char*)pAuthBuf,3+nUserLen+nPassLen,MSG_DUMPPROXY)==SOCKET_ERROR) { NetlibLogf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"NLSend",GetLastError()); mir_free(pAuthBuf); return 0; } mir_free(pAuthBuf); if (!RecvUntilTimeout(nlc,(char*)buf,2,MSG_DUMPPROXY,RECV_DEFAULT_TIMEOUT)) { NetlibLogf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"RecvUntilTimeout",GetLastError()); return 0; } if(buf[1]) { SetLastError(ERROR_ACCESS_DENIED); NetlibLogf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"RecvUntilTimeout",GetLastError()); return 0; } } { PBYTE pInit; int nHostLen; DWORD hostIP; if(nlc->dnsThroughProxy) { if((hostIP=inet_addr(nloc->szHost))==INADDR_NONE) nHostLen=lstrlenA(nloc->szHost)+1; else nHostLen=4; } else { if((hostIP=DnsLookup(nlu,nloc->szHost))==0) return 0; nHostLen=4; } pInit=(PBYTE)mir_alloc(6+nHostLen); pInit[0]=5; //SOCKS5 pInit[1]= nloc->flags & NLOCF_UDP ? 3 : 1; //connect or UDP pInit[2]=0; //reserved if(hostIP==INADDR_NONE) { //DNS lookup through proxy pInit[3]=3; pInit[4]=nHostLen-1; memcpy(pInit+5,nloc->szHost,nHostLen-1); } else { pInit[3]=1; *(PDWORD)(pInit+4)=hostIP; } *(PWORD)(pInit+4+nHostLen)=htons(nloc->wPort); if(NLSend(nlc,(char*)pInit,6+nHostLen,MSG_DUMPPROXY)==SOCKET_ERROR) { NetlibLogf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"NLSend",GetLastError()); mir_free(pInit); return 0; } mir_free(pInit); } if (!RecvUntilTimeout(nlc,(char*)buf,5,MSG_DUMPPROXY,RECV_DEFAULT_TIMEOUT)) { NetlibLogf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"RecvUntilTimeout",GetLastError()); return 0; } if ( buf[0]!=5 || buf[1] ) { const char* err = "Unknown response"; if ( buf[0] != 5 ) SetLastError(ERROR_BAD_FORMAT); else { switch(buf[1]) { case 1: SetLastError(ERROR_GEN_FAILURE); err = "General failure"; break; case 2: SetLastError(ERROR_ACCESS_DENIED); err = "Connection not allowed by ruleset"; break; case 3: SetLastError(WSAENETUNREACH); err = "Network unreachable"; break; case 4: SetLastError(WSAEHOSTUNREACH); err = "Host unreachable"; break; case 5: SetLastError(WSAECONNREFUSED); err = "Connection refused by destination host"; break; case 6: SetLastError(WSAETIMEDOUT); err = "TTL expired"; break; case 7: SetLastError(ERROR_CALL_NOT_IMPLEMENTED); err = "Command not supported / protocol error"; break; case 8: SetLastError(ERROR_INVALID_ADDRESS); err = "Address type not supported"; break; default: SetLastError(ERROR_INVALID_DATA); break; } } NetlibLogf(nlu,"%s %d: Proxy conection failed. %s.",__FILE__,__LINE__, err); return 0; } { int nRecvSize = 0; switch( buf[3] ) { case 1:// ipv4 addr nRecvSize = 5; break; case 3:// dns name addr nRecvSize = buf[4] + 2; break; case 4:// ipv6 addr nRecvSize = 17; break; default: NetlibLogf(nlu,"%s %d: %s() unknown address type (%u)",__FILE__,__LINE__,"NetlibInitSocks5Connection",(int)buf[3]); return 0; } if (!RecvUntilTimeout(nlc,(char*)buf,nRecvSize,MSG_DUMPPROXY,RECV_DEFAULT_TIMEOUT)) { NetlibLogf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"RecvUntilTimeout",GetLastError()); return 0; } } //connected return 1; }