Thrift Example in Lua - lua

Where can I find an example of how to load a Thrift file in lua?
My code so far is below. I can't figure out how to create memory buffer. It fails at TMemoryBuffer:new()
local fullpath = FullPath("ConfigData.bin")
local infile = io.open(fullpath, "rb")
local buffer = infile:read("*all")
local transport1 = TMemoryBuffer:new()
transport1:resetBuffer(buffer)
local transport = TFramedTransportFactory:getTransport(transport1) local protocol = TBinaryProtocolFactory:getProtocol(transport)
flux.assert(protocol)
Data:read(protocol)

Here is a working example:
local fullpath = FullPath("ConfigData.bin")
local infile = io.open(fullpath, "rb")
local buffer = infile:read("*all")
TMemoryBuffer:resetBuffer(buffer)
local protocol = TBinaryProtocolFactory:getProtocol(TMemoryBuffer)
Data:read(protocol)

Related

OpenSSL - as alternative to Lua encdec.hmacsha256()

I’m trying to re-platform a Lua script that uses modules I can’t find. The one I’m stuck on is encdec.hmacsha256() which is used in this specific command sig = encdec.hmacsha256(ciphertext, hmac_key, true)
I’m looking to use openSSL instead in order to create the signature, but I’ve been unable to successfully construct the required command line. Please could someone help?
(FYI - I’m a newbie when it comes to encryption and ciphers etc.)
Here is the Lua code where it fits in..
local hmac_key = createHMACKey()
print ("Returned hmac_key = " ..hmac_key)
local hmac_key_HEX = binascii.hexlify(hmac_key)
print ("Returned hmac_key_HEX = " ..hmac_key_HEX)
--------------------------------
--orig = local sig = encdec.hmacsha256(ciphertext, hmac_key, true)
local opensslHMAC256command = "openssl sha256 -hex -mac HMAC -macopt hexkey:" ..ciphertext..hmac_key
local command = assert(io.popen(opensslHMAC256command, 'r'))
local output = command:read('*all')
command:close()
print("opensslHMAC256command in = " ..output)
local file = "etc/encryptedpayload1.txt"
local outf = io.open(file, "w")
outf:write(payload)
outf:close()
local file = "etc/encryptedpayload2.txt"
local outf = io.open(file, "r")
local encreading = outf:read("*all")
print("opensslHMAC256command out = " ..encreading)
outf:close()
local sig = encreading
print("sig = " ..sig)
You can replace
local sig = encdec.hmacsha256(ciphertext, hmac_key, true)
with
local sha = require("sha2")
local sig = sha.hex_to_bin(sha.hmac(sha.sha256, hmac_key, ciphertext))
The library is here
In my particular situation, we had to alter the require sha2 module and the associated local call, (adding a .z = option) so the function could be requested correctly
local sha = require("sha2").z
local sig = sha.hex_to_bin(sha.hmac(sha.sha256, hmac_key, ciphertext))

Lua Script in suricata to detect the change in file

I am new in lua programming. I was looking for a lua script that can read the file being downloaded through Suricata from the internet and detect if file is changed. Any help would be appreciated. Thanks in advance.
Something like this:
function init(args)
return {http.response_body = tostring(true)}
end
local function read_file(path)
local file = open(path, "rb") -- r read mode and b binary mode
if not file then return nil end
local content = file:read "*a" -- *a or *all reads the whole file
file:close()
return content
end
local fileContent = read_file(path-to-where-previous-file-is-stored);
local fileContent2 = read_file(init());
if fileContent != fileContent2:
print("File changed")
and block if contents are same
drop http any any -> any any (msg:"NVISO PDF file lua"; flow:established,to_client; luajit:pdfcheckname.lua; classtype:policy-violation; sid:1000000; rev:1;)
Unless you have some other open function that is now shown in your snippet local file = open(path, "rb") should be replaced with local file = io.open(path, "rb")
local fileContent2 = read_file(init()); will cause problems as init() will return a table, not a path string. This will cause an error when calling io.open
if fileContent != fileContent2:
print("File changed")
is syntactically incorrect.
Replace it with
if fileContent != fileContent2 then
print("File Changed")
end
Also a name like file2Content would make more sense as it is not the second content of file but the content of file 2. But that's just my personal opinion.

