immunio 0.15.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (157) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +234 -0
  3. data/README.md +147 -0
  4. data/bin/immunio +5 -0
  5. data/lib/immunio.rb +29 -0
  6. data/lib/immunio/agent.rb +260 -0
  7. data/lib/immunio/authentication.rb +96 -0
  8. data/lib/immunio/blocked_app.rb +38 -0
  9. data/lib/immunio/channel.rb +432 -0
  10. data/lib/immunio/cli.rb +39 -0
  11. data/lib/immunio/context.rb +114 -0
  12. data/lib/immunio/errors.rb +43 -0
  13. data/lib/immunio/immunio_ca.crt +45 -0
  14. data/lib/immunio/logger.rb +87 -0
  15. data/lib/immunio/plugins/action_dispatch.rb +45 -0
  16. data/lib/immunio/plugins/action_view.rb +431 -0
  17. data/lib/immunio/plugins/active_record.rb +707 -0
  18. data/lib/immunio/plugins/active_record_relation.rb +370 -0
  19. data/lib/immunio/plugins/authlogic.rb +80 -0
  20. data/lib/immunio/plugins/csrf.rb +24 -0
  21. data/lib/immunio/plugins/devise.rb +40 -0
  22. data/lib/immunio/plugins/environment_reporter.rb +69 -0
  23. data/lib/immunio/plugins/eval.rb +51 -0
  24. data/lib/immunio/plugins/exception_handler.rb +55 -0
  25. data/lib/immunio/plugins/gems_tracker.rb +5 -0
  26. data/lib/immunio/plugins/haml.rb +36 -0
  27. data/lib/immunio/plugins/http_finisher.rb +50 -0
  28. data/lib/immunio/plugins/http_tracker.rb +203 -0
  29. data/lib/immunio/plugins/io.rb +96 -0
  30. data/lib/immunio/plugins/redirect.rb +42 -0
  31. data/lib/immunio/plugins/warden.rb +66 -0
  32. data/lib/immunio/processor.rb +234 -0
  33. data/lib/immunio/rails.rb +26 -0
  34. data/lib/immunio/request.rb +139 -0
  35. data/lib/immunio/rufus_lua_ext/ref.rb +27 -0
  36. data/lib/immunio/rufus_lua_ext/state.rb +157 -0
  37. data/lib/immunio/rufus_lua_ext/table.rb +137 -0
  38. data/lib/immunio/rufus_lua_ext/utils.rb +13 -0
  39. data/lib/immunio/version.rb +5 -0
  40. data/lib/immunio/vm.rb +291 -0
  41. data/lua-hooks/ext/all.c +78 -0
  42. data/lua-hooks/ext/bitop/README +22 -0
  43. data/lua-hooks/ext/bitop/bit.c +189 -0
  44. data/lua-hooks/ext/extconf.rb +38 -0
  45. data/lua-hooks/ext/libinjection/COPYING +37 -0
  46. data/lua-hooks/ext/libinjection/libinjection.h +65 -0
  47. data/lua-hooks/ext/libinjection/libinjection_html5.c +847 -0
  48. data/lua-hooks/ext/libinjection/libinjection_html5.h +54 -0
  49. data/lua-hooks/ext/libinjection/libinjection_sqli.c +2301 -0
  50. data/lua-hooks/ext/libinjection/libinjection_sqli.h +295 -0
  51. data/lua-hooks/ext/libinjection/libinjection_sqli_data.h +9349 -0
  52. data/lua-hooks/ext/libinjection/libinjection_xss.c +531 -0
  53. data/lua-hooks/ext/libinjection/libinjection_xss.h +21 -0
  54. data/lua-hooks/ext/libinjection/lualib.c +109 -0
  55. data/lua-hooks/ext/lpeg/HISTORY +90 -0
  56. data/lua-hooks/ext/lpeg/lpcap.c +537 -0
  57. data/lua-hooks/ext/lpeg/lpcap.h +43 -0
  58. data/lua-hooks/ext/lpeg/lpcode.c +986 -0
  59. data/lua-hooks/ext/lpeg/lpcode.h +34 -0
  60. data/lua-hooks/ext/lpeg/lpeg-128.gif +0 -0
  61. data/lua-hooks/ext/lpeg/lpeg.html +1429 -0
  62. data/lua-hooks/ext/lpeg/lpprint.c +244 -0
  63. data/lua-hooks/ext/lpeg/lpprint.h +35 -0
  64. data/lua-hooks/ext/lpeg/lptree.c +1238 -0
  65. data/lua-hooks/ext/lpeg/lptree.h +77 -0
  66. data/lua-hooks/ext/lpeg/lptypes.h +149 -0
  67. data/lua-hooks/ext/lpeg/lpvm.c +355 -0
  68. data/lua-hooks/ext/lpeg/lpvm.h +58 -0
  69. data/lua-hooks/ext/lpeg/makefile +55 -0
  70. data/lua-hooks/ext/lpeg/re.html +498 -0
  71. data/lua-hooks/ext/lpeg/test.lua +1409 -0
  72. data/lua-hooks/ext/lua-cmsgpack/CMakeLists.txt +45 -0
  73. data/lua-hooks/ext/lua-cmsgpack/README.md +115 -0
  74. data/lua-hooks/ext/lua-cmsgpack/lua_cmsgpack.c +957 -0
  75. data/lua-hooks/ext/lua-cmsgpack/test.lua +570 -0
  76. data/lua-hooks/ext/lua-snapshot/LICENSE +7 -0
  77. data/lua-hooks/ext/lua-snapshot/Makefile +12 -0
  78. data/lua-hooks/ext/lua-snapshot/README.md +18 -0
  79. data/lua-hooks/ext/lua-snapshot/dump.lua +15 -0
  80. data/lua-hooks/ext/lua-snapshot/snapshot.c +455 -0
  81. data/lua-hooks/ext/lua/COPYRIGHT +34 -0
  82. data/lua-hooks/ext/lua/lapi.c +1087 -0
  83. data/lua-hooks/ext/lua/lapi.h +16 -0
  84. data/lua-hooks/ext/lua/lauxlib.c +652 -0
  85. data/lua-hooks/ext/lua/lauxlib.h +174 -0
  86. data/lua-hooks/ext/lua/lbaselib.c +659 -0
  87. data/lua-hooks/ext/lua/lcode.c +831 -0
  88. data/lua-hooks/ext/lua/lcode.h +76 -0
  89. data/lua-hooks/ext/lua/ldblib.c +398 -0
  90. data/lua-hooks/ext/lua/ldebug.c +638 -0
  91. data/lua-hooks/ext/lua/ldebug.h +33 -0
  92. data/lua-hooks/ext/lua/ldo.c +519 -0
  93. data/lua-hooks/ext/lua/ldo.h +57 -0
  94. data/lua-hooks/ext/lua/ldump.c +164 -0
  95. data/lua-hooks/ext/lua/lfunc.c +174 -0
  96. data/lua-hooks/ext/lua/lfunc.h +34 -0
  97. data/lua-hooks/ext/lua/lgc.c +710 -0
  98. data/lua-hooks/ext/lua/lgc.h +110 -0
  99. data/lua-hooks/ext/lua/linit.c +38 -0
  100. data/lua-hooks/ext/lua/liolib.c +556 -0
  101. data/lua-hooks/ext/lua/llex.c +463 -0
  102. data/lua-hooks/ext/lua/llex.h +81 -0
  103. data/lua-hooks/ext/lua/llimits.h +128 -0
  104. data/lua-hooks/ext/lua/lmathlib.c +263 -0
  105. data/lua-hooks/ext/lua/lmem.c +86 -0
  106. data/lua-hooks/ext/lua/lmem.h +49 -0
  107. data/lua-hooks/ext/lua/loadlib.c +705 -0
  108. data/lua-hooks/ext/lua/loadlib_rel.c +760 -0
  109. data/lua-hooks/ext/lua/lobject.c +214 -0
  110. data/lua-hooks/ext/lua/lobject.h +381 -0
  111. data/lua-hooks/ext/lua/lopcodes.c +102 -0
  112. data/lua-hooks/ext/lua/lopcodes.h +268 -0
  113. data/lua-hooks/ext/lua/loslib.c +243 -0
  114. data/lua-hooks/ext/lua/lparser.c +1339 -0
  115. data/lua-hooks/ext/lua/lparser.h +82 -0
  116. data/lua-hooks/ext/lua/lstate.c +214 -0
  117. data/lua-hooks/ext/lua/lstate.h +169 -0
  118. data/lua-hooks/ext/lua/lstring.c +111 -0
  119. data/lua-hooks/ext/lua/lstring.h +31 -0
  120. data/lua-hooks/ext/lua/lstrlib.c +871 -0
  121. data/lua-hooks/ext/lua/ltable.c +588 -0
  122. data/lua-hooks/ext/lua/ltable.h +40 -0
  123. data/lua-hooks/ext/lua/ltablib.c +287 -0
  124. data/lua-hooks/ext/lua/ltm.c +75 -0
  125. data/lua-hooks/ext/lua/ltm.h +54 -0
  126. data/lua-hooks/ext/lua/lua.c +392 -0
  127. data/lua-hooks/ext/lua/lua.def +131 -0
  128. data/lua-hooks/ext/lua/lua.h +388 -0
  129. data/lua-hooks/ext/lua/lua.rc +28 -0
  130. data/lua-hooks/ext/lua/lua_dll.rc +26 -0
  131. data/lua-hooks/ext/lua/luac.c +200 -0
  132. data/lua-hooks/ext/lua/luac.rc +1 -0
  133. data/lua-hooks/ext/lua/luaconf.h +763 -0
  134. data/lua-hooks/ext/lua/luaconf.h.in +724 -0
  135. data/lua-hooks/ext/lua/luaconf.h.orig +763 -0
  136. data/lua-hooks/ext/lua/lualib.h +53 -0
  137. data/lua-hooks/ext/lua/lundump.c +227 -0
  138. data/lua-hooks/ext/lua/lundump.h +36 -0
  139. data/lua-hooks/ext/lua/lvm.c +767 -0
  140. data/lua-hooks/ext/lua/lvm.h +36 -0
  141. data/lua-hooks/ext/lua/lzio.c +82 -0
  142. data/lua-hooks/ext/lua/lzio.h +67 -0
  143. data/lua-hooks/ext/lua/print.c +227 -0
  144. data/lua-hooks/ext/luautf8/README.md +152 -0
  145. data/lua-hooks/ext/luautf8/lutf8lib.c +1274 -0
  146. data/lua-hooks/ext/luautf8/unidata.h +3064 -0
  147. data/lua-hooks/lib/boot.lua +254 -0
  148. data/lua-hooks/lib/encode.lua +4 -0
  149. data/lua-hooks/lib/lexers/LICENSE +21 -0
  150. data/lua-hooks/lib/lexers/bash.lua +134 -0
  151. data/lua-hooks/lib/lexers/bash_dqstr.lua +62 -0
  152. data/lua-hooks/lib/lexers/css.lua +216 -0
  153. data/lua-hooks/lib/lexers/html.lua +106 -0
  154. data/lua-hooks/lib/lexers/javascript.lua +68 -0
  155. data/lua-hooks/lib/lexers/lexer.lua +1575 -0
  156. data/lua-hooks/lib/lexers/markers.lua +33 -0
  157. metadata +308 -0
