- Some formating changes

- Remove unneeded spec, just use the comments
- Syslog interface for my wine usage, disabled in ReactOS tree
 but included here to reduce my diff.


svn path=/trunk/; revision=39432
This commit is contained in:
Steven Edwards 2009-02-06 08:22:18 +00:00
parent fb23e17854
commit 7f0c18cb38
4 changed files with 579 additions and 95 deletions

View file

@ -1,8 +0,0 @@
Here is the short product spec
1. Fix the service stuff
2. Use the event log
3. Do real authentication (LogonUser[Ex]+CreateProcessAsUser maybe?)
4. Properly Set the environment

View file

@ -0,0 +1,308 @@
/*
* syslog-client.c - syslog client implementation for windows
*
* Created by Alexander Yaworsky
*
* THIS SOFTWARE IS NOT COPYRIGHTED
*
* This source code is offered for use in the public domain. You may
* use, modify or distribute it freely.
*
* This code is distributed in the hope that it will be useful but
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
* DISCLAIMED. This includes but is not limited to warranties of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
/* define SYSLOG_CONF_DIR where syslog.host should be
*/
#ifndef SYSLOG_CONF_DIR
static const char *syslog_conf_dir = ".";
#else
static const char *syslog_conf_dir = SYSLOG_CONF_DIR;
#endif
#include <stdio.h>
#include <string.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include "syslog.h"
#ifdef TEST
# define SYSLOG_DGRAM_SIZE 80
#else
# define SYSLOG_DGRAM_SIZE 1024
#endif
static BOOL initialized = FALSE;
static int log_mask = 0xFF;
static char *syslog_ident;
static int syslog_facility;
static char str_pid[ 40 ];
static SOCKADDR_IN sa_logger;
static SOCKET sock;
static char local_hostname[ MAX_COMPUTERNAME_LENGTH + 1 ];
static char datagramm[ SYSLOG_DGRAM_SIZE ];
static int datagramm_size;
/******************************************************************************
* set_syslog_conf_dir
*
* maybe this function will be useful...
*/
const char* set_syslog_conf_dir( const char* dir )
{
const char *ret = syslog_conf_dir;
syslog_conf_dir = dir;
return ret;
}
/******************************************************************************
* init_logger_addr
*
* Read configuration file syslog.host. This file should contain host address
* and, optionally, port. Initialize sa_logger. If the configuration file does
* not exist, use localhost:514.
* Returns: 0 - ok, -1 - error.
*/
static void init_logger_addr()
{
char pathname[ FILENAME_MAX ];
char *p;
FILE *fd;
char host[256];
struct hostent * phe;
memset( &sa_logger, 0, sizeof(SOCKADDR_IN) );
sa_logger.sin_family = AF_INET;
if( '\\' == syslog_conf_dir[0] || '/' == syslog_conf_dir[0] || ':' == syslog_conf_dir[1] )
{
/* absolute path */
strcpy( pathname, syslog_conf_dir );
}
else
{
/* relative path */
char *q;
strcpy( pathname, __argv[0] );
p = strrchr( pathname, '\\' ) + 1;
q = strrchr( pathname, '/' ) + 1;
if( p < q )
*q = 0;
else if( p > q )
*p = 0;
else
pathname[0] = 0;
strcat( pathname, syslog_conf_dir );
}
p = &pathname[ strlen( pathname ) - 1 ];
if( '\\' != *p && '/' != *p )
{
p++; *p = '/';
}
strcpy( ++p, "syslog.host" );
/* read destination host name */
fd = fopen( pathname, "r" );
if( !fd )
goto use_default;
if( NULL == fgets( host, sizeof(host), fd ) )
host[0] = 0;
else
{
p = strchr( host, '\n' );
if( p )
*p = 0;
p = strchr( host, '\r' );
if( p )
*p = 0;
}
fclose( fd );
p = strchr( host, ':' );
if( p )
*p++ = 0;
phe = gethostbyname( host );
if( !phe )
goto use_default;
memcpy( &sa_logger.sin_addr.s_addr, phe->h_addr, phe->h_length );
if( p )
sa_logger.sin_port = htons( (unsigned short) strtoul( p, NULL, 0 ) );
else
sa_logger.sin_port = htons( SYSLOG_PORT );
return;
use_default:
sa_logger.sin_addr.S_un.S_addr = htonl( 0x7F000001 );
sa_logger.sin_port = htons( SYSLOG_PORT );
}
/******************************************************************************
* closelog
*
* Close desriptor used to write to system logger.
*/
void closelog()
{
if( !initialized )
return;
closesocket( sock );
WSACleanup();
initialized = FALSE;
}
/******************************************************************************
* openlog
*
* Open connection to system logger.
*/
void openlog( char* ident, int option, int facility )
{
BOOL failed = TRUE, wsa_initialized = FALSE;
WSADATA wsd;
SOCKADDR_IN sa_local;
DWORD n;
int size;
if( initialized )
return;
syslog_facility = facility? facility : LOG_USER;
/* FIXME: should we reset logmask? */
if( option & LOG_PID )
snprintf( str_pid, sizeof(str_pid), "[%lu]", GetCurrentProcessId() );
else
str_pid[0] = 0;
/* FIXME: handle other options */
n = sizeof(local_hostname);
if( !GetComputerName( local_hostname, &n ) )
goto done;
sock = INVALID_SOCKET;
if( WSAStartup( MAKEWORD( 2, 2 ), &wsd ) )
goto done;
wsa_initialized = TRUE;
init_logger_addr();
for( n = 0;; n++ )
{
sock = socket( AF_INET, SOCK_DGRAM, 0 );
if( INVALID_SOCKET == sock )
goto done;
memset( &sa_local, 0, sizeof(SOCKADDR_IN) );
sa_local.sin_family = AF_INET;
if( bind( sock, (SOCKADDR*) &sa_local, sizeof(SOCKADDR_IN) ) == 0 )
break;
closesocket( sock );
sock = INVALID_SOCKET;
if( n == 100 )
goto done;
Sleep(0);
}
/* get size of datagramm */
size = sizeof(datagramm_size);
if( getsockopt( sock, SOL_SOCKET, SO_MAX_MSG_SIZE, (char*) &datagramm_size, &size ) )
goto done;
if( datagramm_size - strlen(local_hostname) - (ident? strlen(ident) : 0) < 64 )
goto done;
if( datagramm_size > sizeof(datagramm) )
datagramm_size = sizeof(datagramm);
if( atexit( closelog ) )
goto done;
syslog_ident = ident;
syslog_facility = facility;
failed = FALSE;
done:
if( failed )
{
if( sock != INVALID_SOCKET ) closesocket( sock );
if( wsa_initialized ) WSACleanup();
}
initialized = !failed;
}
/******************************************************************************
* setlogmask
*
* Set the log mask level.
*/
int setlogmask( int mask )
{
int ret = log_mask;
if( mask )
log_mask = mask;
return ret;
}
/******************************************************************************
* syslog
*
* Generate a log message using FMT string and option arguments.
*/
void syslog( int pri, char* fmt, ... )
{
va_list ap;
va_start( ap, fmt );
vsyslog( pri, fmt, ap );
va_end( ap );
}
/******************************************************************************
* vsyslog
*
* Generate a log message using FMT and using arguments pointed to by AP.
*/
void vsyslog( int pri, char* fmt, va_list ap )
{
static char *month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
SYSTEMTIME stm;
int len;
char *p;
if( !(LOG_MASK( LOG_PRI( pri )) & log_mask) )
return;
openlog( NULL, 0, pri & LOG_FACMASK );
if( !initialized )
return;
if( !(pri & LOG_FACMASK) )
pri |= syslog_facility;
GetLocalTime( &stm );
len = sprintf( datagramm, "<%d>%s %2d %02d:%02d:%02d %s %s%s: ",
pri,
month[ stm.wMonth - 1 ], stm.wDay, stm.wHour, stm.wMinute, stm.wSecond,
local_hostname, syslog_ident? syslog_ident : "", str_pid );
vsnprintf( datagramm + len, datagramm_size - len, fmt, ap );
p = strchr( datagramm, '\n' );
if( p )
*p = 0;
p = strchr( datagramm, '\r' );
if( p )
*p = 0;
sendto( sock, datagramm, strlen(datagramm), 0, (SOCKADDR*) &sa_logger, sizeof(SOCKADDR_IN) );
}

View file

@ -0,0 +1,197 @@
/*
* Copyright (c) 1982, 1986, 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)syslog.h 8.1 (Berkeley) 6/2/93
*/
#ifndef _SYS_SYSLOG_H
#define _SYS_SYSLOG_H 1
#include <stdarg.h>
/*
* priorities/facilities are encoded into a single 32-bit quantity, where the
* bottom 3 bits are the priority (0-7) and the top 28 bits are the facility
* (0-big number). Both the priorities and the facilities map roughly
* one-to-one to strings in the syslogd(8) source code. This mapping is
* included in this file.
*
* priorities (these are ordered)
*/
#define LOG_EMERG 0 /* system is unusable */
#define LOG_ALERT 1 /* action must be taken immediately */
#define LOG_CRIT 2 /* critical conditions */
#define LOG_ERR 3 /* error conditions */
#define LOG_WARNING 4 /* warning conditions */
#define LOG_NOTICE 5 /* normal but significant condition */
#define LOG_INFO 6 /* informational */
#define LOG_DEBUG 7 /* debug-level messages */
#define LOG_PRIMASK 0x07 /* mask to extract priority part (internal) */
/* extract priority */
#define LOG_PRI(p) ((p) & LOG_PRIMASK)
#define LOG_MAKEPRI(fac, pri) (((fac) << 3) | (pri))
#ifdef SYSLOG_NAMES
#define INTERNAL_NOPRI 0x10 /* the "no priority" priority */
/* mark "facility" */
#define INTERNAL_MARK LOG_MAKEPRI(LOG_NFACILITIES, 0)
typedef struct _code {
char *c_name;
int c_val;
} CODE;
CODE prioritynames[] =
{
{ "alert", LOG_ALERT },
{ "crit", LOG_CRIT },
{ "debug", LOG_DEBUG },
{ "emerg", LOG_EMERG },
{ "err", LOG_ERR },
{ "error", LOG_ERR }, /* DEPRECATED */
{ "info", LOG_INFO },
{ "none", INTERNAL_NOPRI }, /* INTERNAL */
{ "notice", LOG_NOTICE },
{ "panic", LOG_EMERG }, /* DEPRECATED */
{ "warn", LOG_WARNING }, /* DEPRECATED */
{ "warning", LOG_WARNING },
{ NULL, -1 }
};
#endif
/* facility codes */
#define LOG_KERN (0<<3) /* kernel messages */
#define LOG_USER (1<<3) /* random user-level messages */
#define LOG_MAIL (2<<3) /* mail system */
#define LOG_DAEMON (3<<3) /* system daemons */
#define LOG_AUTH (4<<3) /* security/authorization messages */
#define LOG_SYSLOG (5<<3) /* messages generated internally by syslogd */
#define LOG_LPR (6<<3) /* line printer subsystem */
#define LOG_NEWS (7<<3) /* network news subsystem */
#define LOG_UUCP (8<<3) /* UUCP subsystem */
#define LOG_CRON (9<<3) /* clock daemon */
#define LOG_AUTHPRIV (10<<3) /* security/authorization messages (private) */
#define LOG_FTP (11<<3) /* ftp daemon */
/* other codes through 15 reserved for system use */
#define LOG_LOCAL0 (16<<3) /* reserved for local use */
#define LOG_LOCAL1 (17<<3) /* reserved for local use */
#define LOG_LOCAL2 (18<<3) /* reserved for local use */
#define LOG_LOCAL3 (19<<3) /* reserved for local use */
#define LOG_LOCAL4 (20<<3) /* reserved for local use */
#define LOG_LOCAL5 (21<<3) /* reserved for local use */
#define LOG_LOCAL6 (22<<3) /* reserved for local use */
#define LOG_LOCAL7 (23<<3) /* reserved for local use */
#define LOG_NFACILITIES 24 /* current number of facilities */
#define LOG_FACMASK 0x03f8 /* mask to extract facility part */
/* facility of pri */
#define LOG_FAC(p) (((p) & LOG_FACMASK) >> 3)
#ifdef SYSLOG_NAMES
CODE facilitynames[] =
{
{ "auth", LOG_AUTH },
{ "authpriv", LOG_AUTHPRIV },
{ "cron", LOG_CRON },
{ "daemon", LOG_DAEMON },
{ "ftp", LOG_FTP },
{ "kern", LOG_KERN },
{ "lpr", LOG_LPR },
{ "mail", LOG_MAIL },
{ "mark", INTERNAL_MARK }, /* INTERNAL */
{ "news", LOG_NEWS },
{ "security", LOG_AUTH }, /* DEPRECATED */
{ "syslog", LOG_SYSLOG },
{ "user", LOG_USER },
{ "uucp", LOG_UUCP },
{ "local0", LOG_LOCAL0 },
{ "local1", LOG_LOCAL1 },
{ "local2", LOG_LOCAL2 },
{ "local3", LOG_LOCAL3 },
{ "local4", LOG_LOCAL4 },
{ "local5", LOG_LOCAL5 },
{ "local6", LOG_LOCAL6 },
{ "local7", LOG_LOCAL7 },
{ NULL, -1 }
};
#endif
/*
* arguments to setlogmask.
*/
#define LOG_MASK(pri) (1 << (pri)) /* mask for one priority */
#define LOG_UPTO(pri) ((1 << ((pri)+1)) - 1) /* all priorities through pri */
/*
* Option flags for openlog.
*
* LOG_ODELAY no longer does anything.
* LOG_NDELAY is the inverse of what it used to be.
*/
#define LOG_PID 0x01 /* log the pid with each message */
#define LOG_CONS 0x02 /* log on the console if errors in sending */
#define LOG_ODELAY 0x04 /* delay open until first syslog() (default) */
#define LOG_NDELAY 0x08 /* don't delay open */
#define LOG_NOWAIT 0x10 /* don't wait for console forks: DEPRECATED */
#define LOG_PERROR 0x20 /* log to stderr as well */
#define SYSLOG_PORT 514
#ifdef __cplusplus
extern "C" {
#endif
/* Close desriptor used to write to system logger. */
extern void closelog (void);
/* Open connection to system logger. */
extern void openlog (char *__ident, int __option, int __facility);
/* Set the log mask level. */
extern int setlogmask (int __mask);
/* Generate a log message using FMT string and option arguments. */
extern void syslog (int __pri, char *__fmt, ...);
/* Generate a log message using FMT and using arguments pointed to by AP. */
extern void vsyslog (int __pri, char *__fmt, va_list __ap);
/* windows-specific;
set directory from where syslog.host must be read;
this file contains a single line with hostname and port of syslog daemon;
default is localhost:514
*/
extern const char* set_syslog_conf_dir( const char* dir );
#ifdef __cplusplus
}
#endif
#endif /* syslog.h */

