Esempio n. 1
0
/*
 * In IKEv1, some implementations (including freeswan/openswan/libreswan)
 * interpreted the RFC that the whole IKE message must padded to a multiple
 * of 4 octets, but other implementations (i.e. Checkpoint in Aggressive Mode)
 * drop padded IKE packets. Some of the text on this topic can be found in the
 * IKEv1 RFC 2408 section 3.6 Transform Payload.
 *
 * The ikepad= option can be set to yes or no on a per-connection basis,
 * and defaults to yes.
 *
 * In IKEv2, there is no padding specified in the RFC and some implementations
 * will reject IKEv2 messages that are padded. As there are no known IKEv2
 * clients that REQUIRE padding, padding is never done for IKEv2. If IKEv2
 * clients are discovered in the wild, we will revisit this - please contact
 * the libreswan developers if you find such an implementation.
 * Therefor, the ikepad= option has no effect on IKEv2 connections.
 *
 * @param pbs PB Stream
 */
bool close_message(pb_stream *pbs, struct state *st)
{
	size_t padding;

	if (st->st_ikev2) {
		DBG(DBG_CONTROLMORE, DBG_log("no IKE message padding required for IKEv2"));
		close_output_pbs(pbs);
		return TRUE;
	}

	padding =  pad_up(pbs_offset(pbs), 4);

	if (padding != 0 && st != NULL && st->st_connection != NULL &&
	    (st->st_connection->policy & POLICY_NO_IKEPAD)) {
		DBG(DBG_CONTROLMORE, DBG_log("IKEv1 message padding of %zu bytes skipped by policy",
			padding));
	} else if (padding != 0) {
		DBG(DBG_CONTROLMORE, DBG_log("padding IKEv1 message with %zu bytes", padding));
		if (!out_zero(padding, pbs, "message padding"))
			return FALSE;
	} else {
		DBG(DBG_CONTROLMORE, DBG_log("no IKEv1 message padding required"));
	}

	close_output_pbs(pbs);
	return TRUE;
}
Esempio n. 2
0
/** The whole message must be a multiple of 4 octets.
 * I'm not sure where this is spelled out, but look at
 * rfc2408 3.6 Transform Payload.
 * Note: it talks about 4 BYTE boundaries!
 *
 * @param pbs PB Stream
 */
void
close_message(pb_stream *pbs)
{
    size_t padding =  pad_up(pbs_offset(pbs), 4);

    if (padding != 0)
	(void) out_zero(padding, pbs, "message padding");
    close_output_pbs(pbs);
}
Esempio n. 3
0
/** The whole message must be a multiple of 4 octets.
 * I'm not sure where this is spelled out, but look at
 * rfc2408 3.6 Transform Payload.
 * Note: it talks about 4 BYTE boundaries!
 *
 * @param pbs PB Stream
 */
void
close_message(pb_stream *pbs, struct state *st)
{
    size_t padding =  pad_up(pbs_offset(pbs), 4);

    if (st && st->st_connection && (st->st_connection->policy & POLICY_IKEPAD) == 0)
    	padding = 0;

    if (padding != 0)
	(void) out_zero(padding, pbs, "message padding");
    close_output_pbs(pbs);
}
Esempio n. 4
0
bool emit_redirect_notification_decoded_dest(
		v2_notification_t ntype,
		const ip_address *dest_ip,
		const char *dest_str,
		const chunk_t *nonce, /* optional */
		pb_stream *pbs)
{
	struct ikev2_redirect_part gwi;
	size_t id_len;
	const unsigned char *id_bytes;

	if (dest_ip == NULL) {
		id_len = strlen(dest_str);
		id_bytes = (const unsigned char *)dest_str;
	} else {
		passert(dest_str == NULL);

		switch (addrtypeof(dest_ip)) {
		case AF_INET:
			gwi.gw_identity_type = GW_IPV4;
			break;
		case AF_INET6:
			gwi.gw_identity_type = GW_IPV6;
			break;
		default:
			bad_case(addrtypeof(dest_ip));
		}
		id_len = addrbytesptr_read(dest_ip, &id_bytes);
	}

	if (id_len > 0xFF) {
		/* ??? what should we do? */
		loglog(RC_LOG_SERIOUS, "redirect destination longer than 255 octets; ignoring");
		return false;
	}
	gwi.gw_identity_len = id_len;

	passert(nonce == NULL ||
		(nonce->len >= IKEv2_MINIMUM_NONCE_SIZE &&
		 nonce->len <= IKEv2_MAXIMUM_NONCE_SIZE));

	pb_stream gwid_pbs;
	return
-		emit_v2Npl(ntype, pbs, &gwid_pbs) &&
		out_struct(&gwi, &ikev2_redirect_desc, &gwid_pbs, NULL) &&
		out_raw(id_bytes, id_len , &gwid_pbs, "redirect ID") &&
		(nonce == NULL || out_chunk(*nonce, &gwid_pbs, "redirect ID len")) &&
		(close_output_pbs(&gwid_pbs), true);
}
Esempio n. 5
0
/** The whole message must be a multiple of 4 octets.
 * I'm not sure where this is spelled out, but look at
 * rfc2408 3.6 Transform Payload.
 * Note: it talks about 4 BYTE boundaries!
 *
 * @param pbs PB Stream
 */
