extended functionality/make more secure M.Z.

This commit is contained in:
cvs
2004-11-17 11:07:31 +00:00
parent 45476502cd
commit db94826248
2 changed files with 194 additions and 163 deletions

318
conman.c
View File

@ -29,6 +29,11 @@
appending outcode to text, appending outcode to text,
Mark Koennecke, July 2004 Mark Koennecke, July 2004
Made use of unused connections secure (connections are not
freed, but reused on new connections).
Introduced new type SCStore and functions SCSave, SCLoad.
Introduced SCPrintf to avoid many of these pBueffel.
Markus Zolliker, Sept 2004.
Copyright: see copyright.h Copyright: see copyright.h
-----------------------------------------------------------------------------*/ -----------------------------------------------------------------------------*/
@ -41,6 +46,8 @@
#include <zlib.h> #include <zlib.h>
#include <tcl.h> #include <tcl.h>
#include <time.h> #include <time.h>
#include <limits.h>
#include <stdarg.h>
#include "lld.h" #include "lld.h"
#include "sics.h" #include "sics.h"
#include "passwd.h" #include "passwd.h"
@ -78,173 +85,143 @@ extern pServer pServ;
/*------------- a number for generating automatic names --------------------*/ /*------------- a number for generating automatic names --------------------*/
static int iName = 0; static int iName = 0;
static int SCNormalWrite(SConnection *self, char *buffer, int iOut); static int SCNormalWrite(SConnection *self, char *buffer, int iOut);
static SConnection *freeConnections = NULL;
static long lastIdent = 0;
/*===========================================================================*/ /*===========================================================================*/
SConnection *SCreateConnection(SicsInterp *pSics,mkChannel *pSock, int iUser) static char *ConName(long ident) {
static char name[32];
snprintf(name, sizeof(name), "CON%ld", ident);
return name;
}
/*--------------------------------------------------------------------------*/
static void FreeConnection(SConnection *pCon)
{
memset(pCon,0,sizeof(SConnection));
pCon->ident = 0;
pCon->next = freeConnections;
freeConnections = pCon;
}
/*--------------------------------------------------------------------------*/
static SConnection *CreateConnection(SicsInterp *pSics)
{
int i;
SConnection *pRes = NULL;
char pBueffel[253];
char pHost[132];
if (!freeConnections)
{ /* no more free connection: get one by malloc */
pRes = (SConnection *)malloc(sizeof(SConnection));
if(!pRes)
{
/* This is a serious, very serious error! */
SICSLogWrite("ERROR: No memory to allocate connection!!",eInternal);
return NULL;
}
memset(pRes,0,sizeof(SConnection));
}
else
{ /* reuse an old connection */
pRes = freeConnections;
freeConnections = pRes->next;
}
do
{ /* loop until an unused ident is found */
if (lastIdent == LONG_MAX)
{
/* This is a serious, very serious error! */
SICSLogWrite("ERROR: Run out of connection identifiers!!",eInternal);
return NULL;
}
lastIdent++;
} while (FindCommand(pSics, ConName(lastIdent)));
pRes->ident = lastIdent;
/* a descriptor */
pRes->pDes = CreateDescriptor("Connection");
if(!pRes->pDes)
{
/* This is a serious, very serious error! */
SICSLogWrite("ERROR: No memory to allocate connection!!",eInternal);
FreeConnection(pRes);
return NULL;
}
/* the callback registry */
pRes->iList = LLDcreate(sizeof(Item));
/* the command stack */
pRes->pStack = CreateCommandStack();
if( (pRes->iList <0) || (!pRes->pStack))
{
/* This is a serious, very serious error! */
SICSLogWrite("ERROR: No memory to allocate connection!!",eInternal);
DeleteDescriptor(pRes->pDes);
FreeConnection(pRes);
return NULL;
}
pRes->iOutput = eInError; /* gets everything except internal messages */
pRes->iFiles = 0; /* default: no logfiles */
pRes->inUse = 0;
pRes->iMacro = 0;
pRes->iTelnet = 0;
pRes->pSics = pSics;
pRes->eInterrupt = eContinue;
pRes->lMagic = CONMAGIC;
pRes->iLogin = 0;
pRes->conStart = time(NULL);
pRes->write = SCNormalWrite;
for(i = 0; i < 10; i++)
{
pRes->pFiles[i] = NULL;
}
/* install command */
AddCommand(pRes->pSics, ConName(pRes->ident), ConSicsAction, NULL,pRes);
return pRes;
}
/*--------------------------------------------------------------------------*/
SConnection *SCreateConnection(SicsInterp *pSics,mkChannel *pSock, int iUser)
{ {
int i;
SConnection *pRes = NULL; SConnection *pRes = NULL;
char pBueffel[253]; char pBueffel[253];
char pHost[132]; char pHost[132];
pRes = (SConnection *)malloc(sizeof(SConnection)); assert(pSock);
if(!pRes)
{
/* This is a serious, very serious error! */
SICSLogWrite("ERROR: No memory to allocate connection!!",eInternal);
return NULL;
}
memset(pRes,0,sizeof(SConnection));
/* a descriptor */ pRes = CreateConnection(pSics);
pRes->pDes = CreateDescriptor("Connection");
if(!pRes->pDes)
{
/* This is a serious, very serious error! */
SICSLogWrite("ERROR: No memory to allocate connection!!",eInternal);
free(pRes);
return NULL;
}
/* new name */
sprintf(pBueffel,"CON%4.4d",iName);
iName++;
if(iName > 9999)
{
iName = 0;
}
/* the callback registry */
pRes->iList = LLDcreate(sizeof(Item));
/* the command stack */
pRes->pStack = CreateCommandStack();
if( (pRes->iList <0) || (!pRes->pStack))
{
/* This is a serious, very serious error! */
SICSLogWrite("ERROR: No memory to allocate connection!!",eInternal);
DeleteDescriptor(pRes->pDes);
free(pRes);
return NULL;
}
SetCommandStackMaxSize(pRes->pStack,MAXSTACK); SetCommandStackMaxSize(pRes->pStack,MAXSTACK);
pRes->pName = strdup(pBueffel);
pRes->pSock = pSock; pRes->pSock = pSock;
pRes->iUserRights = iUser; pRes->iUserRights = iUser;
pRes->iOutput = eInError; /* gets everything except internal messages */ pRes->iGrab = TokenGrabActive();
pRes->iFiles = 0; /* default: no logfiles */
pRes->inUse = 0; NETInfo(pRes->pSock,pHost,131);
pRes->iMacro = 0; sprintf(pBueffel,"Accepted connection on socket %d from %s",
pRes->iGrab = TokenGrabActive(); pRes->pSock->sockid, pHost);
pRes->iTelnet = 0; SICSLogWrite(pBueffel,eInternal);
pRes->pSics = pSics; WriteToCommandLog("SYS >", pBueffel);
pRes->eInterrupt = eContinue;
pRes->lMagic = CONMAGIC;
pRes->iLogin = 0;
pRes->conStart = time(NULL);
pRes->write = SCNormalWrite;
for(i = 0; i < 10; i++)
{
pRes->pFiles[i] = NULL;
}
if(pRes->pSock)
{
NETInfo(pRes->pSock,pHost,131);
sprintf(pBueffel,"Accepted connection on socket %d from %s",
pRes->pSock->sockid, pHost);
SICSLogWrite(pBueffel,eInternal);
WriteToCommandLog("SYS >", pBueffel);
}
else
{
SICSLogWrite("Accepted dummy connection ",eInternal);
}
/* install command */
AddCommand(pRes->pSics, pRes->pName, ConSicsAction, NULL,pRes);
return pRes; return pRes;
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
SConnection *SCCreateDummyConnection(SicsInterp *pSics) SConnection *SCCreateDummyConnection(SicsInterp *pSics)
{ {
int i;
SConnection *pRes = NULL; SConnection *pRes = NULL;
char pBueffel[132];
pRes = (SConnection *)malloc(sizeof(SConnection)); pRes = CreateConnection(pSics);
if(!pRes)
{
/* This is a serious, very serious error! */
SICSLogWrite("ERROR: No memory to allocate connection!!",eInternal);
return NULL;
}
memset(pRes,0,sizeof(SConnection));
/* a descriptor */
pRes->pDes = CreateDescriptor("Connection");
if(!pRes->pDes)
{
/* This is a serious, very serious error! */
SICSLogWrite("ERROR: No memory to allocate connection!!",eInternal);
free(pRes);
return NULL;
}
/* new name */
sprintf(pBueffel,"CON%4.4d",iName);
iName++;
if(iName > 9999)
{
iName = 0;
}
/* the callback registry */
pRes->iList = LLDcreate(sizeof(Item));
/* the command stack */
pRes->pStack = CreateCommandStack();
if( (pRes->iList <0) || (!pRes->pStack))
{
/* This is a serious, very serious error! */
SICSLogWrite("ERROR: No memory to allocate connection!!",eInternal);
DeleteDescriptor(pRes->pDes);
free(pRes);
return NULL;
}
pRes->pName = strdup(pBueffel);
pRes->pSock = NULL; pRes->pSock = NULL;
pRes->iUserRights = usInternal; pRes->iUserRights = usInternal;
pRes->iOutput = eInError; /* gets everything except internal messages */
pRes->iFiles = 0; /* default: no logfiles */
pRes->inUse = 0;
pRes->iTelnet = 0;
pRes->iGrab = 0; pRes->iGrab = 0;
pRes->iMacro = 0;
pRes->pSics = pSics;
pRes->lMagic = CONMAGIC;
pRes->eInterrupt = eContinue;
pRes->iLogin = 0;
pRes->conStart = time(NULL);
pRes->write = SCNormalWrite;
for(i = 0; i < 10; i++)
{
pRes->pFiles[i] = NULL;
}
if(pRes->pSock)
{
sprintf(pBueffel,"Accepted connection on socket %d",pRes->pSock->sockid);
SICSLogWrite(pBueffel,eInternal);
}
else
{
SICSLogWrite("Accepted dummy connection ",eInternal);
}
/* install command */ SICSLogWrite("Accepted dummy connection ",eInternal);
AddCommand(pRes->pSics, pRes->pName, ConSicsAction, NULL,pRes);
return pRes; return pRes;
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
@ -434,11 +411,7 @@ extern pServer pServ;
fclose(pVictim->pFiles[i]); fclose(pVictim->pFiles[i]);
} }
if(pVictim->pName) RemoveCommand(pVictim->pSics,ConName(pVictim->ident));
{
RemoveCommand(pVictim->pSics,pVictim->pName);
free(pVictim->pName);
}
if(pVictim->pDes) if(pVictim->pDes)
{ {
@ -468,9 +441,9 @@ extern pServer pServ;
{ {
DeleteCommandStack(pVictim->pStack); DeleteCommandStack(pVictim->pStack);
} }
pVictim->lMagic=0; /* make a write to a freed conn. harmless */ pVictim->lMagic=0; /* make a write to a freed connection harmless */
/* finally free pVictim*/ /* finally free pVictim*/
free(pVictim); FreeConnection(pVictim);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static int HasNL(char *buffer) static int HasNL(char *buffer)
@ -563,6 +536,32 @@ extern pServer pServ;
} }
return self->write(self,pBuffer,iOut); return self->write(self,pBuffer,iOut);
} }
/*-------------------------------------------------------------------------*/
int SCPrintf(SConnection *self, int iOut, char *fmt, ...)
{
va_list ap;
char buf[256];
char *dyn;
int l;
int res;
va_start(ap, fmt);
l = vsnprintf(buf, sizeof buf, fmt, ap);
va_end(ap);
if (l >= sizeof buf) {
/* we have probably a C99 conforming snprintf and need a larger buffer */
dyn = malloc(l+1);
if (dyn != NULL) {
va_start(ap, fmt);
vsnprintf(dyn, l+1, fmt, ap);
va_end(ap);
res = SCWrite(self, dyn, iOut);
free(dyn);
return res;
}
}
return SCWrite(self, buf, iOut);
}
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
writeFunc SCGetWriteFunc(SConnection *self) writeFunc SCGetWriteFunc(SConnection *self)
{ {
@ -597,7 +596,7 @@ static int doSockWrite(SConnection *self, char *buffer)
iRet = NETWrite(self->pSock,buffer,strlen(buffer)); iRet = NETWrite(self->pSock,buffer,strlen(buffer));
if(!HasNL(buffer)) if(!HasNL(buffer))
{ {
iRet = NETWrite(self->pSock,"\n",sizeof("\n")); iRet = NETWrite(self->pSock,"\n",strlen("\n"));
} }
} }
if(!iRet) if(!iRet)
@ -1396,7 +1395,7 @@ static void writeToLogFiles(SConnection *self, char *buffer)
} }
else if(strcmp(argv[1],"myname") == 0) else if(strcmp(argv[1],"myname") == 0)
{ {
sprintf(pBueffel,"MyName = %s",pCon->pName); sprintf(pBueffel,"MyName = %s",ConName(pCon->ident));
SCWrite(pCon,pBueffel,eValue); SCWrite(pCon,pBueffel,eValue);
return 1; return 1;
} }
@ -1904,3 +1903,22 @@ int SCActive(SConnection *self)
} }
return 0; return 0;
} }
/*--------------------------------------------------------------------------*/
void SCSave(SCStore *con, SConnection *pCon) {
con->pCon = pCon;
if (pCon) {
con->ident = pCon->ident;
}
}
/*--------------------------------------------------------------------------*/
SConnection *SCLoad(SCStore *con) {
SConnection *pCon;
pCon = con->pCon;
if (pCon) {
if (con->ident != pCon->ident) {
con->pCon == NULL; /* connection has died */
}
}
return pCon;
}

