diff options
Diffstat (limited to 'auth/auth.c')
-rw-r--r-- | auth/auth.c | 61 |
1 files changed, 54 insertions, 7 deletions
diff --git a/auth/auth.c b/auth/auth.c index 13f822b..c78b519 100644 --- a/auth/auth.c +++ b/auth/auth.c @@ -22,7 +22,8 @@ #include <apr_strings.h> static apr_status_t -default_auth_response_handler(int code, +default_auth_response_handler(peer_t peer, + int code, serf_connection_t *conn, serf_request_t *request, serf_bucket_t *response, @@ -83,6 +84,16 @@ static const serf__authn_scheme_t serf_authn_schemes[] = { serf__setup_request_kerb_auth, serf__validate_response_kerb_auth, }, + { + 407, + "Negotiate", + SERF_AUTHN_NEGOTIATE, + serf__init_kerb, + serf__init_kerb_connection, + serf__handle_kerb_auth, + serf__setup_request_kerb_auth, + serf__validate_response_kerb_auth, + }, #endif /* ADD NEW AUTHENTICATION IMPLEMENTATIONS HERE (as they're written) */ @@ -163,12 +174,18 @@ static int handle_auth_header(void *baton, Note that we don't reuse the auth scheme stored in the context, as that may have changed. (ex. fallback from ntlm to basic.) */ for (scheme = serf_authn_schemes; scheme->code != 0; ++scheme) { - if (ab->code == scheme->code && - strcmp(auth_name, scheme->name) == 0 && - ctx->authn_types & scheme->type) { + if (! (ab->code == scheme->code && + ctx->authn_types & scheme->type)) + continue; + + serf__log_skt(AUTH_VERBOSE, __FILE__, conn->skt, + "Client supports: %s\n", scheme->name); + if (strcmp(auth_name, scheme->name) == 0) { serf__auth_handler_func_t handler = scheme->handle_func; apr_status_t status = 0; + serf__log_skt(AUTH_VERBOSE, __FILE__, conn->skt, + "... matched: %s\n", scheme->name); /* If this is the first time we use this scheme on this connection, make sure to initialize the authentication handler first. */ if (ab->code == 401 && ctx->authn_info.scheme != scheme) { @@ -254,6 +271,9 @@ static apr_status_t dispatch_auth(int code, if (!auth_hdr) { return SERF_ERROR_AUTHN_FAILED; } + serf__log_skt(AUTH_VERBOSE, __FILE__, request->conn->skt, + "%s authz required. Response header(s): %s\n", + code == 401 ? "Server" : "Proxy", auth_hdr); /* Iterate over all headers. Try to find a matching authentication scheme handler. @@ -274,9 +294,6 @@ static apr_status_t dispatch_auth(int code, /* No matching authentication found. */ return SERF_ERROR_AUTHN_NOT_SUPPORTED; } - } else { - /* Validate the response authn headers if needed. */ - } return APR_SUCCESS; @@ -295,6 +312,8 @@ apr_status_t serf__handle_auth_response(int *consumed_response, *consumed_response = 0; + /* TODO: the response bucket was created by the application, not at all + guaranteed that this is of type response_bucket!! */ status = serf_bucket_response_status(response, &sl); if (SERF_BUCKET_READ_ERROR(status)) { return status; @@ -342,6 +361,34 @@ apr_status_t serf__handle_auth_response(int *consumed_response, request->setup_baton); return APR_EOF; + } else { + /* Validate the response authn headers if needed. */ + serf__validate_response_func_t validate_resp; + serf_connection_t *conn = request->conn; + serf_context_t *ctx = conn->ctx; + apr_status_t resp_status = APR_SUCCESS; + + if (ctx->authn_info.scheme) { + validate_resp = ctx->authn_info.scheme->validate_response_func; + resp_status = validate_resp(HOST, sl.code, conn, request, response, + pool); + } + if (!resp_status && ctx->proxy_authn_info.scheme) { + validate_resp = ctx->proxy_authn_info.scheme->validate_response_func; + resp_status = validate_resp(PROXY, sl.code, conn, request, response, + pool); + } + if (resp_status) { + /* If there was an error in the final step of the authentication, + consider the reponse body as invalid and discard it. */ + status = discard_body(response); + *consumed_response = 1; + if (!APR_STATUS_IS_EOF(status)) { + return status; + } + /* The whole body was discarded, now return our error. */ + return resp_status; + } } return APR_SUCCESS; |