class ObjectStorageSFTPServer(ForkingTCPServer, paramiko.ServerInterface): """ Expose a ObjectStorageFS object over SFTP. """ allow_reuse_address = True def __init__(self, address, host_key=None, authurl=None, max_children=20, keystone=None): self.log = paramiko.util.get_logger("paramiko") self.log.debug("%s: start server" % self.__class__.__name__) self.fs = ObjectStorageFS(None, None, authurl=authurl, keystone=keystone) # unauthorized self.host_key = host_key self.max_children = max_children ForkingTCPServer.__init__(self, address, ObjectStorageSFTPRequestHandler) def check_channel_request(self, kind, chanid): if kind == 'session': return paramiko.OPEN_SUCCEEDED self.log.warning("Channel request denied from %s, kind=%s" \ % (self.client_address, kind)) # all the check_channel_*_request return False by default but # sftp subsystem because of the set_subsystem_handler call in # the ObjectStorageSFTPRequestHandler return paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED def check_auth_none(self, username): """Check whether the user can proceed without authentication.""" return paramiko.AUTH_FAILED def check_auth_publickey(self, username, key): """Check whether the given public key is valid for authentication.""" return paramiko.AUTH_FAILED def check_auth_password(self, username, password): """Check whether the given password is valid for authentication.""" self.log.info("Auth request (type=password), username=%s, from=%s" \ % (username, self.client_address)) try: if not password: raise EnvironmentError("no password provided") self.fs.authenticate(username, password) except EnvironmentError, e: self.log.warning("%s: Failed to authenticate: %s" % (self.client_address, e)) self.log.error("Authentication failure for %s from %s port %s" % (username, self.client_address[0], self.client_address[1])) return paramiko.AUTH_FAILED self.fs.conn.real_ip = self.client_address[0] self.log.info("%s authenticated from %s" % (username, self.client_address)) return paramiko.AUTH_SUCCESSFUL
class ObjectStorageSFTPServer(ForkingTCPServer, paramiko.ServerInterface): """ Expose a ObjectStorageFS object over SFTP. """ allow_reuse_address = True def __init__(self, address, host_key=None, authurl=None, max_children=20, keystone=None, no_scp=False, split_size=0, hide_part_dir=False, auth_timeout=None, negotiation_timeout=0, keepalive=0, insecure=False, secopts=None, server_ident=None, storage_policy=None, proxy_protocol=None, rsync_bin=None, large_object_container_suffix=None, fail2ban=None): self.log = paramiko.util.get_logger("paramiko") self.log.debug("%s: start server" % self.__class__.__name__) self.fs = ObjectStorageFS( None, None, authurl=authurl, keystone=keystone, hide_part_dir=hide_part_dir, insecure=insecure, storage_policy=storage_policy) # unauthorized self.host_key = host_key self.max_children = max_children self.no_scp = no_scp self.rsync_bin = rsync_bin self.split_size = split_size self.fail2ban = fail2ban if fail2ban: self.f2b = Fail2ban(fail2ban) ObjectStorageSFTPRequestHandler.auth_timeout = auth_timeout ObjectStorageSFTPRequestHandler.negotiation_timeout = negotiation_timeout ObjectStorageSFTPRequestHandler.keepalive = keepalive ObjectStorageSFTPRequestHandler.secopts = secopts ObjectStorageSFTPRequestHandler.server_ident = server_ident ObjectStorageSFTPRequestHandler.proxy_protocol = proxy_protocol ForkingTCPServer.__init__(self, address, ObjectStorageSFTPRequestHandler) ObjectStorageFD.split_size = split_size ObjectStorageFD.storage_policy = storage_policy ObjectStorageFD.large_object_container_suffix = large_object_container_suffix def check_channel_request(self, kind, chanid): if kind == 'session': return paramiko.OPEN_SUCCEEDED self.log.warning("Channel request denied from %s, kind=%s" \ % (self.client_address, kind)) # all the check_channel_*_request return False by default but # sftp subsystem because of the set_subsystem_handler call in # the ObjectStorageSFTPRequestHandler return paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED def check_channel_exec_request(self, channel, command): """Determine if a shell command will be executed for the client.""" # Parse the command if ' -- ' in command: # scp will use -- to delimit the beginning of the unscaped filename # so translate it to something that shelex can manage command = command.replace(' -- ', ' "') + '"' command = shlex.split(command) self.log.debug('check_channel_exec_request %r' % command) try: if command[0] == 'scp': if self.no_scp: self.log.info( "scp exec request denied from=%s (scp is disabled)" % (self.client_address, )) return False self.log.info('invoking %r from=%s' % (command, self.client_address)) # handle the command execution SCPHandler(command[1:], channel, self.fs, self.log).start() return True if command[0] == 'rsync': if self.rsync_bin is None: self.log.info( "rsync exec request denied from=%s (rsync_bin is not set)" % (self.client_address, )) return False self.log.info('invoking %s %r from=%s' % (self.rsync_bin, command, self.client_address)) RsyncHandler(self.rsync_bin, command[1:], channel, self.fs, self.log, self.split_size).start() return True except: self.log.exception("command %r failed from=%s" % (command, self.client_address)) return False return False def check_auth_none(self, username): """Check whether the user can proceed without authentication.""" return paramiko.AUTH_FAILED def check_auth_publickey(self, username, key): """Check whether the given public key is valid for authentication.""" return paramiko.AUTH_FAILED def check_auth_password(self, username, password): """Check whether the given password is valid for authentication.""" self.log.info("Auth request (type=password), username=%s, from=%s" \ % (username, self.client_address)) ip = self.client_address[0] if self.fail2ban: try: if self.f2b.get(ip) == 0: self.log.info( "New authentication request from banned address %s" % ip) return paramiko.AUTH_FAILED except Exception as e: self.log.exception("Failed to get %s value from memcache: %s" % (ip, e)) pass try: if not password: raise EnvironmentError("no password provided") self.fs.authenticate(username, password) except EnvironmentError, e: self.log.warning("%s: Failed to authenticate: %s" % (self.client_address, e)) self.log.error( "Authentication failure for %s from %s port %s" % (username, self.client_address[0], self.client_address[1])) if self.fail2ban: try: self.f2b.set(ip) except Exception as e: self.log.exception( "Failed to set new value in memcache: %s" % e) pass return paramiko.AUTH_FAILED self.fs.conn.real_ip = ip self.log.info("%s authenticated from %s" % (username, self.client_address)) return paramiko.AUTH_SUCCESSFUL
class ObjectStorageSFTPServer(ForkingTCPServer, paramiko.ServerInterface): """ Expose a ObjectStorageFS object over SFTP. """ allow_reuse_address = True def __init__(self, address, host_key=None, authurl=None, max_children=20, keystone=None, no_scp=False, split_size=0, hide_part_dir=False, auth_timeout=None, negotiation_timeout=0): self.log = paramiko.util.get_logger("paramiko") self.log.debug("%s: start server" % self.__class__.__name__) self.fs = ObjectStorageFS(None, None, authurl=authurl, keystone=keystone, hide_part_dir=hide_part_dir) # unauthorized self.host_key = host_key self.max_children = max_children self.no_scp = no_scp ObjectStorageSFTPRequestHandler.auth_timeout = auth_timeout ObjectStorageSFTPRequestHandler.negotiation_timeout = negotiation_timeout ForkingTCPServer.__init__(self, address, ObjectStorageSFTPRequestHandler) ObjectStorageFD.split_size = split_size def check_channel_request(self, kind, chanid): if kind == 'session': return paramiko.OPEN_SUCCEEDED self.log.warning("Channel request denied from %s, kind=%s" \ % (self.client_address, kind)) # all the check_channel_*_request return False by default but # sftp subsystem because of the set_subsystem_handler call in # the ObjectStorageSFTPRequestHandler return paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED def check_channel_exec_request(self, channel, command): """Determine if a shell command will be executed for the client.""" # Parse the command if ' -- ' in command: # scp will use -- to delimit the begining of the unscaped filename # so translate it to something that shelex can manage command = command.replace(' -- ', ' "') + '"' command = shlex.split(command) self.log.debug('check_channel_exec_request %r' % command) try: if command[0] == 'scp': if self.no_scp: self.log.info("scp exec request denied from=%s (scp is disabled)" % (self.client_address,)) return False self.log.info('invoking %r from=%s' % (command, self.client_address)) # handle the command execution SCPHandler(command[1:], channel, self.fs, self.log).start() return True except: self.log.exception("command %r failed from=%s" % (command, self.client_address)) return False return False def check_auth_none(self, username): """Check whether the user can proceed without authentication.""" return paramiko.AUTH_FAILED def check_auth_publickey(self, username, key): """Check whether the given public key is valid for authentication.""" return paramiko.AUTH_FAILED def check_auth_password(self, username, password): """Check whether the given password is valid for authentication.""" self.log.info("Auth request (type=password), username=%s, from=%s" \ % (username, self.client_address)) try: if not password: raise EnvironmentError("no password provided") self.fs.authenticate(username, password) except EnvironmentError, e: self.log.warning("%s: Failed to authenticate: %s" % (self.client_address, e)) self.log.error("Authentication failure for %s from %s port %s" % (username, self.client_address[0], self.client_address[1])) return paramiko.AUTH_FAILED self.fs.conn.real_ip = self.client_address[0] self.log.info("%s authenticated from %s" % (username, self.client_address)) return paramiko.AUTH_SUCCESSFUL
class ObjectStorageSFTPServer(ForkingTCPServer, paramiko.ServerInterface): """ Expose a ObjectStorageFS object over SFTP. """ allow_reuse_address = True def __init__(self, address, host_key=None, authurl=None, max_children=20, keystone=None, no_scp=False, split_size=0, hide_part_dir=False, auth_timeout=None, negotiation_timeout=0): self.log = paramiko.util.get_logger("paramiko") self.log.debug("%s: start server" % self.__class__.__name__) self.fs = ObjectStorageFS(None, None, authurl=authurl, keystone=keystone, hide_part_dir=hide_part_dir) # unauthorized self.host_key = host_key self.max_children = max_children self.no_scp = no_scp ObjectStorageSFTPRequestHandler.auth_timeout = auth_timeout ObjectStorageSFTPRequestHandler.negotiation_timeout = negotiation_timeout ForkingTCPServer.__init__(self, address, ObjectStorageSFTPRequestHandler) ObjectStorageFD.split_size = split_size def check_channel_request(self, kind, chanid): if kind == 'session': return paramiko.OPEN_SUCCEEDED self.log.warning("Channel request denied from %s, kind=%s" \ % (self.client_address, kind)) # all the check_channel_*_request return False by default but # sftp subsystem because of the set_subsystem_handler call in # the ObjectStorageSFTPRequestHandler return paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED def check_channel_exec_request(self, channel, command): """Determine if a shell command will be executed for the client.""" # Parse the command if ' -- ' in command: # scp will use -- to delimit the begining of the unscaped filename # so translate it to something that shelex can manage command = command.replace(' -- ', ' "') + '"' command = shlex.split(command) self.log.debug('check_channel_exec_request %r' % command) try: if command[0] == 'scp': if self.no_scp: self.log.info( "scp exec request denied from=%s (scp is disabled)" % (self.client_address, )) return False self.log.info('invoking %r from=%s' % (command, self.client_address)) # handle the command execution SCPHandler(command[1:], channel, self.fs, self.log).start() return True except: self.log.exception("command %r failed from=%s" % (command, self.client_address)) return False return False def check_auth_none(self, username): """Check whether the user can proceed without authentication.""" return paramiko.AUTH_FAILED def check_auth_publickey(self, username, key): """Check whether the given public key is valid for authentication.""" return paramiko.AUTH_FAILED def check_auth_password(self, username, password): """Check whether the given password is valid for authentication.""" self.log.info("Auth request (type=password), username=%s, from=%s" \ % (username, self.client_address)) try: if not password: raise EnvironmentError("no password provided") result = re.search('(@|^acc-)', username) if (result is None): raise EnvironmentError("bogus username") self.fs.authenticate(username, password) except EnvironmentError, e: self.log.warning("%s: Failed to authenticate: %s" % (self.client_address, e)) self.log.error( "Authentication failure for %s from %s port %s" % (username, self.client_address[0], self.client_address[1])) return paramiko.AUTH_FAILED self.fs.conn.real_ip = self.client_address[0] self.log.info("%s authenticated from %s" % (username, self.client_address)) return paramiko.AUTH_SUCCESSFUL