Esempio n. 1
0
 def test_is_scheme_https(self):
     """
     When called with a URL, ``is_scheme_https()`` should return
     ``True`` if the scheme is HTTPS, and ``False`` otherwise.
     """
     self.assertTrue(is_scheme_https('https://www.example.com/'))
     self.assertFalse(is_scheme_https('http://www.example.com/'))
Esempio n. 2
0
 def test_is_scheme_https(self):
     """
     When called with a URL, ``is_scheme_https()`` should return
     ``True`` if the scheme is HTTPS, and ``False`` otherwise.
     """
     self.assertTrue(is_scheme_https('https://www.example.com/'))
     self.assertFalse(is_scheme_https('http://www.example.com/'))
Esempio n. 3
0
    def validate_pgturl(self, pgturl, pgtid, pgtiou):
        """
        Verify the provided proxy callback URL. This verification process
        requires three steps:

        1. The URL scheme must be HTTPS
        2. The SSL certificate must be valid and its name must match that
           of the service
        3. The callback URL must respond with a 200 or 3xx response code

        It is not required for validation that 3xx redirects be followed.
        """
        # Ensure the scheme is HTTPS before proceeding
        if not is_scheme_https(pgturl):
            raise InternalError("Proxy callback %s is not HTTPS" % pgturl)

        # Connect to proxy callback URL, checking the SSL certificate
        pgturl = add_query_params(pgturl, {'pgtId': pgtid, 'pgtIou': pgtiou})
        try:
            verify = os.environ.get('REQUESTS_CA_BUNDLE', True)
            r = requests.get(pgturl, verify=verify)
        except (requests.exceptions.ConnectionError,
                requests.exceptions.SSLError) as e:
            raise InternalError("Proxy callback %s returned %s" % (pgturl, e))

        # Check the returned HTTP status code
        try:
            r.raise_for_status()
        except requests.exceptions.HTTPError as e:
            raise InternalError("Proxy callback %s returned %s" % (pgturl, e))
Esempio n. 4
0
    def validate_callback(self, service, pgturl, pgtid, pgtiou):
        """Verify the provided proxy callback URL."""
        if not get_config(service, 'PROXY_ALLOW'):
            raise UnauthorizedServiceProxy("%s is not authorized to use proxy authentication" % service)

        if not is_scheme_https(pgturl):
            raise InvalidProxyCallback("Proxy callback %s is not HTTPS" % pgturl)

        if not is_valid_proxy_callback(service, pgturl):
            raise InvalidProxyCallback("%s is not an authorized proxy callback URL" % pgturl)

        # Check the proxy callback URL and SSL certificate
        pgturl_params = add_query_params(pgturl, {'pgtId': pgtid, 'pgtIou': pgtiou})
        verify = os.environ.get('REQUESTS_CA_BUNDLE', True)
        try:
            r = requests.get(pgturl_params, verify=verify, timeout=3.0)
        except requests.exceptions.SSLError:
            msg = "SSL cert validation failed for proxy callback %s" % pgturl
            raise InvalidProxyCallback(msg)
        except requests.exceptions.ConnectionError:
            msg = "Error connecting to proxy callback %s" % pgturl
            raise InvalidProxyCallback(msg)
        except requests.exceptions.Timeout:
            msg = "Timeout connecting to proxy callback %s" % pgturl
            raise InvalidProxyCallback(msg)

        # Check the returned HTTP status code
        try:
            r.raise_for_status()
        except requests.exceptions.HTTPError as e:
            msg = "Proxy callback %s returned %s" % (pgturl, e)
            raise InvalidProxyCallback(msg)
Esempio n. 5
0
    def validate_callback(self, service, pgturl, pgtid, pgtiou):
        """Verify the provided proxy callback URL."""
        if not proxy_allowed(service):
            raise UnauthorizedServiceProxy("%s is not authorized to use proxy authentication" % service)

        if not is_scheme_https(pgturl):
            raise InvalidProxyCallback("Proxy callback %s is not HTTPS" % pgturl)

        if not proxy_callback_allowed(service, pgturl):
            raise InvalidProxyCallback("%s is not an authorized proxy callback URL" % pgturl)

        # Verify that the SSL certificate is valid
        verify = os.environ.get('REQUESTS_CA_BUNDLE', True)
        try:
            requests.get(pgturl, verify=verify, timeout=5)
        except requests.exceptions.SSLError:
            raise InvalidProxyCallback("SSL certificate validation failed for proxy callback %s" % pgturl)
        except requests.exceptions.RequestException as e:
            raise InvalidProxyCallback(e)

        # Callback certificate appears valid, so send the ticket strings
        pgturl = add_query_params(pgturl, {'pgtId': pgtid, 'pgtIou': pgtiou})
        try:
            response = requests.get(pgturl, verify=verify, timeout=5)
        except requests.exceptions.RequestException as e:
            raise InvalidProxyCallback(e)

        try:
            response.raise_for_status()
        except requests.exceptions.HTTPError as e:
            raise InvalidProxyCallback("Proxy callback %s returned %s" % (pgturl, e))