View File

@ -30,8 +30,10 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
typedef struct __SConnection { typedef struct __SConnection {
/* object basics */ /* object basics */
pObjectDescriptor pDes; pObjectDescriptor pDes;
char *pName; /* char *pName; now generated on the fly from ident */
long lMagic; long lMagic;
long ident;
struct __SConnection *next;
/* I/O control */ /* I/O control */
mkChannel *pSock; mkChannel *pSock;
@ -62,15 +64,16 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
/* callback registry */ /* callback registry */
int iList; int iList;
/* Tasking Stuff */ /* Tasking Stuff */
int iEnd; int iEnd;
/* for keeping track of the login /* for keeping track of the login
process on a non telnet connection. process on a non telnet connection.
Should only be used in SCTaskFunction Should only be used in SCTaskFunction
*/ */
int iLogin; int iLogin;
time_t conStart; time_t conStart;
}SConnection;
} SConnection;
#include "nserver.h" #include "nserver.h"
@ -88,6 +91,7 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
int SCDelLogFile(SConnection *pCon, int iFile); int SCDelLogFile(SConnection *pCon, int iFile);
void SCSetOutputClass(SConnection *self, int iClass); void SCSetOutputClass(SConnection *self, int iClass);
int SCWrite(SConnection *self, char *pBuffer, int iOut); int SCWrite(SConnection *self, char *pBuffer, int iOut);
int SCPrintf(SConnection *self, int iOut, char *fmt, ...);
int SCRead(SConnection *self, char *pBuffer, int iBufLen); int SCRead(SConnection *self, char *pBuffer, int iBufLen);
int SCPrompt(SConnection *pCon, char *pPrompt, char *pResult, int iLen); int SCPrompt(SConnection *pCon, char *pPrompt, char *pResult, int iLen);
int SCSendOK(SConnection *self); int SCSendOK(SConnection *self);
@ -140,7 +144,16 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
int argc, char *argv[]); int argc, char *argv[]);
int ConSicsAction(SConnection *pCon, SicsInterp *pSics, void *pData, int ConSicsAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]); int argc, char *argv[]);
/******************************** Store ************************************/
typedef struct {
SConnection *pCon;
long ident;
} SCStore;
void SCSave(SCStore *con, SConnection *pCon);
/* save a connection for later use. */
SConnection *SCLoad(SCStore *con);
/* check con and return SConnection if still valid or NULL otherwise. */
#endif #endif