def make_broctl_config_sh(cmdout): cfg_path = os.path.join(config.Config.broctlconfigdir, "broctl-config.sh") with open(cfg_path, "w") as out: for (varname, value) in config.Config.options(dynamic=False): if isinstance(value, bool): # Convert bools to the string "1" or "0" value = (value and "1" or "0") else: value = str(value) # In order to prevent shell errors, here we convert plugin # option names to use underscores, and double quotes in the value # are escaped. out.write('%s="%s"\n' % (varname.replace(".", "_"), value.replace('"', '\\"'))) symlink = os.path.join(config.Config.scriptsdir, "broctl-config.sh") if not os.path.islink(symlink) or os.readlink(symlink) != cfg_path: # attempt to update the symlink try: util.force_symlink(cfg_path, symlink) except OSError as e: cmdout.error("failed to update symlink '%s' to point to '%s': %s" % (symlink, cfg_path, e.strerror)) return False return True
def make_broctl_config_sh(cmdout): # Rather than just overwriting the file, we first write out a tmp file, # and then rename it to avoid a race condition where a process outside of # broctl (such as archive-log) is trying to read the file while it is # being written. cfg_path = os.path.join(config.Config.broctlconfigdir, "broctl-config.sh") tmp_path = os.path.join(config.Config.broctlconfigdir, ".broctl-config.sh.tmp") with open(tmp_path, "w") as out: for (varname, value) in config.Config.options(dynamic=False): if isinstance(value, bool): # Convert bools to the string "1" or "0" value = (value and "1" or "0") else: value = str(value) # In order to prevent shell errors, here we convert plugin # option names to use underscores, and double quotes in the value # are escaped. out.write('%s="%s"\n' % (varname.replace(".", "_"), value.replace('"', '\\"'))) os.rename(tmp_path, cfg_path) symlink = os.path.join(config.Config.scriptsdir, "broctl-config.sh") if not os.path.islink(symlink) or os.readlink(symlink) != cfg_path: # attempt to update the symlink try: util.force_symlink(cfg_path, symlink) except OSError as e: cmdout.error("failed to update symlink '%s' to point to '%s': %s" % (symlink, cfg_path, e.strerror)) return False return True
def make_broctl_config_sh(cmdout): cfg_path = os.path.join(config.Config.broctlconfigdir, "broctl-config.sh") with open(cfg_path, "w") as out: for (varname, value) in config.Config.options(): # Don't write if variable name is an invalid bash variable name if "-" not in varname: value = str(value) # Don't write if the value contains any double quotes (this # could happen for BroArgs, which we don't need in this file) if '"' not in value: out.write("%s=\"%s\"\n" % (varname.replace(".", "_"), value)) symlink = os.path.join(config.Config.scriptsdir, "broctl-config.sh") try: if os.readlink(symlink) != cfg_path: # attempt to update the symlink try: util.force_symlink(cfg_path, symlink) except OSError as e: cmdout.error( "failed to update symlink '%s' to point to '%s': %s" % (symlink, cfg_path, e.strerror)) return False except OSError as e: cmdout.error("failed to resolve symlink '%s': %s" % (symlink, e.strerror)) return False return True
def make_broctl_config_sh(cmdout): ostr = "" for (varname, value) in config.Config.options(dynamic=False): if isinstance(value, bool): # Convert bools to the string "1" or "0" value = "1" if value else "0" else: value = str(value) # In order to prevent shell errors, here we convert plugin # option names to use underscores, and double quotes in the value # are escaped. ostr += '%s="%s"\n' % (varname.replace(".", "_"), value.replace('"', '\\"')) # Rather than just overwriting the file, we first write out a tmp file, # and then rename it to avoid a race condition where a process outside of # broctl (such as archive-log) is trying to read the file while it is # being written. cfg_path = os.path.join(config.Config.broctlconfigdir, "broctl-config.sh") tmp_path = os.path.join(config.Config.broctlconfigdir, ".broctl-config.sh.tmp") try: with open(tmp_path, "w") as out: out.write(ostr) except IOError as e: cmdout.error("failed to write file: %s" % e) return False try: os.rename(tmp_path, cfg_path) except OSError as e: cmdout.error("failed to rename file %s: %s" % (tmp_path, e)) return False symlink = os.path.join(config.Config.scriptsdir, "broctl-config.sh") # check if the symlink needs to be updated try: update_link = not os.path.islink( symlink) or os.readlink(symlink) != cfg_path except OSError as e: cmdout.error("failed to read symlink: %s" % e) return False if update_link: # attempt to update the symlink try: util.force_symlink(cfg_path, symlink) except OSError as e: cmdout.error("failed to update symlink '%s' to point to '%s': %s" % (symlink, cfg_path, e.strerror)) return False return True
def install(self, local_only): results = cmdresult.CmdResult() try: self.config.record_bro_version() except config.ConfigurationError as err: self.ui.error("%s" % err) results.ok = False return results manager = self.config.manager() # Delete previously installed policy files to not mix things up. policies = [self.config.policydirsiteinstall, self.config.policydirsiteinstallauto] for dirpath in policies: if os.path.isdir(dirpath): self.ui.info("removing old policies in %s ..." % dirpath) try: shutil.rmtree(dirpath) except OSError as err: self.ui.error("failed to remove directory: %s" % err) results.ok = False return results self.ui.info("creating policy directories ...") for dirpath in policies: try: os.makedirs(dirpath) except OSError as err: self.ui.error("failed to create directory: %s" % err) results.ok = False return results # Install local site policy. if self.config.sitepolicypath: self.ui.info("installing site policies ...") dst = self.config.policydirsiteinstall for dir in self.config.sitepolicypath.split(":"): dirpath = self.config.subst(dir) for pathname in glob.glob(os.path.join(dirpath, "*")): if not execute.install(pathname, dst, self.ui): results.ok = False return results install.make_layout(self.config.policydirsiteinstallauto, self.ui) self.ui.info("generating local-networks.bro ...") if not install.make_local_networks(self.config.policydirsiteinstallauto, self.ui): results.ok = False return results self.ui.info("generating broctl-config.bro ...") install.make_broctl_config_policy(self.config.policydirsiteinstallauto, self.ui) current = self.config.subst(os.path.join(self.config.logdir, "current")) try: util.force_symlink(manager.cwd(), current) except (IOError, OSError) as err: results.ok = False self.ui.error("failed to update symlink '%s': %s" % (current, err)) return results self.ui.info("generating broctl-config.sh ...") if not install.make_broctl_config_sh(self.ui): results.ok = False return results if local_only: return results # Make sure we install each remote host only once. nodes = self.config.hosts(nolocal=True) # If there are no remote hosts, then we're done. if not nodes: # Save current configuration state. self.config.update_cfg_hash() return results # Sync to clients. self.ui.info("updating nodes ...") dirs = [] if not self.config.havenfs: # Non-NFS, need to explicitly synchronize. syncs = install.get_syncs() else: # NFS. We only need to take care of the spool/log directories. # We need this only on the manager. dirs.append((manager, self.config.logdir)) syncs = install.get_nfssyncs() createdirs = [self.config.subst(dir) for (dir, mirror) in syncs if not mirror] for n in nodes: for dir in createdirs: dirs.append((n, dir)) for (node, success, output) in self.executor.mkdirs(dirs): if not success: self.ui.error("cannot create a directory on node %s" % node.name) self.ui.error("\n".join(output)) results.ok = False return results paths = [self.config.subst(dir) for (dir, mirror) in syncs if mirror] if not execute.sync(nodes, paths, self.ui): results.ok = False return results # Save current configuration state. self.config.update_cfg_hash() return results
def install(self, local_only): results = cmdresult.CmdResult() try: self.config.record_bro_version() except config.ConfigurationError as err: self.ui.error("%s" % err) results.ok = False return results manager = self.config.manager() # Delete previously installed policy files to not mix things up. policies = [ self.config.policydirsiteinstall, self.config.policydirsiteinstallauto ] for dirpath in policies: if os.path.isdir(dirpath): self.ui.info("removing old policies in %s ..." % dirpath) try: shutil.rmtree(dirpath) except OSError as err: self.ui.error("failed to remove directory: %s" % err) results.ok = False return results self.ui.info("creating policy directories ...") for dirpath in policies: try: os.makedirs(dirpath) except OSError as err: self.ui.error("failed to create directory: %s" % err) results.ok = False return results # Install local site policy. if self.config.sitepolicypath: self.ui.info("installing site policies ...") dst = self.config.policydirsiteinstall for dir in self.config.sitepolicypath.split(":"): dirpath = self.config.subst(dir) for pathname in glob.glob(os.path.join(dirpath, "*")): if not execute.install(pathname, dst, self.ui): results.ok = False return results install.make_layout(self.config.policydirsiteinstallauto, self.ui) self.ui.info("generating local-networks.bro ...") if not install.make_local_networks( self.config.policydirsiteinstallauto, self.ui): results.ok = False return results self.ui.info("generating broctl-config.bro ...") install.make_broctl_config_policy(self.config.policydirsiteinstallauto, self.ui) current = self.config.subst(os.path.join(self.config.logdir, "current")) try: util.force_symlink(manager.cwd(), current) except (IOError, OSError) as err: results.ok = False self.ui.error("failed to update symlink '%s': %s" % (current, err)) return results self.ui.info("generating broctl-config.sh ...") if not install.make_broctl_config_sh(self.ui): results.ok = False return results if local_only: return results # Make sure we install each remote host only once. nodes = self.config.hosts(nolocal=True) # If there are no remote hosts, then we're done. if not nodes: # Save current configuration state. self.config.update_cfg_hash() return results # Sync to clients. self.ui.info("updating nodes ...") dirs = [] if not self.config.havenfs: # Non-NFS, need to explicitly synchronize. syncs = install.get_syncs() else: # NFS. We only need to take care of the spool/log directories. # We need this only on the manager. dirs.append((manager, self.config.logdir)) syncs = install.get_nfssyncs() createdirs = [ self.config.subst(dir) for (dir, mirror) in syncs if not mirror ] for n in nodes: for dir in createdirs: dirs.append((n, dir)) for (node, success, output) in self.executor.mkdirs(dirs): if not success: self.ui.error("cannot create a directory on node %s" % node.name) self.ui.error("\n".join(output)) results.ok = False return results paths = [self.config.subst(dir) for (dir, mirror) in syncs if mirror] if not execute.sync(nodes, paths, self.ui): results.ok = False return results # Save current configuration state. self.config.update_cfg_hash() return results