/* ====================================================================
 *    Licensed to the Apache Software Foundation (ASF) under one
 *    or more contributor license agreements.  See the NOTICE file
 *    distributed with this work for additional information
 *    regarding copyright ownership.  The ASF licenses this file
 *    to you 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 "serf.h"
#include "serf_private.h"
#include "auth_spnego.h"

#ifdef SERF_USE_GSSAPI
#include <apr_strings.h>
#include <gssapi/gssapi.h>


/* This module can support all authentication mechanisms as provided by
   the GSS-API implementation, but for now it only supports SPNEGO for
   Negotiate.
   SPNEGO can delegate authentication to Kerberos if supported by the
   host. */

#ifndef GSS_SPNEGO_MECHANISM
static gss_OID_desc spnego_mech_oid = { 6, "\x2b\x06\x01\x05\x05\x02" };
#define GSS_SPNEGO_MECHANISM &spnego_mech_oid
#endif

struct serf__spnego_context_t
{
    /* GSSAPI context */
    gss_ctx_id_t gss_ctx;

    /* Mechanism used to authenticate. */
    gss_OID gss_mech;
};

static void
log_error(int verbose_flag, serf_config_t *config,
          serf__spnego_context_t *ctx,
          OM_uint32 err_maj_stat,
          OM_uint32 err_min_stat,
          const char *msg)
{
    OM_uint32 maj_stat, min_stat;
    gss_buffer_desc stat_buff;
    OM_uint32 msg_ctx = 0;

    if (verbose_flag) {
        maj_stat = gss_display_status(&min_stat,
                                      err_maj_stat,
                                      GSS_C_GSS_CODE,
                                      ctx->gss_mech,
                                      &msg_ctx,
                                      &stat_buff);
        if (maj_stat == GSS_S_COMPLETE ||
            maj_stat == GSS_S_FAILURE) {
            gss_release_buffer(&min_stat, &stat_buff);
            maj_stat = gss_display_status(&min_stat,
                                          err_min_stat,
                                          GSS_C_MECH_CODE,
                                          ctx->gss_mech,
                                          &msg_ctx,
                                          &stat_buff);
        }

        serf__log(verbose_flag, LOGCOMP_AUTHN, __FILE__, config,
                  "%s (%x,%d): %s\n", msg,
                  err_maj_stat, err_min_stat, stat_buff.value);
        gss_release_buffer(&min_stat, &stat_buff);
    }
}

/* Cleans the GSS context object, when the pool used to create it gets
   cleared or destroyed. */
static apr_status_t
cleanup_ctx(void *data)
{
    serf__spnego_context_t *ctx = data;

    if (ctx->gss_ctx != GSS_C_NO_CONTEXT) {
        OM_uint32 gss_min_stat, gss_maj_stat;

        gss_maj_stat = gss_delete_sec_context(&gss_min_stat, &ctx->gss_ctx,
                                              GSS_C_NO_BUFFER);
        if(GSS_ERROR(gss_maj_stat)) {
            log_error(LOGLVL_ERROR, NULL, ctx, gss_maj_stat, gss_min_stat,
                      "Error cleaning up GSS security context");
            return SERF_ERROR_AUTHN_FAILED;
        }
    }

    return APR_SUCCESS;
}

static apr_status_t
cleanup_sec_buffer(void *data)
{
    OM_uint32 min_stat;
    gss_buffer_desc *gss_buf = data;

    gss_release_buffer(&min_stat, gss_buf);

    return APR_SUCCESS;
}

apr_status_t
serf__spnego_create_sec_context(serf__spnego_context_t **ctx_p,
                                const serf__authn_scheme_t *scheme,
                                apr_pool_t *result_pool,
                                apr_pool_t *scratch_pool)
{
    serf__spnego_context_t *ctx;

    ctx = apr_pcalloc(result_pool, sizeof(*ctx));

    ctx->gss_ctx = GSS_C_NO_CONTEXT;
    ctx->gss_mech = GSS_SPNEGO_MECHANISM;

    apr_pool_cleanup_register(result_pool, ctx,
                              cleanup_ctx,
                              apr_pool_cleanup_null);

    *ctx_p = ctx;

    return APR_SUCCESS;
}

