def delete_conf(logger, filename): """ """ # Import here to prevent circular import from system.error_templates.models import CONF_PATH as ERROR_TPL_PATH from applications.reputation_ctx.models import DATABASES_PATH as REPUTATION_CTX_DB_PATH from system.pki.models import CERT_PATH from darwin.defender_policy.models import DEFENDER_PATH from darwin.defender_policy.policy import HAPROXY_PATH from services.darwin.darwin import DARWIN_PATH from services.rsyslogd.rsyslog import RSYSLOG_PATH allowed_files_regex = [ "{}/\w+_\d+\.html".format(ERROR_TPL_PATH), "{}/reputation_ctx_\d+\.mmdb".format(REPUTATION_CTX_DB_PATH), "{}/[\w\_\-\.]+-\d\.(chain|crt|pem|key)".format(CERT_PATH), "{}/defender_[0-9]+?\.conf".format(DEFENDER_PATH), "{}/spoe_defender_[0-9]+?\.txt".format(HAPROXY_PATH), "{}/backend_defender_[0-9]+?\.cfg".format(HAPROXY_PATH), "{}/parser_[0-9]+\.rb".format(RSYSLOG_PATH), "{}/f[\w-]+/f[\w-]+_[0-9]+.conf".format(DARWIN_PATH) ] allowed = False for regex in allowed_files_regex: if re_match(regex, filename): allowed = True break if not allowed: raise VultureSystemConfigError( "File '{}' not allowed to be deleted.".format(filename)) try: cmd_res = check_output(["/bin/rm", filename], stderr=PIPE).decode('utf8') if cmd_res: raise VultureSystemConfigError("'{}' : {}".format( filename, cmd_res.strip()), "delete config file", traceback=" ") return "Config'{}' successfully deleted.".format(filename) except CalledProcessError as e: """ Command raise if permission denied or file does not exist """ stdout = e.stdout.decode('utf8') stderr = e.stderr.decode('utf8') # logger.exception("Failed to delete frontend filename '{}': {}".format(frontend_filename, stderr or stdout)) raise VultureSystemError("'{}' : {}".format(filename, (stderr or stdout)), "delete config file", traceback=" ")
def write_backend_conf(self): logger.info("write_backend_conf") new_conf = self.generate_haproxy_backend_conf() if not new_conf: return False filename = self.get_backend_filename() try: with open(filename, 'r') as conf_file: current_conf = conf_file.read() except Exception as error: logger.warning(error) current_conf = None # If we don't have any current configuration, or if our new configuration differs if current_conf is None or new_conf != current_conf: try: write_conf(logger, [filename, new_conf, HAPROXY_OWNER, HAPROXY_PERMS]) return True except Exception as e: raise VultureSystemConfigError( "log viewer: error while writing haproxy configuration (backend) for DefenderPolicy" ) return False
def save_conf(self): params = [self.get_filename(), self.rulebase, RSYSLOG_OWNER, RSYSLOG_PERMS] try: Cluster.api_request('system.config.models.write_conf', config=params) except Exception as e: # e used by VultureSystemConfigError logger.error(e, exc_info=1) raise VultureSystemConfigError("on cluster.\nRequest failure to write_conf()")
def save_conf(self): """ Write configuration on disk """ conf = self.generate_conf() params_ipsec = [ '/usr/local/etc/ipsec.conf', conf['template_ipsec'], STRONGSWAN_OWNER, "644" ] params_secrets = [ '/usr/local/etc/ipsec.secrets', conf['template_secrets'], STRONGSWAN_OWNER, "600" ] params_strongswan = [ '/usr/local/etc/strongswan.conf', conf['template_strongswan'], STRONGSWAN_OWNER, "644" ] for params in (params_ipsec, params_secrets, params_strongswan): try: self.node.api_request('system.config.models.write_conf', config=params) except Exception as e: raise VultureSystemConfigError( "on node '{}'.\nRequest failure.".format(self.node.name))
def save_conf(self): """ :return A message of what has been done """ if not self.enable_external: return "No standalone portal, no need to write conf." params = [self.get_filename(), self.generate_conf(), HAPROXY_OWNER, HAPROXY_PERMS] for node in self.external_listener.get_nodes(): try: api_res = node.api_request("system.config.models.write_conf", config=params) if not api_res.get('status'): raise VultureSystemConfigError(". API request failure ", traceback=api_res.get('message')) except Exception: raise VultureSystemConfigError("API request failure.") return "Workflow configuration written."
def save_conf(self): """ Write configuration on disk """ if not self.configuration: return params = [self.get_filename(), self.configuration, BACKEND_OWNER, BACKEND_PERMS] try: Cluster.api_request('system.config.models.write_conf', config=params) except Exception as e: # e used by VultureSystemConfigError logger.error(e, exc_info=1) raise VultureSystemConfigError("on cluster.\nRequest failure to write_conf()")
def save_conf(self): """ :return A message of what has been done """ if not self.authentication: return "No authentication activated, no need to write portal conf." params = [ self.get_filename(), self.generate_conf(), WORKFLOW_OWNER, WORKFLOW_PERMS ] try: api_res = Cluster.api_request("system.config.models.write_conf", config=params) if not api_res.get('status'): raise VultureSystemConfigError( ". API request failure ", traceback=api_res.get('message')) except Exception: raise VultureSystemConfigError("API request failure.") return "Workflow configuration written."
def save_conf(self): """ Write configuration on disk """ conf = self.generate_conf() params = [ '/usr/local/etc/openvpn/openvpn_client.conf', conf['template_client'], OPENVPN_OWNER, "644" ] try: self.node.api_request('system.config.models.write_conf', config=params) except Exception as e: raise VultureSystemConfigError( "on node '{}'.\nRequest failure.".format(self.node.name))
def save_conf(self): """ Write configuration on disk """ params = [ self.absolute_filename, self.download_file(), DATABASES_OWNER, DATABASES_PERMS ] try: Cluster.api_request('system.config.models.write_conf', config=params) except Exception as e: # e used by VultureSystemConfigError raise VultureSystemConfigError( "on cluster.\n" "Request failure to write conf of Reputation context '{}'". format(self.name))
def save_policy_file(self): params = [ self.get_full_filename(), self.generate_content(), DARWIN_OWNERS, DARWIN_PERMS ] try: logger.debug( "InspectionPolicy::save_policy_file:: calling api to save inspection policy file" ) Cluster.api_request('system.config.models.write_conf', config=params) except Exception as e: raise VultureSystemConfigError( "InspectionPolicy::save_policy_file:: failure to save inspection policy file" )
def delete_conf(self): """ Delete all format of the current certificate :return True if success raise VultureSystemConfigError if failure """ # Firstly try to delete the conf, if it fails the object will not be deleted extensions = self.get_extensions() for extension in extensions.keys(): api_res = Cluster.api_request("system.config.models.delete_conf", self.get_base_filename() + extension) if not api_res.get('status'): raise VultureSystemConfigError( ". API request failure.", traceback=api_res.get('message')) return True
def save_conf(self): """ Write cert as all formats currently supported This function raise VultureSystemConfigError if failure """ extensions = self.get_extensions() # Retrieve and stock variable to improve loop perf base_filename = self.get_base_filename() """ For each extensions to be written """ for extension, buffer in extensions.items(): params = [ base_filename + extension, buffer, CERT_OWNER, CERT_PERMS ] """ API request """ api_res = Cluster.api_request('system.config.models.write_conf', config=params, internal=True) if not api_res.get('status'): raise VultureSystemConfigError( ". API request failure ", traceback=api_res.get('message'))
def stop_vm(self): try: self.node.api_request('system.vm.vm.stop_vm', config=self.id) except Exception as e: raise VultureSystemConfigError( "on node '{}'.\nRequest failure.".format(self.node.name))
def write_conf(logger, args): """ Dedicated method used to write a file on disk """ # parse arguments because we can be called by asynchronous api if isinstance(args, str): file_path, file_content, owner, perm = literal_eval(args) else: file_path, file_content, owner, perm = args # Write temporary file info /tmp dir, # because everybody can write onto temp_dir = "/var/tmp/" """ Create a temporary named file in {prefix} path """ tmpfile = mktemp(prefix=temp_dir) logger.debug("Config::write_conf: Writing into {}".format(tmpfile)) command = "" try: """ Try to open the tmp file - it might not raise.... """ with open(tmpfile, "w", encoding="utf8") as f: f.write(str(file_content)) """ Sudo move the file from tmp to file_path """ logger.debug("Moving file from '{}' to '{}'".format( tmpfile, file_path)) command = ['/usr/local/bin/sudo', '/bin/mv', tmpfile, file_path] check_output(command, stderr=PIPE) """ Sudo apply owner on file_path """ logger.debug("Applying owner '{}' on file '{}'".format( owner, file_path)) command = ['/usr/local/bin/sudo', '/usr/sbin/chown', owner, file_path] check_output(command, stderr=PIPE) """ Sudo apply permissions on file_path """ logger.debug("Applying permissions '{}' on file '{}'".format( perm, file_path)) command = ['/usr/local/bin/sudo', '/bin/chmod', perm, file_path] check_output(command, stderr=PIPE) logger.info("File '{}' successfully written.".format(file_path)) except FileNotFoundError as e: logger.error("Failed to open file {}: {}".format(file_path, str(e))) raise VultureSystemConfigError( "The path '{}' or '{}' does not seem to exist.".format( temp_dir, "/".join(file_path.split('/')[:-1]))) except PermissionError as e: logger.error("Failed to create/write file {}:".format(file_path)) logger.exception(e) raise VultureSystemConfigError( "The path '{}' does not have correct permissions. \n " "Cannot create/write the file '{}'.".format(temp_dir, tmpfile)) except CalledProcessError as e: logger.error("Failed to execute command {}: {}".format( command, e.stderr)) logger.exception(e) # Catch sudoers failure if "sudo: no tty present and no askpass program specified" in e.stderr.decode( 'utf8'): raise VultureSystemConfigError( "The file '/usr/local/etc/sudoers.d/vulture_sudoers' is not correct, " "cannot execute command", traceback=e.stderr.decode('utf8')) if "No such file or directory" in e.stderr.decode('utf8'): raise VultureSystemConfigError( "Directory '{}' does not seems to exists.".format('/'.join( file_path.split('/')[:-1])), traceback=e.stderr.decode('utf8')) raise VultureSystemConfigError( "Bad permissions on directory '{}'.".format(temp_dir), traceback=(e.stdout or e.stderr).decode('utf8')) # Do NOT remove THIS ! Used to handle "service vultured stop" except ServiceExit: raise except Exception as e: logger.error("No referenced error in write_conf method : ") logger.exception(e) raise VultureSystemConfigError( "Unknown error occurred. \n" "Please see traceback for more informations.")
def config_edit(request, api=False, update=False): config_model = Cluster.get_global_config() if hasattr(request, "JSON") and api: if update: request.JSON = {**config_model.to_dict(), **request.JSON} request_data = request.JSON else: request_data = request.POST # Verify if attribute has changed HERE, config_model will be modified after (at form.is_valid()) has_customer_changed = request_data.get( 'customer_name') != config_model.customer_name has_portal_cookie_name_changed = request_data.get( 'portal_cookie_name') != config_model.portal_cookie_name ssh_authorized_key_changed = request_data.get( 'ssh_authorized_key') != config_model.ssh_authorized_key logs_ttl_changed = request_data.get('logs_ttl') != config_model.logs_ttl form = ConfigForm(request_data or None, instance=config_model, error_class=DivErrorList) def render_form(**kwargs): save_error = kwargs.get('save_error') if api: if form.errors: return JsonResponse(form.errors.get_json_data(), status=400) if save_error: return JsonResponse({'error': save_error[0]}, status=500) return render(request, 'config/config.html', {'form': form, **kwargs}) if request.method in ("POST", "PUT", "PATCH") and form.is_valid(): config = form.save(commit=False) config.save() """ Write .ssh/authorized_keys if any change detected """ if ssh_authorized_key_changed: params = [ "/usr/home/vlt-adm/.ssh/authorized_keys", request_data.get('ssh_authorized_key'), 'vlt-adm:wheel', '600' ] for node in Node.objects.all(): try: node.api_request('system.config.models.write_conf', config=params) except Exception as e: raise VultureSystemConfigError( "on node '{}'.\nRequest failure.".format(node.name)) """ If customer name has changed, rewrite rsyslog templates """ error = "" if has_customer_changed: api_res = Cluster.api_request( "services.rsyslogd.rsyslog.configure_node") if not api_res.get('status'): error = api_res.get('message') if has_portal_cookie_name_changed: api_res = Cluster.api_request( "services.haproxy.haproxy.configure_node") if not api_res.get('status'): error = api_res.get('message') if logs_ttl_changed: res, mess = config_model.set_logs_ttl() if not res: return render_form(save_error=mess) if error: return render_form(save_error=error) if api: return build_response_config("system.config.api", []) return HttpResponseRedirect('/system/config/') # If request PATCH or PUT & form not valid - return error if api: logger.error("Config api form error : {}".format( form.errors.get_json_data())) return JsonResponse(form.errors.get_json_data(), status=400) return render_form()
def delete_snapshot(self): try: self.node.api_request('system.zfs.zfs.delete_snapshot', config=self.id) except Exception as e: raise VultureSystemConfigError("on node '{}'.\nRequest failure.".format(self.node.name))