Permalink
Browse files

Fixed #7919 -- md5 and sha modules are deprecated since Python 2.5, u…

…se hashlib module when available. Patch from Karen Tracey.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@8193 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
1 parent 8a58f22 commit c85c8f88914cdba05813cc5768377841340bd09d @gdub gdub committed Aug 2, 2008
@@ -1,3 +1,8 @@
+import base64
+import cPickle as pickle
+import datetime
+import re
+
from django import http, template
from django.contrib.admin import ModelAdmin
from django.contrib.auth import authenticate, login
@@ -9,11 +14,7 @@
from django.utils.translation import ugettext_lazy, ugettext as _
from django.views.decorators.cache import never_cache
from django.conf import settings
-import base64
-import cPickle as pickle
-import datetime
-import md5
-import re
+from django.utils.hashcompat import md5_constructor
ERROR_MESSAGE = ugettext_lazy("Please enter a correct username and password. Note that both fields are case-sensitive.")
LOGIN_FORM_KEY = 'this_is_the_login_form'
@@ -29,14 +30,14 @@ class NotRegistered(Exception):
def _encode_post_data(post_data):
from django.conf import settings
pickled = pickle.dumps(post_data)
- pickled_md5 = md5.new(pickled + settings.SECRET_KEY).hexdigest()
+ pickled_md5 = md5_constructor(pickled + settings.SECRET_KEY).hexdigest()
return base64.encodestring(pickled + pickled_md5)
def _decode_post_data(encoded_data):
from django.conf import settings
encoded_data = base64.decodestring(encoded_data)
pickled, tamper_check = encoded_data[:-32], encoded_data[-32:]
- if md5.new(pickled + settings.SECRET_KEY).hexdigest() != tamper_check:
+ if md5_constructor(pickled + settings.SECRET_KEY).hexdigest() != tamper_check:
from django.core.exceptions import SuspiciousOperation
raise SuspiciousOperation, "User may have tampered with session cookie."
return pickle.loads(pickled)
@@ -48,10 +49,10 @@ class AdminSite(object):
register() method, and the root() method can then be used as a Django view function
that presents a full admin interface for the collection of registered models.
"""
-
+
index_template = None
login_template = None
-
+
def __init__(self):
self._registry = {} # model_class class -> admin_class instance
@@ -117,23 +118,23 @@ def has_permission(self, request):
return request.user.is_authenticated() and request.user.is_staff
def root(self, request, url):
- """
+ """
Handles main URL routing for the admin app.
`url` is the remainder of the URL -- e.g. 'comments/comment/'.
"""
if request.method == 'GET' and not request.path.endswith('/'):
return http.HttpResponseRedirect(request.path + '/')
-
+
# Figure out the admin base URL path and stash it for later use
self.root_path = re.sub(re.escape(url) + '$', '', request.path)
-
+
url = url.rstrip('/') # Trim trailing slash, if it exists.
# The 'logout' view doesn't require that the person is logged in.
if url == 'logout':
return self.logout(request)
-
+
# Check permission to continue or display login form.
if not self.has_permission(request):
return self.login(request)
@@ -154,7 +155,7 @@ def root(self, request, url):
match = USER_CHANGE_PASSWORD_URL_RE.match(url)
if match:
return self.user_change_password(request, match.group(1))
-
+
if '/' in url:
return self.model_page(request, *url.split('/', 2))
@@ -320,14 +321,14 @@ def index(self, request, extra_context=None):
# Sort the models alphabetically within each app.
for app in app_list:
app['models'].sort(lambda x, y: cmp(x['name'], y['name']))
-
+
context = {
'title': _('Site administration'),
'app_list': app_list,
'root_path': self.root_path,
}
context.update(extra_context or {})
- return render_to_response(self.index_template or 'admin/index.html', context,
+ return render_to_response(self.index_template or 'admin/index.html', context,
context_instance=template.RequestContext(request)
)
index = never_cache(index)
@@ -342,7 +343,7 @@ def display_login_form(self, request, error_message='', extra_context=None):
post_data = _encode_post_data(request.POST)
else:
post_data = _encode_post_data({})
-
+
context = {
'title': _('Log in'),
'app_path': request.path,
@@ -1,5 +1,4 @@
import base64
-import md5
import cPickle as pickle
try:
from functools import wraps
@@ -12,6 +11,7 @@
from django.contrib.auth import authenticate, login
from django.shortcuts import render_to_response
from django.utils.translation import ugettext_lazy, ugettext as _
+from django.utils.hashcompat import md5_constructor
ERROR_MESSAGE = ugettext_lazy("Please enter a correct username and password. Note that both fields are case-sensitive.")
LOGIN_FORM_KEY = 'this_is_the_login_form'
@@ -35,13 +35,13 @@ def _display_login_form(request, error_message=''):
def _encode_post_data(post_data):
pickled = pickle.dumps(post_data)
- pickled_md5 = md5.new(pickled + settings.SECRET_KEY).hexdigest()
+ pickled_md5 = md5_constructor(pickled + settings.SECRET_KEY).hexdigest()
return base64.encodestring(pickled + pickled_md5)
def _decode_post_data(encoded_data):
encoded_data = base64.decodestring(encoded_data)
pickled, tamper_check = encoded_data[:-32], encoded_data[-32:]
- if md5.new(pickled + settings.SECRET_KEY).hexdigest() != tamper_check:
+ if md5_constructor(pickled + settings.SECRET_KEY).hexdigest() != tamper_check:
from django.core.exceptions import SuspiciousOperation
raise SuspiciousOperation, "User may have tampered with session cookie."
return pickle.loads(pickled)
@@ -87,7 +87,7 @@ def _checklogin(request, *args, **kwargs):
if len(users) == 1:
message = _("Your e-mail address is not your username. Try '%s' instead.") % users[0].username
else:
- # Either we cannot find the user, or if more than 1
+ # Either we cannot find the user, or if more than 1
# we cannot guess which user is the correct one.
message = _("Usernames cannot contain the '@' character.")
return _display_login_form(request, message)
@@ -50,17 +50,17 @@ def _make_token_with_timestamp(self, user, timestamp):
# last_login will also change), we produce a hash that will be
# invalid as soon as it is used.
# We limit the hash to 20 chars to keep URL short
- import sha
- hash = sha.new(settings.SECRET_KEY + unicode(user.id) +
- user.password + unicode(user.last_login) +
- unicode(timestamp)).hexdigest()[::2]
+ from django.utils.hashcompat import sha_constructor
+ hash = sha_constructor(settings.SECRET_KEY + unicode(user.id) +
+ user.password + unicode(user.last_login) +
+ unicode(timestamp)).hexdigest()[::2]
return "%s-%s" % (ts_b36, hash)
def _num_days(self, dt):
- return (dt - date(2001,1,1)).days
+ return (dt - date(2001,1,1)).days
def _today(self):
# Used for mocking in tests
- return date.today()
+ return date.today()
default_token_generator = PasswordResetTokenGenerator()
@@ -29,8 +29,8 @@ def get_security_hash(self, options, photo_options, rating_options, target):
'pa,ra') and target (something like 'lcom.eventtimes:5157'). Used to
validate that submitted form options have not been tampered-with.
"""
- import md5
- return md5.new(options + photo_options + rating_options + target + settings.SECRET_KEY).hexdigest()
+ from django.utils.hashcompat import md5_constructor
+ return md5_constructor(options + photo_options + rating_options + target + settings.SECRET_KEY).hexdigest()
def get_rating_options(self, rating_string):
"""
@@ -2,44 +2,45 @@
Cross Site Request Forgery Middleware.
This module provides a middleware that implements protection
-against request forgeries from other sites.
-
+against request forgeries from other sites.
"""
+
+import re
+import itertools
+
from django.conf import settings
from django.http import HttpResponseForbidden
+from django.utils.hashcompat import md5_constructor
from django.utils.safestring import mark_safe
-import md5
-import re
-import itertools
_ERROR_MSG = mark_safe('<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><body><h1>403 Forbidden</h1><p>Cross Site Request Forgery detected. Request aborted.</p></body></html>')
_POST_FORM_RE = \
re.compile(r'(<form\W[^>]*\bmethod=(\'|"|)POST(\'|"|)\b[^>]*>)', re.IGNORECASE)
-
-_HTML_TYPES = ('text/html', 'application/xhtml+xml')
+
+_HTML_TYPES = ('text/html', 'application/xhtml+xml')
def _make_token(session_id):
- return md5.new(settings.SECRET_KEY + session_id).hexdigest()
+ return md5_constructor(settings.SECRET_KEY + session_id).hexdigest()
class CsrfMiddleware(object):
"""Django middleware that adds protection against Cross Site
- Request Forgeries by adding hidden form fields to POST forms and
- checking requests for the correct value.
-
- In the list of middlewares, SessionMiddleware is required, and must come
- after this middleware. CsrfMiddleWare must come after compression
+ Request Forgeries by adding hidden form fields to POST forms and
+ checking requests for the correct value.
+
+ In the list of middlewares, SessionMiddleware is required, and must come
+ after this middleware. CsrfMiddleWare must come after compression
middleware.
-
- If a session ID cookie is present, it is hashed with the SECRET_KEY
- setting to create an authentication token. This token is added to all
- outgoing POST forms and is expected on all incoming POST requests that
+
+ If a session ID cookie is present, it is hashed with the SECRET_KEY
+ setting to create an authentication token. This token is added to all
+ outgoing POST forms and is expected on all incoming POST requests that
have a session ID cookie.
-
- If you are setting cookies directly, instead of using Django's session
+
+ If you are setting cookies directly, instead of using Django's session
framework, this middleware will not work.
"""
-
+
def process_request(self, request):
if request.method == 'POST':
try:
@@ -54,10 +55,10 @@ def process_request(self, request):
request_csrf_token = request.POST['csrfmiddlewaretoken']
except KeyError:
return HttpResponseForbidden(_ERROR_MSG)
-
+
if request_csrf_token != csrf_token:
return HttpResponseForbidden(_ERROR_MSG)
-
+
return None
def process_response(self, request, response):
@@ -66,20 +67,20 @@ def process_response(self, request, response):
cookie = response.cookies[settings.SESSION_COOKIE_NAME]
csrf_token = _make_token(cookie.value)
except KeyError:
- # No outgoing cookie to set session, but
+ # No outgoing cookie to set session, but
# a session might already exist.
try:
session_id = request.COOKIES[settings.SESSION_COOKIE_NAME]
csrf_token = _make_token(session_id)
except KeyError:
# no incoming or outgoing cookie
pass
-
+
if csrf_token is not None and \
response['Content-Type'].split(';')[0] in _HTML_TYPES:
-
+
# ensure we don't add the 'id' attribute twice (HTML validity)
- idattributes = itertools.chain(("id='csrfmiddlewaretoken'",),
+ idattributes = itertools.chain(("id='csrfmiddlewaretoken'",),
itertools.repeat(''))
def add_csrf_field(match):
"""Returns the matched <form> tag plus the added <input> element"""
@@ -2,12 +2,13 @@
Formtools Preview application.
"""
+import cPickle as pickle
+
from django.conf import settings
from django.http import Http404
from django.shortcuts import render_to_response
from django.template.context import RequestContext
-import cPickle as pickle
-import md5
+from django.utils.hashcompat import md5_constructor
AUTO_ID = 'formtools_%s' # Each form here uses this as its auto_id parameter.
@@ -109,7 +110,7 @@ def security_hash(self, request, form):
# Use HIGHEST_PROTOCOL because it's the most efficient. It requires
# Python 2.3, but Django requires 2.3 anyway, so that's OK.
pickled = pickle.dumps(data, pickle.HIGHEST_PROTOCOL)
- return md5.new(pickled).hexdigest()
+ return md5_constructor(pickled).hexdigest()
def failed_hash(self, request):
"Returns an HttpResponse in the case of an invalid security hash."
@@ -4,13 +4,14 @@
stored on the server side.
"""
+import cPickle as pickle
+
from django import forms
from django.conf import settings
from django.http import Http404
from django.shortcuts import render_to_response
from django.template.context import RequestContext
-import cPickle as pickle
-import md5
+from django.utils.hashcompat import md5_constructor
class FormWizard(object):
# Dictionary of extra template context variables.
@@ -150,7 +151,7 @@ def security_hash(self, request, form):
# Use HIGHEST_PROTOCOL because it's the most efficient. It requires
# Python 2.3, but Django requires 2.3 anyway, so that's OK.
pickled = pickle.dumps(data, pickle.HIGHEST_PROTOCOL)
- return md5.new(pickled).hexdigest()
+ return md5_constructor(pickled).hexdigest()
def determine_step(self, request, *args, **kwargs):
"""
@@ -1,5 +1,4 @@
import base64
-import md5
import os
import random
import sys
@@ -12,6 +11,7 @@
from django.conf import settings
from django.core.exceptions import SuspiciousOperation
+from django.utils.hashcompat import md5_constructor
class SessionBase(object):
@@ -73,13 +73,13 @@ def delete_test_cookie(self):
def encode(self, session_dict):
"Returns the given session dictionary pickled and encoded as a string."
pickled = pickle.dumps(session_dict, pickle.HIGHEST_PROTOCOL)
- pickled_md5 = md5.new(pickled + settings.SECRET_KEY).hexdigest()
+ pickled_md5 = md5_constructor(pickled + settings.SECRET_KEY).hexdigest()
return base64.encodestring(pickled + pickled_md5)
def decode(self, session_data):
encoded_data = base64.decodestring(session_data)
pickled, tamper_check = encoded_data[:-32], encoded_data[-32:]
- if md5.new(pickled + settings.SECRET_KEY).hexdigest() != tamper_check:
+ if md5_constructor(pickled + settings.SECRET_KEY).hexdigest() != tamper_check:
raise SuspiciousOperation("User tampered with session cookie.")
try:
return pickle.loads(pickled)
@@ -117,8 +117,8 @@ def _get_new_session_key(self):
# No getpid() in Jython, for example
pid = 1
while 1:
- session_key = md5.new("%s%s%s%s" % (random.randint(0, sys.maxint - 1),
- pid, time.time(), settings.SECRET_KEY)).hexdigest()
+ session_key = md5_constructor("%s%s%s%s" % (random.randint(0, sys.maxint - 1),
+ pid, time.time(), settings.SECRET_KEY)).hexdigest()
if not self.exists(session_key):
break
return session_key
Oops, something went wrong. Retry.

0 comments on commit c85c8f8

Please sign in to comment.