diff options
| -rw-r--r-- | include/net/sctp/command.h | 1 | ||||
| -rw-r--r-- | net/sctp/associola.c | 21 | ||||
| -rw-r--r-- | net/sctp/sm_make_chunk.c | 162 | ||||
| -rw-r--r-- | net/sctp/sm_sideeffect.c | 5 | ||||
| -rw-r--r-- | net/sctp/sm_statefuns.c | 35 |
5 files changed, 220 insertions, 4 deletions
diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h index f56c8d695a82..b8733364557f 100644 --- a/include/net/sctp/command.h +++ b/include/net/sctp/command.h | |||
| @@ -102,6 +102,7 @@ typedef enum { | |||
| 102 | SCTP_CMD_SET_SK_ERR, /* Set sk_err */ | 102 | SCTP_CMD_SET_SK_ERR, /* Set sk_err */ |
| 103 | SCTP_CMD_ASSOC_CHANGE, /* generate and send assoc_change event */ | 103 | SCTP_CMD_ASSOC_CHANGE, /* generate and send assoc_change event */ |
| 104 | SCTP_CMD_ADAPTATION_IND, /* generate and send adaptation event */ | 104 | SCTP_CMD_ADAPTATION_IND, /* generate and send adaptation event */ |
| 105 | SCTP_CMD_ASSOC_SHKEY, /* generate the association shared keys */ | ||
| 105 | SCTP_CMD_LAST | 106 | SCTP_CMD_LAST |
| 106 | } sctp_verb_t; | 107 | } sctp_verb_t; |
| 107 | 108 | ||
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index ee4b212e66b1..3bdd8dcb76a7 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
| @@ -415,6 +415,9 @@ void sctp_association_free(struct sctp_association *asoc) | |||
| 415 | 415 | ||
| 416 | /* Free peer's cached cookie. */ | 416 | /* Free peer's cached cookie. */ |
| 417 | kfree(asoc->peer.cookie); | 417 | kfree(asoc->peer.cookie); |
| 418 | kfree(asoc->peer.peer_random); | ||
| 419 | kfree(asoc->peer.peer_chunks); | ||
| 420 | kfree(asoc->peer.peer_hmacs); | ||
| 418 | 421 | ||
| 419 | /* Release the transport structures. */ | 422 | /* Release the transport structures. */ |
| 420 | list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { | 423 | list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { |
| @@ -1145,7 +1148,23 @@ void sctp_assoc_update(struct sctp_association *asoc, | |||
| 1145 | } | 1148 | } |
| 1146 | } | 1149 | } |
| 1147 | 1150 | ||
| 1148 | /* SCTP-AUTH: XXX something needs to be done here*/ | 1151 | /* SCTP-AUTH: Save the peer parameters from the new assocaitions |
| 1152 | * and also move the association shared keys over | ||
| 1153 | */ | ||
| 1154 | kfree(asoc->peer.peer_random); | ||
| 1155 | asoc->peer.peer_random = new->peer.peer_random; | ||
| 1156 | new->peer.peer_random = NULL; | ||
| 1157 | |||
| 1158 | kfree(asoc->peer.peer_chunks); | ||
| 1159 | asoc->peer.peer_chunks = new->peer.peer_chunks; | ||
| 1160 | new->peer.peer_chunks = NULL; | ||
| 1161 | |||
| 1162 | kfree(asoc->peer.peer_hmacs); | ||
| 1163 | asoc->peer.peer_hmacs = new->peer.peer_hmacs; | ||
| 1164 | new->peer.peer_hmacs = NULL; | ||
| 1165 | |||
| 1166 | sctp_auth_key_put(asoc->asoc_shared_key); | ||
| 1167 | sctp_auth_asoc_init_active_key(asoc, GFP_ATOMIC); | ||
| 1149 | } | 1168 | } |
| 1150 | 1169 | ||
| 1151 | /* Update the retran path for sending a retransmitted packet. | 1170 | /* Update the retran path for sending a retransmitted packet. |
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 | } | ||
| 288 | nodata: | 322 | nodata: |
| 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 */ |
| 1983 | fallthrough: | ||
| 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; | ||
| 2380 | fall_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 |
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 8d7890083493..bbdc938da86f 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
| @@ -1524,6 +1524,11 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
| 1524 | sctp_cmd_adaptation_ind(commands, asoc); | 1524 | sctp_cmd_adaptation_ind(commands, asoc); |
| 1525 | break; | 1525 | break; |
| 1526 | 1526 | ||
| 1527 | case SCTP_CMD_ASSOC_SHKEY: | ||
| 1528 | error = sctp_auth_asoc_init_active_key(asoc, | ||
| 1529 | GFP_ATOMIC); | ||
| 1530 | break; | ||
| 1531 | |||
| 1527 | default: | 1532 | default: |
| 1528 | printk(KERN_WARNING "Impossible command: %u, %p\n", | 1533 | printk(KERN_WARNING "Impossible command: %u, %p\n", |
| 1529 | cmd->verb, cmd->obj.ptr); | 1534 | cmd->verb, cmd->obj.ptr); |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index ec0328b1cdb1..385486360fe9 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
| @@ -549,6 +549,11 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep, | |||
| 549 | sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, | 549 | sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, |
| 550 | SCTP_STATE(SCTP_STATE_COOKIE_ECHOED)); | 550 | SCTP_STATE(SCTP_STATE_COOKIE_ECHOED)); |
| 551 | 551 | ||
| 552 | /* SCTP-AUTH: genereate the assocition shared keys so that | ||
| 553 | * we can potentially signe the COOKIE-ECHO. | ||
| 554 | */ | ||
| 555 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_SHKEY, SCTP_NULL()); | ||
| 556 | |||
| 552 | /* 5.1 C) "A" shall then send the State Cookie received in the | 557 | /* 5.1 C) "A" shall then send the State Cookie received in the |
| 553 | * INIT ACK chunk in a COOKIE ECHO chunk, ... | 558 | * INIT ACK chunk in a COOKIE ECHO chunk, ... |
| 554 | */ | 559 | */ |
| @@ -686,6 +691,14 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep, | |||
| 686 | peer_init, GFP_ATOMIC)) | 691 | peer_init, GFP_ATOMIC)) |
| 687 | goto nomem_init; | 692 | goto nomem_init; |
| 688 | 693 | ||
| 694 | /* SCTP-AUTH: Now that we've populate required fields in | ||
| 695 | * sctp_process_init, set up the assocaition shared keys as | ||
| 696 | * necessary so that we can potentially authenticate the ACK | ||
| 697 | */ | ||
| 698 | error = sctp_auth_asoc_init_active_key(new_asoc, GFP_ATOMIC); | ||
| 699 | if (error) | ||
| 700 | goto nomem_init; | ||
| 701 | |||
| 689 | repl = sctp_make_cookie_ack(new_asoc, chunk); | 702 | repl = sctp_make_cookie_ack(new_asoc, chunk); |
| 690 | if (!repl) | 703 | if (!repl) |
| 691 | goto nomem_init; | 704 | goto nomem_init; |
| @@ -1247,6 +1260,26 @@ static void sctp_tietags_populate(struct sctp_association *new_asoc, | |||
| 1247 | new_asoc->c.initial_tsn = asoc->c.initial_tsn; | 1260 | new_asoc->c.initial_tsn = asoc->c.initial_tsn; |
| 1248 | } | 1261 | } |
| 1249 | 1262 | ||
| 1263 | static void sctp_auth_params_populate(struct sctp_association *new_asoc, | ||
| 1264 | const struct sctp_association *asoc) | ||
| 1265 | { | ||
| 1266 | /* Only perform this if AUTH extension is enabled */ | ||
| 1267 | if (!sctp_auth_enable) | ||
| 1268 | return; | ||
| 1269 | |||
| 1270 | /* We need to provide the same parameter information as | ||
| 1271 | * was in the original INIT. This means that we need to copy | ||
| 1272 | * the HMACS, CHUNKS, and RANDOM parameter from the original | ||
| 1273 | * assocaition. | ||
| 1274 | */ | ||
| 1275 | memcpy(new_asoc->c.auth_random, asoc->c.auth_random, | ||
| 1276 | sizeof(asoc->c.auth_random)); | ||
| 1277 | memcpy(new_asoc->c.auth_hmacs, asoc->c.auth_hmacs, | ||
| 1278 | sizeof(asoc->c.auth_hmacs)); | ||
| 1279 | memcpy(new_asoc->c.auth_chunks, asoc->c.auth_chunks, | ||
| 1280 | sizeof(asoc->c.auth_chunks)); | ||
| 1281 | } | ||
| 1282 | |||
| 1250 | /* | 1283 | /* |
| 1251 | * Compare vtag/tietag values to determine unexpected COOKIE-ECHO | 1284 | * Compare vtag/tietag values to determine unexpected COOKIE-ECHO |
| 1252 | * handling action. | 1285 | * handling action. |
| @@ -1404,6 +1437,8 @@ static sctp_disposition_t sctp_sf_do_unexpected_init( | |||
| 1404 | 1437 | ||
| 1405 | sctp_tietags_populate(new_asoc, asoc); | 1438 | sctp_tietags_populate(new_asoc, asoc); |
| 1406 | 1439 | ||
| 1440 | sctp_auth_params_populate(new_asoc, asoc); | ||
| 1441 | |||
| 1407 | /* B) "Z" shall respond immediately with an INIT ACK chunk. */ | 1442 | /* B) "Z" shall respond immediately with an INIT ACK chunk. */ |
| 1408 | 1443 | ||
| 1409 | /* If there are errors need to be reported for unknown parameters, | 1444 | /* If there are errors need to be reported for unknown parameters, |
