Skip Menu |

This queue is for tickets about the Net-SSH-Expect CPAN distribution.

Report information
The Basics
Id: 115858
Status: open
Priority: 0/
Queue: Net-SSH-Expect

People
Owner: Nobody in particular
Requestors: chohag [...] jtan.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: ssh(1) does not require a username
Date: Mon, 04 Jul 2016 15:03:38 +0300
To: bug-Net-SSH-Expect [...] rt.cpan.org, bnegrao [...] cpan.org
From: chohag [...] jtan.com
ssh has its own default username, or obtains it from ~/.ssh/config, which process Net::SSH::Expect overrides. The attached patch allows the ssh calculation to still take place if a user is not provided and hopefully handles correctly the case where a username is prompted for. diff -ur perl5-Net::SSH::Expect.orig/lib/Net/SSH/Expect.pm perl5-Net::SSH::Expect/lib/Net/SSH/Expect.pm --- perl5-Net::SSH::Expect.orig/lib/Net/SSH/Expect.pm Wed Apr 23 05:18:13 2008 +++ perl5-Net::SSH::Expect/lib/Net/SSH/Expect.pm Mon Jul 4 13:19:49 2016 @@ -28,8 +28,8 @@ my Net::SSH::Expect $self = fields::new(ref $type || $type); # Options used to configure the SSH command - $self->{host} = $args{host}|| undef; - $self->{user} = $args{user} || $ENV{'USER'}; + $self->{host} = $args{host} || undef; + $self->{user} = $args{user} || undef; $self->{password} = $args{password} || undef; $self->{port} = $args{port} || undef; # ssh -p $self->{no_terminal} = $args{no_terminal} || 0; # ssh -T @@ -73,14 +73,14 @@ # 2) Define the ssh command line using the defaults and user-defined settings # 3) Fork the ssh process using the spawn() method of the Expect instance we created. # The SSH connection is established on this step using the user account set in the 'user' -# constructor attribute. No password is sent here, that happens only in the login() method. +# constructor attribute or relying on ssh(1)'s default. No password is sent here, that +# happens only in the login() method. # # This method is run internally by the login() method so you don't need to run it yourself # in most of the cases. You'll run this method alone if you had set up public-key authentication # between the ssh client and the ssh server. In this case you only need to call this method # to have an authenticated ssh connection, you won't call login(). Note that when you -# use public-key authentication you won't need to set the 'password' constructor attribute -# but you still need to define the 'user' attribute. +# use public-key authentication you won't need to set the 'password' constructor attribute. # If you don't know how to setup public-key authentication there's a good guide at # http://sial.org/howto/openssh/publickey-auth/ # @@ -93,7 +93,6 @@ my $host = $self->{host}; croak(ILLEGAL_STATE . " field 'host' is not set.") unless $host; - croak(ILLEGAL_STATE . " field 'user' is not set.") unless $user; my $log_file = $self->{log_file}; my $log_stdout = $self->{log_stdout}; @@ -114,7 +113,9 @@ $flags .= $ssh_option if $ssh_option; # this sets the ssh command line - my $ssh_string = $self->{binary} . " $flags $user\@$host"; + my $ssh_string = $self->{binary} . " $flags "; + $ssh_string .= "$user\@" if $user; + $ssh_string .= $host; # creating the Expect object my $exp = new Expect(); @@ -165,7 +166,7 @@ # welcome message and/or the remote prompt. You could use this string to do your verification # that the login was successful. The content returned is removed from the input stream. # dies: -# IllegalState: if any of 'host' or 'user' or 'password' fields are unset. +# IllegalState: if 'host' or 'password' fields are unset. # SSHProccessError: if run_ssh() failed to spawn the ssh process # SSHConnectionError: if the connection failed for some reason, like invalid 'host' address or network problems. sub login { @@ -188,7 +189,6 @@ my $timeout = $self->{timeout}; my $t = $self->{terminator}; - croak(ILLEGAL_STATE . " field 'user' is not set.") unless $user; croak(ILLEGAL_STATE . " field 'password' is not set.") unless $password; # spawns the ssh process if this wasn't done yet @@ -202,7 +202,17 @@ $self->_sec_expect($timeout, [ qr/\(yes\/no\)\?\s*$/ => sub { $exp->send("yes$t"); exp_continue; } ], [ $password_prompt => sub { $exp->send("$password$t"); } ], - [ $login_prompt => sub { $exp->send("$user$t"); exp_continue; } ], + [ $login_prompt => sub { + if (not $user) { + $user = $self->user($ENV{'USER'}); + if ($user) { + warn "Login prompt detected and 'user' field is not set; using $user from \$USER."; + } else { + die "Login prompt detected and 'user' field is not set"; + } + } + $exp->send("$user$t"); exp_continue; + } ], [ qr/REMOTE HOST IDEN/ => sub { print "FIX: .ssh/known_hosts\n"; exp_continue; } ], [ timeout => sub { diff -ur perl5-Net::SSH::Expect.orig/lib/Net/SSH/Expect.pod perl5-Net::SSH::Expect/lib/Net/SSH/Expect.pod --- perl5-Net::SSH::Expect.orig/lib/Net/SSH/Expect.pod Wed Apr 23 05:18:17 2008 +++ perl5-Net::SSH::Expect/lib/Net/SSH/Expect.pod Mon Jul 4 13:22:37 2016 @@ -103,7 +103,8 @@ This module is a wrapper to the I<ssh> executable that is available in your system's I<$PATH>. Use this module to execute commands on the remote SSH server. It authenticates with the user and password you passed in the constructor's attributes -C<user> and C<password>. +C<user> and C<password>. If C<user> is not supplied it relies on ssh providing the default unless +it detects a login prompt, in which case it falls back to the $USER environment variable. Once an ssh connection was started using the C<connect()> method it will remain open until you call the C<close()> method. This allows you execute as many commands as you want @@ -298,14 +299,14 @@ # 2) Define the ssh command line using the defaults and user-defined settings # 3) Fork the ssh process using the spawn() method of the Expect instance we created. # The SSH connection is established on this step using the user account set in the 'user' - # constructor attribute. No password is sent here, that happens only in the login() method. + # constructor attribute or relying on ssh(1)'s default. No password is sent here, that + # happens only in the login() method. # # This method is run internally by the login() method so you don't need to run it yourself # in most of the cases. You'll run this method alone if you had set up public-key authentication # between the ssh client and the ssh server. In this case you only need to call this method # to have an authenticated ssh connection, you won't call login(). Note that when you - # use public-key authentication you won't need to set the 'password' constructor attribute - # but you still need to define the 'user' attribute. + # use public-key authentication you won't need to set the 'password' constructor attribute. # If you don't know how to setup public-key authentication there's a good guide at # http://sial.org/howto/openssh/publickey-auth/ # @@ -346,7 +347,7 @@ # welcome message and/or the remote prompt. You could use this string to do your verification # that the login was successful. The content returned is removed from the input stream. # dies: - # IllegalState: if any of 'host' or 'user' or 'password' fields are unset. + # IllegalState: if 'host' or 'password' fields are unset. # SSHProccessError: if run_ssh() failed to spawn the ssh process # SSHConnectionError: if the connection failed for some reason, like invalid 'host' address or network problems.
Hey Bruno, can we get this added? It looks like it would be useful. Perhaps as an option to the constructor so we can retain current behavior. Jason
On Tue Aug 01 18:03:24 2017, jason@froebe.net wrote: Show quoted text
> Hey Bruno, can we get this added? It looks like it would be useful. > Perhaps as an option to the constructor so we can retain current > behavior. > > Jason
Jason, I'm not maintaining this module anymore. Would you like to be the new maintainer?