Guest User

Untitled

a guest
Oct 8th, 2016
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.36 KB | None | 0 0
  1. import paramiko
  2. import socket
  3. import os
  4. from stat import S_ISDIR
  5.  
  6. class SSHSession(object):
  7. # Usage:
  8. # Detects DSA or RSA from key_file, either as a string filename or a
  9. # file object. Password auth is possible, but I will judge you for
  10. # using it. So:
  11. # ssh=SSHSession('targetserver.com','root',key_file=open('mykey.pem','r'))
  12. # ssh=SSHSession('targetserver.com','root',key_file='/home/me/mykey.pem')
  13. # ssh=SSHSession('targetserver.com','root','mypassword')
  14. # ssh.put('filename','/remote/file/destination/path')
  15. # ssh.put_all('/path/to/local/source/dir','/path/to/remote/destination')
  16. # ssh.get_all('/path/to/remote/source/dir','/path/to/local/destination')
  17. # ssh.command('echo "Command to execute"')
  18.  
  19. def __init__(self,hostname,username='root',key_file=None,password=None):
  20. #
  21. # Accepts a file-like object (anything with a readlines() function)
  22. # in either dss_key or rsa_key with a private key. Since I don't
  23. # ever intend to leave a server open to a password auth.
  24. #
  25. self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  26. self.sock.connect((hostname,22))
  27. self.t = paramiko.Transport(self.sock)
  28. self.t.start_client()
  29. keys = paramiko.util.load_host_keys(os.path.expanduser('~/.ssh/known_hosts'))
  30. key = self.t.get_remote_server_key()
  31. # supposed to check for key in keys, but I don't much care right now to find the right notation
  32. if key_file is not None:
  33. if isinstance(key,str):
  34. key_file=open(key,'r')
  35. key_head=key_file.readline()
  36. key_file.seek(0)
  37. if 'DSA' in key_head:
  38. keytype=paramiko.DSSKey
  39. elif 'RSA' in key_head:
  40. keytype=paramiko.RSAKey
  41. else:
  42. raise Exception("Can't identify key type")
  43. pkey=keytype.from_private_key(key_file)
  44. self.t.auth_publickey(username, pkey)
  45. else:
  46. if password is not None:
  47. self.t.auth_password(username,password,fallback=False)
  48. else: raise Exception('Must supply either key_file or password')
  49. self.sftp=paramiko.SFTPClient.from_transport(self.t)
  50.  
  51. def command(self,cmd):
  52. # Breaks the command by lines, sends and receives
  53. # each line and its output separately
  54. #
  55. # Returns the server response text as a string
  56.  
  57. chan = self.t.open_session()
  58. chan.get_pty()
  59. chan.invoke_shell()
  60. chan.settimeout(20.0)
  61. ret=''
  62. try:
  63. ret+=chan.recv(1024)
  64. except:
  65. chan.send('\n')
  66. ret+=chan.recv(1024)
  67. for line in cmd.split('\n'):
  68. chan.send(line.strip() + '\n')
  69. ret+=chan.recv(1024)
  70. return ret
  71.  
  72. def put(self,localfile,remotefile):
  73. # Copy localfile to remotefile, overwriting or creating as needed.
  74. self.sftp.put(localfile,remotefile)
  75.  
  76. def put_all(self,localpath,remotepath):
  77. # recursively upload a full directory
  78. os.chdir(os.path.split(localpath)[0])
  79. parent=os.path.split(localpath)[1]
  80. for walker in os.walk(parent):
  81. try:
  82. self.sftp.mkdir(os.path.join(remotepath,walker[0]))
  83. except:
  84. pass
  85. for file in walker[2]:
  86. self.put(os.path.join(walker[0],file),os.path.join(remotepath,walker[0],file))
  87.  
  88. def get(self,remotefile,localfile):
  89. # Copy remotefile to localfile, overwriting or creating as needed.
  90. self.sftp.get(remotefile,localfile)
  91.  
  92. def sftp_walk(self,remotepath):
  93. # Kindof a stripped down version of os.walk, implemented for
  94. # sftp. Tried running it flat without the yields, but it really
  95. # chokes on big directories.
  96. path=remotepath
  97. files=[]
  98. folders=[]
  99. for f in self.sftp.listdir_attr(remotepath):
  100. if S_ISDIR(f.st_mode):
  101. folders.append(f.filename)
  102. else:
  103. files.append(f.filename)
  104. print (path,folders,files)
  105. yield path,folders,files
  106. for folder in folders:
  107. new_path=os.path.join(remotepath,folder)
  108. for x in self.sftp_walk(new_path):
  109. yield x
  110.  
  111. def get_all(self,remotepath,localpath):
  112. # recursively download a full directory
  113. # Harder than it sounded at first, since paramiko won't walk
  114. #
  115. # For the record, something like this would gennerally be faster:
  116. # ssh user@host 'tar -cz /source/folder' | tar -xz
  117.  
  118. self.sftp.chdir(os.path.split(remotepath)[0])
  119. parent=os.path.split(remotepath)[1]
  120. try:
  121. os.mkdir(localpath)
  122. except:
  123. pass
  124. for walker in self.sftp_walk(parent):
  125. try:
  126. os.mkdir(os.path.join(localpath,walker[0]))
  127. except:
  128. pass
  129. for file in walker[2]:
  130. self.get(os.path.join(walker[0],file),os.path.join(localpath,walker[0],file))
  131. def write_command(self,text,remotefile):
  132. # Writes text to remotefile, and makes remotefile executable.
  133. # This is perhaps a bit niche, but I was thinking I needed it.
  134. # For the record, I was incorrect.
  135. self.sftp.open(remotefile,'w').write(text)
  136. self.sftp.chmod(remotefile,755)
Add Comment
Please, Sign In to add comment