Exemplo n.º 1
0
int STREAMFlush(STREAM *S)
{
	STREAMWriteBytes(S,NULL,0);
}
Exemplo n.º 2
0
int ConnectHopSocks(STREAM *S, int SocksLevel, const char *ProxyURL, const char *Destination)
{
    char *Tempstr=NULL;
    char *Token=NULL, *Host=NULL, *User=NULL, *Pass=NULL;
    uint8_t *ptr;
    uint32_t IP;
    const char *tptr;
    int result, RetVal=FALSE, val;
    uint8_t HostType=HT_IP4;

    ParseConnectDetails(ProxyURL, NULL, &Host, &Token, &User, &Pass, NULL);
    if (! (S->State & SS_INITIAL_CONNECT_DONE))
    {
        val=atoi(Token);
        S->in_fd=TCPConnect(Host, val, 0);
        S->out_fd=S->in_fd;
        if (S->in_fd == -1)
        {
            RaiseError(0, "ConnectHopSocks", "connection to socks proxy at %s failed", ProxyURL);
            return(FALSE);
        }


        if (SocksLevel==CONNECT_HOP_SOCKS5)
        {
            if (! ConnectHopSocks5Auth(S, User, Pass))
            {
                RaiseError(0, "ConnectHopSocks", "authentication to socks proxy at %s failed", ProxyURL);
                return(FALSE);
            }
        }
    }

//Horrid binary protocol.
    Tempstr=SetStrLen(Tempstr, StrLen(User) + 20 + StrLen(Destination));
    ptr=Tempstr;

//version
    if (SocksLevel==CONNECT_HOP_SOCKS5) *ptr=5;
    else *ptr=4; //version number
    ptr++;

//connection type
    *ptr=1; //outward connection (2 binds a port for incoming)
    ptr++;



//Sort out destination now
    tptr=Destination;
    if (strncmp(tptr,"tcp:",4)==0) tptr+=4;
    tptr=GetToken(tptr,":",&Token,0);
    if (IsIP4Address(Token)) HostType=HT_IP4;
    else if (IsIP6Address(Token)) HostType=HT_IP6;
    else HostType=HT_DOMAIN;


    if (SocksLevel==CONNECT_HOP_SOCKS5)
    {
//Socks 5 has a 'reserved' byte after the connection type
        *ptr=0;
        ptr++;

        *ptr=HostType;
        ptr++;
        switch (HostType)
        {
        case HT_IP4:
            *((uint32_t *) ptr) =StrtoIP(Token);
            ptr+=4;
            break;

        case HT_IP6:
            break;

        default:
            val=StrLen(Token);
            *ptr=val;
            ptr++;
            memcpy(ptr, Token, val);
            ptr+=val;
            break;
        }
    }


//destination port. By a weird coincidence this is in the right place
//for either socks4 or 5, despite the fact that it comes after the
//host in socks5, and before the host in socks4
    *((uint16_t *) ptr) =htons(atoi(tptr));
    ptr+=2;

    if (SocksLevel==CONNECT_HOP_SOCKS4)
    {
        //destination host
        switch (HostType)
        {
        case HT_IP4:
            *((uint32_t *) ptr) =StrtoIP(Token);
            ptr+=4;
            val=StrLen(User)+1;
            memcpy(ptr,User,val);
            ptr+=val;
            break;

        default:
            *((uint32_t *) ptr) =StrtoIP("0.0.0.1");
            ptr+=4;
            break;
        }

        val=StrLen(User)+1;
        memcpy(ptr, User, val);
        ptr+=val;

        //+1 to include terminating \0
        val=StrLen(Token) +1;
        memcpy(ptr, Token, val);
        ptr+=val;
    }

    STREAMWriteBytes(S,Tempstr,(char *)ptr-Tempstr);
    STREAMFlush(S);
    Tempstr=SetStrLen(Tempstr, 32);
    result=STREAMReadBytes(S,Tempstr,32);


    if (SocksLevel==CONNECT_HOP_SOCKS5)
    {
        if ((result > 8) && (Tempstr[0]==5) && (Tempstr[1]==0))
        {
            RetVal=TRUE;
        }
    }
    else
    {
        //Positive response will be 0x00 0x5a 0x00 0x00 0x00 0x00 0x00 0x00
        //although only the leading two bytes (0x00 0x5a, or \0Z) matters
        if ((result==8) && (Tempstr[0]=='\0') && (Tempstr[1]=='Z'))
        {
            RetVal=TRUE;

            IP=*(uint32_t *) (Tempstr + 4);
            if (IP != 0) STREAMSetValue(S, "IPAddress", IPtoStr(IP));
        }
    }


    if (! RetVal) RaiseError(0, "ConnectHopSocks", "socks proxy at %s refused connection to %s", ProxyURL, Destination);

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

    return(RetVal);
}
Exemplo n.º 3
0
void RunTelnetSession(TSession *Session)
{
STREAM *Local, *S;
char *Tempstr=NULL;
int result, fd;
ListNode *Streams;
struct passwd *pwent;
struct group *grent;
struct timeval tv;
time_t Duration, Start, Now, LastActivity;

time(&Start);
LastActivity=Start;
Streams=ListCreate();
ListAddItem(Streams,Session->S);

//if '-real-user' was specified on the command-line, then this overrides
//anything read from password files
if (Settings.Flags & FLAG_FORCE_REALUSER)
{
	Session->RealUser=CopyStr(Session->RealUser,Settings.RealUser);
}

//Get User Details before we chroot! 
if (StrLen(Session->RealUser))
{
    pwent=getpwnam(Session->RealUser);
		if (! pwent)
		{
			syslog(Settings.InfoLogLevel,"Failed to lookup RealUser '%s' for user '%s'",Session->RealUser,Session->User);
			exit(1);
		}
		Session->RealUserUID=pwent->pw_uid;
		Session->GroupID=pwent->pw_gid;
}


//if '-shell' was specified on the command-line, then this overrides
//anything read from password files
if (Settings.Flags & FLAG_FORCE_SHELL)
{
	Session->Shell=CopyStr(Session->Shell,Settings.RealUser);
}


if (Settings.Flags & FLAG_DYNHOME)
{
	Session->HomeDir=SessionSubstituteVars(Session->HomeDir,Settings.DynamicHomeDir,Session);
	Session->HomeDir=SlashTerminateDirectoryPath(Session->HomeDir);
	MakeDirPath(Session->HomeDir,0777);
}

//CD to the user's home directory
if (StrLen(Session->HomeDir)) 
{
	chdir(Session->HomeDir);
}

DoBindMounts(Settings.BindMounts,0);

//This login script allows setting up any aspects of the environment before we launch the shell. For instance it 
//might be used to copy files into the chroot environment before chrooting
if (StrLen(Settings.LoginScript)) system(Settings.LoginScript);


//LAUNCH THE SHELL FUNCTION!!! This launches the program that the telnet user is 'speaking' to.
//If chhome is active, then it will be chrooted into the user's home directory


PseudoTTYSpawnFunction(&fd, LaunchPtyFunc, Session,  TTYFLAG_CANON | TTYFLAG_ECHO | TTYFLAG_CRLF | TTYFLAG_LFCR | TTYFLAG_IGNSIG);
Local=STREAMFromFD(fd);
STREAMSetTimeout(Local,0);


//Might as well chroot on this side of the pipe too, unless we have a 'LogoutScript'
//Logout scripts exist to allow copying stuff back out of the chroot when the session is
//finished. We can't do this if we chroot this side as well as the 'shell' side
if (
		(! StrLen(Settings.LogoutScript)) &&
		(Settings.Flags & FLAG_CHHOME) 
	) chroot(".");

//DON'T SWITCH USER. NEED root TO UNBIND MOUNTS
//if (setreuid(Session->RealUserUID,Session->RealUserUID) !=0) exit(1);

ListAddItem(Streams,Local);


Tempstr=SetStrLen(Tempstr,4096);
while (1)
{
	if (Settings.IdleTimeout) tv.tv_sec=Settings.IdleTimeout;
	else tv.tv_sec=3600 * 24;
  S=STREAMSelect(Streams,&tv);
	time(&Now);
  if (S)
  {
    if (S==Session->S)
		{
			result=TelnetReadBytes(Session->S, Tempstr, 4096, TNRB_NONBLOCK);
			if (result ==-1) break;
			STREAMWriteBytes(Local,Tempstr,result);
		}
    else 
		{
			result=STREAMReadBytes(Local,Tempstr,4096);
			if (result < 0) break;
			STREAMWriteBytes(Session->S,Tempstr,result);

    if (result < 0) break;
		}
		if (Settings.Flags & FLAG_WINSIZE) SetWindowSize(Session->S->out_fd);
		LastActivity=Now;
  }

	
	if ((Settings.IdleTimeout > 0) && ((Now - LastActivity) > Settings.IdleTimeout)) break;
}

if (StrLen(Settings.LogoutScript)) system(Settings.LogoutScript);
if (Settings.Flags & FLAG_UNMOUNT) UndoBindMounts(Settings.BindMounts, 0);
if (Settings.Flags & FLAG_DYNHOME) rmdir(Session->HomeDir);

Duration=time(NULL) - Start;
syslog(Settings.InfoLogLevel,"%s@%s logged out after %d secs",Session->User,Session->ClientIP, Duration);

STREAMClose(Session->S);
STREAMClose(Local);
DestroyString(Tempstr);
}
Exemplo n.º 4
0
int ConnectHopSocks5Auth(STREAM *S, const char *User, const char *Pass)
{
    char *Tempstr=NULL;
    const char *p_Password;
    char *ptr;
    int result, RetVal=FALSE;
    uint8_t len, passlen;

    Tempstr=SetStrLen(Tempstr, 10);

//socks5 version
    Tempstr[0]=5;
//Number of Auth Methods (just 1, username/password)
    Tempstr[1]=1;
//Auth method 2, username/password
    if (StrValid(User) || StrValid(Pass)) Tempstr[2]=SOCKS5_AUTH_PASSWD;
    else Tempstr[2]=SOCKS5_AUTH_NONE;

    STREAMWriteBytes(S,Tempstr,3);
    STREAMFlush(S);

    result=STREAMReadBytes(S,Tempstr,10);
    if ((result > 1) && (Tempstr[0]==5))
    {
        // Second Byte is authentication type selected by the server
        switch (Tempstr[1])
        {
        //no authentication required
        case 0:
            RetVal=TRUE;
            break;

        //gssapi
        case 1:
            break;

        //username/password
        case 2:
            if (Pass)
            {
                p_Password=Pass;
                passlen=strlen(Pass);

            }
            // must be careful with password len, as it won't be null terminated
            else passlen=CredsStoreLookup("", User, &p_Password);

            Tempstr=SetStrLen(Tempstr, StrLen(User) + passlen + 10);
            ptr=Tempstr;
            //version 1 of username/password authentication
            *ptr=1;
            ptr++;

            //username
            len=StrLen(User) & 0xFF;
            *ptr=len;
            ptr++;
            memcpy(ptr, User, len);
            ptr+=len;

            //password
            len=passlen & 0xFF;
            *ptr=len;
            ptr++;
            memcpy(ptr, Pass, len);
            ptr+=len;

            len=ptr-Tempstr;
            STREAMWriteBytes(S,Tempstr,len);

            //we have to flush to be sure data is sent, but this also wipes output
            //data buffer, which is useful given that we just sent a password
            STREAMFlush(S);

            //As this memory contained a password, we wipe it
            xmemset(Tempstr, 0, len);

            result=STREAMReadBytes(S,Tempstr,10);

            //two bytes reply. Byte1 is Version Byte2 is 0 for success
            if ((result > 1) && (Tempstr[0]==1) && (Tempstr[1]==0)) RetVal=TRUE;
            break;
        }
    }

    DestroyString(Tempstr);

    return(RetVal);
}