auth.c revision 5c0b7edee9bd9fad49038456b16972ff28fa4187
/*
* 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
* 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"
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
#endif /* RADIUS_ENABLED */
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
*/
/* ------------------ 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
unsigned char authenticator[], int *authenticatorlen,
{
/*
* Initialize the length.
*/
if (msa) {
switch (msa->mipSecAlgorithmType) {
case MD5:
if (*authenticatorlen < AUTHENTICATOR_LEN) {
"Not enough space for MD5 authenticator.");
"for MD5 algorithm.");
} else {
/*
* No longer print MD5 results.
*/
*authenticatorlen = 0;
(unsigned int) msa->mipSecKeyLen);
(unsigned int) buflen);
(unsigned int) msa->mipSecKeyLen);
}
break;
case NONE:
/* we leave the contents of authenticator unchanged */
break;
default:
/*
* Any other authentication transform, which we
* currentlydo not support.
*/
"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
{
int authlen = 0;
if (msa) {
/*
* TODO:
* The length of authenticator actually depends on the
* algorithm. For now, we assume AUTHENTICATOR_LEN.
*/
/* LINTED E_BAD_PTR_CAST_ALIGN */
/*
* We need to set to length to the sizeof the SPI plus the
* length of the authenticator.
*/
if (authlen) {
}
}
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
unsigned char authenticator[], int authenticatorlen,
{
static unsigned char newAuth[32];
int newAuthLen = 32;
int i;
return (_B_FALSE);
}
switch (msa->mipSecAlgorithmType) {
case MD5:
mipverbose(("authenticator = %d bytes, newAuth = %d bytes\n",
if (newAuthLen != authenticatorlen)
return (_B_FALSE);
for (i = 0; i < newAuthLen; i++) {
if (newAuth[i] != authenticator[i]) {
"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
{
int authLen;
/* LINTED E_BAD_PTR_CAST_ALIGN */
/*
* requires support for the generalized authentication header.
*/
case REG_MH_AUTH_EXT_TYPE:
case REG_MF_AUTH_EXT_TYPE:
case REG_FH_AUTH_EXT_TYPE:
mipverbose(("SPI mismatch got %d had %d.\n",
} else {
/* this length includes 4 bytes SPI */
}
break;
case REG_GEN_AUTH_EXT_TYPE:
mipverbose(("Type: %d, subType: %d, Length %d\n",
mipverbose(("SPI mismatch got %d had %d.\n",
} else {
/* This length includes 4 bytes SPI */
}
break;
default:
/*
* Unknown authentication type.... reject
*/
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
{
int i;
unsigned char digest[AUTHENTICATOR_LEN];
int digestlen = AUTHENTICATOR_LEN;
MipSecAssocEntry msae = { { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 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'};
*/
(void) printf("Authenticator for packet = ");
(void) printf("\n");
/* Simulate data corruption or incorrect 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.
*/
{
/*
* Let's see if we can find the SA using the SPI.
*/
/*
* 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.
*/
/*
* 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.
*/
}
}
}
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.
*/
{
/*
* First we need to find the MA structure to get
* the SPI value.
*/
/*
* Good, now let's find the SA itself.
*/
}
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.
*/
{
/*
* First we need to find the MA structure to get
* the SPI value.
*/
return (0);
return (maEntry);
}
#ifdef KEY_DISTRIBUTION
/*
* KEY_DISTRIBUTION MUST ONLY BE COMPILED FOR TESTING!!!
*
* 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.
*
* 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
{
int i;
/*
* First we create the SPI value.
*/
/*
* Now we create the session key
*/
for (i = 0; i < MAX_SESSION_KEY_LEN; i++) {
key[i] = getRandomValue();
}
/*
* Set the length
*/
}
/*
* 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
{
/*
* Extract the information from the generalized key ext
*/
/*
* Create a new Security Association Entry
*/
return (_B_FALSE);
}
/*
* Set the SPI value
*/
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
{
/*
*/
int mnAAAAuthExtLen;
int mnAuthExtLen;
int index;
int result;
/* LINTED E_BAD_PTR_CAST_ALIGN */
*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
* 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) {
"Missing Challenge Extention");
/*
* If the challenge was expected, and found present,
* return a missing challenge error.
*/
return (FA_MISSING_CHALLENGE);
}
/*
* Obviously, we need to validate the challenge.
*/
ADV_CHALLENGE_LENGTH) != 0) {
/*
* Let's try our backup.
*/
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 &&
if (memcmp(
acceptedFave-> \
faVisitorChallengeAdvLen) != 0) {
"Invalid Challenge Extention");
return (FA_UNKNOWN_CHALLENGE);
}
} else {
"Invalid Challenge Extention");
return (FA_UNKNOWN_CHALLENGE);
}
}
}
}
mipverbose(("Checking authext"));
/*
*/
/* LINTED E_BAD_PTR_CAST_ALIGN */
/*
* If a Mobile node Foreign agent authentication extension exists
* check it.
*/
/* LINTED E_BAD_PTR_CAST_ALIGN */
if (mnAuthExtLen) {
/*
* Remember that the node will be locked upon return.
* We need to unlock it when we are done...
*/
if ((mipSecAssocEntry =
return (FA_MN_AUTH_FAILURE);
}
mipSecAssocEntry) == _B_FALSE) {
return (FA_MN_AUTH_FAILURE);
}
/*
* ... and now we are done, let's unlock it.
*/
/*
* Support for differing extension header formats.
*
* Remove the extension by playing with the
* packet's length.
*/
} 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.
*/
mipverbose(("Found a challenge and response\n"));
/*
* First, it is necessary for us to have the NAI in
* order to interact with the AAA.
*/
"MN-AAA present without an NAI");
return (FA_MN_AUTH_FAILURE);
}
/*
* Is AAA Enabled?
*/
if (aaaProtocol == AAA_NONE) {
/* WORK -- why is this here? (PRC?) */
return (0);
#if 0
"Not configured to interact with AAA");
return (FA_MN_AUTH_FAILURE);
#endif
}
if (mnAAAAuthExtLen) {
/*
* If the MN-AAA Authentication extension was
* present, retrieve the SPI value.
*/
}
/*
* If we are using Radius only, then the SPI must be 2.
*/
"- wrong SPI");
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) -
/*
* If using Radius, we'd like to preserve messageHdr
* until we get a reply from the Radius server
*/
if (aaaProtocol == RADIUS)
(unsigned char *)&mnAAAAuthExt[1],
if (result) {
/*
* Now we look at the result code to determine
* what the error was.
*/
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) {
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
{
#ifdef KEY_DISTRIBUTION
#endif /* KEY_DISTRIBUTION */
unsigned char *challenge;
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
*/
/*
* Protect against buffer overflows...
*/
"excessively large or missing Challenge");
/*
* If the challenge was expected and not present,
* return a missing challenge error.
*/
return (FA_MISSING_CHALLENGE);
}
challengeLen) != 0) {
/*
* Protect against buffer overflows...
*/
"invalid Challenge in Registration Reply");
/*
* 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 */
if (keyDataLen) {
/*
* We have a key!!! Let's create our security assoc.
*/
_B_FALSE) {
"unable to create dynamic MN-FA SA");
return (HA_FA_AUTH_FAILURE);
}
}
/*
* 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 */
if (keyDataLen) {
/*
* We have a key!!! Let's create our security assoc.
*/
_B_FALSE) {
"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 */
if (haAuthExtLen) {
/*
* Remember that the node will be locked upon return.
* We need to unlock it when we are done...
*/
if ((mipSecAssocEntry =
return (HA_FA_AUTH_FAILURE);
}
mipSecAssocEntry) == _B_FALSE) {
return (HA_FA_AUTH_FAILURE);
}
/*
* Remove the extension by playing with the
* packet's length.
*/
if (aaaProtocol == DIAMETER &&
/*
* We probably ended up getting a new SPI from the
* AAA Server. Update the Visitor Entry with the
* new SPI.
*/
}
} else {
if (fhAuthRequired) {
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
{
int code = 0;
int result;
int mnAuthExtLen;
int faAuthExtLen;
int index;
/* LINTED E_BAD_PTR_CAST_ALIGN */
#ifdef RADIUS_ENABLED
if (radiusEnabled) {
/*
* We always have to force a RADIUS lookup.
*/
}
#endif /* RADIUS_ENABLED */
/*
* If a Foreign agent Home Agent authentication extension exists
* check it.
*/
/* LINTED E_BAD_PTR_CAST_ALIGN */
if (faAuthExtLen) {
/*
* if an SA is returned, the node will be locked so we
* need to unlock it when we are done.
*/
if ((mipSecAssocEntry =
"Failed FA-HA authentication - SPI (%d) "
"defined", SPI);
return (HA_FA_AUTH_FAILURE);
}
mipSecAssocEntry) == _B_FALSE) {
(void) rw_unlock(
return (HA_FA_AUTH_FAILURE);
}
/*
* 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) {
return (HA_FA_AUTH_FAILURE);
}
} else {
}
/*
* If a Mobile Node Home Agent authentication extension exists
* check it.
*/
/* LINTED E_BAD_PTR_CAST_ALIGN */
if (mnAuthExtLen) {
/*
* if an SA is returned, the node will be locked so we
* need to unlock it when we are done.
*/
if ((mipSecAssocEntry =
"No SPI defined");
return (HA_MN_AUTH_FAILURE);
}
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(
"Node is attempting to use a "
"static key - security violation!");
return (HA_MN_AUTH_FAILURE);
}
_B_FALSE) {
"authentication");
(void) rw_unlock(
return (HA_MN_AUTH_FAILURE);
}
}
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 */
if (mnAuthExtLen == 0) {
return (HA_MN_AUTH_FAILURE);
}
/*
* Get the MN-AAA SPI
*/
/*
* Make sure SPI used is the Radius SPI (2).
*/
if (*mnSPI != RADIUS_SPI) {
return (HA_MN_AUTH_FAILURE);
}
/*
* If using Radius, we'd like to preserve messageHdr
* until we get a reply from the Radius server
*/
(unsigned char *)NULL, 0, 0,
0, (void *)messageHdr, NULL, 0);
if (result) {
/*
* Now we look at the result code to determine
* what the error was.
*/
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) {
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
{
int index;
int mnAuthExtLen;
/* LINTED E_BAD_PTR_CAST_ALIGN */
/*
* 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.
*/
}
/*
* Search for the MobileNodeEntry based on the
* NAI.
*/
NULL, 0, 0, 0);
}
/* LINTED E_BAD_PTR_CAST_ALIGN */
/*
* accept Mobile-AAA Authentication extensions, so if we cannot
* find the Authentication Extension, find the MN-AAA.
*
* Happy Dave?
*/
/*
*
* 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 */
if (mnAuthExtLen == 0) {
return (HA_MN_AUTH_FAILURE);
}
/*
* Get the MN-AAA SPI
*/
#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.
*/
&messageHdr->mnHaSPI);
&messageHdr->mnFaSPI);
&messageHdr->faHaSPI);
#endif /* KEY_DISTRIBUTION */
} else if (mnAuthExt) {
/*
* Get the MN-HA SPI
*/
} else {
SPI = 0;
}
/*
* 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.
*/
/*
* 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.
*/
"As far as I'm concerned, this "
"mobile node doesn't exist");
return (HA_ADM_PROHIBITED);
}
} else {
}
} else {
} else {
/*
* Did the Mobile Node specify the correct SPI?
*/
"Invalid SPI requested %d, looking for %d",
return (HA_MN_AUTH_FAILURE);
}
}
}
/*
* if an SA is returned, the node will be locked so we
* need to unlock it when we are done.
*/
if ((mipSecAssocEntry =
"No SPI defined");
return (HA_MN_AUTH_FAILURE);
}
/*
* 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.
*/
" to use a static key - security violation!");
return (HA_MN_AUTH_FAILURE);
}
mipSecAssocEntry) == _B_FALSE) {
return (HA_MN_AUTH_FAILURE);
}
return (0);
}