· 6 years ago · Sep 20, 2019, 08:42 PM
1--[[
2- SRN v1.0
3- By TheQWERTYCoder
4-
5- Licensed under the GNU GPL.
6- You may copy this API as long as you...
7-
8- 1. License the copy under the GNU GPL
9- 2. Modify it in a way that changes the functionality (You can't make a copy that does the exact same thing)
10- 3. Tell the user that it is modified
11-
12- Thank you for reading!
13]]
14
15
16local localhost
17local version = "1.0"
18function init(side, host)
19 if not fs.exists("/.sys/apis/rsa.lua") then
20 local f = fs.open("/.sys/apis/.keep","w")
21 f.write("-- This is a keep file, made for the purpose of keeping directories with no contents. Don't delete me!\nprint('This is a keep file, made for the purpose of keeping directories with no contents. Don't delete me!')")
22 f.close()
23 print("The RSA API isn't installed, installing now.")
24 shell.run("pastebin","get","yFizJart","/.sys/apis/rsa.lua")
25 print("Done")
26 end
27 if not rsa.new then
28 os.loadAPI("/.sys/apis/rsa.lua")
29 end
30 rednet.open(side) -- Make sure modem is open
31 localhost = host
32 rednet.host("SRNv"..version,(host or os.computerLabel())) -- Enables srn connections
33end
34
35local function srnGetMsg(msg,com,timeout)
36 local id, data
37 local endtime = timeout and (os.clock()+timeout)
38 repeat
39 id,data=rednet.recieve("SRNv"..version,1)
40 until (((data.host==hostname(com)) or (id==com) or true) and (data.msg==msg)) or (timeout and os.clock()==endtime)
41 return id,data
42end
43local function srnSendMsg(com, msg, data)
44 local ID = rednet.lookup("SRNv"..version,host)
45 rednet.send(ID, {msg=msg,host=localhost,data=data}, "SRNv"..version)
46end
47
48local srncon = {}
49function connect(host)
50 local key = rsa.new()
51 srnSendMsg(host,"CONNECT",nil)
52 srnSendMsg(host,"PUBKEY",key.public)
53 local id,data = srnGetMsg("PUBKEY",host)
54 key.public=data.data
55 srncon[host] = {
56 id=id,
57 rsa=key,
58 send=function(msg)
59 srnSendMsg(self.id,"DATA",self.rsa.encrypt(msg))
60 end
61 }
62end
63local function resolveCon(host)
64 local id,data = srnGetMsg("CONNECT",host)
65 srncon[data.host] = {
66 id=host,
67 rsa=rsa.new(),
68 send=function(msg)
69 srnSendMsg(self.id,"DATA",self.rsa.encrypt(msg))
70 end
71 }
72 rednet.send(id, {msg="PUBKEY",host=localhost,data=key.public}, "SRNv"..version)
73 local id,data = srnGetMsg("PUBKEY",id)
74 srncon[data.host].rsa.public = data.data
75end
76
77function listen(host, timeout)
78 parallel.waitForAny(
79 function()
80 resolveCon(host)
81 end,
82 function()
83 local endtime = (timeout and os.clock()+timeout)
84 repeat
85 until (endtime and os.clock()>=endtime)
86 end
87 )
88end
89
90local function hostname(ID)
91 for k,v in srncon do
92 if v.id == ID then
93 return k
94 end
95 end
96 return id
97end
98
99function send(host,msg)
100 if not srncon[host] then
101 connect(host)
102 end
103 srncon[host].send(msg)
104end
105
106function recieve(timeout)
107 listen(nil,timeout)
108 local id,data = srnGetMsg("DATA")
109 return srncon[data.host].rsa.decrypt(data.data)
110end