Пример #1
0
char *FindFileInPath(char *InBuff, const char *File, const char *Path)
{
char *Tempstr=NULL, *CurrPath=NULL, *RetStr=NULL, *ptr;

RetStr=CopyStr(InBuff,"");

if (*File=='/')
{
	CurrPath=CopyStr(CurrPath,"");
	ptr=""; //so we execute once below
}
else ptr=GetToken(Path,":",&CurrPath,0);

while (ptr)
{
CurrPath=SlashTerminateDirectoryPath(CurrPath);
Tempstr=MCopyStr(Tempstr,CurrPath,File,NULL);
if (access(Tempstr,F_OK)==0) 
{
RetStr=CopyStr(RetStr,Tempstr);
break;
}

ptr=GetToken(ptr,":",&CurrPath,0);
}

DestroyString(Tempstr);
DestroyString(CurrPath);

return(RetStr);
}
Пример #2
0
char *FindFileInPath(char *InBuff, char *File, char *Path)
{
char *Tempstr=NULL, *CurrPath=NULL, *RetStr=NULL, *ptr;

RetStr=CopyStr(InBuff,"");

ptr=Gettoken(Path,":",&CurrPath,0);
while (ptr)
{
CurrPath=SlashTerminateDirectoryPath(CurrPath);
Tempstr=MCopyStr(Tempstr,CurrPath,File,NULL);
if (access(Tempstr,F_OK)==0) 
{
RetStr=CopyStr(RetStr,Tempstr);
break;
}

ptr=Gettoken(ptr,":",&CurrPath,0);
}

DestroyString(Tempstr);
DestroyString(CurrPath);

return(RetStr);
}
Пример #3
0
int FindFilesInPath(const char *File, const char *Path, ListNode *Files)
{
char *Tempstr=NULL, *CurrPath=NULL, *ptr;
int i;
glob_t Glob;

if (*File=='/')
{
	CurrPath=CopyStr(CurrPath,"");
	ptr=""; //so we execute once below
}
else ptr=GetToken(Path,":",&CurrPath,0);
while (ptr)
{
CurrPath=SlashTerminateDirectoryPath(CurrPath);
Tempstr=MCopyStr(Tempstr,CurrPath,File,NULL);

glob(Tempstr,0,0,&Glob);
for (i=0; i < Glob.gl_pathc; i++) ListAddItem(Files,CopyStr(NULL,Glob.gl_pathv[i]));
globfree(&Glob);

ptr=GetToken(ptr,":",&CurrPath,0);
}

DestroyString(Tempstr);
DestroyString(CurrPath);

return(ListSize(Files));
}
Пример #4
0
char *ParentDirectory(char *RetBuff, const char *Path)
{
char *RetStr=NULL, *ptr;
int len;

RetStr=CopyStr(RetBuff,Path);
len=StrLen(RetStr);

//Don't strip slash if directory is root dir
if (len > 1)
{
  StripDirectorySlash(RetStr);

  //Now strip off one dir name (the result of '..')
  ptr=strrchr(RetStr,'/');
  if (ptr) *ptr='\0';
  if (StrLen(RetStr)==0) RetStr=CopyStr(RetStr,"/");
}
RetStr=SlashTerminateDirectoryPath(RetStr);

return(RetStr);
}
Пример #5
0
void DoBindMounts(char *DirList, int Flags)
{
char *MntSrc=NULL, *MntDest=NULL, *ptr, *dptr;

ptr=GetToken(DirList,",",&MntSrc,0);
while (ptr)
{
	//if there's a ':' character in the mount definition, then it means that
	//we're mounting a directory in a different place than it would normally exist.
	//the default is to mount, say, /usr/lib as /usr/lib in the chroot. But if we
	//are passed /home/mylibs:/lib then we mount /home/mylibs as /lib in the chroot
	dptr=strrchr(MntSrc,':');
	if (dptr) 
	{
		*dptr='\0';
		dptr++;
	}
	else dptr=MntSrc;

	while (*dptr == '/') dptr++;

	MntDest=CopyStr(MntDest,dptr);
	MntDest=SlashTerminateDirectoryPath(MntDest);
	MakeDirPath(MntDest,0555);

	//Try a remount first. This prevents us mounting over and over
	//on the same mount point
	if (mount(MntSrc,MntDest,"",MS_BIND | MS_REMOUNT,"") !=0)
	{
		mount(MntSrc,MntDest,"",MS_BIND,"");
	}

	ptr=GetToken(ptr,",",&MntSrc,0);
}

DestroyString(MntSrc);
DestroyString(MntDest);
}
Пример #6
0
int HTTPServerSendDirectory(STREAM *S, HTTPSession *Session, char *Path, ListNode *Vars)
{
int DirSent=FALSE;
char *Tempstr=NULL, *Token=NULL, *ptr;
int Flags=0, Format, max=0;
TPathItem **Files;
int result=FALSE;


//Maybe we can get out of sending the directory. Check 'IfModifiedSince'
if ((Session->IfModifiedSince > 0) && (Session->LastModified > 0) && (Session->LastModified <= Session->IfModifiedSince))
{
//		HTTPServerSendHTML(S, Session, "304 Not Modified","");
//		return;
}

	//Get Time for uses like showing 'recent files'
	time(&Now);

	if (HTTPServerDecideToCompress(Session,NULL)) Session->Flags |= SESSION_ENCODE_GZIP;

	if (Settings.DirListFlags & DIR_INDEX_FILES)
	{
		DirSent=DirectoryTryIndex(S, Session, Path);
	}

	if (! DirSent) 
	{
		Format=RequestedListingType(Session,&Flags);
		switch (Format)
		{
			case ACTION_HTML:
			case ACTION_M3U:
			case ACTION_CSV:
				max+=LoadDir(Path, Session, Flags, &Files);
				
				switch (Format)
				{
					case ACTION_M3U: HTTPServerSendM3U(S,Session,Path,max,Files); break;
					case ACTION_CSV: HTTPServerSendCSV(S,Session,Path,max,Files); break;
					case ACTION_HTML: HTTPServerSendDirList(S,Session,Path,Flags,max,Files); break;
				}
			break;

			//TAR doesn't send a list of files, it sends the actual files, so it doesn't need to use
			//LoadDir in order to handle VPaths etc.
			case ACTION_PACK: result=HTTPServerSendPackedDir(S,Session,Path); break;
			case ACTION_UPLOAD: UploadSelectPage(S,Session,Path); break;
			case ACTION_EDIT: DirectoryItemEdit(S,Session,Path,0); break;
			case ACTION_EDIT_ACCESSTOKEN: DirectoryItemEdit(S,Session,Path, FDETAILS_ACCESSTOKEN); break;
			case ACTION_MKDIR: 
				Token=SessionGetArgument(Token, Session, "mkdir");
				Tempstr=CopyStr(Tempstr,Path);
				Tempstr=SlashTerminateDirectoryPath(Tempstr);
				Tempstr=CatStr(Tempstr,Token);	
				LogToFile(Settings.LogPath,"MKDIR: [%s] [%s] [%s]\n",Path,Token,Tempstr);
				mkdir(Tempstr, 0770); 
      	HTTPServerSendResponse(S, Session, "302", "", Session->URL);
			break;

			case ACTION_DELETE:
				DirectoryDeleteItem(S, Session, Path);
				HTTPServerSendToParentDir(S, Session);
			break;

			case ACTION_DELETE_SELECTED:
				DirectoryDeleteSelected(S, Session, Path);
      	HTTPServerSendResponse(S, Session, "302", "", Session->URL);
			break;

			case ACTION_RENAME:
				Token=SessionGetArgument(Token, Session, "renameto");
				Tempstr=CopyStr(Tempstr,Path);
				ptr=strrchr(Tempstr,'/');
				if (ptr) *ptr='\0';
				Tempstr=SlashTerminateDirectoryPath(Tempstr);
				Tempstr=CatStr(Tempstr,Token);	
	      if (rename(Path,Tempstr) !=0)
				{
					LogToFile(Settings.LogPath,"ERROR: Failed to rename: [%s] to [%s]. Error was: %s",Path,Tempstr,strerror(errno));
				}
   			else LogToFile(Settings.LogPath,"Renamed Item: [%s] to [%s]",Path,Tempstr);

				HTTPServerSendToParentDir(S, Session);
			break;

			case ACTION_SAVEPROPS:
				LogToFile(Settings.LogPath,"SAVEPROPS: [%s]\n",Path);
				FileDetailsSaveProps(S, Session, Path);
				Tempstr=MCopyStr(Tempstr,Session->URL,"?format=edit",NULL);
      	HTTPServerSendResponse(S, Session, "302", "", Tempstr);
			break;


			default: HTTPServerSendHTML(S, Session, "403 Index Listing Forbidden","This server is not configured to list directories."); break;
		}
	}

DestroyString(Tempstr);
DestroyString(Token);

return(result);
}
Пример #7
0
//yes, '***', three levels of pointer! It's an array of pointers that
//has to be passed into the function as a pointer
int LoadDir(char *Path, HTTPSession *Session, int Flags, TPathItem ***fl_ptr)
{
char *Tempstr=NULL, *URL=NULL, *Dir=NULL;
glob_t Glob;
struct stat Stat;
TPathItem *File, **Files;
ListNode *Curr;
int i, val, fcount=0;

Tempstr=MCopyStr(Tempstr,Path,"/*",NULL);
glob(Tempstr,0,0,&Glob);


Dir=CopyStr(Dir,Session->URL);
Dir=SlashTerminateDirectoryPath(Dir);
//Allocate As Many Items As glob found, plus VPaths, plus one for '..'

val=Glob.gl_pathc+1;
if (Settings.DirListFlags & DIR_SHOW_VPATHS) val+=ListSize(Settings.VPaths);

*fl_ptr=(TPathItem **) calloc(val , sizeof(TPathItem *));
Files=*fl_ptr;

//if we are at '/' then don't offer a parent directory
if (StrLen(Path) > 1)
{
Tempstr=ParentDirectory(Tempstr, Session->URL);
URL=FormatURL(URL,Session,Tempstr);
Files[0]=PathItemCreate(PATHTYPE_DIR,Tempstr,"..");
fcount++;
}


//LoadVPaths if in top-level dir
if (Settings.DirListFlags & DIR_SHOW_VPATHS) 
{
	if (strcmp(Path,Session->StartDir)==0)
	{
		Curr=ListGetNext(Settings.VPaths);
		while (Curr)
		{	
			File=(TPathItem *) Curr->Item;
			if ((File->Type==PATHTYPE_EXTFILE) && (strcmp(File->URL,"/") !=0)) 
			{
				Files[fcount]=PathItemCreate(PATHTYPE_DIR,File->URL,File->URL);
				fcount++;
			}
		Curr=ListGetNext(Curr);
		}
	}
}

for (i=0; i < Glob.gl_pathc; i++)
{
  Tempstr=MCopyStr(Tempstr,Dir,GetBasename(Glob.gl_pathv[i]),NULL);
	URL=FormatURL(URL,Session,Tempstr);

  if (stat(Glob.gl_pathv[i],&Stat) > -1)
	{
  if (S_ISDIR(Stat.st_mode)) File=PathItemCreate(PATHTYPE_DIR,URL,Glob.gl_pathv[i]);
  else File=PathItemCreate(PATHTYPE_FILE,URL,Glob.gl_pathv[i]);
  File->Mtime=Stat.st_mtime;
  File->Size=Stat.st_size;
	}
  Files[fcount]=File;
	fcount++;
}


switch (Flags & SORT_TYPE_MASK)
{
case SORT_SIZE: qsort(Files,fcount,sizeof(TPathItem *),FilesSortSizeCmp); break;
case SORT_RSIZE: qsort(Files,fcount,sizeof(TPathItem *),FilesRSortSizeCmp); break;
case SORT_TIME: qsort(Files,fcount,sizeof(TPathItem *),FilesSortTimeCmp); break;
case SORT_RTIME: qsort(Files,fcount,sizeof(TPathItem *),FilesRSortTimeCmp); break;
case SORT_NAME: qsort(Files,fcount,sizeof(TPathItem *),FilesSortNameCmp); break;
case SORT_RNAME: qsort(Files,fcount,sizeof(TPathItem *),FilesRSortNameCmp); break;
}


globfree(&Glob);
DestroyString(Dir);
DestroyString(URL);
DestroyString(Tempstr);

//i will equal 'Glob.pathc' at end of loop, we also added '..' so return i+1 
return(fcount);
}
Пример #8
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);
}
Пример #9
0
int HTTPServerSetUserContext(HTTPSession *Session)
{
char *ChrootDir=NULL, *Tempstr=NULL;

Session->StartDir=CopyStr(Session->StartDir,Settings.DefaultDir);
ChrootDir=CopyStr(ChrootDir,Settings.DefaultDir);

LogToFile(Settings.LogPath,"SETCTX: %d %s home=%s",Session->MethodID,ChrootDir,Session->HomeDir);

if (IsProxyMethod(Session->MethodID))
{
	//Do not chroot for proxy commands
}
else 
{
	if (Settings.Flags & FLAG_CHHOME) ChrootDir=CopyStr(ChrootDir,Session->HomeDir);

		//if (Settings.Flags & FLAG_LOG_VERBOSE) 
LogToFile(Settings.LogPath,"ChRoot to: %s home=%s",ChrootDir,Session->HomeDir);

	if (chdir(ChrootDir) !=0) 
	{
		LogToFile(Settings.LogPath,"ERROR: CHDIR FAILED: %d %s %s",getuid(),ChrootDir,strerror(errno));
		HTTPServerSendHTML(Session->S, Session, "500 Internal Server Error","Problem switching to home-directory");
		LogFileFlushAll(TRUE);
 		_exit(1);
	}
	chroot(".");
	Session->StartDir=CopyStr(Session->StartDir,"/");
}

/*
/Not working yet
else if (Settings.Flags & FLAG_CHSHARE) 
{
	chdir(Settings.DefaultDir);
	chroot(".");
	if (strncmp(Session->StartDir,Settings.DefaultDir,StrLen(Settings.DefaultDir))==0)
	{
		Tempstr=MCopyStr(Tempstr,"/",Session->StartDir+StrLen(Settings.DefaultDir),NULL);
		chdir(Tempstr);
		Session->StartDir=CopyStr(Session->StartDir,Tempstr);
	}
}
*/

Session->StartDir=SlashTerminateDirectoryPath(Session->StartDir);

LogToFile(Settings.LogPath,"User Context: Chroot: %s, StartDir: %s, HomeDir: %s, UserID: %d, GroupID: %d,",ChrootDir, Session->StartDir, Session->HomeDir, Session->RealUserUID,Session->GroupID);

if (Session->GroupID > 0)
{
	if (setgid(Session->GroupID) != 0)
	{
		HTTPServerSendHTML(Session->S, Session, "500 Internal Server Error","Problem switching to configured user-group");
	  LogToFile(Settings.LogPath,"ERROR: Failed to switch group to %s/%d. Exiting",Session->RealUser,Session->RealUserUID);
 		_exit(1);
	}
}
else if (Settings.DefaultGroupID > 0) 
{
	if (setgid(Settings.DefaultGroupID) != 0)
	{
		HTTPServerSendHTML(Session->S, Session, "500 Internal Server Error","Problem switching to configured user-group");
		LogToFile(Settings.LogPath,"ERROR: Failed to switch group to %s/%d. Exiting",Session->RealUser,Session->RealUserUID);
 		_exit(1);
	}
}

DropCapabilities(CAPS_LEVEL_CHROOTED);

if (setresuid(Session->RealUserUID,Session->RealUserUID,Session->RealUserUID)!=0)
{
	HTTPServerSendHTML(Session->S, Session, "500 Internal Server Error","Problem switching to configured user");
  LogToFile(Settings.LogPath,"ERROR: Failed to switch user to %s/%d. Exiting",Session->RealUser,Session->RealUserUID);
  _exit(1);
}

//drop everything! (In case someting went wrong with setresuid) 
DropCapabilities(CAPS_LEVEL_SESSION);

DestroyString(Tempstr);
DestroyString(ChrootDir);

return(TRUE);
}