ollyg / Net-Appliance-Session

Development of Net::Appliance::Session Perl distribution
https://metacpan.org/pod/Net::Appliance::Session
12 stars 6 forks source link

Unable to check validity of hostname #15

Closed sakuralihua closed 12 years ago

sakuralihua commented 12 years ago

When I tried to pass an invalid hostname, the code will get into an infinite loop.

my $s = Net::Appliance::Session->new({ personality => 'ios', transport => 'SSH', host => $ip });

Is there a way to overcome this bug?

ollyg commented 12 years ago

I've just released a new version of the module to CPAN which has a fix for this bug. Thanks for the report!

sakuralihua commented 12 years ago

Hi. I have updated the module and the bug still exists. I am passing in an IP address that is not found in the network or is not configured for SSH, the code will get into an infinite loop.

ollyg commented 12 years ago

Okay, thanks for letting me know.

Please would you provide the output of the following two commands on your system:

perl -MNet::CLI::Interact\ 999 perl -MNet::Appliance::Session\ 999

thanks, oliver.

sakuralihua commented 12 years ago

Output of "perl -MNet::CLI::Interact\ 999": Net::CLI::Interact version 999 required--this is only version 1.121570. BEGIN failed--compilation aborted.

Output of "perl -MNet::Appliance::Session\ 999": Net::Appliance::Session version 999 required--this is only version 3.121570. BEGIN failed--compilation aborted.

ollyg commented 12 years ago

Thanks. It's interesting because there is actually a test for your issue in the distribution, and it passes on my system:

https://metacpan.org/source/OLIVER/Net-Appliance-Session-3.121570/t/author-42_ssh_fail_close.t

Please could you provide a short perl program which reproduces the issue so that I can troubleshoot further?

sakuralihua commented 12 years ago

Okay. I have extracted the essential parts of the code. It might not be able to compile as it requires other files to run.

[code] sub check_validIP { my ($ip) = @;

check if the IP address is in the correct format

if(!($ip =~ m/^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$/))
{
    return 0;
}
return 1;

} sub downloadconfig { my ($ip) = @; if(check_valid_IP($ip) == 1) { my $s = Net::Appliance::Session->new({ personality => 'ios', transport => 'SSH', host => $ip });

    eval {
        $s->connect({ username => $username, password => $password });

        $s->begin_privileged({ password => $enable_password });
        #get hostname to set the file name
        $hostname_result = $s->cmd('sh run | inc hostname');
        $hostname_result =~ m/hostname (.*)/;
        $hostname = $1;

        #download the file
        my @running_config = $s->cmd('sh run');
        @running_config = @running_config[ 2 .. (@running_config -1)];#remove header and footer of the file
        open(FH, "> temp/".$hostname.".txt") or die("Cannot open config file : $!");
        print FH @running_config;
        close FH;
        $s->end_privileged;
    };
    if ($@) {
    #when the login details are wrong
        print redirect('../../na/unauthorised.html');
    }
    $s->close;
}
else
{
    print redirect('../../na/unauthorised.html');
}

} download_config("10.106.63.198"); [/code]

10.106.63.198 does not exists in the network thus I expected it to show some form of error message or time-out.

ollyg commented 12 years ago

Sadly I cannot reproduce your problem with this script. I edited the code you provided to what is below, and the output I receive is this:

unauthorised: ssh: connect to host 10.106.63.198 port 22: No route to host

Here's the test script:

#!/usr/bin/perl

use Net::Appliance::Session;
my $ip = '10.106.63.198';

my $s = Net::Appliance::Session->new({
    personality => 'ios',
    transport => 'SSH',
    host => $ip
});
my ($username, $password, $enable_password) = ('user','letmein', 'letmein2');

eval {    $s->connect({ username => $username, password => $password });
    $s->begin_privileged({ password => $enable_password });

    #get hostname to set the file name
    $hostname_result = $s->cmd('sh run | inc hostname');
    $hostname_result =~ m/hostname (.*)/;
    $hostname = $1;

    #download the file
    my @running_config = $s->cmd('sh run');
    #remove header and footer of the file
    @running_config = @running_config[ 2 .. (@running_config -1)];

    open(FH, "> ./".$hostname.".txt") or die("Cannot open config file : $!");
    print FH @running_config;
    close FH;

    $s->end_privileged;
};

if ($@) {
    #when the login details are wrong
    print "unauthorised: $@\n";
}
$s->close;
sakuralihua commented 12 years ago

I copied your code and change the login credentials and I still get an infinite loop. The error log shows the following error: [Thu Jun 07 08:48:07 2012] [error] [client 127.0.0.1] Use of uninitialized value $content in concatenation (.) or string at /usr/lib/perl5/site_perl/5.10/Net/CLI/Interact/Transport/Base/Unix.pm line 42.

ollyg commented 12 years ago

Interesting... Please can you run the script with this environment variable set:

NCI_LOG_AT=debug script.pl ....

and send me the output? You might need to search/replace the username and password with something else in the output. You can email directly to oliver@cpan.org if you want to avoid GitHub.

sakuralihua commented 12 years ago

