View difference between Paste ID: KixyLUWJ and 9KmQN99B
SHOW: | | - or go back to the newest paste.
1
local userDir = ".users"
2
3
--SHA-256 API by GravityScore
4
local MOD = 2^32
5
local MODM = MOD-1
6
7
local function memoize(f)
8
	local mt = {}
9
	local t = setmetatable({}, mt)
10
	function mt:__index(k)
11
		local v = f(k)
12
		t[k] = v
13
		return v
14
	end
15
	return t
16
end
17
18
local function make_bitop_uncached(t, m)
19
	local function bitop(a, b)
20
		local res,p = 0,1
21
		while a ~= 0 and b ~= 0 do
22
			local am, bm = a % m, b % m
23
			res = res + t[am][bm] * p
24
			a = (a - am) / m
25
			b = (b - bm) / m
26
			p = p*m
27
		end
28
		res = res + (a + b) * p
29
		return res
30
	end
31
	return bitop
32
end
33
34
local function make_bitop(t)
35
	local op1 = make_bitop_uncached(t,2^1)
36
	local op2 = memoize(function(a) return memoize(function(b) return op1(a, b) end) end)
37
	return make_bitop_uncached(op2, 2 ^ (t.n or 1))
38
end
39
40
local bxor1 = make_bitop({[0] = {[0] = 0,[1] = 1}, [1] = {[0] = 1, [1] = 0}, n = 4})
41
42
local function bxor(a, b, c, ...)
43
	local z = nil
44
	if b then
45
		a = a % MOD
46
		b = b % MOD
47
		z = bxor1(a, b)
48
		if c then z = bxor(z, c, ...) end
49
		return z
50
	elseif a then return a % MOD
51
	else return 0 end
52
end
53
54
local function band(a, b, c, ...)
55
	local z
56
	if b then
57
		a = a % MOD
58
		b = b % MOD
59
		z = ((a + b) - bxor1(a,b)) / 2
60
		if c then z = bit32_band(z, c, ...) end
61
		return z
62
	elseif a then return a % MOD
63
	else return MODM end
64
end
65
66
local function bnot(x) return (-1 - x) % MOD end
67
68
local function rshift1(a, disp)
69
	if disp < 0 then return lshift(a,-disp) end
70
	return math.floor(a % 2 ^ 32 / 2 ^ disp)
71
end
72
73
local function rshift(x, disp)
74
	if disp > 31 or disp < -31 then return 0 end
75
	return rshift1(x % MOD, disp)
76
end
77
78
local function lshift(a, disp)
79
	if disp < 0 then return rshift(a,-disp) end 
80
	return (a * 2 ^ disp) % 2 ^ 32
81
end
82
83
local function rrotate(x, disp)
84
    x = x % MOD
85
    disp = disp % 32
86
    local low = band(x, 2 ^ disp - 1)
87
    return rshift(x, disp) + lshift(low, 32 - disp)
88
end
89
90
local k = {
91
	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
92
	0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
93
	0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
94
	0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
95
	0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
96
	0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
97
	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
98
	0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
99
	0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
100
	0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
101
	0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
102
	0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
103
	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
104
	0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
105
	0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
106
	0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
107
}
108
109
local function str2hexa(s)
110
	return (string.gsub(s, ".", function(c) return string.format("%02x", string.byte(c)) end))
111
end
112
113
local function num2s(l, n)
114
	local s = ""
115
	for i = 1, n do
116
		local rem = l % 256
117
		s = string.char(rem) .. s
118
		l = (l - rem) / 256
119
	end
120
	return s
121
end
122
123
local function s232num(s, i)
124
	local n = 0
125
	for i = i, i + 3 do n = n*256 + string.byte(s, i) end
126
	return n
127
end
128
129
local function preproc(msg, len)
130
	local extra = 64 - ((len + 9) % 64)
131
	len = num2s(8 * len, 8)
132
	msg = msg .. "\128" .. string.rep("\0", extra) .. len