View file

@ -22,6 +22,17 @@
#include "telnetd.h"
#define telnetd_printf printf
#if 0
extern void syslog (int priority, const char *fmt, ...);
int telnetd_printf(const char *format, ...)
{
syslog (6, format);
}
#endif
/* Local data */
static BOOLEAN bShutdown = 0;
@ -41,9 +52,8 @@ int main(int argc, char **argv)
{
SetConsoleCtrlHandler(Cleanup, 1);
if (!StartSocketInterface()) {
if (!StartSocketInterface())
ErrorExit("Unable to start socket interface\n");
}
CreateSocket();
@ -59,7 +69,7 @@ int main(int argc, char **argv)
static BOOL WINAPI Cleanup(DWORD dwControlType)
{
if (bSocketInterfaceInitialised) {
printf("Cleanup...\n");
telnetd_printf("Cleanup...\n");
WSACleanup();
}
return 0;
@ -75,82 +85,70 @@ static BOOLEAN StartSocketInterface(void)
wVersionRequested = MAKEWORD( 2, 0 );
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
printf("requested winsock version not supported\n");
telnetd_printf("requested winsock version not supported\n");
return 0;
}
bSocketInterfaceInitialised = 1; /* for ErrorExit function */
if ( wsaData.wVersion != wVersionRequested) {
printf("requested winsock version not supported\n");
return 0;
}
printf("TelnetD, using %s\n", wsaData.szDescription);
if ( wsaData.wVersion != wVersionRequested)
ErrorExit("requested winsock version not supported\n");
telnetd_printf("TelnetD, using %s\n", wsaData.szDescription);
return 1;
}
/*
** CreateSocket
*/
/* CreateSocket */
static void CreateSocket(void)
{
struct sockaddr_in sa;
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0) {
if (sock < 0)
ErrorExit("Cannot create socket");
}
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = INADDR_ANY;
sa.sin_port = htons(TELNET_PORT);
if (bind(sock, (struct sockaddr*) &sa, sizeof(sa)) != 0) {
if (bind(sock, (struct sockaddr*) &sa, sizeof(sa)) != 0)
ErrorExit("Cannot bind address to socket");
}
}
/*
** WaitForConnect
*/
/* WaitForConnect */
static void WaitForConnect(void)
{
struct sockaddr_in sa;
int new_sock;
if (listen(sock, 1) < 0) {
if (listen(sock, 1) < 0)
ErrorExit("Cannot listen on socket");
}
if ((new_sock = accept(sock, (struct sockaddr*) &sa, NULL)) < 0) {
fprintf(stderr, "Failed to accept incoming call\n");
} else {
printf("user connected on socket %d, port %d, address %lx\n", new_sock,
telnetd_printf("user connected on socket %d, port %d, address %lx\n", new_sock,
htons(sa.sin_port), sa.sin_addr.s_addr);
UserLogin(new_sock);
}
}
/*
** Function: UserLogin
*/
/* Function: UserLogin */
static void UserLogin(int client_socket)
{
DWORD threadID;
client_t *client = malloc(sizeof(client_t));
if (client == NULL) {
if (client == NULL)
ErrorExit("failed to allocate memory for client");
}
client->socket = client_socket;
CreateThread(NULL, 0, UserLoginThread, client, 0, &threadID);
}
/*
** Function: UserLoginThread
*/
/* Function: UserLoginThread */
static DWORD WINAPI UserLoginThread(LPVOID data)
{
client_t *client = (client_t *) data;
@ -211,7 +209,7 @@ static DWORD WINAPI UserLoginThread(LPVOID data)
/* TODO: do authentication here */
printf("User '%s' logged on\n", userID);
telnetd_printf("User '%p' logged on\n", userID);
#if 0
strcpy(client->userID, userID);
if (send(client->socket, logonPrompt, strlen(logonPrompt), 0) < 0) {
@ -224,9 +222,7 @@ static DWORD WINAPI UserLoginThread(LPVOID data)
return 0;
}
/*
** Function: DoTelnetHandshake
*/
/* Function: DoTelnetHandshake */
static int DoTelnetHandshake(int sock)
{
int retval;
@ -394,7 +390,7 @@ static void RunShell(client_t *client)
// Create the child process (the shell)
printf("Creating child process...\n");
telnetd_printf("Creating child process...\n");
ZeroMemory( &si, sizeof(STARTUPINFO) );
si.cb = sizeof(STARTUPINFO);
@ -424,11 +420,12 @@ static void RunShell(client_t *client)
client->hProcess = piProcInfo.hProcess;
client->dwProcessId = piProcInfo.dwProcessId;
printf("New child created (groupid=%lu)\n", client->dwProcessId);
telnetd_printf("New child created (groupid=%lu)\n", client->dwProcessId);
// No longer need these in the parent...
if (!CloseHandle(hChildStdoutWr))
ErrorExit("Closing handle failed");
if (!CloseHandle(hChildStdinRd))
ErrorExit("Closing handle failed");
@ -437,23 +434,22 @@ static void RunShell(client_t *client)
CreateThread(NULL, 0, MonitorChildThread, client, 0, &threadID);
}
/*
** Function: MonitorChildThread
**
** Abstract: Monitor the child (shell) process
*/
* Function: MonitorChildThread
*
* Abstract: Monitor the child (shell) process
*/
static DWORD WINAPI MonitorChildThread(LPVOID data)
{
DWORD exitCode;
client_t *client = (client_t *) data;
printf("Monitor thread running...\n");
telnetd_printf("Monitor thread running...\n");
WaitForSingleObject(client->hProcess, INFINITE);
GetExitCodeProcess(client->hProcess, &exitCode);
printf("Child process terminated with code %lx\n", exitCode);
telnetd_printf("Child process terminated with code %lx\n", exitCode);
/* signal the other threads to give up */
client->bTerminate = TRUE;
@ -466,25 +462,25 @@ static DWORD WINAPI MonitorChildThread(LPVOID data)
closesocket(client->socket);
printf("Waiting for all threads to give up..\n");
telnetd_printf("Waiting for all threads to give up..\n");
while (client->bWriteToPipe || client->bReadFromPipe) {
printf(".");
telnetd_printf(".");
fflush(stdout);
Sleep(1000);
}
printf("Cleanup for user '%s'\n", client->userID);
telnetd_printf("Cleanup for user '%s'\n", client->userID);
free(client);
return 0;
}
/*
** Function: WriteToPipeThread
**
** Abstract: read data from the telnet client socket
** and pass it on to the shell process.
*/
* Function: WriteToPipeThread
*
* Abstract: read data from the telnet client socket
* and pass it on to the shell process.
*/
static DWORD WINAPI WriteToPipeThread(LPVOID data)
{
int iRead;
@ -495,39 +491,38 @@ static DWORD WINAPI WriteToPipeThread(LPVOID data)
while (!client->bTerminate) {
iRead = ReceiveLine(client->socket, chBuf, BUFSIZE, FALSE);
if (iRead < 0) {
printf("Client disconnect\n");
telnetd_printf("Client disconnect\n");
break;
} else if (iRead > 0) {
if (strchr(chBuf, CTRLC)) {
GenerateConsoleCtrlEvent(CTRL_C_EVENT, client->dwProcessId);
}
if (send(client->socket, chBuf, iRead, 0) < 0) {
printf("error writing to socket\n");
telnetd_printf("error writing to socket\n");
break;
}
if (! WriteFile(client->hChildStdinWr, chBuf, (DWORD) iRead, &dwWritten, NULL)) {
printf("Error writing to pipe\n");
telnetd_printf("Error writing to pipe\n");
break;
}
}
}
if (!client->bTerminate) {
if (!client->bTerminate)
TerminateShell(client);
}
printf("WriteToPipeThread terminated\n");
telnetd_printf("WriteToPipeThread terminated\n");
client->bWriteToPipe = FALSE;
return 0;
}
/*
** Function: ReadFromPipeThread
**
** Abstract: Read data from the shell's stdout handle and
** pass it on to the telnet client socket.
*/
* Function: ReadFromPipeThread
*
* Abstract: Read data from the shell's stdout handle and
* pass it on to the telnet client socket.
*/
static DWORD WINAPI ReadFromPipeThread(LPVOID data)
{
DWORD dwRead;
@ -542,13 +537,13 @@ static DWORD WINAPI ReadFromPipeThread(LPVOID data)
while (!client->bTerminate && client->bWriteToPipe) {
// Since we do not want to block, first peek...
if (PeekNamedPipe(client->hChildStdoutRd, NULL, 0, NULL, &dwAvail, NULL) == 0) {
printf("Failed to peek in pipe\n");
telnetd_printf("Failed to peek in pipe\n");
break;
}
if (dwAvail) {
if( ! ReadFile( client->hChildStdoutRd, chBuf, BUFSIZE, &dwRead, NULL) ||
dwRead == 0) {
printf("Failed to read from pipe\n");
telnetd_printf("Failed to read from pipe\n");
break;
}
for (from=0, to=0; from<dwRead; from++, to++) {
@ -560,26 +555,23 @@ static DWORD WINAPI ReadFromPipeThread(LPVOID data)
}
}
if (send(client->socket, txBuf, to, 0) < 0) {
printf("error writing to socket\n");
telnetd_printf("error writing to socket\n");
break;
}
}
Sleep(100); /* Hmmm, oh well... what the heck! */
}
if (!client->bTerminate) {
if (!client->bTerminate)
TerminateShell(client);
}
printf("ReadFromPipeThread terminated\n");
telnetd_printf("ReadFromPipeThread terminated\n");
client->bReadFromPipe = FALSE;
return 0;
}
/*
** TerminateShell
*/
/* TerminateShell */
static void TerminateShell(client_t *client)
{
DWORD exitCode;
@ -588,42 +580,37 @@ static void TerminateShell(client_t *client)
GetExitCodeProcess(client->hProcess, &exitCode);
if (exitCode == STILL_ACTIVE) {
printf("user shell still active, send Ctrl-Break to group-id %lu\n", client->dwProcessId );
telnetd_printf("user shell still active, send Ctrl-Break to group-id %lu\n", client->dwProcessId );
if (!GenerateConsoleCtrlEvent( CTRL_BREAK_EVENT, client->dwProcessId )) {
printf("Failed to send Ctrl_break\n");
}
if (!GenerateConsoleCtrlEvent( CTRL_BREAK_EVENT, client->dwProcessId ))
telnetd_printf("Failed to send Ctrl_break\n");
Sleep(500);
if (!GenerateConsoleCtrlEvent( CTRL_C_EVENT, client->dwProcessId )) {
printf("Failed to send Ctrl_C\n");
}
if (!GenerateConsoleCtrlEvent( CTRL_C_EVENT, client->dwProcessId ))
telnetd_printf("Failed to send Ctrl_C\n");
Sleep(500);
if (! WriteFile(client->hChildStdinWr, stop, sizeof(stop), &dwWritten, NULL)) {
printf("Error writing to pipe\n");
}
if (!WriteFile(client->hChildStdinWr, stop, sizeof(stop), &dwWritten, NULL))
telnetd_printf("Error writing to pipe\n");
Sleep(500);
GetExitCodeProcess(client->hProcess, &exitCode);
if (exitCode == STILL_ACTIVE) {
printf("user shell still active, attempt to terminate it now...\n");
telnetd_printf("user shell still active, attempt to terminate it now...\n");
TerminateProcess(client->hProcess, 0);
}
}
}
/*
** ErrorExit
*/
/* ErrorExit */
static VOID ErrorExit (LPTSTR lpszMessage)
{
fprintf(stderr, "%s\n", lpszMessage);
if (bSocketInterfaceInitialised) {
printf("WSAGetLastError=%d\n", WSAGetLastError());
telnetd_printf("WSAGetLastError=%d\n", WSAGetLastError());
WSACleanup();
}
ExitProcess(0);