Hello Coders,
I have a requirement to create snmp users dynamically at run time from C code.
I have written similar code to snmpusm app and used the same approach.
At first all I want to do is to generate the user using clonefrom user and it
password.
I isolated the relevant code and made a separate executable for you to examine
and even possibly to compile and run.
I created the initial user by adding it to /etc/net-snmp/snmpd.conf file as
suggested by the docs.
If I use snmpsum command as follow
snmpusm -v3 localhost -l authNoPriv -u InitialAuth1 -A setupauth create beyre01
InitialAuth1
the commands works and the user is added, but using my attached code it doesn't.
when I run the attached program I get
"USM unknown security name (no such user exists)" error as a return code for
snmp_synch_response()
call.
I don't know which user is the one generating the error, the one in the
session, or the one in the pdu;
they both are the same in either case.
Have you done similar thing?
If you have and/or by looking at the attached code you can tell me whats is
wrong I would be appreciated.
Thanks,
Bernadette
#include <wait.h>
/* net-snmp header files */
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <net-snmp/agent/snmp_vars.h>
#define CMD_PASSWD_NAME "passwd"
#define CMD_PASSWD 1
#define CMD_CREATE_NAME "create"
#define CMD_CREATE 2
#define CMD_DELETE_NAME "delete"
#define CMD_DELETE 3
#define CMD_CLONEFROM_NAME "cloneFrom"
#define CMD_CLONEFROM 4
#define CMD_ACTIVATE_NAME "activate"
#define CMD_ACTIVATE 5
#define CMD_DEACTIVATE_NAME "deactivate"
#define CMD_DEACTIVATE 6
#define CMD_CHANGEKEY_NAME "changekey"
#define CMD_CHANGEKEY 7
#define CMD_NUM 7
static const char *successNotes[CMD_NUM] = {
"SNMPv3 Key(s) successfully changed.",
"User successfully created.",
"User successfully deleted.",
"User successfully cloned.",
"User successfully activated.",
"User successfully deactivated.",
"SNMPv3 Key(s) successfully changed."
};
#define USM_OID_LEN 12
#define DH_USM_OID_LEN 11
//static oid authKeyOid[MAX_OID_LEN] = { 1, 3, 6, 1, 6, 3, 15, 1, 2, 2, 1, 6 };
//ownAuthKeyOid[MAX_OID_LEN] = {1, 3, 6, 1, 6, 3, 15, 1, 2, 2, 1, 7},
//privKeyOid[MAX_OID_LEN] = {1, 3, 6, 1, 6, 3, 15, 1, 2, 2, 1, 9},
//ownPrivKeyOid[MAX_OID_LEN] = {1, 3, 6, 1, 6, 3, 15, 1, 2, 2, 1, 10},
static oid usmUserCloneFrom[MAX_OID_LEN] = {1, 3, 6, 1, 6, 3, 15, 1, 2, 2, 1, 4};
static oid usmUserSecurityName[MAX_OID_LEN] = {1, 3, 6, 1, 6, 3, 15, 1, 2, 2, 1, 3};
//usmUserPublic[MAX_OID_LEN] = {1, 3, 6, 1, 6, 3, 15, 1, 2, 2, 1, 11},
static oid usmUserStatus[MAX_OID_LEN] = {1, 3, 6, 1, 6, 3, 15, 1, 2, 2, 1, 13};
/* diffie helman change key objects */
//usmDHUserAuthKeyChange[MAX_OID_LEN] = {1, 3, 6, 1, 3, 101, 1, 1, 2, 1, 1 },
//usmDHUserOwnAuthKeyChange[MAX_OID_LEN] = {1, 3, 6, 1, 3, 101, 1, 1, 2, 1, 2 },
//usmDHUserPrivKeyChange[MAX_OID_LEN] = {1, 3, 6, 1, 3, 101, 1, 1, 2, 1, 3 },
//usmDHUserOwnPrivKeyChange[MAX_OID_LEN] = {1, 3, 6, 1, 3, 101, 1, 1, 2, 1, 4 },
static oid usmDHParameters[] = { 1,3,6,1,3,101,1,1,1,0 };
size_t usmDHParameters_len = OID_LENGTH(usmDHParameters);
//static
//oid *authKeyChange = authKeyOid, *privKeyChange = privKeyOid;
//oid *dhauthKeyChange = usmDHUserAuthKeyChange,
// *dhprivKeyChange = usmDHUserPrivKeyChange;
//int doauthkey = 0, doprivkey = 0, uselocalizedkey = 0;
size_t usmUserEngineIDLen = 0;
u_char *usmUserEngineID = NULL;
char *usmUserPublic_val = NULL;
/*
* setup_oid appends to the oid the index for the engineid/user
*/
void
setup_oid(oid * it, size_t * len, u_char * id, size_t idlen,
const char *user)
{
int i, itIndex = *len;
*len = itIndex + 1 + idlen + 1 + strlen(user);
it[itIndex++] = idlen;
for (i = 0; i < (int) idlen; i++) {
it[itIndex++] = id[i];
}
it[itIndex++] = strlen(user);
for (i = 0; i < (int) strlen(user); i++) {
it[itIndex++] = user[i];
}
fprintf(stderr, " user = %s oid len = %d\n", user, *len);
for (i=0; i< *len; i++)
{
fprintf(stderr, "oid[%d] = %d \n", i, (int)it[i]);
}
}
/*__________________________________________________________________________
==========================================================================*/
int main(int argc, char *argv[])
{
netsnmp_session session, *ss;
netsnmp_pdu *pdu = NULL, *response = NULL;
size_t name_length = USM_OID_LEN;
size_t name_length2 = USM_OID_LEN;
int status;
int command = 0;
long longvar;
unsigned int securityNameLen = 0;
snmp_sess_init(&session); /* set up defaults */
session.peername = "localhost";
session.version = SNMP_VERSION_3;
session.flags &= ~SNMP_FLAGS_DONT_PROBE;
/* clone-from user */
securityNameLen = strlen("InitialAuth1");
/* Allocate a buffer for security name*/
if ( (session.securityName = (char *) malloc(securityNameLen)) == NULL )
{
fprintf( stderr, "securityName buffer request failed, no memory \n");
exit (-1);
}
strncpy(session.securityName, "InitialAuth1", securityNameLen);
session.securityNameLen = securityNameLen;
session.securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV;
session.securityAuthProto = usmHMACMD5AuthProtocol;
session.securityAuthProtoLen = USM_AUTH_PROTO_MD5_LEN;
session.securityAuthKeyLen = USM_AUTH_KU_LEN;
if (generate_Ku(session.securityAuthProto,
session.securityAuthProtoLen,
(u_char *) "InitialAuth1", strlen("InitialAuth1"),
session.securityAuthKey,
&session.securityAuthKeyLen) != SNMPERR_SUCCESS)
{
snmp_perror("InitialAuth1");
fprintf( stderr,
" Error generating a key (Ku) from the supplied authentication pass phrase. \n");
exit (-1);
}
init_snmp("add-user");
ss = snmp_open(&session);
if (ss == NULL)
{
/*
* diagnose snmp_open errors with the input netsnmp_session pointer
*/
snmp_sess_perror("add-user", &session);
exit (-1);
}
/*
* set usmUserEngineID from ss->contextEngineID
*/
if (usmUserEngineID == NULL)
{
usmUserEngineID = ss->contextEngineID;
usmUserEngineIDLen = ss->contextEngineIDLen;
fprintf( stderr, "engine id %s\n", usmUserEngineID);
}
/*
* create PDU for SET request and add object names and values to request
*/
pdu = snmp_pdu_create(SNMP_MSG_SET);
if (!pdu)
{
fprintf( stderr, "failed to create snmp request for %s\n", "helloworld");
snmp_close(ss);
exit (-1);
}
command = CMD_CREATE;
pdu->version = SNMP_VERSION_3;
setup_oid(usmUserStatus, &name_length,
usmUserEngineID, usmUserEngineIDLen, "helloworld");
longvar = RS_CREATEANDGO;
snmp_pdu_add_variable(pdu, usmUserStatus, name_length,
ASN_INTEGER, (u_char *) & longvar,
sizeof(longvar));
name_length = USM_OID_LEN;
/* clone-from user */
setup_oid(usmUserCloneFrom, &name_length,
usmUserEngineID, usmUserEngineIDLen,
"helloworld");
setup_oid(usmUserSecurityName, &name_length2,
usmUserEngineID, usmUserEngineIDLen, "InitialAuth1");
if ( (pdu->securityName = (char *) malloc(securityNameLen)) == NULL )
{
fprintf( stderr, " securityName buffer request failed, no memory \n");
exit (-1);
}
strncpy(pdu->securityName, "InitialAuth1", securityNameLen);
pdu->securityNameLen = securityNameLen;
snmp_pdu_add_variable(pdu, usmUserCloneFrom, name_length,
ASN_OBJECT_ID,
(u_char *) usmUserSecurityName,
sizeof(oid) * name_length2);
/*
* do the request
*/
status = snmp_synch_response(ss, pdu, &response);
if (status == STAT_SUCCESS)
{
if (response)
{
if (response->errstat == SNMP_ERR_NOERROR)
{
fprintf(stdout, "%s\n", successNotes[command - 1]);
}
else
{
fprintf(stderr, " Error in the packet - Reason: %s\n",snmp_errstring(response->errstat));
if (response->errindex != 0)
{
int count;
netsnmp_variable_list *vars;
fprintf(stderr, "Failed object: ");
for (count = 1, vars = response->variables;
vars && count != response->errindex;
vars = vars->next_variable, count++)
/*EMPTY*/;
if (vars)
fprint_objid(stderr, vars->name,
vars->name_length);
fprintf(stderr, "\n");
}
exit (-1);
}
}
} else if (status == STAT_TIMEOUT) {
fprintf(stderr, "Timeout: No Response from %s\n",
session.peername);
exit (-1);
} else { /* status == STAT_ERROR */
snmp_sess_perror("snmpset", ss);
exit (-1);
}
if (session.securityName)
free(session.securityName);
if (response)
snmp_free_pdu(response);
// free pdu????
snmp_close(ss);
exit (-1);
}
------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
_______________________________________________
Net-snmp-coders mailing list
Net-snmp-coders@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/net-snmp-coders