/*
 * Note: this file originally auto-generated by mib2c using
 *       version : 1.19 $ of : mfd-data-set.m2c,v $
 *
 * $Id$
 *
 */
/*
 * standard Net-SNMP includes 
 */
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

#include <openssl/dh.h>

/*
 * include our parent header 
 */
#define NEED_USMDH_FUNCTIONS
#include "usmDHUserKeyTable.h"

int
usmDHUserCheckValue(struct usmUser *user, int for_auth_key,
                    u_char *val, size_t val_len)
{
    /*
     * The set value must be composed of 2 parts, the first being the
     * current value 
     */
    u_char         *current_value;
    size_t          current_value_len;

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserCheckValue",
                "called\n"));
    usmDHGetUserKeyChange(user, for_auth_key,
                          &current_value, &current_value_len);

    if (!current_value)
        return MFD_ERROR;

    if (val_len != current_value_len * 2)
        return MFD_NOT_VALID_NOW;

    if (memcmp(current_value, val, current_value_len) != 0)
        return SNMP_ERR_WRONGVALUE;     /* mandated error string */

    return MFD_SUCCESS;
}

int
usmDHSetKey(struct usmUser *user, int for_auth_key,
            u_char *val, size_t val_len)
{
    DH             *dh;
    BIGNUM         *other_pub;
    u_char         *key;
    size_t          key_len;

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHSetKey", "called\n"));
    /*
     * XXX: mem leaks on errors abound 
     */

    dh = usmDHGetUserDHptr(user, for_auth_key);
    if (!dh)
        return MFD_ERROR;

    other_pub = BN_bin2bn(val + val_len / 2, val_len / 2, NULL);
    if (!other_pub)
        return MFD_ERROR;

    /*
     * Set the new key for a user 
     */
    key_len = DH_size(dh);
    key = malloc(DH_size(dh));
    if (!key)
        return MFD_ERROR;

    if (DH_compute_key(key, other_pub, dh)) {
        u_char        **replkey;
        size_t          replkey_size;

        if (for_auth_key) {
            replkey_size = user->authKeyLen;
            replkey = &user->authKey;
        } else {
            replkey_size = user->privKeyLen;
            replkey = &user->privKey;
        }

        /*
         * is it large enough? 
         */
        if (key_len < replkey_size)
            return MFD_ERROR;

        /*
         * copy right most bits, per the object requirements 
         */
        SNMP_FREE(*replkey);
        memdup(replkey, key + key_len - replkey_size, replkey_size);

        return MFD_SUCCESS;
    }

    return MFD_ERROR;
}

/** @ingroup data_access 
 * @defgroup data_set data_set: Routines to set data
 *
 * These routines are used to set the value for individual objects. The
 * row context is passed, along with the new value.
 * 
 * @{
 */
/**********************************************************************
 **********************************************************************
 ***
 *** Table usmDHUserKeyTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * SNMP-USM-DH-OBJECTS-MIB::usmDHUserKeyTable is subid 2 of usmDHPublicObjects.
 * Its status is Current.
 * OID: .1.3.6.1.3.101.1.1.2, length: 9
 */
    /*
     * NOTE: if you update this chart, please update the versions in
     *       local/mib2c-conf.d/parent-set.m2i
     *       agent/mibgroup/helpers/baby_steps.c
     * while you're at it.
     */
    /*
     ***********************************************************************
     * Baby Steps Flow Chart (2004.06.05)                                  *
     *                                                                     *
     * +--------------+    +================+    U = unconditional path    *
     * |optional state|    ||required state||    S = path for success      *
     * +--------------+    +================+    E = path for error        *
     ***********************************************************************
     *
     *                        +--------------+
     *                        |     pre      |
     *                        |   request    |
     *                        +--------------+
     *                               | U
     *                        +==============+
     *       +----------------||  object    ||
     *       |              E ||  lookup    ||
     *       |                +==============+
     *       |                       | S
     *       |                +==============+
     *       |              E ||   check    ||
     *       |<---------------||   values   ||
     *       |                +==============+
     *       |                       | S
     *       |                +==============+
     *       |       +<-------||   undo     ||
     *       |       |      E ||   setup    ||
     *       |       |        +==============+
     *       |       |               | S
     *       |       |        +==============+
     *       |       |        ||    set     ||-------------------------->+
     *       |       |        ||   value    || E                         |
     *       |       |        +==============+                           |
     *       |       |               | S                                 |
     *       |       |        +--------------+                           |
     *       |       |        |    check     |-------------------------->|
     *       |       |        |  consistency | E                         |
     *       |       |        +--------------+                           |
     *       |       |               | S                                 |
     *       |       |        +==============+         +==============+  |
     *       |       |        ||   commit   ||-------->||     undo   ||  |
     *       |       |        ||            || E       ||    commit  ||  |
     *       |       |        +==============+         +==============+  |
     *       |       |               | S                     U |<--------+
     *       |       |        +--------------+         +==============+
     *       |       |        | irreversible |         ||    undo    ||
     *       |       |        |    commit    |         ||     set    ||
     *       |       |        +--------------+         +==============+
     *       |       |               | U                     U |
     *       |       +-------------->|<------------------------+
     *       |                +==============+
     *       |                ||   undo     ||
     *       |                ||  cleanup   ||
     *       |                +==============+
     *       +---------------------->| U
     *                        +--------------+
     *                        |    post      |
     *                        |   request    |
     *                        +--------------+
     *
     */

