Beispiel #1
0
    def _purge_cache(cls, *refs):
        folders = []
        for orig_ref in refs:
            ref = cls._copy_reference_without_username(orig_ref)
            if cls.debug:
                dprint("Removing cache for %s" % ref)
            if ref in cls.remap301:
                del cls.remap301[ref]
            if ref in cls.response_cache:
                status, responses = cls.response_cache[ref]
                path_found, response = cls._get_response_from_ref(ref, responses)
                try:
                    if response["getcontenttype"] == "httpd/unix-directory":
                        if cls.debug:
                            dprint("Found folder %s" % ref)
                        folders.append(ref)
                except KeyError:
                    pass
                del cls.response_cache[ref]

        # Remove all the cached data for anything contained in any folders that
        # have been removed.
        for folder in folders:
            if cls.debug:
                dprint("Checking folder %s" % folder)
            folder_url = unicode(folder)
            keys = cls.response_cache.keys()
            for ref in keys:
                if cls.debug:
                    dprint("Checking cache %s" % str(ref))
                ref_url = unicode(ref)
                if ref_url.startswith(folder_url):
                    if cls.debug:
                        dprint("Removing cache hit %s for deleted folder: %s" % (ref_url, folder_url))
                    del cls.response_cache[ref]
Beispiel #2
0
def get_transport(transport_key):
    try:
        t = paramiko.Transport(transport_key)
    except Exception, e:
        import traceback
        dprint("".join(traceback.format_exc()))
        raise utils.NetworkError("Failed opening %s:%s -- %s" % (transport_key[0], transport_key[1], str(e)))
Beispiel #3
0
    def _purge_cache(cls, *refs):
        folders = []
        for orig_ref in refs:
            ref = cls._copy_reference_without_username(orig_ref)
            if cls.debug: dprint("Removing cache for %s" % ref)
            if ref in cls.remap301:
                del cls.remap301[ref]
            if ref in cls.response_cache:
                status, responses = cls.response_cache[ref]
                path_found, response = cls._get_response_from_ref(
                    ref, responses)
                try:
                    if response['getcontenttype'] == "httpd/unix-directory":
                        if cls.debug: dprint("Found folder %s" % ref)
                        folders.append(ref)
                except KeyError:
                    pass
                del cls.response_cache[ref]

        # Remove all the cached data for anything contained in any folders that
        # have been removed.
        for folder in folders:
            if cls.debug: dprint("Checking folder %s" % folder)
            folder_url = unicode(folder)
            keys = cls.response_cache.keys()
            for ref in keys:
                if cls.debug: dprint("Checking cache %s" % str(ref))
                ref_url = unicode(ref)
                if ref_url.startswith(folder_url):
                    if cls.debug:
                        dprint("Removing cache hit %s for deleted folder: %s" %
                               (ref_url, folder_url))
                    del cls.response_cache[ref]
Beispiel #4
0
    def open(cls, ref, mode=None):
        ref, client = cls._get_client(ref)
        body = client.get(str(ref.path))
        if client.response.status == 200:
            if cls.debug:
                dprint("%s: %s" % (str(ref), body))

            if mode == WRITE:
                # write truncates
                fh = cls.temp_file_class(ref, cls._save_file, "")
            elif mode == APPEND:
                fh = cls.temp_file_class(ref, cls._save_file, body)
                fh.seek(len(body))
            elif mode == READ_WRITE:
                # Open for read/write but don't position at end of file, i.e. "r+b"
                fh = cls.temp_file_class(ref, cls._save_file, body)
            else:
                fh = cls.temp_file_class(ref, None, body)
            return fh
        else:
            if cls.debug:
                dprint("%s: %s" % (str(ref), client.response.status))
            raise OSError(
                "[Errno %d] %s: '%s'"
                % (
                    client.response.status,
                    BaseHTTPServer.BaseHTTPRequestHandler.responses[client.response.status][0],
                    ref,
                )
            )
Beispiel #5
0
    def move(cls, source, target):
        if cls.is_file(target):
            raise OSError("[Errno 20] Not a directory: '%s'" % target)

        ref, client = cls._get_client(source)
        responses = client.move(source, target)
        if cls.debug: dprint(client.response.status)
        cls._purge_cache(source, target)
Beispiel #6
0
    def remove(cls, ref):
        if not cls.exists(ref):
            raise OSError("[Errno 17] File exists: '%s'" % ref)

        newref, client = cls._get_client(ref)
        path = str(newref.path)
        responses = client.delete(path)
        if cls.debug: dprint(client.response.status)
        cls._purge_cache(ref, newref)
Beispiel #7
0
 def get_names(cls, ref):
     if not cls.exists(ref):
         raise OSError("[Errno 2] No such file or directory: '%s'" % ref)
     if not cls.is_folder(ref):
         raise OSError("[Errno 20] Not a directory: '%s'" % ref)
     client = cls._get_client(ref)
     filenames = client.listdir(str(ref.path))
     if cls.debug: dprint(filenames)
     return filenames
Beispiel #8
0
    def move(cls, source, target):
        if cls.is_file(target):
            raise OSError("[Errno 20] Not a directory: '%s'" % target)

        ref, client = cls._get_client(source)
        responses = client.move(source, target)
        if cls.debug:
            dprint(client.response.status)
        cls._purge_cache(source, target)
Beispiel #9
0
    def remove(cls, ref):
        if not cls.exists(ref):
            raise OSError("[Errno 17] File exists: '%s'" % ref)

        newref, client = cls._get_client(ref)
        path = str(newref.path)
        responses = client.delete(path)
        if cls.debug:
            dprint(client.response.status)
        cls._purge_cache(ref, newref)
Beispiel #10
0
 def make_folder(cls, ref):
     if cls.exists(ref):
         if cls.is_folder(ref):
             return
         raise OSError("[Errno 20] Not a directory: '%s'" % ref)
     parent = utils.get_dirname(ref)
     if not cls.exists(parent):
         raise OSError("[Errno 2] No such file or directory: '%s'" % parent)
     if not cls.is_folder(parent):
         raise OSError("[Errno 20] Not a directory: '%s'" % parent)
     client = cls._get_client(ref)
     path = str(ref.path)
     if cls.debug: dprint(path)
     client.mkdir(path)
Beispiel #11
0
    def _propfind(cls, ref):
        ref, client = cls._get_client(ref)
        if ref in cls.response_cache:
            status, responses = cls.response_cache[ref]
            if cls.debug: dprint("response_cache hit: %s" % str(ref))
        else:
            if cls.debug: dprint("response_cache miss: %s" % str(ref))
            path = str(ref.path)
            responses = client.propfind(path, depth=1)
            if client.response.status == 301:
                #if cls.debug: dprint(client.response.status)
                #if cls.debug: dprint(pp.pformat(responses))
                #if cls.debug: dprint(client.response.body)
                match = cls.re301.search(client.response.body)
                if match:
                    newpath = match.group(1)
                    responses = client.propfind(newpath, depth=1)
                    cls.remap301[ref] = get_reference(newpath)
            status = client.response.status
            if cls.debug:
                dprint("response_cache miss: storing status=%s, response=%s" %
                       (status, responses))
        if responses is not None:
            if cls.debug: dprint(ref)
            newref = cls._copy_reference_without_username(ref)
            cls.response_cache[newref] = (status, responses)

        return ref, status, responses
Beispiel #12
0
    def _propfind(cls, ref):
        ref, client = cls._get_client(ref)
        if ref in cls.response_cache:
            status, responses = cls.response_cache[ref]
            if cls.debug:
                dprint("response_cache hit: %s" % str(ref))
        else:
            if cls.debug:
                dprint("response_cache miss: %s" % str(ref))
            path = str(ref.path)
            responses = client.propfind(path, depth=1)
            if client.response.status == 301:
                # if cls.debug: dprint(client.response.status)
                # if cls.debug: dprint(pp.pformat(responses))
                # if cls.debug: dprint(client.response.body)
                match = cls.re301.search(client.response.body)
                if match:
                    newpath = match.group(1)
                    responses = client.propfind(newpath, depth=1)
                    cls.remap301[ref] = get_reference(newpath)
            status = client.response.status
            if cls.debug:
                dprint("response_cache miss: storing status=%s, response=%s" % (status, responses))
        if responses is not None:
            if cls.debug:
                dprint(ref)
            newref = cls._copy_reference_without_username(ref)
            cls.response_cache[newref] = (status, responses)

        return ref, status, responses
Beispiel #13
0
 def make_folder(cls, ref):
     if cls.exists(ref):
         if cls.is_folder(ref):
             return
         raise OSError("[Errno 20] Not a directory: '%s'" % ref)
     parent = utils.get_dirname(ref)
     if not cls.is_folder(parent):
         raise OSError("[Errno 20] Not a directory: '%s'" % parent)
     ref, client = cls._get_client(ref)
     path = str(ref.path)
     if cls.debug: dprint(path)
     responses = client.mkcol(path)
     # It's also possible (but not required) the parent could be cached, so
     # clean out its cache as well
     if cls.debug: dprint(parent)
     cls._purge_cache(parent)
Beispiel #14
0
 def make_folder(cls, ref):
     if cls.exists(ref):
         if cls.is_folder(ref):
             return
         raise OSError("[Errno 20] Not a directory: '%s'" % ref)
     parent = utils.get_dirname(ref)
     if not cls.is_folder(parent):
         raise OSError("[Errno 20] Not a directory: '%s'" % parent)
     ref, client = cls._get_client(ref)
     path = str(ref.path)
     if cls.debug:
         dprint(path)
     responses = client.mkcol(path)
     # It's also possible (but not required) the parent could be cached, so
     # clean out its cache as well
     if cls.debug:
         dprint(parent)
     cls._purge_cache(parent)
