18a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen#!/usr/bin/env python 28a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 38a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen"""Change passwords on the named machines. passmass host1 host2 host3 . . . 48a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny ChenNote that login shell prompt on remote machine must end in # or $. """ 58a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 68a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenimport pexpect 78a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenimport sys, getpass 88a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 98a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny ChenUSAGE = '''passmass host1 host2 host3 . . .''' 108a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny ChenCOMMAND_PROMPT = '[$#] ' 118a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny ChenTERMINAL_PROMPT = r'Terminal type\?' 128a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny ChenTERMINAL_TYPE = 'vt100' 138a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny ChenSSH_NEWKEY = r'Are you sure you want to continue connecting \(yes/no\)\?' 148a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 158a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chendef login(host, user, password): 168a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 178a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen child = pexpect.spawn('ssh -l %s %s'%(user, host)) 188a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen fout = file ("LOG.TXT","wb") 198a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen child.setlog (fout) 208a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 218a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen i = child.expect([pexpect.TIMEOUT, SSH_NEWKEY, '[Pp]assword: ']) 228a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen if i == 0: # Timeout 238a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen print 'ERROR!' 248a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen print 'SSH could not login. Here is what SSH said:' 258a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen print child.before, child.after 268a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen sys.exit (1) 278a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen if i == 1: # SSH does not have the public key. Just accept it. 288a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen child.sendline ('yes') 298a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen child.expect ('[Pp]assword: ') 308a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen child.sendline(password) 318a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen # Now we are either at the command prompt or 328a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen # the login process is asking for our terminal type. 338a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen i = child.expect (['Permission denied', TERMINAL_PROMPT, COMMAND_PROMPT]) 348a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen if i == 0: 358a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen print 'Permission denied on host:', host 368a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen sys.exit (1) 378a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen if i == 1: 388a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen child.sendline (TERMINAL_TYPE) 398a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen child.expect (COMMAND_PROMPT) 408a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen return child 418a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 428a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen# (current) UNIX password: 438a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chendef change_password(child, user, oldpassword, newpassword): 448a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 458a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen child.sendline('passwd') 468a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen i = child.expect(['[Oo]ld [Pp]assword', '.current.*password', '[Nn]ew [Pp]assword']) 478a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen # Root does not require old password, so it gets to bypass the next step. 488a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen if i == 0 or i == 1: 498a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen child.sendline(oldpassword) 508a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen child.expect('[Nn]ew [Pp]assword') 518a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen child.sendline(newpassword) 528a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen i = child.expect(['[Nn]ew [Pp]assword', '[Rr]etype', '[Rr]e-enter']) 538a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen if i == 0: 548a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen print 'Host did not like new password. Here is what it said...' 558a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen print child.before 568a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen child.send (chr(3)) # Ctrl-C 578a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen child.sendline('') # This should tell remote passwd command to quit. 588a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen return 598a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen child.sendline(newpassword) 608a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 618a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chendef main(): 628a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 638a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen if len(sys.argv) <= 1: 648a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen print USAGE 658a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen return 1 668a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 678a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen user = raw_input('Username: ') 688a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen password = getpass.getpass('Current Password: ') 698a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen newpassword = getpass.getpass('New Password: ') 708a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen newpasswordconfirm = getpass.getpass('Confirm New Password: ') 718a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen if newpassword != newpasswordconfirm: 728a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen print 'New Passwords do not match.' 738a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen return 1 748a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 758a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen for host in sys.argv[1:]: 768a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen child = login(host, user, password) 778a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen if child == None: 788a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen print 'Could not login to host:', host 798a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen continue 808a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen print 'Changing password on host:', host 818a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen change_password(child, user, password, newpassword) 828a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen child.expect(COMMAND_PROMPT) 838a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen child.sendline('exit') 848a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 858a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenif __name__ == '__main__': 868a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen try: 878a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen main() 888a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen except pexpect.ExceptionPexpect, e: 898a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen print str(e) 908a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 91