home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / sbin / ekeydctl < prev    next >
Encoding:
Lua script  |  2011-08-10  |  5.9 KB  |  243 lines

  1. #!/usr/bin/env lua5.1
  2. -- -*- Lua -*-
  3.  
  4. require "socket"
  5.  
  6. -- Try to load the UNIX domain sockets support
  7. pcall(function()
  8.      require "socket.unix"
  9.       end)
  10.  
  11.  
  12. function usage()
  13.    io.stderr:write((([[
  14. %1%: Control the entropy daemon.
  15. Usage: %1% <command> [args...]
  16.  
  17. Where command is one of:
  18.     add        Add an entropy key (dev node provided as argument).
  19.     addall      Add a directory full of keys (dir name provided as argument).
  20.     remove    Remove an entropy key (One of dev node, serial, ID as argument).
  21.     list    List all the entropy keys attached to the daemon.
  22.     stats    Show the statistics for an entropy key (One of dev node, 
  23.                   serial, ID as argument).
  24.     keyring    Load a keyring (keyring filename provided as argument)
  25.     shutdown    Shut the entropy key daemon down.
  26. ]]):gsub("%%(%d+)%%", function(n) return ({arg[0]})[tonumber(n)] end)))
  27. end
  28.  
  29. -- Utility functions
  30.  
  31. do
  32.    local strfind = string.find
  33.    local strlen = string.len
  34.    local tinsert = table.insert
  35.    local strsub = string.sub
  36.  
  37. function split(s, b, c)
  38. --[[
  39.    Return the elements of a delimited string.
  40.  
  41.    Split string \s on boundary \b and return the list of components.
  42.  
  43.    @param s(string) The string to split up
  44.    @param b(string) The boundary to split on
  45.    @param c(boolean) Correctness. If true, splitting '' returns {''}
  46.    @return bits(table) The bits of \s split up on \b
  47. ]]
  48.    local t = {}
  49.    b = b or " "
  50.    local p = strfind(s, b, 1, 1)
  51.    local l = strlen(b)
  52.    
  53.    if (not p) then
  54.       if( s ~= "" or c ) then
  55.          return { s }
  56.       else
  57.          return {}
  58.       end
  59.    end
  60.    
  61.    while strlen(s) ~= 0 do
  62.       p = strfind(s, b, 1, 1)
  63.       if (p) then
  64.          tinsert(t, strsub(s, 1, p - 1))
  65.          s = strsub(s, p + l, -1)
  66.       else
  67.          tinsert(t, s)
  68.          s = ""
  69.       end
  70.    end
  71.    
  72.    return t
  73. end
  74. end
  75.  
  76.  
  77. -- Connectivity
  78.  
  79. local __tcpcontrolport, __unixcontrolpath = nil, nil
  80. local __socket
  81.  
  82. function wait_for(pattern)
  83.    -- Read lines from the socket (max 3s pause) until we hit pattern.
  84.    -- Return a table of all the lines, incl. the one which matches.
  85.    -- On timeout, simply report the error and exit.
  86.    local rett = {}
  87.    local lastline
  88.    repeat
  89.       lastline = assert(__socket:receive())
  90.       rett[#rett + 1] = lastline
  91.       if string.match(lastline, "^ERROR") then
  92.      io.stderr:write(lastline .. "\n")
  93.      os.exit(4)
  94.       end
  95.    until string.match(lastline, pattern)
  96.    return rett
  97. end
  98.  
  99. function connect_to_daemon()
  100.    if __unixcontrolpath then
  101.       __socket = socket.unix()
  102.       local result, msg = __socket:connect(__unixcontrolpath)
  103.       if not result then
  104.      error("Unable to connect to ekeyd at " .. __unixcontrolpath .. " (" .. msg .. ") Is ekeyd running?")
  105.       end
  106.    elseif __tcpcontrolport then
  107.       __socket = socket.tcp()
  108.       local result, msg = __socket:connect("127.0.0.1", tonumber(__tcpcontrolport))
  109.       if not result then
  110.      error("Unable to connect to ekeyd at 127.0.0.1:" .. tostring(__tcpcontrolport) .. " (" .. msg .. ") Is ekeyd running?")
  111.       end
  112.    else
  113.       io.stderr:write("Unable to find control socket\n")
  114.       os.exit(3)
  115.    end
  116.    __socket:settimeout(3)
  117.    wait_for("PROTOCOL EKEYD/%d+")
  118. end
  119.  
  120. function expectarg(argno, val, msg)
  121.    if val ~= nil then
  122.       return
  123.    end
  124.    io.stderr:write("Expected argument " .. tostring(argno) .. " missing: " .. msg .. "\n")
  125.    os.exit(6)
  126. end
  127.  
  128. -- Commands
  129.  
  130. function command_list()
  131.    __socket:send("ListEntropyKeys\n")
  132.    local res = wait_for("^OK$")
  133.    local splits = {}
  134.    for _, s in ipairs(res) do
  135.       splits[#splits+1] = split(s, "\t")
  136.       table.remove(splits[#splits], 1)
  137.    end
  138.    headers = table.remove(splits, 1)
  139.    table.remove(splits, table.getn(splits))
  140.    print(table.concat(headers, ","))
  141.    for _, ktab in ipairs(splits) do
  142.       print(table.concat(ktab, ","))
  143.    end
  144. end
  145.  
  146. function command_stats(node)
  147.    expectarg(1, node, "Entropy Key Identifier")
  148.    __socket:send("StatEntropyKey(" .. string.format("%q", node) .. ")\n")
  149.    local res = wait_for("^OK$")
  150.    res[#res] = nil
  151.    table.sort(res)
  152.    for i, v in ipairs(res) do
  153.       v = split(v, "\t")[2]
  154.       print(v)
  155.    end
  156. end
  157.  
  158. function command_add(node, optserial)
  159.    expectarg(1, node, "Path to Entropy Key")
  160.    if optseral == nil then
  161.       optserial = "nil"
  162.    else
  163.       optserial=string.format("%q", optserial)
  164.    end
  165.    __socket:send("AddEntropyKey(" .. string.format("%q", node) .. "," .. optserial .. ")\n")
  166.    wait_for("^OK")
  167. end
  168.  
  169. function command_remove(node)
  170.    expectarg(1, node, "Entropy Key Identifier")
  171.    __socket:send("RemoveEntropyKey(" .. string.format("%q", node) .. ")\n")
  172.    wait_for("^OK")
  173. end
  174.  
  175. function command_addall(dir)
  176.    expectarg(1, dir, "Path to directory of Entropy Keys")
  177.    __socket:send("AddEntropyKeys(" .. string.format("%q", dir) .. ")\n")
  178.    wait_for("^OK")
  179. end
  180.  
  181. function command_keyring(keyring)
  182.    expectarg(1, keyring, "Path to keyring file to load")
  183.    __socket:send("Keyring(" .. string.format("%q", keyring) .. ")\n")
  184.    wait_for("^OK")
  185. end
  186.  
  187. function command_shutdown()
  188.    __socket:send("Shutdown\n")
  189. end
  190.  
  191. if #arg < 1 then
  192.    usage()
  193.    os.exit(1)
  194. end
  195.  
  196. command = arg[1]
  197.  
  198. cmd = _G["command_" .. command]
  199.  
  200. cmdargs = {}
  201. k = 2
  202. while arg[k] do
  203.    cmdargs[k - 1] = arg[k]
  204.    k = k + 1
  205. end
  206.  
  207. if (cmd == nil) then
  208.    io.stderr:write("Unknown command: " .. command .. "\n")
  209.    usage()
  210.    os.exit(2)
  211. end
  212.  
  213. -- These functions are to emulate the config file of ekeyd
  214. function SetOutputToKernel() end
  215. function AddEntropyKeys() end
  216. function AddEntropyKey() end
  217. function Keyring() end
  218. function SetOutputToFile() end
  219. function TCPControlSocket(port)
  220.    __tcpcontrolport = port
  221. end
  222. function UnixControlSocket(path)
  223.    __unixcontrolpath = path
  224. end
  225. function EGDUnixSocket() end
  226. function EGDTCPSocket() end
  227. function Daemonise() end
  228.  
  229. assert(loadfile"/etc/entropykey/ekeyd.conf")()
  230.  
  231. function do_it()
  232.    connect_to_daemon()
  233.    os.exit(cmd(unpack(cmdargs)) or 0)
  234. end
  235.  
  236. _, msg = xpcall(do_it, function(s) return s end)
  237.  
  238. -- If we reach here, do_it had an error.
  239.  
  240. io.stderr:write("Internal error: " .. msg .. "\n")
  241.  
  242. os.exit(5)
  243.