-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathTelnetHandler.cpp
More file actions
126 lines (117 loc) · 3.38 KB
/
TelnetHandler.cpp
File metadata and controls
126 lines (117 loc) · 3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// TelnetHandler.cpp
// Copyright (c) datadiode
// SPDX-License-Identifier: GPL-2.0-or-later
#include <stdio.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <limits.h>
#include <assert.h>
#include "DualServer.h"
#include "TelnetHandler.h"
static void __cdecl telnetThread(void *pv)
{
SOCKET const client = reinterpret_cast<SOCKET>(pv);
u_long iMode = 1;
ioctlsocket(client, FIONBIO, &iMode);
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof sa;
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
enum { read, write };
HANDLE input[2] = { NULL, NULL };
HANDLE output[2] = { NULL, NULL };
CreatePipe(&input[read], &input[write], &sa, 0);
CreatePipe(&output[read], &output[write], &sa, 0);
STARTUPINFO si;
ZeroMemory(&si, sizeof si);
si.cb = sizeof si;
si.hStdError = output[write];
si.hStdOutput = output[write];
si.hStdInput = input[read];
si.dwFlags = STARTF_USESTDHANDLES;
TCHAR path[MAX_PATH];
PROCESS_INFORMATION pi;
if ((input[read] != input[write]) && (output[read] != output[write]) &&
GetEnvironmentVariable(TEXT("COMSPEC"), path, _countof(path)) &&
CreateProcess(NULL, path, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
{
sprintf(logTelnet<1>(), "Started command shell");
DWORD wait;
do
{
wait = WaitForSingleObject(pi.hProcess, 100);
int result;
DWORD cb;
char buffer[4096];
while (PeekNamedPipe(output[read], buffer, sizeof buffer, &cb, NULL, NULL) && cb != 0)
{
if ((result = send(client, buffer, cb, 0)) > 0)
{
ReadFile(output[read], buffer, result, &cb, NULL);
if (cfig.telnetLogLevel == 255)
{
WriteFile(verbatim, buffer, result, &cb, NULL);
}
}
else if (result < 0 && (result = WSAGetLastError()) != WSAEWOULDBLOCK)
{
sprintf(logTelnet<1>(), "Send error due to %d", result);
break;
}
}
if ((result = recv(client, buffer, sizeof buffer, 0)) > 0)
{
WriteFile(input[write], buffer, result, &cb, NULL);
}
else if (result < 0 && (result = WSAGetLastError()) != WSAEWOULDBLOCK)
{
sprintf(logTelnet<1>(), "Receive error due to %d", result);
break;
}
} while (wait == WAIT_TIMEOUT);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
if (input[read] != input[write])
{
CloseHandle(input[read]);
CloseHandle(input[write]);
}
if (output[read] != output[write])
{
CloseHandle(output[read]);
CloseHandle(output[write]);
}
closesocket(client);
sprintf(logTelnet<1>(), "Disconnected");
EndThread();
}
bool AcceptTelnetConnection(SOCKET selected)
{
SOCKADDR_IN remote;
socklen_t sockLen = sizeof remote;;
SOCKET client = accept(selected, reinterpret_cast<sockaddr*>(&remote), &sockLen);
if (client != INVALID_SOCKET)
{
sprintf(logTelnet<2>(), "Client %s, Telnet Request Received", IP2String(remote.sin_addr.s_addr));
if (cfig.telnetClients[0] && !findServer(cfig.telnetClients, 8, remote.sin_addr.s_addr))
{
sprintf(logTelnet<2>(), "Client %s, Telnet Access Denied", IP2String(remote.sin_addr.s_addr));
}
else if (!BeginThread(telnetThread, 0, reinterpret_cast<void *>(client)))
{
sprintf(logTelnet<1>(), "Thread Creation Failed");
}
else
{
return true;
}
closesocket(client);
}
else
{
int error = WSAGetLastError();
sprintf(logTelnet<1>(), "Accept Failed, WSAError %u", error);
}
return false;
}