Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 66622
b: refs/heads/master
c: 65b07e5
h: refs/heads/master
v: v3
  • Loading branch information
Vlad Yasevich authored and David S. Miller committed Oct 10, 2007
1 parent 57e7fbb commit 904db11
Show file tree
Hide file tree
Showing 8 changed files with 658 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bbd0d59809f923ea2b540cbd781b32110e249f6e
refs/heads/master: 65b07e5d0d09c77e98050b5f0146ead29e5add32
16 changes: 16 additions & 0 deletions trunk/include/net/sctp/auth.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
struct sctp_endpoint;
struct sctp_association;
struct sctp_authkey;
struct sctp_hmacalgo;

/*
* Define a generic struct that will hold all the info
Expand Down Expand Up @@ -109,4 +110,19 @@ int sctp_auth_recv_cid(sctp_cid_t chunk, const struct sctp_association *asoc);
void sctp_auth_calculate_hmac(const struct sctp_association *asoc,
struct sk_buff *skb,
struct sctp_auth_chunk *auth, gfp_t gfp);

/* API Helpers */
int sctp_auth_ep_add_chunkid(struct sctp_endpoint *ep, __u8 chunk_id);
int sctp_auth_ep_set_hmacs(struct sctp_endpoint *ep,
struct sctp_hmacalgo *hmacs);
int sctp_auth_set_key(struct sctp_endpoint *ep,
struct sctp_association *asoc,
struct sctp_authkey *auth_key);
int sctp_auth_set_active_key(struct sctp_endpoint *ep,
struct sctp_association *asoc,
__u16 key_id);
int sctp_auth_del_key_id(struct sctp_endpoint *ep,
struct sctp_association *asoc,
__u16 key_id);

#endif
4 changes: 4 additions & 0 deletions trunk/include/net/sctp/ulpevent.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc,
struct sctp_chunk *chunk,
gfp_t gfp);

struct sctp_ulpevent *sctp_ulpevent_make_authkey(
const struct sctp_association *asoc, __u16 key_id,
__u32 indication, gfp_t gfp);

void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event,
struct msghdr *);
__u16 sctp_ulpevent_get_notification_type(const struct sctp_ulpevent *event);
Expand Down
90 changes: 90 additions & 0 deletions trunk/include/net/sctp/user.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,21 @@ enum sctp_optname {
#define SCTP_PARTIAL_DELIVERY_POINT SCTP_PARTIAL_DELIVERY_POINT
SCTP_MAX_BURST, /* Set/Get max burst */
#define SCTP_MAX_BURST SCTP_MAX_BURST
SCTP_AUTH_CHUNK, /* Set only: add a chunk type to authenticat */
#define SCTP_AUTH_CHUNK SCTP_AUTH_CHUNK
SCTP_HMAC_IDENT,
#define SCTP_HMAC_IDENT SCTP_HMAC_IDENT
SCTP_AUTH_KEY,
#define SCTP_AUTH_KEY SCTP_AUTH_KEY
SCTP_AUTH_ACTIVE_KEY,
#define SCTP_AUTH_ACTIVE_KEY SCTP_AUTH_ACTIVE_KEY
SCTP_AUTH_DELETE_KEY,
#define SCTP_AUTH_DELETE_KEY SCTP_AUTH_DELETE_KEY
SCTP_PEER_AUTH_CHUNKS, /* Read only */
#define SCTP_PEER_AUTH_CHUNKS SCTP_PEER_AUTH_CHUNKS
SCTP_LOCAL_AUTH_CHUNKS, /* Read only */
#define SCTP_LOCAL_AUTH_CHUNKS SCTP_LOCAL_AUTH_CHUNKS


/* Internal Socket Options. Some of the sctp library functions are
* implemented using these socket options.
Expand Down Expand Up @@ -370,6 +385,19 @@ struct sctp_pdapi_event {

enum { SCTP_PARTIAL_DELIVERY_ABORTED=0, };

struct sctp_authkey_event {
__u16 auth_type;
__u16 auth_flags;
__u32 auth_length;
__u16 auth_keynumber;
__u16 auth_altkeynumber;
__u32 auth_indication;
sctp_assoc_t auth_assoc_id;
};

enum { SCTP_AUTH_NEWKEY = 0, };


/*
* Described in Section 7.3
* Ancillary Data and Notification Interest Options
Expand Down Expand Up @@ -405,6 +433,7 @@ union sctp_notification {
struct sctp_shutdown_event sn_shutdown_event;
struct sctp_adaptation_event sn_adaptation_event;
struct sctp_pdapi_event sn_pdapi_event;
struct sctp_authkey_event sn_authkey_event;
};

/* Section 5.3.1
Expand All @@ -421,6 +450,7 @@ enum sctp_sn_type {
SCTP_SHUTDOWN_EVENT,
SCTP_PARTIAL_DELIVERY_EVENT,
SCTP_ADAPTATION_INDICATION,
SCTP_AUTHENTICATION_EVENT,
};

/* Notification error codes used to fill up the error fields in some
Expand Down Expand Up @@ -539,6 +569,54 @@ struct sctp_paddrparams {
__u32 spp_flags;
} __attribute__((packed, aligned(4)));

/*
* 7.1.18. Add a chunk that must be authenticated (SCTP_AUTH_CHUNK)
*
* This set option adds a chunk type that the user is requesting to be
* received only in an authenticated way. Changes to the list of chunks
* will only effect future associations on the socket.
*/
struct sctp_authchunk {
__u8 sauth_chunk;
};

/*
* 7.1.19. Get or set the list of supported HMAC Identifiers (SCTP_HMAC_IDENT)
*
* This option gets or sets the list of HMAC algorithms that the local
* endpoint requires the peer to use.
*/
struct sctp_hmacalgo {
__u16 shmac_num_idents;
__u16 shmac_idents[];
};

/*
* 7.1.20. Set a shared key (SCTP_AUTH_KEY)
*
* This option will set a shared secret key which is used to build an
* association shared key.
*/
struct sctp_authkey {
sctp_assoc_t sca_assoc_id;
__u16 sca_keynumber;
__u16 sca_keylen;
__u8 sca_key[];
};

/*
* 7.1.21. Get or set the active shared key (SCTP_AUTH_ACTIVE_KEY)
*
* This option will get or set the active shared key to be used to build
* the association shared key.
*/

struct sctp_authkeyid {
sctp_assoc_t scact_assoc_id;
__u16 scact_keynumber;
};


/* 7.1.23. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME)
*
* This options will get or set the delayed ack timer. The time is set
Expand Down Expand Up @@ -607,6 +685,18 @@ struct sctp_status {
struct sctp_paddrinfo sstat_primary;
};

/*
* 7.2.3. Get the list of chunks the peer requires to be authenticated
* (SCTP_PEER_AUTH_CHUNKS)
*
* This option gets a list of chunks for a specified association that
* the peer requires to be received authenticated only.
*/
struct sctp_authchunks {
sctp_assoc_t gauth_assoc_id;
uint8_t gauth_chunks[];
};

/*
* 8.3, 8.5 get all peer/local addresses in an association.
* This parameter struct is used by SCTP_GET_PEER_ADDRS and
Expand Down
193 changes: 193 additions & 0 deletions trunk/net/sctp/auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -743,3 +743,196 @@ void sctp_auth_calculate_hmac(const struct sctp_association *asoc,
if (free_key)
sctp_auth_key_put(asoc_key);
}

/* API Helpers */

/* Add a chunk to the endpoint authenticated chunk list */
int sctp_auth_ep_add_chunkid(struct sctp_endpoint *ep, __u8 chunk_id)
{
struct sctp_chunks_param *p = ep->auth_chunk_list;
__u16 nchunks;
__u16 param_len;

/* If this chunk is already specified, we are done */
if (__sctp_auth_cid(chunk_id, p))
return 0;

/* Check if we can add this chunk to the array */
param_len = ntohs(p->param_hdr.length);
nchunks = param_len - sizeof(sctp_paramhdr_t);
if (nchunks == SCTP_NUM_CHUNK_TYPES)
return -EINVAL;

p->chunks[nchunks] = chunk_id;
p->param_hdr.length = htons(param_len + 1);
return 0;
}

/* Add hmac identifires to the endpoint list of supported hmac ids */
int sctp_auth_ep_set_hmacs(struct sctp_endpoint *ep,
struct sctp_hmacalgo *hmacs)
{
int has_sha1 = 0;
__u16 id;
int i;

/* Scan the list looking for unsupported id. Also make sure that
* SHA1 is specified.
*/
for (i = 0; i < hmacs->shmac_num_idents; i++) {
id = hmacs->shmac_idents[i];

if (SCTP_AUTH_HMAC_ID_SHA1 == id)
has_sha1 = 1;

if (!sctp_hmac_list[id].hmac_name)
return -EOPNOTSUPP;
}

if (!has_sha1)
return -EINVAL;

memcpy(ep->auth_hmacs_list->hmac_ids, &hmacs->shmac_idents[0],
hmacs->shmac_num_idents * sizeof(__u16));
ep->auth_hmacs_list->param_hdr.length = htons(sizeof(sctp_paramhdr_t) +
hmacs->shmac_num_idents * sizeof(__u16));
return 0;
}

/* Set a new shared key on either endpoint or association. If the
* the key with a same ID already exists, replace the key (remove the
* old key and add a new one).
*/
int sctp_auth_set_key(struct sctp_endpoint *ep,
struct sctp_association *asoc,
struct sctp_authkey *auth_key)
{
struct sctp_shared_key *cur_key = NULL;
struct sctp_auth_bytes *key;
struct list_head *sh_keys;
int replace = 0;

/* Try to find the given key id to see if
* we are doing a replace, or adding a new key
*/
if (asoc)
sh_keys = &asoc->endpoint_shared_keys;
else
sh_keys = &ep->endpoint_shared_keys;

key_for_each(cur_key, sh_keys) {
if (cur_key->key_id == auth_key->sca_keynumber) {
replace = 1;
break;
}
}

/* If we are not replacing a key id, we need to allocate
* a shared key.
*/
if (!replace) {
cur_key = sctp_auth_shkey_create(auth_key->sca_keynumber,
GFP_KERNEL);
if (!cur_key)
return -ENOMEM;
}

/* Create a new key data based on the info passed in */
key = sctp_auth_create_key(auth_key->sca_keylen, GFP_KERNEL);
if (!key)
goto nomem;

memcpy(key->data, &auth_key->sca_key[0], auth_key->sca_keylen);

/* If we are replacing, remove the old keys data from the
* key id. If we are adding new key id, add it to the
* list.
*/
if (replace)
sctp_auth_key_put(cur_key->key);
else
list_add(&cur_key->key_list, sh_keys);

cur_key->key = key;
sctp_auth_key_hold(key);

return 0;
nomem:
if (!replace)
sctp_auth_shkey_free(cur_key);

return -ENOMEM;
}

int sctp_auth_set_active_key(struct sctp_endpoint *ep,
struct sctp_association *asoc,
__u16 key_id)
{
struct sctp_shared_key *key;
struct list_head *sh_keys;
int found = 0;

/* The key identifier MUST correst to an existing key */
if (asoc)
sh_keys = &asoc->endpoint_shared_keys;
else
sh_keys = &ep->endpoint_shared_keys;

key_for_each(key, sh_keys) {
if (key->key_id == key_id) {
found = 1;
break;
}
}

if (!found)
return -EINVAL;

if (asoc) {
asoc->active_key_id = key_id;
sctp_auth_asoc_init_active_key(asoc, GFP_KERNEL);
} else
ep->active_key_id = key_id;

return 0;
}

int sctp_auth_del_key_id(struct sctp_endpoint *ep,
struct sctp_association *asoc,
__u16 key_id)
{
struct sctp_shared_key *key;
struct list_head *sh_keys;
int found = 0;

/* The key identifier MUST NOT be the current active key
* The key identifier MUST correst to an existing key
*/
if (asoc) {
if (asoc->active_key_id == key_id)
return -EINVAL;

sh_keys = &asoc->endpoint_shared_keys;
} else {
if (ep->active_key_id == key_id)
return -EINVAL;

sh_keys = &ep->endpoint_shared_keys;
}

key_for_each(key, sh_keys) {
if (key->key_id == key_id) {
found = 1;
break;
}
}

if (!found)
return -EINVAL;

/* Delete the shared key */
list_del_init(&key->key_list);
sctp_auth_shkey_free(key);

return 0;
}
13 changes: 13 additions & 0 deletions trunk/net/sctp/sm_statefuns.c
Original file line number Diff line number Diff line change
Expand Up @@ -3848,6 +3848,19 @@ sctp_disposition_t sctp_sf_eat_auth(const struct sctp_endpoint *ep,
break;
}

if (asoc->active_key_id != ntohs(auth_hdr->shkey_id)) {
struct sctp_ulpevent *ev;

ev = sctp_ulpevent_make_authkey(asoc, ntohs(auth_hdr->shkey_id),
SCTP_AUTH_NEWKEY, GFP_ATOMIC);

if (!ev)
return -ENOMEM;

sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
SCTP_ULPEVENT(ev));
}

return SCTP_DISPOSITION_CONSUME;
}

Expand Down
Loading

0 comments on commit 904db11

Please sign in to comment.