ReactOS  0.4.11-dev-946-g431643b
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

Function Documentation

◆ Cleanup()

static BOOL WINAPI Cleanup ( DWORD  dwControlType)
static

Definition at line 69 of file telnetd.c.

Referenced by kickoff_telnetd().

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

◆ CreateSocket()

static void CreateSocket ( void  )
static

Definition at line 102 of file telnetd.c.

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

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 }
#define TELNET_PORT
Definition: telnetd.h:17
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
#define INADDR_ANY
Definition: StrAddr.c:4
static VOID ErrorExit(LPTSTR lpszMessage)
Definition: telnetd.c:647
Definition: tcpcore.h:1455
#define AF_INET
Definition: tcpip.h:117
#define SOCK_STREAM
Definition: tcpip.h:118
#define htons(x)
Definition: module.h:213
#define memset(x, y, z)
Definition: compat.h:39
static struct sockaddr_in sa
Definition: adnsresfilter.c:69

◆ DoTelnetHandshake()

static int DoTelnetHandshake ( int  sock)
static

Definition at line 229 of file telnetd.c.

Referenced by UserLoginThread().

230 {
231  int retval;
232  int received;
233  fd_set set;
234  struct timeval timeout = { HANDSHAKE_TIMEOUT, 0 };
235 
236  char will_echo[]=
237  IAC DONT ECHO
238  IAC WILL ECHO
239  IAC WILL NAWS
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: winsock.h:66
#define DONT
Definition: ftp_var.h:14
#define HANDSHAKE_TIMEOUT
Definition: telnetd.h:42
r received
Definition: btrfs.c:2639
#define WILL
Definition: ftp_var.h:17
Definition: dhcpd.h:245
#define FD_ZERO(set)
Definition: winsock.h:96
#define FD_SET(fd, set)
Definition: winsock.h:89
#define SUPPRESS_GO_AHEAD
Definition: telnetd.h:35
#define DO
Definition: ftp_var.h:15
#define TERMINAL_TYPE
Definition: telnetd.h:36
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
#define LINEMODE
Definition: telnetd.h:38
smooth NULL
Definition: ftsmooth.c:416
INT WSAAPI send(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags)
Definition: send.c:23
#define ECHO
Definition: macro.lex.yy.c:619
#define SB
Definition: ftp_var.h:18
#define NAWS
Definition: telnetd.h:37
#define SE
Definition: ftp_var.h:28
#define IAC
Definition: ftp_var.h:13
Definition: tcpcore.h:1455
#define NEWENVIRON
Definition: telnetd.h:39
#define WONT
Definition: ftp_var.h:16
INT WSAAPI recv(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags)
Definition: recv.c:23

◆ ErrorExit()

static VOID ErrorExit ( LPTSTR  lpszMessage)
static

Definition at line 647 of file telnetd.c.

Referenced by AcpiDsExecBeginOp(), AcpiEvAsynchExecuteGpeMethod(), AcpiEvCreateGpeInfoBlocks(), AcpiEvDetectGpe(), AcpiInstallMethod(), AcpiNsConvertToReference(), AcpiNsInitializeDevices(), AcpiUtCopyEsimpleToIsimple(), AcpiUtCopyIelementToIelement(), AcpiUtUpdateObjectReference(), CreateSocket(), IopValidateID(), kickoff_telnetd(), MENU_TrackMenu(), RunShell(), StartSocketInterface(), URL_ParseUrl(), USBH_CreateDevice(), USBH_PortIdleNotificationCancelRoutine(), USBH_ResetDevice(), USBH_StartHubFdoDevice(), USBH_SyncGetHubDescriptor(), USBPORT_CreateDevice(), UserLogin(), and WaitForConnect().

648 {
649  fprintf(stderr, "%s\n", lpszMessage);
651  telnetd_printf("WSAGetLastError=%d\n", WSAGetLastError());
652  WSACleanup();
653  }
654  ExitProcess(0);
655 }
INT WSAAPI WSACleanup(VOID)
Definition: startup.c:60
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1517
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
INT WSAAPI WSAGetLastError(VOID)
Definition: dllmain.c:112
static BOOLEAN bSocketInterfaceInitialised
Definition: telnetd.c:37
#define telnetd_printf
Definition: telnetd.c:25
FILE * stderr

◆ kickoff_telnetd()

int kickoff_telnetd ( void  )

Definition at line 48 of file telnetd.c.

Referenced by serv_main().

