📄 target_negotiate.c
字号:
retval = -1; goto out; } inputpdu->text_length = be32_to_cpu(inputpdu->length); if (inputpdu->text_length > 0) { padding = (-inputpdu->text_length) & 3; if (inputpdu->text_length < MAX_TEXT_LEN) { if (iscsi_recv_msg(sock, inputpdu->text_length + padding, inputpdu->text, conn->connection_flags) < 0) { TRACE(TRACE_DEBUG, "iscsi_recv_msg failed\n"); retval = -1; goto out; } } else { TRACE_ERROR ("DSL %u greater than default MaxRecvDataSegmentLength %d\n", inputpdu->text_length, MAX_TEXT_LEN); retval = -1; goto out; } } /* exit now if what we just read should not be in security stage */ if (security_step == ss_leave) goto out; if (target_check_login(conn, p_param_tbl, inputpdu, outputpdu, when_called, noperational, login_flags, &count, unknown_key_list) < 0) { TRACE_ERROR("check login failed\n"); retval = -1; goto out; } TRACE(TRACE_ISCSI_FULL, "Target switch on security_step %d\n", security_step); switch (security_step) { case ss_initial: /* looking to find AuthMethod=CHAP */ if (no_security_key_allowed(conn, outputpdu, *unknown_key_list)) goto out; check_authmethod(auth_p, outputpdu, &security_step); break; case ss_find_chap_a: /* looking to find CHAP_A */ for (key = *(key_prev = unknown_key_list); key != NULL; key = key_next) { key_next = key->next; if (!(got_bitmask = print_bad_security_key(key))) { key_prev = &key->next; } else { /* have a security key, is it allowed in this step? */ if (got_bitmask == GOT_CHAP_A) { if (check_step_key(key, &neg_flags, GOT_CHAP_A) || (chap_a = CHAP_SelectAlgorithm(key->keyvalue)) <= 0) { TRACE_ERROR("unable to select algorithm\n"); retval = -1; login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_ERR, outputpdu); goto out; } TRACE(TRACE_ISCSI, "algorithm selected is %d\n", chap_a); CHAP_SetAlgorithm(chap_a, auth_param.chap_local_ctx); CHAP_SetAlgorithm(chap_a, auth_param.chap_peer_ctx); security_step = ss_find_chap_n_r; } else { print_not_allowed_security_key(key); retval = -1; login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_ERR, outputpdu); goto out; } /* now delete this key from the list */ my_kfree((void **) &key->keyvalue, "Key Value"); my_kfree((void **) &key->keyname, "Key Name"); my_kfree((void **) &key, "Unknown key"); *key_prev = key_next; } } if (neg_flags == GOT_CHAP_A) { attach_key_int(outputpdu, CHAP_A, chap_a); /* generate id number and challenge string to send to him */ chap_i = CHAP_GetIdentifier(auth_param.chap_local_ctx); attach_key_int(outputpdu, CHAP_I, chap_i); chap_c = CHAP_GetChallenge(auth_param.chap_local_ctx); if (chap_c == NULL) { TRACE_ERROR("CHAP exchange failed\n"); goto out; } attach_key_string(outputpdu, CHAP_C, chap_c); /* done with printable string version of our challenge */ my_kfree((void **) &chap_c, "CHAP Challenge"); } break; case ss_find_chap_n_r: /* looking for CHAP_N, CHAP_R and maybe CHAP_I and CHAP_C */ for (key = *(key_prev = unknown_key_list); key != NULL; key = key_next) { key_next = key->next; if (!(got_bitmask = print_bad_security_key(key))) { key_prev = &key->next; } else { /* have a security key, is it allowed in this step? */ if (got_bitmask == GOT_CHAP_N) { if (check_step_key(key, &neg_flags, GOT_CHAP_N) || auth_param.chap_local_ctx->name == NULL || strcmp(key->keyvalue, auth_param.chap_local_ctx->name)) { TRACE_ERROR("security authentication failed\n"); retval = -1; login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_NOT_AUTH, outputpdu); goto out; } } else if (got_bitmask == GOT_CHAP_R) { if (check_step_key(key, &neg_flags, GOT_CHAP_R) || ((chap_r = my_kmalloc(strlen(key->keyvalue) + 1, "CHAP Response"))) == NULL) { retval = -1; login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_NOT_AUTH, outputpdu); goto out; } strcpy(chap_r, key->keyvalue); } else if (got_bitmask == GOT_CHAP_I) { if (check_step_key_number(key, &neg_flags, GOT_CHAP_I, 255, &value)) { retval = -1; login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_ERR, outputpdu); goto out; } chap_i = value; } else if (got_bitmask == GOT_CHAP_C) { if (check_step_key(key, &neg_flags, GOT_CHAP_C) || (chap_c = my_kmalloc(strlen(key->keyvalue) + 1, "CHAP Challenge")) == NULL) { retval = -1; login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_NOT_AUTH, outputpdu); goto out; } strcpy(chap_c, key->keyvalue); } else { print_not_allowed_security_key(key); retval = -1; login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_ERR, outputpdu); goto out; } /* now delete this key from the list */ my_kfree((void **) &key->keyvalue, "Key Value"); my_kfree((void **) &key->keyname, "Key Name"); my_kfree((void **) &key, "Unknown key"); *key_prev = key_next; } } if ((neg_flags & (GOT_CHAP_A | GOT_CHAP_N | GOT_CHAP_R)) == (GOT_CHAP_A | GOT_CHAP_N | GOT_CHAP_R)) { /* got both CHAP_N and CHAP_R, check response */ if (CHAP_CheckResponse(chap_r, MAX_CHAP_BINARY_LENGTH, auth_param.chap_local_ctx) <= 0) { TRACE_ERROR("security authentication failed\n"); retval = -1; login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_NOT_AUTH, outputpdu); goto out; } /* finished with his response to our challenge */ my_kfree((void **) &chap_r, "CHAP Response"); } if (neg_flags == (GOT_CHAP_A | GOT_CHAP_N | GOT_CHAP_R | GOT_CHAP_I | GOT_CHAP_C)) { /* got both CHAP_I and CHAP_C from initiator */ if (!CHAP_CheckChallenge(chap_c, auth_param.chap_local_ctx)) { TRACE_ERROR("CHAP_C from Initiator duplicates one " "previously generated by target\n"); retval = -1; login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_NOT_AUTH, outputpdu); goto out; } if ((chap_r = CHAP_GetResponse(chap_i, chap_c, MAX_CHAP_BINARY_LENGTH, auth_param.chap_peer_ctx)) == NULL) { TRACE_ERROR("CHAP_R to Initiator cannot be generated\n"); retval = -1; login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_ERR, outputpdu); goto out; } if ((chap_n = CHAP_GetName(auth_param.chap_peer_ctx)) == NULL) { TRACE_ERROR("CHAP_N to Initiator not configured\n"); retval = -1; login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_ERR, outputpdu); goto out; } attach_key_string(outputpdu, CHAP_N, chap_n); /* finished with our name to him */ my_kfree((void **) &chap_n, "CHAP Get Name"); attach_key_string(outputpdu, CHAP_R, chap_r); if (outputpdu->flags & T_BIT) security_step = ss_leave; else security_step = ss_done; } else { if (outputpdu->flags & T_BIT) security_step = ss_leave; else security_step = ss_find_chap_i_c; } break; case ss_find_srp_u: /* looking for SRP_U and TargetAuth */ for (key = *(key_prev = unknown_key_list); key != NULL; key = key_next) { key_next = key->next; if (!(got_bitmask = print_bad_security_key(key))) { key_prev = &key->next; } else { /* have a security key, is it allowed in this step? */ if (got_bitmask == GOT_SRP_U) { if (check_step_key(key, &neg_flags, GOT_SRP_U) || !(srp_u = SRP_Initiator_GetUsername(auth_param. srp_ctx))) { TRACE_ERROR("unable to set SRP user name\n"); retval = -1; login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_NOT_AUTH, outputpdu); goto out; } if (strcmp(srp_u, key->keyvalue)) { TRACE_ERROR("got SRP user name %s, expected %s\n", key->keyvalue, srp_u); retval = -1; login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_NOT_AUTH, outputpdu); goto out; } } else if (got_bitmask == GOT_SRP_TARGETAUTH) { if (check_step_key(key, &neg_flags, GOT_SRP_TARGETAUTH)) { retval = -1; login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_NOT_AUTH, outputpdu); goto out; } if (!strcmp(key->keyvalue, YES)) target_auth = 1; else if (!strcmp(key->keyvalue, NO)) target_auth = 0; else { TRACE_ERROR("illegal value in %s=%s\n", key->keyname, key->keyvalue); } } else { print_not_allowed_security_key(key); retval = -1; login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_ERR, outputpdu); goto out; } /* now delete this key from the list */ my_kfree((void **) &key->keyvalue, "Key Value"); my_kfree((void **) &key->keyname, "Key Name"); my_kfree((void **) &key, "Unknown key"); *key_prev = key_next; } } if ((neg_flags & (GOT_SRP_U | GOT_SRP_TARGETAUTH)) == (GOT_SRP_U | GOT_SRP_TARGETAUTH)) { /* got both SRP_U and SRP_TargetAuth, * time to send SRP_GROUP and SRP_s */ if (!(srp_grouplist = SRP_Target_GetGroupList(auth_param.srp_ctx))) { TRACE_ERROR("unable to get SRP Group list\n"); retval = -1; login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_ERR, outputpdu); goto out; } attach_key_string(outputpdu, SRP_GROUP, srp_grouplist); if (!(srp_s = SRP_Target_GetSalt(auth_param.srp_ctx))) { TRACE_ERROR("unable to get SRP salt\n"); retval = -1; login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_ERR, outputpdu); goto out; } attach_key_string(outputpdu, SRP_S, srp_s); security_step = ss_find_srp_a_g; } break; case ss_find_srp_a_g: /* looking for SRP_A and SRP_GROUP */ for (key = *(key_prev = unknown_key_list); key != NULL; key = key_next) { key_next = key->next; if (!(got_bitmask = print_bad_security_key(key))) { key_prev = &key->next; } else { /* have a security key, is it allowed in this step? */ if (got_bitmask == GOT_SRP_A) { if (check_step_key(key, &neg_flags, GOT_SRP_A) || !SRP_Target_SetA(key->keyvalue, MAX_SRP_BINARY_LENGTH, auth_param.srp_ctx)) { TRACE_ERROR("unable to set SRP_A\n"); retval = -1; login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_NOT_AUTH, outputpdu); goto out; } } else if (got_bitmask == GOT_SRP_GROUP) { if (check_step_key(key, &neg_flags, GOT_SRP_GROUP) || !SRP_SetSRPGroup(key->keyvalue, auth_param.srp_ctx)) { TRACE_ERROR("unable to set SRP group %s\n", key->keyvalue); retval = -1; login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_NOT_AUTH, outputpdu); goto out; } } else { print_not_allowed_security_key(key); retval = -1; login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_ERR, outputpdu); goto out; } /* now delete this key from the list */ my_kfree((void **) &key->keyvalue, "Key Value"); my_kfree((void **) &key->keyname, "Key Name"); my_kfree((void **) &key, "Unknown key"); *key_prev = key_next; } } if ((neg_flags & (GOT_SRP_A | GOT_SRP_GROUP)) == (GOT_SRP_A | GOT_SRP_GROUP)) { /* got both SRP_A and SRP_GROUP, time to send SRP_B */ if (!(srp_b = SRP_Target_GetB(auth_param.srp_ctx))) { TRACE_ERROR("unable to get SRP_B\n"); retval = -1; login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_ERR, outputpdu); goto out; } attach_key_string(outputpdu, SRP_B, srp_b); security_step = ss_find_srp_m; } break; case ss_find_srp_m: /* looking for SRP_M */ for (key = *(key_prev = unknown_key_list); key != NULL; key = key_next) { key_next = key->next; if (!(got_bitmask = print_bad_security_key(key))) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -