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