49 {
50  printf("Attempting to start Simple TelnetD\n");
51 
52 // DetectPlatform();
54 
55  if (!StartSocketInterface())
56  ErrorExit("Unable to start socket interface\n");
57 
58  CreateSocket();
59 
60  while(!bShutdown) {
62  }
63 
64  WSACleanup();
65  return 0;
66 }
INT WSAAPI WSACleanup(VOID)
Definition: startup.c:60
static BOOLEAN StartSocketInterface(void)
Definition: telnetd.c:79
static BOOL WINAPI Cleanup(DWORD dwControlType)
Definition: telnetd.c:69
BOOL WINAPI DECLSPEC_HOTPATCH SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine, BOOL Add)
Definition: console.c:2111
static BOOLEAN bShutdown
Definition: telnetd.c:36
static void CreateSocket(void)
Definition: telnetd.c:102
static VOID ErrorExit(LPTSTR lpszMessage)
Definition: telnetd.c:647
static void WaitForConnect(void)
Definition: telnetd.c:120
#define printf
Definition: config.h:203

◆ MonitorChildThread()

static DWORD WINAPI MonitorChildThread ( LPVOID  data)
static

Definition at line 461 of file telnetd.c.

Referenced by RunShell().

462 {
463  DWORD exitCode;
464  client_t *client = (client_t *) data;
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 }
HANDLE hChildStdinWr
Definition: telnetd.h:57
HANDLE hProcess
Definition: telnetd.h:55
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:736
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
Definition: proc.c:1198
#define free
Definition: debug_ros.c:5
BOOLEAN bWriteToPipe
Definition: telnetd.h:54
FILE * stdout
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define closesocket
Definition: main.c:39
BOOLEAN bReadFromPipe
Definition: telnetd.h:53
BOOLEAN bTerminate
Definition: telnetd.h:52
static FILE * client
Definition: client.c:41
unsigned long DWORD
Definition: ntddk_ex.h:95
char userID[USERID_SIZE]
Definition: telnetd.h:50
int socket
Definition: telnetd.h:51
_Check_return_opt_ _CRTIMP int __cdecl fflush(_Inout_opt_ FILE *_File)
#define telnetd_printf
Definition: telnetd.c:25
HANDLE hChildStdoutRd
Definition: telnetd.h:58
#define INFINITE
Definition: serial.h:102

◆ ReadFromPipeThread()

static DWORD WINAPI ReadFromPipeThread ( LPVOID  data)
static

Definition at line 545 of file telnetd.c.

Referenced by RunShell().

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 
554  client_t *client = (client_t *) data;
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)
585  TerminateShell(client);
586 
587  telnetd_printf("ReadFromPipeThread terminated\n");
588 
589  client->bReadFromPipe = FALSE;
590  return 0;
591 }
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:736
char CHAR
Definition: xmlstorage.h:175
BOOLEAN bWriteToPipe
Definition: telnetd.h:54
smooth NULL
Definition: ftsmooth.c:416
static void TerminateShell(client_t *client)
Definition: telnetd.c:594
BOOLEAN bReadFromPipe
Definition: telnetd.h:53
INT WSAAPI send(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags)
Definition: send.c:23
BOOLEAN bTerminate
Definition: telnetd.h:52
static FILE * client
Definition: client.c:41
unsigned long DWORD
Definition: ntddk_ex.h:95
int socket
Definition: telnetd.h:51
#define telnetd_printf
Definition: telnetd.c:25
HANDLE hChildStdoutRd
Definition: telnetd.h:58
CardRegion * from
Definition: spigame.cpp:19
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:123
#define BUFSIZE
Definition: discard.c:12
BOOL WINAPI PeekNamedPipe(HANDLE hNamedPipe, LPVOID lpBuffer, DWORD nBufferSize, LPDWORD lpBytesRead, LPDWORD lpTotalBytesAvail, LPDWORD lpBytesLeftThisMessage)
Definition: npipe.c:1214

◆ ReceiveLine()

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

Definition at line 289 of file telnetd.c.

Referenced by UserLoginThread(), and WriteToPipeThread().

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 }
Definition: winsock.h:66
GLuint buffer
Definition: glext.h:5915
Definition: dhcpd.h:245
#define FD_ZERO(set)
Definition: winsock.h:96
#define FD_SET(fd, set)
Definition: winsock.h:89
GLenum GLclampf GLint i
Definition: glfuncs.h:14
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
struct _ACPI_EFI_BOOT_SERVICES * BS
smooth NULL
Definition: ftsmooth.c:416
#define LF
Definition: telnetd.h:24
INT WSAAPI send(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags)
Definition: send.c:23
GLenum GLsizei len
Definition: glext.h:6722
static VOID del(LPHIST_ENTRY item)
Definition: history.c:199
Definition: tcpcore.h:1455
#define DEL
Definition: telnetd.h:25
#define memset(x, y, z)
Definition: compat.h:39
INT WSAAPI recv(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags)
Definition: recv.c:23
#define CR
Definition: telnetd.h:23
Definition: telnetd.h:64

◆ RunShell()

static void RunShell ( client_t client)
static

Definition at line 360 of file telnetd.c.

