feat: Рабочая версия клиента

master
Nihonium 1 week ago
parent 9d71f33432
commit 53cc2a08ce

@ -12,7 +12,7 @@ endif()
project ("shell-server") project ("shell-server")
# Добавьте источник в исполняемый файл этого проекта. # Добавьте источник в исполняемый файл этого проекта.
add_executable (shell-server "main.c" "server.c" "server.h") add_executable (shell-server "main.c" "server.c" "server.h" "client.c" "client.h")
if (CMAKE_VERSION VERSION_GREATER 3.12) if (CMAKE_VERSION VERSION_GREATER 3.12)
set_property(TARGET shell-server PROPERTY CXX_STANDARD 20) set_property(TARGET shell-server PROPERTY CXX_STANDARD 20)

@ -3,14 +3,9 @@
#include "server.h" #include "server.h"
int _tmain(int argc, TCHAR *argv[]) { int _tmain(int argc, char *argv[]) {
if (argc == 2) { if (argc == 2) {
// TODO: implement client if (lstrcmpi(argv[1], TEXT("-s")) == 0) {
if (lstrcmpi(argv[1], TEXT("-c")) == 0) {
// StartShellClient();
return 0;
}
else if (lstrcmpi(argv[1], TEXT("-s")) == 0) {
StartShellServer(); StartShellServer();
return 0; return 0;
} }
@ -20,8 +15,12 @@ int _tmain(int argc, TCHAR *argv[]) {
} }
else if (argc == 3) { else if (argc == 3) {
if (lstrcmpi(argv[1], TEXT("-c")) == 0) {
StartShellClient(argv[2]);
return 0;
}
// TODO: implement service // TODO: implement service
if (lstrcmpi(argv[1], TEXT("-s")) == 0 && lstrcmpi(argv[2], TEXT("-service")) == 0) { else if (lstrcmpi(argv[1], TEXT("-s")) == 0 && lstrcmpi(argv[2], TEXT("-service")) == 0) {
// CreateService // CreateService
return 0; return 0;
} }
@ -35,7 +34,7 @@ int _tmain(int argc, TCHAR *argv[]) {
return 0; return 0;
help_message: help_message:
printf("Wrong usage\nUsage: %s [-c | -s [-service]]\n", argv[0]); printf("Wrong usage\nUsage: %s [-c {remote ip} | -s [-service]]\n", argv[0]);
return -1; return -1;
} }

@ -1,7 +1,6 @@
#include "server.h" #include "server.h"
#define BUFSIZE 4096 #define BUFSIZE 4096
#define DEFAULT_PORT "50113"
#define DEFAULT_BUFLEN 512 #define DEFAULT_BUFLEN 512
typedef struct PipeThreadInfo_t { typedef struct PipeThreadInfo_t {
@ -10,6 +9,7 @@ typedef struct PipeThreadInfo_t {
} PipeThreadInfo; } PipeThreadInfo;
void CreateChildProcess(HANDLE g_hChildStd_IN_Rd, HANDLE g_hChildStd_OUT_Wr); void CreateChildProcess(HANDLE g_hChildStd_IN_Rd, HANDLE g_hChildStd_OUT_Wr);
DWORD WINAPI WorkWithClient(LPVOID lpParam);
DWORD WINAPI WriteToPipe(LPVOID lpParam); DWORD WINAPI WriteToPipe(LPVOID lpParam);
DWORD WINAPI ReadFromPipe(LPVOID lpParam); DWORD WINAPI ReadFromPipe(LPVOID lpParam);
void ErrorExit(PCTSTR); void ErrorExit(PCTSTR);
@ -17,29 +17,15 @@ void ErrorExit(PCTSTR);
void StartShellServer() { void StartShellServer() {
printf("\n->Start of shell server execution.\n"); printf("\n->Start of shell server execution.\n");
/*
* Server variables
*/
WSADATA wsaData; WSADATA wsaData;
struct addrinfo* result = NULL, * ptr = NULL, hints; struct addrinfo* result = NULL, * ptr = NULL, hints;
SOCKET ListenSocket = INVALID_SOCKET;
int iResult; int iResult;
/*
* Client variables
*/
SOCKET ClientSocket = INVALID_SOCKET; SOCKET ClientSocket = INVALID_SOCKET;
// Pipe handles for child STDIN/STDOUT SOCKET ListenSocket = INVALID_SOCKET;
HANDLE g_hChildStd_IN_Rd = NULL;
HANDLE g_hChildStd_IN_Wr = NULL;
HANDLE g_hChildStd_OUT_Rd = NULL;
HANDLE g_hChildStd_OUT_Wr = NULL;
SECURITY_ATTRIBUTES saAttr;
HANDLE PipeThreads[2];
/* /*
* Initialize listening socket * Initialize listening socket
*/ */
// Initialize Winsock // Initialize Winsock
@ -94,6 +80,46 @@ void StartShellServer() {
return 1; return 1;
} }
/*
* Process client connection
*/
for (;;) {
// Accepting a client connection
ClientSocket = INVALID_SOCKET;
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed: %d\n", WSAGetLastError());
break;
}
printf("Client connected\n");
// Create separate thread to process client connection
CreateThread(NULL, 0, WorkWithClient, ClientSocket, 0, NULL);
}
/*
* Finalization
*/
// TODO: properly close all handles
closesocket(ListenSocket);
WSACleanup();
}
DWORD WINAPI WorkWithClient(LPVOID lpParam) {
/*
* Client variables
*/
// Pipe handles for child STDIN/STDOUT
HANDLE g_hChildStd_IN_Rd = NULL;
HANDLE g_hChildStd_IN_Wr = NULL;
HANDLE g_hChildStd_OUT_Rd = NULL;
HANDLE g_hChildStd_OUT_Wr = NULL;
SECURITY_ATTRIBUTES saAttr;
HANDLE PipeThreads[2];
SOCKET ClientSocket = (SOCKET)lpParam;
/* /*
* Initialize pipes * Initialize pipes
*/ */
@ -119,26 +145,11 @@ void StartShellServer() {
ErrorExit(TEXT("Stdin SetHandleInformation")); ErrorExit(TEXT("Stdin SetHandleInformation"));
/* /*
* Create child process * Create child process cmd.exe
*/ */
CreateChildProcess(g_hChildStd_IN_Rd, g_hChildStd_OUT_Wr); CreateChildProcess(g_hChildStd_IN_Rd, g_hChildStd_OUT_Wr);
/*
* Process client connection
*/
// Accepting a connection
ClientSocket = INVALID_SOCKET;
// Accept a client socket
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
// Create threads for STDIN/STDOUT
PipeThreadInfo WriteThreadInfo = { g_hChildStd_IN_Wr, ClientSocket }; PipeThreadInfo WriteThreadInfo = { g_hChildStd_IN_Wr, ClientSocket };
PipeThreadInfo ReadThreadInfo = { g_hChildStd_OUT_Rd, ClientSocket }; PipeThreadInfo ReadThreadInfo = { g_hChildStd_OUT_Rd, ClientSocket };
PipeThreads[0] = CreateThread(NULL, 0, WriteToPipe, &WriteThreadInfo, 0, NULL); PipeThreads[0] = CreateThread(NULL, 0, WriteToPipe, &WriteThreadInfo, 0, NULL);
@ -147,12 +158,6 @@ void StartShellServer() {
WaitForMultipleObjects(2, PipeThreads, TRUE, INFINITE); WaitForMultipleObjects(2, PipeThreads, TRUE, INFINITE);
printf("\n->Client disconnected.\n"); printf("\n->Client disconnected.\n");
/*
* Finalization
*/
// TODO: properly close all handles
closesocket(ListenSocket);
} }
void CreateChildProcess(HANDLE g_hChildStd_IN_Rd, HANDLE g_hChildStd_OUT_Wr) void CreateChildProcess(HANDLE g_hChildStd_IN_Rd, HANDLE g_hChildStd_OUT_Wr)
@ -222,13 +227,19 @@ DWORD WINAPI WriteToPipe(LPVOID lpParam)
char recvbuf[DEFAULT_BUFLEN]; char recvbuf[DEFAULT_BUFLEN];
int iResult, iSendResult; int iResult, iSendResult;
int recvbuflen = DEFAULT_BUFLEN; int recvbuflen = DEFAULT_BUFLEN;
// Change codepage to UTF-8
//CHAR chcpCommand[] = "chcp 65001\n";
//bSuccess = WriteFile(g_hChildStd_IN_Wr, chcpCommand, strlen(chcpCommand), &dwWritten, NULL);
//if (!bSuccess) goto WriteToPipe_end;
do do
{ {
iResult = recv(ClientSocket, recvbuf, recvbuflen, 0); iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
if (iResult > 0) { if (iResult > 0) {
bSuccess = WriteFile(g_hChildStd_IN_Wr, recvbuf, iResult, &dwWritten, NULL); bSuccess = WriteFile(g_hChildStd_IN_Wr, recvbuf, iResult, &dwWritten, NULL);
if (!bSuccess) break; if (!bSuccess) break;
printf("Received command: %s\n");
} }
else if (iResult == 0) else if (iResult == 0)
printf("Connection closing...\n"); printf("Connection closing...\n");
@ -240,6 +251,7 @@ DWORD WINAPI WriteToPipe(LPVOID lpParam)
} }
} while (iResult > 0); } while (iResult > 0);
WriteToPipe_end:
// Closing STDIN => cmd.exe exit // Closing STDIN => cmd.exe exit
if (!CloseHandle(g_hChildStd_IN_Wr)) if (!CloseHandle(g_hChildStd_IN_Wr))
ErrorExit(TEXT("StdInWr CloseHandle")); ErrorExit(TEXT("StdInWr CloseHandle"));
@ -247,19 +259,24 @@ DWORD WINAPI WriteToPipe(LPVOID lpParam)
DWORD WINAPI ReadFromPipe(LPVOID lpParam) DWORD WINAPI ReadFromPipe(LPVOID lpParam)
{ {
DWORD dwRead, dwWritten; DWORD dwRead;
CHAR chBuf[BUFSIZE]; CHAR chBuf[BUFSIZE + 1];
BOOL bSuccess = FALSE; BOOL bSuccess = FALSE;
HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE); //HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
SOCKET ClientSocket = ((PipeThreadInfo*)lpParam)->ClientSocket; SOCKET ClientSocket = ((PipeThreadInfo*)lpParam)->ClientSocket;
HANDLE g_hChildStd_OUT_Rd = ((PipeThreadInfo*)lpParam)->Pipe; HANDLE g_hChildStd_OUT_Rd = ((PipeThreadInfo*)lpParam)->Pipe;
int iSendResult; int iSendResult;
for (;;) for (;;)
{ {
bSuccess = ReadFile(g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL); bSuccess = ReadFile(g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL);
if (!bSuccess || dwRead == 0) break; if (!bSuccess || dwRead == 0) break;
printf("STDOUT: %s\n", chBuf);
chBuf[dwRead] = '\0';
iSendResult = send(ClientSocket, chBuf, dwRead, 0); iSendResult = send(ClientSocket, chBuf, dwRead, 0);
if (iSendResult == SOCKET_ERROR) { if (iSendResult == SOCKET_ERROR) {
@ -268,9 +285,6 @@ DWORD WINAPI ReadFromPipe(LPVOID lpParam)
WSACleanup(); WSACleanup();
return 1; return 1;
} }
// Write to console
bSuccess = WriteFile(hParentStdOut, chBuf,
dwRead, &dwWritten, NULL);
if (!bSuccess) break; if (!bSuccess) break;
} }
} }

@ -12,11 +12,7 @@
#include <winsock2.h> #include <winsock2.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
#define DEFAULT_PORT "50113"
// Defined functions // Defined functions
void StartShellServer(); void StartShellServer();
//void CreatePipes();
//void CreateChildProcess(void);
//DWORD WINAPI WriteToPipe(LPVOID lpParam);
//DWORD WINAPI ReadFromPipe(LPVOID lpParam);
//void ErrorExit(PCTSTR);
//void CreateSocket();
Loading…
Cancel
Save