-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathTCP_23_telnet.lua
137 lines (129 loc) · 3.32 KB
/
TCP_23_telnet.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
return function(socket)
local fifo = {}
local rxbuffer = ''
local ctl = false
local auth = 0
local username = ''
local ctx = {}
local txbytes = 0
local sync_limit=20000
local function sender(c,sync)
if #fifo > 0 then
local str=table.remove(fifo, 1)
txbytes=txbytes+str:len()
c:send(str)
if (tmr.wdclr) then
tmr.wdclr()
end
else
txbytes=0
end
end
local function strip_lf()
if (rxbuffer:byte(1) == 0x0a) then
rxbuffer=rxbuffer:sub(2)
end
end
local function get_line()
strip_lf()
local pos=rxbuffer:find('\r')
if (pos == nil) then
return nil
end
local ret=rxbuffer:sub(1,pos-1)
rxbuffer=rxbuffer:sub(pos+1)
strip_lf()
return ret
end
local function s_output(str)
if (str == nil or str == '') then
return
end
table.insert(fifo, str)
if (txbytes == 0 or txbytes+str:len() < sync_limit) then
sender(socket)
end
end
local function write(self,str)
s_output(str)
end
local function close()
local t=tmr.create()
t:alarm(50, tmr.ALARM_SINGLE, function()
socket:close()
socket=nil
end)
end
socket:on("receive", function(c, l)
rxbuffer=rxbuffer .. l
while (rxbuffer:byte(1) == 0xff and rxbuffer:len()>=3) do
local next=4
if (rxbuffer:byte(2) == 0xfa) then
_,next=rxbuffer:find(string.char(0xff)..string.char(0xf0))
if (next == nil) then
return
end
next=next+1
end
if (ctl == false) then
ctl = true
s_output(string.char(0xff)..string.char(0xfd)..string.char(0x22).. -- DO LINEMODE
string.char(0xff)..string.char(0xfa)..string.char(0x22).. -- SUBNEGOTIATE BEGIN
string.char(1)..string.char(1).. -- LINEMODE EDIT
string.char(0xff)..string.char(0xf0)) -- SUBNEGOTIATE END
end
rxbuffer=rxbuffer:sub(next)
end
local line=get_line()
if (line == nil) then
return
end
if (auth == 0) then
username=line
if (ctl) then
s_output(string.char(0xff)..string.char(0xfb)..string.char(0x01)) -- WILL ECHO
end
s_output("Password: ")
auth=1
elseif (auth == 1) then
s_output("\r\n")
if (ctl) then
s_output(string.char(0xff)..string.char(0xfc)..string.char(0x01)) -- WONT ECHO
end
if (require('auth').authenticate(username,line,true)) then
if (username == 'lua') then auth=2 end
if (username == 'root') then auth=3 end
else
auth=0
end
if (auth < 2) then
s_output("Login incorrect\n")
close()
return
end
if (auth == 2) then
node.output(s_output, 0)
node.input('\n')
elseif (auth == 3) then
require('shell')
ctx.stdin=io:new{write=write}
ctx.stdout=ctx.stdin
ctx.stderr=ctx.stdin
ctx.exit=close
shell.prompt(ctx)
end
elseif (auth == 2) then
node.input(line..'\r')
elseif (auth == 3) then
shell.cmd(ctx, line)
shell.prompt(ctx)
end
end)
socket:on("disconnection", function(c)
if (auth == 2) then
node.output(nil)
end
end)
socket:on("sent", sender)
s_output("Welcome to NodeMCU world.\n"..require('auth').challenge().."\nlogin: ")
end