📄 telnetdlib.c
字号:
/* telnetdLib.c - telnet server library *//* Copyright 1984 - 2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------03n,06jun02,elr Documentation (SPR #78015)03m,07may02,kbw man page edits03l,02may02,elr Removed telnetdMutexSem in telnetdParserSet() (SPR #76641) Corrected uninitialized session data pointers Removed superfluous telnetdInitialized = FALSE03k,30apr02,elr Moved password authentication to telnetd context (SPR 30687) Corrected problems with messy session disconnects leaving many resources still open (SPR 75891) (SPR 72752) (SPR 5059) Corrected security problems Moved the context of authentication/login to telnetd from shell Improved documentation and included an example of a user shell Simplified code as a result of the static creation merge version 03h Added macro for debug messages03j,19oct01,rae merge from truestack ver03j, base 03f (memory leak, doc)03i,24may01,mil Bump up telnet task stack size to 8000.03h,14feb01,spm merged from version 03f of tor2_0_x branch (base 03e): general overhaul of telnet server (SPR #28675)03g,08nov99,pul T2 cumulative patch 203f,30jun99,cno Enable changing the telnet port number (SPR27680)03e,14mar99,jdi doc: removed refs to config.h and/or configAll.h (SPR 25663).03d,05oct98,jmp doc: cleanup.03c,30oct96,dgp doc: change task names for telnetd() per SPR #590103b,09aug94,dzb fixed activeFlag race with cleanupFlag (SPR #2050). made telnetdSocket global (SPR #1941). added logFdFromRlogin (SPR #2212).03a,02may94,ms increased stack size for SIMHPPA.02z,11aug93,jmm Changed ioctl.h and socket.h to sys/ioctl.h and sys/socket.h02y,01feb93,jdi documentation cleanup for 5.1.02x,18jul92,smb Changed errno.h to errnoLib.h.02w,26may92,rrr the tree shuffle -changed includes to have absolute path from h/02v,24apr92,rfs Fixed flaky shell restart upon connection termination. The functions telnetInTask() and telnetdExit() were changed. This is fixing SPR #1427. Also misc ANSI noise.02u,13dec91,gae ANSI cleanup.02t,14nov91,jpb moved remCurIdSet to shellLogout (shellLib.c).02s,04oct91,rrr passed through the ansification filter -changed functions to ansi style -changed includes to have absolute path from h/ -fixed #else and #endif -changed READ, WRITE and UPDATE to O_RDONLY O_WRONLY and ... -changed VOID to void -changed copyright notice02r,01aug91,yao fixed to pass 6 args to excJobAdd() call.02q,13may91,shl undo'ed 02o.02p,30apr91,jdi documentation tweaks.02o,29apr91,shl added call to restore original machine name, user and group ids (spr 916).02n,05apr91,jdi documentation -- removed header parens and x-ref numbers; doc review by dnw.02m,24mar91,jdi documentation cleanup.02l,05oct90,shl fixed telnetExit() to restore original user and password.02k,02oct90,hjb added a call to htons() where needed.02j,08aug90,dnw changed declaration of tnInput from void to int. added forward declaration of setMode().02i,07may90,shl changed entry point of tTelnetd back to telnetd.02h,18apr90,shl added shell security. changed telnetd name to tTelnetd.02g,20aug89,gae bumped telnetTaskStackSize from 1500 to 5000 for SPARC.02f,29sep88,gae documentation.02e,06jun88,dnw changed taskSpawn/taskCreate args.02d,30may88,dnw changed to v4 names.02c,28may88,dnw changed to use shellOrigStdSet (...) instead of shellSetOrig... changed not to use shellTaskId global variable.02b,01apr88,gae made it work with I/O system revision.02a,27jan88,jcf made kernel independent.01g,14dec87,dnw fixed bug in telnetdIn() that caused system crashes.01f,19nov87,dnw changed telnetd to wait for shell to exist before accepting remote connections.01e,17nov87,ecs lint.01d,04nov87,ecs documentation. & fixed bug in use of setsockopt(). dnw changed to call shellLogoutInstall() instead of logoutInstall.01c,24oct87,gae changed setOrig{In,Out,Err}Fd() to shellSetOrig{In,Out,Err}(). made telnetdOut() exit on EOF from master pty fd. made telnetInit() not sweat being called more than once. added shellLock() to telnetd to get exclusive use of shell.01g,20oct87,gae added logging device for telnet shell; made telnetInit() create pty device.01f,05oct87,gae made telnetdExit() from telnetdIn() - used by logout(). removed gratuitous standard I/O ioctl's. made "disconnection" cleaner by having shell do restart.01e,26jul87,dnw changed default priority of telnet tasks from 100 to 2. changed task priority and ids to be global variables so they can be accessed from outside this module.01d,04apr87,dnw de-linted.01c,27mar87,dnw documentation fixed bug causing control sequences from remote to be misinterpreted. added flushing of pty in case anything was left before remote login.01b,27feb87,dnw changed to spawn telnet tasks UNBREAKABLE.01a,20oct86,dnw written.*//*DESCRIPTIONThe telnet protocol enables users on remote systems to login to VxWorks.This library implements a telnet server which accepts remote telnet loginrequests and transfers input and output data between a command interpreterand the remote user. The default configuration redirects the input and outputfrom the VxWorks shell if available. The telnetdParserSet() routine allowsthe installation of an alternative command interpreter to handle the remoteinput and provide the output responses. If INCLUDE_SHELL is not defined,installing a command interpreter is required.The telnetdInit() routine initializes the telnet service when INCLUDE_TELNETis defined. If INCLUDE_SHELL is also defined, the telnetdStart() routineautomatically starts the server. Client sessions will connect to the shell,which only supports one client at a time.VXWORKS AE PROTECTION DOMAINSUnder VxWorks AE, the telnet server runs within the kernel protection domain only. This restriction does not apply under non-AE versions of VxWorks. INTERNALWhen connecting remote users to the VxWorks shell, the pseudo-terminaldriver ptyDrv provides data transfer between the telnet server and the shell.INCLUDE FILES: telnetLib.hSEE ALSO: rlogLib*/#include "vxWorks.h"#include "sys/types.h"#include "sys/socket.h"#include "netinet/in.h"#include "ioLib.h"#include "taskLib.h"#include "telnetLib.h"#include "stdlib.h"#include "unistd.h"#include "errnoLib.h"#include "string.h"#include "stdio.h"#include "fcntl.h"#include "sockLib.h"#include "shellLib.h"#include "remLib.h"#include "sysLib.h"#include "tickLib.h"#include "ptyDrv.h"#include "logLib.h"#include "excLib.h"#define STDIN_BUF_SIZE 512#define STDOUT_BUF_SIZE 512/* telnet input states */#define TS_DATA 0#define TS_IAC 1#define TS_CR 2#define TS_BEGINNEG 3#define TS_ENDNEG 4#define TS_WILL 5#define TS_WONT 6#define TS_DO 7#define TS_DONT 8/* The maximum string length of pty i/o task name */#define IO_TASK_NAME_MAX_LEN 128 /* Pseudo TTY buffers (input and output) */#define PTY_BUFFER_SIZE 1024/* debugging definition for a log messages */#define TELNETD_DEBUG(string, param1, param2, param3, param4, param5, param6)\ { \ if (_func_logMsg != NULL) \ (* _func_logMsg) (string, param1, param2, param3, param4, param5, \ param6);\ }/* global variables */#ifndef DEBUGint telnetTaskOptions = VX_SUPERVISOR_MODE | VX_UNBREAKABLE;#elseint telnetTaskOptions = VX_SUPERVISOR_MODE;#endif#if (CPU_FAMILY == SIMHPPA) || (CPU_FAMILY == SIMSPARCSUNOS)int telnetTaskStackSize = 10000;#else /* CPU_FAMILY == SIMHPPA */int telnetTaskStackSize = 8000;#endif /* CPU_FAMILY == SIMHPPA */int telnetTaskPriority = 55; /* priority of telnet tasks */int telnetdCurrentClients = 0;/* local variables *//* * telnetdSessionList is a pointer to a linked list of active sessions. * This is maintained for cleanup during exit */LOCAL LIST telnetdSessionList;LOCAL BOOL telnetdTaskFlag = TRUE; /* Create tasks when client connects? *//* telnetdTaskList - an array of all sessions (active or inactive) */LOCAL TELNETD_TASK_DATA * telnetdTaskList; LOCAL int telnetdMaxClients = 1; /* Default limit for simultaneous sessions. */LOCAL int telnetdTaskId; /* task ID of telnet server task */LOCAL int telnetdServerSock;LOCAL SEM_ID telnetdMutexSem;LOCAL BOOL telnetdInitialized = FALSE; /* Server initialized? */LOCAL BOOL telnetdParserFlag = FALSE; /* Parser access task registered? */LOCAL BOOL telnetdStartFlag = FALSE; /* Server started? */LOCAL TBOOL myOpts [256]; /* current option settings - this side */LOCAL TBOOL remOpts [256]; /* current option settings - other side */LOCAL BOOL raw; /* TRUE = raw mode enabled */LOCAL BOOL echo; /* TRUE = echo enabled */LOCAL FUNCPTR telnetdParserControl = NULL; /* Accesses command interpreter. */LOCAL BOOL remoteInitFlag = FALSE; /* No remote users have connected. */LOCAL char *ptyRemoteName = "/pty/rmt"; /* terminal for remote user */LOCAL int masterFd; /* master pty for remote users *//* forward declarations */void telnetdExit (UINT32 sessionId);LOCAL void telnetdTaskDelete (int numTasks);LOCAL int tnInput (int state, int slaveFd, int clientSock, int inputFd, char *buf, int n);LOCAL STATUS remDoOpt (int opt, int slaveFd, BOOL enable, int clientSock, BOOL remFlag);LOCAL STATUS localDoOpt (int opt, int slaveFd, BOOL enable, int clientSock, BOOL remFlag);LOCAL void setMode (int slaveFd, int telnetOption, BOOL enable);LOCAL STATUS telnetdIoTasksCreate (TELNETD_SESSION_DATA *pSlot);LOCAL STATUS telnetdSessionPtysCreate (TELNETD_SESSION_DATA *pSlot);LOCAL TELNETD_SESSION_DATA *telnetdSessionAdd (void);LOCAL void telnetdSessionDisconnect (TELNETD_SESSION_DATA *pSlot, BOOL pSlotdeAllocate);LOCAL void telnetdSessionDisconnectFromShell (TELNETD_SESSION_DATA *pSlot);LOCAL void telnetdSessionDisconnectFromRemote (TELNETD_SESSION_DATA *pSlot);/********************************************************************************* telnetdInit - initialize the telnet services** This routine initializes the telnet server, which supports remote login* to VxWorks via the telnet protocol. It is called automatically when the* configuration macro INCLUDE_TELNET is defined. The telnet server supports* simultaneous client sessions up to the limit specified by the* TELNETD_MAX_CLIENTS setting provided in the <numClients> argument. The* <staticFlag> argument is equal to the TELNETD_TASKFLAG setting. It allows* the server to create all of the secondary input and output tasks and allocate* all required resources in advance of any connection. The default value of* FALSE causes the server to spawn a task pair and create the associated data* structures after each new connection.** VXWORKS AE PROTECTION DOMAINS* Under VxWorks AE, you can call this function from within the kernel * protection domain only. This restriction does not apply under non-AE * versions of VxWorks. ** RETURNS: OK, or ERROR if initialization fails*/STATUS telnetdInit ( int numClients, /* maximum number of simultaneous sessions */ BOOL staticFlag /* TRUE: create all tasks in advance of any clients */ ) { int count; int result; if (telnetdInitialized) return (OK); if (numClients <= 0) return (ERROR); /* * If static initialization is selected, * then we must have a parser control installed */ if (staticFlag && (telnetdParserControl == NULL)) { TELNETD_DEBUG ("telnetd: A shell has not been installed - can't initialize library. errno:%#x\n", errno, 0, 0, 0, 0, 0); return (ERROR); } telnetdMutexSem = semMCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE ); if (telnetdMutexSem == NULL) return (ERROR); if (remoteInitFlag == FALSE) { /* Create pty device for all remote sessions. */ if (ptyDrv () == ERROR) { TELNETD_DEBUG ("telnetd: Unable to initialize ptyDrv(). errno:%#x\n", errno, 0, 0, 0, 0, 0); return ERROR; } remoteInitFlag = TRUE; /* Disable further device creation. */ } telnetdTaskFlag = staticFlag; /* Create input/output tasks early? */ telnetdMaxClients = numClients; telnetdTaskList = (TELNETD_TASK_DATA *)calloc (telnetdMaxClients, sizeof (TELNETD_TASK_DATA)); if (telnetdTaskList == NULL) { semDelete (telnetdMutexSem); return (ERROR); } /* Allocate all of the session data structures and initialize them */ for (count = 0; count < numClients; count++) { telnetdTaskList[count].pSession = (TELNETD_SESSION_DATA *)calloc (sizeof (TELNETD_SESSION_DATA), 1); if (telnetdTaskList[count].pSession == NULL) { telnetdTaskDelete (count); return (ERROR); } /* * Initialize all elements of the structure to sane values. * Note that we use '-1' is used in some cases so that we * can differentiate from valid i/o file descriptors such as stdin. * Also we need invalid task id's for initialization so we can * differentiate from taskIdSelf() since 0 is implied as our taskId */ telnetdTaskList[count].pSession->socket = -1; telnetdTaskList[count].pSession->inputFd = -1; telnetdTaskList[count].pSession->outputFd = -1; telnetdTaskList[count].pSession->slaveFd = -1; telnetdTaskList[count].pSession->outputTask = -1; telnetdTaskList[count].pSession->inputTask = -1; telnetdTaskList[count].pSession->parserControl = 0; telnetdTaskList[count].pSession->busyFlag = FALSE; telnetdTaskList[count].pSession->loggedIn = FALSE; /* * Static initialization has all resources and tasks created up front. * Create and spawn all resources and associate them in the session and task structures. */ if (telnetdTaskFlag) { /* * Spawn static input/output tasks for each possible connection. * In this configuration, the command interpreter currently * assigned can never be changed. * * New entries are identical in construction to the * 'one-at-a-time', dynamic telnet session entries. * * The spawned tasks will pend on a semaphore which signifies * the acceptance of a new socket connection. * * The session entry will be filled in when the connection * is accepted. */ if ( telnetdSessionPtysCreate (telnetdTaskList[count].pSession) == ERROR) { TELNETD_DEBUG ("telnetd: Unable to create all sessions in advance. errno:%#x\n", errno, 0, 0, 0, 0, 0); telnetdTaskDelete (count); return ERROR; } if (telnetdIoTasksCreate (telnetdTaskList[count].pSession) == ERROR) { TELNETD_DEBUG ("telnetd: error spawning i/o tasks - can't initialize library. errno:%#x\n", errno, 0, 0, 0, 0, 0); telnetdTaskDelete (count); return ERROR; } /* * Announce to the installed parser control routine that * we have a new session installed. No connection has been * established to this session at this point. */ result = (*telnetdParserControl) (REMOTE_INIT, (UINT32)telnetdTaskList[count].pSession, telnetdTaskList[count].pSession->slaveFd); /* Did we initialize the shell? */ if (result == ERROR) /* No, must have failed */ { TELNETD_DEBUG ("telnetd: error pre-initializing shell. Note:vxWorks shell does not support static initialization! errno:%#x\n", errno, 0, 0, 0, 0, 0); telnetdTaskDelete (count); return ERROR; } /* * File descriptors are available. Save the corresponding * parser control routine. */ telnetdTaskList[count].pSession->parserControl = telnetdParserControl; } } telnetdInitialized = TRUE; return (OK); }/********************************************************************************* telnetdParserSet - specify a command interpreter for telnet sessions** This routine provides the ability to handle telnet connections using* a custom command interpreter or the default VxWorks shell. It is* called automatically during system startup (when the configuration macro* INCLUDE_TELNET is defined) to connect clients to the command interpreter* specified in the TELNETD_PARSER_HOOK parameter. The command interpreter in * use when the telnet server start scan never be changed.*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -