1#!/usr/bin/env python 2 3 4import time 5import socket 6import logging 7import telnetlib 8from collections import deque 9 10 11class TelnetRemoteclient: 12 13 r""" 14 Class to create telnet connection to remote host for command execution. 15 """ 16 17 def __init__(self, hostname, username, password, port=23, read_timeout=None): 18 19 r""" 20 Description of argument(s): 21 22 hostname Name/IP of the remote (targeting) host 23 username User on the remote host with access to FFCD files 24 password Password for user on remote host 25 read_timeout New read timeout value to override default one 26 """ 27 28 self.hostname = hostname 29 self.username = username 30 self.password = password 31 self.tnclient = None 32 self.port = port 33 self.read_timeout = read_timeout 34 35 def tn_remoteclient_login(self): 36 37 is_telnet = True 38 try: 39 self.tnclient = telnetlib.Telnet(self.hostname, self.port, timeout=15) 40 if b'login:' in self.tnclient.read_until(b'login:', timeout=self.read_timeout): 41 self.tnclient.write(self.username.encode('utf-8') + b"\n") 42 43 if b'Password:' in self.tnclient.read_until(b'Password:', timeout=self.read_timeout): 44 self.tnclient.write(self.password.encode('utf-8') + b"\n") 45 46 n, match, pre_match = \ 47 self.tnclient.expect( 48 [b'Login incorrect', b'invalid login name or password.', br'\#', br'\$'], 49 timeout=self.read_timeout) 50 if n == 0 or n == 1: 51 logging.error( 52 "\n\tERROR: Telnet Authentication Failed. Check userid and password.\n\n") 53 is_telnet = False 54 else: 55 # login successful 56 self.fifo = deque() 57 else: 58 # Anything else, telnet server is not running 59 logging.error("\n\tERROR: Telnet Connection Refused.\n\n") 60 is_telnet = False 61 else: 62 is_telnet = False 63 except Exception: 64 # Any kind of exception, skip telnet protocol 65 is_telnet = False 66 67 return is_telnet 68 69 def __del__(self): 70 self.tn_remoteclient_disconnect() 71 72 def tn_remoteclient_disconnect(self): 73 try: 74 self.tnclient.close() 75 except Exception: 76 # the telnet object might not exist yet, so ignore this one 77 pass 78 79 def execute_command(self, cmd, 80 i_timeout=300): 81 82 r''' 83 Executes commands on the remote host 84 85 Description of argument(s): 86 cmd Command to run on remote host 87 rtnpartial Set to True to return command output even 88 if we haven't read the command prompt 89 wait_cnt Number of times to check for command output 90 default is 5 91 i_timeout Timeout for command output 92 default is 300 seconds 93 ''' 94 95 # Execute the command and read the command output 96 return_buffer = b'' 97 try: 98 99 # Do at least one non-blocking read 100 # to flush whatever data is in the read buffer. 101 while self.tnclient.read_very_eager(): 102 continue 103 104 # Execute the command 105 self.tnclient.write(cmd.encode('utf-8') + b'\n') 106 time.sleep(i_timeout) 107 108 local_buffer = b'' 109 # Read the command output one block at a time. 110 return_buffer = self.tnclient.read_very_eager() 111 while return_buffer: 112 local_buffer = b''.join([local_buffer, return_buffer]) 113 time.sleep(3) # let the buffer fill up a bit 114 return_buffer = self.tnclient.read_very_eager() 115 116 except (socket.error, EOFError) as e: 117 self.tn_remoteclient_disconnect() 118 119 if str(e).__contains__("Connection reset by peer"): 120 msg = e 121 elif str(e).__contains__("telnet connection closed"): 122 msg = "Telnet connection closed." 123 else: 124 msg = "Some other issue.%s %s %s\n\n" % (cmd, e.__class__, e) 125 126 logging.error("\t\t ERROR %s " % msg) 127 128 # Return ASCII string data with ending PROMPT stripped 129 return local_buffer.decode('ascii', 'ignore').replace('$ ', '\n') 130