/* 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_spnego.h"

#ifdef SERF_HAVE_SPNEGO

/** These functions implement SPNEGO-based Kerberos and NTLM authentication,
 *  using either GSS-API (RFC 2743) or SSPI on Windows.
 *  The HTTP message exchange is documented in RFC 4559.
 **/

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

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

/** TODO:
 ** - send session key directly on new connections where we already know
 **   the server requires Kerberos authn.
 ** - Add a way for serf to give detailed error information back to the
 **   application.
 **/

/* 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 an (optional) key to proof itself to us. We check this
 *    key with the TGS again. If it checks out, we can return the response
 *    body to the application.
 *
 * Note: It's possible that the server returns 401 again in step 2, if the
 *       Kerberos context isn't complete yet. This means there is 3rd step
 *       where we'll send a request with an Authorization header to the 
 *       server. Some (simple) tests with mod_auth_kerb and MIT Kerberos 5 show
 *       this never happens.
 *
 * Depending on the type of HTTP server, this handshake is required for either
 * every new connection, or for every new request! For more info see the next
 * comment on authn_persistence_state_t.
 *
 * 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!
 */

/* Current state of the authentication of the current request. */
typedef enum {
    gss_api_auth_not_started,
    gss_api_auth_in_progress,
    gss_api_auth_completed,
} gss_api_auth_state;

/**
   authn_persistence_state_t: state that indicates if we are talking with a
   server that requires authentication only of the first request (stateful),
   or of each request (stateless).
 
   INIT: Begin state. Authenticating the first request on this connection.
   UNDECIDED: we haven't identified the server yet, assume STATEFUL for now.
     Pipeline mode disabled, requests are sent only after the response off the
     previous request arrived.
   STATELESS: we know the server requires authentication for each request.
     On all new requests add the Authorization header with an initial SPNEGO
     token (created per request).
     To keep things simple, keep the connection in one by one mode.
     (otherwise we'd have to keep a queue of gssapi context objects to match
      the Negotiate header of the response with the session initiated by the
      mathing request).
     This state is an final state.
   STATEFUL: alright, we have authenticated the connection and for the server
     that is enough. Don't add an Authorization header to new requests.
     Serf will switch to pipelined mode.
     This state is not a final state, although in practical scenario's it will
     be. When we receive a 40x response from the server switch to STATELESS
     mode.

   We start in state init for the first request until it is authenticated.

   The rest of the state machine starts with the arrival of the response to the
   second request, and then goes on with each response:

      --------
      | INIT |     C --> S:    GET request in response to 40x of the server
      --------                 add [Proxy]-Authorization header
          |
          |
    ------------
    | UNDECIDED|   C --> S:    GET request, assume stateful,
    ------------               no [Proxy]-Authorization header
          |
          |
          |------------------------------------------------
          |                                               |
          | C <-- S: 40x Authentication                   | C <-- S: 200 OK
          |          Required                             |
          |                                               |
          v                                               v
      -------------                               ------------
    ->| STATELESS |<------------------------------| STATEFUL |<--
    | -------------       C <-- S: 40x            ------------  |
  * |    |                Authentication                  |     | 200 OK
    |    /                Required                        |     |
    -----                                                 -----/

 **/
typedef enum {
    pstate_init,
    pstate_undecided,
    pstate_stateless,
    pstate_stateful,
} authn_persistence_state_t;


/* 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__spnego_context_t *gss_ctx;

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

    /* Current persistence state. */
    authn_persistence_state_t pstate;

    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__spnego_buffer_t input_buf;
    serf__spnego_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__spnego_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:
        if (output_buf.length == 0) {
            gss_info->state = gss_api_auth_completed;
        } else {
            gss_info->state = gss_api_auth_in_progress;
        }
        break;
    case APR_EAGAIN:
        gss_info->state = gss_api_auth_in_progress;
        status = APR_SUCCESS;
        break;
    default:
        return status;
    }

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

    return status;
}

