ReactOS 0.4.16-dev-303-g11d5cb8
telnetd.c File Reference
#include "telnetd.h"
Include dependency graph for telnetd.c:

Go to the source code of this file.

Macros

#define telnetd_printf   printf
 

Functions

int kickoff_telnetd (void)
 
static BOOL WINAPI Cleanup (DWORD dwControlType)
 
static BOOLEAN StartSocketInterface (void)
 
static void CreateSocket (void)
 
static void WaitForConnect (void)
 
static void UserLogin (int client_socket)
 
static DWORD WINAPI UserLoginThread (LPVOID data)
 
static int DoTelnetHandshake (int sock)
 
static int ReceiveLine (int sock, char *buffer, int len, EchoMode echo)
 
static void RunShell (client_t *client)
 
static DWORD WINAPI MonitorChildThread (LPVOID data)
 
static DWORD WINAPI WriteToPipeThread (LPVOID data)
 
static DWORD WINAPI ReadFromPipeThread (LPVOID data)
 
static void TerminateShell (client_t *client)
 
static VOID ErrorExit (LPTSTR lpszMessage)
 

Variables

static BOOLEAN bShutdown = 0
 
static BOOLEAN bSocketInterfaceInitialised = 0
 
static int sock
 

Macro Definition Documentation

◆ telnetd_printf

#define telnetd_printf   printf

Definition at line 25 of file telnetd.c.

Function Documentation

◆ Cleanup()

static BOOL WINAPI Cleanup ( DWORD  dwControlType)
static

Definition at line 69 of file telnetd.c.

70{
72 telnetd_printf("Cleanup...\n");
73 WSACleanup();
74 }
75 return 0;
76}
static BOOLEAN bSocketInterfaceInitialised
Definition: telnetd.c:37
#define telnetd_printf
Definition: telnetd.c:25
int PASCAL FAR WSACleanup(void)
Definition: startup.c:60

◆ CreateSocket()

static void CreateSocket ( void  )
static

Definition at line 102 of file telnetd.c.

103{
104 struct sockaddr_in sa;
105
107 if (sock < 0)
108 ErrorExit("Cannot create socket");
109
110 memset(&sa, 0, sizeof(sa));
111 sa.sin_family = AF_INET;
112 sa.sin_addr.s_addr = INADDR_ANY;
113 sa.sin_port = htons(TELNET_PORT);
114
115 if (bind(sock, (struct sockaddr*) &sa, sizeof(sa)) != 0)
116 ErrorExit("Cannot bind address to socket");
117}
static struct sockaddr_in sa
Definition: adnsresfilter.c:69
#define IPPROTO_TCP
Definition: ip.h:196
#define SOCK_STREAM
Definition: tcpip.h:118
#define AF_INET
Definition: tcpip.h:117
#define INADDR_ANY
Definition: inet.h:80
#define htons(x)
Definition: module.h:215
#define memset(x, y, z)
Definition: compat.h:39
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
Definition: tcpcore.h:1455
static VOID ErrorExit(LPTSTR lpszMessage)
Definition: telnetd.c:647
#define TELNET_PORT
Definition: telnetd.h:17

Referenced by kickoff_telnetd(), Test_ioctlsocket(), and Test_recv().

◆ DoTelnetHandshake()

static int DoTelnetHandshake ( int  sock)
static

Definition at line 229 of file telnetd.c.

230{
231 int retval;
232 int received;
233 fd_set set;
234 struct timeval timeout = { HANDSHAKE_TIMEOUT, 0 };
235
236 char will_echo[]=
245 IAC DO NAWS
246 IAC SB TERMINAL_TYPE "\x01" IAC SE
247 ;
248
249 unsigned char client_reply[256];
250
251 if (send(sock, will_echo, sizeof(will_echo), 0) < 0) {
252 return -1;
253 }
254
255 /* Now wait for client response (and ignore it) */
256 FD_ZERO(&set);
257 FD_SET(sock, &set);
258
259 do {
260 retval = select(0, &set, NULL, NULL, &timeout);
261 /* check for error */
262 if (retval < 0) {
263 return -1;
264 /* check for timeout */
265 } else if (retval == 0) {
266 return 0;
267 }
268 /* no error and no timeout, we have data in our sock */
269 received = recv(sock, (char *) client_reply, sizeof(client_reply), 0);
270 if (received <= 0) {
271 return -1;
272 }
273 } while (retval);
274
275 return 0;
276}
Definition: _set.h:50
#define NULL
Definition: types.h:112
INT WSAAPI recv(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags)
Definition: recv.c:23
INT WSAAPI select(IN INT s, IN OUT LPFD_SET readfds, IN OUT LPFD_SET writefds, IN OUT LPFD_SET exceptfds, IN CONST struct timeval *timeout)
Definition: select.c:41
INT WSAAPI send(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags)
Definition: send.c:23
r received
Definition: btrfs.c:3005
#define SE
Definition: ftp_var.h:28
#define WONT
Definition: ftp_var.h:16
#define WILL
Definition: ftp_var.h:17
#define SB
Definition: ftp_var.h:18
#define DO
Definition: ftp_var.h:15
#define DONT
Definition: ftp_var.h:14
#define IAC
Definition: ftp_var.h:13
Definition: winsock.h:66
Definition: dhcpd.h:245
#define NAWS
Definition: telnetd.h:37
#define LINEMODE
Definition: telnetd.h:38
#define TERMINAL_TYPE
Definition: telnetd.h:36
#define SUPPRESS_GO_AHEAD
Definition: telnetd.h:35
#define HANDSHAKE_TIMEOUT
Definition: telnetd.h:42
#define NEWENVIRON
Definition: telnetd.h:39
#define ECHO
Definition: telnetd.h:34
#define FD_ZERO(set)
Definition: winsock.h:96
#define FD_SET(fd, set)
Definition: winsock.h:89

Referenced by UserLoginThread().

◆ ErrorExit()

static VOID ErrorExit ( LPTSTR  lpszMessage)
static

◆ kickoff_telnetd()

int kickoff_telnetd ( void  )

Definition at line 48 of file telnetd.c.

49{
50 printf("Attempting to start Simple TelnetD\n");
51
52// DetectPlatform();
54
56 ErrorExit("Unable to start socket interface\n");
57
59
60 while(!bShutdown) {
62 }
63
64 WSACleanup();
65 return 0;
66}
BOOL WINAPI DECLSPEC_HOTPATCH SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine, BOOL Add)
Definition: console.c:2109
static const WCHAR Cleanup[]
Definition: register.c:80
#define printf
Definition: freeldr.h:97
static BOOLEAN StartSocketInterface(void)
Definition: telnetd.c:79
static void CreateSocket(void)
Definition: telnetd.c:102
static BOOLEAN bShutdown
Definition: telnetd.c:36
static void WaitForConnect(void)
Definition: telnetd.c:120

Referenced by serv_main().

◆ MonitorChildThread()

static DWORD WINAPI MonitorChildThread ( LPVOID  data)
static

Definition at line 461 of file telnetd.c.

462{
463 DWORD exitCode;
465
466 telnetd_printf("Monitor thread running...\n");
467
469
470 GetExitCodeProcess(client->hProcess, &exitCode);
471 telnetd_printf("Child process terminated with code %lx\n", exitCode);
472
473 /* signal the other threads to give up */
474 client->bTerminate = TRUE;
475
476 Sleep(500);
477
478 CloseHandle(client->hChildStdoutRd);
479 CloseHandle(client->hChildStdinWr);
480 CloseHandle(client->hProcess);
481
482 closesocket(client->socket);
483
484 telnetd_printf("Waiting for all threads to give up..\n");
485
486 while (client->bWriteToPipe || client->bReadFromPipe) {
487 telnetd_printf(".");
488 fflush(stdout);
489 Sleep(1000);
490 }
491
492 telnetd_printf("Cleanup for user '%s'\n", client->userID);
493 free(client);
494 return 0;
495}
#define free
Definition: debug_ros.c:5
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:739
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
Definition: proc.c:1168
#define INFINITE
Definition: serial.h:102
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define stdout
Definition: stdio.h:99
_Check_return_opt_ _CRTIMP int __cdecl fflush(_Inout_opt_ FILE *_File)
#define closesocket
Definition: ncftp.h:477
static FILE * client
Definition: client.c:41
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790

