[Zope-Checkins] CVS: Zope3/lib/python/Zope/Server/SMTP - SMTPServer.py:1.1.2.3 SMTPServerChannel.py:1.1.2.4
Shane Hathaway
shane@cvs.zope.org
Wed, 10 Apr 2002 17:59:23 -0400
Update of /cvs-repository/Zope3/lib/python/Zope/Server/SMTP
In directory cvs.zope.org:/tmp/cvs-serv18340/SMTP
Modified Files:
Tag: Zope3-Server-Branch
SMTPServer.py SMTPServerChannel.py
Log Message:
- Removed AlternateSocketMapMixin. It was there to support multiple socket
maps, but if we really need multiple socket maps, it would be better to
change asyncore. Had to update a lot of __init__ methods.
- Added IUsernamePassword and IFilesystemAccess, which provide a way to
implement all kinds of authentication schemes without FTP knowing about
any of the details. Modified FTPServerChannel to work based on an
IFilesystemAccess object.
- Added detection of the ZOPE_SERVER_DEBUG env var.
- Added comments here and there.
- Fixed CRs :-)
=== Zope3/lib/python/Zope/Server/SMTP/SMTPServer.py 1.1.2.2 => 1.1.2.3 ===
-#
-# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""
-
-$Id$
-"""
-import asyncore
-from SMTPServerChannel import SMTPServerChannel
-import SMTPConfigurations
-from Zope.Server.ServerBase import ServerBase
-
-from Zope.Server.VFS.UnixFileSystem import UnixFileSystem
-from Zope.Server.Authentication.DictionaryAuthentication import \
- DictionaryAuthentication
-
-
-class SMTPServer(ServerBase):
- """Generic FTP Server"""
-
- channel_class = SMTPServerChannel
- SERVER_IDENT = 'Zope.Server.SMTPServer'
-
- storage = UnixFileSystem('/opt/ZopeMail')
- auth_source = DictionaryAuthentication({'foo': 'bar'})
- config = SMTPConfigurations
-
- def __init__(self, ip, port, maildir, auth, task_dispatcher=None,
- adj=None, start=1, hit_log=None, verbose=0, socket_map=None):
- super(SMTPServer, self).__init__(ip, port, task_dispatcher,
- adj, start, hit_log,
- verbose, socket_map)
-
- self.auth_source = auth
- self.maildir = UnixFileSystem(maildir)
-
-
-if __name__ == '__main__':
- from Zope.Server.TaskThreads import ThreadedTaskDispatcher
- td = ThreadedTaskDispatcher()
- td.setThreadCount(4)
- auth_source = DictionaryAuthentication({'foo': 'bar'})
- SMTPServer('', 25, '/var/mail', auth_source, task_dispatcher=td)
- try:
- while 1:
- asyncore.poll(5)
- print 'active channels:', SMTPServerChannel.active_channels
- except KeyboardInterrupt:
- print 'shutting down...'
- td.shutdown()
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+import asyncore
+from SMTPServerChannel import SMTPServerChannel
+import SMTPConfigurations
+from Zope.Server.ServerBase import ServerBase
+
+from Zope.Server.VFS.UnixFileSystem import UnixFileSystem
+from Zope.Server.Authentication.DictionaryAuthentication import \
+ DictionaryAuthentication
+
+
+class SMTPServer(ServerBase):
+ """Generic FTP Server"""
+
+ channel_class = SMTPServerChannel
+ SERVER_IDENT = 'Zope.Server.SMTPServer'
+
+ storage = UnixFileSystem('/opt/ZopeMail')
+ auth_source = DictionaryAuthentication({'foo': 'bar'})
+ config = SMTPConfigurations
+
+ def __init__(self, ip, port, maildir, auth, *args, **kw):
+
+ self.auth_source = auth
+ self.maildir = UnixFileSystem(maildir)
+
+ super(SMTPServer, self).__init__(ip, port, *args, **kw)
+
+if __name__ == '__main__':
+ from Zope.Server.TaskThreads import ThreadedTaskDispatcher
+ td = ThreadedTaskDispatcher()
+ td.setThreadCount(4)
+ auth_source = DictionaryAuthentication({'foo': 'bar'})
+ SMTPServer('', 25, '/var/mail', auth_source, task_dispatcher=td)
+ try:
+ while 1:
+ asyncore.poll(5)
+ print 'active channels:', SMTPServerChannel.active_channels
+ except KeyboardInterrupt:
+ print 'shutting down...'
+ td.shutdown()
=== Zope3/lib/python/Zope/Server/SMTP/SMTPServerChannel.py 1.1.2.3 => 1.1.2.4 === (718/818 lines abridged)
-#
-# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""
-
-$Id$
-"""
-
-import time
-import fnmatch
-import socket
-
-from Zope.Server.LineReceiver.LineServerChannel import LineServerChannel
-from SMTPStatusMessages import status_msgs
-
-from ISMTPCommandHandler import ISMTPCommandHandler
-
-
-class SMTPServerChannel(LineServerChannel):
- """The SMTP Server Channel represents a connection to a particular
- client. We can therefore store information here."""
-
- __implements__ = ISMTPCommandHandler
-
- # Commands that are run in a separate thread
- # thread_commands = ('cmd_mail', 'cmd_vrfy', 'cmd_data')
-
- # Define the authentication status of the channel. Note that only the
- # "special commands" can be executed without having authenticated.
- authenticated = 1
-
- # Define the reply code for an unrecognized command
- unknown_reply = 'ERR_CMD_UNKNOWN'
-
- # Define the status messages
- status_messages = status_msgs
-
- # Defines the message terminator (a string sequence that signalizes the
- # end of a message)
- message_terminator = '.\r\n'
-
[-=- -=- -=- 718 lines omitted -=- -=- -=-]
+ name = name[1:-1]
+
+ try:
+ username, domain = address.split('@')
+ except:
+ username, domain = address, ''
+
+ return '"%s" <%s@%s>' %(username, username, domain)
+
+
+ def isLocalConnection(self):
+ name = ip2hostname(self.addr[0])
+ match = fnmatch.fnmatch(name, self.server.config.LOCAL_DOMAIN_NAME)
+ return match or name == 'localhost.localdomain'
+
+
+ def isLocalAddress(self, address):
+ # clean up the address
+ if address[0] == '<' or address[-1] == '>':
+ address = address[1:-1]
+
+ # Split the address into it user and domain component
+ try:
+ username, domain = address.split('@')
+ except:
+ username, domain = address, ''
+
+ if ( self.server.auth_source.hasUser(username) and
+ (domain.lower() == self.server.server_name or domain == '') ):
+ return 1
+
+ return 0
+
+
+
+def ip2hostname(ip, default=None):
+ """Resolves an IP into a hostname"""
+ try:
+ return socket.gethostbyaddr(ip)[0]
+ except socket.herror:
+ return default
+
+
+
+def hostname2ip(hostname, default=None):
+ try:
+ return socket.gethostbyname(hostname)
+ except socket.gaierror:
+ return default
+