Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Anvil/Tools.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1318,6 +1318,7 @@ sub _set_paths
man => "/usr/bin/man",
md5sum => "/usr/bin/md5sum",
'mkdir' => "/usr/bin/mkdir",
'mktemp' => "/usr/bin/mktemp",
modifyrepo_c => "/usr/bin/modifyrepo_c",
modprobe => "/usr/sbin/modprobe",
mv => "/usr/bin/mv",
Expand Down Expand Up @@ -1367,6 +1368,7 @@ sub _set_paths
snmpset => "/usr/bin/snmpset",
'sort' => "/usr/bin/sort",
ss => "/usr/sbin/ss",
'ssh-copy-id' => "/usr/bin/ssh-copy-id",
'ssh-keygen' => "/usr/bin/ssh-keygen",
'ssh-keyscan' => "/usr/bin/ssh-keyscan",
'stat' => "/usr/bin/stat",
Expand Down
141 changes: 50 additions & 91 deletions Anvil/Tools/Remote.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1139,7 +1139,7 @@ sub test_access
my $self = shift;
my $parameter = shift;
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
my $debug = 1;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Remote->test_access()" }});

my $close = defined $parameter->{'close'} ? $parameter->{'close'} : 1;
Expand Down Expand Up @@ -1319,106 +1319,65 @@ sub test_access
}});
return(0);
}

# Read the target's authorized_keys file.
my $target_authorized_keys_file = "/root/.ssh/authorized_keys";
if ($user ne "root")
{
$target_authorized_keys_file = "/home/".$user."/.ssh/authorized_keys";
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { target_authorized_keys_file => $target_authorized_keys_file }});

my $old_authorized_keys_body = $anvil->Storage->read_file({
debug => $debug,
file => $target_authorized_keys_file,
force_read => 1,
port => $port,
password => $this_password,
remote_user => $user,
target => $target,

my $wrapper_script = $anvil->System->create_ssh_copy_id_wrapper({
debug => $debug,
target => $target,
password => $this_password,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { old_authorized_keys_body => $old_authorized_keys_body }});
if ($old_authorized_keys_body eq "!!error!!")
{
# Failed to read.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "log_0176", variables => {
target => $target,
password => $anvil->Log->is_secure($this_password),
file => $public_key_file,
}});
return(0);
}

# Look for our key
my $key_found = 0;
my $new_authorized_keys_body = "";
foreach my $line (split/\n/, $old_authorized_keys_body)
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { wrapper_script => $wrapper_script }});

my $shell_call = $wrapper_script." -i ".$public_key_file." -p ".$port." ".$user."@".$target;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { shell_call => $shell_call }});

# Copy the public key to the target
my ($output, $return_code) = $anvil->System->call({secure => 1, shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, secure => 1, list => { output => $output, return_code => $return_code }});

if (($wrapper_script) && (-e $wrapper_script))
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }});
if ($line eq $rsa_key)
{
$key_found = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { key_found => $key_found }});
last;
}
$new_authorized_keys_body .= $line."\n";
unlink $wrapper_script;
}
if (not $key_found)

if ($return_code)
{
# Append our key.
$new_authorized_keys_body .= $rsa_key."\n";

# Write out the new file.
my $problem = $anvil->Storage->write_file({
debug => $debug,
backup => 1,
file => $target_authorized_keys_file,
body => $new_authorized_keys_body,
group => $user,
mode => "0644",
overwrite => 1,
port => $port,
password => $this_password,
target => $target,
user => $user,
remote_user => $user,
});
if ($problem)
{
# Failed.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "log_0194", variables => {
target => $target,
file => $target_authorized_keys_file,
}});
return(0);
}

# Try to connect again, without a password this time.
my $access = $anvil->Remote->test_access({
debug => $debug,
'close' => $close,
password => "",
port => $port,
target => $target,
user => $user,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { access => $access }});

# Did we get access?
if ($access)
if ($output =~ / All keys were skipped because they already exist on the remote system/s)
{
# Success!
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "log_0195", variables => { target => $target }});
return($access);
# Continue to retry because the key exists on the target.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "log_0176", variables => { target => $target }});
}
else
{
# Welp, we tried.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "log_0196", variables => { target => $target }});
return($access);
# Log and stop here because adding the key failed with a different reason.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "log_0194", variables => { target => $target }});
return(0);
}
}

# Try to connect again, without a password this time.
my $access = $anvil->Remote->test_access({
debug => $debug,
'close' => $close,
password => "",
port => $port,
target => $target,
user => $user,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { access => $access }});

# Did we get access?
if ($access)
{
# Success!
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "log_0195", variables => { target => $target }});
return($access);
}
else
{
# Welp, we tried.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "log_0196", variables => { target => $target }});
return($access);
}
}
else
{
Expand Down
82 changes: 2 additions & 80 deletions Anvil/Tools/Storage.pm
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ my $THIS_FILE = "Storage.pm";
# update_config
# update_file
# write_file
# _create_rsync_wrapper
# _wait_if_changing

=pod
Expand Down Expand Up @@ -4882,7 +4881,7 @@ sub rsync
if ($password)
{
# Remote target, wrapper needed.
$wrapper_script = $anvil->Storage->_create_rsync_wrapper({
$wrapper_script = $anvil->System->create_rsync_wrapper({
debug => $debug,
target => $target,
password => $password,
Expand Down Expand Up @@ -6052,83 +6051,6 @@ fi";
#############################################################################################################


=head2 _create_rsync_wrapper

This does the actual work of creating the C<< expect >> wrapper script and returns the path to that wrapper for C<< rsync >> calls.

If there is a problem, an empty string will be returned.

Parameters;

=head3 target (required)

This is the IP address or (resolvable) host name of the remote machine.

=head3 password (required)

This is the password of the user you will be connecting to the remote machine as.

=cut
sub _create_rsync_wrapper
{
my $self = shift;
my $parameter = shift;
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Storage->_create_rsync_wrapper()" }});

# Check my parameters.
my $target = defined $parameter->{target} ? $parameter->{target} : "";
my $password = defined $parameter->{password} ? $parameter->{password} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
password => $anvil->Log->is_secure($password),
target => $target,
}});

if (not $target)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Storage->_create_rsync_wrapper()", parameter => "target" }});
return("");
}
if (not $password)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Storage->_create_rsync_wrapper()", parameter => "password" }});
return("");
}

### NOTE: The first line needs to be the '#!...' line, hence the odd formatting below.
my $timeout = 3600;
my $wrapper_script = "/tmp/rsync.$target";
my $wrapper_body = "#!".$anvil->data->{path}{exe}{expect}."
set timeout ".$timeout."
eval spawn rsync \$argv
expect \"password:\" \{ send \"".$password."\\n\" \}
expect eof
";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
wrapper_script => $wrapper_script,
wrapper_body => $wrapper_body,
}});
$anvil->Storage->write_file({
debug => $debug,
body => $wrapper_body,
file => $wrapper_script,
mode => "0700",
overwrite => 1,
secure => 1,
});

if (not -e $wrapper_script)
{
# Failed!
$wrapper_script = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 0, list => { wrapper_script => $wrapper_script }});
}

return($wrapper_script);
}


=head3 _wait_if_changing

This takes a full path to a file, and watches it for at specified number of seconds to see if the size is changing. If it is, this method waits until the file size stops changing.
Expand All @@ -6154,7 +6076,7 @@ sub _wait_if_changing
my $parameter = shift;
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Storage->_create_rsync_wrapper()" }});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Storage->_wait_if_changing()" }});

# Check my parameters.
my $file = defined $parameter->{file} ? $parameter->{file} : "";
Expand Down
Loading