Credit: Jeff Bauer
You need to send commands to one or more logins that can be on the local machine or on a remote machine, and the Telnet protocol is acceptable.
Telnet is one of the oldest protocols in the TCP/IP stack, but it may
still be serviceable (at least within an intranet that is
well-protected against sniffing and spoofing attacks). In any case,
Python’s standard module
telnetlib
supports Telnet quite well:
# auto_telnet.py - remote control via telnet import os, sys, string, telnetlib from getpass import getpass class AutoTelnet: def _ _init_ _(self, user_list, cmd_list, **kw): self.host = kw.get('host', 'localhost') self.timeout = kw.get('timeout', 600) self.command_prompt = kw.get('command_prompt', "$ ") self.passwd = {} for user in user_list: self.passwd[user] = getpass("Enter user '%s' password: " % user) self.telnet = telnetlib.Telnet( ) for user in user_list: self.telnet.open(self.host) ok = self.action(user, cmd_list) if not ok: print "Unable to process:", user self.telnet.close( ) def action(self, user, cmd_list): t = self.telnet t.write("\n") login_prompt = "login: " response = t.read_until(login_prompt, 5) if string.count(response, login_prompt): print response else: return 0 t.write("%s\n" % user) password_prompt = "Password:" response = t.read_until(password_prompt, 3) if string.count(response, password_prompt): print response else: return 0 t.write("%s\n" % self.passwd[user]) response = t.read_until(self.command_prompt, 5) if not string.count(response, self.command_prompt): return 0 for cmd in cmd_list: t.write("%s\n" % cmd) response = t.read_until(self.command_prompt, self.timeout) if not string.count(response, self.command_prompt): return 0 print response return 1 if _ _name_ _ == '_ _main_ _': basename = os.path.splitext(os.path.basename(sys.argv[0]))[0] logname = os.environ.get("LOGNAME", os.environ.get("USERNAME")) host = 'localhost' import getopt optlist, user_list = getopt.getopt(sys.argv[1:], 'c:f:h:') usage = """ usage: %s [-h host] [-f cmdfile] [-c "command"] user1 user2 ... -c command -f command file -h host (default: '%s') Example: %s -c "echo $HOME" %s """ % (basename, host, basename, logname) if len(sys.argv) < 2: print usage sys.exit(1) cmd_list = [] for opt, optarg in optlist: if opt == '-f': for r in open(optarg).readlines( ): if string.rstrip(r): cmd_list.append(r) elif opt == '-c': command = optarg if command[0] == '"' and command[-1] == '"': command = command[1:-1] cmd_list.append(command) elif opt == '-h': host = optarg autoTelnet = AutoTelnet(user_list, cmd_list, host=host)
Python’s telnetlib
lets you
easily automate access to Telnet servers, even from non-Unix
machines. As a flexible alternative to the popen
functions, telnetlib
is a handy technique to have
in your system-administration toolbox.
Generally, production code will be more robust, but this recipe
should be enough to get you started in the right direction. The
recipe’s
AutoTelnet
class instantiates a single
telnetlib.Telnet
object that it uses in a loop
over a list of users. For each user, it calls the
open
method of the Telnet
instance to open the
connection to the specified host, runs a series of commands in
AutoTelnet
’s
action
method, and finally calls the
close
method of the Telnet
instance to terminate the connection.
AutoTelnet
’s
action
method is where the action is. All
operations depend on two methods of the Telnet
instance. The write
method takes a single string
argument and writes it to the connection. The
t.read_until
method takes two arguments, a string
to wait for and a timeout in seconds, and returns a string with all
the characters received from the connection until the timeout elapsed
or the waited-for string occurred.
action
’s code uses these two
methods to wait for a login prompt and send the username; wait for a
password prompt and send the password; and, repeatedly, wait for a
command prompt (typically from a Unix shell at the other end of the
connection) and send the commands in the list sequentially.
One warning (which applies to Telnet and other old protocols): except, perhaps, for the transmission of completely public data not protected by a password that might be of interest to intruders of ill will, do not run Telnet (or nonanonymous FTP) on networks on which you are not completely sure that nobody is packet-sniffing, since these protocols date from an older, more trusting age. They let passwords, and everything else, travel in the clear, open to any snooper. This is not Python-specific. Whether you use Python or not, be advised: if there is any risk that somebody might be packet-sniffing, use ssh instead, so no password travels on the network in the clear, and the connection stream itself is encrypted.
Get Python Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.