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 }