4

嗨,我知道我应该发送“IAC DONT ECHO”消息,但是我该如何使用 telnetlib 呢?这是我的测试,但它不起作用。

 #!/usr/bin/env python2
 u"""test"""
 # -*- coding: utf-8 -*-

 import sys
 import telnetlib
 import time

 HOST = "10.10.5.1"
 tn = telnetlib.Telnet(HOST, timeout=1)
 tn.read_until("login: ")
 tn.write("login\n")
 tn.read_until("Password: ")
 tn.write("pass\n")

 print "###########"
 time.sleep(0.5)
 print tn.read_very_eager()

 tn.write("ls /\n")
 time.sleep(0.5)
 print tn.read_very_eager()

 # diable echo here
 tn.write(telnetlib.IAC + "\n")
 tn.write(telnetlib.DONT + " " + telnetlib.ECHO + "\n")
 time.sleep(0.5)
 print tn.read_very_eager()

 tn.write("ls /\n")
 time.sleep(0.5)
 print tn.read_very_eager()

 print "########### exit"
 tn.write("exit\n")
 print tn.read_all()
4

3 回答 3

6

您发送的序列错误:

# diable echo here
tn.write(telnetlib.IAC + "\n")
tn.write(telnetlib.DONT + " " + telnetlib.ECHO + "\n")

THEIAC DONT ECHO以三个字节的形式发送,没有任何填充、空格或换行符。所以试试这个:

tn.write(telnetlib.IAC + telnetlib.DONT + telnetlib.ECHO)

但是,实际上关闭回声可能还不够。最常用的解决方案其实就是说会做echoing,这样会让对方停止做echoing:

tn.write(telnetlib.IAC + telnetlib.WILL + telnetlib.ECHO)

编辑:阅读telnetlib 手册页后,我看到该write函数将:

将字符串写入套接字,将任何 IAC 字符加倍。

所以使用 Telnet 对象write函数将无法发送这些序列,您必须获取套接字并使用它来编写序列:

def write_raw_sequence(tn, seq):
    sock = tn.get_socket()
    if sock is not None:
        sock.send(seq)

write_raw_sequence(tn, telnetlib.IAC + telnetlib.WILL + telnetlib.ECHO)
于 2012-09-14T09:45:27.550 回答
1

在当前状态下使用 telnetlib.py 禁用 telnet echo 是不可能的。

telnetlib.py 会自动为您响应 IAC 命令。(参见 telnetlib.process_rawq()) 不幸的是,这是一个简单的实现,只是对传入的请求做出负面响应。当你连接时,远端会发送 IAC WILL ECHO,你端会回复 IAC DONT ECHO。(您可以通过在 telnetlib.py 中将 DEBUGLEVEL 设置为 1 并运行您的代码来确认这一点)。问题很可能是没有正确处理其他命令。

您可以按照以下说明修改 telnetlib.py 以便完全控制控制响应。但是,正确响应需要对 telnet 协议有足够的了解。

您必须通过在 telnetlib.py 中设置第 440 行来禁用自动响应

if c != IAC:

if c:

然后通过注释掉第 289-290 行来禁用 IAC 符号的加倍

if IAC in buffer:
    buffer = buffer.replace(IAC, IAC+IAC)

完成后,以下如何发送 IAC WILL ECHO 的示例将起作用

tn.write(telnetlib.IAC + telnetlib.WILL + telnetlib.ECHO)
于 2015-01-08T23:51:37.413 回答
1

可能是 telnet-server 只是忽略了您的 telnet-requests,就像我试图反对的那样。然而,没有必要实际编辑 telnetlib 代码,至少在 telnet 服务器确实自己发送初始 IAC 命令的情况下。至少在 python 3.5 中,telnetlib 提供了一个回调来处理 IAC 命令。请参阅有关协商 telnet 线路长度的 Stackoverflow 答案。即:安装一个与 telnetlib 相同的回调已经做:

import telnetlib
from telnetlib import DO, DONT, IAC, WILL, WONT


def telnet_option_negotiation_cb(tsocket, command, option):
    """
    :param tsocket: telnet socket object
    :param command: telnet Command
    :param option: telnet option
    :return: None
    """
    if command in (DO, DONT):
        print("CB-send: IAC WONT " + str(ord(option)))
        tsocket.sendall(IAC + WONT + option)
    elif command in (WILL, WONT):
        print("CB-send: IAC DONT " + str(ord(option)))
        tsocket.sendall(IAC + DONT + option)

telnetlib.DEBUGLEVEL = 1
tn = telnetlib.Telnet("192.your.ip.here")
tn.set_option_negotiation_callback(telnet_option_negotiation_cb)

...

该代码设置 telnetlib 调试级别并打印回调答案,这为您提供了与 telnet-server 转换的良好输出。现在您可以通过检查 telnet_option_negotiation_cb() 中的给定选项并提供自定义答案而不是标准答案来更改 ECHO 的答案。IE:

if option == telnetlib.ECHO:
    print("CB-send: IAC WILL ECHO")
    tsocket.sendall(IAC + WILL + option)
    print("CB-send: IAC DONT ECHO")
    tsocket.sendall(IAC + DONT + option)
于 2016-12-20T10:33:30.820 回答