/* Copyright 2009 Justin Erenkrantz and Greg Stein
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "auth_kerb.h"

#ifdef SERF_HAVE_KERB

/*** Kerberos authentication ***/

#include <serf.h>
#include <serf_private.h>
#include <auth/auth.h>

#include <apr.h>
#include <apr_base64.h>
#include <apr_strings.h>

/** These functions implements Kerberos authentication, using GSS-API
 *  (RFC 2743). The message-exchange is documented in RFC 4559.
 *
 * Note: this implementation uses gssapi and only works on *nix.
 **/

/** TODO:
 ** - send session key directly on new connections where we already know
 **   the server requires Kerberos authn.
 ** - fix authn status, as the COMPLETE/CONTINUE status values
 **   are never used.
 ** - Add a way for serf to give detailed error information back to the
 **   application.
 ** - proxy support
 **/

/* Authentication over HTTP using Kerberos
 *
 * Kerberos involves three servers:
 * - Authentication Server (AS): verifies users during login
 * - Ticket-Granting Server (TGS): issues proof of identity tickets
 * - HTTP server (S)
 *
 * Steps:
 * 0. User logs in to the AS and receives a TGS ticket. On workstations
 * where the login program doesn't support Kerberos, the user can use
 * 'kinit'.
 *
 * 1. C  --> S:    GET
 *
 *    C <--  S:    401 Authentication Required
 *                 WWW-Authenticate: Negotiate
 *
 * -> app contacts the TGS to request a session key for the HTTP service
 *    @ target host. The returned session key is encrypted with the HTTP
 *    service's secret key, so we can safely send it to the server.
 *
 * 2. C  --> S:    GET
 *                 Authorization: Negotiate <Base64 encoded session key>
 *                 gss_api_ctx->state = gss_api_auth_in_progress;
 *
 *    C <--  S:    200 OK
 *                 WWW-Authenticate: Negotiate <Base64 encoded server
 *                                              authentication data>
 *
 * -> The server returned a key to proof itself to us. We check this key
 *    with the TGS again.
 *
 * Note: It's possible that the server returns 401 again in step 3, if the
 *       Kerberos context isn't complete yet. Some (simple) tests with
 *       mod_auth_kerb and MIT Kerberos 5 show this never happens.
 *
 * This handshake is required for every new connection. If the handshake is
 * completed successfully, all other requests on the same connection will
 * be authenticated without needing to pass the WWW-Authenticate header.
 *
 * Note: Step 1 of the handshake will only happen on the first connection, once
 * we know the server requires Kerberos authentication, the initial requests
 * on the other connections will include a session key, so we start  at
 * step 2 in the handshake.
 * ### TODO: Not implemented yet!
 */

typedef enum {
    gss_api_auth_not_started,
    gss_api_auth_in_progress,
    gss_api_auth_completed,
} gss_api_auth_state;

/* HTTP Service name, used to get the session key.  */
#define KRB_HTTP_SERVICE "HTTP"

/* Stores the context information related to Kerberos authentication. */
typedef struct
{
    apr_pool_t *pool;

    /* GSSAPI context */
    serf__kerb_context_t *gss_ctx;

    /* Current state of the authentication cycle. */
    gss_api_auth_state state;

    const char *header;
    const char *value;
} gss_authn_info_t;

/* On the initial 401 response of the server, request a session key from
   the Kerberos KDC to pass to the server, proving that we are who we
   claim to be. The session key can only be used with the HTTP service
   on the target host. */
static apr_status_t
gss_api_get_credentials(char *token, apr_size_t token_len,
                        const char *hostname,
                        const char **buf, apr_size_t *buf_len,
                        gss_authn_info_t *gss_info)
{
    serf__kerb_buffer_t input_buf;
    serf__kerb_buffer_t output_buf;
    apr_status_t status = APR_SUCCESS;

    /* If the server sent us a token, pass it to gss_init_sec_token for
       validation. */
    if (token) {
        input_buf.value = token;
        input_buf.length = token_len;
    } else {
        input_buf.value = 0;
        input_buf.length = 0;
    }

    /* Establish a security context to the server. */
    status = serf__kerb_init_sec_context
        (gss_info->gss_ctx,
         KRB_HTTP_SERVICE, hostname,
         &input_buf,
         &output_buf,
         gss_info->pool,
         gss_info->pool
        );

    switch(status) {
    case APR_SUCCESS:
        gss_info->state = gss_api_auth_completed;
        break;
    case APR_EAGAIN:
        gss_info->state = gss_api_auth_in_progress;
        status = APR_SUCCESS;
        break;
    default:
        status = SERF_ERROR_AUTHN_FAILED;
        break;
    }

    /* Return the session key to our caller. */
    *buf = output_buf.value;
    *buf_len = output_buf.length;

    return status;
}

/* Read the header sent by the server (if any), invoke the gssapi authn
   code and use the resulting Server Ticket  on the next request to the
   server. */
