demo stuff, script contexts
git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@1909 e016b1c5-ed68-44aa-a2f7-31cac88cffde
This commit is contained in:
+17
-12
@@ -1,17 +1,22 @@
|
||||
// define script contexts to allow certain commands
|
||||
// in (untrusted) map configuration files
|
||||
// define script security contexts to restrict commands to certain contexts
|
||||
// do NOT modify
|
||||
|
||||
scriptcontext 1 alias
|
||||
scriptcontext 1 loadsky
|
||||
scriptcontext 1 mapmodelreset
|
||||
scriptcontext 1 mapmodel
|
||||
scriptcontext 1 texturereset
|
||||
scriptcontext 1 texture
|
||||
scriptcontext 1 fog
|
||||
scriptcontext 1 fogcolour
|
||||
scriptcontext 1 mapsound
|
||||
scriptcontext 1 watercolour
|
||||
// supported contexts
|
||||
alias context_core 0 // hardcoded scripts
|
||||
alias context_cfg 1 // known scripts
|
||||
alias context_prompt 2 // command propmpt
|
||||
alias context_mapcfg 3 // map configs, we don't trust them
|
||||
|
||||
// set allowed commands for the map config context
|
||||
alias mapcfgidents [ alias loadsky mapmodelreset mapmodel texturereset texture fog fogcolour mapsound watercolour ]
|
||||
loop i (listlen $mapcfgidents) [
|
||||
scriptcontext $context_mapcfg (at $mapcfgidents $i)
|
||||
]
|
||||
|
||||
// isolate the map config context
|
||||
// this disables access from this context to identifiers located in other contexts
|
||||
// also it removes all aliases created in this context once the running context changes
|
||||
isolatecontext $context_mapcfg
|
||||
|
||||
// secure this configuration for the rest of the game
|
||||
sealcontexts
|
||||
|
||||
@@ -215,7 +215,7 @@ void movelocalplayer()
|
||||
moveplayer(player1, 10, false);
|
||||
}
|
||||
}
|
||||
else if(!intermission)
|
||||
else if(player1->state!=CS_SPECTATE && !intermission)
|
||||
{
|
||||
moveplayer(player1, 20, true);
|
||||
checkitems(player1);
|
||||
|
||||
+34
-9
@@ -4,9 +4,10 @@
|
||||
#include "pch.h"
|
||||
#include "cube.h"
|
||||
|
||||
bool allowidentaccess(ident *id);
|
||||
char *exchangestr(char *o, char *n) { delete[] o; return newstring(n); }
|
||||
|
||||
int execcontext = IEXC_CORE;
|
||||
int execcontext;
|
||||
|
||||
hashtable<const char *, ident> *idents = NULL; // contains ALL vars/commands/aliases
|
||||
|
||||
@@ -259,7 +260,7 @@ char *executeret(const char *p) // all evaluation hap
|
||||
}
|
||||
else
|
||||
{
|
||||
if(execcontext > id->context)
|
||||
if(!allowidentaccess(id))
|
||||
{
|
||||
conoutf("not allowed in this execution context: %s", id->name);
|
||||
continue;
|
||||
@@ -577,26 +578,36 @@ void identnames(vector<const char *> &names, bool builtinonly)
|
||||
enumerateht(*idents) if(!builtinonly || idents->enumc->data.type != ID_ALIAS) names.add(idents->enumc->key);
|
||||
}
|
||||
|
||||
void changescriptcontext(int newcontext)
|
||||
vector<int> contextstack;
|
||||
bool contextsealed = false;
|
||||
bool contextisolated[IEXC_NUM] = { false };
|
||||
|
||||
void pushscontext(int newcontext)
|
||||
{
|
||||
if(newcontext < execcontext) // clean up aliases created in the old context
|
||||
contextstack.add((execcontext = newcontext));
|
||||
}
|
||||
|
||||
int popscontext()
|
||||
{
|
||||
ASSERT(contextstack.length() > 0);
|
||||
int old = contextstack.pop();
|
||||
execcontext = contextstack.last();
|
||||
|
||||
if(execcontext < old && old >= IEXC_MAPCFG) // clean up aliases created in the old (map cfg) context
|
||||
{
|
||||
enumerateht(*idents)
|
||||
{
|
||||
ident *id = &idents->enumc->data;
|
||||
if(id->type == ID_ALIAS && id->context > newcontext)
|
||||
if(id->type == ID_ALIAS && id->context > execcontext)
|
||||
{
|
||||
idents->remove(idents->enumc->key);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
execcontext = newcontext;
|
||||
return execcontext;
|
||||
}
|
||||
|
||||
|
||||
bool contextsealed = false;
|
||||
|
||||
void scriptcontext(char *context, char *idname)
|
||||
{
|
||||
if(contextsealed) return;
|
||||
@@ -606,8 +617,22 @@ void scriptcontext(char *context, char *idname)
|
||||
if(c >= 0 && c < IEXC_NUM) id->context = c;
|
||||
}
|
||||
|
||||
void isolatecontext(int context)
|
||||
{
|
||||
if(context >= 0 && context < IEXC_NUM && !contextsealed) contextisolated[context] = true;
|
||||
}
|
||||
|
||||
void sealcontexts() { contextsealed = true; }
|
||||
|
||||
bool allowidentaccess(ident *id) // check if ident is allowed in current context
|
||||
{
|
||||
ASSERT(execcontext >= 0 && execcontext < IEXC_NUM);
|
||||
if(!id) return false;
|
||||
if(!contextisolated[execcontext]) return true; // only check if context is isolated
|
||||
return execcontext <= id->context;
|
||||
}
|
||||
|
||||
COMMAND(scriptcontext, ARG_2STR);
|
||||
COMMAND(isolatecontext, ARG_1INT);
|
||||
COMMAND(sealcontexts, ARG_NONE);
|
||||
|
||||
|
||||
@@ -26,8 +26,10 @@ struct ident
|
||||
int narg; // ID_VAR, ID_COMMAND
|
||||
char *action, *executing; // ID_ALIAS
|
||||
bool persist;
|
||||
|
||||
int context;
|
||||
|
||||
|
||||
ident() {}
|
||||
|
||||
// ID_VAR
|
||||
@@ -72,7 +74,7 @@ enum // function signatures for script functions, see command.cpp
|
||||
ARG_VARI, ARG_VARIW
|
||||
};
|
||||
|
||||
enum { IEXC_CORE = 0, IEXC_FOREIGN, IEXC_NUM }; // script execution context
|
||||
enum { IEXC_CORE = 0, IEXC_CFG, IEXC_PROMPT, IEXC_MAPCFG, IEXC_NUM }; // script execution context
|
||||
|
||||
// nasty macros for registering script functions, abuses globals to avoid excessive infrastructure
|
||||
#define COMMANDN(name, fun, nargs) static bool __dummy_##fun = addcommand(#name, (void (*)())fun, nargs)
|
||||
|
||||
@@ -34,6 +34,7 @@ void quit() // normal exit
|
||||
if(resetcfg) deletecfg();
|
||||
else writecfg();
|
||||
cleanup(NULL);
|
||||
popscontext();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -406,6 +407,8 @@ int main(int argc, char **argv)
|
||||
int uprate = 0, maxcl = DEFAULTCLIENTS, scthreshold = -5, port = 0;
|
||||
const char *sdesc = "", *ip = "", *master = NULL, *passwd = "", *maprot = NULL, *adminpwd = NULL, *srvmsg = NULL;
|
||||
|
||||
pushscontext(IEXC_CFG);
|
||||
|
||||
#define initlog(s) puts("init: " s)
|
||||
|
||||
initing = true;
|
||||
@@ -622,6 +625,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
quit();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -45,6 +45,10 @@ extern void changescriptcontext(int newcontext);
|
||||
extern void explodelist(const char *s, vector<char *> &elems);
|
||||
extern char *indexlist(const char *s, int pos);
|
||||
extern char *parseword(const char *&p);
|
||||
extern void pushscontext(int newcontext);
|
||||
extern int popscontext();
|
||||
extern int curscontext();
|
||||
extern int execcontext;
|
||||
|
||||
// console
|
||||
extern void keypress(int code, bool isdown, int cooked);
|
||||
|
||||
@@ -66,7 +66,10 @@ void mapmodel(char *rad, char *h, char *zoff, char *snap, char *name)
|
||||
s_sprintf(mmi.name)("mapmodels/%s", name);
|
||||
}
|
||||
|
||||
void mapmodelreset() { mapmodels.setsize(0); }
|
||||
void mapmodelreset()
|
||||
{
|
||||
if(execcontext==IEXC_MAPCFG) mapmodels.setsize(0);
|
||||
}
|
||||
|
||||
mapmodelinfo &getmminfo(int i) { return mapmodels.inrange(i) ? mapmodels[i] : *(mapmodelinfo *)0; }
|
||||
|
||||
|
||||
@@ -376,11 +376,13 @@ bool load_world(char *mname) // still supports all map formats that have
|
||||
conoutf("read map %s (%d milliseconds)", cgzname, SDL_GetTicks()-lastmillis);
|
||||
conoutf("%s", hdr.maptitle);
|
||||
startmap(mname);
|
||||
|
||||
pushscontext(IEXC_MAPCFG); // untrusted altogether
|
||||
execfile("config/default_map_settings.cfg");
|
||||
changescriptcontext(IEXC_FOREIGN);
|
||||
execfile(pcfname);
|
||||
execfile(mcfname);
|
||||
changescriptcontext(IEXC_CORE);
|
||||
popscontext();
|
||||
|
||||
c2skeepalive();
|
||||
loopi(256) if(texuse[i]) lookuptexture(i);
|
||||
c2skeepalive();
|
||||
|
||||
Reference in New Issue
Block a user