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

📄 event.c

📁 使用最广泛的radius的linux的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		 *	Delete any reply we had accumulated until now.		 */		pairfree(&request->reply->vps);		/*		 *	Run the packet through the post-proxy stage,		 *	BEFORE playing games with the attributes.		 */		vp = pairfind(request->config_items, PW_POST_PROXY_TYPE);		if (vp) {			DEBUG2("  Found Post-Proxy-Type %s", vp->vp_strvalue);			post_proxy_type = vp->vp_integer;		}		rad_assert(request->home_pool != NULL);		if (request->home_pool->virtual_server) {			const char *old_server = request->server;			request->server = request->home_pool->virtual_server;			DEBUG2(" server %s {", request->server);			rcode = module_post_proxy(post_proxy_type, request);			DEBUG2(" }");			request->server = old_server;		} else {			rcode = module_post_proxy(post_proxy_type, request);		}		/*		 *	There may NOT be a proxy reply, as we may be		 *	running Post-Proxy-Type = Fail.		 */		if (request->proxy_reply) {			/*			 *	Delete the Proxy-State Attributes from			 *	the reply.  These include Proxy-State			 *	attributes from us and remote server.			 */			pairdelete(&request->proxy_reply->vps, PW_PROXY_STATE);			/*			 *	Add the attributes left in the proxy			 *	reply to the reply list.			 */			pairadd(&request->reply->vps, request->proxy_reply->vps);			request->proxy_reply->vps = NULL;			/*			 *	Free proxy request pairs.			 */			pairfree(&request->proxy->vps);		}		switch (rcode) {                default:  /* Don't do anything */			break;                case RLM_MODULE_FAIL:			/* FIXME: debug print stuff */			request->child_state = REQUEST_DONE;			return 0;                case RLM_MODULE_HANDLED:			/* FIXME: debug print stuff */			request->child_state = REQUEST_DONE;			return 0;		}	}	return 1;}/* *	Do state handling when we proxy a request. */static int proxy_request(REQUEST *request){	struct timeval when;	char buffer[128];	if (!insert_into_proxy_hash(request)) {		DEBUG("ERROR: Failed inserting request into proxy hash.");		return 0;	}	request->proxy_listener->encode(request->proxy_listener, request);	when = request->received;	when.tv_sec += request->root->max_request_time;	gettimeofday(&request->proxy_when, NULL);	request->next_when = request->proxy_when;	request->next_when.tv_sec += request->home_server->response_window;	rad_assert(request->home_server->response_window > 0);	if (timercmp(&when, &request->next_when, <)) {		request->next_when = when;	}	request->next_callback = no_response_to_proxied_request;	DEBUG2("Proxying request %d to home server %s port %d",	       request->number,	       inet_ntop(request->proxy->dst_ipaddr.af,			 &request->proxy->dst_ipaddr.ipaddr,			 buffer, sizeof(buffer)),	       request->proxy->dst_port);	/*	 *	Note that we set proxied BEFORE sending the packet.	 *	 *	Once we send it, the request is tainted, as	 *	another thread may have picked it up.  Don't	 *	touch it!	 */	request->num_proxied_requests = 1;	request->num_proxied_responses = 0;	request->child_pid = NO_SUCH_CHILD_PID;	request->child_state = REQUEST_PROXIED;	request->proxy_listener->send(request->proxy_listener,				      request);	return 1;}/* *	"Proxy" the request by sending it to a new virtual server. */static int proxy_to_virtual_server(REQUEST *request){	REQUEST *fake;	if (!request->home_server || !request->home_server->server) return 0;	if (request->parent) {		DEBUG2("WARNING: Cancelling proxy request to virtual server %s as this request was itself proxied.", request->home_server->server);		return 0;	}	fake = request_alloc_fake(request);	if (!fake) {		DEBUG2("WARNING: Out of memory");		return 0;	}	fake->packet->vps = paircopy(request->proxy->vps);	fake->server = request->home_server->server;	DEBUG2(">>> Sending proxied request internally to virtual server.");	radius_handle_request(fake, rad_authenticate);	DEBUG2("<<< Received proxied response from internal virtual server.");	request->proxy_reply = fake->reply;	fake->reply = NULL;	/*	 *	And run it through the post-proxy section...	 */	rad_authenticate(request);	return 2;		/* success, but NOT '1' !*/}/* *	Return 1 if we did proxy it, or the proxy attempt failed *	completely.  Either way, the caller doesn't touch the request *	any more if we return 1. */static int successfully_proxied_request(REQUEST *request){	int rcode;	int pre_proxy_type = 0;	VALUE_PAIR *realmpair;	VALUE_PAIR *strippedname;	VALUE_PAIR *vp;	char *realmname;	home_server *home;	REALM *realm = NULL;	home_pool_t *pool;	/*	 *	If it was already proxied, do nothing.	 *	 *	FIXME: This should really be a serious error.	 */	if (request->in_proxy_hash) {		return 0;	}	realmpair = pairfind(request->config_items, PW_PROXY_TO_REALM);	if (!realmpair || (realmpair->length == 0)) {		return 0;	}	realmname = (char *) realmpair->vp_strvalue;	realm = realm_find2(realmname);	if (!realm) {		DEBUG2("ERROR: Cannot proxy to unknown realm %s", realmname);		return 0;	}	/*	 *	Figure out which pool to use.	 */	if (request->packet->code == PW_AUTHENTICATION_REQUEST) {		pool = realm->auth_pool;	} else if (request->packet->code == PW_ACCOUNTING_REQUEST) {		pool = realm->acct_pool;	} else {		rad_panic("Internal sanity check failed");	}	if (!pool) {		DEBUG2(" WARNING: Cancelling proxy to Realm %s, as the realm is local.",		       realmname);		return 0;	}	home = home_server_ldb(realmname, pool, request);	if (!home) {		DEBUG2("ERROR: Failed to find live home server for realm %s",		       realmname);		return -1;	}	request->home_pool = pool;	/*	 *	Remember that we sent the request to a Realm.	 */	pairadd(&request->packet->vps,		pairmake("Realm", realmname, T_OP_EQ));	/*	 *	We read the packet from a detail file, AND it came from	 *	the server we're about to send it to.  Don't do that.	 */	if ((request->packet->code == PW_ACCOUNTING_REQUEST) &&	    (request->listener->type == RAD_LISTEN_DETAIL) &&	    (home->ipaddr.af == AF_INET) &&	    (request->packet->src_ipaddr.af == AF_INET) &&	    (home->ipaddr.ipaddr.ip4addr.s_addr == request->packet->src_ipaddr.ipaddr.ip4addr.s_addr)) {		DEBUG2("    rlm_realm: Packet came from realm %s, proxy cancelled", realmname);		return 0;	}	/*	 *	Allocate the proxy packet, only if it wasn't already	 *	allocated by a module.  This check is mainly to support	 *	the proxying of EAP-TTLS and EAP-PEAP tunneled requests.	 *	 *	In those cases, the EAP module creates a "fake"	 *	request, and recursively passes it through the	 *	authentication stage of the server.  The module then	 *	checks if the request was supposed to be proxied, and	 *	if so, creates a proxy packet from the TUNNELED request,	 *	and not from the EAP request outside of the tunnel.	 *	 *	The proxy then works like normal, except that the response	 *	packet is "eaten" by the EAP module, and encapsulated into	 *	an EAP packet.	 */	if (!request->proxy) {		if ((request->proxy = rad_alloc(TRUE)) == NULL) {			radlog(L_ERR|L_CONS, "no memory");			exit(1);		}		/*		 *	Copy the request, then look up name and		 *	plain-text password in the copy.		 *		 *	Note that the User-Name attribute is the		 *	*original* as sent over by the client.  The		 *	Stripped-User-Name attribute is the one hacked		 *	through the 'hints' file.		 */		request->proxy->vps =  paircopy(request->packet->vps);	}	/*	 *	Strip the name, if told to.	 *	 *	Doing it here catches the case of proxied tunneled	 *	requests.	 */	if (realm->striprealm == TRUE &&	   (strippedname = pairfind(request->proxy->vps, PW_STRIPPED_USER_NAME)) != NULL) {		/*		 *	If there's a Stripped-User-Name attribute in		 *	the request, then use THAT as the User-Name		 *	for the proxied request, instead of the		 *	original name.		 *		 *	This is done by making a copy of the		 *	Stripped-User-Name attribute, turning it into		 *	a User-Name attribute, deleting the		 *	Stripped-User-Name and User-Name attributes		 *	from the vps list, and making the new		 *	User-Name the head of the vps list.		 */		vp = pairfind(request->proxy->vps, PW_USER_NAME);		if (!vp) {			vp = radius_paircreate(request, NULL,					       PW_USER_NAME, PW_TYPE_STRING);			rad_assert(vp != NULL);	/* handled by above function */			/* Insert at the START of the list */			vp->next = request->proxy->vps;			request->proxy->vps = vp;		}		memcpy(vp->vp_strvalue, strippedname->vp_strvalue,		       sizeof(vp->vp_strvalue));		vp->length = strippedname->length;		/*		 *	Do NOT delete Stripped-User-Name.		 */	}	/*	 *	If there is no PW_CHAP_CHALLENGE attribute but	 *	there is a PW_CHAP_PASSWORD we need to add it	 *	since we can't use the request authenticator	 *	anymore - we changed it.	 */	if (pairfind(request->proxy->vps, PW_CHAP_PASSWORD) &&	    pairfind(request->proxy->vps, PW_CHAP_CHALLENGE) == NULL) {		vp = radius_paircreate(request, &request->proxy->vps,				       PW_CHAP_CHALLENGE, PW_TYPE_OCTETS);		vp->length = AUTH_VECTOR_LEN;		memcpy(vp->vp_strvalue, request->packet->vector, AUTH_VECTOR_LEN);	}	/*	 *	The RFC's say we have to do this, but FreeRADIUS	 *	doesn't need it.	 */	vp = radius_paircreate(request, &request->proxy->vps,			       PW_PROXY_STATE, PW_TYPE_OCTETS);	snprintf(vp->vp_strvalue, sizeof(vp->vp_strvalue), "%d",		 request->packet->id);	vp->length = strlen(vp->vp_strvalue);	/*	 *	Should be done BEFORE inserting into proxy hash, as	 *	pre-proxy may use this information, or change it.	 */	request->proxy->code = request->packet->code;	request->proxy->dst_ipaddr = home->ipaddr;	request->proxy->dst_port = home->port;	request->home_server = home;	/*	 *	Call the pre-proxy routines.	 */	vp = pairfind(request->config_items, PW_PRE_PROXY_TYPE);	if (vp) {		DEBUG2("  Found Pre-Proxy-Type %s", vp->vp_strvalue);		pre_proxy_type = vp->vp_integer;	}	rad_assert(request->home_pool != NULL);	if (request->home_pool->virtual_server) {		const char *old_server = request->server;				request->server = request->home_pool->virtual_server;		DEBUG2(" server %s {", request->server);		rcode = module_pre_proxy(pre_proxy_type, request);		DEBUG2(" }");			request->server = old_server;	} else {		rcode = module_pre_proxy(pre_proxy_type, request);	}	switch (rcode) {	case RLM_MODULE_FAIL:	case RLM_MODULE_INVALID:	case RLM_MODULE_NOTFOUND:	case RLM_MODULE_USERLOCK:	default:		/* FIXME: debug print failed stuff */		return -1;	case RLM_MODULE_REJECT:	case RLM_MODULE_HANDLED:		return 0;	/*	 *	Only proxy the packet if the pre-proxy code succeeded.	 */	case RLM_MODULE_NOOP:	case RLM_MODULE_OK:	case RLM_MODULE_UPDATED:		break;	}	/*	 *	If it's a fake request, don't send the proxy	 *	packet.  The outer tunnel session will take	 *	care of doing that.	 */	if (request->packet->dst_port == 0) {		request->home_server = NULL;		return 1;	}	if (request->home_server->server) {		return proxy_to_virtual_server(request);	}	if (!proxy_request(request)) {		DEBUG("ERROR: Failed to proxy request %d", request->number);		return -1;	}		return 1;}static void request_post_handler(REQUEST *request){	int child_state = -1;	struct timeval when;	VALUE_PAIR *vp;	if ((request->master_state == REQUEST_STOP_PROCESSING) ||	    (request->parent &&	     (request->parent->master_state == REQUEST_STOP_PROCESSING))) {		DEBUG2("Request %d was cancelled.", request->number);		request->child_pid = NO_SUCH_CHILD_PID;		request->child_state = REQUEST_DONE;		return;	}	if (request->child_state != REQUEST_RUNNING) {		rad_panic("Internal sanity check failed");	}	if ((request->reply->code == 0) &&	    ((vp = pairfind(request->config_items, PW_AUTH_TYPE)) != NULL) &&	    (vp->vp_integer == PW_AUTHTYPE_REJECT)) {		request->reply->code = PW_AUTHENTICATION_REJECT;	}	if (request->root->proxy_requests &&	    !request->in_proxy_hash &&	    (request->reply->code == 0) &&	    (request->packet->dst_port != 0) &&	    (request->packet->code != PW_STATUS_SERVER)) {		int rcode = successfully_proxied_request(request);		if (rcode == 1) return;		/*		 *	Failed proxying it (dead home servers, etc.)		 *	Run it through Post-Proxy-Type = Fail, and		 *	respond to the request.		 *		 *	Note that we're in a child thread here, so we		 *	do NOT re-schedule the request.  Instead, we		 *	do what we would have done, which is run the		 *	pre-handler, a NULL request handler, and then		 *	the post handler.		 */		if ((rcode < 0) && setup_post_proxy_fail(request)) {			request_pre_handler(request);		}		/*		 *	Else we weren't supposed to proxy it,		 *	OR we proxied it internally to a virutal server.		 */	}	/*	 *	Fake requests don't get encoded or signed.  The caller	 *	also requires the reply VP's, so we don't free them	 *	here!	 */	if (request->packet->dst_port == 0) {		/* FIXME: DEBUG going to the next request */		request->child_pid = NO_SUCH_CHILD_PID;		request->child_state = REQUEST_DONE;		return;	}	/*	 *	Copy Proxy-State from the request to the reply.	 */	vp = paircopy2(request->packet->vps, PW_PROXY_STATE);	if (vp) pairadd(&request->reply->vps, vp);	/*	 *	Access-Requests get delayed or cached.	 */	switch (request->packet->code) {	case PW_AUTHENTICATION_REQUEST:		gettimeofday(&request->next_when, NULL);		if (request->reply->code == 0) {			/*			 *	Check if the lack of response is intentional.			 */			vp = pairfind(request->config_items,				      PW_RESPONSE_PACKET_TYPE);			if (!vp || (vp->vp_integer != 256)) {				DEBUG2("There was no response configured: rejecting request %d",				       request->number);				request->reply->code = PW_AUTHENTICATION_REJECT;			} else {				DEBUG2("Not responding to request %d",				       request->number);			}		}		/*		 *	Run rejected packets through		 *		 *	Post-Auth-Type = Reject

⌨️ 快捷键说明

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