/******************************************************************************* * * remShellTelnetDisconn - disconnect shell from telnet * * This routine is called from the telnetInTask either as a result of the * connection terminating from the remote host, or as a result of the logout() * command issued to our shell. It is therefore always run in the context of * the telnetInTask. * * The shell standard I/O is redirected back to the console, and the shell is * restarted. * * RETURNS: N/A */ void remShellTelnetDisconn ( int disconnArg ) { shellLogoutInstall ((FUNCPTR) NULL, 0); /* uninstall logout function */ if (logFdFromRlogin != NONE) { logFdDelete (logFdFromRlogin); /* cancel extra log device */ logFdFromRlogin = NONE; /* reset fd */ } #if VX_VERSION == 55 || VX_VERSION == 542 shellOrigStdSet (STD_IN, shellInFd); /* restore shell's stnd I/O */ shellOrigStdSet (STD_OUT, shellOutFd); shellOrigStdSet (STD_ERR, shellErrFd); #endif shellLock (FALSE); /* unlock shell */ /* For typical remote sessions, there is no need to restart the shell. * If we are in shell context, simply restoring the standard I/O * descriptors is enough to get the shell back on track upon return * from this function. If we are in telnetInTask context, the closing * of the pty device will cause the shell to unblock from its read() * and do subsequent I/O from the restored descriptors. * However, problems can occur upon logout if the remote user has * disabled the line editor and/or put the pty device in raw mode. * The problem caused is that the shell does not resume properly. * It is therefore deemed prudent to always restart the shell, thereby * avoiding any funny business. * * The previous version attempted to send a ctrl-D up the pty device * to wakeup and restart the shell. Unfortunately, ctrl-D only has * special meaning when the device is in line mode, and hence did * not work in raw mode. * * The pty device is closed after the shell is restarted, when called * from telnetInTask, to avoid waking the existing shell and causing an * additional prompt to appear on the console. */ activeFlag = FALSE; /* allow new connection */ #if (_WRS_VXWORKS_MAJOR >= 6) excJobAdd((VOIDFUNCPTR)shellRestart, (int)CURRENT_SHELL_SESSION , 0, 0, 0, 0, 0); #else excJobAdd(shellRestart, FALSE, 0, 0, 0, 0, 0); #endif } /* remShellTelnetDisconn */
STATUS shellParserControl ( UINT32 remoteEvent, /* Starting or stopping a connection? */ UINT32 sessionId, /* Unique identifier for each session */ UINT32 slaveFd /* File descriptor for character i/o */ ) { if ((taskNameToId ("tShell")) == ERROR) /* Shell not started yet. */ return (ERROR); if (remoteEvent == REMOTE_START) { /* Handle a new telnet or rlogin session. */ if (remoteId != 0) /* Failed request - only one session allowed. */ return (ERROR); if (!shellLock (TRUE)) /* Shell is not available. */ { fdprintf (slaveFd, "The shell is currently in use.\n"); return (ERROR); } /* Let the user try to login */ if (shellLogin (slaveFd) != OK) { shellLock (FALSE); return (ERROR); } /* setup the slave device to act like a terminal */ (void) ioctl (slaveFd, FIOOPTIONS, OPT_TERMINAL); shellLogoutInstall ((FUNCPTR) telnetdExit, sessionId); /* get the shell's standard I/O fd's so we can restore them later */ shellInFd = ioGlobalStdGet (STD_IN); shellOutFd = ioGlobalStdGet (STD_OUT); shellErrFd = ioGlobalStdGet (STD_ERR); /* set shell's standard I/O to new device; add extra logging device */ shellOrigStdSet (STD_IN, slaveFd); shellOrigStdSet (STD_OUT, slaveFd); shellOrigStdSet (STD_ERR, slaveFd); logFdAdd (slaveFd); logFdFromRlogin = slaveFd; /* store new fd for logFdSet() */ /* Store the session identifier. */ remoteId = sessionId; /* notify the shell we have started a remote session */ shellIsRemoteConnectedSet (TRUE); printErr ("\ntelnetd: This system *IN USE* via telnet.\n"); /* Prevent network denial of service attacks by waiting a second */ taskDelay (sysClkRateGet() / 2); /* Restart the shell to access the redirected file descriptors. */ excJobAdd (shellRestart, TRUE, 0, 0, 0, 0, 0); return (OK); } else if (remoteEvent == REMOTE_STOP) { /* * End an active telnet or rlogin session. This event occurs * after the server closes the socket. */ if (remoteId != sessionId) /* Unknown remote session. */ return (ERROR); shellLogoutInstall ((FUNCPTR) NULL, 0); /* remove logout function */ if (logFdFromRlogin != NONE) { logFdDelete (logFdFromRlogin); /* cancel extra log device */ logFdFromRlogin = NONE; /* reset fd */ } shellOrigStdSet (STD_IN, shellInFd); /* restore shell's stnd I/O */ shellOrigStdSet (STD_OUT, shellOutFd); shellOrigStdSet (STD_ERR, shellErrFd); shellLock (FALSE); /* unlock shell */ /* * For typical remote sessions, restoring the standard I/O * descriptors is enough to reconnect the shell to the console * because closing the pty device will cause the shell to unblock * from its read() and use the restored descriptors. However, * problems can occur upon logout if the remote user has disabled * the line editor and/or put the pty device in raw mode, so the * shell is restarted in all cases. */ remoteId = 0; /* Allow a new session. */ /* notify the shell we have ended a remote session */ shellIsRemoteConnectedSet (FALSE); excJobAdd (shellRestart, FALSE, 0, 0, 0, 0, 0); return (OK); } return (ERROR); /* Ignore unknown control operations. */ }
/******************************************************************************* * * remShellTelnetConn - connect shell to telnet * * This routine is called by the telnet demon to connect the shell with the * remote telnet user. * Remote telnet requests will cause `stdin', `stdout', and `stderr' to be stolen * away from the console. When the remote user disconnects, `stdin', `stdout', * and `stderr' are restored, and the shell is restarted. * * RETURNS: OK or ERROR. */ STATUS remShellTelnetConn ( int interpConnArg, /* argument for interpConn () */ int slaveFd, int exitArg, /* */ int * disconnArg, char * msg ) { /* wait for shell to exist */ while (taskNameToId (telnetShellName) == ERROR) taskDelay (sysClkRateGet ()); /* check to see if there's already an active connection */ if (activeFlag) { strcpy(msg, "\r\nSorry, this system is engaged.\r\n"); return ERROR; } if (!shellLock (TRUE)) { strcpy(msg, "\r\nSorry, shell is locked.\r\n"); printErr ("telnetd: someone tried to login into.\n"); return ERROR; } printErr ("\ntelnetd: This system *IN USE* via telnet.\n"); shellLogoutInstall ((FUNCPTR) telnetdExit, exitArg); activeFlag = TRUE; /* get the shell's standard I/O fd's so we can restore them later */ shellInFd = ioGlobalStdGet (STD_IN); shellOutFd = ioGlobalStdGet (STD_OUT); shellErrFd = ioGlobalStdGet (STD_ERR); #ifndef BROADCOM_DEBUG #if VX_VERSION == 55 || VX_VERSION == 542 /* set shell's standard I/O to pty device; add extra logging device */ shellOrigStdSet (STD_IN, slaveFd); shellOrigStdSet (STD_OUT, slaveFd); shellOrigStdSet (STD_ERR, slaveFd); logFdAdd (slaveFd); logFdFromRlogin = slaveFd; /* store pty fd for logFdSet() */ #endif #endif /* BROADCOM_DEBUG */ /* the shell is currently stuck in a read from the console, so we * restart it */ #ifndef BROADCOM_DEBUG #if (_WRS_VXWORKS_MAJOR >= 6) excJobAdd((VOIDFUNCPTR)shellRestart, (int)CURRENT_SHELL_SESSION , 0, 0, 0, 0, 0); #else excJobAdd (shellRestart, TRUE, 0, 0, 0, 0, 0); #endif #else sp (copyStreams, slaveFd, slaveFd,0,0,0,0,0,0,0); /* !!! */ #endif /* BROADCOM_DEBUG */ (void) ioctl (slaveFd, FIOFLUSH, 0 /*XXX*/); return OK; } /* remShellTelnetConn */