Referenced by RunShell().

◆ ReadFromPipeThread()

static DWORD WINAPI ReadFromPipeThread ( LPVOID  data)
static

Definition at line 545 of file telnetd.c.

546{
547 DWORD dwRead;
548 DWORD dwAvail;
549 CHAR chBuf[BUFSIZE];
550 CHAR txBuf[BUFSIZE*2];
551 DWORD from,to;
552 //char warning[] = "warning: rl_prep_terminal: cannot get terminal settings";
553
555
556 while (!client->bTerminate && client->bWriteToPipe) {
557 // Since we do not want to block, first peek...
558 if (PeekNamedPipe(client->hChildStdoutRd, NULL, 0, NULL, &dwAvail, NULL) == 0) {
559 telnetd_printf("Failed to peek in pipe\n");
560 break;
561 }
562 if (dwAvail) {
563 if( ! ReadFile( client->hChildStdoutRd, chBuf, BUFSIZE, &dwRead, NULL) ||
564 dwRead == 0) {
565 telnetd_printf("Failed to read from pipe\n");
566 break;
567 }
568 for (from=0, to=0; from<dwRead; from++, to++) {
569 txBuf[to] = chBuf[from];
570 if (txBuf[to] == '\n') {
571 txBuf[to] = '\r';
572 to++;
573 txBuf[to] = '\n';
574 }
575 }
576 if (send(client->socket, txBuf, to, 0) < 0) {
577 telnetd_printf("error writing to socket\n");
578 break;
579 }
580 }
581 Sleep(100); /* Hmmm, oh well... what the heck! */
582 }
583
584 if (!client->bTerminate)
586
587 telnetd_printf("ReadFromPipeThread terminated\n");
588
589 client->bReadFromPipe = FALSE;
590 return 0;
591}
#define BUFSIZE
Definition: discard.c:12
#define FALSE
Definition: types.h:117
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
BOOL WINAPI PeekNamedPipe(HANDLE hNamedPipe, LPVOID lpBuffer, DWORD nBufferSize, LPDWORD lpBytesRead, LPDWORD lpTotalBytesAvail, LPDWORD lpBytesLeftThisMessage)
Definition: npipe.c:1214
CardRegion * from
Definition: spigame.cpp:19
static void TerminateShell(client_t *client)
Definition: telnetd.c:594
char CHAR
Definition: xmlstorage.h:175

Referenced by RunShell().

◆ ReceiveLine()

static int ReceiveLine ( int  sock,
char buffer,
int  len,
EchoMode  echo 
)
static

Definition at line 289 of file telnetd.c.

