diff --git a/sshsvc/sshsvc.go b/sshsvc/sshsvc.go index 6952f893..bb7c5130 100644 --- a/sshsvc/sshsvc.go +++ b/sshsvc/sshsvc.go @@ -19,6 +19,7 @@ import ( "be.ems/sshsvc/config" "be.ems/sshsvc/logmml" "be.ems/sshsvc/snmp" + telnetOMC "be.ems/sshsvc/telnet" //"github.com/gliderlabs/ssh" "golang.org/x/crypto/ssh" @@ -110,22 +111,34 @@ func main() { log.Fatal("Failed to Listen: ", err) os.Exit(4) } - fmt.Printf("MML SSH server startup, listen port:%d\n", conf.Sshd.ListenPort) + //fmt.Printf("MML SSH server startup, listen port:%d\n", conf.Sshd.ListenPort) // 启动telnet服务器 - telnetUri := fmt.Sprintf("%s:%d", conf.TelnetServer.ListenAddr, conf.TelnetServer.ListenPort) + //telnetUri := fmt.Sprintf("%s:%d", conf.TelnetServer.ListenAddr, conf.TelnetServer.ListenPort) // telnetListener, err := net.Listen("tcp", telnetUri) // if err != nil { // log.Fatal("Failed to Listen: ", err) // os.Exit(4) // } - fmt.Printf("MML Telnet server startup, listen port:%d\n", conf.TelnetServer.ListenPort) + //fmt.Printf("MML Telnet server startup, listen port:%d\n", conf.TelnetServer.ListenPort) // telnetconn, err := telnetListener.Accept() // if err != nil { // log.Fatal("Failed to accept telnet connection: ", err) // os.Exit(6) // } - go startTelnetServer(telnetUri) + telnetSvc := telnetOMC.TelnetHandler{ + // ListenAddr: conf.TelnetServer.ListenAddr, + // ListenPort: conf.TelnetServer.ListenPort, + // UserName: conf.TelnetServer.UserName, + // Password: conf.TelnetServer.Password, + // AuthType: conf.TelnetServer.AuthType, + // MaxConnNum: conf.TelnetServer.MaxConnNum, + // TagNE: conf.TelnetServer.TagNE, + ListenHost: conf.TelnetServer.ListenAddr + ":" + strconv.Itoa(int(conf.TelnetServer.ListenPort)), + } + // go telnetSvc.StartTelnetServer() + go StartTelnetServer(telnetSvc.ListenHost) + snmpSvc := snmp.SNMPService{ ListenAddr: conf.SNMPServer.ListenAddr, ListenPort: conf.SNMPServer.ListenPort, @@ -183,7 +196,7 @@ func handleAuth(authType, userName, password string) bool { return false } -func startTelnetServer(addr string) { +func StartTelnetServer(addr string) { listener, err := net.Listen("tcp", addr) if err != nil { fmt.Println("Error starting Telnet server:", err) @@ -202,7 +215,7 @@ func startTelnetServer(addr string) { telnetMu.Lock() if telnetCC >= int(conf.TelnetServer.MaxConnNum) { telnetMu.Unlock() - io.WriteString(conn, "Connection limit reached. Try again later.\n") + io.WriteString(conn, "Connection limit reached. Try again later.\r\n") conn.Close() continue } @@ -225,7 +238,7 @@ func handleTelnetConnection(conn net.Conn) { writer := bufio.NewWriter(conn) // 发送欢迎信息 - writer.WriteString("Welcome to the Telnet server!\n") + writer.WriteString("Welcome to the Telnet server!\r\n") writer.Flush() // 请求用户名 @@ -266,41 +279,102 @@ func handleTelnetConnection(conn net.Conn) { writer.Flush() if handleAuth(conf.TelnetServer.AuthType, user, pass) { - writer.WriteString("\nAuthentication successful!\n") + writer.WriteString("\r\nAuthentication successful!\r\n") writer.Flush() - handleCommands(user, conf.TelnetServer.TagNE, reader, writer) + HandleCommands(user, conf.TelnetServer.TagNE, reader, writer) } else { - writer.WriteString("\nAuthentication failed!\n") + writer.WriteString("\r\nAuthentication failed!\r\n") + writer.Flush() + } +} + +// 处理命令输 +func HandleCommands(user, tag string, reader *bufio.Reader, writer *bufio.Writer) { + header := fmt.Sprintf("[%s@%s]> ", user, tag) + clearLine := "\033[2K\r" // ANSI 转义序列,用于清除当前行 + for { + var commandBuilder strings.Builder + for { + b, err := reader.ReadByte() + if err != nil { + return + } + if b == '\n' || b == '\r' { + break + } + if b == '\xff' || b == '\xfe' || b == '\x01' { + continue + } + if b == 127 { // 处理退格键 + if commandBuilder.Len() > 0 { + // 手动截断字符串 + command := commandBuilder.String() + command = command[:len(command)-1] + commandBuilder.Reset() + commandBuilder.WriteString(command) + writer.WriteString("\b \b") // 回显退格 + writer.Flush() + } + } else { + // 回显用户输入的字符 + writer.WriteByte(b) + writer.Flush() + commandBuilder.WriteByte(b) + } + } + command := strings.TrimSpace(commandBuilder.String()) + + // 处理其他命令 + 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 + case "": + // case "\n": + // case "\r\n": + case "\xff\xfe\x01": + default: + writer.WriteString("\r\nUnknown command\r\n") + writer.Flush() + } + writer.WriteString(clearLine + header) writer.Flush() } } // 处理命令输入 -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("Hello, world!\n") + writer.WriteString("\r\nHello, world!\r\n") case "time": - writer.WriteString(fmt.Sprintf("Current time: %s\n", time.Now().Format(time.RFC1123))) + writer.WriteString(fmt.Sprintf("\r\nCurrent time: %s\r\n", time.Now().Format(time.RFC1123))) case "exit", "quit": - writer.WriteString("Goodbye!\n") + writer.WriteString("\r\nGoodbye!\r\n") writer.Flush() return - case "": - case "\n": - case "\xff\xfe\x01": default: - writer.WriteString("Unknown command\n") + writer.WriteString("\r\nUnknown command\r\n") } - writer.WriteString(header) + writer.Flush() } }