diff options
Diffstat (limited to 'Mailman')
-rwxr-xr-x | Mailman/Defaults.py.in | 9 | ||||
-rw-r--r-- | Mailman/Digester.py | 24 | ||||
-rw-r--r-- | Mailman/Gui/Archive.py | 14 | ||||
-rw-r--r-- | Mailman/Gui/Digest.py | 38 | ||||
-rw-r--r-- | Mailman/LockFile.py | 2 | ||||
-rw-r--r-- | Mailman/Logging/StampedLogger.py | 26 | ||||
-rw-r--r-- | Mailman/MailList.py | 2 | ||||
-rw-r--r-- | Mailman/Message.py | 2 | ||||
-rw-r--r-- | Mailman/Utils.py | 15 |
9 files changed, 73 insertions, 59 deletions
diff --git a/Mailman/Defaults.py.in b/Mailman/Defaults.py.in index 5e158e5b..fabd95bd 100755 --- a/Mailman/Defaults.py.in +++ b/Mailman/Defaults.py.in @@ -166,6 +166,15 @@ HTML_TO_PLAIN_TEXT_COMMAND = '/usr/bin/lynx -dump %(filename)s' # character that doesn't match this class. Do not include '/' in this list. ACCEPTABLE_LISTNAME_CHARACTERS = '[-+_.=a-z0-9]' +# The number of characters in the longest listname in the installation. The +# fix for LP: #1780874 truncates list names in web URLs to this length to avoid +# a content spoofing vulnerability. If this is left at its default value of +# 0, the length of the longest listname is calculated on every web access. +# This can have performance implications in installations with a very large +# number of lists. To use this feature to avoid the calculation, set this to +# a number equal to the length of the longest expected valid list name. +MAX_LISTNAME_LENGTH = 0 + # Shall the user's real names be displayed along with their email addresses # in list rosters? Defaults to No to preserve prior behavior. ROSTER_DISPLAY_REALNAME = No diff --git a/Mailman/Digester.py b/Mailman/Digester.py index 8a65043b..3dc7ce49 100644 --- a/Mailman/Digester.py +++ b/Mailman/Digester.py @@ -31,20 +31,20 @@ from Mailman.i18n import _ class Digester: def InitVars(self): - # Configurable - self.digestable = mm_cfg.DEFAULT_DIGESTABLE - self.digest_is_default = mm_cfg.DEFAULT_DIGEST_IS_DEFAULT - self.mime_is_default_digest = mm_cfg.DEFAULT_MIME_IS_DEFAULT_DIGEST - self.digest_size_threshhold = mm_cfg.DEFAULT_DIGEST_SIZE_THRESHHOLD - self.digest_send_periodic = mm_cfg.DEFAULT_DIGEST_SEND_PERIODIC - self.next_post_number = 1 - self.digest_header = mm_cfg.DEFAULT_DIGEST_HEADER - self.digest_footer = mm_cfg.DEFAULT_DIGEST_FOOTER + # Configurable + self.digestable = mm_cfg.DEFAULT_DIGESTABLE + self.digest_is_default = mm_cfg.DEFAULT_DIGEST_IS_DEFAULT + self.mime_is_default_digest = mm_cfg.DEFAULT_MIME_IS_DEFAULT_DIGEST + self.digest_size_threshhold = mm_cfg.DEFAULT_DIGEST_SIZE_THRESHHOLD + self.digest_send_periodic = mm_cfg.DEFAULT_DIGEST_SEND_PERIODIC + self.next_post_number = 1 + self.digest_header = mm_cfg.DEFAULT_DIGEST_HEADER + self.digest_footer = mm_cfg.DEFAULT_DIGEST_FOOTER self.digest_volume_frequency = mm_cfg.DEFAULT_DIGEST_VOLUME_FREQUENCY - # Non-configurable. + # Non-configurable. self.one_last_digest = {} - self.digest_members = {} - self.next_digest_number = 1 + self.digest_members = {} + self.next_digest_number = 1 self.digest_last_sent_at = 0 def send_digest_now(self): diff --git a/Mailman/Gui/Archive.py b/Mailman/Gui/Archive.py index fc313c00..8167a001 100644 --- a/Mailman/Gui/Archive.py +++ b/Mailman/Gui/Archive.py @@ -27,18 +27,18 @@ class Archive(GUIBase): def GetConfigInfo(self, mlist, category, subcat=None): if category <> 'archive': return None - return [ + return [ _("List traffic archival policies."), - ('archive', mm_cfg.Toggle, (_('No'), _('Yes')), 0, - _('Archive messages?')), + ('archive', mm_cfg.Toggle, (_('No'), _('Yes')), 0, + _('Archive messages?')), - ('archive_private', mm_cfg.Radio, (_('public'), _('private')), 0, + ('archive_private', mm_cfg.Radio, (_('public'), _('private')), 0, _('Is archive file source for public or private archival?')), - ('archive_volume_frequency', mm_cfg.Radio, + ('archive_volume_frequency', mm_cfg.Radio, (_('Yearly'), _('Monthly'), _('Quarterly'), _('Weekly'), _('Daily')), 0, - _('How often should a new archive volume be started?')), - ] + _('How often should a new archive volume be started?')), + ] diff --git a/Mailman/Gui/Digest.py b/Mailman/Gui/Digest.py index 55cee19d..9eafb1d2 100644 --- a/Mailman/Gui/Digest.py +++ b/Mailman/Gui/Digest.py @@ -40,37 +40,37 @@ class Digest(GUIBase): return None WIDTH = mm_cfg.TEXTFIELDWIDTH - info = [ + info = [ _("Batched-delivery digest characteristics."), - ('digestable', mm_cfg.Toggle, (_('No'), _('Yes')), 1, - _('Can list members choose to receive list traffic ' - 'bunched in digests?')), + ('digestable', mm_cfg.Toggle, (_('No'), _('Yes')), 1, + _('Can list members choose to receive list traffic ' + 'bunched in digests?')), - ('digest_is_default', mm_cfg.Radio, - (_('Regular'), _('Digest')), 0, - _('Which delivery mode is the default for new users?')), + ('digest_is_default', mm_cfg.Radio, + (_('Regular'), _('Digest')), 0, + _('Which delivery mode is the default for new users?')), - ('mime_is_default_digest', mm_cfg.Radio, - (_('Plain'), _('MIME')), 0, - _('When receiving digests, which format is default?')), + ('mime_is_default_digest', mm_cfg.Radio, + (_('Plain'), _('MIME')), 0, + _('When receiving digests, which format is default?')), - ('digest_size_threshhold', mm_cfg.Number, 3, 0, - _('How big in Kb should a digest be before it gets sent out?' + ('digest_size_threshhold', mm_cfg.Number, 3, 0, + _('How big in Kb should a digest be before it gets sent out?' ' 0 implies no maximum size.')), - ('digest_send_periodic', mm_cfg.Radio, (_('No'), _('Yes')), 1, - _('Should a digest be dispatched daily when the size threshold ' - "isn't reached?")), + ('digest_send_periodic', mm_cfg.Radio, (_('No'), _('Yes')), 1, + _('Should a digest be dispatched daily when the size threshold ' + "isn't reached?")), ('digest_header', mm_cfg.Text, (4, WIDTH), 0, - _('Header added to every digest'), + _('Header added to every digest'), _("Text attached (as an initial message, before the table" " of contents) to the top of digests. ") + Utils.maketext('headfoot.html', raw=1, mlist=mlist)), - ('digest_footer', mm_cfg.Text, (4, WIDTH), 0, - _('Footer added to every digest'), + ('digest_footer', mm_cfg.Text, (4, WIDTH), 0, + _('Footer added to every digest'), _("Text attached (as a final message) to the bottom of digests. ") + Utils.maketext('headfoot.html', raw=1, mlist=mlist)), @@ -89,7 +89,7 @@ class Digest(GUIBase): ('_send_digest_now', mm_cfg.Toggle, (_('No'), _('Yes')), 0, _('''Should Mailman send the next digest right now, if it is not empty?''')), - ] + ] ## if mm_cfg.OWNERS_CAN_ENABLE_PERSONALIZATION: ## info.extend([ diff --git a/Mailman/LockFile.py b/Mailman/LockFile.py index d7cd9252..45d92cd6 100644 --- a/Mailman/LockFile.py +++ b/Mailman/LockFile.py @@ -195,7 +195,7 @@ class LockFile: self.__logprefix = os.path.split(self.__lockfile)[1] # For transferring ownership across a fork. self.__owned = True - + def __repr__(self): return '<LockFile %s: %s [%s: %ssec] pid=%s>' % ( id(self), self.__lockfile, diff --git a/Mailman/Logging/StampedLogger.py b/Mailman/Logging/StampedLogger.py index 2657d7fc..5d259e38 100644 --- a/Mailman/Logging/StampedLogger.py +++ b/Mailman/Logging/StampedLogger.py @@ -42,14 +42,14 @@ class StampedLogger(Logger): """ def __init__(self, category, label=None, manual_reprime=0, nofail=1, immediate=1): - """If specified, optional label is included after timestamp. + """If specified, optional label is included after timestamp. Other options are passed to the Logger class initializer. """ - self.__label = label + self.__label = label self.__manual_reprime = manual_reprime self.__primed = 1 self.__bol = 1 - Logger.__init__(self, category, nofail, immediate) + Logger.__init__(self, category, nofail, immediate) def reprime(self): """Reset so timestamp will be included with next write.""" @@ -77,13 +77,13 @@ class StampedLogger(Logger): self.__bol = 0 def writelines(self, lines): - first = 1 - for l in lines: - if first: - self.write(l) - first = 0 - else: - if l and l[0] not in [' ', '\t', '\n']: - Logger.write(self, ' ' + l) - else: - Logger.write(self, l) + first = 1 + for l in lines: + if first: + self.write(l) + first = 0 + else: + if l and l[0] not in [' ', '\t', '\n']: + Logger.write(self, ' ' + l) + else: + Logger.write(self, l) diff --git a/Mailman/MailList.py b/Mailman/MailList.py index d74978af..f4b38b49 100644 --- a/Mailman/MailList.py +++ b/Mailman/MailList.py @@ -424,7 +424,7 @@ class MailList(HTMLFormatter, Deliverer, ListAdmin, self.dmarc_none_moderation_action = ( mm_cfg.DEFAULT_DMARC_NONE_MODERATION_ACTION) self.dmarc_moderation_notice = '' - self.dmarc_moderation_addresses = [] + self.dmarc_moderation_addresses = [] self.dmarc_wrapped_message_text = ( mm_cfg.DEFAULT_DMARC_WRAPPED_MESSAGE_TEXT) self.equivalent_domains = ( diff --git a/Mailman/Message.py b/Mailman/Message.py index 2d68fd8f..f4ca20c7 100644 --- a/Mailman/Message.py +++ b/Mailman/Message.py @@ -236,7 +236,7 @@ class Message(email.Message.Message): Mailman.Message.Generator. Operates like email.Message.Message.as_string, only - using Mailman's Message.Generator class. Only the top headers will + using Mailman's Message.Generator class. Only the top headers will get folded. """ fp = StringIO() diff --git a/Mailman/Utils.py b/Mailman/Utils.py index 605d0976..10629fc4 100644 --- a/Mailman/Utils.py +++ b/Mailman/Utils.py @@ -292,11 +292,16 @@ def GetPathPieces(envar='PATH_INFO'): remote) # Check for listname injections that won't be websafed. pieces = [p for p in path.split('/') if p] - # Get the longest listname or 20 if none. - if list_names(): - longest = max([len(x) for x in list_names()]) + # Get the longest listname or 20 if none or use MAX_LISTNAME_LENGTH if + # provided > 0. + if mm_cfg.MAX_LISTNAME_LENGTH > 0: + longest = mm_cfg.MAX_LISTNAME_LENGTH else: - longest = 20 + lst_names = list_names() + if lst_names: + longest = max([len(x) for x in lst_names]) + else: + longest = 20 if pieces and len(pieces[0]) > longest: syslog('mischief', 'Hostile listname: listname=%s: remote=%s', pieces[0], remote) @@ -1529,7 +1534,7 @@ def banned_ip(ip): ptr = ipaddress.ip_address(uip).reverse_pointer except ValueError: return False - lookup = '{0}.zen.spamhaus.org'.format('.'.join(ptr.split('.')[:-2])) + lookup = '{0}.zen.spamhaus.org'.format('.'.join(ptr.split('.')[:-2])) else: parts = ip.split('.') if len(parts) != 4: |