/* ====================================================================
 *    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 "auth.h"
#include "auth_spnego.h"
#include "serf.h"
#include "serf_private.h"

#ifdef SERF_USE_SSPI
#include <apr.h>
#include <apr_strings.h>

#define SECURITY_WIN32
#include <sspi.h>

/* SEC_E_MUTUAL_AUTH_FAILED is not defined in Windows Platform SDK 5.0. */
#ifndef SEC_E_MUTUAL_AUTH_FAILED
#define SEC_E_MUTUAL_AUTH_FAILED _HRESULT_TYPEDEF_(0x80090363L)
#endif

struct serf__spnego_context_t
{
    CredHandle sspi_credentials;
    CtxtHandle sspi_context;
    BOOL initalized;
    apr_pool_t *pool;

    /* Service Principal Name (SPN) used for authentication. */
    const char *target_name;

    /* One of SERF_AUTHN_* authentication types.*/
    int authn_type;
};

/* Map SECURITY_STATUS from SSPI to APR error code. Some error codes mapped
 * to our own codes and some to Win32 error codes:
 * http://support.microsoft.com/kb/113996
 */
static apr_status_t
map_sspi_status(SECURITY_STATUS sspi_status)
{
    switch(sspi_status)
    {
    case SEC_E_INSUFFICIENT_MEMORY:
        return APR_FROM_OS_ERROR(ERROR_NO_SYSTEM_RESOURCES);
    case SEC_E_INVALID_HANDLE:
        return APR_FROM_OS_ERROR(ERROR_INVALID_HANDLE);
    case SEC_E_UNSUPPORTED_FUNCTION:
        return APR_FROM_OS_ERROR(ERROR_INVALID_FUNCTION);
    case SEC_E_TARGET_UNKNOWN:
        return APR_FROM_OS_ERROR(ERROR_BAD_NETPATH);
    case SEC_E_INTERNAL_ERROR:
        return APR_FROM_OS_ERROR(ERROR_INTERNAL_ERROR);
    case SEC_E_SECPKG_NOT_FOUND:
    case SEC_E_BAD_PKGID:
        return APR_FROM_OS_ERROR(ERROR_NO_SUCH_PACKAGE);
    case SEC_E_NO_IMPERSONATION:
        return APR_FROM_OS_ERROR(ERROR_CANNOT_IMPERSONATE);
    case SEC_E_NO_AUTHENTICATING_AUTHORITY:
        return APR_FROM_OS_ERROR(ERROR_NO_LOGON_SERVERS);
    case SEC_E_UNTRUSTED_ROOT:
        return APR_FROM_OS_ERROR(ERROR_TRUST_FAILURE);
    case SEC_E_WRONG_PRINCIPAL:
        return APR_FROM_OS_ERROR(ERROR_WRONG_TARGET_NAME);
    case SEC_E_MUTUAL_AUTH_FAILED:
        return APR_FROM_OS_ERROR(ERROR_MUTUAL_AUTH_FAILED);
    case SEC_E_TIME_SKEW:
        return APR_FROM_OS_ERROR(ERROR_TIME_SKEW);
    default:
        return SERF_ERROR_AUTHN_FAILED;
    }
}

/* Cleans the SSPI 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 (SecIsValidHandle(&ctx->sspi_context)) {
        DeleteSecurityContext(&ctx->sspi_context);
        SecInvalidateHandle(&ctx->sspi_context);
    }

    if (SecIsValidHandle(&ctx->sspi_credentials)) {
        FreeCredentialsHandle(&ctx->sspi_credentials);
        SecInvalidateHandle(&ctx->sspi_credentials);
    }

    return APR_SUCCESS;
}

static apr_status_t
cleanup_sec_buffer(void *data)
{
    FreeContextBuffer(data);

    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)
{
    SECURITY_STATUS sspi_status;
    serf__spnego_context_t *ctx;
    const char *sspi_package;

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

    SecInvalidateHandle(&ctx->sspi_context);
    SecInvalidateHandle(&ctx->sspi_credentials);
    ctx->initalized = FALSE;
    ctx->pool = result_pool;
    ctx->target_name = NULL;
    ctx->authn_type = scheme->type;

    apr_pool_cleanup_register(result_pool, ctx,
                              cleanup_ctx,
                              apr_pool_cleanup_null);

    if (ctx->authn_type == SERF_AUTHN_NEGOTIATE)
        sspi_package = "Negotiate";
    else
        sspi_package = "NTLM";

    sspi_status = AcquireCredentialsHandleA(
        NULL, sspi_package, SECPKG_CRED_OUTBOUND,
        NULL, NULL, NULL, NULL,
        &ctx->sspi_credentials, NULL);

    if (FAILED(sspi_status)) {
        return map_sspi_status(sspi_status);
    }

    *ctx_p = ctx;

    return APR_SUCCESS;
}

static apr_status_t
get_canonical_hostname(const char **canonname,
                       const char *hostname,
                       apr_pool_t *pool)
{
    struct addrinfo hints;
    struct addrinfo *addrinfo;

    ZeroMemory(&hints, sizeof(hints));
    hints.ai_flags = AI_CANONNAME;

    if (getaddrinfo(hostname, NULL, &hints, &addrinfo)) {
        return apr_get_netos_error();
    }

    if (addrinfo) {
        /* We got the canonical name and address. Try to perform
         * reverse DNS lookup to find the true hostname.
         * This is how MIT KRB works by default.*/
        char rdnshost[NI_MAXHOST];
        int gaierr;

        gaierr = getnameinfo(addrinfo->ai_addr, addrinfo->ai_addrlen,
                             rdnshost, sizeof(rdnshost),
                             NULL, 0, NI_NAMEREQD);
        if (gaierr) {
            /* Reverse DNS lookup failed -- use canonical name is that case. */
            *canonname = apr_pstrdup(pool, addrinfo->ai_canonname);
        }
        else {
            /* We got the hostname -- use it for SPN. */
            *canonname = apr_pstrdup(pool, rdnshost);
        }
    }
    else {
        *canonname = apr_pstrdup(pool, hostname);
    }

    freeaddrinfo(addrinfo);
    return APR_SUCCESS;
}

