95118dc
--- server/scripting/script.c	2010-02-21 19:35:39.000000000 +0100
95118dc
+++ server/scripting/script.c.old	2010-06-06 09:30:51.000000000 +0200
95118dc
@@ -44,6 +44,48 @@
95118dc
 
95118dc
 
95118dc
 /**************************************************************************
95118dc
+  Unsafe Lua builtin symbols that we to remove access to.
95118dc
+
95118dc
+  If Freeciv's Lua version changes, you have to check how the set of
95118dc
+  unsafe functions and modules changes in the new version. Update the list of
95118dc
+  loaded libraries in script_lualibs, then update the unsafe symbols blacklist
95118dc
+  in script_unsafe_symbols.
95118dc
+
95118dc
+  Once the variables are updated for the new version, update the value of
95118dc
+  SCRIPT_SECURE_LUA_VERSION
95118dc
+
95118dc
+  In general, unsafe is all functionality that gives access to:
95118dc
+  * Reading files and running processes
95118dc
+  * Loading lua files or libraries
95118dc
+**************************************************************************/
95118dc
+#define SCRIPT_SECURE_LUA_VERSION 501
95118dc
+
95118dc
+static const char *script_unsafe_symbols[] = {
95118dc
+  "dofile",
95118dc
+  "loadfile",
95118dc
+  NULL
95118dc
+};
95118dc
+
95118dc
+#if LUA_VERSION_NUM != SCRIPT_SECURE_LUA_VERSION
95118dc
+#warning "The script runtime's unsafe symbols information is not up to date."
95118dc
+#warning "This can be a big security hole!"
95118dc
+#endif
95118dc
+
95118dc
+/**************************************************************************
95118dc
+  Lua libraries to load (all default libraries, excluding operating system
95118dc
+  and library loading modules). See linit.c in Lua 5.1 for the default list.
95118dc
+**************************************************************************/
95118dc
+static luaL_Reg script_lualibs[] = {
95118dc
+  /* Using default libraries excluding: package, io and os */
95118dc
+  {"", luaopen_base},
95118dc
+  {LUA_TABLIBNAME, luaopen_table},
95118dc
+  {LUA_STRLIBNAME, luaopen_string},
95118dc
+  {LUA_MATHLIBNAME, luaopen_math},
95118dc
+  {LUA_DBLIBNAME, luaopen_debug},
95118dc
+  {NULL, NULL}
95118dc
+};
95118dc
+
95118dc
+/**************************************************************************
95118dc
   Report a lua error.
95118dc
 **************************************************************************/
95118dc
 static int script_report(lua_State *L, int status, const char *code)
95118dc
@@ -383,6 +425,31 @@
95118dc
 }
95118dc
 
95118dc
 /**************************************************************************
95118dc
+  Open lua libraries in the array of library definitions in llib.
95118dc
+**************************************************************************/
95118dc
+static void script_openlibs(lua_State *L, const luaL_Reg *llib)
95118dc
+{
95118dc
+  for (; llib->func; llib++) {
95118dc
+    lua_pushcfunction(L, llib->func);
95118dc
+    lua_pushstring(L, llib->name);
95118dc
+    lua_call(L, 1, 0);
95118dc
+  }
95118dc
+}
95118dc
+
95118dc
+/**************************************************************************
95118dc
+  Remove global symbols from lua state L
95118dc
+**************************************************************************/
95118dc
+static void script_blacklist(lua_State *L, const char *lsymbols[])
95118dc
+{
95118dc
+  int i;
95118dc
+
95118dc
+  for (i = 0; lsymbols[i] != NULL; i++) {
95118dc
+    lua_pushnil(L);
95118dc
+    lua_setglobal(L, lsymbols[i]);
95118dc
+  }
95118dc
+}
95118dc
+
95118dc
+/**************************************************************************
95118dc
   Initialize the scripting state.
95118dc
 **************************************************************************/
95118dc
 bool script_init(void)
95118dc
@@ -393,7 +460,8 @@
95118dc
       return FALSE;
95118dc
     }
95118dc
 
95118dc
-    luaL_openlibs(state);
95118dc
+    script_openlibs(state, script_lualibs);
95118dc
+    script_blacklist(state, script_unsafe_symbols);
95118dc
 
95118dc
     tolua_api_open(state);