[Spambayes-checkins] spambayes/scripts sb_server.py,1.39,1.40
Tony Meyer
anadelonbrin at users.sourceforge.net
Mon Jan 3 07:51:46 CET 2005
Update of /cvsroot/spambayes/spambayes/scripts
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13766/scripts
Modified Files:
sb_server.py
Log Message:
Implement part of [ 753708 ] Support POP over SSL
If the use_ssl option is on (or automatic and the POP3 server port is 995) then sb_server
will try and make a SSL/TLS connection to the server, rather than a regular connection.
Note that the connection between sb_server and the mail client is *not* SSL/TLS -
I think that would mean we needed to have SSL/TLS server code, which doesn't look
easy, and isn't in the Python stdlib. That's almost certainly a local (or at least
controlled) connection, anyway, so that shouldn't matter.
This *mostly* works (with Python 2.4 or 2.3.5 - 2.3.4 has an outstanding bug)).
The remaining problem is that if the incoming data is larger than the buffer (4096)
then the final chunk isn't received until a new command is send. This screws all
sorts of things up. I can't figure out why that is though - select.select seems
to ignore the remaining bit waiting (maybe select.select works differently with SSL
sockets?). I'll have another crack at it tomorrow, unless someone else figures it
out overnight.
Index: sb_server.py
===================================================================
RCS file: /cvsroot/spambayes/spambayes/scripts/sb_server.py,v
retrieving revision 1.39
retrieving revision 1.40
diff -C2 -d -r1.39 -r1.40
*** sb_server.py 2 Jan 2005 04:56:40 -0000 1.39
--- sb_server.py 3 Jan 2005 06:51:42 -0000 1.40
***************
*** 91,96 ****
o Slightly-wordy index page; intro paragraph for each page.
! o In both stats and training results, report nham and nspam - warn if
! they're very different (for some value of 'very').
o "Links" section (on homepage?) to project homepage, mailing list,
etc.
--- 91,95 ----
o Slightly-wordy index page; intro paragraph for each page.
! o In both stats and training results, report nham and nspam.
o "Links" section (on homepage?) to project homepage, mailing list,
etc.
***************
*** 102,106 ****
o Graphs. Of something. Who cares what?
o NNTP proxy.
- o Zoe...!
"""
--- 101,104 ----
***************
*** 146,152 ****
synchronously, because that would block the process."""
! lineCallback = None
!
! def __init__(self, serverName, serverPort, lineCallback):
Dibbler.BrighterAsyncChat.__init__(self)
self.lineCallback = lineCallback
--- 144,148 ----
synchronously, because that would block the process."""
! def __init__(self, serverName, serverPort, lineCallback, ssl=False):
Dibbler.BrighterAsyncChat.__init__(self)
self.lineCallback = lineCallback
***************
*** 154,157 ****
--- 150,158 ----
self.set_terminator('\r\n')
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
+ # create_socket creates a non-blocking socket. This is fine for
+ # regular sockets, but not for ssl - if it is non-blocking then the
+ # second ssl connection will fail.
+ if ssl:
+ self.socket.setblocking(1)
try:
self.connect((serverName, serverPort))
***************
*** 162,165 ****
--- 163,203 ----
self.lineCallback('') # "The socket's been closed."
self.close()
+ else:
+ if ssl:
+ try:
+ self.ssl_socket = socket.ssl(self.socket)
+ except socket.sslerror, why:
+ if why[0] == 1: # error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol'
+ # Probably not SSL after all.
+ print >>sys.stderr, "Can't use SSL"
+ else:
+ raise
+ else:
+ self.send = self.send_ssl
+ self.recv = self.recv_ssl
+ self.socket.setblocking(0)
+ print self._fileno
+
+ def send_ssl(self, data):
+ return self.ssl_socket.write(data)
+
+ def recv_ssl(self, buffer_size):
+ try:
+ data = self.ssl_socket.read(buffer_size)
+ if not data:
+ # a closed connection is indicated by signaling
+ # a read condition, and having recv() return 0.
+ self.handle_close()
+ return ''
+ else:
+ return data
+ except socket.sslerror, why:
+ if why[0] == 6: # 'TLS/SSL connection has been closed'
+ self.handle_close()
+ return ''
+ elif why[0] == 2: # 'The operation did not complete (read)'
+ return ''
+ else:
+ raise
def collect_incoming_data(self, data):
***************
*** 173,176 ****
--- 211,218 ----
self.lineCallback('')
self.close()
+ try:
+ del self.ssl_socket, self.socket
+ except AttributeError:
+ pass
***************
*** 188,192 ****
"""
! def __init__(self, clientSocket, serverName, serverPort):
Dibbler.BrighterAsyncChat.__init__(self, clientSocket)
self.request = ''
--- 230,234 ----
"""
! def __init__(self, clientSocket, serverName, serverPort, ssl=False):
Dibbler.BrighterAsyncChat.__init__(self, clientSocket)
self.request = ''
***************
*** 207,211 ****
self.serverSocket = ServerLineReader(serverName, serverPort,
! self.onServerLine)
def onIncomingConnection(self, clientSocket):
--- 249,253 ----
self.serverSocket = ServerLineReader(serverName, serverPort,
! self.onServerLine, ssl)
def onIncomingConnection(self, clientSocket):
***************
*** 345,350 ****
"""
! def __init__(self, serverName, serverPort, proxyPort):
! proxyArgs = (serverName, serverPort)
Dibbler.Listener.__init__(self, proxyPort, BayesProxy, proxyArgs)
print 'Listener on port %s is proxying %s:%d' % \
--- 387,392 ----
"""
! def __init__(self, serverName, serverPort, proxyPort, ssl=False):
! proxyArgs = (serverName, serverPort, ssl)
Dibbler.Listener.__init__(self, proxyPort, BayesProxy, proxyArgs)
print 'Listener on port %s is proxying %s:%d' % \
***************
*** 384,389 ****
"""
! def __init__(self, clientSocket, serverName, serverPort):
! POP3ProxyBase.__init__(self, clientSocket, serverName, serverPort)
self.handlers = {'STAT': self.onStat, 'LIST': self.onList,
'RETR': self.onRetr, 'TOP': self.onTop,
--- 426,432 ----
"""
! def __init__(self, clientSocket, serverName, serverPort, ssl=False):
! POP3ProxyBase.__init__(self, clientSocket, serverName, serverPort,
! ssl)
self.handlers = {'STAT': self.onStat, 'LIST': self.onList,
'RETR': self.onRetr, 'TOP': self.onTop,
***************
*** 897,901 ****
"""Create BayesProxyListeners for all the given servers."""
for (server, serverPort), proxyPort in zip(servers, proxyPorts):
! listener = BayesProxyListener(server, serverPort, proxyPort)
proxyListeners.append(listener)
--- 940,947 ----
"""Create BayesProxyListeners for all the given servers."""
for (server, serverPort), proxyPort in zip(servers, proxyPorts):
! ssl = options["pop3proxy", "use_ssl"]
! if ssl == "automatic":
! ssl = serverPort == 995
! listener = BayesProxyListener(server, serverPort, proxyPort, ssl)
proxyListeners.append(listener)
More information about the Spambayes-checkins
mailing list