fix: telnet server update
This commit is contained in:
@@ -19,7 +19,7 @@ import (
|
|||||||
"be.ems/sshsvc/config"
|
"be.ems/sshsvc/config"
|
||||||
"be.ems/sshsvc/logmml"
|
"be.ems/sshsvc/logmml"
|
||||||
"be.ems/sshsvc/snmp"
|
"be.ems/sshsvc/snmp"
|
||||||
telnetOMC "be.ems/sshsvc/telnet"
|
omctelnet "be.ems/sshsvc/telnet"
|
||||||
|
|
||||||
//"github.com/gliderlabs/ssh"
|
//"github.com/gliderlabs/ssh"
|
||||||
"golang.org/x/crypto/ssh"
|
"golang.org/x/crypto/ssh"
|
||||||
@@ -126,18 +126,18 @@ func main() {
|
|||||||
// os.Exit(6)
|
// os.Exit(6)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
telnetSvc := telnetOMC.TelnetHandler{
|
telnetSvc := omctelnet.TelnetHandler{
|
||||||
// ListenAddr: conf.TelnetServer.ListenAddr,
|
ListenAddr: conf.TelnetServer.ListenAddr,
|
||||||
// ListenPort: conf.TelnetServer.ListenPort,
|
ListenPort: conf.TelnetServer.ListenPort,
|
||||||
// UserName: conf.TelnetServer.UserName,
|
UserName: conf.TelnetServer.UserName,
|
||||||
// Password: conf.TelnetServer.Password,
|
Password: conf.TelnetServer.Password,
|
||||||
// AuthType: conf.TelnetServer.AuthType,
|
AuthType: conf.TelnetServer.AuthType,
|
||||||
// MaxConnNum: conf.TelnetServer.MaxConnNum,
|
MaxConnNum: conf.TelnetServer.MaxConnNum,
|
||||||
// TagNE: conf.TelnetServer.TagNE,
|
TagNE: conf.TelnetServer.TagNE,
|
||||||
ListenHost: conf.TelnetServer.ListenAddr + ":" + strconv.Itoa(int(conf.TelnetServer.ListenPort)),
|
ListenHost: conf.TelnetServer.ListenAddr + ":" + strconv.Itoa(int(conf.TelnetServer.ListenPort)),
|
||||||
}
|
}
|
||||||
// go telnetSvc.StartTelnetServer()
|
go telnetSvc.StartTelnetServer()
|
||||||
go StartTelnetServer(telnetSvc.ListenHost)
|
// go StartTelnetServer(telnetSvc.ListenHost)
|
||||||
|
|
||||||
snmpSvc := snmp.SNMPService{
|
snmpSvc := snmp.SNMPService{
|
||||||
ListenAddr: conf.SNMPServer.ListenAddr,
|
ListenAddr: conf.SNMPServer.ListenAddr,
|
||||||
@@ -335,9 +335,6 @@ func HandleCommands(user, tag string, reader *bufio.Reader, writer *bufio.Writer
|
|||||||
writer.Flush()
|
writer.Flush()
|
||||||
return
|
return
|
||||||
case "":
|
case "":
|
||||||
// case "\n":
|
|
||||||
// case "\r\n":
|
|
||||||
case "\xff\xfe\x01":
|
|
||||||
default:
|
default:
|
||||||
writer.WriteString("\r\nUnknown command\r\n")
|
writer.WriteString("\r\nUnknown command\r\n")
|
||||||
writer.Flush()
|
writer.Flush()
|
||||||
@@ -347,38 +344,6 @@ func HandleCommands(user, tag string, reader *bufio.Reader, writer *bufio.Writer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理命令输入
|
|
||||||
func HandleCommandsNew(user, tag string, reader *bufio.Reader, writer *bufio.Writer) {
|
|
||||||
header := fmt.Sprintf("[%s@%s]> ", user, tag)
|
|
||||||
clearLine := "\033[2K\r" // ANSI 转义序列,用于清除当前行
|
|
||||||
for {
|
|
||||||
writer.WriteString(clearLine + header)
|
|
||||||
writer.Flush()
|
|
||||||
|
|
||||||
command, err := reader.ReadString('\n')
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
command = strings.TrimSpace(command)
|
|
||||||
|
|
||||||
// Handle other commands
|
|
||||||
switch command {
|
|
||||||
case "hello":
|
|
||||||
writer.WriteString("\r\nHello, world!\r\n")
|
|
||||||
case "time":
|
|
||||||
writer.WriteString(fmt.Sprintf("\r\nCurrent time: %s\r\n", time.Now().Format(time.RFC1123)))
|
|
||||||
case "exit", "quit":
|
|
||||||
writer.WriteString("\r\nGoodbye!\r\n")
|
|
||||||
writer.Flush()
|
|
||||||
return
|
|
||||||
default:
|
|
||||||
writer.WriteString("\r\nUnknown command\r\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
writer.Flush()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func handleSSHConnection(conn net.Conn, serverConfig *ssh.ServerConfig) {
|
func handleSSHConnection(conn net.Conn, serverConfig *ssh.ServerConfig) {
|
||||||
// SSH握手
|
// SSH握手
|
||||||
sshConn, chans, reqs, err := ssh.NewServerConn(conn, serverConfig)
|
sshConn, chans, reqs, err := ssh.NewServerConn(conn, serverConfig)
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
package telnetOMC
|
package omctelnet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"be.ems/lib/dborm"
|
"be.ems/lib/dborm"
|
||||||
"github.com/reiver/go-telnet"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type TelnetHandler struct {
|
type TelnetHandler struct {
|
||||||
@@ -25,24 +26,66 @@ type TelnetHandler struct {
|
|||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TelnetHandler) HandleTelnetConnection(w telnet.Writer, r telnet.Reader) {
|
func (t *TelnetHandler) handleTelnetAuth(authType, userName, password string) bool {
|
||||||
t.mu.Lock()
|
switch authType {
|
||||||
if t.connCount >= int(t.MaxConnNum) {
|
case "local":
|
||||||
t.mu.Unlock()
|
if userName == t.UserName && password == t.Password {
|
||||||
w.Write([]byte("Connection limit reached. Try again later.\r\n"))
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
case "radius", "omc":
|
||||||
|
exist, err := dborm.XEngDB().Table("OMC_PUB.sysUser").Where("userName=? AND password=md5(?)", userName, password).Exist()
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return exist
|
||||||
|
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TelnetHandler) StartTelnetServer() {
|
||||||
|
listener, err := net.Listen("tcp", t.ListenHost)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error starting Telnet server:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
t.connCount++
|
defer listener.Close()
|
||||||
t.mu.Unlock()
|
fmt.Println("Telnet server started on", t.ListenHost)
|
||||||
|
|
||||||
|
for {
|
||||||
|
conn, err := listener.Accept()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error accepting Telnet connection:", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
t.mu.Lock()
|
||||||
|
if t.connCount >= int(t.MaxConnNum) {
|
||||||
|
t.mu.Unlock()
|
||||||
|
io.WriteString(conn, "Connection limit reached. Try again later.\r\n")
|
||||||
|
conn.Close()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
t.connCount++
|
||||||
|
t.mu.Unlock()
|
||||||
|
|
||||||
|
go t.handleTelnetConnection(conn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TelnetHandler) handleTelnetConnection(conn net.Conn) {
|
||||||
defer func() {
|
defer func() {
|
||||||
t.mu.Lock()
|
t.mu.Lock()
|
||||||
t.connCount--
|
t.connCount--
|
||||||
t.mu.Unlock()
|
t.mu.Unlock()
|
||||||
}()
|
}()
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
reader := bufio.NewReader(r)
|
reader := bufio.NewReader(conn)
|
||||||
writer := bufio.NewWriter(w)
|
writer := bufio.NewWriter(conn)
|
||||||
|
|
||||||
// 发送欢迎信息
|
// 发送欢迎信息
|
||||||
writer.WriteString("Welcome to the Telnet server!\r\n")
|
writer.WriteString("Welcome to the Telnet server!\r\n")
|
||||||
@@ -85,7 +128,7 @@ func (t *TelnetHandler) HandleTelnetConnection(w telnet.Writer, r telnet.Reader)
|
|||||||
writer.Write([]byte{255, 252, 1}) // IAC WONT ECHO
|
writer.Write([]byte{255, 252, 1}) // IAC WONT ECHO
|
||||||
writer.Flush()
|
writer.Flush()
|
||||||
|
|
||||||
if t.HandleAuth(t.AuthType, user, pass) {
|
if t.handleTelnetAuth(t.AuthType, user, pass) {
|
||||||
writer.WriteString("\r\nAuthentication successful!\r\n")
|
writer.WriteString("\r\nAuthentication successful!\r\n")
|
||||||
writer.Flush()
|
writer.Flush()
|
||||||
t.HandleCommands(user, t.TagNE, reader, writer)
|
t.HandleCommands(user, t.TagNE, reader, writer)
|
||||||
@@ -95,14 +138,11 @@ func (t *TelnetHandler) HandleTelnetConnection(w telnet.Writer, r telnet.Reader)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理命令输入
|
// 处理命令输
|
||||||
func (t *TelnetHandler) HandleCommands(user, tag string, reader *bufio.Reader, writer *bufio.Writer) {
|
func (t *TelnetHandler) HandleCommands(user, tag string, reader *bufio.Reader, writer *bufio.Writer) {
|
||||||
header := fmt.Sprintf("[%s@%s]> ", user, tag)
|
header := fmt.Sprintf("[%s@%s]> ", user, tag)
|
||||||
clearLine := "\033[2K\r" // ANSI 转义序列,用于清除当前行
|
clearLine := "\033[2K\r" // ANSI 转义序列,用于清除当前行
|
||||||
for {
|
for {
|
||||||
writer.WriteString(clearLine + header)
|
|
||||||
writer.Flush()
|
|
||||||
|
|
||||||
var commandBuilder strings.Builder
|
var commandBuilder strings.Builder
|
||||||
for {
|
for {
|
||||||
b, err := reader.ReadByte()
|
b, err := reader.ReadByte()
|
||||||
@@ -112,6 +152,9 @@ func (t *TelnetHandler) HandleCommands(user, tag string, reader *bufio.Reader, w
|
|||||||
if b == '\n' || b == '\r' {
|
if b == '\n' || b == '\r' {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
if b == '\xff' || b == '\xfe' || b == '\x01' {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if b == 127 { // 处理退格键
|
if b == 127 { // 处理退格键
|
||||||
if commandBuilder.Len() > 0 {
|
if commandBuilder.Len() > 0 {
|
||||||
// 手动截断字符串
|
// 手动截断字符串
|
||||||
@@ -131,12 +174,6 @@ func (t *TelnetHandler) HandleCommands(user, tag string, reader *bufio.Reader, w
|
|||||||
}
|
}
|
||||||
command := strings.TrimSpace(commandBuilder.String())
|
command := strings.TrimSpace(commandBuilder.String())
|
||||||
|
|
||||||
// command, err := reader.ReadString('\n')
|
|
||||||
// if err != nil {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// command = strings.TrimSpace(command)
|
|
||||||
|
|
||||||
// 处理其他命令
|
// 处理其他命令
|
||||||
switch command {
|
switch command {
|
||||||
case "hello":
|
case "hello":
|
||||||
@@ -148,161 +185,11 @@ func (t *TelnetHandler) HandleCommands(user, tag string, reader *bufio.Reader, w
|
|||||||
writer.Flush()
|
writer.Flush()
|
||||||
return
|
return
|
||||||
case "":
|
case "":
|
||||||
// case "\n":
|
|
||||||
// case "\r\n":
|
|
||||||
case "\xff\xfe\x01":
|
|
||||||
default:
|
default:
|
||||||
writer.WriteString("\r\nUnknown command\r\n")
|
writer.WriteString("\r\nUnknown command\r\n")
|
||||||
|
writer.Flush()
|
||||||
}
|
}
|
||||||
|
writer.WriteString(clearLine + header)
|
||||||
writer.Flush()
|
writer.Flush()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TelnetHandler) ServeTELNET(ctx telnet.Context, w telnet.Writer, r telnet.Reader) {
|
|
||||||
t.mu.Lock()
|
|
||||||
if t.connCount >= int(t.MaxConnNum) {
|
|
||||||
t.mu.Unlock()
|
|
||||||
w.Write([]byte("Connection limit reached. Try again later.\r\n"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
t.connCount++
|
|
||||||
t.mu.Unlock()
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
t.mu.Lock()
|
|
||||||
t.connCount--
|
|
||||||
t.mu.Unlock()
|
|
||||||
}()
|
|
||||||
|
|
||||||
writer := bufio.NewWriter(w)
|
|
||||||
reader := bufio.NewReader(r)
|
|
||||||
// 发送欢迎信息
|
|
||||||
writer.WriteString("Welcome to the Telnet server!\r\n")
|
|
||||||
writer.Flush()
|
|
||||||
|
|
||||||
// 请求用户名
|
|
||||||
writer.WriteString("Username: ")
|
|
||||||
writer.Flush()
|
|
||||||
user, _ := reader.ReadString('\n')
|
|
||||||
user = strings.TrimSpace(user)
|
|
||||||
|
|
||||||
// 关闭回显模式
|
|
||||||
writer.Write([]byte{255, 251, 1}) // IAC WILL ECHO
|
|
||||||
writer.Flush()
|
|
||||||
|
|
||||||
// 请求密码
|
|
||||||
writer.WriteString("Password: ")
|
|
||||||
writer.Flush()
|
|
||||||
|
|
||||||
// 读取密码并清除控制序列
|
|
||||||
var passBuilder strings.Builder
|
|
||||||
for {
|
|
||||||
b, err := reader.ReadByte()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if b == '\n' || b == '\r' {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if b == 255 { // IAC
|
|
||||||
reader.ReadByte() // 忽略下一个字节
|
|
||||||
reader.ReadByte() // 忽略下一个字节
|
|
||||||
} else {
|
|
||||||
passBuilder.WriteByte(b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pass := passBuilder.String()
|
|
||||||
|
|
||||||
// 恢复回显模式
|
|
||||||
writer.Write([]byte{255, 252, 1}) // IAC WONT ECHO
|
|
||||||
writer.Flush()
|
|
||||||
|
|
||||||
// w.Write([]byte("Welcome to the Telnet server!\r\n"))
|
|
||||||
// w.Write([]byte("Username: "))
|
|
||||||
// writer := bufio.NewWriter(w)
|
|
||||||
// reader := bufio.NewReader(r)
|
|
||||||
// writer.Flush()
|
|
||||||
|
|
||||||
// user, _ := reader.ReadString('\n')
|
|
||||||
// user = strings.TrimSpace(user)
|
|
||||||
|
|
||||||
// w.Write([]byte("Password: "))
|
|
||||||
// writer.Flush()
|
|
||||||
|
|
||||||
// pass, _ := reader.ReadString('\n')
|
|
||||||
// pass = strings.TrimSpace(pass)
|
|
||||||
|
|
||||||
if !t.HandleAuth(t.AuthType, user, pass) {
|
|
||||||
w.Write([]byte("\r\nAuthentication failed!\r\n"))
|
|
||||||
writer.Flush()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Write([]byte("\r\nAuthentication successful!\r\n"))
|
|
||||||
writer.Flush()
|
|
||||||
|
|
||||||
header := fmt.Sprintf("[%s@%s]> ", t.UserName, t.TagNE)
|
|
||||||
for {
|
|
||||||
w.Write([]byte(header))
|
|
||||||
var command strings.Builder
|
|
||||||
for {
|
|
||||||
b := make([]byte, 1)
|
|
||||||
_, err := r.Read(b)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if b[0] == '\r' || b[0] == '\n' {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
command.WriteByte(b[0])
|
|
||||||
}
|
|
||||||
cmd := strings.TrimSpace(command.String())
|
|
||||||
switch cmd {
|
|
||||||
case "hello":
|
|
||||||
w.Write([]byte("Hello, world!\r\n"))
|
|
||||||
case "time":
|
|
||||||
w.Write([]byte(fmt.Sprintf("Current time: %s\r\n", time.Now().Format(time.RFC1123))))
|
|
||||||
case "exit", "quit":
|
|
||||||
w.Write([]byte("Goodbye!\r\n"))
|
|
||||||
return
|
|
||||||
default:
|
|
||||||
w.Write([]byte("Unknown command\r\n"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *TelnetHandler) HandleAuth(authType, userName, password string) bool {
|
|
||||||
switch authType {
|
|
||||||
case "local":
|
|
||||||
if userName == t.UserName && password == t.Password {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
case "radius":
|
|
||||||
exist, err := dborm.XEngDB().Table("OMC_PUB.sysUser").Where("userName=? AND password=md5(?)", userName, password).Exist()
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return exist
|
|
||||||
case "omc":
|
|
||||||
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *TelnetHandler) StartTelnetServer() {
|
|
||||||
// //handle := TelnetHandler{}
|
|
||||||
// listener, err := net.Listen("tcp", t.ListenHost)
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println("Error starting Telnet server:", err)
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// defer listener.Close()
|
|
||||||
// fmt.Printf("Telnet server started on %s\n", t.ListenHost)
|
|
||||||
|
|
||||||
// go telnet.Serve(listener, t)
|
|
||||||
go telnet.ListenAndServe(t.ListenHost, t)
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user