static apr_status_t
do_auth(int code,
        gss_authn_info_t *gss_info,
        serf_connection_t *conn,
        const char *auth_hdr,
        apr_pool_t *pool)
{
    serf_context_t *ctx = conn->ctx;
    serf__authn_info_t *authn_info = (code == 401) ? &ctx->authn_info :
        &ctx->proxy_authn_info;
    const char *tmp = NULL;
    char *token = NULL;
    apr_size_t tmp_len = 0, token_len = 0;
    const char *space = NULL;
    apr_status_t status;

    /* The server will return a token as attribute to the Negotiate key.
       Negotiate YGwGCSqGSIb3EgECAgIAb10wW6ADAgEFoQMCAQ+iTzBNoAMCARCiRgREa6mouM
       BAMFqKVdTGtfpZNXKzyw4Yo1paphJdIA3VOgncaoIlXxZLnkHiIHS2v65pVvrp
       bRIyjF8xve9HxpnNIucCY9c=

       Read this base64 value, decode it and validate it so we're sure the server
       is who we expect it to be. */
    if (auth_hdr)
        space = strchr(auth_hdr, ' ');

    if (space) {
        token = apr_palloc(pool, apr_base64_decode_len(space + 1));
        token_len = apr_base64_decode(token, space + 1);
    }

    /* We can get a whole batch of 401 responses from the server, but we should
       only start the authentication phase once, so if we started authentication
       already ignore all responses with initial Negotiate authentication header.

       Note: as we set the max. transfer rate to one message at a time until the
       authentication cycle is finished, this check shouldn't be needed. */
    if (!token && gss_info->state != gss_api_auth_not_started)
        return APR_SUCCESS;

    status = gss_api_get_credentials(token, token_len, conn->host_info.hostname,
                                     &tmp, &tmp_len,
                                     gss_info);
    if (status)
        return status;

    serf__encode_auth_header(&gss_info->value, authn_info->scheme->name,
                             tmp,
                             tmp_len,
                             pool);
    gss_info->header = (code == 401) ? "Authorization" : "Proxy-Authorization";

    /* If the handshake is finished tell serf it can send as much requests as it
       likes. */
    if (gss_info->state == gss_api_auth_completed)
        serf_connection_set_max_outstanding_requests(conn, 0);

    return APR_SUCCESS;
}

apr_status_t
serf__init_kerb(int code,
                serf_context_t *ctx,
                apr_pool_t *pool)
{
    return APR_SUCCESS;
}

/* A new connection is created to a server that's known to use
   Kerberos. */
apr_status_t
serf__init_kerb_connection(int code,
                           serf_connection_t *conn,
                           apr_pool_t *pool)
{
    gss_authn_info_t *gss_info;
    apr_status_t status;

    gss_info = apr_pcalloc(pool, sizeof(*gss_info));
    gss_info->pool = conn->pool;
    gss_info->state = gss_api_auth_not_started;
    status = serf__kerb_create_sec_context(&gss_info->gss_ctx, pool,
                                           gss_info->pool);

    if (status) {
        return status;
    }

    if (code == 401) {
        conn->authn_baton = gss_info;
    } else {
        conn->proxy_authn_baton = gss_info;
    }

    /* Make serf send the initial requests one by one */
    serf_connection_set_max_outstanding_requests(conn, 1);

    return APR_SUCCESS;
}

/* A 401 response was received, handle the authentication. */
apr_status_t
serf__handle_kerb_auth(int code,
                       serf_request_t *request,
                       serf_bucket_t *response,
                       const char *auth_hdr,
                       const char *auth_attr,
                       void *baton,
                       apr_pool_t *pool)
{
    serf_connection_t *conn = request->conn;
    gss_authn_info_t *gss_info = (code == 401) ? conn->authn_baton :
        conn->proxy_authn_baton;

    return do_auth(code,
                   gss_info,
                   request->conn,
                   auth_hdr,
                   pool);
}

/* Setup the authn headers on this request message. */
apr_status_t
serf__setup_request_kerb_auth(int code,
                              serf_connection_t *conn,
                              const char *method,
                              const char *uri,
                              serf_bucket_t *hdrs_bkt)
{
    gss_authn_info_t *gss_info = (code == 401) ? conn->authn_baton :
        conn->proxy_authn_baton;

    if (gss_info && gss_info->header && gss_info->value) {
        serf_bucket_headers_setn(hdrs_bkt, gss_info->header,
                                 gss_info->value);

        /* We should send each token only once. */
        gss_info->header = NULL;
        gss_info->value = NULL;
        return APR_SUCCESS;
    }

    return SERF_ERROR_AUTHN_FAILED;
}

/* Function is called when 2xx responses are received. Normally we don't
 * have to do anything, except for the first response after the
 * authentication handshake. This specific response includes authentication
 * data which should be validated by the client (mutual authentication).
 */
apr_status_t
serf__validate_response_kerb_auth(int code,
                                    serf_connection_t *conn,
                                    serf_request_t *request,
                                    serf_bucket_t *response,
                                    apr_pool_t *pool)
{
    gss_authn_info_t *gss_info = (code == 401) ? conn->authn_baton :
        conn->proxy_authn_baton;
    serf_bucket_t *hdrs;
    const char *auth_hdr;

    hdrs = serf_bucket_response_get_headers(response);
    auth_hdr = serf_bucket_headers_get(hdrs, "WWW-Authenticate");

    if (gss_info->state != gss_api_auth_completed) {
        return do_auth(code,
                       gss_info,
                       conn,
                       auth_hdr,
                       pool);
    }

    return APR_SUCCESS;
}

#endif /* SERF_HAVE_GSSAPI */
