예제 #1
0
파일: server.py 프로젝트: bearnard/sec-wall
    def _on_xpath(self, unused_env, url_config, unused_client_cert, data):
        """ Handles the authentication based on XPath expressions.
        """
        if not data:
            return AuthResult(False, AUTH_XPATH_NO_DATA)

        request = etree.fromstring(data)

        prefix = 'xpath-'
        expressions = [url_config[header] for header in url_config if header.startswith(prefix)]

        if not expressions:

            # It's clearly an error. We've been requested to use XPath yet no
            # expressions have been defined in the config.
            raise SecWallException('No XPath expressions were found in the config')

        for expr in expressions:
            if not expr(request):
                return AuthResult(False, AUTH_XPATH_EXPR_MISMATCH)
        else:
            auth_result = AuthResult(True, '0')
            auth_result.auth_info = map(str, expressions)

            return auth_result
예제 #2
0
파일: server.py 프로젝트: bearnard/sec-wall
def on_ssl_cert(url_config, client_cert, field_prefix, needs_auth_info=True):
    """ Visit _RequestApp._on_ssl_cert method's docstring.
    """
    if client_cert:
        config_fields = {}
        for field, value in url_config.items():
            if field.startswith(field_prefix):
                config_fields[field.split(field_prefix)[1]] = value

        # There are no fields so the user just wants the connection be
        # encrypted and the client use client certificate however they're
        # not interested in the cert's fields - so as long as the CA is
        # OK (and we know it is because otherwise we wouldn't have gotten
        # so far), we let the client in.
        if not config_fields:
            return True
        else:
            subject =  client_cert.get('subject')
            if not subject:
                return AuthResult(False, AUTH_CERT_NO_SUBJECT)

            cert_fields = dict((elem[0][0].encode('utf-8'), elem[0][1].encode('utf-8')) for elem in subject)
            
            for config_field, config_value in config_fields.items():
                cert_value = cert_fields.get(config_field)
                if not cert_value:
                    return AuthResult(False, AUTH_CERT_NO_VALUE)
                if cert_value != config_value:
                    return AuthResult(False, AUTH_CERT_VALUE_MISMATCH)
            else:
                auth_result = AuthResult(True, '0')
                if needs_auth_info:
                    auth_result.auth_info = dict((quote_plus(k), quote_plus(v)) for k, v in cert_fields.iteritems())

                return auth_result
예제 #3
0
파일: server.py 프로젝트: bearnard/sec-wall
    def _on_custom_http(self, env, url_config, *ignored):
        """ Handles the authentication based on custom HTTP headers.
        """
        prefix = 'custom-http-'

        expected_headers = {}
        expected_headers_keys = (header for header in url_config if header.startswith(prefix))

        for key in expected_headers_keys:
            # This set of operations (.split, .upper, .replace) could be done once
            # when the config's read, well, it's a room for improvement.
            expected_headers[str(key)] = str(env.get('HTTP_' + key.split(prefix)[1].upper().replace('-', '_'), ''))

        if not expected_headers:

            # It's clearly an error. We've been requested to use custom HTTP
            # headers but none are in the config.
            raise SecWallException('No custom HTTP headers were found in the config')

        for key, value in expected_headers.iteritems():
            if not value:
                return AuthResult(False, AUTH_CUSTOM_HTTP_NO_HEADER)

            if value != url_config[key]:
                return AuthResult(False, AUTH_CUSTOM_HTTP_HEADER_MISMATCH)
        else:
            auth_result = AuthResult(True, '0')
            auth_result.auth_info = expected_headers

            return auth_result
예제 #4
0
    def _on_custom_http(self, env, url_config, *ignored):
        """ Handles the authentication based on custom HTTP headers.
        """
        prefix = 'custom-http-'

        expected_headers = {}
        expected_headers_keys = (header for header in url_config if header.startswith(prefix))

        for key in expected_headers_keys:
            # This set of operations (.split, .upper, .replace) could be done once
            # when the config's read, well, it's a room for improvement.
            expected_headers[str(key)] = str(env.get('HTTP_' + key.split(prefix)[1].upper().replace('-', '_'), ''))

        if not expected_headers:

            # It's clearly an error. We've been requested to use custom HTTP
            # headers but none are in the config.
            raise SecWallException('No custom HTTP headers were found in the config')

        for key, value in expected_headers.iteritems():
            if not value:
                return AuthResult(False, AUTH_CUSTOM_HTTP_NO_HEADER)

            if value != url_config[key]:
                return AuthResult(False, AUTH_CUSTOM_HTTP_HEADER_MISMATCH)
        else:
            auth_result = AuthResult(True, '0')
            auth_result.auth_info = expected_headers

            return auth_result
예제 #5
0
    def _on_xpath(self, unused_env, url_config, unused_client_cert, data):
        """ Handles the authentication based on XPath expressions.
        """
        if not data:
            return AuthResult(False, AUTH_XPATH_NO_DATA)

        request = etree.fromstring(data)

        prefix = 'xpath-'
        expressions = [url_config[header] for header in url_config if header.startswith(prefix)]

        if not expressions:

            # It's clearly an error. We've been requested to use XPath yet no
            # expressions have been defined in the config.
            raise SecWallException('No XPath expressions were found in the config')

        for expr in expressions:
            if not expr(request):
                return AuthResult(False, AUTH_XPATH_EXPR_MISMATCH)
        else:
            auth_result = AuthResult(True, '0')
            auth_result.auth_info = map(str, expressions)

            return auth_result
예제 #6
0
def on_ssl_cert(url_config, client_cert, field_prefix, needs_auth_info=True):
    """ Visit _RequestApp._on_ssl_cert method's docstring.
    """
    if client_cert:
        config_fields = {}
        for field, value in url_config.items():
            if field.startswith(field_prefix):
                config_fields[field.split(field_prefix)[1]] = value

        # There are no fields so the user just wants the connection be
        # encrypted and the client use client certificate however they're
        # not interested in the cert's fields - so as long as the CA is
        # OK (and we know it is because otherwise we wouldn't have gotten
        # so far), we let the client in.
        if not config_fields:
            return True
        else:
            subject =  client_cert.get('subject')
            if not subject:
                return AuthResult(False, AUTH_CERT_NO_SUBJECT)

            cert_fields = dict((elem[0][0].encode('utf-8'), elem[0][1].encode('utf-8')) for elem in subject)
            
            for config_field, config_value in config_fields.items():
                cert_value = cert_fields.get(config_field)
                if not cert_value:
                    return AuthResult(False, AUTH_CERT_NO_VALUE)
                if cert_value != config_value:
                    return AuthResult(False, AUTH_CERT_VALUE_MISMATCH)
            else:
                auth_result = AuthResult(True, '0')
                if needs_auth_info:
                    auth_result.auth_info = dict((quote_plus(k), quote_plus(v)) for k, v in cert_fields.iteritems())

                return auth_result
예제 #7
0
파일: test_core.py 프로젝트: dsuch/sec-wall
def test_auth_result_repr():
    """ Tests the AuthResult's __repr__ output.
    """
    at_pattern = '\w*'
    status, code, description = [uuid4().hex for x in range(3)]
    auth_info = {b'abc':b'def'}
    a1 = AuthResult(status, code, description)
    a1.auth_info = auth_info
    r = repr(a1)

    pattern = '<AuthResult at {0} status={1} code={2} description={3} auth_info={{abc: def}}\n>'
    pattern = pattern.format(at_pattern, status, code, description)

    regexp = re.compile(pattern)

    assert_true(regexp.match(r) is not None, (pattern, r))
예제 #8
0
파일: server.py 프로젝트: bearnard/sec-wall
def on_basic_auth(env, url_config, needs_auth_info=True):
    """ Visit _RequestApp._on_basic_auth method's docstring.
    """
    username = url_config['basic-auth-username']
    result = _on_basic_auth(env.get('HTTP_AUTHORIZATION', ''), username, url_config['basic-auth-password'])
    is_success = result is True # Yes, need to check for True
    
    auth_result = AuthResult(is_success)
        
    if is_success: 
        if needs_auth_info:
            auth_result.auth_info = {b'basic-auth-username': quote_plus(username).encode('utf-8')}
    else:
        auth_result.code = result
        
    return auth_result
예제 #9
0
def on_basic_auth(env, url_config, needs_auth_info=True):
    """ Visit _RequestApp._on_basic_auth method's docstring.
    """
    username = url_config['basic-auth-username']
    result = _on_basic_auth(env.get('HTTP_AUTHORIZATION', ''), username, url_config['basic-auth-password'])
    is_success = result is True # Yes, need to check for True
    
    auth_result = AuthResult(is_success)
        
    if is_success: 
        if needs_auth_info:
            auth_result.auth_info = {b'basic-auth-username': quote_plus(username).encode('utf-8')}
    else:
        auth_result.code = result
        
    return auth_result
예제 #10
0
def test_auth_result_repr():
    """ Tests the AuthResult's __repr__ output.
    """
    at_pattern = '\w*'
    status, code, description = [uuid4().hex for x in range(3)]
    auth_info = {b'abc': b'def'}
    a1 = AuthResult(status, code, description)
    a1.auth_info = auth_info
    r = repr(a1)

    pattern = '<AuthResult at {0} status={1} code={2} description={3} auth_info={{abc: def}}\n>'
    pattern = pattern.format(at_pattern, status, code, description)

    regexp = re.compile(pattern)

    assert_true(regexp.match(r) is not None, (pattern, r))
예제 #11
0
def on_wsse_pwd(wsse, url_config, data, needs_auth_info=True):
    """ Visit _RequestApp._on_wsse_pwd method's docstring.
    """
    if not data:
        return AuthResult(False, AUTH_WSSE_NO_DATA)

    request = etree.fromstring(data)
    try:
        ok, wsse_username = wsse.validate(request, url_config)
    except SecurityException as e:
        return AuthResult(False, AUTH_WSSE_VALIDATION_ERROR, e.description)
    else:
        auth_result = AuthResult(True, '0')
        if needs_auth_info:
            auth_result.auth_info = {b'wsse-pwd-username': str(wsse_username)}

        return auth_result
