コード例 #1
0
void SpawnApplyConfig(const char *Config, int Flags)
{
char *User=NULL, *Group=NULL, *Dir=NULL;
char *Name=NULL, *Value=NULL;
const char *ptr;
struct rlimit limit;
rlim_t val;

int i;

//set all signal handlers to default
if (Flags & SPAWN_SIGDEF)
{
for (i =0; i < _NSIG; i++) signal(i,SIG_DFL);
}

//Set controlling tty to be stdin. This means that CTRL-C, SIGWINCH etc is handled for the 
//stdin file descriptor, not for any oher 
if (Flags & SPAWN_DAEMON) demonize();
else
{
	if (Flags & SPAWN_SETSID) setsid();
	if (Flags & SPAWN_CTRL_TTY) tcsetpgrp(0, getpgrp());
}

User=CopyStr(User,"");
Group=CopyStr(Group,"");
ptr=GetNameValuePair(Config,"\\S","=",&Name,&Value);
while (ptr)
{
	if (strcasecmp(Name,"User")==0) User=CopyStr(User, Value);
	else if (strcasecmp(Name,"Group")==0) Group=CopyStr(Group, Value);
	else if (strcasecmp(Name,"Dir")==0) Dir=CopyStr(Dir, Value);
	else if (strcasecmp(Name,"PidFile")==0) WritePidFile(Value);
	else if (strcasecmp(Name,"prio")==0) setpriority(PRIO_PROCESS, 0, atoi(Value));
	else if (strcasecmp(Name,"nice")==0) setpriority(PRIO_PROCESS, 0, atoi(Value));
	else if (strcasecmp(Name,"priority")==0) setpriority(PRIO_PROCESS, 0, atoi(Value));
	else if (strcasecmp(Name,"mem")==0) 
	{
		val=(rlim_t) ParseHumanReadableDataQty(Value, 0);
		limit.rlim_cur=val;
		limit.rlim_max=val;
		setrlimit(RLIMIT_DATA, &limit);
	}
	else if (strcasecmp(Name,"fsize")==0) 
	{
		val=(rlim_t) ParseHumanReadableDataQty(Value, 0);
		limit.rlim_cur=val;
		limit.rlim_max=val;
		setrlimit(RLIMIT_FSIZE, &limit);
	}
	else if (strcasecmp(Name,"files")==0) 
	{
		val=(rlim_t) ParseHumanReadableDataQty(Value, 0);
		limit.rlim_cur=val;
		limit.rlim_max=val;
		setrlimit(RLIMIT_NOFILE, &limit);
	}
	else if (strcasecmp(Name,"coredumps")==0) 
	{
		val=(rlim_t) ParseHumanReadableDataQty(Value, 0);
		limit.rlim_cur=val;
		limit.rlim_max=val;
		setrlimit(RLIMIT_CORE, &limit);
	}
	else if ( (strcasecmp(Name,"procs")==0) || (strcasecmp(Name,"nproc")==0) )
	{
		val=(rlim_t) ParseHumanReadableDataQty(Value, 0);
		limit.rlim_cur=val;
		limit.rlim_max=val;
		setrlimit(RLIMIT_NPROC, &limit);
	}
	ptr=GetNameValuePair(ptr,"\\S","=",&Name,&Value);
}

// This allows us to chroot into a whole different unix directory tree, with its own
// password file etc
if (Flags & SPAWN_CHROOT) chroot(".");

if (StrLen(Dir)) chdir(Dir);

//Always do group first, otherwise we'll lose ability to switch user/group
if (StrLen(Group)) SwitchGroup(Group);
if (StrLen(User)) SwitchUser(User);

//Must do this last! After parsing Config, and also after functions like
//SwitchUser that will need access to /etc/passwd
if (Flags & SPAWN_JAIL) chroot(".");

DestroyString(Name);
DestroyString(Value);
DestroyString(User);
DestroyString(Group);
DestroyString(Dir);
}
コード例 #2
0
ファイル: Settings.c プロジェクト: ColumPaget/Alaya
void ParseConfigItem(char *ConfigLine)
{
const char *ConfTokens[]={"Chroot","Chhome","AllowUsers","DenyUsers","Port","LogFile","AuthPath","BindAddress","LogPasswords","HttpMethods","AuthMethods","DefaultUser","DefaultGroup","Path","FileType","LogVerbose","AuthRealm","Compression","DirListType","DisplayNameLen","MaxLogSize","ScriptHandler","ScriptHashFile","WebsocketHandler","LookupClientName","SanitizeAllowTags","CustomHeader","UserAgentSettings",
"SSLKey","SSLCert","SSLCiphers","SSLDHParams","SSLClientCertificate","SSLVerifyPath", "SSLVersion",
"Event","FileCacheTime","HttpKeepAlive","AccessTokenKey","Timezone","MaxMemory","MaxStack","ActivityTimeout","PackFormats",NULL};
typedef enum {CT_CHROOT, CT_CHHOME, CT_ALLOWUSERS,CT_DENYUSERS,CT_PORT, CT_LOGFILE,CT_AUTHFILE,CT_BINDADDRESS,CT_LOGPASSWORDS,CT_HTTPMETHODS, CT_AUTHMETHODS,CT_DEFAULTUSER, CT_DEFAULTGROUP, CT_PATH, CT_FILETYPE, CT_LOG_VERBOSE, CT_AUTH_REALM, CT_COMPRESSION, CT_DIRTYPE, CT_DISPLAYNAMELEN, CT_MAXLOGSIZE, CT_SCRIPTHANDLER, CT_SCRIPTHASHFILE, CT_WEBSOCKETHANDLER, CT_LOOKUPCLIENT, CT_SANITIZEALLOW, CT_CUSTOMHEADER, CT_USERAGENTSETTINGS, 
CT_SSLKEY, CT_SSLCERT, CT_SSLCIPHERS, CT_SSLDHPARAMS, CT_CLIENT_CERTIFICATION, CT_SSLVERIFY_PATH, CT_SSL_VERSION, 
CT_EVENT, CT_FILE_CACHE_TIME, CT_SESSION_KEEPALIVE, CT_ACCESS_TOKEN_KEY, CT_TIMEZONE, CT_MAX_MEM, CT_MAX_STACK, CT_ACTIVITY_TIMEOUT, CT_ARCHIVE_FORMATS} TConfigTokens;

char *Token=NULL, *ptr;
struct group *grent;
struct stat Stat;
TConfigTokens TokType;


ptr=GetToken(ConfigLine,"=|:",&Token,GETTOKEN_MULTI_SEPARATORS);

StripLeadingWhitespace(Token);
StripTrailingWhitespace(Token);
TokType=MatchTokenFromList(Token,ConfTokens,0);

switch(TokType)
{
	case CT_PORT:
		Settings.Port=atoi(ptr);
	break;

	case CT_CHROOT:
		Settings.Flags &= ~FLAG_CHHOME;
		Settings.Flags |= FLAG_CHROOT;
		Settings.DefaultDir=CopyStr(Settings.DefaultDir,ptr);
	break;

	case CT_CHHOME:
		Settings.Flags &= ~FLAG_CHROOT;
		Settings.Flags|=FLAG_CHHOME;
	break;

	case CT_ALLOWUSERS:
		Settings.AllowUsers=CopyStr(Settings.AllowUsers,ptr);
	break;

	case CT_DENYUSERS:
		Settings.DenyUsers=CopyStr(Settings.DenyUsers,ptr);
	break;

	case CT_AUTHFILE:
		Settings.AuthPath=CopyStr(Settings.AuthPath,ptr);
	break;

	case CT_BINDADDRESS:
		Settings.BindAddress=CopyStr(Settings.BindAddress,ptr);
	break;

	case CT_LOGPASSWORDS:
		//	Settings.Flags |= FLAG_LOGPASSWORDS;
	break;

	case CT_DISPLAYNAMELEN:
		Settings.DisplayNameLen=atoi(ptr);
	break;

	case CT_AUTHMETHODS:
		Settings.AuthMethods=CopyStr(Settings.AuthMethods,ptr);
	break;

	case CT_HTTPMETHODS:
		Settings.HttpMethods=CopyStr(Settings.HttpMethods,ptr);
	break;

	case CT_DEFAULTUSER:
		Settings.DefaultUser=CopyStr(Settings.DefaultUser,ptr);
	break;

	case CT_DEFAULTGROUP:
		Settings.DefaultGroup=CopyStr(Settings.DefaultGroup,ptr);
    grent=getgrnam(ptr);
    if (grent) Settings.DefaultGroupID=grent->gr_gid;
	break;

	case CT_SSLKEY:
		if (! Settings.SSLKeys) Settings.SSLKeys=ListCreate();
		Token=FormatStr(Token,"SSL_KEY_FILE:%d",ListSize(Settings.SSLKeys));
		ListAddNamedItem(Settings.SSLKeys,Token,CopyStr(NULL,ptr));
		Settings.Flags |=FLAG_SSL;
	break;

	case CT_SSLCERT:
		if (! Settings.SSLKeys) Settings.SSLKeys=ListCreate();
		Token=FormatStr(Token,"SSL_CERT_FILE:%d",ListSize(Settings.SSLKeys));
		ListAddNamedItem(Settings.SSLKeys,Token,CopyStr(NULL,ptr));
		Settings.Flags |=FLAG_SSL;
	break;
	
	case CT_SSLCIPHERS:
		LibUsefulSetValue("SSL-Permitted-Ciphers",ptr);
	break;

	case CT_SSLDHPARAMS:
		LibUsefulSetValue("SSL-DHParams-File",ptr);
	break;

	case CT_SSL_VERSION:
		LibUsefulSetValue("SSL-Level",ptr);
	break;

	case CT_AUTH_REALM:
		Settings.AuthRealm=CopyStr(Settings.AuthRealm,ptr);
	break;

	case CT_COMPRESSION:
		if (strcasecmp(ptr,"partial")==0) 
		{
			Settings.Flags &= ~FLAG_COMPRESS;
			Settings.Flags |= FLAG_PARTIAL_COMPRESS;
		}
		else if (! YesNoTrueFalse(ptr)) Settings.Flags &= ~(FLAG_COMPRESS | FLAG_PARTIAL_COMPRESS);
		else
		{
			Settings.Flags &= ~FLAG_PARTIAL_COMPRESS;
			Settings.Flags |= FLAG_COMPRESS;
		}
	break;

	case CT_PATH:
		ptr=GetToken(ptr,",",&Token,0);
		VPathParse(Settings.VPaths, Token, ptr);
	break;

	case CT_FILETYPE:
		VPathParse(Settings.VPaths, Token, ptr);
	break;

	case CT_DIRTYPE:
		ParseDirListType(ptr);
	break;

	case CT_LOGFILE:
		Settings.LogPath=CopyStr(Settings.LogPath,ptr);
	break;

	case CT_LOG_VERBOSE:
		if (YesNoTrueFalse(ptr)) Settings.Flags |= FLAG_LOG_VERBOSE;
		else Settings.Flags &= ~FLAG_LOG_VERBOSE;
	break;

	case CT_MAXLOGSIZE:
		Settings.MaxLogSize = (int) ParseHumanReadableDataQty(ptr, 0);
	break;

  case CT_SCRIPTHANDLER:
    ptr=GetToken(ptr,"=",&Token,0);
    if (! Settings.ScriptHandlers) Settings.ScriptHandlers=ListCreate();
    SetTypedVar(Settings.ScriptHandlers,Token,ptr,PATHTYPE_CGI);
  break;

	case CT_SCRIPTHASHFILE:
		Settings.ScriptHashFile=CopyStr(Settings.ScriptHashFile,ptr);
		Settings.Flags |= FLAG_CHECK_SCRIPTS;
	break;

  case CT_WEBSOCKETHANDLER:
    if (! Settings.ScriptHandlers) Settings.ScriptHandlers=ListCreate();
		ptr=GetToken(ptr,"=",&Token,0);
    SetTypedVar(Settings.ScriptHandlers,Token,ptr,PATHTYPE_WEBSOCKET);
  break;

	case CT_SANITIZEALLOW:
		if (! Settings.SanitizeArgumentsAllowedTags) Settings.SanitizeArgumentsAllowedTags=ListCreate();
		ptr=GetToken(ptr,",",&Token,0);
		while (ptr)
		{
			SetVar(Settings.SanitizeArgumentsAllowedTags,Token,"Y");
			ptr=GetToken(ptr,",",&Token,0);
		}
	break;

	case CT_CUSTOMHEADER:
		if (! Settings.CustomHeaders) Settings.CustomHeaders=ListCreate();
		ptr=GetToken(ptr,":",&Token,0);
		ListAddNamedItem(Settings.CustomHeaders,Token,CopyStr(NULL,ptr));
	break;

	case CT_LOOKUPCLIENT:
		if (YesNoTrueFalse(ptr)) Settings.Flags |= FLAG_LOOKUP_CLIENT;
		else Settings.Flags &= ~FLAG_LOOKUP_CLIENT;
	break;

	case CT_USERAGENTSETTINGS:
		if (! Settings.UserAgents) Settings.UserAgents=ListCreate();
		ptr=GetToken(ptr,",",&Token,0);
		ListAddNamedItem(Settings.UserAgents,Token,CopyStr(NULL,ptr));
	break;

	case CT_SSLVERIFY_PATH:
		if (stat(ptr,&Stat)==0)
		{
		if (S_ISDIR(Stat.st_mode)) LibUsefulSetValue("SSL_VERIFY_CERTDIR",ptr);
		else if (S_ISREG(Stat.st_mode)) LibUsefulSetValue("SSL_VERIFY_CERTFILE",ptr);
		}
		else HandleError(ERR_PRINT|ERR_LOG|ERR_EXIT, "ERROR: Can't access SSL certificate verify data at '%s'",ptr);
	break;

	case CT_CLIENT_CERTIFICATION:
		if (strcasecmp(ptr,"ask")==0) Settings.AuthFlags |= FLAG_AUTH_CERT_ASK;
		if (strcasecmp(ptr,"required")==0) Settings.AuthFlags |= FLAG_AUTH_CERT_REQUIRED;
		if (strcasecmp(ptr,"sufficient")==0) Settings.AuthFlags |= FLAG_AUTH_CERT_SUFFICIENT;
		if (strcasecmp(ptr,"optional")==0) Settings.AuthFlags |= FLAG_AUTH_CERT_SUFFICIENT;
		if (strcasecmp(ptr,"required+sufficient")==0) Settings.AuthFlags |= FLAG_AUTH_CERT_REQUIRED | FLAG_AUTH_CERT_SUFFICIENT;
	break;

	case CT_EVENT:
		ParseEventConfig(ptr);
	break;

	case CT_FILE_CACHE_TIME:
		Settings.DocumentCacheTime=strtol(ptr,NULL,10);
	break;

	case CT_SESSION_KEEPALIVE:
		if (YesNoTrueFalse(ptr)) Settings.Flags |= FLAG_KEEPALIVES;
		else Settings.Flags &= ~FLAG_KEEPALIVES;
	break;

	case CT_ACCESS_TOKEN_KEY:
		Settings.AccessTokenKey=CopyStr(Settings.AccessTokenKey,ptr);
	break;

	case CT_TIMEZONE:
		Settings.Timezone=CopyStr(Settings.Timezone,ptr);
	break;

	case CT_MAX_MEM:
		Settings.AddressSpace=CopyStr(Settings.AddressSpace,ptr);
	break;

	case CT_MAX_STACK:
		Settings.StackSize=CopyStr(Settings.StackSize,ptr);
	break;

	case CT_ACTIVITY_TIMEOUT:
		Settings.ActivityTimeout=atoi(ptr);
	break;

	case CT_ARCHIVE_FORMATS:
		Settings.PackFormats=ParsePackFormats(Settings.PackFormats, ptr);
	break;
}

DestroyString(Token);
}