/**
 * Setup up context with information needed to undo a set request.
 *
 * This function will be called before the individual node undo setup
 * functions are called. If you need to do any undo setup that is not
 * related to a specific column, you can do it here.
 *
 * Note that the undo context has been allocated with
 * usmDHUserKeyTable_allocate_data(), but may need extra
 * initialization similar to what you may have done in
 * usmDHUserKeyTable_rowreq_ctx_init().
 * Note that an individual node's undo_setup function will only be called
 * if that node is being set to a new value.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in the node's undo_setup
 * function, so it won't be done unless it is necessary.
 *
 * @param rowreq_ctx
 *        Pointer to the table context (usmDHUserKeyTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 */
int
usmDHUserKeyTable_undo_setup(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserKeyTable_undo_setup",
                "called\n"));

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);
    /*
     * TODO:451:M: |-> Setup usmDHUserKeyTable undo.
     * set up usmDHUserKeyTable undo information, in preparation for a set.
     * Undo storage is in (* usmDHUserOwnPrivKeyChange_val_ptr_ptr )*
     */

    return rc;
}                               /* usmDHUserKeyTable_undo_setup */

/**
 * Undo a set request.
 *
 * This function will be called before the individual node undo
 * functions are called. If you need to do any undo that is not
 * related to a specific column, you can do it here.
 *
 * Note that an individual node's undo function will only be called
 * if that node is being set to a new value.
 *
 * If there is anything  specific to a particular column (e.g. releasing
 * memory for a string), you should do that setup in the node's undo
 * function, so it won't be done unless it is necessary.
 *
 * @param rowreq_ctx
 *        Pointer to the table context (usmDHUserKeyTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 */
int
usmDHUserKeyTable_undo(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserKeyTable_undo",
                "called\n"));

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:451:M: |-> usmDHUserKeyTable undo.
     * usmDHUserKeyTable undo information, in response to a failed set.
     * Undo storage is in (* usmDHUserOwnPrivKeyChange_val_ptr_ptr )*
     */

    return rc;
}                               /* usmDHUserKeyTable_undo_setup */

/**
 * Cleanup up context undo information.
 *
 * This function will be called after set/commit processing. If you
 * allocated any resources in undo_setup, this is the place to release
 * those resources.
 *
 * This function is called regardless of the success or failure of the set
 * request. If you need to perform different steps for cleanup depending
 * on success or failure, you can add a flag to the rowreq_ctx.
 *
 * @param rowreq_ctx
 *        Pointer to the table context (usmDHUserKeyTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error
 */
int
usmDHUserKeyTable_undo_cleanup(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserKeyTable_undo_cleanup",
                "called\n"));
    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:452:M: |-> Cleanup usmDHUserKeyTable undo.
     * Undo storage is in (* usmDHUserOwnPrivKeyChange_val_ptr_ptr )*
     */

    return rc;
}                               /* usmDHUserKeyTable_undo_cleanup */

/**
 * commit new values.
 *
 * At this point, you should have done everything you can to ensure that
 * this commit will not fail.
 *
 * Should you need different behavior depending on which columns were
 * set, rowreq_ctx->column_set_flags will indicate which writeable columns were
 * set. The definitions for the COLUMN_*_FLAG bits can be found in
 * usmDHUserKeyTable_oids.h.
 * A new row will have the MFD_ROW_CREATED bit set in rowreq_flags.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error
 */
