Esempio n. 1
0
int vmps_process(REQUEST *request)
{
	DEBUG2("Doing VMPS");
	module_post_auth(0, request);
	DEBUG2("Done VMPS");

	request->reply->code = PW_AUTHENTICATION_ACK;

	return 0;
}
Esempio n. 2
0
File: auth.c Progetto: ebichu/dd-wrt
/*
 *	Post-authentication step processes the response before it is
 *	sent to the NAS. It can receive both Access-Accept and Access-Reject
 *	replies.
 */
int rad_postauth(REQUEST *request)
{
	int	result;
	int	postauth_type = 0;
	VALUE_PAIR *vp;

	/*
	 *	Do post-authentication calls. ignoring the return code.
	 */
	vp = pairfind(request->config_items, PW_POST_AUTH_TYPE);
	if (vp) {
		RDEBUG2("Using Post-Auth-Type %s",
			dict_valnamebyattr(PW_POST_AUTH_TYPE, vp->vp_integer));
		postauth_type = vp->vp_integer;
	}
	result = module_post_auth(postauth_type, request);
	switch (result) {
		/*
		 *	The module failed, or said to reject the user: Do so.
		 */
		case RLM_MODULE_FAIL:
		case RLM_MODULE_INVALID:
		case RLM_MODULE_REJECT:
		case RLM_MODULE_USERLOCK:
		default:
			request->reply->code = PW_AUTHENTICATION_REJECT;
			result = RLM_MODULE_REJECT;
			break;
		/*
		 *	The module handled the request, cancel the reply.
		 */
		case RLM_MODULE_HANDLED:
			/* FIXME */
			break;
		/*
		 *	The module had a number of OK return codes.
		 */
		case RLM_MODULE_NOOP:
		case RLM_MODULE_NOTFOUND:
		case RLM_MODULE_OK:
		case RLM_MODULE_UPDATED:
			result = RLM_MODULE_OK;
			break;
	}
	return result;
}
Esempio n. 3
0
/*
 *	Post-authentication step processes the response before it is
 *	sent to the NAS. It can receive both Access-Accept and Access-Reject
 *	replies.
 */
