slayedbylucifer has asked for the wisdom of the Perl Monks concerning the following question:

Here is what I am trying to do. I have few servers on which i have to make sure the password for a normal user and root is what I think it should. Here is my logic:

write expect script.

ssh as normal user and provide password via expect when needed. --------->If this login is successful, then "su root" and provide root password when needed.

every successful/failed attempt will be written to a log file the script will loop through all the IP address that i have saved in a text file.

My problem is, I am able to verify the normal user's password, but if it is correct, my script is failing to run "su -". here is the script:

#!/usr/bin/perl #use strict; use warnings; use Expect; open WRITE, "> output" or die $!; open READ, "ip_address" or die $!; my @ip_array = <READ>; foreach (@ip_array) { chomp ($_); my $command = "ssh"; my @parameters = ("slayedbylucifer\@$_", "uptime"); my $exp = new Expect; $exp->raw_pty(1); $exp->spawn($command, @parameters) or die "Cannont spwan $command: $!\n"; $exp->log_stdout(0); # stop the output going to STDOUT my $timeout=10; $exp->expect($timeout, [ qr/yes/ => sub { my $exp = shift; $exp->send("yes\r"); exp_continue; } ], [qr/assword/i => sub { my $exp = shift; $exp->send("12345\n"); exp_continue; } ] ); if ($? == 0) { print WRITE "The password is correct for \"slayedbylucifer\" on $ +_\n"; ######### Let's su and check the password for root ####### my $command1 = "su"; my @parameters1 = ("-"); my $exp1 = new Expect; $exp1->raw_pty(1); $exp->spawn($command1, @parameters1) or die "Cannt spawn $command1: $!\n"; $exp->expect($timeout, [qr/assword/i => sub { my $exp1 = shift; $exp->send("root_password\n"); exp_continue; } ] ); if ( $? == 0 ) { print WRITE "The password is correct for \"root\" on $_\n"; } else { print WRITE "The password is wrong for \"root\" on $_\n"; } } else { print WRITE "The password is wrong for \"slayedbylucifer\" on $_ +\n"; } } close WRITE;

and here is the output I get:

Cannot reuse an object with an already spawned command at ./ping.pl li +ne 43

I am not good with the OO stuff, but that's how Expect module works. Thanks.

Replies are listed 'Best First'.
Re: Expect module and running "su"
by ahmad (Hermit) on Dec 28, 2010 at 07:52 UTC

    check this out Net::SSH::Expect

    If you want to continue using your current method, then just try fixing this:

    $exp->spawn($command1, @parameters1) or die "Cannt spawn $command1: $!\n"; $exp->expect($timeout, [qr/assword/i => sub { my $exp1 = shift; $exp->send("root_password\n"); exp_continue; } ] );

    Should be:

    $exp1->spawn($command1, @parameters1) or die "Cannt spawn $command1: $!\n"; $exp1->expect($timeout, [qr/assword/i => sub { my $exp1 = shift; $exp1->send("root_password\n"); exp_continue; } ] );

    As you have defined a new Expect, but you're using the old one?

Re: Expect module and running "su"
by afoken (Chancellor) on Dec 28, 2010 at 18:54 UTC

    I think you should read a little bit about (1) sudo and (2) ssh using public key authentication.

    With sudo, you can get rid of any root password, you provide the current user's password instead. The only time you still need the root password is when the machine is in single user mode and you have to sit in front of the console.

    sudo also allows a finer control of what commands each user can execute, and it logs what commands the users invoke.

    sudo can completely emulate su (get a root login shell) by invoking it with the "-i" parameter.

    ssh can run with public key authentication, and I recommend to disable password authentication completely, so sshd will refuse a login even if an attacker correctly guesses a valid name/password combination.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)