int
usmDHUserKeyTable_commit(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserKeyTable_commit",
                "called\n"));

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * nothing to do; we wait for the irreversible commit
     */

    /*
     * if we successfully commited this row, set the dirty flag.
     */
    if (MFD_SUCCESS == rc) {
        rowreq_ctx->rowreq_flags |= MFD_ROW_DIRTY;
    }

    return rc;
}                               /* usmDHUserKeyTable_commit */

/**
 * undo commit new values.
 *
 * Should you need different behavior depending on which columns were
 * set, rowreq_ctx->column_set_flags will indicate which writeable columns were
 * set. The definitions for the COLUMN_*_FLAG bits can be found in
 * usmDHUserKeyTable_oids.h.
 * A new row will have the MFD_ROW_CREATED bit set in rowreq_flags.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error
 */
int
usmDHUserKeyTable_undo_commit(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserKeyTable_undo_commit",
                "called\n"));

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:485:M: |-> Undo usmDHUserKeyTable commit.
     * check the column's flag in rowreq_ctx->column_set_flags to see
     * if it was set during commit, then undo it.
     *
     * eg: if (rowreq_ctx->column_set_flags & COLUMN__FLAG) {}
     */


    /*
     * if we successfully un-commited this row, clear the dirty flag.
     */
    if (MFD_SUCCESS == rc) {
        rowreq_ctx->rowreq_flags &= ~MFD_ROW_DIRTY;
    }

    return rc;
}                               /* usmDHUserKeyTable_undo_commit */

/**
 * perform commit actions that are not reversible
 *
 * THERE IS NO ATTEMPT AT RECOVERY FOR ERRORS FROM THIS STATE!
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : other error
 */
int
usmDHUserKeyTable_irreversible_commit(usmDHUserKeyTable_rowreq_ctx *
                                      rowreq_ctx)
{
    struct usmUser *user;
    int             flags;

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserKeyTable_irreversible_commit", "called\n"));

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:495:o: Irreversible usmDHUserKeyTable commit.
     */
    user = rowreq_ctx->data;
    flags = rowreq_ctx->column_set_flags;

    if (flags & COLUMN_USMDHUSERAUTHKEYCHANGE_FLAG ||
        flags & COLUMN_USMDHUSEROWNAUTHKEYCHANGE_FLAG) {
        /*
         * free the keychange objects so they reset to new values 
         */
        DH_free(user->usmDHUserAuthKeyChange);
        user->usmDHUserAuthKeyChange = NULL;
    }

    if (flags & COLUMN_USMDHUSERPRIVKEYCHANGE_FLAG ||
        flags & COLUMN_USMDHUSEROWNPRIVKEYCHANGE_FLAG) {
        /*
         * free the keychange objects so they reset to new values 
         */
        DH_free(user->usmDHUserPrivKeyChange);
        user->usmDHUserPrivKeyChange = NULL;
    }

    return MFD_SUCCESS;
}                               /* usmDHUserKeyTable_irreversible_commit */

/*
 * TODO:440:M: Implement usmDHUserKeyTable node value checks.
 * TODO:450:M: Implement usmDHUserKeyTable undo functions.
 * TODO:460:M: Implement usmDHUserKeyTable set functions.
 * TODO:480:M: Implement usmDHUserKeyTable commit functions.
 */
/*---------------------------------------------------------------------
 * SNMP-USM-DH-OBJECTS-MIB::usmDHUserKeyEntry.usmDHUserAuthKeyChange
 * usmDHUserAuthKeyChange is subid 1 of usmDHUserKeyEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.3.101.1.1.2.1.1
 * Description:
The object used to change any given user's Authentication Key
    using a Diffie-Hellman key exchange.

    The right-most n bits of the shared secret 'sk', where 'n' is the
    number of bits required for the protocol defined by
    usmUserAuthProtocol, are installed as the operational
    authentication key for this row after a successful SET.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 *
 * Its syntax is DHKeyChange (based on perltype OCTETSTR)
 * The net-snmp type is ASN_OCTET_STR. The C type decl is char (char)
 * This data type requires a length.
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param usmDHUserAuthKeyChange_val_ptr
 *        A char containing the new value.
 * @param usmDHUserAuthKeyChange_val_ptr_len
 *        The size (in bytes) of the data pointed to by usmDHUserAuthKeyChange_val_ptr
 *
 * @retval MFD_SUCCESS        : incoming value is legal
 * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
 *
 * This is the place to check for requirements that are not
 * expressed in the mib syntax (for example, a requirement that
 * is detailed in the description for an object).
 *
 * Since you aren't using a generated data context, you also need to
 * check the length, to make sure you don't overflow your storage space.
 *
 * You should check that the requested change between the undo value and the
 * new value is legal (ie, the transistion from one value to another
 * is legal).
 *      
 *@note
 * This check is only to determine if the new value
 * is \b potentially valid. This is the first check of many, and
 * is one of the simplest ones.
 * 
 *@note
 * this is not the place to do any checks for values
 * which depend on some other value in the mib. Those
 * types of checks should be done in the
 * usmDHUserKeyTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_OCTET_STR
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
usmDHUserAuthKeyChange_check_value(usmDHUserKeyTable_rowreq_ctx *
                                   rowreq_ctx,
                                   u_char *usmDHUserAuthKeyChange_val_ptr,
                                   size_t
                                   usmDHUserAuthKeyChange_val_ptr_len)
{
    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserAuthKeyChange_check_value", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);
    netsnmp_assert(NULL != usmDHUserAuthKeyChange_val_ptr);

    /*
     * TODO:441:o: |-> Check for valid usmDHUserAuthKeyChange value.
     */
    return usmDHUserCheckValue(rowreq_ctx->data, 1,
                               usmDHUserAuthKeyChange_val_ptr,
                               usmDHUserAuthKeyChange_val_ptr_len);
}                               /* usmDHUserAuthKeyChange_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (usmDHUserKeyTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * usmDHUserKeyTable_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
usmDHUserAuthKeyChange_undo_setup(usmDHUserKeyTable_rowreq_ctx *
                                  rowreq_ctx)
{
    struct usmUser *undouser;

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserAuthKeyChange_undo_setup", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:455:o: |-> Setup usmDHUserAuthKeyChange undo.
     */
    /*
     * copy usmDHUserAuthKeyChange and usmDHUserAuthKeyChange_len data
     * set rowreq_ctx->undo->usmDHUserAuthKeyChange from rowreq_ctx->data->usmDHUserAuthKeyChange
     */
    undouser = rowreq_ctx->undo;

    undouser->authKeyLen = rowreq_ctx->data->authKeyLen;
    memdup(&undouser->authKey, rowreq_ctx->data->authKey,
           rowreq_ctx->data->authKeyLen);

    return MFD_SUCCESS;
}                               /* usmDHUserAuthKeyChange_undo_setup */

/**
 * Set the new value.
 *
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param usmDHUserAuthKeyChange_val_ptr
 *        A char containing the new value.
 * @param usmDHUserAuthKeyChange_val_ptr_len
 *        The size (in bytes) of the data pointed to by usmDHUserAuthKeyChange_val_ptr
 */
int
usmDHUserAuthKeyChange_set(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx,
                           u_char *usmDHUserAuthKeyChange_val_ptr,
                           size_t usmDHUserAuthKeyChange_val_ptr_len)
{

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserAuthKeyChange_set",
                "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);
    netsnmp_assert(NULL != usmDHUserAuthKeyChange_val_ptr);

    /*
     * TODO:461:M: |-> Set usmDHUserAuthKeyChange value.
     * set usmDHUserAuthKeyChange value in rowreq_ctx->data
     */
    usmDHSetKey(rowreq_ctx->data, 1,
                usmDHUserAuthKeyChange_val_ptr,
                usmDHUserAuthKeyChange_val_ptr_len);

    return MFD_SUCCESS;
}                               /* usmDHUserAuthKeyChange_set */

/**
 * undo the previous set.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
usmDHUserAuthKeyChange_undo(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx)
{
    struct usmUser *undouser;

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserAuthKeyChange_undo",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up usmDHUserAuthKeyChange undo.
     */
    /*
     * copy usmDHUserAuthKeyChange and usmDHUserAuthKeyChange_len data
     * set rowreq_ctx->data->usmDHUserAuthKeyChange from rowreq_ctx->undo->usmDHUserAuthKeyChange
     */
    undouser = rowreq_ctx->undo;

    undouser->authKeyLen = rowreq_ctx->data->authKeyLen;
    SNMP_FREE(rowreq_ctx->data->authKey);
    rowreq_ctx->data->authKey = undouser->authKey;
    undouser->authKey = NULL;

    return MFD_SUCCESS;
}                               /* usmDHUserAuthKeyChange_undo */