Esempio n. 6
0
    def validate_callback(self, service, pgturl, pgtid, pgtiou):
        """Verify the provided proxy callback URL."""
        if not proxy_allowed(service):
            raise UnauthorizedServiceProxy("%s is not authorized to use proxy authentication" % service)

        if not is_scheme_https(pgturl):
            raise InvalidProxyCallback("Proxy callback %s is not HTTPS" % pgturl)

        if not proxy_callback_allowed(service, pgturl):
            raise InvalidProxyCallback("%s is not an authorized proxy callback URL" % pgturl)

        # Verify that the SSL certificate is valid
        verify = os.environ.get('REQUESTS_CA_BUNDLE', True)
        try:
            requests.get(pgturl, verify=verify, timeout=5)
        except requests.exceptions.SSLError:
            raise InvalidProxyCallback("SSL certificate validation failed for proxy callback %s" % pgturl)
        except requests.exceptions.RequestException as e:
            raise InvalidProxyCallback(e)

        # Callback certificate appears valid, so send the ticket strings
        pgturl = add_query_params(pgturl, {'pgtId': pgtid, 'pgtIou': pgtiou})
        try:
            response = requests.get(pgturl, verify=verify, timeout=5)
        except requests.exceptions.RequestException as e:
            raise InvalidProxyCallback(e)

        try:
            response.raise_for_status()
        except requests.exceptions.HTTPError as e:
            raise InvalidProxyCallback("Proxy callback %s returned %s" % (pgturl, e))
Esempio n. 7
0
    def validate_ticket(self, ticket, service, renew=False, require_https=False):
        """
        Given a ticket string and service identifier, validate the
        corresponding ``Ticket``. If validation succeeds, return the
        ``Ticket``. If validation fails, raise an appropriate error.

        If ``renew`` is ``True``, ``ServiceTicket`` validation will
        only succeed if the ticket was issued from the presentation
        of the user's primary credentials.

        If ``require_https`` is ``True``, ``ServiceTicket`` validation
        will only succeed if the service URL scheme is HTTPS.
        """
        if not ticket:
            raise InvalidRequest("No ticket string provided")

        if not self.model.TICKET_RE.match(ticket):
            raise InvalidTicket("Ticket string %s is invalid" % ticket)

        try:
            t = self.get(ticket=ticket)
        except self.model.DoesNotExist:
            raise InvalidTicket("Ticket %s does not exist" % ticket)

        if t.is_consumed():
            raise InvalidTicket("%s %s has already been used" %
                                (t.name, ticket))
        if t.is_expired():
            raise InvalidTicket("%s %s has expired" % (t.name, ticket))

        if not service:
            raise InvalidRequest("No service identifier provided")

        if require_https and not is_scheme_https(service):
            raise InvalidService("Service %s is not HTTPS" % service)

        if not is_valid_service(service):
            raise InvalidService("Service %s is not a valid %s URL" %
                                 (service, t.name))

        try:
            if not match_service(t.service, service):
                raise InvalidService("%s %s for service %s is invalid for "
                        "service %s" % (t.name, ticket, t.service, service))
        except AttributeError:
            pass

        try:
            if renew and not t.is_primary():
                raise InvalidTicket("%s %s was not issued via primary "
                                    "credentials" % (t.name, ticket))
        except AttributeError:
            pass

        logger.debug("Validated %s %s" % (t.name, ticket))
        return t
Esempio n. 8
0
    def validate_ticket(self, ticket, service, renew=False, require_https=False):
        """
        Given a ticket string and service identifier, validate the
        corresponding ``Ticket``. If validation succeeds, return the
        ``Ticket``. If validation fails, raise an appropriate error.

        If ``renew`` is ``True``, ``ServiceTicket`` validation will
        only succeed if the ticket was issued from the presentation
        of the user's primary credentials.

        If ``require_https`` is ``True``, ``ServiceTicket`` validation
        will only succeed if the service URL scheme is HTTPS.
        """
        if not ticket:
            raise InvalidRequest("No ticket string provided")

        if not self.model.TICKET_RE.match(ticket):
            raise InvalidTicket("Ticket string %s is invalid" % ticket)

        try:
            t = self.get(ticket=ticket)
        except self.model.DoesNotExist:
            raise InvalidTicket("Ticket %s does not exist" % ticket)

        if t.is_consumed():
            raise InvalidTicket("%s %s has already been used" %
                                (t.name, ticket))
        if t.is_expired():
            raise InvalidTicket("%s %s has expired" % (t.name, ticket))

        if not service:
            raise InvalidRequest("No service identifier provided")

        if require_https and not is_scheme_https(service):
            raise InvalidService("Service %s is not HTTPS" % service)

        if not is_valid_service_url(service):
            raise InvalidService("Service %s is not a valid %s URL" %
                                 (service, t.name))

        try:
            if not same_origin(t.service, service):
                raise InvalidService("%s %s for service %s is invalid for "
                        "service %s" % (t.name, ticket, t.service, service))
        except AttributeError:
            pass

        try:
            if renew and not t.is_primary():
                raise InvalidTicket("%s %s was not issued via primary "
                                    "credentials" % (t.name, ticket))
        except AttributeError:
            pass

        logger.debug("Validated %s %s" % (t.name, ticket))
        return t