Referenced by UserLoginThread().

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 
372  if (!GetEnvironmentVariableA("COMSPEC", cmd_path, ARRAYSIZE(cmd_path)))
373  {
374  if (GetSystemDirectoryA(cmd_path, ARRAYSIZE(cmd_path)))
375  {
376  StringCchCatA(cmd_path, ARRAYSIZE(cmd_path), "\\cmd.exe");
377  }
378  else
379  {
380  StringCchCopyA(cmd_path, ARRAYSIZE(cmd_path), "C:\\ReactOS\\system32\\cmd.exe");
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 }
HANDLE hChildStdinWr
Definition: telnetd.h:57
HANDLE hProcess
Definition: telnetd.h:55
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
UINT WINAPI GetSystemDirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2282
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define ZeroMemory
Definition: winbase.h:1635
DWORD dwFlags
Definition: winbase.h:807
INT cmd_path(LPTSTR)
Definition: path.c:36
#define CREATE_NEW_PROCESS_GROUP
Definition: winbase.h:185
BOOLEAN bWriteToPipe
Definition: telnetd.h:54
STRSAFEAPI StringCchCatA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc)
Definition: strsafe.h:320
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:112
smooth NULL
Definition: ftsmooth.c:416
static DWORD WINAPI WriteToPipeThread(LPVOID data)
Definition: telnetd.c:503
BOOLEAN bReadFromPipe
Definition: telnetd.h:53
#define STARTF_USESTDHANDLES
Definition: winbase.h:480
DWORD cb
Definition: winbase.h:796
#define GetEnvironmentVariableA(x, y, z)
Definition: compat.h:411
#define MAX_PATH
Definition: compat.h:26
BOOLEAN bTerminate
Definition: telnetd.h:52
HANDLE hStdOutput
Definition: winbase.h:812
static DWORD WINAPI MonitorChildThread(LPVOID data)
Definition: telnetd.c:461
#define CreateProcess
Definition: winbase.h:3572
BOOL WINAPI CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize)
Definition: npipe.c:117
DWORD dwProcessId
Definition: telnetd.h:56
STRSAFEAPI StringCchCopyA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc)
Definition: strsafe.h:145
LPVOID lpSecurityDescriptor
Definition: compat.h:181
STARTUPINFOA STARTUPINFO
Definition: winbase.h:3533
HANDLE hStdInput
Definition: winbase.h:811
static VOID ErrorExit(LPTSTR lpszMessage)
Definition: telnetd.c:647
#define DETACHED_PROCESS
Definition: winbase.h:179
#define telnetd_printf
Definition: telnetd.c:25
HANDLE hChildStdoutRd
Definition: telnetd.h:58
static DWORD WINAPI ReadFromPipeThread(LPVOID data)
Definition: telnetd.c:545
HANDLE hStdError
Definition: winbase.h:813
struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES

◆ StartSocketInterface()

static BOOLEAN StartSocketInterface ( void  )
static

Definition at line 79 of file telnetd.c.

Referenced by kickoff_telnetd().

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 }
#define MAKEWORD(a, b)
Definition: typedefs.h:247
WORD wVersion
Definition: winsock.h:517
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
static BOOLEAN bSocketInterfaceInitialised
Definition: telnetd.c:37
unsigned short WORD
Definition: ntddk_ex.h:93
#define err(...)
char szDescription[WSADESCRIPTION_LEN+1]
Definition: winsock.h:526
static VOID ErrorExit(LPTSTR lpszMessage)
Definition: telnetd.c:647
#define telnetd_printf
Definition: telnetd.c:25

◆ TerminateShell()

static void TerminateShell ( client_t client)
static

Definition at line 594 of file telnetd.c.

Referenced by ReadFromPipeThread(), and WriteToPipeThread().

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  {
604  HANDLE hEvent = NULL;
605  DWORD dwWaitResult;
606 
607  telnetd_printf("user shell still active, send Ctrl-Break to group-id %lu\n", client->dwProcessId );
608 
609  hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
610 
611  if (hEvent == NULL)
612  printf("CreateEvent error\n");
613 
615  telnetd_printf("Failed to send Ctrl_break\n");
616 
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 }
#define CreateEvent
Definition: winbase.h:3562
HANDLE hChildStdinWr
Definition: telnetd.h:57
HANDLE hProcess
Definition: telnetd.h:55
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
#define CTRL_BREAK_EVENT
Definition: wincon.h:66
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
Definition: proc.c:1198
#define CTRL_C_EVENT
Definition: wincon.h:65
static HANDLE hEvent
Definition: comm.c:54
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
BOOL WINAPI DECLSPEC_HOTPATCH GenerateConsoleCtrlEvent(DWORD dwCtrlEvent, DWORD dwProcessGroupId)
Definition: console.c:2134
smooth NULL
Definition: ftsmooth.c:416
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
#define STILL_ACTIVE
Definition: winbase.h:230
unsigned long DWORD
Definition: ntddk_ex.h:95
#define WAIT_FAILED
Definition: winbase.h:394
DWORD dwProcessId
Definition: telnetd.h:56
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1562
#define telnetd_printf
Definition: telnetd.c:25
#define printf
Definition: config.h:203

