def get_result(): try: data = request.get_json(True) address = data['host'] account = Account(name=data['user'], password=data['passwd']) if data['conntype'] == 'SSH': from Exscript.protocols import SSH2 conn = SSH2() elif data['conntype'] == 'Telnet': from Exscript.protocols import Telnet conn = Telnet() else: raise(Exception('Unsupport connection type')) conn.connect(address) conn.login(account) conn.execute(data['command']) response = to_plain(str(conn.response)) conn.send('exit\n') conn.close() return jsonify(success=True, response=response) except Exception as e: return jsonify(success=False, response="Opus! Some guy poisoned my coffee last night!")
def get_configs(proto, account, host, t_out=30): try: if proto == "ssh": if t_out == 30: conn = SSH2() else: conn = SSH2(timeout=t_out) elif proto == "telnet": conn = Telnet() conn.set_driver('ios') conn.connect(host) conn.login(account) conn.execute('term length 0') conn.execute('term width 0') conn.send('enable\r') conn.app_authorize(account) conn.execute('show version') showver = conn.response.split('\r\n') conn.execute('show startup-config') showstart = conn.response.split('\r\n') conn.execute('show running-config all') showrun = conn.response.split('\r\n') showrun.pop() showstart.pop() showver.pop() outputbuffer = {'version':showver, 'startup-config':showstart, 'running-config':showrun, 'error': None} return outputbuffer except Exception: outputbuffer = {'version': "", 'startup-config': "", 'running-config':"", 'error': True} return outputbuffer
class raisecom2624(): def connect(self, acc, ip): acc = Account(*acc) self.con = Telnet(driver=driver) self.con.connect(ip) self.con.login(acc) self.con.debug = 1 def config(self): self.con.execute('conf t') def normal(self): self.con.execute('end') def createvlan(self, vlan): self.config() self.con.execute('create vlan {} active'.format(vlan)) self.normal() def addvlan(self, vlan, ports): self.config() for port in ports: if port != 0: self.con.execute('interface gigaethernet 1/1/{}'.format( str(port))) self.con.execute('switchport mode trunk') self.con.execute( 'switchport trunk allowed vlan add {}'.format(vlan)) self.normal() def exit(self): self.con.send('exit')
class TelnetBehavior: __metaclass__ = ABCMeta telnet_username = None telnet_password = None exscript_driver = None def __init__(self, host_address, port=23): self.host_address = host_address self.port = port def __enter__(self): self.account = Account(self.telnet_username, password=self.telnet_password) self.conn = Telnet(debug=TELNET_DEBUG_LEVEL, connect_timeout=PYCURL_TIMEOUT) self.conn.connect(self.host_address, port=self.port) self.conn.set_driver(self.exscript_driver()) self.conn.login(self.account) return self def __exit__(self, exc_type, exc_val, exc_tb): self.conn.send('exit\r') self.conn.close(force=True) def execute(self, command): self.conn.execute(command) return self.conn.response
def get_result(): try: data = request.get_json(True) address = data['host'] account = Account(name=data['user'], password=data['passwd']) if data['conntype'] == 'SSH': from Exscript.protocols import SSH2 conn = SSH2() elif data['conntype'] == 'Telnet': from Exscript.protocols import Telnet conn = Telnet() else: raise (Exception('Unsupport connection type')) conn.connect(address) conn.login(account) conn.execute(data['command']) response = to_plain(str(conn.response)) conn.send('exit\n') conn.close() return jsonify(success=True, response=response) except Exception as e: return jsonify( success=False, response="Opus! Some guy poisoned my coffee last night!")
class olt5508(): def connect(self, acc, ip): acc = Account(*acc) self.con = Telnet(driver=driver) self.con.connect(ip) self.con.login(acc) self.con.debug = 1 def getmacbyvlan(self, vlan): self.con.execute( 'show mac-address-table l2-address vlan {}'.format(vlan)) out = self.con.response self.exit() fsm = open('app/textFSM/raisecom_sh_mac.template') re_mac = textfsm.TextFSM(fsm) mac = re_mac.ParseText(out) mac2 = [str(EUI(x[0])) for x in mac] return mac2 def config(self): self.con.execute('conf t') def normal(self): self.con.execute('end') def createvlan(self, vlan): self.config() self.con.execute('create vlan {} active'.format(vlan)) self.normal() def addvlan(self, vlan, ports): pass def exit(self): self.con.send('exit')
def ipsec_audit(h, connection, account, Verbose): if connection == 'Telnet': conn = Telnet() elif connection == 'SSH': conn = SSH2() else: conn = SSH2() conn.set_driver('ios') try: conn.connect(str(h)) conn.login(account) except Exception, e: print 'Error:', e sys.exit()
class JuniperTelnetBehavior(object): def __init__(self, host_address): self.host_address = host_address def __enter__(self): self.account = Account(JUNIPER_ROUTER_TELNET_USER, password=JUNIPER_ROUTER_TELNET_PASS) self.conn = Telnet(debug=TELNET_DEBUG_LEVEL, connect_timeout=None) self.conn.connect(self.host_address) self.conn.set_driver(JunOSDriver()) self.conn.login(self.account) return self def __exit__(self, exc_type, exc_val, exc_tb): self.conn.send('exit\r') self.conn.close(force=True) def execute(self, command): self.conn.execute(command) return self.conn.response
class TelnetCLI: def __init__(self, ip=None, port=23, username=None, password=None, timeout=3, link_right_now=False): self.target_ip = ip self.target_port = port self.username = username self.password = password self.timeout = timeout self.connection = None self.port_num = None if link_right_now is True: if username is None or password is None or ip is None: raise Exception('Too few arguments') self.connect_to_target(self.username, self.password) @staticmethod def check_ip_legality(ip): if not isinstance(ip, str): return False addr = ip.strip().split('.') if len(addr) != 4: return False for i in range(4): if not addr[i].isdigit(): return False if int(addr[i]) < 0 or int(addr[i]) > 255: return False return True @staticmethod def check_netmask_legality(netmask): if not TelnetCLI.check_ip_legality(netmask): return False addr = netmask.strip().split('.') marker = 0 for i in range(4): if marker == 1 and addr[3 - i] != '255': return False tmp = 256 - int(addr[3 - i]) if (tmp - 1) & tmp: return False if addr[3 - i] == '255': marker = 1 return True def connect_to_target(self, username, password): self.username = username self.password = password timeout = self.timeout try: self.connection = Telnet(timeout=timeout) self.connection.connect(hostname=self.target_ip, port=self.target_port) self.connection.login(Account(self.username, self.password)) self.get_device_port_info() except Exception: raise Exception('Fail to set up connection') @staticmethod def prefix_to_netmask(prefix): if type(prefix) is str: if prefix.isdigit(): prefix = int(prefix) else: return None if prefix == 24: return '255.255.255.0' elif prefix == 30: return '255.255.255.252' def config_mode(self): self.connection.execute('conf t') def exit_config_mode(self): if self.check_config_mode() is True: self.connection.execute('exit') else: pass def check_config_mode(self): try: self.connection.execute('show int status') return False except exception.InvalidCommandException: return True def get_device_port_info(self): if self.check_config_mode(): self.exit_config_mode() self.connection.execute('show ip int bri') response = self.connection.response GE_port_num = response.count('GigabitEthernet') FE_port_num = response.count('FastEthernet') self.port_num = GE_port_num + FE_port_num return {'FastEthernet port number': FE_port_num, 'GigabitEthernet port number': GE_port_num, 'Total port number': FE_port_num + GE_port_num,} def set_port_vlan(self, switchport, vlan): if switchport <= 1 or switchport > self.port_num: raise ValueError('No such port') if self.check_config_mode() is False: self.config_mode() self.connection.execute('int gi0/' + str(switchport)) self.connection.execute('switchport access vlan ' + str(vlan)) def get_port_vlan(self, switchport): if switchport < 1 or switchport > self.port_num: raise ValueError('No such port') if self.check_config_mode() is True: self.exit_config_mode() self.connection.execute('show run int gi0/' + str(switchport)) result = self.connection.response pos = result.find('vlan') if pos == -1: return 1 if result[pos + 6].isdigit(): return result[pos + 5] + result[pos + 6] else: return result[pos + 5] def cancel_port_vlan(self, switch_port): self.set_port_vlan(switch_port, 1) def get_all_vlan(self): if self.check_config_mode() is True: self.exit_config_mode() self.connection.execute('show vlan bri') result = self.connection.response item_list = result.split('\r\n')[4:] # TODO: FINISH return item_list def get_vlan_info(self, vlan): try: if self.check_config_mode() is True: self.exit_config_mode() self.connection.execute('show vlan id ' + str(vlan)) info = self.connection.response info = info[info.find('Ports') + 6:] info = info[info.find(str(vlan)) + len(str(vlan)):] ptr = 0 # strip the space in text while info[ptr] == ' ': ptr += 1 info = info[ptr:] ptr = 0 # a method to get the word while info[ptr] != ' ' and info[ptr] != '\r' and info[ptr] != '\n': ptr += 1 vlan_name = info[:ptr] info = info[ptr:] ptr = 0 while info[ptr] == ' ': ptr += 1 info = info[ptr:] ptr = 0 while info[ptr] != ' ' and info[ptr] != '\r' and info[ptr] != '\n': ptr += 1 vlan_status = info[:ptr] info = info[ptr:] ptr = 0 # the port for port in the vlan port_list = [] while info[ptr] == ' ': ptr += 1 info = info[ptr:] ptr = 0 position = info.find('Gi0/') while position != -1: if info[position + 5].isdigit(): port_list.append(int(info[position + 4: position + 6])) else: port_list.append(int(info[position + 4])) info = info[position + 4:] position = info.find('Gi0/') r_json = { 'id': vlan, 'name': vlan_name, 'status': vlan_status, 'port_list': port_list, } return r_json except exception.InvalidCommandException: return {'error_msg': 'No vlan ' + str(vlan) + ' in switch.'} def create_vlan(self, **kwargs): if not self.check_config_mode(): self.config_mode() vlan = kwargs.get('vlan') if vlan is not None: self.connection.execute('vlan ' + str(vlan)) else: vlan_list = kwargs.get('vlan_list') if vlan_list: for v in vlan_list: self.connection.execute('vlan ' + str(v)) else: raise KeyError self.connection.execute('end') def delete_vlan(self, vlan): if vlan == 1: raise ValueError('Can\'t remove default vlan', vlan) if self.check_config_mode() is False: self.config_mode() try: port_list = self.get_vlan_info(vlan=vlan)['port_list'] for port in port_list: self.cancel_port_vlan(switch_port=port) self.connection.execute('no vlan ' + str(vlan)) except exception.InvalidCommandException: pass def get_cdp_info(self): if self.check_config_mode(): self.exit_config_mode() self.connection.execute('show cdp neighbors') result = self.connection.response device_list = [] position = result.find('Port ID') + 9 result = result[position:] temp_list = ['Device ID', 'Local interface', 'Holdtime', 'Capability', 'Platform', 'Port ID', 'test'] while True: position = 0 position_e = result.find('\r\n') line = result[position:position_e] result = result[position_e + 1:] if len(line) <= 5: break temp = '' temp_device = {} i = 0 j = 0 while j < len(line): if line[j] == ' ' and line[j + 1] == ' ': temp_device[temp_list[i]] = temp while line[j] == ' ': j += 1 temp = '' i += 1 else: temp += line[j] j += 1 temp_device[temp_list[i]] = temp device_list.append(temp_device) return device_list def set_port_mode_trunk(self, switchport): if switchport <= 1 or switchport > self.port_num: raise ValueError('No such port') if not self.check_config_mode(): self.config_mode() self.connection.execute('int gi0/' + str(switchport)) self.connection.execute('switchport mode trunk') self.exit_config_mode() def check_port_mode_trunk(self, switchport): if switchport < 1 or switchport > self.port_num: raise ValueError('No such port') if self.check_config_mode(): self.exit_config_mode() self.connection.execute('show run int gi0/' + str(switchport)) result = self.connection.response if result.find('switchport mode trunk') == -1: return False return True def get_trunk_port(self): if self.check_config_mode(): self.exit_config_mode() r_json = [] for i in range(1, 13): r_json.append(self.check_port_mode_trunk(switchport=i)) return r_json def set_port_trunk_accept_vlan(self, switchport, vlan_list): if switchport <= 1 or switchport > self.port_num: raise ValueError('No such port') if self.check_port_mode_trunk(switchport=switchport) is False: raise Exception('Not a trunk port') if not self.check_config_mode(): self.config_mode() self.connection.execute('int gi0/' + str(switchport)) v_list = '' for vlan in vlan_list: v_list += str(vlan) + ',' v_list = v_list[0:-1] self.connection.execute('switchport trunk allowed vlan ' + v_list) self.exit_config_mode() def get_port_trunk_accept_vlan_list(self, switchport): if switchport <= 1 or switchport >self.port_num: raise ValueError('No such port') if not self.check_port_mode_trunk(switchport=switchport): raise Exception('Not trunk mode') ret_list = [] if self.check_config_mode(): self.exit_config_mode() self.connection.execute('show run int gi0/' + str(switchport)) result = self.connection.response position = result.find('switchport trunk allowed vlan') result = result[position + 30:] position = result.find('\r\n') result = result[:position] tmp_lsit = result.split(',') for item in tmp_lsit: position = item.find('-') if position != -1: for i in range(int(item[position-1]), int(item[position+1])+1): ret_list.append(i) else: ret_list.append(int(item)) return ret_list def set_vlan_ip_address(self, vlan, ipaddr, netmask): if vlan == 1: raise ValueError('Cannot modify the default vlan') r_json = self.get_vlan_info(vlan=vlan) if 'error_msg' in r_json: raise ValueError(r_json['error_msg']) if not self.check_ip_legality(ipaddr): raise ValueError('Invalid ip address') if not self.check_netmask_legality(netmask): raise ValueError('Invalid netmask') if not self.check_config_mode(): self.config_mode() self.connection.execute('int vlan ' + str(vlan)) self.connection.execute('ip address ' + ipaddr + ' ' + netmask) self.exit_config_mode() def get_access_list(self): if self.check_config_mode() is True: self.exit_config_mode() self.connection.execute('show access-lists') result = self.connection.response # TODO: Use NetMiko library in this function !!! return result def get_system_temprature(self): if self.check_config_mode(): self.exit_config_mode() self.connection.execute('show env all') response = self.connection.response position = response.find('System Temperature Value:') if position == -1: raise ValueError('Switch error') ret_str = '' response = response[position + 26:] i = 0 while response[i].isdigit(): ret_str += response[i] i += 1 return int(ret_str) def get_all_info_for_view(self): temperature = self.get_system_temprature() port_num = self.port_num port_status = [] port_trunk_list = self.get_trunk_port() for i in range(1, port_num+1): p_json = {'port_id': i, 'port_vlan': self.get_port_vlan(switchport=i), 'port_is_trunk': port_trunk_list[i - 1], } if port_trunk_list[i - 1] is True: p_json['port_accept_vlan'] = self.get_port_trunk_accept_vlan_list(switchport=i) port_status.append(p_json) r_json = { 'ip': self.target_ip, 'temperature': temperature, 'port_num': port_num, 'port_status': port_status, } return r_json
class TelnetCLI: def __init__(self, ip=None, port=23, username=None, password=None, timeout=3, link_right_now=False): self.target_ip = ip self.target_port = port self.username = username self.password = password self.timeout = timeout self.connection = None if link_right_now is True: if username is None or password is None or ip is None: raise Exception('Too few arguments') self.connect_to_target(self.username, self.password) def connect_to_target(self, username, password): self.username = username self.password = password timeout = self.timeout try: self.connection = Telnet(timeout=timeout) self.connection.connect(hostname=self.target_ip, port=self.target_port) self.connection.login(Account(self.username, self.password)) except Exception: raise Exception('Fail to set up connection') def config_mode(self): self.connection.execute('conf t') def exit_config_mode(self): if self.check_config_mode() is True: self.connection.execute('exit') else: pass def check_config_mode(self): try: self.connection.execute('show int status') return False except exception.InvalidCommandException: return True def set_port_vlan(self, switch_port, vlan): if self.check_config_mode() is False: self.config_mode() self.connection.execute('int gi0/' + str(switch_port)) self.connection.execute('switchport access vlan ' + str(vlan)) def get_port_vlan(self, switchport): if self.check_config_mode() is True: self.connection.execute('do show run int gi0/' + str(switchport)) else: self.connection.execute('show run int gi0/' + str(switchport)) result = self.connection.response pos = result.find('vlan') if pos == -1: return 1 if result[pos + 6].isdigit(): return result[pos + 5] + result[pos + 6] else: return result[pos + 5] def cancel_port_vlan(self, switch_port): self.set_port_vlan(switch_port, 1) def get_vlan_info(self, vlan): try: if self.check_config_mode() is True: self.connection.execute('do show vlan id ' + str(vlan)) else: self.connection.execute('show vlan id ' + str(vlan)) info = self.connection.response info = info[info.find('Ports') + 6:] info = info[info.find(str(vlan)) + len(str(vlan)):] ptr = 0 # strip the space in text while info[ptr] == ' ': ptr += 1 info = info[ptr:] ptr = 0 # a method to get the word while info[ptr] != ' ' and info[ptr] != '\r' and info[ptr] != '\n': ptr += 1 vlan_name = info[:ptr] info = info[ptr:] ptr = 0 while info[ptr] == ' ': ptr += 1 info = info[ptr:] ptr = 0 while info[ptr] != ' ' and info[ptr] != '\r' and info[ptr] != '\n': ptr += 1 vlan_status = info[:ptr] info = info[ptr:] ptr = 0 # the port for port in the vlan port_list = [] while info[ptr] == ' ': ptr += 1 info = info[ptr:] ptr = 0 position = info.find('Gi0/') while position != -1: if info[position + 5].isdigit(): port_list.append(int(info[position + 4:position + 6])) else: port_list.append(int(info[position + 4])) info = info[position + 4:] position = info.find('Gi0/') r_json = { 'id': vlan, 'name': vlan_name, 'status': vlan_status, 'port_list': port_list, } return r_json except exception.InvalidCommandException: return {'error_message': 'No vlan ' + str(vlan) + ' in switch.'} def create_vlan(self, **kwargs): if not self.check_config_mode(): self.config_mode() vlan = kwargs.get('vlan') if vlan is not None: self.connection.execute('vlan ' + str(vlan)) else: vlan_list = kwargs.get('vlan_list') if vlan_list: for v in vlan_list: self.connection.execute('vlan ' + str(v)) self.connection.execute('end') def delete_vlan(self, vlan): if vlan == 1: raise ValueError('Can\'t remove default vlan', vlan) if self.check_config_mode() is False: self.config_mode() try: port_list = self.get_vlan_info(vlan=vlan)['port_list'] for port in port_list: self.cancel_port_vlan(switch_port=port) self.connection.execute('no vlan ' + str(vlan)) except exception.InvalidCommandException: pass
def deploy(hostname=None, acls=None, transport='ssh', save_config=False, timeout=60): """ Deploy code in a safe way o a Cisco NX-OS device. """ try: username, enable_pass, password = \ netrc.netrc().authenticators(hostname) account = Account(name=username, password=password, password2=enable_pass) except: print("ERROR: could not find device in ~/.netrc file") print("HINT: either update .netrc or enter username + pass now.") try: account = read_login() except EOFError: print("ERROR: could not find proper username + pass") print("HINT: set username & pass in ~/.netrc for device %s" % hostname) import sys sys.exit(2) def s(conn, line): print(" %s" % line) conn.execute(line) def collect_interfaces(conn): template = """# textfsm Value Required Interface ([^ ]+) Value Inbound (.*) Value Outbound (.*) Start ^${Interface} is up ^ Outgoing access list is ${Outbound} ^ Inbound access list is ${Inbound} -> Record Start """ template_file = StringIO(template) table = textfsm.TextFSM(template_file) s(conn, 'show ip int | inc ine pro|list is') interface_acl_v4 = table.ParseText(conn.response) template = """# textfsm Value Required Interface ([^ ]+) Value Inbound (.*) Value Outbound (.*) Start ^${Interface} is up ^ Inbound access list ${Inbound} ^ Outgoing access list ${Outbound} -> Record Start """ template_file = StringIO(template) table = textfsm.TextFSM(template_file) s(conn, 'show ipv6 int | i ine pro|access list') interface_acl_v6 = table.ParseText(conn.response) template = """# textfsm Value Required Vty (\d+\s\d+) Value Inbound4 ([^ ]+) Value Outbound4 ([^ ]+) Value Inbound6 ([^ ]+) Value Outbound6 ([^ ]+) Start ^line vty ${Vty} ^ access-class ${Inbound4} in ^ access-class ${Outbound4} out ^ ipv6 access-class ${Inbound6} in ^ ipv6 access-class ${Outbound6} out -> Record Start """ template_file = StringIO(template) table = textfsm.TextFSM(template_file) s(conn, 'show run | begin ^line vty') interface_acl_vty = table.ParseText(conn.response) results = {4: interface_acl_v4, 6: interface_acl_v6} # add vty lines for vty in interface_acl_vty: # v4 inbound v4_inbound = vty[1] if vty[1] else "not set" v4_outbound = vty[2] if vty[1] else "not set" v6_inbound = vty[3] if vty[1] else "not set" v6_outbound = vty[4] if vty[1] else "not set" results[4].append(["vty %s" % vty[0], v4_inbound, v4_outbound]) results[6].append(["vty %s" % vty[0], v6_inbound, v6_outbound]) return results # main flow of the program starts here if transport == 'ssh': conn = SSH2(verify_fingerprint=False, debug=0, timeout=timeout) elif transport == 'telnet': conn = Telnet(debug=0) else: print("ERROR: Unknown transport mechanism: %s" % transport) sys.exit(2) conn.set_driver('nxos') conn.connect(hostname) conn.login(account) conn.execute('terminal length 0') conn.auto_app_authorize(account) capabilities = {} s(conn, "show ipv6 cef") capabilities['ipv6'] = False if "%IPv6 CEF not running" in conn.response else True if capabilities['ipv6']: print("INFO: IPv6 support detected") else: print("INFO: NO IPv6 support detected, skipping IPv6 ACLs") # map into structure: # policyname { (int, afi, direction) } map_pol_int = {} interfaces_overview = collect_interfaces(conn) for afi in interfaces_overview: for interface, inbound, outbound in interfaces_overview[afi]: # add inbound rules to map if inbound not in map_pol_int.keys(): map_pol_int[inbound] = [{"int": interface, "afi": afi, "dir": "in"}] else: map_pol_int[inbound].append({"int": interface, "afi": afi, "dir": "in"}) # add outbound if outbound not in map_pol_int.keys(): map_pol_int[outbound] = [{"int": interface, "afi": afi, "dir": "in"}] else: map_pol_int[outbound].append({"int": interface, "afi": afi, "dir": "out"}) print("INFO: interface / policy mapping:") pprint(map_pol_int) def lock_step(lock, pol, capabilities): name = acls[pol]['name'] afi = acls[pol]['afi'] if afi == 6 and not capabilities['ipv6']: return policy = acls[pol]['policy'] print("INFO: uploading name: %s, afi: %s" % (name, afi)) s(conn, 'configure session aclhound') if afi == 4: try: s(conn, "no ip access-list %s%s" % (lock, name)) except: pass s(conn, "ip access-list %s%s" % (lock, name)) for line in policy.split('\n'): s(conn, line) if afi == 6: try: s(conn, "no ipv6 access-list %s%s" % (lock, name)) except: pass s(conn, "ipv6 access-list %s%s" % (lock, name)) for line in policy.split('\n'): s(conn, line) s(conn, "commit") for policy in acls: lock_step("", policy, capabilities) if save_config == True: s(conn, "copy running-config startup-config")
def deploy(hostname=None, acls=None, transport='ssh', save_config=False): """ Deploy code in a safe way o a Cisco IOS device. """ try: username, enable_pass, password = \ netrc.netrc().authenticators(hostname) account = Account(name=username, password=password, password2=enable_pass) except: account = read_login() def s(conn, line): print(" %s" % line) conn.execute(line) def collect_interfaces(conn): template = """# textfsm Value Required Aclname ([^ ]+) Value Required Direction ([^ ]+) Value Required Interface (.*) Start ^access-group ${Aclname} ${Direction} interface ${Interface} -> Record Start """ template_file = StringIO(template) table = textfsm.TextFSM(template_file) conn.execute('show run | include ^access-group') map_acl_int = {} for aclname, direction, interface in table.ParseText(conn.response): if aclname in map_acl_int.keys(): map_acl_int[aclname].append({"dir": direction, "int": interface}) else: map_acl_int[aclname] = [{"dir": direction, "int": interface}] return map_acl_int # main flow of the program starts here if transport == 'ssh': conn = SSH2(verify_fingerprint=False, debug=0) elif transport == 'telnet': conn = Telnet(debug=0) else: print("ERROR: Unknown transport mechanism: %s" % transport) sys.exit(2) conn.set_driver('ios') conn.connect(hostname) try: conn.login(account) except LoginFailure: print("ERROR: Username or Password incorrect for %s" % hostname) print("HINT: verify authentication details in your .netrc file") sys.exit(2) s(conn, "terminal pager 0") map_pol_int = collect_interfaces(conn) pprint(map_pol_int) def lock_step(lock, pol): name = acls[pol]['name'] afi = acls[pol]['afi'] policy = acls[pol]['policy'] print("INFO: uploading name: %s, afi: %s" % (name, afi)) s(conn, 'configure terminal') if afi == 4: try: s(conn, "clear configure access-list %s%s" % (lock, name)) except: pass for line in policy.split('\n'): if lock: line = line.replace("access-list %s " % name, "access-list %s%s " % (lock, name)) s(conn, line) if afi == 6: try: s(conn, "clear configure ipv6 access-list %s%s" % (lock, name)) except: pass for line in policy.split('\n'): if lock: line = line.replace("access-list %s " % name, "access-list %s%s " % (lock, name)) s(conn, line) s(conn, "end") # then replace ACL on all interfaces / VTYs if name in map_pol_int: for entry in map_pol_int[name]: print("INFO: lockstepping policy %s afi %s" % (name, afi)) s(conn, "configure terminal") s(conn, "access-group %s%s %s interface %s" % (lock, name, entry['dir'], entry['int'])) s(conn, "end") for policy in acls: for lock in ["LOCKSTEP-", ""]: lock_step(lock, policy) # cleanup s(conn, "configure terminal") if acls[policy]['afi'] == 4: s(conn, "clear configure access-list LOCKSTEP-%s" % acls[policy]['name']) if acls[policy]['afi'] == 6: s(conn, "clear configure ipv6 access-list LOCKSTEP-%s" % acls[policy]['name']) s(conn, "end") if save_config == True: s(conn, "write")
def deploy(hostname=None, acls=None, transport='ssh', save_config=False, timeout=60): """ Deploy code in a safe way o a Cisco IOS device. """ try: username, enable_pass, password = \ netrc.netrc().authenticators(hostname) account = Account(name=username, password=password, password2=enable_pass) except: print("ERROR: could not find device in ~/.netrc file") print("HINT: either update .netrc or enter username + pass now.") try: account = read_login() except EOFError: print("ERROR: could not find proper username + pass") print("HINT: set username & pass in ~/.netrc for device %s" % hostname) import sys sys.exit(2) def s(conn, line): print(" %s" % line) conn.execute(line) def collect_interfaces(conn): template = """# textfsm Value Required Interface ([^ ]+) Value Inbound (.*) Value Outbound (.*) Start ^${Interface} is up ^ Outgoing access list is ${Outbound} ^ Inbound access list is ${Inbound} -> Record Start """ template_file = StringIO(template) table = textfsm.TextFSM(template_file) s(conn, 'show ip int | inc ine pro|list is') interface_acl_v4 = table.ParseText(conn.response) template = """# textfsm Value Required Interface ([^ ]+) Value Inbound (.*) Value Outbound (.*) Start ^${Interface} is up ^ Inbound access list ${Inbound} ^ Outgoing access list ${Outbound} -> Record Start """ template_file = StringIO(template) table = textfsm.TextFSM(template_file) s(conn, 'show ipv6 int | i ine pro|access list') interface_acl_v6 = table.ParseText(conn.response) template = """# textfsm Value Required Vty (\d+\s\d+) Value Inbound4 ([^ ]+) Value Outbound4 ([^ ]+) Value Inbound6 ([^ ]+) Value Outbound6 ([^ ]+) Start ^line vty ${Vty} ^ access-class ${Inbound4} in ^ access-class ${Outbound4} out ^ ipv6 access-class ${Inbound6} in ^ ipv6 access-class ${Outbound6} out -> Record Start """ template_file = StringIO(template) table = textfsm.TextFSM(template_file) s(conn, 'show run | begin ^line vty') interface_acl_vty = table.ParseText(conn.response) results = {4: interface_acl_v4, 6: interface_acl_v6} # add vty lines for vty in interface_acl_vty: # v4 inbound v4_inbound = vty[1] if vty[1] else "not set" v4_outbound = vty[2] if vty[1] else "not set" v6_inbound = vty[3] if vty[1] else "not set" v6_outbound = vty[4] if vty[1] else "not set" results[4].append(["vty %s" % vty[0], v4_inbound, v4_outbound]) results[6].append(["vty %s" % vty[0], v6_inbound, v6_outbound]) return results # main flow of the program starts here if transport == 'ssh': conn = SSH2(verify_fingerprint=False, debug=0, timeout=timeout) elif transport == 'telnet': conn = Telnet(debug=0) else: print("ERROR: Unknown transport mechanism: %s" % transport) sys.exit(2) conn.set_driver('ios') conn.connect(hostname) conn.login(account) conn.execute('terminal length 0') conn.auto_app_authorize(account) capabilities = {} s(conn, "show ipv6 cef") capabilities['ipv6'] = False if "%IPv6 CEF not running" in conn.response else True if capabilities['ipv6']: print("INFO: IPv6 support detected") else: print("INFO: NO IPv6 support detected, skipping IPv6 ACLs") # map into structure: # policyname { (int, afi, direction) } map_pol_int = {} interfaces_overview = collect_interfaces(conn) for afi in interfaces_overview: for interface, inbound, outbound in interfaces_overview[afi]: # add inbound rules to map if inbound not in map_pol_int.keys(): map_pol_int[inbound] = [{"int": interface, "afi": afi, "dir": "in"}] else: map_pol_int[inbound].append({"int": interface, "afi": afi, "dir": "in"}) # add outbound if outbound not in map_pol_int.keys(): map_pol_int[outbound] = [{"int": interface, "afi": afi, "dir": "in"}] else: map_pol_int[outbound].append({"int": interface, "afi": afi, "dir": "out"}) print("INFO: interface / policy mapping:") pprint(map_pol_int) def lock_step(lock, pol, capabilities): name = acls[pol]['name'] afi = acls[pol]['afi'] if afi == 6 and not capabilities['ipv6']: return policy = acls[pol]['policy'] print("INFO: uploading name: %s, afi: %s" % (name, afi)) s(conn, 'configure terminal') if afi == 4: try: s(conn, "no ip access-list extended %s%s" % (lock, name)) except: pass s(conn, "ip access-list extended %s%s" % (lock, name)) for line in policy.split('\n'): s(conn, line) if afi == 6: try: s(conn, "no ipv6 access-list %s%s" % (lock, name)) except: pass s(conn, "ipv6 access-list %s%s" % (lock, name)) for line in policy.split('\n'): s(conn, line) s(conn, "end") # then replace ACL on all interfaces / VTYs if name in map_pol_int: for entry in map_pol_int[name]: if not entry['afi'] == afi: continue print("INFO: lockstepping policy %s afi %s" % (name, afi)) s(conn, "configure terminal") if entry['int'].startswith('vty '): s(conn, "line %s" % entry['int']) if afi == 4: s(conn, "access-class %s%s %s" % (lock, name, entry['dir'])) if afi == 6: s(conn, "ipv6 access-class %s%s %s" % (lock, name, entry['dir'])) else: s(conn, "interface %s" % entry['int']) if afi == 4: s(conn, "ip access-group %s%s %s" % (lock, name, entry['dir'])) if afi == 6: s(conn, "ipv6 traffic-filter %s%s %s" % (lock, name, entry['dir'])) s(conn, "end") for policy in acls: for lock in ["LOCKSTEP-", ""]: lock_step(lock, policy, capabilities) # cleanup s(conn, "configure terminal") if acls[policy]['afi'] == 4: s(conn, "no ip access-list extended LOCKSTEP-%s" % acls[policy]['name']) if acls[policy]['afi'] == 6 and capabilities['ipv6']: s(conn, "no ipv6 access-list LOCKSTEP-%s" % acls[policy]['name']) s(conn, "end") if save_config == True: s(conn, "write")
class BeagleDriver(object): """ Base Class for driver Classes. Attributes: hostname: Hostname of the device username: Uername to login onto the device password: Password to login onto the device drivername: Name of the Exscript protocol driver username_prompt: REGEX to match the login prompt as defined by Exscript password_prompt REGEX to match the login prompt as defined by Exscript findreplace: List of findreplace dictionaries. See sub() for more details error_re: List of REGEXes to match errors on the device timeout: Timeout for the command in seconds """ def __init__(self, **kwargs): """ Init method of the Class. Args: hostname: Hostname of the device username: Uername to login onto the device password: Password to login onto the device drivername: Name of the Exscript protocol driver for the device username_prompt: REGEX to match the login prompt as defined by Exscript password_prompt REGEX to match the login prompt as defined by Exscript findreplace: List of findreplace dictionaries. See sub() for more details error_re: List of REGEXes to match errors on the device timeout: Timeout for the command in seconds """ self.hostname = kwargs.get('hostname', None) self.username = kwargs.get('username', None) self.password = kwargs.get('password', None) self.drivername = kwargs.get('drivername', None) self.username_prompt = kwargs.get('username_prompt', '[Uu]sername.*:') self.password_prompt = kwargs.get('password_prompt', '[Pp]assword.*:') self.findreplace = kwargs.get('findreplace', []) self.error_re = kwargs.get('error_re', None) self.timeout = kwargs.get('timeout', None) self.transport = kwargs.get('transport', None) self.incremental_buffer = kwargs.get('incremental_buffer', StringIO()) self.device = None def __enter__(self): self.open() return self def __exit__(self, exc_type, exc_value, exc_traceback): self.close() def sub(self, text, findreplace=None): """ Returns the string obtained by replacing the occurrences of find in text with replace. Args: text: Text to be transformed findreplace: List od dicts with the following keys: find: is regular expression that can contain named \ group identified by (?P<name>...) replace: is a string and supports printf() format. \ Group names can be used as a reference Returns: str: Transformed text """ if findreplace: self.findreplace = findreplace if not self.findreplace: return text result = list() for line in text.splitlines(): for item in self.findreplace: try: regex = re.compile(r'%s' % item['find']) except re.error: continue matches = [ # start, end, dictionary with matches [_.start(), _.end(), _.groupdict()] for _ in regex.finditer(line) ] if matches: end = 0 oldend = 0 _ = list() for start, end, groupdict, in matches: # append from oldend (at first run equals to 0) up to the matched dict _.append(line[oldend:start]) # replaces matches from groupdict with "replace" # we have to replace boolean False matches (like None) with empty strings _.append(item['replace'] % {k: (v or "") for k, v in groupdict.items()}) # oldend is equal to end oldend = end _.append(line[end:]) line = ''.join(_) result.append(line) return '\n'.join(result) def open(self, **kwargs): """ Connect to and login into the device. Args: hostname: Hostname of the device username: Uername to login onto the device password: Password to login onto the device drivername: Name of the Exscript protocol driver for the device username_prompt: REGEX to match the login prompt as defined by Exscript password_prompt REGEX to match the login prompt as defined by Exscript Returns: obj: The device object """ hostname = kwargs.get('hostname', self.hostname) username = kwargs.get('username', self.username) password = kwargs.get('password', self.password) drivername = kwargs.get('drivername', self.drivername) username_prompt = kwargs.get('username_prompt', self.username_prompt) password_prompt = kwargs.get('password_prompt', self.password_prompt) transport = kwargs.get('transport', self.transport) incremental_buffer = kwargs.get('incremental_buffer', self.incremental_buffer) self.drivername = drivername self.hostname = hostname self.username = username self.password = password self.username_prompt = username_prompt self.password_prompt = password_prompt self.transport = transport self.incremental_buffer = incremental_buffer transport = str(transport).lower() if transport == "ssh": self.device = SSH2() elif transport == 'telnet': self.device = Telnet() else: raise RuntimeError('Unrecognized transport protocol: %s' % self.transport) self.device.set_driver(drivername) self.device.set_username_prompt(username_prompt) self.device.set_password_prompt(password_prompt) if self.error_re: self.device.set_error_prompt(self.error_re) else: self.error_re = self.device.get_error_prompt() if self.timeout: self.device.set_timeout(self.timeout) else: self.device.get_timeout() # Connect try: self.device.connect(hostname) except: raise ConnectionError(hostname) # Authenticate try: self.device.login(Account(self.username, self.password)) except: raise LoginError(hostname) # Init terminal length and width self.device.autoinit() return self.device def close(self): """ Disconnects from the device Returns: bool: Always returns True """ try: self.device.send('exit\n') self.device.send('exit\n') except Exception: pass self.device.close(force=True) return True def run(self, command, **kwargs): """ Executes command on the device. Args: command: String of the command to be executed hostname: Hostname of the device username: Uername to login onto the device password: Password to login onto the device drivername: Name of the Exscript protocol driver for the device username_prompt: REGEX to match the login prompt as defined by Exscript password_prompt REGEX to match the login prompt as defined by Exscript Returns: str: Output of the command after sub() has been applied """ if not self.device or not self.device.proto_authenticated: self.open(**kwargs) def event_handler(arg): self.incremental_buffer.write(arg) try: # Connect a data event listener self.device.data_received_event.connect(event_handler) self.device.execute(command) result = self.device.response # Disconnect data event listener self.device.data_received_event.disconnect(event_handler) except InvalidCommandException: raise CommandError(self.hostname, self.device.response) return self.sub(result) def ping(self, address, vrf='global', afi=1, safi=1, loopback=False): """ Placeholder for the actual ping method. Args: address: IP address or hostname to ping vrf: VRF for IP route lookup afi: BGP AFI identifier safi: BGP SAFI identifier loopback: Name of the loopback interface Returns: Always raises error. Actual function will return output of the ping command modified by sub() """ raise RuntimeError('Not implemented yet') def traceroute(self, address, vrf='global', afi=1, safi=1, loopback=False): """ Placeholder for the actual traceroute method. Args: address: IP address or hostname to traceroute vrf: VRF for IP route lookup afi: BGP AFI identifier safi: BGP SAFI identifier loopback: Name of the loopback interface Returns: Always raises error. Actual function will return output of the traceroute command modified by sub() """ raise RuntimeError('Not implemented yet') def show_route(self, address, vrf='global', afi=1, safi=1): """ Placeholder for the actual show route method. Args: address: IP address to lookup the route vrf: VRF for route lookup afi: BGP AFI identifier safi: BGP SAFI identifier loopback: Name of the loopback interface Returns: Always raises error. Actual function will return output of the show route command modified by sub() """ raise RuntimeError('Not implemented yet') def show_bgp(self, address, vrf='global', afi=1, safi=1): """ Placeholder for the actual show BGP route method. Args: address: IP address to lookup the BGP route vrf: VRF for BGP route lookup afi: BGP AFI identifier safi: BGP SAFI identifier loopback: Name of the loopback interface Returns: Always raises error. Actual function will return output of the show BGP route command modified by sub() """ raise RuntimeError('Not implemented yet') def show_bgp_neighbors(self, address, vrf='global', afi=1, safi=1): """ Placeholder for the actual show bgp neighbor method. Args: address: Address of the neighbor vrf: VRF of the neighor afi: BGP AFI identifier safi: BGP SAFI identifier Returns: Always raises error. Actual function will return output of the show bgp neighbor command modified by sub() """ raise RuntimeError('Not implemented yet') def show_bgp_summary(self, vrf='global', afi=1, safi=1): """ Placeholder for the actual show bgp summary method. Args: vrf: VRF for the summary afi: BGP AFI identifier safi: BGP SAFI identifier Returns: Always raises error. Actual function will return output of the show bgp summary command modified by sub() """ raise RuntimeError('Not implemented yet')
def main(): args = args_parser() print_banner() host = args.host port = args.port username = args.username password = args.password privatekey = args.privatekey passphrase = args.passphrase keytype = args.keytype ssh = args.ssh telnet = args.telnet category = args.category plugin = args.plugin if plugin and (category == None): sys.exit(RED + '\n[!] No category\n' + ENDC) # Set host if host == None: host = raw_input('set host' + BLUE + ' > ' + ENDC) # Set service if (ssh == False) and (telnet == False): service = raw_input('set service [ssh|telnet]' + BLUE + ' > ' + ENDC) if service.lower() == 'ssh': ssh = True elif service.lower() == 'telnet': telnet = True if ssh: conn = SSH2() elif telnet: conn = Telnet() else: sys.exit(RED + '\n[!] Bad service type. Options: [ssh|telnet]\n' + ENDC) # Set username if username == None: username = raw_input('set username' + BLUE + ' > ' + ENDC) # Set password if (password == None) and (privatekey == None): password = getpass.getpass('set password (leave blank to enter a private key)' + BLUE + ' > ' + ENDC) #set privatekey if (password == None): #set privatekey if (privatekey == None): privatekey = getpass.getpass('set private key path' + BLUE + ' > ' + ENDC) #set passphrase if (passphrase == None): passphrase = getpass.getpass('set private key passphrase (optional)' + BLUE + ' > ' + ENDC) #set keytype if (keytype == None): keytype = raw_input('set keytype (optional)' + BLUE + ' > ' + ENDC) if (keytype != "") and (passphrase != ""): key = PrivateKey.from_file(privatekey, password=passphrase, keytype=keytype) elif (keytype != ""): key = PrivateKey.from_file(privatekey, password=passphrase) else: key = PrivateKey.from_file(privatekey) else: key = None # Create account account = Account(username, password, key = key) # Connect and login conn.connect(host, port) conn.login(account) # Try to disable history for current shell session conn.execute('unset HISTFILE') # Print info about used Exscript driver driver = conn.get_driver() print BLUE + '\n[i] Using driver: ' + ENDC + driver.name # Set logs directory logs_path = LOGS_PATH + '/' + host + '-' + str(int(time.time())) if category: print BLUE + '\n[i] Plugins category: ' + ENDC + category + '\n' dict_categories = {} dict_plugins = {} # Run single plugin if plugin: try: eval_file(conn, INSTALL_PATH + '/plugins/' + category + '/' + plugin) dict_plugins[plugin] = conn.response print ' %-20s' % (plugin) + '[' + GREEN + 'ok' + ENDC + ']' except: print ' %-20s' % (plugin) + '[' + RED + 'ko' + ENDC + ']' pass dict_categories[category] = dict_plugins # Run plugins by single category else: for plugin in sorted(os.listdir(INSTALL_PATH + '/plugins/' + category)): try: eval_file(conn, INSTALL_PATH + '/plugins/' + category + '/' + plugin) dict_plugins[plugin] = conn.response print ' %-20s' % (plugin) + '[' + GREEN + 'ok' + ENDC + ']' except: print ' %-20s' % (plugin) + '[' + RED + 'ko' + ENDC + ']' pass dict_categories[category] = dict_plugins # Run all plugins by category if (category == None) and (plugin == None): dict_categories = {} for category in sorted(os.listdir(INSTALL_PATH + '/plugins')): print BLUE + '\n[i] Plugins category: ' + ENDC + category + '\n' dict_plugins = {} for plugin in sorted(os.listdir(INSTALL_PATH + '/plugins/' + category)): try: eval_file(conn, INSTALL_PATH + '/plugins/' + category + '/' + plugin) dict_plugins[plugin] = conn.response print ' %-20s' % (plugin) + '[' + GREEN + 'ok' + ENDC + ']' except: print ' %-20s' % (plugin) + '[' + RED + 'ko' + ENDC + ']' pass dict_categories[category] = dict_plugins # Exit and close remote connection conn.send('exit\r') conn.close() # Generate report html_report(dict_categories, logs_path) print BLUE + '\n[i] Report saved to: ' + ENDC + logs_path + '/index.html\n'
class raisecom2128(): def connect(self, acc, ip): acc = Account(*acc) self.con = Telnet(driver=driver) self.con.connect(ip) self.con.login(acc) self.con.debug = 1 def config(self): self.con.execute('conf t') def normal(self): self.con.execute('end') def createvlan(self, vlan): self.config() self.con.execute('create vlan {} active'.format(vlan)) self.normal() def getmacbyvlan(self, vlan): self.con.execute( 'show mac-address-table l2-address vlan {}'.format(vlan)) out = self.con.response self.exit() fsm = open('app/textFSM/raisecom_sh_mac.template') re_mac = textfsm.TextFSM(fsm) mac = re_mac.ParseText(out) mac2 = [str(EUI(x[0])) for x in mac] return mac2 def getintstatus(self): self.con.execute('sh int port') out = self.con.response self.exit() fsm = open('app/textFSM/raisecom_sh_int_port.template') re_ports = textfsm.TextFSM(fsm) ports = re_ports.ParseText(out) ports_dict = dict() for x in ports: ports_dict[x[0]] = {'admin status': x[1], 'link status': x[2]} return ports_dict def access(self, port, vlan): self.con.execute('int port {}'.format(str(port))) self.con.execute('switchport mode access') self.con.execute('switchport access vlan {}'.format(vlan)) self.exit() def addvlan(self, vlan, ports): self.config() for port in ports: if port != 0: self.con.execute('int port {}'.format(str(port))) self.con.execute('switchport mode trunk') self.con.execute( 'switchport trunk allowed vlan add {}'.format(vlan)) self.normal() def exit(self): self.con.send('exit')
class Cli: handler = None def __init__(self, address, port, protocol, username='', password='', logger=None, prompt_list=None): """Connect to device with selected protocol :param address: address of the target host :param port: communication port :param protocol: SSH or Telnet :param username: :param password: :param logger: cloudshell.core.logger.qs_logger object :param prompt_list: optional custom list of prompt patterns used to match commnad prompt on receive :return: """ self.account = Exscript.Account(username, password) self.default_prompt_list = prompt_list if logger: self.logger = logger else: self.logger = None self._write_log('Initializing: address=' + address + ';port=' + str(port) + ';protocol=' + protocol + 'prompt_list=' + str(self.default_prompt_list)) if protocol.lower() == 'telnet': try: self.handler = Telnet() self._write_log('Got Telnet handler object') if not self.default_prompt_list: self.default_prompt_list = self.handler.get_prompt() self._write_log('Setting promp list to library default: ' + str(self.default_prompt_list)) self.handler.set_prompt(self.default_prompt_list) self.handler.connect(address, port) self._write_log('Connected') except: self._write_log('Unable to connect to target', 'error') self._write_log(sys.exc_info()[0], 'error') raise elif protocol.lower() == 'ssh': try: self.handler = SSH2() self._write_log('Got SSH handler object') if not self.default_prompt_list: self.default_prompt_list = self.handler.get_prompt() self._write_log('Setting promp list to library default: ' + str(self.default_prompt_list)) self.handler.set_prompt(self.default_prompt_list) self.handler.connect(address, port) self._write_log('Connected') except: self._write_log('Unable to connect to target', 'error') self._write_log(sys.exc_info()[0], 'error') raise else: self._write_log('invalid protocol: ' + protocol, 'error') raise AttributeError('invalid protocol') def login(self): """ Logs in to device usuing protocol login procedure :return: """ try: self.handler.login(self.account) self._write_log('Logged In') except: print "unable to login to target" self._write_log('Unable to login to target', 'error') self._write_log(sys.exc_info()[0], 'error') raise def authenticate(self): """ Logs in to device usuing protocol authenticate procedure :return: """ try: self.handler.authenticate(self.account) self._write_log('Authenticated!') except: self._write_log('Unable to authenticate to target', 'error') self._write_log(sys.exc_info()[0], 'error') raise def send_and_receive(self, command, pattern_list=None): """ Sends a command and receives the response using expect :param command: :param pattern_list: optional, if None uses the default for the session :return: """ if pattern_list: if type(pattern_list) != list: pattern_list = [pattern_list] self.handler.set_prompt(pattern_list) else: pattern_list = self.default_prompt_list self.handler.set_prompt(self.default_prompt_list) pattern_index, match = self.handler.execute(command) return pattern_index, pattern_list[ pattern_index], match.string # Pattern index, pattern, buffer def send(self, command): """ Sends command without reading response buffer :param command: :return: """ self.handler.send(command) def receive(self, pattern_list=None): """ Reads from current response buffer :param pattern_list: if None uses default pattern list for the session :return: """ if pattern_list: if type(pattern_list) != list: pattern_list = [pattern_list] else: pattern_list = self.default_prompt_list pattern_index, match = self.handler.expect(pattern_list) return pattern_index, pattern_list[ pattern_index], match.string # Pattern index, pattern, buffer def _write_log(self, message, level='info'): if self.logger: method = getattr(self.logger, level) method(message)
print "1.Telnet" print "2.SSHv2" print Connection_Type = raw_input('Connection Type :') print print Device_IP = raw_input('IP Address :') conn = None if Connection_Type == '1': enable_pass = raw_input('Enable Password :'******'enable') conn.execute(enable_pass) elif Connection_Type == '2': conn = SSH2() account = read_login() conn.connect(Switch_IP) conn.login(account) conn.execute('term len 0') conn.execute('term width 0') conn.execute("show ip arp | i " + Device_IP)
def main(): args = args_parser() print_banner() host = args.host port = args.port username = args.username password = args.password ssh = args.ssh telnet = args.telnet category = args.category plugin = args.plugin if plugin and (category == None): sys.exit(RED + '\n[!] No category\n' + ENDC) # Set host if host == None: host = raw_input('set host' + BLUE + ' > ' + ENDC) # Set service if (ssh == False) and (telnet == False): service = raw_input('set service [ssh|telnet]' + BLUE + ' > ' + ENDC) if service.lower() == 'ssh': ssh = True elif service.lower() == 'telnet': telnet = True if ssh: conn = SSH2() elif telnet: conn = Telnet() else: sys.exit(RED + '\n[!] Bad service type. Options: [ssh|telnet]\n' + ENDC) # Set username if username == None: username = raw_input('set username' + BLUE + ' > ' + ENDC) # Set password if password == None: password = getpass.getpass('set password' + BLUE + ' > ' + ENDC) # Create account account = Account(username, password) # Connect and login conn.connect(host, port) conn.login(account) # Try to disable history for current shell session conn.execute('unset HISTFILE') # Print info about used Exscript driver driver = conn.get_driver() print BLUE + '\n[i] Using driver: ' + ENDC + driver.name # Set logs directory logs_path = LOGS_PATH + '/' + host + '-' + str(int(time.time())) if category: print BLUE + '\n[i] Plugins category: ' + ENDC + category + '\n' dict_categories = {} dict_plugins = {} # Run single plugin if plugin: try: eval_file(conn, INSTALL_PATH + '/plugins/' + category + '/' + plugin) dict_plugins[plugin] = conn.response print ' %-20s' % (plugin) + '[' + GREEN + 'ok' + ENDC + ']' except: print ' %-20s' % (plugin) + '[' + RED + 'ko' + ENDC + ']' pass dict_categories[category] = dict_plugins # Run plugins by single category else: for plugin in sorted(os.listdir(INSTALL_PATH + '/plugins/' + category)): try: eval_file(conn, INSTALL_PATH + '/plugins/' + category + '/' + plugin) dict_plugins[plugin] = conn.response print ' %-20s' % (plugin) + '[' + GREEN + 'ok' + ENDC + ']' except: print ' %-20s' % (plugin) + '[' + RED + 'ko' + ENDC + ']' pass dict_categories[category] = dict_plugins # Run all plugins by category if (category == None) and (plugin == None): dict_categories = {} for category in sorted(os.listdir(INSTALL_PATH + '/plugins')): print BLUE + '\n[i] Plugins category: ' + ENDC + category + '\n' dict_plugins = {} for plugin in sorted(os.listdir(INSTALL_PATH + '/plugins/' + category)): try: eval_file(conn, INSTALL_PATH + '/plugins/' + category + '/' + plugin) dict_plugins[plugin] = conn.response print ' %-20s' % (plugin) + '[' + GREEN + 'ok' + ENDC + ']' except: print ' %-20s' % (plugin) + '[' + RED + 'ko' + ENDC + ']' pass dict_categories[category] = dict_plugins # Exit and close remote connection conn.send('exit\r') conn.close() # Generate report html_report(dict_categories, logs_path) print BLUE + '\n[i] Report saved to: ' + ENDC + logs_path + '/index.html\n'