1#!/usr/bin/env python
2
3"""Change passwords on the named machines. passmass host1 host2 host3 . . .
4Note that login shell prompt on remote machine must end in # or $. """
5
6import pexpect
7import sys, getpass
8
9USAGE = '''passmass host1 host2 host3 . . .'''
10COMMAND_PROMPT = '[$#] '
11TERMINAL_PROMPT = r'Terminal type\?'
12TERMINAL_TYPE = 'vt100'
13SSH_NEWKEY = r'Are you sure you want to continue connecting \(yes/no\)\?'
14
15def login(host, user, password):
16
17    child = pexpect.spawn('ssh -l %s %s'%(user, host))
18    fout = file ("LOG.TXT","wb")
19    child.setlog (fout)
20
21    i = child.expect([pexpect.TIMEOUT, SSH_NEWKEY, '[Pp]assword: '])
22    if i == 0: # Timeout
23        print 'ERROR!'
24        print 'SSH could not login. Here is what SSH said:'
25        print child.before, child.after
26        sys.exit (1)
27    if i == 1: # SSH does not have the public key. Just accept it.
28        child.sendline ('yes')
29        child.expect ('[Pp]assword: ')
30    child.sendline(password)
31    # Now we are either at the command prompt or
32    # the login process is asking for our terminal type.
33    i = child.expect (['Permission denied', TERMINAL_PROMPT, COMMAND_PROMPT])
34    if i == 0:
35        print 'Permission denied on host:', host
36        sys.exit (1)
37    if i == 1:
38        child.sendline (TERMINAL_TYPE)
39        child.expect (COMMAND_PROMPT)
40    return child
41
42# (current) UNIX password:
43def change_password(child, user, oldpassword, newpassword):
44
45    child.sendline('passwd')
46    i = child.expect(['[Oo]ld [Pp]assword', '.current.*password', '[Nn]ew [Pp]assword'])
47    # Root does not require old password, so it gets to bypass the next step.
48    if i == 0 or i == 1:
49        child.sendline(oldpassword)
50        child.expect('[Nn]ew [Pp]assword')
51    child.sendline(newpassword)
52    i = child.expect(['[Nn]ew [Pp]assword', '[Rr]etype', '[Rr]e-enter'])
53    if i == 0:
54        print 'Host did not like new password. Here is what it said...'
55        print child.before
56	child.send (chr(3)) # Ctrl-C
57        child.sendline('') # This should tell remote passwd command to quit.
58        return
59    child.sendline(newpassword)
60
61def main():
62
63    if len(sys.argv) <= 1:
64        print USAGE
65        return 1
66
67    user = raw_input('Username: ')
68    password = getpass.getpass('Current Password: ')
69    newpassword = getpass.getpass('New Password: ')
70    newpasswordconfirm = getpass.getpass('Confirm New Password: ')
71    if newpassword != newpasswordconfirm:
72        print 'New Passwords do not match.'
73        return 1
74
75    for host in sys.argv[1:]:
76        child = login(host, user, password)
77        if child == None:
78            print 'Could not login to host:', host
79            continue
80        print 'Changing password on host:', host
81        change_password(child, user, password, newpassword)
82        child.expect(COMMAND_PROMPT)
83        child.sendline('exit')
84
85if __name__ == '__main__':
86    try:
87        main()
88    except pexpect.ExceptionPexpect, e:
89        print str(e)
90
91