static unsigned char flash_writeb_cmd(unsigned char value) { unsigned char ret; SET_SPI(FCR_SPDR, value); /* sw: make sure the rf is not empty! */ while ((GET_SPI(FCR_SPSR)) & 0x01); ret = GET_SPI(FCR_SPDR); #ifdef SDCARD_DBG printf("==treg ret value: %08b\n",ret); #endif return ret; }
/* ARGSUSED */ int faCheckRegReqAuth(MessageHdr *messageHdr, FaVisitorEntry *favePtr, FaVisitorEntry *acceptedFave, unsigned char *mnChallenge, uint32_t mnChallengeLen, boolean_t *forwardFlag) { regRequest *reqPtr; MipSecAssocEntry *mipSecAssocEntry; authExt *mnAuthExt; /* * Support for the latest Challenge/response draft. */ genAuthExt *mnAAAAuthExt; uint32_t SPI; uint32_t aaaSPI; size_t length; int mnAAAAuthExtLen; int mnAuthExtLen; int index; int result; /* LINTED E_BAD_PTR_CAST_ALIGN */ reqPtr = (regRequest *)messageHdr->pkt; *forwardFlag = _B_TRUE; /* * We have two different authentication types that we need * to worry about. First, and foremost, we need to be able * to support the case where a Mobile-Foreign Security * Association exists. In the AAA world, an authenticated * and authorized Mobile Node would have the keys setup in * the mnFaNodeHash, and this case would apply. * * The next case is when we are unaware of the Mobile Node. * In this case, the Mobile Node should have include the * Challenge/Response extensions which are used for AAA * purposes. When this is found, we issue a call to the local * AAA daemon to authenticate and authorize the MN. */ if (faChallengeAdv) { if (mnChallengeLen == 0) { syslog(LOG_ERR, "Missing Challenge Extention"); faCounters.faMNAuthFailureCnt++; /* * Support for the latest Challenge/response draft. * If the challenge was expected, and found present, * return a missing challenge error. */ return (FA_MISSING_CHALLENGE); } /* * Obviously, we need to validate the challenge. */ if (memcmp(faLastChallengeIssued[0], mnChallenge, ADV_CHALLENGE_LENGTH) != 0) { /* * Let's try our backup. */ if (memcmp(faLastChallengeIssued[1], mnChallenge, ADV_CHALLENGE_LENGTH) != 0) { /* * If the visitor entry is present, then we * can ALSO check whether a challenge was * previously issued to the mobile node * in a registration reply. */ if (acceptedFave && acceptedFave->faVisitorChallengeAdvLen) { if (memcmp( acceptedFave->faVisitorChallengeAdv, mnChallenge, acceptedFave-> \ faVisitorChallengeAdvLen) != 0) { syslog(LOG_ERR, "Invalid Challenge Extention"); faCounters.faMNAuthFailureCnt++; return (FA_UNKNOWN_CHALLENGE); } } else { syslog(LOG_ERR, "Invalid Challenge Extention"); faCounters.faMNAuthFailureCnt++; return (FA_UNKNOWN_CHALLENGE); } } } } mipverbose(("Checking authext")); /* * Support for the latest Challenge/Response I-D */ /* LINTED E_BAD_PTR_CAST_ALIGN */ GET_GEN_AUTH_EXT(messageHdr, index, GEN_AUTH_MN_AAA, mnAAAAuthExt, mnAAAAuthExtLen); /* * If a Mobile node Foreign agent authentication extension exists * check it. */ /* LINTED E_BAD_PTR_CAST_ALIGN */ GET_AUTH_EXT(messageHdr, index, REG_MF_AUTH_EXT_TYPE, mnAuthExt, mnAuthExtLen); if (mnAuthExtLen) { GET_SPI(SPI, mnAuthExt); /* * Remember that the node will be locked upon return. * We need to unlock it when we are done... */ if ((mipSecAssocEntry = findSecAssocFromSPI(SPI, LOCK_READ)) == NULL) { syslog(LOG_ERR, "Error: No SA for Mobile Node"); faCounters.faMNAuthFailureCnt++; return (FA_MN_AUTH_FAILURE); } if (isAuthExtOk(messageHdr->pkt, (messageHdr->extIdx[index] - messageHdr->pkt), mipSecAssocEntry) == _B_FALSE) { (void) rw_unlock(&mipSecAssocEntry->mipSecNodeLock); syslog(LOG_ERR, "Failed MN-FA authentication"); faCounters.faMNAuthFailureCnt++; return (FA_MN_AUTH_FAILURE); } /* * ... and now we are done, let's unlock it. */ (void) rw_unlock(&mipSecAssocEntry->mipSecNodeLock); /* * Support for differing extension header formats. * * Remove the extension by playing with the * packet's length. */ messageHdr->pktLen = (messageHdr->extIdx[index-1] - messageHdr->pkt) + messageHdr->extHdrLength[index-1] + messageHdr->extLength[index-1]; } else { /* * If we are advertising challenges, and the Mobile-AAA * authentication extension is present, then the * Mobile-Foreign does not need to be present. If the * Mobile-AAA is NOT present, and we are configured to * require Mobile-Foreign, then we will fail * authentication. */ if (faChallengeAdv == _B_TRUE && mnChallengeLen && mnAAAAuthExtLen) { mipverbose(("Found a challenge and response\n")); /* * First, it is necessary for us to have the NAI in * order to interact with the AAA. */ if (messageHdr->mnNAI == NULL) { syslog(LOG_ERR, "MN-AAA present without an NAI"); faCounters.faMNAuthFailureCnt++; return (FA_MN_AUTH_FAILURE); } /* * Is AAA Enabled? */ if (aaaProtocol == AAA_NONE) { /* WORK -- why is this here? (PRC?) */ return (0); #if 0 syslog(LOG_ERR, "Not configured to interact with AAA"); faCounters.faMNAuthFailureCnt++; return (FA_MN_AUTH_FAILURE); #endif } if (mnAAAAuthExtLen) { /* * If the MN-AAA Authentication extension was * present, retrieve the SPI value. */ GET_GEN_AUTH_SPI(aaaSPI, mnAAAAuthExt); } /* * If we are using Radius only, then the SPI must be 2. */ if (aaaProtocol == RADIUS && aaaSPI != RADIUS_SPI) { syslog(LOG_ERR, "Failed MN-FA authentication " "- wrong SPI"); faCounters.faMNAuthFailureCnt++; return (FA_MN_AUTH_FAILURE); } /* * Good, we've made it this far. Now let's go * check with the AAA Infrastructure, if this * was configured. */ /* * Support for the latest Challenge response I-D */ length = ((char *)mnAAAAuthExt) - ((char *)messageHdr->pkt) + sizeof (genAuthExt); /* * If using Radius, we'd like to preserve messageHdr * until we get a reply from the Radius server */ if (aaaProtocol == RADIUS) messageHdr->dontDeleteNow = _B_TRUE; result = AAAAuthenticateRegReq(messageHdr->pkt, messageHdr->pktLen, messageHdr->mnNAI, messageHdr->mnNAILen, aaaSPI, (unsigned char *)&mnAAAAuthExt[1], mnAAAAuthExtLen - sizeof (mnAAAAuthExt), length, reqPtr->homeAddr, reqPtr->haAddr, _B_FALSE, messageHdr->inIfindex, (void *)messageHdr, mnChallenge, mnChallengeLen); if (result) { /* * Now we look at the result code to determine * what the error was. */ faCounters.faMNAuthFailureCnt++; return (FA_MN_AUTH_FAILURE); } else { /* * Make sure that we notify the caller that we * should not forward the request to the Home * Agent since: * - if diameter: it is being done via * diameter server. * - if radius: we need to wait for the auth * answer. */ *forwardFlag = _B_FALSE; } } else if (mfAuthRequired) { syslog(LOG_ERR, "Failed MN-FA authentication - No Ext"); faCounters.faMNAuthFailureCnt++; return (FA_MN_AUTH_FAILURE); } } return (0); }
/* * Function: isAuthExtOk * * Arguments: buffer - Pointer to a packet * buflen - Offset in the packet where the authentication * extension can be found. * msa - Pointer to a Security Assocation Entry * * Description: Buffer contains buflen bytes of a registration request * and an immediately following authentication extension. * Check if the authentication extension is correct * according to the given msa. * * Returns: boolean_t - _B_TRUE if authentication extension was * computed using the protocol security assocation. */ static boolean_t isAuthExtOk(unsigned char buffer[], int buflen, MipSecAssocEntry *msa) { int authLen; boolean_t result = _B_FALSE; authExt *aep; genAuthExt *genAep; uint32_t SPI; /* LINTED E_BAD_PTR_CAST_ALIGN */ aep = (authExt *) (buffer + buflen); /* * Support for the latest Challenge/response draft, which * requires support for the generalized authentication header. */ switch (aep->type) { case REG_MH_AUTH_EXT_TYPE: case REG_MF_AUTH_EXT_TYPE: case REG_FH_AUTH_EXT_TYPE: GET_SPI(SPI, aep); if (SPI != msa->mipSecSPI) { mipverbose(("Type: %d, Length %d\n", aep->type, aep->length)); mipverbose(("SPI mismatch got %d had %d.\n", SPI, msa->mipSecSPI)); result = _B_FALSE; } else { /* this length includes 4 bytes SPI */ authLen = aep->length - 4; result = isAuthOk(buffer, buflen + sizeof (authExt), (buffer + buflen + sizeof (authExt)), authLen, msa); } break; case REG_GEN_AUTH_EXT_TYPE: genAep = (genAuthExt *) aep; GET_GEN_AUTH_SPI(SPI, genAep); if (SPI != msa->mipSecSPI) { mipverbose(("Type: %d, subType: %d, Length %d\n", genAep->type, genAep->subType, genAep->length)); mipverbose(("SPI mismatch got %d had %d.\n", SPI, msa->mipSecSPI)); result = _B_FALSE; } else { /* This length includes 4 bytes SPI */ authLen = ntohs(genAep->length) - 4; result = isAuthOk(buffer, buflen + sizeof (genAuthExt), (buffer + buflen + sizeof (genAuthExt)), authLen, msa); } break; default: /* * Unknown authentication type.... reject */ result = _B_FALSE; break; } return (result); }
/* ARGSUSED */ int haCheckRegReqAuthContinue(MessageHdr *messageHdr, HaMobileNodeEntry **hamnePtr, uint32_t *mnSPI, uint32_t *faSPI) { regRequest *reqPtr; authExt *mnAuthExt = NULL; genAuthExt *maAuthExt = NULL; MipSecAssocEntry *mipSecAssocEntry; uint32_t SPI; int index; int mnAuthExtLen; /* LINTED E_BAD_PTR_CAST_ALIGN */ reqPtr = (regRequest *)messageHdr->pkt; if (reqPtr->homeAddr) { /* * Find the Mobile Node. Remember that this node will * be locked upon return. As it turns out, the caller * to this function will have to unlock the node since * we are passing it the pointer as part of an argument. */ *hamnePtr = findHashTableEntryUint(&haMobileNodeHash, reqPtr->homeAddr, LOCK_WRITE, NULL, 0, 0, 0); } if (*hamnePtr == NULL) { /* * Search for the MobileNodeEntry based on the * NAI. */ *hamnePtr = findHashTableEntryString(&haMobileNodeHash, messageHdr->mnNAI, messageHdr->mnNAILen, LOCK_WRITE, NULL, 0, 0, 0); } /* LINTED E_BAD_PTR_CAST_ALIGN */ GET_AUTH_EXT(messageHdr, index, REG_MH_AUTH_EXT_TYPE, mnAuthExt, mnAuthExtLen); /* * If aaaProtocol != RADIUS/DIAMETER, then the home agent CAN * accept Mobile-AAA Authentication extensions, so if we cannot * find the Authentication Extension, find the MN-AAA. * * Happy Dave? */ if ((mnAuthExtLen == 0) && (aaaProtocol == AAA_NONE)) { /* * Support for the latest Challenge/Response I-D * * This code does not belong in the HA, this is * really targetted to the AAA Server. We will * include it to fully support the protocol. */ /* LINTED E_BAD_PTR_CAST_ALIGN */ GET_GEN_AUTH_EXT(messageHdr, index, GEN_AUTH_MN_AAA, maAuthExt, mnAuthExtLen); if (mnAuthExtLen == 0) { syslog(LOG_ERR, "Missing Challenge or Response"); haCounters.haMNAuthFailureCnt++; return (HA_MN_AUTH_FAILURE); } /* * Get the MN-AAA SPI */ GET_GEN_AUTH_SPI(SPI, maAuthExt); #ifdef KEY_DISTRIBUTION /* * If this code is compiled, the Home Agent will provide AAA * like functionality by creating Session Keys for: * MN-HA * MN-FA * FA-HA * The last one is normally not seen by the Home Agent when * keys are received from DIAMETER, but since we are providing * this functionality (mostly for testing purposes) we will * send it to the Foreign Agent as a vendor specific extension. */ createSessionKey(messageHdr->mnHaKey, &messageHdr->mnHaKeyLen, &messageHdr->mnHaSPI); createSessionKey(messageHdr->mnFaKey, &messageHdr->mnFaKeyLen, &messageHdr->mnFaSPI); createSessionKey(messageHdr->faHaKey, &messageHdr->faHaKeyLen, &messageHdr->faHaSPI); messageHdr->kdcKeysPresent = _B_TRUE; messageHdr->mnAAASPI = SPI; #endif /* KEY_DISTRIBUTION */ } else if (mnAuthExt) { /* * Get the MN-HA SPI */ GET_SPI(SPI, mnAuthExt); } else { SPI = 0; } if (*hamnePtr == NULL) { /* * So we have a couple of options here. The first being * where the packet is received by the AAA. In this * case, the Mobile Node will not exist locally, and the * key would have been installed as a dynamic key. * The second option is where the default node is being * used. When this occurs, it is mandatory that the * mobile node use the default SPI. */ if (messageHdr->pktSource == MIP_PKT_FROM_FA) { /* * So, it looks like we don't know who this is. If a * default SA is setup, we will check if we can * create a dynamic Mobile Node Entry. */ if (defaultNodeSPI == 0 || defaultNodeSPI != SPI) { syslog(LOG_ERR, "As far as I'm concerned, this " "mobile node doesn't exist"); return (HA_ADM_PROHIBITED); } } else { SPI = messageHdr->mnHaSPI; } } else { if ((messageHdr->pktSource == MIP_PKT_FROM_AAA) || (messageHdr->pktSource == MIP_PKT_FROM_RADIUS)) { SPI = messageHdr->mnHaSPI; (*hamnePtr)->haMnSPI = SPI; } else { /* * Did the Mobile Node specify the correct SPI? */ if ((*hamnePtr)->haMnSPI != SPI) { syslog(LOG_ERR, "Failed MN-HA authentication - " "Invalid SPI requested %d, looking for %d", SPI, (*hamnePtr)->haMnSPI); haCounters.haMNAuthFailureCnt++; return (HA_MN_AUTH_FAILURE); } } } *mnSPI = SPI; /* * if an SA is returned, the node will be locked so we * need to unlock it when we are done. */ if ((mipSecAssocEntry = findSecAssocFromSPI(SPI, LOCK_READ)) == NULL) { syslog(LOG_ERR, "Failed MN-HA authentication - " "No SPI defined"); haCounters.haMNAuthFailureCnt++; return (HA_MN_AUTH_FAILURE); } if ((messageHdr->pktSource == MIP_PKT_FROM_AAA) || (messageHdr->pktSource == MIP_PKT_FROM_RADIUS)) { if (mipSecAssocEntry->mipSecIsEntryDynamic != TRUE) { /* * So the packet came from the AAA. We need to * ensure that the key being used is in fact a * dynamic key. Otherwise we are leaving a security * hole wide open. */ (void) rw_unlock(&mipSecAssocEntry->mipSecNodeLock); syslog(LOG_WARNING, "A AAA Mobile Node is attempting" " to use a static key - security violation!"); haCounters.haMNAuthFailureCnt++; return (HA_MN_AUTH_FAILURE); } } else if (isAuthExtOk(messageHdr->pkt, (messageHdr->extIdx[index] - messageHdr->pkt), mipSecAssocEntry) == _B_FALSE) { syslog(LOG_ERR, "Failed MN-HA authentication"); haCounters.haMNAuthFailureCnt++; (void) rw_unlock(&mipSecAssocEntry->mipSecNodeLock); return (HA_MN_AUTH_FAILURE); } (void) rw_unlock(&mipSecAssocEntry->mipSecNodeLock); return (0); }
/* * Function: haCheckRegReqAuth * * Arguments: messageHdr - Pointer to the Message Control Block * hamnePtr - Pointer to a pointer to a mobile node entry * mnSPI - Pointer to the Mobile Node SPI * faSPI - Pointe to the Foreign Agent SPI * * Description: This function is used to authenticate a Registration * request on the Home Agent. First we attempt to find * the Mobile Node Entry using the Home Address. If the * Home Address in the request was set to zero, we will * attempt to find it using the Mobile Node's NAI. * * Next we will ensure that either the Mobile-Home or the * Mobile-AAA autentication extension is present. If none * is present, and the packet was marked as being received * by the Foreign Agent (as opposed to the AAA), we will * make sure that the unknown Mobile Node is attempting * to authenticate using the default SPI. If the packet * was received via the AAA infrastructure, we will * not require any authentication from the Mobile Node. * * Lastly, we will check the Foreign-Home Authentication * extension. If one was not found, and the packet was * not received by the AAA, we will fail authentication. * * Note that if a Mobile Node Entry pointer is returned * by this function, the node will be locked. The caller * is responsible to unlock the node. * * Returns: int - 0 if successful, otherwise the Mobile-IP error code * is returned. */ int haCheckRegReqAuth(MessageHdr *messageHdr, HaMobileNodeEntry **hamnePtr, uint32_t *mnSPI, uint32_t *faSPI) { regRequest *reqPtr; int code = 0; int result; MipSecAssocEntry *mipSecAssocEntry; genAuthExt *maAuthExt = NULL; authExt *mnAuthExt = NULL; authExt *faAuthExt = NULL; int mnAuthExtLen; int faAuthExtLen; int index; uint32_t SPI; /* LINTED E_BAD_PTR_CAST_ALIGN */ reqPtr = (regRequest *)messageHdr->pkt; *hamnePtr = NULL; #ifdef RADIUS_ENABLED if (radiusEnabled) { /* * We always have to force a RADIUS lookup. */ *hamnePtr = radiusCheckUpdate(*hamnePtr, &haMobileNodeHash, reqPtr->homeAddr); } #endif /* RADIUS_ENABLED */ /* * If a Foreign agent Home Agent authentication extension exists * check it. */ /* LINTED E_BAD_PTR_CAST_ALIGN */ GET_AUTH_EXT(messageHdr, index, REG_FH_AUTH_EXT_TYPE, faAuthExt, faAuthExtLen); if (faAuthExtLen) { GET_SPI(SPI, faAuthExt); *faSPI = SPI; /* * if an SA is returned, the node will be locked so we * need to unlock it when we are done. */ if ((mipSecAssocEntry = findSecAssocFromSPI(SPI, LOCK_READ)) == NULL) { syslog(LOG_ERR, "Failed FA-HA authentication - SPI (%d) " "defined", SPI); haCounters.haFAAuthFailureCnt++; return (HA_FA_AUTH_FAILURE); } if (isAuthExtOk(messageHdr->pkt, (messageHdr->extIdx[index] - messageHdr->pkt), mipSecAssocEntry) == _B_FALSE) { syslog(LOG_ERR, "Failed FA-HA authentication"); haCounters.haFAAuthFailureCnt++; (void) rw_unlock( &mipSecAssocEntry->mipSecNodeLock); return (HA_FA_AUTH_FAILURE); } (void) rw_unlock(&mipSecAssocEntry->mipSecNodeLock); } else if ((messageHdr->pktSource != MIP_PKT_FROM_AAA) && (messageHdr->pktSource != MIP_PKT_FROM_RADIUS)) { /* * If the packet comes from the AAA, we do not need * the FA-HA auth, otherwise we may be configured * to require it. */ if (fhAuthRequired) { haCounters.haFAAuthFailureCnt++; return (HA_FA_AUTH_FAILURE); } } else { *faSPI = messageHdr->faHaSPI; } /* * If a Mobile Node Home Agent authentication extension exists * check it. */ /* LINTED E_BAD_PTR_CAST_ALIGN */ GET_AUTH_EXT(messageHdr, index, REG_MH_AUTH_EXT_TYPE, mnAuthExt, mnAuthExtLen); if (mnAuthExtLen) { GET_SPI(SPI, mnAuthExt); /* * if an SA is returned, the node will be locked so we * need to unlock it when we are done. */ if ((mipSecAssocEntry = findSecAssocFromSPI(SPI, LOCK_READ)) == NULL) { syslog(LOG_ERR, "Failed MN-HA authentication - " "No SPI defined"); haCounters.haMNAuthFailureCnt++; return (HA_MN_AUTH_FAILURE); } if ((messageHdr->pktSource == MIP_PKT_FROM_AAA) || (messageHdr->pktSource == MIP_PKT_FROM_RADIUS)) { if (mipSecAssocEntry->mipSecIsEntryDynamic != TRUE) { /* * So the packet came from the AAA. We * need to ensure that the key being * used is in fact a dynamic key. * Otherwise we are leaving a security * hole wide open. */ (void) rw_unlock( &mipSecAssocEntry->mipSecNodeLock); syslog(LOG_WARNING, "A AAA Mobile " "Node is attempting to use a " "static key - security violation!"); haCounters.haMNAuthFailureCnt++; return (HA_MN_AUTH_FAILURE); } } else if (isAuthExtOk(messageHdr->pkt, (messageHdr->extIdx[index] - messageHdr->pkt), mipSecAssocEntry) == _B_FALSE) { syslog(LOG_ERR, "Failed MN-HA " "authentication"); haCounters.haMNAuthFailureCnt++; (void) rw_unlock( &mipSecAssocEntry->mipSecNodeLock); return (HA_MN_AUTH_FAILURE); } (void) rw_unlock(&mipSecAssocEntry->mipSecNodeLock); } if (aaaProtocol == RADIUS) { /* * Validate MN_AAA ext exists before AAA call * This way if an error we don't need * to call on AAA. */ /* LINTED E_BAD_PTR_CAST_ALIGN */ GET_GEN_AUTH_EXT(messageHdr, index, GEN_AUTH_MN_AAA, maAuthExt, mnAuthExtLen); if (mnAuthExtLen == 0) { syslog(LOG_ERR, "Missing MN AAA Ext"); haCounters.haMNAuthFailureCnt++; return (HA_MN_AUTH_FAILURE); } /* * Get the MN-AAA SPI */ GET_GEN_AUTH_SPI(*mnSPI, maAuthExt); /* * Make sure SPI used is the Radius SPI (2). */ if (*mnSPI != RADIUS_SPI) { haCounters.haMNAuthFailureCnt++; return (HA_MN_AUTH_FAILURE); } /* * If using Radius, we'd like to preserve messageHdr * until we get a reply from the Radius server */ messageHdr->dontDeleteNow = _B_TRUE; result = AAAAuthenticateRegReq(messageHdr->pkt, messageHdr->pktLen, messageHdr->mnNAI, messageHdr->mnNAILen, *mnSPI, (unsigned char *)NULL, 0, 0, reqPtr->homeAddr, reqPtr->haAddr, _B_TRUE, 0, (void *)messageHdr, NULL, 0); if (result) { /* * Now we look at the result code to determine * what the error was. */ haCounters.haMNAuthFailureCnt++; return (HA_MN_AUTH_FAILURE); } } /* * If talking to RADIUS client, you must wait for a reponse * back (from AAAAuthenticateRegReq() call) before * continuing on with haCheckRegReqAuthContinue(). * As such, wait until RADIUS responds then continue on * with authentication process. */ if (aaaProtocol != RADIUS) { code = haCheckRegReqAuthContinue(messageHdr, hamnePtr, mnSPI, faSPI); return (code); } return (0); }
/* * Function: faCheckRegRepAuth * * Arguments: messageHdr - Pointer to the Message Control Block * favePtr - Pointer to the Visitor Entry * * Description: This function is used to authenticate a Registration * Reply. If the agent is configured to advertise * challenges, we will make sure that the challenge was * returned by the Home Agent, and that the challenge * value is identical to the value that was used by the * Mobile Node. * * Next, if the Foreign-Home Authentication extension * is present, it is authenticated. If it is present and * the agent is configured to require it, we will fail * authentication. * * Returns: int - 0 if successful, otherwise the Mobile-IP error code * is returned. */ int faCheckRegRepAuth(MessageHdr *messageHdr, FaVisitorEntry *favePtr) { authExt *haAuthExt; MipSecAssocEntry *mipSecAssocEntry; #ifdef KEY_DISTRIBUTION keyDataExt *keyData; uint32_t keyDataLen; #endif /* KEY_DISTRIBUTION */ unsigned char *challenge; uint32_t SPI; int haAuthExtLen; int challengeLen; int index; /* * If a Challenge was received by the Mobile Node (due to our * advertisement, let's make sure that the same challenge is * present in the response. */ if (favePtr->faVisitorChallengeToHALen) { /* * Retrieve the Challenge */ GET_EXT_DATA(messageHdr, index, REG_MF_CHALLENGE_EXT_TYPE, challenge, challengeLen); if (challengeLen == 0 || challengeLen > ADV_CHALLENGE_LENGTH) { /* * Protect against buffer overflows... */ syslog(LOG_ERR, "excessively large or missing Challenge"); faCounters.faPoorlyFormedRepliesCnt++; /* * Support for the latest Challenge/response I-D. * If the challenge was expected and not present, * return a missing challenge error. */ return (FA_MISSING_CHALLENGE); } if (memcmp(challenge, favePtr->faVisitorChallengeToHA, challengeLen) != 0) { /* * Protect against buffer overflows... */ syslog(LOG_ERR, "invalid Challenge in Registration Reply"); faCounters.faPoorlyFormedRepliesCnt++; /* * Support for the latest Challenge/response I-D. * If the challenge was invalid, return * an unknown challenge error. */ return (FA_UNKNOWN_CHALLENGE); } } #ifdef KEY_DISTRIBUTION /* * If KEY_DISTRIBUTION is defined (testing purpose only), we will * extract the FA session keys from the registration reply. */ /* LINTED E_BAD_PTR_CAST_ALIGN */ GET_VEND_KEY_EXT(messageHdr, index, VENDOR_ID_SUN, REG_MN_FA_KEY_EXT, keyData, keyDataLen); if (keyDataLen) { /* * We have a key!!! Let's create our security assoc. */ if (createSecAssocFromKeyData(keyData, keyDataLen, &SPI) == _B_FALSE) { syslog(LOG_ERR, "unable to create dynamic MN-FA SA"); return (HA_FA_AUTH_FAILURE); } favePtr->faVisitorSPI = SPI; } /* * If KEY_DISTRIBUTION is defined (testing purpose only), we will * extract the FA session keys from the registration reply. */ /* LINTED E_BAD_PTR_CAST_ALIGN */ GET_VEND_KEY_EXT(messageHdr, index, VENDOR_ID_SUN, REG_FA_HA_KEY_EXT, keyData, keyDataLen); if (keyDataLen) { /* * We have a key!!! Let's create our security assoc. */ if (createSecAssocFromKeyData(keyData, keyDataLen, &SPI) == _B_FALSE) { syslog(LOG_ERR, "unable to create dynamic FA-HA SA"); return (HA_FA_AUTH_FAILURE); } } #endif /* KEY_DISTRIBUTION */ /* * If a Home agent Foreign agent authentication extension exists * check it. */ /* LINTED E_BAD_PTR_CAST_ALIGN */ GET_AUTH_EXT(messageHdr, index, REG_FH_AUTH_EXT_TYPE, haAuthExt, haAuthExtLen); if (haAuthExtLen) { GET_SPI(SPI, haAuthExt); /* * Remember that the node will be locked upon return. * We need to unlock it when we are done... */ if ((mipSecAssocEntry = findSecAssocFromSPI(SPI, LOCK_READ)) == NULL) { syslog(LOG_ERR, "Error: No Home Agent SA (%d)", SPI); faCounters.faHAAuthFailureCnt++; return (HA_FA_AUTH_FAILURE); } if (isAuthExtOk(messageHdr->pkt, (messageHdr->extIdx[index] - messageHdr->pkt), mipSecAssocEntry) == _B_FALSE) { syslog(LOG_ERR, "Failed FA-HA authentication"); faCounters.faHAAuthFailureCnt++; (void) rw_unlock(&mipSecAssocEntry->mipSecNodeLock); return (HA_FA_AUTH_FAILURE); } (void) rw_unlock(&mipSecAssocEntry->mipSecNodeLock); /* * Remove the extension by playing with the * packet's length. */ messageHdr->pktLen = (messageHdr->extIdx[index-1] - messageHdr->pkt) + messageHdr->extHdrLength[index-1] + messageHdr->extLength[index-1]; if (aaaProtocol == DIAMETER && messageHdr->pktSource == MIP_PKT_FROM_AAA) { /* * We probably ended up getting a new SPI from the * AAA Server. Update the Visitor Entry with the * new SPI. */ favePtr->faVisitorSPI = messageHdr->mnFaSPI; } } else { if (fhAuthRequired) { faCounters.faHAAuthFailureCnt++; return (HA_FA_AUTH_FAILURE); } } return (0); }