-
-
Notifications
You must be signed in to change notification settings - Fork 64
Execute
This section explains how to invoke the Zenroom to execute scripts in various situations: from commandline, from javascript and various other languages.
Javascript has its own way to call zenroom_exec(...)
without losing all the context for execution.
Other languages are recommended to exec()
the Zenroom in a separate process and gather its stdout
and its return value (1 on error and 0 on success).
From command-line the Zenroom is operated passing files as arguments:
Usage: zenroom [-dh] [-c config] [-k KEYS] [-a DATA] [ SCRIPT.lua | - ]
The -d
flag activates more verbose output for debugging.
The SCRIPT.lua
can be the path to a script or a single dash (-
) to instruct zenroom to process the script piped from stdin
.
Just executing zenroom
will open an interactive console with limited functionalities, which is capable to parse finite instruction blocks on each line. To facilitate editing of lines is possible to prefix it with readline using the rlwrap zenroom
command instead.
The content of the KEYS, DATA and SCRIPT files cannot exceed 500KB.
Try:
./zenroom-static [enter]
print("Hello World!") [enter]
[Ctrl-D] to quit
Will print Zenroom's execution details on stderr
and the "Hello World!" string on stdout
.
Zenroom also supports being used as an "hashbang" interpreter at the beginning of executable scripts. Just use:
#!/usr/bin/env zenroom-static -
in the header, please note the final dash which is pretty important to tell zenroom to process the script from stdin
.
For javascript 🎉 now a npm module is available on https://www.npmjs.com/package/zenroom
From javascript the function zenroom_exec()
is exposed with four arguments: four strings and one number from 1 to 3 indicating the verbosity of output on the console.
This is the prototype of the javascript function:
const zenroom = (script_file, conf_file=null, keys_file=null,
data_file=null, verbosity=3)
Only the script_file
argument is mandatory, other arguments can be omitted, then defaults are used. For example after a make js
build we can invoke the zenroom in src/zenroom.js
creating such a script:
const fs = require('fs')
const zenroom_module = require(process.argv[2])
const zenroom = (script_file, conf_file=null, keys_file=null,
data_file=null, verbosity=3) => {
const enc = { encoding: 'utf8' }
const script = fs.readFileSync(script_file, enc)
const conf = (conf_file) ? fs.readFileSync(conf_file, env) : null
const keys = (keys_file) ? fs.readFileSync(keys_file, env) : null
const data = (data_file) ? fs.readFileSync(data_file, env) : null
return zenroom_module.ccall('zenroom_exec', 'number',
['string', 'string', 'string', 'string', 'number'],
[script, conf, keys, data, verbosity])
}
console.log("[JS] zenroom_exec %s %s", process.argv[2], process.argv[3])
zenroom(process.argv[3])
If the above script is saved in zenroom_exec.js
then on the commandline it can be invoked with the path to zenroom.js
as first parameter and the path to a script as second parameter:
nodejs src/zenroom.js zenroom_exec.js examples/hello.lua
The contents of the three strings cannot exceed 500KB in size.
The data
is a simple string, but can be also a json map used to pass multiple arguments and complex data structures. Its contents can be accessed by the script
using the global variable DATA
(all uppercase).
For example create a json file containing a map (this can be a string passed from javascript)
{
"secret": "zen and the art of programming",
"salt": "OU9Qxl3xfClMeiCz"
}
Then run zenroon -a arguments.json
and pass the following script as
final argument, or pipe from stdin or passed as a string argument to
zenroom_exec()
from javascript:
i = require "inspect"
json = require "json"
args = json.decode(DATA)
-- args is now a lua table containing values for each args.argname
i.print(args)
The keys
is also a simple string passed from arguments, separated from DATA since its access permission from caller may be different due to specific privacy restrinctions that may be adopted on the variable. It is accessed by the script
using the global variable KEYS
.
So for instance if we want to encrypt a secret message for multiple recipients who have provided us with their public keys, one would load this example keyfile:
{
"keyring": {
"public":"GoTdVYbTWEoZ4KtCeMghV7UcpJyhvny1QjVPf8K4oi1i",
"secret":"9PSbkNgsbgPnX3hM19MHVMpp2mzvmHcXCcz6iV8r7RyZ"
},
"recipients": {
"jaromil": "A1g6CwFobiMEq6uj4kPxfouLw1Vxk4utZ2W5z17dnNkv",
"francesca": "CQ9DE4E5Ag2e71dUW2STYbwseLLnmY1F9pR85gLWkEC6",
"jimb": "FNUdjaPchQsxSjzSbPsMNVPA2v1XUhNPazStSRmVcTwu",
"mark": "9zxrLG7kwheF3FMa852r3bZ4NEmowYhxdTj3kVfoipPV",
"paulus": "2LbUdFSu9mkvtVE6GuvtJxiFnUWBWdYjK2Snq4VhnzpB",
"mayo": "5LrSGTwmnBFvm3MekxSxE9KWVENdSPtcmx3RZbktRiXc"
}
}
And then with this code encrypt a message to all recipients:
secret="this is a secret that noone knows"
-- this should be a random string every time
nonce="eishai7Queequot7pooc3eiC7Ohthoh1"
json = require "json"
crypto = require "crypto"
keys = json.decode(KEYS)
res = {}
for name,pubkey in pairs(keys.recipients) do
k = crypto.exchange_session_x25519(
crypto.decode_b58(keys.keyring.secret),
crypto.decode_b58(pubkey))
enc = crypto.encrypt_norx(k,nonce,secret)
-- insert in results
res[name]=crypto.encode_b58(enc)
end
print(json.encode(res))
The above script will print out the encrypted message for each recipient reorganised in a similar json structure:
{
"jaromil" : "Ha8185xZoiMiJhfquKRHvtT6vZPWifGaXmD4gxjyfHV9ASNaJF2Xq85NCmeyy4hWLGns4MTbPsRmZ2H7uJh9vEuWt",
"mark" : "13nhCBWKbPAYyhJXD7aeHtiFKb89fycBnoKy2nosJdSqfS2vhhHqBvVKb2oasiga9P3UyaEJZQdyYRfiBBKEswdmQ",
"francesca" : "7ro9u2ViXjp3AaLzvve4E4ebZNoBPLtxAja8wd8YNn51TD9LjMXNGsRvm85UQ2vmhdTeJuvcmBvz5WuFkdgh3kQxH",
"mayo" : "FAjQSYXZdZz3KRuw1MX4aLSjky6kbpRdXdAzhx1YeQxu3JiGDD7GUFK2rhbUfD3i5cEc3tU1RBpoK5NCoWbf2reZc",
"jimb" : "7gb5SLYieoFsP4jYfaPM46Vm4XUP2jbCUnkFRQfwNrnJfqaew5VpwqjbNbLJrqGsgJJ995bP2867nYLcn96wuMDMw",
"paulus" : "8SGBpRjZ21pgYZhXmy7uWGNEEN7wnHkrWtHEKeh7uCJgsDKtoGZHPk29itCV6oRxPbbiWEuN9Sm83jeZ1vinwQyXM"
}
Zenroom is Copyright (C) 2017-2019 by the Dyne.org foundation.
The wiki documentation includes content taken from different Lua extensions, see AUTHORS for details.