[PATCH] testbot/TestAgent: Use Net::OpenSSH instead of Net::SSH2.
Francois Gouget
fgouget at codeweavers.com
Thu Mar 28 16:02:07 CDT 2019
Net::SSH2 just suffers from too many compatiblity issues with OpenSSH
servers.
Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
---
This should fix the TestBot!
testbot/lib/WineTestBot/TestAgent.pm | 148 +++++----------------------
1 file changed, 26 insertions(+), 122 deletions(-)
diff --git a/testbot/lib/WineTestBot/TestAgent.pm b/testbot/lib/WineTestBot/TestAgent.pm
index 21bb534d..3e0e099a 100644
--- a/testbot/lib/WineTestBot/TestAgent.pm
+++ b/testbot/lib/WineTestBot/TestAgent.pm
@@ -3,7 +3,7 @@
# to run scripts.
#
# Copyright 2009 Ge van Geldorp
-# Copyright 2012-2016 Francois Gouget
+# Copyright 2012-2019 Francois Gouget
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -101,9 +101,7 @@ sub new($$$;$)
my $self = {
agenthost => $Hostname,
- host => $Hostname,
agentport => $Port,
- port => $Port,
connection => "$Hostname:$Port",
ctimeout => 20,
cattempts => 3,
@@ -114,9 +112,9 @@ sub new($$$;$)
err => undef};
if ($Tunnel)
{
- $self->{host} = $Tunnel->{sshhost} || $Hostname;
- $self->{port} = $Tunnel->{sshport} || 22;
- $self->{connection} = "$self->{host}:$self->{port}:$self->{connection}";
+ $Tunnel->{sshhost} ||= $Hostname;
+ $Tunnel->{sshport} ||= 22;
+ $self->{connection} = "$Tunnel->{sshhost}:$Tunnel->{sshport}:$self->{connection}";
$self->{tunnel} = $Tunnel;
}
@@ -134,12 +132,8 @@ sub Disconnect($)
# which will avoid undue delays.
$self->{ssh}->disconnect();
$self->{ssh} = undef;
- $self->{nc} = undef;
- }
- if ($self->{sshfd})
- {
- close($self->{sshfd});
- $self->{sshfd} = undef;
+ waitpid($self->{sshpid}, 0);
+ $self->{sshpid} = undef;
}
if ($self->{fd})
{
@@ -210,39 +204,7 @@ sub _SetError($$$)
$self->{err} = $Msg;
# And disconnect on fatal errors since the connection is unusable anyway
- if ($Level == $FATAL)
- {
- if ($self->{ssh})
- {
- # Try to capture the netcat exit code and error message as
- # they may provide important clues as to what went wrong
- my $rc = $self->{fd}->exit_status();
- if ($rc)
- {
- my $ncerr;
- eval
- {
- local $SIG{ALRM} = sub { die "timeout" };
- alarm(2);
- $self->{fd}->read($ncerr, 1024, 1);
- alarm(0);
- };
- $ncerr = $rc if (!$ncerr);
- $ncerr = "the \"$self->{nc}\" command returned $ncerr";
- if ($self->{agentversion})
- {
- $self->{err} .= "\n$ncerr";
- }
- else
- {
- # The real issue is that we failed to connect so
- # ignore the _RecvString('AgentVersion') error message
- $self->{err} = "$ncerr ($self->{rpc})";
- }
- }
- }
- $self->Disconnect();
- }
+ $self->Disconnect() if ($Level == $FATAL);
}
elsif (!$self->{err})
{
@@ -888,8 +850,7 @@ if ($@)
sub _ssherror($)
{
my ($self) = @_;
- my @List = $self->{ssh}->error();
- return $List[2];
+ return $self->{ssh}->error();
}
sub _Connect($)
@@ -910,102 +871,45 @@ sub _Connect($)
$self->{deadline} = $self->{ctimeout} ? time() + $self->{ctimeout} : undef;
$self->_SetAlarm();
- $Step = "create_socket";
- $self->{fd} = &$create_socket(PeerHost => $self->{host},
- PeerPort => $self->{port},
- Type => SOCK_STREAM);
- if (!$self->{fd})
- {
- alarm(0);
- $self->_SetError($FATAL, $!);
- return; # out of eval
- }
-
if ($self->{tunnel})
{
# We are in fact connected to the SSH server.
# Now forward that connection to the TestAgent server.
$Step = "tunnel_connect";
- $self->{sshfd} = $self->{fd};
- $self->{fd} = undef;
- require Net::SSH2;
- $self->{ssh} = Net::SSH2->new();
- $self->{ssh}->debug(1) if ($Debug > 1);
-
- # Set up compression
- $self->{ssh}->method('COMP_CS', 'zlib', 'none');
- $self->{ssh}->method('COMP_SC', 'zlib', 'none');
-
- if (!$self->{ssh}->connect($self->{sshfd}))
+ require Net::OpenSSH;
+ $Net::OpenSSH::debug = ~0 if ($Debug > 1);
+ $self->{ssh} = Net::OpenSSH->new($self->{tunnel}->{sshhost},
+ port => $self->{tunnel}->{sshport},
+ user => $self->{tunnel}->{username},
+ key_path => $self->{tunnel}->{privatekey},
+ batch_mode => 1);
+ if ($self->_ssherror())
{
alarm(0);
$self->_SetError($FATAL, "Unable to connect to the SSH server: " . $self->_ssherror());
return; # out of eval
}
- # Authenticate ourselves
- $Step = "tunnel_auth";
- my $Tunnel = $self->{tunnel};
- my %AuthOptions=(username => $Tunnel->{username} || $ENV{USER});
- foreach my $Key ("username", "password", "publickey", "privatekey",
- "hostname", "local_username")
- {
- $AuthOptions{$Key} = $Tunnel->{$Key} if (defined $Tunnel->{$Key});
- }
- # Old versions of Net::SSH2 won't automatically find DSA keys,
- # and new ones still won't automatically find RSA ones.
- if (defined $ENV{HOME} and !exists $AuthOptions{"privatekey"} and
- !exists $AuthOptions{"publickey"})
- {
- foreach my $key ("id_dsa", "id_rsa")
- {
- if (-f "$ENV{HOME}/.ssh/$key" and -f "$ENV{HOME}/.ssh/$key.pub")
- {
- $AuthOptions{"privatekey"} = "$ENV{HOME}/.ssh/$key";
- $AuthOptions{"publickey"} = "$ENV{HOME}/.ssh/$key.pub";
- last;
- }
- }
- }
- # Interactive authentication makes no sense with automatic reconnects
- $AuthOptions{interact} = 0;
- if (!$self->{ssh}->auth(%AuthOptions))
- {
- alarm(0);
- # auth() returns no error of any sort :-(
- $self->_SetError($FATAL, "Unable to authenticate to the SSH server");
- return; # out of eval
- }
-
$Step = "tunnel_channel";
- $self->{fd} = $self->{ssh}->channel();
+ ($self->{fd}, $self->{sshpid}) = $self->{ssh}->open_tunnel($self->{agenthost}, $self->{agentport});
if (!$self->{fd})
{
alarm(0);
$self->_SetError($FATAL, "Unable to create the SSH channel: " . $self->_ssherror());
return; # out of eval
}
-
- # Check that the agent hostname and port won't mess with quoting.
- if ($self->{agenthost} !~ /^[-a-zA-Z0-9.]*$/ or
- $self->{agentport} !~ /^[a-zA-Z0-9]*$/)
- {
- alarm(0);
- $self->_SetError($FATAL, "The agent hostname or port is invalid");
- return; # out of eval
- }
-
- # Use netcat to forward the connection from the SSH server to the
- # TestAgent server. Note that we won't know about netcat errors at
- # this point.
- $Step = "tunnel_netcat";
- $self->{nc} = "nc -q0 '$self->{agenthost}' '$self->{agentport}'";
- debug("Tunneling command: $self->{nc}\n");
- if (!$self->{fd}->exec($self->{nc}))
+ }
+ else
+ {
+ $Step = "create_socket";
+ $self->{fd} = &$create_socket(PeerHost => $self->{host},
+ PeerPort => $self->{port},
+ Type => SOCK_STREAM);
+ if (!$self->{fd})
{
alarm(0);
- $self->_SetError($FATAL, "Unable to start netcat ($self->{rpc}): " . $self->_ssherror());
+ $self->_SetError($FATAL, $!);
return; # out of eval
}
}
--
2.20.1
More information about the wine-devel
mailing list