/* do_auth is invoked in two situations:
   - when a response from a server is received that contains an authn header
     (either from a 40x or 2xx response)
   - when a request is prepared on a connection with stateless authentication.

   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(peer_t peer,
        int code,
        gss_authn_info_t *gss_info,
        serf_connection_t *conn,
        serf_request_t *request,
        const char *auth_hdr,
        apr_pool_t *pool)
{
    serf_context_t *ctx = conn->ctx;
    serf__authn_info_t *authn_info;
    const char *tmp = NULL;
    char *token = NULL;
    apr_size_t tmp_len = 0, token_len = 0;
    apr_status_t status;

    if (peer == HOST) {
        authn_info = serf__get_authn_info_for_server(conn);
    } else {
        authn_info = &ctx->proxy_authn_info;
    }

    /* Is this a response from a host/proxy? auth_hdr should always be set. */
    if (code && auth_hdr) {
        const char *space = NULL;
        /* The server will return a token as attribute to the Negotiate key.
           Negotiate YGwGCSqGSIb3EgECAgIAb10wW6ADAgEFoQMCAQ+iTzBNoAMCARCiRgREa6
           mouMBAMFqKVdTGtfpZNXKzyw4Yo1paphJdIA3VOgncaoIlXxZLnkHiIHS2v65pVvrp
           bRIyjF8xve9HxpnNIucCY9c=

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

        if (space) {
            token = apr_palloc(pool, apr_base64_decode_len(space + 1));
            token_len = apr_base64_decode(token, space + 1);
        }
    } else {
        /* This is a new request, not a retry in response to a 40x of the
           host/proxy. 
           Only add the Authorization header if we know the server requires
           per-request authentication (stateless). */
        if (gss_info->pstate != pstate_stateless)
            return APR_SUCCESS;
    }

    switch(gss_info->pstate) {
        case pstate_init:
            /* Nothing to do here */
            break;
        case pstate_undecided: /* Fall through */
        case pstate_stateful:
            {
                /* Switch to stateless mode, from now on handle authentication
                   of each request with a new gss context. This is easiest to
                   manage when sending requests one by one. */
                serf__log_skt(AUTH_VERBOSE, __FILE__, conn->skt,
                              "Server requires per-request SPNEGO authn, "
                              "switching to stateless mode.\n");

                gss_info->pstate = pstate_stateless;
                serf_connection_set_max_outstanding_requests(conn, 1);
                break;
            }
        case pstate_stateless:
            /* Nothing to do here */
            break;
    }

    if (request->auth_baton && !token) {
        /* We provided token with this request, but server responded with empty
           authentication header. This means server rejected our credentials.
           XXX: Probably we need separate error code for this case like
           SERF_ERROR_AUTHN_CREDS_REJECTED? */
        return SERF_ERROR_AUTHN_FAILED;
    }

    /* If the server didn't provide us with a token, start with a new initial
       step in the SPNEGO authentication. */
    if (!token) {
        serf__spnego_reset_sec_context(gss_info->gss_ctx);
        gss_info->state = gss_api_auth_not_started;
    }

    if (peer == HOST) {
        status = gss_api_get_credentials(token, token_len,
                                         conn->host_info.hostname,
                                         &tmp, &tmp_len,
                                         gss_info);
    } else {
        char *proxy_host;
        apr_getnameinfo(&proxy_host, conn->ctx->proxy_address, 0);
        status = gss_api_get_credentials(token, token_len, proxy_host,
                                         &tmp, &tmp_len,
                                         gss_info);
    }
    if (status)
        return status;

    /* On the next request, add an Authorization header. */
    if (tmp_len) {
        serf__encode_auth_header(&gss_info->value, authn_info->scheme->name,
                                 tmp,
                                 tmp_len,
                                 pool);
        gss_info->header = (peer == HOST) ?
            "Authorization" : "Proxy-Authorization";
    }

    return APR_SUCCESS;
}

apr_status_t
serf__init_spnego(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_spnego_connection(const serf__authn_scheme_t *scheme,
                             int code,
                             serf_connection_t *conn,
                             apr_pool_t *pool)
{
    gss_authn_info_t *gss_info;
    apr_status_t status;

    gss_info = apr_pcalloc(conn->pool, sizeof(*gss_info));
    gss_info->pool = conn->pool;
    gss_info->state = gss_api_auth_not_started;
    gss_info->pstate = pstate_init;
    status = serf__spnego_create_sec_context(&gss_info->gss_ctx, scheme,
                                             gss_info->pool, 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);

    serf__log_skt(AUTH_VERBOSE, __FILE__, conn->skt,
                  "Initialized Kerberos context for this connection.\n");

    return APR_SUCCESS;
}

/* A 40x response was received, handle the authentication. */
apr_status_t
serf__handle_spnego_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 == 401 ? HOST : PROXY,
                   code,
                   gss_info,
                   request->conn,
                   request,
                   auth_hdr,
                   pool);
}

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

    /* If we have an ongoing authentication handshake, the handler of the
       previous response will have created the authn headers for this request
       already. */
    if (gss_info && gss_info->header && gss_info->value) {
        serf__log_skt(AUTH_VERBOSE, __FILE__, conn->skt,
                      "Set Negotiate authn header on retried request.\n");

        serf_bucket_headers_setn(hdrs_bkt, gss_info->header,
                                 gss_info->value);

        /* Remember that we're using this request for authentication
           handshake. */
        request->auth_baton = (void*) TRUE;

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

        return APR_SUCCESS;
    }

    switch (gss_info->pstate) {
        case pstate_init:
            /* We shouldn't normally arrive here, do nothing. */
            break;
        case pstate_undecided: /* fall through */
            serf__log_skt(AUTH_VERBOSE, __FILE__, conn->skt,
                          "Assume for now that the server supports persistent "
                          "SPNEGO authentication.\n");
            /* Nothing to do here. */
            break;
        case pstate_stateful:
            serf__log_skt(AUTH_VERBOSE, __FILE__, conn->skt,
                          "SPNEGO on this connection is persistent, "
                          "don't set authn header on next request.\n");
            /* Nothing to do here. */
            break;
        case pstate_stateless:
            {
                apr_status_t status;

                /* Authentication on this connection is known to be stateless.
                   Add an initial Negotiate token for the server, to bypass the
                   40x response we know we'll otherwise receive.
                  (RFC 4559 section 4.2) */
                serf__log_skt(AUTH_VERBOSE, __FILE__, conn->skt,
                              "Add initial Negotiate header to request.\n");

                status = do_auth(peer,
                                 code,
                                 gss_info,
                                 conn,
                                 request,
                                 0l,    /* no response authn header */
                                 conn->pool);
                if (status)
                    return status;

                serf_bucket_headers_setn(hdrs_bkt, gss_info->header,
                                         gss_info->value);

                /* Remember that we're using this request for authentication
                   handshake. */
                request->auth_baton = (void*) TRUE;

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

    return APR_SUCCESS;
}

/**
 * Baton passed to the get_auth_header callback function.
 */
typedef struct {
    const char *hdr_name;
    const char *auth_name;
    const char *hdr_value;
    apr_pool_t *pool;
} get_auth_header_baton_t;

static int
get_auth_header_cb(void *baton,
                   const char *key,
                   const char *header)
{
    get_auth_header_baton_t *b = baton;

    /* We're only interested in xxxx-Authenticate headers. */
    if (strcasecmp(key, b->hdr_name) != 0)
        return 0;

    /* Check if header value starts with interesting auth name. */
    if (strncmp(header, b->auth_name, strlen(b->auth_name)) == 0) {
        /* Save interesting header value and stop iteration. */
        b->hdr_value = apr_pstrdup(b->pool,  header);
        return 1;
    }

    return 0;
}

static const char *
get_auth_header(serf_bucket_t *hdrs,
                const char *hdr_name,
                const char *auth_name,
                apr_pool_t *pool)
{
    get_auth_header_baton_t b;

    b.auth_name = hdr_name;
    b.hdr_name = auth_name;
    b.hdr_value = NULL;
    b.pool = pool;

    serf_bucket_headers_do(hdrs, get_auth_header_cb, &b);

    return b.hdr_value;
}

/* 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_spnego_auth(const serf__authn_scheme_t *scheme,
                                    peer_t peer,
                                    int code,
                                    serf_connection_t *conn,
                                    serf_request_t *request,
                                    serf_bucket_t *response,
                                    apr_pool_t *pool)
{
    gss_authn_info_t *gss_info;
    const char *auth_hdr_name;

    /* TODO: currently this function is only called when a response includes
       an Authenticate header. This header is optional. If the server does
       not provide this header on the first 2xx response, we will not promote
       the connection from undecided to stateful. This won't break anything,
       but means we stay in non-pipelining mode. */
    serf__log_skt(AUTH_VERBOSE, __FILE__, conn->skt,
                  "Validate Negotiate response header.\n");

    if (peer == HOST) {
        gss_info = conn->authn_baton;
        auth_hdr_name = "WWW-Authenticate";
    } else {
        gss_info = conn->proxy_authn_baton;
        auth_hdr_name = "Proxy-Authenticate";
    }

    if (gss_info->state != gss_api_auth_completed) {
        serf_bucket_t *hdrs;
        const char *auth_hdr_val;
        apr_status_t status;

        hdrs = serf_bucket_response_get_headers(response);
        auth_hdr_val = get_auth_header(hdrs, auth_hdr_name, scheme->name,
                                       pool);

        if (auth_hdr_val) {
            status = do_auth(peer, code, gss_info, conn, request, auth_hdr_val,
                             pool);
            if (status) {
                return status;
            }
        } else {
            /* No Authenticate headers, nothing to validate: authentication
               completed.*/
            gss_info->state = gss_api_auth_completed;

            serf__log_skt(AUTH_VERBOSE, __FILE__, conn->skt,
                          "SPNEGO handshake completed.\n");
        }
    }

    if (gss_info->state == gss_api_auth_completed) {
        switch(gss_info->pstate) {
            case pstate_init:
                /* Authentication of the first request is done. */
                gss_info->pstate = pstate_undecided;
                break;
            case pstate_undecided:
                /* The server didn't request for authentication even though
                   we didn't add an Authorization header to previous
                   request. That means it supports persistent authentication. */
                gss_info->pstate = pstate_stateful;
                serf_connection_set_max_outstanding_requests(conn, 0);
                break;
            default:
                /* Nothing to do here. */
                break;
        }
    }

    return APR_SUCCESS;
}

#endif /* SERF_HAVE_SPNEGO */
