http://qs321.pair.com?node_id=391202

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

Okay, so I have this really nasty problem and I'm getting a bit frustrated with it, which may be part of the problem, but here goes:

So there are currently two options if you want to use SCP in Perl:

  1. use Net::SCP;         # Doesn't allow passwords.
  2. use Net::SCP::Expect; # Passwords okay.

So I need to scp the files /flash/config.cfg and /flash/boot.cfg from a bunch of switches - not servers - using SCP. I can get the switch IPs, user name, and password into the script, but then it starts to run into problems.

First, I can't use Net::SCP because I can't set up keys on the switches for logistical reasons. (Many users need to use this script and in addition to certain keygen limitations on the switch, I don't want to maintain that many keypairs).

Second, Net::SCP::Expect seems to croak() after the first (successful) file transfer, and I'm having a tough time figuring out why it isn't working. There are some errors that appear, but they pile on top of each other on one line.

To complicate matters, every time one of these switches gets rebooted, the host key is regenerated. Messy...

Anyway, Net::SCP::Expect does have an error_handler method that takes a coderef, but it's unclear on what exactly is passed to that sub. I'm about to try Data::Dumper on @_ to see.

Any other ideas or suggestions? Anybody have any direct experience with this kind of thing and either Net::SCP or Net::SCP::Expect?

--J

Update: Added tags to highlight the fact that I am not using SCP to talk to a unix host, which is the source of most of the limitations in this problem.

Update 2: This has been solved. See below or click the link.

Replies are listed 'Best First'.
Re: Using Perl to do SCP
by Rhys (Pilgrim) on Sep 15, 2004 at 16:03 UTC
    Okay, I did both of what I suggested to myself. :-) I wrote a new error_handler sub with use Data::Dumper, plus I wrote some extra code in there to clean up the data passed through @_. Here's what I used:

    sub showme { use Data::Dumper; print Dumper(@_); print "\n"; foreach ( @_ ) { chomp $_; print "Thing is $_.\n"; } exit; }

    As it turns out, the problem is the way the switch closes the connection at the end of the file transfer. Apparently, Net::SCP::Expect doesn't expect (pardon the pun) the string it gets. So here's the code I'm using (successfully, so far) in the production script to handle it:

    sub scp_errors { use strict; my $line = shift; if ( $line =~ /Connection.+closed by remote host/ ) { # This is expected from an 8600. return(0); } else { # Get rid of CR and LF. $line =~ s/\012//g; $line =~ s/\015//g; print "Got error pulling file:\n"; print "\t", $line; print "\n"; return(1); } }

    As far as I can tell, only one error line gets passed to the error handler. If this turns out not to be the case later, I'll have to change scp_errors to deal with multiple args.

    --J

Re: Using Perl to do SCP
by idsfa (Vicar) on Sep 15, 2004 at 15:45 UTC

    Difficult to comment without seeing your code.

    The docs state:

    error_handler(sub ref)
    This sets up an error handler to catch any problems with a call to 'scp()'. If you do not define an error handler, then a simple 'croak()' call will occur, with the last line sent to the terminal added as part of the error message.

    So what is the error does it croak with?


    If anyone needs me I'll be in the Angry Dome.
      That's one of the problems. Multiple errors that include the carriage return character (but no line feed!) are printed to the screen, so you can't see what went wrong.

      I actually got this solved; I'll post the code I used to troubleshoot it in a sec.

      --J

Re: Using Perl to do SCP
by itub (Priest) on Sep 15, 2004 at 15:21 UTC
    I have a module called IO::All::SCP under development that uses Net::SSH::Perl to do an "scp" by connecting to the server and running cat. I don't know if such an approach would work for you.
      Since I'm pulling down a file, and since the remote end is a switch, not a server, this approach doesn't help me, since there is no 'cat' command at the far end (or anything even close, I don't think).

      Thanks, though...

      --J

Re: Using Perl to do SCP
by Roger (Parson) on Sep 15, 2004 at 15:14 UTC
    I thought if you configure the Public/Private keys properly on the machines, you won't *need* a password?

      Remember, I'm not talking about servers, I'm trying to SCP files from switches, so they don't have as sophisticated a key-handling scheme. They want to have a single DSA key pair. Using the same key pair on every switch creates a new security risk, plus it is sort of a pain to set up. Using different keys for each switch would be a major pain to set up.

      But it goes beyond that. Since SSH is already enabled on each switch, the OS won't let you run the keygen command on the switch. I.e. it won't create or load the keys until SSH is disabled. We use SSH to get to the switches. Catch-22.

      Hence, I need to use password-based authentication (for now).

      --J

Re: Using Perl to do SCP
by tradez (Pilgrim) on Sep 15, 2004 at 18:47 UTC
    Tried Net::SFTP?


    Tradez
    "Never underestimate the predictability of stupidity"
    - Bullet Tooth Tony, Snatch (2001)
      Please remember, I'm using SCP to talk to a switch, not a server, so there isn't anything to accept an SFTP connection. I know it's all over port 22, but SFTP uses semantics that aren't available from this SSH service.

      Case in point:

      [user@mybox user]$ sftp Admin@10.11.12.62 Connecting to 10.11.12.62... Admin@10.11.12.62's password: Request for subsystem 'sftp' failed on channel 0 Couldn't read packet: Connection reset by peer

      --J

Re: Using Perl to do SCP
by Anonymous Monk on Sep 15, 2010 at 11:11 UTC

    I got solution for error_handler()

    but the thing is u dont know how to use it