Windows2003-3790/inetcore/wininet/socks/wsock32.c
2020-09-30 16:53:55 +02:00

1487 lines
40 KiB
C

/*++
Copyright (c) 1997 Microsoft Corporation
Copyright (c) 1996 Hummingbird Corporation of Canada
Module Name:
wsock32.c
Abstract:
Contains Socks V4 support, written by Hummingbird corporation. Licensed from
Hummingbird for ulimited use by Microsoft. Ported to WININET code base.
Contents:
FindSocket
closesocket
connect
getpeername
ALL WSOCK32.DLL exports.
Author:
Arthur L Bierer (arthurbi) 13-Dec-1996
Environment:
Win32 user-mode DLL
Revision History:
13-Dec-1996 arthurbi
Created, removed flagrent calls to CRTs, and unchecked memory allocations.
29-Aug-1997 rfirth
Further reduced from general-purpose SOCKS implementation to Wininet-
specific SOCKS support
--*/
#define _WINSOCKAPI_
#include <windows.h>
#ifdef DO_FILE_CONFIG
#include <stdio.h>
#include <string.h>
#include <io.h>
#include <malloc.h>
#include <ctype.h>
#include <stdlib.h>
#endif
#ifdef OLD_SOCKS
struct User {
char *Name;
struct User *Next;
};
struct Server {
char *Name;
struct Server *Next;
unsigned short port;
};
struct Hosts {
struct User *Users;
struct Server *Servers;
unsigned long dst;
unsigned long mask;
unsigned short port;
unsigned char op;
unsigned char type;
struct Hosts *Next;
} *Head=NULL;
struct Sockets {
int s;
HWND hWnd;
unsigned int wMsg;
long lEvent;
unsigned long Blocking;
int type;
unsigned long ip;
unsigned short port;
struct Sockets *Next;
struct Sockets *Last;
int Socked:1;
} *SHead=NULL;
HANDLE SMutex;
#define CREATE_MUTEX() SMutex = CreateMutex(NULL, FALSE, NULL)
#define DELETE_MUTEX() if (SMutex) CloseHandle(SMutex)
#define ENTER_MUTEX() WaitForSingleObject(SMutex, INFINITE)
#define LEAVE_MUTEX() ReleaseMutex(SMutex)
#else
struct Hosts {
char * user;
int userlen;
unsigned long ip;
unsigned short port;
} *Head = NULL;
struct Sockets {
int s;
int type;
unsigned long ip;
unsigned short port;
struct Sockets * Next;
struct Sockets * Last;
int Socked : 1;
int Blocking : 1;
} *SHead = NULL;
CRITICAL_SECTION CritSec;
#define CREATE_MUTEX() InitializeCriticalSection(&CritSec)
#define DELETE_MUTEX() DeleteCriticalSection(&CritSec)
#define ENTER_MUTEX() EnterCriticalSection(&CritSec)
#define LEAVE_MUTEX() LeaveCriticalSection(&CritSec)
#endif
#define DENY 1
#define DIRECT 2
#define SOCKD 3
#define ANY 0
#define EQ 1
#define NEQ 2
#define LT 3
#define GT 4
#define LE 5
#define GE 6
/*
* Internet address (old style... should be updated)
*/
struct in_addr {
union {
struct { unsigned char s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { unsigned short s_w1,s_w2; } S_un_w;
unsigned long S_addr;
} S_un;
#define s_addr S_un.S_addr
/* can be used for most tcp & ip code */
#define s_host S_un.S_un_b.s_b2
/* host on imp */
#define s_net S_un.S_un_b.s_b1
/* network */
#define s_imp S_un.S_un_w.s_w2
/* imp */
#define s_impno S_un.S_un_b.s_b4
/* imp # */
#define s_lh S_un.S_un_b.s_b3
/* logical host */
};
/*
* Socket address, internet style.
*/
struct sockaddr_in {
short sin_family;
unsigned short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
struct servent {
char * s_name; /* official service name */
char * * s_aliases; /* alias list */
short s_port; /* port # */
char * s_proto; /* protocol to use */
};
struct hostent {
char * h_name; /* official name of host */
char * * h_aliases; /* alias list */
short h_addrtype; /* host address type */
short h_length; /* length of address */
char * * h_addr_list; /* list of addresses */
#define h_addr h_addr_list[0] /* address, for backward compat */
};
#define WSABASEERR 10000
#define WSAECONNREFUSED (WSABASEERR+61)
#define WSAEWOULDBLOCK (WSABASEERR+35)
#define WSAENOBUFS (WSABASEERR+55)
#define SOCKET_ERROR (-1)
#define INVALID_SOCKET (int)(~0)
/*
* Define flags to be used with the WSAAsyncSelect() call.
*/
#define FD_READ 0x01
#define FD_WRITE 0x02
#define FD_OOB 0x04
#define FD_ACCEPT 0x08
#define FD_CONNECT 0x10
#define FD_CLOSE 0x20
#define SOCK_STREAM 1 /* stream socket */
/*
* Commands for ioctlsocket(), taken from the BSD file fcntl.h.
*
*
* Ioctl's have the command encoded in the lower word,
* and the size of any in or out parameters in the upper
* word. The high 2 bits of the upper word are used
* to encode the in/out status of the parameter; for now
* we restrict parameters to at most 128 bytes.
*/
#define IOCPARM_MASK 0x7f /* parameters must be < 128 bytes */
#define IOC_VOID 0x20000000 /* no parameters */
#define IOC_OUT 0x40000000 /* copy out parameters */
#define IOC_IN 0x80000000 /* copy in parameters */
#define IOC_INOUT (IOC_IN|IOC_OUT)
/* 0x20000000 distinguishes new &
old ioctl's */
#define _IO(x,y) (IOC_VOID|((x)<<8)|(y))
#define _IOR(x,y,t) (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
#define _IOW(x,y,t) (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
#define FIONREAD _IOR('f', 127, unsigned long) /* get # bytes to read */
#define FIONBIO _IOW('f', 126, unsigned long) /* set/clear non-blocking i/o */
#define FIOASYNC _IOW('f', 125, unsigned long) /* set/clear async i/o */
#define SO_SET_SOCKS_FIREWALL 0xF0000
DWORD (WINAPI * VArecv)(int a,int b,int c, int d);
DWORD (WINAPI * VAsend)(int a,int b,int c, int d);
DWORD (WINAPI * VEnumProtocolsA)(int a,int b,int c);
DWORD (WINAPI * VEnumProtocolsW)(int a,int b,int c);
DWORD (WINAPI * VGetAddressByNameA)(int a,int b,int c,int d,int e,int f,int g,int h,int i,int j);
DWORD (WINAPI * VGetAddressByNameW)(int a,int b,int c,int d,int e,int f,int g,int h,int i,int j);
DWORD (WINAPI * VGetNameByTypeA)(int a,int b,int c);
DWORD (WINAPI * VGetNameByTypeW)(int a,int b,int c);
DWORD (WINAPI * VGetServiceA)(int a,int b,int c,int d,int e,int f,int g);
DWORD (WINAPI * VGetServiceW)(int a,int b,int c,int d,int e,int f,int g);
DWORD (WINAPI * VGetTypeByNameA)(int a,int b);
DWORD (WINAPI * VGetTypeByNameW)(int a,int b);
DWORD (WINAPI * VNPLoadNameSpaces)(int a,int b,int c);
DWORD (WINAPI * VSetServiceA)(int a,int b,int c,int d,int e,int f);
DWORD (WINAPI * VSetServiceW)(int a,int b,int c,int d,int e,int f);
DWORD (WINAPI * VTransmitFile)(int a,int b,int c,int d,int e,int f,int g);
DWORD (WINAPI * VWSAAsyncGetHostByAddr)(int a,int b,int c,int d,int e,int f,int g);
DWORD (WINAPI * VWSAAsyncGetHostByName)(int a,int b,int c,int d,int e);
DWORD (WINAPI * VWSAAsyncGetProtoByName)(int a,int b,int c,int d,int e);
DWORD (WINAPI * VWSAAsyncGetProtoByNumber)(int a,int b,int c,int d,int e);
DWORD (WINAPI * VWSAAsyncGetServByName)(int a,int b,int c,int d,int e,int f);
DWORD (WINAPI * VWSAAsyncGetServByPort)(int a,int b,int c,int d,int e,int f);
DWORD (WINAPI * VWSAAsyncSelect)(int s, HWND hWnd, unsigned int wMsg, long lEvent);
DWORD (WINAPI * VWSACancelAsyncRequest)(int a);
DWORD (WINAPI * VWSACancelBlockingCall)(void);
DWORD (WINAPI * VWSACleanup)(void);
DWORD (WINAPI * VWSAGetLastError)(void);
DWORD (WINAPI * VWSAIsBlocking)(void);
DWORD (WINAPI * VWSARecvEx)(int a,int b,int c,int d);
DWORD (WINAPI * VWSASetBlockingHook)(int a);
DWORD (WINAPI * VWSASetLastError)(int a);
DWORD (WINAPI * VWSAStartup)(int a,int b);
DWORD (WINAPI * VWSAUnhookBlockingHook)(void);
DWORD ( * VWSHEnumProtocols)(int a,int b,int c,int d);
DWORD (WINAPI * VWsControl)(int a,int b,int c,int d,int e,int f);
DWORD (WINAPI * V__WSAFDIsSet)(int a,int b);
DWORD (WINAPI * Vaccept)(int a,int b,int c);
DWORD (WINAPI * Vbind)(int a,int b,int c);
DWORD (WINAPI * Vclosesocket)(int a);
DWORD (WINAPI * Vclosesockinfo)(int a);
DWORD (WINAPI * Vconnect)(int s, const struct sockaddr_in FAR *name, int namelen);
DWORD (WINAPI * Vdn_expand)(int a,int b,int c,int d,int e);
DWORD (WINAPI * Vgethostbyaddr)(int a,int b,int c);
struct hostent * (WINAPI * Vgethostbyname)(char *);
DWORD (WINAPI * Vgethostname)(int a,int b);
DWORD (WINAPI * Vgetnetbyname)(int a);
DWORD (WINAPI * Vgetpeername)(int s, struct sockaddr_in *name,int *namelen);
DWORD (WINAPI * Vgetprotobyname)(int a);
DWORD (WINAPI * Vgetprotobynumber)(int a);
struct servent * (WINAPI * Vgetservbyname)(const char FAR * name, const char FAR * proto);
DWORD (WINAPI * Vgetservbyport)(int a,int b);
DWORD (WINAPI * Vgetsockname)(int a,int b,int c);
DWORD (WINAPI * Vgetsockopt)(int a,int b,int c,int d,int e);
DWORD (WINAPI * Vhtonl)(int a);
DWORD (WINAPI * Vhtons)(int a);
DWORD (WINAPI * Vinet_addr)(char *p);
DWORD (WINAPI * Vinet_network)(int a);
DWORD (WINAPI * Vinet_ntoa)(int a);
DWORD (WINAPI * Vioctlsocket)(int s, long cmd, unsigned long *argp);
DWORD (WINAPI * Vlisten)(int a,int b);
DWORD (WINAPI * Vntohl)(int a);
DWORD (WINAPI * Vntohs)(int a);
DWORD (WINAPI * Vrcmd)(int a,int b,int c,int d,int e,int f);
DWORD (WINAPI * Vrecv)(int a,int b,int c,int d);
DWORD (WINAPI * Vrecvfrom)(int a,int b,int c,int d,int e,int f);
DWORD (WINAPI * Vrexec)(int a,int b,int c,int d,int e,int f);
DWORD (WINAPI * Vrresvport)(int a);
DWORD (WINAPI * Vs_perror)(int a,int b);
DWORD (WINAPI * Vselect)(int a,int b,int c,int d,int e);
DWORD (WINAPI * Vsend)(int a,int b,int c,int d);
DWORD (WINAPI * Vsendto)(int a,int b,int c,int d,int e,int f);
DWORD (WINAPI * Vsethostname)(int a,int b);
DWORD (WINAPI * Vsetsockopt)(int s,int level,int optname,const char FAR * optval, int optlen);
DWORD (WINAPI * Vshutdown)(int a,int b);
DWORD (WINAPI * Vsocket)(int a,int b,int c);
DWORD (WINAPI * VWEP)(void);
DWORD (WINAPI * VAcceptEx)(int a,int b,int c,int d,int e,int f,int g,int h);
DWORD (WINAPI * VGetAcceptExSockaddrs)(int a,int b,int c,int d,int e,int f,int g,int h);
DWORD (WINAPI * VMigrateWinsockConfiguration)(int a,int b, int c);
DWORD (WINAPI * VWSApSetPostRoutine)(void *a);
BOOL (WINAPI * VPostMessage)(HWND hWnd, unsigned int wMsg, WPARAM wPAram, LPARAM lParam) = NULL;
BOOL MyPostMessage(HWND hWnd, unsigned int wMsg, WPARAM wParam, LPARAM lParam) {
if ( VPostMessage)
return(VPostMessage(hWnd,wMsg, wParam, lParam));
PostMessage(hWnd,wMsg, wParam, lParam);
}
struct Sockets *
FindSocket(
int s
)
/*++
Routine Description:
Find or create SOCKS socket object. Returns with MUTEX held
Arguments:
s - associated socket handle
Return Value:
struct Sockets *
Success - address of Sockets object
Failure - NULL
--*/
{
struct Sockets *So;
ENTER_MUTEX();
So = SHead;
while (So) {
if (s == So->s) {
return So;
}
So = So->Next;
}
if (So = (struct Sockets *)LocalAlloc(LPTR, sizeof(struct Sockets))) {
So->s = s;
So->Next = SHead;
SHead = So;
if (So->Next) {
(So->Next)->Last = So;
}
}
return So;
}
//LPSTR
//NewString(
// IN LPCSTR String
// )
//
///*++
//
//Routine Description:
//
// kind of version of strdup() but using LocalAlloc to allocate memory
//
//Arguments:
//
// String - pointer to string to make copy of
//
//Return Value:
//
// LPSTR
// Success - pointer to duplicated string
// Failure - NULL
//
//--*/
//
//{
// int len = strlen(String) + 1;
// LPSTR string;
//
// if (string = (LPSTR)LocalAlloc(LMEM_FIXED, len)) {
// CopyMemory(string, String, len);
// }
// return string;
//}
DWORD WINAPI __WSAFDIsSet(int a,int b) {
return(V__WSAFDIsSet(a, b));
}
DWORD WINAPI accept(int a,int b,int c) {
return(Vaccept(a, b, c));
}
DWORD WINAPI Arecv(int a,int b,int c,int d) {
return(VArecv(a,b,c,d));
}
DWORD WINAPI Asend(int a,int b,int c,int d) {
return(VAsend(a,b,c,d));
}
DWORD WINAPI bind(int a,int b,int c) {
return(Vbind(a, b, c));
}
DWORD WINAPI AcceptEx(int a,int b,int c,int d,int e,int f,int g,int h) {
return(VAcceptEx(a,b,c,d,e,f,g,h));
}
DWORD WINAPI GetAcceptExSockaddrs(int a,int b,int c,int d,int e,int f,int g,int h) {
return(VGetAcceptExSockaddrs(a,b,c,d,e,f,g,h));
}
DWORD WINAPI MigrateWinsockConfiguration(int a,int b, int c) {
return(VMigrateWinsockConfiguration(a,b,c));
}
DWORD WINAPI WSApSetPostRoutine(void *a) {
VPostMessage=a;
return(VWSApSetPostRoutine(a));
}
DWORD
WINAPI
closesocket(
int s
)
/*++
Routine Description:
Closes socket handle and destroys associated Sockets object if found
Arguments:
s - socket handle
Return Value:
int
Success - 0
Failure - -1
--*/
{
struct Sockets * So = FindSocket(s);
if (So == NULL) {
VWSASetLastError(WSAENOBUFS);
LEAVE_MUTEX();
return SOCKET_ERROR;
}
if (So->Last == NULL) {
SHead = So->Next;
} else {
(So->Last)->Next = So->Next;
}
if (So->Next) {
(So->Next)->Last = So->Last;
}
LEAVE_MUTEX();
LocalFree(So);
return Vclosesocket(s);
}
DWORD WINAPI closesockinfo(int a) {
return(Vclosesockinfo(a));
}
DWORD
WINAPI
connect(
int s,
const struct sockaddr_in FAR * name,
int namelen
)
/*++
Routine Description:
Connect to remote host via SOCKS proxy. Modified from original. If we are
here then we are going specifically via a known SOCKS proxy. There is now
only one Hosts object, containing a single SOCKD socks proxy address and
user name
Arguments:
s - socket to connect
name - sockaddr of remote host
namelen - length of sockaddr
Return Value:
int
Success - 0
Failure - -1
--*/
{
unsigned long ip;
unsigned short port;
struct Hosts * pHost;
int serr;
int blocking;
struct Sockets * pSocket;
struct sockaddr_in sin;
struct {
unsigned char VN;
unsigned char CD;
unsigned short DSTPORT;
unsigned long DSTIP;
char UserId[255];
} request;
int length;
char response[256];
int val;
//
// get IP address and port we want to connect to on other side of firewall
//
port = name->sin_port;
ip = name->sin_addr.s_addr;
//
// initialize sockaddr for connecting to SOCKS firewall
//
memset(&sin, 0, sizeof(sin));
sin.sin_family = 2;
//
// initialize SOCKS request packet
//
request.VN = 4;
request.CD = 1;
request.DSTPORT = port;
request.DSTIP = ip;
pSocket = FindSocket(s);
if (pSocket == NULL) {
VWSASetLastError(WSAENOBUFS);
LEAVE_MUTEX();
return SOCKET_ERROR;
}
pHost = Head;
if (!pHost || (pSocket->type != SOCK_STREAM) || (pSocket->Socked)) {
LEAVE_MUTEX();
return Vconnect(s, name, namelen);
}
//
// get information from pSocket and pHost structures before releasing mutex
//
blocking = pSocket->Blocking;
pSocket->port = port;
pSocket->ip = ip;
memcpy(request.UserId, pHost->user, pHost->userlen);
length = pHost->userlen + 8; // 8 == sizeof fixed portion of request
sin.sin_port = pHost->port;
sin.sin_addr.s_addr = pHost->ip;
//
// from this point, we cannot touch pHost or pSocket until we take the mutex
// again
//
LEAVE_MUTEX();
//
// put socket into blocking mode
//
val = 0;
Vioctlsocket(s, FIONBIO, &val);
//
// communicate with SOCKS firewall: send SOCKS request & receive response
//
serr = Vconnect(s, &sin, sizeof(sin));
if (serr != SOCKET_ERROR) {
serr = Vsend(s, (int)&request, length, 0);
if (serr == length) {
serr = Vrecv(s, (int)response, sizeof(response), 0);
}
}
//
// if originally non-blocking, make socket non-blocking again
//
if (blocking) {
Vioctlsocket(s, FIONBIO, &blocking);
}
//
// if success, mark the socket as being connected through firewall
//
if ((serr == SOCKET_ERROR) || (response[1] != 90)) {
VWSASetLastError(WSAECONNREFUSED);
serr = SOCKET_ERROR;
} else {
//
// if we can't find/crea
//
pSocket = FindSocket(s);
if (pSocket) {
pSocket->Socked = 1;
serr = 0;
} else {
VWSASetLastError(WSAENOBUFS);
serr = SOCKET_ERROR;
}
LEAVE_MUTEX();
}
return serr;
}
DWORD WINAPI dn_expand(int a,int b,int c,int d,int e) {
return(Vdn_expand(a, b, c, d, e));
}
DWORD WINAPI EnumProtocolsA(int a,int b,int c) {
return(VEnumProtocolsA(a, b, c));
}
DWORD WINAPI EnumProtocolsW(int a,int b,int c) {
return(VEnumProtocolsW(a, b, c));
}
DWORD WINAPI GetAddressByNameA(int a,int b,int c,int d,int e,int f,int g,int h,int i,int j) {
return(VGetAddressByNameA(a, b, c, d, e, f, g, h, i, j));
}
DWORD WINAPI GetAddressByNameW(int a,int b,int c,int d,int e,int f,int g,int h,int i,int j) {
return(VGetAddressByNameW(a, b, c, d, e, f, g, h, i, j));
}
DWORD WINAPI gethostbyaddr(int a,int b,int c) {
return(Vgethostbyaddr(a, b, c));
}
struct hostent FAR * WINAPI gethostbyname(char *a) {
return(Vgethostbyname(a));
}
DWORD WINAPI gethostname(int a,int b) {
return(Vgethostname(a, b));
}
DWORD WINAPI GetNameByTypeA(int a,int b,int c) {
return(VGetNameByTypeA(a, b, c));
}
DWORD WINAPI GetNameByTypeW(int a,int b,int c) {
return(VGetNameByTypeW(a, b, c));
}
DWORD WINAPI getnetbyname(int a) {
return(Vgetnetbyname(a));
}
DWORD
WINAPI
getpeername(
int s,
struct sockaddr_in * name,
int *namelen
)
/*++
Routine Description:
description-of-function.
Arguments:
s -
name -
namelen -
Return Value:
int
--*/
{
DWORD ret;
struct Sockets *So;
ret = Vgetpeername(s, name, namelen);
if (ret == 0) {
So = FindSocket(s);
if (So) {
if (So->Socked) {
if (*namelen >= sizeof(struct sockaddr_in)) {
name->sin_port = So->port;
name->sin_addr.s_addr = So->ip;
}
}
} else {
VWSASetLastError(WSAENOBUFS);
ret = SOCKET_ERROR;
}
LEAVE_MUTEX();
}
return ret;
}
DWORD WINAPI getprotobyname(int a) {
return(Vgetprotobyname(a));
}
DWORD WINAPI getprotobynumber(int a) {
return(Vgetprotobynumber(a));
}
struct servent * WINAPI getservbyname(const char FAR * name, const char FAR * proto) {
return(Vgetservbyname(name, proto));
}
DWORD WINAPI getservbyport(int a,int b) {
return(Vgetservbyport(a, b));
}
DWORD WINAPI GetServiceA(int a,int b,int c,int d,int e,int f,int g) {
return(VGetServiceA(a, b, c, d, e, f, g));
}
DWORD WINAPI GetServiceW(int a,int b,int c,int d,int e,int f,int g) {
return(VGetServiceW(a, b, c, d, e, f, g));
}
DWORD WINAPI getsockname(int a,int b,int c) {
return(Vgetsockname(a, b, c));
}
DWORD WINAPI getsockopt(int a,int b,int c,int d,int e) {
return(Vgetsockopt(a, b, c, d, e));
}
DWORD WINAPI GetTypeByNameA(int a,int b) {
return(VGetTypeByNameA(a, b));
}
DWORD WINAPI GetTypeByNameW(int a,int b) {
return(VGetTypeByNameW(a, b));
}
DWORD WINAPI htonl(int a) {
return(Vhtonl(a));
}
DWORD WINAPI htons(int a) {
return(Vhtons(a));
}
DWORD WINAPI inet_addr(char *p) {
return(Vinet_addr(p));
}
DWORD WINAPI inet_network(int a) {
return(Vinet_network(a));
}
DWORD WINAPI inet_ntoa(int a) {
return(Vinet_ntoa(a));
}
DWORD WINAPI ioctlsocket(int s, long cmd, unsigned long *argp) {
if (cmd == FIONBIO) {
struct Sockets * So = FindSocket(s);
if (So == NULL) {
VWSASetLastError(WSAENOBUFS);
LEAVE_MUTEX();
return SOCKET_ERROR;
}
So->Blocking = *argp ? 1 : 0;
LEAVE_MUTEX();
}
return Vioctlsocket(s, cmd, argp);
}
DWORD WINAPI listen(int a,int b) {
return(Vlisten(a, b));
}
DWORD WINAPI NPLoadNameSpaces(int a,int b,int c) {
return(VNPLoadNameSpaces(a, b, c));
}
DWORD WINAPI ntohl(int a) {
return(Vntohl(a));
}
DWORD WINAPI ntohs(int a) {
return(Vntohs(a));
}
DWORD WINAPI rcmd(int a,int b,int c,int d,int e,int f) {
return(Vrcmd(a, b, c, d, e, f));
}
DWORD WINAPI recv(int a,int b,int c,int d) {
return(Vrecv(a, b, c, d));
}
DWORD WINAPI recvfrom(int a,int b,int c,int d,int e,int f) {
return(Vrecvfrom(a, b, c, d, e, f));
}
DWORD WINAPI rexec(int a,int b,int c,int d,int e,int f) {
return(Vrexec(a, b, c, d, e, f));
}
DWORD WINAPI rresvport(int a) {
return(Vrresvport(a));
}
DWORD WINAPI s_perror(int a,int b) {
return(Vs_perror(a, b));
}
DWORD WINAPI select(int a,int b,int c,int d,int e) {
return(Vselect(a, b, c, d, e));
}
DWORD WINAPI send(int a,int b,int c,int d) {
return(Vsend(a, b, c, d));
}
DWORD WINAPI sendto(int a,int b,int c,int d,int e,int f) {
return(Vsendto(a, b, c, d, e, f));
}
DWORD WINAPI sethostname(int a,int b) {
return(Vsethostname(a, b));
}
DWORD WINAPI SetServiceA(int a,int b,int c,int d,int e,int f) {
return(VSetServiceA(a, b, c, d, e, f));
}
DWORD WINAPI SetServiceW(int a,int b,int c,int d,int e,int f) {
return(VSetServiceW(a, b, c, d, e, f));
}
DWORD
WINAPI
setsockopt(
int s,
int level,
int optname,
const char FAR * optval,
int optlen
)
/*++
Routine Description:
If SO_SET_SOCKS_FIREWALL, create SOCKS information if it is new or changed
from current, else pass on the request to wsock32!setsockopt()
Arguments:
s - socket on which to set option
level - option type parameter (SO_SET_SOCKS_FIREWALL)
optname - option type sub-parameter (SOCKS firewall port # in host format)
optval - value to set (pointer to SOCKS information:
DWORD ip address;
LPSTR username
)
optlen - length of value (8)
Return Value:
DWORD
Success - 0
Failure - -1
--*/
{
int rc;
if (level != SO_SET_SOCKS_FIREWALL) {
rc = Vsetsockopt(s, level, optname, optval, optlen);
} else {
struct Hosts * pHost;
struct FirewallInfo {
DWORD ipAddress;
LPSTR userName;
} * pInfo = (struct FirewallInfo *)optval;
optname = Vhtons(optname);
ENTER_MUTEX();
if (pHost = Head) {
if ((pHost->ip != pInfo->ipAddress)
|| (pHost->port != optname)
|| (pHost->user && lstrcmp(pHost->user, pInfo->userName))) {
//char buf[256];
//wsprintf(buf,
// "throwing out: host: %d.%d.%d.%d:%d,%s; info: %d.%d.%d.%d:%d,%s\n",
// pHost->ip & 0xff,
// (pHost->ip >> 8) & 0xff,
// (pHost->ip >> 16) & 0xff,
// (pHost->ip >> 24) & 0xff,
// Vhtons(pHost->port) & 0xffff,
// pHost->user,
// pInfo->ipAddress & 0xff,
// (pInfo->ipAddress >> 8) & 0xff,
// (pInfo->ipAddress >> 16) & 0xff,
// (pInfo->ipAddress >> 24) & 0xff,
// Vhtons(optname) & 0xffff,
// pInfo->userName
// );
//OutputDebugString(buf);
LocalFree(pHost);
pHost = NULL;
}
}
if (!pHost) {
int userlen = lstrlen(pInfo->userName) + 1;
if (pHost = (struct Hosts *)LocalAlloc(LPTR,
sizeof(struct Hosts)
+ userlen
)) {
memcpy(pHost + 1, pInfo->userName, userlen);
pHost->user = (LPSTR)(pHost + 1);
pHost->userlen = userlen;
pHost->ip = pInfo->ipAddress;
pHost->port = (unsigned short)optname;
}
}
Head = pHost;
if (pHost) {
rc = 0;
} else {
VWSASetLastError(WSAENOBUFS);
rc = SOCKET_ERROR;
}
LEAVE_MUTEX();
}
return rc;
}
DWORD WINAPI shutdown(int a,int b) {
return(Vshutdown(a, b));
}
DWORD WINAPI socket(int af,int type,int protocol) {
struct Sockets * So;
int s;
s = Vsocket(af, type, protocol);
if (s != INVALID_SOCKET) {
So = FindSocket(s);
if (So) {
So->type = type;
} else {
Vclosesocket(s);
VWSASetLastError(WSAENOBUFS);
s = INVALID_SOCKET;
}
LEAVE_MUTEX();
}
return s;
}
DWORD WINAPI TransmitFile(int a,int b,int c,int d,int e,int f,int g) {
return(VTransmitFile(a, b, c, d, e, f, g));
}
DWORD WINAPI WEP() {
return(VWEP());
}
DWORD WINAPI WSAAsyncGetHostByAddr(int a,int b,int c,int d,int e,int f,int g) {
return(VWSAAsyncGetHostByAddr(a, b, c, d, e, f, g));
}
DWORD WINAPI WSAAsyncGetHostByName(int a,int b,int c,int d,int e) {
return(VWSAAsyncGetHostByName(a, b, c, d, e));
}
DWORD WINAPI WSAAsyncGetProtoByName(int a,int b,int c,int d,int e) {
return(VWSAAsyncGetProtoByName(a, b, c, d, e));
}
DWORD WINAPI WSAAsyncGetProtoByNumber(int a,int b,int c,int d,int e) {
return(VWSAAsyncGetProtoByNumber(a, b, c, d, e));
}
DWORD WINAPI WSAAsyncGetServByName(int a,int b,int c,int d,int e,int f) {
return(VWSAAsyncGetServByName(a, b, c, d, e, f));
}
DWORD WINAPI WSAAsyncGetServByPort(int a,int b,int c,int d,int e,int f) {
return(VWSAAsyncGetServByPort(a, b, c, d, e, f));
}
DWORD WINAPI WSAAsyncSelect(int s, HWND hWnd, unsigned int wMsg, long lEvent) {
return(VWSAAsyncSelect(s,hWnd,wMsg,lEvent));
}
DWORD WINAPI WSACancelAsyncRequest(int a) {
return(VWSACancelAsyncRequest(a));
}
DWORD WINAPI WSACancelBlockingCall() {
return(VWSACancelBlockingCall());
}
DWORD WINAPI WSACleanup() {
return(VWSACleanup());
}
DWORD WINAPI WSAGetLastError() {
return(VWSAGetLastError());
}
DWORD WINAPI WSAIsBlocking() {
return(VWSAIsBlocking());
}
DWORD WINAPI WSARecvEx(int a,int b,int c,int d) {
return(VWSARecvEx(a, b, c, d));
}
DWORD WINAPI WSASetBlockingHook(int a) {
return(VWSASetBlockingHook(a));
}
DWORD WINAPI WSASetLastError(int a) {
return(VWSASetLastError(a));
}
DWORD WINAPI WSAStartup(int a,int b) {
return(VWSAStartup(a, b));
}
DWORD WINAPI WSAUnhookBlockingHook() {
return(VWSAUnhookBlockingHook());
}
DWORD WINAPI WsControl(int a,int b,int c,int d,int e,int f) {
return(VWsControl(a,b,c,d,e,f));
}
DWORD WSHEnumProtocols(int a,int b, int c,int d) {
return(VWSHEnumProtocols(a,b,c,d));
}
//#ifdef DO_FILE_CONFIG
//
//void
//ParseList(char *List,struct Server **Head,int IsSvr) {
//
// char *p;
// char *p1;
// char *pTok;
// struct Server *tmp,*Current=NULL;
//
// *Head = NULL;
//
// if ( *(List+1) != '=')
// return;
// pTok = List+2;
// List=StrTokEx(&pTok,"\t ");
// p = StrTokEx(&List,",");
// while ( p) {
// if (IsSvr) {
// tmp = (struct Server *)LocalAlloc(LPTR, (sizeof(struct Server)));
// if ( tmp == NULL )
// return;
//
// p1 = strchr(p,':');
// if (p1) {
// *p1++ = 0;
// tmp->port = atoi(p1);
// }
// else
// tmp->port = 1080;
// }
// else {
// tmp = (struct Server *)LocalAlloc(LPTR, (sizeof(struct Server)));
// if ( tmp == NULL )
// return;
// }
// tmp->Name = NewString(p);
// tmp->Next = NULL;
// if (Current == NULL) {
// Current = *Head = tmp;
// }
// else {
// Current->Next = tmp;
// Current=tmp;
// }
// p = StrTokEx(&List,",");
// }
//}
//
//
//void
//LoadConfig(void) {
//
// struct Hosts *Current=NULL,*tmp;
// char Buffer[1024];
// FILE *f;
// char *p;
// char *ServerList;
// char *UserList;
// struct Server *Default=NULL;
// HKEY Key;
//
// GetSystemDirectory(Buffer,sizeof(Buffer));
// strcat(Buffer, "\\socks.cnf");
// f = fopen(Buffer,"rt");
// if ( f == NULL)
// return;
// if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\HummingBird", 0, KEY_QUERY_VALUE, &Key) == ERROR_SUCCESS) {
// int Type, Length=sizeof(Buffer);
// if ( RegQueryValueEx(Key, "SOCKS_SERVER", NULL, &Type, Buffer, &Length) == ERROR_SUCCESS) {
// Buffer[Length] = '\0';
// Default=LocalAlloc(LPTR, sizeof(struct Server));
// if ( Default == NULL )
// return;
//
// p = strchr(Buffer,':');
// if (p) {
// *p++ = 0;
// Default->port = atoi(p);
// }
// else
// Default->port = 1080;
// Default->Name = NewString(Buffer);
// Default->Next = NULL;
// }
// RegCloseKey(Key);
// }
//
// while ( fgets(Buffer,sizeof(Buffer)-1,f) != NULL) {
// Buffer[strlen(Buffer)-1]='\0';
// if ( Buffer[0] == '#')
// continue;
// tmp = (struct Hosts *) LocalAlloc(LPTR, sizeof(struct Hosts));
// if ( tmp == NULL )
// return;
//
// memset(tmp,0,sizeof(struct Hosts));
// ServerList=NULL;
// UserList=NULL;
// p = StrTokEx(&Buffer,"\t ");
// if ( p == NULL) {
// LocalFree(tmp);
// continue;
// }
// if ( lstrcmpi(p,"DENY") == 0) {
// tmp->type = DENY;
// } else if (lstrcmpi(p,"DIRECT") == 0) {
// tmp->type = DIRECT;
// } else if (lstrcmpi(p,"SOCKD") == 0) {
// tmp->type = SOCKD;
// } else {
// LocalFree(tmp);
// continue;
// }
//LookMore:
// p = StrTokEx(&Buffer,"\t ");
// if ( p == NULL) {
// LocalFree(tmp);
// continue;
// }
// if (*p == '*') {
// UserList=p;
// goto LookMore;
// }
// if (*p == '@') {
// ServerList=p;
// goto LookMore;
// }
// tmp->dst = Vinet_addr(p);
// p = StrTokEx(&Buffer,"\t ");
// if ( p == NULL) {
// LocalFree(tmp);
// continue;
// }
// tmp->mask = Vinet_addr(p);
// p = StrTokEx(&Buffer,"\t ");
// if (p) {
// if ( lstrcmpi(p,"EQ") == 0)
// tmp->op = EQ;
// else if ( lstrcmpi(p,"NEQ") == 0)
// tmp->op = NEQ;
// else if ( lstrcmpi(p,"LT") == 0)
// tmp->op = LT;
// else if ( lstrcmpi(p,"GT") == 0)
// tmp->op = GT;
// else if ( lstrcmpi(p,"LE") == 0)
// tmp->op = LE;
// else if ( lstrcmpi(p,"GE") == 0)
// tmp->op = GE;
// else {
// LocalFree(tmp);
// continue;
// }
// p = StrTokEx(&Buffer,"\t ");
// if ( p == NULL) {
// LocalFree(tmp);
// continue;
// }
// if ( isdigit(*p))
// tmp->port = atoi(p);
// else {
// struct servent *se;
// se=Vgetservbyname(p,"tcp");
// if ( se == NULL) {
// LocalFree(tmp);
// continue;
// }
// tmp->port = se->s_port;
// }
// }
// if ( UserList)
// ParseList(UserList,(struct Server **)&tmp->Users,0);
// if ( ServerList)
// ParseList(ServerList,&tmp->Servers,1);
// if ( (tmp->type == SOCKD) && (tmp->Servers == NULL))
// tmp->Servers=Default;
// if ( Current == NULL) {
// Head = Current = tmp;
// }
// else {
// Current->Next = tmp;
// Current = tmp;
// }
// }
// fclose(f);
//}
//
//#endif
HMODULE hModule = NULL;
int LoadCount = 0;
BOOL
WINAPI
DllMain(
IN HINSTANCE hInstance,
IN DWORD reason,
IN LPVOID Reserved
)
{
HKEY hKey;
TCHAR szRegBuf[MAX_PATH+1];
DWORD dwRegBufSize = sizeof(szRegBuf);
DWORD dwRegType;
LONG lResult;
switch(reason) {
case DLL_PROCESS_DETACH:
if (LoadCount == 0) {
DELETE_MUTEX();
return 1;
}
if (--LoadCount == 0) {
FreeLibrary(hModule);
}
return 1;
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
if (++LoadCount == 1) {
break;
}
default:
return 1;
}
// Load an alternate Winsock DLL based on a registry value,
// in the event that a customer wants to load a different wsock32.
//
if (ERROR_SUCCESS == (lResult = RegOpenKeyEx(
HKEY_CURRENT_USER,
TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"),
0,
KEY_QUERY_VALUE,
&hKey
)))
{
if (ERROR_SUCCESS == (lResult = RegQueryValueEx(
hKey,
TEXT("AlternateWinsock"),
NULL,
&dwRegType,
(LPBYTE) szRegBuf,
&dwRegBufSize
)) && dwRegType == REG_SZ) // only allow type REG_SZ
{
// Found a string, so try to load it as the alternate Winsock DLL.
hModule = LoadLibrary(szRegBuf);
}
RegCloseKey(hKey);
}
if (lResult != ERROR_SUCCESS)
{
hModule = LoadLibrary("WSOCK32.DLL");
}
if (hModule < (HMODULE) HINSTANCE_ERROR) {
MessageBox(NULL,
"Unable to find old WSOCK32.DLL named \"WSOCK32.DLL\".",
"Microsoft/Hummingbird SOCKS Shim",
MB_OK
);
LoadCount = 0;
return 0;
}
(FARPROC) VArecv=GetProcAddress(hModule,"Arecv");
(FARPROC) VAsend=GetProcAddress(hModule,"Asend");
(FARPROC) VEnumProtocolsA=GetProcAddress(hModule,"EnumProtocolsA");
(FARPROC) VEnumProtocolsW=GetProcAddress(hModule,"EnumProtocolsW");
(FARPROC) VGetAddressByNameA=GetProcAddress(hModule,"GetAddressByNameA");
(FARPROC) VGetAddressByNameW=GetProcAddress(hModule,"GetAddressByNameW");
(FARPROC) VGetNameByTypeA=GetProcAddress(hModule,"GetNameByTypeA");
(FARPROC) VGetNameByTypeW=GetProcAddress(hModule,"GetNameByTypeW");
(FARPROC) VGetServiceA=GetProcAddress(hModule,"GetServiceA");
(FARPROC) VGetServiceW=GetProcAddress(hModule,"GetServiceW");
(FARPROC) VGetTypeByNameA=GetProcAddress(hModule,"GetTypeByNameA");
(FARPROC) VGetTypeByNameW=GetProcAddress(hModule,"GetTypeByNameW");
(FARPROC) VNPLoadNameSpaces=GetProcAddress(hModule,"NPLoadNameSpaces");
(FARPROC) VSetServiceA=GetProcAddress(hModule,"SetServiceA");
(FARPROC) VSetServiceW=GetProcAddress(hModule,"SetServiceW");
(FARPROC) VTransmitFile=GetProcAddress(hModule,"TransmitFile");
(FARPROC) VWSAAsyncGetHostByAddr=GetProcAddress(hModule,"WSAAsyncGetHostByAddr");
(FARPROC) VWSAAsyncGetHostByName=GetProcAddress(hModule,"WSAAsyncGetHostByName");
(FARPROC) VWSAAsyncGetProtoByName=GetProcAddress(hModule,"WSAAsyncGetProtoByName");
(FARPROC) VWSAAsyncGetProtoByNumber=GetProcAddress(hModule,"WSAAsyncGetProtoByNumber");
(FARPROC) VWSAAsyncGetServByName=GetProcAddress(hModule,"WSAAsyncGetServByName");
(FARPROC) VWSAAsyncGetServByPort=GetProcAddress(hModule,"WSAAsyncGetServByPort");
(FARPROC) VWSAAsyncSelect=GetProcAddress(hModule,"WSAAsyncSelect");
(FARPROC) VWSACancelAsyncRequest=GetProcAddress(hModule,"WSACancelAsyncRequest");
(FARPROC) VWSACancelBlockingCall=GetProcAddress(hModule,"WSACancelBlockingCall");
(FARPROC) VWSACleanup=GetProcAddress(hModule,"WSACleanup");
(FARPROC) VWSAGetLastError=GetProcAddress(hModule,"WSAGetLastError");
(FARPROC) VWSAIsBlocking=GetProcAddress(hModule,"WSAIsBlocking");
(FARPROC) VWSARecvEx=GetProcAddress(hModule,"WSARecvEx");
(FARPROC) VWSASetBlockingHook=GetProcAddress(hModule,"WSASetBlockingHook");
(FARPROC) VWSASetLastError=GetProcAddress(hModule,"WSASetLastError");
(FARPROC) VWSAStartup=GetProcAddress(hModule,"WSAStartup");
(FARPROC) VWSAUnhookBlockingHook=GetProcAddress(hModule,"WSAUnhookBlockingHook");
(FARPROC) VWSHEnumProtocols=GetProcAddress(hModule,"WSHEnumProtocols");
(FARPROC) VWsControl=GetProcAddress(hModule,"WsControl");
(FARPROC) V__WSAFDIsSet=GetProcAddress(hModule,"__WSAFDIsSet");
(FARPROC) Vaccept=GetProcAddress(hModule,"accept");
(FARPROC) Vbind=GetProcAddress(hModule,"bind");
(FARPROC) Vclosesocket=GetProcAddress(hModule,"closesocket");
(FARPROC) Vclosesockinfo=GetProcAddress(hModule,"closesockinfo");
(FARPROC) Vconnect=GetProcAddress(hModule,"connect");
(FARPROC) Vdn_expand=GetProcAddress(hModule,"dn_expand");
(FARPROC) Vgethostbyaddr=GetProcAddress(hModule,"gethostbyaddr");
(FARPROC) Vgethostbyname=GetProcAddress(hModule,"gethostbyname");
(FARPROC) Vgethostname=GetProcAddress(hModule,"gethostname");
(FARPROC) Vgetnetbyname=GetProcAddress(hModule,"getnetbyname");
(FARPROC) Vgetpeername=GetProcAddress(hModule,"getpeername");
(FARPROC) Vgetprotobyname=GetProcAddress(hModule,"getprotobyname");
(FARPROC) Vgetprotobynumber=GetProcAddress(hModule,"getprotobynumber");
(FARPROC) Vgetservbyname=GetProcAddress(hModule,"getservbyname");
(FARPROC) Vgetservbyport=GetProcAddress(hModule,"getservbyport");
(FARPROC) Vgetsockname=GetProcAddress(hModule,"getsockname");
(FARPROC) Vgetsockopt=GetProcAddress(hModule,"getsockopt");
(FARPROC) Vhtonl=GetProcAddress(hModule,"htonl");
(FARPROC) Vhtons=GetProcAddress(hModule,"htons");
(FARPROC) Vinet_addr=GetProcAddress(hModule,"inet_addr");
(FARPROC) Vinet_network=GetProcAddress(hModule,"inet_network");
(FARPROC) Vinet_ntoa=GetProcAddress(hModule,"inet_ntoa");
(FARPROC) Vioctlsocket=GetProcAddress(hModule,"ioctlsocket");
(FARPROC) Vlisten=GetProcAddress(hModule,"listen");
(FARPROC) Vntohl=GetProcAddress(hModule,"ntohl");
(FARPROC) Vntohs=GetProcAddress(hModule,"ntohs");
(FARPROC) Vrcmd=GetProcAddress(hModule,"rcmd");
(FARPROC) Vrecv=GetProcAddress(hModule,"recv");
(FARPROC) Vrecvfrom=GetProcAddress(hModule,"recvfrom");
(FARPROC) Vrexec=GetProcAddress(hModule,"rexec");
(FARPROC) Vrresvport=GetProcAddress(hModule,"rresvport");
(FARPROC) Vs_perror=GetProcAddress(hModule,"s_perror");
(FARPROC) Vselect=GetProcAddress(hModule,"select");
(FARPROC) Vsend=GetProcAddress(hModule,"send");
(FARPROC) Vsendto=GetProcAddress(hModule,"sendto");
(FARPROC) Vsethostname=GetProcAddress(hModule,"sethostname");
(FARPROC) Vsetsockopt=GetProcAddress(hModule,"setsockopt");
(FARPROC) Vshutdown=GetProcAddress(hModule,"shutdown");
(FARPROC) Vsocket=GetProcAddress(hModule,"socket");
(FARPROC) VWEP=GetProcAddress(hModule,"WEP");
(FARPROC) VAcceptEx = GetProcAddress(hModule,"AcceptEx");
(FARPROC) VGetAcceptExSockaddrs = GetProcAddress(hModule,"GetAcceptExSockaddrs");
(FARPROC) VMigrateWinsockConfiguration = GetProcAddress(hModule,"MigrateWinsockConfiguration");
(FARPROC) VWSApSetPostRoutine = GetProcAddress(hModule,"WSApSetPostRoutine");
CREATE_MUTEX();
#ifdef DO_FILE_CONFIG
LoadConfig();
#endif
return 1;
}