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

Reply via email to