如何在 python telnetlib 中禁用 telnet echo?
Posted
技术标签:
【中文标题】如何在 python telnetlib 中禁用 telnet echo?【英文标题】:How to disable telnet echo in python telnetlib? 【发布时间】:2012-09-07 10:59:43 【问题描述】:您好,我知道我应该发送“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()
【问题讨论】:
【参考方案1】:您发送的序列错误:
# diable echo here
tn.write(telnetlib.IAC + "\n")
tn.write(telnetlib.DONT + " " + telnetlib.ECHO + "\n")
IAC DONT ECHO
作为三个字节发送,没有任何填充、空格或换行符。所以试试这个:
tn.write(telnetlib.IAC + telnetlib.DONT + telnetlib.ECHO)
但是,实际上关闭回声可能还不够。最常用的解决方案其实就是说你会做echoing,这样会让对方停止做echoing:
tn.write(telnetlib.IAC + telnetlib.WILL + telnetlib.ECHO)
编辑:阅读telnetlib manual page后,我看到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)
【讨论】:
在对调试输出进行大量实验和分析之后,我得出结论,我一直试图与 telnetlib 通信的 telnetd 不支持禁用其 ECHO。不幸的是,WILL ECHO 或 DONT ECHO 或任何类似的组合都没有效果,除了让服务器告诉我做相反的事情。我要说的是,即使使用 get_socket() 方法(确实回答了问题),人们可能会发现实际上禁用回声没有成功。 :-( 做了同样的检查。如果设备为您发送到设备的每个 telnet 命令发送用于光标闪烁和光标移动的控制字符,并且您真的不需要所有大量的回显,这会令人沮丧。【参考方案2】:在当前状态下使用 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)
【讨论】:
【参考方案3】:可能是 telnet-server 只是忽略了您的 telnet-requests,就像我尝试反对的那个一样。然而,没有必要实际编辑 telnetlib 代码,至少在 telnet 服务器确实自己发送初始 IAC 命令的情况下。至少在 python 3.5 中,telnetlib 提供了一个回调来处理 IAC 命令。见*** answer on negotiating telnet line length。即:安装一个与 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 服务器转换的良好输出。现在您可以通过检查 telnet_option_negotiation_cb() 中的给定选项并提供自定义答案而不是标准答案来更改您的答案,即 ECHO。即:
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)
【讨论】:
以上是关于如何在 python telnetlib 中禁用 telnet echo?的主要内容,如果未能解决你的问题,请参考以下文章