/*-------------------------------------------------------------------------- S I C S T E L N E T Implementation of the telnet task things for SICS. The actual telnet protocoll handling lives in nread.c. coyright: see copyright.h Mark Koennecke, January 1998 ----------------------------------------------------------------------------*/ #include #include "sics.h" #include "passwd.h" #include "telnet.h" #include "commandlog.h" #include "fortify.h" #define LOGINWAIT 300 /* 300 == 5 minutes to wait for valid username password */ /*-------------------------------------------------------------------------*/ typedef struct __TelTask { SConnection *pCon; int iLogin; char pLoginWord[132]; time_t tStart; } TelTask; /*--------------------------------------------------------------------------*/ pTelTask CreateTelnet(SConnection *pCon) { pTelTask pRes = NULL; char *pPtr = NULL; time_t shit; assert(pCon); /* check for the login word */ pPtr = IFindOption(pSICSOptions,"TelWord"); if(!pPtr) { return NULL; } pRes = (pTelTask)malloc(sizeof(TelTask)); if(!pRes) { return NULL; } /* initialise */ memset(pRes,0,sizeof(TelTask)); pRes->pCon = pCon; pRes->iLogin = 0; pRes->tStart = time(&shit); strcpy(pRes->pLoginWord,pPtr); return pRes; } /*--------------------------------------------------------------------------*/ void DeleteTelnet(void *pData) { pTelTask pKill = NULL; assert(pData); pKill = (pTelTask)pData; if(pKill->pCon) { SCDeleteConnection(pKill->pCon); } free(pKill); } /*-------------------------------------------------------------------------*/ static void SendWelcome(SConnection *pCon) { SCWrite(pCon,"--------- Welcome to SICS ------------",eError); SCWrite(pCon,"You are now connected to a SICS Instrument Control Server",eError); SCWrite(pCon,"\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!",eError); SCWrite(pCon,"WARNING: Proceed with utmost care!",eError); SCWrite(pCon,"YOU MAY BE MOVING HARDWARE IN THE EXPERIMENT HALL",eError); SCWrite(pCon,"YOU MAY CAUSE GRIEVIOUS BODILY HARM TO SOMEBODY",eError); SCWrite(pCon,"YOU MAY DAMAGE VALUABLE AND SOMETIMES IRREPLACABLE HARDWARE", eError); SCWrite(pCon,"Continuing here seriously compromises hacker's ethics",eError); SCWrite(pCon,"You will NOT find valuable data here!",eError); SCWrite(pCon,"The SICS server does NOT allow you to spawn to the system",eError); SCWrite(pCon,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!",eError); } /*-------------------------------------------------------------------------*/ static void SendGA(SConnection *pCon) { char pReply[2]; pReply[0] = (char)255; pReply[1] = (char)249; NETWrite(pCon->pSock,pReply,2); } /*--------------------------------------------------------------------------*/ int TelnetTask(void *pData) { pTelTask self = NULL; char *pPtr = NULL; char *pLogin = NULL; char *pUser = NULL, *pPasswd = NULL; char pBuffer[512], pHost[131]; int iRet; time_t shit; self = (pTelTask)pData; assert(self); if(self->pCon->iEnd) { if(SCActive(self->pCon)) { return 1; } else { return 0; } } /* pop and execute */ iRet = CostaPop(self->pCon->pStack,&pPtr); if(iRet) { if(pPtr) { if(self->iLogin) /* handle normal command */ { /* check for logoff */ if(strstr(pPtr,"logoff") != NULL) { NetReadRemove(pServ->pReader,self->pCon->pSock); free(pPtr); self->pCon->iEnd = 1; return 0; } /* invoke command */ CostaLock(self->pCon->pStack); SCInvoke(self->pCon,pServ->pSics,pPtr); CostaUnlock(self->pCon->pStack); SendGA(self->pCon); free(pPtr); } else /* handle login messages */ { pLogin = strstr(pPtr,self->pLoginWord); if(!pLogin) { SCWrite(self->pCon, "------------------- Get Lost -------------------", eError); if(time(&shit) > self->tStart + LOGINWAIT) { SCWrite(self->pCon, "I cannot stand your login attempts anymore!", eError); NetReadRemove(pServ->pReader,self->pCon->pSock); self->pCon->iEnd = 1; free(pPtr); return 0; } free(pPtr); return 1; } else /* check username / password */ { pLogin += strlen(self->pLoginWord); pUser = strtok(pLogin," \t"); pPasswd = strtok(NULL," \t\r\n"); iRet = IsValidUser(pUser,pPasswd); if(iRet < 0) { sprintf(pBuffer,"SYSTEM ATTACK by %s / %s",pUser, pPasswd); SICSLogWrite(pBuffer,eInternal); SCWrite(self->pCon, "I do not know you, I do not let you in",eError); SendGA(self->pCon); free(pPtr); return 1; } else { NETInfo(self->pCon->pSock,pHost,131); sprintf(pBuffer,"Accepted connection on socket %d from %s", self->pCon->pSock->sockid, pHost); SICSLogWrite(pBuffer,eInternal); WriteToCommandLog("SYS >", pBuffer); SendWelcome(self->pCon); SCSetRights(self->pCon,iRet); self->iLogin = 1; SendGA(self->pCon); free(pPtr); return 1; } } } } } /* check for no commands but timeout on telnet */ if( !self->iLogin && (time(&shit) > self->tStart + LOGINWAIT) ) { self->pCon->iEnd = 1; NetReadRemove(pServ->pReader,self->pCon->pSock); return 0; } /* check for end */ if(self->pCon->iEnd) { if(SCActive(self->pCon)) { return 1; } else { return 0; } } return 1; } /*---------------------------------------------------------------------------*/ void TelnetSignal(void *pData, int iSignal, void *pSigData) { pTelTask self = NULL; int *iInt; char *pPtr; self = (pTelTask)pData; assert(self); if(iSignal == SICSINT) { iInt = (int *)pSigData; SCSetInterrupt(self->pCon,*iInt); if(*iInt == eEndServer) { self->pCon->iEnd = 1; } } else if(iSignal == SICSBROADCAST) { pPtr = (char *)pSigData; if(pPtr) { SCWrite(self->pCon,pPtr,eWarning); } } else if(iSignal == TOKENRELEASE) { self->pCon->iGrab = 0; } else if(iSignal == TOKENGRAB) { self->pCon->iGrab = 1; } } /*-------------------------------------------------------------------------*/ static mkChannel *pTelnet = NULL; void InstallTelnet(void) { char *pPtr = NULL; int i, iPort; /* No double telnet ports ! */ assert(!pTelnet); /* if the option is not there or invalid, telnet is disabled */ pPtr = IFindOption(pSICSOptions,"TelnetPort"); if(!pPtr) { return; } i = sscanf(pPtr,"%d",&iPort); if(i > 0) { pTelnet = NETOpenPort(iPort); } /* when we have a port have the NetReader listen and handle it */ if(pTelnet) { NetReadRegister(pServ->pReader,pTelnet, taccept, NULL); } } /*---------------------------------------------------------------------------*/ void KillTelnet(void) { if(pTelnet) { NETClosePort(pTelnet); /* NetReadRemove(pServ->pReader,pTelnet); */ free(pTelnet); pTelnet = NULL; } }