From d4a5882bb46a104b06e9e60a15d2cd92ddb029cb Mon Sep 17 00:00:00 2001 From: Digimer Date: Thu, 26 Dec 2019 21:06:31 -0500 Subject: [PATCH] * Created Validate->is_port() to validate TCP/UDP ports * Got Striker to the point where it can save mail servers (not load existing or delete yet, though). * Added a check to striker-parse-oui so that it only runs once per day. Signed-off-by: Digimer --- Anvil/Tools/Account.pm | 2 +- Anvil/Tools/Validate.pm | 41 +++++++++++++ cgi-bin/striker | 106 ++++++++++++++++++++++++++++++---- html/skins/alteeve/email.html | 26 ++++++--- html/skins/alteeve/main.css | 16 +++++ share/anvil.sql | 20 +++++-- share/words.xml | 8 +++ tools/striker-parse-oui | 86 +++++++++++++++++++++++++++ 8 files changed, 277 insertions(+), 28 deletions(-) diff --git a/Anvil/Tools/Account.pm b/Anvil/Tools/Account.pm index 18da3b7c..297531ce 100644 --- a/Anvil/Tools/Account.pm +++ b/Anvil/Tools/Account.pm @@ -543,7 +543,7 @@ AND AND b.session_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)." ;"; - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0124", variables => { query => $query }}); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0124", variables => { query => $query }}); my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__}); my $count = @{$results}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { diff --git a/Anvil/Tools/Validate.pm b/Anvil/Tools/Validate.pm index 0b271b72..a1013a63 100644 --- a/Anvil/Tools/Validate.pm +++ b/Anvil/Tools/Validate.pm @@ -445,6 +445,47 @@ sub is_mac return($valid); } +=head2 is_port + +This tests to see if the value passed is a valid TCP/UDP port (1 ~ 65536). Returns 'C<< 1 >>' if OK, 'C<< 0 >>' if not. + +B<< Note >>: This is a strict test. A comma will cause this test to return C<< 0 >>. + +Parameters; + +=head3 port (required) + +This is the port being tested. + +=cut +sub is_port +{ + my $self = shift; + my $parameter = shift; + my $anvil = $self->parent; + my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3; + + my $port = defined $parameter->{port} ? $parameter->{port} : ""; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { port => $port }}); + + my $valid = 1; + if ($port =~ /\D/) + { + # Not a digit + $valid = 0; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { valid => $valid }}); + } + elsif (($port < 1) or ($port > 65535)) + { + # Out of range + $valid = 0; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { valid => $valid }}); + } + + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { valid => $valid }}); + return($valid); +} + =head2 is_positive_integer This method verifies that the passed in value is a positive integer. diff --git a/cgi-bin/striker b/cgi-bin/striker index 9e2dce94..f6dc02e0 100755 --- a/cgi-bin/striker +++ b/cgi-bin/striker @@ -411,6 +411,8 @@ sub process_email_server_page my $say_login_password = defined $anvil->data->{cgi}{login_password}{value} ? $anvil->data->{cgi}{login_password}{value} : ""; my $say_connection_security = defined $anvil->data->{cgi}{connection_security}{value} ? $anvil->data->{cgi}{connection_security}{value} : "ifn_link1"; my $say_authentication_method = defined $anvil->data->{cgi}{authentication_method}{value} ? $anvil->data->{cgi}{authentication_method}{value} : "ifn_link1"; + my $say_port = defined $anvil->data->{cgi}{port}{value} ? $anvil->data->{cgi}{port}{value} : ""; + my $say_helo_domain = defined $anvil->data->{cgi}{helo_domain}{value} ? $anvil->data->{cgi}{helo_domain}{value} : ""; my $say_back = defined $anvil->data->{cgi}{back}{value} ? $anvil->data->{cgi}{back}{value} : ""; my $say_save = defined $anvil->data->{cgi}{save}{value} ? $anvil->data->{cgi}{save}{value} : ""; my $say_confirm = defined $anvil->data->{cgi}{confirm}{value} ? $anvil->data->{cgi}{confirm}{value} : ""; @@ -429,12 +431,43 @@ sub process_email_server_page { $say_save = ""; $say_confirm = ""; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { say_save => $say_save, say_confirm => $say_confirm, }}); } + # if the user put a port on the mail server, break it off now. + my $test_outgoing_mail_server = $say_outgoing_mail_server; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { test_outgoing_mail_server => $test_outgoing_mail_server }}); + if ($test_outgoing_mail_server =~ /^(.*):(\d+)$/) + { + $test_outgoing_mail_server = $1; + $say_port = $2; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + test_outgoing_mail_server => $test_outgoing_mail_server, + say_port => $say_port, + }}); + } + else + { + # Port wasn't passed. Use '143' unless $say_connection_security is 'ssl_tls' + $say_port = 143; + if ($say_connection_security eq "ssl_tls") + { + $say_port = 993; + } + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { say_port => $say_port }}); + } + + ### NOTE: For now, the HELO domain is not configurable by the user. + # If we don't have $say_helo_domain, use the host's domain + if (not $say_helo_domain) + { + $say_helo_domain = $anvil->_domain_name(); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { say_helo_domain => $say_helo_domain }}); + } + if ($say_save) { # Did the user give an outgoing mail server? @@ -443,15 +476,15 @@ sub process_email_server_page # Just silently send them back to the form. $say_save = ""; $say_confirm = ""; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { say_save => $say_save, say_confirm => $say_confirm, }}); } - # Verify that the mail server is sane (it's all we can check) - if ((not $anvil->Validate->is_ipv4({ip => $say_outgoing_mail_server})) and - (not $anvil->Validate->is_domain_name({name => $say_outgoing_mail_server}))) + # Verify that the mail server and ports are sane. + if ((not $anvil->Validate->is_ipv4({ip => $test_outgoing_mail_server})) and + (not $anvil->Validate->is_domain_name({name => $test_outgoing_mail_server}))) { # Bad domain my $error_message = $anvil->Words->string({key => "warning_0023"}); @@ -459,7 +492,23 @@ sub process_email_server_page $anvil->data->{cgi}{outgoing_mail_server}{alert} = 1; $say_save = ""; $say_confirm = ""; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + error_message => $error_message, + "form::error_massage" => $anvil->data->{form}{error_massage}, + "cgi::outgoing_mail_server::alert" => $anvil->data->{cgi}{outgoing_mail_server}{alert}, + say_save => $say_save, + say_confirm => $say_confirm, + }}); + } + if (not $anvil->Validate->is_port({port => $say_port})) + { + # Bad port + my $error_message = $anvil->Words->string({key => "warning_0024"}); + $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $error_message }}); + $anvil->data->{cgi}{outgoing_mail_server}{alert} = 1; + $say_save = ""; + $say_confirm = ""; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { error_message => $error_message, "form::error_massage" => $anvil->data->{form}{error_massage}, "cgi::outgoing_mail_server::alert" => $anvil->data->{cgi}{outgoing_mail_server}{alert}, @@ -476,6 +525,36 @@ sub process_email_server_page if ($say_confirm) { # Save! + my ($mail_server_uuid) = $anvil->Database->insert_or_update_mail_servers({ + debug => 2, + mail_server_address => $test_outgoing_mail_server, + mail_server_authentication => $say_authentication_method, + mail_server_helo_domain => $say_helo_domain, + mail_server_password => $say_login_password, + mail_server_port => $say_port, + mail_server_security => $say_connection_security, + mail_server_username => $say_login_name, + }); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mail_server_uuid => $mail_server_uuid }}); + if ($mail_server_uuid) + { + # Saved successfully. + my $ok_message = $anvil->Words->string({key => "ok_0001"}); + $anvil->data->{form}{ok_message} = $anvil->Template->get({file => "main.html", name => "ok_message", variables => { ok_message => $ok_message }}); + + # Clear the form + $say_outgoing_mail_server = ""; + $say_login_name = ""; + $say_login_password = ""; + $say_connection_security = ""; + $say_authentication_method = ""; + } + else + { + # Something went wrong... + my $error_message = $anvil->Words->string({key => "warning_0025"}); + $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $error_message }}); + } } else { @@ -487,11 +566,14 @@ sub process_email_server_page $anvil->data->{form}{back_link} =~ s/save=.*?$//; $anvil->data->{form}{refresh_link} = ""; $anvil->data->{form}{body} = $anvil->Template->get({file => "email.html", name => "mail-server-confirm", variables => { - outgoing_mail_server => $say_outgoing_mail_server, - login_name => $say_login_name, - login_password => $say_login_password, - connection_security => $say_connection_security, - authentication_method => $say_authentication_method, + say_outgoing_mail_server => $test_outgoing_mail_server.":".$say_port, + outgoing_mail_server => $say_outgoing_mail_server, + port => $say_port, + login_name => $say_login_name, + login_password => $say_login_password, + connection_security => $say_connection_security, + authentication_method => $say_authentication_method, + helo_domain => $say_helo_domain, }}); return(0); } @@ -502,7 +584,7 @@ sub process_email_server_page my $outgoing_mail_server_form = $anvil->Template->get({file => "main.html", name => "input_text_form", variables => { name => "outgoing_mail_server", id => "outgoing_mail_server", - field => "#!string!striker_0168!#", + field => "#!string!striker_0185!#", description => "#!string!striker_0169!#", value => $say_outgoing_mail_server, default_value => "", diff --git a/html/skins/alteeve/email.html b/html/skins/alteeve/email.html index 7548a950..5120838b 100644 --- a/html/skins/alteeve/email.html +++ b/html/skins/alteeve/email.html @@ -135,8 +135,9 @@ #!string!striker_0168!# -   #!variable!outgoing_mail_server!# +   #!variable!say_outgoing_mail_server!# + @@ -173,6 +174,20 @@   #!variable!authentication_method!# + + + + + +   + + + + + + + + @@ -183,16 +198,9 @@   - - - - - - - - + diff --git a/html/skins/alteeve/main.css b/html/skins/alteeve/main.css index cc2524f0..70886999 100644 --- a/html/skins/alteeve/main.css +++ b/html/skins/alteeve/main.css @@ -308,6 +308,22 @@ td.button_cell { text-align: center; } +td.close_top { + border-top: 1px solid #8f8f8f; + border-left: 1px solid transparent; + border-right: 1px solid transparent; + border-bottom: 1px solid transparent; +} + +td.no_border { + border: 1px solid transparent; +} + +td.no_border_right { + border: 1px solid transparent; + text-align: right; +} + td.column_header { text-align: left; color: #9ba0a5; diff --git a/share/anvil.sql b/share/anvil.sql index df7eb88e..b15fbee0 100644 --- a/share/anvil.sql +++ b/share/anvil.sql @@ -584,15 +584,23 @@ BEGIN SELECT INTO history_mail_servers * FROM mail_servers WHERE mail_server_uuid = new.mail_server_uuid; INSERT INTO history.mail_servers (mail_server_uuid, - mail_server_recipient_uuid, - mail_server_anvil_uuid, - mail_server_alert_level, + mail_server_address, + mail_server_port, + mail_server_username, + mail_server_password, + mail_server_security, + mail_server_authentication, + mail_server_helo_domain, modified_date) VALUES (history_mail_servers.mail_server_uuid, - history_mail_servers.mail_server_recipient_uuid, - history_mail_servers.mail_server_anvil_uuid, - history_mail_servers.mail_server_alert_level, + history_mail_servers.mail_server_address, + history_mail_servers.mail_server_port, + history_mail_servers.mail_server_username, + history_mail_servers.mail_server_password, + history_mail_servers.mail_server_security, + history_mail_servers.mail_server_authentication, + history_mail_servers.mail_server_helo_domain, history_mail_servers.modified_date); RETURN NULL; END; diff --git a/share/words.xml b/share/words.xml index 1559341b..7457dae2 100644 --- a/share/words.xml +++ b/share/words.xml @@ -802,6 +802,7 @@ Failed to promote the DRBD resource: [#!variable!resource!#] primary. Expected a About to rename the network interface: [#!variable!old_interface!#] to: [#!variable!new_interface!#] Disconnected from all databases and closing all open SSH sessions. Will reconnect after the network configuration changes have taken effect. Network reconfiguration is complete! + Skipping the OUI parse. The next scheduled parse will be done in: [#!variable!next_parse!#]. Override with '--force'. Test @@ -1042,6 +1043,8 @@ If you are comfortable that the target has changed for a known reason, you can s OAuth2 Connection Security Authentication method + host_or_ip[:port] + Indicates when the last time the OUI file was parsed. This is done to translate MAC addresses (and IPs associated with those MAC addresses) to the company that owns them. #!variable!number!#/sec @@ -1185,6 +1188,9 @@ Failure! The return code: [#!variable!return_code!#] was received ('0' was expec Something went wrong adding this database. Please see: [#!data!path::log::main!#] for details. The network configuration will be updated based on the variables stored in the database. When complete, the system will reboot. + + Saved the mail server information successfully! + The IP address will change. You will need to reconnect after applying these changes. The access information appears to not be valid. @@ -1209,6 +1215,8 @@ Failure! The return code: [#!variable!return_code!#] was received ('0' was expec All three networks require the first network pair to be defined. Only one network interface selected for a network pair. The outgoing mail server appear to not be a valid domain name or IP address. + The outgoing mail server port is not valid. Must be 'mail_server:x' where x is 1 ~ 65535. + There was a problem saving the mail server data. Please check the logs for more information. There are not enough network interfaces on this machine. You have: [#!variable!interface_count!#] interface(s), and you need at least: [#!variable!required_interfaces_for_single!#] interfaces to connect to the requested networks (one for Back-Channel and one for each Internet-Facing network). diff --git a/tools/striker-parse-oui b/tools/striker-parse-oui index d94ddd0b..986fc48d 100755 --- a/tools/striker-parse-oui +++ b/tools/striker-parse-oui @@ -36,15 +36,19 @@ if (not $anvil->data->{sys}{database}{connections}) } $anvil->data->{switches}{'job-uuid'} = ""; +$anvil->data->{switches}{force} = ""; $anvil->Get->switches; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "switches::job-uuid" => $anvil->data->{switches}{'job-uuid'}, + "switches::force" => $anvil->data->{switches}{force}, }}); update_progress($anvil, 0, "clear"); update_progress($anvil, 1, "log_0239,!!job-uuid!".$anvil->data->{switches}{'job-uuid'}."!!"); $anvil->data->{progress} = 1; +check_if_time($anvil); + my $oui_file = $anvil->Get->users_home({debug => 3})."/oui.txt"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { oui_file => $oui_file }}); @@ -121,6 +125,18 @@ if ((-e $oui_file) && ($process)) process_oui($anvil, $oui_file); } +# Update the parse time to now. +$anvil->Database->insert_or_update_variables({ + debug => 2, + variable_name => "parse-oui::parsed", + variable_value => time, + variable_default => "", + variable_description => "striker_0186", + variable_section => "system", + variable_source_uuid => $anvil->Get->host_uuid, + variable_source_table => "hosts", +}); + # We're done print $anvil->Words->string({key => "message_0025"})."\n"; update_progress($anvil, 100, "message_0025"); @@ -131,6 +147,76 @@ $anvil->nice_exit({exit_code => 0}); # Functions # ############################################################################################################# +# This checks to see if it's time to parse the OUI file yet or not. If not, it will exit the program. If so, +# it returns with '0'. +sub check_if_time +{ + my ($anvil) = @_; + + # NOTE: We only scan once a day, unless 'force' is used. + if ($anvil->data->{switches}{force}) + { + return(0); + } + elsif (not $anvil->data->{switches}{'job-uuid'}) + { + # No job_uuid, so a manual call. + return(0); + } + else + { + my ($unixtime, $variable_uuid, $modified_date) = $anvil->Database->read_variable({variable_name => "parse-oui::parsed"}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + unixtime => $unixtime, + variable_uuid => $variable_uuid, + modified_date => $modified_date, + }}); + if (($unixtime eq "") or ($unixtime =~ /\D/)) + { + $unixtime = 0; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { unixtime => $unixtime }}); + } + + # If the database variable 'parse-oui::parsed' is not set, or is more than 24 hours old, + # proceed with the parse. + $anvil->data->{'parse-oui'}{'parse-period'} = 86400 if not defined $anvil->data->{'parse-oui'}{'parse-period'}; + $anvil->data->{'parse-oui'}{'parse-period'} =~ s/,//g; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + 'parse-oui::parse-period' => $anvil->data->{'parse-oui'}{'scan-period'}, + }}); + if ($anvil->data->{'parse-oui'}{'parse-period'} =~ /\D/) + { + $anvil->data->{'parse-oui'}{'parse-period'} = 86400; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + 'parse-oui::parse-period' => $anvil->data->{'parse-oui'}{'parse-period'}, + }}); + } + my $time_now = time; + my $next_parse = $unixtime + $anvil->data->{'parse-oui'}{'parse-period'}; + my $difference = ($next_parse - $time_now); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + 's1:time_now' => $time_now, + 's2:next_parse' => $next_parse, + 's3:difference' => $difference, + }}); + if ((not $variable_uuid) or ($unixtime !~ /^\d+/) or ($difference < 0)) + { + # It's been long enough (or it's the first time), scan. + return(0); + } + elsif ($difference > 0) + { + # Log when the next scan will happen and then exit. + my $say_when = $anvil->Convert->time({'time' => $difference, long => 1}); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, 'print' => 1, key => "log_0468", variables => { next_parse => $anvil->Convert->add_commas({number => $say_when}) }}); + update_progress($anvil, 100, "log_0468,!!next_parse!".$anvil->Convert->add_commas({number => $say_when})."!!"); + $anvil->nice_exit({exit_code => 3}); + } + } + + return(0); +} + # If this is being called as a job, this will allow the progress to be updated. sub update_progress {