class DNS: def __init__(self, Main): self.Main = Main self.conn = Main.conn with open(f'{HOME_DIR}/dnx_shell/commands.json', 'r') as commands: valid_commands = json.load(commands) with open(f'{HOME_DIR}/dnx_system/data/dns_server.json', 'r') as categories: category = json.load(categories) self.valid = valid_commands['main']['configuration']['dns'] self.valid_dns = category['dns_server'] self.mod = 'dns' self.Standard = Standard(self) def CommandLoop(self): while True: self.conn.send(f'dnx|{self.mod}$> '.encode('utf-8')) data = self.conn.recv(1024).decode().strip('\r\n') data = data.lower().split() if not data: continue status = self.Parse(data) if (status == 'EXIT'): break elif (status == 'end'): return 'exit' def Parse(self, data): arg_len = len(data) comm, arg, option, option2 = self.Standard.HandleArguments(data) if (comm not in self.valid['commands']): self.Standard.SendNotice( f'invalid command. type "commands" to view all available commands.' ) return # single word commands if (comm == 'exit'): return 'EXIT' elif (comm == 'end'): return 'END' elif (comm == 'help'): self.Standard.ChangeHelpSetting() return elif (comm == 'commands'): for cm, values in self.valid[comm].items(): info = values['info'] cm = self.Standard.CalculateSpace(cm) self.conn.send(f'{cm} {info}\n'.encode('utf-8')) return elif (comm in {'show', 'set', 'clear', 'enable', 'disable'} and not arg and not option): valid_args = self.valid['commands'][comm]['args'].strip('!') for arg, value in self.valid[valid_args].items(): # if (comm == 'show' and arg in {'category', 'tld'}): # arg = value['syntax'] info = value['info'] arg = self.Standard.CalculateSpace(arg) self.conn.send(f'{arg} {info}\n'.encode('utf-8')) return # commands length 2 if (arg_len < 2): return args = self.Standard.GrabArgs(comm) status = self.Standard.ValidateArgs(arg, args) if (not status): self.Standard.SendNotice( f'invalid argument. use "{comm}" command for all available arguments.' ) return elif (comm == 'show'): valid_args = self.valid['commands'][comm]['args'].strip('!') if (arg in self.valid[valid_args]): self.ShowStatus(arg) else: self.Standard.SendNotice( f'invalid argument. use "show" command for all available options.' ) return elif (comm in {'enable', 'disable'}): self.ChangeStatus(comm, arg, option) return # command length 3 if (arg_len < 3): if (arg in {'server1', 'server2'} and not option): arg = 'servers' if (status and not option and arg in {'server1', 'server2'}): self.Standard.SendNotice( f'missing server ip address. use "show {arg}" command to view current servers.' ) return # command length 4 if (comm in {'set'}): if (arg in {'tls-retry'}): if (option not in {'5', '10', '60'}): self.Standard.SendNotice( f'invalid retry amount. use 5, 10, or 60.') else: self.ChangeStatus(comm, arg, option) elif (arg in {'server1', 'server2'}): status = self.Standard.ValidateIP(option) if (status and not option2): self.Standard.SendNotice( f'missing server name after ip address.') elif (status): status = self.Standard.AlphaNum(option2) if (status): self.ConfigureServer(arg, option, option2) def ShowStatus(self, arg): with open(f'{HOME_DIR}/dnx_system/data/dns_server.json', 'r') as settings: setting = json.load(settings) with open(f'{HOME_DIR}/dnx_system/data/dns_cache.json', 'r') as dns_cache: cache = json.load(dns_cache) if (arg == 'servers'): dns_servers = setting['dns_server']['resolvers'] for server_info in dns_servers.values(): name = server_info['name'] server = server_info['ip_address'] self.Standard.ShowSend(name, server) elif (arg == 'top-domains'): top_domains = cache['top_domains'] if (not top_domains): self.Standard.SendNotice(f'no top-domains currently cached') return for domain, pos in top_domains.items(): self.Standard.ShowSend(pos, domain) elif (arg in {'tls', 'udp-fallback'}): status = setting['dns_server']['tls']['enabled'] if (arg == 'udp-fallback'): status = setting['dns_server']['tls']['fallback'] if (status): status = 'ENABLED' else: status = 'DISABLED' self.Standard.ShowSend(arg, status) elif (arg == 'tls-retry'): arg_strip = arg.strip('tls-') retry_time = setting['dns_server']['tls'][arg_strip] retry_time /= 60 retry_time = f'{int(retry_time)} Minutes' self.Standard.ShowSend(arg, retry_time) def ChangeStatus(self, comm, arg, option): with open(f'{HOME_DIR}/dnx_system/data/dns_server.json', 'r') as settings: setting = json.load(settings) if (comm == 'set' and arg == 'tls-retry'): tls = setting['dns_server']['tls'] retry_amount = int(option) * 60 if (tls['retry'] == retry_amount): self.Standard.SendNotice( f'tls-retry is already set to {option} minutes.') else: tls.update({'retry': retry_amount}) with open(f'{HOME_DIR}/dnx_system/data/dns_server.json', 'w') as settings: json.dump(setting, settings, indent=4) self.Standard.SendNotice( f'set {arg} to {option} minutes. use "show tls-retry" command to check current status.' ) return tls_settings = setting['dns_server']['tls'] if (arg == 'udp-fallback'): arg2 = 'fallback' else: arg2 = 'enabled' old_status = tls_settings[arg2] if (comm == 'enable'): tls_settings.update({arg2: True}) elif (comm == 'disable'): tls_settings.update({arg2: False}) new_status = tls_settings[arg2] if (old_status == new_status): self.Standard.SendNotice(f'{arg} already {comm}d.') else: with open(f'{HOME_DIR}/dnx_system/data/dns_server.json', 'w') as settings: json.dump(setting, settings, indent=4) self.Standard.SendNotice( f'{comm}d {arg}. use "show {arg2}" command to check current status.' ) def ConfigureServer(self, arg, option, option2): with open(f'{HOME_DIR}/dnx_system/data/dns_server.json', 'r') as settings: setting = json.load(settings) dns_server = setting['dns_server']['resolvers'][arg] if (dns_server['ip_address'] == option): self.Standard.SendNotice(f'{arg} already configured to {option}.') else: dns_server.update({'name': option2, 'ip_address': option}) with open(f'{HOME_DIR}/dnx_system/data/dns_server.json', 'w') as settings: json.dump(setting, settings, indent=4) self.Standard.SendNotice( f'set {arg} to {option}. use "show servers" command to check current status.' )
class IPS: def __init__(self, Main): self.Main = Main self.conn = Main.conn with open(f'{HOME_DIR}/dnx_shell/commands.json', 'r') as commands: valid_commands = json.load(commands) self.valid = valid_commands['main']['configuration']['ips'] self.mod = 'ips-ids' self.Standard = Standard(self) def CommandLoop(self): while True: self.conn.send(f'dnx|{self.mod}$> '.encode('utf-8')) data = self.conn.recv(1024).decode().strip('\r\n') data = data.lower().split() if not data: continue status = self.Parse(data) if (status == 'EXIT'): break elif (status == 'end'): return 'exit' def Parse(self, data): arg_len = len(data) comm, arg, option, option2 = self.Standard.HandleArguments(data) if (comm is None): return elif (comm not in self.valid['commands']): self.Standard.SendNotice( f'invalid command. type "commands" to view all available commands.' ) return # single word commands if (comm == 'exit'): return 'EXIT' elif (comm == 'end'): return 'END' elif (comm == 'help'): self.Standard.ChangeHelpSetting() return elif (comm == 'commands'): for cm, values in self.valid[comm].items(): info = values['info'] cm = self.Standard.CalculateSpace(cm) self.conn.send(f'{cm} {info}\n'.encode('utf-8')) return elif (comm in {'show', 'set', 'enable', 'disable'} and not arg and not option): arg_list = self.valid['commands'][comm]['args'].strip('!') for arg, value in self.valid[arg_list].items(): if (comm == 'show' and arg in {'category', 'tld'}): arg = value['syntax'] info = value['info'] arg = self.Standard.CalculateSpace(arg) self.conn.send(f'{arg} {info}\n'.encode('utf-8')) return # commands length 2 if (arg_len < 2): return args = self.Standard.GrabArgs(comm) status = self.Standard.ValidateArgs(arg, args) if (not status): self.Standard.SendNotice( f'invalid argument. use "{comm}" command for all available options.' ) return elif (comm == 'show'): self.ShowStatus(arg) return # all subsequent commands require length of 2 if (arg_len < 3): if (status and not option): arg_list = self.valid['commands'][comm]['args'].strip('!') arg_options = self.valid[arg_list][arg]['options'] for option in arg_options: arg2 = self.Standard.CalculateSpace(arg) self.conn.send(f'{arg2} {option}\n'.encode('utf-8')) return if (comm in {'enable', 'disable'} and arg_len == 3): status = self.ValidateEnDisSetting(arg, option) if (status): self.ChangeStatus(comm, arg, option) if (arg_len < 4): if (status and not option2): if (arg == 'ddos' and option in {'tcp', 'udp', 'icmp'}): option = self.Standard.CalculateSpace(option) ddos_option = f'{option} *10-99*' self.conn.send(f'{ddos_option}\n'.encode('utf-8')) elif (arg == 'portscan' and option in {'block-length'}): option = self.Standard.CalculateSpace(option) for val in [0, 24, 48, 72]: portscan_option = f'{option} {val}' self.conn.send(f'{portscan_option}\n'.encode('utf-8')) elif (arg == 'whitelist'): option = self.Standard.CalculateSpace(option) whitelist_option = f'{option} *reason*' self.conn.send(f'{whitelist_option}\n'.encode('utf-8')) return elif (comm == 'set'): status = self.ValidateOptions(arg, option, option2) if (status): self.ConfigureOption(arg, option, option2) def ShowStatus(self, arg): with open(f'{HOME_DIR}/dnx_system/data/ips.json', 'r') as settings: setting = json.load(settings) if (arg == 'whitelist'): dns_servers = setting['ips']['whitelist']['dns_servers'] if (dns_servers): status = 'ENABLED' else: status = 'DISABLED' dns_servers = self.Standard.CalculateSpace(arg) dns_servers_status = f'{dns_servers} {status}' self.conn.send(f'{dns_servers_status}\n'.encode('utf-8')) user_whitelist = setting['ips']['whitelist']['ip_whitelist'] for ip_address, reason in user_whitelist.items(): ip_address = self.Standard.CalculateSpace(ip_address) ip_address_whitelist = f'{ip_address} {reason}' self.conn.send(f'{ip_address_whitelist}\n'.encode('utf-8')) elif (arg in 'portscan'): portscan_settings = setting['ips']['port_scan'] for setting, status in portscan_settings.items(): if (setting != 'length'): if (status): status = 'ENABLED' else: status = 'DISABLED' else: status = f'{status} hours' setting = self.Standard.CalculateSpace(setting) setting_status = f'{setting} {status}' self.conn.send(f'{setting_status}\n'.encode('utf-8')) if (arg == 'ddos'): status = setting['ips']['ddos']['enabled'] if (status): status = 'ENABLED' else: status = 'DISABLED' prevention = self.Standard.CalculateSpace('prevention') prevention_status = f'{prevention} {status}' self.conn.send(f'{prevention_status}\n'.encode('utf-8')) limits = setting['ips']['ddos']['limits'] for direction, settings in limits.items(): self.conn.send(f' {direction}\n'.encode('utf-8')) for protocol, pps in settings.items(): protocol = self.Standard.CalculateSpace(protocol) protocol_pps = f'{protocol} {pps} pps' self.conn.send(f'{protocol_pps}\n'.encode('utf-8')) def ChangeStatus(self, comm, arg, option): with open(f'{HOME_DIR}/dnx_system/data/ips.json', 'r') as settings: setting = json.load(settings) if (arg == 'portscan'): category = setting['ips']['port_scan'] elif (arg == 'ddos'): category = setting['ips']['ddos'] option = 'enabled' elif (arg == 'whitelist'): category = setting['ips']['whitelist'] option = 'dns_servers' old_status = category[option] if (comm == 'enable'): category.update({option: True}) elif (comm == 'disable'): category.update({option: False}) new_status = category[option] if (old_status == new_status): self.Standard.SendNotice(f'{arg} {option} already {comm}d.') else: with open(f'{HOME_DIR}/dnx_system/data/ips.json', 'w') as settings: json.dump(setting, settings, indent=4) self.Standard.SendNotice( f'{comm}d {arg} {option}. use "show {arg}" command to check current status.' ) def ConfigureOption(self, arg, option, option2): with open(f'{HOME_DIR}/dnx_system/data/ips.json', 'r') as settings: setting = json.load(settings) option_setting = setting[arg] if (arg in {'portscan', 'ddos'}): if (arg == 'portscan'): option2 = 'length' old_status = option_setting[option][option2] option_setting.update({option: option2}) new_status = option_setting[option][option2] if (old_status == new_status): self.Standard.SendNotice( f'{arg} {option} already set to {option2}.') else: with open(f'{HOME_DIR}/dnx_system/data/ips.json', 'w') as settings: json.dump(setting, settings, indent=4) self.Standard.SendNotice( f'{arg} {option} set to {option2}. use "show {arg}" command to check current status.' ) def ValidateEnDisSetting(self, arg, option): if (arg == 'portscan'): if (option in {'prevention', 'reject'}): return True elif (arg == 'ddos'): if (option in {'prevention'}): return True elif (arg == 'whitelist'): if (option in {'dns'}): return True self.Standard.SendNotice( f'invalid {arg} setting. use "show {arg}" to view all available settings.' ) def ValidateOptions(self, arg, option, option2): if (arg == 'ddos'): if (option in {'tcp', 'udp', 'icmp'}): if (option2.isdigit() and int(option2) in range(10, 100)): return True else: message = f'invalid packet per second. use "set ddos {option}" command for available options.' else: message = f'invalid protocol. use "set ddos" command for available options.' elif (arg == 'portscan'): if (option in {'block-length'}): if (option2.isdigit() and int(option2) in {0, 24, 48, 72}): return True else: message = 'invalid block length. use "set portscan block-length" command for available options.' else: message = 'invalid option. use "set portscan" command for available options.' def ValidateADDorDelete(self): if (arg == 'whitelist'): valid_ip = self.Standard.ValidateIP(option) if (valid_ip): valid_string = self.Standard.AlphaNum(option2) if (valid_string): return True else: message = 'invalid reason. must be alpha numeric characters.' else: message = 'invalid ip address.' self.Standard.SendNotice(message)
class Whitelist: def __init__(self, Main): self.Main = Main self.conn = Main.conn with open(f'{HOME_DIR}/dnx_shell/commands.json', 'r') as commands: valid_commands = json.load(commands) with open(f'{HOME_DIR}/data/whitelist.json', 'r') as settings: setting = json.load(settings) self.valid = valid_commands['main']['configuration']['whitelist'] self.valid_whitelist = setting['whitelists'] self.mod = 'whitelist' self.Standard = Standard(self) def CommandLoop(self): while True: self.conn.send(f'dnx|{self.mod}$> '.encode('utf-8')) data = self.conn.recv(1024).decode().strip('\r\n') data = data.lower().split() if not data: continue status = self.Parse(data) if (status == 'EXIT'): break def Parse(self, data): arg_count = len(data) comm, arg, option, option2 = self.Standard.HandleArguments(data) if (comm not in self.valid['commands']): self.Standard.SendNotice( f'invalid command. type "commands" to view all available commands.' ) return # single word commands if (comm == 'exit'): return 'EXIT' elif (comm == 'help'): self.Standard.ChangeHelpSetting() return elif (comm == 'commands'): for cm, values in self.valid[comm].items(): info = values['info'] cm = self.Standard.CalculateSpace(cm) self.conn.send(f'{cm} {info}\n'.encode('utf-8')) return elif (comm in {'show', 'add', 'delete'} and not arg): valid_args = self.valid['commands'][comm]['args'].strip('!') for arg, value in self.valid[valid_args].items(): if (comm == 'show' and arg in {'exception'}): arg = value['syntax'] info = value['info'] arg = self.Standard.CalculateSpace(arg) self.conn.send(f'{arg} {info}\n'.encode('utf-8')) return args = self.Standard.GrabArgs(comm) status = self.Standard.ValidateArgs(arg, args) if (not status): self.Standard.SendNotice( f'invalid argument. use "{comm}" command for all available arguments.' ) return # commands length 2 if (arg_count < 2): return elif (comm == 'show'): self.ShowStatus(arg) return # commands length 3 if (arg_count < 3): if (status and not option): self.Standard.SendNotice(f'missing option after argument.') return # commands length 4 if (comm in {'add', 'delete'}): status = self.Standard.ValidateDomain(option) if (status and not option2): self.Standard.SendNotice( f'missing direction after argument. use "inbound", "outbound", or "both".' ) return if (status): if (arg == 'timebased'): status2 = self.Standard.ValidateListTimes(option2) elif (arg == 'exceptions'): status2 = self.Standard.AlphaNum(option2) if (status2): self.AddWhitelist(comm, arg, option, option2) def ShowStatus(self, arg): with open(f'{HOME_DIR}/data/whitelist.json', 'r') as settings: setting = json.load(settings) arg2 = arg if (arg == 'exceptions'): self.SendDescription('domain', 'reason') elif (arg == 'timebased'): arg = 'domains' self.SendDescription('domain', 'time entered', 'expire time') elif (arg == 'ip'): arg = 'ip_whitelist' self.SendDescription('ip address', 'type', 'user') whitelist = setting['whitelists'][arg] if (not whitelist): self.Standard.SendNotice(f'no {arg2} objects configured') return for whitelist, info in whitelist.items(): lists = self.Standard.CalculateSpace(whitelist) if (arg == 'exceptions'): info = info['reason'] elif (arg == 'domains'): time = info['time'] expire = info['expire'] info = self.Standard.FormatDateTime(time) info = self.Standard.CalculateSpace(info, space=12, symbol='| ', dashes=False) info += str(self.Standard.FormatDateTime(expire)) elif (arg == 'ip_whitelist'): user = info['user'] info = info['type'] info = self.Standard.CalculateSpace(info, space=10, symbol='| ', dashes=False) info += user wl_status = f'{lists} {info}' self.conn.send(f'{wl_status}\n'.encode('utf-8')) def AddWhitelist(self, comm, arg, option, option2): with open(f'{HOME_DIR}/data/whitelist.json', 'r') as settings: setting = json.load(settings) whitelist = setting['whitelists'] if (arg == 'exception'): if (option in whitelist['exceptions']): self.Standard.SendNotice(f'{option} is already whitelisted.') return else: whitelist['exceptions'].update({option: {'reason': option2}}) elif (option == 'timebased'): if (option in whitelist['domains']): self.Standard.SendNotice(f'{option} is already whitelisted.') return else: now = time.time() expire = now + (option2 * 60) whitelist['domains'].update({ option: { 'time': now, 'rule_length': option2 * 60, 'expire': expire } }) syntax = self.valid['settings'][arg]['syntax'] with open(f'{HOME_DIR}/data/whitelist.json', 'w') as settings: json.dump(setting, settings, indent=4) self.Standard.SendNotice( f'added {option}. use "show {syntax}" command to check current status.' ) def SendDescription(self, one, two, three=''): top = self.Standard.CalculateSpace(one, symbol=' ', dashes=False) top = top + ' ' + self.Standard.CalculateSpace( two, space=10, symbol=' ', dashes=False) + three self.conn.send(f'{top}\n'.encode('utf-8')) def ValidateCategory(self, arg, option): syntax = self.valid['settings'][arg]['syntax'] valid_whitelist = self.valid_whitelist[syntax] if (arg == 'category'): valid_whitelist = valid_whitelist['default'] if (option not in valid_whitelist): self.Standard.SendNotice( f'invalid {arg}. use "show {syntax}" to view all available {syntax}.' ) else: return True