/*
 * snmptrapd_auth.c - authorize notifications for further processing
 *
 */
#include <net-snmp/net-snmp-config.h>

#if HAVE_WINSOCK_H
#include <winsock.h>
#else
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#endif

#include <net-snmp/net-snmp-includes.h>
#include "snmptrapd_handlers.h"
#include "snmptrapd_auth.h"
#include "snmptrapd_ds.h"

#include <net-snmp/agent/agent_module_config.h>
#include <net-snmp/agent/mib_module_config.h>

#ifdef USING_MIBII_VACM_CONF_MODULE
#include "mibII/vacm_conf.h"
#endif

#include <net-snmp/agent/agent_trap.h>

/**
 * initializes the snmptrapd authorization code registering needed
 * handlers and config parsers.
 */
void
init_netsnmp_trapd_auth(void)
{
    /* register our function as a authorization handler */
    netsnmp_trapd_handler *traph;
    traph = netsnmp_add_global_traphandler(NETSNMPTRAPD_AUTH_HANDLER,
                                           netsnmp_trapd_auth);
    traph->authtypes = TRAP_AUTH_NONE;

#ifdef USING_MIBII_VACM_CONF_MODULE
    /* register our configuration tokens for VACM configs */
    init_vacm_config_tokens();
#endif

    /* register a config token for turning off the authorization entirely */
    netsnmp_ds_register_config(ASN_BOOLEAN, "snmptrapd", "disableAuthorization",
                               NETSNMP_DS_APPLICATION_ID,
                               NETSNMP_DS_APP_NO_AUTHORIZATION);
}

/* XXX: store somewhere in the PDU instead */
static int lastlookup;

/**
 * Authorizes incoming notifications for further processing
 */
int
netsnmp_trapd_auth(netsnmp_pdu           *pdu,
                   netsnmp_transport     *transport,
                   netsnmp_trapd_handler *handler)
{
    int ret = 0;
    oid snmptrapoid[] = { 1,3,6,1,6,3,1,1,4,1,0 };
    size_t snmptrapoid_len = OID_LENGTH(snmptrapoid);
    int i;
    netsnmp_pdu *newpdu = pdu;
    netsnmp_variable_list *var;

    /* check to see if authorization was not disabled */
    if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
                               NETSNMP_DS_APP_NO_AUTHORIZATION)) {
        DEBUGMSGTL(("snmptrapd:auth",
                    "authorization turned off: not checking\n"));
        return NETSNMPTRAPD_HANDLER_OK;
    }

    /* bail early if called illegally */
    if (!pdu || !transport || !handler)
        return NETSNMPTRAPD_HANDLER_FINISH;
    
    /* convert to v2 so we can check it in a consistent manner */
#ifndef NETSNMP_DISABLE_SNMPV1
    if (pdu->version == SNMP_VERSION_1) {
        newpdu = convert_v1pdu_to_v2(pdu);
        if (!newpdu) {
            snmp_log(LOG_ERR, "Failed to duplicate incoming PDU.  Refusing to authorize.\n");
            return NETSNMPTRAPD_HANDLER_FINISH;
        }
    }
#endif

    if (!vacm_is_configured()) {
#ifndef NETSNMP_DISABLE_SNMPV1
        if (newpdu != pdu)
            snmp_free_pdu(newpdu);
#endif
        snmp_log(LOG_WARNING, "No access configuration - dropping trap.\n");
        return NETSNMPTRAPD_HANDLER_FINISH;
    }

    /* loop through each variable and find the snmpTrapOID.0 var
       indicating what the trap is we're staring at. */
    for (var = newpdu->variables; var != NULL; var = var->next_variable) {
        if (netsnmp_oid_equals(var->name, var->name_length,
                               snmptrapoid, snmptrapoid_len) == 0)
            break;
    }

    /* make sure we can continue: we found the snmpTrapOID.0 and its an oid */
    if (!var || var->type != ASN_OBJECT_ID) {
        snmp_log(LOG_ERR, "Can't determine trap identifier; refusing to authorize it\n");
#ifndef NETSNMP_DISABLE_SNMPV1
        if (newpdu != pdu)
            snmp_free_pdu(newpdu);
#endif
        return NETSNMPTRAPD_HANDLER_FINISH;
    }

#ifdef USING_MIBII_VACM_CONF_MODULE
    /* check the pdu against each typo of VACM access we may want to
       check up on later.  We cache the results for future lookup on
       each call to netsnmp_trapd_check_auth */
    for(i = 0; i < VACM_MAX_VIEWS; i++) {
        /* pass the PDU to the VACM routine for handling authorization */
        DEBUGMSGTL(("snmptrapd:auth", "Calling VACM for checking phase %d:%s\n",
                    i, se_find_label_in_slist(VACM_VIEW_ENUM_NAME, i)));
        if (vacm_check_view_contents(newpdu, var->val.objid,
                                     var->val_len/sizeof(oid), 0, i,
                                     VACM_CHECK_VIEW_CONTENTS_DNE_CONTEXT_OK)
            == VACM_SUCCESS) {
            DEBUGMSGTL(("snmptrapd:auth", "  result: authorized\n"));
            ret |= 1 << i;
        } else {
            DEBUGMSGTL(("snmptrapd:auth", "  result: not authorized\n"));
        }
    }
    DEBUGMSGTL(("snmptrapd:auth", "Final bitmask auth: %x\n", ret));
#endif

    if (ret) {
        /* we have policy to at least do "something".  Remember and continue. */
        lastlookup = ret;
#ifndef NETSNMP_DISABLE_SNMPV1
        if (newpdu != pdu)
            snmp_free_pdu(newpdu);
#endif
        return NETSNMPTRAPD_HANDLER_OK;
    }

    /* No policy was met, so we drop the PDU from further processing */
    DEBUGMSGTL(("snmptrapd:auth", "Dropping unauthorized message\n"));
#ifndef NETSNMP_DISABLE_SNMPV1
    if (newpdu != pdu)
        snmp_free_pdu(newpdu);
#endif
    return NETSNMPTRAPD_HANDLER_FINISH;
}

/**
 * Checks to see if the pdu is authorized for a set of given action types.
 * @returns 1 if authorized, 0 if not.
 */
int
netsnmp_trapd_check_auth(int authtypes)
{
    if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
                               NETSNMP_DS_APP_NO_AUTHORIZATION)) {
        DEBUGMSGTL(("snmptrapd:auth", "authorization turned off\n"));
        return 1;
    }

    DEBUGMSGTL(("snmptrapd:auth",
                "Comparing auth types: result=%d, request=%d, result=%d\n",
                lastlookup, authtypes,
                ((authtypes & lastlookup) == authtypes)));
    return ((authtypes & lastlookup) == authtypes);
}

