Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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"));
}
Beispiel #5
0
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));
}