/*---------------------------------------------------------------------
 * SNMP-USM-DH-OBJECTS-MIB::usmDHUserKeyEntry.usmDHUserOwnAuthKeyChange
 * usmDHUserOwnAuthKeyChange is subid 2 of usmDHUserKeyEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.3.101.1.1.2.1.2
 * Description:
The object used to change the agents own Authentication Key
    using a Diffie-Hellman key exchange.

    The right-most n bits of the shared secret 'sk', where 'n' is the
    number of bits required for the protocol defined by
    usmUserAuthProtocol, are installed as the operational
    authentication key for this row after a successful SET.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 *
 * Its syntax is DHKeyChange (based on perltype OCTETSTR)
 * The net-snmp type is ASN_OCTET_STR. The C type decl is char (char)
 * This data type requires a length.
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param usmDHUserOwnAuthKeyChange_val_ptr
 *        A char containing the new value.
 * @param usmDHUserOwnAuthKeyChange_val_ptr_len
 *        The size (in bytes) of the data pointed to by usmDHUserOwnAuthKeyChange_val_ptr
 *
 * @retval MFD_SUCCESS        : incoming value is legal
 * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
 *
 * This is the place to check for requirements that are not
 * expressed in the mib syntax (for example, a requirement that
 * is detailed in the description for an object).
 *
 * Since you aren't using a generated data context, you also need to
 * check the length, to make sure you don't overflow your storage space.
 *
 * You should check that the requested change between the undo value and the
 * new value is legal (ie, the transistion from one value to another
 * is legal).
 *      
 *@note
 * This check is only to determine if the new value
 * is \b potentially valid. This is the first check of many, and
 * is one of the simplest ones.
 * 
 *@note
 * this is not the place to do any checks for values
 * which depend on some other value in the mib. Those
 * types of checks should be done in the
 * usmDHUserKeyTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_OCTET_STR
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
usmDHUserOwnAuthKeyChange_check_value(usmDHUserKeyTable_rowreq_ctx *
                                      rowreq_ctx,
                                      u_char *usmDHUserOwnAuthKeyChange_val_ptr,
                                      size_t
                                      usmDHUserOwnAuthKeyChange_val_ptr_len)
{
    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserOwnAuthKeyChange_check_value", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);
    netsnmp_assert(NULL != usmDHUserOwnAuthKeyChange_val_ptr);

    /*
     * TODO:441:o: |-> Check for valid usmDHUserOwnAuthKeyChange value.
     */
    return
        usmDHUserAuthKeyChange_check_value(rowreq_ctx,
                                           usmDHUserOwnAuthKeyChange_val_ptr,
                                           usmDHUserOwnAuthKeyChange_val_ptr_len);
}                               /* usmDHUserOwnAuthKeyChange_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (usmDHUserKeyTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * usmDHUserKeyTable_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
usmDHUserOwnAuthKeyChange_undo_setup(usmDHUserKeyTable_rowreq_ctx *
                                     rowreq_ctx)
{
    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserOwnAuthKeyChange_undo_setup", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:455:o: |-> Setup usmDHUserOwnAuthKeyChange undo.
     */
    /*
     * copy usmDHUserOwnAuthKeyChange and usmDHUserOwnAuthKeyChange_len data
     * set rowreq_ctx->undo->usmDHUserOwnAuthKeyChange from rowreq_ctx->data->usmDHUserOwnAuthKeyChange
     */
    return usmDHUserAuthKeyChange_undo_setup(rowreq_ctx);
}                               /* usmDHUserOwnAuthKeyChange_undo_setup */

/**
 * Set the new value.
 *
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param usmDHUserOwnAuthKeyChange_val_ptr
 *        A char containing the new value.
 * @param usmDHUserOwnAuthKeyChange_val_ptr_len
 *        The size (in bytes) of the data pointed to by usmDHUserOwnAuthKeyChange_val_ptr
 */
int
usmDHUserOwnAuthKeyChange_set(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx,
                              u_char *usmDHUserOwnAuthKeyChange_val_ptr,
                              size_t usmDHUserOwnAuthKeyChange_val_ptr_len)
{

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserOwnAuthKeyChange_set",
                "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);
    netsnmp_assert(NULL != usmDHUserOwnAuthKeyChange_val_ptr);

    /*
     * TODO:461:M: |-> Set usmDHUserOwnAuthKeyChange value.
     * set usmDHUserOwnAuthKeyChange value in rowreq_ctx->data
     */
    return usmDHUserAuthKeyChange_set(rowreq_ctx,
                                      usmDHUserOwnAuthKeyChange_val_ptr,
                                      usmDHUserOwnAuthKeyChange_val_ptr_len);
}                               /* usmDHUserOwnAuthKeyChange_set */