◆ UserLogin()

static void UserLogin ( int  client_socket)
static

Definition at line 138 of file telnetd.c.

Referenced by WaitForConnect().

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 CloseHandle
Definition: compat.h:398
#define free
Definition: debug_ros.c:5
static DWORD WINAPI UserLoginThread(LPVOID data)
Definition: telnetd.c:155
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:112
smooth NULL
Definition: ftsmooth.c:416
static FILE * client
Definition: client.c:41
int socket
Definition: telnetd.h:51
static VOID ErrorExit(LPTSTR lpszMessage)
Definition: telnetd.c:647
#define malloc
Definition: debug_ros.c:4

◆ UserLoginThread()

static DWORD WINAPI UserLoginThread ( LPVOID  data)
static

Definition at line 155 of file telnetd.c.

Referenced by UserLogin().

156 {
157  client_t *client = (client_t *) data;
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
224  RunShell(client);
225  return 0;
226 }
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
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define free
Definition: debug_ros.c:5
#define USERID_SIZE
Definition: telnetd.h:20
r received
Definition: btrfs.c:2639
char * hostname
Definition: ftp.c:88
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define closesocket
Definition: main.c:39
INT WSAAPI gethostname(OUT char FAR *name, IN INT namelen)
Definition: getxbyxx.c:397
smooth NULL
Definition: ftsmooth.c:416
INT WSAAPI send(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags)
Definition: send.c:23
static int DoTelnetHandshake(int sock)
Definition: telnetd.c:229
static FILE * client
Definition: client.c:41
T1_FIELD_DICT_PRIVATE password
Definition: t1tokens.h:64
char userID[USERID_SIZE]
Definition: telnetd.h:50
int socket
Definition: telnetd.h:51
#define telnetd_printf
Definition: telnetd.c:25
char * strchr(const char *String, int ch)
Definition: utclib.c:501
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define CR
Definition: telnetd.h:23
Definition: telnetd.h:64

◆ WaitForConnect()

static void WaitForConnect ( void  )
static

Definition at line 120 of file telnetd.c.

Referenced by kickoff_telnetd().

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 }
static void UserLogin(int client_socket)
Definition: telnetd.c:138
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
smooth NULL
Definition: ftsmooth.c:416
SOCKET WSAAPI accept(IN SOCKET s, OUT LPSOCKADDR addr, OUT INT FAR *addrlen)
Definition: socklife.c:23
static VOID ErrorExit(LPTSTR lpszMessage)
Definition: telnetd.c:647
#define telnetd_printf
Definition: telnetd.c:25
INT WSAAPI listen(IN SOCKET s, IN INT backlog)
Definition: sockctrl.c:123
Definition: tcpcore.h:1455
FILE * stderr
#define htons(x)
Definition: module.h:213
static struct sockaddr_in sa
Definition: adnsresfilter.c:69

◆ WriteToPipeThread()

static DWORD WINAPI WriteToPipeThread ( LPVOID  data)
static

Definition at line 503 of file telnetd.c.

Referenced by RunShell().

504 {
505  int iRead;
506  DWORD dwWritten;
507  CHAR chBuf[BUFSIZE];
508  client_t *client = (client_t *) data;
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)
531  TerminateShell(client);
532 
533  telnetd_printf("WriteToPipeThread terminated\n");
534 
535  client->bWriteToPipe = FALSE;
536  return 0;
537 }
HANDLE hChildStdinWr
Definition: telnetd.h:57
static int ReceiveLine(int sock, char *buffer, int len, EchoMode echo)
Definition: telnetd.c:289
char CHAR
Definition: xmlstorage.h:175
#define CTRL_C_EVENT
Definition: wincon.h:65
#define CTRLC
Definition: telnetd.h:21
BOOLEAN bWriteToPipe
Definition: telnetd.h:54
BOOL WINAPI DECLSPEC_HOTPATCH GenerateConsoleCtrlEvent(DWORD dwCtrlEvent, DWORD dwProcessGroupId)
Definition: console.c:2134
smooth NULL
Definition: ftsmooth.c:416
static void TerminateShell(client_t *client)
Definition: telnetd.c:594
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
INT WSAAPI send(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags)
Definition: send.c:23
BOOLEAN bTerminate
Definition: telnetd.h:52
static FILE * client
Definition: client.c:41
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD dwProcessId
Definition: telnetd.h:56
int socket
Definition: telnetd.h:51
#define telnetd_printf
Definition: telnetd.c:25
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define BUFSIZE
Definition: discard.c:12

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.