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,
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;
}
pRes = CreateConnection(pSics);
/* 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);
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);
}
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);
/* install command */
AddCommand(pRes->pSics, pRes->pName, ConSicsAction, NULL,pRes);
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;
}

View File

@ -30,8 +30,10 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
typedef struct __SConnection {
/* object basics */
pObjectDescriptor pDes;
char *pName;
/* char *pName; now generated on the fly from ident */
long lMagic;
long ident;
struct __SConnection *next;
/* I/O control */
mkChannel *pSock;
@ -62,15 +64,16 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
/* callback registry */
int iList;
/* Tasking Stuff */
int iEnd;
/* for keeping track of the login
process on a non telnet connection.
Should only be used in SCTaskFunction
*/
int iLogin;
time_t conStart;
}SConnection;
/* Tasking Stuff */
int iEnd;
/* for keeping track of the login
process on a non telnet connection.
Should only be used in SCTaskFunction
*/
int iLogin;
time_t conStart;
} SConnection;
#include "nserver.h"
@ -88,6 +91,7 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
int SCDelLogFile(SConnection *pCon, int iFile);
void SCSetOutputClass(SConnection *self, int iClass);
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 SCPrompt(SConnection *pCon, char *pPrompt, char *pResult, int iLen);
int SCSendOK(SConnection *self);
@ -140,7 +144,16 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
int argc, char *argv[]);
int ConSicsAction(SConnection *pCon, SicsInterp *pSics, void *pData,
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