/*
 * snmptsmsm.c -- Implements RFC #5591
 *
 * This code implements a security model that assumes the local user
 * that executed the agent is the user who's attributes are passed up
 * by the transport underneath.  The RFC describing this security
 * model is RFC5591.
 */

#include <net-snmp/net-snmp-config.h>

#include <net-snmp/net-snmp-includes.h>

#include <net-snmp/library/snmptsm.h>

#ifdef NETSNMP_TRANSPORT_SSH_DOMAIN
#include <net-snmp/library/snmpSSHDomain.h>
#endif
#ifdef NETSNMP_TRANSPORT_DTLSUDP_DOMAIN
#include <net-snmp/library/snmpDTLSUDPDomain.h>
#endif
#ifdef NETSNMP_TRANSPORT_TLSTCP_DOMAIN
#include <net-snmp/library/snmpTLSTCPDomain.h>
#endif
#ifdef NETSNMP_TRANSPORT_DTLSSCTP_DOMAIN
#include <net-snmp/library/snmpDTLSSCTPDomain.h>
#endif

#include <unistd.h>

static int      tsm_session_init(netsnmp_session *);
static void     tsm_free_state_ref(void *);
static int      tsm_clone_pdu(netsnmp_pdu *, netsnmp_pdu *);
static int      tsm_free_pdu(netsnmp_pdu *pdu);

u_int next_sess_id = 1;

/** Initialize the TSM security module */
void
init_tsm(void)
{
    struct snmp_secmod_def *def;
    int ret;

    def = SNMP_MALLOC_STRUCT(snmp_secmod_def);

    if (!def) {
        snmp_log(LOG_ERR,
                 "Unable to malloc snmp_secmod struct, not registering TSM\n");
        return;
    }

    def->encode_reverse = tsm_rgenerate_out_msg;
    def->decode = tsm_process_in_msg;
    def->session_open = tsm_session_init;
    def->pdu_free_state_ref = tsm_free_state_ref;
    def->pdu_clone = tsm_clone_pdu;
    def->pdu_free = tsm_free_pdu;
    def->probe_engineid = snmpv3_probe_contextEngineID_rfc5343;

    DEBUGMSGTL(("tsm","registering ourselves\n"));
    ret = register_sec_mod(SNMP_SEC_MODEL_TSM, "tsm", def);
    DEBUGMSGTL(("tsm"," returned %d\n", ret));

    netsnmp_ds_register_config(ASN_BOOLEAN, "snmp", "tsmUseTransportPrefix",
			       NETSNMP_DS_LIBRARY_ID,
                               NETSNMP_DS_LIB_TSM_USE_PREFIX);
}

/*
 * Initialize specific session information (right now, just set up things to
 * not do an engineID probe)
 */

static int
tsm_session_init(netsnmp_session * sess)
{
    DEBUGMSGTL(("tsm",
                "TSM: Reached our session initialization callback\n"));

    sess->flags |= SNMP_FLAGS_DONT_PROBE;

    /* XXX: likely needed for something: */
    /*
    tsmsession = sess->securityInfo =
    if (!tsmsession)
        return SNMPERR_GENERR;
    */

    return SNMPERR_SUCCESS;
}

/** Free our state information (this is only done on the agent side) */
static void
tsm_free_state_ref(void *ptr)
{
    netsnmp_tsmSecurityReference *tsmRef;

    if (NULL == ptr)
        return;

    tsmRef = (netsnmp_tsmSecurityReference *) ptr;
    /* the tmStateRef is always taken care of by the normal PDU, since this
       is just a reference to that one */
    /* DON'T DO: SNMP_FREE(tsmRef->tmStateRef); */
    /* SNMP_FREE(tsmRef);  ? */
}

static int
tsm_free_pdu(netsnmp_pdu *pdu)
{
    /* free the security reference */
    if (pdu->securityStateRef) {
        tsm_free_state_ref(pdu->securityStateRef);
        pdu->securityStateRef = NULL;
    }
    return 0;
}

