Example #1
0
/* process an input packet, possibly generating a reply.
 *
 * If all goes well, this routine eventually calls a state-specific
 * transition function.
 */
void process_packet(struct msg_digest **mdp)
{
	struct msg_digest *md = *mdp;
	int vmaj, vmin;

	if (!in_struct(&md->hdr, &isakmp_hdr_desc, &md->packet_pbs,
		       &md->message_pbs)) {
		/* The packet was very badly mangled. We can't be sure of any
		 * content - not even to look for major version number!
		 * So we'll just drop it.
		 */
		libreswan_log("Received packet with mangled IKE header - dropped");
		send_notification_from_md(md, PAYLOAD_MALFORMED);
		return;
	}

	if (md->packet_pbs.roof > md->message_pbs.roof) {
		/* Some (old?) versions of the Cisco VPN client send an additional
		 * 16 bytes of zero bytes - Complain but accept it
		 */
		DBG(DBG_CONTROL, {
			DBG_log(
			"size (%u) in received packet is larger than the size "
			"specified in ISAKMP HDR (%u) - ignoring extraneous bytes",
			(unsigned) pbs_room(&md->packet_pbs),
			md->hdr.isa_length);
			DBG_dump("extraneous bytes:", md->message_pbs.roof,
				md->packet_pbs.roof - md->message_pbs.roof);
		});
Example #2
0
/* process an input packet, possibly generating a reply.
 *
 * If all goes well, this routine eventually calls a state-specific
 * transition function.
 */
void process_packet(struct msg_digest **mdp)
{
	struct msg_digest *md = *mdp;
	struct state *st = NULL;
	int vmaj, vmin;
	enum state_kind from_state = STATE_UNDEFINED;   /* state we started in */

#define SEND_NOTIFICATION(t) { \
		if (st) \
			send_notification_from_state(st, from_state, t); \
		else \
			send_notification_from_md(md, t); }

	if (!in_struct(&md->hdr, &isakmp_hdr_desc, &md->packet_pbs,
		       &md->message_pbs)) {
		/*
		 * The packet was very badly mangled. We can't be sure of any
		 * content - not even to look for major version number!
		 * So we'll just silently drop it
		 */
		libreswan_log("Received packet with mangled IKE header - dropped");
		SEND_NOTIFICATION(PAYLOAD_MALFORMED);
		return;
	}

	if (md->packet_pbs.roof < md->message_pbs.roof) {
		/* I don't think this can happen if in_struct() did not fail */
		libreswan_log(
			"received packet size (%u) is smaller than from "
			"size specified in ISAKMP HDR (%u) - packet dropped",
			(unsigned) pbs_room(&md->packet_pbs),
			md->hdr.isa_length);
		/* abort processing corrupt packet */
		return;
	} else if (md->packet_pbs.roof > md->message_pbs.roof) {
		/*
		 * Some (old?) versions of the Cisco VPN client send an additional
		 * 16 bytes of zero bytes - Complain but accept it
		 */
		DBG(DBG_CONTROL, {
			DBG_log(
			"size (%u) in received packet is larger than the size "
			"specified in ISAKMP HDR (%u) - ignoring extraneous bytes",
			(unsigned) pbs_room(&md->packet_pbs),
			md->hdr.isa_length);
			DBG_dump("extraneous bytes:", md->message_pbs.roof,
				md->packet_pbs.roof - md->message_pbs.roof);
		});
Example #3
0
err_t parse_redirect_payload(pb_stream *input_pbs,
			     const char *allowed_targets_list,
			     const chunk_t *nonce,
			     ip_address *redirect_ip /* result */)
{
	struct ikev2_redirect_part gw_info;

	if (!in_struct(&gw_info, &ikev2_redirect_desc, input_pbs, NULL))
		return "received deformed REDIRECT payload";

	int af;

	switch (gw_info.gw_identity_type) {
	case GW_IPV4:
		af = AF_INET;
		break;
	case GW_IPV6:
		af = AF_INET6;
		break;
	case GW_FQDN:
		af  = AF_UNSPEC;
		break;
	default:
		return "bad GW Ident Type";
	}

	/* in_raw() actual GW Identity */
	switch (af) {
	case AF_UNSPEC:
	{
		/*
		 * The FQDN string isn't NUL-terminated.
		 *
		 * The length is stored in a byte so it cannot be
		 * larger than 0xFF.
		 * Some helpful compilers moan about this test being always true
		 * so I eliminated it:
		 *	passert(gw_info.gw_identity_len <= 0xFF);
		 */
		unsigned char gw_str[0xFF];

		if (!in_raw(&gw_str, gw_info.gw_identity_len, input_pbs, "GW Identity"))
			return "error while extracting GW Identity from variable part of IKEv2_REDIRECT Notify payload";

		err_t ugh = ttoaddr((char *) gw_str, gw_info.gw_identity_len,
					AF_UNSPEC, redirect_ip);
		if (ugh != NULL)
			return ugh;
		break;
	}
	case AF_INET:
	case AF_INET6:
	{
		if (pbs_left(input_pbs) < gw_info.gw_identity_len)
			return "variable part of payload is smaller than transfered GW Identity Length";

		/* parse address directly to redirect_ip */
		err_t ugh = initaddr(input_pbs->cur, gw_info.gw_identity_len, af, redirect_ip);
		if (ugh != NULL)
			return ugh;

		DBG(DBG_PARSING, {
			ip_address_buf b;
			DBG_log("   GW Identity IP: %s", ipstr(redirect_ip, &b));
		});
		input_pbs->cur += gw_info.gw_identity_len;
		break;
	}
	}