diff options
| author | Vlad Yasevich <vladislav.yasevich@hp.com> | 2007-09-16 22:31:35 -0400 |
|---|---|---|
| committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:51:30 -0400 |
| commit | a29a5bd4f5c3e8ba2e89688feab8b01c44f1654f (patch) | |
| tree | 2b98f0d572fee7dff79373c64f95a61f940db7e9 | |
| parent | 1f485649f52929d9937b346a920a522a7363e202 (diff) | |
[SCTP]: Implement SCTP-AUTH initializations.
The patch initializes AUTH related members of the generic SCTP
structures and provides a way to enable/disable auth extension.
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | net/sctp/associola.c | 34 | ||||
| -rw-r--r-- | net/sctp/endpointola.c | 83 | ||||
| -rw-r--r-- | net/sctp/output.c | 4 | ||||
| -rw-r--r-- | net/sctp/protocol.c | 3 | ||||
| -rw-r--r-- | net/sctp/sysctl.c | 9 |
5 files changed, 133 insertions, 0 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 9bad8ba0feda..ee4b212e66b1 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
| @@ -74,6 +74,8 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
| 74 | { | 74 | { |
| 75 | struct sctp_sock *sp; | 75 | struct sctp_sock *sp; |
| 76 | int i; | 76 | int i; |
| 77 | sctp_paramhdr_t *p; | ||
| 78 | int err; | ||
| 77 | 79 | ||
| 78 | /* Retrieve the SCTP per socket area. */ | 80 | /* Retrieve the SCTP per socket area. */ |
| 79 | sp = sctp_sk((struct sock *)sk); | 81 | sp = sctp_sk((struct sock *)sk); |
| @@ -298,6 +300,30 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
| 298 | asoc->default_timetolive = sp->default_timetolive; | 300 | asoc->default_timetolive = sp->default_timetolive; |
| 299 | asoc->default_rcv_context = sp->default_rcv_context; | 301 | asoc->default_rcv_context = sp->default_rcv_context; |
| 300 | 302 | ||
| 303 | /* AUTH related initializations */ | ||
| 304 | INIT_LIST_HEAD(&asoc->endpoint_shared_keys); | ||
| 305 | err = sctp_auth_asoc_copy_shkeys(ep, asoc, gfp); | ||
| 306 | if (err) | ||
| 307 | goto fail_init; | ||
| 308 | |||
| 309 | asoc->active_key_id = ep->active_key_id; | ||
| 310 | asoc->asoc_shared_key = NULL; | ||
| 311 | |||
| 312 | asoc->default_hmac_id = 0; | ||
| 313 | /* Save the hmacs and chunks list into this association */ | ||
| 314 | if (ep->auth_hmacs_list) | ||
| 315 | memcpy(asoc->c.auth_hmacs, ep->auth_hmacs_list, | ||
| 316 | ntohs(ep->auth_hmacs_list->param_hdr.length)); | ||
| 317 | if (ep->auth_chunk_list) | ||
| 318 | memcpy(asoc->c.auth_chunks, ep->auth_chunk_list, | ||
| 319 | ntohs(ep->auth_chunk_list->param_hdr.length)); | ||
| 320 | |||
| 321 | /* Get the AUTH random number for this association */ | ||
| 322 | p = (sctp_paramhdr_t *)asoc->c.auth_random; | ||
| 323 | p->type = SCTP_PARAM_RANDOM; | ||
| 324 | p->length = htons(sizeof(sctp_paramhdr_t) + SCTP_AUTH_RANDOM_LENGTH); | ||
| 325 | get_random_bytes(p+1, SCTP_AUTH_RANDOM_LENGTH); | ||
| 326 | |||
| 301 | return asoc; | 327 | return asoc; |
| 302 | 328 | ||
| 303 | fail_init: | 329 | fail_init: |
| @@ -407,6 +433,12 @@ void sctp_association_free(struct sctp_association *asoc) | |||
| 407 | if (asoc->addip_last_asconf) | 433 | if (asoc->addip_last_asconf) |
| 408 | sctp_chunk_free(asoc->addip_last_asconf); | 434 | sctp_chunk_free(asoc->addip_last_asconf); |
| 409 | 435 | ||
| 436 | /* AUTH - Free the endpoint shared keys */ | ||
| 437 | sctp_auth_destroy_keys(&asoc->endpoint_shared_keys); | ||
| 438 | |||
| 439 | /* AUTH - Free the association shared key */ | ||
| 440 | sctp_auth_key_put(asoc->asoc_shared_key); | ||
| 441 | |||
| 410 | sctp_association_put(asoc); | 442 | sctp_association_put(asoc); |
| 411 | } | 443 | } |
| 412 | 444 | ||
| @@ -1112,6 +1144,8 @@ void sctp_assoc_update(struct sctp_association *asoc, | |||
| 1112 | sctp_assoc_set_id(asoc, GFP_ATOMIC); | 1144 | sctp_assoc_set_id(asoc, GFP_ATOMIC); |
| 1113 | } | 1145 | } |
| 1114 | } | 1146 | } |
| 1147 | |||
| 1148 | /* SCTP-AUTH: XXX something needs to be done here*/ | ||
| 1115 | } | 1149 | } |
| 1116 | 1150 | ||
| 1117 | /* Update the retran path for sending a retransmitted packet. | 1151 | /* Update the retran path for sending a retransmitted packet. |
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index 22371185efb6..c8d5023606a5 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c | |||
| @@ -69,12 +69,56 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, | |||
| 69 | struct sock *sk, | 69 | struct sock *sk, |
| 70 | gfp_t gfp) | 70 | gfp_t gfp) |
| 71 | { | 71 | { |
| 72 | struct sctp_hmac_algo_param *auth_hmacs = NULL; | ||
| 73 | struct sctp_chunks_param *auth_chunks = NULL; | ||
| 74 | struct sctp_shared_key *null_key; | ||
| 75 | int err; | ||
| 76 | |||
| 72 | memset(ep, 0, sizeof(struct sctp_endpoint)); | 77 | memset(ep, 0, sizeof(struct sctp_endpoint)); |
| 73 | 78 | ||
| 74 | ep->digest = kzalloc(SCTP_SIGNATURE_SIZE, gfp); | 79 | ep->digest = kzalloc(SCTP_SIGNATURE_SIZE, gfp); |
| 75 | if (!ep->digest) | 80 | if (!ep->digest) |
| 76 | return NULL; | 81 | return NULL; |
| 77 | 82 | ||
| 83 | if (sctp_auth_enable) { | ||
| 84 | /* Allocate space for HMACS and CHUNKS authentication | ||
| 85 | * variables. There are arrays that we encode directly | ||
| 86 | * into parameters to make the rest of the operations easier. | ||
| 87 | */ | ||
| 88 | auth_hmacs = kzalloc(sizeof(sctp_hmac_algo_param_t) + | ||
| 89 | sizeof(__u16) * SCTP_AUTH_NUM_HMACS, gfp); | ||
| 90 | if (!auth_hmacs) | ||
| 91 | goto nomem; | ||
| 92 | |||
| 93 | auth_chunks = kzalloc(sizeof(sctp_chunks_param_t) + | ||
| 94 | SCTP_NUM_CHUNK_TYPES, gfp); | ||
| 95 | if (!auth_chunks) | ||
| 96 | goto nomem; | ||
| 97 | |||
| 98 | /* Initialize the HMACS parameter. | ||
| 99 | * SCTP-AUTH: Section 3.3 | ||
| 100 | * Every endpoint supporting SCTP chunk authentication MUST | ||
| 101 | * support the HMAC based on the SHA-1 algorithm. | ||
| 102 | */ | ||
| 103 | auth_hmacs->param_hdr.type = SCTP_PARAM_HMAC_ALGO; | ||
| 104 | auth_hmacs->param_hdr.length = | ||
| 105 | htons(sizeof(sctp_paramhdr_t) + 2); | ||
| 106 | auth_hmacs->hmac_ids[0] = htons(SCTP_AUTH_HMAC_ID_SHA1); | ||
| 107 | |||
| 108 | /* Initialize the CHUNKS parameter */ | ||
| 109 | auth_chunks->param_hdr.type = SCTP_PARAM_CHUNKS; | ||
| 110 | |||
| 111 | /* If the Add-IP functionality is enabled, we must | ||
| 112 | * authenticate, ASCONF and ASCONF-ACK chunks | ||
| 113 | */ | ||
| 114 | if (sctp_addip_enable) { | ||
| 115 | auth_chunks->chunks[0] = SCTP_CID_ASCONF; | ||
| 116 | auth_chunks->chunks[1] = SCTP_CID_ASCONF_ACK; | ||
| 117 | auth_chunks->param_hdr.length = | ||
| 118 | htons(sizeof(sctp_paramhdr_t) + 2); | ||
| 119 | } | ||
| 120 | } | ||
| 121 | |||
| 78 | /* Initialize the base structure. */ | 122 | /* Initialize the base structure. */ |
| 79 | /* What type of endpoint are we? */ | 123 | /* What type of endpoint are we? */ |
| 80 | ep->base.type = SCTP_EP_TYPE_SOCKET; | 124 | ep->base.type = SCTP_EP_TYPE_SOCKET; |
| @@ -114,7 +158,36 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, | |||
| 114 | ep->last_key = ep->current_key = 0; | 158 | ep->last_key = ep->current_key = 0; |
| 115 | ep->key_changed_at = jiffies; | 159 | ep->key_changed_at = jiffies; |
| 116 | 160 | ||
| 161 | /* SCTP-AUTH extensions*/ | ||
| 162 | INIT_LIST_HEAD(&ep->endpoint_shared_keys); | ||
| 163 | null_key = sctp_auth_shkey_create(0, GFP_KERNEL); | ||
| 164 | if (!null_key) | ||
| 165 | goto nomem; | ||
| 166 | |||
| 167 | list_add(&null_key->key_list, &ep->endpoint_shared_keys); | ||
| 168 | |||
| 169 | /* Allocate and initialize transorms arrays for suported HMACs. */ | ||
| 170 | err = sctp_auth_init_hmacs(ep, gfp); | ||
| 171 | if (err) | ||
| 172 | goto nomem_hmacs; | ||
| 173 | |||
| 174 | /* Add the null key to the endpoint shared keys list and | ||
| 175 | * set the hmcas and chunks pointers. | ||
| 176 | */ | ||
| 177 | ep->auth_hmacs_list = auth_hmacs; | ||
| 178 | ep->auth_chunk_list = auth_chunks; | ||
| 179 | |||
| 117 | return ep; | 180 | return ep; |
| 181 | |||
| 182 | nomem_hmacs: | ||
| 183 | sctp_auth_destroy_keys(&ep->endpoint_shared_keys); | ||
| 184 | nomem: | ||
| 185 | /* Free all allocations */ | ||
| 186 | kfree(auth_hmacs); | ||
| 187 | kfree(auth_chunks); | ||
| 188 | kfree(ep->digest); | ||
| 189 | return NULL; | ||
| 190 | |||
| 118 | } | 191 | } |
| 119 | 192 | ||
| 120 | /* Create a sctp_endpoint with all that boring stuff initialized. | 193 | /* Create a sctp_endpoint with all that boring stuff initialized. |
| @@ -187,6 +260,16 @@ static void sctp_endpoint_destroy(struct sctp_endpoint *ep) | |||
| 187 | /* Free the digest buffer */ | 260 | /* Free the digest buffer */ |
| 188 | kfree(ep->digest); | 261 | kfree(ep->digest); |
| 189 | 262 | ||
| 263 | /* SCTP-AUTH: Free up AUTH releated data such as shared keys | ||
| 264 | * chunks and hmacs arrays that were allocated | ||
| 265 | */ | ||
| 266 | sctp_auth_destroy_keys(&ep->endpoint_shared_keys); | ||
| 267 | kfree(ep->auth_hmacs_list); | ||
| 268 | kfree(ep->auth_chunk_list); | ||
| 269 | |||
| 270 | /* AUTH - Free any allocated HMAC transform containers */ | ||
| 271 | sctp_auth_destroy_hmacs(ep->auth_hmacs); | ||
| 272 | |||
| 190 | /* Cleanup. */ | 273 | /* Cleanup. */ |
| 191 | sctp_inq_free(&ep->base.inqueue); | 274 | sctp_inq_free(&ep->base.inqueue); |
| 192 | sctp_bind_addr_free(&ep->base.bind_addr); | 275 | sctp_bind_addr_free(&ep->base.bind_addr); |
diff --git a/net/sctp/output.c b/net/sctp/output.c index d85543def754..49b9f5f031a4 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
| @@ -79,7 +79,9 @@ struct sctp_packet *sctp_packet_config(struct sctp_packet *packet, | |||
| 79 | packet->vtag = vtag; | 79 | packet->vtag = vtag; |
| 80 | packet->has_cookie_echo = 0; | 80 | packet->has_cookie_echo = 0; |
| 81 | packet->has_sack = 0; | 81 | packet->has_sack = 0; |
| 82 | packet->has_auth = 0; | ||
| 82 | packet->ipfragok = 0; | 83 | packet->ipfragok = 0; |
| 84 | packet->auth = NULL; | ||
| 83 | 85 | ||
| 84 | if (ecn_capable && sctp_packet_empty(packet)) { | 86 | if (ecn_capable && sctp_packet_empty(packet)) { |
| 85 | chunk = sctp_get_ecne_prepend(packet->transport->asoc); | 87 | chunk = sctp_get_ecne_prepend(packet->transport->asoc); |
| @@ -121,8 +123,10 @@ struct sctp_packet *sctp_packet_init(struct sctp_packet *packet, | |||
| 121 | packet->vtag = 0; | 123 | packet->vtag = 0; |
| 122 | packet->has_cookie_echo = 0; | 124 | packet->has_cookie_echo = 0; |
| 123 | packet->has_sack = 0; | 125 | packet->has_sack = 0; |
| 126 | packet->has_auth = 0; | ||
| 124 | packet->ipfragok = 0; | 127 | packet->ipfragok = 0; |
| 125 | packet->malloced = 0; | 128 | packet->malloced = 0; |
| 129 | packet->auth = NULL; | ||
| 126 | return packet; | 130 | return packet; |
| 127 | } | 131 | } |
| 128 | 132 | ||
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 3ec8b12b6da4..4e6b59e8b695 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
| @@ -1185,6 +1185,9 @@ SCTP_STATIC __init int sctp_init(void) | |||
| 1185 | /* Enable PR-SCTP by default. */ | 1185 | /* Enable PR-SCTP by default. */ |
| 1186 | sctp_prsctp_enable = 1; | 1186 | sctp_prsctp_enable = 1; |
| 1187 | 1187 | ||
| 1188 | /* Disable AUTH by default. */ | ||
| 1189 | sctp_auth_enable = 0; | ||
| 1190 | |||
| 1188 | sctp_sysctl_register(); | 1191 | sctp_sysctl_register(); |
| 1189 | 1192 | ||
| 1190 | INIT_LIST_HEAD(&sctp_address_families); | 1193 | INIT_LIST_HEAD(&sctp_address_families); |
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 39b10ee2f017..0669778e4335 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c | |||
| @@ -254,6 +254,15 @@ static ctl_table sctp_table[] = { | |||
| 254 | .mode = 0644, | 254 | .mode = 0644, |
| 255 | .proc_handler = &proc_dointvec, | 255 | .proc_handler = &proc_dointvec, |
| 256 | }, | 256 | }, |
| 257 | { | ||
| 258 | .ctl_name = CTL_UNNUMBERED, | ||
| 259 | .procname = "auth_enable", | ||
| 260 | .data = &sctp_auth_enable, | ||
| 261 | .maxlen = sizeof(int), | ||
| 262 | .mode = 0644, | ||
| 263 | .proc_handler = &proc_dointvec, | ||
| 264 | .strategy = &sysctl_intvec | ||
| 265 | }, | ||
| 257 | { .ctl_name = 0 } | 266 | { .ctl_name = 0 } |
| 258 | }; | 267 | }; |
| 259 | 268 | ||