/** This is called when a PDU is cloned (to increase reference counts) */
static int
tsm_clone_pdu(netsnmp_pdu *pdu, netsnmp_pdu *pdu2)
{
    netsnmp_tsmSecurityReference *oldref, *newref;

    oldref = pdu->securityStateRef;
    if (!oldref)
        return SNMPERR_SUCCESS;

    newref = SNMP_MALLOC_TYPEDEF(netsnmp_tsmSecurityReference);
    DEBUGMSGTL(("tsm", "cloned as pdu=%p, ref=%p (oldref=%p)\n",
            pdu2, newref, pdu2->securityStateRef));
    if (!newref)
        return SNMPERR_GENERR;
    
    memcpy(newref, oldref, sizeof(*oldref));

    pdu2->securityStateRef = newref;

    /* the tm state reference is just a link to the one in the pdu,
       which was already copied by snmp_clone_pdu before handing it to
       us. */

    newref->tmStateRef = netsnmp_memdup(oldref->tmStateRef,
                                        sizeof(*oldref->tmStateRef));
    return SNMPERR_SUCCESS;
}

/* asn.1 easing definitions */
#define TSMBUILD_OR_ERR(fun, args, msg, desc)       \
    DEBUGDUMPHEADER("send", desc); \
    rc = fun args;            \
    DEBUGINDENTLESS();        \
    if (rc == 0) { \
        DEBUGMSGTL(("tsm",msg)); \
        retval = SNMPERR_TOO_LONG; \
        goto outerr; \
    }

/****************************************************************************
 *
 * tsm_generate_out_msg
 *
 * Parameters:
 *	(See list below...)
 *
 * Returns:
 *	SNMPERR_SUCCESS                        On success.
 *	... and others
 *
 *
 * Generate an outgoing message.
 *
 ****************************************************************************/

int
tsm_rgenerate_out_msg(struct snmp_secmod_outgoing_params *parms)
{
    u_char         **wholeMsg = parms->wholeMsg;
    size_t	   *offset = parms->wholeMsgOffset;
    int rc;
    
    size_t         *wholeMsgLen = parms->wholeMsgLen;
    netsnmp_tsmSecurityReference *tsmSecRef;
    netsnmp_tmStateReference *tmStateRef;
    int             tmStateRefLocal = 0;
    
    DEBUGMSGTL(("tsm", "Starting TSM processing\n"));

    /* if we have this, then this message to be sent is in response to
       something that came in earlier and the tsmSecRef was created by
       the tsm_process_in_msg. */
    tsmSecRef = parms->secStateRef;
    
    if (tsmSecRef) {
        /* 4.2, step 1: If there is a securityStateReference (Response
           or Report message), then this Security Model uses the
           cached information rather than the information provided by
           the ASI. */

        /* 4.2, step 1: Extract the tmStateReference from the
           securityStateReference cache. */
        netsnmp_assert_or_return(NULL != tsmSecRef->tmStateRef, SNMPERR_GENERR);
        tmStateRef = tsmSecRef->tmStateRef;

        /* 4.2 step 1: Set the tmRequestedSecurityLevel to the value
           of the extracted tmTransportSecurityLevel. */
        tmStateRef->requestedSecurityLevel = tmStateRef->transportSecurityLevel;

        /* 4.2 step 1: Set the tmSameSecurity parameter in the
           tmStateReference cache to true. */
        tmStateRef->sameSecurity = NETSNMP_TM_USE_SAME_SECURITY;

        /* 4.2 step 1: The cachedSecurityData for this message can
           now be discarded. */
        SNMP_FREE(parms->secStateRef);
    } else {
        /* 4.2, step 2: If there is no securityStateReference (e.g., a
           Request-type or Notification message), then create a
           tmStateReference cache. */
        tmStateRef = SNMP_MALLOC_TYPEDEF(netsnmp_tmStateReference);
        netsnmp_assert_or_return(NULL != tmStateRef, SNMPERR_GENERR);
        tmStateRefLocal = 1;

        /* XXX: we don't actually use this really in our implementation */
        /* 4.2, step 2: Set tmTransportDomain to the value of
           transportDomain, tmTransportAddress to the value of
           transportAddress */

        /* 4.2, step 2: and tmRequestedSecurityLevel to the value of
           securityLevel. */
        tmStateRef->requestedSecurityLevel = parms->secLevel;

        /* 4.2, step 2: Set the transaction-specific tmSameSecurity
           parameter to false. */
        tmStateRef->sameSecurity = NETSNMP_TM_SAME_SECURITY_NOT_REQUIRED;

        if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
                                   NETSNMP_DS_LIB_TSM_USE_PREFIX)) {
            /* XXX: probably shouldn't be a hard-coded list of
               supported transports */
            /* 4.2, step 2: If the snmpTsmConfigurationUsePrefix
               object is set to true, then use the transportDomain to
               look up the corresponding prefix. */
            const char *prefix;
            if (strncmp("ssh:",parms->session->peername,4) == 0)
                prefix = "ssh:";
            else if (strncmp("dtls:",parms->session->peername,5) == 0)
                prefix = "dtls:";
            else if (strncmp("tls:",parms->session->peername,4) == 0)
                prefix = "tls:";
            else {
                /* 4.2, step 2: If the prefix lookup fails for any
                   reason, then the snmpTsmUnknownPrefixes counter is
                   incremented, an error indication is returned to the
                   calling module, and message processing stops. */
                snmp_increment_statistic(STAT_TSM_SNMPTSMUNKNOWNPREFIXES);
                SNMP_FREE(tmStateRef);
                return SNMPERR_GENERR;
            }

            /* 4.2, step 2: If the lookup succeeds, but there is no
               prefix in the securityName, or the prefix returned does
               not match the prefix in the securityName, or the length
               of the prefix is less than 1 or greater than 4 US-ASCII
               alpha-numeric characters, then the
               snmpTsmInvalidPrefixes counter is incremented, an error
               indication is returned to the calling module, and
               message processing stops. */
            if (strchr(parms->secName, ':') == 0 ||
                strlen(prefix)+1 >= parms->secNameLen ||
                strncmp(parms->secName, prefix, strlen(prefix)) != 0 ||
                parms->secName[strlen(prefix)] != ':') {
                /* Note: since we're assiging the prefixes above the
                   prefix lengths always meet the 1-4 criteria */
                snmp_increment_statistic(STAT_TSM_SNMPTSMINVALIDPREFIXES);
                SNMP_FREE(tmStateRef);
                return SNMPERR_GENERR;
            }

            /* 4.2, step 2: Strip the transport-specific prefix and
               trailing ':' character (US-ASCII 0x3a) from the
               securityName.  Set tmSecurityName to the value of
               securityName. */
            memcpy(tmStateRef->securityName,
                   parms->secName + strlen(prefix) + 1,
                   parms->secNameLen - strlen(prefix) - 1);
            tmStateRef->securityNameLen = parms->secNameLen - strlen(prefix) -1;
        } else {
            /* 4.2, step 2: If the snmpTsmConfigurationUsePrefix object is
               set to false, then set tmSecurityName to the value
               of securityName. */
            memcpy(tmStateRef->securityName, parms->secName,
                   parms->secNameLen);
            tmStateRef->securityNameLen = parms->secNameLen;
        }
    }

    /* truncate the security name with a '\0' for safety */
    tmStateRef->securityName[tmStateRef->securityNameLen] = '\0';

    /* 4.2, step 3: Set securityParameters to a zero-length OCTET
     *  STRING ('0400').
     */
    DEBUGDUMPHEADER("send", "tsm security parameters");
    rc = asn_realloc_rbuild_header(wholeMsg, wholeMsgLen, offset, 1,
                                     (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE
                                             | ASN_OCTET_STR), 0);
    DEBUGINDENTLESS();
    if (rc == 0) {
        DEBUGMSGTL(("tsm", "building msgSecurityParameters failed.\n"));
        if (tmStateRefLocal)
            SNMP_FREE(tmStateRef);
        return SNMPERR_TOO_LONG;
    }
    
    /* 4.2, step 4: Combine the message parts into a wholeMsg and
       calculate wholeMsgLength.
     */
    while ((*wholeMsgLen - *offset) < parms->globalDataLen) {
        if (!asn_realloc(wholeMsg, wholeMsgLen)) {
            DEBUGMSGTL(("tsm", "building global data failed.\n"));
            if (tmStateRefLocal)
                SNMP_FREE(tmStateRef);
            return SNMPERR_TOO_LONG;
        }
    }

    *offset += parms->globalDataLen;
    memcpy(*wholeMsg + *wholeMsgLen - *offset,
           parms->globalData, parms->globalDataLen);

    /* 4.2, step 5: The wholeMsg, wholeMsgLength, securityParameters,
       and tmStateReference are returned to the calling Message
       Processing Model with the statusInformation set to success. */

    /* For the Net-SNMP implemantion that actually means we start
       encoding the full packet sequence from here before returning it */

    /*
     * Total packet sequence.  
     */
    rc = asn_realloc_rbuild_sequence(wholeMsg, wholeMsgLen, offset, 1,
                                     (u_char) (ASN_SEQUENCE |
                                               ASN_CONSTRUCTOR), *offset);
    if (rc == 0) {
        DEBUGMSGTL(("tsm", "building master packet sequence failed.\n"));
        if (tmStateRefLocal)
            SNMP_FREE(tmStateRef);
        return SNMPERR_TOO_LONG;
    }

    if (parms->pdu->transport_data &&
        parms->pdu->transport_data != tmStateRef) {
        snmp_log(LOG_ERR, "tsm: needed to free transport data\n");
        SNMP_FREE(parms->pdu->transport_data);
    }

    /* put the transport state reference into the PDU for the transport */
    parms->pdu->transport_data = netsnmp_memdup(tmStateRef, sizeof(*tmStateRef));
    if (!parms->pdu->transport_data)
        snmp_log(LOG_ERR, "tsm: malloc failure\n");
    parms->pdu->transport_data_length = sizeof(*tmStateRef);

    if (tmStateRefLocal)
        SNMP_FREE(tmStateRef);
    DEBUGMSGTL(("tsm", "TSM processing completed.\n"));
    return SNMPERR_SUCCESS;
}

