예제 #1
0
int STREAMDoPostConnect(STREAM *S, int Flags)
{
    int result=TRUE;
    char *ptr;
    struct timeval tv;


    if ((S->in_fd > -1) && (S->Timeout > 0) )
    {
        tv.tv_sec=S->Timeout;
        tv.tv_usec=0;
        if (FDSelect(S->in_fd, SELECT_WRITE, &tv) <=0)
        {
            close(S->in_fd);
            S->in_fd=-1;
            S->out_fd=-1;
        }
        else if (! (Flags & CONNECT_NONBLOCK))  STREAMSetNonBlock(S, FALSE);
    }

    if (S->in_fd > -1)
    {
        S->Type=STREAM_TYPE_TCP;
        result=TRUE;
        STREAMSetFlushType(S,FLUSH_LINE,0);
    }

//if (Flags & CONNECT_SOCKS_PROXY) result=DoSocksProxyTunnel(S);
    if (Flags & CONNECT_SSL) DoSSLClientNegotiation(S, Flags);

    ptr=GetRemoteIP(S->in_fd);
    if (ptr) STREAMSetValue(S,"PeerIP",ptr);

    return(result);
}
예제 #2
0
STREAM *STREAMSpawnFunction(BASIC_FUNC Func, void *Data, const char *Config)
{
    int to_fd, from_fd, *iptr;
    pid_t pid=0;
    STREAM *S=NULL;
    char *Tempstr=NULL;
    int Flags=0;

    Flags=TTYParseConfig(Config, NULL);
    if (Flags & TTYFLAG_PTY)
    {
        pid=PseudoTTYSpawnFunction(&to_fd, Func, Data, Flags, Config);
        from_fd=to_fd;
    }
    else
    {
        iptr=NULL;
        //if (Flags & COMMS_COMBINE_STDERR) iptr=(int *) COMMS_COMBINE_STDERR;
        pid=PipeSpawnFunction(&to_fd, &from_fd, iptr, Func, Data, Config);
    }

    if (pid > 0) S=STREAMFromDualFD(from_fd, to_fd);
    if (S)
    {
        STREAMSetFlushType(S,FLUSH_LINE,0,0);
        Tempstr=FormatStr(Tempstr,"%d",pid);
        STREAMSetValue(S,"PeerPID",Tempstr);
        S->Type=STREAM_TYPE_PIPE;
    }

    DestroyString(Tempstr);
    return(S);
}
예제 #3
0
STREAM *STREAMOpenFile(const char *FilePath, int Flags)
{
int fd, Mode=FALSE;
STREAM *Stream;
struct stat myStat;

Mode = Flags & ~(O_LOCK|O_TRUNC);

if (strcmp(FilePath,"-")==0)
{
Stream=STREAMFromDualFD(0,1);
Stream->Path=CopyStr(Stream->Path,FilePath);
return(Stream);
}

fd=open(FilePath, Mode, 0600);
if (fd==-1) return(NULL);

if (Flags & O_LOCK)
{
	if (flock(fd,LOCK_EX | LOCK_NB)==-1)
	{
		close(fd);
		return(NULL);
	}

}

// check for symlink naughtyness. Basically a malicious user can
// try to guess the name of the file we are going to open in order
// to get us to write somewhere other than intended.


if (lstat(FilePath, &myStat) !=0)
{
  close(fd);
  return(NULL);
}

if (S_ISLNK(myStat.st_mode))
{
	syslog(LOG_USER | LOG_WARNING, "STREAMOpenFile Opened symlink when trying to open %s. Possible DOS attack?",FilePath);
  close(fd);
  return(NULL);
}

if (Flags & O_TRUNC) ftruncate(fd,0);

Stream=STREAMFromFD(fd);
Stream->Path=CopyStr(Stream->Path,FilePath);
STREAMSetTimeout(Stream,0);
STREAMSetFlushType(Stream,FLUSH_FULL,0);

return(Stream);
}
예제 #4
0
STREAM *STREAMSpawnFunction(BASIC_FUNC Func, void *Data)
{
int to_fd, from_fd;
pid_t pid;
STREAM *S=NULL;
char *Tempstr=NULL;

pid=PipeSpawnFunction(&to_fd, &from_fd, COMMS_COMBINE_STDERR, Func, Data, "", "" );
if (pid > 0) S=STREAMFromDualFD(from_fd, to_fd);
if (S)
{
	STREAMSetFlushType(S,FLUSH_LINE,0,0);
	Tempstr=FormatStr(Tempstr,"%d",pid);
	STREAMSetValue(S,"PeerPID",Tempstr);
}

DestroyString(Tempstr);
return(S);
}
예제 #5
0
STREAM *STREAMSpawnCommand(const char *Command, const char *User, const char *Group, int Flags)
{
int to_fd, from_fd;
pid_t pid;
STREAM *S=NULL;
char *Tempstr=NULL;


if (Flags & SPAWN_TRUST_COMMAND) Tempstr=CopyStr(Tempstr,Command);
else Tempstr=MakeShellSafeString(Tempstr, Command, 0);

if (Flags & COMMS_BY_PTY)
{
	pid=PseudoTTYSpawn(&to_fd,Tempstr,User,Group,Flags);
	if (pid > 0) S=STREAMFromFD(to_fd);
}
else 
{
	if (Flags & COMMS_COMBINE_STDERR)
	{
		pid=PipeSpawn(&to_fd, &from_fd, COMMS_COMBINE_STDERR, Tempstr,User,Group);
	}
	else pid=PipeSpawn(&to_fd, &from_fd, NULL, Tempstr,User,Group);
	if (pid > 0) S=STREAMFromDualFD(from_fd, to_fd);
}

if (S)
{
	STREAMSetFlushType(S,FLUSH_LINE,0,0);
	Tempstr=FormatStr(Tempstr,"%d",pid);
	STREAMSetValue(S,"PeerPID",Tempstr);
}

DestroyString(Tempstr);
return(S);
}
예제 #6
0
int STREAMConnectToHost(STREAM *S, char *DesiredHost, int DesiredPort,int Flags)
{
    ListNode *Curr;
    char *Token=NULL, *ptr;
    int result=FALSE;
    int HopNo=0, val;
    ListNode *LastHop=NULL;

    S->Path=FormatStr(S->Path,"tcp:%s:%d",DesiredHost,DesiredPort);
//Find the last hop, used to decide what ssh command to use
    Curr=ListGetNext(S->Values);
    while (Curr)
    {
        ptr=GetToken(Curr->Tag,":",&Token,0);
        if (strcasecmp(Token,"ConnectHop")==0) LastHop=Curr;
        Curr=ListGetNext(Curr);
    }

    STREAMSetFlushType(S,FLUSH_LINE,0);
    Curr=ListGetNext(S->Values);
    while (Curr)
    {
        ptr=GetToken(Curr->Tag,":",&Token,0);

        if (strcasecmp(Token,"ConnectHop")==0) result=STREAMProcessConnectHop(S, (char *) Curr->Item,Curr==LastHop);

        HopNo++;
        if (! result) break;
        Curr=ListGetNext(Curr);
    }

//If we're not handling the connection through 'Connect hops' then
//just connect to host
    if ((HopNo==0) && StrLen(DesiredHost))
    {
        if (Flags & CONNECT_NONBLOCK) S->Flags |= SF_NONBLOCK;
        val=Flags;
        if (S->Timeout > 0) val |= CONNECT_NONBLOCK;

        S->in_fd=ConnectToHost(DesiredHost,DesiredPort,val);
        S->out_fd=S->in_fd;
        if (S->in_fd > -1) result=TRUE;
    }

    if (result==TRUE)
    {
        if (Flags & CONNECT_NONBLOCK)
        {
            S->State |=SS_CONNECTING;
            S->Flags |=SF_NONBLOCK;
        }
        else
        {
            S->State |=SS_CONNECTED;
            STREAMDoPostConnect(S, Flags);
        }
    }


    return(result);
}
예제 #7
0
int STREAMProcessConnectHop(STREAM *S, char *HopURL, int LastHop)
{
int val, result=FALSE;
char *Token=NULL, *Token2=NULL;
char *Tempstr=NULL;
char *User=NULL, *Host=NULL,*Pass=NULL, *KeyFile=NULL;
int Port=0;

ParseConnectDetails(HopURL, &Token, &Host, &Token2, &User, &Pass, NULL);

Port=atoi(Token2);

val=MatchTokenFromList(Token,HopTypes,0);
switch (val)
{
	case CONNECT_HOP_TCP:
		if (S->in_fd==-1)
		{
			S->in_fd=ConnectToHost(Host,Port,0); 
			S->out_fd=S->in_fd;
			if (S->in_fd > -1) result=TRUE;
		}
		break;

	case CONNECT_HOP_HTTPTUNNEL:
		result=DoHTTPProxyTunnel(S, Host, Port, S->Path, 0);
	break;	

	case CONNECT_HOP_SSH:
	case CONNECT_HOP_SSHTUNNEL:
		result=ConnectHopSSH(S, val, Host, Port, User, Pass, S->Path);
	break;

	case CONNECT_HOP_SOCKS4:
		result=ConnectHopSocks(S, val, Host, Port, User, Pass, S->Path);
	break;

	case CONNECT_HOP_SHELL_CMD:
	break;

	case CONNECT_HOP_TELNET:
		if (Port > 0)
		{
		Tempstr=FormatStr(Tempstr,"telnet -8 %s %d ",Host, Port);
		}
		else Tempstr=FormatStr(Tempstr,"telnet -8 %s ",Host);

		if (S->in_fd==-1) 
		{
			PseudoTTYSpawn(& S->in_fd,Tempstr,0);
		        S->out_fd=S->in_fd;
			if (S->in_fd > -1)
			{
				result=TRUE;
				STREAMSetFlushType(S,FLUSH_LINE,0,0);
			}

		}
		else 
		{
			Tempstr=CatStr(Tempstr,";exit\n");
			STREAMWriteLine(Tempstr,S);
			result=TRUE;
		}
		if (StrLen(User) > 0) 
		{
			Tempstr=MCopyStr(Tempstr,User,"\n",NULL);
			STREAMExpectAndReply(S,"ogin:",Tempstr);
		}
		if (StrLen(Pass) > 0) 
		{
			Tempstr=MCopyStr(Tempstr,Pass,"\n",NULL);
			STREAMExpectAndReply(S,"assword:",Tempstr);
		}
		STREAMExpectSilence(S,2);
		break;


}

DestroyString(Tempstr);
DestroyString(Token);
DestroyString(KeyFile);
DestroyString(Host);
DestroyString(User);
DestroyString(Pass);

STREAMFlush(S);
return(result);
}
예제 #8
0
int ConnectHopSSH(STREAM *S,int Type, char *Host, int Port, char *User, char *Pass, char *NextHop)
{
char *Tempstr=NULL, *KeyFile=NULL, *Token=NULL, *Token2=NULL;
STREAM *AuthS;
int result=FALSE, val;
unsigned int TunnelPort=0;

if (Type==CONNECT_HOP_SSHTUNNEL) 
{
	TunnelPort=(rand() % (0xFFFF - 9000)) +9000;
	//Host will be Token, and port Token2
	ParseConnectDetails(NextHop, NULL, &Token, &Token2, NULL, NULL, NULL);
	Tempstr=FormatStr(Tempstr,"ssh -2 -N %s@%s  -L %d:%s:%s ",User,Host,TunnelPort,Token,Token2);

}
else Tempstr=MCopyStr(Tempstr,"ssh -2 -T ",User,"@",Host, " ", NULL );

if (strncmp(Pass,"keyfile:",8)==0)
{

		if (S->in_fd != -1)
		{
			Token=FormatStr(Token,".%d-%d",getpid(),time(NULL));
			SendPublicKeyToRemote(S,Token,Pass+8);
			KeyFile=CopyStr(KeyFile,Token);
		}
		Tempstr=MCatStr(Tempstr,"-i ",KeyFile," ",NULL);
		}

		if (Port > 0)
		{
		Token=FormatStr(Token," -p %d ",Port);
		Tempstr=CatStr(Tempstr,Token);
		}

		if (Type==CONNECT_HOP_SSHTUNNEL) 
		{
			Tempstr=CatStr(Tempstr, " 2> /dev/null");
			AuthS=STREAMSpawnCommand(Tempstr,COMMS_BY_PTY);
			STREAMSetValue(S,"HelperPID:SSH",STREAMGetValue(AuthS,"PeerPID"));
		}
		else if (S->in_fd==-1) 
		{
			Tempstr=CatStr(Tempstr, " 2> /dev/null");
			PseudoTTYSpawn(&S->in_fd,Tempstr,0);
			S->out_fd=S->in_fd;
			if (S->in_fd > -1)
			{
				result=TRUE;
				STREAMSetFlushType(S,FLUSH_LINE,0,0);
			}
			AuthS=S;
		}
		else 
		{
			if (StrLen(KeyFile)) Tempstr=MCatStr(Tempstr," ; rm -f ",KeyFile,NULL);
			Tempstr=CatStr(Tempstr,"; exit\n");
			STREAMWriteLine(Tempstr,S);
			result=TRUE;
			AuthS=S;
		}

		if ((StrLen(KeyFile)==0) && (StrLen(Pass) > 0)) 
		{
			Token=MCopyStr(Token,Pass,"\n",NULL);
			for (val=0; val < 3; val++)
			{
			if (STREAMExpectAndReply(AuthS,"assword:",Token)) break;
			}
		}
		STREAMSetTimeout(AuthS,100);
		//STREAMExpectSilence(AuthS);
		sleep(3);

		if (Type==CONNECT_HOP_SSHTUNNEL) 
		{
			S->in_fd=ConnectToHost("127.0.0.1",TunnelPort,0);
			S->out_fd=S->in_fd;
			if (S->in_fd > -1) result=TRUE;
		}


DestroyString(Tempstr);
DestroyString(KeyFile);
DestroyString(Token2);
DestroyString(Token);

return(result);
}
예제 #9
0
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);
	}

	
}

}