diff --git a/tools/misp-config b/tools/misp-config new file mode 100755 index 000000000..6634bcc53 --- /dev/null +++ b/tools/misp-config @@ -0,0 +1,207 @@ +#!/usr/bin/env perl +# +# Author: Sebastien Tricaud +# This script is written in Perl because it is default to most distributions +# without any dependency. +# +# MISP Configuration is handled mostly via its UI. This script helps to configure +# MISP for anything that can be configured. For now this is mostly CakePHP stuff. +# +# How to use? +# 1) dump the configuration options that are already set: +# misp-config --create +# -> Will dump in /etc/misp/misp.conf.d/ unless to add a --prefix option, such as: +# misp-config --misp-path /var/www/MISP --prefix /var/www/MISP/etc/ --create +# +# 2) set the configuration manually from /etc/misp/misp.conf.d/ with your favorite text editor (emacs) +# then load to MISP using: +# misp-config --apply +# Of course, if your MISP instance is installed in /var/www/MISP you should do: +# misp-config --misp-path /var/www/MISP --apply +# +# Note there is a configuration, Internal.conf, which where CakePHP has no control, for example +# it will change the source code where there was a lack of configuration capability. +# + + +use strict; +use warnings; +use File::Path qw(make_path); + +my $misp_user="www-data"; +my $misp_path="/usr/share/misp"; +my $misp_config_path="/etc/misp/"; +my $prefix=""; +my $create=0; +my $apply=0; +my %CATEGORIES_CREATED = (); + +if ($#ARGV < 0) { + print "\nUsage: misp-config --user www-data + \t --misp-path /usr/share/misp + \t --prefix /usr/local + \t --apply: Applies configuration from $misp_config_path + \t --create: Create configuration from all available options\n\n"; + exit; +} + +sub replace_inplace_content { + my ($filename, $buftoreplace, $replacement) = @_; + + open my $fp, "<:encoding(UTF-8)", $filename or die "unable to open $filename!"; + local $/ = undef; + my $data = <$fp>; + close $fp; + + $data =~ s/$buftoreplace/$replacement/g; + + open $fp, ">:encoding(UTF-8)", $filename or die "Could not write to '$filename'"; + print $fp $data; + close $fp; +} + +while (my ($i, $arg) = each @ARGV) { + if ($arg eq "--user") { + $misp_user = $ARGV[$i+1]; + } + if ($arg eq "--misp-path") { + $misp_path = $ARGV[$i+1]; + } + if ($arg eq "--prefix") { + $prefix = $ARGV[$i+1]; + $misp_config_path = "$prefix/$misp_config_path" + } + if ($arg eq "--create") { + $create = 1; + } + if ($arg eq "--apply") { + $apply = 1; + } +} + +if ( ! $apply && ! $create ) { + print "Argument missing: Please use either --apply or --create.\n"; + exit; +} + +if ( $apply && $create ) { + print "Argument error: Cannot use both --apply and --create.\n"; + exit; +} + +if ($create) { + my $misp_config_path = "$misp_config_path/misp.conf.d"; + make_path($misp_config_path); + + unless(-e "$misp_config_path/Internal.conf") { + open(my $internalfh, ">", "$misp_config_path/Internal.conf"); + print $internalfh "redis_host localhost\n"; + close $internalfh; + } + + die "foo"; + my $settings = `sudo -u $misp_user $misp_path/app/Console/cake admin getSetting all`; + my @lines = split("\n",$settings); + my $value = 0; + my $setting = 0; + foreach(@lines) { + if ($_ =~ m/\"value\": (.*)/) { + $value = substr $1, 0, -1; + } + if ($_ =~ m/\"setting\": \"(.*)\"/) { + $setting = $1; + } + if ($value && $setting) { + #print "$setting -> $value\n"; + my $category = ""; + my $key = ""; + my $section = ""; + + # Plugin.S3_aws_secret_key -> false + # ^ ^ + # | |- Section (S3) + # | |- Key (S3_aws_secret_key) + # |-- Category + # + # We also have: + # Proxy.host -> "" + # Which won't create a section because of the missing _ + if ($setting =~ m/(\w+)\.(\w+)/) { + $category = $1; + $key = $2; + # print "Setting category: $1 and key: $2\n"; + if ($key =~ m/(.*?)_/) { + $section = $1 + # print "Section: $1\n"; + } else { # There is no _, so the section is the key + $section = $key; + } + } else { + # Orphan settings are debug settings: + $category = "Debug"; + $key = $setting; +# print "Orphan setting:$setting\n"; + } + + # + # We have all we needed, we can write the files + # + my $conf_to_write = "$misp_config_path/$category.conf"; + unless($CATEGORIES_CREATED{"$category"}) { + if (-e $conf_to_write) { + die "We cannot overwrite $conf_to_write, it already exists. Remove it manually.\n"; + } + } + $CATEGORIES_CREATED{"$category"} = 1; + open(my $fh, ">>", "$conf_to_write"); + print $fh "$key $value\n"; + close $fh; + + # Unset those two variables to be filled again! + $value = 0; + $setting = 0; + } + } +} + +if ($apply) { + my $misp_config_path = "$misp_config_path/misp.conf.d"; + + unless(-d $misp_config_path) { + die "MISP Configuration Path does not exists: $misp_config_path\n"; + } + + foreach my $fp (glob("$misp_config_path/*.conf")) { + my $category = substr($fp, length($misp_config_path)+1, -5); + my $cake_config = $category eq "Internal" ? 0 : 1; + # print "$category:$cake_config\n"; + # print "$fp\n"; + open(my $fh, "<", $fp) or die "$!"; + while (my $line = <$fh>) { + chomp $line; + $line =~ /(\S+) (.*)/; + my $key = ""; + + if ($category eq "Debug") { + # The Debug category does not... have a category + $key = $1; + } elsif ($category eq "Internal") { + # Internal means we are patching portions of the code to configure + if ($1 eq "redis_host") { + replace_inplace_content("$misp_path/app/Lib/Tools/PubSubTool.php", "localhost", $2); + replace_inplace_content("$misp_path/app/Plugin/CakeResque/Config/config.php", "localhost", $2); + } + } else { + $key = "$category.$1"; + } + + if ($cake_config) { + system("sudo -u $misp_user $misp_path/app/Console/cake admin setSetting $key $2"); + } + + } + close($fh); + } + +} +