/**
 * undo the previous set.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
usmDHUserOwnAuthKeyChange_undo(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx)
{

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserOwnAuthKeyChange_undo",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up usmDHUserOwnAuthKeyChange undo.
     */
    /*
     * copy usmDHUserOwnAuthKeyChange and usmDHUserOwnAuthKeyChange_len data
     * set rowreq_ctx->data->usmDHUserOwnAuthKeyChange from rowreq_ctx->undo->usmDHUserOwnAuthKeyChange
     */
    return usmDHUserAuthKeyChange_undo(rowreq_ctx);
}                               /* usmDHUserOwnAuthKeyChange_undo */

/*---------------------------------------------------------------------
 * SNMP-USM-DH-OBJECTS-MIB::usmDHUserKeyEntry.usmDHUserPrivKeyChange
 * usmDHUserPrivKeyChange is subid 3 of usmDHUserKeyEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.3.101.1.1.2.1.3
 * Description:
The object used to change any given user's Privacy Key using
    a Diffie-Hellman key exchange.

    The right-most n bits of the shared secret 'sk', where 'n' is the
    number of bits required for the protocol defined by
    usmUserPrivProtocol, are installed as the operational privacy key
    for this row after a successful SET.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 *
 * Its syntax is DHKeyChange (based on perltype OCTETSTR)
 * The net-snmp type is ASN_OCTET_STR. The C type decl is char (char)
 * This data type requires a length.
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param usmDHUserPrivKeyChange_val_ptr
 *        A char containing the new value.
 * @param usmDHUserPrivKeyChange_val_ptr_len
 *        The size (in bytes) of the data pointed to by usmDHUserPrivKeyChange_val_ptr
 *
 * @retval MFD_SUCCESS        : incoming value is legal
 * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
 *
 * This is the place to check for requirements that are not
 * expressed in the mib syntax (for example, a requirement that
 * is detailed in the description for an object).
 *
 * Since you aren't using a generated data context, you also need to
 * check the length, to make sure you don't overflow your storage space.
 *
 * You should check that the requested change between the undo value and the
 * new value is legal (ie, the transistion from one value to another
 * is legal).
 *      
 *@note
 * This check is only to determine if the new value
 * is \b potentially valid. This is the first check of many, and
 * is one of the simplest ones.
 * 
 *@note
 * this is not the place to do any checks for values
 * which depend on some other value in the mib. Those
 * types of checks should be done in the
 * usmDHUserKeyTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_OCTET_STR
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
usmDHUserPrivKeyChange_check_value(usmDHUserKeyTable_rowreq_ctx *
                                   rowreq_ctx,
                                   u_char *usmDHUserPrivKeyChange_val_ptr,
                                   size_t
                                   usmDHUserPrivKeyChange_val_ptr_len)
{
    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserPrivKeyChange_check_value", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);
    netsnmp_assert(NULL != usmDHUserPrivKeyChange_val_ptr);

    /*
     * TODO:441:o: |-> Check for valid usmDHUserPrivKeyChange value.
     */
    return usmDHUserCheckValue(rowreq_ctx->data, 0,
                               usmDHUserPrivKeyChange_val_ptr,
                               usmDHUserPrivKeyChange_val_ptr_len);
}                               /* usmDHUserPrivKeyChange_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (usmDHUserKeyTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * usmDHUserKeyTable_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
usmDHUserPrivKeyChange_undo_setup(usmDHUserKeyTable_rowreq_ctx *
                                  rowreq_ctx)
{
    struct usmUser *undouser;

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserPrivKeyChange_undo_setup", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:455:o: |-> Setup usmDHUserPrivKeyChange undo.
     */
    /*
     * copy usmDHUserPrivKeyChange and usmDHUserPrivKeyChange_len data
     * set rowreq_ctx->undo->usmDHUserPrivKeyChange from rowreq_ctx->data->usmDHUserPrivKeyChange
     */
    undouser = rowreq_ctx->undo;

    undouser->privKeyLen = rowreq_ctx->data->privKeyLen;
    memdup(&undouser->privKey, rowreq_ctx->data->privKey,
           rowreq_ctx->data->privKeyLen);

    return MFD_SUCCESS;
}                               /* usmDHUserPrivKeyChange_undo_setup */

/**
 * Set the new value.
 *
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param usmDHUserPrivKeyChange_val_ptr
 *        A char containing the new value.
 * @param usmDHUserPrivKeyChange_val_ptr_len
 *        The size (in bytes) of the data pointed to by usmDHUserPrivKeyChange_val_ptr
 */
