mirror of
				https://github.com/kepler155c/opus
				synced 2025-10-31 07:33:00 +00:00 
			
		
		
		
	security updates
This commit is contained in:
		| @@ -137,10 +137,14 @@ end | ||||
| ]] | ||||
|  | ||||
| function page.ports.grid:update() | ||||
| 	local transport = network:getTransport() | ||||
|  | ||||
| 	local function findConnection(port) | ||||
| 		for _,socket in pairs(_G.transport.sockets) do | ||||
| 			if socket.sport == port then | ||||
| 				return socket | ||||
| 		if transport then | ||||
| 			for _,socket in pairs(transport.sockets) do | ||||
| 				if socket.sport == port then | ||||
| 					return socket | ||||
| 				end | ||||
| 			end | ||||
| 		end | ||||
| 	end | ||||
|   | ||||
| @@ -14,6 +14,7 @@ if not device.wireless_modem then | ||||
| end | ||||
|  | ||||
| print('Net daemon starting') | ||||
| device.wireless_modem.closeAll() | ||||
|  | ||||
| for _,file in pairs(fs.list('sys/apps/network')) do | ||||
| 	local fn, msg = Util.run(_ENV, 'sys/apps/network/' .. file) | ||||
|   | ||||
							
								
								
									
										39
									
								
								sys/apps/network/keygen.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								sys/apps/network/keygen.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| local ECC    = require('opus.crypto.ecc') | ||||