133
	assert(#msg % 64 == 0)
134
	return msg
135
end
136
137
local function initH256(H)
138
	H[1] = 0x6a09e667
139
	H[2] = 0xbb67ae85
140
	H[3] = 0x3c6ef372
141
	H[4] = 0xa54ff53a
142
	H[5] = 0x510e527f
143
	H[6] = 0x9b05688c
144
	H[7] = 0x1f83d9ab
145
	H[8] = 0x5be0cd19
146
	return H
147
end
148
149
local function digestblock(msg, i, H)
150
	local w = {}
151
	for j = 1, 16 do w[j] = s232num(msg, i + (j - 1)*4) end
152
	for j = 17, 64 do
153
		local v = w[j - 15]
154
		local s0 = bxor(rrotate(v, 7), rrotate(v, 18), rshift(v, 3))
155
		v = w[j - 2]
156
		w[j] = w[j - 16] + s0 + w[j - 7] + bxor(rrotate(v, 17), rrotate(v, 19), rshift(v, 10))
157
	end
158
159
	local a, b, c, d, e, f, g, h = H[1], H[2], H[3], H[4], H[5], H[6], H[7], H[8]
160
	for i = 1, 64 do
161
		local s0 = bxor(rrotate(a, 2), rrotate(a, 13), rrotate(a, 22))
162
		local maj = bxor(band(a, b), band(a, c), band(b, c))
163
		local t2 = s0 + maj
164
		local s1 = bxor(rrotate(e, 6), rrotate(e, 11), rrotate(e, 25))
165
		local ch = bxor (band(e, f), band(bnot(e), g))
166
		local t1 = h + s1 + ch + k[i] + w[i]
167
		h, g, f, e, d, c, b, a = g, f, e, d + t1, c, b, a, t1 + t2
168
	end
169
170
	H[1] = band(H[1] + a)
171
	H[2] = band(H[2] + b)
172
	H[3] = band(H[3] + c)
173
	H[4] = band(H[4] + d)
174
	H[5] = band(H[5] + e)
175
	H[6] = band(H[6] + f)
176
	H[7] = band(H[7] + g)
177
	H[8] = band(H[8] + h)
178
end
179
180
local function sha256(msg)
181
	msg = preproc(msg, #msg)
182
	local H = initH256({})
183
	for i = 1, #msg, 64 do digestblock(msg, i, H) end
184
	return str2hexa(num2s(H[1], 4) .. num2s(H[2], 4) .. num2s(H[3], 4) .. num2s(H[4], 4) ..
185
		num2s(H[5], 4) .. num2s(H[6], 4) .. num2s(H[7], 4) .. num2s(H[8], 4))
186
end
187
188
--SHA-256 API end
189
190
191
192
193
194
local tArg = {...}
195
local progname = fs.getName(shell.getRunningProgram())
196
197
local getTime = function()
198
	return ((os.day()-1)*24)+(os.time()*1000)
199
end
200
201
addUser = function(name,password)
202
	local file = fs.open(fs.combine(userDir,name),"w")
203
	local out = {
204
		password = sha256(password),
205
		time = getTime(),
206
		active = true,
207
	}
208
	file.write(textutils.serialize(out))
209
	file.close()
210
end
211
212
if tArg[1] == "adduser" then
213
	if not tArg[3] then
214
		return print(progname.." useradd [name] [password]")
215
	else
216
		if fs.exists(fs.combine(userDir,tArg[2])) then
217
			return print("Already exists...")
218
		end
219
		return adduser(tArg[2],tArg[3])
220
	end
221
elseif tArg[1] == "deluser" then
222
	if not tArg[2] then
223
		return print(progname.." deluser [user]")
224
	else
225
		if not fs.exists(fs.combine(userDir,tArg[2])) then
226
			return print("No such user.")
227
		end
228
		return fs.delete(fs.combing(userDir,tArg[2]))
229
	end
230
end
231
232
-- Find modems
233
local tModems = {}
234
for n,sModem in ipairs( peripheral.getNames() ) do
235
    if peripheral.getType( sModem ) == "modem" then
236
        table.insert( tModems, sModem )
237
    end
238
end
239
if #tModems == 0 then
240
    print( "No modems found." )
241
    return
242
elseif #tModems == 1 then
243
    print( "1 modem found." )
244
else
245
    print( #tModems .. " modems found." )
246
end
247
248
function open( nChannel )
249
    for n=1,#tModems do
250
        local sModem = tModems[n]
251
        peripheral.call( sModem, "open", nChannel )
252
    end
253
end
254
255
function close( nChannel )
256
    for n=1,#tModems do
257
        local sModem = tModems[n]
258
        peripheral.call( sModem, "close", nChannel )
259
    end
260
end
261
262
-- Open channels
263
print( "0 messages repeated." )
264
open( rednet.CHANNEL_REPEAT )
265
266
-- Main loop (terminate to break)
267
local ok, error = pcall( function()
268
    local tReceivedMessages = {}
269
    local tReceivedMessageTimeouts = {}
270
    local nTransmittedMessages = 0
271
272
    while true do
273
        local sEvent, sModem, nChannel, nReplyChannel, tMessage = os.pullEvent()
274
        if sEvent == "modem_message" then
275
            -- Got a modem message, rebroadcast it if it's a rednet thing
276
            if nChannel == rednet.CHANNEL_REPEAT then
277
                if type( tMessage ) == "table" and tMessage.nMessageID and tMessage.nRecipient then
278
                    if not tReceivedMessages[ tMessage.nMessageID ] then
279
                        -- Ensure we only repeat a message once
280
                        tReceivedMessages[ tMessage.nMessageID ] = true
281
                        tReceivedMessageTimeouts[ os.startTimer( 30 ) ] = tMessage.nMessageID
282
283
                        -- Send on all other open modems, to the target and to other repeaters
284
                        for n=1,#tModems do
285
                            local sOtherModem = tModems[n]
286
                            peripheral.call( sOtherModem, "transmit", rednet.CHANNEL_REPEAT, nReplyChannel, tMessage )
287
                            peripheral.call( sOtherModem, "transmit", tMessage.nRecipient, nReplyChannel, tMessage )
288
                        end
289
290
                        -- Log the event
291
                        nTransmittedMessages = nTransmittedMessages + 1
292
                        local x,y = term.getCursorPos()
293
                        term.setCursorPos( 1, y - 1 )
294
                        term.clearLine()
295
                        if nTransmittedMessages == 1 then
296
                            print( nTransmittedMessages .. " message repeated." )
297
                        else
298
                            print( nTransmittedMessages .. " messages repeated." )
299
                        end
300
                    end
301
                end
302
            end
303
304
        elseif sEvent == "timer" then
305
            -- Got a timer event, use it to clear the message history
306
            local nTimer = sModem
307
            local nMessageID = tReceivedMessageTimeouts[ nTimer ]
308
            if nMessageID then
309
                tReceivedMessageTimeouts[ nTimer ] = nil
310
                tReceivedMessages[ nMessageID ] = nil
311
            end
312
313
        end
314
    end
315
end )
316
if not ok then
317
    printError( error )
318
end
319
320
-- Close channels
321
close( rednet.CHANNEL_REPEAT )