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

📄 snmpksm.c

📁 snmp up 2
💻 C
📖 第 1 页 / 共 4 页
字号:
        }        retcode = krb5_auth_con_setrcache(kcontext, auth_context, rcache);        if (retcode) {            DEBUGMSGTL(("ksm", "krb5_auth_con_setrcache failed: %s\n",                        error_message(retcode)));            retval = SNMPERR_KRB5;            snmp_set_detail(error_message(retcode));            goto error;        }        retcode = krb5_rd_req(kcontext, &auth_context, &ap_req, NULL,                              NULL, &flags, &ticket);        krb5_auth_con_setrcache(kcontext, auth_context, NULL);        if (retcode) {            DEBUGMSGTL(("ksm", "krb5_rd_req() failed: %s\n",                        error_message(retcode)));            retval = SNMPERR_KRB5;            snmp_set_detail(error_message(retcode));            goto error;        }        retcode =            krb5_unparse_name(kcontext, ticket->enc_part2->client, &cname);        if (retcode == 0) {            DEBUGMSGTL(("ksm", "KSM authenticated principal name: %s\n",                        cname));            free(cname);        }        /*         * Check to make sure AP_OPTS_MUTUAL_REQUIRED was set         */        if (!(flags & AP_OPTS_MUTUAL_REQUIRED)) {            DEBUGMSGTL(("ksm",                        "KSM MUTUAL_REQUIRED not set in request!\n"));            retval = SNMPERR_KRB5;            snmp_set_detail("MUTUAL_REQUIRED not set in message");            goto error;        }        retcode =            krb5_auth_con_getremotesubkey(kcontext, auth_context, &subkey);        if (retcode) {            DEBUGMSGTL(("ksm", "KSM remote subkey retrieval failed: %s\n",                        error_message(retcode)));            retval = SNMPERR_KRB5;            snmp_set_detail(error_message(retcode));            goto error;        }    } else if (ap_req.length && (ap_req.data[0] == 0x6f ||                                 ap_req.data[0] == 0x4f)) {        /*         * Looks like a response; let's see if we've got that auth_context         * in our cache.         */        krb5_ap_rep_enc_part *repl = NULL;        response = 1;        entry = ksm_get_cache(parms->pdu->msgid);        if (!entry) {            DEBUGMSGTL(("ksm",                        "KSM: Unable to find auth_context for PDU with "                        "message ID of %ld\n", parms->pdu->msgid));            retval = SNMPERR_KRB5;            goto error;        }        auth_context = entry->auth_context;        /*         * In that case, let's call the rd_rep function         */        retcode = krb5_rd_rep(kcontext, auth_context, &ap_req, &repl);        if (repl)            krb5_free_ap_rep_enc_part(kcontext, repl);        if (retcode) {            DEBUGMSGTL(("ksm", "KSM: krb5_rd_rep() failed: %s\n",                        error_message(retcode)));            retval = SNMPERR_KRB5;            goto error;        }        DEBUGMSGTL(("ksm", "KSM: krb5_rd_rep() decoded successfully.\n"));        retcode =            krb5_auth_con_getlocalsubkey(kcontext, auth_context, &subkey);        if (retcode) {            DEBUGMSGTL(("ksm", "Unable to retrieve local subkey: %s\n",                        error_message(retcode)));            retval = SNMPERR_KRB5;            snmp_set_detail("Unable to retrieve local subkey");            goto error;        }    } else {        DEBUGMSGTL(("ksm", "Unknown Kerberos message type (%02x)\n",                    ap_req.data[0]));        retval = SNMPERR_KRB5;        snmp_set_detail("Unknown Kerberos message type");        goto error;    }#ifdef MIT_NEW_CRYPTO    input.data = (char *) parms->wholeMsg;    input.length = parms->wholeMsgLen;    retcode =        krb5_c_verify_checksum(kcontext, subkey, KSM_KEY_USAGE_CHECKSUM,                               &input, &checksum, &valid);#else                           /* MIT_NEW_CRYPTO */    retcode = krb5_verify_checksum(kcontext, cksumtype, &checksum,                                   parms->wholeMsg, parms->wholeMsgLen,                                   (krb5_pointer) subkey->contents,                                   subkey->length);#endif                          /* MIT_NEW_CRYPTO */    if (retcode) {        DEBUGMSGTL(("ksm", "KSM checksum verification failed: %s\n",                    error_message(retcode)));        retval = SNMPERR_KRB5;        snmp_set_detail(error_message(retcode));        goto error;    }    /*     * Don't ask me why they didn't simply return an error, but we have     * to check to see if "valid" is false.     */#ifdef MIT_NEW_CRYPTO    if (!valid) {        DEBUGMSGTL(("ksm", "Computed checksum did not match supplied "                    "checksum!\n"));        retval = SNMPERR_KRB5;        snmp_set_detail            ("Computed checksum did not match supplied checksum");        goto error;    }#endif                          /* MIT_NEW_CRYPTO */    /*     * Handle an encrypted PDU.  Note that it's an OCTET_STRING of the     * output of whatever Kerberos cryptosystem you're using (defined by     * the encryption type).  Note that this is NOT the EncryptedData     * sequence - it's what goes in the "cipher" field of EncryptedData.     */    if (parms->secLevel == SNMP_SEC_LEVEL_AUTHPRIV) {        if ((current = asn_parse_sequence(current, &length, &type,                                          (ASN_UNIVERSAL | ASN_PRIMITIVE |                                           ASN_OCTET_STR), "ksm pdu")) ==            NULL) {            DEBUGMSGTL(("ksm", "KSM sPDU octet decoding failed\n"));            retval = SNMPERR_ASN_PARSE_ERR;            goto error;        }        /*         * The PDU is now pointed at by "current", and the length is in         * "length".         */        DEBUGMSGTL(("ksm", "KSM starting sPDU decode\n"));        /*         * We need to set up a blank initialization vector for the decryption.         * Use a block of all zero's (which is dependent on the block size         * of the encryption method).         */#ifdef MIT_NEW_CRYPTO        retcode = krb5_c_block_size(kcontext, subkey->enctype, &blocksize);        if (retcode) {            DEBUGMSGTL(("ksm",                        "Unable to determine crypto block size: %s\n",                        error_message(retcode)));            snmp_set_detail(error_message(retcode));            retval = SNMPERR_KRB5;            goto error;        }#else                           /* MIT_NEW_CRYPTO */        blocksize =            krb5_enctype_array[subkey->enctype]->system->block_length;#endif                          /* MIT_NEW_CRYPTO */        ivector.data = malloc(blocksize);        if (!ivector.data) {            DEBUGMSGTL(("ksm", "Unable to allocate %d bytes for ivector\n",                        blocksize));            retval = SNMPERR_MALLOC;            goto error;        }        ivector.length = blocksize;        memset(ivector.data, 0, blocksize);#ifndef MIT_NEW_CRYPTO        krb5_use_enctype(kcontext, &eblock, subkey->enctype);        retcode = krb5_process_key(kcontext, &eblock, subkey);        if (retcode) {            DEBUGMSGTL(("ksm", "KSM key post-processing failed: %s\n",                        error_message(retcode)));            snmp_set_detail(error_message(retcode));            retval = SNMPERR_KRB5;            goto error;        }#endif                          /* !MIT_NEW_CRYPTO */        if (length > *parms->scopedPduLen) {            DEBUGMSGTL(("ksm", "KSM not enough room - have %d bytes to "                        "decrypt but only %d bytes available\n", length,                        *parms->scopedPduLen));            retval = SNMPERR_TOO_LONG;#ifndef MIT_NEW_CRYPTO            krb5_finish_key(kcontext, &eblock);#endif                          /* ! MIT_NEW_CRYPTO */            goto error;        }#ifdef MIT_NEW_CRYPTO        in_crypt.ciphertext.data = (char *) current;        in_crypt.ciphertext.length = length;        in_crypt.enctype = subkey->enctype;        output.data = (char *) *parms->scopedPdu;        output.length = *parms->scopedPduLen;        retcode =            krb5_c_decrypt(kcontext, subkey, KSM_KEY_USAGE_ENCRYPTION,                           &ivector, &in_crypt, &output);#else                           /* MIT_NEW_CRYPTO */        retcode = krb5_decrypt(kcontext, (krb5_pointer) current,                               *parms->scopedPdu, length, &eblock,                               ivector.data);        krb5_finish_key(kcontext, &eblock);#endif                          /* MIT_NEW_CRYPTO */        if (retcode) {            DEBUGMSGTL(("ksm", "Decryption failed: %s\n",                        error_message(retcode)));            snmp_set_detail(error_message(retcode));            retval = SNMPERR_KRB5;            goto error;        }        *parms->scopedPduLen = length;    } else {        /*         * Clear PDU         */        *parms->scopedPdu = current;        *parms->scopedPduLen =            parms->wholeMsgLen - (current - parms->wholeMsg);    }    /*     * A HUGE GROSS HACK     */    *parms->maxSizeResponse = parms->maxMsgSize - 200;    DEBUGMSGTL(("ksm", "KSM processing complete\n"));    /*     * Set the secName to the right value (a hack for now).  But that's     * only used for when we're processing a request, not a response.     */    if (!response) {        retcode = krb5_unparse_name(kcontext, ticket->enc_part2->client,                                    &cname);        if (retcode) {            DEBUGMSGTL(("ksm", "KSM krb5_unparse_name failed: %s\n",                        error_message(retcode)));            snmp_set_detail(error_message(retcode));            retval = SNMPERR_KRB5;            goto error;        }        if (strlen(cname) > *parms->secNameLen + 1) {            DEBUGMSGTL(("ksm",                        "KSM: Principal length (%d) is too long (%d)\n",                        strlen(cname), parms->secNameLen));            retval = SNMPERR_TOO_LONG;            free(cname);            goto error;        }        strcpy(parms->secName, cname);        *parms->secNameLen = strlen(cname);        free(cname);        /*         * Also, if we're not a response, keep around our auth_context so we         * can encode the reply message correctly         */        ksm_state = SNMP_MALLOC_STRUCT(ksm_secStateRef);        if (!ksm_state) {            DEBUGMSGTL(("ksm", "KSM unable to malloc memory for "                        "ksm_secStateRef\n"));            retval = SNMPERR_MALLOC;            goto error;        }        ksm_state->auth_context = auth_context;        auth_context = NULL;        ksm_state->cksumtype = cksumtype;        *parms->secStateRef = ksm_state;    } else {        /*         * We _still_ have to set the secName in process_in_msg().  Do         * that now with what we were passed in before (we cached it,         * remember?)         */        memcpy(parms->secName, entry->secName, entry->secNameLen);        *parms->secNameLen = entry->secNameLen;    }    /*     * Just in case     */    parms->secEngineID = (u_char *) "";    *parms->secEngineIDLen = 0;    auth_context = NULL;        /* So we don't try to free it on success */  error:    if (retval == SNMPERR_ASN_PARSE_ERR &&        snmp_increment_statistic(STAT_SNMPINASNPARSEERRS) == 0)        DEBUGMSGTL(("ksm", "Failed to increment statistics.\n"));    if (subkey)        krb5_free_keyblock(kcontext, subkey);    if (checksum.contents)        free(checksum.contents);    if (ivector.data)        free(ivector.data);    if (ticket)        krb5_free_ticket(kcontext, ticket);    if (!response && auth_context)        krb5_auth_con_free(kcontext, auth_context);    if (ap_req.data)        free(ap_req.data);    return retval;}

⌨️ 快捷键说明

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