2365 lines
62 KiB
C
2365 lines
62 KiB
C
/*++
|
|
|
|
Copyright (C) Microsoft Corporation, 1992 - 1999
|
|
|
|
Module Name:
|
|
|
|
Server.c
|
|
|
|
Abstract:
|
|
|
|
The server component of Remote. It spawns a child process
|
|
and redirects the stdin/stdout/stderr of child to itself.
|
|
Waits for connections from clients - passing the
|
|
output of child process to client and the input from clients
|
|
to child process.
|
|
|
|
Author:
|
|
|
|
Rajivendra Nath (rajnath) 2-Jan-1992
|
|
|
|
Environment:
|
|
|
|
Console App. User mode.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <io.h>
|
|
#include <string.h>
|
|
#include "Remote.h"
|
|
|
|
|
|
#define MAX_SESSION 10
|
|
|
|
#define COMMANDFORMAT TEXT("%c%-15s [%-15s %s]\n%c")
|
|
#define LOCALNAME TEXT("Local")
|
|
#define LOCALCLIENT(x) (strcmp((char *)(x->Name),LOCALNAME)==0)
|
|
#define RemoteInfo(prt,flg) {if (!(flg&&0x80000000)) prt;}
|
|
|
|
|
|
#define CMDSTRING(OutBuff,InpBuff,Client,szTime) { \
|
|
_stprintf \
|
|
( \
|
|
&OutBuff[0],COMMANDFORMAT,\
|
|
BEGINMARK,InpBuff, \
|
|
Client->Name,szTime, \
|
|
ENDMARK \
|
|
); \
|
|
} \
|
|
|
|
#ifdef UNICODE
|
|
int MakeCommandString(
|
|
TCHAR * pszOutput,
|
|
TCHAR * pszInput,
|
|
TCHAR * pszName,
|
|
TCHAR * pszTime);
|
|
#endif
|
|
|
|
#define BUFFSIZE 256
|
|
|
|
#ifdef INTERNALUSECOMPONENT
|
|
VOID InitAd(BOOL IsAdvertise);
|
|
VOID ShutAd(BOOL IsAdvertise);
|
|
#endif
|
|
|
|
static SOCKET listenSocket;
|
|
SESSION_TYPE ClientList[MAX_SESSION];
|
|
|
|
|
|
HANDLE ChildStdInp; //Server Writes to it
|
|
HANDLE ChildStdOut; //Server Reads from it
|
|
HANDLE ChildStdErr; //Server Reads from it
|
|
|
|
HANDLE SaveFile; //File containing all that was
|
|
//output by child process.
|
|
//Each connection opens a handle to this file
|
|
//and is sent through PipeWriteH.
|
|
|
|
TCHAR SaveFileName[MAX_PATH+1]; //Name of above file - all new sessions need
|
|
HANDLE ChldProc;
|
|
HANDLE ListenThreadH;
|
|
HANDLE SockListenThreadH;
|
|
|
|
// GetFormattedTime -- returns pointer to formatted time
|
|
//
|
|
// returns pointer to static buffer which should be OK.
|
|
//
|
|
|
|
|
|
TCHAR * GetFormattedTime(VOID)
|
|
{
|
|
static TCHAR szTime[30];
|
|
|
|
//
|
|
// Get time and format to characters
|
|
//
|
|
|
|
GetTimeFormat( LOCALE_USER_DEFAULT,
|
|
TIME_NOSECONDS | TIME_FORCE24HOURFORMAT | TIME_NOTIMEMARKER,
|
|
NULL, // use current time
|
|
NULL, // use default format
|
|
szTime,
|
|
30 );
|
|
|
|
return( (TCHAR *)&szTime );
|
|
}
|
|
|
|
|
|
HANDLE
|
|
ForkChildProcess( // Creates a new process
|
|
TCHAR *cmd, // Redirects its stdin,stdout
|
|
PHANDLE in, // and stderr - returns the
|
|
PHANDLE out, // corresponding pipe ends.
|
|
PHANDLE err
|
|
);
|
|
|
|
HANDLE
|
|
OldForkChildProcess( //Same as above except different
|
|
TCHAR *cmd, //method for redirection...for
|
|
PHANDLE in, //compatibility with.
|
|
PHANDLE out,
|
|
PHANDLE err
|
|
);
|
|
|
|
|
|
DWORD
|
|
ListenForSession( //THREAD:Listens for new connections and
|
|
TCHAR * pipe //spawns of new seesions - Updates the
|
|
); //Status in Client DataStructure.
|
|
|
|
|
|
|
|
DWORD
|
|
NewSession( //Manages the session with a client.
|
|
SESSION_TYPE* Client
|
|
);
|
|
|
|
DWORD //2 THREAD:Each reads either
|
|
GetChldOutput( //StdOut or StdErr of child and
|
|
HANDLE rhandle //writes to SaveFile.
|
|
);
|
|
|
|
|
|
|
|
DWORD
|
|
TransferFileToClient( //X THREADS:Reads the save
|
|
SESSION_TYPE* Client //file and sendsoutput to a client.
|
|
);
|
|
|
|
|
|
DWORD
|
|
GetClientInput( //X THREADS:Gets input from Child pipe
|
|
SESSION_TYPE* Client //and sends to childs StdIn.
|
|
);
|
|
|
|
BOOL
|
|
FilterCommand( //Filters input from client
|
|
SESSION_TYPE *cl, //for commands intended for REMOTE
|
|
TCHAR *buff,
|
|
int dread
|
|
);
|
|
|
|
DWORD
|
|
LocalSession(
|
|
PVOID noarg
|
|
);
|
|
|
|
DWORD
|
|
RemoteSession(
|
|
SESSION_TYPE* Client
|
|
);
|
|
|
|
BOOL
|
|
SrvCtrlHand(
|
|
DWORD event
|
|
);
|
|
|
|
VOID
|
|
SendStatus(
|
|
HANDLE hClientPipe
|
|
);
|
|
|
|
VOID
|
|
SockSendStatus(
|
|
SOCKET MySocket
|
|
);
|
|
|
|
DWORD
|
|
ShowPopup(
|
|
TCHAR *mssg
|
|
);
|
|
|
|
VOID
|
|
RemoveInpMark(
|
|
TCHAR* Buff,
|
|
DWORD Size
|
|
);
|
|
|
|
VOID
|
|
CloseClient(
|
|
SESSION_TYPE *Client
|
|
);
|
|
|
|
VOID
|
|
InitClientList(
|
|
);
|
|
|
|
/*************************************************************/
|
|
/*************************************************************/
|
|
|
|
DWORD
|
|
SockListenForSession( //THREAD:Listens for new connections and
|
|
TCHAR* pipe //spawns of new seesions - Updates the
|
|
); //Status in Client DataStructure.
|
|
|
|
DWORD
|
|
SockNewSession( //Manages the session with a client.
|
|
SESSION_TYPE* Client
|
|
);
|
|
|
|
DWORD
|
|
SockTransferFileToClient( //X THREADS:Reads the save
|
|
SESSION_TYPE* Client //file and sendsoutput to a client.
|
|
);
|
|
|
|
DWORD
|
|
SockRemoteSession(
|
|
SESSION_TYPE* Client
|
|
);
|
|
|
|
DWORD
|
|
SockGetClientInput( //X THREADS:Gets input from Child pipe
|
|
SESSION_TYPE* Client //and sends to childs StdIn.
|
|
);
|
|
|
|
BOOL
|
|
SockAuthenticate(
|
|
SOCKET MySocket
|
|
);
|
|
/*************************************************************/
|
|
/*************************************************************/
|
|
|
|
|
|
/*************************************************************/
|
|
VOID
|
|
Server( //Main routine for server.
|
|
TCHAR* ChildCmd,
|
|
TCHAR* PipeName
|
|
)
|
|
{
|
|
WORD wVersionRequested = MAKEWORD(1,1);
|
|
WSADATA wsaData;
|
|
|
|
DWORD ThreadID ;//No use
|
|
HANDLE WaitH[3];
|
|
DWORD WaitObj;
|
|
TCHAR tmpdir[MAX_PATH+1];
|
|
int nRet;
|
|
|
|
_tprintf(TEXT("**************************************\n")
|
|
TEXT("*********** WSREMOTE ************\n")
|
|
TEXT("*********** SERVER ************\n")
|
|
TEXT("**************************************\n")
|
|
TEXT("To Connect: WSRemote /C %s %s\n\n"),HostName,PipeName);
|
|
|
|
InitClientList();
|
|
|
|
//
|
|
// Initialize WinSock
|
|
//
|
|
nRet = WSAStartup(wVersionRequested, &wsaData);
|
|
if (nRet)
|
|
{
|
|
_tprintf(TEXT("Initialize WinSock Failed"));
|
|
return ;
|
|
}
|
|
// Check version
|
|
if (wsaData.wVersion != wVersionRequested)
|
|
{
|
|
_tprintf(TEXT("Wrong WinSock Version"));
|
|
return;
|
|
}
|
|
|
|
//
|
|
// set environment variable
|
|
//
|
|
|
|
SetEnvironmentVariable(TEXT("_REMOTE"), PipeName);
|
|
|
|
//
|
|
//Start the command as a child process
|
|
//
|
|
|
|
ChldProc=ForkChildProcess(ChildCmd,&ChildStdInp,&ChildStdOut,&ChildStdErr);
|
|
|
|
//
|
|
//Create a tempfile for storing Child process output.
|
|
//
|
|
{
|
|
DWORD rc = GetTempPath(sizeof(tmpdir),tmpdir);
|
|
if (!rc || rc > sizeof(tmpdir))
|
|
{
|
|
_stprintf(tmpdir,TEXT("%s"),TEXT("."));
|
|
}
|
|
if (!GetTempFileName(tmpdir,TEXT("REMOTE"),0,SaveFileName))
|
|
GetTempFileName(TEXT("."),TEXT("REMOTE"),0,SaveFileName);
|
|
}
|
|
|
|
|
|
if ((SaveFile=CreateFile(
|
|
(LPCTSTR)SaveFileName, /* address of name of the file */ \
|
|
GENERIC_READ|GENERIC_WRITE, /* access (read/write) mode */ \
|
|
FILE_SHARE_READ|FILE_SHARE_WRITE,/* share mode */ \
|
|
(LPSECURITY_ATTRIBUTES)NULL, /* security descriptor */ \
|
|
CREATE_ALWAYS, /* how to create */ \
|
|
FILE_ATTRIBUTE_NORMAL, /* File Attribute */ /* file attributes */ \
|
|
(HANDLE)NULL))==NULL)
|
|
{
|
|
TerminateProcess(ChldProc,0);
|
|
ErrorExit(TEXT("Could not Create Output File"));
|
|
}
|
|
|
|
|
|
//
|
|
//Start 2 threads to save the output from stdout and stderr of cmd to savefile.
|
|
//
|
|
|
|
if ((WaitH[0]=CreateThread(
|
|
(LPSECURITY_ATTRIBUTES)NULL, // No security attributes.
|
|
(DWORD)0, // Use same stack size.
|
|
(LPTHREAD_START_ROUTINE)GetChldOutput, // Thread procedure.
|
|
(LPVOID)ChildStdErr, // Parameter to pass.
|
|
(DWORD)0, // Run immediately.
|
|
(LPDWORD)&ThreadID))==NULL)
|
|
{
|
|
|
|
TerminateProcess(ChldProc,0);
|
|
ErrorExit(TEXT("Failed to Create GetGhldOutput#1 Thread"));
|
|
}
|
|
|
|
|
|
if ((WaitH[1]=CreateThread(
|
|
(LPSECURITY_ATTRIBUTES)NULL, // No security attributes.
|
|
(DWORD)0, // Use same stack size.
|
|
(LPTHREAD_START_ROUTINE)GetChldOutput, // Thread procedure.
|
|
(LPVOID)ChildStdOut, // Parameter to pass.
|
|
(DWORD)0, // Run immediately.
|
|
(LPDWORD)&ThreadID))==NULL)
|
|
{
|
|
|
|
TerminateProcess(ChldProc,0);
|
|
ErrorExit(TEXT("Failed to Create GetGhldOutput#2 Thread"));
|
|
}
|
|
|
|
|
|
//
|
|
//Start Thread to listen for new Connections
|
|
//
|
|
|
|
if ((ListenThreadH=CreateThread((LPSECURITY_ATTRIBUTES)NULL, // No security attributes.
|
|
(DWORD)0, // Use same stack size.
|
|
(LPTHREAD_START_ROUTINE)ListenForSession, // Thread procedure.
|
|
(LPVOID)PipeName, // Parameter to pass.
|
|
(DWORD)0, // Run immediately.
|
|
(LPDWORD)&ThreadID))==NULL)
|
|
{
|
|
|
|
TerminateProcess(ChldProc,0);
|
|
ErrorExit(TEXT("Failed To Create ListenForSession Thread"));
|
|
|
|
}
|
|
|
|
|
|
//
|
|
//Start Thread to listen for new Connections
|
|
//
|
|
|
|
if ((SockListenThreadH=CreateThread((LPSECURITY_ATTRIBUTES)NULL, // No security attributes.
|
|
(DWORD)0, // Use same stack size.
|
|
(LPTHREAD_START_ROUTINE)SockListenForSession, // Thread procedure.
|
|
(LPVOID)PipeName, // Parameter to pass.
|
|
(DWORD)0, // Run immediately.
|
|
(LPDWORD)&ThreadID))==NULL)
|
|
{
|
|
|
|
TerminateProcess(ChldProc,0);
|
|
ErrorExit(TEXT("Failed To Create SockListenForSession Thread"));
|
|
|
|
}
|
|
|
|
//
|
|
//Start Local Thread
|
|
//
|
|
|
|
if ((ClientList[0].hThread=CreateThread((LPSECURITY_ATTRIBUTES)NULL, // No security attributes.
|
|
(DWORD)0, // Use same stack size.
|
|
(LPTHREAD_START_ROUTINE)LocalSession, // Thread procedure.
|
|
(LPVOID)NULL, // Parameter to pass.
|
|
(DWORD)0, // Run immediately.
|
|
(LPDWORD)&ThreadID))==NULL)
|
|
{
|
|
|
|
TerminateProcess(ChldProc,0);
|
|
ErrorExit(TEXT("Failed To Create ListenForSession Thread"));
|
|
|
|
}
|
|
|
|
SetConsoleCtrlHandler((PHANDLER_ROUTINE)SrvCtrlHand,TRUE);
|
|
|
|
#ifdef INTERNALUSECOMPONENT
|
|
InitAd(IsAdvertise);
|
|
#endif
|
|
|
|
WaitH[2]=ChldProc;
|
|
WaitObj=WaitForMultipleObjects(3,WaitH,FALSE,INFINITE);
|
|
switch (WaitObj-WAIT_OBJECT_0)
|
|
{
|
|
case 0: // Error Writing to savefile
|
|
case 1:
|
|
TerminateProcess(ChldProc,0);
|
|
break;
|
|
case 2: // Child Proc Terminated
|
|
break;
|
|
|
|
default: // Out of Some Resource
|
|
_tprintf(TEXT("Out of Resource Error %d..Terminating\n"),GetLastError());
|
|
break;
|
|
|
|
}
|
|
|
|
TerminateThread(ListenThreadH,0);
|
|
// SOCK:
|
|
TerminateThread(SockListenThreadH,0);
|
|
|
|
#ifdef INTERNALUSECOMPONENT
|
|
ShutAd(IsAdvertise);
|
|
#endif
|
|
|
|
|
|
CloseHandle(ChildStdInp);
|
|
CloseHandle(ChildStdOut);
|
|
CloseHandle(ChildStdErr);
|
|
|
|
//WSACleanup
|
|
WSACleanup();
|
|
_tprintf(TEXT("\nCalling WSACleanup()..\n"));
|
|
|
|
_tprintf(TEXT("\nRemote:Parent exiting. Child(%s) dead..\n"),ChildCmd);
|
|
|
|
CloseHandle(SaveFile);
|
|
|
|
{
|
|
int i;
|
|
for (i=0;i<MAX_SESSION;i++)
|
|
CloseClient(&ClientList[i]);
|
|
}
|
|
|
|
if (!DeleteFile(SaveFileName))
|
|
_tprintf(TEXT("Temp File %s not deleted..\n"),SaveFileName);
|
|
|
|
return;
|
|
}
|
|
/*************************************************************/
|
|
HANDLE
|
|
ForkChildProcess( // Creates a new process
|
|
TCHAR *cmd, // Redirects its stdin,stdout
|
|
PHANDLE inH, // and stderr - returns the
|
|
PHANDLE outH, // corresponding pipe ends.
|
|
PHANDLE errH
|
|
)
|
|
|
|
{
|
|
SECURITY_ATTRIBUTES lsa;
|
|
STARTUPINFO si;
|
|
PROCESS_INFORMATION pi;
|
|
|
|
HANDLE ChildIn;
|
|
HANDLE ChildOut;
|
|
HANDLE ChildErr;
|
|
|
|
lsa.nLength=sizeof(SECURITY_ATTRIBUTES);
|
|
lsa.lpSecurityDescriptor=NULL;
|
|
lsa.bInheritHandle=TRUE;
|
|
|
|
//
|
|
//Create Parent_Write to ChildStdIn Pipe
|
|
//
|
|
|
|
if (!CreatePipe(&ChildIn,inH,&lsa,0))
|
|
ErrorExit(TEXT("Could Not Create Parent-->Child Pipe"));
|
|
|
|
//
|
|
//Create ChildStdOut to Parent_Read pipe
|
|
//
|
|
|
|
if (!CreatePipe(outH,&ChildOut,&lsa,0))
|
|
ErrorExit(TEXT("Could Not Create Child-->Parent Pipe"));
|
|
|
|
//
|
|
//Create ChildStdOut to Parent_Read pipe
|
|
//
|
|
|
|
if (!CreatePipe(errH,&ChildErr,&lsa,0))
|
|
ErrorExit(TEXT("Could Not Create Child-->Parent Pipe"));
|
|
|
|
//
|
|
// Lets Redirect Console StdHandles - easy enough
|
|
//
|
|
|
|
|
|
si.cb=sizeof(STARTUPINFO);
|
|
si.lpReserved=NULL;
|
|
si.lpTitle=NULL;
|
|
si.lpDesktop=NULL;
|
|
si.dwX=si.dwY=si.dwYSize=si.dwXSize=0;
|
|
si.dwFlags=STARTF_USESTDHANDLES;
|
|
si.hStdInput =ChildIn;
|
|
si.hStdOutput=ChildOut;
|
|
si.hStdError =ChildErr;
|
|
si.wShowWindow=SW_SHOW;
|
|
si.lpReserved2=NULL;
|
|
si.cbReserved2=0;
|
|
|
|
//
|
|
//Create Child Process
|
|
//
|
|
|
|
if (!CreateProcess( NULL,
|
|
cmd,
|
|
NULL,
|
|
NULL,
|
|
TRUE,
|
|
NORMAL_PRIORITY_CLASS,
|
|
NULL,
|
|
NULL,
|
|
&si,
|
|
&pi))
|
|
{
|
|
if (GetLastError()==2)
|
|
_tprintf(TEXT("Executable %s not found\n"),cmd);
|
|
ErrorExit(TEXT("Could Not Create Child Process"));
|
|
}
|
|
|
|
//
|
|
//Close unneccesary Handles and Restore the crt handles
|
|
//
|
|
|
|
CloseHandle(ChildIn);
|
|
CloseHandle(ChildOut);
|
|
CloseHandle(ChildErr);
|
|
|
|
return(pi.hProcess);
|
|
}
|
|
/*************************************************************/
|
|
HANDLE
|
|
OldForkChildProcess(
|
|
TCHAR *cmd,
|
|
PHANDLE inH,
|
|
PHANDLE outH,
|
|
PHANDLE errH
|
|
)
|
|
{
|
|
SECURITY_ATTRIBUTES lsa;
|
|
STARTUPINFO si;
|
|
PROCESS_INFORMATION pi;
|
|
|
|
HANDLE OldStdIn =GetStdHandle(STD_INPUT_HANDLE);
|
|
HANDLE OldStdOut=GetStdHandle(STD_OUTPUT_HANDLE);
|
|
HANDLE OldStdErr=GetStdHandle(STD_ERROR_HANDLE);
|
|
|
|
HANDLE ChildStdIn;
|
|
HANDLE ChildStdOut;
|
|
HANDLE ChildStdErr;
|
|
|
|
lsa.nLength=sizeof(SECURITY_ATTRIBUTES);
|
|
lsa.lpSecurityDescriptor=NULL;
|
|
lsa.bInheritHandle=TRUE;
|
|
|
|
//Create Parent_Write to ChildStdIn Pipe
|
|
if (!CreatePipe(&ChildStdIn,inH,&lsa,0))
|
|
ErrorExit(TEXT("Could Not Create Parent-->Child Pipe"));
|
|
|
|
//Create ChildStdOut to Parent_Read pipe
|
|
if (!CreatePipe(outH,&ChildStdOut,&lsa,0))
|
|
ErrorExit(TEXT("Could Not Create Child-->Parent Pipe"));
|
|
|
|
//Create ChildStdOut to Parent_Read pipe
|
|
if (!CreatePipe(errH,&ChildStdErr,&lsa,0))
|
|
ErrorExit(TEXT("Could Not Create Child-->Parent Pipe"));
|
|
|
|
//Make ChildStdIn and Out as standard handles and get it inherited by child
|
|
if (!SetStdHandle(STD_INPUT_HANDLE,ChildStdIn))
|
|
ErrorExit(TEXT("Could not change StdIn"));
|
|
|
|
if (!SetStdHandle(STD_OUTPUT_HANDLE,ChildStdOut))
|
|
ErrorExit(TEXT("Could Not change StdOut"));
|
|
|
|
if (!SetStdHandle(STD_ERROR_HANDLE,ChildStdErr))
|
|
ErrorExit(TEXT("Could Not change StdErr"));
|
|
|
|
si.cb=sizeof(STARTUPINFO);
|
|
si.lpReserved=NULL;
|
|
si.lpTitle=NULL;
|
|
si.lpDesktop=NULL;
|
|
si.dwX=si.dwY=si.dwYSize=si.dwXSize=si.dwFlags=0L;
|
|
si.wShowWindow=SW_SHOW;
|
|
si.lpReserved2=NULL;
|
|
si.cbReserved2=0;
|
|
|
|
//Create Child Process
|
|
if (!CreateProcess( NULL,
|
|
cmd,
|
|
NULL,
|
|
NULL,
|
|
TRUE,
|
|
NORMAL_PRIORITY_CLASS,
|
|
NULL,
|
|
NULL,
|
|
&si,
|
|
&pi))
|
|
ErrorExit(TEXT("Could Not Create Child Process"));
|
|
|
|
//reset StdIn StdOut
|
|
if (!SetStdHandle(STD_INPUT_HANDLE,OldStdIn))
|
|
{
|
|
TerminateProcess(pi.hProcess,1);
|
|
ErrorExit(TEXT("Could not RESET StdIn"));
|
|
}
|
|
if (!SetStdHandle(STD_OUTPUT_HANDLE,OldStdOut))
|
|
{
|
|
TerminateProcess(pi.hProcess,1);
|
|
ErrorExit(TEXT("Could not RESET StdIn"));
|
|
}
|
|
|
|
if (!SetStdHandle(STD_ERROR_HANDLE,OldStdErr))
|
|
{
|
|
TerminateProcess(pi.hProcess,1);
|
|
ErrorExit(TEXT("Could not RESET StdIn"));
|
|
}
|
|
|
|
//Close unneccesary Handles
|
|
CloseHandle(ChildStdIn);
|
|
CloseHandle(ChildStdOut);
|
|
CloseHandle(ChildStdErr);
|
|
return(pi.hProcess);
|
|
}
|
|
/*************************************************************/
|
|
|
|
#if _MSC_FULL_VER >= 13008827
|
|
#pragma warning(push)
|
|
#pragma warning(disable:4715) // Not all control paths return (due to infinite loop)
|
|
#endif
|
|
/*************************************************************/
|
|
DWORD
|
|
ListenForSession(
|
|
TCHAR* pipename
|
|
)
|
|
{
|
|
int i;
|
|
DWORD ThreadID;
|
|
HANDLE PipeH[2];
|
|
SECURITY_DESCRIPTOR SecurityDescriptor;
|
|
SECURITY_ATTRIBUTES lsa;
|
|
|
|
TCHAR fullnameIn[BUFFSIZE];
|
|
TCHAR fullnameOut[BUFFSIZE];
|
|
|
|
|
|
_stprintf(fullnameIn,SERVER_READ_PIPE ,TEXT("."),pipename);
|
|
_stprintf(fullnameOut,SERVER_WRITE_PIPE,TEXT("."),pipename);
|
|
//
|
|
// Initialize the security descriptor that we're going to
|
|
// use - everyone has access (use remote.exe if you want /u support)
|
|
//
|
|
|
|
InitializeSecurityDescriptor
|
|
(
|
|
&SecurityDescriptor,
|
|
SECURITY_DESCRIPTOR_REVISION
|
|
);
|
|
|
|
(VOID) SetSecurityDescriptorDacl
|
|
(
|
|
&SecurityDescriptor,
|
|
TRUE,
|
|
NULL,
|
|
FALSE
|
|
);
|
|
|
|
lsa.nLength=sizeof(SECURITY_ATTRIBUTES);
|
|
lsa.lpSecurityDescriptor=&SecurityDescriptor;
|
|
lsa.bInheritHandle=TRUE;
|
|
|
|
while(TRUE)
|
|
{
|
|
PipeH[0]=CreateNamedPipe
|
|
(
|
|
fullnameIn ,
|
|
PIPE_ACCESS_INBOUND ,
|
|
PIPE_TYPE_BYTE,
|
|
PIPE_UNLIMITED_INSTANCES,
|
|
0,0,0,&lsa
|
|
);
|
|
|
|
PipeH[1]=CreateNamedPipe
|
|
(
|
|
fullnameOut,
|
|
PIPE_ACCESS_OUTBOUND,
|
|
PIPE_TYPE_BYTE,
|
|
PIPE_UNLIMITED_INSTANCES,
|
|
0,0,0,&lsa
|
|
);
|
|
|
|
if (!ConnectNamedPipe(PipeH[0],NULL))
|
|
{
|
|
if (GetLastError()!=ERROR_PIPE_CONNECTED)
|
|
{
|
|
CloseHandle(PipeH[0]);
|
|
CloseHandle(PipeH[1]);
|
|
continue;
|
|
}
|
|
|
|
}
|
|
|
|
if (!ConnectNamedPipe(PipeH[1],NULL))
|
|
{
|
|
if (GetLastError()!=ERROR_PIPE_CONNECTED)
|
|
{
|
|
CloseHandle(PipeH[0]);
|
|
CloseHandle(PipeH[1]);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
//Look For a Free Slot & if not- then terminate connection
|
|
//
|
|
|
|
for (i=1;i<MAX_SESSION;i++)
|
|
{
|
|
//
|
|
// Locate a Free Client block
|
|
//
|
|
if (!ClientList[i].Active)
|
|
break;
|
|
}
|
|
|
|
if (i<MAX_SESSION)
|
|
{
|
|
//
|
|
// Initialize the Client
|
|
//
|
|
ClientList[i].PipeReadH=PipeH[0];
|
|
ClientList[i].PipeWriteH=PipeH[1];
|
|
ClientList[i].Active=TRUE;
|
|
ClientList[i].SendOutput=TRUE;
|
|
ClientList[i].CommandRcvd=FALSE;
|
|
|
|
}
|
|
else
|
|
{
|
|
_tprintf(TEXT("Remote:Closing New Session - No more slots\n"));
|
|
CloseHandle(PipeH[0]);
|
|
CloseHandle(PipeH[1]);
|
|
continue;
|
|
}
|
|
|
|
//
|
|
//start new thread for this connection
|
|
//
|
|
|
|
if((ClientList[i].hThread=CreateThread (
|
|
(LPSECURITY_ATTRIBUTES)NULL, // No security attributes.
|
|
(DWORD)0, // Use same stack size.
|
|
(LPTHREAD_START_ROUTINE)RemoteSession, // Thread procedure.
|
|
(LPVOID)&ClientList[i], // Parameter to pass.
|
|
(DWORD)0, // Run immediately.
|
|
(LPDWORD)&ThreadID))==NULL)
|
|
{
|
|
CloseClient(&ClientList[i]);
|
|
continue;
|
|
}
|
|
}
|
|
return(0);
|
|
}
|
|
#if _MSC_FULL_VER >= 13008827
|
|
#pragma warning(pop)
|
|
#endif
|
|
|
|
/*************************************************************/
|
|
DWORD
|
|
RemoteSession(
|
|
SESSION_TYPE *MyClient
|
|
)
|
|
{
|
|
DWORD ReadCnt;
|
|
SESSION_STARTUPINFO ssi;
|
|
TCHAR *headerbuff;
|
|
TCHAR msg[BUFFSIZE];
|
|
DWORD tmp;
|
|
SESSION_STARTREPLY ssr;
|
|
|
|
memset((TCHAR *)&ssi,0,sizeof(ssi));
|
|
|
|
if ((MyClient->rSaveFile=CreateFile(
|
|
SaveFileName,
|
|
GENERIC_READ|GENERIC_WRITE,
|
|
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
|
NULL,OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,NULL))==NULL)
|
|
|
|
{
|
|
CloseClient(MyClient);
|
|
return(1);
|
|
}
|
|
|
|
|
|
|
|
{
|
|
DWORD reply=0;
|
|
|
|
ReadFixBytes(MyClient->PipeReadH,(TCHAR *)MyClient->Name,HOSTNAMELEN-1,0);
|
|
|
|
//
|
|
//Last four Bytes contains a code
|
|
//
|
|
|
|
memcpy((TCHAR *)&reply,(TCHAR *)&(MyClient->Name[11]),4);
|
|
|
|
if (reply!=MAGICNUMBER)
|
|
{
|
|
//
|
|
// Unknown client
|
|
//
|
|
CloseClient(MyClient);
|
|
return(1);
|
|
}
|
|
|
|
ssr.MagicNumber=MAGICNUMBER;
|
|
ssr.Size=sizeof(ssr);
|
|
ssr.FileSize=GetFileSize( MyClient->rSaveFile, &tmp );
|
|
|
|
WriteFile(MyClient->PipeWriteH,(TCHAR *)&ssr,sizeof(ssr),&tmp,NULL);
|
|
}
|
|
|
|
if (ReadFixBytes(MyClient->PipeReadH,(TCHAR *)&(ssi.Size),sizeof(ssi.Size),0)!=0)
|
|
{
|
|
CloseClient(MyClient);
|
|
return(1);
|
|
}
|
|
|
|
if (ssi.Size>1024) //Sanity Check
|
|
{
|
|
_stprintf(msg,TEXT("%s"),"Server:Unknown Header..Terminating session\n");
|
|
WriteFile(MyClient->PipeWriteH,msg,_tcslen(msg),&tmp,NULL);
|
|
CloseClient(MyClient);
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
if ((headerbuff=(TCHAR *)calloc(ssi.Size,1))==NULL)
|
|
{
|
|
_stprintf(msg,TEXT("%s"),"Server:Not Enough Memory..Terminating session\n");
|
|
WriteFile(MyClient->PipeWriteH,msg,_tcslen(msg),&tmp,NULL);
|
|
CloseClient(MyClient);
|
|
return(1);
|
|
|
|
}
|
|
|
|
ReadCnt=ssi.Size-sizeof(ssi.Size);
|
|
if (ReadFixBytes(MyClient->PipeReadH,(TCHAR *)headerbuff,ReadCnt,0)!=0)
|
|
{
|
|
CloseClient(MyClient);
|
|
return(1);
|
|
}
|
|
|
|
memcpy((TCHAR *)&ssi+sizeof(ssi.Size),headerbuff,sizeof(ssi)-sizeof(ssi.Size));
|
|
free(headerbuff);
|
|
|
|
/* Version */
|
|
if (ssi.Version!=VERSION)
|
|
{
|
|
_stprintf(msg,TEXT("WSRemote Warning:Server Version=%d Client Version=%d\n"),VERSION,ssi.Version);
|
|
WriteFile(MyClient->PipeWriteH,msg,_tcslen(msg),&tmp,NULL);
|
|
|
|
}
|
|
|
|
/* Name */
|
|
{
|
|
memcpy(MyClient->Name,ssi.ClientName,15);
|
|
MyClient->Name[14]=0;
|
|
|
|
}
|
|
|
|
/* Lines */
|
|
if (ssi.LinesToSend!=-1)
|
|
{
|
|
long PosFromEnd=ssi.LinesToSend*CHARS_PER_LINE;
|
|
DWORD BytesToSend=MINIMUM((DWORD)PosFromEnd,ssr.FileSize);
|
|
DWORD BytesRead;
|
|
TCHAR *buff=(TCHAR *)calloc(BytesToSend+1,1);
|
|
|
|
if (ssr.FileSize > (DWORD)PosFromEnd)
|
|
{
|
|
SetFilePointer( MyClient->rSaveFile,
|
|
-PosFromEnd,
|
|
(PLONG)NULL,
|
|
FILE_END
|
|
);
|
|
|
|
}
|
|
|
|
if (buff!=NULL)
|
|
{
|
|
if (!ReadFile(MyClient->rSaveFile,buff,BytesToSend,&BytesRead,NULL))
|
|
{
|
|
CloseClient(MyClient);
|
|
return(1);
|
|
}
|
|
|
|
RemoveInpMark(buff,BytesRead);
|
|
if (!WriteFile(MyClient->PipeWriteH,buff,BytesRead,&tmp,NULL))
|
|
{
|
|
CloseClient(MyClient);
|
|
return(1);
|
|
}
|
|
}
|
|
free(buff);
|
|
|
|
}
|
|
|
|
RemoteInfo(_tprintf(TEXT("\n**WSRemote:Connected To %s [%s]\n"),MyClient->Name,GetFormattedTime()),ssi.Flag);
|
|
NewSession(MyClient);
|
|
RemoteInfo(_tprintf(TEXT("\n**WSRemote:Disconnected From %s [%s]\n"),MyClient->Name,GetFormattedTime()),ssi.Flag);
|
|
CloseClient(MyClient);
|
|
return(0);
|
|
}
|
|
/*************************************************************/
|
|
DWORD
|
|
NewSession(
|
|
SESSION_TYPE* MyClient
|
|
)
|
|
{
|
|
DWORD ThreadId;
|
|
HANDLE rwThread[3];
|
|
|
|
MyClient->MoreData=CreateEvent
|
|
(
|
|
(LPSECURITY_ATTRIBUTES) NULL,/* address of security attributes */
|
|
FALSE, /* flag for manual-reset event */
|
|
TRUE, /* flag for initial state */
|
|
NULL /* address of event-object name */
|
|
);
|
|
|
|
|
|
|
|
if ((rwThread[0]=CreateThread (
|
|
(LPSECURITY_ATTRIBUTES)NULL, // No security attributes.
|
|
(DWORD)0, // Use same stack size.
|
|
(LPTHREAD_START_ROUTINE)GetClientInput, // Thread procedure.
|
|
(LPVOID)MyClient, // Parameter to pass.
|
|
(DWORD)0, // Run immediately.
|
|
(LPDWORD)&ThreadId))==NULL)
|
|
{
|
|
return(GetLastError());
|
|
}
|
|
|
|
|
|
if ((rwThread[1]=CreateThread (
|
|
(LPSECURITY_ATTRIBUTES)NULL, // No security attributes.
|
|
(DWORD)0, // Use same stack size.
|
|
(LPTHREAD_START_ROUTINE)TransferFileToClient, // Thread procedure.
|
|
(LPVOID)MyClient, // Parameter to pass.
|
|
(DWORD)0, // Run immediately.
|
|
(LPDWORD)&ThreadId))==NULL)
|
|
{
|
|
CloseHandle(rwThread[0]);
|
|
return(GetLastError());
|
|
}
|
|
|
|
rwThread[2]=ChldProc;
|
|
WaitForMultipleObjects(3, rwThread,FALSE, INFINITE);
|
|
|
|
TerminateThread(rwThread[0],1);
|
|
TerminateThread(rwThread[1],1);
|
|
|
|
CloseHandle(rwThread[0]);
|
|
CloseHandle(rwThread[1]);
|
|
|
|
return(0);
|
|
}
|
|
/*************************************************************/
|
|
DWORD
|
|
GetChldOutput(
|
|
HANDLE readH
|
|
)
|
|
{
|
|
TCHAR buff[BUFFSIZE];
|
|
DWORD dread;
|
|
DWORD tmp;
|
|
|
|
|
|
while(ReadFile(readH,buff,BUFFSIZE-1,&dread,NULL))
|
|
{
|
|
buff[dread]='\0';
|
|
|
|
if (!WriteFile(SaveFile,buff,dread,&tmp,NULL))
|
|
{
|
|
return(1);
|
|
}
|
|
|
|
//
|
|
// Signal Reader Thread that more data
|
|
//
|
|
{
|
|
int i;
|
|
DWORD err; //REMOVE
|
|
for (i=0;i<MAX_SESSION;i++)
|
|
{
|
|
if (ClientList[i].Active)
|
|
{
|
|
if (!SetEvent(ClientList[i].MoreData))
|
|
err=GetLastError(); //REMOVE
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return(1);
|
|
}
|
|
/*************************************************************/
|
|
DWORD
|
|
TransferFileToClient(
|
|
SESSION_TYPE *MyClient
|
|
)
|
|
{
|
|
|
|
TCHAR buffin[BUFFSIZE],buffout[BUFFSIZE],cmdbuff[BUFFSIZE];
|
|
DWORD tmp;
|
|
DWORD dread=0,dwrite=0;
|
|
BOOL incmd=FALSE;
|
|
DWORD cmdP=0;
|
|
DWORD i;
|
|
TCHAR MyEchoStr[30];
|
|
|
|
_stprintf(MyEchoStr,TEXT("[%-15s"),MyClient->Name);
|
|
|
|
while(ReadFile(MyClient->rSaveFile,buffin,BUFFSIZE-1,&dread,NULL))
|
|
{
|
|
if (dread==0)
|
|
{
|
|
WaitForSingleObject(MyClient->MoreData,INFINITE);
|
|
continue;
|
|
}
|
|
dwrite=0;
|
|
for(i=0;i<dread;i++)
|
|
{
|
|
if (incmd)
|
|
{
|
|
if ((buffin[i]==ENDMARK)||(cmdP==BUFFSIZE-1))
|
|
{
|
|
incmd=FALSE;
|
|
cmdbuff[cmdP]=0;
|
|
if ((_tcsstr(cmdbuff,MyEchoStr)==NULL)||
|
|
(!MyClient->CommandRcvd))
|
|
{
|
|
if (!WriteFile(
|
|
MyClient->PipeWriteH,
|
|
cmdbuff,cmdP,&tmp,NULL))
|
|
{
|
|
return(1);
|
|
}
|
|
}
|
|
cmdP=0;
|
|
}
|
|
else
|
|
{
|
|
cmdbuff[cmdP++]=buffin[i];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
if (buffin[i]==BEGINMARK)
|
|
{
|
|
if (dwrite!=0)
|
|
{
|
|
if (!WriteFile(
|
|
MyClient->PipeWriteH,
|
|
buffout,dwrite,&tmp,NULL))
|
|
{
|
|
return(1);
|
|
}
|
|
dwrite=0;
|
|
}
|
|
incmd=TRUE;
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
buffout[dwrite++]=buffin[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (dwrite!=0)
|
|
{
|
|
if (!WriteFile(
|
|
MyClient->PipeWriteH,
|
|
buffout,dwrite,&tmp,NULL))
|
|
{
|
|
return(0);
|
|
}
|
|
}
|
|
}
|
|
return(1);
|
|
}
|
|
|
|
/*************************************************************/
|
|
DWORD
|
|
GetClientInput(
|
|
SESSION_TYPE *MyClient
|
|
)
|
|
{
|
|
TCHAR buff[BUFFSIZE];
|
|
DWORD tmp,dread;
|
|
|
|
#ifdef UNICODE
|
|
while(ReadFileW(MyClient->PipeReadH,buff,BUFFSIZE,&dread,NULL))
|
|
#else
|
|
while(ReadFile(MyClient->PipeReadH,buff,BUFFSIZE,&dread,NULL))
|
|
#endif
|
|
{
|
|
buff[dread]=0;
|
|
MyClient->CommandRcvd=TRUE;
|
|
|
|
if (FilterCommand(MyClient,buff,dread))
|
|
continue;
|
|
|
|
|
|
if (!WriteFile(ChildStdInp,buff,dread,&tmp,NULL))
|
|
{
|
|
ExitThread(0);
|
|
}
|
|
}
|
|
return(1);
|
|
}
|
|
/*************************************************************/
|
|
|
|
BOOL
|
|
FilterCommand(
|
|
SESSION_TYPE *cl,
|
|
TCHAR *buff,
|
|
int dread
|
|
)
|
|
{
|
|
TCHAR inp_buff[4096];
|
|
TCHAR tmpchar;
|
|
TCHAR ch[3];
|
|
DWORD tmp;
|
|
int len;
|
|
DWORD ThreadID; //Useless
|
|
|
|
if (dread==0)
|
|
return(FALSE);
|
|
|
|
buff[dread]=0;
|
|
|
|
|
|
if (buff[0]==COMMANDCHAR)
|
|
{
|
|
switch(buff[1])
|
|
{
|
|
case 'l':
|
|
case 'L':
|
|
if (bIPLocked == FALSE)
|
|
{
|
|
bIPLocked=TRUE;
|
|
_tprintf(TEXT("**LOCK: No IP Sessions Allowed\n"));
|
|
}
|
|
else
|
|
{
|
|
bIPLocked=FALSE;
|
|
_tprintf(TEXT("**LOCK: IP Sessions Now Allowed\n"));
|
|
}
|
|
break;
|
|
case 'o':
|
|
case 'O': cl->SendOutput=!cl->SendOutput;
|
|
break;
|
|
case 'k':
|
|
case 'K':TerminateProcess(ChldProc,1);
|
|
break;
|
|
case 's':
|
|
case 'S':
|
|
SendStatus(cl->PipeWriteH);
|
|
break;
|
|
|
|
case 'p':
|
|
case 'P':
|
|
{
|
|
TCHAR *mssg=(TCHAR *)calloc(4096,1); //Free it in called Proc
|
|
TCHAR *ack=TEXT("WSRemote:Popup Shown..\n");
|
|
|
|
if (mssg==NULL)
|
|
break;
|
|
|
|
_stprintf(mssg,TEXT("From %s [%s]\n\n%s\n"),cl->Name,GetFormattedTime(),&buff[2]);
|
|
CreateThread(
|
|
(LPSECURITY_ATTRIBUTES)NULL, // No security attributes.
|
|
(DWORD)0, // Use same stack size.
|
|
(LPTHREAD_START_ROUTINE)ShowPopup, // Thread procedure.
|
|
(LPVOID)mssg, // Parameter to pass.
|
|
(DWORD)0, // Run immediately.
|
|
(LPDWORD)&ThreadID
|
|
);
|
|
#ifdef UNICODE
|
|
WriteFileW(cl->PipeWriteH,ack,_tcslen(ack),&tmp,NULL);
|
|
#else
|
|
WriteFile(cl->PipeWriteH,ack,_tcslen(ack),&tmp,NULL);
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
case 'm':
|
|
case 'M':
|
|
buff[dread-2]=0;
|
|
#ifdef UNICODE
|
|
MakeCommandString( inp_buff, buff, cl->Name, GetFormattedTime());
|
|
#else
|
|
CMDSTRING(inp_buff,buff,cl,GetFormattedTime());
|
|
#endif
|
|
len=_tcslen(inp_buff);
|
|
#ifdef UNICODE
|
|
WriteFileW(SaveFile,inp_buff,len,&tmp,NULL);
|
|
#else
|
|
WriteFile(SaveFile,inp_buff,len,&tmp,NULL);
|
|
#endif
|
|
break;
|
|
|
|
case '@':
|
|
buff[dread-2]=0;
|
|
#ifdef UNICODE
|
|
MakeCommandString( inp_buff, buff, cl->Name, GetFormattedTime());
|
|
#else
|
|
CMDSTRING(inp_buff,&buff[1],cl,GetFormattedTime());
|
|
#endif
|
|
len=_tcslen(inp_buff);
|
|
#ifdef UNICODE
|
|
WriteFileW(SaveFile,inp_buff,len,&tmp,NULL);
|
|
#else
|
|
WriteFile(SaveFile,inp_buff,len,&tmp,NULL);
|
|
#endif
|
|
//
|
|
// Remove the first @ sign
|
|
//
|
|
MoveMemory(buff,&buff[1],dread-1);
|
|
buff[dread-1]=' ';
|
|
return(FALSE); //Send it it to the chile process
|
|
break;
|
|
|
|
|
|
default :
|
|
_stprintf(inp_buff,TEXT("%s"),"** Unknown Command **\n");
|
|
#ifdef UNICODE
|
|
WriteFileW( cl->PipeWriteH,inp_buff,_tcslen(inp_buff),&tmp,NULL);
|
|
#else
|
|
WriteFile( cl->PipeWriteH,inp_buff,_tcslen(inp_buff),&tmp,NULL);
|
|
#endif
|
|
case 'h':
|
|
case 'H':
|
|
{
|
|
#ifdef UNICODE
|
|
_stprintf(inp_buff,TEXT("%cM: To Send Message\n"),COMMANDCHAR);
|
|
WriteFileW(cl->PipeWriteH,inp_buff,_tcslen(inp_buff),&tmp,NULL);
|
|
_stprintf(inp_buff,TEXT("%cP: To Generate popup\n"),COMMANDCHAR);
|
|
WriteFileW(cl->PipeWriteH,inp_buff,_tcslen(inp_buff),&tmp,NULL);
|
|
_stprintf(inp_buff,TEXT("%cK: To kill the server\n"),COMMANDCHAR);
|
|
WriteFileW(cl->PipeWriteH,inp_buff,_tcslen(inp_buff),&tmp,NULL);
|
|
_stprintf(inp_buff,TEXT("%cH: This Help\n"),COMMANDCHAR);
|
|
WriteFileW(cl->PipeWriteH,inp_buff,_tcslen(inp_buff),&tmp,NULL);
|
|
#else
|
|
_stprintf(inp_buff,TEXT("%cM: To Send Message\n"),COMMANDCHAR);
|
|
WriteFile(cl->PipeWriteH,inp_buff,_tcslen(inp_buff),&tmp,NULL);
|
|
_stprintf(inp_buff,TEXT("%cP: To Generate popup\n"),COMMANDCHAR);
|
|
WriteFile(cl->PipeWriteH,inp_buff,_tcslen(inp_buff),&tmp,NULL);
|
|
_stprintf(inp_buff,TEXT("%cK: To kill the server\n"),COMMANDCHAR);
|
|
WriteFile(cl->PipeWriteH,inp_buff,_tcslen(inp_buff),&tmp,NULL);
|
|
_stprintf(inp_buff,TEXT("%cH: This Help\n"),COMMANDCHAR);
|
|
WriteFile(cl->PipeWriteH,inp_buff,_tcslen(inp_buff),&tmp,NULL);
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
if ((buff[0]<26))
|
|
{
|
|
BOOL ret=FALSE;
|
|
#ifdef UNICODE
|
|
TCHAR * pszTime;
|
|
#endif
|
|
|
|
_stprintf(ch,TEXT("^%c"),buff[0]+64);
|
|
#ifdef UNICODE
|
|
pszTime = GetFormattedTime();
|
|
MakeCommandString( inp_buff, ch, cl->Name, pszTime);
|
|
#else
|
|
CMDSTRING(inp_buff,ch,cl,GetFormattedTime());
|
|
#endif
|
|
len=_tcslen(inp_buff);
|
|
|
|
if (buff[0]==CTRLC)
|
|
{
|
|
cl->CommandRcvd=FALSE;
|
|
GenerateConsoleCtrlEvent(CTRL_C_EVENT,0);
|
|
ret=TRUE; //Already sent to child
|
|
}
|
|
|
|
WriteFile(SaveFile,inp_buff,len,&tmp,NULL);
|
|
return(ret); //FALSE:send it to child StdIn
|
|
}
|
|
|
|
|
|
tmpchar=buff[dread-2]; //must be 13;but just incase
|
|
buff[dread-2]=0;
|
|
#ifdef UNICODE
|
|
MakeCommandString( inp_buff, buff, cl->Name, GetFormattedTime());
|
|
#else
|
|
CMDSTRING(inp_buff,buff,cl,GetFormattedTime());
|
|
#endif
|
|
buff[dread-2]=tmpchar;
|
|
len=_tcslen(inp_buff);
|
|
WriteFile(SaveFile,inp_buff,len,&tmp,NULL);
|
|
return(FALSE);
|
|
}
|
|
/*************************************************************/
|
|
|
|
BOOL
|
|
SockFilterCommand(
|
|
SESSION_TYPE *cl,
|
|
TCHAR *buff,
|
|
int dread
|
|
)
|
|
{
|
|
TCHAR inp_buff[4096];
|
|
TCHAR tmpchar;
|
|
TCHAR ch[3];
|
|
DWORD tmp;
|
|
int len;
|
|
DWORD ThreadID; //Useless
|
|
|
|
if (dread==0)
|
|
return(FALSE);
|
|
|
|
buff[dread]=0;
|
|
|
|
if (buff[0]==COMMANDCHAR)
|
|
{
|
|
switch(buff[1])
|
|
{
|
|
case 'o':
|
|
case 'O': cl->SendOutput=!cl->SendOutput;
|
|
break;
|
|
case 'k':
|
|
case 'K':TerminateProcess(ChldProc,1);
|
|
break;
|
|
case 's':
|
|
case 'S':
|
|
SockSendStatus(cl->Socket);
|
|
break;
|
|
|
|
case 'p':
|
|
case 'P':
|
|
{
|
|
TCHAR *mssg=(TCHAR *)calloc(4096,1); //Free it in called Proc
|
|
TCHAR *ack=TEXT("WSRemote:Popup Shown..\n");
|
|
|
|
if (mssg==NULL)
|
|
break;
|
|
|
|
_stprintf(mssg,TEXT("From %s [%s]\n\n%s\n"),cl->Name,GetFormattedTime(),&buff[2]);
|
|
CreateThread(
|
|
(LPSECURITY_ATTRIBUTES)NULL, // No security attributes.
|
|
(DWORD)0, // Use same stack size.
|
|
(LPTHREAD_START_ROUTINE)ShowPopup, // Thread procedure.
|
|
(LPVOID)mssg, // Parameter to pass.
|
|
(DWORD)0, // Run immediately.
|
|
(LPDWORD)&ThreadID
|
|
);
|
|
WriteSocket(cl->Socket,ack,_tcslen(ack),&tmp);
|
|
break;
|
|
}
|
|
|
|
case 'm':
|
|
case 'M':
|
|
buff[dread-2]=0;
|
|
#ifdef UNICODE
|
|
MakeCommandString( inp_buff, buff, cl->Name, GetFormattedTime());
|
|
#else
|
|
CMDSTRING(inp_buff,buff,cl,GetFormattedTime());
|
|
#endif
|
|
len=_tcslen(inp_buff);
|
|
WriteFile(SaveFile,inp_buff,len,&tmp,NULL);
|
|
break;
|
|
|
|
case '@':
|
|
buff[dread-2]=0;
|
|
#ifdef UNICODE
|
|
MakeCommandString( inp_buff, buff, cl->Name, GetFormattedTime());
|
|
#else
|
|
CMDSTRING(inp_buff,&buff[1],cl,GetFormattedTime());
|
|
#endif
|
|
len=_tcslen(inp_buff);
|
|
WriteFile(SaveFile,inp_buff,len,&tmp,NULL);
|
|
//
|
|
// Remove the first @ sign
|
|
//
|
|
MoveMemory(buff,&buff[1],dread-1);
|
|
buff[dread-1]=' ';
|
|
return(FALSE); //Send it it to the chile process
|
|
break;
|
|
|
|
|
|
default :
|
|
_stprintf(inp_buff,TEXT("%s"),"** Unknown Command **\n");
|
|
WriteSocket(cl->Socket,inp_buff,_tcslen(inp_buff),&tmp);
|
|
case 'h':
|
|
case 'H':
|
|
_stprintf(inp_buff,TEXT("%cM: To Send Message\n"),COMMANDCHAR);
|
|
WriteSocket(cl->Socket,inp_buff,_tcslen(inp_buff),&tmp);
|
|
_stprintf(inp_buff,TEXT("%cP: To Generate popup\n"),COMMANDCHAR);
|
|
WriteSocket(cl->Socket,inp_buff,_tcslen(inp_buff),&tmp);
|
|
_stprintf(inp_buff,TEXT("%cK: To kill the server\n"),COMMANDCHAR);
|
|
WriteSocket(cl->Socket,inp_buff,_tcslen(inp_buff),&tmp);
|
|
_stprintf(inp_buff,TEXT("%cH: This Help\n"),COMMANDCHAR);
|
|
WriteSocket(cl->Socket,inp_buff,_tcslen(inp_buff),&tmp);
|
|
break;
|
|
}
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
if ((buff[0]<26))
|
|
{
|
|
BOOL ret=FALSE;
|
|
|
|
_stprintf(ch,TEXT("^%c"),buff[0]+64);
|
|
#ifdef UNICODE
|
|
MakeCommandString( inp_buff, ch, cl->Name, GetFormattedTime());
|
|
#else
|
|
CMDSTRING(inp_buff,ch,cl,GetFormattedTime());
|
|
#endif
|
|
len=_tcslen(inp_buff);
|
|
|
|
|
|
if (buff[0]==CTRLC)
|
|
{
|
|
cl->CommandRcvd=FALSE;
|
|
GenerateConsoleCtrlEvent(CTRL_C_EVENT,0);
|
|
ret=TRUE; //Already sent to child
|
|
}
|
|
|
|
WriteFile(SaveFile,inp_buff,len,&tmp,NULL);
|
|
return(ret); //FALSE:send it to child StdIn
|
|
}
|
|
|
|
|
|
tmpchar=buff[dread-2]; //must be 13;but just incase
|
|
buff[dread-2]=0;
|
|
#ifdef UNICODE
|
|
MakeCommandString( inp_buff, buff, cl->Name, GetFormattedTime());
|
|
#else
|
|
CMDSTRING(inp_buff,buff,cl,GetFormattedTime());
|
|
#endif
|
|
buff[dread-2]=tmpchar;
|
|
len=_tcslen(inp_buff);
|
|
WriteFile(SaveFile,inp_buff,len,&tmp,NULL);
|
|
return(FALSE);
|
|
}
|
|
/*************************************************************/
|
|
|
|
|
|
|
|
VOID
|
|
SendStatus(
|
|
HANDLE hClientPipe
|
|
)
|
|
{
|
|
TCHAR buff[1024];
|
|
int i;
|
|
DWORD tmp;
|
|
TCHAR *env=(TCHAR *)GetEnvironmentStrings();
|
|
DWORD ver=GetVersion();
|
|
|
|
_stprintf(buff,TEXT("Command = %s\n"),ChildCmd);
|
|
WriteFile(hClientPipe,buff,_tcslen(buff),&tmp,NULL);
|
|
|
|
_stprintf(buff,TEXT("Server = %s PIPE=%s\n"),HostName,PipeName);
|
|
WriteFile(hClientPipe,buff,_tcslen(buff),&tmp,NULL);
|
|
|
|
_stprintf(buff,TEXT("IP Blocking= %d\n"),(DWORD)bIPLocked);
|
|
WriteFile(hClientPipe,buff,_tcslen(buff),&tmp,NULL);
|
|
|
|
_stprintf(buff,TEXT("Username= %s Password=%s\n"),Username,Password);
|
|
WriteFile(hClientPipe,buff,_tcslen(buff),&tmp,NULL);
|
|
|
|
_stprintf(buff,TEXT("Build = %d \n"),((WORD *)&ver)[1]);
|
|
WriteFile(hClientPipe,buff,_tcslen(buff),&tmp,NULL);
|
|
|
|
for (i=1;i<MAX_SESSION;i++)
|
|
{
|
|
if (ClientList[i].Active)
|
|
{
|
|
_stprintf(buff,TEXT("ACTIVE SESSION=%s\n"),ClientList[i].Name);
|
|
WriteFile(hClientPipe,buff,_tcslen(buff),&tmp,NULL);
|
|
}
|
|
}
|
|
|
|
_stprintf(buff,TEXT("====================\n"),Server,PipeName);
|
|
WriteFile(hClientPipe,buff,_tcslen(buff),&tmp,NULL);
|
|
|
|
_stprintf(buff,TEXT("ENVIRONMENT VARIABLES\n"),Server,PipeName);
|
|
WriteFile(hClientPipe,buff,_tcslen(buff),&tmp,NULL);
|
|
|
|
_stprintf(buff,TEXT("====================\n"),Server,PipeName);
|
|
WriteFile(hClientPipe,buff,_tcslen(buff),&tmp,NULL);
|
|
|
|
|
|
__try
|
|
{
|
|
while (*env!=0)
|
|
{
|
|
_stprintf(buff,TEXT("%s\n"),env);
|
|
WriteFile(hClientPipe,buff,_tcslen(buff),&tmp,NULL);
|
|
|
|
while(*(env++)!=0);
|
|
}
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
_stprintf(buff,TEXT("Exception Generated Getting Environment Block\n"),env);
|
|
WriteFile(hClientPipe,buff,_tcslen(buff),&tmp,NULL);
|
|
|
|
}
|
|
|
|
_stprintf(buff,TEXT("====================\n"),Server,PipeName);
|
|
WriteFile(hClientPipe,buff,_tcslen(buff),&tmp,NULL);
|
|
return;
|
|
}
|
|
/*************************************************************/
|
|
VOID
|
|
SockSendStatus(
|
|
SOCKET MySocket
|
|
)
|
|
{
|
|
TCHAR buff[1024];
|
|
int i;
|
|
DWORD tmp;
|
|
TCHAR *env=(TCHAR *)GetEnvironmentStrings();
|
|
DWORD ver=GetVersion();
|
|
|
|
_stprintf(buff,TEXT("Command = %s\n"),ChildCmd);
|
|
WriteSocket(MySocket,buff,_tcslen(buff),&tmp);
|
|
|
|
_stprintf(buff,TEXT("Server = %s Port=%s\n"),HostName,PipeName);
|
|
WriteSocket(MySocket,buff,_tcslen(buff),&tmp);
|
|
|
|
_stprintf(buff,TEXT("IP Blocking= %d\n"),(DWORD)bIPLocked);
|
|
WriteSocket(MySocket,buff,_tcslen(buff),&tmp);
|
|
|
|
_stprintf(buff,TEXT("Username= %s Password=%s\n"),Username,Password);
|
|
WriteSocket(MySocket,buff,_tcslen(buff),&tmp);
|
|
|
|
_stprintf(buff,TEXT("Build = %d \n"),((WORD *)&ver)[1]);
|
|
WriteSocket(MySocket,buff,_tcslen(buff),&tmp);
|
|
|
|
for (i=1;i<MAX_SESSION;i++)
|
|
{
|
|
if (ClientList[i].Active)
|
|
{
|
|
_stprintf(buff,TEXT("ACTIVE SESSION=%s from IP %s \n"),ClientList[i].Name, ClientList[i].szIP );
|
|
WriteSocket(MySocket,buff,_tcslen(buff),&tmp);
|
|
}
|
|
}
|
|
|
|
_stprintf(buff,TEXT("====================\n"),Server,PipeName);
|
|
WriteSocket(MySocket,buff,_tcslen(buff),&tmp);
|
|
|
|
_stprintf(buff,TEXT("ENVIRONMENT VARIABLES\n"),Server,PipeName);
|
|
WriteSocket(MySocket,buff,_tcslen(buff),&tmp);
|
|
|
|
_stprintf(buff,TEXT("====================\n"),Server,PipeName);
|
|
WriteSocket(MySocket,buff,_tcslen(buff),&tmp);
|
|
|
|
|
|
__try
|
|
{
|
|
while (*env!=0)
|
|
{
|
|
_stprintf(buff,TEXT("%s\n"),env);
|
|
WriteSocket(MySocket,buff,_tcslen(buff),&tmp);
|
|
|
|
while(*(env++)!=0);
|
|
}
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
_stprintf(buff,TEXT("Exception Generated Getting Environment Block\n"),env);
|
|
WriteSocket(MySocket,buff,_tcslen(buff),&tmp);
|
|
|
|
}
|
|
|
|
_stprintf(buff,TEXT("====================\n"),Server,PipeName);
|
|
WriteSocket(MySocket,buff,_tcslen(buff),&tmp);
|
|
return;
|
|
}
|
|
/*************************************************************/
|
|
|
|
|
|
DWORD
|
|
ShowPopup(
|
|
TCHAR *mssg
|
|
)
|
|
{
|
|
MessageBox(GetActiveWindow(),mssg,TEXT("***WSREMOTE***"),MB_OK|MB_SETFOREGROUND);
|
|
free(mssg);
|
|
return(0);
|
|
|
|
}
|
|
/*************************************************************/
|
|
BOOL SrvCtrlHand(
|
|
DWORD event
|
|
)
|
|
{
|
|
if (event==CTRL_BREAK_EVENT)
|
|
{
|
|
TerminateProcess(ChldProc,1);
|
|
return(TRUE);
|
|
}
|
|
else if (event==CTRL_C_EVENT)
|
|
return(TRUE);
|
|
return(FALSE);
|
|
}
|
|
/*************************************************************/
|
|
|
|
DWORD LocalSession(PVOID noarg)
|
|
{
|
|
//Local is ClientList[0]
|
|
TCHAR *name=(TCHAR *)ClientList[0].Name;
|
|
|
|
_tcscpy(name,LOCALNAME);
|
|
if ((ClientList[0].rSaveFile=CreateFile(SaveFileName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL))==NULL)
|
|
{
|
|
_tprintf(TEXT("WSRemote:Cannot open ReadHandle to Savefile:%d\n"),GetLastError());
|
|
ClientList[0].Active=FALSE;
|
|
return(1);
|
|
|
|
}
|
|
|
|
ClientList[0].PipeReadH=GetStdHandle(STD_INPUT_HANDLE);
|
|
ClientList[0].PipeWriteH=GetStdHandle(STD_OUTPUT_HANDLE);
|
|
ClientList[0].SendOutput=TRUE;
|
|
ClientList[0].Active=TRUE;
|
|
NewSession(&ClientList[0]);
|
|
CloseClient(&ClientList[0]);
|
|
return(0);
|
|
}
|
|
|
|
VOID
|
|
CloseClient(
|
|
SESSION_TYPE *Client
|
|
)
|
|
{
|
|
int nRet;
|
|
ZeroMemory(Client->Name,HOSTNAMELEN);
|
|
|
|
if (Client->PipeReadH!=INVALID_HANDLE_VALUE)
|
|
{
|
|
CloseHandle(Client->PipeReadH);
|
|
Client->PipeReadH=INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
if (Client->PipeWriteH!=INVALID_HANDLE_VALUE)
|
|
{
|
|
CloseHandle(Client->PipeWriteH);
|
|
Client->PipeWriteH=INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
if (Client->rSaveFile!=INVALID_HANDLE_VALUE)
|
|
{
|
|
CloseHandle(Client->rSaveFile);
|
|
Client->rSaveFile=INVALID_HANDLE_VALUE;
|
|
}
|
|
if (Client->MoreData!=NULL)
|
|
{
|
|
CloseHandle(Client->MoreData);
|
|
Client->MoreData=NULL;
|
|
}
|
|
if (Client->Socket!=INVALID_SOCKET)
|
|
{
|
|
nRet = shutdown(Client->Socket, SD_BOTH);
|
|
if (nRet == SOCKET_ERROR)
|
|
_tprintf(TEXT("** shutdown()..error %d"), WSAGetLastError());
|
|
closesocket(Client->Socket);
|
|
|
|
Client->Socket=INVALID_SOCKET;
|
|
}
|
|
ZeroMemory(Client->szIP,16);
|
|
|
|
Client->Active=FALSE; //Keep it last else synch problem.
|
|
return;
|
|
}
|
|
|
|
VOID
|
|
InitClientList(
|
|
)
|
|
{
|
|
int i;
|
|
for (i=0;i<MAX_SESSION;i++)
|
|
{
|
|
ZeroMemory(ClientList[i].Name,HOSTNAMELEN);
|
|
ClientList[i].PipeReadH=INVALID_HANDLE_VALUE;
|
|
ClientList[i].PipeWriteH=INVALID_HANDLE_VALUE;
|
|
ClientList[i].rSaveFile=INVALID_HANDLE_VALUE;
|
|
ClientList[i].MoreData=NULL;
|
|
ClientList[i].Socket=INVALID_SOCKET;
|
|
ClientList[i].Active=FALSE;
|
|
ClientList[i].CommandRcvd=FALSE;
|
|
ClientList[i].SendOutput=FALSE;
|
|
ClientList[i].hThread=NULL;
|
|
ZeroMemory(ClientList[i].szIP,16);
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
RemoveInpMark(
|
|
TCHAR* Buff,
|
|
DWORD Size
|
|
)
|
|
|
|
{
|
|
DWORD i;
|
|
for (i=0;i<Size;i++)
|
|
{
|
|
switch (Buff[i])
|
|
{
|
|
case BEGINMARK:
|
|
Buff[i]=' ';
|
|
break;
|
|
|
|
case ENDMARK:
|
|
if (i<2)
|
|
{
|
|
Buff[i]= ' ';
|
|
}
|
|
else
|
|
{
|
|
Buff[i] =Buff[i-1];
|
|
Buff[i-1]=Buff[i-2];
|
|
Buff[i-2]=' ';
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*************************************************************/
|
|
DWORD
|
|
SockListenForSession(
|
|
TCHAR* szListenPort
|
|
)
|
|
{
|
|
// Bind and Listen
|
|
DWORD ThreadID;
|
|
SOCKADDR_IN saServer;
|
|
int nRet;
|
|
unsigned short usPort;
|
|
int i;
|
|
|
|
// Accept
|
|
SOCKET socketClient;
|
|
SOCKADDR_IN SockAddr;
|
|
int nLen;
|
|
|
|
int iWSAErr;
|
|
TCHAR * pszInetAddress = NULL;
|
|
//
|
|
// Create a TCP/IP stream socket
|
|
//
|
|
|
|
listenSocket = socket ( AF_INET,
|
|
SOCK_STREAM,
|
|
IPPROTO_TCP);
|
|
|
|
if (listenSocket == INVALID_SOCKET)
|
|
{
|
|
_tprintf (TEXT("Could not create listen socket: %d"), WSAGetLastError() );
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Get the port number
|
|
// TODO: Check szListenPort for Alpha Chars
|
|
//
|
|
usPort = (unsigned short)_ttoi( szListenPort );
|
|
if (usPort == 0)
|
|
{
|
|
_tprintf (TEXT("**Invalid Listen Port: %s\n"),szListenPort);
|
|
_tprintf (TEXT("**No Socket Connections Allowed....\n"));
|
|
|
|
nRet = shutdown(listenSocket, SD_BOTH);
|
|
if (nRet == SOCKET_ERROR)
|
|
_tprintf(TEXT("** shutdown()..error %d"), WSAGetLastError());
|
|
closesocket(listenSocket);
|
|
return FALSE;
|
|
}
|
|
|
|
saServer.sin_port = htons(usPort);
|
|
|
|
//
|
|
// Fill in the rest of the address structure
|
|
//
|
|
saServer.sin_family = AF_INET;
|
|
saServer.sin_addr.s_addr = INADDR_ANY;
|
|
|
|
//
|
|
// Bind our name to the socket
|
|
//
|
|
nRet = bind( listenSocket,
|
|
(LPSOCKADDR)&saServer,
|
|
sizeof(struct sockaddr));
|
|
|
|
if (nRet == SOCKET_ERROR)
|
|
{
|
|
_tprintf (TEXT("bind() error: %d"), WSAGetLastError() );
|
|
nRet = shutdown(listenSocket, SD_BOTH);
|
|
if (nRet == SOCKET_ERROR)
|
|
_tprintf(TEXT("** shutdown()..error %d"), WSAGetLastError());
|
|
closesocket(listenSocket);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Set the Socket to listen
|
|
//
|
|
nRet = listen(listenSocket, SOMAXCONN);
|
|
if (nRet == SOCKET_ERROR)
|
|
{
|
|
_tprintf (TEXT("listen error() error: %d"), WSAGetLastError() );
|
|
nRet = shutdown(listenSocket, SD_BOTH);
|
|
if (nRet == SOCKET_ERROR)
|
|
_tprintf(TEXT("** shutdown()..error %d"), WSAGetLastError());
|
|
closesocket(listenSocket);
|
|
return FALSE;
|
|
}
|
|
|
|
while (1)
|
|
{
|
|
|
|
// Block on Accept()
|
|
nLen = sizeof(SOCKADDR_IN);
|
|
socketClient = accept (listenSocket,
|
|
(LPSOCKADDR)&SockAddr,
|
|
&nLen);
|
|
if (socketClient == INVALID_SOCKET)
|
|
{
|
|
//Accept Failed
|
|
_tprintf (TEXT("accept error() error: %d"), WSAGetLastError() );
|
|
break;
|
|
}// if
|
|
|
|
#ifdef UNICODE
|
|
pszInetAddress = inet_ntoaw(SockAddr.sin_addr);
|
|
#else
|
|
pszInetAddress = inet_ntoa(SockAddr.sin_addr);
|
|
|
|
#endif
|
|
|
|
_tprintf( TEXT("\nCONNECT on socket: %d\nFROM ip: %s"),
|
|
socketClient,
|
|
pszInetAddress );
|
|
|
|
//
|
|
//Look For a Free Slot & if not- then terminate connection
|
|
//
|
|
|
|
for (i=1;i<MAX_SESSION;i++)
|
|
{
|
|
//
|
|
// Locate a Free Client block
|
|
//
|
|
if (!ClientList[i].Active)
|
|
break;
|
|
}// for
|
|
|
|
if ( (i<MAX_SESSION) && (bIPLocked == FALSE) )
|
|
{
|
|
//
|
|
// Initialize the Client
|
|
//
|
|
ClientList[i].PipeReadH=INVALID_HANDLE_VALUE;
|
|
ClientList[i].PipeWriteH=INVALID_HANDLE_VALUE;
|
|
ClientList[i].Active=TRUE;
|
|
ClientList[i].SendOutput=TRUE;
|
|
ClientList[i].CommandRcvd=FALSE;
|
|
// SOCK
|
|
ClientList[i].Socket=socketClient;
|
|
_tcscpy(ClientList[i].szIP,pszInetAddress);
|
|
|
|
#ifdef UNICODE
|
|
free( pszInetAddress );
|
|
#endif
|
|
|
|
//
|
|
//start new thread for this connection
|
|
//
|
|
|
|
if((ClientList[i].hThread=CreateThread (
|
|
(LPSECURITY_ATTRIBUTES)NULL, // No security attributes.
|
|
(DWORD)0, // Use same stack size.
|
|
(LPTHREAD_START_ROUTINE)SockRemoteSession, // Thread procedure.
|
|
(LPVOID)&ClientList[i], // Parameter to pass.
|
|
(DWORD)0, // Run immediately.
|
|
(LPDWORD)&ThreadID))==NULL)
|
|
{
|
|
CloseClient(&ClientList[i]);
|
|
continue;
|
|
}// if
|
|
}
|
|
else
|
|
{
|
|
_tprintf(TEXT("WSRemote:Closing New Session - No more slots or IP is Locked Out\n"));
|
|
nRet = shutdown(socketClient, SD_BOTH);
|
|
if (nRet == SOCKET_ERROR)
|
|
_tprintf(TEXT("** shutdown()..error %d"), WSAGetLastError());
|
|
closesocket(socketClient);
|
|
continue;
|
|
}//if
|
|
|
|
|
|
}// while
|
|
|
|
iWSAErr = WSAGetLastError();
|
|
|
|
_tprintf (TEXT("FATAL ERROR, Exiting SockListenForSession: %d"),
|
|
iWSAErr );
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*************************************************************/
|
|
DWORD
|
|
SockRemoteSession(
|
|
SESSION_TYPE *MyClient
|
|
)
|
|
{
|
|
//Declare Variables
|
|
//
|
|
DWORD ReadCnt;
|
|
DWORD tmp;
|
|
SESSION_STARTUPINFO ssi;
|
|
TCHAR * headerbuff;
|
|
TCHAR msg[BUFFSIZE];
|
|
SESSION_STARTREPLY ssr;
|
|
DWORD reply =0;
|
|
BOOL bRet;
|
|
|
|
if ((MyClient->rSaveFile=CreateFile(
|
|
SaveFileName,
|
|
GENERIC_READ|GENERIC_WRITE,
|
|
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
|
NULL,OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,NULL))==NULL)
|
|
|
|
{
|
|
CloseClient(MyClient);
|
|
return(1);
|
|
}
|
|
|
|
bRet = SockAuthenticate(MyClient->Socket);
|
|
if (bRet == FALSE)
|
|
{
|
|
_tprintf(TEXT("\nAuth:Bad Username or Password\n"));
|
|
CloseClient(MyClient);
|
|
return(1);
|
|
}
|
|
|
|
// ReadSocket( MyClient->Socket,
|
|
// (TCHAR *)MyClient->Name,
|
|
// HOSTNAMELEN-1,
|
|
// &dwBytesRead);
|
|
|
|
SockReadFixBytes(MyClient->Socket,(TCHAR *)MyClient->Name,HOSTNAMELEN-1,0);
|
|
|
|
//
|
|
//Last four Bytes contains a code
|
|
//
|
|
|
|
memcpy((TCHAR *)&reply,(TCHAR *)&(MyClient->Name[11]),4);
|
|
|
|
if (reply!=MAGICNUMBER)
|
|
{
|
|
//
|
|
// Unknown client
|
|
//
|
|
CloseClient(MyClient);
|
|
return(1);
|
|
}
|
|
|
|
ssr.MagicNumber=MAGICNUMBER;
|
|
ssr.Size=sizeof(ssr);
|
|
ssr.FileSize=GetFileSize( MyClient->rSaveFile, &tmp );
|
|
|
|
send(MyClient->Socket,(const char *)&ssr,sizeof(ssr),0);
|
|
|
|
|
|
|
|
if (SockReadFixBytes(MyClient->Socket,(TCHAR *)&(ssi.Size),sizeof(ssi.Size),0)!=0)
|
|
{
|
|
CloseClient(MyClient);
|
|
return(1);
|
|
}
|
|
|
|
if (ssi.Size>1024) //Sanity Check
|
|
{
|
|
_stprintf(msg,TEXT("%s"),"Server:Unknown Header..Terminating session\n");
|
|
WriteSocket(MyClient->Socket,msg,_tcslen(msg),&tmp);
|
|
CloseClient(MyClient);
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
if ((headerbuff=(TCHAR *)calloc(ssi.Size,1))==NULL)
|
|
{
|
|
_stprintf(msg,TEXT("%s"),"Server:Not Enough Memory..Terminating session\n");
|
|
WriteSocket(MyClient->Socket,msg,_tcslen(msg),&tmp);
|
|
CloseClient(MyClient);
|
|
return(1);
|
|
|
|
}
|
|
|
|
ReadCnt=ssi.Size-sizeof(ssi.Size);
|
|
if (SockReadFixBytes(MyClient->Socket,(TCHAR *)headerbuff,ReadCnt,0)!=0)
|
|
{
|
|
CloseClient(MyClient);
|
|
return(1);
|
|
}
|
|
|
|
memcpy((TCHAR *)&ssi+sizeof(ssi.Size),headerbuff,sizeof(ssi)-sizeof(ssi.Size));
|
|
free(headerbuff);
|
|
|
|
/* Version */
|
|
if (ssi.Version!=VERSION)
|
|
{
|
|
_stprintf(msg,TEXT("WSRemote Warning:Server Version=%d Client Version=%d\n"),VERSION,ssi.Version);
|
|
WriteSocket(MyClient->Socket,msg,_tcslen(msg),&tmp);
|
|
}
|
|
|
|
/* Name */
|
|
{
|
|
memcpy(MyClient->Name,ssi.ClientName,15);
|
|
MyClient->Name[14]=0;
|
|
|
|
}
|
|
|
|
/* Lines */
|
|
if (ssi.LinesToSend!=-1)
|
|
{
|
|
long PosFromEnd=ssi.LinesToSend*CHARS_PER_LINE;
|
|
DWORD BytesToSend=MINIMUM((DWORD)PosFromEnd,ssr.FileSize);
|
|
DWORD BytesRead;
|
|
TCHAR *buff=(TCHAR *)calloc(BytesToSend+1,1);
|
|
|
|
if (ssr.FileSize > (DWORD)PosFromEnd)
|
|
{
|
|
SetFilePointer( MyClient->rSaveFile,
|
|
-PosFromEnd,
|
|
(PLONG)NULL,
|
|
FILE_END
|
|
);
|
|
|
|
}
|
|
|
|
if (buff!=NULL)
|
|
{
|
|
if (!ReadFile(MyClient->rSaveFile,buff,BytesToSend,&BytesRead,NULL))
|
|
{
|
|
CloseClient(MyClient);
|
|
return(1);
|
|
}
|
|
|
|
RemoveInpMark(buff,BytesRead);
|
|
if (!WriteSocket(MyClient->Socket,buff,BytesRead,&tmp))
|
|
{
|
|
CloseClient(MyClient);
|
|
return(1);
|
|
}
|
|
}
|
|
free(buff);
|
|
|
|
}
|
|
|
|
RemoteInfo(_tprintf(TEXT("\n**WSRemote:Connected To %s ip=%s [%s]\n"),MyClient->Name,MyClient->szIP,GetFormattedTime()),ssi.Flag);
|
|
SockNewSession(MyClient);
|
|
RemoteInfo(_tprintf(TEXT("\n**WSRemote:Disconnected From %s ip=%s [%s]\n"),MyClient->Name,MyClient->szIP,GetFormattedTime()),ssi.Flag);
|
|
CloseClient(MyClient);
|
|
return(0);
|
|
}
|
|
|
|
/*************************************************************/
|
|
DWORD
|
|
SockNewSession(
|
|
SESSION_TYPE* MyClient
|
|
)
|
|
{
|
|
DWORD ThreadId;
|
|
HANDLE rwThread[3];
|
|
|
|
MyClient->MoreData=CreateEvent
|
|
(
|
|
(LPSECURITY_ATTRIBUTES) NULL,/* address of security attributes */
|
|
FALSE, /* flag for manual-reset event */
|
|
TRUE, /* flag for initial state */
|
|
NULL /* address of event-object name */
|
|
);
|
|
|
|
|
|
|
|
if ((rwThread[0]=CreateThread (
|
|
(LPSECURITY_ATTRIBUTES)NULL, // No security attributes.
|
|
(DWORD)0, // Use same stack size.
|
|
(LPTHREAD_START_ROUTINE)SockGetClientInput, // Thread procedure.
|
|
(LPVOID)MyClient, // Parameter to pass.
|
|
(DWORD)0, // Run immediately.
|
|
(LPDWORD)&ThreadId))==NULL)
|
|
{
|
|
return(GetLastError());
|
|
}
|
|
|
|
if ((rwThread[1]=CreateThread (
|
|
(LPSECURITY_ATTRIBUTES)NULL, // No security attributes.
|
|
(DWORD)0, // Use same stack size.
|
|
(LPTHREAD_START_ROUTINE)SockTransferFileToClient, // Thread procedure.
|
|
(LPVOID)MyClient, // Parameter to pass.
|
|
(DWORD)0, // Run immediately.
|
|
(LPDWORD)&ThreadId))==NULL)
|
|
{
|
|
CloseHandle(rwThread[0]);
|
|
return(GetLastError());
|
|
}
|
|
|
|
rwThread[2]=ChldProc;
|
|
WaitForMultipleObjects(3, rwThread,FALSE, INFINITE);
|
|
|
|
TerminateThread(rwThread[0],1);
|
|
TerminateThread(rwThread[1],1);
|
|
|
|
CloseHandle(rwThread[0]);
|
|
CloseHandle(rwThread[1]);
|
|
|
|
return(0);
|
|
}
|
|
|
|
/*************************************************************/
|
|
DWORD
|
|
SockGetClientInput(
|
|
SESSION_TYPE *MyClient
|
|
)
|
|
{
|
|
TCHAR buf[BUFFSIZE];
|
|
DWORD tmp,
|
|
dread;
|
|
|
|
memset(buf, 0, sizeof(buf));
|
|
|
|
while(ReadSocket(MyClient->Socket,buf,BUFFSIZE,&dread))
|
|
{
|
|
buf[sizeof(buf)]=0;
|
|
MyClient->CommandRcvd=TRUE;
|
|
|
|
if (0 == buf[0] )
|
|
return(1);
|
|
|
|
if (SockFilterCommand(MyClient,buf,dread))
|
|
continue;
|
|
|
|
|
|
if (!WriteFile(ChildStdInp,buf,dread,&tmp,NULL))
|
|
{
|
|
ExitThread(0);
|
|
}
|
|
memset(buf, 0, sizeof(buf));
|
|
}
|
|
return(1);
|
|
}
|
|
|
|
/*************************************************************/
|
|
DWORD
|
|
SockTransferFileToClient(
|
|
SESSION_TYPE *MyClient
|
|
)
|
|
{
|
|
|
|
TCHAR buffin[BUFFSIZE],
|
|
buffout[BUFFSIZE],
|
|
cmdbuff[BUFFSIZE];
|
|
DWORD tmp;
|
|
DWORD dread=0,dwrite=0;
|
|
BOOL incmd=FALSE;
|
|
DWORD cmdP=0;
|
|
DWORD i;
|
|
TCHAR MyEchoStr[30];
|
|
|
|
_stprintf(MyEchoStr,TEXT("[%-15s"),MyClient->Name);
|
|
|
|
|
|
while(ReadFile(MyClient->rSaveFile,buffin,BUFFSIZE-1,&dread,NULL))
|
|
{
|
|
if (dread==0)
|
|
{
|
|
WaitForSingleObject(MyClient->MoreData,INFINITE);
|
|
continue;
|
|
}
|
|
dwrite=0;
|
|
for(i=0;i<dread;i++)
|
|
{
|
|
if (incmd)
|
|
{
|
|
if ((buffin[i]==ENDMARK)||(cmdP==BUFFSIZE-1))
|
|
{
|
|
incmd=FALSE;
|
|
cmdbuff[cmdP]=0;
|
|
if ((_tcsstr(cmdbuff,MyEchoStr)==NULL)||
|
|
(!MyClient->CommandRcvd))
|
|
{
|
|
//if (!send (MyClient->Socket, cmdbuff, cmdP, 0));
|
|
//if (!SendBuffer(MyClient, cmdbuff, cmdP))
|
|
if (!WriteSocket(MyClient->Socket, cmdbuff,cmdP,&tmp))
|
|
{
|
|
return(1);
|
|
}
|
|
}
|
|
cmdP=0;
|
|
}
|
|
else
|
|
{
|
|
cmdbuff[cmdP++]=buffin[i];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
if (buffin[i]==BEGINMARK)
|
|
{
|
|
if (dwrite!=0)
|
|
{
|
|
//if (!send (MyClient->Socket, buffout, dwrite, 0));
|
|
//if (!SendBuffer(MyClient, buffout, dwrite))
|
|
if (!WriteSocket(
|
|
MyClient->Socket,
|
|
buffout,dwrite,&tmp))
|
|
{
|
|
return(1);
|
|
}
|
|
dwrite=0;
|
|
}
|
|
incmd=TRUE;
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
buffout[dwrite++]=buffin[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (dwrite!=0)
|
|
{
|
|
//if (!send (MyClient->Socket, buffout, dwrite, 0));
|
|
//if (!SendBuffer(MyClient, buffout, dwrite))
|
|
if (!WriteSocket(
|
|
MyClient->Socket,
|
|
buffout,dwrite,&tmp))
|
|
{
|
|
return(0);
|
|
}
|
|
}
|
|
}
|
|
return(1);
|
|
}
|
|
|
|
|
|
BOOL
|
|
SockAuthenticate(
|
|
SOCKET MySocket
|
|
)
|
|
{
|
|
BOOL bRead;
|
|
DWORD dread;
|
|
int bufflen;
|
|
int iCmp;
|
|
TCHAR EncodeBuffer[1024];
|
|
TCHAR CheckEncodeBuffer[1024];
|
|
TCHAR UserBuffer[1024];
|
|
TCHAR * String = UserBuffer;
|
|
TCHAR * pEncodeBuffer;
|
|
TCHAR * pCheckEncodeBuffer;
|
|
|
|
SetLastError(0);
|
|
|
|
memset(CheckEncodeBuffer, 0, sizeof(CheckEncodeBuffer));
|
|
|
|
_stprintf(
|
|
UserBuffer, TEXT("%s:%s"),
|
|
Username,
|
|
Password);
|
|
|
|
pCheckEncodeBuffer = CheckEncodeBuffer + _tcslen(CheckEncodeBuffer);
|
|
Base64Encode(UserBuffer, _tcslen(UserBuffer), pCheckEncodeBuffer);
|
|
bufflen = _tcslen(pCheckEncodeBuffer);
|
|
|
|
memset(EncodeBuffer, 0, sizeof(EncodeBuffer));
|
|
|
|
bRead = ReadSocket(MySocket,EncodeBuffer,bufflen,&dread);
|
|
|
|
pEncodeBuffer = EncodeBuffer;
|
|
|
|
iCmp = _tcscmp(pEncodeBuffer, pCheckEncodeBuffer);
|
|
if (iCmp != 0)
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
#ifdef UNICODE
|
|
int MakeCommandString(
|
|
TCHAR * pszOutput,
|
|
TCHAR * pszInput,
|
|
TCHAR * pszName,
|
|
TCHAR * pszTime
|
|
)
|
|
{
|
|
int nStrLen =_stprintf( pszOutput,
|
|
TEXT("\xfe%-15s [%-15s %s]\n\xff"),
|
|
pszInput,
|
|
pszName,
|
|
pszTime );
|
|
|
|
return nStrLen;
|
|
}
|
|
#endif |