apr_status_t
serf__spnego_reset_sec_context(serf__spnego_context_t *ctx)
{
    if (SecIsValidHandle(&ctx->sspi_context)) {
        DeleteSecurityContext(&ctx->sspi_context);
        SecInvalidateHandle(&ctx->sspi_context);
    }

    ctx->initalized = FALSE;

    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
                              )
{
    SECURITY_STATUS status;
    ULONG actual_attr;
    SecBuffer sspi_in_buffer;
    SecBufferDesc sspi_in_buffer_desc;
    SecBuffer sspi_out_buffer;
    SecBufferDesc sspi_out_buffer_desc;
    apr_status_t apr_status;
    const char *canonname;

    if (!ctx->initalized && ctx->authn_type == SERF_AUTHN_NEGOTIATE) {
        apr_status = get_canonical_hostname(&canonname, hostname, scratch_pool);
        if (apr_status) {
            return apr_status;
        }

        ctx->target_name = apr_pstrcat(scratch_pool, service, "/", canonname,
                                       NULL);

        serf__log(LOGLVL_DEBUG, LOGCOMP_AUTHN, __FILE__, conn->config,
                  "Using SPN '%s' for '%s'\n", ctx->target_name, hostname);
    }
    else if (ctx->authn_type == SERF_AUTHN_NTLM)
    {
        /* Target name is not used for NTLM authentication. */
        ctx->target_name = NULL;
    }

    /* Prepare input buffer description. */
    sspi_in_buffer.BufferType = SECBUFFER_TOKEN;
    sspi_in_buffer.pvBuffer = input_buf->value;
    sspi_in_buffer.cbBuffer = input_buf->length;

    sspi_in_buffer_desc.cBuffers = 1;
    sspi_in_buffer_desc.pBuffers = &sspi_in_buffer;
    sspi_in_buffer_desc.ulVersion = SECBUFFER_VERSION;

    /* Output buffers. Output buffer will be allocated by system. */
    sspi_out_buffer.BufferType = SECBUFFER_TOKEN;
    sspi_out_buffer.pvBuffer = NULL;
    sspi_out_buffer.cbBuffer = 0;

    sspi_out_buffer_desc.cBuffers = 1;
    sspi_out_buffer_desc.pBuffers = &sspi_out_buffer;
    sspi_out_buffer_desc.ulVersion = SECBUFFER_VERSION;

    status = InitializeSecurityContextA(
        &ctx->sspi_credentials,
        ctx->initalized ? &ctx->sspi_context : NULL,
        ctx->target_name,
        ISC_REQ_ALLOCATE_MEMORY
        | ISC_REQ_MUTUAL_AUTH,
        0,                          /* Reserved1 */
        SECURITY_NETWORK_DREP,
        &sspi_in_buffer_desc,
        0,                          /* Reserved2 */
        &ctx->sspi_context,
        &sspi_out_buffer_desc,
        &actual_attr,
        NULL);

    if (sspi_out_buffer.cbBuffer > 0) {
        apr_pool_cleanup_register(result_pool, sspi_out_buffer.pvBuffer,
                                  cleanup_sec_buffer,
                                  apr_pool_cleanup_null);
    }

    ctx->initalized = TRUE;

    /* Finish authentication if SSPI requires so. */
    if (status == SEC_I_COMPLETE_NEEDED
        || status == SEC_I_COMPLETE_AND_CONTINUE)
    {
        CompleteAuthToken(&ctx->sspi_context, &sspi_out_buffer_desc);
    }

    output_buf->value = sspi_out_buffer.pvBuffer;
    output_buf->length = sspi_out_buffer.cbBuffer;

    switch(status) {
    case SEC_I_COMPLETE_AND_CONTINUE:
    case SEC_I_CONTINUE_NEEDED:
        return APR_EAGAIN;

    case SEC_I_COMPLETE_NEEDED:
    case SEC_E_OK:
        return APR_SUCCESS;

    default:
        return map_sspi_status(status);
    }
}

#endif /* SERF_USE_SSPI */