int
usmDHUserPrivKeyChange_set(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx,
                           u_char *usmDHUserPrivKeyChange_val_ptr,
                           size_t usmDHUserPrivKeyChange_val_ptr_len)
{

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserPrivKeyChange_set",
                "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);
    netsnmp_assert(NULL != usmDHUserPrivKeyChange_val_ptr);

    /*
     * TODO:461:M: |-> Set usmDHUserPrivKeyChange value.
     * set usmDHUserPrivKeyChange value in rowreq_ctx->data
     */
    usmDHSetKey(rowreq_ctx->data, 0,
                usmDHUserPrivKeyChange_val_ptr,
                usmDHUserPrivKeyChange_val_ptr_len);

    return MFD_SUCCESS;
}                               /* usmDHUserPrivKeyChange_set */

/**
 * undo the previous set.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
usmDHUserPrivKeyChange_undo(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx)
{
    struct usmUser *undouser;

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserPrivKeyChange_undo",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up usmDHUserPrivKeyChange undo.
     */
    /*
     * copy usmDHUserPrivKeyChange and usmDHUserPrivKeyChange_len data
     * set rowreq_ctx->data->usmDHUserPrivKeyChange from rowreq_ctx->undo->usmDHUserPrivKeyChange
     */
    undouser = rowreq_ctx->undo;

    /** uncopy priv key */
    undouser->privKeyLen = rowreq_ctx->data->privKeyLen;
    SNMP_FREE(rowreq_ctx->data->privKey);
    rowreq_ctx->data->privKey = undouser->privKey;
    undouser->privKey = NULL;

    return MFD_SUCCESS;
}                               /* usmDHUserPrivKeyChange_undo */

/*---------------------------------------------------------------------
 * SNMP-USM-DH-OBJECTS-MIB::usmDHUserKeyEntry.usmDHUserOwnPrivKeyChange
 * usmDHUserOwnPrivKeyChange is subid 4 of usmDHUserKeyEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.3.101.1.1.2.1.4
 * Description:
The object used to change the agent's own Privacy Key using a
    Diffie-Hellman key exchange.

    The right-most n bits of the shared secret 'sk', where 'n' is the
    number of bits required for the protocol defined by
    usmUserPrivProtocol, are installed as the operational privacy key
    for this row after a successful SET.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 *
 * Its syntax is DHKeyChange (based on perltype OCTETSTR)
 * The net-snmp type is ASN_OCTET_STR. The C type decl is char (char)
 * This data type requires a length.
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param usmDHUserOwnPrivKeyChange_val_ptr
 *        A char containing the new value.
 * @param usmDHUserOwnPrivKeyChange_val_ptr_len
 *        The size (in bytes) of the data pointed to by usmDHUserOwnPrivKeyChange_val_ptr
 *
 * @retval MFD_SUCCESS        : incoming value is legal
 * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
 *
 * This is the place to check for requirements that are not
 * expressed in the mib syntax (for example, a requirement that
 * is detailed in the description for an object).
 *
 * Since you aren't using a generated data context, you also need to
 * check the length, to make sure you don't overflow your storage space.
 *
 * You should check that the requested change between the undo value and the
 * new value is legal (ie, the transistion from one value to another
 * is legal).
 *      
 *@note
 * This check is only to determine if the new value
 * is \b potentially valid. This is the first check of many, and
 * is one of the simplest ones.
 * 
 *@note
 * this is not the place to do any checks for values
 * which depend on some other value in the mib. Those
 * types of checks should be done in the
 * usmDHUserKeyTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_OCTET_STR
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
usmDHUserOwnPrivKeyChange_check_value(usmDHUserKeyTable_rowreq_ctx *
                                      rowreq_ctx,
                                      u_char *usmDHUserOwnPrivKeyChange_val_ptr,
                                      size_t
                                      usmDHUserOwnPrivKeyChange_val_ptr_len)
{
    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserOwnPrivKeyChange_check_value", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);
    netsnmp_assert(NULL != usmDHUserOwnPrivKeyChange_val_ptr);

    /*
     * TODO:441:o: |-> Check for valid usmDHUserOwnPrivKeyChange value.
     */
    return
        usmDHUserPrivKeyChange_check_value(rowreq_ctx,
                                           usmDHUserOwnPrivKeyChange_val_ptr,
                                           usmDHUserOwnPrivKeyChange_val_ptr_len);
}                               /* usmDHUserOwnPrivKeyChange_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (usmDHUserKeyTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * usmDHUserKeyTable_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
usmDHUserOwnPrivKeyChange_undo_setup(usmDHUserKeyTable_rowreq_ctx *
                                     rowreq_ctx)
{
    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserOwnPrivKeyChange_undo_setup", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:455:o: |-> Setup usmDHUserOwnPrivKeyChange undo.
     */
    /*
     * copy usmDHUserOwnPrivKeyChange and usmDHUserOwnPrivKeyChange_len data
     * set rowreq_ctx->undo->usmDHUserOwnPrivKeyChange from rowreq_ctx->data->usmDHUserOwnPrivKeyChange
     */
    return usmDHUserPrivKeyChange_undo_setup(rowreq_ctx);
}                               /* usmDHUserOwnPrivKeyChange_undo_setup */

