* Created tools/striker-get-peer-data that will query a target's host UUID and host name. It's meant to be called by apache, avoiding apache itself needing to call ssh against a target machine.
* Fixed a bug in Storage->read_file() where a remote read, where the remote user wasn't specified, would cause the call to hange. * Cleaned up striker->add_sync_peer() to use more clear variable names. Signed-off-by: Digimer <digimer@alteeve.ca>main
parent
b8816382b8
commit
2906a42d96
7 changed files with 266 additions and 26 deletions
@ -0,0 +1,233 @@ |
|||||||
|
#!/usr/bin/perl |
||||||
|
# |
||||||
|
# This program is setuid 'admin' and calls a (new) peer to read its hostname and system UUID. It takes the |
||||||
|
# target's password in via a file. |
||||||
|
# |
||||||
|
# Exit codes; |
||||||
|
# 0 = Normal exit. |
||||||
|
# 1 = Password file given, but not found |
||||||
|
# 2 = Password file given, but not readable |
||||||
|
# 3 = Peer not accessible |
||||||
|
# 4 = Unable to find the peer's host UUID |
||||||
|
# |
||||||
|
|
||||||
|
use strict; |
||||||
|
use warnings; |
||||||
|
use Anvil::Tools; |
||||||
|
|
||||||
|
my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0]; |
||||||
|
my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0]; |
||||||
|
if (($running_directory =~ /^\./) && ($ENV{PWD})) |
||||||
|
{ |
||||||
|
$running_directory =~ s/^\./$ENV{PWD}/; |
||||||
|
} |
||||||
|
|
||||||
|
# Turn off buffering so that the pinwheel will display while waiting for the SSH call(s) to complete. |
||||||
|
$| = 1; |
||||||
|
|
||||||
|
my $anvil = Anvil::Tools->new(); |
||||||
|
$anvil->Log->level({set => 2}); |
||||||
|
$anvil->Log->secure({set => 1}); |
||||||
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0115", variables => { program => $THIS_FILE }}); |
||||||
|
|
||||||
|
# Read switches (target ([user@]host[:port]) and the file with the target's password. |
||||||
|
$anvil->data->{switches}{target} = ""; |
||||||
|
$anvil->data->{switches}{password} = ""; |
||||||
|
$anvil->Get->switches; |
||||||
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { |
||||||
|
'switches::target' => $anvil->data->{switches}{target}, |
||||||
|
'switches::password' => $anvil->data->{switches}{password}, |
||||||
|
}}); |
||||||
|
|
||||||
|
$anvil->data->{target}{user} = "admin"; |
||||||
|
$anvil->data->{target}{host} = $anvil->data->{switches}{target}; |
||||||
|
$anvil->data->{target}{port} = 22; |
||||||
|
$anvil->data->{target}{password} = get_password($anvil); |
||||||
|
if ($anvil->data->{target}{host} =~ /^(.*?)@/) |
||||||
|
{ |
||||||
|
$anvil->data->{target}{user} = $1; |
||||||
|
$anvil->data->{target}{host} =~ s/^(.*?)@//; |
||||||
|
} |
||||||
|
if ($anvil->data->{target}{host} =~ /:(\d+)$/) |
||||||
|
{ |
||||||
|
$anvil->data->{target}{port} = $1; |
||||||
|
$anvil->data->{target}{host} =~ s/:(\d+)$//; |
||||||
|
} |
||||||
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||||
|
'target::user' => $anvil->data->{target}{user}, |
||||||
|
'target::target' => $anvil->data->{target}{host}, |
||||||
|
'target::port' => $anvil->data->{target}{port}, |
||||||
|
'target::password' => $anvil->Log->is_secure($anvil->data->{target}{password}), |
||||||
|
}}); |
||||||
|
|
||||||
|
my $host_uuid = get_host_uuid($anvil); |
||||||
|
my $host_name = get_host_name($anvil); |
||||||
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||||
|
host_uuid => $host_uuid, |
||||||
|
host_name => $host_name, |
||||||
|
}}); |
||||||
|
print "host_name=".$host_name."\n"; |
||||||
|
print "host_uuid=".$host_uuid."\n"; |
||||||
|
|
||||||
|
$anvil->nice_exit({code => 0}); |
||||||
|
|
||||||
|
|
||||||
|
############################################################################################################# |
||||||
|
# Functions # |
||||||
|
############################################################################################################# |
||||||
|
|
||||||
|
# This tries to read the target's UUID either via host.uuid or via dmidecode. |
||||||
|
sub get_host_name |
||||||
|
{ |
||||||
|
my ($anvil) = @_; |
||||||
|
|
||||||
|
my ($host_name, $error, $return_code) = $anvil->Remote->call({ |
||||||
|
debug => 2, |
||||||
|
shell_call => $anvil->data->{path}{exe}{hostnamectl}." --static", |
||||||
|
user => $anvil->data->{target}{user}, |
||||||
|
target => $anvil->data->{target}{host}, |
||||||
|
port => $anvil->data->{target}{port}, |
||||||
|
password => $anvil->data->{target}{password}, |
||||||
|
}); |
||||||
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||||
|
host_name => $host_name, |
||||||
|
error => $error, |
||||||
|
return_code => $return_code, |
||||||
|
}}); |
||||||
|
|
||||||
|
return($host_name); |
||||||
|
} |
||||||
|
|
||||||
|
# This tries to read the target's UUID either via host.uuid or via dmidecode. |
||||||
|
sub get_host_uuid |
||||||
|
{ |
||||||
|
my ($anvil) = @_; |
||||||
|
|
||||||
|
# This is the first thing called, so start by verifying we can talk to the target at all. |
||||||
|
my $access = $anvil->Remote->test_access({ |
||||||
|
user => $anvil->data->{target}{user}, |
||||||
|
target => $anvil->data->{target}{host}, |
||||||
|
port => $anvil->data->{target}{port}, |
||||||
|
password => $anvil->data->{target}{password}, |
||||||
|
}); |
||||||
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { access => $access }}); |
||||||
|
if (not $access) |
||||||
|
{ |
||||||
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0069", variables => { |
||||||
|
host => $anvil->data->{target}{user}.'@'.$anvil->data->{target}{host}.':'.$anvil->data->{target}{port}, |
||||||
|
}}); |
||||||
|
$anvil->nice_exit({exit_code => 3}); |
||||||
|
} |
||||||
|
|
||||||
|
# Try to read the host.uuid file on the target, if possible. |
||||||
|
my $host_uuid = ""; |
||||||
|
my $file_body = $anvil->Storage->read_file({ |
||||||
|
debug => 3, |
||||||
|
file => $anvil->data->{path}{data}{host_uuid}, |
||||||
|
user => $anvil->data->{target}{user}, |
||||||
|
target => $anvil->data->{target}{host}, |
||||||
|
port => $anvil->data->{target}{port}, |
||||||
|
password => $anvil->data->{target}{password}, |
||||||
|
}); |
||||||
|
$file_body =~ s/\n$//g; |
||||||
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { file_body => $file_body }}); |
||||||
|
if (($file_body eq "!!error!!") or (not $anvil->Validate->is_uuid({uuid => $file_body}))) |
||||||
|
{ |
||||||
|
# No good, Try dmidecode. |
||||||
|
my ($output, $error, $return_code) = $anvil->Remote->call({ |
||||||
|
debug => 2, |
||||||
|
shell_call => $anvil->data->{path}{exe}{dmidecode}." --string system-uuid", |
||||||
|
user => $anvil->data->{target}{user}, |
||||||
|
target => $anvil->data->{target}{host}, |
||||||
|
port => $anvil->data->{target}{port}, |
||||||
|
password => $anvil->data->{target}{password}, |
||||||
|
}); |
||||||
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||||
|
output => $output, |
||||||
|
error => $error, |
||||||
|
return_code => $return_code, |
||||||
|
}}); |
||||||
|
if ($anvil->Validate->is_uuid({uuid => $output})) |
||||||
|
{ |
||||||
|
# Got it. |
||||||
|
$host_uuid = $output; |
||||||
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_uuid => $host_uuid }}); |
||||||
|
} |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
$host_uuid = $file_body; |
||||||
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_uuid => $host_uuid }}); |
||||||
|
} |
||||||
|
|
||||||
|
# Exit out if I failed to get the host's UUID. |
||||||
|
if (not $host_uuid) |
||||||
|
{ |
||||||
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0070", variables => { |
||||||
|
host => $anvil->data->{target}{user}.'@'.$anvil->data->{target}{host}.':'.$anvil->data->{target}{port}, |
||||||
|
}}); |
||||||
|
$anvil->nice_exit({exit_code => 4}); |
||||||
|
} |
||||||
|
|
||||||
|
return($host_uuid); |
||||||
|
} |
||||||
|
|
||||||
|
# This reads in the password from the password file, if possible. |
||||||
|
sub get_password |
||||||
|
{ |
||||||
|
my ($anvil) = @_; |
||||||
|
|
||||||
|
my $password = ""; |
||||||
|
if ($anvil->data->{switches}{password}) |
||||||
|
{ |
||||||
|
my $found = 0; |
||||||
|
my $file = $anvil->data->{switches}{password}; |
||||||
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { file => $file }}); |
||||||
|
if (-e $file) |
||||||
|
{ |
||||||
|
$found = 1; |
||||||
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { found => $found }}); |
||||||
|
} |
||||||
|
elsif ($anvil->data->{switches}{password} !~ /^\//) |
||||||
|
{ |
||||||
|
$file = "/tmp/".$anvil->data->{switches}{password}; |
||||||
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { file => $file }}); |
||||||
|
if (-e $file) |
||||||
|
{ |
||||||
|
$found = 1; |
||||||
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { found => $found }}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (not $found) |
||||||
|
{ |
||||||
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0067", variables => { file => $file }}); |
||||||
|
$anvil->nice_exit({exit_code => 1}); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
# Read the file in. |
||||||
|
my $body = $anvil->Storage->read_file({ |
||||||
|
debug => 3, |
||||||
|
file => $file, |
||||||
|
secure => 1, |
||||||
|
}); |
||||||
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, secure => 1, list => { body => $body }}); |
||||||
|
|
||||||
|
if ($body eq "!!error!!") |
||||||
|
{ |
||||||
|
# Something went wrong. |
||||||
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0068", variables => { file => $file }}); |
||||||
|
$anvil->nice_exit({exit_code => 2}); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
$password = $body; |
||||||
|
$password =~ s/\n$//; |
||||||
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, secure => 1, list => { password => $password }}); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return($password); |
||||||
|
} |
Loading…
Reference in new issue