Python Cookbook 2Nd Edition Jun 1002005 [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Python Cookbook 2Nd Edition Jun 1002005 [Electronic resources] - نسخه متنی

David Ascher, Alex Martelli, Anna Ravenscroft

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید







Recipe 15.9. Performing Remote Logins Using telnetlib


Credit: Jeff Bauer


Problem


You need to
send commands to one or more logins that can be on a local machine,
or a remote machine, and the Telnet protocol is acceptable.


Solution


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, telnetlib
from getpass import getpass
class AutoTelnet(object):
def _ _init_ _(self, user_list, cmd_list, **kw):
# optional parameters are host, timeout in seconds, command
# prompt to expect from the host on successful logins:
self.host = kw.get('host', 'localhost')
self.timeout = kw.get('timeout', 600)
self.command_prompt = kw.get('command_prompt', "$ ")
# collect passwords for each user, interactively
self.passwd = { }
for user in user_list:
self.passwd[user] = getpass("Enter user '%s' password: " % user)
# instantiate Telnet proxy
self.telnet = telnetlib.Telnet( )
for user in user_list:
# login with given host and user, and act appropriately
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):
# wait for a login prompt
t = self.telnet
t.write("\n")
login_prompt = "login: "
response = t.read_until(login_prompt, 5)
if login_prompt in response:
print response
else:
return 0
# supply user and password for login
t.write("%s\n" % user)
password_prompt = "Password:"
response = t.read_until(password_prompt, 3)
if password_prompt in response:
print response
else:
return 0
t.write("%s\n" % self.passwd[user])
# wait for command prompt to indicate successful login
response = t.read_until(self.command_prompt, 5)
if self.command_prompt not in response:
return 0
# send each command and wait for command prompt after each
for cmd in cmd_list:
t.write("%s\n" % cmd)
response = t.read_until(self.command_prompt, self.timeout)
if self.command_prompt not in response:
return 0
print response
return 1
if _ _name_ _ == '_ _main_ _':
# code which runs as a main script, only
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):
if r.rstrip( ):
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)


Discussion


Python's telnetlib lets you
easily automate access to Telnet servers, even from non-Unix
machines. As a flexible alternative to the popen
functions, which only run commands locally as the user
that's running the script,
telnetlib, which can work across an intranet and
can login and run commands as different users, is a handy technique
to have in your system administration toolbox.

Production code generally has to be made 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 and
uses that single object in a loop over a list of users. For each
user, the recipe 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 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 then, 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
(waiting for a command prompt again after sending each one).

One warning (which applies to any use of Telnet
and some other old protocols): except when transmitting completely
public data, not protected by passwords that might be of interest to
intruders of ill will, do not run Telnet (or non-anonymous FTP, for
that matter) on networks on which you are not
completely sure that nobody is packet-sniffing,
since these protocols date from an older, more trusting age. These
protocols let passwords and everything else travel in the clear, open
to any snooper. This issue is not Python specific; it applies to any
implementation of these protocols, since it depends on the definition
of the protocols themselves. Whether or not you use Python, be
advised: if there is any risk that someone might be packet-sniffing,
use SSH instead, as shown next in Recipe 15.10 so that no password ever
travels on the network in the clear, and so that the connection
stream itself gets encrypted.


See Also


Documentation on the standard library module
telnetlib in the Library
Reference
; Recipe 15.10.


/ 394