/*
 * 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);
        *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;

    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;
    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,
                           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;
    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,
                           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 */

/** @} */
