Exemple #1
0
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
Exemple #2
0
    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>''',
            )
        )
Exemple #3
0
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
Exemple #4
0
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"
Exemple #5
0
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
Exemple #6
0
    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>''',
             ))
Exemple #7
0
    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",
            )
        )
Exemple #8
0
    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)
Exemple #9
0
def _get_loop_count():
    pref_form = AuthPreferencesForm()
    preferences = pref_form.get_preferences()
    loop_count = preferences["loop_count"]
    return loop_count
Exemple #10
0
def _get_loop_count():
    pref_form = AuthPreferencesForm()
    preferences = pref_form.get_preferences()
    loop_count = preferences["loop_count"]
    return loop_count
Exemple #11
0
    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",
            ))
Exemple #12
0
    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)