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