summaryrefslogtreecommitdiff
path: root/auth/auth.c
diff options
context:
space:
mode:
Diffstat (limited to 'auth/auth.c')
-rw-r--r--auth/auth.c61
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;