diff options
Diffstat (limited to 'usr/src/cmd/cmd-inet/usr.lib/mipagent/auth.c')
| -rw-r--r-- | usr/src/cmd/cmd-inet/usr.lib/mipagent/auth.c | 1661 |
1 files changed, 0 insertions, 1661 deletions
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mipagent/auth.c b/usr/src/cmd/cmd-inet/usr.lib/mipagent/auth.c deleted file mode 100644 index 6672556174..0000000000 --- a/usr/src/cmd/cmd-inet/usr.lib/mipagent/auth.c +++ /dev/null @@ -1,1661 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1999-2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * file: auth.c - * - * This function contains all of the routines - * necessary to authenticate Registration Requests, - * including the functions which add and validate - * the authentication extensions, the SPI lookup - * routines, etc. - */ - -#include <stdio.h> -#include <string.h> -#include <syslog.h> - -#include "agent.h" -#include "mip.h" -#include "md5.h" -#include "auth.h" - -#include <sys/types.h> -#include <netinet/in.h> - - -extern char msg[]; -extern AAA_Protocol_Code aaaProtocol; -extern boolean_t faChallengeAdv; -extern boolean_t mfAuthRequired; -extern boolean_t fhAuthRequired; -extern int logVerbosity; - -/* - * Default Values... - */ -extern uint32_t defaultPool; -extern uint32_t defaultNodeSPI; - -#ifdef RADIUS_ENABLED -HaMobileNodeEntry *radiusCheckUpdate(HaMobileNodeEntry *dest, - struct hash_table *htbl, ipaddr_t mnAddr); -#endif /* RADIUS_ENABLED */ - -static boolean_t isAuthExtOk(unsigned char *, int, MipSecAssocEntry *); -extern int hexdump(char *, unsigned char *, int); -extern uint32_t getRandomValue(); - -/* ----------------- Common to all mobility agents ------------------- */ -/* - * This table stores all of the Security Assocations - */ -extern HashTable mipSecAssocHash; - -/* - * This table has one entry for each known Mobility Agent - */ -extern HashTable mipAgentHash; - -/* - * This table has one entry for each pool defined in the config file - */ -extern HashTable mipPoolHash; - -/* ------------------ Specific to foreign agents -------------------- */ - -/* - * Counters maintained by Foreign Agents - */ -extern ForeignAgentCounters faCounters; - -/* - * The last two challenges advertised - */ -extern char faLastChallengeIssued[2][ADV_CHALLENGE_LENGTH]; - - -/* ------------------ Specific to home agents -------------------- */ -/* - * This table has one entry for each mobile node for which a mobility - * agent offers Home Agent services. - */ -extern HashTable haMobileNodeHash; - -/* - * Counters maintained by Home Agents - */ -extern HomeAgentCounters haCounters; - -/* - * Compute authenticator for the data in buffer based on the - * Mobile IP Security Association pointed to by msaEntry. - */ - -/* - * Function: computeAuth - * - * Arguments: buffer - Pointer to buffer - * buflen - Length of data in the buffer - * authenticator - Pointer to the output buffer - * authenticationlen - length of the output buffer - * msa - Pointer to the security association entry. - * - * Description: Compute authenticator for the data in buffer based on the - * Mobile IP Security Association pointed to by msaEntry. - * - * Returns: void - */ -static void -computeAuth(unsigned char buffer[], int buflen, - unsigned char authenticator[], int *authenticatorlen, - MipSecAssocEntry *msa) -{ - MD5_CTX context; - - /* - * Initialize the length. - */ - - if (msa) { - switch (msa->mipSecAlgorithmType) { - case MD5: - if (*authenticatorlen < AUTHENTICATOR_LEN) { - syslog(LOG_ERR, - "Not enough space for MD5 authenticator."); - } else if (msa->mipSecAlgorithmMode != PREFIXSUFFIX) { - syslog(LOG_ERR, "Unknown mode specified " \ - "for MD5 algorithm."); - } else { - /* - * No longer print MD5 results. - */ - *authenticatorlen = 0; - MD5Init(&context); - MD5Update(&context, msa->mipSecKey, - (unsigned int) msa->mipSecKeyLen); - MD5Update(&context, buffer, - (unsigned int) buflen); - MD5Update(&context, msa->mipSecKey, - (unsigned int) msa->mipSecKeyLen); - MD5Final(authenticator, &context); - *authenticatorlen = AUTHENTICATOR_LEN; - } - break; - - case NONE: - /* we leave the contents of authenticator unchanged */ - *authenticatorlen = AUTHENTICATOR_LEN; - break; - - default: - /* - * Any other authentication transform, which we - * currentlydo not support. - */ - syslog(LOG_ERR, "Invalid Authentication Type " \ - "requested"); - } - } -} - - -/* - * Function: appendAuthExt - * - * Arguments: buffer - Pointer to the packet - * buflen - Offset in the packet where extension is - * to be added. - * type - Extension Id - * msa - Pointer to the Security Assocation Entry - * - * Description: Append authentication extension to a registration - * reply contained in buffer based on the Mobile IP - * Security Association pointed to by MSA. Returns - * total number of bytes in the extension. - * - * Returns: The number of bytes added to the packet. - */ -int -appendAuthExt(unsigned char *buffer, size_t buflen, uint8_t type, - MipSecAssocEntry *msa) -{ - int authlen = 0; - authExt *aep; - uint32_t SPI; - uint16_t tempShort; - - if (msa) { - /* - * TODO: - * The length of authenticator actually depends on the - * algorithm. For now, we assume AUTHENTICATOR_LEN. - */ - - /* LINTED E_BAD_PTR_CAST_ALIGN */ - aep = (authExt *)(buffer + buflen); - aep->type = type; - - /* - * We need to set to length to the sizeof the SPI plus the - * length of the authenticator. - */ - aep->length = (sizeof (SPI) + AUTHENTICATOR_LEN); - SPI = (msa == NULL) ? 0 : msa->mipSecSPI; - tempShort = htons(SPI >> AUTHENTICATOR_LEN); - (void) memcpy(&aep->SPIhi, &tempShort, sizeof (uint16_t)); - tempShort = htons(SPI & 0xffff); - (void) memcpy(&aep->SPIlo, &tempShort, sizeof (uint16_t)); - - authlen = AUTHENTICATOR_LEN; - computeAuth(buffer, buflen + sizeof (authExt), - buffer + buflen + sizeof (authExt), &authlen, msa); - - if (authlen) { - authlen += sizeof (authExt); - } - } - - return (authlen); -} - - -/* - * Function: isAuthOk - * - * Arguments: buffer - Pointer to buffer - * buflen - Length of data in the buffer - * authenticator - Pointer to hash to compare against - * authenticationlen - length of hash buffer - * msa - Pointer to the security association entry - * - * Description: This function computes a hash using the buffer and - * compares the result with the data in the authenticator. - * If both values match, the packet is considered - * authenticated. - * - * Returns: boolean_t - _B_FALSE if packet is not authenticated. - */ -static boolean_t -isAuthOk(unsigned char buffer[], int buflen, - unsigned char authenticator[], int authenticatorlen, - MipSecAssocEntry *msa) -{ - static unsigned char newAuth[32]; - int newAuthLen = 32; - int i; - - if (msa == NULL) { - return (_B_FALSE); - } - - switch (msa->mipSecAlgorithmType) { - case MD5: - computeAuth(buffer, buflen, newAuth, &newAuthLen, msa); - mipverbose(("authenticator = %d bytes, newAuth = %d bytes\n", - authenticatorlen, newAuthLen)); - if (newAuthLen != authenticatorlen) - return (_B_FALSE); - - for (i = 0; i < newAuthLen; i++) { - if (newAuth[i] != authenticator[i]) { - syslog(LOG_ERR, - "isAuthOk: bad key at position %d (%02X <> %02X)\n", - i, authenticator[i], newAuth[i]); - return (_B_FALSE); - } - } - - break; - - case NONE: - /* No checks required */ - break; - } - - return (_B_TRUE); -} - - -/* - * 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); -} - -#ifdef TEST_AUTH -/* - * Function: main - * - * Arguments: argc - Number of command line parameters - * argv - Pointer to command line arguments - * - * Description: This function is used to validate our MD5 implementation. - * It is no longer in use, but is kept in case one needs - * to test the authentication computation in this file - * stand-alone. - * - * Returns: exits - */ -int -main(int argc, char *argv[]) -{ - int i; - unsigned char digest[AUTHENTICATOR_LEN]; - int digestlen = AUTHENTICATOR_LEN; - MipSecAssocEntry msae = { { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - 1, 0, MD5, PREFIXSUFFIX, 16, - { 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11 - }, - TIMESTAMPS, 0 }; - - unsigned char packet[30] = { - /* - * 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - * 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - */ - 0x01, 0x00, 0x00, 0x28, 0x81, 0x92, 0x7a, 0xcc, - 0x81, 0x92, 0x7a, 0xbf, 0x81, 0x92, 0xc9, 0x09, - 0x00, 0x00, 0x00, 0x00, 0xe4, 0xa8, 0x5f, 0xcb, - 0x20, 0x14, 0x00, 0x00, 0x00, 0x01 - /* - * 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - * 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 - */ - }; - /* - * 0x01, 0x00, 0x01, 0x2c, 0x81, 0x92, 0x7a, 0xc0, - * 0x81, 0x92, 0x7a, 0x7b, 0x81, 0x92, 0xc9, 0x09, - * 0x00, 0x00, 0x00, 0x00, 0x17, 0xe1, 0x2c, 0x23, - * 0x20, 0x14, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - * 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - * 0x11, 0x11 - * }; - * unsigned char packet[] = {'J', 'i', 'm'}; - */ - - printMSAE(&msae); - computeAuth(packet, 30, digest, &digestlen, &msae); - (void) printf("Authenticator for packet = "); - printBuffer(digest, digestlen); - (void) printf("\n"); - - /* Simulate data corruption or incorrect MSAE */ - msae.mipSecKeyLen = 2; - packet[2] = 0x00; - msae.mipSecKey[0] = 'A'; - printMSAE(&msae); - if (isAuthOk(packet, 3, digest, digestlen, &msae)) - (void) printf("Check succeeded.\n"); - -} -#endif /* TEST_AUTH */ - -/* - * Function: findSecAssocFromSPI - * - * Arguments: SPI - The Security Parameter Index value - * lockType - The Lock type, which can be: - * LOCK_NONE - No Lock - * LOCK_READ - Read Lock - * LOCK_WRITE - Write Lock - * - * Description: This function will look for a security assocation - * entry in the hash table matching on the SPI. If - * a lock type was requested, upon return the node - * will be locked. The caller will be responsible - * for unlocking the node when it no longer needs - * the security association entry. - * - * If a security association entry was found, and - * the entry is marked as dynamic and if the key - * has expired, a NULL value will be returned. - * - * Returns: If successful, a pointer to a Security Association - * Entry will be returned, otherwise NULL. - */ -MipSecAssocEntry * -findSecAssocFromSPI(uint32_t SPI, int lockType) -{ - MipSecAssocEntry *saEntry = NULL; - time_t currentTime; - - /* - * Let's see if we can find the SA using the SPI. - */ - if ((saEntry = findHashTableEntryUint(&mipSecAssocHash, - SPI, lockType, NULL, 0, 0, 0)) != NULL) { - /* - * Keys has a defined lifetime, which is set by the - * home AAA Server. We need to check whether the - * key being used is still valid. - */ - - GET_TIME(currentTime); - if (saEntry->mipSecIsEntryDynamic == TRUE && - saEntry->mipSecKeyLifetime < currentTime) { - /* - * The Security Association has expired. - * If the node was locked, we need to - * unlock it. We will be returning a NULL - * to the caller since this is no longer - * valid. - */ - if (lockType != LOCK_NONE) { - (void) rw_unlock(&saEntry->mipSecNodeLock); - } - saEntry = NULL; - } - } - - return (saEntry); -} - - -/* - * Note that upon return of a security association entry, the - * node will be locked. The caller must unlock the node once - * it is finished with the entry. - */ -/* - * Function: findSecAssocFromIp - * - * Arguments: address - Peer's IP Address - * lockType - The Lock type, which can be: - * LOCK_NONE - No Lock - * LOCK_READ - Read Lock - * LOCK_WRITE - Write Lock - * - * Description: This function will look for a security assocation - * entry in the hash table matching on the IP Address. - * If a lock type was requested, upon return the node - * will be locked. The caller will be responsible - * for unlocking the node when it no longer needs - * the security association entry. - * - * If a security association entry was found, and - * the entry is marked as dynamic, if the key has - * expired - * - * Returns: If successful, a pointer to a Security Association - * Entry will be returned - * If not successful, NULL is returned. - */ -MipSecAssocEntry * -findSecAssocFromIp(ipaddr_t address, int lockType) -{ - MobilityAgentEntry *maEntry; - MipSecAssocEntry *saEntry = NULL; - - /* - * First we need to find the MA structure to get - * the SPI value. - */ - if ((maEntry = findHashTableEntryUint(&mipAgentHash, - address, LOCK_READ, NULL, 0, 0, 0)) != NULL) { - /* - * Good, now let's find the SA itself. - */ - saEntry = findSecAssocFromSPI(maEntry->maSPI, lockType); - - (void) rw_unlock(&maEntry->maNodeLock); - } - - return (saEntry); -} - -/* - * Function: findMaeFromIp - * - * Arguments: address - Peer's IP Address - * lockType - The Lock type, which can be: - * LOCK_NONE - No Lock - * LOCK_READ - Read Lock - * LOCK_WRITE - Write Lock - * - * Description: This function will look for an IPsec Policy - * entry in the hash table matching on the IP Address. - * If a lock type was requested, upon return the node - * will be locked. The caller will be responsible - * for unlocking the node when it no longer needs - * the security association entry. - * - * Returns: If successful, a pointer to a Security Association - * Entry will be returned, otherwise NULL. - */ -MobilityAgentEntry * -findMaeFromIp(ipaddr_t address, int lockType) -{ - MobilityAgentEntry *maEntry; - - /* - * First we need to find the MA structure to get - * the SPI value. - */ - if ((maEntry = findHashTableEntryUint(&mipAgentHash, - address, lockType, NULL, 0, 0, 0)) == NULL) - return (0); - - return (maEntry); -} - - -#ifdef KEY_DISTRIBUTION -/* - * KEY_DISTRIBUTION MUST ONLY BE COMPILED FOR TESTING!!! - * - * This version of mipagent supports a AAA/DIAMETER - * interface. The DIAMETER server generates keying - * material that is sent to the Home Agent. The keys - * sent are both for the Home Agent, and for the Mobile - * Node. The keys for the Mobile Nodes are added to the - * registration reply, and the keys for the Home Agent - * cause the Home Agent to create a local SA. - * - * Since DIAMETER/AAA is not currently a product, and key - * distribution must still be tested, we have added some - * test code in mipagent. When KEY_DISTRIBUTION is enabled, - * the home agent creates and encrypts session keys for - * the Mobile Node (mimicking DIAMETER), and creates local - * SAs. Further, since the session keys MUST also be sent - * to the Foreign Agent, the session keys are sent in the - * clear to the Foreign Agent through Vendor Specific - * extensions. - * - * Again, this code is for testing purpose only and must not - * be enabled for production code, since it hasn't been - * fully tested. - */ -#define MAX_SESSION_KEY_LEN 16 -/* - * Function: createSessionKey - * - * Arguments: key - Pointer to session key buffer - * keyLen - Pointer to Length of session key - * spi - Pointer to SPI - * - * Description: This function is used to create pseudo-random - * session keys, and SPI values. Note that the - * keys created here are by no means random, and - * this function is only used for testing purposes. - * - * Returns: none - */ -static void -createSessionKey(uint8_t *key, uint32_t *keyLen, uint32_t *spi) -{ - int i; - - /* - * First we create the SPI value. - */ - *spi = htonl(getRandomValue()); - - /* - * Now we create the session key - */ - for (i = 0; i < MAX_SESSION_KEY_LEN; i++) { - key[i] = getRandomValue(); - } - - /* - * Set the length - */ - *keyLen = MAX_SESSION_KEY_LEN; - -} - -/* - * Function: createSessionKey - * - * Arguments: keyData - Pointer to Genrealized key extension - * keyLen - Length of key extension - * spi - Pointer to SPI - * - * Description: This function will create a local Security - * association, using the information found in - * a generalized key extension. Note that this - * function is only used for testing purposes. - * - * Returns: _B_TRUE if successful - */ -static boolean_t -createSecAssocFromKeyData(keyDataExt *keyData, int keyDataLen, uint32_t *SPI) -{ - uint32_t spi; - uint32_t lifetime; - - /* - * Extract the information from the generalized key ext - */ - (void) memcpy(&spi, &keyData->nodeSPI, sizeof (uint32_t)); - (void) memcpy(&lifetime, &keyData->lifetime, sizeof (uint32_t)); - - /* - * Create a new Security Association Entry - */ - if (aaaCreateKey(ntohl(spi), (uint8_t *)((char *)keyData) + - sizeof (keyDataExt), keyDataLen - sizeof (keyDataExt), - ntohl(lifetime))) { - syslog(LOG_CRIT, "Unable to create SA from keydata"); - return (_B_FALSE); - } - - /* - * Set the SPI value - */ - *SPI = ntohl(spi); - - return (_B_TRUE); -} - -#endif /* KEY_DISTRIBUTION */ - -/* - * Function: faCheckRegReqAuth - * - * Arguments: messageHdr - Pointer to Message Control Block - * mnSPI - Pointer to Mobile Node's SPI - * mnChallenge - Pointer to the FA Challenge - * mnChallengeLen - Length of the Challenge - * forwardFlag - Pointer to the forward msg flag. - * - * Description: This function is responsible for authenticating - * the Registration Request. First, the function - * will check whether the Challenge is present, which - * MUST be if the agent is configured to advertise - * challenges. Next, the Mobile-Foreign is checked - * to ensure that the message is authenticated. If - * the extension was not found, and the agent is - * configured to require this extension, authentication - * will fail. - * - * Lastly, if the Mobile-AAA authentication extension - * is present, we will send a request to the AAA - * infrastructure. If this request is successfully sent, - * the forward flag will be set to _B_FALSE to ensure that the - * caller does not forward the Registration Request to - * the Home Agent. - * - * Returns: int - 0 if successful, otherwise the Mobile-IP error code - * is returned. The forwardFlag will be set to _B_FALSE if - * the message is being sent to the AAA infrastructure. - */ -/* 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: 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); -} - - -/* - * 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: haCheckRegReqAuthContinue - * - * 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. - * - * if aaaProtocol is RADIUS, this funtion will be called after - * an ANSWER is received from the Radius client. - * Otherwise, the processing will continue from - * haCheckRegReqAuth() function. - * - * 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. - */ -/* 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); -} |
