fixed handling of SSL errors
This commit is contained in:
parent
cbfa9d97df
commit
4504861084
|
@ -515,13 +515,12 @@ class Connection(ConnectionHandlers):
|
|||
'connection_types').split()
|
||||
else:
|
||||
self._connection_types = ['tls', 'ssl', 'plain']
|
||||
#THEHACK
|
||||
#self._connection_types = ['ssl', 'plain']
|
||||
|
||||
if self._proxy and self._proxy['type']=='bosh':
|
||||
# with BOSH, we can't do TLS negotiation with <starttls>, we do only "plain"
|
||||
# connection and TLS with handshake right after TCP connecting ("ssl")
|
||||
try: self._connection_types.remove('tls')
|
||||
try:
|
||||
self._connection_types.remove('tls')
|
||||
except ValueError: pass
|
||||
|
||||
host = self.select_next_host(self._hosts)
|
||||
|
@ -553,7 +552,12 @@ class Connection(ConnectionHandlers):
|
|||
|
||||
if self._current_type == 'ssl':
|
||||
# SSL (force TLS on different port than plain)
|
||||
port = self._current_host['ssl_port']
|
||||
# If we do TLS over BOSH, port of XMPP server should be the standard one
|
||||
# and TLS should be negotiated because immediate TLS on 5223 is deprecated
|
||||
if self._proxy and self._proxy['type']=='bosh':
|
||||
port = self._current_host['port']
|
||||
else:
|
||||
port = self._current_host['ssl_port']
|
||||
elif self._current_type == 'tls':
|
||||
# TLS - negotiate tls after XMPP stream is estabilished
|
||||
port = self._current_host['port']
|
||||
|
|
|
@ -113,9 +113,8 @@ class NonBlockingBOSH(NonBlockingTransport):
|
|||
self.disconnect()
|
||||
return
|
||||
|
||||
print 'SSSSSSSSSSEEEEEEEEEND'
|
||||
#Hack for making the non-secure warning dialog work
|
||||
if hasattr(self._owner, 'NonBlockingNonSASL') or hasattr(self._owner, 'SASL'):
|
||||
#FIXME: Hack for making the non-secure warning dialog work
|
||||
self.send_BOSH(None)
|
||||
else:
|
||||
self.http_socks[0]._plug_idle(writable=False, readable=True)
|
||||
|
@ -453,31 +452,31 @@ class AckChecker():
|
|||
|
||||
|
||||
class KeyStack():
|
||||
def __init__(self, count):
|
||||
self.count = count
|
||||
self.keys = []
|
||||
self.reset()
|
||||
def __init__(self, count):
|
||||
self.count = count
|
||||
self.keys = []
|
||||
self.reset()
|
||||
self.first_call = True
|
||||
|
||||
def reset(self):
|
||||
seed = str(get_rand_number())
|
||||
self.keys = [sha.new(seed).hexdigest()]
|
||||
for i in range(self.count-1):
|
||||
curr_seed = self.keys[i]
|
||||
self.keys.append(sha.new(curr_seed).hexdigest())
|
||||
def reset(self):
|
||||
seed = str(get_rand_number())
|
||||
self.keys = [sha.new(seed).hexdigest()]
|
||||
for i in range(self.count-1):
|
||||
curr_seed = self.keys[i]
|
||||
self.keys.append(sha.new(curr_seed).hexdigest())
|
||||
|
||||
def get(self):
|
||||
def get(self):
|
||||
if self.first_call:
|
||||
self.first_call = False
|
||||
return (None, self.keys.pop())
|
||||
|
||||
if len(self.keys)>1:
|
||||
return (self.keys.pop(), None)
|
||||
else:
|
||||
last_key = self.keys.pop()
|
||||
self.reset()
|
||||
new_key = self.keys.pop()
|
||||
return (last_key, new_key)
|
||||
if len(self.keys)>1:
|
||||
return (self.keys.pop(), None)
|
||||
else:
|
||||
last_key = self.keys.pop()
|
||||
self.reset()
|
||||
new_key = self.keys.pop()
|
||||
return (last_key, new_key)
|
||||
|
||||
# http://www.xmpp.org/extensions/xep-0124.html#errorstatus-terminal
|
||||
bosh_errors = {
|
||||
|
|
|
@ -23,7 +23,7 @@ These classes can be used for simple applications "AS IS" though.
|
|||
|
||||
import socket
|
||||
|
||||
import transports_nb, tls_nb, dispatcher_nb, auth_nb, roster_nb, protocol, bosh
|
||||
import transports_nb, dispatcher_nb, auth_nb, roster_nb, protocol, bosh
|
||||
from client import *
|
||||
|
||||
from protocol import NS_TLS
|
||||
|
@ -234,6 +234,7 @@ class NBCommonClient:
|
|||
xmlns=NS_TLS)
|
||||
self.send('<starttls xmlns="%s"/>' % NS_TLS)
|
||||
else:
|
||||
# we got <proceed> or <failure>
|
||||
if tag.getNamespace() <> NS_TLS:
|
||||
self._on_connect_failure('Unknown namespace: %s' % tag.getNamespace())
|
||||
return
|
||||
|
|
|
@ -110,9 +110,8 @@ class IdleQueue:
|
|||
if alarm_time > current_time:
|
||||
break
|
||||
if self.alarms.has_key(alarm_time):
|
||||
for cb in self.alarms[alarm_time]:
|
||||
cb()
|
||||
del(self.alarms[alarm_time])
|
||||
for cb in self.alarms[alarm_time]: cb()
|
||||
if self.alarms.has_key(alarm_time): del(self.alarms[alarm_time])
|
||||
|
||||
def plug_idle(self, obj, writable = True, readable = True):
|
||||
if obj.fd == -1:
|
||||
|
|
|
@ -20,7 +20,6 @@ I'm personally using it in many other separate projects. It is designed to be as
|
|||
import xml.parsers.expat
|
||||
import logging
|
||||
log = logging.getLogger('gajim.c.x.simplexml')
|
||||
#log.setLevel(logging.DEBUG)
|
||||
|
||||
def XMLescape(txt):
|
||||
'''Returns provided string with symbols & < > " replaced by their respective XML entities.'''
|
||||
|
|
|
@ -150,7 +150,6 @@ class PyOpenSSLWrapper(SSLWrapper):
|
|||
else: retval = self.sslobj.recv(bufsize, flags)
|
||||
except (OpenSSL.SSL.WantReadError, OpenSSL.SSL.WantWriteError), e:
|
||||
log.debug("Recv: Want-error: " + repr(e))
|
||||
pass
|
||||
except OpenSSL.SSL.SysCallError, e:
|
||||
log.debug("Recv: Got OpenSSL.SSL.SysCallError: " + repr(e), exc_info=True)
|
||||
#traceback.print_exc()
|
||||
|
@ -202,8 +201,7 @@ class StdlibSSLWrapper(SSLWrapper):
|
|||
try:
|
||||
return self.sslobj.read(bufsize)
|
||||
except socket.sslerror, e:
|
||||
#log.debug("Recv: Caught socket.sslerror:", exc_info=True)
|
||||
#traceback.print_exc()
|
||||
log.debug("Recv: Caught socket.sslerror:", exc_info=True)
|
||||
if e.args[0] not in (socket.SSL_ERROR_WANT_READ, socket.SSL_ERROR_WANT_WRITE):
|
||||
raise SSLWrapper.Error(self.sock or self.sslobj, e)
|
||||
return None
|
||||
|
@ -213,8 +211,7 @@ class StdlibSSLWrapper(SSLWrapper):
|
|||
try:
|
||||
return self.sslobj.write(data)
|
||||
except socket.sslerror, e:
|
||||
#log.debug("Send: Caught socket.sslerror:", exc_info=True)
|
||||
#traceback.print_exc()
|
||||
log.debug("Send: Caught socket.sslerror:", exc_info=True)
|
||||
if e.args[0] not in (socket.SSL_ERROR_WANT_READ, socket.SSL_ERROR_WANT_WRITE):
|
||||
raise SSLWrapper.Error(self.sock or self.sslobj, e)
|
||||
return 0
|
||||
|
@ -274,13 +271,12 @@ class NonBlockingTLS(PlugIn):
|
|||
print >> stream, "PKey type: %s (%d)" % (typedict.get(pkey.type(), "Unknown"), pkey.type())
|
||||
|
||||
def _startSSL(self):
|
||||
''' Immidiatedly switch socket to TLS mode. Used internally.'''
|
||||
''' Immediatedly switch socket to TLS mode. Used internally.'''
|
||||
log.debug("_startSSL called")
|
||||
if USE_PYOPENSSL: return self._startSSL_pyOpenSSL()
|
||||
else: return self._startSSL_stdlib()
|
||||
|
||||
def _startSSL_pyOpenSSL(self):
|
||||
#log.debug("_startSSL_pyOpenSSL called, thread id: %s", str(thread.get_ident()))
|
||||
log.debug("_startSSL_pyOpenSSL called")
|
||||
tcpsock = self._owner
|
||||
# FIXME: should method be configurable?
|
||||
|
|
|
@ -21,7 +21,7 @@ from simplexml import ustr
|
|||
from client import PlugIn
|
||||
from idlequeue import IdleObject
|
||||
from protocol import *
|
||||
from tls_nb import NonBlockingTLS
|
||||
import tls_nb
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
@ -304,7 +304,7 @@ class NonBlockingTCP(NonBlockingTransport, IdleObject):
|
|||
|
||||
def tls_init(self, on_succ, on_fail):
|
||||
cacerts, mycerts = self.certs
|
||||
result = NonBlockingTLS(cacerts, mycerts).PlugIn(self)
|
||||
result = tls_nb.NonBlockingTLS(cacerts, mycerts).PlugIn(self)
|
||||
if result: on_succ()
|
||||
else: on_fail()
|
||||
|
||||
|
@ -436,7 +436,10 @@ class NonBlockingTCP(NonBlockingTransport, IdleObject):
|
|||
|
||||
def _do_receive(self):
|
||||
''' Reads all pending incoming data. Calls owner's disconnected() method if appropriate.'''
|
||||
ERR_DISCONN = -2 # Misc error signifying that we got disconnected
|
||||
# Misc error signifying that we got disconnected
|
||||
ERR_DISCONN = -2
|
||||
# code for unknown/other errors
|
||||
ERR_OTHER = -3
|
||||
received = None
|
||||
errnum = 0
|
||||
errstr = 'No Error Set'
|
||||
|
@ -444,9 +447,13 @@ class NonBlockingTCP(NonBlockingTransport, IdleObject):
|
|||
try:
|
||||
# get as many bites, as possible, but not more than RECV_BUFSIZE
|
||||
received = self._recv(RECV_BUFSIZE)
|
||||
except (socket.error, socket.herror, socket.gaierror), (errnum, errstr):
|
||||
except socket.error, (errnum, errstr):
|
||||
# save exception number and message to errnum, errstr
|
||||
log.info("_do_receive: got %s:" % received , exc_info=True)
|
||||
except tls_nb.SSLWrapper.Error, e:
|
||||
log.info("_do_receive, caugth SSL error: got %s:" % received , exc_info=True)
|
||||
errnum = tls_nb.gattr(e, 'errno') or ERR_OTHER
|
||||
errstr = tls_nb.gattr(e, 'exc_str')
|
||||
|
||||
if received == '':
|
||||
errnum = ERR_DISCONN
|
||||
|
@ -456,25 +463,24 @@ class NonBlockingTCP(NonBlockingTransport, IdleObject):
|
|||
# ECONNRESET - connection you are trying to access has been reset by the peer
|
||||
# ENOTCONN - Transport endpoint is not connected
|
||||
# ESHUTDOWN - shutdown(2) has been called on a socket to close down the
|
||||
# sending end of the transmision, and then data was attempted to be sent
|
||||
# sending end of the transmision, and then data was attempted to be sent
|
||||
log.error("Connection to %s lost: %s %s" % ( self.server, errnum, errstr), exc_info=True)
|
||||
if hasattr(self, 'on_remote_disconnect'): self.on_remote_disconnect()
|
||||
else: self.disconnect()
|
||||
return
|
||||
|
||||
if received is None:
|
||||
# in case of SSL error - because there are two types of TLS wrappers, the TLS
|
||||
# pluging recv method returns None in case of error
|
||||
print 'SSL ERROR'
|
||||
# because there are two types of TLS wrappers, the TLS plugin recv method
|
||||
# returns None in case of error
|
||||
if errnum != 0:
|
||||
log.error("CConnection to %s lost: %s %s" % (self.server, errnum, errstr))
|
||||
self.disconnect()
|
||||
return
|
||||
received = ''
|
||||
return
|
||||
|
||||
# we have received some bytes, stop the timeout!
|
||||
self.renew_send_timeout()
|
||||
print '-->%s<--' % received
|
||||
# pass received data to owner
|
||||
if self.on_receive:
|
||||
self.raise_event(DATA_RECEIVED, received)
|
||||
|
@ -732,7 +738,7 @@ class NBHTTPProxySocket(NBProxySocket):
|
|||
return
|
||||
if len(reply) != 2:
|
||||
pass
|
||||
NonBlockingT._on_connect(self)
|
||||
NonBlockingTCP._on_connect(self)
|
||||
#self.onreceive(self._on_proxy_auth)
|
||||
|
||||
def _on_proxy_auth(self, reply):
|
||||
|
|
Loading…
Reference in New Issue