1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <sys/cpuvar.h> 27 #include <sys/types.h> 28 #include <sys/conf.h> 29 #include <sys/file.h> 30 #include <sys/ddi.h> 31 #include <sys/sunddi.h> 32 #include <sys/modctl.h> 33 34 #include <sys/socket.h> 35 #include <sys/strsubr.h> 36 #include <sys/sysmacros.h> 37 #include <sys/note.h> 38 #include <sys/sdt.h> 39 40 #include <sys/stmf.h> 41 #include <sys/stmf_ioctl.h> 42 #include <sys/portif.h> 43 #include <sys/idm/idm.h> 44 #include <sys/idm/idm_text.h> 45 46 #define ISCSIT_LOGIN_SM_STRINGS 47 #include <iscsit.h> 48 #include <iscsit_auth.h> 49 50 typedef struct { 51 list_node_t le_ctx_node; 52 iscsit_login_event_t le_ctx_event; 53 idm_pdu_t *le_pdu; 54 } login_event_ctx_t; 55 56 #ifndef TRUE 57 #define TRUE B_TRUE 58 #endif 59 60 #ifndef FALSE 61 #define FALSE B_FALSE 62 #endif 63 64 #define DEFAULT_RADIUS_PORT 1812 65 66 static void 67 login_sm_complete(void *ict_void); 68 69 static void 70 login_sm_event_dispatch(iscsit_conn_login_t *lsm, iscsit_conn_t *ict, 71 login_event_ctx_t *ctx); 72 73 static void 74 login_sm_init(iscsit_conn_t *ict, login_event_ctx_t *ctx); 75 76 static void 77 login_sm_waiting(iscsit_conn_t *ict, login_event_ctx_t *ctx); 78 79 static void 80 login_sm_processing(iscsit_conn_t *ict, login_event_ctx_t *ctx); 81 82 static void 83 login_sm_responding(iscsit_conn_t *ict, login_event_ctx_t *ctx); 84 85 static void 86 login_sm_responded(iscsit_conn_t *ict, login_event_ctx_t *ctx); 87 88 static void 89 login_sm_ffp(iscsit_conn_t *ict, login_event_ctx_t *ctx); 90 91 static void 92 login_sm_done(iscsit_conn_t *ict, login_event_ctx_t *ctx); 93 94 static void 95 login_sm_error(iscsit_conn_t *ict, login_event_ctx_t *ctx); 96 97 static void 98 login_sm_new_state(iscsit_conn_t *ict, login_event_ctx_t *ctx, 99 iscsit_login_state_t new_state); 100 101 static void 102 login_sm_send_ack(iscsit_conn_t *ict, idm_pdu_t *pdu); 103 104 static idm_status_t 105 login_sm_validate_ack(iscsit_conn_t *ict, idm_pdu_t *pdu); 106 107 static boolean_t 108 login_sm_is_last_response(idm_pdu_t *pdu); 109 110 static void 111 login_sm_handle_initial_login(iscsit_conn_t *ict, idm_pdu_t *pdu); 112 113 static void 114 login_sm_send_next_response(iscsit_conn_t *ict, idm_pdu_t *pdu); 115 116 static void 117 login_sm_process_request(iscsit_conn_t *ict); 118 119 static idm_status_t 120 login_sm_req_pdu_check(iscsit_conn_t *ict, idm_pdu_t *pdu); 121 122 static idm_status_t 123 login_sm_process_nvlist(iscsit_conn_t *ict); 124 125 static idm_status_t 126 login_sm_check_security(iscsit_conn_t *ict); 127 128 static idm_pdu_t * 129 login_sm_build_login_response(iscsit_conn_t *ict); 130 131 static void 132 login_sm_ffp_actions(iscsit_conn_t *ict); 133 134 static idm_status_t 135 login_sm_validate_initial_parameters(iscsit_conn_t *ict); 136 137 static idm_status_t 138 login_sm_session_bind(iscsit_conn_t *ict); 139 140 static idm_status_t 141 login_sm_set_auth(iscsit_conn_t *ict); 142 143 static idm_status_t 144 login_sm_session_register(iscsit_conn_t *ict); 145 146 static kv_status_t 147 iscsit_handle_key(iscsit_conn_t *ict, nvpair_t *nvp, char *nvp_name); 148 149 static kv_status_t 150 iscsit_handle_common_key(iscsit_conn_t *ict, nvpair_t *nvp, 151 const idm_kv_xlate_t *ikvx); 152 153 static kv_status_t 154 iscsit_handle_security_key(iscsit_conn_t *ict, nvpair_t *nvp, 155 const idm_kv_xlate_t *ikvx); 156 157 static kv_status_t 158 iscsit_reply_security_key(iscsit_conn_t *ict); 159 160 static kv_status_t 161 iscsit_handle_operational_key(iscsit_conn_t *ict, nvpair_t *nvp, 162 const idm_kv_xlate_t *ikvx); 163 164 static kv_status_t 165 iscsit_reply_numerical(iscsit_conn_t *ict, 166 const char *nvp_name, const uint64_t value); 167 168 static kv_status_t 169 iscsit_reply_string(iscsit_conn_t *ict, 170 const char *nvp_name, const char *text); 171 172 static kv_status_t 173 iscsit_handle_digest(iscsit_conn_t *ict, nvpair_t *choices, 174 const idm_kv_xlate_t *ikvx); 175 176 static kv_status_t 177 iscsit_handle_boolean(iscsit_conn_t *ict, nvpair_t *nvp, boolean_t value, 178 const idm_kv_xlate_t *ikvx, boolean_t iscsit_value); 179 180 static kv_status_t 181 iscsit_handle_numerical(iscsit_conn_t *ict, nvpair_t *nvp, uint64_t value, 182 const idm_kv_xlate_t *ikvx, 183 uint64_t iscsi_min_value, uint64_t iscsi_max_value, 184 uint64_t iscsit_max_value); 185 186 static void 187 iscsit_process_negotiated_values(iscsit_conn_t *ict); 188 189 static void 190 login_resp_complete_cb(idm_pdu_t *pdu, idm_status_t status); 191 192 idm_status_t 193 iscsit_login_sm_init(iscsit_conn_t *ict) 194 { 195 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 196 197 bzero(lsm, sizeof (iscsit_conn_login_t)); 198 199 (void) nvlist_alloc(&lsm->icl_negotiated_values, NV_UNIQUE_NAME, 200 KM_SLEEP); 201 202 /* 203 * Hold connection until the login state machine completes 204 */ 205 iscsit_conn_hold(ict); 206 207 /* 208 * Pre-allocating a login response PDU means we will always be 209 * able to respond to a login request -- even if we can't allocate 210 * a data buffer to hold the text responses we can at least send 211 * a login failure. 212 */ 213 lsm->icl_login_resp_tmpl = kmem_zalloc(sizeof (iscsi_login_rsp_hdr_t), 214 KM_SLEEP); 215 216 idm_sm_audit_init(&lsm->icl_state_audit); 217 mutex_init(&lsm->icl_mutex, NULL, MUTEX_DEFAULT, NULL); 218 list_create(&lsm->icl_login_events, sizeof (login_event_ctx_t), 219 offsetof(login_event_ctx_t, le_ctx_node)); 220 list_create(&lsm->icl_pdu_list, sizeof (idm_pdu_t), 221 offsetof(idm_pdu_t, isp_client_lnd)); 222 223 lsm->icl_login_state = ILS_LOGIN_INIT; 224 lsm->icl_login_last_state = ILS_LOGIN_INIT; 225 226 /* 227 * Initialize operational parameters to default values. Anything 228 * we don't specifically negotiate stays at the default. 229 */ 230 ict->ict_op.op_discovery_session = B_FALSE; 231 ict->ict_op.op_initial_r2t = ISCSI_DEFAULT_INITIALR2T; 232 ict->ict_op.op_immed_data = ISCSI_DEFAULT_IMMEDIATE_DATA; 233 ict->ict_op.op_data_pdu_in_order = ISCSI_DEFAULT_DATA_PDU_IN_ORDER; 234 ict->ict_op.op_data_sequence_in_order = 235 ISCSI_DEFAULT_DATA_SEQUENCE_IN_ORDER; 236 ict->ict_op.op_max_connections = ISCSI_DEFAULT_MAX_CONNECTIONS; 237 ict->ict_op.op_max_recv_data_segment_length = 238 ISCSI_DEFAULT_MAX_RECV_SEG_LEN; 239 ict->ict_op.op_max_burst_length = ISCSI_DEFAULT_MAX_BURST_LENGTH; 240 ict->ict_op.op_first_burst_length = ISCSI_DEFAULT_FIRST_BURST_LENGTH; 241 ict->ict_op.op_default_time_2_wait = ISCSI_DEFAULT_TIME_TO_WAIT; 242 ict->ict_op.op_default_time_2_retain = ISCSI_DEFAULT_TIME_TO_RETAIN; 243 ict->ict_op.op_max_outstanding_r2t = ISCSI_DEFAULT_MAX_OUT_R2T; 244 ict->ict_op.op_error_recovery_level = 245 ISCSI_DEFAULT_ERROR_RECOVERY_LEVEL; 246 247 return (IDM_STATUS_SUCCESS); 248 } 249 250 static void 251 login_resp_complete_cb(idm_pdu_t *pdu, idm_status_t status) 252 { 253 iscsit_conn_t *ict = pdu->isp_private; 254 255 /* 256 * Check that this is a login pdu 257 */ 258 ASSERT((pdu->isp_flags & IDM_PDU_LOGIN_TX) != 0); 259 idm_pdu_free(pdu); 260 261 if ((status != IDM_STATUS_SUCCESS) || 262 (ict->ict_login_sm.icl_login_resp_err_class != 0)) { 263 /* 264 * Transport or login error occurred. 265 */ 266 iscsit_login_sm_event(ict, ILE_LOGIN_ERROR, NULL); 267 } 268 iscsit_conn_rele(ict); 269 } 270 271 void 272 iscsit_login_sm_fini(iscsit_conn_t *ict) 273 { 274 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 275 276 mutex_enter(&lsm->icl_mutex); 277 list_destroy(&lsm->icl_pdu_list); 278 list_destroy(&lsm->icl_login_events); 279 280 kmem_free(lsm->icl_login_resp_tmpl, sizeof (iscsi_login_rsp_hdr_t)); 281 282 /* clean up the login response idm text buffer */ 283 if (lsm->icl_login_resp_itb != NULL) { 284 idm_itextbuf_free(lsm->icl_login_resp_itb); 285 lsm->icl_login_resp_itb = NULL; 286 } 287 288 nvlist_free(lsm->icl_negotiated_values); 289 mutex_destroy(&lsm->icl_mutex); 290 } 291 292 void 293 iscsit_login_sm_event(iscsit_conn_t *ict, iscsit_login_event_t event, 294 idm_pdu_t *pdu) 295 { 296 /* 297 * This is a bit ugly but if we're already in ILS_LOGIN_ERROR 298 * or ILS_LOGIN_DONE then just drop any additional events. They 299 * won't change the state and it's possible we've already called 300 * iscsit_login_sm_fini in which case the mutex is destroyed. 301 */ 302 if ((ict->ict_login_sm.icl_login_state == ILS_LOGIN_ERROR) || 303 (ict->ict_login_sm.icl_login_state == ILS_LOGIN_DONE)) 304 return; 305 306 mutex_enter(&ict->ict_login_sm.icl_mutex); 307 iscsit_login_sm_event_locked(ict, event, pdu); 308 mutex_exit(&ict->ict_login_sm.icl_mutex); 309 } 310 void 311 iscsit_login_sm_event_locked(iscsit_conn_t *ict, iscsit_login_event_t event, 312 idm_pdu_t *pdu) 313 { 314 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 315 login_event_ctx_t *ctx; 316 317 ASSERT(mutex_owned(&lsm->icl_mutex)); 318 ctx = kmem_zalloc(sizeof (*ctx), KM_SLEEP); 319 320 ctx->le_ctx_event = event; 321 ctx->le_pdu = pdu; 322 323 list_insert_tail(&lsm->icl_login_events, ctx); 324 325 /* 326 * Use the icl_busy flag to keep the state machine single threaded. 327 * This also serves as recursion avoidance since this flag will 328 * always be set if we call login_sm_event from within the 329 * state machine code. 330 */ 331 if (!lsm->icl_busy) { 332 lsm->icl_busy = B_TRUE; 333 while (!list_is_empty(&lsm->icl_login_events)) { 334 ctx = list_head(&lsm->icl_login_events); 335 list_remove(&lsm->icl_login_events, ctx); 336 idm_sm_audit_event(&lsm->icl_state_audit, 337 SAS_ISCSIT_LOGIN, (int)lsm->icl_login_state, 338 (int)ctx->le_ctx_event, (uintptr_t)pdu); 339 340 /* 341 * If the lsm is in a terminal state, just drain 342 * any remaining events. 343 */ 344 if ((lsm->icl_login_state == ILS_LOGIN_ERROR) || 345 (lsm->icl_login_state == ILS_LOGIN_DONE)) { 346 kmem_free(ctx, sizeof (*ctx)); 347 continue; 348 } 349 mutex_exit(&lsm->icl_mutex); 350 login_sm_event_dispatch(lsm, ict, ctx); 351 mutex_enter(&lsm->icl_mutex); 352 } 353 lsm->icl_busy = B_FALSE; 354 355 /* 356 * When the state machine reaches ILS_LOGIN_DONE or 357 * ILS_LOGIN_ERROR state the login process has completed 358 * and it's time to cleanup. The state machine code will 359 * mark itself "complete" when this happens. 360 * 361 * To protect against spurious events (which shouldn't 362 * happen) set icl_busy again. 363 */ 364 if (lsm->icl_login_complete) { 365 lsm->icl_busy = B_TRUE; 366 if (taskq_dispatch(iscsit_global.global_dispatch_taskq, 367 login_sm_complete, ict, DDI_SLEEP) == NULL) { 368 cmn_err(CE_WARN, "iscsit_login_sm_event_locked:" 369 " Failed to dispatch task"); 370 } 371 } 372 } 373 } 374 375 static void 376 login_sm_complete(void *ict_void) 377 { 378 iscsit_conn_t *ict = ict_void; 379 380 /* 381 * State machine has run to completion, resources 382 * will be cleaned up when connection is destroyed. 383 */ 384 iscsit_conn_rele(ict); 385 } 386 387 static void 388 login_sm_event_dispatch(iscsit_conn_login_t *lsm, iscsit_conn_t *ict, 389 login_event_ctx_t *ctx) 390 { 391 idm_pdu_t *pdu = ctx->le_pdu; /* Only valid for some events */ 392 393 DTRACE_PROBE2(login__event, iscsit_conn_t *, ict, 394 login_event_ctx_t *, ctx); 395 396 IDM_SM_LOG(CE_NOTE, "login_sm_event_dispatch: ict %p event %s(%d)", 397 (void *)ict, 398 iscsit_ile_name[ctx->le_ctx_event], ctx->le_ctx_event); 399 400 /* State independent actions */ 401 switch (ctx->le_ctx_event) { 402 case ILE_LOGIN_RCV: 403 /* Perform basic sanity checks on the header */ 404 if (login_sm_req_pdu_check(ict, pdu) != IDM_STATUS_SUCCESS) { 405 idm_pdu_t *rpdu; 406 407 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_INITIATOR_ERR, 408 ISCSI_LOGIN_STATUS_INVALID_REQUEST); 409 /* 410 * If we haven't processed any PDU's yet then use 411 * this one as a template for the response 412 */ 413 if (ict->ict_login_sm.icl_login_resp_tmpl->opcode == 0) 414 login_sm_handle_initial_login(ict, pdu); 415 rpdu = login_sm_build_login_response(ict); 416 login_sm_send_next_response(ict, rpdu); 417 idm_pdu_complete(pdu, IDM_STATUS_SUCCESS); 418 kmem_free(ctx, sizeof (*ctx)); 419 return; 420 } 421 break; 422 default: 423 break; 424 } 425 426 /* State dependent actions */ 427 switch (lsm->icl_login_state) { 428 case ILS_LOGIN_INIT: 429 login_sm_init(ict, ctx); 430 break; 431 case ILS_LOGIN_WAITING: 432 login_sm_waiting(ict, ctx); 433 break; 434 case ILS_LOGIN_PROCESSING: 435 login_sm_processing(ict, ctx); 436 break; 437 case ILS_LOGIN_RESPONDING: 438 login_sm_responding(ict, ctx); 439 break; 440 case ILS_LOGIN_RESPONDED: 441 login_sm_responded(ict, ctx); 442 break; 443 case ILS_LOGIN_FFP: 444 login_sm_ffp(ict, ctx); 445 break; 446 case ILS_LOGIN_DONE: 447 login_sm_done(ict, ctx); 448 break; 449 case ILS_LOGIN_ERROR: 450 login_sm_error(ict, ctx); 451 break; 452 } 453 454 kmem_free(ctx, sizeof (*ctx)); 455 } 456 457 static void 458 login_sm_init(iscsit_conn_t *ict, login_event_ctx_t *ctx) 459 { 460 idm_pdu_t *pdu; 461 462 switch (ctx->le_ctx_event) { 463 case ILE_LOGIN_RCV: 464 pdu = ctx->le_pdu; 465 466 /* 467 * This is the first login PDU we've received so use 468 * it to build the login response template and set our CSG. 469 */ 470 login_sm_handle_initial_login(ict, pdu); 471 472 /* 473 * Accumulate all the login PDU's that make up this 474 * request on a queue. 475 */ 476 mutex_enter(&ict->ict_login_sm.icl_mutex); 477 list_insert_tail(&ict->ict_login_sm.icl_pdu_list, pdu); 478 mutex_exit(&ict->ict_login_sm.icl_mutex); 479 480 if (pdu->isp_hdr->flags & ISCSI_FLAG_LOGIN_CONTINUE) { 481 login_sm_send_ack(ict, pdu); 482 login_sm_new_state(ict, ctx, ILS_LOGIN_WAITING); 483 } else { 484 login_sm_new_state(ict, ctx, ILS_LOGIN_PROCESSING); 485 } 486 break; 487 case ILE_LOGIN_CONN_ERROR: 488 case ILE_LOGIN_ERROR: 489 login_sm_new_state(ict, ctx, ILS_LOGIN_ERROR); 490 break; 491 default: 492 ASSERT(0); 493 } 494 } 495 496 static void 497 login_sm_waiting(iscsit_conn_t *ict, login_event_ctx_t *ctx) 498 { 499 idm_pdu_t *pdu; 500 501 switch (ctx->le_ctx_event) { 502 case ILE_LOGIN_RCV: 503 pdu = ctx->le_pdu; 504 mutex_enter(&ict->ict_login_sm.icl_mutex); 505 list_insert_tail(&ict->ict_login_sm.icl_pdu_list, pdu); 506 mutex_exit(&ict->ict_login_sm.icl_mutex); 507 if (!(pdu->isp_hdr->flags & ISCSI_FLAG_LOGIN_CONTINUE)) { 508 login_sm_new_state(ict, ctx, ILS_LOGIN_PROCESSING); 509 } else { 510 login_sm_send_ack(ict, pdu); 511 } 512 break; 513 case ILE_LOGIN_ERROR: 514 login_sm_new_state(ict, ctx, ILS_LOGIN_ERROR); 515 break; 516 case ILE_LOGIN_RESP_COMPLETE: 517 break; 518 default: 519 ASSERT(0); 520 } 521 } 522 523 static void 524 login_sm_processing(iscsit_conn_t *ict, login_event_ctx_t *ctx) 525 { 526 switch (ctx->le_ctx_event) { 527 case ILE_LOGIN_RESP_READY: 528 login_sm_new_state(ict, ctx, ILS_LOGIN_RESPONDING); 529 break; 530 case ILE_LOGIN_RCV: 531 idm_pdu_complete(ctx->le_pdu, IDM_STATUS_SUCCESS); 532 /*FALLTHROUGH*/ 533 case ILE_LOGIN_CONN_ERROR: 534 case ILE_LOGIN_ERROR: 535 login_sm_new_state(ict, ctx, ILS_LOGIN_ERROR); 536 break; 537 default: 538 ASSERT(0); 539 } 540 } 541 542 static void 543 login_sm_responding(iscsit_conn_t *ict, login_event_ctx_t *ctx) 544 { 545 idm_pdu_t *pdu, *rpdu; 546 547 switch (ctx->le_ctx_event) { 548 case ILE_LOGIN_RCV: 549 pdu = ctx->le_pdu; 550 /* 551 * We should only be in "responding" state if we have not 552 * sent the last PDU of a multi-PDU login response sequence. 553 * In that case we expect this received PDU to be an 554 * acknowledgement from the initiator (login PDU with C 555 * bit cleared and no data). If it's the acknowledgement 556 * we are expecting then we send the next PDU in the login 557 * response sequence. Otherwise it's a protocol error and 558 * the login fails. 559 */ 560 if (login_sm_validate_ack(ict, pdu) == IDM_STATUS_SUCCESS) { 561 rpdu = login_sm_build_login_response(ict); 562 login_sm_send_next_response(ict, rpdu); 563 } else { 564 login_sm_new_state(ict, ctx, ILS_LOGIN_ERROR); 565 } 566 idm_pdu_complete(pdu, IDM_STATUS_SUCCESS); 567 break; 568 case ILE_LOGIN_FFP: 569 login_sm_new_state(ict, ctx, ILS_LOGIN_FFP); 570 break; 571 case ILE_LOGIN_RESP_COMPLETE: 572 login_sm_new_state(ict, ctx, ILS_LOGIN_RESPONDED); 573 break; 574 case ILE_LOGIN_CONN_ERROR: 575 case ILE_LOGIN_ERROR: 576 login_sm_new_state(ict, ctx, ILS_LOGIN_ERROR); 577 break; 578 default: 579 ASSERT(0); 580 } 581 } 582 583 static void 584 login_sm_responded(iscsit_conn_t *ict, login_event_ctx_t *ctx) 585 { 586 idm_pdu_t *pdu; 587 iscsi_login_hdr_t *lh; 588 589 switch (ctx->le_ctx_event) { 590 case ILE_LOGIN_RCV: 591 pdu = ctx->le_pdu; 592 lh = (iscsi_login_hdr_t *)pdu->isp_hdr; 593 /* 594 * Set the CSG, NSG and Transit bits based on the this PDU. 595 * The CSG already validated in login_sm_req_pdu_check(). 596 * We'll clear the transit bit if we encounter any login 597 * parameters in the request that required an additional 598 * login transfer (i.e. no acceptable 599 * choices in range or we needed to change a boolean 600 * value from "Yes" to "No"). 601 */ 602 ict->ict_login_sm.icl_login_csg = 603 ISCSI_LOGIN_CURRENT_STAGE(lh->flags); 604 ict->ict_login_sm.icl_login_nsg = 605 ISCSI_LOGIN_NEXT_STAGE(lh->flags); 606 ict->ict_login_sm.icl_login_transit = 607 lh->flags & ISCSI_FLAG_LOGIN_TRANSIT; 608 mutex_enter(&ict->ict_login_sm.icl_mutex); 609 list_insert_tail(&ict->ict_login_sm.icl_pdu_list, pdu); 610 mutex_exit(&ict->ict_login_sm.icl_mutex); 611 if (pdu->isp_hdr->flags & ISCSI_FLAG_LOGIN_CONTINUE) { 612 login_sm_send_ack(ict, pdu); 613 login_sm_new_state(ict, ctx, ILS_LOGIN_WAITING); 614 } else { 615 login_sm_new_state(ict, ctx, ILS_LOGIN_PROCESSING); 616 } 617 break; 618 case ILE_LOGIN_CONN_ERROR: 619 case ILE_LOGIN_ERROR: 620 login_sm_new_state(ict, ctx, ILS_LOGIN_ERROR); 621 break; 622 default: 623 ASSERT(0); 624 } 625 } 626 627 static void 628 login_sm_ffp(iscsit_conn_t *ict, login_event_ctx_t *ctx) 629 { 630 switch (ctx->le_ctx_event) { 631 case ILE_LOGIN_RESP_COMPLETE: 632 login_sm_new_state(ict, ctx, ILS_LOGIN_DONE); 633 break; 634 case ILE_LOGIN_CONN_ERROR: 635 case ILE_LOGIN_ERROR: 636 login_sm_new_state(ict, ctx, ILS_LOGIN_ERROR); 637 break; 638 default: 639 ASSERT(0); 640 } 641 642 } 643 644 /*ARGSUSED*/ 645 static void 646 login_sm_done(iscsit_conn_t *ict, login_event_ctx_t *ctx) 647 { 648 /* Terminal state, we should get no events */ 649 switch (ctx->le_ctx_event) { 650 case ILE_LOGIN_RCV: 651 /* 652 * We've already processed everything we're going to 653 * process. Drop any additional login PDU's. 654 */ 655 idm_pdu_complete(ctx->le_pdu, IDM_STATUS_SUCCESS); 656 break; 657 case ILE_LOGIN_CONN_ERROR: 658 /* Don't care */ 659 break; 660 default: 661 ASSERT(0); 662 } 663 } 664 665 /*ARGSUSED*/ 666 static void 667 login_sm_error(iscsit_conn_t *ict, login_event_ctx_t *ctx) 668 { 669 switch (ctx->le_ctx_event) { 670 case ILE_LOGIN_RCV: 671 /* 672 * We've already processed everything we're going to 673 * process. Drop any additional login PDU's. 674 */ 675 idm_pdu_complete(ctx->le_pdu, IDM_STATUS_SUCCESS); 676 break; 677 case ILE_LOGIN_CONN_ERROR: 678 /* Don't care */ 679 break; 680 default: 681 ASSERT(0); 682 } 683 } 684 685 static void 686 login_sm_new_state(iscsit_conn_t *ict, login_event_ctx_t *ctx, 687 iscsit_login_state_t new_state) 688 { 689 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 690 idm_pdu_t *rpdu; 691 692 /* 693 * Validate new state 694 */ 695 ASSERT(new_state != ILS_UNDEFINED); 696 ASSERT3U(new_state, <, ILS_MAX_STATE); 697 698 new_state = (new_state < ILS_MAX_STATE) ? 699 new_state : ILS_UNDEFINED; 700 701 IDM_SM_LOG(CE_NOTE, "login_sm_new_state: conn %p " 702 "%s (%d) --> %s (%d)\n", (void *)ict->ict_ic, 703 iscsit_ils_name[lsm->icl_login_state], lsm->icl_login_state, 704 iscsit_ils_name[new_state], new_state); 705 706 DTRACE_PROBE3(login__state__change, 707 iscsit_conn_t *, ict, login_event_ctx_t *, ctx, 708 iscsit_login_state_t, new_state); 709 710 mutex_enter(&lsm->icl_mutex); 711 idm_sm_audit_state_change(&lsm->icl_state_audit, SAS_ISCSIT_LOGIN, 712 (int)lsm->icl_login_state, (int)new_state); 713 lsm->icl_login_last_state = lsm->icl_login_state; 714 lsm->icl_login_state = new_state; 715 mutex_exit(&lsm->icl_mutex); 716 717 switch (lsm->icl_login_state) { 718 case ILS_LOGIN_WAITING: 719 /* Do nothing, waiting for more login PDU's */ 720 break; 721 case ILS_LOGIN_PROCESSING: 722 /* All login PDU's received, process login request */ 723 login_sm_process_request(ict); 724 break; 725 case ILS_LOGIN_RESPONDING: 726 rpdu = login_sm_build_login_response(ict); 727 login_sm_send_next_response(ict, rpdu); 728 break; 729 case ILS_LOGIN_RESPONDED: 730 /* clean up the login response idm text buffer */ 731 if (lsm->icl_login_resp_itb != NULL) { 732 idm_itextbuf_free(lsm->icl_login_resp_itb); 733 lsm->icl_login_resp_itb = NULL; 734 } 735 break; 736 case ILS_LOGIN_FFP: 737 login_sm_ffp_actions(ict); 738 break; 739 case ILS_LOGIN_DONE: 740 case ILS_LOGIN_ERROR: 741 /* 742 * Flag the terminal state for the dispatcher 743 */ 744 lsm->icl_login_complete = B_TRUE; 745 break; 746 case ILS_LOGIN_INIT: /* Initial state, can't return */ 747 default: 748 ASSERT(0); 749 /*NOTREACHED*/ 750 } 751 } 752 753 /*ARGSUSED*/ 754 static void 755 login_sm_send_ack(iscsit_conn_t *ict, idm_pdu_t *pdu) 756 { 757 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 758 idm_pdu_t *lack; 759 760 /* 761 * allocate the response pdu 762 */ 763 lack = idm_pdu_alloc(sizeof (iscsi_hdr_t), 0); 764 idm_pdu_init(lack, ict->ict_ic, ict, login_resp_complete_cb); 765 lack->isp_flags |= IDM_PDU_LOGIN_TX; 766 767 /* 768 * copy the response template into the response pdu 769 */ 770 bcopy(lsm->icl_login_resp_tmpl, lack->isp_hdr, sizeof (iscsi_hdr_t)); 771 772 iscsit_conn_hold(ict); 773 idm_pdu_tx(lack); 774 } 775 776 /*ARGSUSED*/ 777 static idm_status_t 778 login_sm_validate_ack(iscsit_conn_t *ict, idm_pdu_t *pdu) 779 { 780 iscsi_hdr_t *ihp = pdu->isp_hdr; 781 if (ihp->flags & ISCSI_FLAG_TEXT_CONTINUE) { 782 return (IDM_STATUS_FAIL); 783 } 784 if (ntoh24(ihp->dlength) != 0) { 785 return (IDM_STATUS_FAIL); 786 } 787 return (IDM_STATUS_SUCCESS); 788 } 789 790 static boolean_t 791 login_sm_is_last_response(idm_pdu_t *pdu) 792 { 793 794 if (pdu->isp_hdr->flags & ISCSI_FLAG_LOGIN_CONTINUE) { 795 return (B_FALSE); 796 } 797 return (B_TRUE); 798 } 799 800 801 static void 802 login_sm_handle_initial_login(iscsit_conn_t *ict, idm_pdu_t *pdu) 803 { 804 iscsi_login_hdr_t *lh_req = (iscsi_login_hdr_t *)pdu->isp_hdr; 805 iscsi_login_rsp_hdr_t *lh_resp = 806 ict->ict_login_sm.icl_login_resp_tmpl; 807 808 /* 809 * First login PDU, this connection should not have a sesssion 810 * associated. 811 */ 812 ASSERT(ict->ict_sess == NULL); 813 814 /* 815 * Save off TSIH and ISID for later use in finding a session 816 */ 817 ict->ict_login_sm.icl_cmdsn = ntohl(lh_req->cmdsn); 818 ict->ict_login_sm.icl_tsih = ntohs(lh_req->tsid); 819 bcopy(lh_req->isid, ict->ict_login_sm.icl_isid, ISCSI_ISID_LEN); 820 821 /* 822 * We'll need the CID as well 823 */ 824 ict->ict_cid = ntohs(lh_req->cid); 825 826 /* 827 * Set the CSG, NSG and Transit bits based on the first PDU 828 * in the login sequence. The CSG already validated in 829 * login_sm_req_pdu_check(). We'll clear the transit bit if 830 * we encounter any login parameters in the request that 831 * required an additional login transfer (i.e. no acceptable 832 * choices in range or we needed to change a boolean 833 * value from "Yes" to "No"). 834 */ 835 ict->ict_login_sm.icl_login_csg = 836 ISCSI_LOGIN_CURRENT_STAGE(lh_req->flags); 837 ict->ict_login_sm.icl_login_nsg = 838 ISCSI_LOGIN_NEXT_STAGE(lh_req->flags); 839 ict->ict_login_sm.icl_login_transit = 840 lh_req->flags & ISCSI_FLAG_LOGIN_TRANSIT; 841 842 /* 843 * Initialize header for login reject response. This will also 844 * be copied for use as a template for other login responses 845 */ 846 lh_resp->opcode = ISCSI_OP_LOGIN_RSP; 847 lh_resp->max_version = ISCSIT_MAX_VERSION; 848 849 /* 850 * We already validated that we can support one of the initiator's 851 * versions in login_sm_req_pdu_check(). 852 */ 853 #if (ISCSIT_MAX_VERSION > 0) 854 if (ISCSIT_MAX_VERSION >= lh_req->min_version) { 855 lh_resp->active_version = 856 MIN(lh_req->max_version, ISCSIT_MAX_VERSION); 857 } else { 858 ASSERT(ISCSIT_MAX_VERSION <= lh_req->max_version); 859 lh_resp->active_version = ISCSIT_MAX_VERSION; 860 } 861 #endif 862 863 lh_resp->hlength = 0; /* No AHS */ 864 bcopy(lh_req->isid, lh_resp->isid, ISCSI_ISID_LEN); 865 lh_resp->tsid = lh_req->tsid; 866 lh_resp->itt = lh_req->itt; 867 868 /* 869 * StatSn, ExpCmdSn and MaxCmdSn will be set immediately before 870 * transmission 871 */ 872 } 873 874 static void 875 login_sm_send_next_response(iscsit_conn_t *ict, idm_pdu_t *pdu) 876 { 877 iscsi_login_rsp_hdr_t *lh_resp = (iscsi_login_rsp_hdr_t *)pdu->isp_hdr; 878 879 /* Make sure this PDU is part of the login phase */ 880 ASSERT((pdu->isp_flags & IDM_PDU_LOGIN_TX) != 0); 881 882 /* 883 * Fill in header values 884 */ 885 hton24(lh_resp->dlength, pdu->isp_datalen); 886 887 /* 888 * If this is going to be the last PDU of a login response 889 * that moves us to FFP then generate the ILE_LOGIN_FFP event. 890 */ 891 if (lh_resp->status_class == ISCSI_STATUS_CLASS_SUCCESS) { 892 ASSERT(ict->ict_sess != NULL); 893 894 if ((lh_resp->flags & ISCSI_FLAG_LOGIN_TRANSIT) && 895 (ISCSI_LOGIN_NEXT_STAGE(lh_resp->flags) == 896 ISCSI_FULL_FEATURE_PHASE) && 897 !(lh_resp->flags & ISCSI_FLAG_LOGIN_CONTINUE)) { 898 iscsit_login_sm_event(ict, ILE_LOGIN_FFP, NULL); 899 } 900 if (login_sm_is_last_response(pdu) == B_TRUE) { 901 /* 902 * The last of a potentially mult-PDU response finished. 903 */ 904 iscsit_login_sm_event(ict, ILE_LOGIN_RESP_COMPLETE, 905 NULL); 906 } 907 908 iscsit_conn_hold(ict); 909 iscsit_pdu_tx(pdu); 910 } else { 911 /* 912 * If status_class != ISCSI_STATUS_CLASS_SUCCESS then 913 * StatSN is not valid and we can call idm_pdu_tx instead 914 * of iscsit_pdu_tx. This is very good thing since in 915 * some cases of login failure we may not have a session. 916 * Since iscsit_calc_rspsn grabs the session mutex while 917 * it is retrieving values for expcmdsn and maxcmdsn this 918 * would cause a panic. 919 * 920 * Since we still want a value for expcmdsn, fill in an 921 * appropriate value based on the login request before 922 * sending the response. Cmdsn/expcmdsn do not advance during 923 * login phase. 924 */ 925 lh_resp->expcmdsn = htonl(ict->ict_login_sm.icl_cmdsn); 926 lh_resp->maxcmdsn = htonl(ict->ict_login_sm.icl_cmdsn + 1); 927 928 iscsit_conn_hold(ict); 929 idm_pdu_tx(pdu); 930 } 931 932 } 933 934 static void 935 login_sm_process_request(iscsit_conn_t *ict) 936 { 937 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 938 uint8_t error_class = 0; 939 uint8_t error_detail = 0; 940 941 /* 942 * First walk all the PDU's that make up this login request 943 * and compile all the iSCSI key-value pairs into nvlist format. 944 */ 945 946 ASSERT(lsm->icl_request_nvlist == NULL); 947 /* create an nvlist for request key/value pairs */ 948 if (idm_pdu_list_to_nvlist(&lsm->icl_pdu_list, 949 &lsm->icl_request_nvlist, &error_detail) != IDM_STATUS_SUCCESS) { 950 error_class = ISCSI_STATUS_CLASS_TARGET_ERR; 951 SET_LOGIN_ERROR(ict, error_class, error_detail); 952 goto request_fail; 953 } 954 955 /* Allocate a new nvlist for response key/value pairs */ 956 ASSERT(lsm->icl_response_nvlist == NULL); 957 if (nvlist_alloc(&lsm->icl_response_nvlist, NV_UNIQUE_NAME, 958 KM_NOSLEEP) != 0) { 959 error_class = ISCSI_STATUS_CLASS_TARGET_ERR; 960 error_detail = ISCSI_LOGIN_STATUS_NO_RESOURCES; 961 SET_LOGIN_ERROR(ict, error_class, error_detail); 962 goto request_fail; 963 } 964 965 /* 966 * This would be a very good time to make sure we have 967 * negotiated the required values for the login phase. For 968 * example we definitely should have defined InitiatorName, 969 * and Target name regardless of our current login phase. 970 */ 971 if (!ict->ict_op.op_initial_params_set) { 972 if (login_sm_validate_initial_parameters(ict) != 973 IDM_STATUS_SUCCESS) { 974 goto request_fail; 975 } 976 977 /* 978 * Now setup our session association. This includes 979 * create a new session or looking up an existing session, 980 * and if this is not a discovery session then we will 981 * also register this session with STMF. 982 */ 983 if (login_sm_session_bind(ict) != IDM_STATUS_SUCCESS) { 984 goto request_fail; 985 } 986 987 if (login_sm_set_auth(ict) != IDM_STATUS_SUCCESS) { 988 goto request_fail; 989 } 990 991 /* 992 * Prepend TargetAlias and PortalGroupTag 993 */ 994 if (ict->ict_op.op_discovery_session == B_FALSE) { 995 if ((lsm->icl_auth.ca_tgt_alias[0]) != '\0') { 996 (void) iscsit_reply_string(ict, 997 "TargetAlias", 998 &lsm->icl_auth.ca_tgt_alias[0]); 999 } 1000 (void) iscsit_reply_numerical(ict, 1001 "TargetPortalGroupTag", 1002 (uint64_t)lsm->icl_tpgt_tag); 1003 } 1004 1005 ict->ict_op.op_initial_params_set = B_TRUE; 1006 } 1007 1008 if (login_sm_process_nvlist(ict) != IDM_STATUS_SUCCESS) { 1009 goto request_fail; 1010 } 1011 1012 if (login_sm_check_security(ict) != IDM_STATUS_SUCCESS) { 1013 goto request_fail; 1014 } 1015 1016 /* clean up request_nvlist */ 1017 if (lsm->icl_request_nvlist != NULL) { 1018 nvlist_free(lsm->icl_request_nvlist); 1019 lsm->icl_request_nvlist = NULL; 1020 } 1021 1022 /* convert any responses to textbuf form */ 1023 ASSERT(lsm->icl_login_resp_itb == NULL); 1024 if (lsm->icl_response_nvlist) { 1025 lsm->icl_login_resp_itb = idm_nvlist_to_itextbuf( 1026 lsm->icl_response_nvlist); 1027 if (lsm->icl_login_resp_itb == NULL) { 1028 /* Still need to send the resp so continue */ 1029 SET_LOGIN_ERROR(ict, 1030 ISCSI_STATUS_CLASS_TARGET_ERR, 1031 ISCSI_LOGIN_STATUS_NO_RESOURCES); 1032 } 1033 /* clean up response_nvlist */ 1034 nvlist_free(lsm->icl_response_nvlist); 1035 lsm->icl_response_nvlist = NULL; 1036 } 1037 1038 /* tell the state machine to send the textbuf */ 1039 iscsit_login_sm_event(ict, ILE_LOGIN_RESP_READY, NULL); 1040 return; 1041 1042 request_fail: 1043 1044 /* clean up request_nvlist and response_nvlist */ 1045 if (lsm->icl_request_nvlist != NULL) { 1046 nvlist_free(lsm->icl_request_nvlist); 1047 lsm->icl_request_nvlist = NULL; 1048 } 1049 if (lsm->icl_response_nvlist != NULL) { 1050 nvlist_free(lsm->icl_response_nvlist); 1051 lsm->icl_response_nvlist = NULL; 1052 } 1053 } 1054 1055 1056 static void 1057 login_sm_ffp_actions(iscsit_conn_t *ict) 1058 { 1059 iscsit_process_negotiated_values(ict); 1060 } 1061 1062 static idm_status_t 1063 login_sm_validate_initial_parameters(iscsit_conn_t *ict) 1064 { 1065 int nvrc; 1066 char *string_val; 1067 uint8_t error_class = ISCSI_STATUS_CLASS_INITIATOR_ERR; 1068 uint8_t error_detail = ISCSI_LOGIN_STATUS_MISSING_FIELDS; 1069 idm_status_t status = IDM_STATUS_FAIL; 1070 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 1071 1072 /* 1073 * Make sure we received the required information from the initial 1074 * login. Add these declaratives to the negotiated list and 1075 * remove them from the request list as we go. If anything fails, 1076 * the caller will clean-up the nvlists. 1077 */ 1078 1079 /* 1080 * Initiator name 1081 */ 1082 if ((nvrc = nvlist_lookup_string(lsm->icl_request_nvlist, 1083 "InitiatorName", &string_val)) != 0) { 1084 goto initial_params_done; 1085 } 1086 if ((nvrc = nvlist_add_string(lsm->icl_negotiated_values, 1087 "InitiatorName", string_val)) != 0) { 1088 goto initial_params_done; 1089 } 1090 if ((nvrc = nvlist_lookup_string(lsm->icl_negotiated_values, 1091 "InitiatorName", &string_val)) != 0) { 1092 goto initial_params_done; 1093 } 1094 lsm->icl_initiator_name = string_val; 1095 if ((nvrc = nvlist_remove(lsm->icl_request_nvlist, 1096 "InitiatorName", DATA_TYPE_STRING)) != 0) { 1097 goto initial_params_done; 1098 } 1099 1100 /* 1101 * Session type 1102 */ 1103 ict->ict_op.op_discovery_session = B_FALSE; 1104 nvrc = nvlist_lookup_string(lsm->icl_request_nvlist, 1105 "SessionType", &string_val); 1106 if (nvrc != ENOENT && nvrc != 0) { 1107 goto initial_params_done; 1108 } 1109 if (nvrc == 0) { 1110 if (strcmp(string_val, "Discovery") == 0) { 1111 ict->ict_op.op_discovery_session = B_TRUE; 1112 } else if (strcmp(string_val, "Normal") != 0) { 1113 goto initial_params_done; 1114 } 1115 if ((nvrc = nvlist_add_string(lsm->icl_negotiated_values, 1116 "SessionType", string_val)) != 0) { 1117 goto initial_params_done; 1118 } 1119 if ((nvrc = nvlist_remove(lsm->icl_request_nvlist, 1120 "SessionType", DATA_TYPE_STRING)) != 0) { 1121 goto initial_params_done; 1122 } 1123 } 1124 1125 /* 1126 * Must have either TargetName or SessionType==Discovery 1127 */ 1128 lsm->icl_target_name = NULL; 1129 nvrc = nvlist_lookup_string(lsm->icl_request_nvlist, 1130 "TargetName", &string_val); 1131 if (nvrc != ENOENT && nvrc != 0) { 1132 goto initial_params_done; 1133 } 1134 if (nvrc == 0) { 1135 if ((nvrc = nvlist_add_string(lsm->icl_negotiated_values, 1136 "TargetName", string_val)) != 0) { 1137 goto initial_params_done; 1138 } 1139 if ((nvrc = nvlist_lookup_string(lsm->icl_negotiated_values, 1140 "TargetName", &string_val)) != 0) { 1141 goto initial_params_done; 1142 } 1143 lsm->icl_target_name = string_val; 1144 if ((nvrc = nvlist_remove(lsm->icl_request_nvlist, 1145 "TargetName", DATA_TYPE_STRING)) != 0) { 1146 goto initial_params_done; 1147 } 1148 } else if (ict->ict_op.op_discovery_session == B_FALSE) { 1149 /* 1150 * Missing target name 1151 */ 1152 goto initial_params_done; 1153 } 1154 1155 IDM_SM_LOG(CE_NOTE, "conn %p: initiator=%s", (void *)ict->ict_ic, 1156 (lsm->icl_initiator_name == NULL) ? "N/A" : 1157 lsm->icl_initiator_name); 1158 IDM_SM_LOG(CE_NOTE, "conn %p: target=%s", (void *)ict->ict_ic, 1159 (lsm->icl_target_name == NULL) ? "N/A" : 1160 lsm->icl_target_name); 1161 IDM_SM_LOG(CE_NOTE, "conn %p: sessiontype=%s", (void *)ict->ict_ic, 1162 ict->ict_op.op_discovery_session ? "Discovery" : "Normal"); 1163 1164 /* Sucess */ 1165 status = IDM_STATUS_SUCCESS; 1166 error_class = ISCSI_STATUS_CLASS_SUCCESS; 1167 error_detail = ISCSI_LOGIN_STATUS_ACCEPT; 1168 1169 initial_params_done: 1170 SET_LOGIN_ERROR(ict, error_class, error_detail); 1171 return (status); 1172 } 1173 1174 1175 /* 1176 * login_sm_session_bind 1177 * 1178 * This function looks at the data from the initial login request 1179 * of a new connection and either looks up and existing session, 1180 * creates a new session, or returns an error. RFC3720 section 5.3.1 1181 * defines these rules: 1182 * 1183 * +------------------------------------------------------------------+ 1184 * |ISID | TSIH | CID | Target action | 1185 * +------------------------------------------------------------------+ 1186 * |new | non-zero | any | fail the login | 1187 * | | | | ("session does not exist") | 1188 * +------------------------------------------------------------------+ 1189 * |new | zero | any | instantiate a new session | 1190 * +------------------------------------------------------------------+ 1191 * |existing | zero | any | do session reinstatement | 1192 * | | | | (see section 5.3.5) | 1193 * +------------------------------------------------------------------+ 1194 * |existing | non-zero | new | add a new connection to | 1195 * | | existing | | the session | 1196 * +------------------------------------------------------------------+ 1197 * |existing | non-zero |existing| do connection reinstatement| 1198 * | | existing | | (see section 5.3.4) | 1199 * +------------------------------------------------------------------+ 1200 * |existing | non-zero | any | fail the login | 1201 * | | new | | ("session does not exist") | 1202 * +------------------------------------------------------------------+ 1203 * 1204 */ 1205 1206 /* 1207 * Map an <ipv6,port> address to an <ipv4,port> address if possible. 1208 * Returns: 1209 * 1 - success 1210 * 0 - address not mapable 1211 */ 1212 1213 static int 1214 iscsit_is_v4_mapped(struct sockaddr_storage *sa, struct sockaddr_storage *v4sa) 1215 { 1216 struct sockaddr_in *sin; 1217 struct in_addr *in; 1218 struct sockaddr_in6 *sin6; 1219 struct in6_addr *in6; 1220 int ret = 0; 1221 1222 sin6 = (struct sockaddr_in6 *)sa; 1223 in6 = &sin6->sin6_addr; 1224 if ((sa->ss_family == AF_INET6) && 1225 (IN6_IS_ADDR_V4MAPPED(in6) || IN6_IS_ADDR_V4COMPAT(in6))) { 1226 sin = (struct sockaddr_in *)v4sa; 1227 in = &sin->sin_addr; 1228 v4sa->ss_family = AF_INET; 1229 sin->sin_port = sin6->sin6_port; 1230 IN6_V4MAPPED_TO_INADDR(in6, in); 1231 ret = 1; 1232 } 1233 return (ret); 1234 } 1235 1236 static idm_status_t 1237 login_sm_session_bind(iscsit_conn_t *ict) 1238 { 1239 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 1240 iscsit_tgt_t *tgt = NULL; 1241 iscsit_tpgt_t *tpgt = NULL; 1242 iscsit_portal_t *portal = NULL; 1243 iscsit_sess_t *existing_sess = NULL; 1244 iscsit_sess_t *new_sess = NULL; 1245 iscsit_conn_t *existing_ict = NULL; 1246 uint8_t error_class; 1247 uint8_t error_detail; 1248 1249 /* 1250 * Look up target and then check if there are sessions or connections 1251 * that match this request (see below). Any holds taken on objects 1252 * must be released at the end of the function (let's keep things 1253 * simple). 1254 * 1255 * If target name is set then we should have a corresponding target 1256 * context configured. 1257 */ 1258 if (lsm->icl_target_name != NULL) { 1259 /* 1260 * iscsit_tgt_lookup implicitly takes a ref on the target 1261 */ 1262 ISCSIT_GLOBAL_LOCK(RW_READER); 1263 tgt = iscsit_tgt_lookup_locked(lsm->icl_target_name); 1264 if (tgt == NULL) { 1265 ISCSIT_GLOBAL_UNLOCK(); 1266 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_INITIATOR_ERR, 1267 ISCSI_LOGIN_STATUS_TGT_NOT_FOUND); 1268 goto session_bind_error; 1269 } else { 1270 mutex_enter(&tgt->target_mutex); 1271 tpgt = avl_first(&tgt->target_tpgt_list); 1272 1273 if (IS_DEFAULT_TPGT(tpgt)) { 1274 lsm->icl_tpgt_tag = ISCSIT_DEFAULT_TPGT; 1275 } else { 1276 /* 1277 * Find the portal group tag for the 1278 * login response. 1279 */ 1280 struct sockaddr_storage v4sa, *sa; 1281 1282 sa = &ict->ict_ic->ic_laddr; 1283 portal = iscsit_tgt_lookup_portal(tgt, 1284 sa, &tpgt); 1285 if (portal == NULL && 1286 iscsit_is_v4_mapped(sa, &v4sa)) { 1287 /* 1288 * Try again if the local address 1289 * was v6 mappable to v4. 1290 */ 1291 portal = iscsit_tgt_lookup_portal(tgt, 1292 &v4sa, &tpgt); 1293 1294 } 1295 if (portal == NULL) { 1296 /* 1297 * Initiator came in on wrong address 1298 */ 1299 SET_LOGIN_ERROR(ict, 1300 ISCSI_STATUS_CLASS_INITIATOR_ERR, 1301 ISCSI_LOGIN_STATUS_TGT_NOT_FOUND); 1302 mutex_exit(&tgt->target_mutex); 1303 ISCSIT_GLOBAL_UNLOCK(); 1304 goto session_bind_error; 1305 } 1306 1307 /* 1308 * Need to release holds on the portal and 1309 * tpgt after processing is complete. 1310 */ 1311 lsm->icl_tpgt_tag = tpgt->tpgt_tag; 1312 iscsit_portal_rele(portal); 1313 iscsit_tpgt_rele(tpgt); 1314 } 1315 1316 if ((tgt->target_state != TS_STMF_ONLINE) || 1317 ((iscsit_global.global_svc_state != ISE_ENABLED) && 1318 ((iscsit_global.global_svc_state != ISE_BUSY)))) { 1319 SET_LOGIN_ERROR(ict, 1320 ISCSI_STATUS_CLASS_TARGET_ERR, 1321 ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE); 1322 mutex_exit(&tgt->target_mutex); 1323 ISCSIT_GLOBAL_UNLOCK(); 1324 goto session_bind_error; 1325 } 1326 mutex_exit(&tgt->target_mutex); 1327 ISCSIT_GLOBAL_UNLOCK(); 1328 } 1329 } 1330 1331 ASSERT((tgt != NULL) || (ict->ict_op.op_discovery_session == B_TRUE)); 1332 1333 /* 1334 * Check if there is an existing session matching this ISID. If 1335 * tgt == NULL then we'll look for the session on the global list 1336 * of discovery session. If we find a session then the ISID 1337 * exists. 1338 */ 1339 existing_sess = iscsit_tgt_lookup_sess(tgt, lsm->icl_initiator_name, 1340 lsm->icl_isid, lsm->icl_tsih, lsm->icl_tpgt_tag); 1341 if (existing_sess != NULL) { 1342 existing_ict = iscsit_sess_lookup_conn(existing_sess, 1343 ict->ict_cid); 1344 } 1345 1346 /* 1347 * If this is a discovery session, make sure it has appropriate 1348 * parameters. 1349 */ 1350 if ((ict->ict_op.op_discovery_session == B_TRUE) && 1351 ((lsm->icl_tsih != ISCSI_UNSPEC_TSIH) || (existing_sess != NULL))) { 1352 /* XXX Do we need to check for existing ISID (sess != NULL)? */ 1353 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_INITIATOR_ERR, 1354 ISCSI_LOGIN_STATUS_INVALID_REQUEST); 1355 goto session_bind_error; 1356 } 1357 1358 /* 1359 * Check the two error conditions from the table. 1360 * 1361 * ISID=new, TSIH=non-zero 1362 */ 1363 if ((existing_sess == NULL) && (lsm->icl_tsih != ISCSI_UNSPEC_TSIH)) { 1364 /* fail the login */ 1365 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_INITIATOR_ERR, 1366 ISCSI_LOGIN_STATUS_NO_SESSION); 1367 goto session_bind_error; 1368 } 1369 1370 /* ISID=existing, TSIH=non-zero new */ 1371 if ((existing_sess != NULL) && (lsm->icl_tsih != 0) && 1372 (existing_sess->ist_tsih != lsm->icl_tsih)) { 1373 /* fail the login */ 1374 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_INITIATOR_ERR, 1375 ISCSI_LOGIN_STATUS_NO_SESSION); 1376 goto session_bind_error; 1377 } 1378 1379 /* 1380 * Handle the remaining table cases in order 1381 */ 1382 if (existing_sess == NULL) { 1383 /* Should have caught this above */ 1384 ASSERT(lsm->icl_tsih == ISCSI_UNSPEC_TSIH); 1385 /* 1386 * ISID=new, TSIH=zero --> instantiate a new session 1387 */ 1388 new_sess = iscsit_sess_create(tgt, ict, lsm->icl_cmdsn, 1389 lsm->icl_isid, lsm->icl_tpgt_tag, lsm->icl_initiator_name, 1390 lsm->icl_target_name, &error_class, &error_detail); 1391 ASSERT(new_sess != NULL); 1392 1393 /* Session create may have failed even if it returned a value */ 1394 if (error_class != ISCSI_STATUS_CLASS_SUCCESS) { 1395 SET_LOGIN_ERROR(ict, error_class, error_detail); 1396 goto session_bind_error; 1397 } 1398 1399 /* 1400 * If we don't already have an STMF session and this is not 1401 * a discovery session then we need to allocate and register 1402 * one. 1403 */ 1404 if (!ict->ict_op.op_discovery_session) { 1405 if (login_sm_session_register(ict) != 1406 IDM_STATUS_SUCCESS) { 1407 /* login_sm_session_register sets error codes */ 1408 goto session_bind_error; 1409 } 1410 } 1411 1412 } else { 1413 if (lsm->icl_tsih == ISCSI_UNSPEC_TSIH) { 1414 /* 1415 * ISID=existing, TSIH=zero --> Session reinstatement 1416 */ 1417 new_sess = iscsit_sess_reinstate(tgt, existing_sess, 1418 ict, &error_class, &error_detail); 1419 ASSERT(new_sess != NULL); 1420 1421 if (error_class != ISCSI_STATUS_CLASS_SUCCESS) { 1422 SET_LOGIN_ERROR(ict, error_class, error_detail); 1423 goto session_bind_error; 1424 } 1425 1426 /* 1427 * If we don't already have an STMF session and this is 1428 * not a discovery session then we need to allocate and 1429 * register one. 1430 */ 1431 if (!ict->ict_op.op_discovery_session) { 1432 if (login_sm_session_register(ict) != 1433 IDM_STATUS_SUCCESS) { 1434 /* 1435 * login_sm_session_register sets 1436 * error codes 1437 */ 1438 goto session_bind_error; 1439 } 1440 } 1441 } else { 1442 /* 1443 * The following code covers these two cases: 1444 * ISID=existing, TSIH=non-zero existing, CID=new 1445 * --> add new connection to MC/S session 1446 * ISID=existing, TSIH=non-zero existing, CID=existing 1447 * --> do connection reinstatement 1448 * 1449 * Session continuation uses this path as well 1450 */ 1451 cmn_err(CE_NOTE, "login_sm_session_bind: add new " 1452 "conn/sess continue"); 1453 if (existing_ict != NULL) { 1454 /* 1455 * ISID=existing, TSIH=non-zero existing, 1456 * CID=existing --> do connection reinstatement 1457 */ 1458 if (iscsit_conn_reinstate(existing_ict, ict) != 1459 IDM_STATUS_SUCCESS) { 1460 /* 1461 * Most likely this means the connection 1462 * the initiator is trying to reinstate 1463 * is not in an acceptable state. 1464 */ 1465 SET_LOGIN_ERROR(ict, 1466 ISCSI_STATUS_CLASS_INITIATOR_ERR, 1467 ISCSI_LOGIN_STATUS_INIT_ERR); 1468 goto session_bind_error; 1469 } 1470 } 1471 1472 iscsit_sess_sm_event(existing_sess, SE_CONN_IN_LOGIN, 1473 ict); 1474 } 1475 } 1476 1477 if (tgt != NULL) 1478 iscsit_tgt_rele(tgt); 1479 if (existing_sess != NULL) 1480 iscsit_sess_rele(existing_sess); 1481 if (existing_ict != NULL) 1482 iscsit_conn_rele(existing_ict); 1483 1484 return (IDM_STATUS_SUCCESS); 1485 1486 session_bind_error: 1487 if (tgt != NULL) 1488 iscsit_tgt_rele(tgt); 1489 if (existing_sess != NULL) 1490 iscsit_sess_rele(existing_sess); 1491 if (existing_ict != NULL) 1492 iscsit_conn_rele(existing_ict); 1493 1494 /* 1495 * If session bind fails we will fail the login but don't destroy 1496 * the session until later. 1497 */ 1498 return (IDM_STATUS_FAIL); 1499 } 1500 1501 1502 static idm_status_t 1503 login_sm_set_auth(iscsit_conn_t *ict) 1504 { 1505 idm_status_t idmrc = IDM_STATUS_SUCCESS; 1506 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 1507 iscsit_ini_t *ini; 1508 iscsit_tgt_t *tgt; 1509 char *auth = ""; 1510 char *radiusserver = ""; 1511 char *radiussecret = ""; 1512 char *chapuser = ""; 1513 char *chapsecret = ""; 1514 char *targetchapuser = ""; 1515 char *targetchapsecret = ""; 1516 char *targetalias = ""; 1517 int i; 1518 1519 ISCSIT_GLOBAL_LOCK(RW_READER); 1520 1521 /* 1522 * Set authentication method to none for discovery session. 1523 */ 1524 if (ict->ict_op.op_discovery_session == B_TRUE) { 1525 lsm->icl_auth.ca_method_valid_list[0] = AM_NONE; 1526 ISCSIT_GLOBAL_UNLOCK(); 1527 return (idmrc); 1528 } 1529 1530 /* 1531 * Get all the authentication parameters we need -- since we hold 1532 * the global config lock we guarantee that the parameters will 1533 * be consistent with each other. 1534 */ 1535 (void) nvlist_lookup_string(iscsit_global.global_props, 1536 PROP_AUTH, &auth); 1537 (void) nvlist_lookup_string(iscsit_global.global_props, 1538 PROP_RADIUS_SERVER, &radiusserver); 1539 (void) nvlist_lookup_string(iscsit_global.global_props, 1540 PROP_RADIUS_SECRET, &radiussecret); 1541 1542 ini = iscsit_ini_lookup_locked(lsm->icl_initiator_name); 1543 if (ini != NULL) { 1544 /* Get Initiator CHAP parameters */ 1545 (void) nvlist_lookup_string(ini->ini_props, PROP_CHAP_USER, 1546 &chapuser); 1547 (void) nvlist_lookup_string(ini->ini_props, PROP_CHAP_SECRET, 1548 &chapsecret); 1549 } 1550 1551 tgt = ict->ict_sess->ist_tgt; 1552 if (tgt != NULL) { 1553 /* See if we have a target-specific authentication setting */ 1554 (void) nvlist_lookup_string(tgt->target_props, PROP_AUTH, 1555 &auth); 1556 /* Get target CHAP parameters */ 1557 (void) nvlist_lookup_string(tgt->target_props, 1558 PROP_TARGET_CHAP_USER, &targetchapuser); 1559 (void) nvlist_lookup_string(tgt->target_props, 1560 PROP_TARGET_CHAP_SECRET, &targetchapsecret); 1561 /* Get alias */ 1562 (void) nvlist_lookup_string(tgt->target_props, 1563 PROP_ALIAS, &targetalias); 1564 } 1565 1566 /* Set authentication method */ 1567 i = 0; 1568 if (strcmp(auth, PA_AUTH_RADIUS) == 0) { 1569 /* CHAP authentication using RADIUS server */ 1570 lsm->icl_auth.ca_method_valid_list[i++] = AM_CHAP; 1571 lsm->icl_auth.ca_use_radius = B_TRUE; 1572 } else if (strcmp(auth, PA_AUTH_CHAP) == 0) { 1573 /* Local CHAP authentication */ 1574 lsm->icl_auth.ca_method_valid_list[i++] = AM_CHAP; 1575 lsm->icl_auth.ca_use_radius = B_FALSE; 1576 } else if ((strcmp(auth, PA_AUTH_NONE) == 0) || 1577 (strcmp(auth, "") == 0)) { 1578 /* No authentication */ 1579 lsm->icl_auth.ca_method_valid_list[i++] = AM_NONE; 1580 } 1581 1582 /* 1583 * If initiator/target CHAP username is not set then use the 1584 * node name. If lsm->icl_target_name == NULL then this is 1585 * a discovery session so we don't need to work about the target. 1586 */ 1587 if (strcmp(chapuser, "") == 0) { 1588 (void) strlcpy(lsm->icl_auth.ca_ini_chapuser, 1589 lsm->icl_initiator_name, 1590 min(iscsitAuthStringMaxLength, MAX_ISCSI_NODENAMELEN)); 1591 } else { 1592 (void) strlcpy(lsm->icl_auth.ca_ini_chapuser, chapuser, 1593 iscsitAuthStringMaxLength); 1594 } 1595 if ((lsm->icl_target_name != NULL) && 1596 (strcmp(targetchapuser, "") == 0)) { 1597 (void) strlcpy(lsm->icl_auth.ca_tgt_chapuser, 1598 lsm->icl_target_name, 1599 min(iscsitAuthStringMaxLength, MAX_ISCSI_NODENAMELEN)); 1600 } else { 1601 (void) strlcpy(lsm->icl_auth.ca_tgt_chapuser, 1602 targetchapuser, iscsitAuthStringMaxLength); 1603 } 1604 1605 /* 1606 * Secrets are stored in base64-encoded format so we need to 1607 * decode them into binary form 1608 */ 1609 if (strcmp(chapsecret, "") == 0) { 1610 lsm->icl_auth.ca_ini_chapsecretlen = 0; 1611 } else { 1612 if (iscsi_base64_str_to_binary(chapsecret, 1613 strnlen(chapsecret, iscsitAuthStringMaxLength), 1614 lsm->icl_auth.ca_ini_chapsecret, iscsitAuthStringMaxLength, 1615 &lsm->icl_auth.ca_ini_chapsecretlen) != 0) { 1616 cmn_err(CE_WARN, "Corrupted CHAP secret" 1617 " for initiator %s", lsm->icl_initiator_name); 1618 lsm->icl_auth.ca_ini_chapsecretlen = 0; 1619 } 1620 } 1621 if (strcmp(targetchapsecret, "") == 0) { 1622 lsm->icl_auth.ca_tgt_chapsecretlen = 0; 1623 } else { 1624 if (iscsi_base64_str_to_binary(targetchapsecret, 1625 strnlen(targetchapsecret, iscsitAuthStringMaxLength), 1626 lsm->icl_auth.ca_tgt_chapsecret, iscsitAuthStringMaxLength, 1627 &lsm->icl_auth.ca_tgt_chapsecretlen) != 0) { 1628 cmn_err(CE_WARN, "Corrupted CHAP secret" 1629 " for target %s", lsm->icl_target_name); 1630 lsm->icl_auth.ca_tgt_chapsecretlen = 0; 1631 } 1632 } 1633 if (strcmp(radiussecret, "") == 0) { 1634 lsm->icl_auth.ca_radius_secretlen = 0; 1635 } else { 1636 if (iscsi_base64_str_to_binary(radiussecret, 1637 strnlen(radiussecret, iscsitAuthStringMaxLength), 1638 lsm->icl_auth.ca_radius_secret, iscsitAuthStringMaxLength, 1639 &lsm->icl_auth.ca_radius_secretlen) != 0) { 1640 cmn_err(CE_WARN, "Corrupted RADIUS secret"); 1641 lsm->icl_auth.ca_radius_secretlen = 0; 1642 } 1643 } 1644 1645 /* 1646 * Set alias 1647 */ 1648 (void) strlcpy(lsm->icl_auth.ca_tgt_alias, targetalias, 1649 MAX_ISCSI_NODENAMELEN); 1650 1651 /* 1652 * Now that authentication parameters are setup, validate the parameters 1653 * against the authentication mode 1654 * Decode RADIUS server value int lsm->icl_auth.ca_radius_server 1655 */ 1656 if ((strcmp(auth, PA_AUTH_RADIUS) == 0) && 1657 ((lsm->icl_auth.ca_radius_secretlen == 0) || 1658 (strcmp(radiusserver, "") == 0) || 1659 it_common_convert_sa(radiusserver, 1660 &lsm->icl_auth.ca_radius_server, 1661 DEFAULT_RADIUS_PORT) == NULL)) { 1662 cmn_err(CE_WARN, "RADIUS authentication selected " 1663 "for target %s but RADIUS parameters are not " 1664 "configured.", lsm->icl_target_name); 1665 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_TARGET_ERR, 1666 ISCSI_LOGIN_STATUS_TARGET_ERROR); 1667 idmrc = IDM_STATUS_FAIL; 1668 } else if ((strcmp(auth, PA_AUTH_CHAP) == 0) && 1669 (lsm->icl_auth.ca_ini_chapsecretlen == 0)) { 1670 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_INITIATOR_ERR, 1671 ISCSI_LOGIN_STATUS_AUTH_FAILED); 1672 idmrc = IDM_STATUS_FAIL; 1673 } 1674 1675 ISCSIT_GLOBAL_UNLOCK(); 1676 1677 return (idmrc); 1678 } 1679 1680 1681 static idm_status_t 1682 login_sm_session_register(iscsit_conn_t *ict) 1683 { 1684 iscsit_sess_t *ist = ict->ict_sess; 1685 stmf_scsi_session_t *ss; 1686 1687 /* 1688 * Hold target mutex until we have finished registering with STMF 1689 */ 1690 mutex_enter(&ist->ist_tgt->target_mutex); 1691 if (ist->ist_tgt->target_state != TS_STMF_ONLINE) { 1692 mutex_exit(&ist->ist_tgt->target_mutex); 1693 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_INITIATOR_ERR, 1694 ISCSI_LOGIN_STATUS_TGT_REMOVED); 1695 return (IDM_STATUS_FAIL); 1696 } 1697 1698 ss = stmf_alloc(STMF_STRUCT_SCSI_SESSION, 0, 1699 0); 1700 if (ss == NULL) { 1701 mutex_exit(&ist->ist_tgt->target_mutex); 1702 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_TARGET_ERR, 1703 ISCSI_LOGIN_STATUS_NO_RESOURCES); 1704 return (IDM_STATUS_FAIL); 1705 } 1706 1707 ss->ss_rport_id = kmem_zalloc(sizeof (scsi_devid_desc_t) + 1708 strlen(ist->ist_initiator_name) + 1, KM_SLEEP); 1709 (void) strcpy((char *)ss->ss_rport_id->ident, ist->ist_initiator_name); 1710 ss->ss_rport_id->ident_length = strlen(ist->ist_initiator_name); 1711 ss->ss_rport_id->protocol_id = PROTOCOL_iSCSI; 1712 ss->ss_rport_id->piv = 1; 1713 ss->ss_rport_id->code_set = CODE_SET_ASCII; 1714 ss->ss_rport_id->association = ID_IS_TARGET_PORT; 1715 1716 ss->ss_lport = ist->ist_lport; 1717 1718 if (stmf_register_scsi_session(ict->ict_sess->ist_lport, ss) != 1719 STMF_SUCCESS) { 1720 mutex_exit(&ist->ist_tgt->target_mutex); 1721 kmem_free(ss->ss_rport_id, 1722 sizeof (scsi_devid_desc_t) + 1723 strlen(ist->ist_initiator_name) + 1); 1724 stmf_free(ss); 1725 SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_TARGET_ERR, 1726 ISCSI_LOGIN_STATUS_TARGET_ERROR); 1727 return (IDM_STATUS_FAIL); 1728 } 1729 1730 ss->ss_port_private = ict->ict_sess; 1731 ict->ict_sess->ist_stmf_sess = ss; 1732 mutex_exit(&ist->ist_tgt->target_mutex); 1733 1734 return (IDM_STATUS_SUCCESS); 1735 } 1736 1737 1738 static idm_status_t 1739 login_sm_req_pdu_check(iscsit_conn_t *ict, idm_pdu_t *pdu) 1740 { 1741 uint8_t csg_req; 1742 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 1743 iscsi_login_hdr_t *lh = (iscsi_login_hdr_t *)pdu->isp_hdr; 1744 iscsi_login_rsp_hdr_t *lh_resp = lsm->icl_login_resp_tmpl; 1745 1746 /* 1747 * Check CSG 1748 */ 1749 csg_req = ISCSI_LOGIN_CURRENT_STAGE(lh->flags); 1750 switch (csg_req) { 1751 case ISCSI_SECURITY_NEGOTIATION_STAGE: 1752 case ISCSI_OP_PARMS_NEGOTIATION_STAGE: 1753 if ((csg_req != lsm->icl_login_csg) && 1754 (lsm->icl_login_state != ILS_LOGIN_INIT)) { 1755 /* 1756 * Inappropriate CSG change. Initiator can only 1757 * change CSG after we've responded with the 1758 * transit bit set. If we had responded with 1759 * a CSG change previous we would have updated 1760 * our copy of CSG. 1761 * 1762 * The exception is when we are in ILS_LOGIN_INIT 1763 * state since we haven't determined our initial 1764 * CSG value yet. 1765 */ 1766 goto pdu_check_fail; 1767 } 1768 break; 1769 case ISCSI_FULL_FEATURE_PHASE: 1770 default: 1771 goto pdu_check_fail; 1772 } 1773 1774 /* 1775 * If this is the first login PDU for a new connection then 1776 * the session will be NULL. 1777 */ 1778 if (ict->ict_sess != NULL) { 1779 /* 1780 * We've already created a session on a previous PDU. Make 1781 * sure this PDU is consistent with what we've already seen 1782 */ 1783 if ((ict->ict_cid != ntohs(lh->cid)) || 1784 (bcmp(ict->ict_sess->ist_isid, lh->isid, 1785 ISCSI_ISID_LEN) != 0)) { 1786 goto pdu_check_fail; 1787 } 1788 } 1789 1790 /* 1791 * Make sure we are compatible with the version range 1792 */ 1793 #if (ISCSIT_MAX_VERSION > 0) 1794 if ((lh->min_version > ISCSIT_MAX_VERSION) || 1795 (lh->max_version < ISCSIT_MIN_VERSION)) { 1796 goto pdu_check_fail; 1797 } 1798 #endif 1799 1800 /* 1801 * Just in case the initiator changes things up on us along the way 1802 * check against our active_version -- we can't change the active 1803 * version and the initiator is not *supposed* to change its 1804 * min_version and max_version values so this should never happen. 1805 * Of course we only do this if the response header template has 1806 * been built. 1807 */ 1808 if ((lh_resp->opcode == ISCSI_OP_LOGIN_RSP) && /* header valid */ 1809 ((lh->min_version > lh_resp->active_version) || 1810 (lh->max_version < lh_resp->active_version))) { 1811 goto pdu_check_fail; 1812 } 1813 1814 return (IDM_STATUS_SUCCESS); 1815 1816 pdu_check_fail: 1817 return (IDM_STATUS_FAIL); 1818 } 1819 1820 static idm_status_t 1821 login_sm_process_nvlist(iscsit_conn_t *ict) 1822 { 1823 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 1824 char *nvp_name; 1825 nvpair_t *nvp; 1826 nvpair_t *next_nvp; 1827 nvpair_t *negotiated_nvp; 1828 kv_status_t kvrc; 1829 uint8_t error_class; 1830 uint8_t error_detail; 1831 idm_status_t idm_status; 1832 1833 error_class = ISCSI_STATUS_CLASS_SUCCESS; 1834 error_detail = ISCSI_LOGIN_STATUS_ACCEPT; 1835 1836 /* First, request that the transport process the list */ 1837 kvrc = idm_negotiate_key_values(ict->ict_ic, lsm->icl_request_nvlist, 1838 lsm->icl_response_nvlist, lsm->icl_negotiated_values); 1839 idm_kvstat_to_error(kvrc, &error_class, &error_detail); 1840 if (error_class != ISCSI_STATUS_CLASS_SUCCESS) { 1841 SET_LOGIN_ERROR(ict, error_class, error_detail); 1842 idm_status = IDM_STATUS_FAIL; 1843 return (idm_status); 1844 } 1845 1846 /* Ensure we clear transit bit if the transport layer has countered */ 1847 if (kvrc == KV_HANDLED_NO_TRANSIT) { 1848 lsm->icl_login_transit = B_FALSE; 1849 } 1850 1851 /* Now, move on and process the rest of the pairs */ 1852 nvp = nvlist_next_nvpair(lsm->icl_request_nvlist, NULL); 1853 while (nvp != NULL) { 1854 next_nvp = nvlist_next_nvpair(lsm->icl_request_nvlist, nvp); 1855 nvp_name = nvpair_name(nvp); 1856 /* 1857 * If we've already agreed upon a value then make sure this 1858 * is not attempting to change that value. From RFC3270 1859 * section 5.3: 1860 * 1861 * "Neither the initiator nor the target should attempt to 1862 * declare or negotiate a parameter more than once during 1863 * login except for responses to specific keys that 1864 * explicitly allow repeated key declarations (e.g., 1865 * TargetAddress). An attempt to renegotiate/redeclare 1866 * parameters not specifically allowed MUST be detected 1867 * by the initiator and target. If such an attempt is 1868 * detected by the target, the target MUST respond 1869 * with Login reject (initiator error); ..." 1870 */ 1871 if (nvlist_lookup_nvpair(lsm->icl_negotiated_values, 1872 nvp_name, &negotiated_nvp) == 0) { 1873 kvrc = KV_HANDLED; 1874 } else { 1875 kvrc = iscsit_handle_key(ict, nvp, nvp_name); 1876 } 1877 1878 idm_kvstat_to_error(kvrc, &error_class, &error_detail); 1879 if (error_class != ISCSI_STATUS_CLASS_SUCCESS) { 1880 break; 1881 } 1882 1883 nvp = next_nvp; 1884 } 1885 1886 if (error_class == ISCSI_STATUS_CLASS_SUCCESS) { 1887 idm_status = IDM_STATUS_SUCCESS; 1888 } else { 1889 /* supply login class/detail for login errors */ 1890 SET_LOGIN_ERROR(ict, error_class, error_detail); 1891 idm_status = IDM_STATUS_FAIL; 1892 } 1893 1894 return (idm_status); 1895 } 1896 1897 static idm_status_t 1898 login_sm_check_security(iscsit_conn_t *ict) 1899 { 1900 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 1901 conn_auth_t *auth = &lsm->icl_auth; 1902 iscsit_auth_method_t *am_list = &auth->ca_method_valid_list[0]; 1903 kv_status_t kvrc; 1904 uint8_t error_class; 1905 uint8_t error_detail; 1906 idm_status_t idm_status; 1907 1908 error_class = ISCSI_STATUS_CLASS_SUCCESS; 1909 error_detail = ISCSI_LOGIN_STATUS_ACCEPT; 1910 1911 /* Check authentication status. */ 1912 if (lsm->icl_login_csg == ISCSI_SECURITY_NEGOTIATION_STAGE) { 1913 /* 1914 * We should have some authentication key/value pair(s) 1915 * received from initiator and the authentication phase 1916 * has been shifted when the key/value pair(s) are being 1917 * handled in the previous call iscsit_handle_security_key. 1918 * Now it turns to target to check the authentication phase 1919 * and shift it after taking some authentication action. 1920 */ 1921 kvrc = iscsit_reply_security_key(ict); 1922 idm_kvstat_to_error(kvrc, &error_class, &error_detail); 1923 } else if (!ict->ict_login_sm.icl_auth_pass) { 1924 /* 1925 * Check to see if the target allows initiators to bypass the 1926 * security check. If the target is configured to require 1927 * authentication, we reject the connection. 1928 */ 1929 if (am_list[0] == AM_NONE || am_list[0] == 0) { 1930 ict->ict_login_sm.icl_auth_pass = 1; 1931 } else { 1932 error_class = ISCSI_STATUS_CLASS_INITIATOR_ERR; 1933 error_detail = ISCSI_LOGIN_STATUS_AUTH_FAILED; 1934 } 1935 } 1936 1937 if (error_class == ISCSI_STATUS_CLASS_SUCCESS) { 1938 idm_status = IDM_STATUS_SUCCESS; 1939 } else { 1940 /* supply login class/detail for login errors */ 1941 SET_LOGIN_ERROR(ict, error_class, error_detail); 1942 idm_status = IDM_STATUS_FAIL; 1943 } 1944 1945 return (idm_status); 1946 } 1947 1948 static idm_pdu_t * 1949 login_sm_build_login_response(iscsit_conn_t *ict) 1950 { 1951 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 1952 iscsi_login_rsp_hdr_t *lh; 1953 int transit, text_transit = 1; 1954 idm_pdu_t *login_resp; 1955 1956 /* 1957 * Create a response PDU and fill it with as much of 1958 * the response text that will fit. 1959 */ 1960 1961 if (lsm->icl_login_resp_itb) { 1962 /* allocate a pdu with space for text */ 1963 login_resp = idm_pdu_alloc(sizeof (iscsi_hdr_t), 1964 ISCSI_DEFAULT_MAX_RECV_SEG_LEN); 1965 /* copy a chunk of text into the pdu */ 1966 lsm->icl_login_resp_buf = idm_pdu_init_text_data( 1967 login_resp, lsm->icl_login_resp_itb, 1968 ISCSI_DEFAULT_MAX_RECV_SEG_LEN, 1969 lsm->icl_login_resp_buf, &text_transit); 1970 if (text_transit) { 1971 /* text buf has been consumed */ 1972 idm_itextbuf_free(lsm->icl_login_resp_itb); 1973 lsm->icl_login_resp_itb = NULL; 1974 lsm->icl_login_resp_buf = NULL; 1975 } 1976 } else { 1977 /* allocate a pdu for just a header */ 1978 login_resp = idm_pdu_alloc(sizeof (iscsi_hdr_t), 0); 1979 } 1980 /* finish initializing the pdu */ 1981 idm_pdu_init(login_resp, 1982 ict->ict_ic, ict, login_resp_complete_cb); 1983 login_resp->isp_flags |= IDM_PDU_LOGIN_TX; 1984 1985 /* 1986 * Use the BHS header values from the response template 1987 */ 1988 bcopy(lsm->icl_login_resp_tmpl, 1989 login_resp->isp_hdr, sizeof (iscsi_login_rsp_hdr_t)); 1990 1991 lh = (iscsi_login_rsp_hdr_t *)login_resp->isp_hdr; 1992 1993 /* Set error class/detail */ 1994 lh->status_class = lsm->icl_login_resp_err_class; 1995 lh->status_detail = lsm->icl_login_resp_err_detail; 1996 /* Set CSG, NSG and Transit */ 1997 lh->flags = 0; 1998 lh->flags |= lsm->icl_login_csg << 2; 1999 2000 2001 if (lh->status_class == ISCSI_STATUS_CLASS_SUCCESS) { 2002 if (lsm->icl_login_transit && 2003 lsm->icl_auth_pass != 0) { 2004 transit = 1; 2005 } else { 2006 transit = 0; 2007 } 2008 /* 2009 * inititalize the text data 2010 */ 2011 if (transit == 1 && text_transit == 1) { 2012 lh->flags |= lsm->icl_login_nsg; 2013 lsm->icl_login_csg = lsm->icl_login_nsg; 2014 lh->flags |= ISCSI_FLAG_LOGIN_TRANSIT; 2015 } else { 2016 lh->flags &= ~ISCSI_FLAG_LOGIN_TRANSIT; 2017 } 2018 2019 /* If we are transitioning to FFP then set TSIH */ 2020 if (transit && (lh->flags & ISCSI_FLAG_LOGIN_TRANSIT) && 2021 lsm->icl_login_csg == ISCSI_FULL_FEATURE_PHASE) { 2022 lh->tsid = htons(ict->ict_sess->ist_tsih); 2023 } 2024 } else { 2025 login_resp->isp_data = 0; 2026 login_resp->isp_datalen = 0; 2027 } 2028 return (login_resp); 2029 } 2030 2031 static kv_status_t 2032 iscsit_handle_key(iscsit_conn_t *ict, nvpair_t *nvp, char *nvp_name) 2033 { 2034 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2035 kv_status_t kvrc; 2036 const idm_kv_xlate_t *ikvx; 2037 2038 ikvx = idm_lookup_kv_xlate(nvp_name, strlen(nvp_name)); 2039 if (ikvx->ik_key_id == KI_MAX_KEY) { 2040 /* 2041 * Any key not understood by the acceptor may be igonred 2042 * by the acceptor without affecting the basic function. 2043 * However, the answer for a key not understood MUST be 2044 * key=NotUnderstood. 2045 */ 2046 kvrc = iscsit_reply_string(ict, nvp_name, 2047 ISCSI_TEXT_NOTUNDERSTOOD); 2048 } else { 2049 kvrc = iscsit_handle_common_key(ict, nvp, ikvx); 2050 if (kvrc == KV_UNHANDLED) { 2051 switch (lsm->icl_login_csg) { 2052 case ISCSI_SECURITY_NEGOTIATION_STAGE: 2053 kvrc = iscsit_handle_security_key( 2054 ict, nvp, ikvx); 2055 break; 2056 case ISCSI_OP_PARMS_NEGOTIATION_STAGE: 2057 kvrc = iscsit_handle_operational_key( 2058 ict, nvp, ikvx); 2059 break; 2060 case ISCSI_FULL_FEATURE_PHASE: 2061 default: 2062 /* What are we doing here? */ 2063 ASSERT(0); 2064 kvrc = KV_UNHANDLED; 2065 } 2066 } 2067 } 2068 2069 return (kvrc); 2070 } 2071 2072 static kv_status_t 2073 iscsit_handle_common_key(iscsit_conn_t *ict, nvpair_t *nvp, 2074 const idm_kv_xlate_t *ikvx) 2075 { 2076 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2077 kv_status_t kvrc; 2078 char *string_val; 2079 int nvrc; 2080 2081 switch (ikvx->ik_key_id) { 2082 case KI_INITIATOR_NAME: 2083 case KI_INITIATOR_ALIAS: 2084 nvrc = nvlist_add_nvpair(lsm->icl_negotiated_values, nvp); 2085 kvrc = idm_nvstat_to_kvstat(nvrc); 2086 break; 2087 case KI_TARGET_NAME: 2088 /* We'll validate the target during login_sm_session_bind() */ 2089 nvrc = nvpair_value_string(nvp, &string_val); 2090 ASSERT(nvrc == 0); /* We built this nvlist */ 2091 2092 nvrc = nvlist_add_nvpair(lsm->icl_negotiated_values, nvp); 2093 kvrc = idm_nvstat_to_kvstat(nvrc); 2094 break; 2095 case KI_TARGET_ALIAS: 2096 case KI_TARGET_ADDRESS: 2097 case KI_TARGET_PORTAL_GROUP_TAG: 2098 kvrc = KV_TARGET_ONLY; /* Only the target can declare this */ 2099 break; 2100 case KI_SESSION_TYPE: 2101 /* 2102 * If we don't receive this key on the initial login 2103 * we assume this is a normal session. 2104 */ 2105 nvrc = nvlist_add_nvpair(lsm->icl_negotiated_values, nvp); 2106 kvrc = idm_nvstat_to_kvstat(nvrc); 2107 nvrc = nvpair_value_string(nvp, &string_val); 2108 ASSERT(nvrc == 0); /* We built this nvlist */ 2109 ict->ict_op.op_discovery_session = 2110 strcmp(string_val, "Discovery") == 0 ? B_TRUE : B_FALSE; 2111 break; 2112 default: 2113 /* 2114 * This is not really an error but we should 2115 * leave this nvpair on the list since we 2116 * didn't do anything with it. Either 2117 * the security or operational phase 2118 * handling functions should process it. 2119 */ 2120 kvrc = KV_UNHANDLED; 2121 break; 2122 } 2123 2124 return (kvrc); 2125 } 2126 2127 static kv_status_t 2128 iscsit_handle_security_key(iscsit_conn_t *ict, nvpair_t *nvp, 2129 const idm_kv_xlate_t *ikvx) 2130 { 2131 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2132 iscsit_auth_client_t *client = &lsm->icl_auth_client; 2133 iscsikey_id_t kv_id; 2134 kv_status_t kvrc; 2135 iscsit_auth_handler_t handler; 2136 2137 /* 2138 * After all of security keys are handled, this function will 2139 * be called again to verify current authentication status 2140 * and perform some actual authentication work. At this time, 2141 * the nvp and ikvx will be passed in as NULLs. 2142 */ 2143 if (ikvx != NULL) { 2144 kv_id = ikvx->ik_key_id; 2145 } else { 2146 kv_id = 0; 2147 } 2148 2149 handler = iscsit_auth_get_handler(client, kv_id); 2150 if (handler) { 2151 kvrc = handler(ict, nvp, ikvx); 2152 } else { 2153 kvrc = KV_UNHANDLED; /* invalid request */ 2154 } 2155 2156 return (kvrc); 2157 } 2158 2159 static kv_status_t 2160 iscsit_reply_security_key(iscsit_conn_t *ict) 2161 { 2162 return (iscsit_handle_security_key(ict, NULL, NULL)); 2163 } 2164 2165 static kv_status_t 2166 iscsit_handle_operational_key(iscsit_conn_t *ict, nvpair_t *nvp, 2167 const idm_kv_xlate_t *ikvx) 2168 { 2169 kv_status_t kvrc = KV_UNHANDLED; 2170 boolean_t bool_val; 2171 uint64_t num_val; 2172 int nvrc; 2173 2174 /* 2175 * Retrieve values. All value lookups are expected to succeed 2176 * since we build the nvlist while decoding the text buffer. This 2177 * step is intended to eliminate some duplication of code (for example 2178 * we only need to code the numerical value lookup once). We will 2179 * handle the values (if necessary) below. 2180 */ 2181 switch (ikvx->ik_key_id) { 2182 /* Lists */ 2183 case KI_HEADER_DIGEST: 2184 case KI_DATA_DIGEST: 2185 break; 2186 /* Booleans */ 2187 case KI_INITIAL_R2T: 2188 case KI_IMMEDIATE_DATA: 2189 case KI_DATA_PDU_IN_ORDER: 2190 case KI_DATA_SEQUENCE_IN_ORDER: 2191 case KI_IFMARKER: 2192 case KI_OFMARKER: 2193 nvrc = nvpair_value_boolean_value(nvp, &bool_val); 2194 ASSERT(nvrc == 0); /* We built this nvlist */ 2195 break; 2196 /* Numericals */ 2197 case KI_MAX_CONNECTIONS: 2198 case KI_MAX_RECV_DATA_SEGMENT_LENGTH: 2199 case KI_MAX_BURST_LENGTH: 2200 case KI_FIRST_BURST_LENGTH: 2201 case KI_DEFAULT_TIME_2_WAIT: 2202 case KI_DEFAULT_TIME_2_RETAIN: 2203 case KI_MAX_OUTSTANDING_R2T: 2204 case KI_ERROR_RECOVERY_LEVEL: 2205 nvrc = nvpair_value_uint64(nvp, &num_val); 2206 ASSERT(nvrc == 0); 2207 break; 2208 /* Ranges */ 2209 case KI_OFMARKERINT: 2210 case KI_IFMARKERINT: 2211 break; 2212 default: 2213 break; 2214 } 2215 2216 /* 2217 * Now handle the values according to the key name. Sometimes we 2218 * don't care what the value is -- in that case we just add the nvpair 2219 * to the negotiated values list. 2220 */ 2221 switch (ikvx->ik_key_id) { 2222 case KI_HEADER_DIGEST: 2223 kvrc = iscsit_handle_digest(ict, nvp, ikvx); 2224 break; 2225 case KI_DATA_DIGEST: 2226 kvrc = iscsit_handle_digest(ict, nvp, ikvx); 2227 break; 2228 case KI_INITIAL_R2T: 2229 /* We *require* INITIAL_R2T=yes */ 2230 kvrc = iscsit_handle_boolean(ict, nvp, bool_val, ikvx, 2231 B_TRUE); 2232 break; 2233 case KI_IMMEDIATE_DATA: 2234 kvrc = iscsit_handle_boolean(ict, nvp, bool_val, ikvx, 2235 bool_val); 2236 break; 2237 case KI_DATA_PDU_IN_ORDER: 2238 kvrc = iscsit_handle_boolean(ict, nvp, bool_val, ikvx, 2239 B_TRUE); 2240 break; 2241 case KI_DATA_SEQUENCE_IN_ORDER: 2242 /* We allow any value for DATA_SEQUENCE_IN_ORDER */ 2243 kvrc = iscsit_handle_boolean(ict, nvp, bool_val, ikvx, 2244 bool_val); 2245 break; 2246 case KI_OFMARKER: 2247 case KI_IFMARKER: 2248 /* We don't support markers */ 2249 kvrc = iscsit_handle_boolean(ict, nvp, bool_val, ikvx, 2250 B_FALSE); 2251 break; 2252 case KI_MAX_CONNECTIONS: 2253 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx, 2254 ISCSI_MIN_CONNECTIONS, 2255 ISCSI_MAX_CONNECTIONS, 2256 ISCSIT_MAX_CONNECTIONS); 2257 break; 2258 case KI_MAX_RECV_DATA_SEGMENT_LENGTH: 2259 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx, 2260 ISCSI_MIN_RECV_DATA_SEGMENT_LENGTH, 2261 ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH, 2262 ISCSIT_MAX_RECV_DATA_SEGMENT_LENGTH); 2263 break; 2264 case KI_MAX_BURST_LENGTH: 2265 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx, 2266 ISCSI_MIN_MAX_BURST_LENGTH, 2267 ISCSI_MAX_BURST_LENGTH, 2268 ISCSIT_MAX_BURST_LENGTH); 2269 break; 2270 case KI_FIRST_BURST_LENGTH: 2271 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx, 2272 ISCSI_MIN_FIRST_BURST_LENGTH, 2273 ISCSI_MAX_FIRST_BURST_LENGTH, 2274 ISCSIT_MAX_FIRST_BURST_LENGTH); 2275 break; 2276 case KI_DEFAULT_TIME_2_WAIT: 2277 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx, 2278 ISCSI_MIN_TIME2WAIT, 2279 ISCSI_MAX_TIME2WAIT, 2280 ISCSIT_MAX_TIME2WAIT); 2281 break; 2282 case KI_DEFAULT_TIME_2_RETAIN: 2283 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx, 2284 ISCSI_MIN_TIME2RETAIN, 2285 ISCSI_MAX_TIME2RETAIN, 2286 ISCSIT_MAX_TIME2RETAIN); 2287 break; 2288 case KI_MAX_OUTSTANDING_R2T: 2289 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx, 2290 ISCSI_MIN_MAX_OUTSTANDING_R2T, 2291 ISCSI_MAX_OUTSTANDING_R2T, 2292 ISCSIT_MAX_OUTSTANDING_R2T); 2293 break; 2294 case KI_ERROR_RECOVERY_LEVEL: 2295 kvrc = iscsit_handle_numerical(ict, nvp, num_val, ikvx, 2296 ISCSI_MIN_ERROR_RECOVERY_LEVEL, 2297 ISCSI_MAX_ERROR_RECOVERY_LEVEL, 2298 ISCSIT_MAX_ERROR_RECOVERY_LEVEL); 2299 break; 2300 case KI_OFMARKERINT: 2301 case KI_IFMARKERINT: 2302 kvrc = iscsit_reply_string(ict, ikvx->ik_key_name, 2303 ISCSI_TEXT_IRRELEVANT); 2304 break; 2305 default: 2306 kvrc = KV_UNHANDLED; /* invalid request */ 2307 break; 2308 } 2309 2310 return (kvrc); 2311 } 2312 2313 static kv_status_t 2314 iscsit_reply_numerical(iscsit_conn_t *ict, 2315 const char *nvp_name, const uint64_t value) 2316 { 2317 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2318 kv_status_t kvrc; 2319 int nvrc; 2320 2321 nvrc = nvlist_add_uint64(lsm->icl_response_nvlist, 2322 nvp_name, value); 2323 kvrc = idm_nvstat_to_kvstat(nvrc); 2324 2325 return (kvrc); 2326 } 2327 2328 static kv_status_t 2329 iscsit_reply_string(iscsit_conn_t *ict, 2330 const char *nvp_name, const char *text) 2331 { 2332 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2333 kv_status_t kvrc; 2334 int nvrc; 2335 2336 nvrc = nvlist_add_string(lsm->icl_response_nvlist, 2337 nvp_name, text); 2338 kvrc = idm_nvstat_to_kvstat(nvrc); 2339 2340 return (kvrc); 2341 } 2342 2343 static kv_status_t 2344 iscsit_handle_digest(iscsit_conn_t *ict, nvpair_t *choices, 2345 const idm_kv_xlate_t *ikvx) 2346 { 2347 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2348 kv_status_t kvrc = KV_VALUE_ERROR; 2349 int nvrc; 2350 nvpair_t *digest_choice; 2351 char *digest_choice_string; 2352 2353 /* 2354 * Need to add persistent config here if we want users to allow 2355 * disabling of digests on the target side. You could argue that 2356 * this makes things too complicated... just let the initiator state 2357 * what it wants and we'll take it. For now that's exactly what 2358 * we'll do. 2359 * 2360 * Basic digest negotiation happens here at iSCSI level. IDM 2361 * can override this during negotiate_key_values phase to 2362 * decline to set up any digest processing. 2363 */ 2364 digest_choice = idm_get_next_listvalue(choices, NULL); 2365 2366 /* 2367 * Loop through all choices. As soon as we find a choice 2368 * that we support add the value to our negotiated values list 2369 * and respond with that value in the login response. 2370 */ 2371 while (digest_choice != NULL) { 2372 nvrc = nvpair_value_string(digest_choice, 2373 &digest_choice_string); 2374 ASSERT(nvrc == 0); 2375 2376 if ((strcasecmp(digest_choice_string, "crc32c") == 0) || 2377 (strcasecmp(digest_choice_string, "none") == 0)) { 2378 /* Add to negotiated values list */ 2379 nvrc = nvlist_add_string(lsm->icl_negotiated_values, 2380 ikvx->ik_key_name, digest_choice_string); 2381 kvrc = idm_nvstat_to_kvstat(nvrc); 2382 if (nvrc == 0) { 2383 /* Add to login response list */ 2384 nvrc = nvlist_add_string( 2385 lsm->icl_response_nvlist, 2386 ikvx->ik_key_name, digest_choice_string); 2387 kvrc = idm_nvstat_to_kvstat(nvrc); 2388 } 2389 break; 2390 } 2391 digest_choice = idm_get_next_listvalue(choices, 2392 digest_choice); 2393 } 2394 2395 if (digest_choice == NULL) 2396 kvrc = KV_VALUE_ERROR; 2397 2398 return (kvrc); 2399 } 2400 2401 static kv_status_t 2402 iscsit_handle_boolean(iscsit_conn_t *ict, nvpair_t *nvp, boolean_t value, 2403 const idm_kv_xlate_t *ikvx, boolean_t iscsit_value) 2404 { 2405 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2406 kv_status_t kvrc; 2407 int nvrc; 2408 2409 if (value != iscsit_value) { 2410 /* Respond back to initiator with our value */ 2411 value = iscsit_value; 2412 lsm->icl_login_transit = B_FALSE; 2413 nvrc = 0; 2414 } else { 2415 /* Add this to our negotiated values */ 2416 nvrc = nvlist_add_nvpair(lsm->icl_negotiated_values, 2417 nvp); 2418 } 2419 2420 /* Response of Simple-value Negotiation */ 2421 if (nvrc == 0 && !ikvx->ik_declarative) { 2422 nvrc = nvlist_add_boolean_value( 2423 lsm->icl_response_nvlist, ikvx->ik_key_name, value); 2424 } 2425 kvrc = idm_nvstat_to_kvstat(nvrc); 2426 2427 return (kvrc); 2428 } 2429 2430 static kv_status_t 2431 iscsit_handle_numerical(iscsit_conn_t *ict, nvpair_t *nvp, uint64_t value, 2432 const idm_kv_xlate_t *ikvx, 2433 uint64_t iscsi_min_value, uint64_t iscsi_max_value, 2434 uint64_t iscsit_max_value) 2435 { 2436 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2437 kv_status_t kvrc; 2438 int nvrc; 2439 2440 /* Validate against standard */ 2441 if ((value < iscsi_min_value) || (value > iscsi_max_value)) { 2442 kvrc = KV_VALUE_ERROR; 2443 } else { 2444 if (value > iscsit_max_value) { 2445 /* Respond back to initiator with our value */ 2446 value = iscsit_max_value; 2447 lsm->icl_login_transit = B_FALSE; 2448 nvrc = 0; 2449 } else { 2450 /* Add this to our negotiated values */ 2451 nvrc = nvlist_add_nvpair(lsm->icl_negotiated_values, 2452 nvp); 2453 } 2454 2455 /* Response of Simple-value Negotiation */ 2456 if (nvrc == 0 && !ikvx->ik_declarative) { 2457 nvrc = nvlist_add_uint64(lsm->icl_response_nvlist, 2458 ikvx->ik_key_name, value); 2459 } 2460 kvrc = idm_nvstat_to_kvstat(nvrc); 2461 } 2462 2463 return (kvrc); 2464 } 2465 2466 2467 static void 2468 iscsit_process_negotiated_values(iscsit_conn_t *ict) 2469 { 2470 iscsit_conn_login_t *lsm = &ict->ict_login_sm; 2471 char *string_val; 2472 boolean_t boolean_val; 2473 uint64_t uint64_val; 2474 int nvrc; 2475 2476 /* Let the IDM level activate its parameters first */ 2477 idm_notice_key_values(ict->ict_ic, lsm->icl_negotiated_values); 2478 2479 /* 2480 * Initiator alias and target alias 2481 */ 2482 if ((nvrc = nvlist_lookup_string(lsm->icl_negotiated_values, 2483 "InitiatorAlias", &string_val)) != ENOENT) { 2484 ASSERT(nvrc == 0); 2485 ict->ict_sess->ist_initiator_alias = 2486 kmem_alloc(strlen(string_val) + 1, KM_SLEEP); 2487 (void) strcpy(ict->ict_sess->ist_initiator_alias, string_val); 2488 } 2489 2490 if ((nvrc = nvlist_lookup_string(lsm->icl_negotiated_values, 2491 "TargetAlias", &string_val)) != ENOENT) { 2492 ASSERT(nvrc == 0); 2493 ict->ict_sess->ist_target_alias = 2494 kmem_alloc(strlen(string_val) + 1, KM_SLEEP); 2495 (void) strcpy(ict->ict_sess->ist_target_alias, string_val); 2496 } 2497 2498 /* 2499 * Operational parameters. We process SessionType when it is 2500 * initially received since it is required on the initial login. 2501 */ 2502 if ((nvrc = nvlist_lookup_boolean_value(lsm->icl_negotiated_values, 2503 "InitialR2T", &boolean_val)) != ENOENT) { 2504 ASSERT(nvrc == 0); 2505 ict->ict_op.op_initial_r2t = boolean_val; 2506 } 2507 2508 if ((nvrc = nvlist_lookup_boolean_value(lsm->icl_negotiated_values, 2509 "ImmediateData", &boolean_val)) != ENOENT) { 2510 ASSERT(nvrc == 0); 2511 ict->ict_op.op_immed_data = boolean_val; 2512 } 2513 2514 if ((nvrc = nvlist_lookup_boolean_value(lsm->icl_negotiated_values, 2515 "DataPDUInOrder", &boolean_val)) != ENOENT) { 2516 ASSERT(nvrc == 0); 2517 ict->ict_op.op_data_pdu_in_order = boolean_val; 2518 } 2519 2520 if ((nvrc = nvlist_lookup_boolean_value(lsm->icl_negotiated_values, 2521 "DataSequenceInOrder", &boolean_val)) != ENOENT) { 2522 ASSERT(nvrc == 0); 2523 ict->ict_op.op_data_sequence_in_order = boolean_val; 2524 } 2525 2526 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values, 2527 "MaxConnections", &uint64_val)) != ENOENT) { 2528 ASSERT(nvrc == 0); 2529 ict->ict_op.op_max_connections = uint64_val; 2530 } 2531 2532 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values, 2533 "MaxRecvDataSegmentLength", &uint64_val)) != ENOENT) { 2534 ASSERT(nvrc == 0); 2535 ict->ict_op.op_max_recv_data_segment_length = uint64_val; 2536 } 2537 2538 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values, 2539 "MaxBurstLength", &uint64_val)) != ENOENT) { 2540 ASSERT(nvrc == 0); 2541 ict->ict_op.op_max_burst_length = uint64_val; 2542 } 2543 2544 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values, 2545 "FirstBurstLength", &uint64_val)) != ENOENT) { 2546 ASSERT(nvrc == 0); 2547 ict->ict_op.op_first_burst_length = uint64_val; 2548 } 2549 2550 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values, 2551 "DefaultTime2Wait", &uint64_val)) != ENOENT) { 2552 ASSERT(nvrc == 0); 2553 ict->ict_op.op_default_time_2_wait = uint64_val; 2554 } 2555 2556 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values, 2557 "DefaultTime2Retain", &uint64_val)) != ENOENT) { 2558 ASSERT(nvrc == 0); 2559 ict->ict_op.op_default_time_2_retain = uint64_val; 2560 } 2561 2562 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values, 2563 "MaxOutstandingR2T", &uint64_val)) != ENOENT) { 2564 ASSERT(nvrc == 0); 2565 ict->ict_op.op_max_outstanding_r2t = uint64_val; 2566 } 2567 2568 if ((nvrc = nvlist_lookup_uint64(lsm->icl_negotiated_values, 2569 "ErrorRecoveryLevel", &uint64_val)) != ENOENT) { 2570 ASSERT(nvrc == 0); 2571 ict->ict_op.op_error_recovery_level = uint64_val; 2572 } 2573 } 2574