Esempio n. 9
0
    def validate_callback(self, service, pgturl, pgtid, pgtiou):
        """Verify the provided proxy callback URL."""
        if not can_proxy_authentication(service):
            raise UnauthorizedServiceProxy(
                "%s is not authorized to use proxy authentication" % service)

        if not is_scheme_https(pgturl):
            raise InvalidProxyCallback("Proxy callback %s is not HTTPS" %
                                       pgturl)

        if not is_valid_proxy_callback(service, pgturl):
            raise InvalidProxyCallback(
                "%s is not an authorized proxy callback URL" % pgturl)

        # Check the proxy callback URL and SSL certificate
        pgturl_params = add_query_params(pgturl, {
            'pgtId': pgtid,
            'pgtIou': pgtiou
        })
        verify = os.environ.get('REQUESTS_CA_BUNDLE', True)
        try:
            r = requests.get(pgturl_params, verify=verify, timeout=3.0)
        except requests.exceptions.SSLError:
            msg = "SSL cert validation failed for proxy callback %s" % pgturl
            raise InvalidProxyCallback(msg)
        except requests.exceptions.ConnectionError:
            msg = "Error connecting to proxy callback %s" % pgturl
            raise InvalidProxyCallback(msg)
        except requests.exceptions.Timeout:
            msg = "Timeout connecting to proxy callback %s" % pgturl
            raise InvalidProxyCallback(msg)

        # Check the returned HTTP status code
        try:
            r.raise_for_status()
        except requests.exceptions.HTTPError as e:
            msg = "Proxy callback %s returned %s" % (pgturl, e)
            raise InvalidProxyCallback(msg)
Esempio n. 10
0
    def validate_callback(self, url, pgtid, pgtiou):
        """
        Verify the provided proxy callback URL. This verification process
        requires three steps:

        1. The URL scheme must be HTTPS
        2. The SSL certificate must be valid and its name must match that
           of the service
        3. The callback URL must respond with a 200 or 3xx response code

        It is not required for validation that 3xx redirects be followed.
        """
        # Ensure the scheme is HTTPS before proceeding
        if not is_scheme_https(url):
            raise InvalidProxyCallback("Proxy callback %s is not HTTPS" % url)

        # Connect to proxy callback URL, checking the SSL certificate
        url_params = add_query_params(url, {'pgtId': pgtid, 'pgtIou': pgtiou})
        verify = os.environ.get('REQUESTS_CA_BUNDLE', True)
        try:
            r = requests.get(url_params, verify=verify, timeout=3.0)
        except requests.exceptions.SSLError:
            msg = "SSL cert validation failed for proxy callback %s" % url
            raise InvalidProxyCallback(msg)
        except requests.exceptions.ConnectionError:
            msg = "Error connecting to proxy callback %s" % url
            raise InvalidProxyCallback(msg)
        except requests.exceptions.Timeout:
            msg = "Timeout connecting to proxy callback %s" % url
            raise InvalidProxyCallback(msg)

        # Check the returned HTTP status code
        try:
            r.raise_for_status()
        except requests.exceptions.HTTPError as e:
            msg = "Proxy callback %s returned %s" % (url, e)
            raise InvalidProxyCallback(msg)
Esempio n. 11
0
    def validate_callback(self, url, pgtid, pgtiou):
        """
        Verify the provided proxy callback URL. This verification process
        requires three steps:

        1. The URL scheme must be HTTPS
        2. The SSL certificate must be valid and its name must match that
           of the service
        3. The callback URL must respond with a 200 or 3xx response code

        It is not required for validation that 3xx redirects be followed.
        """
        # Ensure the scheme is HTTPS before proceeding
        if not is_scheme_https(url):
            raise InvalidProxyCallback("Proxy callback %s is not HTTPS" % url)

        # Connect to proxy callback URL, checking the SSL certificate
        url_params = add_query_params(url, {'pgtId': pgtid, 'pgtIou': pgtiou})
        verify = os.environ.get('REQUESTS_CA_BUNDLE', True)
        try:
            r = requests.get(url_params, verify=verify, timeout=3.0)
        except requests.exceptions.SSLError:
            msg = "SSL cert validation failed for proxy callback %s" % url
            raise InvalidProxyCallback(msg)
        except requests.exceptions.ConnectionError:
            msg = "Error connecting to proxy callback %s" % url
            raise InvalidProxyCallback(msg)
        except requests.exceptions.Timeout:
            msg = "Timeout connecting to proxy callback %s" % url
            raise InvalidProxyCallback(msg)

        # Check the returned HTTP status code
        try:
            r.raise_for_status()
        except requests.exceptions.HTTPError as e:
            msg = "Proxy callback %s returned %s" % (url, e)
            raise InvalidProxyCallback(msg)