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