290{
291 int i = 0;
292 int retval;
293 fd_set set;
294 struct timeval timeout = { 0, 100000 };
295 char del[3] = { BS, ' ', BS };
296 char asterisk[1] = { '*' };
297
298 FD_ZERO(&set);
299 FD_SET(sock, &set);
300
301 memset(buffer, '\0', len);
302
303 do {
304 /* When we're in echo mode, we do not need a timeout */
305 retval = select(0, &set, NULL, NULL, (echo ? NULL : &timeout) );
306 /* check for error */
307 if (retval < 0) {
308 return -1;
309 /* check for timeout */
310 } else if (retval == 0) {
311 /* return number of characters received so far */
312 return i;
313 }
314 /* no error and no timeout, we have data in our sock */
315 if (recv(sock, &buffer[i], 1, 0) <= 0) {
316 return -1;
317 }
318 if ((buffer[i] == '\0') || (buffer[i] == LF)) {
319 /* ignore null characters and linefeeds from DOS telnet clients */
320 buffer[i] = '\0';
321 } else if ((buffer[i] == DEL) || (buffer[i] == BS)) {
322 /* handle delete and backspace */
323 buffer[i] = '\0';
324 if (echo) {
325 if (i > 0) {
326 i--;
327 buffer[i] = '\0';
328 if (send(sock, del, sizeof(del), 0) < 0) {
329 return -1;
330 }
331 }
332 } else {
333 buffer[i] = BS; /* Let shell process handle it */
334 i++;
335 }
336 } else {
337 /* echo typed characters */
338 if (echo == Echo && send(sock, &buffer[i], 1, 0) < 0) {
339 return -1;
340 } else if (echo == Password && send(sock, asterisk, sizeof(asterisk), 0) < 0) {
341 return -1;
342 }
343 if (buffer[i] == CR) {
344 i++;
345 buffer[i] = LF; /* append LF for DOS command processor */
346 i++;
347 return i;
348 }
349
350 i++;
351 }
352 } while (i < len);
353
354 return i;
355}
static VOID del(LPHIST_ENTRY item)
Definition: history.c:199
GLuint buffer
Definition: glext.h:5915
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define LF
Definition: telnetd.h:24
#define BS
Definition: telnetd.h:22
#define CR
Definition: telnetd.h:23
#define DEL
Definition: telnetd.h:25
@ Password
Definition: telnetd.h:65
@ Echo
Definition: telnetd.h:64

Referenced by UserLoginThread(), and WriteToPipeThread().

◆ RunShell()

static void RunShell ( client_t client)
static

Definition at line 360 of file telnetd.c.

361{
362 HANDLE threadHandle;
363 HANDLE hChildStdinRd;
364 HANDLE hChildStdinWr;
365 HANDLE hChildStdoutRd;
366 HANDLE hChildStdoutWr;
367 STARTUPINFO si;
368 PROCESS_INFORMATION piProcInfo;
369 SECURITY_ATTRIBUTES saAttr;
370 char cmd_path[MAX_PATH];
371
373 {
375 {
377 }
378 else
379 {
380 ErrorExit("GetSystemDirectoryA failed\n");
381 }
382 }
383
384 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
385 saAttr.bInheritHandle = TRUE;
386 saAttr.lpSecurityDescriptor = NULL;
387
388 // Create a pipe for the child process's STDOUT.
389 if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
390 ErrorExit("Stdout pipe creation failed\n");
391
392 if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
393 ErrorExit("Stdin pipe creation failed\n");
394
395
396 client->bTerminate = FALSE;
397 client->bWriteToPipe = TRUE;
398 client->bReadFromPipe = TRUE;
399 client->hChildStdinWr = hChildStdinWr;
400 client->hChildStdoutRd = hChildStdoutRd;
401
402
403 // Create the child process (the shell)
404 telnetd_printf("Creating child process...\n");
405
406 ZeroMemory( &si, sizeof(STARTUPINFO) );
407 si.cb = sizeof(STARTUPINFO);
408
410 si.hStdInput = hChildStdinRd;
411 si.hStdOutput = hChildStdoutWr;
412 si.hStdError = hChildStdoutWr;
413
414 //si.dwFlags |= STARTF_USESHOWWINDOW;
415 //si.wShowWindow = SW_SHOW;
416
417 if (!CreateProcess(cmd_path, // executable module
418 NULL, // command line
419 NULL, // process security attributes
420 NULL, // primary thread security attributes
421 TRUE, // handles are inherited
422 DETACHED_PROCESS + // creation flags
424 NULL, // use parent's environment
425 NULL, // use parent's current directory
426 &si, // startup info
427 &piProcInfo)) {
428 ErrorExit("Create process failed");
429 }
430
431 client->hProcess = piProcInfo.hProcess;
432 client->dwProcessId = piProcInfo.dwProcessId;
433
434 telnetd_printf("New child created (groupid=%lu)\n", client->dwProcessId);
435
436 // No longer need these in the parent...
437 if (!CloseHandle(hChildStdoutWr))
438 ErrorExit("Closing handle failed");
439
440 if (!CloseHandle(hChildStdinRd))
441 ErrorExit("Closing handle failed");
442
443 threadHandle = CreateThread(NULL, 0, WriteToPipeThread, client, 0, NULL);
444 if (threadHandle != NULL)
445 CloseHandle(threadHandle);
446
447 threadHandle = CreateThread(NULL, 0, ReadFromPipeThread, client, 0, NULL);
448 if (threadHandle != NULL)
449 CloseHandle(threadHandle);
450
451 threadHandle = CreateThread(NULL, 0, MonitorChildThread, client, 0, NULL);
452 if (threadHandle != NULL)
453 CloseHandle(threadHandle);
454}
INT cmd_path(LPTSTR)
Definition: path.c:36
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES
#define MAX_PATH
Definition: compat.h:34
#define GetEnvironmentVariableA(x, y, z)
Definition: compat.h:754
UINT WINAPI GetSystemDirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2283
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
BOOL WINAPI CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize)
Definition: npipe.c:117
STRSAFEAPI StringCchCatA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc)
Definition: strsafe.h:320
LPVOID lpSecurityDescriptor
Definition: compat.h:193
HANDLE hStdOutput
Definition: winbase.h:872
HANDLE hStdError
Definition: winbase.h:873
DWORD dwFlags
Definition: winbase.h:867
DWORD cb
Definition: winbase.h:856
HANDLE hStdInput
Definition: winbase.h:871
static DWORD WINAPI ReadFromPipeThread(LPVOID data)
Definition: telnetd.c:545
static DWORD WINAPI MonitorChildThread(LPVOID data)
Definition: telnetd.c:461
static DWORD WINAPI WriteToPipeThread(LPVOID data)
Definition: telnetd.c:503
#define CreateProcess
Definition: winbase.h:3783
#define ZeroMemory
Definition: winbase.h:1737
STARTUPINFOA STARTUPINFO
Definition: winbase.h:3744
#define CREATE_NEW_PROCESS_GROUP
Definition: winbase.h:188
#define STARTF_USESTDHANDLES
Definition: winbase.h:525
#define DETACHED_PROCESS
Definition: winbase.h:182

Referenced by UserLoginThread().

◆ StartSocketInterface()

static BOOLEAN StartSocketInterface ( void  )
static

Definition at line 79 of file telnetd.c.

80{
81 WORD wVersionRequested;
82 WSADATA wsaData;
83 int err;
84
85 wVersionRequested = MAKEWORD( 2, 0 );
86 err = WSAStartup(wVersionRequested, &wsaData);
87 if (err != 0) {
88 telnetd_printf("requested winsock version not supported\n");
89 return 0;
90 }
91
92 bSocketInterfaceInitialised = 1; /* for ErrorExit function */
93
94 if ( wsaData.wVersion != wVersionRequested)
95 ErrorExit("requested winsock version not supported\n");
96
97 telnetd_printf("TelnetD, using %s\n", wsaData.szDescription);
98 return 1;
99}
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
unsigned short WORD
Definition: ntddk_ex.h:93
#define err(...)
char szDescription[WSADESCRIPTION_LEN+1]
Definition: winsock.h:526
WORD wVersion
Definition: winsock.h:517
#define MAKEWORD(a, b)
Definition: typedefs.h:248

Referenced by kickoff_telnetd().

◆ TerminateShell()

static void TerminateShell ( client_t client)
static

Definition at line 594 of file telnetd.c.

595{
596 DWORD exitCode;
597 DWORD dwWritten;
598 char stop[] = "\003\r\nexit\r\n"; /* Ctrl-C + exit */
599
600 GetExitCodeProcess(client->hProcess, &exitCode);
601
602 if (exitCode == STILL_ACTIVE)
603 {
605 DWORD dwWaitResult;
606
607 telnetd_printf("user shell still active, send Ctrl-Break to group-id %lu\n", client->dwProcessId );
608
610
611 if (hEvent == NULL)
612 printf("CreateEvent error\n");
613
615 telnetd_printf("Failed to send Ctrl_break\n");
616
617 if (!GenerateConsoleCtrlEvent( CTRL_C_EVENT, client->dwProcessId ))
618 telnetd_printf("Failed to send Ctrl_C\n");
619
620 if (!WriteFile(client->hChildStdinWr, stop, sizeof(stop), &dwWritten, NULL))
621 telnetd_printf("Error writing to pipe\n");
622
623 /* wait for our handler to be called */
624 dwWaitResult=WaitForSingleObject(hEvent, 500);
625
626 if (WAIT_FAILED==dwWaitResult)
627 telnetd_printf("WaitForSingleObject failed\n");
628
629 GetExitCodeProcess(client->hProcess, &exitCode);
630 if (exitCode == STILL_ACTIVE)
631 {
632 telnetd_printf("user shell still active, attempt to terminate it now...\n");
633
634 if (hEvent != NULL)
635 {
636 if (!CloseHandle(hEvent))
637 telnetd_printf("CloseHandle");
638 }
639 TerminateProcess(client->hProcess, 0);
640 }
641 TerminateProcess(client->hProcess, 0);
642 }
643 TerminateProcess(client->hProcess, 0);
644}
BOOL WINAPI DECLSPEC_HOTPATCH GenerateConsoleCtrlEvent(DWORD dwCtrlEvent, DWORD dwProcessGroupId)
Definition: console.c:2132
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1532
static HANDLE hEvent
Definition: comm.c:54
#define STILL_ACTIVE
Definition: winbase.h:259
#define CreateEvent
Definition: winbase.h:3773
#define WAIT_FAILED
Definition: winbase.h:439
#define CTRL_C_EVENT
Definition: wincon.h:68
#define CTRL_BREAK_EVENT
Definition: wincon.h:69

