package telnetOMC import ( "bufio" "fmt" "strings" "sync" "time" "be.ems/lib/dborm" "github.com/reiver/go-telnet" ) type TelnetHandler struct { ListenAddr string ListenPort uint16 UserName string Password string AuthType string MaxConnNum uint8 TagNE string ListenHost string connCount int mu sync.Mutex } func (t *TelnetHandler) HandleTelnetConnection(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() }() reader := bufio.NewReader(r) writer := bufio.NewWriter(w) // 发送欢迎信息 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() if t.HandleAuth(t.AuthType, user, pass) { writer.WriteString("\r\nAuthentication successful!\r\n") writer.Flush() t.HandleCommands(user, t.TagNE, reader, writer) } else { writer.WriteString("\r\nAuthentication failed!\r\n") writer.Flush() } } // 处理命令输入 func (t *TelnetHandler) HandleCommands(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() var commandBuilder strings.Builder for { b, err := reader.ReadByte() if err != nil { return } if b == '\n' || b == '\r' { break } 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()) // command, err := reader.ReadString('\n') // if err != nil { // return // } // command = strings.TrimSpace(command) // 处理其他命令 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() } } 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) }