/****************************************************************************
 *
 * tsm_process_in_msg
 *
 * Parameters:
 *	(See list below...)
 *
 * Returns:
 *	TSM_ERR_NO_ERROR                        On success.
 *	TSM_ERR_GENERIC_ERROR
 *	TSM_ERR_UNSUPPORTED_SECURITY_LEVEL
 *
 *
 * Processes an incoming message.
 *
 ****************************************************************************/

int
tsm_process_in_msg(struct snmp_secmod_incoming_params *parms)
{
    u_char type_value;
    size_t remaining;
    u_char *data_ptr;
    netsnmp_tmStateReference *tmStateRef;
    netsnmp_tsmSecurityReference *tsmSecRef;
    u_char          ourEngineID[SNMP_MAX_ENG_SIZE];
    static size_t   ourEngineID_len = sizeof(ourEngineID);
    
    /* Section 5.2, step 1: Set the securityEngineID to the local
       snmpEngineID. */
    ourEngineID_len =
        snmpv3_get_engineID((u_char*) ourEngineID, ourEngineID_len);
    netsnmp_assert_or_return(ourEngineID_len != 0 &&
                             ourEngineID_len <= *parms->secEngineIDLen,
                             SNMPERR_GENERR);
    memcpy(parms->secEngineID, ourEngineID, *parms->secEngineIDLen);

    /* Section 5.2, step 2: If tmStateReference does not refer to a
       cache containing values for tmTransportDomain,
       tmTransportAddress, tmSecurityName, and
       tmTransportSecurityLevel, then the snmpTsmInvalidCaches counter
       is incremented, an error indication is returned to the calling
       module, and Security Model processing stops for this
       message. */
    if (!parms->pdu->transport_data ||
        sizeof(netsnmp_tmStateReference) !=
        parms->pdu->transport_data_length) {
        /* if we're not coming in over a proper transport; bail! */
        DEBUGMSGTL(("tsm","improper transport data\n"));
        return -1;
    }
    tmStateRef = (netsnmp_tmStateReference *) parms->pdu->transport_data;
    parms->pdu->transport_data = NULL;

    if (tmStateRef == NULL ||
        /* not needed: tmStateRef->transportDomain == NULL || */
        /* not needed: tmStateRef->transportAddress == NULL || */
        tmStateRef->securityName[0] == '\0'
        ) {
        snmp_increment_statistic(STAT_TSM_SNMPTSMINVALIDCACHES);
        return SNMPERR_GENERR;
    }

    /* Section 5.2, step 3: Copy the tmSecurityName to securityName. */
    if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
                               NETSNMP_DS_LIB_TSM_USE_PREFIX)) {
        /* Section 5.2, step 3:
          If the snmpTsmConfigurationUsePrefix object is set to true, then
          use the tmTransportDomain to look up the corresponding prefix.
        */
        const char *prefix = NULL;
        /*
          possibilities:
           |--------------------+-------|
           | snmpTLSTCPDomain   | tls:  |
           | snmpDTLSUDPDomain  | dtls: |
           | snmpSSHDomain      | ssh:  |
           |--------------------+-------|
        */
        
        if (tmStateRef->transportDomain == NULL) {
            /* XXX: snmpTsmInvalidCaches++ ??? */
            return SNMPERR_GENERR;
        }

        /* XXX: cache in session! */
#ifdef NETSNMP_TRANSPORT_SSH_DOMAIN
        if (netsnmp_oid_equals(netsnmp_snmpSSHDomain,
                               netsnmp_snmpSSHDomain_len,
                               tmStateRef->transportDomain,
                               tmStateRef->transportDomainLen) == 0) {
            prefix = "ssh";
        }
#endif /*  NETSNMP_TRANSPORT_SSH_DOMAIN */

#ifdef NETSNMP_TRANSPORT_DTLSUDP_DOMAIN
        if (netsnmp_oid_equals(netsnmpDTLSUDPDomain,
                               netsnmpDTLSUDPDomain_len,
                               tmStateRef->transportDomain,
                               tmStateRef->transportDomainLen) == 0) {
            
            prefix = "dtls";
        }
#endif /* NETSNMP_TRANSPORT_DTLSUDP_DOMAIN */

#ifdef NETSNMP_TRANSPORT_TLSTCP_DOMAIN
        if (netsnmp_oid_equals(netsnmpTLSTCPDomain,
                               netsnmpTLSTCPDomain_len,
                               tmStateRef->transportDomain,
                               tmStateRef->transportDomainLen) == 0) {
            
            prefix = "tls";
        }
#endif /* NETSNMP_TRANSPORT_TLSTCP_DOMAIN */

        /* Section 5.2, step 3:
          If the prefix lookup fails for any reason, then the
          snmpTsmUnknownPrefixes counter is incremented, an error
          indication is returned to the calling module, and message
          processing stops.
        */
        if (prefix == NULL) {
            snmp_increment_statistic(STAT_TSM_SNMPTSMUNKNOWNPREFIXES);
            return SNMPERR_GENERR;
        }

        /* Section 5.2, step 3:
          If the lookup succeeds but the prefix length is less than 1 or
          greater than 4 octets, then the snmpTsmInvalidPrefixes counter
          is incremented, an error indication is returned to the calling
          module, and message processing stops.
        */
#ifdef NOT_USING_HARDCODED_PREFIXES
        /* the above code actually ensures this will never happen as
           we don't support a dynamic prefix database where this might
           happen. */
        if (strlen(prefix) < 1 || strlen(prefix) > 4) {
            /* XXX: snmpTsmInvalidPrefixes++ */
            return SNMPERR_GENERR;
        }
#endif
        
        /* Section 5.2, step 3:
          Set the securityName to be the concatenation of the prefix, a
          ':' character (US-ASCII 0x3a), and the tmSecurityName.
        */
        snprintf(parms->secName, *parms->secNameLen,
                 "%s:%s", prefix, tmStateRef->securityName);
    } else {
        /* if the use prefix flag wasn't set, do a straight copy */
        strncpy(parms->secName, tmStateRef->securityName, *parms->secNameLen);
    }

    /* set the length of the security name */
    *parms->secNameLen = strlen(parms->secName);
    DEBUGMSGTL(("tsm", "user: %s/%d\n", parms->secName, (int)*parms->secNameLen));

    /* Section 5.2 Step 4:
       Compare the value of tmTransportSecurityLevel in the
       tmStateReference cache to the value of the securityLevel
       parameter passed in the processIncomingMsg ASI.  If securityLevel
       specifies privacy (Priv) and tmTransportSecurityLevel specifies
       no privacy (noPriv), or if securityLevel specifies authentication
       (auth) and tmTransportSecurityLevel specifies no authentication
       (noAuth) was provided by the Transport Model, then the
       snmpTsmInadequateSecurityLevels counter is incremented, an error
       indication (unsupportedSecurityLevel) together with the OID and
       value of the incremented counter is returned to the calling
       module, and Transport Security Model processing stops for this
       message.*/
    if (parms->secLevel > tmStateRef->transportSecurityLevel) {
        snmp_increment_statistic(STAT_TSM_SNMPTSMINADEQUATESECURITYLEVELS);
        DEBUGMSGTL(("tsm", "inadequate security level %d\n", parms->secLevel));
        /* net-snmp returns error codes not OIDs, which are dealt with later */
        return SNMPERR_UNSUPPORTED_SEC_LEVEL;
    }

    /* Section 5.2 Step 5
       The tmStateReference is cached as cachedSecurityData so that a
       possible response to this message will use the same security
       parameters.  Then securityStateReference is set for subsequent
       references to this cached data.
    */
    if (NULL == *parms->secStateRef) {
        tsmSecRef = SNMP_MALLOC_TYPEDEF(netsnmp_tsmSecurityReference);
    } else {
        tsmSecRef = *parms->secStateRef;
    }

    netsnmp_assert_or_return(NULL != tsmSecRef, SNMPERR_GENERR);

    *parms->secStateRef = tsmSecRef;
    tsmSecRef->tmStateRef = tmStateRef;

    /* If this did not come through a tunneled connection, this
       security model is inappropriate (and would be a HUGE security
       hole to assume otherwise).  This is functionally a double check
       since the pdu wouldn't have transport data otherwise.  But this
       is safer though is functionally an extra step beyond the TSM
       RFC. */
    DEBUGMSGTL(("tsm","checking how we got here\n"));
    if (!(parms->pdu->flags & UCD_MSG_FLAG_TUNNELED)) {
        DEBUGMSGTL(("tsm","  pdu not tunneled\n"));
        if (!(parms->sess->flags & NETSNMP_TRANSPORT_FLAG_TUNNELED)) {
            DEBUGMSGTL(("tsm","  session not tunneled\n"));
            return SNMPERR_USM_AUTHENTICATIONFAILURE;
        }
        DEBUGMSGTL(("tsm","  but session is tunneled\n"));
    } else {
        DEBUGMSGTL(("tsm","  tunneled\n"));
    }

    /* Section 5.2, Step 6:
       The scopedPDU component is extracted from the wholeMsg. */
    /*
     * Eat the first octet header.
     */
    remaining = parms->wholeMsgLen - (parms->secParams - parms->wholeMsg);
    if ((data_ptr = asn_parse_sequence(parms->secParams, &remaining,
                                        &type_value,
                                        (ASN_UNIVERSAL | ASN_PRIMITIVE |
                                         ASN_OCTET_STR),
                                        "tsm first octet")) == NULL) {
        /*
         * RETURN parse error 
         */
        return SNMPERR_ASN_PARSE_ERR;
    }
    
    *parms->scopedPdu = data_ptr;
    *parms->scopedPduLen = parms->wholeMsgLen - (data_ptr - parms->wholeMsg);

    /* Section 5.2, Step 7:
       The maxSizeResponseScopedPDU is calculated.  This is the maximum
       size allowed for a scopedPDU for a possible Response message.
     */
    *parms->maxSizeResponse = parms->maxMsgSize; /* XXX */

    /* Section 5.2, Step 8:
       The statusInformation is set to success and a return is made to
       the calling module passing back the OUT parameters as specified
       in the processIncomingMsg ASI.
    */
    return SNMPERR_SUCCESS;
}
