⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mn_reg.c

📁 mobile ip 在linux下的一种实现
💻 C
📖 第 1 页 / 共 3 页
字号:
		keyreq->length = htons(4);		/* FIX: mn_spi is the SPI that MN will assign for the security		 * association; this may need to be uniquely selected for some		 * cases(?) */		keyreq->mn_spi = htonl(1000);		pos += GET_GEN_MN_FA_KEY_REQ_EXT_LEN(keyreq);		left -= GET_GEN_MN_FA_KEY_REQ_EXT_LEN(keyreq);	}	if (add_mn_aaa_auth_ext && config.use_aaa) {		/* add MN-AAA authentication extension */		if (left < sizeof(struct generalized_auth_ext) + MAX_SK_LEN)			return -1;		DEBUG(DEBUG_MESSAGES, " * gen_auth_ext(MN-AAA)\n");		n = auth_add_gen(config.mn_aaa_auth_alg,				 config.mn_aaa_shared_secret,				 config.mn_aaa_shared_secret_len,				 (unsigned char *) start,				 challenge != NULL ?				 MSG_CHALLENGE_EXT_DATA(challenge) : NULL,				 challenge != NULL ?				 GET_CHALLENGE_LEN(challenge) : 0,				 (struct generalized_auth_ext *) pos,				 GENERALIZED_AUTH_MN_AAA,				 htonl(config.mn_aaa_spi));		pos += n;		left -= n;	}	mn.prev_req_replied = 0;	return (int) (pos - orig);}/* send_registration: * @request_type:  *    REG_DISC    - deregistration *    REG_CONNECT - normal connection request *    REG_REREG   - reregistration (do not send sk_auth extension *                  and ask full time) * * Send registration message. *  * Returns: 0 on success, -1 on error. */int send_registration(int request_type){        char sendbuf[MAXMSG];	char *pos; /* pointer to next byte to write in sendbuf */        int n, len;        struct sockaddr_in addr;	int use_reverse;	struct msg_extensions ext;        if (MAXMSG < (sizeof(struct reg_req) +                      2 * (sizeof(struct msg_auth) + 16))) {                DEBUG(DEBUG_INFO, "MN: send_reg: too small send buffer!");                return -1;        }	use_reverse = config.tunneling_mode == TUNMODE_AUTO_REVERSE ||		config.tunneling_mode == TUNMODE_REVERSE;	if (mn.current_adv != NULL) {		if (mn.current_adv->addr.s_addr != mn.fa_addr.s_addr) {			DEBUG(DEBUG_INFO, "fa_addr=%s != ",			      inet_ntoa(mn.fa_addr));			DEBUG(DEBUG_INFO, "current_adv->addr=%s\n",			      inet_ntoa(mn.current_adv->addr));		}		DEBUG(DEBUG_INFO, "Setting in_use=%i for FA %s (send reg)\n",		      request_type == REG_DISC ? 0 : 1,		      inet_ntoa(mn.current_adv->addr));		mn.current_adv->in_use = request_type == REG_DISC ? 0 : 1;		if (config.tunneling_mode == TUNMODE_AUTO_REVERSE &&		    (ntohs(mn.current_adv->adv.ext->opts) &		     AGENT_ADV_BIDIR_TUNNELING) == 0)			use_reverse = 0;		if (config.tunneling_mode == TUNMODE_AUTO_TRIANGLE &&		    mn.current_adv->adv.own_ext != NULL &&		    (mn.current_adv->adv.own_ext->opts &		     AGENT_ADV_OWN_TRIANGLE_TUNNELING) == 0)			use_reverse = 1;	} else {		DEBUG(DEBUG_INFO,		      "send_registration: current_adv == NULL!?\n");	}	if ((use_reverse && config.tunneling_mode == TUNMODE_TRIANGLE) ||	    (!use_reverse && config.tunneling_mode == TUNMODE_REVERSE)) {		DEBUG(DEBUG_INFO, "FA does not support wanted tunneling mode -"		      " aborting registration\n");		if (mn.current_adv != NULL)			mn.current_adv->reg_failed = 1;		return -1;	}	if (use_reverse)		DEBUG(DEBUG_MESSAGES, "Requesting reverse tunneling\n");	pos = sendbuf;	DEBUG(DEBUG_MESSAGES, "Sending registration message:\n * header\n");	n = fill_req_header(pos, request_type, use_reverse);	if (n < 0) return -1;	pos += n;	n = add_req_extensions(pos, MAXMSG - n, sendbuf, request_type,			       use_reverse);	if (n < 0) {		LOG2(LOG_ERR, "Registration request buffer overflow - unable"		     " to send the request\n");		return -1;	}	pos += n;        len = (int) (pos - sendbuf);	assert(len <= MAXMSG);	/* call parse_msg() to parse the message in order to get the details	 * of the sent message into debug output; in addition, this validates	 * the format of the request */	if (parse_msg(sendbuf, len, &ext) != 0) {		DEBUG(DEBUG_INFO, "WARNING! Own registration request was not "		      "valid!\n");	}	/* add ARP entry, if not already added */	if (mn.current_adv != NULL &&	    mn.current_adv->adv_type == MN_ADV_TYPE_FA &&	    !mn.current_adv->arpentry) {		struct sockaddr hwaddr;		DEBUG(DEBUG_INFO, "Adding ARP entry for FA\n");		memset(&hwaddr, 0, sizeof(hwaddr));		hwaddr.sa_family = ARPHRD_ETHER;#ifdef DYN_TARGET_LINUX		memcpy(hwaddr.sa_data, mn.current_adv->adv.from.sll_addr,		       mn.current_adv->adv.from.sll_halen);#else		memcpy(hwaddr.sa_data, mn.current_adv->adv.eth->h_source,		       ETH_ALEN);#endif		if (arp_add_permanent_item(mn.current_adv->addr,					   mn.current_adv->ifname,					   &hwaddr) < 0) {			LOG2(LOG_WARNING, "arp_add_permanent_item(%s, %s, %s) "			     "failed\n", inet_ntoa(mn.current_adv->addr),			     mn.current_adv->ifname,			     ether_hwtoa((unsigned char *)hwaddr.sa_data));		}		mn.current_adv->arpentry = 1;	}	/* add host route to FA, if not already added */	if (config.enable_fa_decapsulation &&	    mn.current_adv != NULL &&	    mn.current_adv->adv_type == MN_ADV_TYPE_FA &&	    !mn.current_adv->routeentry) {		DEBUG(DEBUG_INFO, "Adding routing entry for FA\n");		add_fa_host_route(mn.current_adv->ifname, mn.agentadv,				  mn.current_adv->ifindex, mn.fa_addr);	}        /* send the message */	memset(&addr, 0, sizeof(addr));        addr.sin_family = AF_INET;        addr.sin_addr.s_addr = mn.fa_addr.s_addr;	addr.sin_port = htons(config.udp_port);	DEBUG(DEBUG_MESSAGES, "sending registration request to %s:%i, "	      "type=%i\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port),	      request_type);	gettimeofday(&mn.last_reg_send_time, NULL);	DEBUG(DEBUG_TIMERS, "last_reg_send_time=%li.%06li (FA=%s)\n",	      mn.last_reg_send_time.tv_sec,	      mn.last_reg_send_time.tv_usec,	      inet_ntoa(addr.sin_addr));        n = sendto(mn.registration_socket, sendbuf, len, 0,                   (struct sockaddr *) &addr, sizeof(addr));        if (n == len) {                /* store id for reply */                mn.registration_id[0] =			ntohl(((struct reg_req *)sendbuf)->id[0]);                mn.registration_id[1] =			ntohl(((struct reg_req *)sendbuf)->id[1]);                /* set registration time */		gettimeofday(&timers[TIMER_REQUEST], NULL);		mn.last_request_sent = timers[TIMER_REQUEST].tv_sec;                return 0;        } else {		LOG2(LOG_ERR, "send_reg - sendto: %s\n", strerror(errno));                return -1;        }}static void show_key_dump(const char *title, const unsigned char *key,			  int keylen){	int i;	DEBUG(DEBUG_INFO, "%s: ", title);	for (i = 0; i < keylen; i++)		DEBUG(DEBUG_INFO, "%02x", key[i]);	DEBUG(DEBUG_INFO, "\n");}/** * handle_reply_aaa: * @ext: parsed registration reply extensions * * Handle AAA related extensions: validate the reply and generate MN-FA and/or * MN-HA security association if key material was present. * * Returns: 1 = valid extensions, 0 = invalid extensions */static int handle_reply_aaa(struct msg_extensions *ext, struct in_addr addr){	unsigned char *nodeaddr;	unsigned int nodeaddrlen;	unsigned char fa_secret[MAXSHAREDSECRETLEN];	int fa_secret_len;	unsigned char ha_secret[MAXSHAREDSECRETLEN];	int ha_secret_len;	struct mn_fa_key_material_from_aaa *fa_key = NULL;	struct mn_ha_key_material_from_aaa *ha_key = NULL;	if (config.mn_home_ip_addr.s_addr == 0 &&	    config.mn_nai_len > 0) {		nodeaddr = config.mn_nai;		nodeaddrlen = config.mn_nai_len;	} else {		nodeaddr = (unsigned char *) &config.mn_home_ip_addr;		nodeaddrlen = 4;	}	if (!config.use_aaa) {		DEBUG(DEBUG_INFO, "Registration reply has key material from "		      "AAA, but AAA is not configured; ignoring extension\n");		ext->mn_fa_key_material_aaa = NULL;		ext->mn_ha_key_material_aaa = NULL;		return 1;	}	if (ext->mn_fa_key_material_aaa) {		fa_key = (struct mn_fa_key_material_from_aaa *)			(ext->mn_fa_key_material_aaa + 1);		if (ext->mf_auth == NULL ||		    !auth_is_protected(ext->mn_fa_key_material_aaa,				       ext->mf_auth)) {			LOG2(LOG_ALERT, "MN-FA auth. ext. does not protect "			     "MN-FA key material from AAA\n");			return 0;		}		/* generate MN-FA key from key material */		fa_secret_len = MAXSHAREDSECRETLEN;		if (auth_generate_key(			    config.mn_aaa_keygen_alg,			    config.mn_aaa_shared_secret,			    config.mn_aaa_shared_secret_len,			    (unsigned char *) (fa_key + 1),			    GET_GEN_MN_FA_KEY_REP_LEN(				    ext->mn_fa_key_material_aaa) -			    sizeof(struct mn_fa_key_material_from_aaa),			    nodeaddr, nodeaddrlen,			    fa_secret, &fa_secret_len)) {			LOG2(LOG_ALERT, "MN-FA key generation with material "			     "from AAA failed\n");			return 0;		}		show_key_dump("MN-FA key", fa_secret, fa_secret_len);		/* check that MN-FA auth ext is valid before accepting the		 * key */		if (!auth_check(auth_aaa_key_alg_id_to_dynamics(ntohs(			fa_key->alg_id)),				fa_secret, fa_secret_len,				(unsigned char *) ext->rep, ext->mf_auth)) {			LOG2(LOG_ALERT, "MN-FA key from AAA does not match "			     "with MN-FA auth. ext.\n");			return 0;		}	}	if (ext->mn_ha_key_material_aaa) {		ha_key = (struct mn_ha_key_material_from_aaa *)			(ext->mn_ha_key_material_aaa + 1);		if (ext->mh_auth == NULL ||		    !auth_is_protected(ext->mn_ha_key_material_aaa,				       ext->mh_auth)) {			LOG2(LOG_ALERT, "MN-HA auth. ext. does not protect "			     "MN-HA key material from AAA\n");			return 0;		}		/* generate MN-HA key from key material */		ha_secret_len = MAXSHAREDSECRETLEN;		if (auth_generate_key(			    config.mn_aaa_keygen_alg,			    config.mn_aaa_shared_secret,			    config.mn_aaa_shared_secret_len,			    (unsigned char *) (ha_key + 1),			    GET_GEN_MN_HA_KEY_REP_LEN(				    ext->mn_ha_key_material_aaa) -			    sizeof(struct mn_ha_key_material_from_aaa),			    nodeaddr, nodeaddrlen,			    ha_secret, &ha_secret_len)) {			LOG2(LOG_ALERT, "MN-HA key generation with material "			     "from AAA failed\n");			return 0;		}		show_key_dump("MN-HA key", ha_secret, ha_secret_len);		/* check that MN-HA auth ext is valid before accepting the		 * key */		if (!auth_check(auth_aaa_key_alg_id_to_dynamics(			ntohs(ha_key->alg_id)),				ha_secret, ha_secret_len,				(unsigned char *) ext->rep, ext->mh_auth)) {			LOG2(LOG_ALERT, "MN-HA key from AAA does not match "			     "with MN-HA auth. ext.\n");			return 0;		}	}	/* Generated keys matched with authentication extensions - add new	 * dynamic security associations */	if (ext->mn_fa_key_material_aaa) {		struct fa_spi_entry *spi;		spi = malloc(sizeof(struct fa_spi_entry));		if (spi == NULL) {			DEBUG(DEBUG_INFO, "Could not allocate memory for new "			      "FA security association\n");			return 0;		}		memset(spi, 0, sizeof(struct fa_spi_entry));		list_init_node(&spi->node);		spi->spi = ntohl(fa_key->fa_spi);		spi->addr.s_addr = addr.s_addr;		spi->alg =			auth_aaa_key_alg_id_to_dynamics(ntohs(fa_key->alg_id));		time(&spi->created);		spi->lifetime = ntohl(fa_key->lifetime);		memcpy(spi->shared_secret, fa_secret, sizeof(fa_secret));		spi->shared_secret_len = fa_secret_len;		add_fa_spi(spi, 1);	}	if (ext->mn_ha_key_material_aaa) {		config.spi = ntohl(ha_key->ha_spi);		mn.use_auth_alg = config.auth_alg =			auth_aaa_key_alg_id_to_dynamics(ntohs(ha_key->alg_id));		config.replay_meth = auth_aaa_key_replay_to_dynamics(			ntohs(ha_key->replay_method));		memcpy(config.shared_secret, ha_secret, sizeof(ha_secret));		config.shared_secret_len = ha_secret_len;		time(&config.mn_ha_key_timestamp);		config.mn_ha_key_lifetime =			ntohl(ext->mn_ha_key_material_aaa->lifetime);	}	mn.aaa_rekey = 0;	return 1;}/* * Check if ext contains valid registration reply. * correct reply should have id[1] same as in request. * Return nonzero if it's valid, zero otherwise. */static int is_valid_reply(struct msg_extensions *ext, struct sockaddr_in addr){	int auth_alg;	struct fa_spi_entry *fa_spi;	ASSERT(ext != NULL);        /* verify fields */        if (ext->rep == NULL || ext->rep->type != REG_REP) {		LOG2(LOG_WARNING, "Received message from %s:%i was not a "		     "registration reply\n",		     inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));		return 0;	}#ifndef MN_ENABLE_VALIDATION	DEBUG(DEBUG_INFO, "MN - no message validation in use\n");	return 1;#else	if ((ext->mn_fa_key_material_aaa != NULL ||	     ext->mn_ha_key_material_aaa != NULL) &&	    handle_reply_aaa(ext, addr.sin_addr) != 1) {		LOG2(LOG_ALERT, "Registration reply validation failed for AAA "			"related data - dropping reply\n");		return 0;	}        /* verify mac */	if (ext->mh_auth != NULL) {		if (config.shared_secret_len < 0) {			LOG2(LOG_ALERT, "MN-HA in reply, but security "			     "association does not exists yet\n");			return 0;		}		if (!auth_check(mn.use_auth_alg, config.shared_secret,				config.shared_secret_len,				(unsigned char *) ext->rep, ext->mh_auth)) {			if (mn.use_auth_alg == AUTH_ALG_MD5)				auth_alg = AUTH_ALG_MD5_RFC2002;			else if (mn.use_auth_alg == AUTH_ALG_MD5_RFC2002)				auth_alg = AUTH_ALG_MD5;			else				auth_alg = 0;			if (auth_alg == 0 ||			    !auth_check(auth_alg, config.shared_secret,					config.shared_secret_len,					(unsigned char *) ext->rep,					ext->mh_auth)) {				LOG2(LOG_ALERT,				     "Incorrect HA->MN authentication "				     "extension received in the reply\n");				if (config.use_aaa)					mn.aaa_rekey = 1;				return 0;			} else {				/* non-standard authentication method used */				DEBUG(DEBUG_MESSAGES,				      "Non-standard MAC calculation detected "				      "- trying to use the same method\n");				mn.use_auth_alg = auth_alg;				return 0;			}		}	} else if (ext->sk_auth != NULL && mn.session_key_len > 0) {		if (!auth_check_vendor(config.auth_alg, mn.session_key,				       mn.session_key_len,				       (unsigned char *) ext->rep,				       ext->sk_auth)) {			LOG2(LOG_ALERT, "Incorrect session key based "			     "authentication extension in the reply.\n");			return 0;		}		/* FAs cannot send session_keys */		if (ext->mn_keyrep != NULL) {			DEBUG(DEBUG_MESSAGES, "Registration reply from FA "			      "contained mn_keyrep extension - dropped it\n");			/* Just clear the session key to prevent FAs from			 * sending them us. */			ext->mn_keyrep = NULL;		}	} else if (ext->rep->code < 64 || ext->rep->code > 127) {		/* codes 64 .. 127 are for Foreign Agent denial; only require		 * authentication extension in messages that are from the

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -