Table of Contents
Preface
Chapter 1. Intro-What Is Expect?
Chapter 2. Tcl-Introduction And Overview
Chapter 3. Getting Started With Expect
Chapter 4. Glob Patterns And Other Basics
Chapter 5. Regular Expressions
Chapter 6. Patterns, Actions, And Limits
Chapter 7. Debugging Patterns And Controlling Output
Chapter 8. Handling A Process And A User
Chapter 9. The Expect Program
Chapter 10. Handling Multiple Processes
Chapter 11. Handling Multiple Processes Simultaneously
Chapter 12. Send
Chapter 13. Spawn
Chapter 14. Signals
Chapter 15. Interact
Chapter 16. Interacting With Multiple Processes
Chapter 17. Background Processing
Chapter 18. Debugging Scripts
Chapter 19. Expect + Tk = Expectk
Chapter 20. Extended Examples
Chapter 21. Expect, C, And C++
Chapter 22. Expect As Just Another Tcl Extension
Chapter 23. Miscellaneous
Appendix: Commands and Variables
Commands And Flags Variables
Index Of Scripts
Index
Read an Excerpt
Chapter 8: Handling a Process and a User
Security And Insecurity
Quite often, it is possible to automate everything except reading the password. As I explained earlier, the password should not be passed as an argument to a script for security reasons. An alternative to prompting is to embed the password directly in the script. There are two ways to secure such files-by file protection or by host protection. I prefer host protection but I will cover file protection first-if only to make the merits of host protection more obvious.
Securing Scripts By File Protection
Scripts containing passwords should be unreadable to users with normal utilities such as cat and vi. However, such scripts must still be executable. Unfortunately, the UNIX file system has no direct way of creating scripts which are executable but unreadable. On systems which support setgid shell scripts, you may indirectly simulate this as follows:
Create the Expect script (that contains the password) as usual. Make its permissions be 750 (-rwxr-x---) and owned by a trusted group, i.e., a group which is allowed to read it. if necessary, create a new group for this purpose. Next, create a /bin/sh script with permissions 2751 (-rwxr-s--x) owned by the same group as before. The shell script should invoke both Expect and the script name by their absolute pathnames.
The resulting shell script can be run by anyone, and the shell script in turn has permission to run the Expect script which is otherwise unreadable to everyone.
This may seem a little kludgey. In fact, it is worse than that. Storing unencrypted passwords in files is almost always a disaster, and there are usually better ways of getting the same effect. Consider that when the password is stored in your head, it is much easier to update. But once a password is stored in a script, each script containing the password has to be found and changed. Even worse, the scripts are more susceptible (than your brain) to yielding their contents. Consider what might happen if you run out of your office for a bathroom emergency. Someone could walk in, sit down at your workstation, and immediately have complete access to your files including the ones containing passwords. If a hacker steals a backup tape or stumbles onto a root login, all the files on the system can be read along with any unencrypted passwords in scripts.
As if this is not bad enough, the implementation of setuid and setgid scripts is insecure on some UNIX systems. It is often possible to trick such scripts into running a completely different program than the script originally called for. To avoid this problem, you must write a C program that is setuid to invoke the Expect script. To avoid a total breech of security, it is best to avoid root-setuid shell scripts on such systems. The use of a non-root group in the technique described earlier is a reasonable compromise at medium security sites.
A very different problem is that of writing setuid or setgid Expect scripts in the first place. Setuid Expect scripts have many of the same problems as setuid shell scripts. Writing such scripts should be avoided except by very experienced programmers. Examples and explanations of such scripts are beyond the scope of this book. If you are interested in more information on this aspect of scripts, read the Computer Security FAQ frequently posted to the Usenet newsgroup news. answers.
Securing Scripts By Host Protection
As I described in the previous section, it is unwise to depend on the file system to protect passwords embedded in scripts. A better alternative is to depend on the protection of a secure host. Such a host must prevent users who should not read the script from even logging in. In this case, the file protections are irrelevant since the users cannot even get to the file system that holds the file. ideally, the host should be physically secure as well. This means that random users cannot physically access it nor can they walk off with the backup tapes. The host should not even permit root access over the network. Of course, remote mounting should not be permitted. Indeed, all unnecessary daemons should be disabled.
Given a secure host, passwords may be embedded in scripts. If necessary, the scripts can begin by connecting to another host and then performing the desired interaction. Passwords will be available to a network sniffer, of course, but the risk is no greater than from a real person doing the same thing.
Such scripts may be run out of cron, allowing scripts to run programs that normally require passwords to run automatically and at times when no users are available. This is a common problem with databases that collect information that must be processed in the wee hours of the morning.
Scripts may also be run on demand at user request. Although users cannot log in to secure hosts, Expect scripts may be installed as inetd daemons allowing them to be started simply by running telnet with the specific port number or service name. I will describe this further in Chapter 17 (P. 392) with an example demonstrating how to allow users to interact with remote applications that require secret passwords.
Resetting The Terminal Upon Exit
When an Expect script ends, the terminal modes are automatically restored to those that were in effect when the Expect script began. For example, if the script put the terminal into raw mode, the terminal is taken out of raw mode when the script ends. This occurs whether the exit command is called explicitly or the script simply ends.
This makes error handling a little easier especially while debugging. During script development, it is not uncommon to have the script blow up as errors are encountered. By default, when an error occurs, Expect restores the terminal modes and exits. This makes it very easy to recover even from severe errors in the script.
More On The stty Command
Except for stty, all of the non-interactive UNIX programs executed so far have been run by the exec command. Compare:
exec kill -9 $pid
exec cat /etc/motd
exec touch foo
stty raw
It is possible to execute stty via exec on some systems but the required redirection is system dependent. Some stty implementations are sensitive to any redirection of standard error while other implementations require the standard error be redirected in order to catch errors. There is no way to call stty with exec that is both portable and reliable.
Expect addresses this problem by providing a built-in stty that uses the native UNIX stty command with redirection defined appropriately for your system. Additional redirection should be omitted if you want to affect the controlling terminal. For example, the following command disables echoing on the controlling terminal....