def recv(self, buffer_size): try: return super(SSLConnection, self).recv(buffer_size) except (SSL.WantReadError, SSL.WantWriteError): return b('') except SSL.ZeroReturnError: super(SSLConnection, self).handle_close() return b('') except SSL.SysCallError: err = sys.exc_info()[1] errnum, errstr = err.args if errnum in _DISCONNECTED or errstr == 'Unexpected EOF': super(SSLConnection, self).handle_close() return b('') else: raise
def test_unforseen_ssl_shutdown(self): self.client.login() try: sock = self.client.sock.unwrap() except socket.error: err = sys.exc_info()[1] if err.errno == 0: return raise sock.sendall(b('noop')) try: chunk = sock.recv(1024) except socket.error: pass else: self.assertEqual(chunk, b(""))
def test_unforseen_ssl_shutdown(self): self.client.login() try: sock = self.client.sock.unwrap() except socket.error: err = sys.exc_info()[1] if err.errno == 0: return raise sock.settimeout(TIMEOUT) sock.sendall(b('noop')) try: chunk = sock.recv(1024) except socket.error: pass else: self.assertEqual(chunk, b(""))
def main(): # get a hash digest from a clear-text password hash = md5(b('12345')).hexdigest() authorizer = DummyMD5Authorizer() authorizer.add_user('user', hash, os.getcwd(), perm='elradfmw') authorizer.add_anonymous(os.getcwd()) handler = ftpserver.FTPHandler handler.authorizer = authorizer ftpd = ftpserver.FTPServer(('', 21), handler) ftpd.serve_forever()
def validate_authentication(self, username, password): hash = md5(b(password)).hexdigest() return self.user_table[username]['pwd'] == hash
def _do_ssl_shutdown(self): """Executes a SSL_shutdown() call to revert the connection back to clear-text. twisted/internet/tcp.py code has been used as an example. """ self._ssl_closing = True # since SSL_shutdown() doesn't report errors, an empty # write call is done first, to try to detect if the # connection has gone away try: os.write(self.socket.fileno(), b('')) except (OSError, socket.error): err = sys.exc_info()[1] if err.args[0] in (errno.EINTR, errno.EWOULDBLOCK, errno.ENOBUFS): return elif err.args[0] in _DISCONNECTED: return super(SSLConnection, self).close() else: raise # Ok, this a mess, but the underlying OpenSSL API simply # *SUCKS* and I really couldn't do any better. # # Here we just want to shutdown() the SSL layer and then # close() the connection so we're not interested in a # complete SSL shutdown() handshake, so let's pretend # we already received a "RECEIVED" shutdown notification # from the client. # Once the client received our "SENT" shutdown notification # then we close() the connection. # # Since it is not clear what errors to expect during the # entire procedure we catch them all and assume the # following: # - WantReadError and WantWriteError means "retry" # - ZeroReturnError, SysCallError[EOF], Error[] are all # aliases for disconnection try: laststate = self.socket.get_shutdown() self.socket.set_shutdown(laststate | SSL.RECEIVED_SHUTDOWN) done = self.socket.shutdown() if not (laststate & SSL.RECEIVED_SHUTDOWN): self.socket.set_shutdown(SSL.SENT_SHUTDOWN) except (SSL.WantReadError, SSL.WantWriteError): pass except SSL.ZeroReturnError: super(SSLConnection, self).close() except SSL.SysCallError: err = sys.exc_info()[1] errnum, errstr = err.args if errnum in _DISCONNECTED or errstr == 'Unexpected EOF': super(SSLConnection, self).close() else: raise except SSL.Error: # see: # http://code.google.com/p/pyftpdlib/issues/detail?id=171 # https://bugs.launchpad.net/pyopenssl/+bug/785985 err = sys.exc_info()[1] if err.args and not err.args[0]: pass else: raise except socket.error: err = sys.exc_info()[1] if err.args[0] in _DISCONNECTED: super(SSLConnection, self).close() else: raise else: if done: self._ssl_established = False self._ssl_closing = False self.handle_ssl_shutdown()