net-snmp 5.7
|
00001 /* 00002 * snmptsmsm.c -- Implements RFC #5591 00003 * 00004 * This code implements a security model that assumes the local user 00005 * that executed the agent is the user who's attributes are passed up 00006 * by the transport underneath. The RFC describing this security 00007 * model is RFC5591. 00008 */ 00009 00010 #include <net-snmp/net-snmp-config.h> 00011 00012 #include <net-snmp/net-snmp-features.h> 00013 #include <net-snmp/net-snmp-includes.h> 00014 00015 #include <net-snmp/library/snmptsm.h> 00016 00017 #ifdef NETSNMP_TRANSPORT_SSH_DOMAIN 00018 #include <net-snmp/library/snmpSSHDomain.h> 00019 #endif 00020 #ifdef NETSNMP_TRANSPORT_DTLSUDP_DOMAIN 00021 #include <net-snmp/library/snmpDTLSUDPDomain.h> 00022 #endif 00023 #ifdef NETSNMP_TRANSPORT_TLSTCP_DOMAIN 00024 #include <net-snmp/library/snmpTLSTCPDomain.h> 00025 #endif 00026 #ifdef NETSNMP_TRANSPORT_DTLSSCTP_DOMAIN 00027 #include <net-snmp/library/snmpDTLSSCTPDomain.h> 00028 #endif 00029 00030 netsnmp_feature_require(snmpv3_probe_contextEngineID_rfc5343) 00031 netsnmp_feature_require(row_create) 00032 00033 #include <unistd.h> 00034 00035 static int tsm_session_init(netsnmp_session *); 00036 static void tsm_free_state_ref(void *); 00037 static int tsm_clone_pdu(netsnmp_pdu *, netsnmp_pdu *); 00038 static int tsm_free_pdu(netsnmp_pdu *pdu); 00039 00040 u_int next_sess_id = 1; 00041 00043 void 00044 init_tsm(void) 00045 { 00046 struct snmp_secmod_def *def; 00047 int ret; 00048 00049 def = SNMP_MALLOC_STRUCT(snmp_secmod_def); 00050 00051 if (!def) { 00052 snmp_log(LOG_ERR, 00053 "Unable to malloc snmp_secmod struct, not registering TSM\n"); 00054 return; 00055 } 00056 00057 def->encode_reverse = tsm_rgenerate_out_msg; 00058 def->decode = tsm_process_in_msg; 00059 def->session_open = tsm_session_init; 00060 def->pdu_free_state_ref = tsm_free_state_ref; 00061 def->pdu_clone = tsm_clone_pdu; 00062 def->pdu_free = tsm_free_pdu; 00063 def->probe_engineid = snmpv3_probe_contextEngineID_rfc5343; 00064 00065 DEBUGMSGTL(("tsm","registering ourselves\n")); 00066 ret = register_sec_mod(SNMP_SEC_MODEL_TSM, "tsm", def); 00067 DEBUGMSGTL(("tsm"," returned %d\n", ret)); 00068 00069 netsnmp_ds_register_config(ASN_BOOLEAN, "snmp", "tsmUseTransportPrefix", 00070 NETSNMP_DS_LIBRARY_ID, 00071 NETSNMP_DS_LIB_TSM_USE_PREFIX); 00072 } 00073 00075 void 00076 shutdown_tsm(void) 00077 { 00078 } 00079 00080 /* 00081 * Initialize specific session information (right now, just set up things to 00082 * not do an engineID probe) 00083 */ 00084 00085 static int 00086 tsm_session_init(netsnmp_session * sess) 00087 { 00088 DEBUGMSGTL(("tsm", 00089 "TSM: Reached our session initialization callback\n")); 00090 00091 sess->flags |= SNMP_FLAGS_DONT_PROBE; 00092 00093 /* XXX: likely needed for something: */ 00094 /* 00095 tsmsession = sess->securityInfo = 00096 if (!tsmsession) 00097 return SNMPERR_GENERR; 00098 */ 00099 00100 return SNMPERR_SUCCESS; 00101 } 00102 00104 static void 00105 tsm_free_state_ref(void *ptr) 00106 { 00107 netsnmp_tsmSecurityReference *tsmRef; 00108 00109 if (NULL == ptr) 00110 return; 00111 00112 tsmRef = (netsnmp_tsmSecurityReference *) ptr; 00113 /* the tmStateRef is always taken care of by the normal PDU, since this 00114 is just a reference to that one */ 00115 /* DON'T DO: SNMP_FREE(tsmRef->tmStateRef); */ 00116 /* SNMP_FREE(tsmRef); ? */ 00117 } 00118 00119 static int 00120 tsm_free_pdu(netsnmp_pdu *pdu) 00121 { 00122 /* free the security reference */ 00123 if (pdu->securityStateRef) { 00124 tsm_free_state_ref(pdu->securityStateRef); 00125 pdu->securityStateRef = NULL; 00126 } 00127 return 0; 00128 } 00129 00131 static int 00132 tsm_clone_pdu(netsnmp_pdu *pdu, netsnmp_pdu *pdu2) 00133 { 00134 netsnmp_tsmSecurityReference *oldref, *newref; 00135 00136 oldref = pdu->securityStateRef; 00137 if (!oldref) 00138 return SNMPERR_SUCCESS; 00139 00140 newref = SNMP_MALLOC_TYPEDEF(netsnmp_tsmSecurityReference); 00141 DEBUGMSGTL(("tsm", "cloned as pdu=%p, ref=%p (oldref=%p)\n", 00142 pdu2, newref, pdu2->securityStateRef)); 00143 if (!newref) 00144 return SNMPERR_GENERR; 00145 00146 memcpy(newref, oldref, sizeof(*oldref)); 00147 00148 pdu2->securityStateRef = newref; 00149 00150 /* the tm state reference is just a link to the one in the pdu, 00151 which was already copied by snmp_clone_pdu before handing it to 00152 us. */ 00153 00154 memdup((u_char **) &newref->tmStateRef, oldref->tmStateRef, 00155 sizeof(*oldref->tmStateRef)); 00156 return SNMPERR_SUCCESS; 00157 } 00158 00159 /* asn.1 easing definitions */ 00160 #define TSMBUILD_OR_ERR(fun, args, msg, desc) \ 00161 DEBUGDUMPHEADER("send", desc); \ 00162 rc = fun args; \ 00163 DEBUGINDENTLESS(); \ 00164 if (rc == 0) { \ 00165 DEBUGMSGTL(("tsm",msg)); \ 00166 retval = SNMPERR_TOO_LONG; \ 00167 goto outerr; \ 00168 } 00169 00170 /**************************************************************************** 00171 * 00172 * tsm_generate_out_msg 00173 * 00174 * Parameters: 00175 * (See list below...) 00176 * 00177 * Returns: 00178 * SNMPERR_SUCCESS On success. 00179 * ... and others 00180 * 00181 * 00182 * Generate an outgoing message. 00183 * 00184 ****************************************************************************/ 00185 00186 int 00187 tsm_rgenerate_out_msg(struct snmp_secmod_outgoing_params *parms) 00188 { 00189 u_char **wholeMsg = parms->wholeMsg; 00190 size_t *offset = parms->wholeMsgOffset; 00191 int rc; 00192 00193 size_t *wholeMsgLen = parms->wholeMsgLen; 00194 netsnmp_tsmSecurityReference *tsmSecRef; 00195 netsnmp_tmStateReference *tmStateRef; 00196 00197 DEBUGMSGTL(("tsm", "Starting TSM processing\n")); 00198 00199 /* if we have this, then this message to be sent is in response to 00200 something that came in earlier and the tsmSecRef was created by 00201 the tsm_process_in_msg. */ 00202 tsmSecRef = parms->secStateRef; 00203 00204 if (tsmSecRef) { 00205 /* 4.2, step 1: If there is a securityStateReference (Response 00206 or Report message), then this Security Model uses the 00207 cached information rather than the information provided by 00208 the ASI. */ 00209 00210 /* 4.2, step 1: Extract the tmStateReference from the 00211 securityStateReference cache. */ 00212 netsnmp_assert_or_return(NULL != tsmSecRef->tmStateRef, SNMPERR_GENERR); 00213 tmStateRef = tsmSecRef->tmStateRef; 00214 00215 /* 4.2 step 1: Set the tmRequestedSecurityLevel to the value 00216 of the extracted tmTransportSecurityLevel. */ 00217 tmStateRef->requestedSecurityLevel = tmStateRef->transportSecurityLevel; 00218 00219 /* 4.2 step 1: Set the tmSameSecurity parameter in the 00220 tmStateReference cache to true. */ 00221 tmStateRef->sameSecurity = NETSNMP_TM_USE_SAME_SECURITY; 00222 00223 /* 4.2 step 1: The cachedSecurityData for this message can 00224 now be discarded. */ 00225 SNMP_FREE(parms->secStateRef); 00226 } else { 00227 /* 4.2, step 2: If there is no securityStateReference (e.g., a 00228 Request-type or Notification message), then create a 00229 tmStateReference cache. */ 00230 tmStateRef = SNMP_MALLOC_TYPEDEF(netsnmp_tmStateReference); 00231 netsnmp_assert_or_return(NULL != tmStateRef, SNMPERR_GENERR); 00232 00233 /* XXX: we don't actually use this really in our implementation */ 00234 /* 4.2, step 2: Set tmTransportDomain to the value of 00235 transportDomain, tmTransportAddress to the value of 00236 transportAddress */ 00237 00238 /* 4.2, step 2: and tmRequestedSecurityLevel to the value of 00239 securityLevel. */ 00240 tmStateRef->requestedSecurityLevel = parms->secLevel; 00241 00242 /* 4.2, step 2: Set the transaction-specific tmSameSecurity 00243 parameter to false. */ 00244 tmStateRef->sameSecurity = NETSNMP_TM_SAME_SECURITY_NOT_REQUIRED; 00245 00246 if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, 00247 NETSNMP_DS_LIB_TSM_USE_PREFIX)) { 00248 /* XXX: probably shouldn't be a hard-coded list of 00249 supported transports */ 00250 /* 4.2, step 2: If the snmpTsmConfigurationUsePrefix 00251 object is set to true, then use the transportDomain to 00252 look up the corresponding prefix. */ 00253 const char *prefix; 00254 if (strncmp("ssh:",parms->session->peername,4) == 0) 00255 prefix = "ssh:"; 00256 else if (strncmp("dtls:",parms->session->peername,5) == 0) 00257 prefix = "dtls:"; 00258 else if (strncmp("tls:",parms->session->peername,4) == 0) 00259 prefix = "tls:"; 00260 else { 00261 /* 4.2, step 2: If the prefix lookup fails for any 00262 reason, then the snmpTsmUnknownPrefixes counter is 00263 incremented, an error indication is returned to the 00264 calling module, and message processing stops. */ 00265 snmp_increment_statistic(STAT_TSM_SNMPTSMUNKNOWNPREFIXES); 00266 return SNMPERR_GENERR; 00267 } 00268 00269 /* 4.2, step 2: If the lookup succeeds, but there is no 00270 prefix in the securityName, or the prefix returned does 00271 not match the prefix in the securityName, or the length 00272 of the prefix is less than 1 or greater than 4 US-ASCII 00273 alpha-numeric characters, then the 00274 snmpTsmInvalidPrefixes counter is incremented, an error 00275 indication is returned to the calling module, and 00276 message processing stops. */ 00277 if (strchr(parms->secName, ':') == 0 || 00278 strlen(prefix)+1 >= parms->secNameLen || 00279 strncmp(parms->secName, prefix, strlen(prefix)) != 0 || 00280 parms->secName[strlen(prefix)] != ':') { 00281 /* Note: since we're assiging the prefixes above the 00282 prefix lengths always meet the 1-4 criteria */ 00283 snmp_increment_statistic(STAT_TSM_SNMPTSMINVALIDPREFIXES); 00284 return SNMPERR_GENERR; 00285 } 00286 00287 /* 4.2, step 2: Strip the transport-specific prefix and 00288 trailing ':' character (US-ASCII 0x3a) from the 00289 securityName. Set tmSecurityName to the value of 00290 securityName. */ 00291 memcpy(tmStateRef->securityName, 00292 parms->secName + strlen(prefix) + 1, 00293 parms->secNameLen - strlen(prefix) - 1); 00294 tmStateRef->securityNameLen = parms->secNameLen - strlen(prefix) -1; 00295 } else { 00296 /* 4.2, step 2: If the snmpTsmConfigurationUsePrefix object is 00297 set to false, then set tmSecurityName to the value 00298 of securityName. */ 00299 memcpy(tmStateRef->securityName, parms->secName, 00300 parms->secNameLen); 00301 tmStateRef->securityNameLen = parms->secNameLen; 00302 } 00303 } 00304 00305 /* truncate the security name with a '\0' for safety */ 00306 tmStateRef->securityName[tmStateRef->securityNameLen] = '\0'; 00307 00308 /* 4.2, step 3: Set securityParameters to a zero-length OCTET 00309 * STRING ('0400'). 00310 */ 00311 DEBUGDUMPHEADER("send", "tsm security parameters"); 00312 rc = asn_realloc_rbuild_header(wholeMsg, wholeMsgLen, offset, 1, 00313 (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE 00314 | ASN_OCTET_STR), 0); 00315 DEBUGINDENTLESS(); 00316 if (rc == 0) { 00317 DEBUGMSGTL(("tsm", "building msgSecurityParameters failed.\n")); 00318 return SNMPERR_TOO_LONG; 00319 } 00320 00321 /* 4.2, step 4: Combine the message parts into a wholeMsg and 00322 calculate wholeMsgLength. 00323 */ 00324 while ((*wholeMsgLen - *offset) < parms->globalDataLen) { 00325 if (!asn_realloc(wholeMsg, wholeMsgLen)) { 00326 DEBUGMSGTL(("tsm", "building global data failed.\n")); 00327 return SNMPERR_TOO_LONG; 00328 } 00329 } 00330 00331 *offset += parms->globalDataLen; 00332 memcpy(*wholeMsg + *wholeMsgLen - *offset, 00333 parms->globalData, parms->globalDataLen); 00334 00335 /* 4.2, step 5: The wholeMsg, wholeMsgLength, securityParameters, 00336 and tmStateReference are returned to the calling Message 00337 Processing Model with the statusInformation set to success. */ 00338 00339 /* For the Net-SNMP implemantion that actually means we start 00340 encoding the full packet sequence from here before returning it */ 00341 00342 /* 00343 * Total packet sequence. 00344 */ 00345 rc = asn_realloc_rbuild_sequence(wholeMsg, wholeMsgLen, offset, 1, 00346 (u_char) (ASN_SEQUENCE | 00347 ASN_CONSTRUCTOR), *offset); 00348 if (rc == 0) { 00349 DEBUGMSGTL(("tsm", "building master packet sequence failed.\n")); 00350 return SNMPERR_TOO_LONG; 00351 } 00352 00353 if (parms->pdu->transport_data && 00354 parms->pdu->transport_data != tmStateRef) { 00355 snmp_log(LOG_ERR, "tsm: needed to free transport data\n"); 00356 SNMP_FREE(parms->pdu->transport_data); 00357 } 00358 00359 /* put the transport state reference into the PDU for the transport */ 00360 if (SNMPERR_SUCCESS != 00361 memdup((u_char **) &parms->pdu->transport_data, 00362 tmStateRef, sizeof(*tmStateRef))) { 00363 snmp_log(LOG_ERR, "tsm: malloc failure\n"); 00364 } 00365 parms->pdu->transport_data_length = sizeof(*tmStateRef); 00366 00367 DEBUGMSGTL(("tsm", "TSM processing completed.\n")); 00368 return SNMPERR_SUCCESS; 00369 } 00370 00371 /**************************************************************************** 00372 * 00373 * tsm_process_in_msg 00374 * 00375 * Parameters: 00376 * (See list below...) 00377 * 00378 * Returns: 00379 * TSM_ERR_NO_ERROR On success. 00380 * TSM_ERR_GENERIC_ERROR 00381 * TSM_ERR_UNSUPPORTED_SECURITY_LEVEL 00382 * 00383 * 00384 * Processes an incoming message. 00385 * 00386 ****************************************************************************/ 00387 00388 int 00389 tsm_process_in_msg(struct snmp_secmod_incoming_params *parms) 00390 { 00391 u_char type_value; 00392 size_t remaining; 00393 u_char *data_ptr; 00394 netsnmp_tmStateReference *tmStateRef; 00395 netsnmp_tsmSecurityReference *tsmSecRef; 00396 u_char ourEngineID[SNMP_MAX_ENG_SIZE]; 00397 static size_t ourEngineID_len = sizeof(ourEngineID); 00398 00399 /* Section 5.2, step 1: Set the securityEngineID to the local 00400 snmpEngineID. */ 00401 ourEngineID_len = 00402 snmpv3_get_engineID((u_char*) ourEngineID, ourEngineID_len); 00403 netsnmp_assert_or_return(ourEngineID_len != 0 && 00404 ourEngineID_len <= *parms->secEngineIDLen, 00405 SNMPERR_GENERR); 00406 memcpy(parms->secEngineID, ourEngineID, *parms->secEngineIDLen); 00407 00408 /* Section 5.2, step 2: If tmStateReference does not refer to a 00409 cache containing values for tmTransportDomain, 00410 tmTransportAddress, tmSecurityName, and 00411 tmTransportSecurityLevel, then the snmpTsmInvalidCaches counter 00412 is incremented, an error indication is returned to the calling 00413 module, and Security Model processing stops for this 00414 message. */ 00415 if (!parms->pdu->transport_data || 00416 sizeof(netsnmp_tmStateReference) != 00417 parms->pdu->transport_data_length) { 00418 /* if we're not coming in over a proper transport; bail! */ 00419 DEBUGMSGTL(("tsm","improper transport data\n")); 00420 return -1; 00421 } 00422 tmStateRef = (netsnmp_tmStateReference *) parms->pdu->transport_data; 00423 parms->pdu->transport_data = NULL; 00424 00425 if (tmStateRef == NULL || 00426 /* not needed: tmStateRef->transportDomain == NULL || */ 00427 /* not needed: tmStateRef->transportAddress == NULL || */ 00428 tmStateRef->securityName[0] == '\0' 00429 ) { 00430 snmp_increment_statistic(STAT_TSM_SNMPTSMINVALIDCACHES); 00431 return SNMPERR_GENERR; 00432 } 00433 00434 /* Section 5.2, step 3: Copy the tmSecurityName to securityName. */ 00435 if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, 00436 NETSNMP_DS_LIB_TSM_USE_PREFIX)) { 00437 /* Section 5.2, step 3: 00438 If the snmpTsmConfigurationUsePrefix object is set to true, then 00439 use the tmTransportDomain to look up the corresponding prefix. 00440 */ 00441 const char *prefix = NULL; 00442 /* 00443 possibilities: 00444 |--------------------+-------| 00445 | snmpTLSTCPDomain | tls: | 00446 | snmpDTLSUDPDomain | dtls: | 00447 | snmpSSHDomain | ssh: | 00448 |--------------------+-------| 00449 */ 00450 00451 if (tmStateRef->transportDomain == NULL) { 00452 /* XXX: snmpTsmInvalidCaches++ ??? */ 00453 return SNMPERR_GENERR; 00454 } 00455 00456 /* XXX: cache in session! */ 00457 #ifdef NETSNMP_TRANSPORT_SSH_DOMAIN 00458 if (netsnmp_oid_equals(netsnmp_snmpSSHDomain, 00459 netsnmp_snmpSSHDomain_len, 00460 tmStateRef->transportDomain, 00461 tmStateRef->transportDomainLen) == 0) { 00462 prefix = "ssh"; 00463 } 00464 #endif /* NETSNMP_TRANSPORT_SSH_DOMAIN */ 00465 00466 #ifdef NETSNMP_TRANSPORT_DTLSUDP_DOMAIN 00467 if (netsnmp_oid_equals(netsnmpDTLSUDPDomain, 00468 netsnmpDTLSUDPDomain_len, 00469 tmStateRef->transportDomain, 00470 tmStateRef->transportDomainLen) == 0) { 00471 00472 prefix = "dtls"; 00473 } 00474 #endif /* NETSNMP_TRANSPORT_DTLSUDP_DOMAIN */ 00475 00476 #ifdef NETSNMP_TRANSPORT_TLSTCP_DOMAIN 00477 if (netsnmp_oid_equals(netsnmpTLSTCPDomain, 00478 netsnmpTLSTCPDomain_len, 00479 tmStateRef->transportDomain, 00480 tmStateRef->transportDomainLen) == 0) { 00481 00482 prefix = "tls"; 00483 } 00484 #endif /* NETSNMP_TRANSPORT_TLSTCP_DOMAIN */ 00485 00486 /* Section 5.2, step 3: 00487 If the prefix lookup fails for any reason, then the 00488 snmpTsmUnknownPrefixes counter is incremented, an error 00489 indication is returned to the calling module, and message 00490 processing stops. 00491 */ 00492 if (prefix == NULL) { 00493 snmp_increment_statistic(STAT_TSM_SNMPTSMUNKNOWNPREFIXES); 00494 return SNMPERR_GENERR; 00495 } 00496 00497 /* Section 5.2, step 3: 00498 If the lookup succeeds but the prefix length is less than 1 or 00499 greater than 4 octets, then the snmpTsmInvalidPrefixes counter 00500 is incremented, an error indication is returned to the calling 00501 module, and message processing stops. 00502 */ 00503 #ifdef NOT_USING_HARDCODED_PREFIXES 00504 /* the above code actually ensures this will never happen as 00505 we don't support a dynamic prefix database where this might 00506 happen. */ 00507 if (strlen(prefix) < 1 || strlen(prefix) > 4) { 00508 /* XXX: snmpTsmInvalidPrefixes++ */ 00509 return SNMPERR_GENERR; 00510 } 00511 #endif 00512 00513 /* Section 5.2, step 3: 00514 Set the securityName to be the concatenation of the prefix, a 00515 ':' character (US-ASCII 0x3a), and the tmSecurityName. 00516 */ 00517 snprintf(parms->secName, *parms->secNameLen, 00518 "%s:%s", prefix, tmStateRef->securityName); 00519 } else { 00520 /* if the use prefix flag wasn't set, do a straight copy */ 00521 strncpy(parms->secName, tmStateRef->securityName, *parms->secNameLen); 00522 } 00523 00524 /* set the length of the security name */ 00525 *parms->secNameLen = strlen(parms->secName); 00526 DEBUGMSGTL(("tsm", "user: %s/%d\n", parms->secName, (int)*parms->secNameLen)); 00527 00528 /* Section 5.2 Step 4: 00529 Compare the value of tmTransportSecurityLevel in the 00530 tmStateReference cache to the value of the securityLevel 00531 parameter passed in the processIncomingMsg ASI. If securityLevel 00532 specifies privacy (Priv) and tmTransportSecurityLevel specifies 00533 no privacy (noPriv), or if securityLevel specifies authentication 00534 (auth) and tmTransportSecurityLevel specifies no authentication 00535 (noAuth) was provided by the Transport Model, then the 00536 snmpTsmInadequateSecurityLevels counter is incremented, an error 00537 indication (unsupportedSecurityLevel) together with the OID and 00538 value of the incremented counter is returned to the calling 00539 module, and Transport Security Model processing stops for this 00540 message.*/ 00541 if (parms->secLevel > tmStateRef->transportSecurityLevel) { 00542 snmp_increment_statistic(STAT_TSM_SNMPTSMINADEQUATESECURITYLEVELS); 00543 DEBUGMSGTL(("tsm", "inadequate security level: %d\n", parms->secLevel)); 00544 /* net-snmp returns error codes not OIDs, which are dealt with later */ 00545 return SNMPERR_UNSUPPORTED_SEC_LEVEL; 00546 } 00547 00548 /* Section 5.2 Step 5 00549 The tmStateReference is cached as cachedSecurityData so that a 00550 possible response to this message will use the same security 00551 parameters. Then securityStateReference is set for subsequent 00552 references to this cached data. 00553 */ 00554 if (NULL == *parms->secStateRef) { 00555 tsmSecRef = SNMP_MALLOC_TYPEDEF(netsnmp_tsmSecurityReference); 00556 } else { 00557 tsmSecRef = *parms->secStateRef; 00558 } 00559 00560 netsnmp_assert_or_return(NULL != tsmSecRef, SNMPERR_GENERR); 00561 00562 *parms->secStateRef = tsmSecRef; 00563 tsmSecRef->tmStateRef = tmStateRef; 00564 00565 /* If this did not come through a tunneled connection, this 00566 security model is inappropriate (and would be a HUGE security 00567 hole to assume otherwise). This is functionally a double check 00568 since the pdu wouldn't have transport data otherwise. But this 00569 is safer though is functionally an extra step beyond the TSM 00570 RFC. */ 00571 DEBUGMSGTL(("tsm","checking how we got here\n")); 00572 if (!(parms->pdu->flags & UCD_MSG_FLAG_TUNNELED)) { 00573 DEBUGMSGTL(("tsm"," pdu not tunneled\n")); 00574 if (!(parms->sess->flags & NETSNMP_TRANSPORT_FLAG_TUNNELED)) { 00575 DEBUGMSGTL(("tsm"," session not tunneled\n")); 00576 return SNMPERR_USM_AUTHENTICATIONFAILURE; 00577 } 00578 DEBUGMSGTL(("tsm"," but session is tunneled\n")); 00579 } else { 00580 DEBUGMSGTL(("tsm"," tunneled\n")); 00581 } 00582 00583 /* Section 5.2, Step 6: 00584 The scopedPDU component is extracted from the wholeMsg. */ 00585 /* 00586 * Eat the first octet header. 00587 */ 00588 remaining = parms->wholeMsgLen - (parms->secParams - parms->wholeMsg); 00589 if ((data_ptr = asn_parse_sequence(parms->secParams, &remaining, 00590 &type_value, 00591 (ASN_UNIVERSAL | ASN_PRIMITIVE | 00592 ASN_OCTET_STR), 00593 "tsm first octet")) == NULL) { 00594 /* 00595 * RETURN parse error 00596 */ 00597 return SNMPERR_ASN_PARSE_ERR; 00598 } 00599 00600 *parms->scopedPdu = data_ptr; 00601 *parms->scopedPduLen = parms->wholeMsgLen - (data_ptr - parms->wholeMsg); 00602 00603 /* Section 5.2, Step 7: 00604 The maxSizeResponseScopedPDU is calculated. This is the maximum 00605 size allowed for a scopedPDU for a possible Response message. 00606 */ 00607 *parms->maxSizeResponse = parms->maxMsgSize; /* XXX */ 00608 00609 /* Section 5.2, Step 8: 00610 The statusInformation is set to success and a return is made to 00611 the calling module passing back the OUT parameters as specified 00612 in the processIncomingMsg ASI. 00613 */ 00614 return SNMPERR_SUCCESS; 00615 }