Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
/* 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);
}
Exemplo n.º 3
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);
}
Exemplo n.º 4
0
/* 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);
}
Exemplo n.º 5
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);
}
Exemplo n.º 6
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);
}