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

📄 radius_server.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
	struct eap_hdr eapfail;	RADIUS_DEBUG("Reject invalid request from %s:%d",		     from_addr, from_port);	msg = radius_msg_new(RADIUS_CODE_ACCESS_REJECT,			     request->hdr->identifier);	if (msg == NULL) {		return -1;	}	os_memset(&eapfail, 0, sizeof(eapfail));	eapfail.code = EAP_CODE_FAILURE;	eapfail.identifier = 0;	eapfail.length = host_to_be16(sizeof(eapfail));	if (!radius_msg_add_eap(msg, (u8 *) &eapfail, sizeof(eapfail))) {		RADIUS_DEBUG("Failed to add EAP-Message attribute");	}	if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) {		RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)");		radius_msg_free(msg);		os_free(msg);		return -1;	}	if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret,				  client->shared_secret_len,				  request->hdr->authenticator) < 0) {		RADIUS_DEBUG("Failed to add Message-Authenticator attribute");	}	if (wpa_debug_level <= MSG_MSGDUMP) {		radius_msg_dump(msg);	}	data->counters.access_rejects++;	client->counters.access_rejects++;	if (sendto(data->auth_sock, msg->buf, msg->buf_used, 0,		   (struct sockaddr *) from, sizeof(*from)) < 0) {		perror("sendto[RADIUS SRV]");		ret = -1;	}	radius_msg_free(msg);	os_free(msg);	return ret;}static int radius_server_request(struct radius_server_data *data,				 struct radius_msg *msg,				 struct sockaddr *from, socklen_t fromlen,				 struct radius_client *client,				 const char *from_addr, int from_port,				 struct radius_session *force_sess){	u8 *eap = NULL;	size_t eap_len;	int res, state_included = 0;	u8 statebuf[4];	unsigned int state;	struct radius_session *sess;	struct radius_msg *reply;	if (force_sess)		sess = force_sess;	else {		res = radius_msg_get_attr(msg, RADIUS_ATTR_STATE, statebuf,					  sizeof(statebuf));		state_included = res >= 0;		if (res == sizeof(statebuf)) {			state = WPA_GET_BE32(statebuf);			sess = radius_server_get_session(client, state);		} else {			sess = NULL;		}	}	if (sess) {		RADIUS_DEBUG("Request for session 0x%x", sess->sess_id);	} else if (state_included) {		RADIUS_DEBUG("State attribute included but no session found");		radius_server_reject(data, client, msg, from, fromlen,				     from_addr, from_port);		return -1;	} else {		sess = radius_server_get_new_session(data, client, msg);		if (sess == NULL) {			RADIUS_DEBUG("Could not create a new session");			radius_server_reject(data, client, msg, from, fromlen,					     from_addr, from_port);			return -1;		}	}	if (sess->last_from_port == from_port &&	    sess->last_identifier == msg->hdr->identifier &&	    os_memcmp(sess->last_authenticator, msg->hdr->authenticator, 16) ==	    0) {		RADIUS_DEBUG("Duplicate message from %s", from_addr);		data->counters.dup_access_requests++;		client->counters.dup_access_requests++;		if (sess->last_reply) {			res = sendto(data->auth_sock, sess->last_reply->buf,				     sess->last_reply->buf_used, 0,				     (struct sockaddr *) from, fromlen);			if (res < 0) {				perror("sendto[RADIUS SRV]");			}			return 0;		}		RADIUS_DEBUG("No previous reply available for duplicate "			     "message");		return -1;	}		      	eap = radius_msg_get_eap(msg, &eap_len);	if (eap == NULL) {		RADIUS_DEBUG("No EAP-Message in RADIUS packet from %s",			     from_addr);		data->counters.packets_dropped++;		client->counters.packets_dropped++;		return -1;	}	RADIUS_DUMP("Received EAP data", eap, eap_len);	/* FIX: if Code is Request, Success, or Failure, send Access-Reject;	 * RFC3579 Sect. 2.6.2.	 * Include EAP-Response/Nak with no preferred method if	 * code == request.	 * If code is not 1-4, discard the packet silently.	 * Or is this already done by the EAP state machine? */	wpabuf_free(sess->eap_if->eapRespData);	sess->eap_if->eapRespData = wpabuf_alloc_ext_data(eap, eap_len);	if (sess->eap_if->eapRespData == NULL)		os_free(eap);	eap = NULL;	sess->eap_if->eapResp = TRUE;	eap_server_sm_step(sess->eap);	if ((sess->eap_if->eapReq || sess->eap_if->eapSuccess ||	     sess->eap_if->eapFail) && sess->eap_if->eapReqData) {		RADIUS_DUMP("EAP data from the state machine",			    wpabuf_head(sess->eap_if->eapReqData),			    wpabuf_len(sess->eap_if->eapReqData));	} else if (sess->eap_if->eapFail) {		RADIUS_DEBUG("No EAP data from the state machine, but eapFail "			     "set");	} else if (eap_sm_method_pending(sess->eap)) {		if (sess->last_msg) {			radius_msg_free(sess->last_msg);			os_free(sess->last_msg);		}		sess->last_msg = msg;		sess->last_from_port = from_port;		os_free(sess->last_from_addr);		sess->last_from_addr = os_strdup(from_addr);		sess->last_fromlen = fromlen;		os_memcpy(&sess->last_from, from, fromlen);		return -2;	} else {		RADIUS_DEBUG("No EAP data from the state machine - ignore this"			     " Access-Request silently (assuming it was a "			     "duplicate)");		data->counters.packets_dropped++;		client->counters.packets_dropped++;		return -1;	}	reply = radius_server_encapsulate_eap(data, client, sess, msg);	if (reply) {		RADIUS_DEBUG("Reply to %s:%d", from_addr, from_port);		if (wpa_debug_level <= MSG_MSGDUMP) {			radius_msg_dump(reply);		}		switch (reply->hdr->code) {		case RADIUS_CODE_ACCESS_ACCEPT:			data->counters.access_accepts++;			client->counters.access_accepts++;			break;		case RADIUS_CODE_ACCESS_REJECT:			data->counters.access_rejects++;			client->counters.access_rejects++;			break;		case RADIUS_CODE_ACCESS_CHALLENGE:			data->counters.access_challenges++;			client->counters.access_challenges++;			break;		}		res = sendto(data->auth_sock, reply->buf, reply->buf_used, 0,			     (struct sockaddr *) from, fromlen);		if (res < 0) {			perror("sendto[RADIUS SRV]");		}		if (sess->last_reply) {			radius_msg_free(sess->last_reply);			os_free(sess->last_reply);		}		sess->last_reply = reply;		sess->last_from_port = from_port;		sess->last_identifier = msg->hdr->identifier;		os_memcpy(sess->last_authenticator, msg->hdr->authenticator,			  16);	} else {		data->counters.packets_dropped++;		client->counters.packets_dropped++;	}	if (sess->eap_if->eapSuccess || sess->eap_if->eapFail) {		RADIUS_DEBUG("Removing completed session 0x%x after timeout",			     sess->sess_id);		eloop_cancel_timeout(radius_server_session_remove_timeout,				     data, sess);		eloop_register_timeout(10, 0,				       radius_server_session_remove_timeout,				       data, sess);	}	return 0;}static void radius_server_receive_auth(int sock, void *eloop_ctx,				       void *sock_ctx){	struct radius_server_data *data = eloop_ctx;	u8 *buf = NULL;	struct sockaddr_storage from;	socklen_t fromlen;	int len;	struct radius_client *client = NULL;	struct radius_msg *msg = NULL;	char abuf[50];	int from_port = 0;	buf = os_malloc(RADIUS_MAX_MSG_LEN);	if (buf == NULL) {		goto fail;	}	fromlen = sizeof(from);	len = recvfrom(sock, buf, RADIUS_MAX_MSG_LEN, 0,		       (struct sockaddr *) &from, &fromlen);	if (len < 0) {		perror("recvfrom[radius_server]");		goto fail;	}#ifdef CONFIG_IPV6	if (data->ipv6) {		struct sockaddr_in6 *from6 = (struct sockaddr_in6 *) &from;		if (inet_ntop(AF_INET6, &from6->sin6_addr, abuf, sizeof(abuf))		    == NULL)			abuf[0] = '\0';		from_port = ntohs(from6->sin6_port);		RADIUS_DEBUG("Received %d bytes from %s:%d",			     len, abuf, from_port);		client = radius_server_get_client(data,						  (struct in_addr *)						  &from6->sin6_addr, 1);	}#endif /* CONFIG_IPV6 */	if (!data->ipv6) {		struct sockaddr_in *from4 = (struct sockaddr_in *) &from;		os_strlcpy(abuf, inet_ntoa(from4->sin_addr), sizeof(abuf));		from_port = ntohs(from4->sin_port);		RADIUS_DEBUG("Received %d bytes from %s:%d",			     len, abuf, from_port);		client = radius_server_get_client(data, &from4->sin_addr, 0);	}	RADIUS_DUMP("Received data", buf, len);	if (client == NULL) {		RADIUS_DEBUG("Unknown client %s - packet ignored", abuf);		data->counters.invalid_requests++;		goto fail;	}	msg = radius_msg_parse(buf, len);	if (msg == NULL) {		RADIUS_DEBUG("Parsing incoming RADIUS frame failed");		data->counters.malformed_access_requests++;		client->counters.malformed_access_requests++;		goto fail;	}	os_free(buf);	buf = NULL;	if (wpa_debug_level <= MSG_MSGDUMP) {		radius_msg_dump(msg);	}	if (msg->hdr->code != RADIUS_CODE_ACCESS_REQUEST) {		RADIUS_DEBUG("Unexpected RADIUS code %d", msg->hdr->code);		data->counters.unknown_types++;		client->counters.unknown_types++;		goto fail;	}	data->counters.access_requests++;	client->counters.access_requests++;	if (radius_msg_verify_msg_auth(msg, (u8 *) client->shared_secret,				       client->shared_secret_len, NULL)) {		RADIUS_DEBUG("Invalid Message-Authenticator from %s", abuf);		data->counters.bad_authenticators++;		client->counters.bad_authenticators++;		goto fail;	}	if (radius_server_request(data, msg, (struct sockaddr *) &from,				  fromlen, client, abuf, from_port, NULL) ==	    -2)		return; /* msg was stored with the session */fail:	if (msg) {		radius_msg_free(msg);		os_free(msg);	}	os_free(buf);}static int radius_server_open_socket(int port){	int s;	struct sockaddr_in addr;	s = socket(PF_INET, SOCK_DGRAM, 0);	if (s < 0) {		perror("socket");		return -1;	}	os_memset(&addr, 0, sizeof(addr));	addr.sin_family = AF_INET;	addr.sin_port = htons(port);	if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {		perror("bind");		close(s);		return -1;	}	return s;}#ifdef CONFIG_IPV6static int radius_server_open_socket6(int port){	int s;	struct sockaddr_in6 addr;	s = socket(PF_INET6, SOCK_DGRAM, 0);	if (s < 0) {		perror("socket[IPv6]");		return -1;	}	os_memset(&addr, 0, sizeof(addr));	addr.sin6_family = AF_INET6;	os_memcpy(&addr.sin6_addr, &in6addr_any, sizeof(in6addr_any));	addr.sin6_port = htons(port);	if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {		perror("bind");		close(s);		return -1;	}	return s;}#endif /* CONFIG_IPV6 */static void radius_server_free_sessions(struct radius_server_data *data,					struct radius_session *sessions){	struct radius_session *session, *prev;	session = sessions;	while (session) {		prev = session;		session = session->next;		radius_server_session_free(data, prev);	}}static void radius_server_free_clients(struct radius_server_data *data,				       struct radius_client *clients){	struct radius_client *client, *prev;	client = clients;	while (client) {		prev = client;		client = client->next;		radius_server_free_sessions(data, prev->sessions);		os_free(prev->shared_secret);		os_free(prev);	}}static struct radius_client *radius_server_read_clients(const char *client_file, int ipv6){	FILE *f;	const int buf_size = 1024;	char *buf, *pos;	struct radius_client *clients, *tail, *entry;	int line = 0, mask, failed = 0, i;	struct in_addr addr;

⌨️ 快捷键说明

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