void close_message(pb_stream *pbs, struct state *st)
{
	size_t padding =  pad_up(pbs_offset(pbs), 4);

	/* Workaround for overzealous Checkpoint firewal */
	if (padding && st && st->st_connection &&
	    (st->st_connection->policy & POLICY_NO_IKEPAD)) {
		DBG(DBG_CONTROLMORE, DBG_log("IKE message padding of %lu bytes skipped by policy",
			padding));
		padding = 0;
	}

	if (padding != 0) {
		DBG(DBG_CONTROLMORE, DBG_log("padding IKE message with %lu bytes", padding));
		(void) out_zero(padding, pbs, "message padding");
	} else {
		DBG(DBG_CONTROLMORE, DBG_log("no IKE message padding required"));
	}

	close_output_pbs(pbs);
}
Esempio n. 6
0
void send_v2_notification(struct state *p1st, u_int16_t type
		     , struct state *encst
		     , u_char *icookie 
		     , u_char *rcookie 
		     , chunk_t *n_data)
{
    u_char buffer[1024];
    pb_stream reply;
    pb_stream rbody;
	/* this function is not generic enough yet just enough for 6msg 
	 * TBD accept HDR FLAGS as arg. default ISAKMP_FLAGS_R
	 * TBD when there is a child SA use that SPI in the notify paylod.
	 * TBD support encrypted notifications payloads.
	 * TBD accept Critical bit as an argument. default is set.
	 * TBD accept exchange type as an arg, default is ISAKMP_v2_SA_INIT
	 * do we need to send a notify with empty data?
	 * do we need to support more Protocol ID? more than PROTO_ISAKMP
	 */

    IPSEC_dbg("sending %snotification %s to %s:%u"
		 , encst ? "encrypted " : ""
		 , enum_name(&ikev2_notify_names, type)
		 , ip_str(&p1st->st_remoteaddr)
		 , p1st->st_remoteport);
	
    if(n_data == NULL) 
	{ 
    	DBG(DBG_CONTROLMORE, DBG_log("don't send packet when notification data empty"));  
			return; 
	}

    memset(buffer, 0, sizeof(buffer));
    init_pbs(&reply, buffer, sizeof(buffer), "notification msg");

    /* HDR out */
    {
	struct isakmp_hdr n_hdr ;
	zero(&n_hdr);     /* default to 0 */  /* AAA should we copy from MD? */
	n_hdr.isa_version = IKEv2_MAJOR_VERSION << ISA_MAJ_SHIFT | IKEv2_MINOR_VERSION;
	memcpy(n_hdr.isa_rcookie, rcookie, COOKIE_SIZE);
	memcpy(n_hdr.isa_icookie, icookie, COOKIE_SIZE);
	n_hdr.isa_xchg = ISAKMP_v2_SA_INIT;  
	n_hdr.isa_np = ISAKMP_NEXT_v2N;
	n_hdr.isa_flags &= ~ISAKMP_FLAGS_I;
	n_hdr.isa_flags  |=  ISAKMP_FLAGS_R;
	if (!out_struct(&n_hdr, &isakmp_hdr_desc, &reply, &rbody)) 
	{
    	IPSEC_dbg("error initializing hdr for notify message");
	    return;
	}
		
    } 
	chunk_t child_spi;
	child_spi.ptr = NULL;
	child_spi.len = 0;

	/* build and add v2N payload to the packet */
	ship_v2N (ISAKMP_NEXT_NONE, ISAKMP_PAYLOAD_CRITICAL, 
					PROTO_ISAKMP, &child_spi,type, n_data, &rbody);

   	close_message(&rbody);
	close_output_pbs(&reply); 

  	clonetochunk(p1st->st_tpacket, reply.start, pbs_offset(&reply)
		                    , "notification packet");

	ipsec_child_send_packet(p1st, "notification", TRUE);
}