def lucidTag(request): """ Create login/logout link example: {% lucidTag auth %} """ context = { "honypot_url": "#top" # Don't use honypot } if request.user.is_authenticated(): template_name = "auth/logout_link.html" if hasattr(request.PYLUCID, "pagetree"): # We are on a normal cms page -> Dont's change the url url = "" else: # We are in the django admin panel -> Go to root page url = "/" url += "?auth=logout" else: template_name = "auth/login_link.html" url = "?auth=login" pref_form = AuthPreferencesForm() preferences = pref_form.get_preferences() use_honypot = preferences["use_honypot"] if use_honypot: try: # Use the first PluginPage instance honypot_url = PluginPage.objects.reverse("auth", 'Auth-login_honeypot') except urlresolvers.NoReverseMatch, err: if settings.RUN_WITH_DEV_SERVER: print "*** Can't get 'Auth-login_honeypot' url: %s" % err else: context["honypot_url"] = honypot_url
def test_https_login_link(self): pref_form = AuthPreferencesForm() pref_form["https_urls"] = True pref_form.save() pref_form = AuthPreferencesForm() preferences = pref_form.get_preferences() self.assertTrue(preferences["https_urls"]) response = self.client.get("/en/welcome/") self.assertDOM(response, must_contain=( '''<a href="#top" id="login_link" rel="nofollow" onclick="window.location.href = 'https://testserver/en/welcome/?auth=login'; return false;">Log in</a>''', ) )
def _wrong_login(request, debug_msg, user=None): """ username or password is wrong. """ if settings.DEBUG: error_msg = debug_msg else: error_msg = _("Wrong username/password.") # Protection against DOS attacks. pref_form = AuthPreferencesForm() preferences = pref_form.get_preferences() min_pause = preferences["min_pause"] ban_limit = preferences["ban_limit"] try: LogEntry.objects.request_limit( request, min_pause, ban_limit, app_label="pylucid_plugin.auth", action="login error", no_page_msg=True ) except LogEntry.RequestTooFast, err: # min_pause is not observed error_msg = unicode(err) # ugettext_lazy
def lucidTag(request): """ Create login/logout link example: {% lucidTag auth %} """ context = { "honypot_url": "#top" # Don't use honypot } if request.user.is_authenticated(): template_name = "auth/logout_link.html" if hasattr(request.PYLUCID, "pagetree"): # We are on a normal cms page -> Dont's change the url url = "" else: # We are in the django admin panel -> Go to root page url = "/" url += "?auth=logout" else: pref_form = AuthPreferencesForm() preferences = pref_form.get_preferences() use_honypot = preferences["use_honypot"] if use_honypot: try: # Use the first PluginPage instance honypot_url = PluginPage.objects.reverse( "auth", 'Auth-login_honeypot') except urlresolvers.NoReverseMatch, err: if settings.RUN_WITH_DEV_SERVER: print "*** Can't get 'Auth-login_honeypot' url: %s" % err else: context["honypot_url"] = honypot_url https_urls = preferences["https_urls"] if not https_urls: template_name = "auth/login_link.html" url = "" else: # Use https for login template_name = "auth/login_link_https.html" url = "https://%s%s" % (request.get_host(), request.path) url += "?auth=login"
def _wrong_login(request, debug_msg, user=None): """ username or password is wrong. """ if settings.DEBUG: error_msg = debug_msg else: error_msg = _("Wrong username/password.") # Protection against DOS attacks. pref_form = AuthPreferencesForm() preferences = pref_form.get_preferences() min_pause = preferences["min_pause"] ban_limit = preferences["ban_limit"] try: LogEntry.objects.request_limit(request, min_pause, ban_limit, app_label="pylucid_plugin.auth", action="login error", no_page_msg=True) except LogEntry.RequestTooFast, err: # min_pause is not observed error_msg = unicode(err) # ugettext_lazy
def test_https_login_link(self): pref_form = AuthPreferencesForm() pref_form["https_urls"] = True pref_form.save() pref_form = AuthPreferencesForm() preferences = pref_form.get_preferences() self.assertTrue(preferences["https_urls"]) response = self.client.get("/en/welcome/") self.assertDOM( response, must_contain= ('''<a href="#top" id="login_link" rel="nofollow" onclick="window.location.href = 'https://testserver/en/welcome/?auth=login'; return false;">Log in</a>''', ))
def test_complete_login(self): cache.clear() test_userdata = self._get_userdata("normal") userpass = test_userdata["password"] user = self._get_user("normal") username = user.username csrf_client = Client(enforce_csrf_checks=True) response = csrf_client.get("/en/welcome/") # Put page into cache self.assertStatusCode(response, 200) # Get the CSRF token response = csrf_client.get(LOGIN_URL, HTTP_X_REQUESTED_WITH='XMLHttpRequest') csrf_cookie = response.cookies[settings.CSRF_COOKIE_NAME] csrf_token = csrf_cookie.value challenge = csrf_client.session["challenge"] self.assertResponse(response, must_contain=('var challenge="%s";' % challenge), must_not_contain=("Traceback", 'Permission denied'), ) self.assertEqual(len(challenge), crypt.HASH_LEN) # Get the salt via AJAX response = csrf_client.post("/en/welcome/?auth=get_salt", HTTP_X_REQUESTED_WITH='XMLHttpRequest', HTTP_X_CSRFTOKEN=csrf_token, data={"username": username} ) salt = response.content self.assertEqual(len(salt), crypt.SALT_LEN) # Build the response: shapass = hashlib.sha1(salt + userpass).hexdigest() sha_a = shapass[:20] sha_b = shapass[20:] pref_form = AuthPreferencesForm() preferences = pref_form.get_preferences() loop_count = preferences["loop_count"] cnonce = "0123456789abcdef0123456789abcdef01234567" for i in range(loop_count): sha_a = hashlib.sha1( "%s%s%s%s" % (sha_a, i, challenge, cnonce) ).hexdigest() # Login with calculated sha pass response = csrf_client.post("/en/welcome/?auth=sha_auth", HTTP_X_REQUESTED_WITH='XMLHttpRequest', HTTP_X_CSRFTOKEN=csrf_token, data={ "username": username, "sha_a": sha_a, "sha_b": sha_b, "cnonce": cnonce, } ) self.assertStatusCode(response, 200) self.assertEqual(response.content, "OK") # Check if we are really login: response = csrf_client.get("/en/welcome/") self.assertResponse(response, must_contain=( "You are logged in. Last login was:", '<a href="?auth=logout">Log out [%s]</a>' % username ), must_not_contain=( 'Forbidden', 'CSRF verification failed.', 'CSRF cookie not set.', "Traceback", "Form errors", "field is required", ) )
def test_DOS_attack(self): settings.DEBUG = True client = self.client userdata = self._get_userdata("normal") username = userdata["username"] # self.login("normal") # client.logout() # Get the login form: The challenge value would be stored into session client.get("/en/welcome/?auth=login", HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.failUnless("challenge" in client.session) pref_form = AuthPreferencesForm() preferences = pref_form.get_preferences() ban_limit = preferences["ban_limit"] # Hold if all events would been received. tested_first_login = False tested_under_limit = False tested_limit_reached = False tested_banned = False for no in xrange(1, ban_limit + 3): # get the salt response1 = client.post( "/en/welcome/?auth=get_salt", {"username": username}, HTTP_X_REQUESTED_WITH='XMLHttpRequest' ) # every request must have a unique client-nonce cnonce = "%s0123456789abcdef0123456789abcdef01234567" % no cnonce = cnonce[:40] response2 = client.post( "/en/welcome/?auth=sha_auth", { "username": username, "sha_a": "0123456789abcdef0123456789abcdef01234567", "sha_b": "0123456789abcdef0123", "cnonce": cnonce, }, HTTP_X_REQUESTED_WITH='XMLHttpRequest' ) if no == 1: # first request, normal failed self.assertStatusCode(response1, 200) self.assertResponse(response2, must_contain=( 'auth.authenticate() failed.', 'must be a wrong password)', ), must_not_contain=( "Traceback", "Form errors", "field is required", "<!DOCTYPE", "<body", "</html>", ) ) self.assertStatusCode(response2, 200) tested_first_login = True self.failUnless(len(response1.content) == 12) # the salt elif no == ban_limit + 1: # The limit has been reached tested_banned = True self.assertResponse(response2, must_contain=('You are now banned.',)) self.assertStatusCode(response2, 404) self.failUnless(len(response1.content) == 12) # the salt elif no > ban_limit: # IP is on the ban list tested_limit_reached = True self.assertStatusCode(response1, 403) # get forbidden page self.assertStatusCode(response2, 403) # get forbidden page else: # under ban limit: comment was saved, page should be reloaded tested_under_limit = True self.assertStatusCode(response1, 200) self.assertStatusCode(response2, 200) self.failUnless(len(response1.content) == 12) # the salt self.assertResponse(response2, must_contain=( 'Request too fast!', 'IP is blocked by', ), must_not_contain=( "Traceback", "Form errors", "field is required", "<!DOCTYPE", "<body", "</html>", ) ) # Check if all events have been received. self.failUnless(tested_first_login == True) self.failUnless(tested_limit_reached == True) self.failUnless(tested_under_limit == True) self.failUnless(tested_banned == True)
def _get_loop_count(): pref_form = AuthPreferencesForm() preferences = pref_form.get_preferences() loop_count = preferences["loop_count"] return loop_count
def test_complete_login(self): cache.clear() test_userdata = self._get_userdata("normal") userpass = test_userdata["password"] user = self._get_user("normal") username = user.username csrf_client = Client(enforce_csrf_checks=True) response = csrf_client.get("/en/welcome/") # Put page into cache self.assertStatusCode(response, 200) # Get the CSRF token response = csrf_client.get(LOGIN_URL, HTTP_X_REQUESTED_WITH='XMLHttpRequest') csrf_cookie = response.cookies[settings.CSRF_COOKIE_NAME] csrf_token = csrf_cookie.value challenge = csrf_client.session["challenge"] self.assertResponse( response, must_contain=('var challenge="%s";' % challenge), must_not_contain=("Traceback", 'Permission denied'), ) self.assertEqual(len(challenge), crypt.HASH_LEN) # Get the salt via AJAX response = csrf_client.post("/en/welcome/?auth=get_salt", HTTP_X_REQUESTED_WITH='XMLHttpRequest', HTTP_X_CSRFTOKEN=csrf_token, data={"username": username}) salt = response.content self.assertEqual(len(salt), crypt.SALT_LEN) # Build the response: shapass = hashlib.sha1(salt + userpass).hexdigest() sha_a = shapass[:20] sha_b = shapass[20:] pref_form = AuthPreferencesForm() preferences = pref_form.get_preferences() loop_count = preferences["loop_count"] cnonce = "0123456789abcdef0123456789abcdef01234567" for i in range(loop_count): sha_a = hashlib.sha1("%s%s%s%s" % (sha_a, i, challenge, cnonce)).hexdigest() # Login with calculated sha pass response = csrf_client.post("/en/welcome/?auth=sha_auth", HTTP_X_REQUESTED_WITH='XMLHttpRequest', HTTP_X_CSRFTOKEN=csrf_token, data={ "username": username, "sha_a": sha_a, "sha_b": sha_b, "cnonce": cnonce, }) self.assertStatusCode(response, 200) self.assertEqual(response.content, "OK") # Check if we are really login: response = csrf_client.get("/en/welcome/") self.assertResponse( response, must_contain=("You are logged in. Last login was:", '<a href="?auth=logout">Log out [%s]</a>' % username), must_not_contain=( 'Forbidden', 'CSRF verification failed.', 'CSRF cookie not set.', "Traceback", "Form errors", "field is required", ))
def test_DOS_attack(self): settings.DEBUG = True client = self.client userdata = self._get_userdata("normal") username = userdata["username"] # self.login("normal") # client.logout() # Get the login form: The challenge value would be stored into session client.get("/en/welcome/?auth=login", HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.failUnless("challenge" in client.session) pref_form = AuthPreferencesForm() preferences = pref_form.get_preferences() ban_limit = preferences["ban_limit"] # Hold if all events would been received. tested_first_login = False tested_under_limit = False tested_limit_reached = False tested_banned = False for no in xrange(1, ban_limit + 3): # get the salt response1 = client.post("/en/welcome/?auth=get_salt", {"username": username}, HTTP_X_REQUESTED_WITH='XMLHttpRequest') # every request must have a unique client-nonce cnonce = "%s0123456789abcdef0123456789abcdef01234567" % no cnonce = cnonce[:40] response2 = client.post("/en/welcome/?auth=sha_auth", { "username": username, "sha_a": "0123456789abcdef0123456789abcdef01234567", "sha_b": "0123456789abcdef0123", "cnonce": cnonce, }, HTTP_X_REQUESTED_WITH='XMLHttpRequest') if no == 1: # first request, normal failed self.assertStatusCode(response1, 200) self.assertResponse(response2, must_contain=( 'auth.authenticate() failed.', 'must be a wrong password)', ), must_not_contain=( "Traceback", "Form errors", "field is required", "<!DOCTYPE", "<body", "</html>", )) self.assertStatusCode(response2, 200) tested_first_login = True self.failUnless(len(response1.content) == 12) # the salt elif no == ban_limit + 1: # The limit has been reached tested_banned = True self.assertResponse(response2, must_contain=('You are now banned.', )) self.assertStatusCode(response2, 404) self.failUnless(len(response1.content) == 12) # the salt elif no > ban_limit: # IP is on the ban list tested_limit_reached = True self.assertStatusCode(response1, 403) # get forbidden page self.assertStatusCode(response2, 403) # get forbidden page else: # under ban limit: comment was saved, page should be reloaded tested_under_limit = True self.assertStatusCode(response1, 200) self.assertStatusCode(response2, 200) self.failUnless(len(response1.content) == 12) # the salt self.assertResponse(response2, must_contain=( 'Request too fast!', 'IP is blocked by', ), must_not_contain=( "Traceback", "Form errors", "field is required", "<!DOCTYPE", "<body", "</html>", )) # Check if all events have been received. self.failUnless(tested_first_login == True) self.failUnless(tested_limit_reached == True) self.failUnless(tested_under_limit == True) self.failUnless(tested_banned == True)