summaryrefslogtreecommitdiff
path: root/src/modules/netlib
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/netlib')
-rw-r--r--src/modules/netlib/netlib.cpp527
-rw-r--r--src/modules/netlib/netlib.h220
-rw-r--r--src/modules/netlib/netlibautoproxy.cpp453
-rw-r--r--src/modules/netlib/netlibbind.cpp307
-rw-r--r--src/modules/netlib/netlibhttp.cpp1168
-rw-r--r--src/modules/netlib/netlibhttpproxy.cpp459
-rw-r--r--src/modules/netlib/netliblog.cpp532
-rw-r--r--src/modules/netlib/netlibopenconn.cpp890
-rw-r--r--src/modules/netlib/netlibopts.cpp530
-rw-r--r--src/modules/netlib/netlibpktrecver.cpp89
-rw-r--r--src/modules/netlib/netlibsecurity.cpp427
-rw-r--r--src/modules/netlib/netlibsock.cpp313
-rw-r--r--src/modules/netlib/netlibupnp.cpp826
13 files changed, 0 insertions, 6741 deletions
diff --git a/src/modules/netlib/netlib.cpp b/src/modules/netlib/netlib.cpp
deleted file mode 100644
index a900c77f93..0000000000
--- a/src/modules/netlib/netlib.cpp
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (ñ) 2012-15 Miranda NG project (http://miranda-ng.org),
-Copyright (c) 2000-12 Miranda IM project,
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "..\..\core\commonheaders.h"
-#include "netlib.h"
-
-static BOOL bModuleInitialized = FALSE;
-
-HANDLE hConnectionHeaderMutex, hConnectionOpenMutex;
-DWORD g_LastConnectionTick;
-int connectionTimeout;
-HANDLE hSendEvent = NULL, hRecvEvent = NULL;
-
-typedef BOOL (WINAPI *tGetProductInfo)(DWORD, DWORD, DWORD, DWORD, PDWORD);
-
-static int CompareNetlibUser(const NetlibUser* p1, const NetlibUser* p2)
-{
- return mir_strcmp(p1->user.szSettingsModule, p2->user.szSettingsModule);
-}
-
-LIST<NetlibUser> netlibUser(5, CompareNetlibUser);
-mir_cs csNetlibUser;
-
-SSL_API si;
-
-void NetlibFreeUserSettingsStruct(NETLIBUSERSETTINGS *settings)
-{
- mir_free(settings->szIncomingPorts);
- mir_free(settings->szOutgoingPorts);
- mir_free(settings->szProxyAuthPassword);
- mir_free(settings->szProxyAuthUser);
- mir_free(settings->szProxyServer);
-}
-
-int GetNetlibHandleType(void *p)
-{
- __try {
- return *(int*)p;
- }
- __except(EXCEPTION_EXECUTE_HANDLER)
- {}
-
- return NLH_INVALID;
-}
-
-void NetlibInitializeNestedCS(NetlibNestedCriticalSection *nlncs)
-{
- nlncs->dwOwningThreadId = 0;
- nlncs->lockCount = 0;
- nlncs->hMutex = CreateMutex(NULL, FALSE, NULL);
-}
-
-void NetlibDeleteNestedCS(NetlibNestedCriticalSection *nlncs)
-{
- CloseHandle(nlncs->hMutex);
-}
-
-int NetlibEnterNestedCS(NetlibConnection *nlc, int which)
-{
- NetlibNestedCriticalSection *nlncs;
- DWORD dwCurrentThreadId = GetCurrentThreadId();
-
- WaitForSingleObject(hConnectionHeaderMutex, INFINITE);
- if (nlc == NULL || nlc->handleType != NLH_CONNECTION) {
- ReleaseMutex(hConnectionHeaderMutex);
- SetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
- nlncs = (which == NLNCS_SEND) ? &nlc->ncsSend : &nlc->ncsRecv;
- if (nlncs->lockCount && nlncs->dwOwningThreadId == dwCurrentThreadId) {
- nlncs->lockCount++;
- ReleaseMutex(hConnectionHeaderMutex);
- return 1;
- }
- InterlockedIncrement(&nlc->dontCloseNow);
- ResetEvent(nlc->hOkToCloseEvent);
- ReleaseMutex(hConnectionHeaderMutex);
- WaitForSingleObject(nlncs->hMutex, INFINITE);
- nlncs->dwOwningThreadId = dwCurrentThreadId;
- nlncs->lockCount = 1;
- if (InterlockedDecrement(&nlc->dontCloseNow) == 0)
- SetEvent(nlc->hOkToCloseEvent);
- return 1;
-}
-
-void NetlibLeaveNestedCS(NetlibNestedCriticalSection *nlncs)
-{
- if (--nlncs->lockCount == 0) {
- nlncs->dwOwningThreadId = 0;
- ReleaseMutex(nlncs->hMutex);
- }
-}
-
-static INT_PTR GetNetlibUserSettingInt(const char *szUserModule, const char *szSetting, int defValue)
-{
- DBVARIANT dbv;
- if (db_get(NULL, szUserModule, szSetting, &dbv) && db_get(NULL, "Netlib", szSetting, &dbv))
- return defValue;
-
- if (dbv.type == DBVT_BYTE) return dbv.bVal;
- if (dbv.type == DBVT_WORD) return dbv.wVal;
- return dbv.dVal;
-}
-
-static char *GetNetlibUserSettingString(const char *szUserModule, const char *szSetting)
-{
- char *szRet = db_get_sa(NULL, szUserModule, szSetting);
- if (szRet == NULL)
- if ((szRet = db_get_sa(NULL, "Netlib", szSetting)) == NULL)
- return NULL;
-
- return szRet;
-}
-
-static INT_PTR NetlibRegisterUser(WPARAM, LPARAM lParam)
-{
- NETLIBUSER *nlu = (NETLIBUSER*)lParam;
- if (nlu == NULL || nlu->cbSize != sizeof(NETLIBUSER) || nlu->szSettingsModule == NULL ||
- (!(nlu->flags & NUF_NOOPTIONS) && nlu->szDescriptiveName == NULL) ||
- (nlu->flags & NUF_HTTPGATEWAY && (nlu->pfnHttpGatewayInit == NULL)))
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- NetlibUser *thisUser = (NetlibUser*)mir_calloc(sizeof(NetlibUser));
- thisUser->handleType = NLH_USER;
- thisUser->user = *nlu;
-
- int idx;
- {
- mir_cslock lck(csNetlibUser);
- idx = netlibUser.getIndex(thisUser);
- }
- if (idx != -1) {
- mir_free(thisUser);
- SetLastError(ERROR_DUP_NAME);
- return 0;
- }
-
- if (nlu->szDescriptiveName)
- thisUser->user.ptszDescriptiveName = (thisUser->user.flags&NUF_UNICODE ? mir_u2t((WCHAR*)nlu->ptszDescriptiveName) : mir_a2t(nlu->szDescriptiveName));
-
- if ((thisUser->user.szSettingsModule = mir_strdup(nlu->szSettingsModule)) == NULL
- || (nlu->szDescriptiveName && thisUser->user.ptszDescriptiveName == NULL)
- || (nlu->szHttpGatewayUserAgent && (thisUser->user.szHttpGatewayUserAgent = mir_strdup(nlu->szHttpGatewayUserAgent)) == NULL))
- {
- mir_free(thisUser);
- SetLastError(ERROR_OUTOFMEMORY);
- return 0;
- }
- if (nlu->szHttpGatewayHello)
- thisUser->user.szHttpGatewayHello = mir_strdup(nlu->szHttpGatewayHello);
- else
- thisUser->user.szHttpGatewayHello = NULL;
-
- thisUser->settings.cbSize = sizeof(NETLIBUSERSETTINGS);
- thisUser->settings.useProxy = GetNetlibUserSettingInt(thisUser->user.szSettingsModule, "NLUseProxy", 0);
- thisUser->settings.proxyType = GetNetlibUserSettingInt(thisUser->user.szSettingsModule, "NLProxyType", PROXYTYPE_SOCKS5);
- if (thisUser->user.flags&NUF_NOHTTPSOPTION && thisUser->settings.proxyType == PROXYTYPE_HTTPS)
- thisUser->settings.proxyType = PROXYTYPE_HTTP;
- if (!(thisUser->user.flags&(NUF_HTTPCONNS|NUF_HTTPGATEWAY)) && thisUser->settings.proxyType == PROXYTYPE_HTTP) {
- thisUser->settings.useProxy = 0;
- thisUser->settings.proxyType = PROXYTYPE_SOCKS5;
- }
- thisUser->settings.szProxyServer = GetNetlibUserSettingString(thisUser->user.szSettingsModule, "NLProxyServer");
- thisUser->settings.wProxyPort = GetNetlibUserSettingInt(thisUser->user.szSettingsModule, "NLProxyPort", 1080);
- thisUser->settings.useProxyAuth = GetNetlibUserSettingInt(thisUser->user.szSettingsModule, "NLUseProxyAuth", 0);
- thisUser->settings.szProxyAuthUser = GetNetlibUserSettingString(thisUser->user.szSettingsModule, "NLProxyAuthUser");
- thisUser->settings.szProxyAuthPassword = GetNetlibUserSettingString(thisUser->user.szSettingsModule, "NLProxyAuthPassword");
- thisUser->settings.dnsThroughProxy = GetNetlibUserSettingInt(thisUser->user.szSettingsModule, "NLDnsThroughProxy", 1);
- thisUser->settings.specifyIncomingPorts = GetNetlibUserSettingInt(thisUser->user.szSettingsModule, "NLSpecifyIncomingPorts", 0);
- thisUser->settings.szIncomingPorts = GetNetlibUserSettingString(thisUser->user.szSettingsModule, "NLIncomingPorts");
- thisUser->settings.specifyOutgoingPorts = GetNetlibUserSettingInt(thisUser->user.szSettingsModule, "NLSpecifyOutgoingPorts", 0);
- thisUser->settings.szOutgoingPorts = GetNetlibUserSettingString(thisUser->user.szSettingsModule, "NLOutgoingPorts");
- thisUser->settings.enableUPnP = GetNetlibUserSettingInt(thisUser->user.szSettingsModule, "NLEnableUPnP", 1); //default to on
- thisUser->settings.validateSSL = GetNetlibUserSettingInt(thisUser->user.szSettingsModule, "NLValidateSSL", 0);
-
- thisUser->toLog = GetNetlibUserSettingInt(thisUser->user.szSettingsModule, "NLlog", 1);
-
- mir_cslock lck(csNetlibUser);
- netlibUser.insert(thisUser);
- return (INT_PTR)thisUser;
-}
-
-static INT_PTR NetlibGetUserSettings(WPARAM wParam, LPARAM lParam)
-{
- NETLIBUSERSETTINGS *nlus = (NETLIBUSERSETTINGS*)lParam;
- NetlibUser *nlu = (NetlibUser*)wParam;
-
- if (GetNetlibHandleType(nlu) != NLH_USER || nlus == NULL || nlus->cbSize != sizeof(NETLIBUSERSETTINGS)) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
- *nlus = nlu->settings;
- return 1;
-}
-
-static INT_PTR NetlibSetUserSettings(WPARAM wParam, LPARAM lParam)
-{
- NETLIBUSERSETTINGS *nlus = (NETLIBUSERSETTINGS*)lParam;
- NetlibUser *nlu = (NetlibUser*)wParam;
-
- if (GetNetlibHandleType(nlu) != NLH_USER || nlus == NULL || nlus->cbSize != sizeof(NETLIBUSERSETTINGS)) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
- NetlibSaveUserSettingsStruct(nlu->user.szSettingsModule, nlus);
- return 1;
-}
-
-void NetlibDoClose(NetlibConnection *nlc, bool noShutdown)
-{
- if (nlc->s == INVALID_SOCKET) return;
-
- NetlibLogf(nlc->nlu, "(%p:%u) Connection closed internal", nlc, nlc->s);
- if (nlc->hSsl) {
- if (!noShutdown) si.shutdown(nlc->hSsl);
- si.sfree(nlc->hSsl);
- nlc->hSsl = NULL;
- }
- closesocket(nlc->s);
- nlc->s = INVALID_SOCKET;
-}
-
-INT_PTR NetlibCloseHandle(WPARAM wParam, LPARAM)
-{
- if (wParam == NULL)
- return 0;
-
- switch(GetNetlibHandleType((void*)wParam)) {
- case NLH_USER:
- {
- NetlibUser *nlu = (NetlibUser*)wParam;
- {
- mir_cslock lck(csNetlibUser);
- int i = netlibUser.getIndex(nlu);
- if (i >= 0)
- netlibUser.remove(i);
- }
-
- NetlibFreeUserSettingsStruct(&nlu->settings);
- mir_free(nlu->user.szSettingsModule);
- mir_free(nlu->user.szDescriptiveName);
- mir_free(nlu->user.szHttpGatewayHello);
- mir_free(nlu->user.szHttpGatewayUserAgent);
- mir_free(nlu->szStickyHeaders);
- break;
- }
- case NLH_CONNECTION:
- {
- NetlibConnection *nlc = (struct NetlibConnection*)wParam;
- HANDLE waitHandles[4];
- DWORD waitResult;
-
- WaitForSingleObject(hConnectionHeaderMutex, INFINITE);
- if (nlc->usingHttpGateway)
- HttpGatewayRemovePacket(nlc, -1);
- else {
- if (nlc->s != INVALID_SOCKET)
- NetlibDoClose(nlc, nlc->termRequested);
- if (nlc->s2 != INVALID_SOCKET) closesocket(nlc->s2);
- nlc->s2 = INVALID_SOCKET;
- }
- ReleaseMutex(hConnectionHeaderMutex);
-
- waitHandles[0] = hConnectionHeaderMutex;
- waitHandles[1] = nlc->hOkToCloseEvent;
- waitHandles[2] = nlc->ncsRecv.hMutex;
- waitHandles[3] = nlc->ncsSend.hMutex;
- waitResult = WaitForMultipleObjects(SIZEOF(waitHandles), waitHandles, TRUE, INFINITE);
- if (waitResult >= WAIT_OBJECT_0 + SIZEOF(waitHandles)) {
- ReleaseMutex(hConnectionHeaderMutex);
- SetLastError(ERROR_INVALID_PARAMETER); //already been closed
- return 0;
- }
- nlc->handleType = 0;
- mir_free(nlc->nlhpi.szHttpPostUrl);
- mir_free(nlc->nlhpi.szHttpGetUrl);
- mir_free(nlc->dataBuffer);
- mir_free((char*)nlc->nloc.szHost);
- mir_free(nlc->szNewUrl);
- mir_free(nlc->szProxyServer);
- NetlibDeleteNestedCS(&nlc->ncsRecv);
- NetlibDeleteNestedCS(&nlc->ncsSend);
- CloseHandle(nlc->hOkToCloseEvent);
- DeleteCriticalSection(&nlc->csHttpSequenceNums);
- ReleaseMutex(hConnectionHeaderMutex);
- NetlibLogf(nlc->nlu, "(%p:%u) Connection closed", nlc, nlc->s);
- }
- break;
-
- case NLH_BOUNDPORT:
- return NetlibFreeBoundPort((struct NetlibBoundPort*)wParam);
-
- case NLH_PACKETRECVER:
- {
- struct NetlibPacketRecver *nlpr = (struct NetlibPacketRecver*)wParam;
- mir_free(nlpr->packetRecver.buffer);
- }
- break;
-
- default:
- SetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
- mir_free((void*)wParam);
- return 1;
-}
-
-static INT_PTR NetlibGetSocket(WPARAM wParam, LPARAM)
-{
- SOCKET s;
- if (wParam == 0) {
- s = INVALID_SOCKET;
- SetLastError(ERROR_INVALID_PARAMETER);
- }
- else {
- WaitForSingleObject(hConnectionHeaderMutex, INFINITE);
- switch (GetNetlibHandleType((void*)wParam)) {
- case NLH_CONNECTION:
- s = ((struct NetlibConnection*)wParam)->s;
- break;
- case NLH_BOUNDPORT:
- s = ((struct NetlibBoundPort*)wParam)->s;
- break;
- default:
- s = INVALID_SOCKET;
- SetLastError(ERROR_INVALID_PARAMETER);
- break;
- }
- ReleaseMutex(hConnectionHeaderMutex);
- }
- return s;
-}
-
-INT_PTR NetlibStringToAddressSrv(WPARAM wParam, LPARAM lParam)
-{
- return (INT_PTR)!NetlibStringToAddress((char*)wParam, (SOCKADDR_INET_M*)lParam);
-}
-
-INT_PTR NetlibAddressToStringSrv(WPARAM wParam, LPARAM lParam)
-{
- if (wParam) {
- SOCKADDR_INET_M iaddr = {0};
- iaddr.Ipv4.sin_family = AF_INET;
- iaddr.Ipv4.sin_addr.s_addr = htonl((unsigned)lParam);
- return (INT_PTR)NetlibAddressToString(&iaddr);
- }
- return (INT_PTR)NetlibAddressToString((SOCKADDR_INET_M*)lParam);
-}
-
-INT_PTR NetlibGetConnectionInfoSrv(WPARAM wParam, LPARAM lParam)
-{
- NetlibGetConnectionInfo((NetlibConnection*)wParam, (NETLIBCONNINFO*)lParam);
- return 0;
-}
-
-INT_PTR NetlibGetMyIp(WPARAM wParam, LPARAM)
-{
- return (INT_PTR)GetMyIp((unsigned)wParam);
-}
-
-INT_PTR NetlibShutdown(WPARAM wParam, LPARAM)
-{
- if (wParam) {
- WaitForSingleObject(hConnectionHeaderMutex, INFINITE);
- switch(GetNetlibHandleType((void*)wParam)) {
- case NLH_CONNECTION:
- {
- NetlibConnection *nlc = (NetlibConnection*)wParam;
- if (!nlc->termRequested) {
- if (nlc->hSsl) si.shutdown(nlc->hSsl);
- if (nlc->s != INVALID_SOCKET) shutdown(nlc->s, 2);
- if (nlc->s2 != INVALID_SOCKET) shutdown(nlc->s2, 2);
- nlc->termRequested = true;
- }
- }
- break;
-
- case NLH_BOUNDPORT:
- struct NetlibBoundPort* nlb = (struct NetlibBoundPort*)wParam;
- if (nlb->s != INVALID_SOCKET)
- shutdown(nlb->s, 2);
- break;
- }
- ReleaseMutex(hConnectionHeaderMutex);
- }
- return 0;
-}
-
-void UnloadNetlibModule(void)
-{
- if (!bModuleInitialized || hConnectionHeaderMutex == NULL) return;
-
- NetlibUnloadIeProxy();
- NetlibUPnPDestroy();
- NetlibLogShutdown();
-
- DestroyHookableEvent(hRecvEvent); hRecvEvent = NULL;
- DestroyHookableEvent(hSendEvent); hSendEvent = NULL;
-
- for (int i = netlibUser.getCount(); i > 0; i--)
- NetlibCloseHandle((WPARAM)netlibUser[i-1], 0);
-
- CloseHandle(hConnectionHeaderMutex);
- if (hConnectionOpenMutex)
- CloseHandle(hConnectionOpenMutex);
- WSACleanup();
-}
-
-int LoadNetlibModule(void)
-{
- WSADATA wsadata;
-
- bModuleInitialized = TRUE;
-
- WSAStartup(MAKEWORD(2, 2), &wsadata);
-
- HookEvent(ME_OPT_INITIALISE, NetlibOptInitialise);
-
- hConnectionHeaderMutex = CreateMutex(NULL, FALSE, NULL);
- NetlibLogInit();
-
- connectionTimeout = 0;
-
- OSVERSIONINFOEX osvi = {0};
- osvi.dwOSVersionInfoSize = sizeof(osvi);
- if (GetVersionEx((LPOSVERSIONINFO)&osvi)) {
- // Connection limiting was introduced in Windows XP SP2 and later and set to 10 / sec
- if (osvi.dwMajorVersion == 5 && ((osvi.dwMinorVersion == 1 && osvi.wServicePackMajor >= 2) || osvi.dwMinorVersion > 1))
- connectionTimeout = 150;
- // Connection limiting has limits based on addition Windows Vista pre SP2
- else if (osvi.dwMajorVersion == 6 && osvi.wServicePackMajor < 2) {
- DWORD dwType = 0;
- tGetProductInfo pGetProductInfo = (tGetProductInfo) GetProcAddress(GetModuleHandleA("kernel32"), "GetProductInfo");
- if (pGetProductInfo != NULL) pGetProductInfo(6, 0, 0, 0, &dwType);
- switch(dwType) {
- case 0x01: // Vista Ultimate edition have connection limit of 25 / sec - plenty for Miranda
- case 0x1c:
- break;
-
- case 0x02: // Vista Home Basic edition have connection limit of 2 / sec
- case 0x05:
- connectionTimeout = 1000;
- break;
-
- default: // all other editions have connection limit of 10 / sec
- connectionTimeout = 150;
- break;
- }
- }
- // Connection limiting is disabled by default and is controlled by registry setting in Windows Vista SP2 and later
- else if (osvi.dwMajorVersion >= 6) {
- static const char keyn[] = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters";
- static const char valn[] = "EnableConnectionRateLimiting";
-
- HKEY hSettings;
- if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyn, 0, KEY_QUERY_VALUE, &hSettings) == ERROR_SUCCESS) {
- DWORD tValueLen, enabled;
- tValueLen = sizeof(enabled);
- if (RegQueryValueExA(hSettings, valn, NULL, NULL, (BYTE*)&enabled, &tValueLen) == ERROR_SUCCESS && enabled)
- connectionTimeout = 150; // if enabled limit is set to 10 / sec
- RegCloseKey(hSettings);
- }
- }
- }
-
- hConnectionOpenMutex = connectionTimeout ? CreateMutex(NULL, FALSE, NULL) : NULL;
- g_LastConnectionTick = GetTickCount();
-
- CreateServiceFunction(MS_NETLIB_REGISTERUSER, NetlibRegisterUser);
- CreateServiceFunction(MS_NETLIB_GETUSERSETTINGS, NetlibGetUserSettings);
- CreateServiceFunction(MS_NETLIB_SETUSERSETTINGS, NetlibSetUserSettings);
- CreateServiceFunction(MS_NETLIB_CLOSEHANDLE, NetlibCloseHandle);
- CreateServiceFunction(MS_NETLIB_BINDPORT, NetlibBindPort);
- CreateServiceFunction(MS_NETLIB_OPENCONNECTION, NetlibOpenConnection);
- CreateServiceFunction(MS_NETLIB_SETHTTPPROXYINFO, NetlibHttpGatewaySetInfo);
- CreateServiceFunction(MS_NETLIB_SETSTICKYHEADERS, NetlibHttpSetSticky);
- CreateServiceFunction(MS_NETLIB_GETSOCKET, NetlibGetSocket);
- CreateServiceFunction(MS_NETLIB_SENDHTTPREQUEST, NetlibHttpSendRequest);
- CreateServiceFunction(MS_NETLIB_RECVHTTPHEADERS, NetlibHttpRecvHeaders);
- CreateServiceFunction(MS_NETLIB_FREEHTTPREQUESTSTRUCT, NetlibHttpFreeRequestStruct);
- CreateServiceFunction(MS_NETLIB_HTTPTRANSACTION, NetlibHttpTransaction);
- CreateServiceFunction(MS_NETLIB_SEND, NetlibSend);
- CreateServiceFunction(MS_NETLIB_RECV, NetlibRecv);
- CreateServiceFunction(MS_NETLIB_SELECT, NetlibSelect);
- CreateServiceFunction(MS_NETLIB_SELECTEX, NetlibSelectEx);
- CreateServiceFunction(MS_NETLIB_SHUTDOWN, NetlibShutdown);
- CreateServiceFunction(MS_NETLIB_CREATEPACKETRECVER, NetlibPacketRecverCreate);
- CreateServiceFunction(MS_NETLIB_GETMOREPACKETS, NetlibPacketRecverGetMore);
- CreateServiceFunction(MS_NETLIB_SETPOLLINGTIMEOUT, NetlibHttpSetPollingTimeout);
- CreateServiceFunction(MS_NETLIB_STARTSSL, NetlibStartSsl);
- CreateServiceFunction(MS_NETLIB_STRINGTOADDRESS, NetlibStringToAddressSrv);
- CreateServiceFunction(MS_NETLIB_ADDRESSTOSTRING, NetlibAddressToStringSrv);
- CreateServiceFunction(MS_NETLIB_GETCONNECTIONINFO, NetlibGetConnectionInfoSrv);
- CreateServiceFunction(MS_NETLIB_GETMYIP, NetlibGetMyIp);
-
- hRecvEvent = CreateHookableEvent(ME_NETLIB_FASTRECV);
- hSendEvent = CreateHookableEvent(ME_NETLIB_FASTSEND);
-
- NetlibUPnPInit();
- NetlibSecurityInit();
- NetlibLoadIeProxy();
- return 0;
-}
diff --git a/src/modules/netlib/netlib.h b/src/modules/netlib/netlib.h
deleted file mode 100644
index 949d1755b2..0000000000
--- a/src/modules/netlib/netlib.h
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (ñ) 2012-15 Miranda NG project (http://miranda-ng.org),
-Copyright (c) 2000-12 Miranda IM project,
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#define NLH_INVALID 0
-#define NLH_USER 'USER'
-#define NLH_CONNECTION 'CONN'
-#define NLH_BOUNDPORT 'BIND'
-#define NLH_PACKETRECVER 'PCKT'
-int GetNetlibHandleType(void*);
-
-struct NetlibUser
-{
- int handleType;
- NETLIBUSER user;
- NETLIBUSERSETTINGS settings;
- char * szStickyHeaders;
- int toLog;
- int inportnum;
- int outportnum;
-};
-
-struct NetlibNestedCriticalSection
-{
- HANDLE hMutex;
- DWORD dwOwningThreadId;
- int lockCount;
-};
-
-struct NetlibHTTPProxyPacketQueue
-{
- NetlibHTTPProxyPacketQueue *next;
- PBYTE dataBuffer;
- int dataBufferLen;
-};
-
-typedef union _SOCKADDR_INET_M {
- SOCKADDR_IN Ipv4;
- SOCKADDR_IN6 Ipv6;
- USHORT si_family;
-} SOCKADDR_INET_M, *PSOCKADDR_INET_M;
-
-struct NetlibConnection
-{
- int handleType;
- SOCKET s, s2;
- bool usingHttpGateway;
- bool usingDirectHttpGateway;
- bool proxyAuthNeeded;
- bool dnsThroughProxy;
- bool termRequested;
- NetlibUser *nlu;
- NETLIBHTTPPROXYINFO nlhpi;
- PBYTE dataBuffer;
- int dataBufferLen;
- CRITICAL_SECTION csHttpSequenceNums;
- HANDLE hOkToCloseEvent;
- LONG dontCloseNow;
- NetlibNestedCriticalSection ncsSend, ncsRecv;
- HSSL hSsl;
- NetlibHTTPProxyPacketQueue * pHttpProxyPacketQueue;
- char *szNewUrl;
- char *szProxyServer;
- WORD wProxyPort;
- int proxyType;
- int pollingTimeout;
- unsigned lastPost;
- NETLIBOPENCONNECTION nloc;
-};
-
-struct NetlibBoundPort {
- int handleType;
- SOCKET s;
- SOCKET s6;
- WORD wPort;
- WORD wExPort;
- NetlibUser *nlu;
- NETLIBNEWCONNECTIONPROC_V2 pfnNewConnectionV2;
- HANDLE hThread;
- void *pExtra;
-};
-
-struct NetlibPacketRecver {
- int handleType;
- NetlibConnection *nlc;
- NETLIBPACKETRECVER packetRecver;
-};
-
-//netlib.c
-void NetlibFreeUserSettingsStruct(NETLIBUSERSETTINGS *settings);
-void NetlibDoClose(NetlibConnection *nlc, bool noShutdown = false);
-INT_PTR NetlibCloseHandle(WPARAM wParam, LPARAM lParam);
-void NetlibInitializeNestedCS(NetlibNestedCriticalSection *nlncs);
-void NetlibDeleteNestedCS(NetlibNestedCriticalSection *nlncs);
-#define NLNCS_SEND 0
-#define NLNCS_RECV 1
-int NetlibEnterNestedCS(NetlibConnection *nlc, int which);
-void NetlibLeaveNestedCS(NetlibNestedCriticalSection *nlncs);
-INT_PTR NetlibBase64Encode(WPARAM wParam, LPARAM lParam);
-INT_PTR NetlibBase64Decode(WPARAM wParam, LPARAM lParam);
-INT_PTR NetlibHttpUrlEncode(WPARAM wParam, LPARAM lParam);
-
-extern mir_cs csNetlibUser;
-extern LIST<NetlibUser> netlibUser;
-
-//netlibautoproxy.c
-void NetlibLoadIeProxy(void);
-void NetlibUnloadIeProxy(void);
-char* NetlibGetIeProxy(char *szUrl);
-bool NetlibGetIeProxyConn(NetlibConnection *nlc, bool forceHttps);
-
-//netlibbind.c
-int NetlibFreeBoundPort(NetlibBoundPort *nlbp);
-INT_PTR NetlibBindPort(WPARAM wParam, LPARAM lParam);
-bool BindSocketToPort(const char *szPorts, SOCKET s, SOCKET s6, int* portn);
-
-//netlibhttp.c
-INT_PTR NetlibHttpSendRequest(WPARAM wParam, LPARAM lParam);
-INT_PTR NetlibHttpRecvHeaders(WPARAM wParam, LPARAM lParam);
-INT_PTR NetlibHttpFreeRequestStruct(WPARAM wParam, LPARAM lParam);
-INT_PTR NetlibHttpTransaction(WPARAM wParam, LPARAM lParam);
-void NetlibHttpSetLastErrorUsingHttpResult(int result);
-NETLIBHTTPREQUEST* NetlibHttpRecv(NetlibConnection* nlc, DWORD hflags, DWORD dflags, bool isConnect = false);
-void NetlibConnFromUrl(const char* szUrl, bool secur, NETLIBOPENCONNECTION &nloc);
-
-//netlibhttpproxy.c
-int NetlibInitHttpConnection(NetlibConnection *nlc, NetlibUser *nlu, NETLIBOPENCONNECTION *nloc);
-int NetlibHttpGatewayRecv(NetlibConnection *nlc, char *buf, int len, int flags);
-int NetlibHttpGatewayPost(NetlibConnection *nlc, const char *buf, int len, int flags);
-void HttpGatewayRemovePacket(NetlibConnection *nlc, int pck);
-
-INT_PTR NetlibHttpGatewaySetInfo(WPARAM wParam, LPARAM lParam);
-INT_PTR NetlibHttpSetPollingTimeout(WPARAM wParam, LPARAM lParam);
-INT_PTR NetlibHttpSetSticky(WPARAM wParam, LPARAM lParam);
-
-//netliblog.c
-void NetlibLogShowOptions(void);
-void NetlibDumpData(NetlibConnection *nlc, PBYTE buf, int len, int sent, int flags);
-void NetlibLogf(NetlibUser* nlu, const char *fmt, ...);
-void NetlibLogInit(void);
-void NetlibLogShutdown(void);
-
-//netlibopenconn.c
-DWORD DnsLookup(NetlibUser *nlu, const char *szHost);
-int WaitUntilReadable(SOCKET s, DWORD dwTimeout, bool check = false);
-int WaitUntilWritable(SOCKET s, DWORD dwTimeout);
-bool NetlibDoConnect(NetlibConnection *nlc);
-bool NetlibReconnect(NetlibConnection *nlc);
-INT_PTR NetlibOpenConnection(WPARAM wParam, LPARAM lParam);
-INT_PTR NetlibStartSsl(WPARAM wParam, LPARAM lParam);
-
-//netlibopts.c
-int NetlibOptInitialise(WPARAM wParam, LPARAM lParam);
-void NetlibSaveUserSettingsStruct(const char *szSettingsModule, NETLIBUSERSETTINGS *settings);
-
-//netlibpktrecver.c
-INT_PTR NetlibPacketRecverCreate(WPARAM wParam, LPARAM lParam);
-INT_PTR NetlibPacketRecverGetMore(WPARAM wParam, LPARAM lParam);
-
-//netlibsock.c
-#define NL_SELECT_READ 0x0001
-#define NL_SELECT_WRITE 0x0002
-#define NL_SELECT_ALL (NL_SELECT_READ+NL_SELECT_WRITE)
-
-INT_PTR NetlibSend(WPARAM wParam, LPARAM lParam);
-INT_PTR NetlibRecv(WPARAM wParam, LPARAM lParam);
-INT_PTR NetlibSelect(WPARAM wParam, LPARAM lParam);
-INT_PTR NetlibSelectEx(WPARAM wParam, LPARAM lParam);
-INT_PTR NetlibShutdown(WPARAM wParam, LPARAM lParam);
-
-bool NetlibStringToAddress(const char* str, SOCKADDR_INET_M* addr);
-char* NetlibAddressToString(SOCKADDR_INET_M* addr);
-void NetlibGetConnectionInfo(NetlibConnection* nlc, NETLIBCONNINFO *connInfo);
-NETLIBIPLIST* GetMyIp(unsigned flags);
-
-//netlibupnp.c
-bool NetlibUPnPAddPortMapping(WORD intport, char *proto,
- WORD *extport, DWORD *extip, bool search);
-void NetlibUPnPDeletePortMapping(WORD extport, char* proto);
-void NetlibUPnPCleanup(void*);
-void NetlibUPnPInit(void);
-void NetlibUPnPDestroy(void);
-
-//netlibsecurity.c
-void NetlibSecurityInit(void);
-void NetlibDestroySecurityProvider(HANDLE hSecurity);
-HANDLE NetlibInitSecurityProvider(const TCHAR* szProvider, const TCHAR* szPrincipal);
-HANDLE NetlibInitSecurityProvider(const char* szProvider, const char* szPrincipal);
-char* NtlmCreateResponseFromChallenge(HANDLE hSecurity, const char *szChallenge, const TCHAR* login, const TCHAR* psw,
- bool http, unsigned& complete);
-
-static __inline INT_PTR NLSend(NetlibConnection *nlc, const char *buf, int len, int flags) {
- NETLIBBUFFER nlb = {(char*)buf, len, flags};
- return NetlibSend((WPARAM)nlc, (LPARAM)&nlb);
-}
-
-static __inline INT_PTR NLRecv(NetlibConnection *nlc, char *buf, int len, int flags) {
- NETLIBBUFFER nlb = {buf, len, flags};
- return NetlibRecv((WPARAM)nlc, (LPARAM)&nlb);
-}
diff --git a/src/modules/netlib/netlibautoproxy.cpp b/src/modules/netlib/netlibautoproxy.cpp
deleted file mode 100644
index 6410c49e74..0000000000
--- a/src/modules/netlib/netlibautoproxy.cpp
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (ñ) 2012-15 Miranda NG project (http://miranda-ng.org),
-Copyright (c) 2000-12 Miranda IM project,
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "..\..\core\commonheaders.h"
-#include "netlib.h"
-
-#include <wininet.h>
-
-/*
-/////////////////////////////////////////////////////////////////////
-// ResolveHostName (a helper function)
-/////////////////////////////////////////////////////////////////////
-DWORD __stdcall ResolveHostName(LPSTR lpszHostName,
- LPSTR lpszIPAddress, LPDWORD lpdwIPAddressSize)
-{
- if (*lpdwIPAddressSize < 17 || lpszIPAddress == NULL)
- {
- *lpdwIPAddressSize = 17;
- return ERROR_INSUFFICIENT_BUFFER;
- }
-
- IN_ADDR ip;
- ip.s_addr = inet_addr(lpszHostName);
- if (ip.s_addr == INADDR_NONE)
- {
- PHOSTENT myhost = gethostbyname(lpszHostName);
- if (myhost != NULL)
- ip = *(PIN_ADDR)myhost->h_addr;
- else
- return SOCKET_ERROR;
- }
- mir_snprintf(lpszIPAddress, *lpdwIPAddressSize, "%u.%u.%u.%u",
- ip.s_net, ip.s_host, ip.s_lh, ip.s_impno);
-
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////
-// IsResolvable (a helper function)
-/////////////////////////////////////////////////////////////////////
-BOOL __stdcall IsResolvable(LPSTR lpszHost)
-{
- char szDummy[255];
- DWORD dwDummySize = sizeof (szDummy) - 1;
-
- if (ResolveHostName(lpszHost, szDummy, &dwDummySize))
- return FALSE;
- return TRUE;
-}
-
-/////////////////////////////////////////////////////////////////////
-// GetIPAddress (a helper function)
-/////////////////////////////////////////////////////////////////////
-DWORD __stdcall GetIPAddress(LPSTR lpszIPAddress, LPDWORD lpdwIPAddressSize)
-{
- char szHostBuffer[255];
-
- if (gethostname(szHostBuffer, sizeof (szHostBuffer) - 1) != ERROR_SUCCESS)
- return (ERROR_INTERNET_INTERNAL_ERROR);
- return (ResolveHostName(szHostBuffer, lpszIPAddress, lpdwIPAddressSize));
-}
-
-/////////////////////////////////////////////////////////////////////
-// IsInNet (a helper function)
-/////////////////////////////////////////////////////////////////////
-BOOL __stdcall IsInNet(LPSTR lpszIPAddress, LPSTR lpszDest, LPSTR lpszMask)
-{
- DWORD dwDest;
- DWORD dwIpAddr;
- DWORD dwMask;
-
- dwIpAddr = inet_addr(lpszIPAddress);
- dwDest = inet_addr(lpszDest);
- dwMask = inet_addr(lpszMask);
-
- if ((dwDest == INADDR_NONE) ||
- (dwIpAddr == INADDR_NONE) || ((dwIpAddr & dwMask) != dwDest))
- return (FALSE);
-
- return (TRUE);
-}
-
-static const AutoProxyHelperVtbl OurVtbl =
-{
- IsResolvable,
- GetIPAddress,
- ResolveHostName,
- IsInNet,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-static AutoProxyHelperFunctions HelperFunctions = { &OurVtbl };
-*/
-
-static char *szProxyHost[3];
-static LIST<char> proxyBypass(5);
-
-static HMODULE hModJS;
-
-static pfnInternetInitializeAutoProxyDll pInternetInitializeAutoProxyDll;
-static pfnInternetDeInitializeAutoProxyDll pInternetDeInitializeAutoProxyDll;
-static pfnInternetGetProxyInfo pInternetGetProxyInfo;
-
-static bool bEnabled, bOneProxy;
-
-static void GetFile(char* szUrl, AUTO_PROXY_SCRIPT_BUFFER &buf)
-{
- NetlibUser nlu = {0};
- NETLIBHTTPREQUEST nlhr = {0};
-
- nlu.handleType = NLH_USER;
- nlu.user.flags = NUF_OUTGOING | NUF_HTTPCONNS;
- nlu.user.szSettingsModule = "(NULL)";
- nlu.toLog = 1;
-
- // initialize the netlib request
- nlhr.cbSize = sizeof(nlhr);
- nlhr.requestType = REQUEST_GET;
- nlhr.flags = NLHRF_HTTP11 | NLHRF_DUMPASTEXT | NLHRF_REDIRECT;
- nlhr.szUrl = szUrl;
-
- // download the page
- NETLIBHTTPREQUEST *nlhrReply = (NETLIBHTTPREQUEST*)NetlibHttpTransaction((WPARAM)&nlu, (LPARAM)&nlhr);
-
- if (nlhrReply)
- {
- if (nlhrReply->resultCode == 200)
- {
- buf.lpszScriptBuffer = nlhrReply->pData;
- buf.dwScriptBufferSize = nlhrReply->dataLength + 1;
-
- nlhrReply->dataLength = 0;
- nlhrReply->pData = NULL;
- }
- CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)nlhrReply);
- }
-}
-
-bool NetlibGetIeProxyConn(NetlibConnection *nlc, bool forceHttps)
-{
- bool noHttp = false;
- bool usingSsl = false;
- char szUrl[256];
-
- if ((nlc->nloc.flags & (NLOCF_HTTP | NLOCF_HTTPGATEWAY) && nlc->nloc.flags & NLOCF_SSL) ||
- nlc->nloc.wPort == 443 || forceHttps)
- {
- mir_snprintf(szUrl, "https://%s", nlc->nloc.szHost);
- usingSsl = true;
- }
- else if (nlc->nloc.flags & (NLOCF_HTTPGATEWAY | NLOCF_HTTP) || nlc->usingHttpGateway)
- mir_snprintf(szUrl, "http://%s", nlc->nloc.szHost);
- else
- {
- strncpy_s(szUrl, nlc->nloc.szHost, _TRUNCATE);
- noHttp = true;
- }
-
- mir_free(nlc->szProxyServer); nlc->szProxyServer = NULL;
- nlc->wProxyPort = 0;
- nlc->proxyType = 0;
-
- char *mt = NetlibGetIeProxy(szUrl);
- char *m = NEWSTR_ALLOCA(mt);
- mir_free(mt);
-
- if (m == NULL) return false;
-
- // if multiple servers, use the first one
- char *c = strchr(m, ';'); if (c) *c = 0;
-
- // if 'direct' no proxy
- if (_stricmp(lrtrim(m), "direct") == 0) return false;
-
- // find proxy address
- char *h = strchr(m, ' ');
- if (h) { *h = 0; ++h; } else return false;
-
- // find proxy port
- char *p = strchr(h, ':');
- if (p) { *p = 0; ++p; }
-
- lrtrim(h); ltrim(p);
- if (_stricmp(m, "proxy") == 0 && h[0])
- {
- nlc->proxyType = (usingSsl || noHttp) ? PROXYTYPE_HTTPS : PROXYTYPE_HTTP;
- nlc->wProxyPort = p ? atol(p) : 8080;
- nlc->szProxyServer = mir_strdup(h);
- }
- else if (_stricmp(m, "socks") == 0 && h[0])
- {
- nlc->proxyType = PROXYTYPE_SOCKS4;
- nlc->wProxyPort = p ? atol(p) : 1080;
- nlc->szProxyServer = mir_strdup(h);
- }
- else if (_stricmp(m, "socks5") == 0 && h[0])
- {
- nlc->proxyType = PROXYTYPE_SOCKS5;
- nlc->wProxyPort = p ? atol(p) : 1080;
- nlc->szProxyServer = mir_strdup(h);
- }
- else
- return false;
-
- return true;
-}
-
-static char szAutoUrlStr[MAX_PATH] = "";
-static AUTO_PROXY_SCRIPT_BUFFER abuf = {0};
-static HANDLE hIeProxyMutex;
-static bool bAutoProxyInit;
-
-static void NetlibInitAutoProxy(void)
-{
- if (bAutoProxyInit) return;
-
- if (!hModJS)
- {
- if (!(hModJS = LoadLibraryA("jsproxy.dll")))
- return;
-
- pInternetInitializeAutoProxyDll = (pfnInternetInitializeAutoProxyDll)
- GetProcAddress(hModJS, "InternetInitializeAutoProxyDll");
-
- pInternetDeInitializeAutoProxyDll = (pfnInternetDeInitializeAutoProxyDll)
- GetProcAddress(hModJS, "InternetDeInitializeAutoProxyDll");
-
- pInternetGetProxyInfo = (pfnInternetGetProxyInfo)
- GetProcAddress(hModJS, "InternetGetProxyInfo");
- }
-
- if (strstr(szAutoUrlStr, "file://") == NULL && strstr(szAutoUrlStr, "://") != NULL)
- {
- abuf.dwStructSize = sizeof(abuf);
- GetFile(szAutoUrlStr, abuf);
- }
- bAutoProxyInit = true;
-}
-
-struct IeProxyParam
-{
- char *szUrl;
- char *szHost;
- char *szProxy;
-};
-
-static void NetlibIeProxyThread(void *arg)
-{
- IeProxyParam *param = (IeProxyParam*)arg;
- param->szProxy = NULL;
-
- if (!bAutoProxyInit) {
- WaitForSingleObject(hIeProxyMutex, INFINITE);
- NetlibInitAutoProxy();
- ReleaseMutex(hIeProxyMutex);
- }
-
- BOOL res;
- char *loc = strstr(szAutoUrlStr, "file://");
- if (loc || strstr(szAutoUrlStr, "://") == NULL) {
- NetlibLogf(NULL, "Autoproxy Init file: %s", loc);
- loc = loc ? loc + 7 : szAutoUrlStr;
- res = pInternetInitializeAutoProxyDll(0, loc, NULL, NULL /*&HelperFunctions*/, NULL);
- }
- else {
- NetlibLogf(NULL, "Autoproxy Init %d", abuf.dwScriptBufferSize);
- if (abuf.dwScriptBufferSize)
- res = pInternetInitializeAutoProxyDll(0, NULL, NULL, NULL /*&HelperFunctions*/, &abuf);
- else
- res = false;
- }
-
- if (res) {
- char proxyBuffer[1024];
- char *proxy = proxyBuffer;
- DWORD dwProxyLen = sizeof(proxyBuffer);
-
- if (pInternetGetProxyInfo(param->szUrl, (DWORD)mir_strlen(param->szUrl),
- param->szHost, (DWORD)mir_strlen(param->szHost), &proxy, &dwProxyLen))
- param->szProxy = mir_strdup(lrtrim(proxy));
-
- NetlibLogf(NULL, "Autoproxy got response %s, Param: %s %s", param->szProxy, param->szUrl, param->szHost);
- pInternetDeInitializeAutoProxyDll(NULL, 0);
- }
- else NetlibLogf(NULL, "Autoproxy init failed");
-}
-
-char* NetlibGetIeProxy(char *szUrl)
-{
- char *res = NULL;
- char* p = strstr(szUrl, "://");
- if (p) p += 3; else p = szUrl;
-
- char *szHost = NEWSTR_ALLOCA(p);
- p = strchr(szHost, '/'); if (p) *p = 0;
- p = strchr(szHost, ':'); if (p) *p = 0;
- _strlwr(szHost);
-
- if (bEnabled)
- {
- for (int i=0; i < proxyBypass.getCount(); i++)
- {
- if (mir_strcmp(proxyBypass[i], "<local>") == 0)
- {
- if (strchr(szHost, '.') == NULL) return NULL;
- }
- else if (wildcmp(szHost, proxyBypass[i])) return NULL;
- }
-
- int ind = -1;
- if (strstr(szUrl, "http://"))
- ind = szProxyHost[0] ? 0 : 2;
- else if (strstr(szUrl, "https://"))
- ind = bOneProxy ? 0 : (szProxyHost[1] ? 1 : 2);
- else
- ind = szProxyHost[2] ? 2 : (bOneProxy ? 0 : (szProxyHost[1] ? 1 : 2));
-
- if (ind < 0 || !szProxyHost[ind]) return NULL;
-
- size_t len = mir_strlen(szHost) + 20;
- res = (char*)mir_alloc(len);
- mir_snprintf(res, len, "%s %s", ind == 2 ? "SOCKS" : "PROXY", szProxyHost[ind]);
- return res;
- }
-
- if (szAutoUrlStr[0]) {
- IeProxyParam param = { szUrl, szHost, NULL };
- HANDLE hThread = mir_forkthread(NetlibIeProxyThread, &param);
- WaitForSingleObject(hThread, INFINITE);
- res = param.szProxy;
- }
- return res;
-}
-
-void NetlibLoadIeProxy(void)
-{
- HKEY hSettings;
- if (RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
- 0, KEY_QUERY_VALUE, &hSettings))
- return;
-
- DWORD tValueLen, enabled = 0;
- char szHostStr[256] = "", szProxyBypassStr[4096] = "";
-
- tValueLen = sizeof(enabled);
- int tResult = RegQueryValueExA(hSettings, "ProxyEnable", NULL, NULL, (BYTE*)&enabled, &tValueLen);
- bEnabled = enabled && tResult == ERROR_SUCCESS;
-
- tValueLen = SIZEOF(szHostStr);
- tResult = RegQueryValueExA(hSettings, "ProxyServer", NULL, NULL, (BYTE*)szHostStr, &tValueLen);
- bEnabled = bEnabled && tResult == ERROR_SUCCESS;
-
- tValueLen = SIZEOF(szAutoUrlStr);
- RegQueryValueExA(hSettings, "AutoConfigUrl", NULL, NULL, (BYTE*)szAutoUrlStr, &tValueLen);
-
- tValueLen = SIZEOF(szProxyBypassStr);
- RegQueryValueExA(hSettings, "ProxyOverride", NULL, NULL, (BYTE*)szProxyBypassStr, &tValueLen);
-
- RegCloseKey(hSettings);
-
- if (bEnabled)
- {
- char* szProxy = ltrim(szHostStr);
- if (szProxy[0] == 0) { enabled = false; return; }
-
- while(true)
- {
- char *szProxyEnd = strchr(szProxy, ';');
- if (szProxyEnd) *szProxyEnd = 0;
-
- int ind = -1;
- if (strncmp(szProxy, "http = ", 5) == 0) { ind = 0; szProxy += 5; }
- else if (strncmp(szProxy, "https = ", 6) == 0) { ind = 1; szProxy += 6; }
- else if (strncmp(szProxy, "socks = ", 6) == 0) { ind = 2; szProxy += 6; }
- else if (strchr(szProxy, '=')) ind = -2;
-
- if (ind != -2)
- {
- bOneProxy = ind < 0; if (ind < 0) ind = 0;
-
- lrtrim(szProxy);
-
- if (strchr(szProxy, ':'))
- szProxyHost[ind] = mir_strdup(szProxy);
- else
- {
- size_t len = mir_strlen(szProxy) + 10;
- szProxyHost[ind] = (char*)mir_alloc(len);
- mir_snprintf(szProxyHost[ind], len, "%s:%u", szProxy, ind == 2 ? 1080 : 8080);
- }
- if (bOneProxy) break;
- }
- if (szProxyEnd == NULL) break;
- szProxy = szProxyEnd + 1;
- }
-
- char* szProxyBypass = szProxyBypassStr;
- while(true)
- {
- char *szProxyBypassEnd = strchr(szProxyBypass, ';');
- if (szProxyBypassEnd) *szProxyBypassEnd = 0;
-
- lrtrim(szProxyBypass);
-
- proxyBypass.insert(_strlwr(mir_strdup(szProxyBypass)));
- if (szProxyBypassEnd == NULL) break;
-
- szProxyBypass = szProxyBypassEnd + 1;
- }
- }
-
- if (bEnabled || szAutoUrlStr[0])
- hIeProxyMutex = CreateMutex(NULL, FALSE, NULL);
-}
-
-void NetlibUnloadIeProxy(void)
-{
- int i;
-
- for (i=0; i < 3; i++)
- mir_free(szProxyHost[i]);
-
- for (i=0; i < proxyBypass.getCount(); i++)
- mir_free(proxyBypass[i]);
-
- mir_free(abuf.lpszScriptBuffer);
-
- CloseHandle(hIeProxyMutex);
-}
diff --git a/src/modules/netlib/netlibbind.cpp b/src/modules/netlib/netlibbind.cpp
deleted file mode 100644
index 699799dd17..0000000000
--- a/src/modules/netlib/netlibbind.cpp
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (ñ) 2012-15 Miranda NG project (http://miranda-ng.org),
-Copyright (c) 2000-12 Miranda IM project,
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "..\..\core\commonheaders.h"
-#include "netlib.h"
-
-bool BindSocketToPort(const char *szPorts, SOCKET s, SOCKET s6, int* portn)
-{
- SOCKADDR_IN sin = {0};
- sin.sin_family = AF_INET;
-
- SOCKADDR_IN6 sin6 = {0};
- sin6.sin6_family = AF_INET6;
-
- mir_cslock lck(csNetlibUser);
-
- if (--*portn < 0 && (s != INVALID_SOCKET || s6 != INVALID_SOCKET)) {
- BindSocketToPort(szPorts, INVALID_SOCKET, INVALID_SOCKET, portn);
- if (*portn == 0)
- return false;
-
- WORD num;
- CallService(MS_UTILS_GETRANDOM, sizeof(WORD), (LPARAM)&num);
- *portn = num % *portn;
- }
-
- bool before = false;
- while (true) {
- const char *psz;
- char *pszEnd;
- int portMin, portMax, port, portnum = 0;
-
- for (psz = szPorts;*psz;) {
- while (*psz == ' ' || *psz == ',') psz++;
- portMin = strtol(psz, &pszEnd, 0);
- if (pszEnd == psz)
- break;
- while (*pszEnd == ' ')
- pszEnd++;
- if (*pszEnd == '-') {
- psz = pszEnd + 1;
- portMax = strtol(psz, &pszEnd, 0);
- if (pszEnd == psz) portMax = 65535;
- if (portMin > portMax) {
- port = portMin;
- portMin = portMax;
- portMax = port;
- }
- }
- else portMax = portMin;
- if (portMax >= 1) {
- if (portMin <= 0) portMin = 1;
- for (port = portMin; port <= portMax; port++) {
- if (port > 65535)
- break;
-
- ++portnum;
-
- if (s == INVALID_SOCKET) continue;
- if (!before && portnum <= *portn) continue;
- if (before && portnum >= *portn)
- return false;
-
- sin.sin_port = htons((WORD)port);
- bool bV4Mapped = s == INVALID_SOCKET || bind(s, (SOCKADDR*)&sin, sizeof(sin)) == 0;
-
- sin6.sin6_port = htons((WORD)port);
- bool bV6Mapped = s6 == INVALID_SOCKET || bind(s6, (PSOCKADDR)&sin6, sizeof(sin6)) == 0;
-
- if (bV4Mapped && bV6Mapped) {
- *portn = portnum + 1;
- return true;
- }
- }
- }
- psz = pszEnd;
- }
-
- if (*portn < 0) {
- *portn = portnum;
- return true;
- }
-
- if (*portn >= portnum)
- *portn = 0;
- else
- before = true;
- }
-}
-
-int NetlibFreeBoundPort(struct NetlibBoundPort *nlbp)
-{
- closesocket(nlbp->s);
- closesocket(nlbp->s6);
- if (nlbp->hThread)
- WaitForSingleObject(nlbp->hThread, INFINITE);
- NetlibLogf(nlbp->nlu, "(%u) Port %u closed for incoming connections", nlbp->s, nlbp->wPort);
- mir_free(nlbp);
- return 1;
-}
-
-static void NetlibBindAcceptThread(void* param)
-{
- NetlibBoundPort *nlbp = (NetlibBoundPort*)param;
- NetlibLogf(nlbp->nlu, "(%u) Port %u opened for incoming connections", nlbp->s, nlbp->wPort);
-
- while (true) {
- fd_set r;
- FD_ZERO(&r);
- if (nlbp->s != INVALID_SOCKET)
- FD_SET(nlbp->s, &r);
- if (nlbp->s6 != INVALID_SOCKET)
- FD_SET(nlbp->s6, &r);
- if (select(0, &r, NULL, NULL, NULL) == SOCKET_ERROR) {
- NetlibLogf(nlbp->nlu, "NetlibBindAcceptThread (%p): select failed (%d)", nlbp->s, GetLastError());
- break;
- }
-
- SOCKADDR_INET_M sin;
- int sinLen = sizeof(sin);
- memset(&sin, 0, sizeof(sin));
-
- SOCKET s;
- if (FD_ISSET(nlbp->s, &r)) {
- s = accept(nlbp->s, (sockaddr*)&sin, &sinLen);
- if (s == INVALID_SOCKET) {
- NetlibLogf(nlbp->nlu, "NetlibBindAcceptThread (%p): accept V4 failed (%d)", nlbp->s, GetLastError());
- break;
- }
- }
- else if (FD_ISSET(nlbp->s6, &r)) {
- s = accept(nlbp->s6, (sockaddr*)&sin, &sinLen);
- if (s == INVALID_SOCKET) {
- NetlibLogf(nlbp->nlu, "NetlibBindAcceptThread (%p): accept V6 failed (%d)", nlbp->s, GetLastError());
- break;
- }
- }
-
- NetlibLogf(nlbp->nlu, "New incoming connection on port %u from %s (%p)", nlbp->wPort, ptrA(NetlibAddressToString(&sin)), s);
-
- NetlibConnection *nlc = (NetlibConnection*)mir_calloc(sizeof(NetlibConnection));
- nlc->handleType = NLH_CONNECTION;
- nlc->nlu = nlbp->nlu;
- nlc->s = s;
- nlc->s2 = INVALID_SOCKET;
- InitializeCriticalSection(&nlc->csHttpSequenceNums);
- nlc->hOkToCloseEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
- NetlibInitializeNestedCS(&nlc->ncsSend);
- NetlibInitializeNestedCS(&nlc->ncsRecv);
-
- if (nlbp->pfnNewConnectionV2)
- nlbp->pfnNewConnectionV2(nlc, ntohl(sin.Ipv4.sin_addr.S_un.S_addr), nlbp->pExtra);
- }
-
- NetlibUPnPDeletePortMapping(nlbp->wExPort, "TCP");
- nlbp->hThread = 0;
-
- NetlibLogf(nlbp->nlu, "NetlibBindAcceptThread: (%p) thread for port %u closed", nlbp->s, nlbp->wPort);
-}
-
-INT_PTR NetlibBindPort(WPARAM wParam, LPARAM lParam)
-{
- NETLIBBIND *nlb = (NETLIBBIND*)lParam;
- NetlibUser *nlu = (NetlibUser*)wParam;
- struct NetlibBoundPort *nlbp;
- SOCKADDR_IN sin = { 0 };
- SOCKADDR_IN6 sin6 = { 0 };
- int foundPort = 0;
-
- if (GetNetlibHandleType(nlu) != NLH_USER || !(nlu->user.flags & NUF_INCOMING) ||
- nlb == NULL || nlb->pfnNewConnection == NULL) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
- if (nlb->cbSize != sizeof(NETLIBBIND))
- return 0;
-
- nlbp = (NetlibBoundPort*)mir_calloc(sizeof(NetlibBoundPort));
- nlbp->handleType = NLH_BOUNDPORT;
- nlbp->nlu = nlu;
- nlbp->pfnNewConnectionV2 = nlb->pfnNewConnectionV2;
-
- nlbp->s = socket(PF_INET, SOCK_STREAM, 0);
- nlbp->s6 = socket(PF_INET6, SOCK_STREAM, 0);
- nlbp->pExtra = nlb->pExtra;
- if (nlbp->s == INVALID_SOCKET && nlbp->s6 == INVALID_SOCKET) {
- NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "socket", WSAGetLastError());
- mir_free(nlbp);
- return 0;
- }
- sin.sin_family = AF_INET;
- sin6.sin6_family = AF_INET6;
-
- /* if the netlib user wanted a free port given in the range, then
- they better have given wPort == 0, let's hope so */
- if (nlu->settings.specifyIncomingPorts && nlu->settings.szIncomingPorts && nlb->wPort == 0) {
- if (!BindSocketToPort(nlu->settings.szIncomingPorts, nlbp->s, nlbp->s6, &nlu->outportnum)) {
- NetlibLogf(nlu, "Netlib bind: Not enough ports for incoming connections specified");
- SetLastError(WSAEADDRINUSE);
- }
- else foundPort = 1;
- }
- else {
- /* if ->wPort == 0 then they'll get any free port, otherwise they'll
- be asking for whatever was in nlb->wPort*/
- if (nlb->wPort != 0) {
- NetlibLogf(nlu, "%s %d: trying to bind port %d, this 'feature' can be abused, please be sure you want to allow it.", __FILE__, __LINE__, nlb->wPort);
- sin.sin_port = htons(nlb->wPort);
- sin6.sin6_port = htons(nlb->wPort);
- }
-
- if (nlbp->s != INVALID_SOCKET)
- if (bind(nlbp->s, (PSOCKADDR)&sin, sizeof(sin)) == 0) {
- SOCKADDR_IN sin = { 0 };
- int len = sizeof(sin);
- if (!getsockname(nlbp->s, (PSOCKADDR)&sin, &len))
- sin6.sin6_port = sin.sin_port;
- foundPort = 1;
- }
-
- if (nlbp->s6 != INVALID_SOCKET)
- if (bind(nlbp->s6, (PSOCKADDR)&sin6, sizeof(sin6)) == 0)
- foundPort = 1;
- }
- if (!foundPort) {
- NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "bind", WSAGetLastError());
-LBL_Error:
- closesocket(nlbp->s);
- closesocket(nlbp->s6);
- mir_free(nlbp);
- return 0;
- }
-
- if (nlbp->s != INVALID_SOCKET && listen(nlbp->s, 5)) {
- NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "listen", WSAGetLastError());
- goto LBL_Error;
- }
-
- if (nlbp->s6 != INVALID_SOCKET && listen(nlbp->s6, 5)) {
- NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "listen", WSAGetLastError());
- goto LBL_Error;
- }
-
- SOCKADDR_INET_M sinm = { 0 };
- int len = sizeof(sinm);
- if (!getsockname(nlbp->s, (PSOCKADDR)&sinm, &len)) {
- nlb->wPort = ntohs(sinm.Ipv4.sin_port);
- nlb->dwInternalIP = ntohl(sinm.Ipv4.sin_addr.S_un.S_addr);
- }
- else if (!getsockname(nlbp->s6, (PSOCKADDR)&sinm, &len))
- nlb->wPort = ntohs(sinm.Ipv6.sin6_port);
- else {
- NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "getsockname", WSAGetLastError());
- goto LBL_Error;
- }
- nlbp->wPort = nlb->wPort;
-
- if (nlb->dwInternalIP == 0) {
- char hostname[64] = "";
- gethostname(hostname, SIZEOF(hostname));
-
- PHOSTENT he = gethostbyname(hostname);
- if (he && he->h_addr)
- nlb->dwInternalIP = ntohl(*(PDWORD)he->h_addr);
- }
-
- DWORD extIP;
- if (nlu->settings.enableUPnP && NetlibUPnPAddPortMapping(nlb->wPort, "TCP", &nlbp->wExPort, &extIP, true)) {
- NetlibLogf(NULL, "UPnP port mapping succeeded. Internal Port: %u External Port: %u\n", nlb->wPort, nlbp->wExPort);
- nlb->wExPort = nlbp->wExPort;
- nlb->dwExternalIP = extIP;
- }
- else {
- if (nlu->settings.enableUPnP)
- NetlibLogf(NULL, "UPnP port mapping failed. Internal Port: %u\n", nlb->wPort);
- else
- NetlibLogf(NULL, "UPnP disabled. Internal Port: %u\n", nlb->wPort);
-
- nlbp->wExPort = 0;
- nlb->wExPort = nlb->wPort;
- nlb->dwExternalIP = nlb->dwInternalIP;
- }
-
- nlbp->hThread = mir_forkthread(NetlibBindAcceptThread, nlbp);
- return (INT_PTR)nlbp;
-}
diff --git a/src/modules/netlib/netlibhttp.cpp b/src/modules/netlib/netlibhttp.cpp
deleted file mode 100644
index 3fe48d5dc1..0000000000
--- a/src/modules/netlib/netlibhttp.cpp
+++ /dev/null
@@ -1,1168 +0,0 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (ñ) 2012-15 Miranda NG project (http://miranda-ng.org),
-Copyright (c) 2000-12 Miranda IM project,
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "..\..\core\commonheaders.h"
-#include "../plugins/zlib/src/zlib.h"
-#include "netlib.h"
-
-#define HTTPRECVHEADERSTIMEOUT 30000 //in ms
-#define HTTPRECVDATATIMEOUT 20000
-
-struct ResizableCharBuffer
-{
- char *sz;
- int iEnd, cbAlloced;
-};
-
-struct ProxyAuth
-{
- char *szServer;
- char *szMethod;
-// char *szUserName;
-// char *szPassword;
-
- ProxyAuth(const char *pszServer, const char *pszMethod)
- {
- szServer = mir_strdup(pszServer);
- szMethod = mir_strdup(pszMethod);
- }
- ~ProxyAuth()
- {
- mir_free(szServer);
- mir_free(szMethod);
- }
- static int Compare(const ProxyAuth* p1, const ProxyAuth* p2)
- { return mir_strcmpi(p1->szServer, p2->szServer); }
-};
-
-struct ProxyAuthList : OBJLIST<ProxyAuth>
-{
- ProxyAuthList() : OBJLIST<ProxyAuth>(2, ProxyAuth::Compare) {}
-
- void add(const char *szServer, const char *szMethod)
- {
- if (szServer == NULL) return;
- int i = getIndex((ProxyAuth*)&szServer);
- if (i >= 0) {
- ProxyAuth &rec = (*this)[i];
- if (szMethod == NULL)
- remove(i);
- else if (_stricmp(rec.szMethod, szMethod)) {
- mir_free(rec.szMethod);
- rec.szMethod = mir_strdup(szMethod);
- }
- }
- else insert(new ProxyAuth(szServer, szMethod));
- }
-
- const char* find(const char *szServer)
- {
- ProxyAuth * rec = szServer ? OBJLIST<ProxyAuth>::find((ProxyAuth*)&szServer) : NULL;
- return rec ? rec->szMethod : NULL;
- }
-};
-
-ProxyAuthList proxyAuthList;
-
-static void AppendToCharBuffer(struct ResizableCharBuffer *rcb, const char *fmt, ...)
-{
- va_list va;
- int charsDone;
-
- if (rcb->cbAlloced == 0) {
- rcb->cbAlloced = 512;
- rcb->sz = (char*)mir_alloc(rcb->cbAlloced);
- }
- va_start(va, fmt);
- while (true) {
- charsDone = mir_vsnprintf(rcb->sz + rcb->iEnd, rcb->cbAlloced-rcb->iEnd, fmt, va);
- if (charsDone >= 0) break;
- rcb->cbAlloced += 512;
- rcb->sz = (char*)mir_realloc(rcb->sz, rcb->cbAlloced);
- }
- va_end(va);
- rcb->iEnd += charsDone;
-}
-
-static int RecvWithTimeoutTime(NetlibConnection *nlc, unsigned dwTimeoutTime, char *buf, int len, int flags)
-{
- DWORD dwTimeNow;
-
- if (!si.pending(nlc->hSsl)) {
- while ((dwTimeNow = GetTickCount()) < dwTimeoutTime) {
- unsigned dwDeltaTime = min(dwTimeoutTime - dwTimeNow, 1000);
- int res = WaitUntilReadable(nlc->s, dwDeltaTime);
-
- switch (res) {
- case SOCKET_ERROR:
- return SOCKET_ERROR;
-
- case 1:
- return NLRecv(nlc, buf, len, flags);
- }
-
- if (nlc->termRequested || Miranda_Terminated())
- return 0;
- }
- SetLastError(ERROR_TIMEOUT);
- return SOCKET_ERROR;
- }
- return NLRecv(nlc, buf, len, flags);
-}
-
-static char* NetlibHttpFindHeader(NETLIBHTTPREQUEST *nlhrReply, const char *hdr)
-{
- for (int i=0; i < nlhrReply->headersCount; i++) {
- NETLIBHTTPHEADER &p = nlhrReply->headers[i];
- if (_stricmp(p.szName, hdr) == 0)
- return p.szValue;
- }
-
- return NULL;
-}
-
-static char* NetlibHttpFindAuthHeader(NETLIBHTTPREQUEST *nlhrReply, const char *hdr, const char *szProvider)
-{
- char *szBasicHdr = NULL;
- char *szNegoHdr = NULL;
- char *szNtlmHdr = NULL;
-
- for (int i=0; i < nlhrReply->headersCount; i++) {
- NETLIBHTTPHEADER &p = nlhrReply->headers[i];
- if (_stricmp(p.szName, hdr) == 0) {
- if (_strnicmp(p.szValue, "Negotiate", 9) == 0)
- szNegoHdr = p.szValue;
- else if (_strnicmp(p.szValue, "NTLM", 4) == 0)
- szNtlmHdr = p.szValue;
- else if (_strnicmp(p.szValue, "Basic", 5) == 0)
- szBasicHdr = p.szValue;
- }
- }
-
- if (szNegoHdr && (!szProvider || !_stricmp(szProvider, "Negotiate"))) return szNegoHdr;
- if (szNtlmHdr && (!szProvider || !_stricmp(szProvider, "NTLM"))) return szNtlmHdr;
- if (!szProvider || !_stricmp(szProvider, "Basic")) return szBasicHdr;
- return NULL;
-}
-
-void NetlibConnFromUrl(const char* szUrl, bool secur, NETLIBOPENCONNECTION &nloc)
-{
- secur = secur || _strnicmp(szUrl, "https", 5) == 0;
- const char* phost = strstr(szUrl, "://");
-
- char* szHost = mir_strdup(phost ? phost + 3 : szUrl);
-
- char* ppath = strchr(szHost, '/');
- if (ppath) *ppath = '\0';
-
- memset(&nloc, 0, sizeof(nloc));
- nloc.cbSize = sizeof(nloc);
- nloc.szHost = szHost;
-
- char* pcolon = strrchr(szHost, ':');
- if (pcolon) {
- *pcolon = '\0';
- nloc.wPort = (WORD)strtol(pcolon+1, NULL, 10);
- }
- else nloc.wPort = secur ? 443 : 80;
- nloc.flags = (secur ? NLOCF_SSL : 0);
-}
-
-static NetlibConnection* NetlibHttpProcessUrl(NETLIBHTTPREQUEST *nlhr, NetlibUser *nlu, NetlibConnection* nlc, const char* szUrl = NULL)
-{
- NETLIBOPENCONNECTION nloc;
-
- if (szUrl == NULL)
- NetlibConnFromUrl(nlhr->szUrl, (nlhr->flags & NLHRF_SSL) != 0, nloc);
- else
- NetlibConnFromUrl(szUrl, false, nloc);
-
- nloc.flags |= NLOCF_HTTP;
- if (nloc.flags & NLOCF_SSL) nlhr->flags |= NLHRF_SSL; else nlhr->flags &= ~NLHRF_SSL;
-
- if (nlc != NULL) {
- bool httpProxy = !(nloc.flags & NLOCF_SSL) && nlc->proxyType == PROXYTYPE_HTTP;
- bool sameHost = mir_strcmp(nlc->nloc.szHost, nloc.szHost) == 0 && nlc->nloc.wPort == nloc.wPort;
-
- if (!httpProxy && !sameHost) {
- NetlibDoClose(nlc);
-
- mir_free((char*)nlc->nloc.szHost);
- nlc->nloc = nloc;
- return NetlibDoConnect(nlc) ? nlc : NULL;
- }
- }
- else nlc = (NetlibConnection*)NetlibOpenConnection((WPARAM)nlu, (LPARAM)&nloc);
-
- mir_free((char*)nloc.szHost);
-
- return nlc;
-}
-
-struct HttpSecurityContext
-{
- HANDLE m_hNtlmSecurity;
- char *m_szHost;
- char *m_szProvider;
-
- HttpSecurityContext()
- { m_hNtlmSecurity = NULL; m_szHost = NULL; m_szProvider = NULL; }
-
- ~HttpSecurityContext() { Destroy(); }
-
- void Destroy(void)
- {
- if (!m_hNtlmSecurity) return;
-
- NetlibDestroySecurityProvider(m_hNtlmSecurity);
- m_hNtlmSecurity = NULL;
- mir_free(m_szHost); m_szHost = NULL;
- mir_free(m_szProvider); m_szProvider = NULL;
- }
-
- bool TryBasic(void)
- {
- return m_hNtlmSecurity && m_szProvider && _stricmp(m_szProvider, "Basic");
- }
-
- char* Execute(NetlibConnection *nlc, char* szHost, const char* szProvider,
- const char* szChallenge, unsigned& complete)
- {
- char* szAuthHdr = NULL;
- bool justCreated = false;
-
- if (m_hNtlmSecurity) {
- bool newAuth = !m_szProvider || !szProvider || _stricmp(m_szProvider, szProvider);
- newAuth = newAuth || (m_szHost != szHost && (!m_szHost || !szHost || _stricmp(m_szHost, szHost)));
- if (newAuth)
- Destroy();
- }
-
- if (m_hNtlmSecurity == NULL) {
- char szSpnStr[256] = "";
- if (szHost && _stricmp(szProvider, "Basic")) {
- unsigned long ip = inet_addr(szHost);
- PHOSTENT host = (ip == INADDR_NONE) ? gethostbyname(szHost) : gethostbyaddr((char*)&ip, 4, AF_INET);
- mir_snprintf(szSpnStr, SIZEOF(szSpnStr), "HTTP/%s", host && host->h_name ? host->h_name : szHost);
- _strlwr(szSpnStr + 5);
- NetlibLogf(nlc->nlu, "Host SPN: %s", szSpnStr);
- }
- m_hNtlmSecurity = NetlibInitSecurityProvider(szProvider, szSpnStr[0] ? szSpnStr : NULL);
- if (m_hNtlmSecurity) {
- m_szProvider = mir_strdup(szProvider);
- m_szHost = mir_strdup(szHost);
- justCreated = true;
- }
- }
-
- if (m_hNtlmSecurity) {
- TCHAR *szLogin = NULL, *szPassw = NULL;
-
- if (nlc->nlu->settings.useProxyAuth) {
- mir_cslock lck(csNetlibUser);
- szLogin = mir_a2t(nlc->nlu->settings.szProxyAuthUser);
- szPassw = mir_a2t(nlc->nlu->settings.szProxyAuthPassword);
- }
-
- szAuthHdr = NtlmCreateResponseFromChallenge(m_hNtlmSecurity,
- szChallenge, szLogin, szPassw, true, complete);
-
- if (!szAuthHdr) {
- NetlibLogf(NULL, "Security login %s failed, user: %S pssw: %S",
- szProvider, szLogin ? szLogin : _T("(no user)"), szPassw ? _T("(exist)") : _T("(no psw)"));
- }
- else if (justCreated)
- proxyAuthList.add(m_szHost, m_szProvider);
-
- mir_free(szLogin);
- mir_free(szPassw);
- }
- else complete = 1;
-
- return szAuthHdr;
- }
-};
-
-static int HttpPeekFirstResponseLine(NetlibConnection *nlc, DWORD dwTimeoutTime, DWORD recvFlags, int *resultCode, char **ppszResultDescr, int *length)
-{
- int bytesPeeked;
- char buffer[2048];
- char *peol;
-
- while(true) {
- bytesPeeked = RecvWithTimeoutTime(nlc, dwTimeoutTime, buffer, SIZEOF(buffer) - 1, MSG_PEEK | recvFlags);
-
- if (bytesPeeked == 0) {
- SetLastError(ERROR_HANDLE_EOF);
- return 0;
- }
- if (bytesPeeked == SOCKET_ERROR)
- return 0;
-
- buffer[bytesPeeked] = '\0';
- if ((peol = strchr(buffer, '\n')) != NULL)
- break;
-
- if ((int)mir_strlen(buffer) < bytesPeeked) {
- SetLastError(ERROR_BAD_FORMAT);
- return 0;
- }
- if (bytesPeeked == SIZEOF(buffer) - 1) {
- SetLastError(ERROR_BUFFER_OVERFLOW);
- return 0;
- }
- if (Miranda_Terminated()) return 0;
- Sleep(10);
- }
-
- if (peol == buffer) {
- SetLastError(ERROR_BAD_FORMAT);
- return 0;
- }
-
- *peol = '\0';
-
- if (_strnicmp(buffer, "HTTP/", 5)) {
- SetLastError(ERROR_BAD_FORMAT);
- return 0;
- }
-
- size_t off = strcspn(buffer, " \t");
- if (off >= (unsigned)bytesPeeked)
- return 0;
-
- char* pResultCode = buffer + off;
- *(pResultCode++) = 0;
-
- char* pResultDescr;
- *resultCode = strtol(pResultCode, &pResultDescr, 10);
-
- if (ppszResultDescr)
- *ppszResultDescr = mir_strdup(lrtrimp(pResultDescr));
-
- if (length) *length = peol - buffer + 1;
- return 1;
-}
-
-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;
-}
-
-INT_PTR NetlibHttpSendRequest(WPARAM wParam, LPARAM lParam)
-{
- NetlibConnection *nlc = (struct NetlibConnection*)wParam;
- NETLIBHTTPREQUEST *nlhr = (NETLIBHTTPREQUEST*)lParam;
- NETLIBHTTPREQUEST *nlhrReply = NULL;
- HttpSecurityContext httpSecurity;
-
- struct ResizableCharBuffer httpRequest = {0};
- char *szHost = NULL, *szNewUrl = NULL;
- char *pszProxyAuthHdr = NULL, *pszAuthHdr = NULL;
- int i, doneHostHeader, doneContentLengthHeader, doneProxyAuthHeader, doneAuthHeader;
- int bytesSent;
- bool lastFirstLineFail = false;
-
- if (nlhr == NULL || nlhr->cbSize != sizeof(NETLIBHTTPREQUEST) || nlhr->szUrl == NULL || nlhr->szUrl[0] == '\0') {
- SetLastError(ERROR_INVALID_PARAMETER);
- return SOCKET_ERROR;
- }
-
- int hdrTimeout = (nlhr->timeout) ? nlhr->timeout : HTTPRECVHEADERSTIMEOUT;
-
- const char *pszRequest;
- switch(nlhr->requestType) {
- case REQUEST_GET: pszRequest = "GET"; break;
- case REQUEST_POST: pszRequest = "POST"; break;
- case REQUEST_CONNECT: pszRequest = "CONNECT"; break;
- case REQUEST_HEAD: pszRequest = "HEAD"; break;
- case REQUEST_PUT: pszRequest = "PUT"; break;
- case REQUEST_DELETE: pszRequest = "DELETE"; break;
- default:
- SetLastError(ERROR_INVALID_PARAMETER);
- return SOCKET_ERROR;
- }
-
- if (!nlc->usingHttpGateway)
- if (!NetlibEnterNestedCS(nlc, NLNCS_SEND))
- return SOCKET_ERROR;
-
- const char *pszFullUrl = nlhr->szUrl;
- const char *pszUrl = NULL;
-
- unsigned complete = false;
- int count = 11;
- while (--count) {
- if (!NetlibReconnect(nlc)) {
- bytesSent = SOCKET_ERROR;
- break;
- }
-
- if (!pszUrl) {
- pszUrl = pszFullUrl;
- if (nlhr->flags & (NLHRF_SMARTREMOVEHOST | NLHRF_REMOVEHOST | NLHRF_GENERATEHOST)) {
- bool usingProxy = nlc->proxyType == PROXYTYPE_HTTP && !(nlhr->flags & NLHRF_SSL);
-
- mir_free(szHost);
- szHost = NULL;
-
- const char *ppath, *phost;
- phost = strstr(pszUrl, "://");
- if (phost == NULL) phost = pszUrl;
- else phost += 3;
- ppath = strchr(phost, '/');
- if (ppath == phost) phost = NULL;
-
- if (nlhr->flags & NLHRF_GENERATEHOST) {
- szHost = mir_strdup(phost);
- if (ppath && phost) szHost[ppath - phost] = 0;
- }
-
- if (nlhr->flags & NLHRF_REMOVEHOST || (nlhr->flags & NLHRF_SMARTREMOVEHOST && !usingProxy))
- pszUrl = ppath ? ppath : "/";
-
- if (usingProxy && phost && !nlc->dnsThroughProxy) {
- char* tszHost = mir_strdup(phost);
- if (ppath && phost) tszHost[ppath - phost] = 0;
- char* cln = strchr(tszHost, ':'); if (cln) *cln = 0;
-
- if (inet_addr(tszHost) == INADDR_NONE) {
- DWORD ip = DnsLookup(nlc->nlu, tszHost);
- if (ip && szHost) {
- mir_free(szHost);
- szHost = (char*)mir_alloc(64);
- if (cln) *cln = ':';
- mir_snprintf(szHost, 64, "%s%s", inet_ntoa(*(PIN_ADDR)&ip), cln ? cln : "");
- }
- }
- mir_free(tszHost);
- }
- }
- }
-
- if (nlc->proxyAuthNeeded && proxyAuthList.getCount()) {
- if (httpSecurity.m_szProvider == NULL && nlc->szProxyServer) {
- const char* szAuthMethodNlu = proxyAuthList.find(nlc->szProxyServer);
- if (szAuthMethodNlu) {
- mir_free(pszProxyAuthHdr);
- pszProxyAuthHdr = httpSecurity.Execute(nlc, nlc->szProxyServer, szAuthMethodNlu, "", complete);
- }
- }
- }
- nlc->proxyAuthNeeded = false;
-
- AppendToCharBuffer(&httpRequest, "%s %s HTTP/1.%d\r\n", pszRequest, pszUrl, (nlhr->flags & NLHRF_HTTP11) != 0);
-
- //HTTP headers
- doneHostHeader = doneContentLengthHeader = doneProxyAuthHeader = doneAuthHeader = 0;
- for (i=0; i < nlhr->headersCount; i++) {
- NETLIBHTTPHEADER &p = nlhr->headers[i];
- if (!mir_strcmpi(p.szName, "Host")) doneHostHeader = 1;
- else if (!mir_strcmpi(p.szName, "Content-Length")) doneContentLengthHeader = 1;
- else if (!mir_strcmpi(p.szName, "Proxy-Authorization")) doneProxyAuthHeader = 1;
- else if (!mir_strcmpi(p.szName, "Authorization")) doneAuthHeader = 1;
- else if (!mir_strcmpi(p.szName, "Connection")) continue;
- if (p.szValue == NULL) continue;
- AppendToCharBuffer(&httpRequest, "%s: %s\r\n", p.szName, p.szValue);
- }
- if (szHost && !doneHostHeader)
- AppendToCharBuffer(&httpRequest, "%s: %s\r\n", "Host", szHost);
- if (pszProxyAuthHdr && !doneProxyAuthHeader)
- AppendToCharBuffer(&httpRequest, "%s: %s\r\n", "Proxy-Authorization", pszProxyAuthHdr);
- if (pszAuthHdr && !doneAuthHeader)
- AppendToCharBuffer(&httpRequest, "%s: %s\r\n", "Authorization", pszAuthHdr);
- AppendToCharBuffer(&httpRequest, "%s: %s\r\n", "Connection", "Keep-Alive");
- AppendToCharBuffer(&httpRequest, "%s: %s\r\n", "Proxy-Connection", "Keep-Alive");
-
- // Add Sticky Headers
- if (nlc->nlu->szStickyHeaders != NULL)
- AppendToCharBuffer(&httpRequest, "%s\r\n", nlc->nlu->szStickyHeaders);
-
- //send it
- bytesSent = SendHttpRequestAndData(nlc, &httpRequest, nlhr, !doneContentLengthHeader);
- if (bytesSent == SOCKET_ERROR)
- break;
-
- //ntlm reply
- if (doneContentLengthHeader && nlhr->requestType != REQUEST_HEAD)
- break;
-
- DWORD fflags = MSG_PEEK | MSG_NODUMP | ((nlhr->flags & NLHRF_NOPROXY) ? MSG_RAW : 0);
- DWORD dwTimeOutTime = hdrTimeout < 0 ? -1 : GetTickCount() + hdrTimeout;
- if (!HttpPeekFirstResponseLine(nlc, dwTimeOutTime, fflags, &nlhr->resultCode, NULL, NULL)) {
- NetlibLogf(nlc->nlu, "%s %d: %s Failed (%u %u)", __FILE__, __LINE__, "HttpPeekFirstResponseLine", GetLastError(), count);
- DWORD err = GetLastError();
- if (err == ERROR_TIMEOUT || err == ERROR_BAD_FORMAT || err == ERROR_BUFFER_OVERFLOW || lastFirstLineFail || nlc->termRequested || nlhr->requestType == REQUEST_CONNECT) {
- bytesSent = SOCKET_ERROR;
- break;
- }
-
- lastFirstLineFail = true;
- continue;
- }
-
- int resultCode = nlhr->resultCode;
- lastFirstLineFail = false;
-
- DWORD hflags = (nlhr->flags & (NLHRF_NODUMP|NLHRF_NODUMPHEADERS|NLHRF_NODUMPSEND) ?
- MSG_NODUMP : (nlhr->flags & NLHRF_DUMPPROXY ? MSG_DUMPPROXY : 0)) |
- (nlhr->flags & NLHRF_NOPROXY ? MSG_RAW : 0);
-
- DWORD dflags = (nlhr->flags & (NLHRF_NODUMP | NLHRF_NODUMPSEND) ? MSG_NODUMP : MSG_DUMPASTEXT | MSG_DUMPPROXY) |
- (nlhr->flags & NLHRF_NOPROXY ? MSG_RAW : 0) | MSG_NODUMP;
-
- if (resultCode == 100)
- nlhrReply = (NETLIBHTTPREQUEST*)NetlibHttpRecvHeaders((WPARAM)nlc, hflags);
-
- else if (resultCode == 307 || ((resultCode == 301 || resultCode == 302) && (nlhr->flags & NLHRF_REDIRECT))) { // redirect
- pszUrl = NULL;
-
- if (nlhr->requestType == REQUEST_HEAD)
- nlhrReply = (NETLIBHTTPREQUEST*)NetlibHttpRecvHeaders((WPARAM)nlc, hflags);
- else
- nlhrReply = NetlibHttpRecv(nlc, hflags, dflags);
-
- if (nlhrReply) {
- char* tmpUrl = NetlibHttpFindHeader(nlhrReply, "Location");
- if (tmpUrl) {
- size_t rlen = 0;
- if (tmpUrl[0] == '/') {
- const char *ppath, *phost;
- phost = strstr(pszFullUrl, "://");
- phost = phost ? phost + 3 : pszFullUrl;
- ppath = strchr(phost, '/');
- rlen = ppath ? ppath - pszFullUrl : mir_strlen(pszFullUrl);
- }
-
- nlc->szNewUrl = (char*)mir_realloc(nlc->szNewUrl, rlen + mir_strlen(tmpUrl) * 3 + 1);
-
- strncpy(nlc->szNewUrl, pszFullUrl, rlen);
- mir_strcpy(nlc->szNewUrl + rlen, tmpUrl);
- pszFullUrl = nlc->szNewUrl;
- pszUrl = NULL;
-
- if (NetlibHttpProcessUrl(nlhr, nlc->nlu, nlc, pszFullUrl) == NULL) {
- bytesSent = SOCKET_ERROR;
- break;
- }
- }
- else {
- NetlibHttpSetLastErrorUsingHttpResult(resultCode);
- bytesSent = SOCKET_ERROR;
- break;
- }
- }
- else {
- NetlibHttpSetLastErrorUsingHttpResult(resultCode);
- bytesSent = SOCKET_ERROR;
- break;
- }
- }
- else if (resultCode == 401 && !doneAuthHeader) { //auth required
- if (nlhr->requestType == REQUEST_HEAD)
- nlhrReply = (NETLIBHTTPREQUEST*)NetlibHttpRecvHeaders((WPARAM)nlc, hflags);
- else
- nlhrReply = NetlibHttpRecv(nlc, hflags, dflags);
-
- mir_free(pszAuthHdr); pszAuthHdr = NULL;
- if (nlhrReply) {
- char *szAuthStr = NULL;
- if (!complete) {
- szAuthStr = NetlibHttpFindAuthHeader(nlhrReply, "WWW-Authenticate", httpSecurity.m_szProvider);
- if (szAuthStr) {
- char *szChallenge = strchr(szAuthStr, ' ');
- if (!szChallenge || !*lrtrimp(szChallenge))
- complete = true;
- }
- }
- if (complete && httpSecurity.m_hNtlmSecurity)
- szAuthStr = httpSecurity.TryBasic() ? NetlibHttpFindAuthHeader(nlhrReply, "WWW-Authenticate", "Basic") : NULL;
-
- if (szAuthStr) {
- char *szChallenge = strchr(szAuthStr, ' ');
- if (szChallenge) { *szChallenge = 0; szChallenge = lrtrimp(szChallenge + 1); }
-
- pszAuthHdr = httpSecurity.Execute(nlc, szHost, szAuthStr, szChallenge, complete);
- }
- }
- if (pszAuthHdr == NULL) {
- proxyAuthList.add(szHost, NULL);
- NetlibHttpSetLastErrorUsingHttpResult(resultCode);
- bytesSent = SOCKET_ERROR;
- break;
- }
- }
- else if (resultCode == 407 && !doneProxyAuthHeader) { //proxy auth required
- if (nlhr->requestType == REQUEST_HEAD)
- nlhrReply = (NETLIBHTTPREQUEST*)NetlibHttpRecvHeaders((WPARAM)nlc, hflags);
- else
- nlhrReply = NetlibHttpRecv(nlc, hflags, dflags);
-
- mir_free(pszProxyAuthHdr); pszProxyAuthHdr = NULL;
- if (nlhrReply) {
- char *szAuthStr = NULL;
- if (!complete) {
- szAuthStr = NetlibHttpFindAuthHeader(nlhrReply, "Proxy-Authenticate", httpSecurity.m_szProvider);
- if (szAuthStr) {
- char *szChallenge = strchr(szAuthStr, ' ');
- if (!szChallenge || !*lrtrimp(szChallenge + 1))
- complete = true;
- }
- }
- if (complete && httpSecurity.m_hNtlmSecurity)
- szAuthStr = httpSecurity.TryBasic() ? NetlibHttpFindAuthHeader(nlhrReply, "Proxy-Authenticate", "Basic") : NULL;
-
- if (szAuthStr) {
- char *szChallenge = strchr(szAuthStr, ' ');
- if (szChallenge) { *szChallenge = 0; szChallenge = lrtrimp(szChallenge + 1); }
-
- pszProxyAuthHdr = httpSecurity.Execute(nlc, nlc->szProxyServer, szAuthStr, szChallenge, complete);
- }
- }
- if (pszProxyAuthHdr == NULL) {
- proxyAuthList.add(nlc->szProxyServer, NULL);
- NetlibHttpSetLastErrorUsingHttpResult(resultCode);
- bytesSent = SOCKET_ERROR;
- break;
- }
- }
- else break;
-
- if (pszProxyAuthHdr && resultCode != 407 && !doneProxyAuthHeader)
- replaceStr(pszProxyAuthHdr, NULL);
-
- if (pszAuthHdr && resultCode != 401 && !doneAuthHeader)
- replaceStr(pszAuthHdr, NULL);
-
- if (nlhrReply) {
- NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply);
- nlhrReply = NULL;
- }
- }
-
- if (count == 0) bytesSent = SOCKET_ERROR;
- if (nlhrReply) NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply);
-
- //clean up
- mir_free(pszProxyAuthHdr);
- mir_free(pszAuthHdr);
- mir_free(szHost);
- mir_free(szNewUrl);
-
- if (!nlc->usingHttpGateway)
- NetlibLeaveNestedCS(&nlc->ncsSend);
-
- return bytesSent;
-}
-
-INT_PTR NetlibHttpFreeRequestStruct(WPARAM, LPARAM lParam)
-{
- NETLIBHTTPREQUEST *nlhr = (NETLIBHTTPREQUEST*)lParam;
-
- if (nlhr == NULL || nlhr->cbSize != sizeof(NETLIBHTTPREQUEST) || nlhr->requestType != REQUEST_RESPONSE) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
- if (nlhr->headers) {
- for (int i=0; i < nlhr->headersCount; i++) {
- NETLIBHTTPHEADER &p = nlhr->headers[i];
- mir_free(p.szName);
- mir_free(p.szValue);
- }
- mir_free(nlhr->headers);
- }
- mir_free(nlhr->pData);
- mir_free(nlhr->szResultDescr);
- mir_free(nlhr->szUrl);
- mir_free(nlhr);
- return 1;
-}
-
-INT_PTR NetlibHttpRecvHeaders(WPARAM wParam, LPARAM lParam)
-{
- NetlibConnection *nlc = (struct NetlibConnection*)wParam;
- if (!NetlibEnterNestedCS(nlc, NLNCS_RECV))
- return 0;
-
- char *peol, *pbuffer;
- int headersCount = 0, bufferSize = 8192;
-
- DWORD dwRequestTimeoutTime = GetTickCount() + HTTPRECVDATATIMEOUT;
- NETLIBHTTPREQUEST *nlhr = (NETLIBHTTPREQUEST*)mir_calloc(sizeof(NETLIBHTTPREQUEST));
- nlhr->cbSize = sizeof(NETLIBHTTPREQUEST);
- nlhr->nlc = nlc; // Needed to id connection in the protocol HTTP gateway wrapper functions
- nlhr->requestType = REQUEST_RESPONSE;
-
- int firstLineLength = 0;
- if (!HttpPeekFirstResponseLine(nlc, dwRequestTimeoutTime, lParam | MSG_PEEK, &nlhr->resultCode, &nlhr->szResultDescr, &firstLineLength)) {
- NetlibLeaveNestedCS(&nlc->ncsRecv);
- NetlibHttpFreeRequestStruct(0, (LPARAM)nlhr);
- return 0;
- }
-
- char *buffer = (char*)mir_alloc(bufferSize + 1);
- int bytesPeeked = NLRecv(nlc, buffer, min(firstLineLength, bufferSize), lParam | MSG_DUMPASTEXT);
- if (bytesPeeked != firstLineLength) {
- NetlibLeaveNestedCS(&nlc->ncsRecv);
- NetlibHttpFreeRequestStruct(0, (LPARAM)nlhr);
- if (bytesPeeked != SOCKET_ERROR) SetLastError(ERROR_HANDLE_EOF);
- mir_free(buffer);
- return 0;
- }
-
- // Make sure all headers arrived
- bytesPeeked = 0;
- for (bool headersCompleted = false; !headersCompleted; ) {
- if (bytesPeeked >= bufferSize) {
- bufferSize += 8192;
- mir_free(buffer);
- if (bufferSize > 32 * 1024) {
- bytesPeeked = 0;
- break;
- }
- buffer = (char*)mir_alloc(bufferSize + 1);
- }
-
- bytesPeeked = RecvWithTimeoutTime(nlc, dwRequestTimeoutTime, buffer, bufferSize, MSG_PEEK | MSG_NODUMP | lParam);
- if (bytesPeeked == 0)
- break;
-
- if (bytesPeeked == SOCKET_ERROR) {
- bytesPeeked = 0;
- break;
- }
- buffer[bytesPeeked] = 0;
-
- for (pbuffer = buffer, headersCount = 0;; pbuffer = peol + 1, ++headersCount) {
- peol = strchr(pbuffer, '\n');
- if (peol == NULL) break;
- if (peol == pbuffer || (peol == (pbuffer + 1) && *pbuffer == '\r')) {
- bytesPeeked = peol - buffer + 1;
- headersCompleted = true;
- break;
- }
- }
- }
-
- // Receive headers
- if (bytesPeeked > 0)
- bytesPeeked = NLRecv(nlc, buffer, bytesPeeked, lParam | MSG_DUMPASTEXT);
- if (bytesPeeked <= 0) {
- NetlibLeaveNestedCS(&nlc->ncsRecv);
- NetlibHttpFreeRequestStruct(0, (LPARAM)nlhr);
- mir_free(buffer);
- return 0;
- }
- buffer[bytesPeeked] = 0;
-
- nlhr->headersCount = headersCount;
- nlhr->headers = (NETLIBHTTPHEADER*)mir_calloc(sizeof(NETLIBHTTPHEADER) * headersCount);
-
- for (pbuffer = buffer, headersCount = 0;; pbuffer = peol + 1, ++headersCount) {
- peol = strchr(pbuffer, '\n');
- if (peol == NULL || peol == pbuffer || (peol == (pbuffer + 1) && *pbuffer == '\r')) break;
- *peol = 0;
-
- char *pColon = strchr(pbuffer, ':');
- if (pColon == NULL) {
- NetlibHttpFreeRequestStruct(0, (LPARAM)nlhr); nlhr = NULL;
- SetLastError(ERROR_INVALID_DATA);
- break;
- }
-
- *(pColon++) = 0;
- nlhr->headers[headersCount].szName = mir_strdup(rtrim(pbuffer));
- nlhr->headers[headersCount].szValue = mir_strdup(lrtrimp(pColon));
- }
-
- NetlibLeaveNestedCS(&nlc->ncsRecv);
- mir_free(buffer);
- return (INT_PTR)nlhr;
-}
-
-INT_PTR NetlibHttpTransaction(WPARAM wParam, LPARAM lParam)
-{
- NetlibUser *nlu = (NetlibUser*)wParam;
- NETLIBHTTPREQUEST *nlhr = (NETLIBHTTPREQUEST*)lParam, *nlhrReply;
-
- if (GetNetlibHandleType(nlu) != NLH_USER || !(nlu->user.flags & NUF_OUTGOING) ||
- nlhr == NULL || nlhr->cbSize != sizeof(NETLIBHTTPREQUEST) ||
- nlhr->szUrl == NULL || nlhr->szUrl[0] == 0)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- if (nlhr->nlc != NULL && GetNetlibHandleType(nlhr->nlc) != NLH_CONNECTION)
- nlhr->nlc = NULL;
-
- NetlibConnection* nlc = NetlibHttpProcessUrl(nlhr, nlu, (NetlibConnection*)nlhr->nlc);
- if (nlc == NULL)
- return 0;
-
- NETLIBHTTPREQUEST nlhrSend;
- char szUserAgent[64];
-
- nlhrSend = *nlhr;
- nlhrSend.flags &= ~NLHRF_REMOVEHOST;
- nlhrSend.flags |= NLHRF_GENERATEHOST | NLHRF_SMARTREMOVEHOST | NLHRF_SMARTAUTHHEADER;
-
- bool doneUserAgentHeader = NetlibHttpFindHeader(nlhr, "User-Agent") != NULL;
- bool doneAcceptEncoding = NetlibHttpFindHeader(nlhr, "Accept-Encoding") != NULL;
-
- if (!doneUserAgentHeader || !doneAcceptEncoding) {
- nlhrSend.headers = (NETLIBHTTPHEADER*)mir_alloc(sizeof(NETLIBHTTPHEADER) * (nlhrSend.headersCount + 2));
- memcpy(nlhrSend.headers, nlhr->headers, sizeof(NETLIBHTTPHEADER) * nlhr->headersCount);
- }
-
- if (!doneUserAgentHeader) {
- nlhrSend.headers[nlhrSend.headersCount].szName = "User-Agent";
- nlhrSend.headers[nlhrSend.headersCount].szValue = szUserAgent;
- ++nlhrSend.headersCount;
-
- char szMirandaVer[64];
- CallService(MS_SYSTEM_GETVERSIONTEXT, SIZEOF(szMirandaVer), (LPARAM)szMirandaVer);
- char *pspace = strchr(szMirandaVer, ' ');
- if (pspace) {
- *pspace++='\0';
- mir_snprintf(szUserAgent, SIZEOF(szUserAgent), "Miranda/%s (%s)", szMirandaVer, pspace);
- }
- else mir_snprintf(szUserAgent, SIZEOF(szUserAgent), "Miranda/%s", szMirandaVer);
- }
- if (!doneAcceptEncoding) {
- nlhrSend.headers[nlhrSend.headersCount].szName = "Accept-Encoding";
- nlhrSend.headers[nlhrSend.headersCount].szValue = "deflate, gzip";
- ++nlhrSend.headersCount;
- }
- if (NetlibHttpSendRequest((WPARAM)nlc, (LPARAM)&nlhrSend) == SOCKET_ERROR) {
- if (!doneUserAgentHeader || !doneAcceptEncoding) mir_free(nlhrSend.headers);
- nlhr->resultCode = nlhrSend.resultCode;
- NetlibCloseHandle((WPARAM)nlc, 0);
- return 0;
- }
- if (!doneUserAgentHeader || !doneAcceptEncoding)
- mir_free(nlhrSend.headers);
-
- DWORD dflags = (nlhr->flags & NLHRF_DUMPASTEXT ? MSG_DUMPASTEXT : 0) |
- (nlhr->flags & NLHRF_NODUMP ? MSG_NODUMP : (nlhr->flags & NLHRF_DUMPPROXY ? MSG_DUMPPROXY : 0)) |
- (nlhr->flags & NLHRF_NOPROXY ? MSG_RAW : 0);
-
- DWORD hflags =
- (nlhr->flags & NLHRF_NODUMP ? MSG_NODUMP : (nlhr->flags & NLHRF_DUMPPROXY ? MSG_DUMPPROXY : 0)) |
- (nlhr->flags & NLHRF_NOPROXY ? MSG_RAW : 0);
-
- if (nlhr->requestType == REQUEST_HEAD)
- nlhrReply = (NETLIBHTTPREQUEST*)NetlibHttpRecvHeaders((WPARAM)nlc, 0);
- else
- nlhrReply = NetlibHttpRecv(nlc, hflags, dflags);
-
- if (nlhrReply) {
- nlhrReply->szUrl = nlc->szNewUrl;
- nlc->szNewUrl = NULL;
- }
-
- if ((nlhr->flags & NLHRF_PERSISTENT) == 0 || nlhrReply == NULL) {
- NetlibCloseHandle((WPARAM)nlc, 0);
- if (nlhrReply)
- nlhrReply->nlc = NULL;
- }
- else nlhrReply->nlc = nlc;
-
- return (INT_PTR)nlhrReply;
-}
-
-void NetlibHttpSetLastErrorUsingHttpResult(int result)
-{
- if (result >= 200 && result < 300) {
- SetLastError(ERROR_SUCCESS);
- return;
- }
- switch(result) {
- case 400: SetLastError(ERROR_BAD_FORMAT); break;
- case 401:
- case 402:
- case 403:
- case 407: SetLastError(ERROR_ACCESS_DENIED); break;
- case 404: SetLastError(ERROR_FILE_NOT_FOUND); break;
- case 405:
- case 406: SetLastError(ERROR_INVALID_FUNCTION); break;
- case 408: SetLastError(ERROR_TIMEOUT); break;
- default: SetLastError(ERROR_GEN_FAILURE); break;
- }
-}
-
-char* gzip_decode(char *gzip_data, int *len_ptr, int window)
-{
- if (*len_ptr == 0) return NULL;
-
- int gzip_len = *len_ptr * 5;
- char* output_data = NULL;
-
- int gzip_err;
- z_stream zstr;
-
- do {
- output_data = (char*)mir_realloc(output_data, gzip_len+1);
-
- zstr.next_in = (Bytef*)gzip_data;
- zstr.avail_in = *len_ptr;
- zstr.zalloc = Z_NULL;
- zstr.zfree = Z_NULL;
- zstr.opaque = Z_NULL;
- inflateInit2_(&zstr, window, ZLIB_VERSION, sizeof(z_stream));
-
- zstr.next_out = (Bytef*)output_data;
- zstr.avail_out = gzip_len;
-
- gzip_err = inflate(&zstr, Z_FINISH);
-
- inflateEnd(&zstr);
- gzip_len *= 2;
- }
- while (gzip_err == Z_BUF_ERROR);
-
- gzip_len = gzip_err == Z_STREAM_END ? zstr.total_out : -1;
-
- if (gzip_len <= 0) {
- mir_free(output_data);
- output_data = NULL;
- }
- else output_data[gzip_len] = 0;
-
- *len_ptr = gzip_len;
- return output_data;
-}
-
-static int NetlibHttpRecvChunkHeader(NetlibConnection* nlc, bool first, DWORD flags)
-{
- char data[64], *peol1;
-
- while(true) {
- int recvResult = NLRecv(nlc, data, 31, MSG_RAW | MSG_PEEK);
- if (recvResult <= 0)
- return SOCKET_ERROR;
-
- data[recvResult] = 0;
-
- peol1 = strchr(data, '\n');
- if (peol1 != NULL) {
- char *peol2 = first ? peol1 : strchr(peol1 + 1, '\n');
- if (peol2 != NULL) {
- int sz = peol2 - data + 1;
- int r = strtol(first ? data : peol1 + 1, NULL, 16);
- if (r == 0) {
- char *peol3 = strchr(peol2 + 1, '\n');
- if (peol3 == NULL) continue;
- sz = peol3 - data + 1;
- }
- NLRecv(nlc, data, sz, MSG_RAW | flags);
- return r;
- }
- else if (recvResult >= 31)
- return SOCKET_ERROR;
- }
- }
-}
-
-NETLIBHTTPREQUEST* NetlibHttpRecv(NetlibConnection* nlc, DWORD hflags, DWORD dflags, bool isConnect)
-{
- int dataLen = -1, i, chunkhdr = 0;
- bool chunked = false;
- int cenc = 0, cenctype = 0, close = 0;
-
-next:
- NETLIBHTTPREQUEST *nlhrReply = (NETLIBHTTPREQUEST*)NetlibHttpRecvHeaders((WPARAM)nlc, hflags);
- if (nlhrReply == NULL)
- return NULL;
-
- if (nlhrReply->resultCode == 100) {
- NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply);
- goto next;
- }
-
- for (i=0; i<nlhrReply->headersCount; i++) {
- NETLIBHTTPHEADER &p = nlhrReply->headers[i];
- if (!mir_strcmpi(p.szName, "Content-Length"))
- dataLen = atoi(p.szValue);
-
- if (!mir_strcmpi(p.szName, "Content-Encoding")) {
- cenc = i;
- if (strstr(p.szValue, "gzip"))
- cenctype = 1;
- else if (strstr(p.szValue, "deflate"))
- cenctype = 2;
- }
-
- if (!mir_strcmpi(p.szName, "Connection"))
- close = !mir_strcmpi(p.szValue, "close");
-
- if (!mir_strcmpi(p.szName, "Transfer-Encoding") &&
- !mir_strcmpi(p.szValue, "chunked"))
- {
- chunked = true;
- chunkhdr = i;
- dataLen = -1;
- }
- }
-
- if (nlhrReply->resultCode >= 200 && (dataLen > 0 || (!isConnect && dataLen < 0))) {
- int recvResult, chunksz = -1;
- int dataBufferAlloced;
-
- if (chunked) {
- chunksz = NetlibHttpRecvChunkHeader(nlc, true, dflags);
- if (chunksz == SOCKET_ERROR) {
- NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply);
- return NULL;
- }
- dataLen = chunksz;
- }
- dataBufferAlloced = dataLen < 0 ? 2048 : dataLen + 1;
- nlhrReply->pData = (char*)mir_realloc(nlhrReply->pData, dataBufferAlloced);
-
- while (chunksz != 0) {
- while(true) {
- recvResult = RecvWithTimeoutTime(nlc, GetTickCount() + HTTPRECVDATATIMEOUT,
- nlhrReply->pData + nlhrReply->dataLength,
- dataBufferAlloced - nlhrReply->dataLength - 1,
- dflags | (cenctype ? MSG_NODUMP : 0));
-
- if (recvResult == 0) break;
- if (recvResult == SOCKET_ERROR) {
- NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply);
- return NULL;
- }
- nlhrReply->dataLength += recvResult;
-
- if (dataLen >= 0)
- {
- if (nlhrReply->dataLength >= dataLen)
- break;
- }
- else if ((dataBufferAlloced - nlhrReply->dataLength) < 256) {
- dataBufferAlloced += 2048;
- nlhrReply->pData = (char*)mir_realloc(nlhrReply->pData, dataBufferAlloced);
- if (nlhrReply->pData == NULL) {
- SetLastError(ERROR_OUTOFMEMORY);
- NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply);
- return NULL;
- }
- }
- Sleep(10);
- }
-
- if (!chunked)
- break;
-
- chunksz = NetlibHttpRecvChunkHeader(nlc, false, dflags);
- if (chunksz == SOCKET_ERROR) {
- NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply);
- return NULL;
- }
- dataLen += chunksz;
- dataBufferAlloced += chunksz;
-
- nlhrReply->pData = (char*)mir_realloc(nlhrReply->pData, dataBufferAlloced);
- }
-
- nlhrReply->pData[nlhrReply->dataLength] = '\0';
- }
-
- if (chunked) {
- nlhrReply->headers[chunkhdr].szName = (char*)mir_realloc(nlhrReply->headers[chunkhdr].szName, 16);
- mir_strcpy(nlhrReply->headers[chunkhdr].szName, "Content-Length");
-
- nlhrReply->headers[chunkhdr].szValue = (char*)mir_realloc(nlhrReply->headers[chunkhdr].szValue, 16);
- mir_snprintf(nlhrReply->headers[chunkhdr].szValue, 16, "%u", nlhrReply->dataLength);
- }
-
- if (cenctype) {
- int bufsz = nlhrReply->dataLength;
- char* szData = NULL;
-
- switch (cenctype) {
- case 1:
- szData = gzip_decode(nlhrReply->pData, &bufsz, 0x10 | MAX_WBITS);
- break;
-
- case 2:
- szData = gzip_decode(nlhrReply->pData, &bufsz, -MAX_WBITS);
- if (bufsz < 0)
- {
- bufsz = nlhrReply->dataLength;
- szData = gzip_decode(nlhrReply->pData, &bufsz, MAX_WBITS);
- }
- break;
- }
-
- if (bufsz > 0) {
- NetlibDumpData(nlc, (PBYTE)szData, bufsz, 0, dflags);
- mir_free(nlhrReply->pData);
- nlhrReply->pData = szData;
- nlhrReply->dataLength = bufsz;
-
- mir_free(nlhrReply->headers[cenc].szName);
- mir_free(nlhrReply->headers[cenc].szValue);
- memmove(&nlhrReply->headers[cenc], &nlhrReply->headers[cenc+1], (--nlhrReply->headersCount-cenc)*sizeof(nlhrReply->headers[0]));
- }
- else if (bufsz == 0) {
- mir_free(nlhrReply->pData);
- nlhrReply->pData = NULL;
- nlhrReply->dataLength = 0;
- }
- }
-
- if (close &&
- (nlc->proxyType != PROXYTYPE_HTTP || nlc->nloc.flags & NLOCF_SSL) &&
- (!isConnect || nlhrReply->resultCode != 200))
- NetlibDoClose(nlc);
-
- return nlhrReply;
-}
diff --git a/src/modules/netlib/netlibhttpproxy.cpp b/src/modules/netlib/netlibhttpproxy.cpp
deleted file mode 100644
index 892554542d..0000000000
--- a/src/modules/netlib/netlibhttpproxy.cpp
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (ñ) 2012-15 Miranda NG project (http://miranda-ng.org),
-Copyright (c) 2000-12 Miranda IM project,
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "..\..\core\commonheaders.h"
-#include "netlib.h"
-
-typedef enum
-{
- reqHelloGet,
- reqOldGet,
- reqOldPost,
- reqNewPost,
-}
-RequestType;
-
-static int HttpGatewayReadSetResult(NetlibConnection *nlc, char *buf, int num, int peek)
-{
- if (nlc->dataBufferLen == 0) return 0;
-
- int bytes = min(num, nlc->dataBufferLen);
- int rbytes = nlc->dataBufferLen - bytes;
-
- memcpy(buf, nlc->dataBuffer, bytes);
- if (!peek) {
- memmove(nlc->dataBuffer, nlc->dataBuffer + bytes, rbytes);
- nlc->dataBufferLen = rbytes;
- }
-
- return bytes;
-}
-
-void HttpGatewayRemovePacket(NetlibConnection *nlc, int pck)
-{
- mir_cslock lck(nlc->csHttpSequenceNums);
- while (pck-- && nlc->pHttpProxyPacketQueue != NULL) {
- NetlibHTTPProxyPacketQueue *p = nlc->pHttpProxyPacketQueue;
- nlc->pHttpProxyPacketQueue = nlc->pHttpProxyPacketQueue->next;
-
- mir_free(p->dataBuffer);
- mir_free(p);
- }
-}
-
-static bool NetlibHttpGatewaySend(NetlibConnection *nlc, RequestType reqType, const char *buf, int len)
-{
- NETLIBHTTPREQUEST nlhrSend = { 0 };
- char szUrl[512];
-
- nlhrSend.cbSize = sizeof(nlhrSend);
- nlhrSend.nlc = nlc;
-
- nlhrSend.pData = (char*)buf;
- nlhrSend.dataLength = len;
-
- nlhrSend.flags = NLHRF_GENERATEHOST | NLHRF_DUMPPROXY | NLHRF_SMARTAUTHHEADER | NLHRF_NOPROXY | NLHRF_REDIRECT;
- if (nlc->nlhpi.flags & NLHPIF_HTTP11)
- nlhrSend.flags |= NLHRF_HTTP11;
-
- switch (reqType) {
- case reqHelloGet:
- nlhrSend.requestType = REQUEST_GET;
- nlhrSend.szUrl = nlc->nlu->user.szHttpGatewayHello;
- break;
-
- case reqOldGet:
- nlhrSend.requestType = REQUEST_GET;
- nlhrSend.timeout = -1;
- if ((nlc->nlhpi.flags & NLHPIF_USEGETSEQUENCE) && (nlc->nlhpi.szHttpGetUrl != NULL)) {
- mir_cslock lck(nlc->csHttpSequenceNums);
- mir_snprintf(szUrl, "%s%u", nlc->nlhpi.szHttpGetUrl, nlc->nlhpi.firstGetSequence++);
- if (nlc->nlhpi.flags & NLHPIF_GETPOSTSAMESEQUENCE)
- nlc->nlhpi.firstPostSequence++;
- nlhrSend.szUrl = szUrl;
- }
- else nlhrSend.szUrl = nlc->nlhpi.szHttpGetUrl;
- break;
-
- case reqOldPost:
- nlhrSend.requestType = REQUEST_POST;
- if ((nlc->nlhpi.flags & NLHPIF_USEPOSTSEQUENCE) && (nlc->nlhpi.szHttpPostUrl != NULL)) {
- mir_snprintf(szUrl, "%s%u", nlc->nlhpi.szHttpPostUrl, nlc->nlhpi.firstPostSequence);
- nlhrSend.szUrl = szUrl;
- }
- else nlhrSend.szUrl = nlc->nlhpi.szHttpPostUrl;
- break;
-
- case reqNewPost:
- nlhrSend.requestType = REQUEST_POST;
- nlhrSend.szUrl = nlc->nlhpi.szHttpPostUrl;
- break;
- }
-
- if (nlc->usingDirectHttpGateway) {
- NETLIBOPENCONNECTION nloc;
- NetlibConnFromUrl(nlhrSend.szUrl, false, nloc);
-
- bool sameHost = mir_strcmp(nlc->nloc.szHost, nloc.szHost) == 0 && nlc->nloc.wPort == nloc.wPort;
- if (!sameHost) {
- NetlibDoClose(nlc);
-
- mir_free((char*)nlc->nloc.szHost);
- nlc->nloc = nloc;
- if (!NetlibDoConnect(nlc))
- return false;
- }
- else mir_free((char*)nloc.szHost);
- }
-
- nlhrSend.headersCount = 3;
- nlhrSend.headers = (NETLIBHTTPHEADER*)alloca(sizeof(NETLIBHTTPHEADER) * nlhrSend.headersCount);
- nlhrSend.headers[0].szName = "User-Agent";
- nlhrSend.headers[0].szValue = nlc->nlu->user.szHttpGatewayUserAgent;
- nlhrSend.headers[1].szName = "Cache-Control";
- nlhrSend.headers[1].szValue = "no-cache, no-store ";
- nlhrSend.headers[2].szName = "Pragma";
- nlhrSend.headers[2].szValue = "no-cache";
- return NetlibHttpSendRequest((WPARAM)nlc, (LPARAM)&nlhrSend) != SOCKET_ERROR;
-}
-
-static bool NetlibHttpGatewayStdPost(NetlibConnection *nlc, int &numPackets)
-{
- int np = 0, len = 0;
- char *buf;
- NetlibHTTPProxyPacketQueue *p;
- {
- mir_cslock lck(nlc->csHttpSequenceNums);
-
- for (p = nlc->pHttpProxyPacketQueue; p != NULL && np < nlc->nlhpi.combinePackets; p = p->next) {
- np++;
- len += p->dataBufferLen;
- }
-
- int dlen = 0;
- buf = (char*)alloca(len);
- numPackets = np;
-
- for (p = nlc->pHttpProxyPacketQueue; np--; p = p->next) {
- memcpy(buf + dlen, p->dataBuffer, p->dataBufferLen);
- dlen += p->dataBufferLen;
- }
- }
-
- return NetlibHttpGatewaySend(nlc, reqNewPost, buf, len);
-}
-
-static bool NetlibHttpGatewayOscarPost(NetlibConnection *nlc, const char *buf, int len, int flags)
-{
- NetlibConnection nlcSend = { 0 };
- nlcSend.handleType = NLH_CONNECTION;
- nlcSend.nlu = nlc->nlu;
- nlcSend.nlhpi = nlc->nlhpi;
- nlcSend.s = nlc->s2;
- nlcSend.usingHttpGateway = nlc->usingHttpGateway;
- nlcSend.szProxyServer = nlc->szProxyServer;
- nlcSend.wProxyPort = nlc->wProxyPort;
- nlcSend.proxyType = nlc->proxyType;
-
- if (!NetlibReconnect(&nlcSend)) return false;
- nlc->s2 = nlcSend.s;
-
- nlcSend.hOkToCloseEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
- NetlibInitializeNestedCS(&nlcSend.ncsRecv);
- NetlibInitializeNestedCS(&nlcSend.ncsSend);
-
- bool res = NetlibHttpGatewaySend(&nlcSend, reqOldPost, buf, len);
- if (res) {
- NETLIBHTTPREQUEST *nlhrReply = NetlibHttpRecv(&nlcSend, flags | MSG_RAW | MSG_DUMPPROXY, MSG_RAW | MSG_DUMPPROXY);
- if (nlhrReply != NULL) {
- if (nlhrReply->resultCode != 200) {
- NetlibHttpSetLastErrorUsingHttpResult(nlhrReply->resultCode);
- res = false;
- }
- NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply);
- }
- else res = false;
- }
-
- NetlibDeleteNestedCS(&nlcSend.ncsSend);
- NetlibDeleteNestedCS(&nlcSend.ncsRecv);
- CloseHandle(nlcSend.hOkToCloseEvent);
-
- nlc->s2 = nlcSend.s;
- mir_free((char*)nlcSend.nloc.szHost);
-
- mir_cslock lck(nlc->csHttpSequenceNums);
- nlc->nlhpi.firstPostSequence++;
- if (nlc->nlhpi.flags & NLHPIF_GETPOSTSAMESEQUENCE)
- nlc->nlhpi.firstGetSequence++;
-
- return res;
-}
-
-int NetlibHttpGatewayPost(NetlibConnection *nlc, const char *buf, int len, int flags)
-{
- if (nlc->nlhpi.szHttpGetUrl != NULL)
- return NetlibHttpGatewayOscarPost(nlc, buf, len, flags) ? len : SOCKET_ERROR;
-
- /*
- * Gena01 - many changes here, do compare against the other version.
- *
- * Change #1: simplify to use similar code to GET
- * Change #2: we need to allow to parse POST reply if szHttpGetUrl is NULL
- * Change #3: Keep connection open if we need to.
- *
- * Impact: NONE! Since currently miranda doesn't allow szHttpGetUrl to be NULL, it will not connect
- * with the new plugins that use this code.
- */
-
- NetlibHTTPProxyPacketQueue *p = (NetlibHTTPProxyPacketQueue*)mir_alloc(sizeof(struct NetlibHTTPProxyPacketQueue));
- p->dataBuffer = (PBYTE)mir_alloc(len);
- memcpy(p->dataBuffer, buf, len);
- p->dataBufferLen = len;
- p->next = NULL;
-
- /*
- * Now check to see where to insert this in our queue
- */
-
- mir_cslock lck(nlc->csHttpSequenceNums);
- if (nlc->pHttpProxyPacketQueue == NULL)
- nlc->pHttpProxyPacketQueue = p;
- else {
- NetlibHTTPProxyPacketQueue *t = nlc->pHttpProxyPacketQueue;
- while (t->next != NULL)
- t = t->next;
- t->next = p;
- }
-
- /*
- * Gena01 - fake a Send!! tell 'em all is ok. We catch errors in Recv.
- */
- return len;
-}
-
-#define NETLIBHTTP_RETRYCOUNT 3
-#define NETLIBHTTP_RETRYTIMEOUT 2000
-
-int NetlibHttpGatewayRecv(NetlibConnection *nlc, char *buf, int len, int flags)
-{
- bool peek = (flags & MSG_PEEK) != 0;
-
- if (nlc->dataBufferLen != 0 && (!peek || nlc->dataBufferLen >= len)) {
- return HttpGatewayReadSetResult(nlc, buf, len, peek);
- }
-
- for (int retryCount = 0; retryCount < NETLIBHTTP_RETRYCOUNT;) {
- if (nlc->nlhpi.szHttpGetUrl == NULL && retryCount == 0) {
- if (nlc->pollingTimeout == 0) nlc->pollingTimeout = 30;
-
- /* We Need to sleep/wait for the data to send before we do receive */
- for (int pollCount = nlc->pollingTimeout; pollCount--;) {
- if (nlc->pHttpProxyPacketQueue != NULL && GetTickCount() - nlc->lastPost > 1000)
- break;
-
- if (nlc->termRequested || (SleepEx(1000, TRUE) && Miranda_Terminated()))
- return SOCKET_ERROR;
- }
-
- nlc->lastPost = GetTickCount();
- if (nlc->pHttpProxyPacketQueue == NULL && nlc->nlu->user.pfnHttpGatewayWrapSend != NULL) {
- if (nlc->nlu->user.pfnHttpGatewayWrapSend(nlc, (PBYTE)"", 0, MSG_NOHTTPGATEWAYWRAP, NetlibSend) == SOCKET_ERROR)
- return SOCKET_ERROR;
- }
- }
-
- int numPackets = 0;
- if (nlc->nlhpi.szHttpGetUrl) {
- if (!NetlibHttpGatewaySend(nlc, reqOldGet, NULL, 0)) {
- if (GetLastError() == ERROR_ACCESS_DENIED || nlc->termRequested)
- break;
-
- ++retryCount;
- continue;
- }
- }
- else {
- if (!NetlibHttpGatewayStdPost(nlc, numPackets)) {
- if (GetLastError() == ERROR_ACCESS_DENIED || nlc->termRequested)
- break;
-
- ++retryCount;
- continue;
- }
- }
- NETLIBHTTPREQUEST *nlhrReply = NetlibHttpRecv(nlc, flags | MSG_RAW | MSG_DUMPPROXY, MSG_RAW | MSG_DUMPPROXY);
- if (nlhrReply == NULL) return SOCKET_ERROR;
-
- if (nlc->nlu->user.pfnHttpGatewayUnwrapRecv && !(flags & MSG_NOHTTPGATEWAYWRAP)) {
- nlhrReply->pData = (char*)nlc->nlu->user.pfnHttpGatewayUnwrapRecv(nlhrReply,
- (PBYTE)nlhrReply->pData, nlhrReply->dataLength, &nlhrReply->dataLength, mir_realloc);
- }
-
- if (nlhrReply->resultCode >= 300) {
- int resultCode = nlhrReply->resultCode;
- NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply);
-
- if (nlc->nlhpi.szHttpGetUrl && resultCode != 404) {
- NetlibLogf(nlc->nlu, "Error received from proxy, retrying");
- continue;
- }
- else {
- NetlibLogf(nlc->nlu, "Error received from proxy, retry attempts exceeded (%u)", retryCount);
- SetLastError(ERROR_GEN_FAILURE);
- return SOCKET_ERROR;
- }
- }
- else {
- retryCount = 0;
- HttpGatewayRemovePacket(nlc, numPackets);
- }
-
- if (nlhrReply->dataLength) {
- if (peek) {
- int rbytes = nlc->dataBufferLen + nlhrReply->dataLength;
-
- nlc->dataBuffer = (PBYTE)mir_realloc(nlc->dataBuffer, rbytes);
- memcpy(nlc->dataBuffer + nlc->dataBufferLen, nlhrReply->pData, nlhrReply->dataLength);
- nlc->dataBufferLen = rbytes;
-
- NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply);
-
- return HttpGatewayReadSetResult(nlc, buf, len, peek);
- }
- else {
- int bytes = min(len, nlhrReply->dataLength);
- int rbytes = nlhrReply->dataLength - bytes;
-
- memcpy(buf, nlhrReply->pData, bytes);
-
- nlc->dataBuffer = (PBYTE)mir_realloc(nlc->dataBuffer, rbytes);
- if (rbytes) memcpy(nlc->dataBuffer, nlhrReply->pData + bytes, rbytes);
- nlc->dataBufferLen = rbytes;
-
- NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply);
- return bytes;
- }
- }
- else {
- if ((peek && nlc->dataBufferLen != 0) || nlhrReply->pData) {
- NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply);
- return HttpGatewayReadSetResult(nlc, buf, len, peek);
- }
- }
- NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply);
- }
-
- SetLastError(ERROR_GEN_FAILURE);
- return SOCKET_ERROR;
-}
-
-int NetlibInitHttpConnection(NetlibConnection *nlc, NetlibUser *nlu, NETLIBOPENCONNECTION *nloc)
-{
- NETLIBHTTPREQUEST *nlhrReply = NULL;
- {
- mir_cslock lck(nlc->csHttpSequenceNums);
- nlc->nlhpi.firstGetSequence = 1;
- nlc->nlhpi.firstPostSequence = 1;
- }
-
- if (nlu->user.szHttpGatewayHello != NULL) {
- nlc->usingHttpGateway = true;
- if (NetlibHttpGatewaySend(nlc, reqHelloGet, NULL, 0))
- nlhrReply = NetlibHttpRecv(nlc, MSG_DUMPPROXY | MSG_RAW, MSG_DUMPPROXY | MSG_RAW);
- nlc->usingHttpGateway = false;
- if (nlhrReply == NULL) return 0;
-
- if (nlhrReply->resultCode != 200) {
- NetlibHttpSetLastErrorUsingHttpResult(nlhrReply->resultCode);
- NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply);
- return 0;
- }
- }
- if (!nlu->user.pfnHttpGatewayInit(nlc, nloc, nlhrReply)) {
- NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply);
- return 0;
- }
- NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply);
-
- /*
- * Gena01 - Ok, we should be able to use just POST. Needed for Yahoo, NO GET requests
- */
- if (nlc->nlhpi.szHttpPostUrl == NULL) {
- SetLastError(ERROR_BAD_FORMAT);
- return 0;
- }
-
- nlc->usingHttpGateway = true;
-
- //now properly connected
- if (nlu->user.pfnHttpGatewayBegin && !nlu->user.pfnHttpGatewayBegin(nlc, nloc))
- return 0;
-
- return 1;
-}
-
-INT_PTR NetlibHttpGatewaySetInfo(WPARAM wParam, LPARAM lParam)
-{
- NETLIBHTTPPROXYINFO *nlhpi = (NETLIBHTTPPROXYINFO*)lParam;
- NetlibConnection *nlc = (struct NetlibConnection*)wParam;
-
- if (GetNetlibHandleType(nlc) != NLH_CONNECTION || nlhpi == NULL ||
- nlhpi->cbSize < (sizeof(NETLIBHTTPPROXYINFO) - sizeof(int)) ||
- nlhpi->szHttpPostUrl == NULL) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- mir_free(nlc->nlhpi.szHttpGetUrl);
- mir_free(nlc->nlhpi.szHttpPostUrl);
-
- nlc->nlhpi.combinePackets = 1;
- memcpy(&nlc->nlhpi, nlhpi, min(nlhpi->cbSize, sizeof(*nlhpi)));
- if (nlc->nlhpi.combinePackets == 0) nlc->nlhpi.combinePackets = 1;
-
- nlc->nlhpi.szHttpGetUrl = mir_strdup(nlc->nlhpi.szHttpGetUrl);
- nlc->nlhpi.szHttpPostUrl = mir_strdup(nlc->nlhpi.szHttpPostUrl);
-
- return 1;
-}
-
-INT_PTR NetlibHttpSetSticky(WPARAM wParam, LPARAM lParam)
-{
- NetlibUser * nu = (NetlibUser*)wParam;
- if (GetNetlibHandleType(nu) != NLH_USER) return ERROR_INVALID_PARAMETER;
- mir_free(nu->szStickyHeaders);
- nu->szStickyHeaders = mir_strdup((char*)lParam); // pointer is ours
- return 0;
-}
-
-INT_PTR NetlibHttpSetPollingTimeout(WPARAM wParam, LPARAM lParam)
-{
- int oldTimeout;
- NetlibConnection *nlc = (struct NetlibConnection*)wParam;
- if (GetNetlibHandleType(nlc) != NLH_CONNECTION) return -1;
- oldTimeout = nlc->pollingTimeout;
- nlc->pollingTimeout = lParam;
- return oldTimeout;
-}
diff --git a/src/modules/netlib/netliblog.cpp b/src/modules/netlib/netliblog.cpp
deleted file mode 100644
index 2d3db45941..0000000000
--- a/src/modules/netlib/netliblog.cpp
+++ /dev/null
@@ -1,532 +0,0 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (ñ) 2012-15 Miranda NG project (http://miranda-ng.org),
-Copyright (c) 2000-12 Miranda IM project,
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "..\..\core\commonheaders.h"
-#include "netlib.h"
-
-#define MS_NETLIB_LOGWIN "Netlib/Log/Win"
-
-extern HANDLE hConnectionHeaderMutex;
-
-#define TIMEFORMAT_NONE 0
-#define TIMEFORMAT_HHMMSS 1
-#define TIMEFORMAT_MILLISECONDS 2
-#define TIMEFORMAT_MICROSECONDS 3
-struct {
- HWND hwndOpts;
- int toOutputDebugString;
- int toFile;
- int toLog;
- int timeFormat;
- int showUser;
- int dumpSent, dumpRecv, dumpProxy, dumpSsl;
- int textDumps, autoDetectText;
- CMString tszFile, tszUserFile;
-}
-static logOptions = { 0 };
-
-struct LOGMSG
-{
- const char* pszHead;
- const char* pszMsg;
-};
-
-static __int64 mirandaStartTime, perfCounterFreq;
-static int bIsActive = TRUE;
-static HANDLE hLogEvent = NULL;
-static HANDLE hLogger = NULL;
-
-static void InitLog()
-{
- if (hLogger) {
- mir_closeLog(hLogger);
- hLogger = NULL;
- }
-
- ptrT szBuf(db_get_tsa(NULL, "Netlib", "File"));
- if (mir_tstrlen(szBuf)) {
- logOptions.tszUserFile = szBuf;
-
- TCHAR path[MAX_PATH];
- PathToAbsoluteT(VARST(szBuf), path);
- logOptions.tszFile = path;
- }
- else {
- db_set_ts(NULL, "Netlib", "File", logOptions.tszUserFile = _T("%miranda_logpath%\\netlog.txt"));
- logOptions.tszFile = Utils_ReplaceVarsT(logOptions.tszUserFile);
- }
-
- if (logOptions.toFile)
- hLogger = mir_createLog("Netlib", LPGENT("Standard netlib log"), logOptions.tszFile, 0);
-}
-
-static const TCHAR* szTimeFormats[] =
-{
- LPGENT("No times"),
- LPGENT("Standard hh:mm:ss times"),
- LPGENT("Times in milliseconds"),
- LPGENT("Times in microseconds")
-};
-
-static INT_PTR CALLBACK LogOptionsDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
-{
- TCHAR str[MAX_PATH];
-
- switch (message) {
- case WM_INITDIALOG:
- logOptions.hwndOpts = hwndDlg;
- TranslateDialogDefault(hwndDlg);
- CheckDlgButton(hwndDlg, IDC_DUMPRECV, logOptions.dumpRecv ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hwndDlg, IDC_DUMPSENT, logOptions.dumpSent ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hwndDlg, IDC_DUMPPROXY, logOptions.dumpProxy ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hwndDlg, IDC_DUMPSSL, logOptions.dumpSsl ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hwndDlg, IDC_TEXTDUMPS, logOptions.textDumps ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hwndDlg, IDC_AUTODETECTTEXT, logOptions.autoDetectText ? BST_CHECKED : BST_UNCHECKED);
- {
- for (int i=0; i < SIZEOF(szTimeFormats); i++)
- SendDlgItemMessage(hwndDlg, IDC_TIMEFORMAT, CB_ADDSTRING, 0, (LPARAM)TranslateTS(szTimeFormats[i]));
- }
- SendDlgItemMessage(hwndDlg, IDC_TIMEFORMAT, CB_SETCURSEL, logOptions.timeFormat, 0);
- CheckDlgButton(hwndDlg, IDC_SHOWNAMES, logOptions.showUser ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hwndDlg, IDC_TOOUTPUTDEBUGSTRING, logOptions.toOutputDebugString ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hwndDlg, IDC_TOFILE, logOptions.toFile ? BST_CHECKED : BST_UNCHECKED);
- SetDlgItemText(hwndDlg, IDC_FILENAME, logOptions.tszUserFile);
- SetDlgItemText(hwndDlg, IDC_PATH, logOptions.tszFile);
- CheckDlgButton(hwndDlg, IDC_SHOWTHISDLGATSTART, db_get_b(NULL, "Netlib", "ShowLogOptsAtStart", 0) ? BST_CHECKED : BST_UNCHECKED);
- {
- ptrA szRun(db_get_sa(NULL, "Netlib", "RunAtStart"));
- if (szRun)
- SetDlgItemTextA(hwndDlg, IDC_RUNATSTART, szRun);
-
- HWND hwndFilter = GetDlgItem(hwndDlg, IDC_FILTER);
- SetWindowLongPtr(hwndFilter, GWL_STYLE, GetWindowLongPtr(hwndFilter, GWL_STYLE) | (TVS_NOHSCROLL | TVS_CHECKBOXES));
-
- TVINSERTSTRUCT tvis = { 0 };
- tvis.hInsertAfter = TVI_SORT;
- tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_STATE;
- tvis.item.stateMask = TVIS_STATEIMAGEMASK;
-
- for (int i = 0; i < netlibUser.getCount(); i++) {
- tvis.item.pszText = netlibUser[i]->user.ptszDescriptiveName;
- tvis.item.lParam = i;
- tvis.item.state = INDEXTOSTATEIMAGEMASK((netlibUser[i]->toLog) ? 2 : 1);
- TreeView_InsertItem(hwndFilter, &tvis);
- }
- tvis.item.lParam = -1;
- tvis.item.pszText = TranslateT("(Miranda core logging)");
- tvis.item.state = INDEXTOSTATEIMAGEMASK((logOptions.toLog) ? 2 : 1);
- TreeView_InsertItem(hwndFilter, &tvis);
- }
- return TRUE;
-
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDC_FILENAME:
- if (HIWORD(wParam) == EN_CHANGE) {
- if ((HWND)lParam == GetFocus())
- CheckDlgButton(hwndDlg, IDC_TOFILE, BST_CHECKED);
-
- TCHAR path[MAX_PATH];
- GetWindowText((HWND)lParam, path, SIZEOF(path));
-
- PathToAbsoluteT(VARST(path), path);
- SetDlgItemText(hwndDlg, IDC_PATH, path);
- }
- break;
-
- case IDC_FILENAMEBROWSE:
- case IDC_RUNATSTARTBROWSE:
- GetWindowText(GetWindow((HWND)lParam, GW_HWNDPREV), str, SIZEOF(str));
- {
- TCHAR filter[200];
- mir_sntprintf(filter, SIZEOF(filter), _T("%s (*)%c*%c"), TranslateT("All files"), 0, 0);
-
- OPENFILENAME ofn = { 0 };
- ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
- ofn.hwndOwner = hwndDlg;
- ofn.Flags = OFN_HIDEREADONLY | OFN_DONTADDTORECENT;
- if (LOWORD(wParam) == IDC_FILENAMEBROWSE)
- ofn.lpstrTitle = TranslateT("Select where log file will be created");
- else {
- ofn.Flags |= OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
- ofn.lpstrTitle = TranslateT("Select program to be run");
- }
- ofn.lpstrFilter = filter;
- ofn.lpstrFile = str;
- ofn.nMaxFile = SIZEOF(str) - 2;
- ofn.nMaxFileTitle = MAX_PATH;
- if (LOWORD(wParam) == IDC_FILENAMEBROWSE) {
- if (!GetSaveFileName(&ofn)) return 1;
- }
- else if (!GetOpenFileName(&ofn))
- return 1;
-
- if (LOWORD(wParam) == IDC_RUNATSTARTBROWSE && _tcschr(str, ' ') != NULL) {
- memmove(str + 1, str, ((SIZEOF(str) - 2) * sizeof(TCHAR)));
- str[0] = '"';
- mir_tstrcat(str, _T("\""));
- }
- SetWindowText(GetWindow((HWND)lParam, GW_HWNDPREV), str);
- }
- break;
-
- case IDC_RUNNOW:
- GetDlgItemText(hwndDlg, IDC_RUNATSTART, str, SIZEOF(str));
- if (str[0]) {
- STARTUPINFO si = { sizeof(si) };
- PROCESS_INFORMATION pi;
- CreateProcess(NULL, str, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
- }
- break;
-
- case IDOK:
- GetDlgItemText(hwndDlg, IDC_RUNATSTART, str, SIZEOF(str));
- db_set_ts(NULL, "Netlib", "RunAtStart", str);
- db_set_b(NULL, "Netlib", "ShowLogOptsAtStart", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_SHOWTHISDLGATSTART));
-
- GetDlgItemText(hwndDlg, IDC_FILENAME, str, SIZEOF(str));
- logOptions.tszUserFile = rtrimt(str);
- db_set_ts(NULL, "Netlib", "File", str);
-
- GetDlgItemText(hwndDlg, IDC_PATH, str, SIZEOF(str));
- logOptions.tszFile = rtrimt(str);
-
- db_set_b(NULL, "Netlib", "DumpRecv", logOptions.dumpRecv = IsDlgButtonChecked(hwndDlg, IDC_DUMPRECV));
- db_set_b(NULL, "Netlib", "DumpSent", logOptions.dumpSent = IsDlgButtonChecked(hwndDlg, IDC_DUMPSENT));
- db_set_b(NULL, "Netlib", "DumpProxy", logOptions.dumpProxy = IsDlgButtonChecked(hwndDlg, IDC_DUMPPROXY));
- db_set_b(NULL, "Netlib", "DumpSsl", logOptions.dumpSsl = IsDlgButtonChecked(hwndDlg, IDC_DUMPSSL));
- db_set_b(NULL, "Netlib", "TextDumps", logOptions.textDumps = IsDlgButtonChecked(hwndDlg, IDC_TEXTDUMPS));
- db_set_b(NULL, "Netlib", "AutoDetectText", logOptions.autoDetectText = IsDlgButtonChecked(hwndDlg, IDC_AUTODETECTTEXT));
- db_set_b(NULL, "Netlib", "TimeFormat", logOptions.timeFormat = SendDlgItemMessage(hwndDlg, IDC_TIMEFORMAT, CB_GETCURSEL, 0, 0));
- db_set_b(NULL, "Netlib", "ShowUser", logOptions.showUser = IsDlgButtonChecked(hwndDlg, IDC_SHOWNAMES));
- db_set_b(NULL, "Netlib", "ToOutputDebugString", logOptions.toOutputDebugString = IsDlgButtonChecked(hwndDlg, IDC_TOOUTPUTDEBUGSTRING));
- db_set_b(NULL, "Netlib", "ToFile", logOptions.toFile = IsDlgButtonChecked(hwndDlg, IDC_TOFILE));
- {
- HWND hwndFilter = GetDlgItem(logOptions.hwndOpts, IDC_FILTER);
- TVITEM tvi = { 0 };
- BOOL checked;
-
- tvi.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_STATE | TVIF_TEXT;
- tvi.hItem = TreeView_GetRoot(hwndFilter);
-
- while (tvi.hItem) {
- TreeView_GetItem(hwndFilter, &tvi);
- checked = ((tvi.state & TVIS_STATEIMAGEMASK) >> 12 == 2);
-
- if (tvi.lParam == -1) {
- logOptions.toLog = checked;
- db_set_dw(NULL, "Netlib", "NLlog", checked);
- }
- else if (tvi.lParam < netlibUser.getCount()) {
- netlibUser[tvi.lParam]->toLog = checked;
- db_set_dw(NULL, netlibUser[tvi.lParam]->user.szSettingsModule, "NLlog", checked);
- }
-
- tvi.hItem = TreeView_GetNextSibling(hwndFilter, tvi.hItem);
- }
- }
- InitLog();
- // fall through
- case IDCANCEL:
- DestroyWindow(hwndDlg);
- }
- break;
-
- case WM_CLOSE:
- DestroyWindow(hwndDlg);
- break;
-
- case WM_DESTROY:
- ImageList_Destroy(TreeView_GetImageList(GetDlgItem(hwndDlg, IDC_FILTER), TVSIL_STATE));
- logOptions.hwndOpts = NULL;
- break;
- }
- return FALSE;
-}
-
-void NetlibLogShowOptions(void)
-{
- if (logOptions.hwndOpts == NULL)
- logOptions.hwndOpts = CreateDialog(hInst, MAKEINTRESOURCE(IDD_NETLIBLOGOPTS), NULL, LogOptionsDlgProc);
- SetForegroundWindow(logOptions.hwndOpts);
-}
-
-static INT_PTR ShowOptions(WPARAM, LPARAM)
-{
- NetlibLogShowOptions();
- return 0;
-}
-
-static INT_PTR NetlibLog(WPARAM wParam, LPARAM lParam)
-{
- if (!bIsActive)
- return 0;
-
- DWORD dwOriginalLastError = GetLastError();
-
- NetlibUser *nlu = (NetlibUser*)wParam;
- const char *pszMsg = (const char*)lParam;
- if ((nlu != NULL && GetNetlibHandleType(nlu) != NLH_USER) || pszMsg == NULL) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- /* if the Netlib user handle is NULL, just pretend its not */
- if (!(nlu != NULL ? nlu->toLog : logOptions.toLog))
- return 1;
-
- LARGE_INTEGER liTimeNow;
- char szTime[32], szHead[128];
- switch (logOptions.timeFormat) {
- case TIMEFORMAT_HHMMSS:
- GetTimeFormatA(LOCALE_USER_DEFAULT, TIME_FORCE24HOURFORMAT | TIME_NOTIMEMARKER, NULL, NULL, szTime, SIZEOF(szTime));
- mir_strcat(szTime, " ");
- break;
-
- case TIMEFORMAT_MILLISECONDS:
- QueryPerformanceCounter(&liTimeNow);
- liTimeNow.QuadPart -= mirandaStartTime;
- mir_snprintf(szTime, SIZEOF(szTime), "%I64u.%03I64u ", liTimeNow.QuadPart / perfCounterFreq,
- 1000 * (liTimeNow.QuadPart % perfCounterFreq) / perfCounterFreq);
- break;
-
- case TIMEFORMAT_MICROSECONDS:
- QueryPerformanceCounter(&liTimeNow);
- liTimeNow.QuadPart -= mirandaStartTime;
- mir_snprintf(szTime, SIZEOF(szTime), "%I64u.%06I64u ", liTimeNow.QuadPart / perfCounterFreq,
- 1000000 * (liTimeNow.QuadPart % perfCounterFreq) / perfCounterFreq);
- break;
-
- default:
- szTime[0] = '\0';
- break;
- }
-
- char *szUser = (logOptions.showUser) ? (nlu == NULL ? NULL : nlu->user.szSettingsModule) : NULL;
- if (szUser)
- mir_snprintf(szHead, SIZEOF(szHead), "[%s%04X] [%s] ", szTime, GetCurrentThreadId(), szUser);
- else
- mir_snprintf(szHead, SIZEOF(szHead), "[%s%04X] ", szTime, GetCurrentThreadId());
-
- if (logOptions.toOutputDebugString) {
- if (szHead[0])
- OutputDebugStringA(szHead);
- OutputDebugStringA(pszMsg);
- OutputDebugStringA("\n");
- }
-
- if (logOptions.toFile && !logOptions.tszFile.IsEmpty()) {
- size_t len = mir_strlen(pszMsg);
- mir_writeLogA(hLogger, "%s%s%s", szHead, pszMsg, pszMsg[len-1] == '\n' ? "" : "\r\n");
- }
-
- LOGMSG logMsg = { szHead, pszMsg };
- NotifyFastHook(hLogEvent, (WPARAM)nlu, (LPARAM)&logMsg);
-
- SetLastError(dwOriginalLastError);
- return 1;
-}
-
-static INT_PTR NetlibLogW(WPARAM wParam, LPARAM lParam)
-{
- const wchar_t *pszMsg = (const wchar_t*)lParam;
- char* szMsg = Utf8EncodeW(pszMsg);
- INT_PTR res = NetlibLog(wParam, (LPARAM)szMsg);
- mir_free(szMsg);
- return res;
-}
-
-void NetlibLogf(NetlibUser* nlu, const char *fmt, ...)
-{
- if (nlu == NULL) {
- if (!logOptions.toLog)
- return;
- }
- else if (!nlu->toLog)
- return;
-
- va_list va;
- char szText[1024];
-
- va_start(va, fmt);
- mir_vsnprintf(szText, sizeof(szText), fmt, va);
- va_end(va);
-
- NetlibLog((WPARAM)nlu, (LPARAM)szText);
-}
-
-void NetlibDumpData(NetlibConnection *nlc, PBYTE buf, int len, int sent, int flags)
-{
- char szTitleLine[128];
- char *szBuf;
- bool useStack = false;
-
- // This section checks a number of conditions and aborts
- // the dump if the data should not be written to the log
-
- // Check packet flags
- if (flags & (MSG_PEEK | MSG_NODUMP))
- return;
-
- // Check user's log settings
- if (!(logOptions.toOutputDebugString || GetSubscribersCount(hLogEvent) != 0 || (logOptions.toFile && !logOptions.tszFile.IsEmpty())))
- return;
- if ((sent && !logOptions.dumpSent) || (!sent && !logOptions.dumpRecv))
- return;
- if ((flags & MSG_DUMPPROXY) && !logOptions.dumpProxy)
- return;
- if ((flags & MSG_DUMPSSL) && !logOptions.dumpSsl)
- return;
-
- WaitForSingleObject(hConnectionHeaderMutex, INFINITE);
- NetlibUser *nlu = nlc ? nlc->nlu : NULL;
- int titleLineLen = mir_snprintf(szTitleLine, SIZEOF(szTitleLine), "(%p:%u) Data %s%s\r\n",
- nlc, nlc ? nlc->s : 0, sent ? "sent" : "received", flags & MSG_DUMPPROXY ? " (proxy)" : "");
- ReleaseMutex(hConnectionHeaderMutex);
-
- // check filter settings
- if (nlu == NULL) {
- if (!logOptions.toLog)
- return;
- }
- else if (!nlu->toLog)
- return;
-
- bool isText = true;
- if (!logOptions.textDumps)
- isText = false;
- else if (!(flags & MSG_DUMPASTEXT)) {
- if (logOptions.autoDetectText) {
- for (int i = 0; i < len; i++) {
- if ((buf[i] < ' ' && buf[i] != '\t' && buf[i] != '\r' && buf[i] != '\n') || buf[i] >= 0x80) {
- isText = false;
- break;
- }
- }
- }
- else isText = false;
- }
-
- // Text data
- if (isText) {
- int sz = titleLineLen + len + 1;
- useStack = sz <= 8192;
- szBuf = (char*)(useStack ? alloca(sz) : mir_alloc(sz));
- memcpy(szBuf, szTitleLine, titleLineLen);
- memcpy(szBuf + titleLineLen, (const char*)buf, len);
- szBuf[titleLineLen + len] = '\0';
- }
- // Binary data
- else {
- int line, col, colsInLine;
- int sz = titleLineLen + ((len + 16) >> 4) * 78 + 1;
- useStack = sz <= 8192;
-
- szBuf = (char*)(useStack ? alloca(sz) : mir_alloc(sz));
- memcpy(szBuf, szTitleLine, titleLineLen);
- char *pszBuf = szBuf + titleLineLen;
- for (line = 0;; line += 16) {
- colsInLine = min(16, len - line);
-
- if (colsInLine == 16) {
- PBYTE p = buf + line;
- pszBuf += wsprintfA(
- pszBuf, "%08X: %02X %02X %02X %02X-%02X %02X %02X %02X-%02X %02X %02X %02X-%02X %02X %02X %02X ",
- line, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); //!!!!!!!!!!
- }
- else {
- pszBuf += wsprintfA(pszBuf, "%08X: ", line); //!!!!!!!!!!
- // Dump data as hex
- for (col = 0; col < colsInLine; col++)
- pszBuf += wsprintfA(pszBuf, "%02X%c", buf[line + col], ((col & 3) == 3 && col != 15) ? '-' : ' '); //!!!!!!!!!!
- // Fill out last line with blanks
- for (; col < 16; col++) {
- mir_strcpy(pszBuf, " ");
- pszBuf += 3;
- }
- *pszBuf++ = ' ';
- }
-
- for (col = 0; col < colsInLine; col++)
- *pszBuf++ = (buf[line + col] < ' ') ? '.' : (char)buf[line + col];
-
- if (len - line <= 16)
- break;
-
- *pszBuf++ = '\r'; // End each line with a break
- *pszBuf++ = '\n'; // End each line with a break
- }
- *pszBuf = '\0';
- }
-
- NetlibLog((WPARAM)nlu, (LPARAM)szBuf);
- if (!useStack)
- mir_free(szBuf);
-}
-
-void NetlibLogInit(void)
-{
- LARGE_INTEGER li;
- QueryPerformanceFrequency(&li);
- perfCounterFreq = li.QuadPart;
- QueryPerformanceCounter(&li);
- mirandaStartTime = li.QuadPart;
-
- CreateServiceFunction(MS_NETLIB_LOGWIN, ShowOptions);
- CreateServiceFunction(MS_NETLIB_LOG, NetlibLog);
- CreateServiceFunction(MS_NETLIB_LOGW, NetlibLogW);
- hLogEvent = CreateHookableEvent(ME_NETLIB_FASTDUMP);
-
- logOptions.dumpRecv = db_get_b(NULL, "Netlib", "DumpRecv", 1);
- logOptions.dumpSent = db_get_b(NULL, "Netlib", "DumpSent", 1);
- logOptions.dumpProxy = db_get_b(NULL, "Netlib", "DumpProxy", 1);
- logOptions.dumpSsl = db_get_b(NULL, "Netlib", "DumpSsl", 0);
- logOptions.textDumps = db_get_b(NULL, "Netlib", "TextDumps", 1);
- logOptions.autoDetectText = db_get_b(NULL, "Netlib", "AutoDetectText", 1);
- logOptions.timeFormat = db_get_b(NULL, "Netlib", "TimeFormat", TIMEFORMAT_HHMMSS);
- logOptions.showUser = db_get_b(NULL, "Netlib", "ShowUser", 1);
- logOptions.toOutputDebugString = db_get_b(NULL, "Netlib", "ToOutputDebugString", 0);
- logOptions.toFile = db_get_b(NULL, "Netlib", "ToFile", 0);
- logOptions.toLog = db_get_dw(NULL, "Netlib", "NLlog", 1);
-
- InitLog();
-
- if (db_get_b(NULL, "Netlib", "ShowLogOptsAtStart", 0))
- NetlibLogShowOptions();
-
- ptrT szBuf(db_get_tsa(NULL, "Netlib", "RunAtStart"));
- if (szBuf) {
- STARTUPINFO si = { sizeof(si) };
- PROCESS_INFORMATION pi;
- CreateProcess(NULL, szBuf, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
- }
-}
-
-void NetlibLogShutdown(void)
-{
- bIsActive = FALSE;
- DestroyHookableEvent(hLogEvent); hLogEvent = NULL;
- if (IsWindow(logOptions.hwndOpts))
- DestroyWindow(logOptions.hwndOpts);
-}
diff --git a/src/modules/netlib/netlibopenconn.cpp b/src/modules/netlib/netlibopenconn.cpp
deleted file mode 100644
index 1eb1ba633c..0000000000
--- a/src/modules/netlib/netlibopenconn.cpp
+++ /dev/null
@@ -1,890 +0,0 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (ñ) 2012-15 Miranda NG project (http://miranda-ng.org),
-Copyright (c) 2000-12 Miranda IM project,
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "..\..\core\commonheaders.h"
-#include "netlib.h"
-
-extern mir_cs csNetlibUser;
-extern HANDLE hConnectionOpenMutex;
-extern DWORD g_LastConnectionTick;
-extern int connectionTimeout;
-static int iUPnPCleanup = 0;
-
-#define RECV_DEFAULT_TIMEOUT 60000
-
-//returns in network byte order
-DWORD DnsLookup(NetlibUser *nlu, const char *szHost)
-{
- HOSTENT* host;
- DWORD ip = inet_addr(szHost);
- if (ip != INADDR_NONE)
- return ip;
-
- __try
- {
- host = gethostbyname(szHost);
- if (host)
- return *(u_long*)host->h_addr_list[0];
-
- NetlibLogf(nlu, "%s %d: %s() for host %s failed (%u)", __FILE__, __LINE__, "gethostbyname", szHost, WSAGetLastError());
- }
- __except(EXCEPTION_EXECUTE_HANDLER) {}
-
- return 0;
-}
-
-int WaitUntilReadable(SOCKET s, DWORD dwTimeout, bool check)
-{
- fd_set readfd;
- TIMEVAL tv;
-
- if (s == INVALID_SOCKET) return SOCKET_ERROR;
-
- tv.tv_sec = dwTimeout / 1000;
- tv.tv_usec = (dwTimeout % 1000) * 1000;
-
- FD_ZERO(&readfd);
- FD_SET(s, &readfd);
-
- int result = select(0, &readfd, 0, 0, &tv);
- if (result == 0 && !check) SetLastError(ERROR_TIMEOUT);
- return result;
-}
-
-int WaitUntilWritable(SOCKET s, DWORD dwTimeout)
-{
- fd_set writefd;
- TIMEVAL tv;
-
- tv.tv_sec = dwTimeout / 1000;
- tv.tv_usec = (dwTimeout % 1000) * 1000;
-
- FD_ZERO(&writefd);
- FD_SET(s, &writefd);
-
- switch(select(0, 0, &writefd, 0, &tv)) {
- case 0:
- SetLastError(ERROR_TIMEOUT);
- case SOCKET_ERROR:
- return 0;
- }
- return 1;
-}
-
-bool RecvUntilTimeout(NetlibConnection *nlc, char *buf, int len, int flags, DWORD dwTimeout)
-{
- int nReceived = 0;
- DWORD dwTimeNow, dwCompleteTime = GetTickCount() + dwTimeout;
-
- while ((dwTimeNow = GetTickCount()) < dwCompleteTime) {
- if (WaitUntilReadable(nlc->s, dwCompleteTime - dwTimeNow) <= 0) return false;
- nReceived = NLRecv(nlc, buf, len, flags);
- if (nReceived <= 0) return false;
-
- buf += nReceived;
- len -= nReceived;
- if (len <= 0) return true;
- }
- SetLastError(ERROR_TIMEOUT);
- return false;
-}
-
-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 || !nloc->szHost || !nloc->szHost[0]) return 0;
-
- size_t nHostLen = mir_strlen(nloc->szHost) + 1;
- size_t nUserLen = nlu->settings.szProxyAuthUser ? mir_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(NetlibConnection *nlc, 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
- size_t nUserLen = mir_strlen(nlu->settings.szProxyAuthUser);
- size_t nPassLen = mir_strlen(nlu->settings.szProxyAuthPassword);
- PBYTE pAuthBuf = (PBYTE)mir_alloc(3 + nUserLen + nPassLen);
- pAuthBuf[0] = 1; //auth version
- pAuthBuf[1] = (BYTE)nUserLen;
- memcpy(pAuthBuf + 2, nlu->settings.szProxyAuthUser, nUserLen);
- pAuthBuf[2 + nUserLen] = (BYTE)nPassLen;
- memcpy(pAuthBuf + 3 + nUserLen, nlu->settings.szProxyAuthPassword, nPassLen);
- if (NLSend(nlc, (char*)pAuthBuf, int(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;
- }
- }
-
- size_t nHostLen;
- DWORD hostIP;
-
- if (nlc->dnsThroughProxy) {
- hostIP = inet_addr(nloc->szHost);
- nHostLen = (hostIP == INADDR_NONE) ? mir_strlen(nloc->szHost) + 1 : 4;
- }
- else {
- hostIP = DnsLookup(nlu, nloc->szHost);
- if (hostIP == 0)
- return 0;
- nHostLen = 4;
- }
- PBYTE 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] = BYTE(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, int(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;
-}
-
-static bool NetlibInitHttpsConnection(NetlibConnection *nlc, NetlibUser *nlu, NETLIBOPENCONNECTION *nloc)
-{
- //rfc2817
- NETLIBHTTPREQUEST nlhrSend = { 0 };
- 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, "%s:%u", nloc->szHost, nloc->wPort);
- else {
- DWORD ip = DnsLookup(nlu, nloc->szHost);
- if (ip == 0) return false;
- mir_snprintf(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;
- }
-
- NETLIBHTTPREQUEST *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;
-}
-
-static void FreePartiallyInitedConnection(NetlibConnection *nlc)
-{
- DWORD dwOriginalLastError = GetLastError();
-
- if (nlc->s != INVALID_SOCKET) closesocket(nlc->s);
- mir_free(nlc->nlhpi.szHttpPostUrl);
- mir_free(nlc->nlhpi.szHttpGetUrl);
- mir_free((char*)nlc->nloc.szHost);
- mir_free(nlc->szProxyServer);
- NetlibDeleteNestedCS(&nlc->ncsSend);
- NetlibDeleteNestedCS(&nlc->ncsRecv);
- CloseHandle(nlc->hOkToCloseEvent);
- DeleteCriticalSection(&nlc->csHttpSequenceNums);
- mir_free(nlc);
- SetLastError(dwOriginalLastError);
-}
-
-static bool my_connectIPv4(NetlibConnection *nlc, NETLIBOPENCONNECTION *nloc)
-{
- int rc = 0, retrycnt = 0;
- u_long notblocking = 1;
- DWORD lasterr = 0;
- static const TIMEVAL tv = { 1, 0 };
-
- // if dwTimeout is zero then its an old style connection or new with a 0 timeout, select() will error quicker anyway
- unsigned int dwTimeout = (nloc && (nloc->cbSize == sizeof(NETLIBOPENCONNECTION)) && (nloc->flags & NLOCF_V2) && (nloc->timeout>0)) ? nloc->timeout : 30;
-
- // this is for XP SP2 where there is a default connection attempt limit of 10/second
- if (connectionTimeout) {
- WaitForSingleObject(hConnectionOpenMutex, 10000);
- int waitdiff = GetTickCount() - g_LastConnectionTick;
- if (waitdiff < connectionTimeout) SleepEx(connectionTimeout, TRUE);
- g_LastConnectionTick = GetTickCount();
- ReleaseMutex(hConnectionOpenMutex);
-
- // might of died in between the wait
- if (Miranda_Terminated()) return false;
- }
-
- PHOSTENT he;
- SOCKADDR_IN sin = { 0 };
- sin.sin_family = AF_INET;
-
- if (nlc->proxyType) {
- if (!nlc->szProxyServer) return false;
-
- if (nloc)
- NetlibLogf(nlc->nlu, "(%p) Connecting to proxy %s:%d for %s:%d ....", nlc, nlc->szProxyServer, nlc->wProxyPort, nloc->szHost, nloc->wPort);
- else
- NetlibLogf(nlc->nlu, "(%p) Connecting to proxy %s:%d ....", nlc, nlc->szProxyServer, nlc->wProxyPort);
-
- sin.sin_port = htons(nlc->wProxyPort);
- he = gethostbyname(nlc->szProxyServer);
- }
- else {
- if (!nloc || !nloc->szHost || nloc->szHost[0] == '[' || strchr(nloc->szHost, ':')) return false;
- NetlibLogf(nlc->nlu, "(%p) Connecting to server %s:%d....", nlc, nloc->szHost, nloc->wPort);
-
- sin.sin_port = htons(nloc->wPort);
- he = gethostbyname(nloc->szHost);
- }
-
- for (char** har = he->h_addr_list; *har && !Miranda_Terminated(); ++har) {
- sin.sin_addr.s_addr = *(u_long*)*har;
-
- char* szIp = NetlibAddressToString((SOCKADDR_INET_M*)&sin);
- NetlibLogf(nlc->nlu, "(%p) Connecting to ip %s ....", nlc, szIp);
- mir_free(szIp);
-
-retry:
- nlc->s = socket(AF_INET, nloc->flags & NLOCF_UDP ? SOCK_DGRAM : SOCK_STREAM, 0);
- if (nlc->s == INVALID_SOCKET)
- return false;
-
- // return the socket to non blocking
- if (ioctlsocket(nlc->s, FIONBIO, &notblocking) != 0)
- return false;
-
- if (nlc->nlu->settings.specifyOutgoingPorts && nlc->nlu->settings.szOutgoingPorts && nlc->nlu->settings.szOutgoingPorts[0]) {
- if (!BindSocketToPort(nlc->nlu->settings.szOutgoingPorts, nlc->s, INVALID_SOCKET, &nlc->nlu->inportnum))
- NetlibLogf(nlc->nlu, "Netlib connect: Not enough ports for outgoing connections specified");
- }
-
- // try a connect
- if (connect(nlc->s, (LPSOCKADDR)&sin, sizeof(sin)) == 0) {
- rc = 0;
- break;
- }
-
- // didn't work, was it cos of nonblocking?
- if (WSAGetLastError() != WSAEWOULDBLOCK) {
- rc = SOCKET_ERROR;
- closesocket(nlc->s);
- nlc->s = INVALID_SOCKET;
- continue;
- }
-
- while (true) {
- fd_set r, w, e;
- FD_ZERO(&r); FD_ZERO(&w); FD_ZERO(&e);
- FD_SET(nlc->s, &r);
- FD_SET(nlc->s, &w);
- FD_SET(nlc->s, &e);
- if ((rc = select(0, &r, &w, &e, &tv)) == SOCKET_ERROR)
- break;
-
- if (rc > 0) {
- if (FD_ISSET(nlc->s, &w)) {
- // connection was successful
- rc = 0;
- }
- if (FD_ISSET(nlc->s, &r)) {
- // connection was closed
- rc = SOCKET_ERROR;
- lasterr = WSAECONNRESET;
- }
- if (FD_ISSET(nlc->s, &e)) {
- // connection failed.
- int len = sizeof(lasterr);
- rc = SOCKET_ERROR;
- getsockopt(nlc->s, SOL_SOCKET, SO_ERROR, (char*)&lasterr, &len);
- if (lasterr == WSAEADDRINUSE && ++retrycnt <= 2) {
- closesocket(nlc->s);
- goto retry;
- }
- }
- break;
- }
- else if (Miranda_Terminated()) {
- rc = SOCKET_ERROR;
- lasterr = ERROR_TIMEOUT;
- break;
- }
- else if (nloc->cbSize == sizeof(NETLIBOPENCONNECTION) && nloc->flags & NLOCF_V2 && nloc->waitcallback != NULL && nloc->waitcallback(&dwTimeout) == 0) {
- rc = SOCKET_ERROR;
- lasterr = ERROR_TIMEOUT;
- break;
- }
- if (--dwTimeout == 0) {
- rc = SOCKET_ERROR;
- lasterr = ERROR_TIMEOUT;
- break;
- }
- }
-
- if (rc == 0) break;
-
- closesocket(nlc->s);
- nlc->s = INVALID_SOCKET;
- }
-
- notblocking = 0;
- if (nlc->s != INVALID_SOCKET) ioctlsocket(nlc->s, FIONBIO, &notblocking);
- if (rc && lasterr) SetLastError(lasterr);
- return rc == 0;
-}
-
-static bool my_connectIPv6(NetlibConnection *nlc, NETLIBOPENCONNECTION *nloc)
-{
- if (!nloc)
- return false;
-
- int rc = SOCKET_ERROR, retrycnt = 0;
- u_long notblocking = 1;
- DWORD lasterr = 0;
- static const TIMEVAL tv = { 1, 0 };
- unsigned int dwTimeout = (nloc->cbSize == sizeof(NETLIBOPENCONNECTION) && nloc->flags & NLOCF_V2) ? nloc->timeout : 0;
- // if dwTimeout is zero then its an old style connection or new with a 0 timeout, select() will error quicker anyway
- if (dwTimeout == 0) dwTimeout = 30;
-
- // this is for XP SP2 where there is a default connection attempt limit of 10/second
- if (connectionTimeout) {
- WaitForSingleObject(hConnectionOpenMutex, 10000);
- int waitdiff = GetTickCount() - g_LastConnectionTick;
- if (waitdiff < connectionTimeout) SleepEx(connectionTimeout, TRUE);
- g_LastConnectionTick = GetTickCount();
- ReleaseMutex(hConnectionOpenMutex);
-
- // might of died in between the wait
- if (Miranda_Terminated()) return false;
- }
-
- char szPort[6];
- addrinfo *air = NULL, *ai, hints = { 0 };
-
- hints.ai_family = AF_UNSPEC;
-
- if (nloc->flags & NLOCF_UDP) {
- hints.ai_socktype = SOCK_DGRAM;
- hints.ai_protocol = IPPROTO_UDP;
- }
- else {
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
- }
-
- if (nlc->proxyType) {
- if (!nlc->szProxyServer)
- return false;
-
- NetlibLogf(nlc->nlu, "(%p) Connecting to proxy %s:%d for %s:%d ....", nlc, nlc->szProxyServer, nlc->wProxyPort, nloc->szHost, nloc->wPort);
-
- _itoa(nlc->wProxyPort, szPort, 10);
- if (GetAddrInfoA(nlc->szProxyServer, szPort, &hints, &air)) {
- NetlibLogf(nlc->nlu, "%s %d: %s() for host %s failed (%u)", __FILE__, __LINE__, "getaddrinfo", nlc->szProxyServer, WSAGetLastError());
- return false;
- }
- }
- else {
- if (!nloc->szHost)
- return false;
-
- NetlibLogf(nlc->nlu, "(%p) Connecting to server %s:%d....", nlc, nloc->szHost, nloc->wPort);
-
- _itoa(nlc->nloc.wPort, szPort, 10);
-
- if (GetAddrInfoA(nlc->nloc.szHost, szPort, &hints, &air)) {
- NetlibLogf(nlc->nlu, "%s %d: %s() for host %s failed (%u)", __FILE__, __LINE__, "getaddrinfo", nlc->nloc.szHost, WSAGetLastError());
- return false;
- }
- }
-
- for (ai = air; ai && !Miranda_Terminated(); ai = ai->ai_next) {
- NetlibLogf(nlc->nlu, "(%p) Connecting to ip %s ....", nlc, ptrA(NetlibAddressToString((SOCKADDR_INET_M*)ai->ai_addr)));
-retry:
- nlc->s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
- if (nlc->s == INVALID_SOCKET) {
- FreeAddrInfoA(air);
- return false;
- }
-
- // return the socket to non blocking
- if (ioctlsocket(nlc->s, FIONBIO, &notblocking) != 0) {
- FreeAddrInfoA(air);
- return false;
- }
-
- if (nlc->nlu->settings.specifyOutgoingPorts && nlc->nlu->settings.szOutgoingPorts && nlc->nlu->settings.szOutgoingPorts[0]) {
- SOCKET s = ai->ai_family == AF_INET ? nlc->s : INVALID_SOCKET;
- SOCKET s6 = ai->ai_family == AF_INET6 ? nlc->s : INVALID_SOCKET;
- if (!BindSocketToPort(nlc->nlu->settings.szOutgoingPorts, s, s6, &nlc->nlu->inportnum))
- NetlibLogf(nlc->nlu, "Netlib connect: Not enough ports for outgoing connections specified");
- }
-
- // try a connect
- if (connect(nlc->s, ai->ai_addr, (int)ai->ai_addrlen) == 0) {
- rc = 0;
- break;
- }
-
- // didn't work, was it cos of nonblocking?
- if (WSAGetLastError() != WSAEWOULDBLOCK) {
- rc = SOCKET_ERROR;
- closesocket(nlc->s);
- nlc->s = INVALID_SOCKET;
- continue;
- }
-
- while (true) { // timeout loop
- fd_set r, w, e;
- FD_ZERO(&r); FD_ZERO(&w); FD_ZERO(&e);
- FD_SET(nlc->s, &r);
- FD_SET(nlc->s, &w);
- FD_SET(nlc->s, &e);
- if ((rc = select(0, &r, &w, &e, &tv)) == SOCKET_ERROR)
- break;
-
- if (rc > 0) {
- if (FD_ISSET(nlc->s, &w)) {
- // connection was successful
- rc = 0;
- lasterr = 0;
- }
- if (FD_ISSET(nlc->s, &r)) {
- // connection was closed
- rc = SOCKET_ERROR;
- lasterr = WSAECONNRESET;
- }
- if (FD_ISSET(nlc->s, &e)) {
- // connection failed.
- int len = sizeof(lasterr);
- rc = SOCKET_ERROR;
- getsockopt(nlc->s, SOL_SOCKET, SO_ERROR, (char*)&lasterr, &len);
- if (lasterr == WSAEADDRINUSE && ++retrycnt <= 2) {
- closesocket(nlc->s);
- nlc->s = INVALID_SOCKET;
- goto retry;
- }
- }
- break;
- }
- else if (Miranda_Terminated()) {
- rc = SOCKET_ERROR;
- lasterr = ERROR_TIMEOUT;
- break;
- }
- else if (nloc->cbSize == sizeof(NETLIBOPENCONNECTION) && nloc->flags & NLOCF_V2 && nloc->waitcallback != NULL && nloc->waitcallback(&dwTimeout) == 0) {
- rc = SOCKET_ERROR;
- lasterr = ERROR_TIMEOUT;
- break;
- }
- if (--dwTimeout == 0) {
- rc = SOCKET_ERROR;
- lasterr = ERROR_TIMEOUT;
- break;
- }
- }
-
- if (rc == 0) break;
-
- closesocket(nlc->s);
- nlc->s = INVALID_SOCKET;
- }
-
- FreeAddrInfoA(air);
-
- notblocking = 0;
- if (nlc->s != INVALID_SOCKET) ioctlsocket(nlc->s, FIONBIO, &notblocking);
- if (rc && lasterr) SetLastError(lasterr);
- return rc == 0;
-}
-
-static bool my_connect(NetlibConnection *nlc, NETLIBOPENCONNECTION *nloc)
-{
- return my_connectIPv6(nlc, nloc);
-}
-
-static int NetlibHttpFallbackToDirect(NetlibConnection *nlc, NetlibUser *nlu, NETLIBOPENCONNECTION *nloc)
-{
- NetlibDoClose(nlc, true);
-
- NetlibLogf(nlu, "Fallback to direct connection");
-
- nlc->proxyAuthNeeded = false;
- nlc->proxyType = 0;
- mir_free(nlc->szProxyServer); nlc->szProxyServer = NULL;
- if (!my_connect(nlc, nloc)) {
- NetlibLogf(nlu, "%s %d: %s() failed (%u)", __FILE__, __LINE__, "connect", WSAGetLastError());
- return false;
- }
- 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)) {
- // if connection failed, the state of nlc might be unpredictable
- if (GetNetlibHandleType(nlc) == NLH_CONNECTION) {
- // 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;
-}
-
-bool NetlibReconnect(NetlibConnection *nlc)
-{
- // a connection might be freed already
- if (GetNetlibHandleType(nlc) != NLH_CONNECTION)
- return false;
-
- char buf[4];
- bool opened = nlc->s != INVALID_SOCKET;
- if (opened) {
- switch (WaitUntilReadable(nlc->s, 0, true)) {
- case SOCKET_ERROR:
- opened = false;
- break;
-
- case 0:
- opened = true;
- break;
-
- case 1:
- opened = recv(nlc->s, buf, 1, MSG_PEEK) > 0;
- break;
- }
-
- if (!opened)
- NetlibDoClose(nlc, true);
- }
-
- if (!opened) {
- if (Miranda_Terminated())
- return false;
-
- if (nlc->usingHttpGateway) {
- nlc->proxyAuthNeeded = true;
- return my_connect(nlc, &nlc->nloc);
- }
- return NetlibDoConnect(nlc);
- }
- return true;
-}
-
-INT_PTR NetlibOpenConnection(WPARAM wParam, LPARAM lParam)
-{
- NETLIBOPENCONNECTION *nloc = (NETLIBOPENCONNECTION*)lParam;
- if (nloc == NULL || nloc->cbSize != sizeof(NETLIBOPENCONNECTION) || nloc->szHost == NULL || nloc->wPort == 0) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- NetlibUser *nlu = (NetlibUser*)wParam;
- if (GetNetlibHandleType(nlu) != NLH_USER || !(nlu->user.flags & NUF_OUTGOING))
- return 0;
-
- NetlibLogf(nlu, "Connection request to %s:%d (Flags %x)....", nloc->szHost, nloc->wPort, nloc->flags);
-
- NetlibConnection *nlc = (NetlibConnection*)mir_calloc(sizeof(struct NetlibConnection));
- nlc->handleType = NLH_CONNECTION;
- nlc->nlu = nlu;
- nlc->nloc = *nloc;
- nlc->nloc.szHost = mir_strdup(nloc->szHost);
- nlc->s = INVALID_SOCKET;
- nlc->s2 = INVALID_SOCKET;
- nlc->dnsThroughProxy = nlu->settings.dnsThroughProxy != 0;
-
- InitializeCriticalSection(&nlc->csHttpSequenceNums);
- nlc->hOkToCloseEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
- nlc->dontCloseNow = 0;
- NetlibInitializeNestedCS(&nlc->ncsSend);
- NetlibInitializeNestedCS(&nlc->ncsRecv);
-
- if (!NetlibDoConnect(nlc)) {
- FreePartiallyInitedConnection(nlc);
- return 0;
- }
-
- if (iUPnPCleanup == 0) {
- mir_cslock lck(csNetlibUser);
- if (iUPnPCleanup == 0) {
- iUPnPCleanup = 1;
- forkthread(NetlibUPnPCleanup, 0, NULL);
- }
- }
-
- return (INT_PTR)nlc;
-}
-
-INT_PTR NetlibStartSsl(WPARAM wParam, LPARAM lParam)
-{
- NetlibConnection *nlc = (NetlibConnection*)wParam;
- if (nlc == NULL)
- return 0;
-
- NETLIBSSL *sp = (NETLIBSSL*)lParam;
- const char *szHost = sp ? sp->host : nlc->nloc.szHost;
-
- NetlibLogf(nlc->nlu, "(%d %s) Starting SSL negotiation", nlc->s, szHost);
- nlc->hSsl = si.connect(nlc->s, szHost, nlc->nlu->settings.validateSSL);
-
- if (nlc->hSsl == NULL)
- NetlibLogf(nlc->nlu, "(%d %s) Failure to negotiate SSL connection", nlc->s, szHost);
- else
- NetlibLogf(nlc->nlu, "(%d %s) SSL negotiation successful", nlc->s, szHost);
-
- return nlc->hSsl != NULL;
-}
diff --git a/src/modules/netlib/netlibopts.cpp b/src/modules/netlib/netlibopts.cpp
deleted file mode 100644
index fff81944d3..0000000000
--- a/src/modules/netlib/netlibopts.cpp
+++ /dev/null
@@ -1,530 +0,0 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (ñ) 2012-15 Miranda NG project (http://miranda-ng.org),
-Copyright (c) 2000-12 Miranda IM project,
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "..\..\core\commonheaders.h"
-#include "netlib.h"
-
-struct NetlibTempSettings
-{
- DWORD flags;
- char *szSettingsModule;
- NETLIBUSERSETTINGS settings;
-};
-
-static LIST <NetlibTempSettings> tempSettings(5);
-
-static const UINT outgoingConnectionsControls[] =
-{
- IDC_STATIC12,
- IDC_USEPROXY,
- IDC_STATIC21, IDC_PROXYTYPE,
- IDC_STATIC22, IDC_PROXYHOST, IDC_STATIC23, IDC_PROXYPORT, IDC_STOFTENPORT,
- IDC_PROXYAUTH,
- IDC_STATIC31, IDC_PROXYUSER, IDC_STATIC32, IDC_PROXYPASS,
- IDC_PROXYDNS,
- IDC_SPECIFYPORTSO,
- IDC_PORTSRANGEO,
- IDC_STATIC54,
- IDC_VALIDATESSL};
-static const UINT useProxyControls[] = {
- IDC_STATIC21, IDC_PROXYTYPE,
- IDC_STATIC22, IDC_PROXYHOST, IDC_STATIC23, IDC_PROXYPORT, IDC_STOFTENPORT,
- IDC_PROXYAUTH,
- IDC_STATIC31, IDC_PROXYUSER, IDC_STATIC32, IDC_PROXYPASS,
- IDC_PROXYDNS};
-static const UINT specifyOPortsControls[] = {
- IDC_PORTSRANGEO,
- IDC_STATIC54
-};
-static const UINT incomingConnectionsControls[] = {
- IDC_STATIC43,
- IDC_SPECIFYPORTS,
- IDC_PORTSRANGE,
- IDC_STATIC52,
- IDC_ENABLEUPNP};
-static const UINT specifyPortsControls[] = {
- IDC_PORTSRANGE,
- IDC_STATIC52};
-
-static const TCHAR* szProxyTypes[] = {LPGENT("<mixed>"), _T("SOCKS4"), _T("SOCKS5"), _T("HTTP"), _T("HTTPS"), _T("Internet Explorer")};
-static const WORD oftenProxyPorts[] = {1080, 1080, 1080, 8080, 8080, 8080};
-
-#define M_REFRESHALL (WM_USER+100)
-#define M_REFRESHENABLING (WM_USER+101)
-
-static void ShowMultipleControls(HWND hwndDlg, const UINT *controls, int cControls, int state)
-{
- for (int i = 0; i < cControls; i++)
- ShowWindow(GetDlgItem(hwndDlg, controls[i]), state);
-}
-
-static void EnableMultipleControls(HWND hwndDlg, const UINT *controls, int cControls, int state)
-{
- for (int i = 0; i < cControls; i++)
- EnableWindow(GetDlgItem(hwndDlg, controls[i]), state);
-}
-
-static void AddProxyTypeItem(HWND hwndDlg, int type, int selectType)
-{
- int i = SendDlgItemMessage(hwndDlg, IDC_PROXYTYPE, CB_ADDSTRING, 0, (LPARAM)(type == 0 ? TranslateTS(szProxyTypes[type]) : szProxyTypes[type]));
- SendDlgItemMessage(hwndDlg, IDC_PROXYTYPE, CB_SETITEMDATA, i, type);
- if (type == selectType)
- SendDlgItemMessage(hwndDlg, IDC_PROXYTYPE, CB_SETCURSEL, i, 0);
-}
-
-static void CopySettingsStruct(NETLIBUSERSETTINGS *dest, NETLIBUSERSETTINGS *source)
-{
- *dest = *source;
- if (dest->szIncomingPorts) dest->szIncomingPorts = mir_strdup(dest->szIncomingPorts);
- if (dest->szOutgoingPorts) dest->szOutgoingPorts = mir_strdup(dest->szOutgoingPorts);
- if (dest->szProxyAuthPassword) dest->szProxyAuthPassword = mir_strdup(dest->szProxyAuthPassword);
- if (dest->szProxyAuthUser) dest->szProxyAuthUser = mir_strdup(dest->szProxyAuthUser);
- if (dest->szProxyServer) dest->szProxyServer = mir_strdup(dest->szProxyServer);
-}
-
-static void CombineSettingsStrings(char **dest, char **source)
-{
- if (*dest != NULL && (*source == NULL || mir_strcmpi(*dest, *source))) { mir_free(*dest); *dest = NULL; }
-}
-
-static void CombineSettingsStructs(NETLIBUSERSETTINGS *dest, DWORD *destFlags, NETLIBUSERSETTINGS *source, DWORD sourceFlags)
-{
- if (sourceFlags&NUF_OUTGOING) {
- if (*destFlags&NUF_OUTGOING) {
- if (dest->validateSSL != source->validateSSL) dest->validateSSL = 2;
- if (dest->useProxy != source->useProxy) dest->useProxy = 2;
- if (dest->proxyType != source->proxyType) dest->proxyType = 0;
- CombineSettingsStrings(&dest->szProxyServer, &source->szProxyServer);
- if (dest->wProxyPort != source->wProxyPort) dest->wProxyPort = 0;
- if (dest->useProxyAuth != source->useProxyAuth) dest->useProxyAuth = 2;
- CombineSettingsStrings(&dest->szProxyAuthUser, &source->szProxyAuthUser);
- CombineSettingsStrings(&dest->szProxyAuthPassword, &source->szProxyAuthPassword);
- if (dest->dnsThroughProxy != source->dnsThroughProxy) dest->dnsThroughProxy = 2;
- if (dest->specifyOutgoingPorts != source->specifyOutgoingPorts) dest->specifyOutgoingPorts = 2;
- CombineSettingsStrings(&dest->szOutgoingPorts, &source->szOutgoingPorts);
- }
- else {
- dest->validateSSL = source->validateSSL;
- dest->useProxy = source->useProxy;
- dest->proxyType = source->proxyType;
- dest->szProxyServer = source->szProxyServer;
- if (dest->szProxyServer) dest->szProxyServer = mir_strdup(dest->szProxyServer);
- dest->wProxyPort = source->wProxyPort;
- dest->useProxyAuth = source->useProxyAuth;
- dest->szProxyAuthUser = source->szProxyAuthUser;
- if (dest->szProxyAuthUser) dest->szProxyAuthUser = mir_strdup(dest->szProxyAuthUser);
- dest->szProxyAuthPassword = source->szProxyAuthPassword;
- if (dest->szProxyAuthPassword) dest->szProxyAuthPassword = mir_strdup(dest->szProxyAuthPassword);
- dest->dnsThroughProxy = source->dnsThroughProxy;
- dest->specifyOutgoingPorts = source->specifyOutgoingPorts;
- dest->szOutgoingPorts = source->szOutgoingPorts;
- if (dest->szOutgoingPorts) dest->szOutgoingPorts = mir_strdup(dest->szOutgoingPorts);
- }
- }
- if (sourceFlags&NUF_INCOMING) {
- if (*destFlags&NUF_INCOMING) {
- if (dest->enableUPnP != source->enableUPnP) dest->enableUPnP = 2;
- if (dest->specifyIncomingPorts != source->specifyIncomingPorts) dest->specifyIncomingPorts = 2;
- CombineSettingsStrings(&dest->szIncomingPorts, &source->szIncomingPorts);
- }
- else {
- dest->enableUPnP = source->enableUPnP;
- dest->specifyIncomingPorts = source->specifyIncomingPorts;
- dest->szIncomingPorts = source->szIncomingPorts;
- if (dest->szIncomingPorts) dest->szIncomingPorts = mir_strdup(dest->szIncomingPorts);
- }
- }
- if ((*destFlags&NUF_NOHTTPSOPTION) != (sourceFlags&NUF_NOHTTPSOPTION))
- *destFlags = (*destFlags | sourceFlags)&~NUF_NOHTTPSOPTION;
- else *destFlags |= sourceFlags;
-}
-
-static void ChangeSettingIntByCheckbox(HWND hwndDlg, UINT ctrlId, int iUser, int memberOffset)
-{
- int newValue = IsDlgButtonChecked(hwndDlg, ctrlId) != BST_CHECKED;
- CheckDlgButton(hwndDlg, ctrlId, newValue ? BST_CHECKED : BST_UNCHECKED);
- if (iUser == -1) {
- for (int i = 0; i < tempSettings.getCount(); i++) {
- NetlibTempSettings *p = tempSettings[i];
- if (!(p->flags & NUF_NOOPTIONS))
- *(int*)(((PBYTE)&p->settings) + memberOffset) = newValue;
- }
- }
- else *(int*)(((PBYTE)&tempSettings[iUser]->settings) + memberOffset) = newValue;
- SendMessage(hwndDlg, M_REFRESHENABLING, 0, 0);
-}
-
-static void ChangeSettingStringByEdit(HWND hwndDlg, UINT ctrlId, int iUser, int memberOffset)
-{
- int newValueLen = GetWindowTextLength(GetDlgItem(hwndDlg, ctrlId));
- char *szNewValue = (char*)mir_alloc(newValueLen+1);
- GetDlgItemTextA(hwndDlg, ctrlId, szNewValue, newValueLen+1);
- if (iUser == -1) {
- for (int i = 0; i < tempSettings.getCount(); i++) {
- NetlibTempSettings *p = tempSettings[i];
- if (!(p->flags & NUF_NOOPTIONS)) {
- char **ppszNew = (char**)(((PBYTE)&p->settings) + memberOffset);
- mir_free(*ppszNew);
- *ppszNew = mir_strdup(szNewValue);
- }
- }
- mir_free(szNewValue);
- }
- else {
- char **ppszNew = (char**)(((PBYTE)&tempSettings[iUser]->settings) + memberOffset);
- mir_free(*ppszNew);
- *ppszNew = szNewValue;
- }
-}
-
-static void WriteSettingsStructToDb(const char *szSettingsModule, NETLIBUSERSETTINGS *settings, DWORD flags)
-{
- if (flags & NUF_OUTGOING) {
- db_set_b(NULL, szSettingsModule, "NLValidateSSL", (BYTE)settings->validateSSL);
- db_set_b(NULL, szSettingsModule, "NLUseProxy", (BYTE)settings->useProxy);
- db_set_b(NULL, szSettingsModule, "NLProxyType", (BYTE)settings->proxyType);
- db_set_s(NULL, szSettingsModule, "NLProxyServer", settings->szProxyServer ? settings->szProxyServer : "");
- db_set_w(NULL, szSettingsModule, "NLProxyPort", (WORD)settings->wProxyPort);
- db_set_b(NULL, szSettingsModule, "NLUseProxyAuth", (BYTE)settings->useProxyAuth);
- db_set_s(NULL, szSettingsModule, "NLProxyAuthUser", settings->szProxyAuthUser ? settings->szProxyAuthUser : "");
- db_set_s(NULL, szSettingsModule, "NLProxyAuthPassword", settings->szProxyAuthPassword ? settings->szProxyAuthPassword : "");
- db_set_b(NULL, szSettingsModule, "NLDnsThroughProxy", (BYTE)settings->dnsThroughProxy);
- db_set_b(NULL, szSettingsModule, "NLSpecifyOutgoingPorts", (BYTE)settings->specifyOutgoingPorts);
- db_set_s(NULL, szSettingsModule, "NLOutgoingPorts", settings->szOutgoingPorts ? settings->szOutgoingPorts : "");
- }
- if (flags & NUF_INCOMING) {
- db_set_b(NULL, szSettingsModule, "NLEnableUPnP", (BYTE)settings->enableUPnP);
- db_set_b(NULL, szSettingsModule, "NLSpecifyIncomingPorts", (BYTE)settings->specifyIncomingPorts);
- db_set_s(NULL, szSettingsModule, "NLIncomingPorts", settings->szIncomingPorts ? settings->szIncomingPorts : "");
- }
-}
-
-void NetlibSaveUserSettingsStruct(const char *szSettingsModule, NETLIBUSERSETTINGS *settings)
-{
- mir_cslock lck(csNetlibUser);
-
- NetlibUser tUser;
- tUser.user.szSettingsModule = (char*)szSettingsModule;
- NetlibUser *thisUser = netlibUser.find(&tUser);
- if (thisUser == NULL)
- return;
-
- NetlibFreeUserSettingsStruct(&thisUser->settings);
- CopySettingsStruct(&thisUser->settings, settings);
- WriteSettingsStructToDb(thisUser->user.szSettingsModule, &thisUser->settings, thisUser->user.flags);
-
- NETLIBUSERSETTINGS combinedSettings = { 0 };
- combinedSettings.cbSize = sizeof(combinedSettings);
-
- DWORD flags = 0;
- for (int i = 0; i < netlibUser.getCount(); i++) {
- if (thisUser->user.flags & NUF_NOOPTIONS)
- continue;
- CombineSettingsStructs(&combinedSettings, &flags, &thisUser->settings, thisUser->user.flags);
- }
- if (combinedSettings.validateSSL == 2) combinedSettings.validateSSL = 0;
- if (combinedSettings.useProxy == 2) combinedSettings.useProxy = 0;
- if (combinedSettings.proxyType == 0) combinedSettings.proxyType = PROXYTYPE_SOCKS5;
- if (combinedSettings.useProxyAuth == 2) combinedSettings.useProxyAuth = 0;
- if (combinedSettings.dnsThroughProxy == 2) combinedSettings.dnsThroughProxy = 1;
- if (combinedSettings.enableUPnP == 2) combinedSettings.enableUPnP = 1;
- if (combinedSettings.specifyIncomingPorts == 2) combinedSettings.specifyIncomingPorts = 0;
- WriteSettingsStructToDb("Netlib", &combinedSettings, flags);
- NetlibFreeUserSettingsStruct(&combinedSettings);
-}
-
-static INT_PTR CALLBACK DlgProcNetlibOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- int iUser;
-
- switch (msg) {
- case WM_INITDIALOG:
- TranslateDialogDefault(hwndDlg);
- {
- int iItem = SendDlgItemMessage(hwndDlg, IDC_NETLIBUSERS, CB_ADDSTRING, 0, (LPARAM)TranslateT("<All connections>"));
- SendDlgItemMessage(hwndDlg, IDC_NETLIBUSERS, CB_SETITEMDATA, iItem, (LPARAM)-1);
- SendDlgItemMessage(hwndDlg, IDC_NETLIBUSERS, CB_SETCURSEL, iItem, 0);
- {
- mir_cslock lck(csNetlibUser);
- for (int i = 0; i < netlibUser.getCount(); ++i) {
- NetlibTempSettings *thisSettings = (NetlibTempSettings*)mir_calloc(sizeof(NetlibTempSettings));
- thisSettings->flags = netlibUser[i]->user.flags;
- thisSettings->szSettingsModule = mir_strdup(netlibUser[i]->user.szSettingsModule);
- CopySettingsStruct(&thisSettings->settings, &netlibUser[i]->settings);
- tempSettings.insert(thisSettings);
-
- if (netlibUser[i]->user.flags & NUF_NOOPTIONS)
- continue;
- iItem = SendDlgItemMessage(hwndDlg, IDC_NETLIBUSERS, CB_ADDSTRING, 0, (LPARAM)netlibUser[i]->user.ptszDescriptiveName);
- SendDlgItemMessage(hwndDlg, IDC_NETLIBUSERS, CB_SETITEMDATA, iItem, i);
- }
- }
- }
-
- SendMessage(hwndDlg, M_REFRESHALL, 0, 0);
- return TRUE;
-
- case M_REFRESHALL:
- iUser = SendDlgItemMessage(hwndDlg, IDC_NETLIBUSERS, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_NETLIBUSERS, CB_GETCURSEL, 0, 0), 0);
- {
- NETLIBUSERSETTINGS settings = { 0 };
- DWORD flags = 0;
-
- if (iUser == -1) {
- settings.cbSize = sizeof(settings);
- for (int i = 0; i < tempSettings.getCount(); i++) {
- NetlibTempSettings *p = tempSettings[i];
- if (!(p->flags & NUF_NOOPTIONS))
- CombineSettingsStructs(&settings, &flags, &p->settings, p->flags);
- }
- }
- else {
- NetlibFreeUserSettingsStruct(&settings);
- CopySettingsStruct(&settings, &tempSettings[iUser]->settings);
- flags = tempSettings[iUser]->flags;
- }
- ShowMultipleControls(hwndDlg, outgoingConnectionsControls, SIZEOF(outgoingConnectionsControls), flags&NUF_OUTGOING ? SW_SHOW : SW_HIDE);
- CheckDlgButton(hwndDlg, IDC_USEPROXY, settings.useProxy ? BST_CHECKED : BST_UNCHECKED);
- SendDlgItemMessage(hwndDlg, IDC_PROXYTYPE, CB_RESETCONTENT, 0, 0);
- if (settings.proxyType == 0) AddProxyTypeItem(hwndDlg, 0, settings.proxyType);
- AddProxyTypeItem(hwndDlg, PROXYTYPE_SOCKS4, settings.proxyType);
- AddProxyTypeItem(hwndDlg, PROXYTYPE_SOCKS5, settings.proxyType);
- if (flags & (NUF_HTTPCONNS | NUF_HTTPGATEWAY)) AddProxyTypeItem(hwndDlg, PROXYTYPE_HTTP, settings.proxyType);
- if (!(flags & NUF_NOHTTPSOPTION)) AddProxyTypeItem(hwndDlg, PROXYTYPE_HTTPS, settings.proxyType);
- if (flags & (NUF_HTTPCONNS | NUF_HTTPGATEWAY) || !(flags & NUF_NOHTTPSOPTION))
- AddProxyTypeItem(hwndDlg, PROXYTYPE_IE, settings.proxyType);
- SetDlgItemTextA(hwndDlg, IDC_PROXYHOST, settings.szProxyServer ? settings.szProxyServer : "");
- if (settings.wProxyPort) SetDlgItemInt(hwndDlg, IDC_PROXYPORT, settings.wProxyPort, FALSE);
- else SetDlgItemTextA(hwndDlg, IDC_PROXYPORT, "");
- CheckDlgButton(hwndDlg, IDC_PROXYAUTH, settings.useProxyAuth ? BST_CHECKED : BST_UNCHECKED);
- SetDlgItemTextA(hwndDlg, IDC_PROXYUSER, settings.szProxyAuthUser ? settings.szProxyAuthUser : "");
- SetDlgItemTextA(hwndDlg, IDC_PROXYPASS, settings.szProxyAuthPassword ? settings.szProxyAuthPassword : "");
- CheckDlgButton(hwndDlg, IDC_PROXYDNS, settings.dnsThroughProxy ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(hwndDlg, IDC_VALIDATESSL, settings.validateSSL ? BST_CHECKED : BST_UNCHECKED);
-
- ShowMultipleControls(hwndDlg, incomingConnectionsControls, SIZEOF(incomingConnectionsControls), flags&NUF_INCOMING ? SW_SHOW : SW_HIDE);
- CheckDlgButton(hwndDlg, IDC_SPECIFYPORTS, settings.specifyIncomingPorts ? BST_CHECKED : BST_UNCHECKED);
- SetDlgItemTextA(hwndDlg, IDC_PORTSRANGE, settings.szIncomingPorts ? settings.szIncomingPorts : "");
-
- CheckDlgButton(hwndDlg, IDC_SPECIFYPORTSO, settings.specifyOutgoingPorts ? BST_CHECKED : BST_UNCHECKED);
- SetDlgItemTextA(hwndDlg, IDC_PORTSRANGEO, settings.szOutgoingPorts ? settings.szOutgoingPorts : "");
-
- CheckDlgButton(hwndDlg, IDC_ENABLEUPNP, settings.enableUPnP ? BST_CHECKED : BST_UNCHECKED);
-
- NetlibFreeUserSettingsStruct(&settings);
- SendMessage(hwndDlg, M_REFRESHENABLING, 0, 0);
- }
- break;
-
- case M_REFRESHENABLING:
- TCHAR str[80];
- {
- int selectedProxyType = SendDlgItemMessage(hwndDlg, IDC_PROXYTYPE, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_PROXYTYPE, CB_GETCURSEL, 0, 0), 0);
- mir_sntprintf(str, SIZEOF(str), TranslateT("(often %d)"), oftenProxyPorts[selectedProxyType]);
- SetDlgItemText(hwndDlg, IDC_STOFTENPORT, str);
- if (IsDlgButtonChecked(hwndDlg, IDC_USEPROXY) != BST_UNCHECKED) {
- int enableAuth = 0, enableUser = 0, enablePass = 0, enableServer = 1;
- EnableMultipleControls(hwndDlg, useProxyControls, SIZEOF(useProxyControls), TRUE);
- if (selectedProxyType == 0) {
- for (int i = 0; i < tempSettings.getCount(); i++) {
- NetlibTempSettings *p = tempSettings[i];
- if (!p->settings.useProxy ||
- p->flags & NUF_NOOPTIONS || !(p->flags & NUF_OUTGOING))
- continue;
-
- if (p->settings.proxyType == PROXYTYPE_SOCKS4) enableUser = 1;
- else {
- enableAuth = 1;
- if (p->settings.useProxyAuth)
- enableUser = enablePass = 1;
- }
- }
- }
- else {
- if (selectedProxyType == PROXYTYPE_SOCKS4) enableUser = 1;
- else {
- if (selectedProxyType == PROXYTYPE_IE) enableServer = 0;
- enableAuth = 1;
- if (IsDlgButtonChecked(hwndDlg, IDC_PROXYAUTH) != BST_UNCHECKED)
- enableUser = enablePass = 1;
- }
- }
- EnableWindow(GetDlgItem(hwndDlg, IDC_PROXYAUTH), enableAuth);
- EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC31), enableUser);
- EnableWindow(GetDlgItem(hwndDlg, IDC_PROXYUSER), enableUser);
- EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC32), enablePass);
- EnableWindow(GetDlgItem(hwndDlg, IDC_PROXYPASS), enablePass);
- EnableWindow(GetDlgItem(hwndDlg, IDC_PROXYHOST), enableServer);
- EnableWindow(GetDlgItem(hwndDlg, IDC_PROXYPORT), enableServer);
- }
- else EnableMultipleControls(hwndDlg, useProxyControls, SIZEOF(useProxyControls), FALSE);
- EnableMultipleControls(hwndDlg, specifyPortsControls, SIZEOF(specifyPortsControls), IsDlgButtonChecked(hwndDlg, IDC_SPECIFYPORTS) != BST_UNCHECKED);
- EnableMultipleControls(hwndDlg, specifyOPortsControls, SIZEOF(specifyOPortsControls), IsDlgButtonChecked(hwndDlg, IDC_SPECIFYPORTSO) != BST_UNCHECKED);
- }
- break;
-
- case WM_COMMAND:
- iUser = SendDlgItemMessage(hwndDlg, IDC_NETLIBUSERS, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_NETLIBUSERS, CB_GETCURSEL, 0, 0), 0);
- switch (LOWORD(wParam)) {
- case IDC_NETLIBUSERS:
- if (HIWORD(wParam) == CBN_SELCHANGE) SendMessage(hwndDlg, M_REFRESHALL, 0, 0);
- return 0;
-
- case IDC_LOGOPTIONS:
- NetlibLogShowOptions();
- return 0;
-
- case IDC_PROXYTYPE:
- if (HIWORD(wParam) != CBN_SELCHANGE) return 0;
- {
- int newValue = SendDlgItemMessage(hwndDlg, IDC_PROXYTYPE, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_PROXYTYPE, CB_GETCURSEL, 0, 0), 0);
- if (iUser == -1) {
- if (newValue == 0) return 0;
- for (int i=0; i < tempSettings.getCount(); i++) {
- NetlibTempSettings *p = tempSettings[i];
- if (p->flags & NUF_NOOPTIONS) continue;
- if (newValue == PROXYTYPE_HTTP && !(p->flags & (NUF_HTTPCONNS | NUF_HTTPGATEWAY)))
- p->settings.proxyType = PROXYTYPE_HTTPS;
- else if (newValue == PROXYTYPE_HTTPS && p->flags & NUF_NOHTTPSOPTION)
- p->settings.proxyType = PROXYTYPE_HTTP;
- else p->settings.proxyType = newValue;
- }
- SendMessage(hwndDlg, M_REFRESHALL, 0, 0);
- }
- else {
- tempSettings[iUser]->settings.proxyType = newValue;
- SendMessage(hwndDlg, M_REFRESHENABLING, 0, 0);
- }
- }
- break;
- case IDC_USEPROXY:
- ChangeSettingIntByCheckbox(hwndDlg, LOWORD(wParam), iUser, offsetof(NETLIBUSERSETTINGS, useProxy));
- break;
- case IDC_PROXYAUTH:
- ChangeSettingIntByCheckbox(hwndDlg, LOWORD(wParam), iUser, offsetof(NETLIBUSERSETTINGS, useProxyAuth));
- break;
- case IDC_PROXYDNS:
- ChangeSettingIntByCheckbox(hwndDlg, LOWORD(wParam), iUser, offsetof(NETLIBUSERSETTINGS, dnsThroughProxy));
- break;
- case IDC_SPECIFYPORTS:
- ChangeSettingIntByCheckbox(hwndDlg, LOWORD(wParam), iUser, offsetof(NETLIBUSERSETTINGS, specifyIncomingPorts));
- break;
- case IDC_SPECIFYPORTSO:
- ChangeSettingIntByCheckbox(hwndDlg, LOWORD(wParam), iUser, offsetof(NETLIBUSERSETTINGS, specifyOutgoingPorts));
- break;
- case IDC_ENABLEUPNP:
- ChangeSettingIntByCheckbox(hwndDlg, LOWORD(wParam), iUser, offsetof(NETLIBUSERSETTINGS, enableUPnP));
- break;
- case IDC_VALIDATESSL:
- ChangeSettingIntByCheckbox(hwndDlg, LOWORD(wParam), iUser, offsetof(NETLIBUSERSETTINGS, validateSSL));
- break;
- case IDC_PROXYHOST:
- if (HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus()) return 0;
- ChangeSettingStringByEdit(hwndDlg, LOWORD(wParam), iUser, offsetof(NETLIBUSERSETTINGS, szProxyServer));
- break;
- case IDC_PROXYPORT:
- if (HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus()) return 0;
- {
- int newValue = GetDlgItemInt(hwndDlg, LOWORD(wParam), NULL, FALSE);
- if (iUser == -1) {
- for (int i = 0; i < tempSettings.getCount(); i++) {
- NetlibTempSettings *p = tempSettings[i];
- if (!(p->flags & NUF_NOOPTIONS))
- p->settings.wProxyPort = newValue;
- }
- }
- else tempSettings[iUser]->settings.wProxyPort = newValue;
- }
- break;
- case IDC_PROXYUSER:
- if (HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus()) return 0;
- ChangeSettingStringByEdit(hwndDlg, LOWORD(wParam), iUser, offsetof(NETLIBUSERSETTINGS, szProxyAuthUser));
- break;
- case IDC_PROXYPASS:
- if (HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus()) return 0;
- ChangeSettingStringByEdit(hwndDlg, LOWORD(wParam), iUser, offsetof(NETLIBUSERSETTINGS, szProxyAuthPassword));
- break;
- case IDC_PORTSRANGE:
- if (HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus()) return 0;
- ChangeSettingStringByEdit(hwndDlg, LOWORD(wParam), iUser, offsetof(NETLIBUSERSETTINGS, szIncomingPorts));
- break;
- case IDC_PORTSRANGEO:
- if (HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus()) return 0;
- ChangeSettingStringByEdit(hwndDlg, LOWORD(wParam), iUser, offsetof(NETLIBUSERSETTINGS, szOutgoingPorts));
- break;
- }
- ShowWindow(GetDlgItem(hwndDlg, IDC_RECONNECTREQD), SW_SHOW);
- SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
- break;
-
- case WM_NOTIFY:
- switch (((LPNMHDR)lParam)->idFrom) {
- case 0:
- switch (((LPNMHDR)lParam)->code) {
- case PSN_APPLY:
- for (iUser = 0; iUser < tempSettings.getCount(); iUser++)
- NetlibSaveUserSettingsStruct(tempSettings[iUser]->szSettingsModule,
- &tempSettings[iUser]->settings);
- return TRUE;
- }
- break;
- }
- break;
-
- case WM_DESTROY:
- for (int i = 0; i < tempSettings.getCount(); ++i) {
- NetlibTempSettings *p = tempSettings[i];
- mir_free(p->szSettingsModule);
- NetlibFreeUserSettingsStruct(&p->settings);
- mir_free(tempSettings[i]);
- }
- tempSettings.destroy();
- break;
- }
- return FALSE;
-}
-
-int NetlibOptInitialise(WPARAM wParam, LPARAM)
-{
- int optionsCount = 0;
- {
- mir_cslock lck(csNetlibUser);
- for (int i=0; i < netlibUser.getCount(); i++)
- if (!(netlibUser[i]->user.flags & NUF_NOOPTIONS))
- ++optionsCount;
- }
-
- if (optionsCount == 0)
- return 0;
-
- OPTIONSDIALOGPAGE odp = { 0 };
- odp.position = 900000000;
- odp.hInstance = hInst;
- odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_NETLIB);
- odp.pszTitle = LPGEN("Network");
- odp.pfnDlgProc = DlgProcNetlibOpts;
- odp.flags = ODPF_BOLDGROUPS;
- Options_AddPage(wParam, &odp);
- return 0;
-}
diff --git a/src/modules/netlib/netlibpktrecver.cpp b/src/modules/netlib/netlibpktrecver.cpp
deleted file mode 100644
index 5783cda6b3..0000000000
--- a/src/modules/netlib/netlibpktrecver.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (ñ) 2012-15 Miranda NG project (http://miranda-ng.org),
-Copyright (c) 2000-12 Miranda IM project,
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "..\..\core\commonheaders.h"
-#include "netlib.h"
-
-INT_PTR NetlibPacketRecverCreate(WPARAM wParam, LPARAM lParam)
-{
- NetlibConnection *nlc = (struct NetlibConnection*)wParam;
- struct NetlibPacketRecver *nlpr;
-
- if (GetNetlibHandleType(nlc) != NLH_CONNECTION || lParam == 0) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return (INT_PTR)(struct NetlibPacketRecver*)NULL;
- }
- nlpr = (struct NetlibPacketRecver*)mir_calloc(sizeof(struct NetlibPacketRecver));
- if (nlpr == NULL) {
- SetLastError(ERROR_OUTOFMEMORY);
- return (INT_PTR)(struct NetlibPacketRecver*)NULL;
- }
- nlpr->handleType = NLH_PACKETRECVER;
- nlpr->nlc = nlc;
- nlpr->packetRecver.cbSize = sizeof(nlpr->packetRecver);
- nlpr->packetRecver.bufferSize = lParam;
- nlpr->packetRecver.buffer = (PBYTE)mir_alloc(nlpr->packetRecver.bufferSize);
- nlpr->packetRecver.bytesUsed = 0;
- nlpr->packetRecver.bytesAvailable = 0;
- return (INT_PTR)nlpr;
-}
-
-INT_PTR NetlibPacketRecverGetMore(WPARAM wParam, LPARAM lParam)
-{
- struct NetlibPacketRecver *nlpr = (struct NetlibPacketRecver*)wParam;
- NETLIBPACKETRECVER *nlprParam = (NETLIBPACKETRECVER*)lParam;
-
- if (GetNetlibHandleType(nlpr) != NLH_PACKETRECVER || nlprParam == NULL || nlprParam->cbSize != sizeof(NETLIBPACKETRECVER) || nlprParam->bytesUsed > nlpr->packetRecver.bytesAvailable) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return SOCKET_ERROR;
- }
- if (Miranda_Terminated()) { /* HACK: Lame, break while loops of protocols that can't kill their while loops, (cough, ICQ, cough) */
- SetLastError(ERROR_TIMEOUT);
- return SOCKET_ERROR;
- }
- nlpr->packetRecver.dwTimeout = nlprParam->dwTimeout;
- if (nlprParam->bytesUsed == 0) {
- if (nlpr->packetRecver.bytesAvailable == nlpr->packetRecver.bufferSize) {
- nlpr->packetRecver.bytesAvailable = 0;
- NetlibLogf(nlpr->nlc->nlu, "Packet recver: packet overflowed buffer, ditching");
- }
- }
- else {
- memmove(nlpr->packetRecver.buffer, nlpr->packetRecver.buffer + nlprParam->bytesUsed, nlpr->packetRecver.bytesAvailable - nlprParam->bytesUsed);
- nlpr->packetRecver.bytesAvailable -= nlprParam->bytesUsed;
- }
-
- if (nlprParam->dwTimeout != INFINITE) {
- if (!si.pending(nlpr->nlc->hSsl) && WaitUntilReadable(nlpr->nlc->s, nlprParam->dwTimeout) <= 0) {
- *nlprParam = nlpr->packetRecver;
- return SOCKET_ERROR;
- }
- }
-
- INT_PTR recvResult = NLRecv(nlpr->nlc, (char*)nlpr->packetRecver.buffer + nlpr->packetRecver.bytesAvailable, nlpr->packetRecver.bufferSize - nlpr->packetRecver.bytesAvailable, 0);
- if (recvResult > 0)
- nlpr->packetRecver.bytesAvailable += recvResult;
- *nlprParam = nlpr->packetRecver;
- return recvResult;
-}
diff --git a/src/modules/netlib/netlibsecurity.cpp b/src/modules/netlib/netlibsecurity.cpp
deleted file mode 100644
index 4c3cb4301c..0000000000
--- a/src/modules/netlib/netlibsecurity.cpp
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (ñ) 2012-15 Miranda NG project (http://miranda-ng.org),
-Copyright (c) 2000-12 Miranda IM project,
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "..\..\core\commonheaders.h"
-#include "netlib.h"
-
-#define SECURITY_WIN32
-#include <security.h>
-#include <rpcdce.h>
-
-#pragma comment(lib, "secur32.lib")
-
-struct NtlmHandleType
-{
- CtxtHandle hClientContext;
- CredHandle hClientCredential;
- TCHAR* szProvider;
- TCHAR* szPrincipal;
- unsigned cbMaxToken;
- bool hasDomain;
-};
-
-struct NTLM_String
-{
- WORD len;
- WORD allocedSpace;
- DWORD offset;
-};
-
-struct NtlmType2packet
-{
- char sign[8];
- DWORD type; // == 2
- NTLM_String targetName;
- DWORD flags;
- BYTE challenge[8];
- BYTE context[8];
- NTLM_String targetInfo;
-};
-
-static unsigned ntlmCnt = 0;
-static mir_cs csSec;
-
-static void ReportSecError(SECURITY_STATUS scRet, int line)
-{
- char szMsgBuf[256];
- FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, scRet, LANG_USER_DEFAULT, szMsgBuf, SIZEOF(szMsgBuf), NULL);
-
- char *p = strchr(szMsgBuf, 13); if (p) *p = 0;
-
- NetlibLogf(NULL, "Security error 0x%x on line %u (%s)", scRet, line, szMsgBuf);
-}
-
-HANDLE NetlibInitSecurityProvider(const TCHAR* szProvider, const TCHAR* szPrincipal)
-{
- HANDLE hSecurity = NULL;
-
- if (mir_tstrcmpi(szProvider, _T("Basic")) == 0) {
- NtlmHandleType* hNtlm = (NtlmHandleType*)mir_calloc(sizeof(NtlmHandleType));
- hNtlm->szProvider = mir_tstrdup(szProvider);
- SecInvalidateHandle(&hNtlm->hClientContext);
- SecInvalidateHandle(&hNtlm->hClientCredential);
- ntlmCnt++;
-
- return hNtlm;
- }
-
- mir_cslock lck(csSec);
-
- PSecPkgInfo ntlmSecurityPackageInfo;
- bool isGSSAPI = mir_tstrcmpi(szProvider, _T("GSSAPI")) == 0;
- const TCHAR *szProviderC = isGSSAPI ? _T("Kerberos") : szProvider;
- SECURITY_STATUS sc = QuerySecurityPackageInfo((LPTSTR)szProviderC, &ntlmSecurityPackageInfo);
- if (sc == SEC_E_OK) {
- NtlmHandleType* hNtlm;
-
- hSecurity = hNtlm = (NtlmHandleType*)mir_calloc(sizeof(NtlmHandleType));
- hNtlm->cbMaxToken = ntlmSecurityPackageInfo->cbMaxToken;
- FreeContextBuffer(ntlmSecurityPackageInfo);
-
- hNtlm->szProvider = mir_tstrdup(szProvider);
- hNtlm->szPrincipal = mir_tstrdup(szPrincipal ? szPrincipal : _T(""));
- SecInvalidateHandle(&hNtlm->hClientContext);
- SecInvalidateHandle(&hNtlm->hClientCredential);
- ntlmCnt++;
- }
- return hSecurity;
-}
-
-HANDLE NetlibInitSecurityProvider(const char* szProvider, const char* szPrincipal)
-{
- return NetlibInitSecurityProvider(_A2T(szProvider), _A2T(szPrincipal));
-}
-
-void NetlibDestroySecurityProvider(HANDLE hSecurity)
-{
- if (hSecurity == NULL)
- return;
-
- mir_cslock lck(csSec);
-
- if (ntlmCnt != 0) {
- NtlmHandleType* hNtlm = (NtlmHandleType*)hSecurity;
- if (hNtlm != NULL) {
- if (SecIsValidHandle(&hNtlm->hClientContext))
- DeleteSecurityContext(&hNtlm->hClientContext);
- if (SecIsValidHandle(&hNtlm->hClientCredential))
- FreeCredentialsHandle(&hNtlm->hClientCredential);
- mir_free(hNtlm->szProvider);
- mir_free(hNtlm->szPrincipal);
- mir_free(hNtlm);
- }
-
- --ntlmCnt;
- }
-}
-
-char* CompleteGssapi(HANDLE hSecurity, unsigned char *szChallenge, unsigned chlsz)
-{
- if (!szChallenge || !szChallenge[0]) return NULL;
-
- NtlmHandleType* hNtlm = (NtlmHandleType*)hSecurity;
- unsigned char inDataBuffer[1024];
-
- SecBuffer inBuffers[2] =
- {
- { sizeof(inDataBuffer), SECBUFFER_DATA, inDataBuffer },
- { chlsz, SECBUFFER_STREAM, szChallenge }
- };
-
- SecBufferDesc inBuffersDesc = { SECBUFFER_VERSION, 2, inBuffers };
-
- unsigned long qop = 0;
- SECURITY_STATUS sc = DecryptMessage(&hNtlm->hClientContext, &inBuffersDesc, 0, &qop);
- if (sc != SEC_E_OK) {
- ReportSecError(sc, __LINE__);
- return NULL;
- }
-
- unsigned char LayerMask = inDataBuffer[0];
- unsigned int MaxMessageSize = htonl(*(unsigned*)&inDataBuffer[1]);
-
- SecPkgContext_Sizes sizes;
- sc = QueryContextAttributes(&hNtlm->hClientContext, SECPKG_ATTR_SIZES, &sizes);
- if (sc != SEC_E_OK) {
- ReportSecError(sc, __LINE__);
- return NULL;
- }
-
- unsigned char *tokenBuffer = (unsigned char*)alloca(sizes.cbSecurityTrailer);
- unsigned char *paddingBuffer = (unsigned char*)alloca(sizes.cbBlockSize);
-
- unsigned char outDataBuffer[4] = { 1, 0, 16, 0 };
-
- SecBuffer outBuffers[3] =
- {
- { sizes.cbSecurityTrailer, SECBUFFER_TOKEN, tokenBuffer },
- { sizeof(outDataBuffer), SECBUFFER_DATA, outDataBuffer },
- { sizes.cbBlockSize, SECBUFFER_PADDING, paddingBuffer }
- };
- SecBufferDesc outBuffersDesc = { SECBUFFER_VERSION, 3, outBuffers };
-
- sc = EncryptMessage(&hNtlm->hClientContext, SECQOP_WRAP_NO_ENCRYPT, &outBuffersDesc, 0);
- if (sc != SEC_E_OK) {
- ReportSecError(sc, __LINE__);
- return NULL;
- }
-
- unsigned i, ressz = 0;
- for (i = 0; i < outBuffersDesc.cBuffers; i++)
- ressz += outBuffersDesc.pBuffers[i].cbBuffer;
-
- unsigned char *response = (unsigned char*)alloca(ressz), *p = response;
- for (i = 0; i < outBuffersDesc.cBuffers; i++) {
- memcpy(p, outBuffersDesc.pBuffers[i].pvBuffer, outBuffersDesc.pBuffers[i].cbBuffer);
- p += outBuffersDesc.pBuffers[i].cbBuffer;
- }
-
- return mir_base64_encode(response, ressz);
-}
-
-char* NtlmCreateResponseFromChallenge(HANDLE hSecurity, const char *szChallenge, const TCHAR* login, const TCHAR* psw, bool http, unsigned& complete)
-{
- if (hSecurity == NULL || ntlmCnt == 0)
- return NULL;
-
- SecBufferDesc outputBufferDescriptor, inputBufferDescriptor;
- SecBuffer outputSecurityToken, inputSecurityToken;
- TimeStamp tokenExpiration;
- ULONG contextAttributes;
- char *szOutputToken;
-
- NtlmHandleType* hNtlm = (NtlmHandleType*)hSecurity;
- if (mir_tstrcmpi(hNtlm->szProvider, _T("Basic"))) {
- bool isGSSAPI = mir_tstrcmpi(hNtlm->szProvider, _T("GSSAPI")) == 0;
- TCHAR *szProvider = isGSSAPI ? _T("Kerberos") : hNtlm->szProvider;
- bool hasChallenge = szChallenge != NULL && szChallenge[0] != '\0';
- if (hasChallenge) {
- unsigned tokenLen;
- BYTE *token = (BYTE*)mir_base64_decode(szChallenge, &tokenLen);
- if (token == NULL)
- return NULL;
-
- if (isGSSAPI && complete)
- return CompleteGssapi(hSecurity, token, tokenLen);
-
- inputBufferDescriptor.cBuffers = 1;
- inputBufferDescriptor.pBuffers = &inputSecurityToken;
- inputBufferDescriptor.ulVersion = SECBUFFER_VERSION;
- inputSecurityToken.BufferType = SECBUFFER_TOKEN;
- inputSecurityToken.cbBuffer = tokenLen;
- inputSecurityToken.pvBuffer = token;
-
- // try to decode the domain name from the NTLM challenge
- if (login != NULL && login[0] != '\0' && !hNtlm->hasDomain) {
- NtlmType2packet* pkt = (NtlmType2packet*)token;
- if (!strncmp(pkt->sign, "NTLMSSP", 8) && pkt->type == 2) {
-
- wchar_t* domainName = (wchar_t*)&token[pkt->targetName.offset];
- int domainLen = pkt->targetName.len;
-
- // Negotiate ANSI? if yes, convert the ANSI name to unicode
- if ((pkt->flags & 1) == 0) {
- int bufsz = MultiByteToWideChar(CP_ACP, 0, (char*)domainName, domainLen, NULL, 0);
- wchar_t* buf = (wchar_t*)alloca(bufsz * sizeof(wchar_t));
- domainLen = MultiByteToWideChar(CP_ACP, 0, (char*)domainName, domainLen, buf, bufsz) - 1;
- domainName = buf;
- }
- else domainLen /= sizeof(wchar_t);
-
- if (domainLen) {
- size_t newLoginLen = mir_tstrlen(login) + domainLen + 1;
- TCHAR *newLogin = (TCHAR*)alloca(newLoginLen * sizeof(TCHAR));
-
- _tcsncpy(newLogin, domainName, domainLen);
- newLogin[domainLen] = '\\';
- mir_tstrcpy(newLogin + domainLen + 1, login);
-
- char* szChl = NtlmCreateResponseFromChallenge(hSecurity, NULL, newLogin, psw, http, complete);
- mir_free(szChl);
- }
- }
- }
- }
- else {
- if (SecIsValidHandle(&hNtlm->hClientContext))
- DeleteSecurityContext(&hNtlm->hClientContext);
- if (SecIsValidHandle(&hNtlm->hClientCredential))
- FreeCredentialsHandle(&hNtlm->hClientCredential);
-
- SEC_WINNT_AUTH_IDENTITY auth;
-
- if (login != NULL && login[0] != '\0') {
- memset(&auth, 0, sizeof(auth));
-
- NetlibLogf(NULL, "Security login requested, user: %S pssw: %s", login, psw ? "(exist)" : "(no psw)");
-
- const TCHAR* loginName = login;
- const TCHAR* domainName = _tcschr(login, '\\');
- size_t domainLen = 0;
- size_t loginLen = mir_tstrlen(loginName);
- if (domainName != NULL) {
- loginName = domainName + 1;
- loginLen = mir_tstrlen(loginName);
- domainLen = domainName - login;
- domainName = login;
- }
- else if ((domainName = _tcschr(login, '@')) != NULL) {
- loginName = login;
- loginLen = domainName - login;
- domainLen = mir_tstrlen(++domainName);
- }
-
- auth.User = (PWORD)loginName;
- auth.UserLength = (ULONG)loginLen;
- auth.Password = (PWORD)psw;
- auth.PasswordLength = (ULONG)mir_tstrlen(psw);
- auth.Domain = (PWORD)domainName;
- auth.DomainLength = (ULONG)domainLen;
- auth.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
-
- hNtlm->hasDomain = domainLen != 0;
- }
-
- SECURITY_STATUS sc = AcquireCredentialsHandle(NULL, szProvider,
- SECPKG_CRED_OUTBOUND, NULL, hNtlm->hasDomain ? &auth : NULL, NULL, NULL,
- &hNtlm->hClientCredential, &tokenExpiration);
- if (sc != SEC_E_OK) {
- ReportSecError(sc, __LINE__);
- return NULL;
- }
- }
-
- outputBufferDescriptor.cBuffers = 1;
- outputBufferDescriptor.pBuffers = &outputSecurityToken;
- outputBufferDescriptor.ulVersion = SECBUFFER_VERSION;
- outputSecurityToken.BufferType = SECBUFFER_TOKEN;
- outputSecurityToken.cbBuffer = hNtlm->cbMaxToken;
- outputSecurityToken.pvBuffer = alloca(outputSecurityToken.cbBuffer);
-
- SECURITY_STATUS sc = InitializeSecurityContext(&hNtlm->hClientCredential,
- hasChallenge ? &hNtlm->hClientContext : NULL,
- hNtlm->szPrincipal, isGSSAPI ? ISC_REQ_MUTUAL_AUTH | ISC_REQ_STREAM : 0, 0, SECURITY_NATIVE_DREP,
- hasChallenge ? &inputBufferDescriptor : NULL, 0, &hNtlm->hClientContext,
- &outputBufferDescriptor, &contextAttributes, &tokenExpiration);
-
- complete = (sc != SEC_I_COMPLETE_AND_CONTINUE && sc != SEC_I_CONTINUE_NEEDED);
-
- if (sc == SEC_I_COMPLETE_NEEDED || sc == SEC_I_COMPLETE_AND_CONTINUE)
- sc = CompleteAuthToken(&hNtlm->hClientContext, &outputBufferDescriptor);
-
- if (sc != SEC_E_OK && sc != SEC_I_CONTINUE_NEEDED) {
- ReportSecError(sc, __LINE__);
- return NULL;
- }
-
- szOutputToken = mir_base64_encode((PBYTE)outputSecurityToken.pvBuffer, outputSecurityToken.cbBuffer);
- }
- else {
- if (!login || !psw) return NULL;
-
- char *szLogin = mir_t2a(login);
- char *szPassw = mir_t2a(psw);
-
- size_t authLen = mir_strlen(szLogin) + mir_strlen(szPassw) + 5;
- char *szAuth = (char*)alloca(authLen);
-
- int len = mir_snprintf(szAuth, authLen, "%s:%s", szLogin, szPassw);
- szOutputToken = mir_base64_encode((BYTE*)szAuth, len);
- complete = true;
-
- mir_free(szPassw);
- mir_free(szLogin);
- }
-
- if (szOutputToken == NULL)
- return NULL;
-
- if (!http)
- return szOutputToken;
-
- ptrA szProvider(mir_t2a(hNtlm->szProvider));
- size_t resLen = mir_strlen(szOutputToken) + mir_strlen(szProvider) + 10;
- char *result = (char*)mir_alloc(resLen);
- mir_snprintf(result, resLen, "%s %s", szProvider, szOutputToken);
- mir_free(szOutputToken);
- return result;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-static INT_PTR InitSecurityProviderService(WPARAM, LPARAM lParam)
-{
- HANDLE hSecurity = NetlibInitSecurityProvider((char*)lParam, NULL);
- return (INT_PTR)hSecurity;
-}
-
-static INT_PTR InitSecurityProviderService2(WPARAM, LPARAM lParam)
-{
- NETLIBNTLMINIT2 *req = (NETLIBNTLMINIT2*)lParam;
- if (req == NULL || req->cbSize < sizeof(*req))
- return 0;
-
- if (req->flags & NNR_UNICODE)
- return (INT_PTR)NetlibInitSecurityProvider(req->szProviderName, req->szPrincipal);
- return (INT_PTR)NetlibInitSecurityProvider((char*)req->szProviderName, (char*)req->szPrincipal);
-}
-
-static INT_PTR DestroySecurityProviderService(WPARAM, LPARAM lParam)
-{
- NetlibDestroySecurityProvider((HANDLE)lParam);
- return 0;
-}
-
-static INT_PTR NtlmCreateResponseService(WPARAM wParam, LPARAM lParam)
-{
- NETLIBNTLMREQUEST *req = (NETLIBNTLMREQUEST*)lParam;
- if (req == NULL)
- return 0;
-
- unsigned complete = 0;
- char *response = NtlmCreateResponseFromChallenge((HANDLE)wParam, req->szChallenge, _A2T(req->userName), _A2T(req->password), false, complete);
- return (INT_PTR)response;
-}
-
-static INT_PTR NtlmCreateResponseService2(WPARAM wParam, LPARAM lParam)
-{
- NETLIBNTLMREQUEST2 *req = (NETLIBNTLMREQUEST2*)lParam;
- if (req == NULL || req->cbSize < sizeof(*req))
- return 0;
-
- if (req->flags & NNR_UNICODE)
- return (INT_PTR)NtlmCreateResponseFromChallenge((HANDLE)wParam, req->szChallenge, req->szUserName, req->szPassword, false, req->complete);
-
- return (INT_PTR)NtlmCreateResponseFromChallenge((HANDLE)wParam, req->szChallenge, _A2T((char*)req->szUserName), _A2T((char*)req->szPassword), false, req->complete);
-}
-
-void NetlibSecurityInit(void)
-{
- CreateServiceFunction(MS_NETLIB_INITSECURITYPROVIDER, InitSecurityProviderService);
- CreateServiceFunction(MS_NETLIB_INITSECURITYPROVIDER2, InitSecurityProviderService2);
- CreateServiceFunction(MS_NETLIB_DESTROYSECURITYPROVIDER, DestroySecurityProviderService);
- CreateServiceFunction(MS_NETLIB_NTLMCREATERESPONSE, NtlmCreateResponseService);
- CreateServiceFunction(MS_NETLIB_NTLMCREATERESPONSE2, NtlmCreateResponseService2);
-}
diff --git a/src/modules/netlib/netlibsock.cpp b/src/modules/netlib/netlibsock.cpp
deleted file mode 100644
index e53e73bd89..0000000000
--- a/src/modules/netlib/netlibsock.cpp
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (ñ) 2012-15 Miranda NG project (http://miranda-ng.org),
-Copyright (c) 2000-12 Miranda IM project,
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "..\..\core\commonheaders.h"
-#include "netlib.h"
-
-extern HANDLE hConnectionHeaderMutex, hSendEvent, hRecvEvent;
-
-INT_PTR NetlibSend(WPARAM wParam, LPARAM lParam)
-{
- NetlibConnection *nlc = (NetlibConnection*)wParam;
- NETLIBBUFFER *nlb = (NETLIBBUFFER*)lParam;
- INT_PTR result;
-
- if (nlb == NULL) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return SOCKET_ERROR;
- }
-
- if (!NetlibEnterNestedCS(nlc, NLNCS_SEND))
- return SOCKET_ERROR;
-
- if (nlc->usingHttpGateway && !(nlb->flags & MSG_RAW)) {
- if (!(nlb->flags & MSG_NOHTTPGATEWAYWRAP) && nlc->nlu->user.pfnHttpGatewayWrapSend) {
- NetlibDumpData(nlc, (PBYTE)nlb->buf, nlb->len, 1, nlb->flags);
- result = nlc->nlu->user.pfnHttpGatewayWrapSend((HANDLE)nlc, (PBYTE)nlb->buf, nlb->len, nlb->flags | MSG_NOHTTPGATEWAYWRAP, NetlibSend);
- }
- else result = NetlibHttpGatewayPost(nlc, nlb->buf, nlb->len, nlb->flags);
- }
- else {
- NetlibDumpData(nlc, (PBYTE)nlb->buf, nlb->len, 1, nlb->flags);
- if (nlc->hSsl)
- result = si.write(nlc->hSsl, nlb->buf, nlb->len);
- else
- result = send(nlc->s, nlb->buf, nlb->len, nlb->flags & 0xFFFF);
- }
- NetlibLeaveNestedCS(&nlc->ncsSend);
-
- NETLIBNOTIFY nln = { nlb, result };
- NotifyFastHook(hSendEvent, (WPARAM)&nln, (LPARAM)&nlc->nlu->user);
-
- return result;
-}
-
-INT_PTR NetlibRecv(WPARAM wParam, LPARAM lParam)
-{
- NetlibConnection *nlc = (NetlibConnection*)wParam;
- NETLIBBUFFER* nlb = (NETLIBBUFFER*)lParam;
- int recvResult;
-
- if (nlb == NULL) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return SOCKET_ERROR;
- }
-
- if (!NetlibEnterNestedCS(nlc, NLNCS_RECV))
- return SOCKET_ERROR;
-
- if (nlc->usingHttpGateway && !(nlb->flags & MSG_RAW))
- recvResult = NetlibHttpGatewayRecv(nlc, nlb->buf, nlb->len, nlb->flags);
- else {
- if (nlc->hSsl)
- recvResult = si.read(nlc->hSsl, nlb->buf, nlb->len, (nlb->flags & MSG_PEEK) != 0);
- else
- recvResult = recv(nlc->s, nlb->buf, nlb->len, nlb->flags & 0xFFFF);
- }
- NetlibLeaveNestedCS(&nlc->ncsRecv);
- if (recvResult <= 0)
- return recvResult;
-
- NetlibDumpData(nlc, (PBYTE)nlb->buf, recvResult, 0, nlb->flags);
-
- if ((nlb->flags & MSG_PEEK) == 0) {
- NETLIBNOTIFY nln = { nlb, recvResult };
- NotifyFastHook(hRecvEvent, (WPARAM)&nln, (LPARAM)&nlc->nlu->user);
- }
- return recvResult;
-}
-
-static int ConnectionListToSocketList(HANDLE *hConns, fd_set *fd, int& pending)
-{
- FD_ZERO(fd);
- for (int i = 0; hConns[i] && hConns[i] != INVALID_HANDLE_VALUE && i < FD_SETSIZE; i++) {
- NetlibConnection *nlcCheck = (NetlibConnection*)hConns[i];
- if (nlcCheck->handleType != NLH_CONNECTION && nlcCheck->handleType != NLH_BOUNDPORT) {
- SetLastError(ERROR_INVALID_DATA);
- return 0;
- }
- FD_SET(nlcCheck->s, fd);
- if (si.pending(nlcCheck->hSsl))
- pending++;
- }
- return 1;
-}
-
-INT_PTR NetlibSelect(WPARAM, LPARAM lParam)
-{
- NETLIBSELECT *nls = (NETLIBSELECT*)lParam;
- if (nls == NULL || nls->cbSize != sizeof(NETLIBSELECT)) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return SOCKET_ERROR;
- }
-
- TIMEVAL tv;
- tv.tv_sec = nls->dwTimeout/1000;
- tv.tv_usec = (nls->dwTimeout%1000)*1000;
-
- int pending = 0;
- fd_set readfd, writefd, exceptfd;
- WaitForSingleObject(hConnectionHeaderMutex, INFINITE);
- if (!ConnectionListToSocketList(nls->hReadConns, &readfd, pending)
- || !ConnectionListToSocketList(nls->hWriteConns, &writefd, pending)
- || !ConnectionListToSocketList(nls->hExceptConns, &exceptfd, pending))
- {
- ReleaseMutex(hConnectionHeaderMutex);
- return SOCKET_ERROR;
- }
- ReleaseMutex(hConnectionHeaderMutex);
- if (pending)
- return 1;
-
- return select(0, &readfd, &writefd, &exceptfd, nls->dwTimeout == INFINITE ? NULL : &tv);
-}
-
-INT_PTR NetlibSelectEx(WPARAM, LPARAM lParam)
-{
- NETLIBSELECTEX *nls = (NETLIBSELECTEX*)lParam;
- if (nls == NULL || nls->cbSize != sizeof(NETLIBSELECTEX)) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return SOCKET_ERROR;
- }
-
- TIMEVAL tv;
- tv.tv_sec = nls->dwTimeout / 1000;
- tv.tv_usec = (nls->dwTimeout % 1000) * 1000;
- WaitForSingleObject(hConnectionHeaderMutex, INFINITE);
-
- int pending = 0;
- fd_set readfd, writefd, exceptfd;
- if (!ConnectionListToSocketList(nls->hReadConns, &readfd, pending)
- || !ConnectionListToSocketList(nls->hWriteConns, &writefd, pending)
- || !ConnectionListToSocketList(nls->hExceptConns, &exceptfd, pending))
- {
- ReleaseMutex(hConnectionHeaderMutex);
- return SOCKET_ERROR;
- }
- ReleaseMutex(hConnectionHeaderMutex);
-
- int rc = (pending) ? pending : select(0, &readfd, &writefd, &exceptfd, nls->dwTimeout == INFINITE ? NULL : &tv);
-
- WaitForSingleObject(hConnectionHeaderMutex, INFINITE);
- /* go thru each passed HCONN array and grab its socket handle, then give it to FD_ISSET()
- to see if an event happened for that socket, if it has it will be returned as TRUE (otherwise not)
- This happens for read/write/except */
- NetlibConnection *conn = NULL;
- int j;
- for (j = 0; j < FD_SETSIZE; j++) {
- conn = (NetlibConnection*)nls->hReadConns[j];
- if (conn == NULL || conn == INVALID_HANDLE_VALUE) break;
-
- if (si.pending(conn->hSsl))
- nls->hReadStatus[j] = TRUE;
- if (conn->usingHttpGateway && conn->nlhpi.szHttpGetUrl == NULL && conn->dataBuffer == NULL)
- nls->hReadStatus[j] = (conn->pHttpProxyPacketQueue != NULL);
- else
- nls->hReadStatus[j] = FD_ISSET(conn->s, &readfd);
- }
- for (j = 0; j < FD_SETSIZE; j++) {
- conn = (NetlibConnection*)nls->hWriteConns[j];
- if (conn == NULL || conn == INVALID_HANDLE_VALUE) break;
- nls->hWriteStatus[j] = FD_ISSET(conn->s, &writefd);
- }
- for (j = 0; j < FD_SETSIZE; j++) {
- conn = (NetlibConnection*)nls->hExceptConns[j];
- if (conn == NULL || conn == INVALID_HANDLE_VALUE) break;
- nls->hExceptStatus[j] = FD_ISSET(conn->s, &exceptfd);
- }
- ReleaseMutex(hConnectionHeaderMutex);
- return rc;
-}
-
-bool NetlibStringToAddress(const char* str, SOCKADDR_INET_M* addr)
-{
- if (!str) return false;
-
- int len = sizeof(SOCKADDR_INET_M);
- return !WSAStringToAddressA((char*)str, AF_INET6, NULL, (PSOCKADDR)addr, &len);
-}
-
-char* NetlibAddressToString(SOCKADDR_INET_M* addr)
-{
- char saddr[128];
- DWORD len = sizeof(saddr);
- if (!WSAAddressToStringA((PSOCKADDR)addr, sizeof(*addr), NULL, saddr, &len))
- return mir_strdup(saddr);
-
- if (addr->si_family == AF_INET) {
- char *szIp = inet_ntoa(addr->Ipv4.sin_addr);
- if (addr->Ipv4.sin_port != 0) {
- mir_snprintf(saddr, SIZEOF(saddr), "%s:%d", szIp, htons(addr->Ipv4.sin_port));
- return mir_strdup(saddr);
- }
- return mir_strdup(szIp);
- }
- return NULL;
-}
-
-void NetlibGetConnectionInfo(NetlibConnection* nlc, NETLIBCONNINFO *connInfo)
-{
- if (!nlc || !connInfo || connInfo->cbSize < sizeof(NETLIBCONNINFO)) return;
-
- SOCKADDR_INET_M sin = { 0 };
- int len = sizeof(sin);
- if (!getsockname(nlc->s, (PSOCKADDR)&sin, &len)) {
- connInfo->wPort = ntohs(sin.Ipv4.sin_port);
- connInfo->dwIpv4 = sin.si_family == AF_INET ? htonl(sin.Ipv4.sin_addr.s_addr) : 0;
-
- char *szTmp = NetlibAddressToString(&sin);
- strncpy(connInfo->szIpPort, szTmp, sizeof(connInfo->szIpPort));
- connInfo->szIpPort[sizeof(connInfo->szIpPort) - 1] = 0;
- mir_free(szTmp);
- }
-}
-
-inline bool IsAddrGlobal(const IN6_ADDR *a)
-{
- unsigned char High = a->s6_bytes[0] & 0xf0;
- return High != 0 && High != 0xf0;
-}
-
-static NETLIBIPLIST* GetMyIpv6(unsigned flags)
-{
- addrinfo *air = NULL, *ai, hints = { 0 };
- const char *szMyHost = "";
-
- hints.ai_family = AF_UNSPEC;
- hints.ai_flags = AI_PASSIVE;
-
- if (GetAddrInfoA(szMyHost, NULL, &hints, &air))
- return NULL;
-
- unsigned n = 0;
- for (ai = air; ai; ai = ai->ai_next) {
- SOCKADDR_INET_M *iaddr = (SOCKADDR_INET_M*)ai->ai_addr;
- if (ai->ai_family == AF_INET || (ai->ai_family == AF_INET6 && (!(flags & 1) || IsAddrGlobal(&iaddr->Ipv6.sin6_addr))))
- ++n;
- }
-
- NETLIBIPLIST *addr = (NETLIBIPLIST*)mir_calloc(n * 64 + 4);
- addr->cbNum = n;
-
- unsigned i = 0;
- for (ai = air; ai; ai = ai->ai_next) {
- SOCKADDR_INET_M *iaddr = (SOCKADDR_INET_M*)ai->ai_addr;
- if (ai->ai_family == AF_INET ||
- (ai->ai_family == AF_INET6 &&
- (!(flags & 1) || IsAddrGlobal(&iaddr->Ipv6.sin6_addr))))
- {
- char *szIp = NetlibAddressToString(iaddr);
- if (szIp)
- strncpy_s(addr->szIp[i++], szIp, _TRUNCATE);
- mir_free(szIp);
- }
- }
- FreeAddrInfoA(air);
- return addr;
-}
-
-static NETLIBIPLIST* GetMyIpv4(void)
-{
- char hostname[256] = "";
-
- gethostname(hostname, sizeof(hostname));
- PHOSTENT he = gethostbyname(hostname);
-
- unsigned n;
- for (n = 0; he->h_addr_list[n]; ++n)
- ;
-
- NETLIBIPLIST *addr = (NETLIBIPLIST*)mir_calloc(n * 64 + 4);
- addr->cbNum = n;
-
- for (unsigned i = 0; i < n; i++)
- strncpy_s(addr->szIp[i], inet_ntoa(*(PIN_ADDR)he->h_addr_list[i]), _TRUNCATE);
-
- return addr;
-}
-
-NETLIBIPLIST* GetMyIp(unsigned flags)
-{
- return GetMyIpv6(flags);
-}
diff --git a/src/modules/netlib/netlibupnp.cpp b/src/modules/netlib/netlibupnp.cpp
deleted file mode 100644
index d3f30498d6..0000000000
--- a/src/modules/netlib/netlibupnp.cpp
+++ /dev/null
@@ -1,826 +0,0 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (ñ) 2012-15 Miranda NG project (http://miranda-ng.org),
-Copyright (c) 2000-12 Miranda IM project,
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "..\..\core\commonheaders.h"
-#include "netlib.h"
-
-static const char search_request_msg[] =
- "M-SEARCH * HTTP/1.1\r\n"
- "HOST: 239.255.255.250:1900\r\n"
- "MAN: \"ssdp:discover\"\r\n"
- "MX: 1\r\n"
- "ST: urn:schemas-upnp-org:service:%s\r\n"
- "\r\n";
-
-static const char xml_get_hdr[] =
- "GET %s HTTP/1.1\r\n"
- "HOST: %s:%u\r\n"
- "ACCEPT-LANGUAGE: *\r\n\r\n";
-
-static const char soap_post_hdr[] =
- "POST %s HTTP/1.1\r\n"
- "HOST: %s:%u\r\n"
- "CONTENT-LENGTH: %u\r\n"
- "CONTENT-TYPE: text/xml; charset = \"utf-8\"\r\n"
- "SOAPACTION: \"%s#%s\"\r\n\r\n"
- "%s";
-
-static const char soap_post_hdr_m[] =
- "M-POST %s URL HTTP/1.1\r\n"
- "HOST: %s:%u\r\n"
- "CONTENT-LENGTH: %u\r\n"
- "CONTENT-TYPE: text/xml; charset = \"utf-8\"\r\n"
- "MAN: \"http://schemas.xmlsoap.org/soap/envelope/\"; ns = 01\r\n"
- "01-SOAPACTION: \"%s#%s\"\r\n\r\n"
- "%s";
-
-static const char search_device[] =
- "<serviceType>%s</serviceType>";
-
-static const char soap_action[] =
- "<?xml version = \"1.0\"?>\r\n"
- "<s:Envelope\r\n"
- " xmlns:s = \"http://schemas.xmlsoap.org/soap/envelope/\"\r\n"
- " s:encodingStyle = \"http://schemas.xmlsoap.org/soap/encoding/\">\r\n"
- " <s:Body>\r\n"
- " <u:%s xmlns:u = \"%s\">\r\n"
- "%s"
- " </u:%s>\r\n"
- " </s:Body>\r\n"
- "</s:Envelope>\r\n";
-
-static const char soap_query[] =
- "<s:Envelope\r\n"
- " xmlns:s = \"http://schemas.xmlsoap.org/soap/envelope/\"\r\n"
- " s:encodingStyle = \"http://schemas.xmlsoap.org/soap/encoding/\">\r\n"
- " <s:Body>\r\n"
- " <u:QueryStateVariable xmlns:u = \"urn:schemas-upnp-org:control-1-0\">\r\n"
- " <u:varName>%s</u:varName>\r\n"
- " </u:QueryStateVariable>\r\n"
- " </s:Body>\r\n"
- "</s:Envelope>\r\n";
-
-static const char add_port_mapping[] =
- " <NewRemoteHost></NewRemoteHost>\r\n"
- " <NewExternalPort>%i</NewExternalPort>\r\n"
- " <NewProtocol>%s</NewProtocol>\r\n"
- " <NewInternalPort>%i</NewInternalPort>\r\n"
- " <NewInternalClient>%s</NewInternalClient>\r\n"
- " <NewEnabled>1</NewEnabled>\r\n"
- " <NewPortMappingDescription>Miranda</NewPortMappingDescription>\r\n"
- " <NewLeaseDuration>0</NewLeaseDuration>\r\n";
-
-static const char delete_port_mapping[] =
- " <NewRemoteHost></NewRemoteHost>\r\n"
- " <NewExternalPort>%i</NewExternalPort>\r\n"
- " <NewProtocol>%s</NewProtocol>\r\n";
-
-static const char get_port_mapping[] =
- " <NewPortMappingIndex>%i</NewPortMappingIndex>\r\n";
-
-static bool gatewayFound;
-static SOCKADDR_IN locIP;
-static time_t lastDiscTime;
-static int expireTime = 120;
-
-static int retryCount;
-static SOCKET sock = INVALID_SOCKET;
-static char szConnHost[256];
-static unsigned short sConnPort;
-
-static WORD *portList;
-static unsigned numports, numportsAlloc;
-static HANDLE portListMutex;
-
-static char szCtlUrl[256], szDev[256];
-
-typedef enum
-{
- DeviceGetReq,
- ControlAction,
- ControlQuery
-} ReqType;
-
-static bool txtParseParam(char* szData, char* presearch,
- char* start, char* finish, char* param, size_t size)
-{
- char *cp, *cp1;
- size_t len;
-
- *param = 0;
-
- if (presearch != NULL) {
- cp1 = strstr(szData, presearch);
- if (cp1 == NULL) return false;
- }
- else
- cp1 = szData;
-
- cp = strstr(cp1, start);
- if (cp == NULL) return false;
- cp += mir_strlen(start);
- while (*cp == ' ') ++cp;
-
- cp1 = strstr(cp, finish);
- if (cp1 == NULL) return false;
- while (*(cp1-1) == ' ' && cp1 > cp) --cp1;
-
- len = min((size_t)(cp1 - cp), size-1);
- strncpy(param, cp, len);
- param[len] = 0;
-
- return true;
-}
-
-void parseURL(char* szUrl, char* szHost, unsigned short* sPort, char* szPath)
-{
- char *ppath, *phost, *pport;
- int sz;
-
- phost = strstr(szUrl, "://");
- if (phost == NULL) phost = szUrl;
- else phost += 3;
-
- ppath = strchr(phost, '/');
- if (ppath == NULL) ppath = phost + mir_strlen(phost);
-
- pport = strchr(phost, ':');
- if (pport == NULL) pport = ppath;
-
- if (szHost != NULL) {
- sz = pport - phost + 1;
- if (sz > 256) sz = 256;
- strncpy(szHost, phost, sz);
- szHost[sz - 1] = 0;
- }
-
- if (sPort != NULL) {
- if (pport < ppath) {
- long prt = atol(pport + 1);
- *sPort = prt != 0 ? (unsigned short)prt : 80;
- }
- else
- *sPort = 80;
- }
-
- if (szPath != NULL) {
- strncpy(szPath, ppath, 256);
- szPath[255] = 0;
- }
-}
-
-static void LongLog(char* szData)
-{
- CallService(MS_NETLIB_LOG, 0, (LPARAM)szData);
-}
-
-static void closeRouterConnection(void)
-{
- if (sock != INVALID_SOCKET) {
- closesocket(sock);
- sock = INVALID_SOCKET;
- }
-}
-
-static void validateSocket(void)
-{
- static const TIMEVAL tv = { 0, 0 };
- fd_set rfd;
- char buf[4];
- bool opened;
-
- if (sock == INVALID_SOCKET)
- return;
-
- FD_ZERO(&rfd);
- FD_SET(sock, &rfd);
-
- switch (select(1, &rfd, NULL, NULL, &tv)) {
- case SOCKET_ERROR:
- opened = false;
- break;
-
- case 0:
- opened = true;
- break;
-
- case 1:
- opened = recv(sock, buf, 1, MSG_PEEK) > 0;
- break;
- }
-
- if (!opened)
- closeRouterConnection();
-}
-
-static int httpTransact(char* szUrl, char* szResult, int resSize, char* szActionName, ReqType reqtype)
-{
- // Parse URL
- char szHost[256], szPath[256], szRes[16];
- int sz = 0, res = 0;
- unsigned short sPort;
- bool needClose = false;
-
- const char* szPostHdr = soap_post_hdr;
- char* szData = (char*)mir_alloc(4096);
- char* szReq = NULL;
-
- parseURL(szUrl, szHost, &sPort, szPath);
-
- if (sPort != sConnPort || _stricmp(szHost, szConnHost))
- closeRouterConnection();
- else
- validateSocket();
-
- while (true) {
- retryCount = 0;
- switch (reqtype) {
- case DeviceGetReq:
- sz = mir_snprintf(szData, 4096, xml_get_hdr, szPath, szHost, sPort);
- break;
-
- case ControlAction:
- {
- char szData1[1024];
-
- szReq = mir_strdup(szResult);
- sz = mir_snprintf(szData1, SIZEOF(szData1),
- soap_action, szActionName, szDev, szReq, szActionName);
-
- sz = mir_snprintf(szData, 4096,
- szPostHdr, szPath, szHost, sPort,
- sz, szDev, szActionName, szData1);
- }
- break;
-
- case ControlQuery:
- {
- char szData1[1024];
-
- sz = mir_snprintf(szData1, SIZEOF(szData1),
- soap_query, szActionName);
-
- sz = mir_snprintf(szData, 4096,
- szPostHdr, szPath, szHost, sPort,
- sz, "urn:schemas-upnp-org:control-1-0", "QueryStateVariable", szData1);
- }
- break;
- }
- szResult[0] = 0;
- {
- static const TIMEVAL tv = { 6, 0 };
- static unsigned ttl = 4;
- static u_long mode = 1;
- fd_set rfd, wfd, efd;
- SOCKADDR_IN enetaddr;
-
-retrycon:
- if (sock == INVALID_SOCKET) {
- sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-
- enetaddr.sin_family = AF_INET;
- enetaddr.sin_port = htons(sPort);
- enetaddr.sin_addr.s_addr = inet_addr(szHost);
-
- // Resolve host name if needed
- if (enetaddr.sin_addr.s_addr == INADDR_NONE) {
- PHOSTENT he = gethostbyname(szHost);
- if (he)
- enetaddr.sin_addr.s_addr = *(unsigned*)he->h_addr_list[0];
- }
-
- NetlibLogf(NULL, "UPnP HTTP connection Host: %s Port: %u", szHost, sPort);
-
- FD_ZERO(&rfd); FD_ZERO(&wfd); FD_ZERO(&efd);
- FD_SET(sock, &rfd); FD_SET(sock, &wfd); FD_SET(sock, &efd);
-
- // Limit the scope of the connection (does not work for
- setsockopt(sock, IPPROTO_IP, IP_TTL, (char *)&ttl, sizeof(unsigned));
-
- // Put socket into non-blocking mode for timeout on connect
- ioctlsocket(sock, FIONBIO, &mode);
-
- // Connect to the remote host
- if (connect(sock, (SOCKADDR*)&enetaddr, sizeof(enetaddr)) == SOCKET_ERROR) {
- int err = WSAGetLastError();
-
- // Socket connection failed
- if (err != WSAEWOULDBLOCK) {
- closeRouterConnection();
- NetlibLogf(NULL, "UPnP connect failed %d", err);
- break;
- }
- // Wait for socket to connect
- else if (select(1, &rfd, &wfd, &efd, &tv) != 1) {
- closeRouterConnection();
- NetlibLogf(NULL, "UPnP connect timeout");
- break;
- }
- else if (!FD_ISSET(sock, &wfd)) {
- closeRouterConnection();
- NetlibLogf(NULL, "UPnP connect failed");
- break;
- }
- }
- strncpy_s(szConnHost, szHost, _TRUNCATE);
- sConnPort = sPort;
- }
-
- if (send(sock, szData, sz, 0) != SOCKET_ERROR) {
- char *hdrend = NULL;
- int acksz = 0, pktsz = 0;
-
- if (szActionName == NULL) {
- int len = sizeof(locIP);
- getsockname(sock, (SOCKADDR*)&locIP, &len);
- if (locIP.sin_addr.S_un.S_addr == 0x0100007f) {
- struct hostent *he;
-
- gethostname(szPath, sizeof(szPath));
- he = gethostbyname(szPath);
- if (he != NULL)
- locIP.sin_addr.S_un.S_addr = *(PDWORD)he->h_addr_list[0];
- }
- }
-
- LongLog(szData);
- sz = 0;
- while (true) {
- int bytesRecv;
-
- FD_ZERO(&rfd);
- FD_SET(sock, &rfd);
-
- // Wait for the next packet
- if (select(1, &rfd, NULL, NULL, &tv) != 1) {
- closeRouterConnection();
- NetlibLogf(NULL, "UPnP recieve timeout");
- break;
- }
-
- //
- bytesRecv = recv(sock, &szResult[sz], resSize - sz, 0);
-
- // Connection closed or aborted, all data received
- if (bytesRecv == 0 || bytesRecv == SOCKET_ERROR) {
- closeRouterConnection();
- if ((bytesRecv == SOCKET_ERROR || sz == 0) && retryCount < 2) {
- ++retryCount;
- goto retrycon;
- }
- break;
- }
-
- sz += bytesRecv;
-
- // Insert null terminator to use string functions
- if (sz >= (resSize - 1)) {
- szResult[resSize - 1] = 0;
- break;
- }
- else
- szResult[sz] = 0;
-
- // HTTP header found?
- if (hdrend == NULL) {
- // Find HTTP header end
- hdrend = strstr(szResult, "\r\n\r\n");
- if (hdrend == NULL) {
- hdrend = strstr(szResult, "\n\n");
- if (hdrend) hdrend += 2;
- }
-
- else
- hdrend += 4;
-
- if (hdrend != NULL) {
- // Get packet size if provided
- if (txtParseParam(szResult, NULL, "Content-Length:", "\n", szRes, sizeof(szRes)) ||
- txtParseParam(szResult, NULL, "CONTENT-LENGTH:", "\n", szRes, sizeof(szRes))) {
- // Add size of HTTP header to the packet size to compute full transmission size
- pktsz = atol(ltrimp(szRes)) + (hdrend - szResult);
- }
- // Get encoding type if provided
- else if (txtParseParam(szResult, NULL, "Transfer-Encoding:", "\n", szRes, sizeof(szRes))) {
- if (_stricmp(lrtrimp(szRes), "Chunked") == 0)
- acksz = hdrend - szResult;
- }
- if (txtParseParam(szResult, NULL, "Connection:", "\n", szRes, sizeof(szRes))) {
- needClose = (_stricmp(lrtrimp(szRes), "close") == 0);
- }
- }
- }
-
- // Content-Length bytes reached, all data received
- if (sz >= pktsz && pktsz != 0) {
- szResult[pktsz] = 0;
- break;
- }
-
- // Chunked encoding processing
- if (sz > acksz && acksz != 0) {
-retry:
- // Parse out chunk size
- char* data = szResult + acksz;
- char* peol1 = data == hdrend ? data - 1 : strchr(data, '\n');
- if (peol1 != NULL) {
- char *peol2 = strchr(++peol1, '\n');
- if (peol2 != NULL) {
- // Get chunk size
- int chunkBytes = strtol(peol1, NULL, 16);
- acksz += chunkBytes;
- peol2++;
-
- memmove(data, peol2, mir_strlen(peol2) + 1);
- sz -= peol2 - data;
-
- // Last chunk, all data received
- if (chunkBytes == 0) break;
- if (sz > acksz) goto retry;
- }
- }
- }
- }
- LongLog(szResult);
- }
- else {
- if (retryCount < 2) {
- closeRouterConnection();
- ++retryCount;
- goto retrycon;
- }
- else
- NetlibLogf(NULL, "UPnP send failed %d", WSAGetLastError());
- }
- }
- txtParseParam(szResult, "HTTP", " ", " ", szRes, sizeof(szRes));
- res = atol(szRes);
- if (szActionName != NULL && res == 405 && szPostHdr == soap_post_hdr)
- szPostHdr = soap_post_hdr_m;
- else
- break;
- }
-
- if (needClose)
- closeRouterConnection();
-
- mir_free(szData);
- mir_free(szReq);
- return res;
-}
-
-static unsigned getExtIP(void)
-{
- char szExtIP[30];
- char* szData = (char*)mir_alloc(4096); szData[0] = 0;
-
- unsigned extip = 0;
- int res = httpTransact(szCtlUrl, szData, 4096, "GetExternalIPAddress", ControlAction);
- if (res == 200 && txtParseParam(szData, "<NewExternalIPAddress", ">", "<", szExtIP, sizeof(szExtIP)))
- extip = ntohl(inet_addr(szExtIP));
-
- mir_free(szData);
- return extip;
-}
-
-static bool getUPnPURLs(char* szUrl, size_t sizeUrl)
-{
- char* szData = (char*)mir_alloc(8192);
-
- gatewayFound = httpTransact(szUrl, szData, 8192, NULL, DeviceGetReq) == 200;
- if (gatewayFound) {
- char szTemp[256], *rpth;
- size_t ctlLen;
-
- txtParseParam(szData, NULL, "<URLBase>", "</URLBase>", szTemp, sizeof(szTemp));
- strncpy(szCtlUrl, szTemp[0] ? szTemp : szUrl, sizeof(szCtlUrl));
- szCtlUrl[sizeof(szCtlUrl) - 1] = 0;
-
- mir_snprintf(szTemp, search_device, szDev);
- txtParseParam(szData, szTemp, "<controlURL>", "</controlURL>", szUrl, sizeUrl);
-
- // URL combining per RFC 2396
- if (szUrl[0] != 0) {
- if (strstr(szUrl, "://") != NULL) // absolute URI
- rpth = szCtlUrl;
- else if (strncmp(szUrl, "//", 2) == 0) // relative URI net_path
- {
- rpth = strstr(szCtlUrl, "//");
- if (rpth == NULL) rpth = szCtlUrl;
- }
- else if (szUrl[0] == '/') // relative URI abs_path
- {
- rpth = strstr(szCtlUrl, "//");
- rpth = rpth ? rpth + 2 : szCtlUrl;
-
- rpth = strchr(rpth, '/');
- if (rpth == NULL) rpth = szCtlUrl + mir_strlen(szCtlUrl);
- }
- else { // relative URI rel_path
- size_t ctlCLen = mir_strlen(szCtlUrl);
- rpth = szCtlUrl + ctlCLen;
- if (ctlCLen != 0 && *(rpth - 1) != '/')
- strncpy(rpth++, "/", sizeof(szCtlUrl) - ctlCLen);
- }
-
- ctlLen = sizeof(szCtlUrl) - (rpth - szCtlUrl);
- strncpy(rpth, szUrl, ctlLen);
- szCtlUrl[sizeof(szCtlUrl) - 1] = 0;
- }
- else {
- szCtlUrl[0] = 0;
- gatewayFound = false;
- }
- }
- mir_free(szData);
-
- return gatewayFound;
-}
-
-static void discoverUPnP(void)
-{
- char* buf;
- int buflen;
- unsigned i, j, nip = 0;
- unsigned* ips = NULL;
-
- static const unsigned any = INADDR_ANY;
- static const TIMEVAL tv = { 1, 600000 };
-
- char szUrl[256] = "";
- char hostname[256];
- PHOSTENT he;
- fd_set readfd;
-
- SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-
- SOCKADDR_IN enetaddr;
- enetaddr.sin_family = AF_INET;
- enetaddr.sin_port = htons(1900);
- enetaddr.sin_addr.s_addr = inet_addr("239.255.255.250");
-
- gethostname(hostname, sizeof(hostname));
- he = gethostbyname(hostname);
-
- if (he) {
- while (he->h_addr_list[nip]) ++nip;
-
- ips = (unsigned*)mir_alloc(nip * sizeof(unsigned));
-
- for (j = 0; j < nip; j++)
- ips[j] = *(unsigned*)he->h_addr_list[j];
- }
-
- buf = (char*)mir_alloc(1500);
-
- for (i = 3; --i && szUrl[0] == 0;) {
- for (j = 0; j < nip; j++) {
- if (ips)
- setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, (char *)&ips[j], sizeof(unsigned));
-
- buflen = mir_snprintf(buf, 1500, search_request_msg, "WANIPConnection:1");
- sendto(sock, buf, buflen, 0, (SOCKADDR*)&enetaddr, sizeof(enetaddr));
- LongLog(buf);
-
- buflen = mir_snprintf(buf, 1500, search_request_msg, "WANPPPConnection:1");
- sendto(sock, buf, buflen, 0, (SOCKADDR*)&enetaddr, sizeof(enetaddr));
- LongLog(buf);
- }
-
- if (Miranda_Terminated()) break;
-
- FD_ZERO(&readfd);
- FD_SET(sock, &readfd);
-
- while (select(1, &readfd, NULL, NULL, &tv) >= 1) {
- buflen = recv(sock, buf, 1500, 0);
- if (buflen != SOCKET_ERROR) {
- buf[buflen] = 0;
- LongLog(buf);
-
- if (txtParseParam(buf, NULL, "LOCATION:", "\n", szUrl, sizeof(szUrl)) ||
- txtParseParam(buf, NULL, "Location:", "\n", szUrl, sizeof(szUrl))) {
- char age[30];
- char szHostNew[256], szHostExist[256];
-
- lrtrim(szUrl);
-
- parseURL(szUrl, szHostNew, NULL, NULL);
- parseURL(szCtlUrl, szHostExist, NULL, NULL);
- if (mir_strcmp(szHostNew, szHostExist) == 0) {
- gatewayFound = true;
- break;
- }
-
- txtParseParam(buf, NULL, "ST:", "\n", szDev, sizeof(szDev));
- txtParseParam(buf, "max-age", " = ", "\n", age, sizeof(age));
- expireTime = atoi(lrtrimp(age));
- lrtrim(szDev);
-
- if (getUPnPURLs(szUrl, sizeof(szUrl))) {
- gatewayFound = getExtIP() != 0;
- if (gatewayFound) break;
- }
- }
- }
- FD_ZERO(&readfd);
- FD_SET(sock, &readfd);
- }
- }
-
- mir_free(buf);
- mir_free(ips);
- setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, (char *)&any, sizeof(unsigned));
- closesocket(sock);
-}
-
-static bool findUPnPGateway(void)
-{
- if ((time(NULL) - lastDiscTime) >= expireTime) {
- WaitForSingleObject(portListMutex, INFINITE);
-
- time_t curTime = time(NULL);
-
- if ((curTime - lastDiscTime) >= expireTime) {
- gatewayFound = false;
-
- discoverUPnP();
- lastDiscTime = curTime;
-
- NetlibLogf(NULL, "UPnP Gateway detected %d, Control URL: %s", gatewayFound, szCtlUrl);
- }
-
- ReleaseMutex(portListMutex);
- }
-
- return gatewayFound;
-}
-
-bool NetlibUPnPAddPortMapping(WORD intport, char *proto, WORD *extport, DWORD *extip, bool search)
-{
- int res = 0, i = 5;
-
- if (findUPnPGateway()) {
- char* szData = (char*)mir_alloc(4096);
- char szExtIP[30];
-
- *extport = intport - 1;
- *extip = ntohl(locIP.sin_addr.S_un.S_addr);
-
- WaitForSingleObject(portListMutex, INFINITE);
-
- do {
- ++*extport;
- mir_snprintf(szData, 4096, add_port_mapping,
- *extport, proto, intport, inet_ntoa(locIP.sin_addr));
- res = httpTransact(szCtlUrl, szData, 4096, "AddPortMapping", ControlAction);
- txtParseParam(szData, NULL, "<errorCode>", "</errorCode>", szExtIP, sizeof(szExtIP));
-
- } while (search && res == 500 && atol(szExtIP) == 718 && --i);
-
- mir_free(szData);
-
- if (res == 200) {
- unsigned ip = getExtIP();
- if (ip) *extip = ip;
-
- if (numports >= numportsAlloc)
- mir_realloc(portList, sizeof(WORD)*(numportsAlloc += 10));
- portList[numports++] = *extport;
- }
-
- ReleaseMutex(portListMutex);
- }
-
- return res == 200;
-}
-
-void NetlibUPnPDeletePortMapping(WORD extport, char* proto)
-{
- if (extport == 0)
- return;
-
- // findUPnPGateway();
-
- if (gatewayFound) {
- unsigned i;
- char* szData = (char*)mir_alloc(4096);
-
- WaitForSingleObject(portListMutex, INFINITE);
- mir_snprintf(szData, 4096, delete_port_mapping, extport, proto);
- httpTransact(szCtlUrl, szData, 4096, "DeletePortMapping", ControlAction);
-
- for (i = 0; i < numports; i++)
- if (portList[i] == extport && --numports > 0)
- memmove(&portList[i], &portList[i + 1], (numports - i) * sizeof(WORD));
-
- mir_free(szData);
- ReleaseMutex(portListMutex);
- }
-}
-
-void NetlibUPnPCleanup(void*)
-{
- // upnp is disabled globally, no need for a cleanup
- if (db_get_b(NULL, "Netlib", "NLEnableUPnP", 1) == 0)
- return;
-
- {
- int incoming = 0;
- mir_cslock lck(csNetlibUser);
- for (int i = 0; i < netlibUser.getCount(); i++)
- if (netlibUser[i]->user.flags & NUF_INCOMING) {
- incoming = 1;
- break;
- }
-
- if (!incoming)
- return;
- }
-
- if (findUPnPGateway()) {
- char *szData = (char*)alloca(4096);
- char buf[50], lip[50];
- unsigned j = 0, k, num = 100;
-
- strncpy_s(lip, inet_ntoa(locIP.sin_addr), _TRUNCATE);
-
- WaitForSingleObject(portListMutex, INFINITE);
-
- if (httpTransact(szCtlUrl, szData, 4096, "PortMappingNumberOfEntries", ControlQuery) == 200 &&
- txtParseParam(szData, "QueryStateVariableResponse", "<return>", "<", buf, sizeof(buf)))
- num = atol(buf);
-
- WORD ports[30];
- for (unsigned i = 0; i < num && !Miranda_Terminated(); i++) {
- mir_snprintf(szData, 4096, get_port_mapping, i);
-
- ReleaseMutex(portListMutex);
- WaitForSingleObject(portListMutex, INFINITE);
-
- if (httpTransact(szCtlUrl, szData, 4096, "GetGenericPortMappingEntry", ControlAction) != 200)
- break;
-
- if (!txtParseParam(szData, "<NewPortMappingDescription", ">", "<", buf, sizeof(buf)) || mir_strcmp(buf, "Miranda") != 0)
- continue;
-
- if (!txtParseParam(szData, "<NewInternalClient", ">", "<", buf, sizeof(buf)) || mir_strcmp(buf, lip) != 0)
- continue;
-
- if (txtParseParam(szData, "<NewExternalPort", ">", "<", buf, sizeof(buf))) {
- WORD mport = (WORD)atol(buf);
-
- if (j >= SIZEOF(ports))
- break;
-
- for (k = 0; k < numports; ++k)
- if (portList[k] == mport)
- break;
-
- if (k >= numports)
- ports[j++] = mport;
- }
- }
-
- ReleaseMutex(portListMutex);
-
- for (unsigned i = 0; i < j && !Miranda_Terminated(); i++)
- NetlibUPnPDeletePortMapping(ports[i], "TCP");
- }
-}
-
-void NetlibUPnPInit(void)
-{
- numports = 0;
- numportsAlloc = 10;
- portList = (WORD*)mir_alloc(sizeof(WORD)*numportsAlloc);
-
- portListMutex = CreateMutex(NULL, FALSE, NULL);
-}
-
-void NetlibUPnPDestroy(void)
-{
- mir_free(portList);
- CloseHandle(portListMutex);
-}