Here's the output: [0.002097] p finding prompt [0.015047] t creating Net::Telnet wrapper for ssh [0.015598] t command expands to: ssh -l admin 10.106.63.198 [11.218894] p failed: [read timed-out at /usr/lib/perl5/site_perl/5.10/Net/CLI/Interact/Transport/Base/Unix.pm line 41 ], sending WAKE_UP and trying again [11.219651] p finding prompt [21.625277] d SEEN: ssh: connect to host 10.106.63.198 port 22: Connection timed out [21.696945] p reading phrasebook /usr/lib/perl5/site_perl/5.10/Net/CLI/Interact/phrasebook/cisco/pb [21.698497] p storing prompt prompt [21.700197] p storing prompt basic [21.701612] p storing prompt privileged [21.703015] p storing prompt configure [21.704568] p storing prompt user [21.706002] p storing prompt pass [21.707453] p storing macro begin_privileged [21.709432] p storing macro end_privileged [21.711303] p storing macro begin_configure [21.713169] p storing macro end_configure [21.715029] p storing macro disconnect [21.716837] p reading phrasebook /usr/lib/perl5/site_perl/5.10/Net/CLI/Interact/phrasebook/cisco/ios/pb [21.718189] p storing macro paging [21.720038] p nope, doesn't (yet) match basic [21.720638] p nope, doesn't (yet) match pass [21.721206] p nope, doesn't (yet) match user [21.721777] p nope, doesn't (yet) match configure [21.722349] p nope, doesn't (yet) match privileged [21.722949] p nope, doesn't (yet) match prompt [21.723456] p no match so far, more data? Use of uninitialized value $content in concatenation (.) or string at /usr/lib/perl5/site_perl/5.10/Net/CLI/Interact/Transport/Base/Unix.pm line 42. [21.724262] d SEEN: ssh: connect to host 10.106.63.198 port 22: Connection timed out [21.724632] p nope, doesn't (yet) match basic [21.725206] p nope, doesn't (yet) match pass [21.725777] p nope, doesn't (yet) match user [21.726349] p nope, doesn't (yet) match configure [21.726920] p nope, doesn't (yet) match privileged [21.727524] p nope, doesn't (yet) match prompt [21.728032] p no match so far, more data? Use of uninitialized value $content in concatenation (.) or string at /usr/lib/perl5/site_perl/5.10/Net/CLI/Interact/Transport/Base/Unix.pm line 42. [21.728575] d SEEN: ssh: connect to host 10.106.63.198 port 22: Connection timed out [21.728937] p nope, doesn't (yet) match basic [21.729511] p nope, doesn't (yet) match pass [21.730083] p nope, doesn't (yet) match user [21.730653] p nope, doesn't (yet) match configure [21.731225] p nope, doesn't (yet) match privileged [21.731822] p nope, doesn't (yet) match prompt [21.732328] p no match so far, more data? Use of uninitialized value $content in concatenation (.) or string at /usr/lib/perl5/site_perl/5.10/Net/CLI/Interact/Transport/Base/Unix.pm line 42. [21.732871] d SEEN: ssh: connect to host 10.106.63.198 port 22: Connection timed out [21.733233] p nope, doesn't (yet) match basic [21.733799] p nope, doesn't (yet) match pass [21.734545] p nope, doesn't (yet) match user [21.735184] p nope, doesn't (yet) match configure [21.735765] p nope, doesn't (yet) match privileged [21.736387] p nope, doesn't (yet) match prompt [21.736901] p no match so far, more data? Use of uninitialized value $content in concatenation (.) or string at /usr/lib/perl5/site_perl/5.10/Net/CLI/Interact/Transport/Base/Unix.pm line 42. [21.737448] d SEEN: ssh: connect to host 10.106.63.198 port 22: Connection timed out [21.737820] p nope, doesn't (yet) match basic [21.738403] p nope, doesn't (yet) match pass [21.738975] p nope, doesn't (yet) match user [21.739566] p nope, doesn't (yet) match configure [21.740146] p nope, doesn't (yet) match privileged [21.740778] p nope, doesn't (yet) match prompt [21.741340] p no match so far, more data? Use of uninitialized value $content in concatenation (.) or string at /usr/lib/perl5/site_perl/5.10/Net/CLI/Interact/Transport/Base/Unix.pm line 42. [21.741914] d SEEN: ssh: connect to host 10.106.63.198 port 22: Connection timed out [21.742295] p nope, doesn't (yet) match basic [21.742879] p nope, doesn't (yet) match pass [21.743450] p nope, doesn't (yet) match user [21.744021] p nope, doesn't (yet) match configure [21.744585] p nope, doesn't (yet) match privileged [21.745180] p nope, doesn't (yet) match prompt [21.745683] p no match so far, more data? Use of uninitialized value $content in concatenation (.) or string at /usr/lib/perl5/site_perl/5.10/Net/CLI/Interact/Transport/Base/Unix.pm line 42. [21.746226] d SEEN: ssh: connect to host 10.106.63.198 port 22: Connection timed out

It got into an infinite loop with the last few debug lines.

ollyg commented 12 years ago

I've just released a minor update to Net::CLI::Interact and Net::Appliance::Session. The default options for openssh are changed, and both modules also log their version number.

Please you would be able to run the test script I provided, with debug enabled, and let me know whether there is any change.

sakuralihua commented 12 years ago

I can't seems to be able to upgrade to the latest version. I keep getting this message: Reading '/home/sakuralihua/.cpan/Metadata' Database was generated on Tue, 12 Jun 2012 22:13:42 GMT All modules are up to date for net::appliance::session

ollyg commented 12 years ago

It should be Net::CLI::Interact and Net::Appliance::Session (like that with capitals).

Alternatively, you can just move the ~/.cpan directory and start over, in case the CPAN shell is confused. Personally, I use cpanm (cpanminus) instead of the CPAN shell.

Let me know how it goes...

sakuralihua commented 12 years ago

Thanks! I am using cpanm to upgrade the Perl modules.

I still get the same error: $ NCI_LOG_AT=debug perl test.pl [0.001999] e NCI loaded, version 1.121640 [0.014931] e NAS loaded, version 3.121640 [0.015543] p finding prompt [0.016122] t creating Net::Telnet wrapper for ssh [0.016683] t command expands to: ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o CheckHostIP=no -l admin 10.106.63.198 [11.218750] p failed: [read timed-out at /usr/lib/perl5/site_perl/5.10/Net/CLI/Interact/Transport/Base/Unix.pm line 41 ], sending WAKE_UP and trying again [11.219510] p finding prompt [21.218750] d SEEN: ssh: connect to host 10.106.63.198 port 22: Connection timed out [21.290778] p reading phrasebook /usr/lib/perl5/site_perl/5.10/Net/CLI/Interact/phrasebook/cisco/pb [21.292345] p storing prompt prompt [21.294036] p storing prompt basic [21.295445] p storing prompt privileged [21.296913] p storing prompt configure [21.298477] p storing prompt user [21.299922] p storing prompt pass [21.301383] p storing macro begin_privileged [21.303354] p storing macro end_privileged [21.305218] p storing macro begin_configure [21.307080] p storing macro end_configure [21.308942] p storing macro disconnect [21.310757] p reading phrasebook /usr/lib/perl5/site_perl/5.10/Net/CLI/Interact/phrasebook/cisco/ios/pb [21.312195] p storing macro paging [21.313717] p nope, doesn't (yet) match basic [21.314308] p nope, doesn't (yet) match pass [21.314906] p nope, doesn't (yet) match user [21.315483] p nope, doesn't (yet) match configure [21.316060] p nope, doesn't (yet) match privileged [21.316667] p nope, doesn't (yet) match prompt [21.317181] p no match so far, more data? Use of uninitialized value $content in concatenation (.) or string at /usr/lib/perl5/site_perl/5.10/Net/CLI/Interact/Transport/Base/Unix.pm line 42. [21.318061] d SEEN: ssh: connect to host 10.106.63.198 port 22: Connection timed out [21.318468] p nope, doesn't (yet) match basic [21.319037] p nope, doesn't (yet) match pass [21.319606] p nope, doesn't (yet) match user [21.320177] p nope, doesn't (yet) match configure [21.320747] p nope, doesn't (yet) match privileged [21.321347] p nope, doesn't (yet) match prompt [21.321849] p no match so far, more data? Use of uninitialized value $content in concatenation (.) or string at /usr/lib/perl5/site_perl/5.10/Net/CLI/Interact/Transport/Base/Unix.pm line 42. [21.322391] d SEEN: ssh: connect to host 10.106.63.198 port 22: Connection timed out [21.322753] p nope, doesn't (yet) match basic [21.323321] p nope, doesn't (yet) match pass [21.323893] p nope, doesn't (yet) match user [21.324499] p nope, doesn't (yet) match configure [21.325071] p nope, doesn't (yet) match privileged [21.325675] p nope, doesn't (yet) match prompt [21.326182] p no match so far, more data? Use of uninitialized value $content in concatenation (.) or string at /usr/lib/perl5/site_perl/5.10/Net/CLI/Interact/Transport/Base/Unix.pm line 42. [21.326725] d SEEN: ssh: connect to host 10.106.63.198 port 22: Connection timed out

ollyg commented 12 years ago

I have another suggestion... in the connect_options please can you set "reap" to a true value, and see if that has an effect?

my $s = Net::Appliance::Session->new({
    personality => 'ios',
    transport => 'SSH',
    host => $ip,
    connect_options => {
        reap => 1,
    },
});
sakuralihua commented 12 years ago

No, it doesn't help.

I found a way to overcome this problem. I am going to ping the IP address to see if there's any response from the host. If there is no response, I will not call the download_config subroutine, hence will not get into an infinite loop.

Thanks for your help and support regarding this issue!

ollyg commented 12 years ago

Yes, I'm sorry that we've not managed to find a fix. It's difficult for me because I can't reproduce the error. However I do have an idea what's happening - for some reason the code isn't noticing that openssh has terminated, so keeps checking to see if there's more output. On my system, it can detect openssh has terminated after the connect timeout.

I'm glad you have a workaround, at least. I'll close this ticket now, and thanks for your patience in troubleshooting! :-)