ReactOS  0.4.12-dev-57-g7050ac4
telnetd.c
Go to the documentation of this file.
1 /*
2  * Abstract: a simple telnet 'daemon' for Windows hosts.
3  *
4  * Compiled & run successfully using MSVC 5.0 under Windows95 (requires
5  * Winsock2 update) and Windows98 and MSVC 6.0 under WindowsNT4
6  *
7  * Compiler options : no special options needed
8  * Linker options : add wsock32.lib or ws2_32.lib
9  *
10  * Written by fred.van.lieshout 'at' zonnet.nl
11  * Use freely, no copyrights.
12  * Use Linux.
13  *
14  * Parts Copyright Steven Edwards
15  * Public Domain
16  *
17  * TODO:
18  * - access control
19  * - will/won't handshake
20  * - Unify Debugging output and return StatusCodes
21  */
22 
23 #include "telnetd.h"
24 
25 #define telnetd_printf printf
26 #if 0
27 static inline int telnetd_printf(const char *format, ...);
28 {
29  printf(format,...);
30  syslog (6, format);
31 }
32 #endif
33 
34 /* Local data */
35 
36 static BOOLEAN bShutdown = 0;
38 static int sock;
39 
40 /* In the future, some options might be passed here to handle
41  * authentication options in the registry or command line
42  * options passed to the service
43  *
44  * Once you are ready to turn on the service
45  * rename this function
46  * int kickoff_telnetd(void)
47  */
48 int kickoff_telnetd(void)
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 }
67 
68 /* Cleanup */
69 static BOOL WINAPI Cleanup(DWORD dwControlType)
70 {
72  telnetd_printf("Cleanup...\n");
73  WSACleanup();
74  }
75  return 0;
76 }
77 
78 /* StartSocketInterface */
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 }
100 
101 /* CreateSocket */
102 static void CreateSocket(void)
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 }
118 
119 /* WaitForConnect */
120 static void WaitForConnect(void)
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 }
136 
137 /* Function: UserLogin */
138 static void UserLogin(int client_socket)
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 }
153 
154 /* Function: UserLoginThread */
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 }
227 
228 /* Function: DoTelnetHandshake */
229 static int DoTelnetHandshake(int sock)
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 }
277 
278 /*
279 ** Function: ReceiveLine
280 **
281 ** Abstract: receive until timeout or CR
282 ** In : sock, len
283 ** Out : buffer
284 ** Result : int
285 ** Pre : 'sock' must be valid socket
286 ** Post : (result = the number of bytes read into 'buffer')
287 ** OR (result = -1 and error)
288 */
289 static int ReceiveLine(int sock, char *buffer, int len, EchoMode echo)
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 }
356 
357 /*
358 ** Function: RunShell
359 */
360 static void RunShell(client_t *client)
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 }
455 
456 /*
457  * Function: MonitorChildThread
458  *
459  * Abstract: Monitor the child (shell) process
460  */
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 }
496 
497 /*
498  * Function: WriteToPipeThread
499  *
500  * Abstract: read data from the telnet client socket
501  * and pass it on to the shell process.
502  */
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 }
538 
539 /*
540  * Function: ReadFromPipeThread
541  *
542  * Abstract: Read data from the shell's stdout handle and
543  * pass it on to the telnet client socket.
544  */
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 }
592 
593 /* TerminateShell */
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 }
645 
646 /* ErrorExit */
647 static VOID ErrorExit (LPTSTR lpszMessage)
648 {
649  fprintf(stderr, "%s\n", lpszMessage);
651  telnetd_printf("WSAGetLastError=%d\n", WSAGetLastError());
652  WSACleanup();
653  }
654  ExitProcess(0);
655 }
656 
#define CreateEvent
Definition: winbase.h:3562
Definition: winsock.h:66
static void RunShell(client_t *client)
Definition: telnetd.c:360
HANDLE hChildStdinWr
Definition: telnetd.h:57
HANDLE hProcess
Definition: telnetd.h:55
#define TRUE
Definition: types.h:120
#define TELNET_PORT
Definition: telnetd.h:17
#define CloseHandle
Definition: compat.h:398
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:736
#define CTRL_BREAK_EVENT
Definition: wincon.h:66
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
u_short sin_port
Definition: winsock.h:511
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 MAKEWORD(a, b)
Definition: typedefs.h:247
int kickoff_telnetd(void)
Definition: telnetd.c:48
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
#define DONT
Definition: ftp_var.h:14
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
Definition: proc.c:1198
WORD wVersion
Definition: winsock.h:517
#define HANDSHAKE_TIMEOUT
Definition: telnetd.h:42
char CHAR
Definition: xmlstorage.h:175
#define free
Definition: debug_ros.c:5
#define USERID_SIZE
Definition: telnetd.h:20
INT WSAAPI WSACleanup(VOID)
Definition: startup.c:60
r received
Definition: btrfs.c:2639
static void UserLogin(int client_socket)
Definition: telnetd.c:138
#define CTRL_C_EVENT
Definition: wincon.h:65
UINT WINAPI GetSystemDirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2282
#define WILL
Definition: ftp_var.h:17
#define CTRLC
Definition: telnetd.h:21
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1517
#define INADDR_ANY
Definition: StrAddr.c:4
#define ZeroMemory
Definition: winbase.h:1635
GLuint buffer
Definition: glext.h:5915
DWORD dwFlags
Definition: winbase.h:807
static BOOLEAN StartSocketInterface(void)
Definition: telnetd.c:79
void syslog(int pri, char *fmt,...)
Definition: syslog.c:261
static BOOL WINAPI Cleanup(DWORD dwControlType)
Definition: telnetd.c:69
#define FD_ZERO(set)
Definition: winsock.h:96
INT cmd_path(LPTSTR)
Definition: path.c:36
#define FD_SET(fd, set)
Definition: winsock.h:89
#define CREATE_NEW_PROCESS_GROUP
Definition: winbase.h:185
BOOLEAN bWriteToPipe
Definition: telnetd.h:54
CHAR * LPTSTR
Definition: xmlstorage.h:192
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
FILE * stdout
#define SUPPRESS_GO_AHEAD
Definition: telnetd.h:35
static HANDLE hEvent
Definition: comm.c:54
char * hostname
Definition: ftp.c:88
#define DO
Definition: ftp_var.h:15
#define sprintf(buf, format,...)
Definition: sprintf.c:55
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
GLenum GLclampf GLint i
Definition: glfuncs.h:14
static DWORD WINAPI UserLoginThread(LPVOID data)
Definition: telnetd.c:155
#define TERMINAL_TYPE
Definition: telnetd.h:36
BOOL WINAPI DECLSPEC_HOTPATCH GenerateConsoleCtrlEvent(DWORD dwCtrlEvent, DWORD dwProcessGroupId)
Definition: console.c:2134
#define closesocket
Definition: main.c:39
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
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
STRSAFEAPI StringCchCatA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc)
Definition: strsafe.h:320
INT WSAAPI gethostname(OUT char FAR *name, IN INT namelen)
Definition: getxbyxx.c:397
BOOL WINAPI DECLSPEC_HOTPATCH SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine, BOOL Add)
Definition: console.c:2111
struct _ACPI_EFI_BOOT_SERVICES * BS
#define LINEMODE
Definition: telnetd.h:38
unsigned char BOOLEAN
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
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
smooth NULL
Definition: ftsmooth.c:416
static void TerminateShell(client_t *client)
Definition: telnetd.c:594
static int sock
Definition: telnetd.c:38
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
static DWORD WINAPI WriteToPipeThread(LPVOID data)
Definition: telnetd.c:503
BOOLEAN bReadFromPipe
Definition: telnetd.h:53
#define STARTF_USESTDHANDLES
Definition: winbase.h:480
#define LF
Definition: telnetd.h:24
INT WSAAPI WSAGetLastError(VOID)
Definition: dllmain.c:112
unsigned int BOOL
Definition: ntddk_ex.h:94
DWORD cb
Definition: winbase.h:796
#define GetEnvironmentVariableA(x, y, z)
Definition: compat.h:411
#define STILL_ACTIVE
Definition: winbase.h:230
INT WSAAPI send(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags)
Definition: send.c:23
static BOOLEAN bShutdown
Definition: telnetd.c:36
static int DoTelnetHandshake(int sock)
Definition: telnetd.c:229
static BOOLEAN bSocketInterfaceInitialised
Definition: telnetd.c:37
EchoMode
Definition: telnetd.h:61
#define MAX_PATH
Definition: compat.h:26
BOOLEAN bTerminate
Definition: telnetd.h:52
static FILE * client
Definition: client.c:41
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
#define WAIT_FAILED
Definition: winbase.h:394
HANDLE hStdOutput
Definition: winbase.h:812
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define ECHO
Definition: macro.lex.yy.c:619
#define SB
Definition: ftp_var.h:18
#define NAWS
Definition: telnetd.h:37
T1_FIELD_DICT_PRIVATE password
Definition: t1tokens.h:64
GLenum GLsizei len
Definition: glext.h:6722
static DWORD WINAPI MonitorChildThread(LPVOID data)
Definition: telnetd.c:461
#define err(...)
#define CreateProcess
Definition: winbase.h:3572
SOCKET WSAAPI accept(IN SOCKET s, OUT LPSOCKADDR addr, OUT INT FAR *addrlen)
Definition: socklife.c:23
char szDescription[WSADESCRIPTION_LEN+1]
Definition: winsock.h:526
BOOL WINAPI CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize)
Definition: npipe.c:117
#define WINAPI
Definition: msvc.h:20
DWORD dwProcessId
Definition: telnetd.h:56
#define SE
Definition: ftp_var.h:28
struct in_addr sin_addr
Definition: winsock.h:512
static VOID del(LPHIST_ENTRY item)
Definition: history.c:199
STRSAFEAPI StringCchCopyA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc)
Definition: strsafe.h:145
LPVOID lpSecurityDescriptor
Definition: compat.h:181
char userID[USERID_SIZE]
Definition: telnetd.h:50
int socket
Definition: telnetd.h:51
STARTUPINFOA STARTUPINFO
Definition: winbase.h:3533
HANDLE hStdInput
Definition: winbase.h:811
_Check_return_opt_ _CRTIMP int __cdecl fflush(_Inout_opt_ FILE *_File)
static void CreateSocket(void)
Definition: telnetd.c:102
static VOID ErrorExit(LPTSTR lpszMessage)
Definition: telnetd.c:647
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1562
#define DETACHED_PROCESS
Definition: winbase.h:179
#define telnetd_printf
Definition: telnetd.c:25
#define IAC
Definition: ftp_var.h:13
INT WSAAPI listen(IN SOCKET s, IN INT backlog)
Definition: sockctrl.c:123
char * strchr(const char *String, int ch)
Definition: utclib.c:501
Definition: tcpcore.h:1455
#define DEL
Definition: telnetd.h:25
#define NEWENVIRON
Definition: telnetd.h:39
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
FILE * stderr
#define AF_INET
Definition: tcpip.h:117
HANDLE hChildStdoutRd
Definition: telnetd.h:58
#define malloc
Definition: debug_ros.c:4
#define WONT
Definition: ftp_var.h:16
#define SOCK_STREAM
Definition: tcpip.h:118
static DWORD WINAPI ReadFromPipeThread(LPVOID data)
Definition: telnetd.c:545
#define htons(x)
Definition: module.h:213
CardRegion * from
Definition: spigame.cpp:19
#define INFINITE
Definition: serial.h:102
static void WaitForConnect(void)
Definition: telnetd.c:120
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 memset(x, y, z)
Definition: compat.h:39
#define BUFSIZE
Definition: discard.c:12
HANDLE hStdError
Definition: winbase.h:813
INT WSAAPI recv(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags)
Definition: recv.c:23
short sin_family
Definition: winsock.h:510
#define CR
Definition: telnetd.h:23
BOOL WINAPI PeekNamedPipe(HANDLE hNamedPipe, LPVOID lpBuffer, DWORD nBufferSize, LPDWORD lpBytesRead, LPDWORD lpTotalBytesAvail, LPDWORD lpBytesLeftThisMessage)
Definition: npipe.c:1214
Definition: telnetd.h:64
struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES
#define printf
Definition: config.h:203