Lua LGI unpack GLib.Variant object

I'm trying to get password from keyring for awesome-wm session (using DBus via lgi library).
I'm able to find keyring entry path, open communication session and unlock entry.
Then I call GetSecrets method and store result into secret variable.
According to the documentation it is supposed to be a struct Secret. Seems like lgi cannot handle this type and passes it as userdata type (at least I wasn't able to make it give access to struct fields). Is there a way to get struct Secret value field contents without writing custom C handler?
Here is the code:
local bus = Gio.bus_get_sync(Gio.BusType.SESSION, nil)
local attr = {}
attr[1] = {attribute = "value"} -- attribute-value pair to search for
-- search for secret path
local name = "org.freedesktop.secrets"
local object = "/org/freedesktop/secrets"
local interface = "org.freedesktop.Secret.Service"
local method = "SearchItems"
local message = Gio.DBusMessage.new_method_call(name, object, interface, method)
message:set_body(GLib.Variant("(a{ss})", attr))
local result, err = bus:send_message_with_reply_sync(message, Gio.DBusSendMessageFlags.NONE,
-1, nil)
local location
for _, l in result:get_body():pairs() do
if #l > 0 then location = l[1] end
end
print(location) -- returns "/org/freedesktop/secrets/collection/Default/1"
-- open session
local name = "org.freedesktop.secrets"
local object = "/org/freedesktop/secrets"
local interface = "org.freedesktop.Secret.Service"
local method = "OpenSession"
local message = Gio.DBusMessage.new_method_call(name, object, interface, method)
message:set_body(GLib.Variant("(sv)", {"plain", GLib.Variant("s", "")}))
local result, err = bus:send_message_with_reply_sync(message, Gio.DBusSendMessageFlags.NONE,
-1, nil)
local session = result:get_body()[2]
print(session) -- returns "/org/freedesktop/secrets/session/s4"
-- unlock key
local name = "org.freedesktop.secrets"
local object = "/org/freedesktop/secrets"
local interface = "org.freedesktop.Secret.Service"
local method = "Unlock"
local message = Gio.DBusMessage.new_method_call(name, object, interface, method)
message:set_body(GLib.Variant("(ao)", {{location}}))
local result, err = bus:send_message_with_reply_sync(message, Gio.DBusSendMessageFlags.NONE,
-1, nil)
-- at this point key property "Locked" if false. tested using d-feet
-- get secret
local name = "org.freedesktop.secrets"
local object = "/org/freedesktop/secrets"
local interface = "org.freedesktop.Secret.Service"
local method = "GetSecrets"
local message = Gio.DBusMessage.new_method_call(name, object, interface, method)
message:set_body(GLib.Variant("(aoo)", {{location},session}))
local result, err = bus:send_message_with_reply_sync(message, Gio.DBusSendMessageFlags.NONE,
-1, nil)
local secret = result:get_body()
print(#secret) -- returns "1"
print(secret) -- returns table address
print(type(secret)) -- returns "userdata"
-- lock key
local name = "org.freedesktop.secrets"
local object = "/org/freedesktop/secrets"
local interface = "org.freedesktop.Secret.Service"
local method = "Lock"
local message = Gio.DBusMessage.new_method_call(name, object, interface, method)
message:set_body(GLib.Variant("(ao)", {{location}}))
local result, err = bus:send_message_with_reply_sync(message, Gio.DBusSendMessageFlags.NONE,
-1, nil)
-- close session
local name = "org.freedesktop.secrets"
local object = location
local interface = "org.freedesktop.Secret.Session"
local method = "Close"
local message = Gio.DBusMessage.new_method_call(name, object, interface, method)
local result, err = bus:send_message_with_reply_sync(message, Gio.DBusSendMessageFlags.NONE,
-1, nil)
edit
When I do print(secret), lgi.rec 0x7f57d0014960:GLib.Variant is returned.
So, secret is an object. How can I retrieve value field from GLib.Variant object?
edit 2
secret:get_data_as_bytes():get_data() dumps struct in bytearray form; secret:print() returns formatted string of struct. I wonder if there's a better way.
edit 3
type of secret variable is (a{o(oayays)})
Code to recreate an object of that type:
local lgi = require 'lgi'
local Gio = lgi.require 'Gio'
local GLib = lgi.require 'GLib'
local var = GLib.Variant("(a{o(oayays)})", {{["/path/to/object"]={"/path/to/session","parameters","value","content_type"}}})
(Note that I didn't install this password manager or try any of this at all)
Last time I asked the author of LGI about such issue, the answer was:
I have submitted fix to Variant which restores this functionality. So
an example of use will be:
local function called_from_C(userdata)
local variant = GLib.Variant(userdata)
print(variant)
end
if you have to support older (well, released :) lgi versions, you can
use undocumented way:
local core = require 'lgi.core'
local function called_from_C(userdata)
local variant = core.record.new(GLib.Variant, userdata)
print(variant)
end
Note that there is other ways. To work around another such bugs, I also once created a C Lua plugin and just wrote that code in C. That's actually rather trivial with Lua [2].
Another way, if you use LuaJIT, is to use the built-in FFI to just-in-time compile the struct definition into a Lua object [1].
Finally, if the question is more about how to unpack "working" GVariant values once they are consumed properly by LGI, look at my code for this here https://github.com/Elv13/wirefu/blob/master/proxy.lua
[1] http://luajit.org/ext_ffi_api.html
[2] https://github.com/Elv13/lua_async_binding/blob/master/src/luabridge.c#L407
Finally I've found a solution. To unpack a value of a complex type, for example (a{o(oayays)}), one should use get_child_value function.
secret:get_child_value(0):get_child_value(0):get_child_value(1):get_child_value(2).value
Explanation: index tuple; index array; index dict; index tuple

Issues with LUA copy

I am using the following program to copy one file another. I am often seeing source and destination is not exactly the same (md5sum is different). Are there anything wrong with the below code?
local size = 2^13 -- good buffer size (8K)
local params = {...}
local srcfile = params[1]
local outfile = params[1] .. "_copy"
print (srcfile)
print (outfile)
local inf = io.open(srcfile, "r")
local of = io.open(outfile, "w")
while true do
local block = inf:read(size)
print(size)
if not block then break end
of:write(block)
end
inf:close()
of:close()
Thanks,
GL
You may want to use binary mode to ensure endline characters were not modified.
local inf = io.open(srcfile, "rb")
local of = io.open(outfile, "wb")

How to use strtok in luajit?

My code are as follow:
local ffi = require "ffi"
local ffi_C = ffi.C
local ffi_typeof = ffi.typeof
local ffi_new = ffi.new
local ffi_string = ffi.string
local NULL = ngx.null
local tostring = tostring
ffi.cdef[[
char * strtok(char * str, const char * delimiters);
]]
local p_char_type = ffi_typeof("char[?]")
function split(src, c)
local result = {}
local pch = ffi_new(p_char_type, 1)
local psrc = ffi_new(p_char_type, #src)
local pc = ffi_new(p_char_type, #c)
ffi.copy(psrc, src)
ffi.copy(pc, c)
pch = ffi_C.strtok(psrc, pc)
while pch do
table.insert(result, ffi_string(pch))
pch = ffi_C.strtok(NULL, pc)
ngx.log(ngx.ERR, "pch ok")
end
ngx.log(ngx.ERR, "split ok")
return result
end
When I run my nginx, there are something wrong happened!
After return by the while loop, the nginx worker process crashed with signal 11.
The last ngx.log can not run.
How can I deal with it?
local psrc = ffi_new(p_char_type, #src)
ffi.copy(psrc, src)
ffi.copy when given a string source also copies a null terminator, but your array is too small to hold it, resulting an overflow.
Also, instead of using strtok, consider using Lua patterns. They are safer, easier to use, and don't depend on the FFI.

Resources