/* ====================================================================
 *    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.
 * ====================================================================
 */

/*** Basic authentication ***/

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

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

/* Stores the context information related to Basic authentication.
   This information is stored in the per server cache in the serf context. */
typedef struct basic_authn_info_t {
    const char *header;
    const char *value;
} basic_authn_info_t;

/* Implements serf__auth_handler_func_t callback. */
static apr_status_t
serf__handle_basic_auth(const serf__authn_scheme_t *scheme,
                        int code,
                        serf_request_t *request,
                        serf_bucket_t *response,
                        const char *auth_hdr,
                        const char *auth_attr,
                        apr_pool_t *pool)
{
    const char *tmp;
    apr_size_t tmp_len;
    serf_connection_t *conn = request->conn;
    serf_context_t *ctx = conn->ctx;
    serf__authn_info_t *authn_info;
    basic_authn_info_t *basic_info;
    apr_status_t status;
    apr_pool_t *cred_pool;
    char *username, *password, *realm_name;
    const char *eq, *realm = NULL;

    /* Can't do Basic authentication if there's no callback to get
       username & password. */
    if (!ctx->cred_cb) {
        return SERF_ERROR_AUTHN_FAILED;
    }

    if (code == 401) {
        authn_info = serf__get_authn_info_for_server(conn);
    } else {
        authn_info = &ctx->proxy_authn_info;
    }
    basic_info = authn_info->baton;

    realm_name = NULL;
    eq = strchr(auth_attr, '=');

    if (eq && strncasecmp(auth_attr, "realm", 5) == 0) {
        realm_name = apr_pstrdup(pool, eq + 1);
        if (realm_name[0] == '\"') {
            apr_size_t realm_len;

            realm_len = strlen(realm_name);
            if (realm_name[realm_len - 1] == '\"') {
                realm_name[realm_len - 1] = '\0';
                realm_name++;
            }
        }

        if (!realm_name) {
            return SERF_ERROR_AUTHN_MISSING_ATTRIBUTE;
        }

        realm = serf__construct_realm(code == 401 ? HOST : PROXY,
                                      conn, realm_name,
                                      pool);
    }

    /* Ask the application for credentials */
    apr_pool_create(&cred_pool, pool);
    status = serf__provide_credentials(ctx,
                                       &username, &password,
                                       request,
                                       code, scheme->name,
                                       realm, cred_pool);
    if (status) {
        apr_pool_destroy(cred_pool);
        return status;
    }

    tmp = apr_pstrcat(conn->pool, username, ":", password, NULL);
    tmp_len = strlen(tmp);
    apr_pool_destroy(cred_pool);

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

    return APR_SUCCESS;
}

/* For Basic authentication we expect all authn info to be the same for all
   connections in the context to the same server (same realm, username,
   password). Therefore we can keep the header value in the per-server store
   context instead of per connection. Implements serf__init_conn_func_t
   callback.
   TODO: we currently don't cache this info per realm, so each time a request
   'switches realms', we have to ask the application for new credentials. */
static apr_status_t
serf__init_basic_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;

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

    if (!authn_info->baton) {
        authn_info->baton = apr_pcalloc(pool, sizeof(basic_authn_info_t));
    }

    return APR_SUCCESS;
}

/* Implements serf__setup_request_func_t callback. */
static apr_status_t
serf__setup_request_basic_auth(const serf__authn_scheme_t *scheme,
                               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;
    serf__authn_info_t *authn_info;
    basic_authn_info_t *basic_info;

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

    if (basic_info && basic_info->header && basic_info->value) {
        serf_bucket_headers_setn(hdrs_bkt, basic_info->header,
                                 basic_info->value);
        return APR_SUCCESS;
    }

    return SERF_ERROR_AUTHN_FAILED;
}

/* Implements serf__validate_response_func_t callback. */
static apr_status_t
validate_response_func(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)
{
    return APR_SUCCESS;
}

const serf__authn_scheme_t serf__basic_authn_scheme = {
    "Basic",
    "basic",
    SERF_AUTHN_BASIC,
    serf__init_basic_connection,
    serf__handle_basic_auth,
    serf__setup_request_basic_auth,
    validate_response_func,
};