Referenced by ReadFromPipeThread(), and WriteToPipeThread().

◆ UserLogin()

static void UserLogin ( int  client_socket)
static

Definition at line 138 of file telnetd.c.

139{
140 HANDLE threadHandle;
141 client_t *client = malloc(sizeof(client_t));
142
143 if (client == NULL)
144 ErrorExit("failed to allocate memory for client");
145
146 client->socket = client_socket;
147 threadHandle = CreateThread(NULL, 0, UserLoginThread, client, 0, NULL);
148 if (threadHandle == NULL)
149 free(client);
150 else
151 CloseHandle(threadHandle);
152}
#define malloc
Definition: debug_ros.c:4
static DWORD WINAPI UserLoginThread(LPVOID data)
Definition: telnetd.c:155

Referenced by WaitForConnect().

◆ UserLoginThread()

static DWORD WINAPI UserLoginThread ( LPVOID  data)
static

Definition at line 155 of file telnetd.c.

156{
158 char welcome[256];
159 char hostname[64] = "Unknown";
160 char *pwdPrompt = "\r\npass:";
161 //char *logonPrompt = "\r\nLogin OK, please wait...";
162 //char *byebye = "\r\nWrong! bye bye...\r\n";
163 char userID[USERID_SIZE];
164 char password[USERID_SIZE];
165 int received;
166 char *terminator;
167
168 if (DoTelnetHandshake(client->socket)) {
169 closesocket(client->socket);
170 free(client);
171 return 0;
172 }
173
174 gethostname(hostname, sizeof(hostname));
175 sprintf(welcome, "\r\nWelcome to %s, please identify yourself\r\n\r\nuser:", hostname);
176
177 if (send(client->socket, welcome, strlen(welcome), 0) < 0) {
178 closesocket(client->socket);
179 free(client);
180 return 0;
181 }
182 received = ReceiveLine(client->socket, userID, sizeof(userID), Echo );
183 if (received < 0) {
184 closesocket(client->socket);
185 free(client);
186 return 0;
187 } else if (received) {
188 if ((terminator = strchr(userID, CR)) != NULL) {
189 *terminator = '\0';
190 }
191 }
192
193 if (send(client->socket, pwdPrompt, strlen(pwdPrompt), 0) < 0) {
194 closesocket(client->socket);
195 free(client);
196 return 0;
197 }
198 received = ReceiveLine(client->socket, password, sizeof(password), Password );
199
200#if 0
201 if (received < 0) {
202 closesocket(client->socket);
203 free(client);
204 return 0;
205 } else if (received) {
206 if ((terminator = strchr(password, CR)) != NULL) {
207 *terminator = '\0';
208 }
209 }
210#endif
211
212 /* TODO: do authentication here */
213
214
215 telnetd_printf("User '%p' logged on\n", userID);
216#if 0
217 strcpy(client->userID, userID);
218 if (send(client->socket, logonPrompt, strlen(logonPrompt), 0) < 0) {
219 closesocket(client->socket);
220 free(client);
221 return 0;
222 }
223#endif
225 return 0;
226}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
char * strchr(const char *String, int ch)
Definition: utclib.c:501
char * hostname
Definition: ftp.c:88
INT WSAAPI gethostname(OUT char FAR *name, IN INT namelen)
Definition: getxbyxx.c:397
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static WCHAR password[]
Definition: url.c:33
static void RunShell(client_t *client)
Definition: telnetd.c:360
static int ReceiveLine(int sock, char *buffer, int len, EchoMode echo)
Definition: telnetd.c:289
static int DoTelnetHandshake(int sock)
Definition: telnetd.c:229
#define USERID_SIZE
Definition: telnetd.h:20

