diff options
-rw-r--r-- | Makefile.am | 9 | ||||
-rw-r--r-- | Makefile.nmake | 4 | ||||
-rw-r--r-- | make-init-lua.pl | 94 | ||||
-rw-r--r-- | plugins/lua/packet-lua.c | 173 | ||||
-rw-r--r-- | plugins/lua/packet-lua.h | 3 | ||||
-rw-r--r-- | template-init.lua | 58 |
6 files changed, 306 insertions, 35 deletions
diff --git a/Makefile.am b/Makefile.am index 921a778d40..33d6f693e2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -682,7 +682,10 @@ EXTRA_DIST = \ text2pcap-scanner.l \ text2pcap.c \ text2pcap.h \ - wka.tmpl + wka.tmpl \ + template-init.lua \ + make-init-lua.pl \ + init.lua if SETUID_INSTALL install-exec-hook: @@ -841,3 +844,7 @@ test-splint: $(ethereal_SOURCES) -I./tools/lemon \ -I./wiretap \ $(ethereal_SOURCES) + +init.lua: template-init.lua make-init-lua.pl epan/ftypes/ftypes.h wiretap/wtap.h + $(PERL) make-init-lua.pl template-init.lua > init.lua + diff --git a/Makefile.nmake b/Makefile.nmake index 1268f2b1dd..ecad5375c1 100644 --- a/Makefile.nmake +++ b/Makefile.nmake @@ -672,4 +672,8 @@ clean-deps: $(MAKE) /$(MAKEFLAGS) -f Makefile.nmake clean-deps cd .. +init.lua: template-init.lua make-init-lua.pl epan/ftypes/ftypes.h wiretap/wtap.h + $(PERL) make-init-lua.pl template-init.lua > init.lua + + diff --git a/make-init-lua.pl b/make-init-lua.pl new file mode 100644 index 0000000000..aa9e5c49a1 --- /dev/null +++ b/make-init-lua.pl @@ -0,0 +1,94 @@ +#!/usr/bin/perl +# create the init.lua file based on a template (stdin) +# +# $Id: $ +# +# Ethereal - Network traffic analyzer +# By Gerald Combs <gerald@ethereal.com> +# Copyright 2004 Gerald Combs +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +use strict; + +my $wtap_encaps_table = ''; +my $ft_types_table = ''; + + +my %replacements = %{{ + WTAP_ENCAPS => \$wtap_encaps_table, + FT_TYPES => \$ft_types_table, +}}; + + +# +# load template +# +my $template = ''; +$template .= $_ while(<>); + + +# +# make wiretap encapusulation table +# + +$wtap_encaps_table = "-- Wiretap encapsulations\nwtap = {\n"; + +open WTAP_H, "< wiretap/wtap.h"; + +while(<WTAP_H>) { + if ( /^#define WTAP_ENCAP_([A-Z0-9_]+)\s+(\d+)/ ) { + $wtap_encaps_table .= "\t[\"$1\"] = $2,\n"; + } +} + +$wtap_encaps_table =~ s/,\n$/\n}\n/msi; + +# +# enum fttype +# + +$ft_types_table = " -- Field Types\nftypes = {\n"; + +my $ftype_num = 0; + +open FTYPES_H, "< ./epan/ftypes/ftypes.h"; +while(<FTYPES_H>) { + if ( /^\s+(FT_[A-Z0-9a-z_]+)\s*,/ ) { + $ft_types_table .= "\t[\"$1\"] = $ftype_num,\n"; + $ftype_num++; + } +} +close FTYPES_H; + +$ft_types_table =~ s/,\n$/\n}\n/msi; + + + +# +# +# + + +# +# replace macros +# + +for my $key (keys %replacements) { + $template =~ s/%$key%/${$replacements{$key}}/msig; +} + + +print $template; diff --git a/plugins/lua/packet-lua.c b/plugins/lua/packet-lua.c index 7ff4bee583..875cff4aa3 100644 --- a/plugins/lua/packet-lua.c +++ b/plugins/lua/packet-lua.c @@ -92,6 +92,45 @@ static int lua_not_register_menu(lua_State* L) { return 0; } +static int lua_not_print(lua_State* L) { + luaL_error(L,"do not use print use either a TextWindow or critical(),\n" + "warn(), message(), info() or debug()"); + return 0; +} + +int lua_log(lua_State* L, GLogLevelFlags log_level) { + GString* str = g_string_new(""); + int n = lua_gettop(L); /* number of arguments */ + int i; + + lua_getglobal(L, "tostring"); + for (i=1; i<=n; i++) { + const char *s; + lua_pushvalue(L, -1); /* function to be called */ + lua_pushvalue(L, i); /* value to print */ + lua_call(L, 1, 1); + s = lua_tostring(L, -1); /* get result */ + if (s == NULL) + return luaL_error(L, "`tostring' must return a string to `print'"); + + if (i>1) g_string_append(str,"\t"); + g_string_append(str,s); + + lua_pop(L, 1); /* pop result */ + } + + g_log(LOG_DOMAIN_LUA, log_level, "%s\n", str->str); + g_string_free(str,TRUE); + + return 0; +} + +int lua_critical( lua_State* L ) { lua_log(L,G_LOG_LEVEL_CRITICAL); return 0; } +int lua_warn( lua_State* L ) { lua_log(L,G_LOG_LEVEL_WARNING); return 0; } +int lua_message( lua_State* L ) { lua_log(L,G_LOG_LEVEL_MESSAGE); return 0; } +int lua_info( lua_State* L ) { lua_log(L,G_LOG_LEVEL_INFO); return 0; } +int lua_debug( lua_State* L ) { lua_log(L,G_LOG_LEVEL_DEBUG); return 0; } + void dissect_lua(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree) { lua_pinfo = pinfo; @@ -243,44 +282,37 @@ void lua_load_script(const gchar* filename) { } +static void basic_logger(const gchar *log_domain _U_, + GLogLevelFlags log_level _U_, + const gchar *message, + gpointer user_data _U_) { + fputs(message,stderr); +} + void register_lua(void) { const gchar* filename; - GPtrArray* filenames = g_ptr_array_new(); - guint i; - - filename = get_datafile_path("init.lua"); - - if (( file_exists(filename))) { - g_ptr_array_add(filenames,(void*)filename); - } - - - if (! started_with_special_privs() ) { - filename = get_persconffile_path("init.lua", FALSE); - - if (( file_exists(filename))) { - g_ptr_array_add(filenames,(void*)filename); - } - - while((filename = ex_opt_get_next("lua_script"))) { - g_ptr_array_add(filenames,(void*)filename); - } - } + const funnel_ops_t* ops = funnel_get_funnel_ops(); + gboolean run_anyway = FALSE; - if (! filenames->len) { - g_ptr_array_free(filenames,TRUE); - return; - } + /* set up the logger */ + g_log_set_handler(LOG_DOMAIN_LUA, G_LOG_LEVEL_CRITICAL| + G_LOG_LEVEL_WARNING| + G_LOG_LEVEL_MESSAGE| + G_LOG_LEVEL_INFO| + G_LOG_LEVEL_DEBUG, + ops ? ops->logger : basic_logger, NULL); - register_init_routine(init_lua); + /* initialize the lua machine */ L = lua_open(); + /* load lua's standard library */ luaopen_base(L); luaopen_table(L); luaopen_io(L); luaopen_string(L); - + + /* load ethereal's API */ ProtoField_register(L); ProtoFieldArray_register(L); SubTree_register(L); @@ -299,7 +331,35 @@ void register_lua(void) { Tap_register(L); Address_register(L); TextWindow_register(L); - + + /* print has been changed to yield an error if used */ + lua_pushstring(L, "print"); + lua_pushcfunction(L, lua_not_print); + lua_settable(L, LUA_GLOBALSINDEX); + + /* logger functions */ + lua_pushstring(L, "critical"); + lua_pushcfunction(L, lua_critical); + lua_settable(L, LUA_GLOBALSINDEX); + + lua_pushstring(L, "warn"); + lua_pushcfunction(L, lua_warn); + lua_settable(L, LUA_GLOBALSINDEX); + + lua_pushstring(L, "message"); + lua_pushcfunction(L, lua_message); + lua_settable(L, LUA_GLOBALSINDEX); + + lua_pushstring(L, "info"); + lua_pushcfunction(L, lua_info); + lua_settable(L, LUA_GLOBALSINDEX); + + lua_pushstring(L, "debug"); + lua_pushcfunction(L, lua_debug); + lua_settable(L, LUA_GLOBALSINDEX); + + + /* functions not registered by any other module */ lua_pushstring(L, "format_date"); lua_pushcfunction(L, lua_format_date); lua_settable(L, LUA_GLOBALSINDEX); @@ -323,26 +383,73 @@ void register_lua(void) { lua_pushstring(L, "dialog"); lua_pushcfunction(L, lua_new_dialog); lua_settable(L, LUA_GLOBALSINDEX); - + + /* the init_routines table (accessible by the user) */ lua_pushstring(L, LUA_INIT_ROUTINES); lua_newtable (L); lua_settable(L, LUA_GLOBALSINDEX); + /* the dissectors table goes in the registry (not accessible) */ lua_newtable (L); lua_dissectors_table_ref = luaL_ref(L, LUA_REGISTRYINDEX); + + /* set running_superuser variable to it's propper value */ + lua_pushstring(L,"running_superuser"); + lua_pushboolean(L,started_with_special_privs()); + lua_settable(L, LUA_GLOBALSINDEX); + + /* load system's init.lua */ + filename = get_datafile_path("init.lua"); - for (i=0 ; i < filenames->len ; i++) { - filename = g_ptr_array_index(filenames,i); + if (( file_exists(filename))) { lua_load_script(filename); } - g_ptr_array_free(filenames,TRUE); + /* check if lua is to be disabled */ + lua_pushstring(L,"lua_disabled"); + lua_gettable(L, LUA_GLOBALSINDEX); - /* after the body it is too late to register a menu */ + if (lua_isboolean(L,-1) && lua_toboolean(L,-1)) { + /* disable lua */ + lua_close(L); + L = NULL; + return; + } + + /* check whether we should run other scripts even if running superuser */ + lua_pushstring(L,"run_user_scripts_when_superuser"); + lua_gettable(L, LUA_GLOBALSINDEX); + + if (lua_isboolean(L,-1) && lua_toboolean(L,-1)) { + run_anyway = TRUE; + } + + + /* if we are indeed superuser run user scripts only if told to do so */ + if ( (!started_with_special_privs()) || run_anyway ) { + filename = get_persconffile_path("init.lua", FALSE); + + if (( file_exists(filename))) { + lua_load_script(filename); + } + + while((filename = ex_opt_get_next("lua_script"))) { + lua_load_script(filename); + } + } + + /* at this point we're set up so register the init routine */ + register_init_routine(init_lua); + + /* + * after this point it is too late to register a menu + * disable the function to avoid weirdness + */ lua_pushstring(L, "register_menu"); lua_pushcfunction(L, lua_not_register_menu); lua_settable(L, LUA_GLOBALSINDEX); + /* set up some essential globals */ lua_pinfo = NULL; lua_tree = NULL; lua_tvb = NULL; diff --git a/plugins/lua/packet-lua.h b/plugins/lua/packet-lua.h index 954ab41587..4b21b65de6 100644 --- a/plugins/lua/packet-lua.h +++ b/plugins/lua/packet-lua.h @@ -52,6 +52,7 @@ #define LUA_DISSECTORS_TABLE "dissectors" #define LUA_INIT_ROUTINES "init_routines" #define LUA_HANDOFF_ROUTINES "handoff_routines" +#define LOG_DOMAIN_LUA "Lua" struct _eth_tvbrange { tvbuff_t* tvb; @@ -193,7 +194,7 @@ C* push##C(lua_State* L, C v) { \ gboolean is##C(lua_State* L,int i) { \ return (gboolean)(lua_isuserdata(L,i) && luaL_checkudata(L,3,CN)); \ } \ -extern C shift##C(lua_State* L,int i) { \ +C shift##C(lua_State* L,int i) { \ C* p; \ if ((p = (C*)luaL_checkudata(L, i, CN))) {\ lua_remove(L,i); \ diff --git a/template-init.lua b/template-init.lua new file mode 100644 index 0000000000..85f316aac3 --- /dev/null +++ b/template-init.lua @@ -0,0 +1,58 @@ +-- init.lua +-- +-- initilaize ethereal's lua +-- +-- This file is going to be executed before any other lua script. +-- It can be used to load libraries, disable functions and more. +-- +-- $Id: $ +-- +-- Ethereal - Network traffic analyzer +-- By Gerald Combs <gerald@ethereal.com> +-- Copyright 1998 Gerald Combs +-- +-- This program is free software; you can redistribute it and/or +-- modify it under the terms of the GNU General Public License +-- as published by the Free Software Foundation; either version 2 +-- of the License, or (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +-- If lua is to be disabled even if it was installed uncomment the following +-- line. +-- disable_lua = true; do return end; + + +-- If set and we are running with special privileges this setting +-- tells whether scripts other than this one are to be run. +run_user_scripts_when_superuser = false + +-- disable potentialy harmful lua functions when running superuser +if running_superuser then + dofile = function() error("dofile has been disabled") end + loadfile = function() error("loadfile has been disabled") end + loadlib = function() error("loadlib has been disabled") end + require = function() error("require has been disabled") end + os = {} + io = {} + file = {} +end + +-- to avoid output to stdout which can caause problems lua's print () +-- has been suppresed so that it yields an error. +-- have print() call info() instead. +print = info + +-- %WTAP_ENCAPS% + +-- %FT_TYPES% + + |