admin.lua 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. -- Cjdns admin module for Lua
  2. -- Written by Philip Horger
  3. common = require 'cjdns/common'
  4. AdminInterface = {}
  5. AdminInterface.__index = AdminInterface
  6. common.AdminInterface = AdminInterface
  7. function AdminInterface.new(properties)
  8. properties = properties or {}
  9. properties.host = properties.host or "127.0.0.1"
  10. properties.port = properties.port or 11234
  11. properties.password = properties.password or nil
  12. properties.config = properties.config or common.ConfigFile.new("/etc/cjdroute.conf", false)
  13. properties.timeout = properties.timeout or 2
  14. properties.udp = common.UDPInterface.new(properties)
  15. return setmetatable(properties, AdminInterface)
  16. end
  17. function AdminInterface:send(object)
  18. local bencoded, err = bencode.encode(object)
  19. if err then
  20. return nil, err
  21. end
  22. local sock_obj = assert(socket.udp())
  23. sock_obj:settimeout(self.timeout)
  24. local _, err = sock_obj:sendto(bencoded, self.host, self.port)
  25. if err then
  26. return nil, err
  27. end
  28. return sock_obj
  29. end
  30. function AdminInterface:recv(sock_obj)
  31. local retrieved, err = sock_obj:receive()
  32. if not retrieved then
  33. return nil, "ai:recv > " .. err
  34. end
  35. local bencoded, err = bencode.decode(retrieved)
  36. if bencoded then
  37. return bencoded
  38. else
  39. return nil, "ai:recv > " .. err
  40. end
  41. end
  42. function AdminInterface:call(request)
  43. local sock_obj, err = self:send(request)
  44. if err then
  45. return nil, "ai:call > " .. err
  46. end
  47. return self:recv(sock_obj)
  48. end
  49. function AdminInterface:getCookie()
  50. local cookie_response, err = self:call({ q = "cookie" })
  51. if not cookie_response then
  52. return nil, "ai:getCookie > " .. err
  53. end
  54. return cookie_response.cookie
  55. end
  56. function AdminInterface:auth(request)
  57. local funcname = request.q
  58. local args = {}
  59. for k, v in pairs(request) do
  60. args[k] = v
  61. end
  62. -- Step 1: Get cookie
  63. local cookie, err = self:getCookie()
  64. if err then
  65. return nil, err
  66. end
  67. -- Step 2: Calculate hash1 (password + cookie)
  68. local plaintext1 = self.password .. cookie
  69. local hash1 = sha2.sha256hex(plaintext1)
  70. -- Step 3: Calculate hash2 (intermediate stage request)
  71. local request = {
  72. q = "auth",
  73. aq = funcname,
  74. args = args,
  75. hash = hash1,
  76. cookie = cookie
  77. }
  78. local plaintext2, err = bencode.encode(request)
  79. if err then
  80. return nil, err
  81. end
  82. local hash2 = sha2.sha256hex(plaintext2)
  83. -- Step 4: Update hash in request, then ship it out
  84. request.hash = hash2
  85. return self:call(request)
  86. end