apr_status_t
serf__spnego_reset_sec_context(serf__spnego_context_t *ctx)
{
    OM_uint32 dummy_stat;

    if (ctx->gss_ctx)
        (void)gss_delete_sec_context(&dummy_stat, &ctx->gss_ctx,
                                     GSS_C_NO_BUFFER);
    ctx->gss_ctx = GSS_C_NO_CONTEXT;

    return APR_SUCCESS;
}

apr_status_t
serf__spnego_init_sec_context(serf_connection_t *conn,
                              serf__spnego_context_t *ctx,
                              const char *service,
                              const char *hostname,
                              serf__spnego_buffer_t *input_buf,
                              serf__spnego_buffer_t *output_buf,
                              apr_pool_t *result_pool,
                              apr_pool_t *scratch_pool
                              )
{
    gss_buffer_desc gss_input_buf = GSS_C_EMPTY_BUFFER;
    gss_buffer_desc *gss_output_buf_p;
    OM_uint32 gss_min_stat, gss_maj_stat;
    gss_name_t host_gss_name;
    gss_buffer_desc bufdesc;
    gss_OID dummy;        /* value unused */
    OM_uint32 dummy_stat; /* value unused */

    /* Get the name for the HTTP service at the target host. */
    /* TODO: should be shared between multiple requests. */
    bufdesc.value = apr_pstrcat(scratch_pool, service, "@", hostname, NULL);
    bufdesc.length = strlen(bufdesc.value);
    serf__log(LOGLVL_DEBUG, LOGCOMP_AUTHN, __FILE__, conn->config,
              "Get principal for %s\n", bufdesc.value);
    gss_maj_stat = gss_import_name (&gss_min_stat, &bufdesc,
                                    GSS_C_NT_HOSTBASED_SERVICE,
                                    &host_gss_name);
    if (GSS_ERROR(gss_maj_stat)) {
        log_error(LOGLVL_ERROR, conn->config, ctx,
                  gss_maj_stat, gss_min_stat,
                  "Error converting principal name to GSS internal format ");
        gss_release_name(&dummy_stat, &host_gss_name);
        return SERF_ERROR_AUTHN_FAILED;
    }

    /* If the server sent us a token, pass it to gss_init_sec_token for
       validation. */
    gss_input_buf.value = input_buf->value;
    gss_input_buf.length = input_buf->length;

    gss_output_buf_p = apr_pcalloc(result_pool, sizeof(*gss_output_buf_p));

    /* Establish a security context to the server. */
    gss_maj_stat = gss_init_sec_context
        (&gss_min_stat,             /* minor_status */
         GSS_C_NO_CREDENTIAL,       /* XXXXX claimant_cred_handle */
         &ctx->gss_ctx,              /* gssapi context handle */
         host_gss_name,             /* HTTP@server name */
         ctx->gss_mech,             /* mech_type (SPNEGO) */
         GSS_C_MUTUAL_FLAG,         /* ensure the peer authenticates itself */
         0,                         /* default validity period */
         GSS_C_NO_CHANNEL_BINDINGS, /* do not use channel bindings */
         &gss_input_buf,            /* server token, initially empty */
         &dummy,                    /* actual mech type */
         gss_output_buf_p,           /* output_token */
         NULL,                      /* ret_flags */
         NULL                       /* not interested in remaining validity */
         );

    gss_release_name(&dummy_stat, &host_gss_name);
    apr_pool_cleanup_register(result_pool, gss_output_buf_p,
                              cleanup_sec_buffer,
                              apr_pool_cleanup_null);

    output_buf->value = gss_output_buf_p->value;
    output_buf->length = gss_output_buf_p->length;

    switch(gss_maj_stat) {
    case GSS_S_COMPLETE:
        return APR_SUCCESS;
    case GSS_S_CONTINUE_NEEDED:
        return APR_EAGAIN;
    default:
        log_error(LOGLVL_ERROR, conn->config, ctx, gss_maj_stat, gss_min_stat,
                  "Error during Kerberos handshake");
        return SERF_ERROR_AUTHN_FAILED;
    }
}

#endif /* SERF_USE_GSSAPI */