Beispiel #15
0
    def open(cls, ref, mode=None):
        ref, client = cls._get_client(ref)
        body = client.get(str(ref.path))
        if client.response.status == 200:
            if cls.debug: dprint("%s: %s" % (str(ref), body))

            if mode == WRITE:
                # write truncates
                fh = cls.temp_file_class(ref, cls._save_file, "")
            elif mode == APPEND:
                fh = cls.temp_file_class(ref, cls._save_file, body)
                fh.seek(len(body))
            elif mode == READ_WRITE:
                # Open for read/write but don't position at end of file, i.e. "r+b"
                fh = cls.temp_file_class(ref, cls._save_file, body)
            else:
                fh = cls.temp_file_class(ref, None, body)
            return fh
        else:
            if cls.debug: dprint("%s: %s" % (str(ref), client.response.status))
            raise OSError(
                "[Errno %d] %s: '%s'" %
                (client.response.status, BaseHTTPServer.BaseHTTPRequestHandler.
                 responses[client.response.status][0], ref))
Beispiel #16
0
 def _get_client(cls, ref):
     client = None
     newref = cls._copy_root_reference_without_username(ref)
     if newref in cls.connection_cache:
         client = cls.connection_cache[newref]
         if cls.debug: dprint("Found cached sftp connection: %s" % client)
         transport = client.get_channel().get_transport()
         if not transport.is_active():
             dprint("Cached channel closed.  Opening new connection for %s" % ref)
             client = None
         
     if client is None:
         client = cls._get_sftp(ref)
         if cls.debug: dprint("Creating sftp connection: %s" % client)
         cls.connection_cache[newref] = client
     return client
Beispiel #17
0
 def _password_auth(cls, transport_key, username, passwd):
     while True:
         if cls.debug: dprint("username=%s, passwd=%s" % (username, passwd))
         if not passwd:
             if transport_key in cls.credentials:
                 username, passwd = cls.credentials[transport_key]
                 if cls.debug: dprint("Found cached credentials for %s" % str(transport_key))
             else:
                 callback = utils.get_authentication_callback()
                 username, passwd = callback(transport_key[0], "sftp", None, username)
                 if cls.debug: dprint("User entered credentials: username=%s, passwd=%s" % (username, passwd))
         if username and passwd:
             try:
                 t = get_transport(transport_key)
                 t.auth_password(username=username, password=passwd)
                 if cls.debug: dprint("Authenticated for user %s" % username)
                 cls.credentials[transport_key] = (username, passwd)
                 return t
             except paramiko.AuthenticationException:
                 import traceback
                 error = traceback.format_exc()
                 dprint(error)
                 pass
             if cls.debug: dprint("Failed password for user %s" % username)
             if transport_key in cls.credentials:
                 del cls.credentials[transport_key]
             passwd = ""
Beispiel #18
0
 def _stat(cls, ref):
     client = cls._get_client(ref)
     attrs = client.stat(str(ref.path))
     if cls.debug: dprint("%s: %s" % (ref, repr(attrs)))
     return attrs
Beispiel #19
0
 def _private_key_auth(cls, transport_key, username):
     """Attempt to authenticate to the given transport using the private keys
     available from the user's home directory
     """
     callback = utils.get_authentication_callback()
     t = get_transport(transport_key)
     if not username:
         username = getpass.getuser()
     if not t.is_authenticated():
         agent = paramiko.Agent()
         agent_keys = agent.get_keys()
         if len(agent_keys) > 0:
             for key in agent_keys:
                 if cls.debug: dprint('Trying ssh-agent key %s' % hexlify(key.get_fingerprint()))
                 try:
                     t.auth_publickey(username, key)
                     if cls.debug: dprint('... success!')
                     break
                 except paramiko.SSHException:
                     if not t.is_active():
                         t = get_transport(transport_key)
         
     if not t.is_authenticated():
         path = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa')
         if os.path.exists(path):
             if cls.debug: dprint("Trying RSA private key")
             try:
                 key = paramiko.RSAKey.from_private_key_file(path)
             except paramiko.PasswordRequiredException:
                 username, passwd = callback(transport_key[0], "sftp", "RSA key pass phrase", username)
                 key = paramiko.RSAKey.from_private_key_file(path, passwd)
             try:
                 t.auth_publickey(username, key)
                 if cls.debug: dprint("RSA private key authorization successful.")
             except paramiko.AuthenticationException:
                 dprint("RSA private key authorization failed.")
                 if not t.is_active():
                     t = get_transport(transport_key)
     
     if not t.is_authenticated():
         path = os.path.join(os.environ['HOME'], '.ssh', 'id_dsa')
         if os.path.exists(path):
             if cls.debug: dprint("Trying DSS private key")
             try:
                 key = paramiko.DSSKey.from_private_key_file(path)
             except paramiko.PasswordRequiredException:
                 username, passwd = callback(transport_key[0], "sftp", "DSS key pass phrase", username)
                 key = paramiko.DSSKey.from_private_key_file(path, password)
             try:
                 t.auth_publickey(username, key)
                 if cls.debug: dprint("DSS private key authorization successful.")
             except paramiko.AuthenticationException:
                 if cls.debug: dprint("DSS private key authorization failed.")
                 if not t.is_active():
                     t = get_transport(transport_key)
     
     return t