aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/sm_make_chunk.c
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2007-09-16 22:32:11 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:51:30 -0400
commit730fc3d05cd4ba4c9ce2de91f3d43349e95dbbf5 (patch)
tree50a59c6592a7546f9d54364f26dc2a03f5f18345 /net/sctp/sm_make_chunk.c
parenta29a5bd4f5c3e8ba2e89688feab8b01c44f1654f (diff)
[SCTP]: Implete SCTP-AUTH parameter processing
Implement processing for the CHUNKS, RANDOM, and HMAC parameters and deal with how this parameters are effected by association restarts. In particular, during unexpeted INIT processing, we need to reply with parameters from the original INIT chunk. Also, after restart, we need to update the old association with new peer parameters and change the association shared keys. Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/sm_make_chunk.c')
-rw-r--r--net/sctp/sm_make_chunk.c162
1 files changed, 159 insertions, 3 deletions
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 71cc204a9ea5..4c02875786ac 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -182,6 +182,8 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
182 sctp_supported_ext_param_t ext_param; 182 sctp_supported_ext_param_t ext_param;
183 int num_ext = 0; 183 int num_ext = 0;
184 __u8 extensions[3]; 184 __u8 extensions[3];
185 sctp_paramhdr_t *auth_chunks = NULL,
186 *auth_hmacs = NULL;
185 187
186 /* RFC 2960 3.3.2 Initiation (INIT) (1) 188 /* RFC 2960 3.3.2 Initiation (INIT) (1)
187 * 189 *
@@ -214,8 +216,6 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
214 * An implementation supporting this extension [ADDIP] MUST list 216 * An implementation supporting this extension [ADDIP] MUST list
215 * the ASCONF,the ASCONF-ACK, and the AUTH chunks in its INIT and 217 * the ASCONF,the ASCONF-ACK, and the AUTH chunks in its INIT and
216 * INIT-ACK parameters. 218 * INIT-ACK parameters.
217 * XXX: We don't support AUTH just yet, so don't list it. AUTH
218 * support should add it.
219 */ 219 */
220 if (sctp_addip_enable) { 220 if (sctp_addip_enable) {
221 extensions[num_ext] = SCTP_CID_ASCONF; 221 extensions[num_ext] = SCTP_CID_ASCONF;
@@ -226,6 +226,29 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
226 chunksize += sizeof(aiparam); 226 chunksize += sizeof(aiparam);
227 chunksize += vparam_len; 227 chunksize += vparam_len;
228 228
229 /* Account for AUTH related parameters */
230 if (sctp_auth_enable) {
231 /* Add random parameter length*/
232 chunksize += sizeof(asoc->c.auth_random);
233
234 /* Add HMACS parameter length if any were defined */
235 auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs;
236 if (auth_hmacs->length)
237 chunksize += ntohs(auth_hmacs->length);
238 else
239 auth_hmacs = NULL;
240
241 /* Add CHUNKS parameter length */
242 auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks;
243 if (auth_chunks->length)
244 chunksize += ntohs(auth_chunks->length);
245 else
246 auth_hmacs = NULL;
247
248 extensions[num_ext] = SCTP_CID_AUTH;
249 num_ext += 1;
250 }
251
229 /* If we have any extensions to report, account for that */ 252 /* If we have any extensions to report, account for that */
230 if (num_ext) 253 if (num_ext)
231 chunksize += sizeof(sctp_supported_ext_param_t) + num_ext; 254 chunksize += sizeof(sctp_supported_ext_param_t) + num_ext;
@@ -285,6 +308,17 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
285 aiparam.adaptation_ind = htonl(sp->adaptation_ind); 308 aiparam.adaptation_ind = htonl(sp->adaptation_ind);
286 sctp_addto_chunk(retval, sizeof(aiparam), &aiparam); 309 sctp_addto_chunk(retval, sizeof(aiparam), &aiparam);
287 310
311 /* Add SCTP-AUTH chunks to the parameter list */
312 if (sctp_auth_enable) {
313 sctp_addto_chunk(retval, sizeof(asoc->c.auth_random),
314 asoc->c.auth_random);
315 if (auth_hmacs)
316 sctp_addto_chunk(retval, ntohs(auth_hmacs->length),
317 auth_hmacs);
318 if (auth_chunks)
319 sctp_addto_chunk(retval, ntohs(auth_chunks->length),
320 auth_chunks);
321 }
288nodata: 322nodata:
289 kfree(addrs.v); 323 kfree(addrs.v);
290 return retval; 324 return retval;
@@ -305,6 +339,9 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
305 sctp_supported_ext_param_t ext_param; 339 sctp_supported_ext_param_t ext_param;
306 int num_ext = 0; 340 int num_ext = 0;
307 __u8 extensions[3]; 341 __u8 extensions[3];
342 sctp_paramhdr_t *auth_chunks = NULL,
343 *auth_hmacs = NULL,
344 *auth_random = NULL;
308 345
309 retval = NULL; 346 retval = NULL;
310 347
@@ -350,6 +387,26 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
350 chunksize += sizeof(ext_param) + num_ext; 387 chunksize += sizeof(ext_param) + num_ext;
351 chunksize += sizeof(aiparam); 388 chunksize += sizeof(aiparam);
352 389
390 if (asoc->peer.auth_capable) {
391 auth_random = (sctp_paramhdr_t *)asoc->c.auth_random;
392 chunksize += ntohs(auth_random->length);
393
394 auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs;
395 if (auth_hmacs->length)
396 chunksize += ntohs(auth_hmacs->length);
397 else
398 auth_hmacs = NULL;
399
400 auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks;
401 if (auth_chunks->length)
402 chunksize += ntohs(auth_chunks->length);
403 else
404 auth_chunks = NULL;
405
406 extensions[num_ext] = SCTP_CID_AUTH;
407 num_ext += 1;
408 }
409
353 /* Now allocate and fill out the chunk. */ 410 /* Now allocate and fill out the chunk. */
354 retval = sctp_make_chunk(asoc, SCTP_CID_INIT_ACK, 0, chunksize); 411 retval = sctp_make_chunk(asoc, SCTP_CID_INIT_ACK, 0, chunksize);
355 if (!retval) 412 if (!retval)
@@ -381,6 +438,17 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
381 aiparam.adaptation_ind = htonl(sctp_sk(asoc->base.sk)->adaptation_ind); 438 aiparam.adaptation_ind = htonl(sctp_sk(asoc->base.sk)->adaptation_ind);
382 sctp_addto_chunk(retval, sizeof(aiparam), &aiparam); 439 sctp_addto_chunk(retval, sizeof(aiparam), &aiparam);
383 440
441 if (asoc->peer.auth_capable) {
442 sctp_addto_chunk(retval, ntohs(auth_random->length),
443 auth_random);
444 if (auth_hmacs)
445 sctp_addto_chunk(retval, ntohs(auth_hmacs->length),
446 auth_hmacs);
447 if (auth_chunks)
448 sctp_addto_chunk(retval, ntohs(auth_chunks->length),
449 auth_chunks);
450 }
451
384 /* We need to remove the const qualifier at this point. */ 452 /* We need to remove the const qualifier at this point. */
385 retval->asoc = (struct sctp_association *) asoc; 453 retval->asoc = (struct sctp_association *) asoc;
386 454
@@ -1736,6 +1804,12 @@ static void sctp_process_ext_param(struct sctp_association *asoc,
1736 !asoc->peer.prsctp_capable) 1804 !asoc->peer.prsctp_capable)
1737 asoc->peer.prsctp_capable = 1; 1805 asoc->peer.prsctp_capable = 1;
1738 break; 1806 break;
1807 case SCTP_CID_AUTH:
1808 /* if the peer reports AUTH, assume that he
1809 * supports AUTH.
1810 */
1811 asoc->peer.auth_capable = 1;
1812 break;
1739 case SCTP_CID_ASCONF: 1813 case SCTP_CID_ASCONF:
1740 case SCTP_CID_ASCONF_ACK: 1814 case SCTP_CID_ASCONF_ACK:
1741 /* don't need to do anything for ASCONF */ 1815 /* don't need to do anything for ASCONF */
@@ -1871,7 +1945,42 @@ static int sctp_verify_param(const struct sctp_association *asoc,
1871 case SCTP_PARAM_FWD_TSN_SUPPORT: 1945 case SCTP_PARAM_FWD_TSN_SUPPORT:
1872 if (sctp_prsctp_enable) 1946 if (sctp_prsctp_enable)
1873 break; 1947 break;
1948 goto fallthrough;
1949
1950 case SCTP_PARAM_RANDOM:
1951 if (!sctp_auth_enable)
1952 goto fallthrough;
1953
1954 /* SCTP-AUTH: Secion 6.1
1955 * If the random number is not 32 byte long the association
1956 * MUST be aborted. The ABORT chunk SHOULD contain the error
1957 * cause 'Protocol Violation'.
1958 */
1959 if (SCTP_AUTH_RANDOM_LENGTH !=
1960 ntohs(param.p->length) - sizeof(sctp_paramhdr_t))
1961 return sctp_process_inv_paramlength(asoc, param.p,
1962 chunk, err_chunk);
1963 break;
1964
1965 case SCTP_PARAM_CHUNKS:
1966 if (!sctp_auth_enable)
1967 goto fallthrough;
1968
1969 /* SCTP-AUTH: Section 3.2
1970 * The CHUNKS parameter MUST be included once in the INIT or
1971 * INIT-ACK chunk if the sender wants to receive authenticated
1972 * chunks. Its maximum length is 260 bytes.
1973 */
1974 if (260 < ntohs(param.p->length))
1975 return sctp_process_inv_paramlength(asoc, param.p,
1976 chunk, err_chunk);
1977 break;
1978
1979 case SCTP_PARAM_HMAC_ALGO:
1980 if (!sctp_auth_enable)
1981 break;
1874 /* Fall Through */ 1982 /* Fall Through */
1983fallthrough:
1875 default: 1984 default:
1876 SCTP_DEBUG_PRINTK("Unrecognized param: %d for chunk %d.\n", 1985 SCTP_DEBUG_PRINTK("Unrecognized param: %d for chunk %d.\n",
1877 ntohs(param.p->type), cid); 1986 ntohs(param.p->type), cid);
@@ -1976,13 +2085,19 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
1976 } 2085 }
1977 2086
1978 /* Process the initialization parameters. */ 2087 /* Process the initialization parameters. */
1979
1980 sctp_walk_params(param, peer_init, init_hdr.params) { 2088 sctp_walk_params(param, peer_init, init_hdr.params) {
1981 2089
1982 if (!sctp_process_param(asoc, param, peer_addr, gfp)) 2090 if (!sctp_process_param(asoc, param, peer_addr, gfp))
1983 goto clean_up; 2091 goto clean_up;
1984 } 2092 }
1985 2093
2094 /* AUTH: After processing the parameters, make sure that we
2095 * have all the required info to potentially do authentications.
2096 */
2097 if (asoc->peer.auth_capable && (!asoc->peer.peer_random ||
2098 !asoc->peer.peer_hmacs))
2099 asoc->peer.auth_capable = 0;
2100
1986 /* Walk list of transports, removing transports in the UNKNOWN state. */ 2101 /* Walk list of transports, removing transports in the UNKNOWN state. */
1987 list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { 2102 list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
1988 transport = list_entry(pos, struct sctp_transport, transports); 2103 transport = list_entry(pos, struct sctp_transport, transports);
@@ -2222,6 +2337,47 @@ static int sctp_process_param(struct sctp_association *asoc,
2222 break; 2337 break;
2223 } 2338 }
2224 /* Fall Through */ 2339 /* Fall Through */
2340 goto fall_through;
2341
2342 case SCTP_PARAM_RANDOM:
2343 if (!sctp_auth_enable)
2344 goto fall_through;
2345
2346 /* Save peer's random parameter */
2347 asoc->peer.peer_random = kmemdup(param.p,
2348 ntohs(param.p->length), gfp);
2349 if (!asoc->peer.peer_random) {
2350 retval = 0;
2351 break;
2352 }
2353 break;
2354
2355 case SCTP_PARAM_HMAC_ALGO:
2356 if (!sctp_auth_enable)
2357 goto fall_through;
2358
2359 /* Save peer's HMAC list */
2360 asoc->peer.peer_hmacs = kmemdup(param.p,
2361 ntohs(param.p->length), gfp);
2362 if (!asoc->peer.peer_hmacs) {
2363 retval = 0;
2364 break;
2365 }
2366
2367 /* Set the default HMAC the peer requested*/
2368 sctp_auth_asoc_set_default_hmac(asoc, param.hmac_algo);
2369 break;
2370
2371 case SCTP_PARAM_CHUNKS:
2372 if (!sctp_auth_enable)
2373 goto fall_through;
2374
2375 asoc->peer.peer_chunks = kmemdup(param.p,
2376 ntohs(param.p->length), gfp);
2377 if (!asoc->peer.peer_chunks)
2378 retval = 0;
2379 break;
2380fall_through:
2225 default: 2381 default:
2226 /* Any unrecognized parameters should have been caught 2382 /* Any unrecognized parameters should have been caught
2227 * and handled by sctp_verify_param() which should be 2383 * and handled by sctp_verify_param() which should be