예제 #12
0
파일: server.py 프로젝트: brtsz/sec-wall
    def _on_basic_auth(self, env, url_config, *ignored):
        """ Handles HTTP Basic Authentication.
        """
        auth = env.get('HTTP_AUTHORIZATION')
        if not auth:
            return AuthResult(False, AUTH_BASIC_NO_AUTH)

        prefix = 'Basic '
        if not auth.startswith(prefix):
            return AuthResult(False, AUTH_BASIC_INVALID_PREFIX)

        _, auth = auth.split(prefix)
        auth = auth.strip().decode('base64')

        username, password = auth.split(':', 1)

        if username == url_config['basic-auth-username'] and \
           password == url_config['basic-auth-password']:
            auth_result = AuthResult(True, '0')
            auth_result.auth_info = {b'basic-auth-username': quote_plus(username)}

            return auth_result
        else:
            return AuthResult(False, AUTH_BASIC_USERNAME_OR_PASSWORD_MISMATCH)
예제 #13
0
파일: server.py 프로젝트: brtsz/sec-wall
    def _on_ssl_cert(self, env, url_config, client_cert, data):
        """ Validates the client SSL/TLS certificates, its very existence and
        the values of its fields (commonName, organizationName etc.)
        """
        if client_cert:
            field_prefix = 'ssl-cert-'
            config_fields = {}
            for field, value in url_config.items():
                if field.startswith(field_prefix):
                    config_fields[field.split(field_prefix)[1]] = value

            # There are no fields so the user just wants the connection be
            # encrypted and the client use client certificate however they're
            # not interested in the cert's fields - so as long as the CA is
            # OK (and we know it is because otherwise we wouldn't have gotten
            # so far), we let the client in.
            if not config_fields:
                return True
            else:
                subject =  client_cert.get('subject')
                if not subject:
                    return AuthResult(False, AUTH_CERT_NO_SUBJECT)

                cert_fields = dict(elem[0] for elem in subject)

                for config_field, config_value in config_fields.items():
                    cert_value = cert_fields.get(config_field)
                    if not cert_value:
                        return AuthResult(False, AUTH_CERT_NO_VALUE)
                    if cert_value != config_value:
                        return AuthResult(False, AUTH_CERT_VALUE_MISMATCH)
                else:
                    auth_result = AuthResult(True, '0')
                    auth_result.auth_info = dict((quote_plus(k), quote_plus(v)) for k, v in cert_fields.iteritems())

                    return auth_result
예제 #14
0
파일: server.py 프로젝트: bearnard/sec-wall
def on_wsse_pwd(wsse, url_config, data, needs_auth_info=True):
    """ Visit _RequestApp._on_wsse_pwd method's docstring.
    """
    if not data:
        return AuthResult(False, AUTH_WSSE_NO_DATA)

    request = etree.fromstring(data)
    try:
        ok, wsse_username = wsse.validate(request, url_config)
    except SecurityException, e:
        return AuthResult(False, AUTH_WSSE_VALIDATION_ERROR, e.description)
    else:
        auth_result = AuthResult(True, '0')
        if needs_auth_info:
            auth_result.auth_info = {b'wsse-pwd-username': str(wsse_username)}

        return auth_result
        
def _on_basic_auth(auth, expected_username, expected_password):
    """ A low-level call for checking the HTTP Basic Auth credentials.
    """
    if not auth:
        return AUTH_BASIC_NO_AUTH

    prefix = 'Basic '
    if not auth.startswith(prefix):
        return AUTH_BASIC_INVALID_PREFIX

    _, auth = auth.split(prefix)
    auth = auth.strip().decode('base64')
예제 #15
0
def on_wsse_pwd(wsse, url_config, data, needs_auth_info=True):
    """ Visit _RequestApp._on_wsse_pwd method's docstring.
    """
    if not data:
        return AuthResult(False, AUTH_WSSE_NO_DATA)

    request = etree.fromstring(data)
    try:
        ok, wsse_username = wsse.validate(request, url_config)
    except SecurityException, e:
        return AuthResult(False, AUTH_WSSE_VALIDATION_ERROR, e.description)
    else:
        auth_result = AuthResult(True, '0')
        if needs_auth_info:
            auth_result.auth_info = {b'wsse-pwd-username': str(wsse_username)}

        return auth_result
        
def _on_basic_auth(auth, expected_username, expected_password):
    """ A low-level call for checking the HTTP Basic Auth credentials.
    """
    if not auth:
        return AUTH_BASIC_NO_AUTH

    prefix = 'Basic '
    if not auth.startswith(prefix):
        return AUTH_BASIC_INVALID_PREFIX

    _, auth = auth.split(prefix)
    auth = auth.strip().decode('base64')