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

📄 listen.c

📁 使用最广泛的radius的linux的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
			DEBUG("WARNING: Ignoring Status-Server request due to security configuration");			return 0;		}		fun = rad_status_server;		break;	default:		rad_recv_discard(listener->fd);		RAD_SNMP_INC(rad_snmp.auth.total_unknown_types);		RAD_SNMP_CLIENT_INC(listener, client, unknown_types);		DEBUG("Invalid packet code %d sent to authentication port from client %s port %d : IGNORED",		      code, client->shortname, src_port);		return 0;		break;	} /* switch over packet types */	/*	 *	Now that we've sanity checked everything, receive the	 *	packet.	 */	packet = rad_recv(listener->fd, client->message_authenticator);	if (!packet) {		RAD_SNMP_TYPE_INC(listener, total_malformed_requests);		DEBUG("%s", librad_errstr);		return 0;	}	if (!received_request(listener, packet, prequest, client)) {		RAD_SNMP_TYPE_INC(listener, total_packets_dropped);		RAD_SNMP_CLIENT_INC(listener, client, packets_dropped);		rad_free(&packet);		return 0;	}	*pfun = fun;	return 1;}/* *	Receive packets from an accounting socket */static int acct_socket_recv(rad_listen_t *listener,			    RAD_REQUEST_FUNP *pfun, REQUEST **prequest){	ssize_t		rcode;	int		code, src_port;	RADIUS_PACKET	*packet;	RAD_REQUEST_FUNP fun = NULL;	char		buffer[128];	RADCLIENT	*client;	fr_ipaddr_t	src_ipaddr;	rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);	if (rcode < 0) return 0;	RAD_SNMP_TYPE_INC(listener, total_requests);	if (rcode < 20) {	/* AUTH_HDR_LEN */		RAD_SNMP_TYPE_INC(listener, total_malformed_requests);		return 0;	}	if ((client = client_listener_find(listener,					   &src_ipaddr)) == NULL) {		rad_recv_discard(listener->fd);		RAD_SNMP_TYPE_INC(listener, total_invalid_requests);		/*		 *	This is debugging rather than logging, so that		 *	DoS attacks don't affect us.		 */		if (debug_flag > 0) {			char name[1024];			listener->print(listener, name, sizeof(name));			DEBUG("Ignoring request to %s from unknown client %s port %d",			      name,			      inet_ntop(src_ipaddr.af, &src_ipaddr.ipaddr,					buffer, sizeof(buffer)), src_port);		}		return 0;	}	/*	 *	Some sanity checks, based on the packet code.	 */	switch(code) {	case PW_ACCOUNTING_REQUEST:		RAD_SNMP_CLIENT_INC(listener, client, requests);		fun = rad_accounting;		break;	case PW_STATUS_SERVER:		if (!mainconfig.status_server) {			rad_recv_discard(listener->fd);			RAD_SNMP_TYPE_INC(listener, total_packets_dropped);			RAD_SNMP_CLIENT_INC(listener, client, unknown_types);			DEBUG("WARNING: Ignoring Status-Server request due to security configuration");			return 0;		}		fun = rad_status_server;		break;	default:		rad_recv_discard(listener->fd);		RAD_SNMP_TYPE_INC(listener, total_unknown_types);		RAD_SNMP_CLIENT_INC(listener, client, unknown_types);		DEBUG("Invalid packet code %d sent to a accounting port from client %s port %d : IGNORED",		      code, client->shortname, src_port);		return 0;	} /* switch over packet types */	/*	 *	Now that we've sanity checked everything, receive the	 *	packet.	 */	packet = rad_recv(listener->fd, 0);	if (!packet) {		RAD_SNMP_TYPE_INC(listener, total_malformed_requests);		radlog(L_ERR, "%s", librad_errstr);		return 0;	}	/*	 *	There can be no duplicate accounting packets.	 */	if (!received_request(listener, packet, prequest, client)) {		RAD_SNMP_TYPE_INC(listener, total_packets_dropped);		RAD_SNMP_CLIENT_INC(listener, client, packets_dropped);		rad_free(&packet);		return 0;	}	*pfun = fun;	return 1;}/* *	Recieve packets from a proxy socket. */static int proxy_socket_recv(rad_listen_t *listener,			      RAD_REQUEST_FUNP *pfun, REQUEST **prequest){	REQUEST		*request;	RADIUS_PACKET	*packet;	RAD_REQUEST_FUNP fun = NULL;	char		buffer[128];	packet = rad_recv(listener->fd, 0);	if (!packet) {		radlog(L_ERR, "%s", librad_errstr);		return 0;	}	/*	 *	FIXME: Client MIB updates?	 */	switch(packet->code) {	case PW_AUTHENTICATION_ACK:	case PW_ACCESS_CHALLENGE:	case PW_AUTHENTICATION_REJECT:		fun = rad_authenticate;		break;	case PW_ACCOUNTING_RESPONSE:		fun = rad_accounting;		break;	default:		/*		 *	FIXME: Update MIB for packet types?		 */		radlog(L_ERR, "Invalid packet code %d sent to a proxy port "		       "from home server %s port %d - ID %d : IGNORED",		       packet->code,		       ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),		       packet->src_port, packet->id);		rad_free(&packet);		return 0;	}	request = received_proxy_response(packet);	if (!request) {		return 0;	}	rad_assert(fun != NULL);	*pfun = fun;	*prequest = request;	return 1;}static int client_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request){	if (!request->reply->code) return 0;	rad_encode(request->reply, request->packet,		   request->client->secret);	rad_sign(request->reply, request->packet,		 request->client->secret);	return 0;}static int client_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request){	if (rad_verify(request->packet, NULL,		       request->client->secret) < 0) {		return -1;	}	return rad_decode(request->packet, NULL,			  request->client->secret);}static int proxy_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request){	rad_encode(request->proxy, NULL, request->home_server->secret);	rad_sign(request->proxy, NULL, request->home_server->secret);	return 0;}static int proxy_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request){	if (rad_verify(request->proxy_reply, request->proxy,		       request->home_server->secret) < 0) {		return -1;	}	return rad_decode(request->proxy_reply, request->proxy,			   request->home_server->secret);}#ifdef WITH_SNMPstatic int radius_snmp_recv(rad_listen_t *listener,			    UNUSED RAD_REQUEST_FUNP *pfun,			    UNUSED REQUEST **prequest){	if ((rad_snmp.smux_fd >= 0) &&	    (rad_snmp.smux_event == SMUX_READ)) {		smux_read();	}	/*	 *  If we've got to re-connect, then do so now,	 *  before calling select again.	 */	if (rad_snmp.smux_event == SMUX_CONNECT) {		smux_connect();	}	/*	 *	Reset this every time, as the smux connect may have	 *	opened a new socket.	 */	listener->fd = rad_snmp.smux_fd;	return 0;}static int radius_snmp_print(UNUSED rad_listen_t *this, char *buffer, size_t bufsize){	return snprintf(buffer, bufsize, "SMUX with OID .1.3.6.1.4.1.11344.1.1.1");}#endif#include "dhcpd.c"static const rad_listen_master_t master_listen[RAD_LISTEN_MAX] = {	{ NULL, NULL, NULL, NULL, NULL, NULL, NULL},	/* RAD_LISTEN_NONE */	/* proxying */	{ common_socket_parse, NULL,	  proxy_socket_recv, proxy_socket_send,	  socket_print, proxy_socket_encode, proxy_socket_decode },	/* authentication */	{ common_socket_parse, NULL,	  auth_socket_recv, auth_socket_send,	  socket_print, client_socket_encode, client_socket_decode },	/* accounting */	{ common_socket_parse, NULL,	  acct_socket_recv, acct_socket_send,	  socket_print, client_socket_encode, client_socket_decode},	/* detail */	{ detail_parse, detail_free,	  detail_recv, detail_send,	  detail_print, detail_encode, detail_decode },#ifdef WITH_VMPS	/* vlan query protocol */	{ common_socket_parse, NULL,	  vqp_socket_recv, vqp_socket_send,	  socket_print, vqp_socket_encode, vqp_socket_decode },#else	{ NULL, NULL, NULL, NULL, NULL, NULL, NULL},#endif#ifdef WITH_DHCP	/* dhcp query protocol */	{ dhcp_socket_parse, NULL,	  dhcp_socket_recv, dhcp_socket_send,	  socket_print, dhcp_socket_encode, dhcp_socket_decode },#else	{ NULL, NULL, NULL, NULL, NULL, NULL, NULL},#endif	{ NULL, NULL, NULL, NULL, NULL, NULL, NULL}	/* RAD_LISTEN_SNMP */};/* *	Binds a listener to a socket. */static int listen_bind(rad_listen_t *this){	listen_socket_t *sock = this->data;	/*	 *	If the port is zero, then it means the appropriate	 *	thing from /etc/services.	 */	if (sock->port == 0) {		struct servent	*svp;		switch (this->type) {		case RAD_LISTEN_AUTH:			svp = getservbyname ("radius", "udp");			if (svp != NULL) {				sock->port = ntohs(svp->s_port);			} else {				sock->port = PW_AUTH_UDP_PORT;			}			break;		case RAD_LISTEN_ACCT:			svp = getservbyname ("radacct", "udp");			if (svp != NULL) {				sock->port = ntohs(svp->s_port);			} else {				sock->port = PW_ACCT_UDP_PORT;			}			break;		case RAD_LISTEN_PROXY:			sock->port = 0;			break;#ifdef WITH_VMPS		case RAD_LISTEN_VQP:			sock->port = 1589;			break;#endif		default:			radlog(L_ERR, "ERROR: Non-fatal internal sanity check failed in bind.");			return -1;		}	}	this->fd = fr_socket(&sock->ipaddr, sock->port);	if (this->fd < 0) {		radlog(L_ERR, "ERROR: Failed to open socket: %s",		       librad_errstr);		return -1;	}	/*	 *	FreeBSD jail issues.  We bind to 0.0.0.0, but the	 *	kernel instead binds us to a 1.2.3.4.  If this	 *	happens, notice, and remember our real IP.	 */	{		struct sockaddr_storage	src;		socklen_t	        sizeof_src = sizeof(src);		memset(&src, 0, sizeof_src);		if (getsockname(this->fd, (struct sockaddr *) &src,				&sizeof_src) < 0) {			radlog(L_ERR, "Failed getting socket name: %s",			       strerror(errno));			return -1;		}		if (src.ss_family == AF_INET) {			struct sockaddr_in	*s4;						s4 = (struct sockaddr_in *)&src;			sock->ipaddr.ipaddr.ip4addr = s4->sin_addr;			sock->port = ntohs(s4->sin_port);			#ifdef HAVE_STRUCT_SOCKADDR_IN6		} else if (src.ss_family == AF_INET6) {			struct sockaddr_in6	*s6;						s6 = (struct sockaddr_in6 *)&src;			sock->ipaddr.ipaddr.ip6addr = s6->sin6_addr;			sock->port = ntohs(s6->sin6_port);#endif		} else {			radlog(L_ERR, "Socket has unsupported address family");			return -1;		}	}#ifdef O_NONBLOCK	{		int flags;				if ((flags = fcntl(this->fd, F_GETFL, NULL)) < 0)  {			radlog(L_ERR, "Failure getting socket flags: %s)\n",			       strerror(errno));			return -1;		}				flags |= O_NONBLOCK;		if( fcntl(this->fd, F_SETFL, flags) < 0) {			radlog(L_ERR, "Failure setting socket flags: %s)\n",			       strerror(errno));			return -1;		}	}#endif	return 0;}/* *	Allocate & initialize a new listener. */static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type){	rad_listen_t *this;	this = rad_malloc(sizeof(*this));	memset(this, 0, sizeof(*this));	this->type = type;	this->recv = master_listen[this->type].recv;	this->send = master_listen[this->type].send;	this->print = master_listen[this->type].print;	this->encode = master_listen[this->type].encode;	this->decode = master_listen[this->type].decode;	switch (type) {	case RAD_LISTEN_AUTH:	case RAD_LISTEN_ACCT:	case RAD_LISTEN_PROXY:	case RAD_LISTEN_VQP:	case RAD_LISTEN_DHCP:		this->data = rad_malloc(sizeof(listen_socket_t));		memset(this->data, 0, sizeof(listen_socket_t));		break;	case RAD_LISTEN_DETAIL:		this->data = NULL;		break;	default:		rad_assert("Unsupported option!" == NULL);		break;	}	return this;}/* *	Externally visible function for creating a new proxy LISTENER. * *	For now, don't take ipaddr or port. * *	Not thread-safe, but all calls to it are protected by the *	proxy mutex in request_list.c */rad_listen_t *proxy_new_listener(){	int last_proxy_port, port;	rad_listen_t *this, *tmp, **last;	listen_socket_t *sock, *old;

⌨️ 快捷键说明

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