Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bbd0d598 authored by Vlad Yasevich's avatar Vlad Yasevich Committed by David S. Miller
Browse files

[SCTP]: Implement the receive and verification of AUTH chunk



This patch implements the receive path needed to process authenticated
chunks.  Add ability to process the AUTH chunk and handle edge cases
for authenticated COOKIE-ECHO as well.

Signed-off-by: default avatarVlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4cd57c80
Loading
Loading
Loading
Loading
+3 −1
Original line number Original line Diff line number Diff line
@@ -183,7 +183,9 @@ typedef enum {
	SCTP_IERROR_NO_DATA,
	SCTP_IERROR_NO_DATA,
	SCTP_IERROR_BAD_STREAM,
	SCTP_IERROR_BAD_STREAM,
	SCTP_IERROR_BAD_PORTS,
	SCTP_IERROR_BAD_PORTS,

	SCTP_IERROR_AUTH_BAD_HMAC,
	SCTP_IERROR_AUTH_BAD_KEYID,
	SCTP_IERROR_PROTO_VIOLATION,
} sctp_ierror_t;
} sctp_ierror_t;




+1 −0
Original line number Original line Diff line number Diff line
@@ -143,6 +143,7 @@ sctp_state_fn_t sctp_sf_do_asconf_ack;
sctp_state_fn_t sctp_sf_do_9_2_reshutack;
sctp_state_fn_t sctp_sf_do_9_2_reshutack;
sctp_state_fn_t sctp_sf_eat_fwd_tsn;
sctp_state_fn_t sctp_sf_eat_fwd_tsn;
sctp_state_fn_t sctp_sf_eat_fwd_tsn_fast;
sctp_state_fn_t sctp_sf_eat_fwd_tsn_fast;
sctp_state_fn_t sctp_sf_eat_auth;


/* Prototypes for primitive event state functions.  */
/* Prototypes for primitive event state functions.  */
sctp_state_fn_t sctp_sf_do_prm_asoc;
sctp_state_fn_t sctp_sf_do_prm_asoc;
+8 −0
Original line number Original line Diff line number Diff line
@@ -724,6 +724,13 @@ struct sctp_chunk {
	 */
	 */
	struct sctp_transport *transport;
	struct sctp_transport *transport;


	/* SCTP-AUTH:  For the special case inbound processing of COOKIE-ECHO
	 * we need save a pointer to the AUTH chunk, since the SCTP-AUTH
	 * spec violates the principle premis that all chunks are processed
	 * in order.
	 */
	struct sk_buff *auth_chunk;

	__u8 rtt_in_progress;	/* Is this chunk used for RTT calculation? */
	__u8 rtt_in_progress;	/* Is this chunk used for RTT calculation? */
	__u8 resent;		/* Has this chunk ever been retransmitted. */
	__u8 resent;		/* Has this chunk ever been retransmitted. */
	__u8 has_tsn;		/* Does this chunk have a TSN yet? */
	__u8 has_tsn;		/* Does this chunk have a TSN yet? */
@@ -1067,6 +1074,7 @@ void sctp_inq_init(struct sctp_inq *);
void sctp_inq_free(struct sctp_inq *);
void sctp_inq_free(struct sctp_inq *);
void sctp_inq_push(struct sctp_inq *, struct sctp_chunk *packet);
void sctp_inq_push(struct sctp_inq *, struct sctp_chunk *packet);
struct sctp_chunk *sctp_inq_pop(struct sctp_inq *);
struct sctp_chunk *sctp_inq_pop(struct sctp_inq *);
struct sctp_chunkhdr *sctp_inq_peek(struct sctp_inq *);
void sctp_inq_set_th_handler(struct sctp_inq *, work_func_t);
void sctp_inq_set_th_handler(struct sctp_inq *, work_func_t);


/* This is the structure we use to hold outbound chunks.  You push
/* This is the structure we use to hold outbound chunks.  You push
+10 −0
Original line number Original line Diff line number Diff line
@@ -1011,6 +1011,16 @@ static void sctp_assoc_bh_rcv(struct work_struct *work)
		state = asoc->state;
		state = asoc->state;
		subtype = SCTP_ST_CHUNK(chunk->chunk_hdr->type);
		subtype = SCTP_ST_CHUNK(chunk->chunk_hdr->type);


		/* SCTP-AUTH, Section 6.3:
		 *    The receiver has a list of chunk types which it expects
		 *    to be received only after an AUTH-chunk.  This list has
		 *    been sent to the peer during the association setup.  It
		 *    MUST silently discard these chunks if they are not placed
		 *    after an AUTH chunk in the packet.
		 */
		if (sctp_auth_recv_cid(subtype.chunk, asoc) && !chunk->auth)
			continue;

		/* Remember where the last DATA chunk came from so we
		/* Remember where the last DATA chunk came from so we
		 * know where to send the SACK.
		 * know where to send the SACK.
		 */
		 */
+29 −0
Original line number Original line Diff line number Diff line
@@ -400,6 +400,7 @@ static void sctp_endpoint_bh_rcv(struct work_struct *work)
	sctp_subtype_t subtype;
	sctp_subtype_t subtype;
	sctp_state_t state;
	sctp_state_t state;
	int error = 0;
	int error = 0;
	int first_time = 1;	/* is this the first time through the looop */


	if (ep->base.dead)
	if (ep->base.dead)
		return;
		return;
@@ -411,6 +412,29 @@ static void sctp_endpoint_bh_rcv(struct work_struct *work)
	while (NULL != (chunk = sctp_inq_pop(inqueue))) {
	while (NULL != (chunk = sctp_inq_pop(inqueue))) {
		subtype = SCTP_ST_CHUNK(chunk->chunk_hdr->type);
		subtype = SCTP_ST_CHUNK(chunk->chunk_hdr->type);


		/* If the first chunk in the packet is AUTH, do special
		 * processing specified in Section 6.3 of SCTP-AUTH spec
		 */
		if (first_time && (subtype.chunk == SCTP_CID_AUTH)) {
			struct sctp_chunkhdr *next_hdr;

			next_hdr = sctp_inq_peek(inqueue);
			if (!next_hdr)
				goto normal;

			/* If the next chunk is COOKIE-ECHO, skip the AUTH
			 * chunk while saving a pointer to it so we can do
			 * Authentication later (during cookie-echo
			 * processing).
			 */
			if (next_hdr->type == SCTP_CID_COOKIE_ECHO) {
				chunk->auth_chunk = skb_clone(chunk->skb,
								GFP_ATOMIC);
				chunk->auth = 1;
				continue;
			}
		}
normal:
		/* We might have grown an association since last we
		/* We might have grown an association since last we
		 * looked, so try again.
		 * looked, so try again.
		 *
		 *
@@ -426,6 +450,8 @@ static void sctp_endpoint_bh_rcv(struct work_struct *work)
		}
		}


		state = asoc ? asoc->state : SCTP_STATE_CLOSED;
		state = asoc ? asoc->state : SCTP_STATE_CLOSED;
		if (sctp_auth_recv_cid(subtype.chunk, asoc) && !chunk->auth)
			continue;


		/* Remember where the last DATA chunk came from so we
		/* Remember where the last DATA chunk came from so we
		 * know where to send the SACK.
		 * know where to send the SACK.
@@ -449,5 +475,8 @@ static void sctp_endpoint_bh_rcv(struct work_struct *work)
		 */
		 */
		if (!sctp_sk(sk)->ep)
		if (!sctp_sk(sk)->ep)
			break;
			break;

		if (first_time)
			first_time = 0;
	}
	}
}
}
Loading