void PTelnetDServerMode() { int listensock, fd, i; struct sigaction sigact; char *Tempstr=NULL, *IPStr=NULL; listensock=InitServerSock(Settings.Interface,Settings.Port); if (listensock==-1) { printf("ERROR: Cannot bind to port %d on interface %s\n",Settings.Port,Settings.Interface); exit(3); } if (! (Settings.Flags & FLAG_NODEMON)) demonize(); SetupPidFile(); if (Settings.Flags & FLAG_HONEYPOT) JailAndSwitchUser(FLAG_CHROOT, Settings.RealUser, Settings.ChDir); while (1) { /*Set up a signal handler for SIGCHLD so that our 'select' gets interrupted when something exits*/ sigact.sa_handler = default_signal_handler; sigemptyset(&sigact.sa_mask); sigact.sa_flags = 0; sigaction(SIGCHLD, &sigact, NULL); if (FDSelect(listensock, SELECT_READ, NULL)) { fd=TCPServerSockAccept(listensock, &IPStr); if (fork()==0) { //Sub processes shouldn't keep the pid file open, only the parent server //should close(PidFile); //if we've been passed a socket, then make it into stdin/stdout/stderr //but don't do this is fd==0, because then this has already been done by inetd close(0); close(1); close(2); dup(fd); dup(fd); dup(fd); //Having dupped it we no longer need to keep this copy open close(fd); Tempstr=MCopyStr(Tempstr, g_argv[0]," ",IPStr,NULL); for (i=0; i <g_argc; i++) memset(g_argv[i],0,StrLen(g_argv[i])); strcpy(g_argv[0],Tempstr); //In case logging demon was restarted, ensure we have connection before we chroot //Eric Wedaa modified the following line to log to the LongTail honeypot consolidation server openlog("ptelnetd",LOG_PID|LOG_NDELAY,LOG_AUTH); HandleClient(); //Should be redundant, but if something goes wrong in HandleClient, we might want this //exit call _exit(0); } close(fd); } waitpid(-1,NULL,WNOHANG); } }
void ConnectManagerMainLoop() { TConnectManagerItem *Item, *NewItem; ListNode *Curr, *Prev; int highfd=0; fd_set ReadSet, WriteSet; int sock, result, SelectResult, NextTimerFire; STREAM *S; time_t Now; struct timeval tv; int MoreData=FALSE; while (1) { MoreData=FALSE; time(&Now); NextTimerFire=60; Curr=ListGetNext(Timers); while (Curr) { Item=(TConnectManagerItem *) Curr->Item; if (Item->LastTimerFire==0) Item->LastTimerFire=Now; result=(Item->LastTimerFire + Item->TimerVal) - Now; if (result < NextTimerFire) NextTimerFire=result; Curr=ListGetNext(Curr); } FD_ZERO(&ReadSet); FD_ZERO(&WriteSet); Curr=ListGetNext(ConnectManServers); while (Curr) { Item=(TConnectManagerItem *) Curr->Item; S=(STREAM *) Item->Data; FD_SET(S->in_fd,&ReadSet); if (S->in_fd > highfd) highfd=S->in_fd; Curr=ListGetNext(Curr); } Curr=ListGetNext(ConnectManClients); while (Curr) { Item=(TConnectManagerItem *) Curr->Item; S=(STREAM *) Item->Data; if (! S) { ListDeleteNode(Curr); continue; } if (S->State & SS_CONNECTING) { FD_SET(S->in_fd,&WriteSet); } if (S->InEnd > S->InStart) MoreData=TRUE; else { //always add to read set FD_SET(S->in_fd,&ReadSet); if (S->in_fd > highfd) highfd=S->in_fd; } Curr=ListGetNext(Curr); } if (MoreData) { tv.tv_usec = 10; tv.tv_sec = 0; SelectResult=0; } else { //SELECT!!! tv.tv_usec = 20000; tv.tv_sec = NextTimerFire; } SelectResult=select(highfd+1,&ReadSet,&WriteSet,NULL,&tv); if (SelectResult > 0) { Curr=ListGetNext(ConnectManServers); while (Curr) { Item=(TConnectManagerItem *) Curr->Item; S=(STREAM *) Item->Data; if (! S) { ListDeleteNode(Curr); continue; } if (FD_ISSET(S->in_fd,&ReadSet)) { sock=TCPServerSockAccept(S->in_fd,&S->Path); if (sock > -1) { S=STREAMFromFD(sock); STREAMSetFlushType(S,FLUSH_LINE,0,0); NewItem=ConnectManagerAddIncoming(S,Item->Name, Item->OnData); if (Item->OnConnect) Item->OnConnect(NewItem); } } Curr=ListGetNext(Curr); } } Curr=ListGetNext(ConnectManClients); while (Curr) { Item=(TConnectManagerItem *) Curr->Item; S=(STREAM *) Item->Data; if (! S) { ListDeleteNode(Curr); continue; } if ((SelectResult > 0) && FD_ISSET(S->in_fd,&WriteSet)) { if (S->State & SS_CONNECTING) { if (STREAMIsConnected(S)) { STREAMSetFlags(S, 0, SF_NONBLOCK); if (Item->OnConnect) Item->OnConnect(Item); } } } if ( (S->InEnd > S->InStart) || ((SelectResult > 0) && (FD_ISSET(S->in_fd,&ReadSet))) ) { if (! (S->State & SS_CONNECTING)) { if (Item->OnData) { result=Item->OnData(S, Item->Name); if (! result) { STREAMClose(S); Prev=ListGetPrev(Curr); ListDeleteNode(Curr); free(Item); Curr=Prev; } else if (result==RECONNECT) { STREAMClose(S); S=STREAMCreate(); STREAMConnectToHost(S,Item->Host,Item->Port,CONNECT_NONBLOCK); Item->Data=(void *) S; } } } } Curr=ListGetNext(Curr); } time(&Now); Curr=ListGetNext(Timers); while (Curr) { Item=(TConnectManagerItem *) Curr->Item; if ( (Now - Item->LastTimerFire) >= Item->TimerVal ) { if (Item->OnData) ((ONTIMER_FUNC)Item->OnData)(Item->Data,Item->Name); Item->LastTimerFire=Now; } Curr=ListGetNext(Curr); } } }