/*
 * 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,
                    char *val, size_t val_len)
{
    /*
     * The set value must be composed of 2 parts, the first being the
     * current value 
     */
    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,
            char *val, size_t val_len)
{
    DH             *dh;
    BIGNUM         *other_pub;
    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);
        *replkey = netsnmp_memdup(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;
    int             save_flags;

    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,
                                   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;
    undouser->authKey = netsnmp_memdup(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,
                           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, 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,
                              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,
                                   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;
    undouser->privKey = netsnmp_memdup(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,
                           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, 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,
                              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 */

/** @} */
