⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snmpusm.c

📁 snmp up 2
💻 C
📖 第 1 页 / 共 5 页
字号:
     */    if (theSecLevel == SNMP_SEC_LEVEL_AUTHPRIV) {        offSet = ptr_len - remaining;        asn_build_header(&ptr[offSet],                         &remaining,                         (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE |                                   ASN_OCTET_STR),                         theTotalLength - dataOffset);    }    /*     * Adjust overall length and store it as the first SEQ length     * of the SNMPv3Message.     *     * FIX  4 is a magic number!     */    remaining = theTotalLength;    asn_build_sequence(ptr, &remaining,                       (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR),                       theTotalLength - 4);    /*     * Now, time to consider / do authentication.     */    if (theSecLevel == SNMP_SEC_LEVEL_AUTHNOPRIV        || theSecLevel == SNMP_SEC_LEVEL_AUTHPRIV) {        size_t          temp_sig_len = msgAuthParmLen;        u_char         *temp_sig = (u_char *) malloc(temp_sig_len);        if (temp_sig == NULL) {            DEBUGMSGTL(("usm", "Out of memory.\n"));            usm_free_usmStateReference(secStateRef);            return SNMPERR_USM_GENERICERROR;        }        if (sc_generate_keyed_hash(theAuthProtocol, theAuthProtocolLength,                                   theAuthKey, theAuthKeyLength,                                   ptr, ptr_len, temp_sig, &temp_sig_len)            != SNMP_ERR_NOERROR) {            /*             * FIX temp_sig_len defined?!             */            SNMP_ZERO(temp_sig, temp_sig_len);            SNMP_FREE(temp_sig);            DEBUGMSGTL(("usm", "Signing failed.\n"));            usm_free_usmStateReference(secStateRef);            return SNMPERR_USM_AUTHENTICATIONFAILURE;        }        if (temp_sig_len != msgAuthParmLen) {            SNMP_ZERO(temp_sig, temp_sig_len);            SNMP_FREE(temp_sig);            DEBUGMSGTL(("usm", "Signing lengths failed.\n"));            usm_free_usmStateReference(secStateRef);            return SNMPERR_USM_AUTHENTICATIONFAILURE;        }        memcpy(&ptr[authParamsOffset], temp_sig, msgAuthParmLen);        SNMP_ZERO(temp_sig, temp_sig_len);        SNMP_FREE(temp_sig);    }    /*     * endif -- create keyed hash      */    usm_free_usmStateReference(secStateRef);    DEBUGMSGTL(("usm", "USM processing completed.\n"));    return SNMPERR_SUCCESS;}                               /* end usm_generate_out_msg() */#ifdef USE_REVERSE_ASNENCODINGintusm_secmod_rgenerate_out_msg(struct snmp_secmod_outgoing_params *parms){    if (!parms)        return SNMPERR_GENERR;    return usm_rgenerate_out_msg(parms->msgProcModel,                                 parms->globalData, parms->globalDataLen,                                 parms->maxMsgSize, parms->secModel,                                 parms->secEngineID, parms->secEngineIDLen,                                 parms->secName, parms->secNameLen,                                 parms->secLevel,                                 parms->scopedPdu, parms->scopedPduLen,                                 parms->secStateRef,                                 parms->wholeMsg, parms->wholeMsgLen,                                 parms->wholeMsgOffset);}intusm_rgenerate_out_msg(int msgProcModel, /* (UNUSED) */                      u_char * globalData,      /* IN */                      /*                       * points at the msgGlobalData, which is of length given by next                        * parameter.                         */                      size_t globalDataLen,     /* IN - Length of msg header data.      */                      int maxMsgSize,   /* (UNUSED) */                      int secModel,     /* (UNUSED) */                      u_char * secEngineID,     /* IN - Pointer snmpEngineID.           */                      size_t secEngineIDLen,    /* IN - SnmpEngineID length.            */                      char *secName,    /* IN - Pointer to securityName.        */                      size_t secNameLen,        /* IN - SecurityName length.            */                      int secLevel,     /* IN - AuthNoPriv, authPriv etc.       */                      u_char * scopedPdu,       /* IN */                      /*                       * Pointer to scopedPdu will be encrypted by USM if needed                       * * and written to packet buffer immediately following                       * * securityParameters, entire msg will be authenticated by                       * * USM if needed.                       */                      size_t scopedPduLen,      /* IN - scopedPdu length. */                      void *secStateRef,        /* IN */                      /*                       * secStateRef, pointer to cached info provided only for                       * * Response, otherwise NULL.                       */                      u_char ** wholeMsg,       /*  IN/OUT  */                      /*                       * Points at the pointer to the packet buffer, which might get extended                       * if necessary via realloc().                         */                      size_t * wholeMsgLen,     /*  IN/OUT  */                      /*                       * Length of the entire packet buffer, **not** the length of the                       * packet.                         */                      size_t * offset   /*  IN/OUT  */                      /*                       * Offset from the end of the packet buffer to the start of the packet,                       * also known as the packet length.                         */    ){    size_t          msgAuthParmLen = 0;#ifdef SNMP_TESTING_CODE    size_t          theTotalLength;#endif    u_int           boots_uint;    u_int           time_uint;    long            boots_long;    long            time_long;    /*     * Indirection because secStateRef values override parameters.     *      * None of these are to be free'd - they are either pointing to     * what's in the secStateRef or to something either in the     * actual prarmeter list or the user list.     */    char           *theName = NULL;    u_int           theNameLength = 0;    u_char         *theEngineID = NULL;    u_int           theEngineIDLength = 0;    u_char         *theAuthKey = NULL;    u_int           theAuthKeyLength = 0;    const oid      *theAuthProtocol = NULL;    u_int           theAuthProtocolLength = 0;    u_char         *thePrivKey = NULL;    u_int           thePrivKeyLength = 0;    const oid      *thePrivProtocol = NULL;    u_int           thePrivProtocolLength = 0;    int             theSecLevel = 0;    /* No defined const for bad                                         * value (other then err). */    size_t          salt_length = 0, save_salt_length = 0, save_salt_offset = 0;    u_char          salt[BYTESIZE(USM_MAX_SALT_LENGTH)];    u_char          authParams[USM_MAX_AUTHSIZE];    u_char          iv[BYTESIZE(USM_MAX_SALT_LENGTH)];    size_t          sp_offset = 0, mac_offset = 0;    int             rc = 0;    DEBUGMSGTL(("usm", "USM processing has begun (offset %d)\n", *offset));    if (secStateRef != NULL) {        /*         * To hush the compiler for now.  XXX          */        struct usmStateReference *ref            = (struct usmStateReference *) secStateRef;        theName = ref->usr_name;        theNameLength = ref->usr_name_length;        theEngineID = ref->usr_engine_id;        theEngineIDLength = ref->usr_engine_id_length;        if (!theEngineIDLength) {            theEngineID = secEngineID;            theEngineIDLength = secEngineIDLen;        }        theAuthProtocol = ref->usr_auth_protocol;        theAuthProtocolLength = ref->usr_auth_protocol_length;        theAuthKey = ref->usr_auth_key;        theAuthKeyLength = ref->usr_auth_key_length;        thePrivProtocol = ref->usr_priv_protocol;        thePrivProtocolLength = ref->usr_priv_protocol_length;        thePrivKey = ref->usr_priv_key;        thePrivKeyLength = ref->usr_priv_key_length;        theSecLevel = ref->usr_sec_level;    }    /*     * * Identify the user record.     */    else {        struct usmUser *user;        /*         * we do allow an unknown user name for         * unauthenticated requests.          */        if ((user = usm_get_user(secEngineID, secEngineIDLen, secName))            == NULL && secLevel != SNMP_SEC_LEVEL_NOAUTH) {            DEBUGMSGTL(("usm", "Unknown User\n"));            usm_free_usmStateReference(secStateRef);            return SNMPERR_USM_UNKNOWNSECURITYNAME;        }        theName = secName;        theNameLength = secNameLen;        theEngineID = secEngineID;        theSecLevel = secLevel;        theEngineIDLength = secEngineIDLen;        if (user) {            theAuthProtocol = user->authProtocol;            theAuthProtocolLength = user->authProtocolLen;            theAuthKey = user->authKey;            theAuthKeyLength = user->authKeyLen;            thePrivProtocol = user->privProtocol;            thePrivProtocolLength = user->privProtocolLen;            thePrivKey = user->privKey;            thePrivKeyLength = user->privKeyLen;        } else {            /*             * unknown users can not do authentication (obviously)              */            theAuthProtocol = usmNoAuthProtocol;            theAuthProtocolLength =                sizeof(usmNoAuthProtocol) / sizeof(oid);            theAuthKey = NULL;            theAuthKeyLength = 0;            thePrivProtocol = usmNoPrivProtocol;            thePrivProtocolLength =                sizeof(usmNoPrivProtocol) / sizeof(oid);            thePrivKey = NULL;            thePrivKeyLength = 0;        }    }                           /* endif -- secStateRef==NULL */    /*     * From here to the end of the function, avoid reference to     * secName, secEngineID, secLevel, and associated lengths.     */    /*     * Check to see if the user can use the requested sec services.     */    if (usm_check_secLevel_vs_protocols(theSecLevel,                                        theAuthProtocol,                                        theAuthProtocolLength,                                        thePrivProtocol,                                        thePrivProtocolLength) == 1) {        DEBUGMSGTL(("usm", "Unsupported Security Level or type (%d)\n",                    theSecLevel));        usm_free_usmStateReference(secStateRef);        return SNMPERR_USM_UNSUPPORTEDSECURITYLEVEL;    }    /*     * * Retrieve the engine information.     * *     * * XXX    No error is declared in the EoP when sending messages to     * *        unknown engines, processing continues w/ boots/time == (0,0).     */    if (get_enginetime(theEngineID, theEngineIDLength,                       &boots_uint, &time_uint, FALSE) == -1) {        DEBUGMSGTL(("usm", "%s\n", "Failed to find engine data."));    }    boots_long = boots_uint;    time_long = time_uint;    if (theSecLevel == SNMP_SEC_LEVEL_AUTHPRIV) {        /*         * Initially assume that the ciphertext will end up the same size as         * the plaintext plus some padding.  Really sc_encrypt ought to be able         * to grow this for us, a la asn_realloc_rbuild_<type> functions, but         * this will do for now.           */        u_char         *ciphertext = NULL;        size_t          ciphertextlen = scopedPduLen + 64;        if ((ciphertext = (u_char *) malloc(ciphertextlen)) == NULL) {            DEBUGMSGTL(("usm",                        "couldn't malloc %d bytes for encrypted PDU\n",                        ciphertextlen));            usm_free_usmStateReference(secStateRef);            return SNMPERR_MALLOC;        }        /*         * XXX Hardwired to seek into a 1DES private key!           */#ifdef HAVE_AES        if (ISTRANSFORM(thePrivProtocol, AES128Priv) ||            ISTRANSFORM(thePrivProtocol, AES192Priv) ||            ISTRANSFORM(thePrivProtocol, AES256Priv)) {            salt_length = BYTESIZE(USM_AES_SALT_LENGTH);            save_salt_length = BYTESIZE(USM_AES_SALT_LENGTH)/2;            save_salt_offset = 0;            if (!thePrivKey ||                usm_set_aes_iv(salt, &salt_length,                               htonl(boots_uint), htonl(time_uint),                               iv) == -1) {                DEBUGMSGTL(("usm", "Can't set AES iv.\n"));                usm_free_usmStateReference(secStateRef);                free(ciphertext);                return SNMPERR_USM_GENERICERROR;            }        } else if (ISTRANSFORM(thePrivProtocol, DESPriv)) {#endif            salt_length = BYTESIZE(USM_DES_SALT_LENGTH);            save_salt_length = BYTESIZE(USM_DES_SALT_LENGTH);            save_salt_offset = 0;            if (!thePrivKey || (usm_set_salt(salt, &salt_length,                                             thePrivKey + 8,                                             thePrivKeyLength - 8,                                             iv) == -1)) {                DEBUGMSGTL(("usm", "Can't set DES-CBC salt.\n"));                usm_free_usmStateReference(secStateRef);                free(ciphertext);                return SNMPERR_USM_GENERICERROR;            }#ifdef HAVE_AES        }#endif#ifdef SNMP_TESTING_CODE        if (debug_is_token_registered("usm/dump") == SNMPERR_SUCCESS) {            dump_chunk("usm/dump", "This data was encrypted:",                       scopedPdu, scopedPduLen);        }#endif        if (sc_encrypt(thePrivProtocol, thePrivProtocolLength,                       thePrivKey, thePrivKeyLength,                       salt, salt_length,                       scopedPdu, scopedPduLen,                       ciphertext, &ciphertextlen) != SNMP_ERR_NOERROR) {            DEBUGMSGTL(("usm", "DES-CBC error.\n"));            usm_free_usmStateReference(secStateRef);            free(ciphertext);            return SNMPERR_USM_ENCRYPTIONERROR;        }        /*         * Write the encrypted scopedPdu back into the packet buffer.           */#ifdef SNMP_TESTING_CODE        theTotalLength = *wholeMsgLen;#endif        *offset = 0;        rc = asn_realloc_rbuild_string(wholeMsg, wholeMsgLen, offset, 1,                                       (u_char) (ASN_UNIVERSAL |                                                 ASN_PRIMITIVE |                                                 ASN_OCTET_STR),                                       ciphertext, ciphertextlen);#ifdef SNMP_TESTING_CODE        if (debug_is_token_registered("usm/dump") == SNMPERR_SUCCESS) {            dump_chunk("usm/dump", "salt + Encrypted form: ", salt,                       salt_length);            dump_chunk("usm/dump", "wholeMsg:",                       (*wholeMsg + *wholeMsgLen - *offset), *offset);        }#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -