/* 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(serf_connection_t *conn,
                        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(
         conn,
         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(conn,
                                         token, token_len,
                                         conn->host_info.hostname,
                                         &tmp, &tmp_len,
                                         gss_info);
    } else {
        char *proxy_host = conn->ctx->proxy_address->hostname;
        status = gss_api_get_credentials(conn,
                                         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)
{
    serf_context_t *ctx = conn->ctx;
    serf__authn_info_t *authn_info;
    gss_authn_info_t *gss_info = NULL;

    /* For proxy authentication, reuse the gss context for all connections. 
       For server authentication, create a new gss context per connection. */
    if (code == 401) {
        authn_info = &conn->authn_info;
    } else {
        authn_info = &ctx->proxy_authn_info;
    }
    gss_info = authn_info->baton;

    if (!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;
        }
        authn_info->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;
    serf_context_t *ctx = conn->ctx;
    gss_authn_info_t *gss_info = (code == 401) ? conn->authn_info.baton :
                                                 ctx->proxy_authn_info.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)
{
    serf_context_t *ctx = conn->ctx;
    gss_authn_info_t *gss_info = (peer == HOST) ? conn->authn_info.baton :
                                                  ctx->proxy_authn_info.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)
{
    serf_context_t *ctx = conn->ctx;
    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_info.baton;
        auth_hdr_name = "WWW-Authenticate";
    } else {
        gss_info = ctx->proxy_authn_info.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 */
