diff --git a/tes/sshwrapper/__init__.py b/tes/sshwrapper/__init__.py
index 2dc0160e9ca736be61158d2068228dcb6bef3293..ed80faba085f8d3cf065826963d0356b72884d80 100644
--- a/tes/sshwrapper/__init__.py
+++ b/tes/sshwrapper/__init__.py
@@ -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):
         """
diff --git a/tes/tunnelstat/__init__.py b/tes/tunnelstat/__init__.py
index de537d5fdbbc74785380527cc62c28b03bb00bbd..c6b9b5b64083a9d1692d098ae940287390a55be0 100644
--- a/tes/tunnelstat/__init__.py
+++ b/tes/tunnelstat/__init__.py
@@ -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