Search code examples
pythontelnettelnetlib

Python telnetlib read_until returns cut off string


[Python telnetlib read_until recv problem]

"read_until" function returns cut off string with long commands.
The commands ran perfectly, but it does not show full texts.
How can I fix this? Please help.

# my code

tn = telnetlib.Telnet(ip, 23, 5)
prompt = ']# '
tn.write('echo "this is a long command for the test purpose... > test.txt"\n')
print tn.read_until(prompt, 1)

# debug output

Telnet(192.168.220.4,23): send 'echo "this is a long command for the test purpose... > test.txt"\n'
Telnet(192.168.220.4,23): recv 'echo "this is a l'
Telnet(192.168.220.4,23): recv 'ong command for the test purpose... > te\r\x00<his is '
Telnet(192.168.220.4,23): recv 'a long command for the test purpose... > tes '
Telnet(192.168.220.4,23): recv ' \x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x0 8t.txt"'
Telnet(192.168.220.4,23): recv '\r\nthis is a long command for the test purpose... >'
Telnet(192.168.220.4,23): recv ' test.txt\r\n[root@RHEL6-5 tmp]# '

# real output

<his is a long command for the test purpose... > test.txt"
this is a long command for the test purpose... > test.txt
[root@RHEL6-5 tmp]#


Solution

  • The issue appears to be occurring due to line-wrapping. I found a solution where setting the window size width to near the max value allows long lines to be received without line-wrapping applied by the telnet server.

    (See the Window Size Option RFC for details on setting the option https://www.ietf.org/rfc/rfc1073.txt )

    import telnetlib
    import struct
    from telnetlib import DO, DONT, IAC, WILL, WONT, NAWS, SB, SE
    
    MAX_WINDOW_WIDTH = 65000  # Max Value: 65535
    MAX_WINDOW_HEIGHT = 5000
    
    
    def set_max_window_size(tsocket, command, option):
        """
        Set Window size to resolve line width issue
        Set Windows size command: IAC SB NAWS <16-bit value> <16-bit value> IAC SE
        --> inform the Telnet server of the window width and height.
        Refer to https://www.ietf.org/rfc/rfc1073.txt
        :param tsocket: telnet socket object
        :param command: telnet Command
        :param option: telnet option
        :return: None
        """
        if option == NAWS:
            width = struct.pack('H', MAX_WINDOW_WIDTH)
            height = struct.pack('H', MAX_WINDOW_HEIGHT)
            tsocket.send(IAC + WILL + NAWS)
            tsocket.send(IAC + SB + NAWS + width + height + IAC + SE)
        # -- below code taken from telnetlib source
        elif command in (DO, DONT):
            tsocket.send(IAC + WONT + option)
        elif command in (WILL, WONT):
            tsocket.send(IAC + DONT + option)
    
    ip = 'x.x.x.x'
    tn = telnetlib.Telnet(ip, 23, timeout=5)
    tn.set_option_negotiation_callback(set_max_window_size)
    
    tn.write('echo "this is a long command for the test purpose... > test.txt"\n')
    
    prompt = ']# '
    print tn.read_until(prompt, timeout=1)