From 5842303b3cca30c189b05662a4090ffab3fd2351 Mon Sep 17 00:00:00 2001 From: Lonny Wong Date: Sat, 3 Feb 2024 15:37:53 +0800 Subject: [PATCH] support expect pass sleep --- README.cn.md | 5 +++++ README.en.md | 5 +++++ tssh/expect.go | 37 ++++++++++++++++++++++++++++++++++--- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/README.cn.md b/README.cn.md index 6a163fd..aa7a8c2 100644 --- a/README.cn.md +++ b/README.cn.md @@ -428,6 +428,11 @@ trzsz-ssh ( tssh ) 设计为 ssh 客户端的直接替代品,提供与 openssh #!! ExpectSendText2 \|1\|\|\r # 先 sleep 100ms,然后发送 1,再 sleep 200ms,最后发送 \r 回车 ``` +- 有些服务器连密码也不支持连着发送,则需要配置 `ExpectPassSleep`,默认为 `no`,可配置为 `each` 或 `enter`: + + - 配置 `ExpectPassSleep each` 则每输入一个字符就 sleep 一小段时间,默认 100 毫秒,可配置 `ExpectSleepMS` 进行调整。 + - 配置 `ExpectPassSleep enter` 则只是在发送 `\r` 回车之前 sleep 一小段时间,默认 100 毫秒,可配置 `ExpectSleepMS` 进行调整。 + - 如果不知道 `ExpectPattern2` 如何配置,可以先将 `ExpectCount` 配置为 `2`,然后使用 `tssh --debug` 登录,就会看到 `expect` 捕获到的输出,可以直接复制输出的最后部分来配置 `ExpectPattern2`。把 `2` 换成其他任意的数字也适用。 ## 记住密码 diff --git a/README.en.md b/README.en.md index d2c2437..464b102 100644 --- a/README.en.md +++ b/README.en.md @@ -428,6 +428,11 @@ trzsz-ssh ( tssh ) is an ssh client designed as a drop-in replacement for the op #!! ExpectSendText2 \|1\|\|\r # Configures the second automated input, sleep 100ms, send 1, sleep 200ms, send \r. ``` +- Some servers may not support sending password continuously. Then you need to configure `ExpectPassSleep`, which is `no` by default, and can be configured as `each` or `enter`: + + - Configuring `ExpectPassSleep each` will sleep for a short period of time for each character send, the default is 100 milliseconds, and you can configure `ExpectSleepMS` to adjust it. + - Configuring `ExpectPassSleep enter` will only sleep for a short period of time before `\r` send, the default is 100 milliseconds, and you can configure `ExpectSleepMS` to adjust it. + - If you don’t know how to configure `ExpectPattern2`, you can first configure `ExpectCount` to `2`, then use `tssh --debug` to log in, you will see the output captured by `expect`, and you can directly copy the last part of the output to configure `ExpectPattern2`. Replacing `2` with any other number will also work. ## Remember Password diff --git a/tssh/expect.go b/tssh/expect.go index 62a2bcb..9f3bc7c 100644 --- a/tssh/expect.go +++ b/tssh/expect.go @@ -122,6 +122,18 @@ func (s *expectSender) decodeText(text string) [][]string { return texts } +func (s *expectSender) getExpectPsssSleep() (bool, bool) { + passSleep := getExConfig(s.expect.alias, fmt.Sprintf("%sExpectPassSleep", s.expect.pre)) + switch strings.ToLower(passSleep) { + case "each": + return true, false + case "enter": + return false, true + default: + return false, false + } +} + func (s *expectSender) getExpectSleepTime() time.Duration { expectSleepMS := getExConfig(s.expect.alias, fmt.Sprintf("%sExpectSleepMS", s.expect.pre)) if expectSleepMS == "" { @@ -140,15 +152,34 @@ func (s *expectSender) sendInput(writer io.Writer, id string) bool { warning("expect %s send nothing", id) return true } + var sleepTime time.Duration if s.passwd { - debug("expect %s send: %s\\r", id, strings.Repeat("*", len(s.input))) - if err := writeAll(writer, []byte(s.input+"\r")); err != nil { + eachSleep, enterSleep := s.getExpectPsssSleep() + if eachSleep || enterSleep { + sleepTime = s.getExpectSleepTime() + } + for _, input := range []byte(s.input) { + debug("expect %s send: %s", id, "*") + if err := writeAll(writer, []byte{input}); err != nil { + warning("expect %s send input failed: %v", id, err) + return false + } + if eachSleep { + debug("expect %s sleep: %v", id, sleepTime) + time.Sleep(sleepTime) + } + } + if enterSleep { + debug("expect %s sleep: %v", id, sleepTime) + time.Sleep(sleepTime) + } + debug("expect %s send: \\r", id) + if err := writeAll(writer, []byte("\r")); err != nil { warning("expect %s send input failed: %v", id, err) return false } return true } - var sleepTime time.Duration for i, text := range s.decodeText(s.input) { if i > 0 { if i == 1 {