Example #1
0
int STREAMWriteLine(const char *Buffer, STREAM *S)
{
int result;

if (StrLen(Buffer) < 1) return(FALSE);
result=STREAMWriteBytes(S,Buffer,strlen(Buffer));
if (result < 0) return(result);
if (S->Flags & FLUSH_LINE) result=STREAMFlush(S);
return(result);
}
Example #2
0
int ConnectHopHTTPSProxy(STREAM *S, const char *Proxy, const char *Destination)
{
    char *Tempstr=NULL, *Token=NULL;
    char *Proto=NULL, *Host=NULL, *User=NULL, *Pass=NULL;
    const char *ptr=NULL;
    int result=FALSE, Port;

    ParseConnectDetails(Proxy, &Token, &Host, &Token, &User, &Pass, NULL);
    Port=atoi(Token);
    if (! (S->State & SS_INITIAL_CONNECT_DONE))
    {
        if (Port==0) Port=443;
        S->in_fd=TCPConnect(Host,Port,0);
        S->out_fd=S->in_fd;
        if (S->in_fd == -1)
        {
            RaiseError(0, "ConnectHopHTTPSProxy", "failed to connect to proxy at %s:%d", Host, Port);
            return(FALSE);
        }
    }

    ptr=Destination;
    if (strncmp(ptr,"tcp:",4)==0) ptr+=4;
    Tempstr=FormatStr(Tempstr,"CONNECT %s HTTP/1.1\r\n\r\n",ptr);

    STREAMWriteLine(Tempstr,S);
    STREAMFlush(S);

    Tempstr=STREAMReadLine(Tempstr,S);
    if (Tempstr)
    {
        StripTrailingWhitespace(Tempstr);

        ptr=GetToken(Tempstr," ",&Token,0);
        ptr=GetToken(ptr," ",&Token,0);

        if (*Token=='2') result=TRUE;
        else RaiseError(0, "ConnectHopHTTPSProxy", "proxy request to %s:%d failed. %s", Host, Port, Tempstr);

        while (StrLen(Tempstr))
        {
            Tempstr=STREAMReadLine(Tempstr,S);
            StripTrailingWhitespace(Tempstr);
        }
    }
    else RaiseError(0, "ConnectHopHTTPSProxy", "proxy request to %s:%d failed. Server Disconnectd.", Host, Port);

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

    return(result);
}
Example #3
0
int STREAMDisassociateFromFD(STREAM *Stream)
{
int fd;

if (! Stream) return(-1);
fd=Stream->in_fd;
STREAMFlush(Stream);
DestroyString(Stream->InputBuff);
DestroyString(Stream->OutputBuff);
DestroyString(Stream->Path);
free(Stream);
return(fd);
}
Example #4
0
int HTTPServerExecCGI(STREAM *ClientCon, HTTPSession *Session, const char *ScriptPath)
{
char *Tempstr=NULL;
int i;

      if (StrLen(Session->Group) && (! SwitchGroup(Session->Group)))
      {
        LogToFile(Settings.LogPath,"WARN: Failed to switch to group '%s' to execute script: %s",Session->Group, ScriptPath);
      }


    //Switch user. ALAYA WILL NOT RUN SCRIPTS AS ROOT!
      if ((geteuid()==0) && (! SwitchUser(Session->RealUser)))
      {
        LogToFile(Settings.LogPath,"ERROR: Failed to switch to user '%s' to execute script: %s",Session->RealUser, ScriptPath);
				return(FALSE);
      }

      if (geteuid()==0)
      {
        HTTPServerSendHTML(ClientCon, NULL, "403 Forbidden","Alaya will not run .cgi programs as 'root'.<br>\r\nTry setting 'Default User' in config file or command line.");
        LogToFile(Settings.LogPath, "Failed to switch user to '%s' for running a .cgi program. Will not run programs as 'root'. Set 'DefaultUser' in config file or command line.",Session->RealUser);
      }
      else
      {
        Session->ResponseCode=CopyStr(Session->ResponseCode,"200 OK");
        HTTPServerSendHeaders(ClientCon, Session, HEADERS_CGI);
        STREAMFlush(ClientCon);

        SetupEnvironment(Session, ScriptPath);
        Tempstr=FindScriptHandlerForScript(Tempstr,ScriptPath);
        if (Tempstr) LogToFile(Settings.LogPath,"Execute script: %s using handler '%s'",ScriptPath,Tempstr);
        else LogToFile(Settings.LogPath,"Execute script: %s QUERY_STRING= '%s'",ScriptPath,getenv("QUERY_STRING"));

        //Only do this late! Otherwise logging won't work.
        for (i=3; i < 1000; i++) close(i);

        if (StrLen(Tempstr)) execl(Tempstr, Tempstr, ScriptPath,NULL);
        else execl(ScriptPath,ScriptPath,NULL);

        /*If this code gets executed, then 'execl' failed*/
        HTTPServerSendHTML(ClientCon, Session, "403 Forbidden","You don't have permission for that.");
  
        //Logging won't work after we've closed all the file descriptors!
        LogToFile(Settings.LogPath,"Cannot execute script: %s",ScriptPath);
    }

	//if we get there then, for whatever reason, our script didn't run
	DestroyString(Tempstr);
	return(FALSE);
}
Example #5
0
pid_t HandleChildRegisterRequest(STREAM *S, char *Data)
{
char *Tempstr=NULL, *Host=NULL, *ptr;
int Flags=0;
time_t LastTime;

ptr=GetToken(Data,":",&Host,0);

if (*ptr=='A') Flags |= LOGIN_CHECK_ALLOWED;
if (*ptr=='I') Flags |= LOGGED_IN;
if (*ptr=='F') Flags |= LOGIN_FAIL;
if (*ptr=='C') Flags |= LOGIN_CHANGE;

ptr=GetVar(Settings.HostConnections,Host);

LastTime=time(NULL);
if (Flags & LOGIN_CHECK_ALLOWED) 
{
	if (ptr && (strcmp(ptr,"logout")==0))
	{
	SetVar(Settings.HostConnections,Host,"");
	STREAMWriteLine("logout\n",S);
	}
	else
	{
		STREAMWriteLine("okay\n",S);
	}
}
else if (Flags & LOGIN_CHANGE) 
{
	Tempstr=CopyStr(Tempstr,"logout");
	SetVar(Settings.HostConnections,Host,Tempstr);
	STREAMWriteLine("okay\n",S);
}
else
{
	if (Flags & LOGGED_IN) LastTime=0;
	Tempstr=FormatStr(Tempstr,"%ld",LastTime);
	SetVar(Settings.HostConnections,Host,Tempstr);
	STREAMWriteLine("okay\n",S);
}

STREAMFlush(S);

DestroyString(Tempstr);
DestroyString(Host);

return(0);
}
Example #6
0
int ConnectHopSocks(STREAM *S, int Type, const char *Host, int Port, const char *User, const char *Pass, const char *Path)
{
char *Tempstr=NULL;
uint8_t *ptr;
char *Token=NULL;
const char *tptr;
int result, RetVal=FALSE;

S->in_fd=ConnectToHost(Host,Port,0); 
S->out_fd=S->in_fd;
if (S->in_fd == -1) return(FALSE);


//Horrid binary protocol. 
Tempstr=SetStrLen(Tempstr, StrLen(User) +20);
ptr=Tempstr;
*ptr=4; //version number
ptr++;
*ptr=1; //outward connection (2 binds a port for incoming)
ptr++;

tptr=Path;
if (strncmp(tptr,"tcp:",4)==0) tptr+=4;
tptr=GetToken(tptr,":",&Token,0);

//destination port
*((uint16_t *) ptr) =htons(atoi(tptr));
ptr+=2;

//destination host
*((uint32_t *) ptr) =StrtoIP(Token);
ptr+=4;

strcpy(ptr,User);
ptr+=StrLen(User);
ptr++;
STREAMWriteBytes(S,Tempstr,(char *)ptr-Tempstr); STREAMFlush(S);
result=STREAMReadBytes(S,Tempstr,8);

//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;


DestroyString(Tempstr);
DestroyString(Token);

return(RetVal);
}
Example #7
0
int IDriveCloseFileWrite(TFileStore *FS, STREAM *S)
{
	char *Tempstr=NULL, *Error=NULL, *ptr;
	ListNode *Vars=NULL;
	HTTPInfoStruct *Info;
	int result=FALSE, val;

	Info=(HTTPInfoStruct *) FS->Extra;
	if (Info)
	{
	Tempstr=MCopyStr(Tempstr,"\r\n--",STREAMGetValue(S,"Boundary"),"--\r\n",NULL);
	STREAMWriteLine(Tempstr,S);
	STREAMFlush(S);

	HTTPTransact(Info);
			

	
/*
<?xml version="1.0" encoding="UTF-8"?>
<tree message="SUCCESS">
    <item filename="autoget.c" filesize="27620"
        lmd="1969/12/31 16:00:00" message="SUCCESS"/>
</tree>
*/

		val=HTTPReadDocument(S, &Tempstr);
		if (Settings.Flags & FLAG_VERBOSE) printf("\n%s\n",Tempstr);

		Vars=ListCreate();
		IDriveParseResponse(Tempstr, Vars);
		Tempstr=CopyStr(Tempstr,GetVar(Vars,"message"));
		if (strcmp(Tempstr,"SUCCESS")==0) 
		{
				val=atoi(STREAMGetValue(S,"Transfer-Size"));

				if (val==atoi(GetVar(Vars,"filesize"))) result=TRUE;	
				else result=ERR_INTERRUPTED;
		}
		else 
		{
			SetVar(FS->Vars,"Error",GetVar(Vars,"desc"));
			result=ERR_CUSTOM;
		}
	}

DestroyString(Tempstr);
return(result);
}
Example #8
0
double STREAMTell(STREAM *S)
{
double pos;

if (S->OutEnd > 0) STREAMFlush(S);

#ifdef _LARGEFILE64_SOURCE
pos=(double) lseek64(S->in_fd,0,SEEK_CUR);
#else
pos=(double) lseek(S->in_fd,0,SEEK_CUR);
#endif
pos-=(S->InEnd-S->InStart);

return(pos);
}
Example #9
0
int STREAMDeleteDataProcessor(STREAM *S, char *Class, char *Name)
{
ListNode *Curr;
char *Tempstr=NULL;
int len;

STREAMFlush(S);

Tempstr=MCopyStr(Tempstr,Class,":",Name,NULL);
Curr=ListFindNamedItem(S->ProcessingModules,Tempstr);
ListDeleteNode(Curr);

DestroyString(Tempstr);
return(TRUE);
}
Example #10
0
void AlayaLog(char *Msg)
{
char *Tempstr=NULL;
     
if (ParentProcessPipe)
{
  Tempstr=MCopyStr(Tempstr,"LOG ",Msg, "'\n",NULL);
  STREAMWriteLine(Tempstr,ParentProcessPipe);
  STREAMFlush(ParentProcessPipe);
}
else LogToFile(Settings.LogPath,Msg);


DestroyString(Tempstr);
}
Example #11
0
char *TerminalReadText(char *RetStr, int Flags, STREAM *S)
{
int inchar, len=0;
char outchar;

inchar=STREAMReadChar(S);
while (inchar != EOF)
{
	if (Flags & TERM_SHOWTEXT) outchar=inchar & 0xFF;
	if (Flags & TERM_SHOWSTARS) 
	{
		if ((outchar & 0xFF) =='\n') outchar=inchar & 0xFF;
		else if ((outchar & 0xFF) =='\b') outchar=inchar & 0xFF;
		else outchar='*';
	}


	if (Flags & TERM_SHOWTEXTSTARS) 
	{
		switch (inchar)
		{

		case '\n':
		case '\r':
		case 0x08:
		break;

		default:
		if (len > 0) STREAMWriteString("\x08*",S);
		break;
		}

		outchar=inchar & 0xFF;
	}


	STREAMWriteBytes(S, &outchar,1);
	STREAMFlush(S);
	if (inchar == '\n') break;
	if (inchar == '\r') break;

	RetStr=AddCharToBuffer(RetStr,len++, inchar & 0xFF);
	inchar=STREAMReadChar(S);
}

return(RetStr);
}
Example #12
0
off_t STREAMSendFile(STREAM *In, STREAM *Out, off_t Max)
{
char *Buffer=NULL;
int BuffSize=BUFSIZ;
off_t val, result=SENDFILE_FAILED;

#ifdef USE_SENDFILE

//if we are not using ssl and not using processor modules, we can use 
//kernel-level copy!

#include <sys/sendfile.h>

val=In->Flags | Out->Flags;
if ((! (val & SF_SSL)) && (ListSize(In->ProcessingModules)==0) && (ListSize(Out->ProcessingModules)==0))
{
	val=0;
	STREAMFlush(Out);
	result=sendfile(Out->out_fd, In->in_fd,0,BUFSIZ);
	while (result > 0)
	{
		val+=result;
		if ((Max > 0) && (val >= Max)) break;
		result=sendfile(Out->out_fd, In->in_fd,0,BUFSIZ);
	}
}

#endif

if (result==SENDFILE_FAILED)
{
	val=0;
	Buffer=SetStrLen(Buffer,BuffSize);
	result=STREAMReadBytes(In,Buffer,BuffSize);
	while (result >=0)
	{
		val+=STREAMWriteBytes(Out,Buffer,result);
		if ((Max > 0) && (val >= Max)) break;
		result=STREAMReadBytes(In,Buffer,BuffSize);
	}
}

DestroyString(Buffer);

return(val);
}
Example #13
0
int ProxyControlConnect(TSession *Session, char *Host, int Port)
{
char *Tempstr=NULL;
int fd, result=FALSE;

if (StrLen(Host)==0) 
{
	SendLoggedLine(Session,"421 ERROR: Proxy cannot connect. No destination host.");
}
else 
{
Tempstr=IPCRequest(Tempstr, Session, "GetIP", Host);

   if (strcmp(Tempstr,"DENIED")==0)
   {
      Tempstr=FormatStr(Tempstr,"421 ERROR: Proxy connection denied for host %s:%d",Host,Port);
      SendLoggedLine(Session,Tempstr);

   }
   else
  {
      fd=ConnectToHost(Tempstr,Port,FALSE);
      if (fd==-1)
      {
      	Tempstr=FormatStr(Tempstr,"421 ERROR: Proxy cannot connect to host %s:%d",Host,Port);
        SendLoggedLine(Session,Tempstr);
      }
			else
			{
     	 Session->ProxySock=STREAMFromFD(fd);
     	 result=TRUE;
     	 do
     	 {
     	  Tempstr=STREAMReadLine(Tempstr,Session->ProxySock);
     	  STREAMWriteLine(Tempstr,Session->ClientSock);
     	 } while ( (Tempstr[3]=='-') || (isspace(Tempstr[0])) );
			STREAMFlush(Session->ClientSock);
			}
  }
}

DestroyString(Tempstr);
return(result);
}
Example #14
0
pid_t HandlePostFileRequest(STREAM *ClientCon, char *Data)
{
HTTPSession *Response;
STREAM *S;
char *Tempstr=NULL;
pid_t pid;

pid=fork();
if (pid==0)
{	
	Response=ParseSessionInfo(Data);
	Tempstr=FindFileInPath(Tempstr,Response->Path,Response->SearchPath);
	Response->Path=CopyStr(Response->Path, Tempstr);

	if (! SwitchGroup(Response->Group))
	{
		LogToFile(Settings.LogPath,"WARN: Failed to switch to group '%s' when posting  '%s'", Response->RealUser, Tempstr);
	}


	if (! SwitchUser(Response->RealUser))
	{
		LogToFile(Settings.LogPath,"ERROR: Failed to switch to user '%s' when posting to document '%s'", Tempstr);
		LogFileFlushAll(TRUE);
		_exit(0);
	}

 LogToFile(Settings.LogPath,"SWITCH USER: '******' posting document '%s'", Response->RealUser, Response->Group, Tempstr);

	STREAMWriteLine("READY\n",ClientCon); STREAMFlush(ClientCon);
	HTTPServerHandlePost(ClientCon, Response);
	
	//exit 1 means that we can keep connection alive for re-use
	LogFileFlushAll(TRUE);
	if (Response->Flags & SESSION_KEEPALIVE) _exit(1);
	_exit(0);
}
else ClientCon->State |= SS_EMBARGOED;

DestroyString(Tempstr);

return(pid);
}
Example #15
0
int PipeCommandProcessorWrite(TProcessingModule *ProcMod, const char *InData, int InLen, char **OutData, int *OutLen, int Flush)
{
STREAM *S;

S=(STREAM *) ProcMod->Data;
if (InLen > 0)
{
	STREAMWriteBytes(S,InData,InLen);
	STREAMFlush(S);
}

if (Flush) 
{
	if (S->out_fd > -1) close(S->out_fd);
	S->out_fd=-1;
}
else if (! STREAMCheckForBytes(S)) return(0);
return(STREAMReadBytes(S,*OutData,*OutLen));
}
Example #16
0
STREAM *STREAMSelect(ListNode *Streams, struct timeval *tv)
{
 fd_set SelectSet;
 STREAM *S;
 ListNode *Curr;
 int highfd=0, result;
 
 FD_ZERO(&SelectSet);
 
 Curr=ListGetNext(Streams);
 while (Curr)
 {
  S=(STREAM *) Curr->Item;
	if (! (S->State & SS_EMBARGOED))
	{
	//Pump any data in the stream
	 STREAMFlush(S);
   if (S->InEnd > S->InStart) return(S);
   FD_SET(S->in_fd,&SelectSet);
   if (S->in_fd > highfd) highfd=S->in_fd;
	}

  Curr=ListGetNext(Curr);
 }
   
 result=select(highfd+1,&SelectSet,NULL,NULL,tv);
 
 if (result > 0)
 {
   Curr=ListGetNext(Streams);
   while (Curr)
   {
     S=(STREAM *) Curr->Item;
    if (FD_ISSET(S->in_fd,&SelectSet)) return(S);
     Curr=ListGetNext(Curr);
   }
 }
 
 return(NULL);
}
Example #17
0
int SMTPInteract(const char *Line, STREAM *S)
{
    char *Tempstr=NULL;
    int result=FALSE;

    if (StrValid(Line)) STREAMWriteLine(Line, S);
    STREAMFlush(S);
    Tempstr=SMTPRead(Tempstr, S);

    /*
    syslog(LOG_DEBUG,"mail >> %s",Line);
    syslog(LOG_DEBUG,"mail << %s",Tempstr);
    */

    if (
        StrValid(Tempstr) &&
        ( (*Tempstr=='2') || (*Tempstr=='3') )
    ) result=TRUE;

    DestroyString(Tempstr);
    return(result);
}
Example #18
0
pid_t HandleGetFileRequest(STREAM *ClientCon, char *Data)
{
HTTPSession *Response;
char *Tempstr=NULL;
pid_t pid;


pid=fork();
if (pid==0)
{
	Response=ParseSessionInfo(Data);
	Tempstr=FindFileInPath(Tempstr,Response->Path,Response->SearchPath);
	if (! SwitchGroup(Response->Group))
	{
		LogToFile(Settings.LogPath,"WARN: Failed to switch to group '%s' when getting document '%s'", Response->RealUser, Tempstr);
	}

	if (! SwitchUser(Response->RealUser))
	{
		LogToFile(Settings.LogPath,"ERROR: Failed to switch to user '%s' when getting document '%s'", Tempstr);
		LogFileFlushAll(TRUE);
		_exit(0);
	}


	STREAMWriteLine("READY\n",ClientCon); STREAMFlush(ClientCon);
	HTTPServerSendDocument(ClientCon, Response, Tempstr, HEADERS_SENDFILE|HEADERS_USECACHE|HEADERS_KEEPALIVE);
		
	//exit 1 means that we can keep connection alive for re-use
	LogFileFlushAll(TRUE);
	if (Response->Flags & SESSION_KEEPALIVE) _exit(1);
	_exit(0);
}

DestroyString(Tempstr);

return(pid);
}
Example #19
0
int HTTPServerHandleRegister(HTTPSession *Session, int Flags)
{
char *Tempstr=NULL, *Name=NULL, *Value=NULL, *ptr;
char *FlagChar="";
int result=FALSE;


	if (Flags & LOGGED_IN) FlagChar="I";
	if (Flags & LOGIN_FAIL) FlagChar="F";
	Tempstr=MCopyStr(Tempstr,"REG ",Session->ClientIP,":",FlagChar,"\n",NULL);

	//Override above tempstr if Logout value found
	if (Flags & LOGIN_CHANGE) Tempstr=MCopyStr(Tempstr,"REG ",Session->Path,":C\n",NULL);
	if (Flags & LOGIN_CHECK_ALLOWED) 
	{
		FlagChar="A";
		ptr=GetNameValuePair(Session->Arguments,"&","=",&Name,&Value);
		while (ptr)
		{
			if (Name && (strcmp(Name,"Logout")==0)) Tempstr=MCopyStr(Tempstr,"REG ",Value,":",FlagChar,"\n",NULL);
			ptr=GetNameValuePair(ptr,"&","=",&Name,&Value);
		}
	}

	
	STREAMWriteLine(Tempstr,ParentProcessPipe);
	STREAMFlush(ParentProcessPipe);

	Tempstr=STREAMReadLine(Tempstr,ParentProcessPipe);
	if (strcmp(Tempstr,"okay\n")==0) result=TRUE;

DestroyString(Tempstr);
DestroyString(Name);
DestroyString(Value);

return(result);
}
Example #20
0
pid_t HandleChildProcessRequest(STREAM *S)
{
char *Tempstr=NULL, *Token=NULL, *ptr;
pid_t Pid=0;

Tempstr=STREAMReadLine(Tempstr,S);

if (! Tempstr) return(FALSE);

StripTrailingWhitespace(Tempstr);
if (Settings.Flags & FLAG_LOG_MORE_VERBOSE) LogToFile(Settings.LogPath, "HANDLE CHROOT REQUEST: %s",Tempstr);

ptr=GetToken(Tempstr,"\\S",&Token,0);
if (strcmp(Token,"EXEC")==0) Pid=HandleCGIExecRequest(S,ptr);
else if (strcmp(Token,"WEBSOCKET")==0) Pid=HandleWebsocketExecRequest(S,ptr);
else if (strcmp(Token,"LOG")==0) 
{
	LogToFile(Settings.LogPath,ptr);
	Pid=0;
}
else if (strcmp(Token,"GETF")==0) Pid=HandleGetFileRequest(S,ptr);
else if (strcmp(Token,"POST")==0) Pid=HandlePostFileRequest(S,ptr);
else if (strcmp(Token,"GETIP")==0) Pid=HandleResolveIPRequest(S,ptr);
else if (strcmp(Token,"REG")==0) Pid=HandleChildRegisterRequest(S,ptr);
else if (strcmp(Token,"PROXY")==0) Pid=HandleProxyRequest(S,ptr);
else if (strcmp(Token,"MIMEICON")==0) Pid=HandleIconRequest(S, ptr);
else if (strcmp(Token,"EVENT")==0) Pid=RunEventScript(S, ptr);

STREAMSetValue(S,"HelperType", Token); 

STREAMFlush(S);

DestroyString(Tempstr);
DestroyString(Token);

return(Pid);
}
Example #21
0
STREAM *STREAMClose(STREAM *S)
{
ListNode *Curr;
int len;

if (! S) return(NULL);
len=S->OutEnd; 

STREAMReadThroughProcessors(S, NULL, 0);
STREAMFlush(S);

if ( 
		(StrLen(S->Path)==0) ||
	 (strcmp(S->Path,"-") !=0)
	)
{
if ((S->out_fd != -1) && (S->out_fd != S->in_fd)) close(S->out_fd);
if (S->in_fd != -1) close(S->in_fd);
}

Curr=ListGetNext(S->Values);
while (Curr)
{
if (strncmp(Curr->Tag,"HelperPID",9)==0) kill(atoi(Curr->Item),SIGKILL);
Curr=ListGetNext(Curr);
}


ListDestroy(S->Values,(LIST_ITEM_DESTROY_FUNC)DestroyString);
ListDestroy(S->ProcessingModules,DataProcessorDestroy);
DestroyString(S->InputBuff);
DestroyString(S->OutputBuff);
DestroyString(S->Path);
free(S);

return(NULL);
}
int InternalCopyFile(TTransferContext *Ctx, TFileInfo *iSrcFI)
{
STREAM *Src=NULL, *Dest=NULL;
TFileInfo *SrcFI=NULL, *DestFI=NULL;
char *Buffer=NULL, *Tempstr=NULL, *ptr;
int BuffSize=4096;
int result, bytes=0, towrite=0; 
unsigned int  TotalBytes=0, BytesSent=0, percent=0, secs=0, val;
double bigval;
//TFileInfo *FI;
int RetVal=TRANSFER_OKAY;
struct timeval StartTime, Now;
TProcessingModule *CompressionMod=NULL;

if (! Ctx->SrcFS->ReadBytes) return(ERR_READ_NOTSUPPORTED);
if (Ctx->DestFS && (! Ctx->DestFS->WriteBytes)) return(ERR_WRITE_NOTSUPPORTED);


gettimeofday(&StartTime,NULL); 


if (Ctx->DestFS && Ctx->DestFS->BuffSize) BuffSize=Ctx->DestFS->BuffSize;
Buffer=SetStrLen(Buffer,BuffSize*2+1);


SrcFI=FileInfoClone(iSrcFI);
DestFI=FileInfoClone(iSrcFI);
DestFI->Path=FileStoreFormatPath(DestFI->Path, Ctx->DestFS, iSrcFI->Name);

//if a PreCopyHook script is specified, then run it
if (StrLen(Ctx->PreCopyHook))
{
	Tempstr=FormatStr(Tempstr,"%s '%s' '%s' '%s'",Ctx->PreCopyHook,DestFI->Name,DestFI->Path,"");
	system(Tempstr);
}


Src=InternalCopyOpenSource(Ctx, SrcFI);

TotalBytes=SrcFI->Size;
if (Ctx->CmdFlags & FLAG_CMD_RESUME) BytesSent=SrcFI->ResumePoint;

if (Src)
{
	if (Ctx->SrcFS->Settings & FS_COMPRESSION) CompressionMod=ActivateCompression(Ctx->DestFS,Ctx->SrcFS);


	if (Ctx->DestFS) Dest=InternalCopyOpenDest(Ctx, SrcFI, DestFI);
	else Dest=STREAMFromFD(1);

	if (Dest)
	{

		result=Ctx->SrcFS->ReadBytes(Ctx->SrcFS,Src,Buffer,BuffSize*2);
		while ((bytes > 0) || (result != EOF))
		{
			if (CompressionMod) result=HandleCompression(CompressionMod,Buffer,result);
			if (result > 0) bytes+=result;
			if (bytes > BuffSize) towrite=BuffSize;
			else towrite=bytes;

			if (Ctx->DestFS) result=Ctx->DestFS->WriteBytes(Ctx->DestFS,Dest,Buffer,towrite);
			else result=STREAMWriteBytes(Dest,Buffer,towrite);

			if (result==-1)
			{
				RetVal=ERR_INTERRUPTED;
				break;
			}


			if (Settings.Flags & FLAG_INTERRUPT)
			{
				Settings.Flags &= ~FLAG_INTERRUPT;
				RetVal=ERR_CANCEL;
				break;
			}

			BytesSent+=result;
			bytes-=result;
			if (bytes > 0) memmove(Buffer,Buffer+result,bytes);
			
			gettimeofday(&Now,NULL);
			val=Now.tv_sec - StartTime.tv_sec;
			if (val > secs)
			{
				secs=val;
				if (secs > 0) DisplayTransferStatus(SrcFI->Name,BytesSent,TotalBytes,&percent,secs,Ctx->CmdFlags,Ctx->Throttle);
			}

			result=Ctx->SrcFS->ReadBytes(Ctx->SrcFS,Src,Buffer+bytes,BuffSize*2 -bytes);
		}

		if (Ctx->SrcFS->CloseFile) Ctx->SrcFS->CloseFile(Ctx->SrcFS,Src);

		if (Ctx->DestFS && Ctx->DestFS->CloseFile) 
		{
			result=Ctx->DestFS->CloseFile(Ctx->DestFS,Dest);
			if (result !=TRUE)
			{
				//Handle Errors returned by Close file
				if (RetVal >= FALSE) RetVal=result;
				SetVar(Ctx->Vars,"Error",GetVar(Ctx->DestFS->Vars,"Error"));
				SetVar(Ctx->DestFS->Vars,"Error","");
			}
			else ListAddNamedItem(Ctx->DestFS->DirListing,DestFI->Name,FileInfoClone(DestFI));
		}
		else STREAMFlush(Dest);

	if ((TotalBytes > 0) && (BytesSent < TotalBytes)) RetVal=ERR_INTERRUPTED;
	}
	else RetVal=ERR_DESTFILE;

secs=Now.tv_sec - StartTime.tv_sec;
if (secs < 1) secs=1;
DisplayTransferStatus(SrcFI->Name,BytesSent,TotalBytes,&percent,secs,0,0);
//if (! (CmdFlags & FLAG_QUIET)) 

printf("\n");
}
else RetVal=ERR_SOURCEFILE;

Ctx->TotalBytes+=BytesSent;


FileInfoDestroy(DestFI);
FileInfoDestroy(SrcFI);
DestroyString(Buffer);
DestroyString(Tempstr);

return(RetVal);
}
Example #23
0
void HTTPSendHeaders(STREAM *S, HTTPInfoStruct *Info)
{
char *SendStr=NULL, *Tempstr=NULL, *ptr;
ListNode *Curr;
int count;
int i;
static int AuthCounter=0;

STREAMClearDataProcessors(S);
SendStr=CopyStr(SendStr,Info->Method);
SendStr=CatStr(SendStr," ");

if (Info->Flags & HTTP_PROXY) Tempstr=HTTPInfoToURL(Tempstr, Info);
else Tempstr=HTTPQuoteChars(Tempstr,Info->Doc," ");
SendStr=CatStr(SendStr,Tempstr);

if (Info->Flags & HTTP_VER1_0) SendStr=CatStr(SendStr," HTTP/1.0\r\n");
else SendStr=MCatStr(SendStr," HTTP/1.1\r\n","Host: ",Info->Host,"\r\n",NULL);

if (StrLen(Info->PostContentType) >0)
{
	Tempstr=FormatStr(Tempstr,"Content-type: %s\r\n",Info->PostContentType);
	SendStr=CatStr(SendStr,Tempstr);
}

if (Info->PostContentLength > 0) 
{
	Tempstr=FormatStr(Tempstr,"Content-Length: %d\r\n",Info->PostContentLength);
	SendStr=CatStr(SendStr,Tempstr);
}

if (StrLen(Info->Destination))
{
	Tempstr=FormatStr(Tempstr,"Destination: %s\r\n",Info->Destination);
	SendStr=CatStr(SendStr,Tempstr);
}

/* If we have authorisation details then send them */
if (Info->Authorization) SendStr=HTTPHeadersAppendAuth(SendStr, "Authorization", Info, Info->Authorization);
if (Info->ProxyAuthorization) SendStr=HTTPHeadersAppendAuth(SendStr, "Proxy-Authorization", Info, Info->ProxyAuthorization);

if (Info->Flags & HTTP_NOCACHE) SendStr=CatStr(SendStr,"Pragma: no-cache\r\nCache-control: no-cache\r\n");


if (Info->Depth > 0)
{
Tempstr=FormatStr(Tempstr,"Depth: %d\r\n",Info->Depth);
SendStr=CatStr(SendStr,Tempstr);
}

/*
if ((PathData->Options.Restart) && (PathData->offset >0))
{
snprintf(Buffer,sizeof(Buffer),"Range: bytes=%d-\r\n",PathData->offset);
SendStr=CatStr(SendStr,Buffer);

}
*/

  if (Info->IfModifiedSince > 0)
	{
		Tempstr=CopyStr(Tempstr,GetDateStrFromSecs("%a, %d %b %Y %H:%M:%S GMT",Info->IfModifiedSince,NULL));
		SendStr=MCatStr(SendStr,"If-Modified-Since: ",Tempstr, "\r\n",NULL);
	}

if (
		 (strcasecmp(Info->Method,"DELETE") !=0) &&
		 (strcasecmp(Info->Method,"HEAD") !=0) &&
		 (strcasecmp(Info->Method,"PUT") !=0) 
	)
{

Tempstr=CopyStr(Tempstr,"");

if (! (Info->Flags & HTTP_NOCOMPRESS))
{
	if (DataProcessorAvailable("Compression","gzip")) Tempstr=CatStr(Tempstr,"gzip");
	if (DataProcessorAvailable("Compression","zlib")) 
	{
		if (StrLen(Tempstr)) Tempstr=CatStr(Tempstr,", deflate");
		else Tempstr=CatStr(Tempstr,"deflate");
	}
}

if (StrLen(Tempstr)) SendStr=MCatStr(SendStr,"Accept-Encoding: ",Tempstr,"\r\n",NULL);
else SendStr=CatStr(SendStr,"Accept-Encoding:\r\n");
}

if (Info->Flags & HTTP_KEEPALIVE) 
{
//if (Info->Flags & HTTP_VER1_0) 
SendStr=CatStr(SendStr,"Connection: Keep-Alive\r\n");
//SendStr=CatStr(SendStr,"Content-Length: 0\r\n");
}
else
{
SendStr=CatStr(SendStr,"Connection: Close\r\n");
}

ptr=LibUsefulGetValue("HTTP:User-Agent");
if (StrLen(ptr)) SendStr=MCatStr(SendStr,"User-Agent: ",ptr, "\r\n",NULL);

Curr=ListGetNext(Info->CustomSendHeaders);
while (Curr)
{
SendStr=MCatStr(SendStr,Curr->Tag, ": ", (char *)  Curr->Item, "\r\n",NULL);
Curr=ListGetNext(Curr);
}

if (! (Info->Flags & HTTP_NOCOOKIES))
{
SendStr=AppendCookies(SendStr,Cookies);
}

SendStr=CatStr(SendStr,"\r\n");

Info->State |= HTTP_HEADERS_SENT;
if (Info->Flags & HTTP_DEBUG) fprintf(stderr,"HTTPSEND: ------\n%s------\n\n",SendStr);
STREAMWriteLine(SendStr,S);
STREAMFlush(S);

DestroyString(Tempstr);
DestroyString(SendStr);
}
Example #24
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);
}
Example #25
0
int ChrootProcessRequest(STREAM *S, HTTPSession *Session, const char *Type, const char *Path, const char *SearchPath)
{
char *Tempstr=NULL;
char *ResponseLine=NULL, *Headers=NULL, *ptr;
off_t ContentLength=0;
int KeepAlive=FALSE, RetVal=FALSE;


LogFileFlushAll(TRUE);
if (! ChrootSendRequest(Session, Type, Path, SearchPath)) return(FALSE);

//Wait till process outside of chroot responds to our request, 
while (STREAMCheckForBytes(ParentProcessPipe)==0) usleep(10000);

//Read 'OKAY' line
Tempstr=STREAMReadLine(Tempstr, ParentProcessPipe);

//then send it the post data if there is any.
if (strcmp(Session->Method,"POST") ==0) 
{
if (Session->ContentSize > 0) 
{
	LogToFile(Settings.LogPath,"PUSH POST: [%d]",Session->ContentSize);
	STREAMSendFile(S, ParentProcessPipe, Session->ContentSize, SENDFILE_KERNEL|SENDFILE_LOOP);
	LogToFile(Settings.LogPath,"PUSH POST:DONE [%d]",Session->ContentSize);
}

//we shouldn't need this CR-LF, as we've sent 'Content-Length' characters
//but some CGI implementations seem to expect it, and it does no harm to
//provide it anyway
STREAMWriteLine("\r\n",ParentProcessPipe); 
STREAMFlush(ParentProcessPipe);
}

//Handle Headers from CGI script
Headers=CopyStr(Headers,"");
ResponseLine=STREAMReadLine(ResponseLine,ParentProcessPipe);
StripTrailingWhitespace(ResponseLine);
if (StrLen(ResponseLine)) RetVal=TRUE;

Tempstr=STREAMReadLine(Tempstr,ParentProcessPipe);
while (Tempstr)
{
	StripTrailingWhitespace(Tempstr);
	if (StrLen(Tempstr)==0) break;
	
	//Handle 'Status' header that changes the 1st Response line
	if (strncasecmp(Tempstr,"Status:",7)==0) 
	{
		ptr=Tempstr+7;
		while (isspace(*ptr) && (*ptr != '\0')) ptr++;
		ResponseLine=MCopyStr(ResponseLine, Session->Protocol, " ", ptr, NULL);
	}
	else if (strncasecmp(Tempstr,"Content-Length:",15)==0)
	{
		ptr=Tempstr+15;
		while (isspace(*ptr)) ptr++;
		ContentLength=(off_t) strtoull(ptr,NULL,10);
		Headers=MCatStr(Headers,Tempstr,"\r\n",NULL);
	}
	else if (strncasecmp(Tempstr,"Connection:",11)==0)
	{
		ptr=Tempstr+11;
		while (isspace(*ptr)) ptr++;
		if (strncasecmp(ptr,"Keep-Alive",10)==0) KeepAlive=TRUE;
		Headers=MCatStr(Headers,Tempstr,"\r\n",NULL);
	}
	else Headers=MCatStr(Headers,Tempstr,"\r\n",NULL);
	Tempstr=STREAMReadLine(Tempstr,ParentProcessPipe);
}

//The second "\r\n" here will provide the blank line that marks the end
//of the headers

Tempstr=MCopyStr(Tempstr, ResponseLine,"\r\n",Headers,"\r\n",NULL);
STREAMWriteLine(Tempstr,S);

if (Settings.Flags & FLAG_LOG_MORE_VERBOSE) LogToFile(Settings.LogPath,"CGI HEADERS: [%s]",Tempstr);


//Read remaining data from CGI
STREAMSendFile(ParentProcessPipe, S, ContentLength,SENDFILE_KERNEL|SENDFILE_LOOP);
STREAMFlush(S);


//if we're running a cgi program, then it will close the session when done, so
//turn off the 'reuse session' flag
if (KeepAlive) Session->Flags |= SESSION_KEEPALIVE | SESSION_REUSE;
else Session->Flags &= ~(SESSION_KEEPALIVE | SESSION_REUSE);


DestroyString(Tempstr);
DestroyString(Headers);
DestroyString(ResponseLine);

return(RetVal);
}
Example #26
0
STREAM *ChrootSendRequest(HTTPSession *Session, const char *Type, const char *Path, const char *SearchPath)
{
char *Tempstr=NULL, *ContentLengthStr=NULL;
char *Quoted=NULL;

if (! ParentProcessPipe) return(NULL);

ContentLengthStr=FormatStr(ContentLengthStr,"%d",Session->ContentSize);

//Trying to do this all as one string causes a problem!
Tempstr=MCopyStr(Tempstr,Type," Host='",Session->Host, "' ClientIP='",Session->ClientIP, "' ClientMAC='",Session->ClientMAC,"'",NULL);

Quoted=QuoteCharsInStr(Quoted,Session->URL,"'&");
Tempstr=MCatStr(Tempstr, " URL='",Quoted,"'",NULL);

Quoted=QuoteCharsInStr(Quoted,Path,"'&");
Tempstr=MCatStr(Tempstr, " Path='",Quoted,"'",NULL);

Quoted=QuoteCharsInStr(Quoted,SearchPath,"'&");
Tempstr=MCatStr(Tempstr, " SearchPath='",Quoted,"'",NULL);

Tempstr=MCatStr(Tempstr," Method=",Session->Method," UserAgent='",Session->UserAgent,"' ContentLength='",ContentLengthStr,"'",NULL);

if (StrLen(Session->ContentBoundary)) Tempstr=MCatStr(Tempstr, " ContentType='",Session->ContentType, "; boundary=",Session->ContentBoundary, "'",NULL);
else Tempstr=MCatStr(Tempstr, " ContentType='",Session->ContentType,"'", NULL);

Quoted=FormatStr(Quoted,"%d",Session->ServerPort);
Tempstr=MCatStr(Tempstr," ServerName=",Session->ServerName," ServerPort=",Quoted,NULL);
if (StrLen(Session->Cipher)) Tempstr=MCatStr(Tempstr," Cipher='",Session->Cipher,"'",NULL);
if (StrLen(Session->Cookies)) Tempstr=MCatStr(Tempstr," Cookies='",Session->Cookies,"'",NULL);

Quoted=QuoteCharsInStr(Quoted,Session->StartDir,"'&");
Tempstr=MCatStr(Tempstr," StartDir='",Quoted,"'",NULL);

Quoted=QuoteCharsInStr(Quoted,Session->ClientReferrer,"'&");
Tempstr=MCatStr(Tempstr, " ClientReferrer='",Quoted,"'",NULL);

if (Session->Flags & SESSION_KEEPALIVE) Tempstr=CatStr(Tempstr," KeepAlive=Y");
if (Session->Flags & SESSION_UPLOAD) Tempstr=CatStr(Tempstr," Upload=Y");
if (Session->AuthFlags & FLAG_AUTH_HASCOOKIE) Tempstr=CatStr(Tempstr," AuthCookie=Y");
if (Session->CacheTime > 0)
{
	Quoted=FormatStr(Quoted," Cache=%d",Session->CacheTime);
	Tempstr=CatStr(Tempstr,Quoted);
}
if (StrLen(Session->UserName)) Tempstr=MCatStr(Tempstr," User='******'",NULL);
if (StrLen(Session->RealUser)) Tempstr=MCatStr(Tempstr," RealUser='******'",NULL);
if (StrLen(Session->Group)) Tempstr=MCatStr(Tempstr," Group='",Session->Group,"'",NULL);
if (StrLen(Session->RemoteAuthenticate)) Tempstr=MCatStr(Tempstr," RemoteAuthenticate='",Session->RemoteAuthenticate,"'",NULL);

Quoted=QuoteCharsInStr(Quoted,Session->Arguments,"'&");
Tempstr=MCatStr(Tempstr, " Arguments='",Quoted,"'", NULL);

Tempstr=CatStr(Tempstr,"\n");

if (Settings.Flags & FLAG_LOG_MORE_VERBOSE) LogToFile(Settings.LogPath,"REQUESTING DATA FROM OUTSIDE CHROOT: [%s]",Tempstr);
STREAMWriteLine(Tempstr,ParentProcessPipe);
STREAMFlush(ParentProcessPipe);

DestroyString(Tempstr);
DestroyString(Quoted);
DestroyString(ContentLengthStr);

return(ParentProcessPipe);
}
Example #27
0
void STREAMClear(STREAM *S)
{
 STREAMFlush(S);
 S->InStart=0;
}
Example #28
0
pid_t HandleIconRequest(STREAM *ClientCon, char *Data)
{
HTTPSession *Response;
char *Name=NULL, *Value=NULL, *ptr, *tptr;
char *Tempstr=NULL;
ListNode *Vars;
pid_t pid;


pid=fork();
if (pid==0)
{
Response=ParseSessionInfo(Data);
Vars=ListCreate();
ptr=GetNameValuePair(Response->Arguments,"&","=",&Name,&Tempstr);
while (ptr)
{
	Value=HTTPUnQuote(Value,Tempstr);
	SetVar(Vars,Name,Value);
	if (strcasecmp(Name,"MimeType")==0)
	{
		tptr=GetToken(Value,"/",&Tempstr,0);
		SetVar(Vars,"MimeClass",Tempstr);
		SetVar(Vars,"MimeSub",tptr);
	}
	ptr=GetNameValuePair(ptr,"&","=",&Name,&Tempstr);
}

	if (! SwitchGroup(Response->Group))
	{
		LogToFile(Settings.LogPath,"WARN: Failed to switch to group '%s' for mimeicons '%s'", Response->RealUser, Tempstr);
	}

	if (! SwitchUser(Response->RealUser))
	{
		LogToFile(Settings.LogPath,"ERROR: Failed to switch to user '%s' when getting icons from '%s'", Response->SearchPath);
		LogFileFlushAll(TRUE);
		_exit(0);
	}


	STREAMWriteLine("READY\n",ClientCon); STREAMFlush(ClientCon);
	ptr=GetToken(Response->SearchPath,":",&Value,0);
	while (ptr)
	{
		Tempstr=SubstituteVarsInString(Tempstr,Value,Vars,0);
		if (access(Tempstr,R_OK)==0) break;
		ptr=GetToken(ptr,":",&Value,0);
	}
		
	//HTTPServerSendDocument(ClientCon, Response, Tempstr, HEADERS_SENDFILE|HEADERS_USECACHE|HEADERS_KEEPALIVE);
	HTTPServerSendDocument(ClientCon, Response, Tempstr, HEADERS_SENDFILE|HEADERS_USECACHE);
	//exit 1 means we can keep connection alive for reuse
	LogFileFlushAll(TRUE);
	_exit(1);
}

DestroyString(Name);
DestroyString(Value);
DestroyString(Tempstr);

return(pid);
}
Example #29
0
pid_t HandleCGIExecRequest(STREAM *ClientCon, char *Data)
{
char *Tempstr=NULL, *Name=NULL, *Value=NULL;
char *ScriptPath=NULL;
int result, i;
HTTPSession *Response;

	//We will never read from this stream again. Any further data will be read
	//by the process we spawn off
	ClientCon->State |= SS_EMBARGOED;
	Response=ParseSessionInfo(Data);
	CleanStr(Response->Path);
	CleanStr(Response->SearchPath);
	CleanStr(Response->StartDir);
	ScriptPath=FindFileInPath(ScriptPath,Response->Path,Response->SearchPath);

	if (access(ScriptPath,F_OK) !=0)
	{
			HTTPServerSendHTML(ClientCon, Response, "404 Not Found","Couldn't find that script.");
			LogToFile(Settings.LogPath,"No such script: %s in path %s = %s",Response->Path,Response->SearchPath,ScriptPath);
	}
	else if (
					(access(ScriptPath,X_OK) !=0) || 
					(! CheckScriptIntegrity(ScriptPath))
			)
	{
			HTTPServerSendHTML(ClientCon, Response, "403 Forbidden","You don't have permission for that.");
			LogToFile(Settings.LogPath,"Cannot execute script: %s",ScriptPath);
	}
	else
	{
		STREAMFlush(ClientCon);
		LogFileFlushAll(TRUE);
		result=fork();
		if (result==0)
		{
			//do this so that when we exec the script, anything output goes to the client
			close(0);
			dup(ClientCon->in_fd);
			close(1);
			dup(ClientCon->out_fd);

			//must use write because stream is embargoed
			write(1,"READY\n",6);

			HTTPServerExecCGI(ClientCon, Response, ScriptPath);

			//exit whether script ran or not!
			_exit(0);
		}
	}


HTTPSessionDestroy(Response);
DestroyString(ScriptPath);
DestroyString(Tempstr);
DestroyString(Name);
DestroyString(Value);


//Always return STREAM_CLOSED, so that pipe gets closed regardless of exit status of 
//forked helper process
return(STREAM_CLOSED);
}
Example #30
0
pid_t HandleWebsocketExecRequest(STREAM *ClientCon, char *Data)
{
char *Tempstr=NULL, *Name=NULL, *Value=NULL;
char *ScriptPath=NULL;
int result, i;
HTTPSession *Response;

	//We will never read from this stream again. Any further data will be read
	//by the process we spawn off
	ClientCon->State |= SS_EMBARGOED;
	Response=ParseSessionInfo(Data);
	CleanStr(Response->Path);
	CleanStr(Response->SearchPath);
	CleanStr(Response->StartDir);
	ScriptPath=FindFileInPath(ScriptPath, Response->Path, Response->SearchPath);
	LogToFile(Settings.LogPath,"Script: Found=[%s] SearchPath=[%s] ScriptName=[%s] Arguments=[%s]", ScriptPath, Response->SearchPath, Response->Path, Response->Arguments);

	if (access(ScriptPath,F_OK) !=0)
	{
			LogToFile(Settings.LogPath,"No such script: %s in path %s = %s",Response->Path, Response->SearchPath, ScriptPath);
	}
	else if (
					(access(ScriptPath,X_OK) !=0) || 
					(! CheckScriptIntegrity(ScriptPath))
			)
	{
			LogToFile(Settings.LogPath,"Cannot execute script: %s", ScriptPath);
	}
	else
	{
		STREAMFlush(ClientCon);
		result=fork();
		if (result==0)
		{
			//do this so that when we exec the script, anything output goes to the client
			close(0);
			dup(ClientCon->in_fd);
			close(1);
			dup(ClientCon->out_fd);

      if (! SwitchGroup(Response->Group))
			{
        LogToFile(Settings.LogPath,"WARN: Failed to switch to group '%s' to execute script: %s using handler '%s'", Response->RealUser, ScriptPath, Tempstr);
			}

      //Switch user. ALAYA WILL NOT RUN SCRIPTS AS ROOT!
      if (! SwitchUser(Response->RealUser))
      {
        LogToFile(Settings.LogPath,"ERROR: Failed to switch to user '%s' to execute script: %s using handler '%s'", Response->RealUser, ScriptPath, Tempstr);
				LogFileFlushAll(TRUE);
        _exit(0);
      }

			if (geteuid()==0)
			{
				LogToFile(Settings.LogPath, "Failed to switch user to '%s' for running a .cgi program. Will not run programs as 'root'. Set 'DefaultUser' in config file or command line.", Response->RealUser);
			}
			else
			{
				SetupEnvironment(Response, ScriptPath);
				Tempstr=FindScriptHandlerForScript(Tempstr,ScriptPath);
				if (Tempstr) LogToFile(Settings.LogPath,"Execute script: %s using handler '%s'",ScriptPath,Tempstr);
				else LogToFile(Settings.LogPath,"Execute script: %s QUERY_STRING= '%s'",ScriptPath,getenv("QUERY_STRING"));

				//Only do this late! Otherwise logging won't work.
				for (i=3; i < 1000; i++) close(i);

				if (StrLen(Tempstr)) execl(Tempstr, Tempstr, ScriptPath,NULL);
				else execl(ScriptPath,ScriptPath,NULL);

				//Logging won't work after we've closed all the file descriptors!
				LogToFile(Settings.LogPath,"Cannot execute script: %s",ScriptPath);
		}
		LogFileFlushAll(TRUE);
		_exit(0);
	}
	else
	{

	}
}


HTTPSessionDestroy(Response);
DestroyString(ScriptPath);
DestroyString(Tempstr);
DestroyString(Name);
DestroyString(Value);


//Always return STREAM_CLOSED, so that pipe gets closed regardless of exit status of 
//forked helper process
return(STREAM_CLOSED);
}