18a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen# 28a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen# Eric S. Raymond 38a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen# 48a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen# Greatly modified by Nigel W. Moriarty 58a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen# April 2003 68a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen# 78a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenfrom pexpect import * 88a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenimport os, sys 98a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenimport getpass 108a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenimport time 118a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 128a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenclass ssh_session: 138a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 148a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen "Session with extra state including the password to be used." 158a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 168a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen def __init__(self, user, host, password=None, verbose=0): 178a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 188a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen self.user = user 198a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen self.host = host 208a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen self.verbose = verbose 218a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen self.password = password 228a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen self.keys = [ 238a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 'authenticity', 248a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 'assword:', 258a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen '@@@@@@@@@@@@', 268a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 'Command not found.', 278a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen EOF, 288a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen ] 298a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 308a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen self.f = open('ssh.out','w') 318a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 328a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen def __repr__(self): 338a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 348a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen outl = 'class :'+self.__class__.__name__ 358a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen for attr in self.__dict__: 368a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen if attr == 'password': 378a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen outl += '\n\t'+attr+' : '+'*'*len(self.password) 388a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen else: 398a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen outl += '\n\t'+attr+' : '+str(getattr(self, attr)) 408a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen return outl 418a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 428a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen def __exec(self, command): 438a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 448a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen "Execute a command on the remote host. Return the output." 458a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen child = spawn(command, 468a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen #timeout=10, 478a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen ) 488a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen if self.verbose: 498a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen sys.stderr.write("-> " + command + "\n") 508a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen seen = child.expect(self.keys) 518a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen self.f.write(str(child.before) + str(child.after)+'\n') 528a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen if seen == 0: 538a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen child.sendline('yes') 548a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen seen = child.expect(self.keys) 558a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen if seen == 1: 568a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen if not self.password: 578a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen self.password = getpass.getpass('Remote password: ') 588a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen child.sendline(self.password) 598a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen child.readline() 608a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen time.sleep(5) 618a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen # Added to allow the background running of remote process 628a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen if not child.isalive(): 638a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen seen = child.expect(self.keys) 648a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen if seen == 2: 658a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen lines = child.readlines() 668a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen self.f.write(lines) 678a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen if self.verbose: 688a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen sys.stderr.write("<- " + child.before + "|\n") 698a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen try: 708a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen self.f.write(str(child.before) + str(child.after)+'\n') 718a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen except: 728a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen pass 738a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen self.f.close() 748a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen return child.before 758a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 768a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen def ssh(self, command): 778a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 788a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen return self.__exec("ssh -l %s %s \"%s\"" \ 798a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen % (self.user,self.host,command)) 808a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 818a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen def scp(self, src, dst): 828a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 838a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen return self.__exec("scp %s %s@%s:%s" \ 848a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen % (src, session.user, session.host, dst)) 858a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 868a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen def exists(self, file): 878a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 888a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen "Retrieve file permissions of specified remote file." 898a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen seen = self.ssh("/bin/ls -ld %s" % file) 908a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen if string.find(seen, "No such file") > -1: 918a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen return None # File doesn't exist 928a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen else: 938a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen return seen.split()[0] # Return permission field of listing. 948a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen 95