int init_snmpv3_post_config(int majorid, int minorid, void *serverarg, void *clientarg) { int engineIDLen; u_char *c_engineID; c_engineID = snmpv3_generate_engineID(&engineIDLen); if ( engineIDLen < 0 ) { /* Somethine went wrong - help! */ return SNMPERR_GENERR; } /* if our engineID has changed at all, the boots record must be set to 1 */ if (engineIDLen != (int)oldEngineIDLength || oldEngineID == NULL || c_engineID == NULL || memcmp(oldEngineID, c_engineID, engineIDLen) != 0) { engineBoots = 1; } /* set our local engineTime in the LCD timing cache */ set_enginetime(c_engineID, engineIDLen, snmpv3_local_snmpEngineBoots(), snmpv3_local_snmpEngineTime(), TRUE); free(c_engineID); return SNMPERR_SUCCESS; }
int write_ucdDemoResetKeys(int action, u_char * var_val, u_char var_val_type, size_t var_val_len, u_char * statP, oid * name, size_t name_len) { /* * variables we may use later */ static long long_ret; unsigned char *engineID; size_t engineIDLen; int i; struct usmUser *user; if (var_val_type != ASN_INTEGER) { DEBUGMSGTL(("ucdDemoPublic", "write to ucdDemoResetKeys not ASN_INTEGER\n")); return SNMP_ERR_WRONGTYPE; } if (var_val_len > sizeof(long_ret)) { DEBUGMSGTL(("ucdDemoPublic", "write to ucdDemoResetKeys: bad length\n")); return SNMP_ERR_WRONGLENGTH; } if (action == COMMIT) { long_ret = *((long *) var_val); if (long_ret == 1) { engineID = snmpv3_generate_engineID(&engineIDLen); for (i = 0; i < num; i++) { user = usm_get_user(engineID, engineIDLen, demoUsers[i]); if (user) { usm_set_user_password(user, "userSetAuthPass", demopass); usm_set_user_password(user, "userSetPrivPass", demopass); } } /* * reset the keys */ } } return SNMP_ERR_NOERROR; }
int main (int argc, char *argv[]) { netsnmp_session session, *ss; netsnmp_pdu *pdu, *response; oid name[MAX_OID_LEN]; size_t name_length; int arg; int status; char *trap = NULL; char *prognam; int exitval = 0; #ifndef NETSNMP_DISABLE_SNMPV1 char *specific = NULL, *description = NULL, *agent = NULL; in_addr_t *pdu_in_addr_t; #endif prognam = strrchr (argv[0], '/'); if (prognam) prognam++; else prognam = argv[0]; putenv (strdup ("POSIXLY_CORRECT=1")); if (strcmp (prognam, "snmpinform") == 0) inform = 1; switch (arg = snmp_parse_args (argc, argv, &session, "C:", optProc)) { case NETSNMP_PARSE_ARGS_ERROR: exit (1); case NETSNMP_PARSE_ARGS_SUCCESS_EXIT: exit (0); case NETSNMP_PARSE_ARGS_ERROR_USAGE: usage (); exit (1); default: break; } SOCK_STARTUP; session.callback = snmp_input; session.callback_magic = NULL; /* * setup the local engineID which may be for either or both of the * contextEngineID and/or the securityEngineID. */ setup_engineID (NULL, NULL); /* if we don't have a contextEngineID set via command line arguments, use our internal engineID as the context. */ if (session.contextEngineIDLen == 0 || session.contextEngineID == NULL) { session.contextEngineID = snmpv3_generate_engineID (&session.contextEngineIDLen); } if (session.version == SNMP_VERSION_3 && !inform) { /* * for traps, we use ourselves as the authoritative engine * which is really stupid since command line apps don't have a * notion of a persistent engine. Hence, our boots and time * values are probably always really wacked with respect to what * a manager would like to see. * * The following should be enough to: * * 1) prevent the library from doing discovery for engineid & time. * 2) use our engineid instead of the remote engineid for * authoritative & privacy related operations. * 3) The remote engine must be configured with users for our engineID. * * -- Wes */ /* * pick our own engineID */ if (session.securityEngineIDLen == 0 || session.securityEngineID == NULL) { session.securityEngineID = snmpv3_generate_engineID (&session.securityEngineIDLen); } /* * set boots and time, which will cause problems if this * machine ever reboots and a remote trap receiver has cached our * boots and time... I'll cause a not-in-time-window report to * be sent back to this machine. */ if (session.engineBoots == 0) session.engineBoots = 1; if (session.engineTime == 0) /* not really correct, */ session.engineTime = get_uptime (); /* but it'll work. Sort of. */ } ss = snmp_add (&session, netsnmp_transport_open_client ("snmptrap", session.peername), NULL, NULL); if (ss == NULL) { /* * diagnose netsnmp_transport_open_client and snmp_add errors with * the input netsnmp_session pointer */ snmp_sess_perror ("snmptrap", &session); SOCK_CLEANUP; exit (1); } #ifndef NETSNMP_DISABLE_SNMPV1 if (session.version == SNMP_VERSION_1) { if (inform) { fprintf (stderr, "Cannot send INFORM as SNMPv1 PDU\n"); SOCK_CLEANUP; exit (1); } pdu = snmp_pdu_create (SNMP_MSG_TRAP); if (!pdu) { fprintf (stderr, "Failed to create trap PDU\n"); SOCK_CLEANUP; exit (1); } pdu_in_addr_t = (in_addr_t *) pdu->agent_addr; if (arg == argc) { fprintf (stderr, "No enterprise oid\n"); usage (); SOCK_CLEANUP; exit (1); } if (argv[arg][0] == 0) { pdu->enterprise = (oid *) malloc (sizeof (objid_enterprise)); memcpy (pdu->enterprise, objid_enterprise, sizeof (objid_enterprise)); pdu->enterprise_length = sizeof (objid_enterprise) / sizeof (oid); } else { name_length = MAX_OID_LEN; if (!snmp_parse_oid (argv[arg], name, &name_length)) { snmp_perror (argv[arg]); usage (); SOCK_CLEANUP; exit (1); } pdu->enterprise = (oid *) malloc (name_length * sizeof (oid)); memcpy (pdu->enterprise, name, name_length * sizeof (oid)); pdu->enterprise_length = name_length; } if (++arg >= argc) { fprintf (stderr, "Missing agent parameter\n"); usage (); SOCK_CLEANUP; exit (1); } agent = argv[arg]; if (agent != NULL && strlen (agent) != 0) { int ret = netsnmp_gethostbyname_v4 (agent, pdu_in_addr_t); if (ret < 0) { fprintf (stderr, "unknown host: %s\n", agent); exit (1); } } else { *pdu_in_addr_t = get_myaddr (); } if (++arg == argc) { fprintf (stderr, "Missing generic-trap parameter\n"); usage (); SOCK_CLEANUP; exit (1); } trap = argv[arg]; pdu->trap_type = atoi (trap); if (++arg == argc) { fprintf (stderr, "Missing specific-trap parameter\n"); usage (); SOCK_CLEANUP; exit (1); } specific = argv[arg]; pdu->specific_type = atoi (specific); if (++arg == argc) { fprintf (stderr, "Missing uptime parameter\n"); usage (); SOCK_CLEANUP; exit (1); } description = argv[arg]; if (description == NULL || *description == 0) pdu->time = get_uptime (); else pdu->time = atol (description); } else #endif { long sysuptime; char csysuptime[20]; pdu = snmp_pdu_create (inform ? SNMP_MSG_INFORM : SNMP_MSG_TRAP2); if (!pdu) { fprintf (stderr, "Failed to create notification PDU\n"); SOCK_CLEANUP; exit (1); } if (arg == argc) { fprintf (stderr, "Missing up-time parameter\n"); usage (); SOCK_CLEANUP; exit (1); } trap = argv[arg]; if (*trap == 0) { sysuptime = get_uptime (); sprintf (csysuptime, "%ld", sysuptime); trap = csysuptime; } snmp_add_var (pdu, objid_sysuptime, sizeof (objid_sysuptime) / sizeof (oid), 't', trap); if (++arg == argc) { fprintf (stderr, "Missing trap-oid parameter\n"); usage (); SOCK_CLEANUP; exit (1); } if (snmp_add_var (pdu, objid_snmptrap, sizeof (objid_snmptrap) / sizeof (oid), 'o', argv[arg]) != 0) { snmp_perror (argv[arg]); SOCK_CLEANUP; exit (1); } } arg++; while (arg < argc) { arg += 3; if (arg > argc) { fprintf (stderr, "%s: Missing type/value for variable\n", argv[arg - 3]); SOCK_CLEANUP; exit (1); } name_length = MAX_OID_LEN; if (!snmp_parse_oid (argv[arg - 3], name, &name_length)) { snmp_perror (argv[arg - 3]); SOCK_CLEANUP; exit (1); } if (snmp_add_var (pdu, name, name_length, argv[arg - 2][0], argv[arg - 1]) != 0) { snmp_perror (argv[arg - 3]); SOCK_CLEANUP; exit (1); } } if (inform) status = snmp_synch_response (ss, pdu, &response); else status = snmp_send (ss, pdu) == 0; if (status) { snmp_sess_perror (inform ? "snmpinform" : "snmptrap", ss); if (!inform) snmp_free_pdu (pdu); exitval = 1; } else if (inform) snmp_free_pdu (response); snmp_close (ss); snmp_shutdown ("snmpapp"); SOCK_CLEANUP; return exitval; }
void usm_parse_create_usmUser(const char *token, char *line) { char *cp; char buf[SNMP_MAXBUF_MEDIUM]; struct usmUser *newuser; u_char userKey[SNMP_MAXBUF_SMALL], *tmpp; size_t userKeyLen = SNMP_MAXBUF_SMALL; size_t privKeyLen = 0; size_t ret; int ret2; int testcase; newuser = usm_create_user(); /* * READ: Security Name */ cp = copy_nword(line, buf, sizeof(buf)); /* * might be a -e ENGINEID argument */ if (strcmp(buf, "-e") == 0) { size_t ebuf_len = 32, eout_len = 0; u_char *ebuf = (u_char *) malloc(ebuf_len); if (ebuf == NULL) { config_perror("malloc failure processing -e flag"); usm_free_user(newuser); return; } /* * Get the specified engineid from the line. */ cp = copy_nword(cp, buf, sizeof(buf)); if (!snmp_hex_to_binary(&ebuf, &ebuf_len, &eout_len, 1, buf)) { config_perror("invalid EngineID argument to -e"); usm_free_user(newuser); SNMP_FREE(ebuf); return; } newuser->engineID = ebuf; newuser->engineIDLen = eout_len; cp = copy_nword(cp, buf, sizeof(buf)); } else { newuser->engineID = snmpv3_generate_engineID(&ret); if (ret == 0) { usm_free_user(newuser); return; } newuser->engineIDLen = ret; } newuser->secName = strdup(buf); newuser->name = strdup(buf); if (!cp) goto add; /* no authentication or privacy type */ /* * READ: Authentication Type */ #ifndef NETSNMP_DISABLE_MD5 if (strncmp(cp, "MD5", 3) == 0) { memcpy(newuser->authProtocol, usmHMACMD5AuthProtocol, sizeof(usmHMACMD5AuthProtocol)); } else #endif if (strncmp(cp, "SHA", 3) == 0) { memcpy(newuser->authProtocol, usmHMACSHA1AuthProtocol, sizeof(usmHMACSHA1AuthProtocol)); } else { config_perror("Unknown authentication protocol"); usm_free_user(newuser); return; } cp = skip_token(cp); /* * READ: Authentication Pass Phrase or key */ if (!cp) { config_perror("no authentication pass phrase"); usm_free_user(newuser); return; } cp = copy_nword(cp, buf, sizeof(buf)); if (strcmp(buf,"-m") == 0) { /* a master key is specified */ cp = copy_nword(cp, buf, sizeof(buf)); ret = sizeof(userKey); tmpp = userKey; userKeyLen = 0; if (!snmp_hex_to_binary(&tmpp, &ret, &userKeyLen, 0, buf)) { config_perror("invalid key value argument to -m"); usm_free_user(newuser); return; } } else if (strcmp(buf,"-l") != 0) { /* a password is specified */ userKeyLen = sizeof(userKey); ret2 = generate_Ku(newuser->authProtocol, newuser->authProtocolLen, (u_char *) buf, strlen(buf), userKey, &userKeyLen); if (ret2 != SNMPERR_SUCCESS) { config_perror("could not generate the authentication key from the " "supplied pass phrase."); usm_free_user(newuser); return; } } /* * And turn it into a localized key */ ret2 = sc_get_properlength(newuser->authProtocol, newuser->authProtocolLen); if (ret2 <= 0) { config_perror("Could not get proper authentication protocol key length"); return; } newuser->authKey = (u_char *) malloc(ret2); if (strcmp(buf,"-l") == 0) { /* a local key is directly specified */ cp = copy_nword(cp, buf, sizeof(buf)); newuser->authKeyLen = 0; ret = ret2; if (!snmp_hex_to_binary(&newuser->authKey, &ret, &newuser->authKeyLen, 0, buf)) { config_perror("invalid key value argument to -l"); usm_free_user(newuser); return; } if (ret != newuser->authKeyLen) { config_perror("improper key length to -l"); usm_free_user(newuser); return; } } else { newuser->authKeyLen = ret2; ret2 = generate_kul(newuser->authProtocol, newuser->authProtocolLen, newuser->engineID, newuser->engineIDLen, userKey, userKeyLen, newuser->authKey, &newuser->authKeyLen); if (ret2 != SNMPERR_SUCCESS) { config_perror("could not generate localized authentication key " "(Kul) from the master key (Ku)."); usm_free_user(newuser); return; } } if (!cp) goto add; /* no privacy type (which is legal) */ /* * READ: Privacy Type */ testcase = 0; #ifndef NETSNMP_DISABLE_DES if (strncmp(cp, "DES", 3) == 0) { memcpy(newuser->privProtocol, usmDESPrivProtocol, sizeof(usmDESPrivProtocol)); testcase = 1; /* DES uses a 128 bit key, 64 bits of which is a salt */ privKeyLen = 16; } #endif #ifdef HAVE_AES if (strncmp(cp, "AES128", 6) == 0 || strncmp(cp, "AES", 3) == 0) { memcpy(newuser->privProtocol, usmAESPrivProtocol, sizeof(usmAESPrivProtocol)); testcase = 1; privKeyLen = 16; } #endif if (testcase == 0) { config_perror("Unknown privacy protocol"); usm_free_user(newuser); return; } cp = skip_token(cp); /* * READ: Encryption Pass Phrase or key */ if (!cp) { /* * assume the same as the authentication key */ memdup(&newuser->privKey, newuser->authKey, newuser->authKeyLen); newuser->privKeyLen = newuser->authKeyLen; } else { cp = copy_nword(cp, buf, sizeof(buf)); if (strcmp(buf,"-m") == 0) { /* a master key is specified */ cp = copy_nword(cp, buf, sizeof(buf)); ret = sizeof(userKey); tmpp = userKey; userKeyLen = 0; if (!snmp_hex_to_binary(&tmpp, &ret, &userKeyLen, 0, buf)) { config_perror("invalid key value argument to -m"); usm_free_user(newuser); return; } } else if (strcmp(buf,"-l") != 0) { /* a password is specified */ userKeyLen = sizeof(userKey); ret2 = generate_Ku(newuser->authProtocol, newuser->authProtocolLen, (u_char *) buf, strlen(buf), userKey, &userKeyLen); if (ret2 != SNMPERR_SUCCESS) { config_perror("could not generate the privacy key from the " "supplied pass phrase."); usm_free_user(newuser); return; } } /* * And turn it into a localized key */ ret2 = sc_get_properlength(newuser->authProtocol, newuser->authProtocolLen); if (ret2 < 0) { config_perror("could not get proper key length to use for the " "privacy algorithm."); usm_free_user(newuser); return; } newuser->privKey = (u_char *) malloc(ret2); if (strcmp(buf,"-l") == 0) { /* a local key is directly specified */ cp = copy_nword(cp, buf, sizeof(buf)); ret = ret2; newuser->privKeyLen = 0; if (!snmp_hex_to_binary(&newuser->privKey, &ret, &newuser->privKeyLen, 0, buf)) { config_perror("invalid key value argument to -l"); usm_free_user(newuser); return; } } else { newuser->privKeyLen = ret2; ret2 = generate_kul(newuser->authProtocol, newuser->authProtocolLen, newuser->engineID, newuser->engineIDLen, userKey, userKeyLen, newuser->privKey, &newuser->privKeyLen); if (ret2 != SNMPERR_SUCCESS) { config_perror("could not generate localized privacy key " "(Kul) from the master key (Ku)."); usm_free_user(newuser); return; } } } if ((newuser->privKeyLen >= privKeyLen) || (privKeyLen == 0)){ newuser->privKeyLen = privKeyLen; } else { /* The privKey length is smaller than required by privProtocol */ usm_free_user(newuser); return; } add: usm_add_user(newuser); DEBUGMSGTL(("usmUser", "created a new user %s at ", newuser->secName)); DEBUGMSGHEX(("usmUser", newuser->engineID, newuser->engineIDLen)); DEBUGMSG(("usmUser", "\n")); }
void usm_parse_create_usmUser(const char *token, char *line) { char *cp; char buf[SNMP_MAXBUF_MEDIUM]; struct usmUser *newuser; u_char userKey[SNMP_MAXBUF_SMALL]; size_t userKeyLen = SNMP_MAXBUF_SMALL; int ret; newuser = usm_create_user(); /* READ: Security Name */ cp = copy_word(line, buf); newuser->secName = strdup(buf); newuser->name = strdup(buf); newuser->engineID = snmpv3_generate_engineID(&ret); if ( ret < 0 ) { usm_free_user(newuser); return; } newuser->engineIDLen = ret; if (!cp) goto add; /* no authentication or privacy type */ /* READ: Authentication Type */ if (strncmp(cp, "MD5", 3) == 0) { memcpy(newuser->authProtocol, usmHMACMD5AuthProtocol, sizeof(usmHMACMD5AuthProtocol)); } else if (strncmp(cp, "SHA", 3) == 0) { memcpy(newuser->authProtocol, usmHMACSHA1AuthProtocol, sizeof(usmHMACSHA1AuthProtocol)); } else { config_perror("Unknown authentication protocol"); usm_free_user(newuser); return; } cp = skip_token(cp); /* READ: Authentication Pass Phrase */ if (!cp) { config_perror("no authentication pass phrase"); usm_free_user(newuser); return; } cp = copy_word(cp, buf); /* And turn it into a localized key */ ret = generate_Ku(newuser->authProtocol, newuser->authProtocolLen, (u_char *)buf, strlen(buf), userKey, &userKeyLen ); if (ret != SNMPERR_SUCCESS) { config_perror("Error generating auth key from pass phrase."); usm_free_user(newuser); return; } newuser->authKeyLen = sc_get_properlength(newuser->authProtocol, newuser->authProtocolLen); newuser->authKey = (u_char *) malloc(newuser->authKeyLen); ret = generate_kul(newuser->authProtocol, newuser->authProtocolLen, newuser->engineID, newuser->engineIDLen, userKey, userKeyLen, newuser->authKey, &newuser->authKeyLen ); if (ret != SNMPERR_SUCCESS) { config_perror("Error generating localized auth key (Kul) from Ku."); usm_free_user(newuser); return; } if (!cp) goto add; /* no privacy type (which is legal) */ /* READ: Privacy Type */ if (strncmp(cp, "DES", 3) == 0) { memcpy(newuser->privProtocol, usmDESPrivProtocol, sizeof(usmDESPrivProtocol)); } else { config_perror("Unknown privacy protocol"); usm_free_user(newuser); return; } cp = skip_token(cp); /* READ: Authentication Pass Phrase */ if (!cp) { /* assume the same as the authentication key */ memdup(&newuser->privKey, newuser->authKey, newuser->authKeyLen); } else { cp = copy_word(cp, buf); /* And turn it into a localized key */ ret = generate_Ku(newuser->authProtocol, newuser->authProtocolLen, (u_char *)buf, strlen(buf), userKey, &userKeyLen ); if (ret != SNMPERR_SUCCESS) { config_perror("Error generating priv key from pass phrase."); usm_free_user(newuser); return; } ret = sc_get_properlength(newuser->authProtocol, newuser->authProtocolLen); if (ret < 0) { config_perror("Error getting proper key length for priv algorithm."); usm_free_user(newuser); return; } newuser->privKeyLen = ret; newuser->privKey = (u_char *) malloc(newuser->privKeyLen); ret = generate_kul(newuser->authProtocol, newuser->authProtocolLen, newuser->engineID, newuser->engineIDLen, userKey, userKeyLen, newuser->privKey, &newuser->privKeyLen ); if (ret != SNMPERR_SUCCESS) { config_perror("Error generating localized priv key (Kul) from Ku."); usm_free_user(newuser); return; } } add: usm_add_user(newuser); DEBUGMSGTL(("usmUser","created a new user %s\n", newuser->secName)); }