Add support for miniupnpd and cjdns
[librecmc/package-feed.git] / net / 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