summaryrefslogtreecommitdiff
path: root/mailman/web/Cgi/private.py
diff options
context:
space:
mode:
Diffstat (limited to 'mailman/web/Cgi/private.py')
-rw-r--r--mailman/web/Cgi/private.py190
1 files changed, 0 insertions, 190 deletions
diff --git a/mailman/web/Cgi/private.py b/mailman/web/Cgi/private.py
deleted file mode 100644
index 87cad7966..000000000
--- a/mailman/web/Cgi/private.py
+++ /dev/null
@@ -1,190 +0,0 @@
-# Copyright (C) 1998-2009 by the Free Software Foundation, Inc.
-#
-# This file is part of GNU Mailman.
-#
-# GNU Mailman is free software: you can redistribute it and/or modify it under
-# the terms of the GNU General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option)
-# any later version.
-#
-# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along with
-# GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
-
-"""Provide a password-interface wrapper around private archives."""
-
-import os
-import sys
-import cgi
-import logging
-import mimetypes
-
-from Mailman import Errors
-from Mailman import MailList
-from Mailman import Utils
-from Mailman import i18n
-from Mailman.configuration import config
-from Mailman.htmlformat import *
-
-# Set up i18n. Until we know which list is being requested, we use the
-# server's default.
-_ = i18n._
-i18n.set_language(config.DEFAULT_SERVER_LANGUAGE)
-
-SLASH = '/'
-
-log = logging.getLogger('mailman.error')
-mlog = logging.getLogger('mailman.mischief')
-
-
-
-def true_path(path):
- "Ensure that the path is safe by removing .."
- # Workaround for path traverse vulnerability. Unsuccessful attempts will
- # be logged in logs/error.
- parts = [x for x in path.split(SLASH) if x not in ('.', '..')]
- return SLASH.join(parts)[1:]
-
-
-
-def guess_type(url, strict):
- if hasattr(mimetypes, 'common_types'):
- return mimetypes.guess_type(url, strict)
- return mimetypes.guess_type(url)
-
-
-
-def main():
- doc = Document()
- doc.set_language(config.DEFAULT_SERVER_LANGUAGE)
-
- parts = Utils.GetPathPieces()
- if not parts:
- doc.SetTitle(_("Private Archive Error"))
- doc.AddItem(Header(3, _("You must specify a list.")))
- print doc.Format()
- return
-
- path = os.environ.get('PATH_INFO')
- tpath = true_path(path)
- if tpath <> path[1:]:
- msg = _('Private archive - "./" and "../" not allowed in URL.')
- doc.SetTitle(msg)
- doc.AddItem(Header(2, msg))
- print doc.Format()
- mlog.error('Private archive hostile path: %s', path)
- return
- # BAW: This needs to be converted to the Site module abstraction
- true_filename = os.path.join(
- config.PRIVATE_ARCHIVE_FILE_DIR, tpath)
-
- listname = parts[0].lower()
- mboxfile = ''
- if len(parts) > 1:
- mboxfile = parts[1]
-
- # See if it's the list's mbox file is being requested
- if listname.endswith('.mbox') and mboxfile.endswith('.mbox') and \
- listname[:-5] == mboxfile[:-5]:
- listname = listname[:-5]
- else:
- mboxfile = ''
-
- # If it's a directory, we have to append index.html in this script. We
- # must also check for a gzipped file, because the text archives are
- # usually stored in compressed form.
- if os.path.isdir(true_filename):
- true_filename = true_filename + '/index.html'
- if not os.path.exists(true_filename) and \
- os.path.exists(true_filename + '.gz'):
- true_filename = true_filename + '.gz'
-
- try:
- mlist = MailList.MailList(listname, lock=0)
- except Errors.MMListError, e:
- # Avoid cross-site scripting attacks
- safelistname = Utils.websafe(listname)
- msg = _('No such list <em>%(safelistname)s</em>')
- doc.SetTitle(_("Private Archive Error - %(msg)s"))
- doc.AddItem(Header(2, msg))
- print doc.Format()
- log.error('No such list "%s": %s\n', listname, e)
- return
-
- i18n.set_language(mlist.preferred_language)
- doc.set_language(mlist.preferred_language)
-
- cgidata = cgi.FieldStorage()
- username = cgidata.getvalue('username', '')
- password = cgidata.getvalue('password', '')
-
- is_auth = 0
- realname = mlist.real_name
- message = ''
-
- if not mlist.WebAuthenticate((config.AuthUser,
- config.AuthListModerator,
- config.AuthListAdmin,
- config.AuthSiteAdmin),
- password, username):
- if cgidata.has_key('submit'):
- # This is a re-authorization attempt
- message = Bold(FontSize('+1', _('Authorization failed.'))).Format()
- # Output the password form
- charset = Utils.GetCharSet(mlist.preferred_language)
- print 'Content-type: text/html; charset=' + charset + '\n\n'
- # Put the original full path in the authorization form, but avoid
- # trailing slash if we're not adding parts. We add it below.
- action = mlist.GetScriptURL('private')
- if parts[1:]:
- action = os.path.join(action, SLASH.join(parts[1:]))
- # If we added '/index.html' to true_filename, add a slash to the URL.
- # We need this because we no longer add the trailing slash in the
- # private.html template. It's always OK to test parts[-1] since we've
- # already verified parts[0] is listname. The basic rule is if the
- # post URL (action) is a directory, it must be slash terminated, but
- # not if it's a file. Otherwise, relative links in the target archive
- # page don't work.
- if true_filename.endswith('/index.html') and parts[-1] <> 'index.html':
- action += SLASH
- # Escape web input parameter to avoid cross-site scripting.
- print Utils.maketext(
- 'private.html',
- {'action' : Utils.websafe(action),
- 'realname': mlist.real_name,
- 'message' : message,
- }, mlist=mlist)
- return
-
- lang = mlist.getMemberLanguage(username)
- i18n.set_language(lang)
- doc.set_language(lang)
-
- # Authorization confirmed... output the desired file
- try:
- ctype, enc = guess_type(path, strict=0)
- if ctype is None:
- ctype = 'text/html'
- if mboxfile:
- f = open(os.path.join(mlist.archive_dir() + '.mbox',
- mlist.internal_name() + '.mbox'))
- ctype = 'text/plain'
- elif true_filename.endswith('.gz'):
- import gzip
- f = gzip.open(true_filename, 'r')
- else:
- f = open(true_filename, 'r')
- except IOError:
- msg = _('Private archive file not found')
- doc.SetTitle(msg)
- doc.AddItem(Header(2, msg))
- print doc.Format()
- log.error('Private archive file not found: %s', true_filename)
- else:
- print 'Content-type: %s\n' % ctype
- sys.stdout.write(f.read())
- f.close()