| local Event  = require('opus.event') | ||||
| local Util   = require('opus.util') | ||||
|  | ||||
| local network = _G.network | ||||
| local os      = _G.os | ||||
|  | ||||
| local keyPairs = { } | ||||
|  | ||||
| local function generateKeyPair() | ||||
| 	local key = { } | ||||
| 	for _ = 1, 32 do | ||||
| 		table.insert(key, ("%02x"):format(math.random(0, 0xFF))) | ||||
| 	end | ||||
|   local privateKey = Util.hexToByteArray(table.concat(key)) | ||||
| 	return privateKey, ECC.publicKey(privateKey) | ||||
| end | ||||
|  | ||||
| getmetatable(network).__index.getKeyPair = function() | ||||
|   local keys = table.remove(keyPairs) | ||||
|   os.queueEvent('generate_keypair') | ||||
|   if not keys then | ||||
|     return generateKeyPair() | ||||
|   end | ||||
|   return table.unpack(keys) | ||||
| end | ||||
|  | ||||
| -- Generate key pairs in the background as this is a time-consuming process | ||||
| Event.on('generate_keypair', function() | ||||
|   while true do | ||||
|     os.sleep(5) | ||||
|     local timer = Util.timer() | ||||
|     table.insert(keyPairs, { generateKeyPair() }) | ||||
|     _G._syslog('Generated keypair in ' .. timer()) | ||||
|     if #keyPairs >= 3 then | ||||
|       break | ||||
|     end | ||||
|   end | ||||
| end) | ||||
| @@ -6,7 +6,9 @@ | ||||
| ]]-- | ||||
|  | ||||
| local Event = require('opus.event') | ||||
| local SHA   = require('opus.crypto.sha2') | ||||
|  | ||||
| local network = _G.network | ||||
| local os = _G.os | ||||
|  | ||||
| local computerId = os.getComputerID() | ||||
| @@ -15,7 +17,10 @@ local transport = { | ||||
| 	sockets = { }, | ||||
| 	UID = 0, | ||||
| } | ||||
| _G.transport = transport | ||||
|  | ||||
| getmetatable(network).__index.getTransport = function() | ||||
| 	return transport | ||||
| end | ||||
|  | ||||
| function transport.open(socket) | ||||
| 	transport.UID = transport.UID + 1 | ||||
| @@ -33,19 +38,11 @@ function transport.read(socket) | ||||
| end | ||||
|  | ||||
| function transport.write(socket, data) | ||||
| 	--_syslog('>> ' .. Util.tostring({ type = 'DATA', seq = socket.wseq })) | ||||
| 	socket.transmit(socket.dport, socket.dhost, data) | ||||
|  | ||||
| 	--local timerId = os.startTimer(3) | ||||
|  | ||||
| 	--transport.timers[timerId] = socket | ||||
| 	--socket.timers[socket.wseq] = timerId | ||||
|  | ||||
| 	socket.wseq = socket.wseq + 1 | ||||
| 	socket.wseq = SHA.digest(socket.wseq):toHex() | ||||
| end | ||||
|  | ||||
| function transport.ping(socket) | ||||
| 	--_syslog('>> ' .. Util.tostring({ type = 'DATA', seq = socket.wseq })) | ||||
| 	if os.clock() - socket.activityTimer > 10 then | ||||
| 		socket.activityTimer = os.clock() | ||||
| 		socket.transmit(socket.dport, socket.dhost, { | ||||
| @@ -53,7 +50,7 @@ function transport.ping(socket) | ||||
| 				seq = -1, | ||||
| 			}) | ||||
|  | ||||
| 		local timerId = os.startTimer(5) | ||||
| 		local timerId = os.startTimer(3) | ||||
| 		transport.timers[timerId] = socket | ||||
| 		socket.timers[-1] = timerId | ||||
| 	end | ||||
| @@ -78,18 +75,19 @@ Event.on('modem_message', function(_, _, dport, dhost, msg, distance) | ||||
| 		local socket = transport.sockets[dport] | ||||
| 		if socket and socket.connected then | ||||
|  | ||||
| 			--if msg.type then _syslog('<< ' .. Util.tostring(msg)) end | ||||
| 			if socket.co and coroutine.status(socket.co) == 'dead' then | ||||
| 				_G._syslog('socket coroutine dead') | ||||
| 				socket:close() | ||||
|  | ||||
| 			elseif msg.type == 'DISC' then | ||||
| 				-- received disconnect from other end | ||||
| 				if socket.connected then | ||||
| 					os.queueEvent('transport_' .. socket.uid) | ||||
| 				if msg.seq == socket.rseq then | ||||
| 					if socket.connected then | ||||
| 						os.queueEvent('transport_' .. socket.uid) | ||||
| 					end | ||||
| 					socket.connected = false | ||||
| 					socket:close() | ||||
| 				end | ||||
| 				socket.connected = false | ||||
| 				socket:close() | ||||
|  | ||||
| 			elseif msg.type == 'ACK' then | ||||
| 				local ackTimerId = socket.timers[msg.seq] | ||||
| @@ -108,28 +106,19 @@ Event.on('modem_message', function(_, _, dport, dhost, msg, distance) | ||||
| 				}) | ||||
|  | ||||
| 			elseif msg.type == 'DATA' and msg.data then | ||||
| 				socket.activityTimer = os.clock() | ||||
| 				if msg.seq ~= socket.rseq then | ||||
| 					print('transport seq error - closing socket ' .. socket.sport) | ||||
| 					_syslog(msg.data) | ||||
| 					_syslog('current ' .. socket.rseq) | ||||
| 					_syslog('expected ' .. msg.seq) | ||||
| --					socket:close() | ||||
| --					os.queueEvent('transport_' .. socket.uid) | ||||
| 					_syslog('expected ' .. socket.rseq) | ||||
| 					_syslog('got ' .. msg.seq) | ||||
| 				else | ||||
| 					socket.rseq = socket.rseq + 1 | ||||
| 					socket.activityTimer = os.clock() | ||||
| 					socket.rseq = SHA.digest(socket.rseq):toHex() | ||||
| 					table.insert(socket.messages, { msg.data, distance }) | ||||
|  | ||||
| 					-- use resume instead ?? | ||||
| 					if not socket.messages[2] then  -- table size is 1 | ||||
| 						os.queueEvent('transport_' .. socket.uid) | ||||
| 					end | ||||
|  | ||||
| 					--_syslog('>> ' .. Util.tostring({ type = 'ACK', seq = msg.seq })) | ||||
| 					--socket.transmit(socket.dport, socket.dhost, { | ||||
| 					--  type = 'ACK', | ||||
| 					--  seq = msg.seq, | ||||
| 					--}) | ||||
| 				end | ||||
| 			end | ||||
| 		end | ||||
|   | ||||
| @@ -4,6 +4,8 @@ local Security = require('opus.security') | ||||
| local Socket   = require('opus.socket') | ||||
| local Util     = require('opus.util') | ||||
|  | ||||
| local trustId = '01c3ba27fe01383a03a1785276d99df27c3edcef68fbf231ca' | ||||
|  | ||||
| local function trustConnection(socket) | ||||
| 	local data = socket:read(2) | ||||
| 	if data then | ||||
| @@ -14,7 +16,7 @@ local function trustConnection(socket) | ||||
| 			data = Crypto.decrypt(data, password) | ||||
| 			if data and data.pk and data.dh == socket.dhost then | ||||
| 				local trustList = Util.readTable('usr/.known_hosts') or { } | ||||
| 				trustList[data.dh] = Util.byteArrayToHex(data.pk) | ||||
| 				trustList[data.dh] = data.pk | ||||
| 				Util.writeTable('usr/.known_hosts', trustList) | ||||
|  | ||||
| 				socket:write({ success = true, msg = 'Trust accepted' }) | ||||
| @@ -29,7 +31,7 @@ Event.addRoutine(function() | ||||
| 	print('trust: listening on port 19') | ||||
|  | ||||
| 	while true do | ||||
| 		local socket = Socket.server(19) | ||||
| 		local socket = Socket.server(19, { identifier = trustId }) | ||||
|  | ||||
| 		print('trust: connection from ' .. socket.dhost) | ||||
|  | ||||
|   | ||||
| @@ -27,15 +27,16 @@ if not password then | ||||
| end | ||||
|  | ||||
| print('connecting...') | ||||
| local socket, msg = Socket.connect(remoteId, 19) | ||||
| local trustId = '01c3ba27fe01383a03a1785276d99df27c3edcef68fbf231ca' | ||||
| local socket, msg = Socket.connect(remoteId, 19, { identifier = trustId }) | ||||
|  | ||||
| if not socket then | ||||
| 	error(msg) | ||||
| end | ||||
|  | ||||
| local publicKey = Security.getPublicKey() | ||||
| local identifier = Security.getIdentifier() | ||||
|  | ||||
| socket:write(Crypto.encrypt({ pk = publicKey, dh = os.getComputerID() }, SHA.compute(password))) | ||||
| socket:write(Crypto.encrypt({ pk = identifier, dh = os.getComputerID() }, SHA.compute(password))) | ||||
|  | ||||
| local data = socket:read(2) | ||||
| socket:close() | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| -- By Anavrins | ||||
|  | ||||
| local sha2 = require('opus.crypto.sha2') | ||||
| local util = require('opus.util') | ||||
| local Util = require('opus.util') | ||||
|  | ||||
| local ROUNDS = 20 -- Adjust this for speed tradeoff | ||||
|  | ||||
| @@ -115,7 +115,7 @@ local function crypt(data, key, nonce, cntr, round) | ||||
| 	cntr = tonumber(cntr) or 1 | ||||
| 	round = tonumber(round) or 20 | ||||
|  | ||||
| 	local throttle = util.throttle() | ||||
| 	local throttle = Util.throttle() | ||||
| 	local out = {} | ||||
| 	local state = initState(key, nonce, cntr) | ||||
| 	local blockAmt = math.floor(#data/64) | ||||
| @@ -157,8 +157,8 @@ local function encrypt(data, key) | ||||
| end | ||||
|  | ||||
| local function decrypt(data, key) | ||||
| 	local nonce = util.hexToByteArray(data[1]) | ||||
| 	data = util.hexToByteArray(data[2]) | ||||
| 	local nonce = Util.hexToByteArray(data[1]) | ||||
| 	data = Util.hexToByteArray(data[2]) | ||||
| 	key = sha2.digest(key) | ||||
| 	local ptx = crypt(data, key, nonce, 1, ROUNDS) | ||||
| 	return textutils.unserialise(tostring(ptx)) | ||||
|   | ||||
| @@ -22,6 +22,8 @@ | ||||
| -- Indistinguishability? No: The curve does not support indistinguishability maps. | ||||
|  | ||||
| local fp = require('opus.crypto.ecc.fp') | ||||
| local Util = require('opus.util') | ||||
|  | ||||
| local eq = fp.eq | ||||
| local mul = fp.mul | ||||
| local sqr = fp.sqr | ||||
| @@ -31,6 +33,7 @@ local shr = fp.shr | ||||
| local mont = fp.mont | ||||
| local invMont = fp.invMont | ||||
| local sub192 = fp.sub192 | ||||
| local unpack = table.unpack | ||||
|  | ||||
| local bits = 192 | ||||
| local pMinusTwoBinary = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} | ||||
| @@ -203,20 +206,23 @@ local function scalarMul(s, P1) | ||||
| 	end | ||||
|  | ||||
| 	local Q = {{unpack(ZERO)}, {unpack(ONE)}, {unpack(ONE)}} | ||||
| 	for i = #naf, 1, -1 do | ||||
| 	for i = #naf, 1, -1 do -- can this loop be optimized ? | ||||
| 		local n = naf[i] | ||||
| 		Q = pointDouble(Q) | ||||
| 		if naf[i] > 0 then | ||||
| 			Q = pointAdd(Q, PTable[naf[i]]) | ||||
| 		elseif naf[i] < 0 then | ||||
| 			Q = pointSub(Q, PTable[-naf[i]]) | ||||
| 		if n > 0 then | ||||
| 			Q = pointAdd(Q, PTable[n]) | ||||
| 		elseif n < 0 then | ||||
| 			Q = pointSub(Q, PTable[-n]) | ||||
| 		end | ||||
| 	end | ||||
|  | ||||
| 	return Q | ||||
| end | ||||
|  | ||||
| local throttle = Util.throttle() | ||||
| for i = 2, 196 do | ||||
| 	GTable[i] = pointDouble(GTable[i - 1]) | ||||
| 	throttle() | ||||
| end | ||||
|  | ||||
| local function scalarMulG(s) | ||||
|   | ||||
| @@ -1,5 +1,7 @@ | ||||
| -- Fp Integer Arithmetic | ||||
|  | ||||
| local unpack = table.unpack | ||||
|  | ||||
| local n = 0xffff | ||||
| local m = 0x10000 | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,7 @@ | ||||
| -- Fq Integer Arithmetic | ||||
|  | ||||
| local unpack = table.unpack | ||||
|  | ||||
| local n = 0xffff | ||||
| local m = 0x10000 | ||||
|  | ||||
|   | ||||
| @@ -3,6 +3,7 @@ local elliptic = require('opus.crypto.ecc.elliptic') | ||||
| local sha256   = require('opus.crypto.sha2') | ||||
|  | ||||
| local os = _G.os | ||||
| local unpack = table.unpack | ||||
|  | ||||
| local q = {1372, 62520, 47765, 8105, 45059, 9616, 65535, 65535, 65535, 65535, 65535, 65532} | ||||
|  | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| -- SHA-256, HMAC and PBKDF2 functions in ComputerCraft | ||||
| -- By Anavrins | ||||
| local Util = require('opus.util') | ||||
|  | ||||
| local bit     = _G.bit | ||||
| local os      = _G.os | ||||
| local mod32   = 2^32 | ||||
| local band    = bit32 and bit32.band or bit.band | ||||
| local bnot    = bit32 and bit32.bnot or bit.bnot | ||||
| @@ -162,25 +162,13 @@ local function hmac(data, key) | ||||
| 	return digest(padded_key) | ||||
| end | ||||
|  | ||||
| local function throttler() | ||||
| 	local ts = os.clock() | ||||
| 	local timeout = .095 | ||||
| 	return function() | ||||
| 		local nts = os.clock() | ||||
| 		if nts > ts + timeout then | ||||
| 			os.sleep(0) | ||||
| 			ts = os.clock() | ||||
| 		end | ||||
| 	end | ||||
| end | ||||
|  | ||||
| local function pbkdf2(pass, salt, iter, dklen) | ||||
| 	salt = type(salt) == "table" and salt or {tostring(salt):byte(1,-1)} | ||||
| 	local hashlen = 32 | ||||
| 	dklen = dklen or 32 | ||||
| 	local block = 1 | ||||
| 	local out = {} | ||||
| 	local throttle = throttler() | ||||
| 	local throttle = Util.throttle() | ||||
|  | ||||
| 	while dklen > 0 do | ||||
| 		local ikey = {} | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| local Config = require('opus.config') | ||||
| local Util   = require('opus.util') | ||||
| local ECC    = require('opus.crypto.ecc') | ||||
| local Util   = require('opus.util') | ||||
|  | ||||
| local Security = { } | ||||
|  | ||||
| @@ -21,16 +21,6 @@ local function genKey() | ||||
| 	return table.concat(key) | ||||
| end | ||||
|  | ||||
| function Security.generateKeyPair() | ||||
| 	local privateKey = Util.hexToByteArray(genKey()) | ||||
| 	return privateKey, ECC.publicKey(privateKey) | ||||
| end | ||||
|  | ||||
| function Security.getIdentifier() | ||||
| 	return Security.getPublicKey() | ||||
| end | ||||
|  | ||||
| -- deprecate - will use getIdentifier | ||||
| function Security.getSecretKey() | ||||
| 	local config = Config.load('os') | ||||
| 	if not config.secretKey then | ||||
| @@ -40,9 +30,17 @@ function Security.getSecretKey() | ||||
| 	return Util.hexToByteArray(config.secretKey) | ||||
| end | ||||
|  | ||||
| function Security.getPublicKey() | ||||
| 	local secretKey = Security.getSecretKey() | ||||
| 	return ECC.publicKey(secretKey) | ||||
| function Security.getIdentifier() | ||||
| 	local config = Config.load('os') | ||||
| 	if config.identifier then | ||||
| 		return config.identifier | ||||
| 	end | ||||
| 	-- preserve the hash the user generated | ||||
| 	local identifier = ECC.publicKey(Security.getSecretKey()) | ||||
| 	config.identifier = Util.byteArrayToHex(identifier) | ||||
| 	Config.update('os', config) | ||||
|  | ||||
| 	return config.identifier | ||||
| end | ||||
|  | ||||
| function Security.updatePassword(password) | ||||
|   | ||||
| @@ -6,11 +6,12 @@ local Util     = require('opus.util') | ||||
|  | ||||
| local device    = _G.device | ||||
| local os        = _G.os | ||||
| local network   = _G.network | ||||
|  | ||||
| local socketClass = { } | ||||
|  | ||||
| function socketClass:read(timeout) | ||||
| 	local data, distance = _G.transport.read(self) | ||||
| 	local data, distance = network.getTransport().read(self) | ||||
| 	if data then | ||||
| 		return data, distance | ||||
| 	end | ||||
| @@ -25,7 +26,7 @@ function socketClass:read(timeout) | ||||
| 		local e, id = os.pullEvent() | ||||
|  | ||||
| 		if e == 'transport_' .. self.uid then | ||||
| 			data, distance = _G.transport.read(self) | ||||
| 			data, distance = network.getTransport().read(self) | ||||
| 			if data then | ||||
| 				os.cancelTimer(timerId) | ||||
| 				return data, distance | ||||
| @@ -46,7 +47,7 @@ end | ||||
|  | ||||
| function socketClass:write(data) | ||||
| 	if self.connected then | ||||
| 		_G.transport.write(self, { | ||||
| 		network.getTransport().write(self, { | ||||
| 			type = 'DATA', | ||||
| 			seq = self.wseq, | ||||
| 			data = data, | ||||
| @@ -57,30 +58,31 @@ end | ||||
|  | ||||
| function socketClass:ping() | ||||
| 	if self.connected then | ||||
| 		_G.transport.ping(self) | ||||
| 		network.getTransport().ping(self) | ||||
| 		return true | ||||
| 	end | ||||
| end | ||||
|  | ||||
| function socketClass:setupEncryption() | ||||
| 	if false then | ||||
| function socketClass:setupEncryption(x) | ||||
| local timer = Util.timer() | ||||
| 	self.sharedKey = ECC.exchange(self.privKey, self.remotePubKey) | ||||
| 	self.enckey  = SHA.pbkdf2(self.sharedKey, "1enc", 1) | ||||
| 	self.hmackey  = SHA.pbkdf2(self.sharedKey, "2hmac", 1) | ||||
| 	self.rseed  = SHA.pbkdf2(self.sharedKey, "3rseed", 1) | ||||
| 	self.wseed  = SHA.pbkdf2(self.sharedKey, "4sseed", 1) | ||||
| 	end | ||||
| 	self.rseq  = SHA.pbkdf2(self.sharedKey, x and "3rseed" or "4sseed", 1):toHex() | ||||
| 	self.wseq  = SHA.pbkdf2(self.sharedKey, x and "4sseed" or "3rseed", 1):toHex() | ||||
| _syslog('shared in ' .. timer()) | ||||
| end | ||||
|  | ||||
| function socketClass:close() | ||||
| 	if self.connected then | ||||
| 		self.transmit(self.dport, self.dhost, { | ||||
| 			type = 'DISC', | ||||
| 			seq = self.wseq, | ||||
| 		}) | ||||
| 		self.connected = false | ||||
| 	end | ||||
| 	device.wireless_modem.close(self.sport) | ||||
| 	_G.transport.close(self) | ||||
| 	network.getTransport().close(self) | ||||
| end | ||||
|  | ||||
| local Socket = { } | ||||
| @@ -115,27 +117,24 @@ local function newSocket(isLoopback) | ||||
| 	error('No ports available') | ||||
| end | ||||
|  | ||||
| function Socket.connect(host, port) | ||||
| function Socket.connect(host, port, options) | ||||
| 	if not device.wireless_modem then | ||||
| 		return false, 'Wireless modem not found', 'NOMODEM' | ||||
| 	end | ||||
|  | ||||
| local timer = Util.timer() | ||||
| 	local socket = newSocket(host == os.getComputerID()) | ||||
| 	socket.dhost = tonumber(host) | ||||
| 	socket.privKey, socket.pubKey = Security.generateKeyPair() | ||||
| 	socket.privKey, socket.pubKey = network.getKeyPair() | ||||
| 	local identifier = options and options.identifier or Security.getIdentifier() | ||||
|  | ||||
| 	socket.transmit(port, socket.sport, { | ||||
| 		type = 'OPEN', | ||||
| 		shost = socket.shost, | ||||
| 		dhost = socket.dhost, | ||||
| 		rseq = socket.wseq, | ||||
| 		wseq = socket.rseq, | ||||
| 		t = Crypto.encrypt({ | ||||
| 			ts = os.time(), | ||||
| 			seq = socket.seq, | ||||
| 			nts = os.epoch('utc'), | ||||
| 		t = Crypto.encrypt({ -- this is not that much data... | ||||
| 			ts = os.epoch('utc'), | ||||
| 			pk = Util.byteArrayToHex(socket.pubKey), | ||||
| 		}, Security.getPublicKey()), | ||||
| 		}, Util.hexToByteArray(identifier)), | ||||
| 	}) | ||||
|  | ||||
| 	local timerId = os.startTimer(3) | ||||
| @@ -152,10 +151,11 @@ function Socket.connect(host, port) | ||||
| 				socket.dport = dport | ||||
| 				socket.connected = true | ||||
| 				socket.remotePubKey = Util.hexToByteArray(msg.pk) | ||||
| 				socket:setupEncryption() | ||||
| 				socket:setupEncryption(true) | ||||
| 				-- Logger.log('socket', 'connection established to %d %d->%d', | ||||
| 				--											host, socket.sport, socket.dport) | ||||
| 				_G.transport.open(socket) | ||||
| 				network.getTransport().open(socket) | ||||
| _syslog('connection in ' .. timer()) | ||||
| 				return socket | ||||
|  | ||||
| 			elseif msg.type == 'NOPASS' then | ||||
| @@ -173,35 +173,30 @@ function Socket.connect(host, port) | ||||
| 	return false, 'Connection timed out', 'TIMEOUT' | ||||
| end | ||||
|  | ||||
| local function trusted(socket, msg, port) | ||||
| 	if port == 19 or msg.shost == os.getComputerID() then | ||||
| 		-- no auth for trust server or loopback | ||||
| 		return true | ||||
| local function trusted(socket, msg, options) | ||||
| 	local function getIdentifier() | ||||
| 		local trustList = Util.readTable('usr/.known_hosts') or { } | ||||
| 		return trustList[msg.shost] | ||||
| 	end | ||||
|  | ||||
| 	if not Security.hasPassword() then | ||||
| 		-- no password has been set on this computer | ||||
| 		--return true | ||||
| 	end | ||||
| 	local identifier = options and options.identifier or getIdentifier() | ||||
|  | ||||
| 	local trustList = Util.readTable('usr/.known_hosts') or { } | ||||
| 	local pubKey = trustList[msg.shost] | ||||
| 	if identifier and msg.t and type(msg.t) == 'table' then | ||||
| 		local data = Crypto.decrypt(msg.t, Util.hexToByteArray(identifier)) | ||||
|  | ||||
| 	if pubKey and msg.t then | ||||
| 		local data = Crypto.decrypt(msg.t, Util.hexToByteArray(pubKey)) | ||||
|  | ||||
| 		if data and data.nts then -- upgraded security | ||||
| 			if data.nts and tonumber(data.nts) and math.abs(os.epoch('utc') - data.nts) < 1024 then | ||||
| 		if data and data.ts and tonumber(data.ts) then | ||||
| _G._syslog('time diff ' .. math.abs(os.epoch('utc') - data.ts)) | ||||
| 			if math.abs(os.epoch('utc') - data.ts) < 4096 then | ||||
| 				socket.remotePubKey = Util.hexToByteArray(data.pk) | ||||
| 				socket.privKey, socket.pubKey = network.getKeyPair() | ||||
| 				socket:setupEncryption() | ||||
| 				return true | ||||
| 			end | ||||
| 		end | ||||
|  | ||||
| 		--local sharedKey = modexp(pubKey, exchange.secretKey, public.primeMod) | ||||
| 		return data and data.ts and tonumber(data.ts) and math.abs(os.time() - data.ts) < 24 | ||||
| 	end | ||||
| end | ||||
|  | ||||
| function Socket.server(port) | ||||
| function Socket.server(port, options) | ||||
| 	device.wireless_modem.open(port) | ||||
| 	-- Logger.log('socket', 'Waiting for connections on port ' .. port) | ||||
|  | ||||
| @@ -219,6 +214,7 @@ function Socket.server(port) | ||||
| 			socket.dhost = msg.shost | ||||
| 			socket.wseq = msg.wseq | ||||
| 			socket.rseq = msg.rseq | ||||
| 			socket.options = options | ||||
|  | ||||
| 			if not Security.hasPassword() then | ||||
| 				socket.transmit(socket.dport, socket.sport, { | ||||
| @@ -228,10 +224,8 @@ function Socket.server(port) | ||||
| 				}) | ||||
| 				socket:close() | ||||
|  | ||||
| 			elseif trusted(socket, msg, port) then | ||||
| 			elseif trusted(socket, msg, options) then | ||||
| 				socket.connected = true | ||||
| 				socket.privKey, socket.pubKey = Security.generateKeyPair() | ||||
| 				socket:setupEncryption() | ||||
| 				socket.transmit(socket.dport, socket.sport, { | ||||
| 					type = 'CONN', | ||||
| 					dhost = socket.dhost, | ||||
| @@ -241,7 +235,7 @@ function Socket.server(port) | ||||
|  | ||||
| 				-- Logger.log('socket', 'Connection established %d->%d', socket.sport, socket.dport) | ||||
|  | ||||
| 				_G.transport.open(socket) | ||||
| 				network.getTransport().open(socket) | ||||
| 				return socket | ||||
|  | ||||
| 			else | ||||
|   | ||||
| @@ -20,6 +20,7 @@ function Util.hexToByteArray(str) | ||||
| end | ||||
|  | ||||
| function Util.byteArrayToHex(tbl) | ||||
| 	if not tbl then error('byteArrayToHex: invalid table', 2) end | ||||
| 	return ("%02x"):rep(#tbl):format(unpack(tbl)) | ||||
| end | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 kepler155c@gmail.com
					kepler155c@gmail.com