def test_get_error(self): t = (None,AVConfigParserErrors.ERROR_CODE_MAP_STR[AVConfigParserErrors.EXCEPTION_INVALID_ERROR_CODE]) self.assertEqual(AVConfigParserErrors.get_error(None),t) t = (999999,AVConfigParserErrors.ERROR_CODE_MAP_STR[AVConfigParserErrors.EXCEPTION_INVALID_ERROR_CODE]) self.assertEqual(AVConfigParserErrors.get_error(999999),t) t = ("999999",AVConfigParserErrors.ERROR_CODE_MAP_STR[AVConfigParserErrors.EXCEPTION_INVALID_ERROR_CODE]) self.assertEqual(AVConfigParserErrors.get_error("999999"),t) t = (0,AVConfigParserErrors.ERROR_CODE_MAP_STR[AVConfigParserErrors.SUCCESS]) self.assertEqual(AVConfigParserErrors.get_error(0),t)
def read(self, filename): """Reads the given filename @param filename the ossim-setup.conf path @returns a tuple (code, "error string") """ if not os.path.isfile(filename): return AVConfigParserErrors.get_error_msg( AVConfigParserErrors.FILE_NOT_EXIST) try: self.__sections.clear() configfile = open(filename, 'r') current_section = None nline = 0 for line in configfile.readlines(): nline += 1 if line.strip() == '' or line[0] in '#;': continue line = line.strip() sec_data = self.SECTION_REGEX.match(line) if sec_data: section_name = sec_data.group('header') if not self.__sections.has_key(section_name): current_section = section_name self.__sections[section_name] = {} else: raise DuplicatedConfigSeciton(filename=filename, lineno=nline, msg=section_name) else: opt_data = self.OPTION_REGEX.match(line) if opt_data: optname, vi, optval = opt_data.group( 'option', 'vi', 'value') if ';' in optval: # ';' is a comment delimiter only if it follows # a spacing character pos = optval.find(';') if pos != -1 and optval[pos - 1].isspace(): optval = optval[:pos] # allow empty values if optval == '""': optval = '' optname = optname.rstrip().lower() if not current_section: current_section = self.__defualt self.__sections[current_section] = {} self.__sections[current_section][optname] = optval else: raise InvalidConfigLine(filename=filename, lineno=nline, msg=line) configfile.close() except Exception, e: self.__sections.clear() return AVConfigParserErrors.get_error_msg( AVConfigParserErrors.EXCEPTION, str(e))
def test_get_str_on_exception(self): self.assertEqual( AVConfigParserErrors.get_str_on_exception(None, None), "Exception (KeyError), Invalid error code Exception: None") self.assertEqual(AVConfigParserErrors.get_str_on_exception(0, None), "Success. Exception: None") self.assertEqual( AVConfigParserErrors.get_str_on_exception(0, KeyError), "Success. Exception: <type 'exceptions.KeyError'>") self.assertEqual( AVConfigParserErrors.get_str_on_exception(0, ValueError), "Success. Exception: <type 'exceptions.ValueError'>")
def test_get_error_msg(self): t = (None,AVConfigParserErrors.ERROR_CODE_MAP_STR[AVConfigParserErrors.EXCEPTION_INVALID_ERROR_CODE]+"<TTT>") self.assertEqual(AVConfigParserErrors.get_error_msg(None,"TTT"),t) t = (999999,AVConfigParserErrors.ERROR_CODE_MAP_STR[AVConfigParserErrors.EXCEPTION_INVALID_ERROR_CODE]+"<TTT>") self.assertEqual(AVConfigParserErrors.get_error_msg(999999,"TTT"),t) t = ("999999",AVConfigParserErrors.ERROR_CODE_MAP_STR[AVConfigParserErrors.EXCEPTION_INVALID_ERROR_CODE]+"<TTT>") self.assertEqual(AVConfigParserErrors.get_error_msg("999999","TTT"),t) t = (0,AVConfigParserErrors.ERROR_CODE_MAP_STR[AVConfigParserErrors.SUCCESS]+"<TTT>") self.assertEqual(AVConfigParserErrors.get_error_msg(0,"TTT"),t)
def test_get_error(self): t = (None, AVConfigParserErrors.ERROR_CODE_MAP_STR[ AVConfigParserErrors.EXCEPTION_INVALID_ERROR_CODE]) self.assertEqual(AVConfigParserErrors.get_error(None), t) t = (999999, AVConfigParserErrors.ERROR_CODE_MAP_STR[ AVConfigParserErrors.EXCEPTION_INVALID_ERROR_CODE]) self.assertEqual(AVConfigParserErrors.get_error(999999), t) t = ("999999", AVConfigParserErrors.ERROR_CODE_MAP_STR[ AVConfigParserErrors.EXCEPTION_INVALID_ERROR_CODE]) self.assertEqual(AVConfigParserErrors.get_error("999999"), t) t = (0, AVConfigParserErrors.ERROR_CODE_MAP_STR[ AVConfigParserErrors.SUCCESS]) self.assertEqual(AVConfigParserErrors.get_error(0), t)
def read(self, filename): """Reads the given filename @param filename the ossim-setup.conf path @returns a tuple (code, "error string") """ if not os.path.isfile(filename): return AVConfigParserErrors.get_error_msg(AVConfigParserErrors.FILE_NOT_EXIST) try: self.__sections.clear() configfile = open(filename, 'r') current_section = None nline = 0 for line in configfile.readlines(): nline +=1 if line.strip() == '' or line[0] in '#;': continue line = line.strip() sec_data = self.SECTION_REGEX.match(line) if sec_data: section_name = sec_data.group('header') if not self.__sections.has_key(section_name): current_section = section_name self.__sections[section_name] = {} else: raise DuplicatedConfigSeciton(filename=filename,lineno=nline,msg=section_name) else: opt_data = self.OPTION_REGEX.match(line) if opt_data: optname, vi, optval = opt_data.group('option', 'vi', 'value') if ';' in optval: # ';' is a comment delimiter only if it follows # a spacing character pos = optval.find(';') if pos != -1 and optval[pos - 1].isspace(): optval = optval[:pos] # allow empty values if optval == '""': optval = '' optname = optname.rstrip().lower() if not current_section: current_section = self.__defualt self.__sections[current_section] = {} self.__sections[current_section][optname] = optval else: raise InvalidConfigLine(filename=filename,lineno=nline,msg=line) configfile.close() except Exception, e: self.__sections.clear() return AVConfigParserErrors.get_error_msg(AVConfigParserErrors.EXCEPTION, str(e))
def set_hosts_config (self, entry = "2", ipaddr = None, canonical = None, aliases = []): """ Set the configuracion for a /etc/hosts entry. ToDo: be able to set new values. """ hosts_entry_path = "/files/etc/hosts/%s" % entry hosts_entry_list = self.__augeas_host.match(hosts_entry_path) if hosts_entry_list == []: return AVConfigParserErrors.get_error_msg(AVConfigParserErrors.HOSTS_ENTRY_NOT_FOUND, additional_message=str(entry)) if ipaddr != None: ipaddr_path = hosts_entry_path + '/ipaddr' self.__augeas_host.set(ipaddr_path, ipaddr) self.__pending['Host %s address' % entry] = (ipaddr_path, ipaddr) if canonical != None: canonical_path = hosts_entry_path + '/canonical' self.__augeas_host.set(canonical_path, canonical) self.__pending['Host %s canonical name' % entry] = (canonical_path, canonical) if aliases != []: for counter, alias in enumerate(aliases, start = 1): alias_path = hosts_entry_path + '/alias[%d]' % counter self.__augeas_host.set(alias_path, alias) self.__pending['Host %s alias[%d]' % (entry, counter)] = (alias_path, alias) return AVConfigParserErrors.ALL_OK
def write(self, filename): """Write an .ini-format representation of the configuration state. Returns true on success, false otherwise """ try: fp = open(filename, 'w') if self.__sections.has_key(self.__defualt): sorted_keys = sorted(self.__sections[self.__defualt].keys()) for key in sorted_keys: value = self.__sections[self.__defualt][key] fp.write("%s=%s\n" % (key, str(value).replace('\n', '\n\t'))) fp.write("\n") for section in sorted(self.__sections.keys()): if section == self.__defualt: continue fp.write("[%s]\n" % section) sorted_keys = sorted(self.__sections[section].keys()) for key in sorted_keys: value = self.__sections[section][key] if section == 'sensor' and key == 'detectors' and value !='': detector_plugin_list = value.replace(' ','') detector_plugin_list = detector_plugin_list.split(',') detector_plugin_list = ["suricata" if p == "AlienVault_NIDS" else p for p in detector_plugin_list] detector_plugin_list = ["ossec-single-line" if p == "AlienVault_HIDS" else p for p in detector_plugin_list] detector_plugin_list = ["nagios" if p == "availability_monitoring" else p for p in detector_plugin_list] detector_plugin_list = ["ossec-idm-single-line" if p == "AlienVault_HIDS-IDM" else p for p in detector_plugin_list] value = ', '.join(detector_plugin_list) fp.write("%s=%s\n" % (key, str(value).replace('\n', '\n\t'))) fp.write("\n") except Exception, e: return AVConfigParserErrors.get_error_msg(AVConfigParserErrors.EXCEPTION, str(e))
def test_get_error_msg(self): t = (None, AVConfigParserErrors.ERROR_CODE_MAP_STR[ AVConfigParserErrors.EXCEPTION_INVALID_ERROR_CODE] + "<TTT>") self.assertEqual(AVConfigParserErrors.get_error_msg(None, "TTT"), t) t = (999999, AVConfigParserErrors.ERROR_CODE_MAP_STR[ AVConfigParserErrors.EXCEPTION_INVALID_ERROR_CODE] + "<TTT>") self.assertEqual(AVConfigParserErrors.get_error_msg(999999, "TTT"), t) t = ("999999", AVConfigParserErrors.ERROR_CODE_MAP_STR[ AVConfigParserErrors.EXCEPTION_INVALID_ERROR_CODE] + "<TTT>") self.assertEqual(AVConfigParserErrors.get_error_msg("999999", "TTT"), t) t = (0, AVConfigParserErrors.ERROR_CODE_MAP_STR[ AVConfigParserErrors.SUCCESS] + "<TTT>") self.assertEqual(AVConfigParserErrors.get_error_msg(0, "TTT"), t)
def test_get_str(self): #Test invalid code: self.assertEqual( AVConfigParserErrors.get_str("unknowcode"), AVConfigParserErrors.ERROR_CODE_MAP_STR[ AVConfigParserErrors.EXCEPTION_INVALID_ERROR_CODE]) self.assertEqual( AVConfigParserErrors.get_str(None), AVConfigParserErrors.ERROR_CODE_MAP_STR[ AVConfigParserErrors.EXCEPTION_INVALID_ERROR_CODE]) self.assertEqual( AVConfigParserErrors.get_str(1000), AVConfigParserErrors.ERROR_CODE_MAP_STR[ AVConfigParserErrors.FILE_NOT_EXIST]) self.assertEqual( AVConfigParserErrors.get_str(0), AVConfigParserErrors.ERROR_CODE_MAP_STR[ AVConfigParserErrors.SUCCESS])
def apply_changes (self): """ Apply pending changes and reload configuration. """ if not self.is_pending(): return AVConfigParserErrors.ALL_OK try: self.__augeas_iface.save() self.__augeas_vpn.save() except IOError, msg: return AVConfigParserErrors.get_error_msg(AVConfigParserErrors.CANNOT_SAVE_AVSYSCONFIG, str(msg))
def apply_changes(self): """Apply pending changes and reload configuration. """ if not self.is_pending(): return AVConfigParserErrors.ALL_OK try: self.__augeas_iface.save() self.__augeas_vpn.save() except IOError, msg: return AVConfigParserErrors.get_error_msg( AVConfigParserErrors.CANNOT_SAVE_AVSYSCONFIG, str(msg))
def write(self, filename): """Write an .ini-format representation of the configuration state. Returns true on success, false otherwise """ try: fp = open(filename, 'w') if self.__sections.has_key(self.__defualt): sorted_keys = sorted(self.__sections[self.__defualt].keys()) for key in sorted_keys: value = self.__sections[self.__defualt][key] fp.write("%s=%s\n" % (key, str(value).replace('\n', '\n\t'))) fp.write("\n") for section in sorted(self.__sections.keys()): if section == self.__defualt: continue fp.write("[%s]\n" % section) sorted_keys = sorted(self.__sections[section].keys()) for key in sorted_keys: value = self.__sections[section][key] if section == 'sensor' and key == 'detectors' and value != '': detector_plugin_list = value.replace(' ', '') detector_plugin_list = detector_plugin_list.split(',') detector_plugin_list = [ "suricata" if p == "AlienVault_NIDS" else p for p in detector_plugin_list ] detector_plugin_list = [ "ossec-single-line" if p == "AlienVault_HIDS" else p for p in detector_plugin_list ] detector_plugin_list = [ "nagios" if p == "availability_monitoring" else p for p in detector_plugin_list ] detector_plugin_list = [ "ossec-idm-single-line" if p == "AlienVault_HIDS-IDM" else p for p in detector_plugin_list ] value = ', '.join(detector_plugin_list) fp.write("%s=%s\n" % (key, str(value).replace('\n', '\n\t'))) fp.write("\n") except Exception, e: return AVConfigParserErrors.get_error_msg( AVConfigParserErrors.EXCEPTION, str(e))
value = self.__sections[section][key] if section == 'sensor' and key == 'detectors' and value !='': detector_plugin_list = value.replace(' ','') detector_plugin_list = detector_plugin_list.split(',') detector_plugin_list = ["suricata" if p == "AlienVault_NIDS" else p for p in detector_plugin_list] detector_plugin_list = ["ossec-single-line" if p == "AlienVault_HIDS" else p for p in detector_plugin_list] detector_plugin_list = ["nagios" if p == "availability_monitoring" else p for p in detector_plugin_list] detector_plugin_list = ["ossec-idm-single-line" if p == "AlienVault_HIDS-IDM" else p for p in detector_plugin_list] value = ', '.join(detector_plugin_list) fp.write("%s=%s\n" % (key, str(value).replace('\n', '\n\t'))) fp.write("\n") except Exception, e: return AVConfigParserErrors.get_error_msg(AVConfigParserErrors.EXCEPTION, str(e)) return AVConfigParserErrors.get_error_msg(AVConfigParserErrors.SUCCESS) def set(self, section, option, value): """Set an option.""" result = True if not section or section == "": section = self.__defualt try: self.__sections[section][option] = value except KeyError: result = False return result
def set_avvpn_config (self, iface, role = None, config_file = None, network = None, netmask = None, port = None, ca = None, cert = None, key = None, dh = None, enabled = None): """ Set the AlienVault VPN configuration under /etc/alienvault/network/vpn.conf """ entry_path = '/files/etc/alienvault/network/vpn.conf/%s' % iface # Run a check, just in case someone is trying to set up a VPN without all the needed parameters. is_new = self.__augeas_vpn.match(entry_path) == [] args = locals() bad_args = filter(lambda x: args[x] == None, args) if is_new and bad_args != []: return AVConfigParserErrors.get_error_msg(AVConfigParserErrors.INCOMPLETE_AVVPN_ENTRY, additional_message=', '.join(bad_args)) # If we are setting a path, just check it. paths = [config_file, ca, cert, key, dh] bad_paths = filter(lambda x: not(x is None or os.path.isfile(x)), paths) if bad_paths != []: return AVConfigParserErrors.get_error_msg(AVConfigParserErrors.INVALID_AVVPN_ENTRY_FIELD, additional_message=', '.join(bad_paths)) if role != None: if role not in ['server', 'client']: return AVConfigParserErrors.get_error_msg(AVConfigParserErrors.INVALID_AVVPN_ENTRY_FIELD, additional_message=str(role)) role_path = entry_path + '/role' self.__augeas_vpn.set(role_path, role) self.__pending['VPN interface %s role' % iface] = (role_path, role) if config_file != None: config_file_path = entry_path + '/config_file' self.__augeas_vpn.set(config_file_path, config_file) self.__pending['VPN interface %s config_file' % iface] = (config_file_path, config_file) if network != None: try: network_check = IP(network) except: return AVConfigParserErrors.get_error_msg(AVConfigParserErrors.INVALID_AVVPN_ENTRY_FIELD, additional_message=str(network)) network_path = entry_path + '/network' self.__augeas_vpn.set(network_path, network) self.__pending['VPN interface %s network' % iface] = (network_path, network) if netmask != None: try: netmask_check = IP(netmask) except: return AVConfigParserErrors.get_error_msg(AVConfigParserErrors.INVALID_AVVPN_ENTRY_FIELD, additional_message=str(netmask)) netmask_path = entry_path + '/netmask' self.__augeas_vpn.set(netmask_path, netmask) self.__pending['VPN interface %s netmask' % iface] = (netmask_path, netmask) if port != None: try: port_int = int(port) if port_int < 1 or port_int > 65535: return AVConfigParserErrors.get_error_msg(AVConfigParserErrors.INVALID_AVVPN_ENTRY_FIELD, additional_message=str(port)) except: return AVConfigParserErrors.get_error_msg(AVConfigParserErrors.INVALID_AVVPN_ENTRY_FIELD, additional_message=str(port)) port_path = entry_path + '/port' self.__augeas_vpn.set(port_path, port) self.__pending['VPN interface %s port' % iface] = (port_path, port) if ca != None: ca_path = entry_path + '/ca' self.__augeas_vpn.set(ca_path, ca) self.__pending['VPN interface %s ca' % iface] = (ca_path, ca) if cert != None: cert_path = entry_path + '/cert' self.__augeas_vpn.set(cert_path, cert) self.__pending['VPN interface %s cert' % iface] = (cert_path, cert) if key != None: key_path = entry_path + '/key' self.__augeas_vpn.set(key_path, key) self.__pending['VPN interface %s key' % iface] = (key_path, key) if dh != None: dh_path = entry_path + '/dh' self.__augeas_vpn.set(dh_path, dh) self.__pending['VPN interface %s dh' % iface] = (dh_path, dh) if enabled != None: if enabled not in ['yes', 'no']: return AVConfigParserErrors.get_error_msg(AVConfigParserErrors.INVALID_AVVPN_ENTRY_FIELD, additional_message=str(enabled)) enabled_path = entry_path + '/enabled' self.__augeas_vpn.set(enabled_path, enabled) self.__pending['VPN interface %s enabled' % iface] = (enabled_path, enabled) return AVConfigParserErrors.ALL_OK
def set_net_iface_config (self, iface, address = None, netmask = None, gateway = None, dns_search= None, dns_nameservers = None, broadcast = None, network = None, is_administration = None, is_log_management = None, is_monitor = None): """ Set the network configuration for the interface 'iface'. """ iface_path = "/files/etc/alienvault/network/interfaces.conf/%s" % iface is_new = self.__augeas_iface.match(iface_path) == [] # Bare minimum to set up an interface (only for log_management interfaces). if is_log_management == 'yes': minimum = ['address', 'netmask'] args = locals() bad_args = filter(lambda x: args[x] == None and x in minimum, args) if is_new and bad_args != []: return AVConfigParserErrors.get_error_msg(AVConfigParserErrors.INCOMPLETE_NETWORK_ENTRY, additional_message=', '.join(bad_args)) # Set the interface role, regarding the following constraints: # * Only one interface can be the administration interface. if is_administration == 'yes' and iface != self.__os_interface: admin_iface_path = "/files/etc/alienvault/network/interfaces.conf/%s" % self.__os_interface self.__augeas_iface.set(iface_path + '/address', self.__augeas_iface.get(admin_iface_path + '/address')) self.__augeas_iface.set(iface_path + '/netmask', self.__augeas_iface.get(admin_iface_path + '/netmask')) self.__augeas_iface.set(iface_path + '/network', self.__augeas_iface.get(admin_iface_path + '/network')) self.__augeas_iface.set(iface_path + '/broadcast', self.__augeas_iface.get(admin_iface_path + '/broadcast')) self.__augeas_iface.set(iface_path + '/gateway', self.__augeas_iface.get(admin_iface_path + '/gateway')) self.__augeas_iface.set(iface_path + '/dns-nameservers', self.__augeas_iface.get(admin_iface_path + '/dns-nameservers')) self.__augeas_iface.set(iface_path + '/dns-search', self.__augeas_iface.get(admin_iface_path + '/dns-search')) self.__augeas_iface.set(iface_path + '/administration', 'yes') self.__augeas_iface.set(iface_path + '/log_management', self.__augeas_iface.get(admin_iface_path + '/log_management')) self.__augeas_iface.set(iface_path + '/monitor', self.__augeas_iface.get(admin_iface_path + '/monitor')) self.__augeas_iface.set(iface_path + '/enabled', 'yes') self.__augeas_iface.set(admin_iface_path + '/address', 'TBD') self.__augeas_iface.set(admin_iface_path + '/netmask', 'TBD') self.__augeas_iface.set(admin_iface_path + '/network', 'TBD') self.__augeas_iface.set(admin_iface_path + '/broadcast', 'TBD') self.__augeas_iface.set(admin_iface_path + '/gateway', 'TBD') self.__augeas_iface.set(admin_iface_path + '/dns-nameservers', 'TBD') self.__augeas_iface.set(admin_iface_path + '/dns-search', 'TBD') self.__augeas_iface.set(admin_iface_path + '/log_management', 'no') self.__augeas_iface.set(admin_iface_path + '/monitor', 'no') self.__augeas_iface.set(admin_iface_path + '/administration', 'no') self.__augeas_iface.set(admin_iface_path + '/enabled', 'no') self.__os_interface = iface if is_log_management is not None: log_management_path = iface_path + '/log_management' self.__augeas_iface.set(log_management_path, is_log_management) if is_administration is None or is_administration is 'no': self.__pending['Network interface %s log management' % iface] = (log_management_path, is_log_management) if is_monitor is not None: monitor_path = iface_path + '/monitor' self.__augeas_iface.set(monitor_path, is_monitor) if is_administration is None or is_administration is 'no': self.__pending['Network interface %s monitor' % iface] = (monitor_path, is_monitor) # Remember: don't allow re-configuring the admin interface, or using the admin ip address if address is not None: if address == self.__os_admin_ip and iface != self.__os_interface: return AVConfigParserErrors.get_error_msg(AVConfigParserErrors.CANNOT_OVERWRITE_ADMIN_IP, additional_message='') elif (address == '0.0.0.0' and \ (self.__augeas_iface.get(iface_path + '/log_management') in [None, 'TBD', 'no'] and \ self.__augeas_iface.get(iface_path + '/administration') in [None, 'TBD', 'no'])) or \ address != '0.0.0.0': # This will be setted as a monitoring interface, setting the IP address only if it does not have one. address_path = iface_path + '/address' self.__augeas_iface.set(address_path, address) self.__pending['Network interface %s address' % iface] = (address_path, address) if netmask is not None: netmask_path = iface_path + '/netmask' self.__augeas_iface.set(netmask_path, netmask) self.__pending['Network interface %s netmask' % iface] = (netmask_path, netmask) if gateway is not None: gateway_path = iface_path + '/gateway' self.__augeas_iface.set(gateway_path, gateway) self.__pending['Network interface %s gateway' % iface] = (gateway_path, gateway) if dns_search is not None: dns_search_path = iface_path + '/dns-search' self.__augeas_iface.set(dns_search_path, dns_search) self.__pending['Network interface %s domain' % iface] = (dns_search_path, dns_search) if dns_nameservers is not None: # DNS nameservers is a comma separated list # Blank space separated list in av network config file dns_nameservers_path = iface_path + '/dns-nameservers' self.__augeas_iface.set(dns_nameservers_path, dns_nameservers.replace(',', ' ')) self.__pending['Network interface %s nameserver(s)' % iface] = (dns_nameservers_path, dns_nameservers) if broadcast is not None: broadcast_path = iface_path + '/broadcast' self.__augeas_iface.set(broadcast_path, broadcast) if network is not None: network_path = iface_path + '/network' self.__augeas_iface.set(network_path, network) # Well, I need to fix here the broadcast and network address local_ip = self.__augeas_iface.get(iface_path + '/address') local_netmask = self.__augeas_iface.get(iface_path + '/netmask') if local_ip not in (None, 'TBD') and local_netmask not in (None, 'TBD'): # Only set the broadcast / network in this case net_iface_ip_and_mask = IP(local_ip).make_net(local_netmask) net_iface_broadcast = str(net_iface_ip_and_mask.broadcast()) net_iface_network = str(net_iface_ip_and_mask.net()) if broadcast is None: net_iface_broadcast_path = iface_path + '/broadcast' self.__augeas_iface.set(net_iface_broadcast_path, net_iface_broadcast) if network is None: net_iface_network_path = iface_path + '/network' self.__augeas_iface.set(net_iface_network_path, net_iface_network) # Lastly, for now, all interfaces are enabled by default if they have a role. if self.__augeas_iface.get(iface_path + '/administration') in [None, 'TBD', 'no'] and \ self.__augeas_iface.get(iface_path + '/log_management') in [None, 'TBD', 'no'] and \ self.__augeas_iface.get(iface_path + '/monitor') in [None, 'TBD', 'no']: enabled = 'no' else: enabled = 'yes' enabled_path = iface_path + '/enabled' self.__augeas_iface.set(enabled_path, enabled) return AVConfigParserErrors.ALL_OK
class AVSysConfig(object): def __init__(self, system_ip=None, system_id=None, system_type=None): """ Initialize this object with non system related data, like the OSSIM administration IP address. """ self.__system_ip = system_ip if is_ipv4(system_ip) else None self.__system_id = system_id self.__system_type = system_type # augeas = imp.load_source('augeas', '/usr/share/alienvault/api_core/lib/python2.6/site-packages/augeas.py') self.__augeas_iface = augeas.Augeas(flags=augeas.Augeas.SAVE_BACKUP) self.__augeas_host = augeas.Augeas(flags=augeas.Augeas.SAVE_BACKUP) self.__augeas_vpn = augeas.Augeas(flags=augeas.Augeas.SAVE_BACKUP) # Load extra files into Augeas... self.__augeas_vpn.set('/augeas/load/Puppet/lens', 'Puppet.lns') try: self.__augeas_vpn.set('/augeas/load/Puppet/incl', '/etc/alienvault/network/vpn.conf') except ValueError: self.__augeas_vpn.set('/augeas/load/Puppet/incl[1]', '/etc/alienvault/network/vpn.conf') self.__augeas_vpn.load() self.__augeas_iface.set('/augeas/load/Puppet/lens', 'Puppet.lns') try: self.__augeas_iface.set('/augeas/load/Puppet/incl', '/etc/alienvault/network/interfaces.conf') except ValueError: self.__augeas_iface.set('/augeas/load/Puppet/incl[1]', '/etc/alienvault/network/interfaces.conf') self.__augeas_iface.load() # Get some interesting information from ossim_setup.conf with open('/etc/ossim/ossim_setup.conf', 'r') as o: ossim_setup_data = o.read() try: self.__os_interface = re.findall(r"^interface=(\S+)$", ossim_setup_data, re.MULTILINE)[0] self.__os_admin_ip = re.findall(r"^admin_ip=(\S+)$", ossim_setup_data, re.MULTILINE)[0] except: pass # Load the trigger object. self.__trigger_launch = AVSysConfigTriggerLaunch() self.__pending = {} # System data self.__hosts_entries = {} # AV data self.__net_ifaces = {} self.__avvpn_entries = {} # Initialize pure system data. self.__reload_config__() # # Public methods # def is_pending(self): """Are there pending changes? """ return bool(self.__pending) def get_pending(self): """Get which changes are pending """ return self.__pending def get_pending_str(self): """Like get_pending(), but in human format (no need for paths) """ data = '' for key, (path, desc) in self.__pending.iteritems(): data += '\n[%s]\n%s' % (key, desc if desc != 'TBD' else 'not set') return data def apply_changes(self): """Apply pending changes and reload configuration. """ if not self.is_pending(): return AVConfigParserErrors.ALL_OK try: self.__augeas_iface.save() self.__augeas_vpn.save() except IOError, msg: return AVConfigParserErrors.get_error_msg( AVConfigParserErrors.CANNOT_SAVE_AVSYSCONFIG, str(msg)) # Launch triggers, if needed. paths = [path for key, (path, desc) in self.__pending.iteritems()] (ret, message) = self.__trigger_launch.run(paths=paths) if not ret: return AVConfigParserErrors.get_error_msg( AVConfigParserErrors.CANNOT_LAUNCH_TRIGGERS, str(message)) self.__pending = {} self.__reload_config__() return AVConfigParserErrors.ALL_OK
def set_net_iface_config(self, iface, address=None, netmask=None, gateway=None, dns_search=None, dns_nameservers=None, broadcast=None, network=None, is_administration=None, is_log_management=None, is_monitor=None): """Set the network configuration for the interface 'iface'. """ iface_path = "/files/etc/alienvault/network/interfaces.conf/{}".format( iface) is_new = self.__augeas_iface.match(iface_path) == [] # Bare minimum to set up an interface (only for log_management interfaces). if is_log_management == 'yes': minimum = ['address', 'netmask'] args = locals() bad_args = filter(lambda x: args[x] is None and x in minimum, args) if is_new and bad_args: return AVConfigParserErrors.get_error_msg( AVConfigParserErrors.INCOMPLETE_NETWORK_ENTRY, additional_message=', '.join(bad_args)) # Set the interface role, regarding the following constraints: # * Only one interface can be the administration interface. if is_administration == 'yes' and iface != self.__os_interface: admin_iface_path = "/files/etc/alienvault/network/interfaces.conf/%s" % self.__os_interface self.__augeas_iface.set( iface_path + '/address', self.__augeas_iface.get(admin_iface_path + '/address')) self.__augeas_iface.set( iface_path + '/netmask', self.__augeas_iface.get(admin_iface_path + '/netmask')) self.__augeas_iface.set( iface_path + '/network', self.__augeas_iface.get(admin_iface_path + '/network')) self.__augeas_iface.set( iface_path + '/broadcast', self.__augeas_iface.get(admin_iface_path + '/broadcast')) self.__augeas_iface.set( iface_path + '/gateway', self.__augeas_iface.get(admin_iface_path + '/gateway')) self.__augeas_iface.set( iface_path + '/dns-nameservers', self.__augeas_iface.get(admin_iface_path + '/dns-nameservers')) self.__augeas_iface.set( iface_path + '/dns-search', self.__augeas_iface.get(admin_iface_path + '/dns-search')) self.__augeas_iface.set(iface_path + '/administration', 'yes') self.__augeas_iface.set( iface_path + '/log_management', self.__augeas_iface.get(admin_iface_path + '/log_management')) self.__augeas_iface.set( iface_path + '/monitor', self.__augeas_iface.get(admin_iface_path + '/monitor')) self.__augeas_iface.set(iface_path + '/enabled', 'yes') self.__augeas_iface.set(admin_iface_path + '/address', 'TBD') self.__augeas_iface.set(admin_iface_path + '/netmask', 'TBD') self.__augeas_iface.set(admin_iface_path + '/network', 'TBD') self.__augeas_iface.set(admin_iface_path + '/broadcast', 'TBD') self.__augeas_iface.set(admin_iface_path + '/gateway', 'TBD') self.__augeas_iface.set(admin_iface_path + '/dns-nameservers', 'TBD') self.__augeas_iface.set(admin_iface_path + '/dns-search', 'TBD') self.__augeas_iface.set(admin_iface_path + '/log_management', 'no') self.__augeas_iface.set(admin_iface_path + '/monitor', 'no') self.__augeas_iface.set(admin_iface_path + '/administration', 'no') self.__augeas_iface.set(admin_iface_path + '/enabled', 'no') self.__os_interface = iface if is_log_management is not None: log_management_path = iface_path + '/log_management' self.__augeas_iface.set(log_management_path, is_log_management) if is_administration is None or is_administration is 'no': self.__pending['Network interface %s log management' % iface] = (log_management_path, is_log_management) if is_monitor is not None: monitor_path = iface_path + '/monitor' self.__augeas_iface.set(monitor_path, is_monitor) if is_administration is None or is_administration is 'no': self.__pending['Network interface %s monitor' % iface] = (monitor_path, is_monitor) # Remember: don't allow re-configuring the admin interface, or using the admin ip address if address is not None: if address == self.__os_admin_ip and iface != self.__os_interface: return AVConfigParserErrors.get_error_msg( AVConfigParserErrors.CANNOT_OVERWRITE_ADMIN_IP, additional_message='') elif (address == '0.0.0.0' and \ (self.__augeas_iface.get(iface_path + '/log_management') in [None, 'TBD', 'no'] and \ self.__augeas_iface.get(iface_path + '/administration') in [None, 'TBD', 'no'])) or \ address != '0.0.0.0': # This will be setted as a monitoring interface, setting the IP address only if it does not have one. address_path = iface_path + '/address' self.__augeas_iface.set(address_path, address) self.__pending['Network interface %s address' % iface] = (address_path, address) if netmask is not None: netmask_path = iface_path + '/netmask' self.__augeas_iface.set(netmask_path, netmask) self.__pending['Network interface %s netmask' % iface] = (netmask_path, netmask) if gateway is not None: gateway_path = iface_path + '/gateway' self.__augeas_iface.set(gateway_path, gateway) self.__pending['Network interface %s gateway' % iface] = (gateway_path, gateway) if dns_search is not None: dns_search_path = iface_path + '/dns-search' self.__augeas_iface.set(dns_search_path, dns_search) self.__pending['Network interface %s domain' % iface] = (dns_search_path, dns_search) if dns_nameservers is not None: # DNS nameservers is a comma separated list # Blank space separated list in av network config file dns_nameservers_path = iface_path + '/dns-nameservers' self.__augeas_iface.set(dns_nameservers_path, dns_nameservers.replace(',', ' ')) self.__pending['Network interface %s nameserver(s)' % iface] = (dns_nameservers_path, dns_nameservers) if broadcast is not None: broadcast_path = iface_path + '/broadcast' self.__augeas_iface.set(broadcast_path, broadcast) if network is not None: network_path = iface_path + '/network' self.__augeas_iface.set(network_path, network) # Well, I need to fix here the broadcast and network address local_ip = self.__augeas_iface.get(iface_path + '/address') local_netmask = self.__augeas_iface.get(iface_path + '/netmask') if local_ip not in (None, 'TBD') and local_netmask not in (None, 'TBD'): # Only set the broadcast / network in this case net_iface_ip_and_mask = IP(local_ip).make_net(local_netmask) net_iface_broadcast = str(net_iface_ip_and_mask.broadcast()) net_iface_network = str(net_iface_ip_and_mask.net()) if broadcast is None: net_iface_broadcast_path = iface_path + '/broadcast' self.__augeas_iface.set(net_iface_broadcast_path, net_iface_broadcast) if network is None: net_iface_network_path = iface_path + '/network' self.__augeas_iface.set(net_iface_network_path, net_iface_network) # Lastly, for now, all interfaces are enabled by default if they have a role. if self.__augeas_iface.get(iface_path + '/administration') in [None, 'TBD', 'no'] and \ self.__augeas_iface.get(iface_path + '/log_management') in [None, 'TBD', 'no'] and \ self.__augeas_iface.get(iface_path + '/monitor') in [None, 'TBD', 'no']: enabled = 'no' else: enabled = 'yes' enabled_path = iface_path + '/enabled' self.__augeas_iface.set(enabled_path, enabled) return AVConfigParserErrors.ALL_OK
detector_plugin_list = [ "nagios" if p == "availability_monitoring" else p for p in detector_plugin_list ] detector_plugin_list = [ "ossec-idm-single-line" if p == "AlienVault_HIDS-IDM" else p for p in detector_plugin_list ] value = ', '.join(detector_plugin_list) fp.write("%s=%s\n" % (key, str(value).replace('\n', '\n\t'))) fp.write("\n") except Exception, e: return AVConfigParserErrors.get_error_msg( AVConfigParserErrors.EXCEPTION, str(e)) return AVConfigParserErrors.get_error_msg(AVConfigParserErrors.SUCCESS) def set(self, section, option, value): """Set an option.""" result = True if not section or section == "": section = self.__defualt try: self.__sections[section][option] = value except KeyError: result = False return result
def test_get_str_on_exception(self): self.assertEqual(AVConfigParserErrors.get_str_on_exception(None,None),"Exception (KeyError), Invalid error code Exception: None") self.assertEqual(AVConfigParserErrors.get_str_on_exception(0,None),"Success. Exception: None") self.assertEqual(AVConfigParserErrors.get_str_on_exception(0,KeyError),"Success. Exception: <type 'exceptions.KeyError'>") self.assertEqual(AVConfigParserErrors.get_str_on_exception(0,ValueError),"Success. Exception: <type 'exceptions.ValueError'>")
def test_get_str(self): #Test invalid code: self.assertEqual(AVConfigParserErrors.get_str("unknowcode"),AVConfigParserErrors.ERROR_CODE_MAP_STR[AVConfigParserErrors.EXCEPTION_INVALID_ERROR_CODE]) self.assertEqual(AVConfigParserErrors.get_str(None),AVConfigParserErrors.ERROR_CODE_MAP_STR[AVConfigParserErrors.EXCEPTION_INVALID_ERROR_CODE]) self.assertEqual(AVConfigParserErrors.get_str(1000),AVConfigParserErrors.ERROR_CODE_MAP_STR[AVConfigParserErrors.FILE_NOT_EXIST]) self.assertEqual(AVConfigParserErrors.get_str(0),AVConfigParserErrors.ERROR_CODE_MAP_STR[AVConfigParserErrors.SUCCESS])
def set_avvpn_config(self, iface, role=None, config_file=None, network=None, netmask=None, port=None, ca=None, cert=None, key=None, dh=None, enabled=None): """ Set the AlienVault VPN configuration under /etc/alienvault/network/vpn.conf """ entry_path = '/files/etc/alienvault/network/vpn.conf/%s' % iface # Run a check, just in case someone is trying to set up a VPN without all the needed parameters. is_new = self.__augeas_vpn.match(entry_path) == [] args = locals() bad_args = filter(lambda x: args[x] is None, args) if is_new and bad_args != []: return AVConfigParserErrors.get_error_msg( AVConfigParserErrors.INCOMPLETE_AVVPN_ENTRY, additional_message=', '.join(bad_args)) # If we are setting a path, just check it. paths = [config_file, ca, cert, key, dh] bad_paths = filter(lambda x: not (x is None or os.path.isfile(x)), paths) if bad_paths: return AVConfigParserErrors.get_error_msg( AVConfigParserErrors.INVALID_AVVPN_ENTRY_FIELD, additional_message=', '.join(bad_paths)) if role is not None: if role not in ['server', 'client']: return AVConfigParserErrors.get_error_msg( AVConfigParserErrors.INVALID_AVVPN_ENTRY_FIELD, additional_message=str(role)) role_path = entry_path + '/role' self.__augeas_vpn.set(role_path, role) self.__pending['VPN interface %s role' % iface] = (role_path, role) if config_file is not None: config_file_path = entry_path + '/config_file' self.__augeas_vpn.set(config_file_path, config_file) self.__pending['VPN interface %s config_file' % iface] = (config_file_path, config_file) if network is not None: try: network_check = IP(network) except: return AVConfigParserErrors.get_error_msg( AVConfigParserErrors.INVALID_AVVPN_ENTRY_FIELD, additional_message=str(network)) network_path = entry_path + '/network' self.__augeas_vpn.set(network_path, network) self.__pending['VPN interface %s network' % iface] = (network_path, network) if netmask is not None: try: netmask_check = IP(netmask) except: return AVConfigParserErrors.get_error_msg( AVConfigParserErrors.INVALID_AVVPN_ENTRY_FIELD, additional_message=str(netmask)) netmask_path = entry_path + '/netmask' self.__augeas_vpn.set(netmask_path, netmask) self.__pending['VPN interface %s netmask' % iface] = (netmask_path, netmask) if port is not None: try: port_int = int(port) if port_int < 1 or port_int > 65535: return AVConfigParserErrors.get_error_msg( AVConfigParserErrors.INVALID_AVVPN_ENTRY_FIELD, additional_message=str(port)) except: return AVConfigParserErrors.get_error_msg( AVConfigParserErrors.INVALID_AVVPN_ENTRY_FIELD, additional_message=str(port)) port_path = entry_path + '/port' self.__augeas_vpn.set(port_path, port) self.__pending['VPN interface %s port' % iface] = (port_path, port) if ca is not None: ca_path = entry_path + '/ca' self.__augeas_vpn.set(ca_path, ca) self.__pending['VPN interface %s ca' % iface] = (ca_path, ca) if cert is not None: cert_path = entry_path + '/cert' self.__augeas_vpn.set(cert_path, cert) self.__pending['VPN interface %s cert' % iface] = (cert_path, cert) if key is not None: key_path = entry_path + '/key' self.__augeas_vpn.set(key_path, key) self.__pending['VPN interface %s key' % iface] = (key_path, key) if dh is not None: dh_path = entry_path + '/dh' self.__augeas_vpn.set(dh_path, dh) self.__pending['VPN interface %s dh' % iface] = (dh_path, dh) if enabled is not None: if enabled not in ['yes', 'no']: return AVConfigParserErrors.get_error_msg( AVConfigParserErrors.INVALID_AVVPN_ENTRY_FIELD, additional_message=str(enabled)) enabled_path = entry_path + '/enabled' self.__augeas_vpn.set(enabled_path, enabled) if 'no' == enabled: subprocess.call( 'echo "update system set vpn_ip=NULL;" | ossim-db', shell=True) self.__pending['VPN interface %s enabled' % iface] = (enabled_path, enabled) return AVConfigParserErrors.ALL_OK
class AVConfigParser(): """Class to read INI files Note: we can't use ConfigParser due to the ossim_setup.conf file format. It's possible to find values without section. This code is based on python2.6 RawConfigParser """ VARIABLES_WITHOUT_SECTION = "DEFAULT" SECTION_REGEX = re.compile("\[(?P<header>[^]]+)\]") OPTION_REGEX = re.compile( "^(?P<option>[^\[\]:=\s][^\[\]:=]*)\s*(?P<vi>[:=])\s*(?P<value>.*)$") BOOLEAN_VALUES = { '1': True, 'yes': True, 'true': True, 'on': True, '0': False, 'no': False, 'false': False, 'off': False } def __init__(self, default_section_for_values_without_section=None): """Constructor @param default_section_for_values_without_section: Name of the section assigned to those variables that doesn't have section. """ self.__filename = "" self.__sections = {} self.__defualt = self.VARIABLES_WITHOUT_SECTION if default_section_for_values_without_section: self.__defualt = default_section_for_values_without_section def sections(self): """Returns the list of section names. Those values without section will be in the default section """ return self.__sections.keys() def has_section(self, section): """Indicate whether the named section is present in the configuration.""" return self.__sections.has_key(section) def options(self, section): """Return the list of option names for the given section name""" if self.__sections.has_key(section): return self.__sections[section].keys() return [] def read(self, filename): """Reads the given filename @param filename the ossim-setup.conf path @returns a tuple (code, "error string") """ if not os.path.isfile(filename): return AVConfigParserErrors.get_error_msg( AVConfigParserErrors.FILE_NOT_EXIST) try: self.__sections.clear() configfile = open(filename, 'r') current_section = None nline = 0 for line in configfile.readlines(): nline += 1 if line.strip() == '' or line[0] in '#;': continue line = line.strip() sec_data = self.SECTION_REGEX.match(line) if sec_data: section_name = sec_data.group('header') if not self.__sections.has_key(section_name): current_section = section_name self.__sections[section_name] = {} else: raise DuplicatedConfigSeciton(filename=filename, lineno=nline, msg=section_name) else: opt_data = self.OPTION_REGEX.match(line) if opt_data: optname, vi, optval = opt_data.group( 'option', 'vi', 'value') if ';' in optval: # ';' is a comment delimiter only if it follows # a spacing character pos = optval.find(';') if pos != -1 and optval[pos - 1].isspace(): optval = optval[:pos] # allow empty values if optval == '""': optval = '' optname = optname.rstrip().lower() if not current_section: current_section = self.__defualt self.__sections[current_section] = {} self.__sections[current_section][optname] = optval else: raise InvalidConfigLine(filename=filename, lineno=nline, msg=line) configfile.close() except Exception, e: self.__sections.clear() return AVConfigParserErrors.get_error_msg( AVConfigParserErrors.EXCEPTION, str(e)) if self.__sections['sensor']['detectors'] != '': detector_plugin_list = self.__sections['sensor']['detectors'] detector_plugin_list = detector_plugin_list.replace(' ', '') detector_plugin_list = detector_plugin_list.split(',') detector_plugin_list = [ "AlienVault_NIDS" if p == "suricata" else p for p in detector_plugin_list ] detector_plugin_list = [ "AlienVault_HIDS" if p == "ossec-single-line" else p for p in detector_plugin_list ] detector_plugin_list = [ "availability_monitoring" if p == "nagios" else p for p in detector_plugin_list ] detector_plugin_list = [ "AlienVault_HIDS-IDM" if p == "ossec-idm-single-line" else p for p in detector_plugin_list ] self.__sections['sensor']['detectors'] = ', '.join( detector_plugin_list) return AVConfigParserErrors.get_error_msg(AVConfigParserErrors.SUCCESS)