/**
 * Set the new value.
 *
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param usmDHUserOwnPrivKeyChange_val_ptr
 *        A char containing the new value.
 * @param usmDHUserOwnPrivKeyChange_val_ptr_len
 *        The size (in bytes) of the data pointed to by usmDHUserOwnPrivKeyChange_val_ptr
 */
int
usmDHUserOwnPrivKeyChange_set(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx,
                              u_char *usmDHUserOwnPrivKeyChange_val_ptr,
                              size_t usmDHUserOwnPrivKeyChange_val_ptr_len)
{

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserOwnPrivKeyChange_set",
                "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);
    netsnmp_assert(NULL != usmDHUserOwnPrivKeyChange_val_ptr);

    /*
     * TODO:461:M: |-> Set usmDHUserOwnPrivKeyChange value.
     * set usmDHUserOwnPrivKeyChange value in rowreq_ctx->data
     */
    return usmDHUserPrivKeyChange_set(rowreq_ctx,
                                      usmDHUserOwnPrivKeyChange_val_ptr,
                                      usmDHUserOwnPrivKeyChange_val_ptr_len);
}                               /* usmDHUserOwnPrivKeyChange_set */

/**
 * undo the previous set.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
usmDHUserOwnPrivKeyChange_undo(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx)
{

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserOwnPrivKeyChange_undo",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up usmDHUserOwnPrivKeyChange undo.
     */
    /*
     * copy usmDHUserOwnPrivKeyChange and usmDHUserOwnPrivKeyChange_len data
     * set rowreq_ctx->data->usmDHUserOwnPrivKeyChange from rowreq_ctx->undo->usmDHUserOwnPrivKeyChange
     */
    return usmDHUserPrivKeyChange_undo(rowreq_ctx);
}                               /* usmDHUserOwnPrivKeyChange_undo */

/**
 * check dependencies
 *
 * This is useful for for tables which have dependencies between columns
 * (or rows, or tables). For example, two columns allocating a percentage
 * of something add up 100%.
 *
 * Should you need different behavior depending on which columns were
 * set, rowreq_ctx->column_set_flags will indicate which writeable columns were
 * set. The definitions for the COLUMN_*_FLAG bits can be found in
 * usmDHUserKeyTable_oids.h.
 * A new row will have the MFD_ROW_CREATED bit set in rowreq_flags.
 *
 * @retval MFD_SUCCESS all the changes to the row are legal
 * @retval MFD_ERROR   one or more changes are not legal
 *
 * (see README-table-usmDHUserKeyTable if you don't have dependencies)
 */
int
usmDHUserKeyTable_check_dependencies(usmDHUserKeyTable_rowreq_ctx *
                                     rowreq_ctx)
{
    int             rc = MFD_SUCCESS;
    int             flags;

    DEBUGMSGTL(("internal:usmDHUserKeyTable:usmDHUserKeyTable_check_dependencies", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:470:o: Check usmDHUserKeyTable row dependencies.
     * check that all new value are legal and consistent with each other
     */
    flags = rowreq_ctx->column_set_flags;

    if (flags & COLUMN_USMDHUSERAUTHKEYCHANGE_FLAG &&
        flags & COLUMN_USMDHUSEROWNAUTHKEYCHANGE_FLAG) {
        return MFD_ERROR;
    }

    if (flags & COLUMN_USMDHUSERPRIVKEYCHANGE_FLAG &&
        flags & COLUMN_USMDHUSEROWNPRIVKEYCHANGE_FLAG) {
        return MFD_ERROR;
    }

    return rc;
}                               /* usmDHUserKeyTable_check_dependencies */

/** @} */
