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"));
}
Exemple #2
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));
}