#!/usr/bin/env python
"""Change passwords on the named machines. passmass host1 host2 host3 . . .
Note that login shell prompt on remote machine must end in # or $. """
import pexpect
import sys, getpass
USAGE = '''passmass host1 host2 host3 . . .'''
COMMAND_PROMPT = '[$#] '
TERMINAL_PROMPT = r'Terminal type\?'
TERMINAL_TYPE = 'vt100'
SSH_NEWKEY = r'Are you sure you want to continue connecting \(yes/no\)\?'
def login(host, user, password):
child = pexpect.spawn('ssh -l %s %s'%(user, host))
fout = file ("LOG.TXT","wb")
child.setlog (fout)
i = child.expect([pexpect.TIMEOUT, SSH_NEWKEY, '[Pp]assword: '])
if i == 0: # Timeout
print 'ERROR!'
print 'SSH could not login. Here is what SSH said:'
print child.before, child.after
sys.exit (1)
if i == 1: # SSH does not have the public key. Just accept it.
child.sendline ('yes')
child.expect ('[Pp]assword: ')
child.sendline(password)
# Now we are either at the command prompt or
# the login process is asking for our terminal type.
i = child.expect (['Permission denied', TERMINAL_PROMPT, COMMAND_PROMPT])
if i == 0:
print 'Permission denied on host:', host
sys.exit (1)
if i == 1:
child.sendline (TERMINAL_TYPE)
child.expect (COMMAND_PROMPT)
return child
# (current) UNIX password:
def change_password(child, user, oldpassword, newpassword):
child.sendline('passwd')
i = child.expect(['[Oo]ld [Pp]assword', '.current.*password', '[Nn]ew [Pp]assword'])
# Root does not require old password, so it gets to bypass the next step.
if i == 0 or i == 1:
child.sendline(oldpassword)
child.expect('[Nn]ew [Pp]assword')
child.sendline(newpassword)
i = child.expect(['[Nn]ew [Pp]assword', '[Rr]etype', '[Rr]e-enter'])
if i == 0:
print 'Host did not like new password. Here is what it said...'
print child.before
child.send (chr(3)) # Ctrl-C
child.sendline('') # This should tell remote passwd command to quit.
return
child.sendline(newpassword)
def main():
if len(sys.argv) <= 1:
print USAGE
return 1
user = raw_input('Username: ')
password = getpass.getpass('Current Password: ')
newpassword = getpass.getpass('New Password: ')
newpasswordconfirm = getpass.getpass('Confirm New Password: ')
if newpassword != newpasswordconfirm:
print 'New Passwords do not match.'
return 1
for host in sys.argv[1:]:
child = login(host, user, password)
if child == None:
print 'Could not login to host:', host
continue
print 'Changing password on host:', host
change_password(child, user, password, newpassword)
child.expect(COMMAND_PROMPT)
child.sendline('exit')
if __name__ == '__main__':
try:
main()
except pexpect.ExceptionPexpect, e:
print str(e)