1=head1 NAME
2
3Net::SSH::Expect - SSH wrapper to execute remote commands
4
5=head1 SYNOPSIS
6
7	use Net::SSH::Expect;
8
9	#
10	# You can do SSH authentication with user-password or without it.
11	#
12
13	# Making an ssh connection with user-password authentication
14	# 1) construct the object
15	my $ssh = Net::SSH::Expect->new (
16	    host => "myserver.com",
17	    password=> 'pass87word',
18	    user => 'bnegrao',
19	    raw_pty => 1
20	);
21
22	# 2) logon to the SSH server using those credentials.
23	# test the login output to make sure we had success
24	my $login_output = $ssh->login();
25	if ($login_output !~ /Welcome/) {
26	    die "Login has failed. Login output was $login_output";
27	}
28
29	# - now you know you're logged in - #
30
31	# Starting ssh without password
32	# 1) run the constructor
33	my $ssh = Net::SSH::Expect->new (
34	    host => "myserver.com",
35	    user => 'bnegrao',
36	    raw_pty => 1
37	);
38	# 2) now start the ssh process
39	$ssh->run_ssh() or die "SSH process couldn't start: $!";
40
41	# 3) you should be logged on now. Test if you received the remote prompt:
42	($ssh->read_all(2) =~ />\s*\z/) or die "where's the remote prompt?"
43
44	# - now you know you're logged in - #
45
46	# disable terminal translations and echo on the SSH server
47	# executing on the server the stty command:
48	$ssh->exec("stty raw -echo");
49
50	# runs arbitrary commands and print their outputs
51	# (including the remote prompt comming at the end)
52	my $ls = $ssh->exec("ls -l /");
53	print($ls);
54
55	my $who = $ssh->exec("who");
56	print ($who);
57
58	# When running a command that causes a huge output,
59	# lets get the output line by line:
60	$ssh->send("find /");   # using send() instead of exec()
61	my $line;
62	# returns the next line, removing it from the input stream:
63  	while ( defined ($line = $ssh->read_line()) ) {
64	    print $line . "\n";
65	}
66
67	# take a look in what is immediately available on the input stream
68	print $ssh->peek(0);	# you'll probably see the remote prompt
69
70	# the last read_line() on the previous loop will not include the
71	# remote prompt that appears at the end of the output, because the prompt
72	# doesn't end with a '\n' character. So let's remove the remainder
73	# prompt from the input stream:
74	$ssh->eat($ssh->peek(0));  # removes whatever is on the input stream now
75
76	# We can also iterate over the output in chunks,
77	# printing everything that's available at each 1 second:
78	$ssh->send ("find /home");
79	my $chunk;
80	while ($chunk = $ssh->peek(1)) { # grabs chunks of output each 1 second
81	    print $ssh->eat($chunk);
82	}
83
84	# Now let's run an interactive command, like passwd.
85	# This is done combining send() and waitfor() methods together:
86	$ssh->send("passwd");
87	$ssh->waitfor('password:\s*\z', 1) or die "prompt 'password' not found after 1 second";
88	$ssh->send("curren_password");
89	$ssh->waitfor(':\s*\z', 1) or die "prompt 'New password:' not found";
90	$ssh->send("new_password");
91	$ssh->waitfor(':\s*\z', 1) or die "prompt 'Confirm new password:' not found";
92	$ssh->send("new_password");
93
94	# check that we have the system prompt again.
95	my ($before_match, $match) = $ssh->waitfor('>\s*\z', 1);  # waitfor() in a list context
96	die "passwd failed. passwd said '$before_match'." unless ($match);
97
98	# closes the ssh connection
99	$ssh->close();
100
101=head1 DESCRIPTION
102
103This module is a wrapper to the I<ssh> executable that is available in your system's I<$PATH>.
104Use this module to execute commands on the remote SSH server.
105It authenticates with the user and password you passed in the constructor's attributes
106C<user> and C<password>.
107
108Once an ssh connection was started using the C<connect()> method it will remain open
109until you call the C<close()> method. This allows you execute as many commands as you want
110with the C<exec()> method using only one connection. This is a better approach over other
111ssh wrapper implementations, i.e: Net::SCP, Net::SSH and Net::SCP::Expect, that start a new
112ssh connection each time a remote command is issued or a file is transfered.
113
114It uses I<Expect.pm> module to interact with the SSH server. A C<get_expect()> method is
115provided so you can obtain the internal C<Expect> object connected to the SSH server. Use
116this only if you have some special need that you can't do with the C<exec()> method.
117
118This module was inspired by Net::SCP::Expect L<http://search.cpan.org/~djberg/Net-SCP-Expect-0.12/Expect.pm>
119and by Net::Telnet and some of its methods work the same as these two modules.
120
121=head2 IMPORTANT NOTES ABOUT DEALING WITH SSH AND PSEUDO-TERMINALS
122
123This module uses Expect to start the local ssh client process, and Expect will interact with this process
124through a local pseudo-terminal (ptty). Similarly, the ssh client will connect to the SSH server and
125there will receive an ssh login process attached to a ptty too.
126
127During my tests I realized that the I/O to and from the ssh server changes drastically from OS to OS
128if we let the local and remote pttys configured on their defaults. The echo's and the \r\n translations
129make a mess that we are never sure what will be sent to the other side and what will be received here.
130
131Many ptty features are system dependent and we can't rely on them working the same on different OS's.
132
133To avoid these problems I always recommend you to:
134
1351) enable the 'raw_pty' constructor attribute. This disables most (if not all) of the problematic features
136on the local ptty.
137
1382) Similarly set the ptty on the remote server to 'raw -echo' as soon as you login.
139This can be done with:
140
141    $ssh->exec("stty raw -echo");
142
143Obviously your server must support the 'stty' command for that.
144
1453) If you won't run on the server interactive commands that prompt for input, like 'passwd', you
146could prevent the ssh server from attributing a ptty for the ssh login process. This is done
147by enabling the 'no_terminal' constructor attribute. What that does is passing the '-T' option
148to the ssh client process when it is created. From the BSD ssh client manual:
149    -T      Disable pseudo-tty allocation.
150
151This will create the cleaner connection possible. You won't have a ptty on the server, and,
152weirdly, you won't receive a remote prompt. Try yourself 'ssh -T my.ssh.server' to see how it
153works. Notice that some system commands that rely on a terminal won't work, say, 'who am i',
154'stty', etc.
155
156Also, interactive commands like 'passwd' or 'mail' won't be able to print their prompts.
157
158But other system commands will run better: 'ls -l' will be printed without terminal control characters.
159'ps -ef' will have the command lines printed fully, since there is no 'columns' terminal limitation.
160
161Moral of the story: pseudo terminals do many character translations that can bring some unexpected results
162in some situations. Avoid them if you can.
163
164=head1 EXPORT
165
166None by default.
167
168=head1 CONSTRUCTOR ATTRIBUTES
169
170The constructor accepts all the following attributes that can be set in the form of attribute => 'value' pairs.
171They are presentend in three groups:
1721) attributes to configure the ssh client process;
1732) attributes to configure the underlying Expect object;
1743) attributes to configure this module;
175
176=head2 ATTRIBUTES TO CONFIGURE THE SSH CLIENT PROCESS
177
178Some of the attributes bellow will enable/disable some options of the ssh client. Refer to you ssh client documentation
179to know what each one does.
180
181=over 4
182
183=item string B<binary>
184
185the complete path to the 'ssh' executable in your machine. The default is 'ssh' what means the ssh used by default is the first one found in your $PATH environment variable.
186
187=item string B<user>
188
189the username to login.
190
191=item string B<password>
192
193the password used to login. You won't need to set this field if you have public-key authentication configured for you ssh user. Read run_ssh() documentation for more info.
194
195=item string B<host>
196
197the address(dns name/ip) to the ssh server
198
199=item string B<port>
200
201Feeds the -p ssh client option with alternate ssh port. This option is not set by default.
202
203=item boolean B<no_terminal>
204
205If enabled adds the -T ssh client option to the ssh command line. See the discussion on "IMPORTANT NOTES
206ABOUT DEALING WITH SSH AND PSEUDO-TERMINALS" to know if you want to enable this.
207
208=item char B<escape_char>
209
210Passes a character to the -e ssh client option. This enables ssh escapes. Since this
211option can cause trouble, it is explicitly turned off by default with a '-e none' option
212being set on the ssh command line.
213
214=item string B<ssh_option>
215
216This lets you add your own ssh options to the command line. Set this string to the options you want,
217like '-v -p 2022', and your options will be added to the ssh command line that will start the ssh process.
218
219=back
220
221=head2 CONSTRUCTOR OPTIONS THAT CONFIGURE THE INTERNAL EXPECT OBJECT
222
223The following constructor attributes can be used to configure special features of the internal Expect object used to communicate with the ssh server. These options will be passed to the Expect object inside the C<connect> method before it spawns the ssh process.
224
225=over 4
226
227=item string B<log_file>
228
229Used as argument to the internal Expect->log_file() method. Default is no logfile.
230
231=item boolean B<log_stdout>
232
233Used as argument to the internal Expect->log_sdtout() method. Default is 0, to disable log to stdout.
234
235=item boolean B<exp_internal>
236
237Argument to be passed to the internal Expect->exp_internal() method. Default is 0, to disable the internal exposure.
238
239=item boolean B<exp_debug>
240
241Argument to be passed to the internal Expect->debug() method. Default is 0, to disable debug.
242
243=item boolean B<raw_pty>
244
245Argument to be passed to the internal Expect->raw_pty() method. It's recommended that you enable this. See the disscussion
246in "IMPORTANT NOTES ABOUT DEALING WITH SSH AND PSEUDO-TERMINALS" to know why.
247Default is 0 to let the local ptty as its defaults.
248
249=item boolean B<restart_timeout_upon_receive>
250
251If this is enabled the timeout in all reading operations works as an inactivity timeout - it'll not start counting
252while there is data arriving on input stream. Default is 0.
253
254=back
255
256=head2 CONSTRUCTOR OPTIONS TO CONFIGURE THIS MODULE
257
258=over 4
259
260=item string B<terminator>
261
262the line terminator in use on the SSH server, this will added at the end of each command
263passed to the C<exec()> method. The default is C<\n>.
264
265It also affects the read_line() method, it expect each line to be terminated by the 'teminator'
266character. Lines can also be ended with "\r" or "\r\n" in some systems.
267Remember to adjust this for your system.
268
269You can also use the terminator() method to set this attribute.
270
271=item integer B<timeout>
272
273The maximum time to wait for a pattern to show up on input stream before giving up
274in a read operation. The default is 1 second.
275
276Timeout must always be an integer >= 0.
277
278This attribute can also be get/set with the C<timeout()> method.
279
280=item boolean B<debug>
281
282Causes some methods to print debug messages to the STDERR. This feature is not widely implemented yet.
283(only eat() implements it until this moment)
284
285=back
286
287=head1 METHODS
288
289=over 4
290
291=item boolean B<run_ssh()> - forks the ssh client process
292
293	# boolean run_ssh() - forks the ssh client process opening an ssh connection to the SSH server.
294	#
295	#	This method has three roles:
296	#	1) 	Instantiate a new Expect object configuring it with all the defaults and user-defined
297	#		settings.
298	#	2)	Define the ssh command line using the defaults and user-defined settings
299	#	3)	Fork the ssh process using the spawn() method of the Expect instance we created.
300	#		The SSH connection is established on this step using the user account set in the 'user'
301	#		constructor attribute. No password is sent here, that happens only in the login() method.
302	#
303	#	This method is run internally by the login() method so you don't need to run it yourself
304	#	in most of the cases. You'll run this method alone if you had set up public-key authentication
305	#	between the ssh client and the ssh server. In this case you only need to call this method
306	#	to have an authenticated ssh connection, you won't call login(). Note that when you
307	#	use public-key authentication you won't need to set the 'password' constructor attribute
308	#	but you still need to define the 'user' attribute.
309	#	If you don't know how to setup public-key authentication there's a good guide at
310	#	http://sial.org/howto/openssh/publickey-auth/
311	#
312	# returns:
313	#	boolean: 1 if the ssh ran OK or 0 otherwise. In case of failures, use $! to do get info.
314
315
316=item string B<login([$login_prompt, $password_prompt] [,$test_success])>  - authenticates on the ssh server.
317
318	# string login ([$login_prompt, $password_prompt] [,$test_success]) - authenticates on the ssh server.
319	#	This method responds to the authentication prompt sent by the SSH server.
320	#	You can customize the "Login:" and "Password:" prompts that must be expected by passing their
321	#	patterns as arguments to this method, although this method has default values that work to most
322	#	SSH servers out there.
323	#	It runs the run_ssh() method only if it wasn't run before(), but it'll die
324	#	if run_ssh() returns false.
325	#
326	# param:
327	#	$login_prompt: A pattern string used to match the "Login:" prompt. The default
328	#		pattern is qr/ogin:\s*$/
329	#
330	#	$password_prompt: A pattern string used to match the "Password:" prompt. The default
331	#		pattern is qr/[Pp]assword.*?:|[Pp]assphrase.*?:/
332	#
333	#	$test_success: 0 | 1. if 1, login will do an extra-test to verify if the password
334	# 		entered was accepted. The test consists in verifying if, after sending the password,
335	#		the "Password" prompt shows up again what would indicate that the password was rejected.
336	#		This test is disabled by default.
337	#
338	#	OBS: the number of paramaters passed to this method will tell it what parameters are being passed:
339	#	0 parameters: login() : All the default values will be used.
340	#	1 parameter:  login(1) : The $test_success parameter is set.
341	#	2 parameters: login("Login:", "Password:") : the $login_prompt and $password_prompt parameters are set.
342	#	3 parameters: login("Login:", "Password;", 1) : the three parameters received values on this order.
343	#
344	# returns:
345	#	string: whatever the SSH server wrote in my input stream after loging in. This usually is some
346	#		welcome message and/or the remote prompt. You could use this string to do your verification
347	#		that the login was successful. The content returned is removed from the input stream.
348	# dies:
349	#	IllegalState: if any of 'host' or 'user' or 'password' fields are unset.
350	#	SSHProccessError: if run_ssh() failed to spawn the ssh process
351	# 	SSHConnectionError: if the connection failed for some reason, like invalid 'host' address or network problems.
352
353=item string B<exec($cmd [,$timeout])> - executes a command in the remote machine returning its output
354
355exec('command') runs 'command' in the remote machine and returns all the output generated by 'command' into a string.
356
357=item boolean B<waitfor($pattern [,$timeout])>
358
359	# boolean waitfor ($string [, $timeout, $match_type])
360	# This method reads until a pattern or string is found in the input stream.
361	# All the characters before and including the match are removed from the input stream.
362	#
363	# After waitfor returns, use the methods before(), match() and after() to get the data
364	# 'before the match', 'what matched', and 'after the match' respectively.
365	#
366	# If waitfor returns false, whatever content is on input stream can be accessed with
367	# before(). In this case before() will return the same content as peek().
368	#
369	# params:
370	#	$string: a string to be matched. It can be a regular expression or a literal string
371	#			 anb its interpretation as one or other depends on $match_type. Default is
372	#			 're', what treats $string as a regular expression.
373	#
374	#	$timeout: the timeout in seconds while waiting for $string
375	#
376	#	$match_type: match_type affects how $string will be matched:
377	#		'-re': means $string is a regular expression.
378	#		'-ex': means $string is an "exact match", i.e., will be matched literally.
379	#
380	# returns:
381	#	boolean: 1 is returned if string was found, 0 otherwise. When the match fails
382	#			 waitfor() will only return after waiting $timeout seconds.
383	#
384	# dies:
385	#	SSH_CONNECTION_ABORTED if EOF is found (error type 2)
386	#	SSH_PROCESS_ERROR if the ssh process has died (error type 3)
387	#	SSH_CONNECTION_ERROR if unknown error (type 4) is found
388
389=item string B<before()> - returns the "before match" data of the last waitfor() call.
390
391When waitfor() matches, if there is any content before the match, this will be returned by before().
392
393If the last waitfor() didn't match, before() will return all the current content on the input
394stream, just as if you had called peek() with the same timeout.
395
396=item string B<match()> - returns the "match" data of the last waitfor() call, or undef if didn't match.
397
398=item string B<after()> - returns the "after match" data of the last waitfor() call, or undef if didn't match.
399
400=item void B<close()> - terminates the ssh connection
401
402=item void B<send($string)> - sends $string to the SSH server, returns nothing
403
404Sends the string to the SSH server. If the ssh server process is attached to a pseudo-terminal (this is the default)
405it is likely that the echo terminal property will be on, what will make the server place the command you just sent in our
406input stream, i.e., you'll see the command you sent in your next read operation.
407
408To avoid this, try to disable the echo property on the server-side, using
409
410 $ssh->exec("stty -echo");
411
412It's also advisable to disable the terminal character convertions on server-side, what will make you sure that
413every character you sent will be received "as-is" to the other side.
414
415So you'll probably use this to disable character conversions and echo:
416
417 $ssh->exec("stty raw -echo");
418
419Of course you're server must support the 'stty' command for that work.
420
421To guarantee that your characters are not converted by your local pseudo-terminal before you send them out,
422set the constructor option:
423
424	raw_pty => 1
425
426And if you don't need a terminal on the server-side at all, set the constructor option bellow to 1:
427
428	no_terminal => 1
429
430=item string B<peek([$timeout])> - returns what is in the input stream without removing anything
431
432	# peek([$timeout]) - returns what is in the input stream without removing anything
433	# 	peek() returns what is available on the input stream until $timeout seconds.
434	#	If there is data continuosly arriving on the input stream, subsequent calls to peek()
435	#	will return a growing amount of data.
436	#
437	# dies:
438	#	SSH_CONNECTION_ABORTED if EOF is found (error type 2)
439	#	SSH_PROCESS_ERROR if the ssh process has died (error type 3)
440	#	SSH_CONNECTION_ERROR if unknown error (type 4) is found
441
442=item string B<eat($string)> - removes all the head of the input stream until $string inclusive.
443
444	# string eat($string)- removes all the head of the input stream until $string inclusive.
445	#	eat() will only be able	to remove the $string if it's currently present on the
446	#	input stream because eat() will wait 0 seconds before removing it.
447	#
448	#	Use it associated with peek to eat everything that appears on the input stream:
449	#
450	#	while ($chunk = $exp->eat($exp->peak())) {
451	#		print $chunk;
452	#	}
453	#
454	#	Or use the read_all() method that does the above loop for you returning the accumulated
455	#	result.
456	#
457	# param:
458	#	string: a string currently available on the input stream.
459	#		If $string doesn't start in the head, all the content before $string will also
460	#		be removed.
461	#
462	#		If $string is undef or empty string it will be returned immediately as it.
463	#
464	# returns:
465	#	string: the removed content or empty string if there is nothing in the input stream.
466	#
467	# dies:
468	#	SSH_CONNECTION_ABORTED if EOF is found (error type 2)
469	#	SSH_PROCESS_ERROR if the ssh process has died (error type 3)
470	#	SSH_CONNECTION_ERROR if unknown error (type 4) is found
471	#
472	# debbuging features:
473	#	The following warnings are printed to STDERR if $exp->debug() == 1:
474	#		eat() prints a warning is $string wasn't found in the head of the input stream.
475	#		eat() prints a warning is $string was empty or undefined.
476	#
477
478=item string B<read_all([$timeout])> - reads and removes all the output from the input stream.
479
480The reading/removing process will be interrupted after $timeout seconds of inactivity
481on the input stream.
482
483=item string B<read_line([$timeout])> - reads the next line from the input stream and returns it.
484
485	# string read_line([$timeout]) - reads the next line from the input stream
486	# Read a line of text. A line is considered to be terminated by the 'teminator'
487	# character. Default is "\n". Lines can also be ended with "\r" or "\r\n".
488	# Remember to adequate this for your system with the terminator() method.
489	# When there are no more lines available, read_line() returns undef. Note that this doen't mean
490	# there is no data left on input stream since there can be a string not terminated with the
491	# 'terminator' character, notably the remote prompt could be left there when read_line() returns
492	# undef.
493	#
494	# params:
495	#	$timeout: the timeout waiting for a line. Defaults to timeout().
496	#
497	# returns:
498	#	string: a line on the input stream, without the trailing 'terminator' character.
499	#			An empty string indicates that the line read only contained the 'terminator'
500	#			character (an empty line).
501	#	undef: when there are no more lines on the input stream.
502	#
503
504=item void B<restart_timeout_upon_receive( 0 | 1 )> - changes the timeout counter behaviour
505
506	# void restart_timeout_upon_receive( 0 | 1 ) - changes the timeout counter behaviour
507	# params:
508	#	boolean: if true, sets the timeout to "inactivity timeout", if false
509	#			sets it to "absolute timeout".
510	# dies:
511	#	IllegalParamenter if argument is not given.
512
513=item Expect B<get_expect()> - returns the internal Expect object
514
515=over 4
516
517=item params:
518
519none
520
521=item returns:
522
523an C<Expect> object connected to the SSH server. It will die if you try to run it without being connected.
524
525=item dies:
526
527IllegalState: if this there is no valid ssh connection established
528
529=back
530
531=back
532
533=head1 SEE ALSO
534
535Net::SCP::Expect, Net::SCP, Net::SSH::Perl, L<Expect>
536
537=head1 REPORTING BUGS
538
539To report bugs please use the bug reporting tool available on CPAN website, in the module's page. That way I can
540keep track of what I need to do and I can also communicate with you through that tool.
541
542=head1 AUTHOR
543
544Bruno Negrao Guimaraes Zica. E<lt>bnegrao@cpan.orgE<gt>.
545
546=head1 THANKS
547
548Daniel Berger, author of Net::SCP::Expect. Special thanks to the people helping me improve this module by reporting their tests and the bugs they find.
549
550=head1 COPYRIGHT AND LICENSE
551
552Copyright (C) 2007 by Bruno Negrao Guimaraes Zica
553
554This library is free software; you can redistribute it and/or modify
555it under the same terms as Perl itself, either Perl version 5.8.3 or,
556at your option, any later version of Perl 5 you may have available.
557
558=cut
559