Referenced by UserLogin().

◆ WaitForConnect()

static void WaitForConnect ( void  )
static

Definition at line 120 of file telnetd.c.

121{
122 struct sockaddr_in sa;
123 int new_sock;
124
125 if (listen(sock, 1) < 0)
126 ErrorExit("Cannot listen on socket");
127
128 if ((new_sock = accept(sock, (struct sockaddr*) &sa, NULL)) < 0) {
129 fprintf(stderr, "Failed to accept incoming call\n");
130 } else {
131 telnetd_printf("user connected on socket %d, port %d, address %lx\n", new_sock,
132 htons(sa.sin_port), sa.sin_addr.s_addr);
133 UserLogin(new_sock);
134 }
135}
INT WSAAPI listen(IN SOCKET s, IN INT backlog)
Definition: sockctrl.c:123
SOCKET WSAAPI accept(IN SOCKET s, OUT LPSOCKADDR addr, OUT INT FAR *addrlen)
Definition: socklife.c:23
static void UserLogin(int client_socket)
Definition: telnetd.c:138

Referenced by kickoff_telnetd().

◆ WriteToPipeThread()

static DWORD WINAPI WriteToPipeThread ( LPVOID  data)
static

Definition at line 503 of file telnetd.c.

504{
505 int iRead;
506 DWORD dwWritten;
507 CHAR chBuf[BUFSIZE];
509
510 while (!client->bTerminate) {
511 iRead = ReceiveLine(client->socket, chBuf, BUFSIZE, FALSE);
512 if (iRead < 0) {
513 telnetd_printf("Client disconnect\n");
514 break;
515 } else if (iRead > 0) {
516 if (strchr(chBuf, CTRLC)) {
518 }
519 if (send(client->socket, chBuf, iRead, 0) < 0) {
520 telnetd_printf("error writing to socket\n");
521 break;
522 }
523 if (! WriteFile(client->hChildStdinWr, chBuf, (DWORD) iRead, &dwWritten, NULL)) {
524 telnetd_printf("Error writing to pipe\n");
525 break;
526 }
527 }
528 }
529
530 if (!client->bTerminate)
532
533 telnetd_printf("WriteToPipeThread terminated\n");
534
535 client->bWriteToPipe = FALSE;
536 return 0;
537}
#define CTRLC
Definition: telnetd.h:21

Referenced by RunShell().

Variable Documentation

◆ bShutdown

BOOLEAN bShutdown = 0
static

Definition at line 36 of file telnetd.c.

Referenced by kickoff_telnetd().

◆ bSocketInterfaceInitialised

BOOLEAN bSocketInterfaceInitialised = 0
static

Definition at line 37 of file telnetd.c.

Referenced by Cleanup(), ErrorExit(), and StartSocketInterface().

◆ sock

int sock
static

Definition at line 38 of file telnetd.c.