snmpusm.c
来自「eCos操作系统源码」· C语言 代码 · 共 2,486 行 · 第 1/5 页
C
2,486 行
* Set wholeMsg as a pointer to globalData. Sanity check for * the proper size. * * Mark workspace in the message with bytes of all 1's to make it * easier to find mistakes in raw message dumps. */ ptr = *wholeMsg = globalData; if (theTotalLength > *wholeMsgLen) { DEBUGMSGTL(("usm","Message won't fit in buffer.\n")); usm_free_usmStateReference (secStateRef); return SNMPERR_USM_GENERICERROR; } ptr_len = *wholeMsgLen = theTotalLength;#ifdef SNMP_TESTING_CODE memset (&ptr[globalDataLen], 0xFF, theTotalLength-globalDataLen);#endif /* SNMP_TESTING_CODE */ /* * Do the encryption. */ if (theSecLevel == SNMP_SEC_LEVEL_AUTHPRIV) { size_t encrypted_length = theTotalLength - dataOffset; size_t salt_length = BYTESIZE(USM_MAX_SALT_LENGTH); u_char salt[BYTESIZE(USM_MAX_SALT_LENGTH)]; /* XXX Hardwired to seek into a 1DES private key! */ if ( usm_set_salt( salt, &salt_length, thePrivKey+8, thePrivKeyLength-8, &ptr[privParamsOffset]) == -1 ) { DEBUGMSGTL(("usm","Can't set DES-CBC salt.\n")); usm_free_usmStateReference (secStateRef); return SNMPERR_USM_GENERICERROR; } if ( sc_encrypt( thePrivProtocol, thePrivProtocolLength, thePrivKey, thePrivKeyLength, salt, salt_length, scopedPdu, scopedPduLen, &ptr[dataOffset], &encrypted_length) != SNMP_ERR_NOERROR ) { DEBUGMSGTL(("usm","DES-CBC error.\n")); usm_free_usmStateReference (secStateRef); return SNMPERR_USM_ENCRYPTIONERROR; }#ifdef SNMP_TESTING_CODE if ( debug_is_token_registered("usm/dump") == SNMPERR_SUCCESS) { dump_chunk("usm/dump", "This data was encrypted:", scopedPdu, scopedPduLen); dump_chunk("usm/dump", "salt + Encrypted form:", salt, salt_length); dump_chunk("usm/dump", NULL, &ptr[dataOffset], encrypted_length); dump_chunk("usm/dump", "*wholeMsg:", *wholeMsg, theTotalLength); }#endif ptr = *wholeMsg; ptr_len = *wholeMsgLen = theTotalLength; /* * XXX Sanity check for salt length should be moved up * under usm_calc_offsets() or tossed. */ if ( (encrypted_length != (theTotalLength - dataOffset)) || (salt_length != msgPrivParmLen) ) { DEBUGMSGTL(("usm","DES-CBC length error.\n")); usm_free_usmStateReference (secStateRef); return SNMPERR_USM_ENCRYPTIONERROR; } DEBUGMSGTL(("usm","Encryption successful.\n")); } /* * No encryption for you! */ else { memcpy( &ptr[dataOffset], scopedPdu, scopedPduLen ); } /* * Start filling in the other fields (in prep for authentication). * * offSet is an octet string header, which is different from all * the other headers. */ remaining = ptr_len - globalDataLen; offSet = ptr_len - remaining; asn_build_header (&ptr[offSet], &remaining, (u_char)(ASN_UNIVERSAL|ASN_PRIMITIVE|ASN_OCTET_STR), otstlen); offSet = ptr_len - remaining; asn_build_sequence (&ptr[offSet], &remaining, (u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), seq_len); offSet = ptr_len - remaining; asn_build_string (&ptr[offSet], &remaining, (u_char)(ASN_UNIVERSAL|ASN_PRIMITIVE|ASN_OCTET_STR), theEngineID, theEngineIDLength); offSet = ptr_len - remaining; asn_build_int (&ptr[offSet], &remaining, (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), &boots_long, sizeof(long)); offSet = ptr_len - remaining; asn_build_int (&ptr[offSet], &remaining, (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), &time_long, sizeof(long)); offSet = ptr_len - remaining; asn_build_string (&ptr[offSet], &remaining, (u_char)(ASN_UNIVERSAL|ASN_PRIMITIVE|ASN_OCTET_STR), (u_char *)theName, theNameLength); /* Note: if there is no authentication being done, msgAuthParmLen is 0, and there is no effect (other than inserting a zero-length header) of the following statements. */ offSet = ptr_len - remaining; asn_build_header( &ptr[offSet], &remaining, (u_char)(ASN_UNIVERSAL|ASN_PRIMITIVE|ASN_OCTET_STR), msgAuthParmLen); if (theSecLevel == SNMP_SEC_LEVEL_AUTHNOPRIV || theSecLevel == SNMP_SEC_LEVEL_AUTHPRIV) { offSet = ptr_len - remaining; memset (&ptr[offSet],0,msgAuthParmLen); } remaining -= msgAuthParmLen; /* Note: if there is no encryption being done, msgPrivParmLen is 0, and there is no effect (other than inserting a zero-length header) of the following statements. */ offSet = ptr_len - remaining; asn_build_header( &ptr[offSet], &remaining, (u_char)(ASN_UNIVERSAL|ASN_PRIMITIVE|ASN_OCTET_STR), msgPrivParmLen); remaining -= msgPrivParmLen; /* Skipping the IV already there. */ /* * For privacy, need to add the octet string header for it. */ 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() *//*******************************************************************-o-****** * usm_parse_security_parameters * * Parameters: * (See list below...) * * Returns: * 0 On success, * -1 Otherwise. * * tab stop 4 * * Extracts values from the security header and data portions of the * incoming buffer. */intusm_parse_security_parameters ( u_char *secParams, size_t remaining, u_char *secEngineID, size_t *secEngineIDLen, u_int *boots_uint, u_int *time_uint, char *secName, size_t *secNameLen, u_char *signature, size_t *signature_length, u_char *salt, size_t *salt_length, u_char **data_ptr){ u_char *parse_ptr = secParams; u_char *value_ptr; u_char *next_ptr; u_char type_value; size_t octet_string_length = remaining; size_t sequence_length; size_t remaining_bytes; long boots_long; long time_long; u_int origNameLen; /* * Eat the first octet header. */ if ((value_ptr = asn_parse_sequence (parse_ptr, &octet_string_length, &type_value, (ASN_UNIVERSAL|ASN_PRIMITIVE|ASN_OCTET_STR), "usm first octet")) == NULL) { /* RETURN parse error */ return -1; } /* * Eat the sequence header. */ parse_ptr = value_ptr; sequence_length = octet_string_length; if ((value_ptr = asn_parse_sequence (parse_ptr, &sequence_length, &type_value, (ASN_SEQUENCE | ASN_CONSTRUCTOR), "usm sequence")) == NULL) { /* RETURN parse error */ return -1; } /* * Retrieve the engineID. */ parse_ptr = value_ptr; remaining_bytes = sequence_length; DEBUGDUMPHEADER("dump_recv", "Parsing msgAuthoritativeEngineID\n"); if ( (next_ptr = asn_parse_string (parse_ptr, &remaining_bytes, &type_value, secEngineID, secEngineIDLen)) == NULL ) { DEBUGINDENTLESS(); /* RETURN parse error */ return -1; } DEBUGINDENTLESS(); if (type_value != (u_char) (ASN_UNIVERSAL|ASN_PRIMITIVE|ASN_OCTET_STR)) { /* RETURN parse error */ return -1; } /* * Retrieve the engine boots, notice switch in the way next_ptr and * remaining_bytes are used (to accomodate the asn code). */ DEBUGDUMPHEADER("dump_recv", "Parsing msgAuthoritativeEngineBoots\n"); if ((next_ptr = asn_parse_int (next_ptr, &remaining_bytes, &type_value, &boots_long, sizeof(long))) == NULL) { DEBUGINDENTLESS(); /* RETURN parse error */ return -1; } DEBUGINDENTLESS(); if (type_value != (u_char) (ASN_UNIVERSAL|ASN_PRIMITIVE|ASN_INTEGER)) { DEBUGINDENTLESS(); /* RETURN parse error */ return -1; } *boots_uint = (u_int) boots_long; /* * Retrieve the time value. */ DEBUGDUMPHEADER("dump_recv", "Parsing msgAuthoritativeEngineTime\n"); if ((next_ptr = asn_parse_int (next_ptr, &remaining_bytes, &type_value, &time_long, sizeof(long))) == NULL) { /* RETURN parse error */ return -1; } if (type_value != (u_char) (ASN_UNIVERSAL|ASN_PRIMITIVE|ASN_INTEGER)) { DEBUGINDENTLESS(); /* RETURN parse error */ return -1; } *time_uint = (u_int) time_long; /* * Retrieve the secName. */ origNameLen = *secNameLen; DEBUGDUMPHEADER("dump_recv", "Parsing msgUserName\n"); if ( (next_ptr = asn_parse_string (next_ptr, &remaining_bytes, &type_value, (u_char *)secName, secNameLen)) == NULL ) { DEBUGINDENTLESS(); /* RETURN parse error */ return -1; } DEBUGINDENTLESS(); /* FIX -- doesn't this also indicate a buffer overrun? */ if ((int)origNameLen < *secNameLen + 1) { /* RETURN parse error, but it's really a parameter error */ return -1; } secName[*secNameLen] = '\0'; if (type_value != (u_char) (ASN_UNIVERSAL|ASN_PRIMITIVE|ASN_OCTET_STR)) { /* RETURN parse error */ return -1; } /* * Retrieve the signature and blank it if there. */ DEBUGDUMPHEADER("dump_recv", "Parsing msgAuthenticationParameters\n"); if ( (next_ptr = asn_parse_string (next_ptr, &remaining_bytes, &type_value, signature, signature_length)) == NULL ) { DEBUGINDENTLESS(); /* RETURN parse error */ return -1; } DEBUGINDENTLESS(); if (type_value != (u_char) (ASN_UNIVERSAL|ASN_PRIMITIVE|ASN_OCTET_STR)) { /* RETURN parse error */ return -1; } if (*signature_length != 0) /* Blanking for authentication step later */ { memset (next_ptr-(u_long)*signature_length, 0, *signature_length); } /* * Retrieve the salt. * * Note that the next ptr is where the data section starts. */ DEBUGDUMPHEADER("dump_recv", "Parsing msgPrivacyParameters\n"); if ( (*data_ptr = asn_parse_string (next_ptr, &remaining_bytes, &type_value, salt, salt_length)) == NULL ) { DEBUGINDENTLESS(); /* RETURN parse error */ return -1; } DEBUGINDENTLESS(); if (type_value != (u_char) (ASN_UNIVERSAL|ASN_PRIMITIVE|ASN_OCTET_STR)) { /* RETURN parse error */ return -1; } return 0;} /* end usm_parse_security_parameters() *//*******************************************************************-o-****** * usm_check_and_update_timeliness * * Parameters: * *secEngineID * secEngineIDen * boots_uint * time_uint * *error * * Returns: * 0 On success, * -1 Otherwise. * * * Performs the incoming timeliness checking and setting. */int
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?