Skip to content
Snippets Groups Projects
Commit 4f47719d authored by Ubuntu's avatar Ubuntu
Browse files
parents c74b3280 ae2bec62
No related branches found
No related tags found
No related merge requests found
......@@ -23,6 +23,7 @@ class SshCtrlException(Exception):
"""
pass
class Ssh:
"""
Ssh class can execute or create tunnelstat
......@@ -74,6 +75,8 @@ class Ssh:
"""
import os
import stat
import logging
logger = logging.getLogger()
ctrlsocket = "/tmp/cm-{}-{}".format(user,host)
try:
mode = os.stat(ctrlsocket).st_mode
......@@ -81,11 +84,10 @@ class Ssh:
mode = None
if mode is None:
ctrlsocket = "/tmp/cm-{}-{}".format(user,host)
sshcmd = ["ssh", '-o', 'StrictHostKeyChecking=no',
"-S", ctrlsocket,
"-M", '-o', 'ControlPersist=10m',
'-l', user, host]
'-N','-l', user, host]
env = os.environ.copy()
if sess.socket is None:
raise SshAgentException("No ssh-agent yet")
......@@ -93,16 +95,94 @@ class Ssh:
ctrl_p = subprocess.Popen(sshcmd,
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
stdin=subprocess.PIPE, env=env)
env=env)
stdout = ctrl_p.communicate()
logger.debug('communicate on the control port complete')
sess.pids.append(ctrl_p.pid)
try:
mode = os.stat(ctrlsocket).st_mode
except FileNotFoundError:
mode = None
logger.debug("control socket not open")
logger.error(ctrl_p.stderr.read())
raise SshCtrlException()
if not stat.S_ISSOCK(mode):
raise SshCtrlException()
return ctrlsocket
@staticmethod
def parse_sftp_output(output):
import logging
logger = logging.getLogger()
rv = []
pwd = None
import dateutil.parser
for l in output.splitlines():
fields = l.split(None,8)
fd = {}
if len(fields) == 9:
fd['name'] = fields[8]
fd['mode'] = fields[0]
fd['hardlinks'] = fields[1]
fd['user'] = fields[2]
fd['group'] = fields[3]
fd['size'] = fields[4]
fd['mtime'] = dateutil.parser.parse("{} {} {}".format(fields[5],fields[6],fields[7])).isoformat()
fd['name'] = fields[8]
rv.append(fd)
remotestr = "Remote working directory: "
if remotestr in l:
pwd = l[len(remotestr):].rstrip()
return ({'pwd':pwd,'files':rv})
@staticmethod
def sftpls(sess, host, user, path="",changepath="."):
"""
Use sftp to run an ls on the given path.
Return the directory listing (as a list) and the cwd
"""
import os
import logging
logger = logging.getLogger()
env = os.environ.copy()
if sess.socket is None:
raise SshAgentException("No ssh-agent yet")
env['SSH_AUTH_SOCK'] = sess.socket
Ssh.validate_username(user)
Ssh.validate_hostname(host)
ctrlsocket = Ssh.get_ctrl_master_socket(sess, host, user)
exec_p = subprocess.Popen(['sftp', '-b', '-','-o', 'Stricthostkeychecking=no',
'-o', 'ControlPath={}'.format(ctrlsocket),
'{}@{}'.format(user, host)],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
stdin=subprocess.PIPE, env=env)
sftpcmd="cd {}\n cd {}\n pwd\nls -al\n".format(path,changepath)
(stdout, stderr) = exec_p.communicate(sftpcmd.encode())
if stderr is not None:
if not (stderr == b''):
logger.error('sftp failure')
if ('Couldn\'t canonicalize: No such file or directory' in stderr.decode()):
logger.error('can\'t change to that directory')
return Ssh.sftpls(sess,host,user,path,changepath='.')
if ('Permission denied' in stderr.decode()):
logger.error('can\'t change to that directory')
return Ssh.sftpls(sess,host,user,path,changepath='.')
logger.error(stderr.decode())
logger.error(('Permission denied' in stderr.decode()))
logger.error('Couldn\'t canonicalize: No such file or directory' in stderr.decode())
raise SshCtrlException()
dirlist = Ssh.parse_sftp_output(stdout.decode())
return dirlist
@staticmethod
def execute(sess, host, user, cmd, stdin=None):
"""
......
......@@ -89,6 +89,8 @@ class SSHSession:
keygenout,keygenerr = p.communicate(l)
certcontents = SSHSession.parse_cert_contents(keygenout.decode().splitlines())
res.append(certcontents)
else:
res.append({'pubkey':l.decode()})
return res
@staticmethod
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment