mirror of
https://github.com/kepler155c/opus
synced 2024-09-27 22:58:14 +00:00
secure telnet
This commit is contained in:
parent
1c29197983
commit
67779ab814
@ -6,7 +6,7 @@ local kernel = _G.kernel
|
|||||||
local term = _G.term
|
local term = _G.term
|
||||||
local window = _G.window
|
local window = _G.window
|
||||||
|
|
||||||
local function telnetHost(socket)
|
local function telnetHost(socket, mode)
|
||||||
local methods = { 'clear', 'clearLine', 'setCursorPos', 'write', 'blit',
|
local methods = { 'clear', 'clearLine', 'setCursorPos', 'write', 'blit',
|
||||||
'setTextColor', 'setTextColour', 'setBackgroundColor',
|
'setTextColor', 'setTextColour', 'setBackgroundColor',
|
||||||
'setBackgroundColour', 'scroll', 'setCursorBlink', }
|
'setBackgroundColour', 'scroll', 'setCursorBlink', }
|
||||||
@ -43,7 +43,7 @@ local function telnetHost(socket)
|
|||||||
local shellThread = kernel.run({
|
local shellThread = kernel.run({
|
||||||
terminal = win,
|
terminal = win,
|
||||||
window = win,
|
window = win,
|
||||||
title = 'Telnet client',
|
title = mode .. ' client',
|
||||||
hidden = true,
|
hidden = true,
|
||||||
co = coroutine.create(function()
|
co = coroutine.create(function()
|
||||||
Util.run(_ENV, 'sys/apps/shell.lua', table.unpack(termInfo.program))
|
Util.run(_ENV, 'sys/apps/shell.lua', table.unpack(termInfo.program))
|
||||||
@ -68,6 +68,23 @@ local function telnetHost(socket)
|
|||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Event.addRoutine(function()
|
||||||
|
print('ssh: listening on port 22')
|
||||||
|
while true do
|
||||||
|
local socket = Socket.server(22, { ENCRYPT = true })
|
||||||
|
|
||||||
|
print('ssh: connection from ' .. socket.dhost)
|
||||||
|
|
||||||
|
Event.addRoutine(function()
|
||||||
|
local s, m = pcall(telnetHost, socket, 'SSH')
|
||||||
|
if not s and m then
|
||||||
|
print('ssh error')
|
||||||
|
_G.printError(m)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
Event.addRoutine(function()
|
Event.addRoutine(function()
|
||||||
print('telnet: listening on port 23')
|
print('telnet: listening on port 23')
|
||||||
while true do
|
while true do
|
||||||
@ -76,7 +93,7 @@ Event.addRoutine(function()
|
|||||||
print('telnet: connection from ' .. socket.dhost)
|
print('telnet: connection from ' .. socket.dhost)
|
||||||
|
|
||||||
Event.addRoutine(function()
|
Event.addRoutine(function()
|
||||||
local s, m = pcall(telnetHost, socket)
|
local s, m = pcall(telnetHost, socket, 'Telnet')
|
||||||
if not s and m then
|
if not s and m then
|
||||||
print('Telnet error')
|
print('Telnet error')
|
||||||
_G.printError(m)
|
_G.printError(m)
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
* background read buffering
|
* background read buffering
|
||||||
]]--
|
]]--
|
||||||
|
|
||||||
local Event = require('opus.event')
|
local Crypto = require('opus.crypto.chacha20')
|
||||||
|
local Event = require('opus.event')
|
||||||
|
|
||||||
local network = _G.network
|
local network = _G.network
|
||||||
local os = _G.os
|
local os = _G.os
|
||||||
@ -32,7 +33,10 @@ end
|
|||||||
function transport.read(socket)
|
function transport.read(socket)
|
||||||
local data = table.remove(socket.messages, 1)
|
local data = table.remove(socket.messages, 1)
|
||||||
if data then
|
if data then
|
||||||
return unpack(data)
|
if socket.options.ENCRYPT then
|
||||||
|
return table.unpack(Crypto.decrypt(data[1], socket.enckey)), data[2]
|
||||||
|
end
|
||||||
|
return table.unpack(data)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ local read = _G.read
|
|||||||
local shell = _ENV.shell
|
local shell = _ENV.shell
|
||||||
local term = _G.term
|
local term = _G.term
|
||||||
|
|
||||||
local args = { ... }
|
local args, options = Util.parse(...)
|
||||||
|
|
||||||
local remoteId = tonumber(table.remove(args, 1) or '')
|
local remoteId = tonumber(table.remove(args, 1) or '')
|
||||||
if not remoteId then
|
if not remoteId then
|
||||||
@ -22,13 +22,14 @@ if not remoteId then
|
|||||||
end
|
end
|
||||||
|
|
||||||
if multishell then
|
if multishell then
|
||||||
multishell.setTitle(multishell.getCurrent(), 'Telnet ' .. remoteId)
|
multishell.setTitle(multishell.getCurrent(),
|
||||||
|
(options.s and 'Secure ' or 'Telnet ') .. remoteId)
|
||||||
end
|
end
|
||||||
|
|
||||||
local socket, msg, reason
|
local socket, msg, reason
|
||||||
|
|
||||||
while true do
|
while true do
|
||||||
socket, msg, reason = Socket.connect(remoteId, 23)
|
socket, msg, reason = Socket.connect(remoteId, options.s and 22 or 23)
|
||||||
|
|
||||||
if socket then
|
if socket then
|
||||||
break
|
break
|
||||||
|
@ -166,10 +166,10 @@ local function decrypt(data, key)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local obj = {}
|
local obj = {}
|
||||||
local mt = {['__index'] = obj}
|
local rng_mt = {['__index'] = obj}
|
||||||
|
|
||||||
function obj:nextInt(byte)
|
function obj:nextInt(byte)
|
||||||
if byte < 1 or byte > 6 then error("Can only return 1-6 bytes", 2) end
|
if not byte or byte < 1 or byte > 6 then error("Can only return 1-6 bytes", 2) end
|
||||||
local output = 0
|
local output = 0
|
||||||
for i = 0, byte-1 do
|
for i = 0, byte-1 do
|
||||||
if #self.block == 0 then
|
if #self.block == 0 then
|
||||||
@ -189,7 +189,7 @@ local function newRNG(seed)
|
|||||||
o.cnt = 0
|
o.cnt = 0
|
||||||
o.block = {}
|
o.block = {}
|
||||||
|
|
||||||
return setmetatable(o, mt)
|
return setmetatable(o, rng_mt)
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
local Config = require('opus.config')
|
local Config = require('opus.config')
|
||||||
local ECC = require('opus.crypto.ecc')
|
|
||||||
local Util = require('opus.util')
|
|
||||||
|
|
||||||
local Security = { }
|
local Security = { }
|
||||||
|
|
||||||
@ -13,32 +11,18 @@ function Security.hasPassword()
|
|||||||
return not not Security.getPassword()
|
return not not Security.getPassword()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function genKey()
|
|
||||||
local key = { }
|
|
||||||
for _ = 1, 32 do
|
|
||||||
table.insert(key, ("%02x"):format(math.random(0, 0xFF)))
|
|
||||||
end
|
|
||||||
return table.concat(key)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Security.getSecretKey()
|
|
||||||
local config = Config.load('os')
|
|
||||||
if not config.secretKey then
|
|
||||||
config.secretKey = genKey()
|
|
||||||
Config.update('os', config)
|
|
||||||
end
|
|
||||||
return Util.hexToByteArray(config.secretKey)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Security.getIdentifier()
|
function Security.getIdentifier()
|
||||||
local config = Config.load('os')
|
local config = Config.load('os')
|
||||||
if config.identifier then
|
|
||||||
return config.identifier
|
if not config.identifier then
|
||||||
|
local key = { }
|
||||||
|
for _ = 1, 32 do
|
||||||
|
table.insert(key, ("%02x"):format(math.random(0, 0xFF)))
|
||||||
|
end
|
||||||
|
config.identifier = table.concat(key)
|
||||||
|
|
||||||
|
Config.update('os', config)
|
||||||
end
|
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
|
return config.identifier
|
||||||
end
|
end
|
||||||
|
@ -47,6 +47,9 @@ end
|
|||||||
|
|
||||||
function socketClass:write(data)
|
function socketClass:write(data)
|
||||||
if self.connected then
|
if self.connected then
|
||||||
|
if self.options.ENCRYPT then
|
||||||
|
data = Crypto.encrypt({ data }, self.enckey)
|
||||||
|
end
|
||||||
network.getTransport().write(self, {
|
network.getTransport().write(self, {
|
||||||
type = 'DATA',
|
type = 'DATA',
|
||||||
seq = self.wseq,
|
seq = self.wseq,
|
||||||
@ -70,7 +73,7 @@ function socketClass:setupEncryption(x)
|
|||||||
SHA.pbkdf2(self.sharedKey, x and "4sseed" or "3rseed", 1))
|
SHA.pbkdf2(self.sharedKey, x and "4sseed" or "3rseed", 1))
|
||||||
|
|
||||||
self.sharedKey = ECC.exchange(self.privKey, self.remotePubKey)
|
self.sharedKey = ECC.exchange(self.privKey, self.remotePubKey)
|
||||||
--self.enckey = SHA.pbkdf2(self.sharedKey, "1enc", 1)
|
self.enckey = SHA.pbkdf2(self.sharedKey, "1enc", 1)
|
||||||
--self.hmackey = SHA.pbkdf2(self.sharedKey, "2hmac", 1)
|
--self.hmackey = SHA.pbkdf2(self.sharedKey, "2hmac", 1)
|
||||||
self.rseq = self.rrng:nextInt(5)
|
self.rseq = self.rrng:nextInt(5)
|
||||||
self.wseq = self.wrng:nextInt(5)
|
self.wseq = self.wrng:nextInt(5)
|
||||||
@ -144,15 +147,15 @@ function Socket.connect(host, port, options)
|
|||||||
if e == 'modem_message' and
|
if e == 'modem_message' and
|
||||||
sport == socket.sport and
|
sport == socket.sport and
|
||||||
type(msg) == 'table' and
|
type(msg) == 'table' and
|
||||||
msg.dhost == socket.shost and
|
msg.dhost == socket.shost then
|
||||||
type(msg.pk) == 'string' then
|
|
||||||
|
|
||||||
os.cancelTimer(timerId)
|
os.cancelTimer(timerId)
|
||||||
|
|
||||||
if msg.type == 'CONN' then
|
if msg.type == 'CONN' and type(msg.pk) == 'string' then
|
||||||
socket.dport = dport
|
socket.dport = dport
|
||||||
socket.connected = true
|
socket.connected = true
|
||||||
socket.remotePubKey = Util.hexToByteArray(msg.pk)
|
socket.remotePubKey = Util.hexToByteArray(msg.pk)
|
||||||
|
socket.options = msg.options or { }
|
||||||
socket:setupEncryption(true)
|
socket:setupEncryption(true)
|
||||||
network.getTransport().open(socket)
|
network.getTransport().open(socket)
|
||||||
return socket
|
return socket
|
||||||
@ -210,7 +213,7 @@ function Socket.server(port, options)
|
|||||||
local socket = newSocket(msg.shost == os.getComputerID())
|
local socket = newSocket(msg.shost == os.getComputerID())
|
||||||
socket.dport = dport
|
socket.dport = dport
|
||||||
socket.dhost = msg.shost
|
socket.dhost = msg.shost
|
||||||
socket.options = options
|
socket.options = options or { }
|
||||||
|
|
||||||
if not Security.hasPassword() then
|
if not Security.hasPassword() then
|
||||||
socket.transmit(socket.dport, socket.sport, {
|
socket.transmit(socket.dport, socket.sport, {
|
||||||
@ -227,6 +230,7 @@ function Socket.server(port, options)
|
|||||||
dhost = socket.dhost,
|
dhost = socket.dhost,
|
||||||
shost = socket.shost,
|
shost = socket.shost,
|
||||||
pk = Util.byteArrayToHex(socket.pubKey),
|
pk = Util.byteArrayToHex(socket.pubKey),
|
||||||
|
options = socket.options.ENCRYPT and { ENCRYPT = true },
|
||||||
})
|
})
|
||||||
|
|
||||||
network.getTransport().open(socket)
|
network.getTransport().open(socket)
|
||||||
|
Loading…
Reference in New Issue
Block a user