[Mailman-Developers] ssl for admin pages

Donn Cave donn at u.washington.edu
Mon Jun 9 16:55:37 EDT 2003


Quoth matze <matze at indymedia.org>:
...
| so i dived into the mailman sources and figured out a possible
| solution. it seems to me that the best way to achieve ssl connections
| for the admin is putting a condition in ScriptURL() in Utils.py.
|
| if((0 != mm_cfg.DEFAULT_ADMIN_USE_SSL) and
|    (target[0:5] == 'admin')):
|   web_page_url = replace(web_page_url, 'http:', 'https:')
|
| as you see a new paramerter DEFAULT_ADMIN_USE_SSL has been added to
| Default.py. i tested this on the lists of both projects and it's
| working fine. as i'm sure that there are more ppl out there who would
| like this feature i ask you whether you are interrested in adding it
| to the mailman distribution. i uploaded a patch for mailman 2.1 on the

We don't support passwords for admin at all, at our site, so I didn't
have exactly the same problem.  We do use cookies for authentication,
though (as does standard Mailman password authentication), and we
needed to make these ``secure'' cookies that only go to the server
via SSL.  And we need that for everyone, not only admin.

I added a parameter to ScriptURL(..., upgrade=0) and a couple of
functions to deal with the protocol part of the URL (http vs. https.)
The upgrade parameter indicates that the URL must be https.  And then
I had to change a few modules other than Utils.py - some to specify a
"true" value for upgrade, if for example the link is to an archive
page that is protected, and some to pass this upgrade parameter through
from there to ScriptURL() (GetScriptURL(), for example.)

The effect is to present either an http or an https view of the site,
depending on the preceding URL.  If you get there via https, the links
will _all_ be https, even to listinfo etc.  This gets a little complicated,
but is in my opinion better than making everything https hard coded, which
would cause problems for some people, and yet it does support an all-https
site as an option for SSL browsers.

Following is highlights of the code changes.

	Donn Cave, University Computing Services, University of Washington
	donn at u.washington.edu

===================================================================
RCS file: RCS/SecurityManager.py,v
retrieving revision 1.3
diff -c -r1.3 SecurityManager.py
*** 1.3 2003/04/28 22:50:48
--- SecurityManager.py  2003/02/21 00:18:39
***************
*** 239,244 ****
--- 239,245 ----
          # We use session cookies, so don't set `expires' or `max-age' keys.
          # Set the RFC 2109 required header.
          c[key]['version'] = 1
+         c[key]['secure'] = 'yes'
          return c

      def ZapCookie(self, authcontext, user=None):

===================================================================
RCS file: RCS/Utils.py,v
retrieving revision 1.3
diff -c -r1.3 Utils.py
*** 1.3 2003/04/28 22:50:48
--- Utils.py    2003/06/09 22:23:50
***************
*** 238,254 ****
          return [p for p in path.split('/') if p]
      return None



! def ScriptURL(target, web_page_url=None, absolute=0):
      """target - scriptname only, nothing extra
      web_page_url - the list's configvar of the same name
      absolute - a flag which if set, generates an absolute url
      """
      if web_page_url is None:
!         web_page_url = mm_cfg.DEFAULT_URL_PATTERN % get_domain()
          if web_page_url[-1] <> '/':
              web_page_url = web_page_url + '/'
      fullpath = os.environ.get('REQUEST_URI')
      if fullpath is None:
          fullpath = os.environ.get('SCRIPT_NAME', '') + \
--- 238,288 ----
          return [p for p in path.split('/') if p]
      return None

+ def CurrentHTTPProtocol(default):
+     server_port = os.environ.get('SERVER_PORT', None)
+     if server_port is None:
+         return default
+     elif server_port == '443':
+         return 'https'
+     else:
+         return 'http'
+
+ def DefaultURL(host = None):
+     protocol = CurrentHTTPProtocol('http')
+     if host is None:
+         host = mm_cfg.DEFAULT_URL_HOST
+     return mm_cfg.PROTOCOL_URL_PATTERN % (protocol, host)
+
+ def UpgradeURL(old, force):
+     if force:
+         protocol = 'https'
+     else:
+         protocol = CurrentHTTPProtocol(None)
+         if protocol is None:
+             return old
+     try:
+         oldproto, rest = old.split(':', 1)
+     except ValueError, TypeError:
+         return old
+     if protocol == 'http' or oldproto == protocol:
+         return old
+     else:
+         return protocol + ':' + rest


! def ScriptURL(target, web_page_url=None, absolute=0, upgrade=0):
      """target - scriptname only, nothing extra
      web_page_url - the list's configvar of the same name
      absolute - a flag which if set, generates an absolute url
      """
      if web_page_url is None:
!         web_page_url = DefaultURL(get_domain())
!         if upgrade:
!             web_page_url = UpgradeURL(web_page_url, upgrade)
          if web_page_url[-1] <> '/':
              web_page_url = web_page_url + '/'
+     else:
+         web_page_url = UpgradeURL(web_page_url, upgrade)
      fullpath = os.environ.get('REQUEST_URI')
      if fullpath is None:
          fullpath = os.environ.get('SCRIPT_NAME', '') + \

===================================================================
RCS file: RCS/HTMLFormatter.py,v
retrieving revision 1.3
diff -c -r1.3 HTMLFormatter.py
*** 1.3 2003/04/28 22:50:47
--- HTMLFormatter.py    2003/02/20 23:24:57
***************
*** 321,328 ****
              container.AddItem("</center>")
          return container

!     def FormatFormStart(self, name, extra='', method=None):
!         base_url = self.GetScriptURL(name)
          if extra:
              full_url = "%s/%s" % (base_url, extra)
          else:
--- 321,328 ----
              container.AddItem("</center>")
          return container

!     def FormatFormStart(self, name, extra='', method=None, upgrade=0, absolute=0):
!         base_url = self.GetScriptURL(name, upgrade=upgrade, absolute=absolute)
          if extra:
              full_url = "%s/%s" % (base_url, extra)
          else:
$ rcsdiff -c listinfo.py
===================================================================
RCS file: RCS/listinfo.py,v
retrieving revision 1.4
diff -c -r1.4 listinfo.py
*** 1.4 2003/05/28 23:18:40
--- listinfo.py 2003/05/28 23:11:45
***************
*** 276,282 ****
                                      mm_cfg.AuthListModerator,
                                      mm_cfg.AuthListAdmin,
                                      mm_cfg.AuthSiteAdmin])
!     replacements['<mm-roster-form-start>'] = mlist.FormatFormStart('roster')
      replacements['<mm-roster-option>'] = mlist.FormatRosterOptionForUser(lang, persona)
      # Options form substitutions
      replacements['<mm-options-form-start>'] = mlist.FormatFormStart('options')
--- 276,286 ----
                                      mm_cfg.AuthListModerator,
                                      mm_cfg.AuthListAdmin,
                                      mm_cfg.AuthSiteAdmin])
!     if mlist.private_roster:
!         replacements['<mm-roster-form-start>'] = mlist.FormatFormStart('roster',
!                 absolute=1, upgrade=1)
!     else:
!         replacements['<mm-roster-form-start>'] = mlist.FormatFormStart('roster')
      replacements['<mm-roster-option>'] = mlist.FormatRosterOptionForUser(lang, persona)
      # Options form substitutions
      replacements['<mm-options-form-start>'] = mlist.FormatFormStart('options')



More information about the Mailman-Developers mailing list