int rad_postauth(REQUEST *request)
{
	int	result;
	int	postauth_type = 0;
	VALUE_PAIR	*postauth_type_item = NULL;

	/*
	 *	Do post-authentication calls. ignoring the return code.
	 */
	postauth_type_item = pairfind(request->config_items, PW_POST_AUTH_TYPE);
	if (postauth_type_item)
		postauth_type = postauth_type_item->lvalue;
	result = module_post_auth(postauth_type, request);
	switch (result) {
	default:
	  break;

	  /*
	   *	The module failed, or said to reject the user: Do so.
	   */
	case RLM_MODULE_FAIL:
	case RLM_MODULE_REJECT:
	case RLM_MODULE_USERLOCK:
	case RLM_MODULE_INVALID:
	  request->reply->code = PW_AUTHENTICATION_REJECT;
	  result = RLM_MODULE_REJECT;
	  break;

	  /*
	   *	The module had a number of OK return codes.
	   */
	case RLM_MODULE_NOTFOUND:
	case RLM_MODULE_NOOP:
	case RLM_MODULE_UPDATED:
	case RLM_MODULE_OK:
	case RLM_MODULE_HANDLED:
	  result = RLM_MODULE_OK;
	  break;
	}
	return result;
}
Esempio n. 4
0
static int dhcp_process(REQUEST *request)
{
	int rcode;
	VALUE_PAIR *vp;

	vp = pairfind(request->packet->vps, 53, DHCP_MAGIC_VENDOR); /* DHCP-Message-Type */
	if (vp) {
		DICT_VALUE *dv = dict_valbyattr(53, DHCP_MAGIC_VENDOR, vp->vp_integer);
		DEBUG("Trying sub-section dhcp %s {...}",
		      dv->name ? dv->name : "<unknown>");
		rcode = module_post_auth(vp->vp_integer, request);
	} else {
		DEBUG("DHCP: Failed to find DHCP-Message-Type in packet!");
		rcode = RLM_MODULE_FAIL;
	}

	/*
	 *	For messages from a client, look for Relay attribute,
	 *	and forward it if necessary.
	 */
	vp = NULL;
	if (request->packet->data[0] == 1) {
		vp = pairfind(request->config_items, 270, DHCP_MAGIC_VENDOR);
	}
	if (vp) {
		VALUE_PAIR *giaddr;
		
		/*
		 *	Find the original giaddr.
		 *	FIXME: Maybe look in the original packet?
		 *
		 *	It's invalid to have giaddr=0 AND a relay option
		 */
		giaddr = pairfind(request->packet->vps, 266, DHCP_MAGIC_VENDOR);
		if (giaddr && (giaddr->vp_ipaddr == htonl(INADDR_ANY))) {
			if (pairfind(request->packet->vps, 82, DHCP_MAGIC_VENDOR)) {
				RDEBUG("DHCP: Received packet with giaddr = 0 and containing relay option: Discarding packet");
				return 1;
			}
		}

		if (request->packet->data[3] > 10) {
			RDEBUG("DHCP: Number of hops is greater than 10: not relaying");
			return 1;
		}

		/*
		 *	Forward a reply...
		 */
		pairfree(&request->reply->vps);
		request->reply->vps = paircopy(request->packet->vps);
		request->reply->code = request->packet->code;
		request->reply->id = request->packet->id;
		request->reply->src_ipaddr = request->packet->dst_ipaddr;
		request->reply->src_port = request->packet->dst_port;
		request->reply->dst_ipaddr.af = AF_INET;
		request->reply->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
		/*
		 *	Don't change the destination port.  It's the
		 *	server port.
		 */

		/*
		 *	Hop count goes up.
		 */
		vp = pairfind(request->reply->vps, 259, DHCP_MAGIC_VENDOR);
		if (vp) vp->vp_integer++;
		
		return 1;
	}

	/*
	 *	Responses from a server.  Handle them differently.
	 */
	if (request->packet->data[0] == 2) {
		pairfree(&request->reply->vps);
		request->reply->vps = paircopy(request->packet->vps);
		request->reply->code = request->packet->code;
		request->reply->id = request->packet->id;

		/*
		 *	Delete any existing giaddr.  If we received a
		 *	message from the server, then we're NOT the
		 *	server.  So we must be the destination of the
		 *	giaddr field.
		 */
		pairdelete(&request->packet->vps, 266, DHCP_MAGIC_VENDOR);

		/*
		 *	Search for client IP address.
		 */
		vp = pairfind(request->packet->vps, 264, DHCP_MAGIC_VENDOR);
		if (!vp) {
			request->reply->code = 0;
			RDEBUG("DHCP: No YIAddr in the reply. Discarding packet");
			return 1;
		}

		/*
		 *	FROM us, TO the client's IP, OUR port + 1.
		 */
		request->reply->src_ipaddr = request->packet->dst_ipaddr;
		request->reply->src_port = request->packet->dst_port;
		request->reply->dst_ipaddr.af = AF_INET;
		request->reply->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
		request->reply->dst_port = request->packet->dst_port + 1;

		/*
		 *	Hop count goes down.
		 */
		vp = pairfind(request->reply->vps, 259, DHCP_MAGIC_VENDOR);
		if (vp && (vp->vp_integer > 0)) vp->vp_integer--;

		/*
		 *	FIXME: Keep original somewhere?  If the
		 *	broadcast flags are set, use them here?
		 */
		
		return 1;
	}

	vp = pairfind(request->reply->vps, 53, DHCP_MAGIC_VENDOR); /* DHCP-Message-Type */
	if (vp) {
		request->reply->code = vp->vp_integer;
		if ((request->reply->code != 0) &&
		    (request->reply->code < PW_DHCP_OFFSET)) {
			request->reply->code += PW_DHCP_OFFSET;
		}
	}
	else switch (rcode) {
	case RLM_MODULE_OK:
	case RLM_MODULE_UPDATED:
		if (request->packet->code == PW_DHCP_DISCOVER) {
			request->reply->code = PW_DHCP_OFFER;
			break;

		} else if (request->packet->code == PW_DHCP_REQUEST) {
			request->reply->code = PW_DHCP_ACK;
			break;
		}
		request->reply->code = PW_DHCP_NAK;
		break;

	default:
	case RLM_MODULE_REJECT:
	case RLM_MODULE_FAIL:
	case RLM_MODULE_INVALID:
	case RLM_MODULE_NOOP:
	case RLM_MODULE_NOTFOUND:	
		if (request->packet->code == PW_DHCP_DISCOVER) {
			request->reply->code = 0; /* ignore the packet */
		} else {
			request->reply->code = PW_DHCP_NAK;
		}
		break;

	case RLM_MODULE_HANDLED:
		break;
	}

	/*
	 *	Releases don't get replies.
	 */
	if (request->packet->code == PW_DHCP_RELEASE) {
		request->reply->code = 0;
	}

	return 1;
}
Esempio n. 5
0
static int dhcp_process(REQUEST *request)
{
	int rcode;
	VALUE_PAIR *vp;

	vp = pairfind(request->packet->vps, 53, DHCP_MAGIC_VENDOR); /* DHCP-Message-Type */
	if (vp) {
		DICT_VALUE *dv = dict_valbyattr(53, DHCP_MAGIC_VENDOR, vp->vp_integer);
		DEBUG("Trying sub-section dhcp %s {...}",
		      dv->name ? dv->name : "<unknown>");
		rcode = module_post_auth(vp->vp_integer, request);
	} else {
		DEBUG("DHCP: Failed to find DHCP-Message-Type in packet!");
		rcode = RLM_MODULE_FAIL;
	}

	/*
	 *	Look for Relay attribute, and forward it if necessary.
	 */
	vp = pairfind(request->config_items, 270, DHCP_MAGIC_VENDOR);
	if (vp) {
		VALUE_PAIR *giaddr;
		RADIUS_PACKET relayed;
		
		request->reply->code = 0; /* don't reply to the client */

		/*
		 *	Find the original giaddr.
		 *	FIXME: Maybe look in the original packet?
		 *
		 *	It's invalid to have giaddr=0 AND a relay option
		 */
		giaddr = pairfind(request->packet->vps, 266, DHCP_MAGIC_VENDOR);
		if (giaddr && (giaddr->vp_ipaddr == htonl(INADDR_ANY))) {
			if (pairfind(request->packet->vps, 82, DHCP_MAGIC_VENDOR)) {
				RDEBUG("DHCP: Received packet with giaddr = 0 and containing relay option: Discarding packet");
				return 1;
			}

			/*
			 *	FIXME: Add cache by XID.
			 */
			RDEBUG("DHCP: Cannot yet relay packets with giaddr = 0");
			return 1;
		}

		if (request->packet->data[3] > 10) {
			RDEBUG("DHCP: Number of hops is greater than 10: not relaying");
			return 1;
		}

		/*
		 *	Forward it VERBATIM to the next server, rather
		 *	than to the client.
		 */
		memcpy(&relayed, request->packet, sizeof(relayed));

		relayed.dst_ipaddr.af = AF_INET;
		relayed.dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
		relayed.dst_port = request->packet->dst_port;

		relayed.src_ipaddr = request->packet->dst_ipaddr;
		relayed.src_port = request->packet->dst_port;

		relayed.data = rad_malloc(relayed.data_len);
		memcpy(relayed.data, request->packet->data, request->packet->data_len);
		relayed.vps = NULL;

		/*
		 *	The only field that changes is the number of hops
		 */
		relayed.data[3]++; /* number of hops */
		
		/*
		 *	Forward the relayed packet VERBATIM, don't
		 *	respond to the client, and forget completely
		 *	about this request.
		 */
		fr_dhcp_send(&relayed);
		free(relayed.data);
		return 1;
	}

	vp = pairfind(request->reply->vps, 53, DHCP_MAGIC_VENDOR); /* DHCP-Message-Type */
	if (vp) {
		request->reply->code = vp->vp_integer;
		if ((request->reply->code != 0) &&
		    (request->reply->code < PW_DHCP_OFFSET)) {
			request->reply->code += PW_DHCP_OFFSET;
		}
	}
	else switch (rcode) {
	case RLM_MODULE_OK:
	case RLM_MODULE_UPDATED:
		if (request->packet->code == PW_DHCP_DISCOVER) {
			request->reply->code = PW_DHCP_OFFER;
			break;

		} else if (request->packet->code == PW_DHCP_REQUEST) {
			request->reply->code = PW_DHCP_ACK;
			break;
		}
		request->reply->code = PW_DHCP_NAK;
		break;

	default:
	case RLM_MODULE_REJECT:
	case RLM_MODULE_FAIL:
	case RLM_MODULE_INVALID:
	case RLM_MODULE_NOOP:
	case RLM_MODULE_NOTFOUND:	
		if (request->packet->code == PW_DHCP_DISCOVER) {
			request->reply->code = 0; /* ignore the packet */
		} else {
			request->reply->code = PW_DHCP_NAK;
		}
		break;

	case RLM_MODULE_HANDLED:
		break;
	}

	/*
	 *	Releases don't get replies.
	 */
	if (request->packet->code == PW_DHCP_RELEASE) {
		request->reply->code = 0;
	}

	return 1;
}
Esempio n. 6
0
static int dhcp_process(REQUEST *request)
{
	int rcode;
	unsigned int i;
	VALUE_PAIR *vp;
	dhcp_socket_t *sock;

	vp = pairfind(request->packet->vps, DHCP2ATTR(53)); /* DHCP-Message-Type */
	if (vp) {
		DICT_VALUE *dv = dict_valbyattr(DHCP2ATTR(53), vp->vp_integer);
		DEBUG("Trying sub-section dhcp %s {...}",
		      dv->name ? dv->name : "<unknown>");
		rcode = module_post_auth(vp->vp_integer, request);
	} else {
		DEBUG("DHCP: Failed to find DHCP-Message-Type in packet!");
		rcode = RLM_MODULE_FAIL;
	}

	vp = pairfind(request->reply->vps, DHCP2ATTR(53)); /* DHCP-Message-Type */
	if (vp) {
		request->reply->code = vp->vp_integer;
		if ((request->reply->code != 0) &&
		    (request->reply->code < PW_DHCP_OFFSET)) {
			request->reply->code += PW_DHCP_OFFSET;
		}
	}
	else switch (rcode) {
	case RLM_MODULE_OK:
	case RLM_MODULE_UPDATED:
		if (request->packet->code == PW_DHCP_DISCOVER) {
			request->reply->code = PW_DHCP_OFFER;
			break;

		} else if (request->packet->code == PW_DHCP_REQUEST) {
			request->reply->code = PW_DHCP_ACK;
			break;
		}
		request->reply->code = PW_DHCP_NAK;
		break;

	default:
	case RLM_MODULE_REJECT:
	case RLM_MODULE_FAIL:
	case RLM_MODULE_INVALID:
	case RLM_MODULE_NOOP:
	case RLM_MODULE_NOTFOUND:
		if (request->packet->code == PW_DHCP_DISCOVER) {
			request->reply->code = 0; /* ignore the packet */
		} else {
			request->reply->code = PW_DHCP_NAK;
		}
		break;

	case RLM_MODULE_HANDLED:
		request->reply->code = 0; /* ignore the packet */
		break;
	}

	/*
	 *	TODO: Handle 'output' of RLM_MODULE when acting as a
	 *	DHCP relay We may want to not forward packets in
	 *	certain circumstances.
	 */

	/*
	 * 	Handle requests when acting as a DHCP relay
	 */
	vp = pairfind(request->packet->vps, DHCP2ATTR(256)); /* DHCP-Opcode */
	if (!vp) {
		RDEBUG("FAILURE: Someone deleted the DHCP-Opcode!");
		return 1;
	}

	/* BOOTREPLY received on port 67 (i.e. from a server) */
	if (vp->vp_integer == 2) {
		return dhcprelay_process_server_reply(request);
	}

	/* Packet from client, and we have DHCP-Relay-To-IP-Address */
	if (pairfind(request->config_items, DHCP2ATTR(270))) { 
		return dhcprelay_process_client_request(request);
	}

	/* else it's a packet from a client, without relaying */
	rad_assert(vp->vp_integer == 1); /* BOOTREQUEST */

	sock = request->listener->data;

	/*
	 *	Handle requests when acting as a DHCP server
	 */

	/*
	 *	Releases don't get replies.
	 */
	if (request->packet->code == PW_DHCP_RELEASE) {
		request->reply->code = 0;
	}

	if (request->reply->code == 0) {
		return 1;
	}

	request->reply->sockfd = request->packet->sockfd;

	/*
	 *	Copy specific fields from packet to reply, if they
	 *	don't already exist
	 */
	for (i = 0; i < sizeof(attrnums) / sizeof(attrnums[0]); i++) {
		uint32_t attr = attrnums[i];

		if (pairfind(request->reply->vps, DHCP2ATTR(attr))) continue;
		if ((vp = pairfind(request->packet->vps, DHCP2ATTR(attr)))) {
			pairadd(&request->reply->vps, paircopyvp(vp));
		}
	}

	vp = pairfind(request->reply->vps, DHCP2ATTR(256)); /* DHCP-Opcode */
	rad_assert(vp != NULL);
	vp->vp_integer = 2; /* BOOTREPLY */

	/*
	 * Prepare the reply packet for sending through dhcp_socket_send()
	 */
	request->reply->dst_ipaddr.af = AF_INET;
	request->reply->src_ipaddr.af = AF_INET;
	request->reply->src_ipaddr.ipaddr.ip4addr.s_addr = sock->src_ipaddr.ipaddr.ip4addr.s_addr;

	request->reply->dst_port = request->packet->src_port;
	request->reply->src_port = request->packet->dst_port;

	vp = pairfind(request->reply->vps, DHCP2ATTR(266)); /* DHCP-Gateway-IP-Address */
	if (vp && (vp->vp_ipaddr != htonl(INADDR_ANY))) {
		/* Answer to client's nearest DHCP relay */
		request->reply->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
	} else if ((request->reply->code == PW_DHCP_NAK) ||
	    ((vp = pairfind(request->reply->vps, DHCP2ATTR(262))) /* DHCP-Flags */ &&
		(vp->vp_integer & 0x8000) &&
		((vp = pairfind(request->reply->vps, DHCP2ATTR(263))) /* DHCP-Client-IP-Address */ &&
		    (vp->vp_ipaddr == htonl(INADDR_ANY))))) {
		/*
		 * RFC 2131, page 23
		 *
		 * Broadcast on
		 * - DHCPNAK
		 * or
		 * - Broadcast flag is set up and ciaddr == NULL
		 */
		request->reply->dst_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_BROADCAST);
	} else {
		/*
		 * RFC 2131, page 23
		 *
		 * Unicast to
		 * - ciaddr if present
		 * otherwise to yiaddr
		 */
		if ((vp = pairfind(request->reply->vps, DHCP2ATTR(263))) /* DHCP-Client-IP-Address */ &&
		    (vp->vp_ipaddr != htonl(INADDR_ANY))) {
			request->reply->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
		} else {
			vp = pairfind(request->reply->vps, DHCP2ATTR(264)); /* DHCP-Your-IP-Address */
			if (!vp) {
				DEBUG("DHCP: Failed to find IP Address for request.");
				return -1;
			}
			
			request->reply->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;

			/*
			 * When sending a DHCP_OFFER, make sure our ARP table
			 * contains an entry for the client IP address, or else
			 * packet may not be forwarded if it was the first time
			 * the client was requesting an IP address.
			 */
			if (request->reply->code == PW_DHCP_OFFER) {
				VALUE_PAIR *hwvp = pairfind(request->reply->vps, DHCP2ATTR(267)); /* DHCP-Client-Hardware-Address */

				if (!hwvp) return -1;

				if (fr_dhcp_add_arp_entry(request->reply->sockfd, sock->src_interface, hwvp, vp) < 0) {
					return -1;
				}
			}
		}
	}

	return 1;
}