El siguiente ejemplo muestra como conmutar entre el modo dirigido y el modo interactivo:
pp2@nereida:/tmp$ cat -n remoteinteract.pl 1 #!/usr/bin/perl -w 2 # $Id: remoteinteract.pl,v 1.1 2001/03/22 01:44:57 btrott Exp $ 3 4 ## remoteinteract.pl is an example of using Net::SSH::Perl to communicate 5 ## interactively with a remote command. In this case, that command is the 6 ## passwd command. 7 ## 8 ## Generally when executing a command that prompts you for information, 9 ## you need to be interactive to respond to the prompts. Net::SSH::Perl 10 ## allows you to register handlers for specific packet types that are sent 11 ## to your client; in these handlers, you can check for recognizable 12 ## prompts and act accordingly by sending a response (using a STDIN 13 ## packet). 14 ## 15 ## remoteinteract.pl shows you how in an example of changing a password 16 ## using the 'passwd' command. We check for three prompts: the prompt 17 ## for the user's current password, the prompt for the new password, and 18 ## the prompt for confirmation of the new password. 19 ## 20 ## You'll need to set the variables $host, $username, $new_password, and 21 ## $old_password. 22 ## 23 ## Remember that this is just an example and should not be used without 24 ## the addition of better error checking. 25 26 my($host, $username, $new_password, $old_password) 27 = ('------------------', '--------', '---------', '--------'); 28 29 use strict; 30 use Net::SSH::Perl; 31 32 ## We need to import the Constants module because we need the constant 33 ## for the SSH_SMSG_STDERR_DATA and SSH_CMSG_STDIN_DATA packet types. 34 ## Importing the :msg tag imports all of the SSH_xMSG constants. 35 ## 36 ## If we just wanted to import constants for the above two packet types, 37 ## we could use this instead: 38 ## 39 ## use Net::SSH::Perl::Constants qw( 40 ## SSH_SMSG_STDERR_DATA SSH_CMSG_STDIN_DATA 41 ## ); 42 ## 43 ## It's more verbose, certainly, but it does cut down on the number of 44 ## constants imported into our package. 45 46 use Net::SSH::Perl::Constants qw( :msg ); 47 48 ## Create a Net::SSH::Perl object and login to the remote host. 49 50 my $ssh = Net::SSH::Perl->new($host, debug => 1); 51 $ssh->login($username, $old_password); 52 53 ## Register a handler routine for packets of type SSH_SMSG_STDERR_DATA. 54 ## This routine will be called whenever the client loop (in 55 ## Net::SSH::Perl) receives packets of this type. It will be given 56 ## two arguments: the Net::SSH::Perl object, and the Net::SSH::Perl::Packet 57 ## object that was received. 58 ## 59 ## We use get_str to get the contents of the STDERR message (because 60 ## passwd writes its prompts to STDERR), then check those against the 61 ## interactive prompts we expect. 62 ## 63 ## For each prompt, we send a packet of STDIN data, which is our response 64 ## to the prompt. For example, when prompted for our current password, 65 ## we send a packet containing that current password. 66 ## 67 ## NOTE: this does not include error checking, and thus should not be 68 ## used wholesale. 69 70 $ssh->register_handler(SSH_SMSG_STDERR_DATA, sub { 71 my($ssh, $packet) = @_; 72 my $str = $packet->get_str; 73 74 if ($str eq "(current) UNIX password: ") { 75 my $packet = $ssh->packet_start(SSH_CMSG_STDIN_DATA); 76 $packet->put_str($old_password); 77 $packet->send; 78 } 79 80 elsif ($str eq "New UNIX password: ") { 81 my $packet = $ssh->packet_start(SSH_CMSG_STDIN_DATA); 82 $packet->put_str($new_password); 83 $packet->send; 84 } 85 86 elsif ($str eq "Retype new UNIX password: ") { 87 my $packet = $ssh->packet_start(SSH_CMSG_STDIN_DATA); 88 $packet->put_str($new_password); 89 $packet->send; 90 } 91 }); 92 93 ## After registering the handler, we run the command. 94 95 $ssh->cmd('passwd');
Véase un ejemplo de ejecución:
pp2@nereida:/tmp$ remoteinteract.pl local.host: Reading configuration data /home/pp2/.ssh/config local.host: Reading configuration data /etc/ssh_config local.host: Connecting to some.remote.host, port 22. local.host: Remote version string: SSH-2.0-OpenSSH_4.7p1 Debian-9 local.host: Remote protocol version 2.0, remote software version OpenSSH_4.7p1 Debian-9 local.host: Net::SSH::Perl Version 1.30, protocol version 2.0. local.host: No compat match: OpenSSH_4.7p1 Debian-9. local.host: Connection established. local.host: Sent key-exchange init (KEXINIT), wait response. local.host: Algorithms, c->s: 3des-cbc hmac-sha1 none local.host: Algorithms, s->c: 3des-cbc hmac-sha1 none local.host: Entering Diffie-Hellman Group 1 key exchange. local.host: Sent DH public key, waiting for reply. local.host: Received host key, type 'ssh-dss'. local.host: Host 'some.remote.host' is known and matches the host key. local.host: Computing shared secret key. local.host: Verifying server signature. local.host: Waiting for NEWKEYS message. local.host: Enabling incoming encryption/MAC/compression. local.host: Send NEWKEYS, enable outgoing encryption/MAC/compression. local.host: Sending request for user-authentication service. local.host: Service accepted: ssh-userauth. local.host: Trying empty user-authentication request. local.host: Authentication methods that can continue: publickey,password. local.host: Next method to try is publickey. local.host: Trying pubkey authentication with key file '/home/pp2/.ssh/id_dsa' local.host: Authentication methods that can continue: publickey,password. local.host: Next method to try is publickey. local.host: Next method to try is password. local.host: Trying password authentication. local.host: Login completed, opening dummy shell channel. local.host: channel 0: new [client-session] local.host: Requesting channel_open for channel 0. local.host: channel 0: open confirm rwindow 0 rmax 32768 local.host: Got channel open confirmation, requesting shell. local.host: Requesting service shell on channel 0. local.host: channel 1: new [client-session] local.host: Requesting channel_open for channel 1. local.host: Entering interactive session. local.host: Sending command: passwd local.host: Requesting service exec on channel 1. local.host: channel 1: open confirm rwindow 0 rmax 32768 --------- <- MODO INTERACTIVO: old password ********* <- MODO INTERACTIVO: new password ********* <- MODO INTERACTIVO: repeat new password local.host: input_channel_request: rtype exit-status reply 0 local.host: channel 1: rcvd eof local.host: channel 1: output open -> drain local.host: channel 1: rcvd close local.host: channel 1: input open -> closed local.host: channel 1: close_read local.host: channel 1: obuf empty local.host: channel 1: output drain -> closed local.host: channel 1: close_write local.host: channel 1: send close local.host: channel 1: full closed
Casiano Rodríguez León