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