@@ -0,0 +1,13 @@
1
+ module Rufus::Lua
2
+ def self.to_lua_s_with_symbol(o)
3
+ case o
4
+ when Symbol then o.to_s.inspect
5
+ else
6
+ to_lua_s_without_symbol o
7
+ end
8
+ end
9
+ class << self
10
+ alias_method :to_lua_s_without_symbol, :to_lua_s
11
+ alias_method :to_lua_s, :to_lua_s_with_symbol
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ module Immunio
2
+ AGENT_TYPE = "agent-ruby"
3
+ VERSION = "0.15.2"
4
+ VM_VERSION = "2.2.0"
5
+ end
@@ -0,0 +1,291 @@
1
+ require_relative "errors"
2
+
3
+ # Use our custom Lua lib.
4
+ ext = RbConfig::CONFIG['DLEXT']
5
+ ENV['LUA_LIB'] = "#{Immunio::DIR}/immunio/lua-hooks.#{ext}"
6
+
7
+ require 'rufus-lua'
8
+
9
+ # Load rufus-lua extensions
10
+ require_relative "rufus_lua_ext/ref"
11
+ require_relative "rufus_lua_ext/state"
12
+ require_relative "rufus_lua_ext/table"
13
+ require_relative "rufus_lua_ext/utils"
14
+
15
+ module Immunio
16
+ class VMError < Error; end
17
+
18
+ class VMFactory
19
+ attr_reader :code_version, :data_version
20
+
21
+ def initialize(key, secret, dev_mode = false, debug_mode = false)
22
+
23
+ # Code is lua functions plus utils generated by the __init__ function
24
+ @code_version = nil
25
+ @functions = {}
26
+ @utils = {}
27
+
28
+ # Data is to hold serverdata
29
+ @data_version = nil
30
+ @data = nil
31
+
32
+ @update_lock = Mutex.new
33
+
34
+ # Cached VM - reusable by multiple clients
35
+ @lua_vm = LuaVM.new(key, secret, dev_mode, debug_mode)
36
+ @dev_mode = dev_mode
37
+ @dev_checksum = ""
38
+ end
39
+
40
+ def update_code(version, code)
41
+ functions = {}
42
+ code.each { |fun_name, lua_code|
43
+ functions[fun_name] = @lua_vm.create_function lua_code, fun_name
44
+ }
45
+
46
+ init_hook = functions.delete("__init__")
47
+ if init_hook
48
+ utils = @lua_vm.call(init_hook)
49
+ else
50
+ utils = {}
51
+ end
52
+
53
+ @update_lock.synchronize {
54
+ @code_version = version
55
+ @functions = functions
56
+ @utils = utils
57
+ }
58
+ Immunio.logger.info "Lua code updated to version #{version}."
59
+ end
60
+
61
+ def update_data(version, data)
62
+ # Allow server data to be overridden in the Agent config file
63
+ data = data.deep_merge(Immunio.agent.config.vm_data)
64
+ new_data = @lua_vm.create_object(data)
65
+ @update_lock.synchronize {
66
+ @data_version = version
67
+ @data = new_data
68
+ }
69
+ Immunio.logger.debug "Lua data updated to version #{version}."
70
+ end
71
+
72
+ def current_state
73
+ {
74
+ vmcode_version: @code_version,
75
+ vmdata_version: @data_version
76
+ }
77
+ end
78
+
79
+ def new_vm
80
+ Immunio.logger.debug "Creating new Lua VM"
81
+ dev_mode_hook_update if @dev_mode
82
+
83
+ @update_lock.synchronize {
84
+ return VM.new(@lua_vm, @functions, @utils, @data, @code_version, @data_version)
85
+ }
86
+ end
87
+
88
+ def dev_mode_hook_update
89
+ # Load default hook handlers if present (they do not ship with the gem)
90
+ path = File.expand_path("#{Immunio::DIR}/../lua-hooks/hooks")
91
+ Immunio.logger.info "Checking hook handlers from #{path}"
92
+
93
+ unique_files = Dir[path + "/*.lua"].collect do |file|
94
+ name = File.basename(file, ".*")
95
+
96
+ fstat = File.stat(file)
97
+ mtime = fstat.mtime
98
+ size = fstat.size
99
+
100
+ "-#{name}:#{mtime}:#{size}-"
101
+ end
102
+ checksum = unique_files.join
103
+ if checksum == @dev_checksum
104
+ Immunio.logger.info "Reusing dev vm, files unchanged"
105
+ return
106
+ end
107
+
108
+ functions = Dir[path + "/*.lua"].inject({}) do |handlers, file|
109
+ name = File.basename(file, ".*")
110
+
111
+ # NB: because this code is part of the creation of a VM
112
+ # calling any code that fires off a plugin could result
113
+ # in an infinite loop.
114
+ if File.respond_to? :read_without_immunio
115
+ data = File.read_without_immunio file
116
+ else
117
+ data = File.read file
118
+ end
119
+ handlers[name] = data
120
+ handlers
121
+ end
122
+ Immunio.logger.info "Updating dev vm code, files changed"
123
+ update_code("DEV-#{Time.now.strftime("%H:%M:%S")}", functions)
124
+ @dev_checksum = checksum
125
+ end
126
+
127
+ end
128
+
129
+ class LuaVM
130
+ # An internal LuaVM. Should not be used outside of this module.
131
+
132
+ # One Monitor for the class, which means while we can have more than one VM,
133
+ # we can't allow more than one to be called at a time. Unfortunate necessity
134
+ # because we can't tell which VM every rufus-lua method is called on.
135
+ @@monitor = Monitor.new
136
+
137
+ # For each class listed below, wrap every public method in a Monitor lock.
138
+ # This ensures we can be reentrant into Rufus from the same thread, but not
139
+ # from other threads. Big hack, but desperate times call for desperate
140
+ # measures.
141
+ classes = [
142
+ Rufus::Lua::Ref,
143
+ Rufus::Lua::Function,
144
+ Rufus::Lua::Coroutine,
145
+ Rufus::Lua::Table,
146
+ Rufus::Lua::State
147
+ ]
148
+ classes.each do |klass|
149
+ klass.public_instance_methods(false).each do |method|
150
+ # This is a metaprogramming way of using alias_method_chain because we
151
+ # must generate the method symbols on the fly.
152
+ with_symbol = "#{method}_with_lock".to_sym
153
+ without_symbol = "#{method}_without_lock".to_sym
154
+
155
+ klass.send(:define_method, with_symbol) do |*args|
156
+ @@monitor.synchronize do
157
+ self.send(without_symbol, *args)
158
+ end
159
+ end
160
+
161
+ klass.send(:alias_method, without_symbol, method)
162
+ klass.send(:alias_method, method, with_symbol)
163
+ end
164
+ end
165
+
166
+ def initialize(key, secret, dev_mode = false, debug_mode = false)
167
+ @state = Rufus::Lua::State.new
168
+
169
+ # Bootstrap the VM ...
170
+
171
+ # Define load path for `require`.
172
+ lua_hooks = File.expand_path("#{Immunio::DIR}/../lua-hooks")
173
+ @state['package.path'] = lua_hooks + "/lib/?.lua;" + lua_hooks + "/lib/lexers/?.lua"
174
+ # Set the config key
175
+ @state['IMMUNIO_KEY'] = key
176
+ # Set the secret key
177
+ @state['IMMUNIO_SECRET'] = secret
178
+ # Pass dev mode option
179
+ @state['DEV_MODE'] = dev_mode
180
+ # Pass debug mode option
181
+ @state['DEBUG_MODE'] = debug_mode
182
+ # Pass platform to the vm.
183
+ # From: http://stackoverflow.com/questions/170956/how-can-i-find-which-operating-system-my-ruby-program-is-running-on
184
+ if (/cygwin|mswin|mingw|bccwin|wince|emx|windows/ =~ RUBY_PLATFORM) != nil then
185
+ @state['LUA_PLATFORM'] = 'windows'
186
+ elsif (/darwin/ =~ RUBY_PLATFORM) != nil
187
+ @state['LUA_PLATFORM'] = 'darwin'
188
+ else
189
+ @state['LUA_PLATFORM'] = 'unix'
190
+ end
191
+ # Boot it. Yeaaaaah!
192
+ @state.eval "require 'boot'"
193
+
194
+ @error_handler = @state["debug.traceback"]
195
+ @call_function = @state['sandboxed_call']
196
+
197
+ self.class.check_rufus_stack @state, "Stack not empty after bootstrap"
198
+ end
199
+
200
+ # Create a function wrapping some Lua code or base64-encoded bytecode.
201
+ def create_function(code, name=nil)
202
+ lua_call do
203
+ @state.load code, name
204
+ end
205
+ end
206
+
207
+ def create_object(object)
208
+ return object if object.is_a?(Rufus::Lua::Ref)
209
+
210
+ lua_call do
211
+ @state.eval "return #{Rufus::Lua.to_lua_s(object)}"
212
+ end
213
+ end
214
+
215
+ def self.check_rufus_stack(state, message)
216
+ top = state.send(:stack_top)
217
+ if top != 0
218
+ raise VMError, "#{message} (#{top})"
219
+ end
220
+ end
221
+
222
+ # Wrap calls to Lua VM.
223
+ def lua_call
224
+ @@monitor.synchronize { yield }
225
+ rescue Rufus::Lua::LuaError => e
226
+ raise VMError, e.message, e.backtrace
227
+ end
228
+
229
+ def call(code, vars = nil)
230
+ lua_call do
231
+ # Setup the error handler
232
+ @error_handler.load_onto_stack
233
+ @call_function.error_handler = @call_function.send :stack_top
234
+
235
+ # For the VM heavy thread test, we need to cause out-of-order execution
236
+ # in methods modifying the Lua stack. Here we tell Ruby to swap out
237
+ # threads if we are in the thread test.
238
+ Thread.pass if $IMMUNIO_IN_THREAD_TEST
239
+
240
+ ret = @call_function.call code, vars
241
+ @state.send :stack_pop # Pop the error handler
242
+ Array === ret ? ret.first : ret
243
+ end
244
+ end
245
+
246
+ # Call a Lua function by name, outside of the sandbox.
247
+ def unsafe_call_by_name(name, *args)
248
+ lua_call do
249
+ @state[name].call(*args)
250
+ end
251
+ end
252
+ end
253
+
254
+ class VM
255
+ attr_reader :code_version, :data_version
256
+
257
+ def initialize(lua_vm, functions, utils, data, code_version, data_version)
258
+ @lua_vm = lua_vm
259
+ @functions = functions
260
+ @utils = utils
261
+ @data = data
262
+ @code_version = code_version
263
+ @data_version = data_version
264
+ end
265
+
266
+ def call(function_name, vars=nil)
267
+ if has_function? function_name
268
+ vars ||= {}
269
+ expanded_vars = vars.merge(
270
+ {
271
+ "serverdata" => @data,
272
+ "utils" => @utils
273
+ })
274
+
275
+ @lua_vm.call @functions[function_name], expanded_vars
276
+ end
277
+ end
278
+
279
+ def unsafe_call_by_name(name, *args)
280
+ @lua_vm.unsafe_call_by_name name, *args
281
+ end
282
+
283
+ def has_function?(function_name)
284
+ @functions.has_key? function_name
285
+ end
286
+
287
+ def create_object(object)
288
+ @lua_vm.create_object(object)
289
+ end
290
+ end
291
+ end
@@ -0,0 +1,78 @@
1
+ /*
2
+ * Based on Lua's all.c -- Lua core & libraries in a single file.
3
+ */
4
+
5
+ #define luaall_c
6
+
7
+ #define LUA_USE_POSIX
8
+
9
+ #include "lua/lapi.c"
10
+ #include "lua/lcode.c"
11
+ #include "lua/ldebug.c"
12
+ #include "lua/ldo.c"
13
+ #include "lua/ldump.c"
14
+ #include "lua/lfunc.c"
15
+ #include "lua/lgc.c"
16
+ #include "lua/llex.c"
17
+ #include "lua/lmem.c"
18
+ #include "lua/lobject.c"
19
+ #include "lua/lopcodes.c"
20
+ #include "lua/lparser.c"
21
+ #include "lua/lstate.c"
22
+ #include "lua/lstring.c"
23
+ #include "lua/ltable.c"
24
+ #include "lua/ltm.c"
25
+ #include "lua/lundump.c"
26
+ #include "lua/lvm.c"
27
+ #include "lua/lzio.c"
28
+
29
+ #include "lua/lauxlib.c"
30
+ #include "lua/lbaselib.c"
31
+ #include "lua/ldblib.c"
32
+ #include "lua/liolib.c"
33
+ #include "lua/lmathlib.c"
34
+ #include "lua/loadlib.c"
35
+ #include "lua/loslib.c"
36
+ #include "lua/lstrlib.c"
37
+ #include "lua/ltablib.c"
38
+
39
+ // Include our custom modules
40
+ #include "bitop/bit.c"
41
+ #include "libinjection/lualib.c"
42
+ #include "luautf8/lutf8lib.c"
43
+ #include "lpeg/lptree.c"
44
+ #include "lua-cmsgpack/lua_cmsgpack.c"
45
+ #include "lua-snapshot/snapshot.c"
46
+
47
+ // Activate the Lua modules we need and our custom ones.
48
+ static const luaL_Reg lualibs[] = {
49
+ {"", luaopen_base},
50
+ {LUA_TABLIBNAME, luaopen_table},
51
+ {LUA_STRLIBNAME, luaopen_string},
52
+ {LUA_MATHLIBNAME, luaopen_math},
53
+
54
+ // Include unsafe libs in tests
55
+ #if defined(LUA_UNSAFE_MODE)
56
+ {LUA_IOLIBNAME, luaopen_io},
57
+ {LUA_OSLIBNAME, luaopen_os},
58
+ #endif
59
+
60
+ // SECURITY NOTE:
61
+ // The following modules are unsafe according to http://lua-users.org/wiki/SandBoxes.
62
+ // They are loaded, but never exposed to the sandbox used to run the hook handlers.
63
+ // See lib/boot.lua for more details.
64
+ {LUA_LOADLIBNAME, luaopen_package},
65
+ {LUA_DBLIBNAME, luaopen_debug},
66
+
67
+ // Our custom modules
68
+ {"libinjection", luaopen_libinjection},
69
+ {"utf8", luaopen_utf8},
70
+ {"bit", luaopen_bit},
71
+ {"lpeg", luaopen_lpeg},
72
+ {LUACMSGPACK_NAME, luaopen_cmsgpack},
73
+ {"snapshot", luaopen_snapshot},
74
+ {NULL, NULL}
75
+ };
76
+ // The previous array replaces the one in linit.c.
77
+ // If you update Lua, make sure to comment the lualibs declaration in the following file.
78
+ #include "lua/linit.c"
@@ -0,0 +1,22 @@
1
+ README for Lua BitOp 1.0.2
2
+ --------------------------
3
+
4
+ Lua BitOp is a C extension module for Lua 5.1/5.2 which adds
5
+ bitwise operations on numbers.
6
+
7
+ Homepage: http://bitop.luajit.org/
8
+
9
+ Lua BitOp is Copyright (C) 2008-2012 Mike Pall.
10
+ Lua BitOp is free software, released under the MIT license.
11
+
12
+ --------------------------
13
+
14
+ Full documentation for Lua BitOp is available in HTML format.
15
+ Please point your favourite browser to:
16
+
17
+ doc/index.html
18
+
19
+ Detailed installation instructions are here:
20
+
21
+ doc/install.html
22
+
@@ -0,0 +1,189 @@
1
+ /*
2
+ ** Lua BitOp -- a bit operations library for Lua 5.1/5.2.
3
+ ** http://bitop.luajit.org/
4
+ **
5
+ ** Copyright (C) 2008-2012 Mike Pall. All rights reserved.
6
+ **
7
+ ** Permission is hereby granted, free of charge, to any person obtaining
8
+ ** a copy of this software and associated documentation files (the
9
+ ** "Software"), to deal in the Software without restriction, including
10
+ ** without limitation the rights to use, copy, modify, merge, publish,
11
+ ** distribute, sublicense, and/or sell copies of the Software, and to
12
+ ** permit persons to whom the Software is furnished to do so, subject to
13
+ ** the following conditions:
14
+ **
15
+ ** The above copyright notice and this permission notice shall be
16
+ ** included in all copies or substantial portions of the Software.
17
+ **
18
+ ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21
+ ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22
+ ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23
+ ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24
+ ** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
+ **
26
+ ** [ MIT license: http://www.opensource.org/licenses/mit-license.php ]
27
+ */
28
+
29
+ #define LUA_BITOP_VERSION "1.0.2"
30
+
31
+ #define LUA_LIB
32
+ #include "lua/lua.h"
33
+ #include "lua/lauxlib.h"
34
+
35
+ #ifdef _MSC_VER
36
+ /* MSVC is stuck in the last century and doesn't have C99's stdint.h. */
37
+ typedef __int32 int32_t;
38
+ typedef unsigned __int32 uint32_t;
39
+ typedef unsigned __int64 uint64_t;
40
+ #else
41
+ #include <stdint.h>
42
+ #endif
43
+
44
+ typedef int32_t SBits;
45
+ typedef uint32_t UBits;
46
+
47
+ typedef union {
48
+ lua_Number n;
49
+ #ifdef LUA_NUMBER_DOUBLE
50
+ uint64_t b;
51
+ #else
52
+ UBits b;
53
+ #endif
54
+ } BitNum;
55
+
56
+ /* Convert argument to bit type. */
57
+ static UBits barg(lua_State *L, int idx)
58
+ {
59
+ BitNum bn;
60
+ UBits b;
61
+ #if LUA_VERSION_NUM < 502
62
+ bn.n = lua_tonumber(L, idx);
63
+ #else
64
+ bn.n = luaL_checknumber(L, idx);
65
+ #endif
66
+ #if defined(LUA_NUMBER_DOUBLE)
67
+ bn.n += 6755399441055744.0; /* 2^52+2^51 */
68
+ #ifdef SWAPPED_DOUBLE
69
+ b = (UBits)(bn.b >> 32);
70
+ #else
71
+ b = (UBits)bn.b;
72
+ #endif
73
+ #elif defined(LUA_NUMBER_INT) || defined(LUA_NUMBER_LONG) || \
74
+ defined(LUA_NUMBER_LONGLONG) || defined(LUA_NUMBER_LONG_LONG) || \
75
+ defined(LUA_NUMBER_LLONG)
76
+ if (sizeof(UBits) == sizeof(lua_Number))
77
+ b = bn.b;
78
+ else
79
+ b = (UBits)(SBits)bn.n;
80
+ #elif defined(LUA_NUMBER_FLOAT)
81
+ #error "A 'float' lua_Number type is incompatible with this library"
82
+ #else
83
+ #error "Unknown number type, check LUA_NUMBER_* in luaconf.h"
84
+ #endif
85
+ #if LUA_VERSION_NUM < 502
86
+ if (b == 0 && !lua_isnumber(L, idx)) {
87
+ luaL_typerror(L, idx, "number");
88
+ }
89
+ #endif
90
+ return b;
91
+ }
92
+
93
+ /* Return bit type. */
94
+ #define BRET(b) lua_pushnumber(L, (lua_Number)(SBits)(b)); return 1;
95
+
96
+ static int bit_tobit(lua_State *L) { BRET(barg(L, 1)) }
97
+ static int bit_bnot(lua_State *L) { BRET(~barg(L, 1)) }
98
+
99
+ #define BIT_OP(func, opr) \
100
+ static int func(lua_State *L) { int i; UBits b = barg(L, 1); \
101
+ for (i = lua_gettop(L); i > 1; i--) b opr barg(L, i); BRET(b) }
102
+ BIT_OP(bit_band, &=)
103
+ BIT_OP(bit_bor, |=)
104
+ BIT_OP(bit_bxor, ^=)
105
+
106
+ #define bshl(b, n) (b << n)
107
+ #define bshr(b, n) (b >> n)
108
+ #define bsar(b, n) ((SBits)b >> n)
109
+ #define brol(b, n) ((b << n) | (b >> (32-n)))
110
+ #define bror(b, n) ((b << (32-n)) | (b >> n))
111
+ #define BIT_SH(func, fn) \
112
+ static int func(lua_State *L) { \
113
+ UBits b = barg(L, 1); UBits n = barg(L, 2) & 31; BRET(fn(b, n)) }
114
+ BIT_SH(bit_lshift, bshl)
115
+ BIT_SH(bit_rshift, bshr)
116
+ BIT_SH(bit_arshift, bsar)
117
+ BIT_SH(bit_rol, brol)
118
+ BIT_SH(bit_ror, bror)
119
+
120
+ static int bit_bswap(lua_State *L)
121
+ {
122
+ UBits b = barg(L, 1);
123
+ b = (b >> 24) | ((b >> 8) & 0xff00) | ((b & 0xff00) << 8) | (b << 24);
124
+ BRET(b)
125
+ }
126
+
127
+ static int bit_tohex(lua_State *L)
128
+ {
129
+ UBits b = barg(L, 1);
130
+ SBits n = lua_isnone(L, 2) ? 8 : (SBits)barg(L, 2);
131
+ const char *hexdigits = "0123456789abcdef";
132
+ char buf[8];
133
+ int i;
134
+ if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; }
135
+ if (n > 8) n = 8;
136
+ for (i = (int)n; --i >= 0; ) { buf[i] = hexdigits[b & 15]; b >>= 4; }
137
+ lua_pushlstring(L, buf, (size_t)n);
138
+ return 1;
139
+ }
140
+
141
+ static const struct luaL_Reg bit_funcs[] = {
142
+ { "tobit", bit_tobit },
143
+ { "bnot", bit_bnot },
144
+ { "band", bit_band },
145
+ { "bor", bit_bor },
146
+ { "bxor", bit_bxor },
147
+ { "lshift", bit_lshift },
148
+ { "rshift", bit_rshift },
149
+ { "arshift", bit_arshift },
150
+ { "rol", bit_rol },
151
+ { "ror", bit_ror },
152
+ { "bswap", bit_bswap },
153
+ { "tohex", bit_tohex },
154
+ { NULL, NULL }
155
+ };
156
+
157
+ /* Signed right-shifts are implementation-defined per C89/C99.
158
+ ** But the de facto standard are arithmetic right-shifts on two's
159
+ ** complement CPUs. This behaviour is required here, so test for it.
160
+ */
161
+ #define BAD_SAR (bsar(-8, 2) != (SBits)-2)
162
+
163
+ LUALIB_API int luaopen_bit(lua_State *L)
164
+ {
165
+ UBits b;
166
+ lua_pushnumber(L, (lua_Number)1437217655L);
167
+ b = barg(L, -1);
168
+ if (b != (UBits)1437217655L || BAD_SAR) { /* Perform a simple self-test. */
169
+ const char *msg = "compiled with incompatible luaconf.h";
170
+ #ifdef LUA_NUMBER_DOUBLE
171
+ #ifdef _WIN32
172
+ if (b == (UBits)1610612736L)
173
+ msg = "use D3DCREATE_FPU_PRESERVE with DirectX";
174
+ #endif
175
+ if (b == (UBits)1127743488L)
176
+ msg = "not compiled with SWAPPED_DOUBLE";
177
+ #endif
178
+ if (BAD_SAR)
179
+ msg = "arithmetic right-shift broken";
180
+ luaL_error(L, "bit library self-test failed (%s)", msg);
181
+ }
182
+ #if LUA_VERSION_NUM < 502
183
+ luaL_register(L, "bit", bit_funcs);
184
+ #else
185
+ luaL_newlib(L, bit_funcs);
186
+ #endif
187
+ return 1;
188
+ }
189
+