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

320
conman.c
View File

@ -29,6 +29,11 @@
appending outcode to text,
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
-----------------------------------------------------------------------------*/
@ -41,6 +46,8 @@
#include <zlib.h>
#include <tcl.h>
#include <time.h>
#include <limits.h>
#include <stdarg.h>
#include "lld.h"
#include "sics.h"
#include "passwd.h"
@ -78,173 +85,143 @@ extern pServer pServ;
/*------------- a number for generating automatic names --------------------*/
static int iName = 0;
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;
char pBueffel[253];
char pHost[132];
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));
assert(pSock);
/* 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;
}
pRes = CreateConnection(pSics);
/* 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);
pRes->pName = strdup(pBueffel);
pRes->pSock = pSock;
pRes->iUserRights = iUser;
pRes->iOutput = eInError; /* gets everything except internal messages */
pRes->iFiles = 0; /* default: no logfiles */
pRes->inUse = 0;
pRes->iMacro = 0;
pRes->iGrab = TokenGrabActive();
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;
}
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);
pRes->iGrab = TokenGrabActive();
NETInfo(pRes->pSock,pHost,131);
sprintf(pBueffel,"Accepted connection on socket %d from %s",
pRes->pSock->sockid, pHost);
SICSLogWrite(pBueffel,eInternal);
WriteToCommandLog("SYS >", pBueffel);
return pRes;
}
/*--------------------------------------------------------------------------*/
SConnection *SCCreateDummyConnection(SicsInterp *pSics)
{
int i;
SConnection *pRes = NULL;
char pBueffel[132];
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));
pRes = CreateConnection(pSics);
/* 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->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->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 */
AddCommand(pRes->pSics, pRes->pName, ConSicsAction, NULL,pRes);
SICSLogWrite("Accepted dummy connection ",eInternal);
return pRes;
}
/*--------------------------------------------------------------------------*/
@ -434,11 +411,7 @@ extern pServer pServ;
fclose(pVictim->pFiles[i]);
}
if(pVictim->pName)
{
RemoveCommand(pVictim->pSics,pVictim->pName);
free(pVictim->pName);
}
RemoveCommand(pVictim->pSics,ConName(pVictim->ident));
if(pVictim->pDes)
{
@ -468,9 +441,9 @@ extern pServer pServ;
{
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*/
free(pVictim);
FreeConnection(pVictim);
}
/*---------------------------------------------------------------------------*/
static int HasNL(char *buffer)
@ -563,6 +536,32 @@ extern pServer pServ;
}
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)
{
@ -597,7 +596,7 @@ static int doSockWrite(SConnection *self, char *buffer)
iRet = NETWrite(self->pSock,buffer,strlen(buffer));
if(!HasNL(buffer))
{
iRet = NETWrite(self->pSock,"\n",sizeof("\n"));
iRet = NETWrite(self->pSock,"\n",strlen("\n"));
}
}
if(!iRet)
@ -1396,7 +1395,7 @@ static void writeToLogFiles(SConnection *self, char *buffer)
}
else if(strcmp(argv[1],"myname") == 0)
{
sprintf(pBueffel,"MyName = %s",pCon->pName);
sprintf(pBueffel,"MyName = %s",ConName(pCon->ident));
SCWrite(pCon,pBueffel,eValue);
return 1;
}
@ -1904,3 +1903,22 @@ int SCActive(SConnection *self)
}
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;
}