a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap/*
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * CDDL HEADER START
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap *
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * The contents of this file are subject to the terms of the
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * Common Development and Distribution License (the "License").
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * You may not use this file except in compliance with the License.
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap *
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * or http://www.opensolaris.org/os/licensing.
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * See the License for the specific language governing permissions
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * and limitations under the License.
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap *
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * When distributing Covered Code, include this CDDL HEADER in each
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * If applicable, add the following below this CDDL HEADER, with the
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * fields enclosed by brackets "[]" replaced with your own identifying
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * information: Portions Copyright [yyyy] [name of copyright owner]
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap *
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * CDDL HEADER END
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap/*
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap#include <sys/cpuvar.h>
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap#include <sys/types.h>
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap#include <sys/conf.h>
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap#include <sys/file.h>
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap#include <sys/ddi.h>
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap#include <sys/sunddi.h>
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap#include <sys/modctl.h>
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap#include <sys/socket.h>
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap#include <sys/strsubr.h>
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap#include <sys/sysmacros.h>
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap#include <sys/stmf.h>
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap#include <sys/stmf_ioctl.h>
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap#include <sys/portif.h>
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap#include <sys/idm/idm.h>
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap#include <sys/idm/idm_text.h>
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan#include "iscsit.h"
4558d122136f151d62acbbc02ddb42df89a5ef66Viswanathan Kannappan#include "iscsit_auth.h"
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic kv_status_t
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapiscsit_select_auth(iscsit_conn_t *ict, nvpair_t *nvp,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const idm_kv_xlate_t *ikvx);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic kv_status_t
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapauth_propose_chap(iscsit_conn_t *ict, nvpair_t *nvp,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const idm_kv_xlate_t *ikvx);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic kv_status_t
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapauth_chap_select_alg(iscsit_conn_t *ict, nvpair_t *nvp,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const idm_kv_xlate_t *ikvx);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic kv_status_t
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapauth_chap_recv_n(iscsit_conn_t *ict, nvpair_t *nvp,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const idm_kv_xlate_t *ikvx);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic kv_status_t
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapauth_chap_recv_r(iscsit_conn_t *ict, nvpair_t *nvp,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const idm_kv_xlate_t *ikvx);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic kv_status_t
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapauth_chap_recv_i(iscsit_conn_t *ict, nvpair_t *nvp,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const idm_kv_xlate_t *ikvx);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic kv_status_t
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapauth_chap_recv_c(iscsit_conn_t *ict, nvpair_t *nvp,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const idm_kv_xlate_t *ikvx);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic kv_status_t
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapiscsit_auth_propose(iscsit_conn_t *ict, nvpair_t *nvp,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const idm_kv_xlate_t *ikvx);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic kv_status_t
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapiscsit_auth_expect_key(iscsit_conn_t *ict, nvpair_t *nvp,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const idm_kv_xlate_t *ikvx);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic kv_status_t
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapauth_chap_expect_r(iscsit_conn_t *ict, nvpair_t *nvp,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const idm_kv_xlate_t *ikvx);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic kv_status_t
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapauth_chap_done(iscsit_conn_t *ict, nvpair_t *nvp,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const idm_kv_xlate_t *ikvx);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic kv_status_t
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapiscsit_auth_gen_challenge(iscsit_conn_t *ict);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic kv_status_t
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapiscsit_auth_gen_response(iscsit_conn_t *ict);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlaptypedef struct {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_auth_phase_t phase;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsikey_id_t kv_id;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_auth_handler_t handler;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap} auth_phase_entry_t;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap/*
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * This table defines all authentication phases which have valid
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * handler. The entries which have a non-zero key index are for
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * a key/value pair handling when a key/value is being received,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * the rest of entries are for target checking the authentication
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * phase after all key/value pair(s) are handled.
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic const auth_phase_entry_t apet[] = {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap /* by key */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap { AP_AM_UNDECIDED, KI_AUTH_METHOD, iscsit_select_auth },
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap { AP_AM_PROPOSED, KI_CHAP_A, auth_propose_chap },
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap { AP_CHAP_A_WAITING, KI_CHAP_A, auth_chap_select_alg },
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap { AP_CHAP_R_WAITING, KI_CHAP_N, auth_chap_recv_n },
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap { AP_CHAP_R_WAITING, KI_CHAP_R, auth_chap_recv_r },
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap { AP_CHAP_R_WAITING, KI_CHAP_I, auth_chap_recv_i },
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap { AP_CHAP_R_WAITING, KI_CHAP_C, auth_chap_recv_c },
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap { AP_CHAP_R_RCVD, KI_CHAP_N, auth_chap_recv_n },
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap { AP_CHAP_R_RCVD, KI_CHAP_R, auth_chap_recv_r },
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap { AP_CHAP_R_RCVD, KI_CHAP_I, auth_chap_recv_i },
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap { AP_CHAP_R_RCVD, KI_CHAP_C, auth_chap_recv_c },
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap /* by target */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap { AP_AM_UNDECIDED, 0, iscsit_auth_propose },
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap { AP_AM_DECIDED, 0, iscsit_auth_expect_key },
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap { AP_CHAP_A_RCVD, 0, auth_chap_expect_r },
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap { AP_CHAP_R_RCVD, 0, auth_chap_done }
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap};
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlaptypedef struct {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_auth_method_t am_id;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap char *am_name;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap} auth_id_name_t;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap/*
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * a table of mapping from the authentication index to name.
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic const auth_id_name_t aint[] = {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap { AM_CHAP, "CHAP" },
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap { AM_NONE, "None" },
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap /* { AM_KRB5, "KRB5" }, */ /* Not supported */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap /* { AM_SPKM1, "SPKM1" }, */ /* Not supported */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap /* { AM_SPKM2, "SPKM2" }, */ /* Not supported */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap /* { AM_SRP, "SRP" }, */ /* Not supported */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap};
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap#define ARRAY_LENGTH(ARRAY) (sizeof (ARRAY) / sizeof (ARRAY[0]))
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap/*
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * get the authentication method name for the method id.
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic const char *
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapam_id_to_name(int id)
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap{
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap int i;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const auth_id_name_t *p;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap i = 0;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap while (i < ARRAY_LENGTH(aint)) {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap p = &(aint[i]);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap if (id == p->am_id) {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap return (p->am_name);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap }
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap i ++;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap }
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap return (NULL);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap}
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap/*
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * Look for an apporiate function handler which is defined for
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * current authentication phase and matches the key which is
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * being handled. The key index is passed in as zero when it
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * is looking for an handler for checking the authentication phase
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * after all security keys are handled.
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapiscsit_auth_handler_t
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapiscsit_auth_get_handler(iscsit_auth_client_t *client, iscsikey_id_t kv_id)
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap{
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_auth_phase_t phase = client->phase;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap int i;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const auth_phase_entry_t *p;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap i = 0;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap p = NULL;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap while (i < ARRAY_LENGTH(apet)) {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap p = &(apet[i]);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap if (phase == p->phase &&
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap kv_id == p->kv_id) {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap return (p->handler);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap }
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap i ++;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap }
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap /* No handler can be found, it must be an invalid requst. */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap return (NULL);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap}
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap/*
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * Select an authentication method from a list of values proposed
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * by initiator. After a valid method is selected, shift the
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * authentication phase to AP_AM_DECIDED.
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic kv_status_t
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapiscsit_select_auth(iscsit_conn_t *ict, nvpair_t *nvp,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const idm_kv_xlate_t *ikvx)
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap{
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_conn_login_t *lsm = &ict->ict_login_sm;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap conn_auth_t *auth = &lsm->icl_auth;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_auth_method_t *am_list = &auth->ca_method_valid_list[0];
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_auth_client_t *client = &lsm->icl_auth_client;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap int nvrc;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap kv_status_t kvrc;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap nvpair_t *am_choice;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap char *am;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const char *am_name;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const char *text;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_auth_method_t am_id;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap int i;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client->phase = AP_AM_DECIDED;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap /* select a valid authentication method */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap am_choice = idm_get_next_listvalue(nvp, NULL);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap while (am_choice != NULL) {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap nvrc = nvpair_value_string(am_choice, &am);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap ASSERT(nvrc == 0);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap i = 0;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap am_id = am_list[i];
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap while (am_id != 0) {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap am_name = am_id_to_name(am_id);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap if (strcasecmp(am, am_name) == 0) {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap text = am;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap goto am_decided;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap }
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap i++;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap am_id = am_list[i];
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap }
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap am_choice = idm_get_next_listvalue(nvp, am_choice);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap }
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap /* none of authentication method is valid */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap am_id = 0;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap text = ISCSI_TEXT_REJECT;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapam_decided:
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client->negotiatedMethod = am_id;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap /* add the selected method to the response nvlist */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap nvrc = nvlist_add_string(lsm->icl_response_nvlist,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap ikvx->ik_key_name, text);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap kvrc = idm_nvstat_to_kvstat(nvrc);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap return (kvrc);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap}
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap/*
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * Initiator chooses to use CHAP after target proposed a list of
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * authentication method. Set the authentication method to CHAP and
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * continue on chap authentication phase.
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic kv_status_t
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapauth_propose_chap(iscsit_conn_t *ict, nvpair_t *nvp,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const idm_kv_xlate_t *ikvx)
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap{
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_conn_login_t *lsm = &ict->ict_login_sm;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_auth_client_t *client = &lsm->icl_auth_client;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client->negotiatedMethod = AM_CHAP;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client->phase = AP_AM_DECIDED;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap return (auth_chap_select_alg(ict, nvp, ikvx));
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap}
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap/*
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * Select a CHAP algorithm from a list of values proposed by
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * initiator and shift the authentication phase to AP_CHAP_A_RCVD.
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic kv_status_t
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapauth_chap_select_alg(iscsit_conn_t *ict, nvpair_t *nvp,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const idm_kv_xlate_t *ikvx)
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap{
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_conn_login_t *lsm = &ict->ict_login_sm;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_auth_client_t *client = &lsm->icl_auth_client;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap int nvrc, rc;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap kv_status_t kvrc;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap nvpair_t *alg_choice;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap char *alg_string;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap uint64_t alg;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const char *text;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client->phase = AP_CHAP_A_RCVD;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap alg_choice = idm_get_next_listvalue(nvp, NULL);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap while (alg_choice != NULL) {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap nvrc = nvpair_value_string(alg_choice, &alg_string);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap ASSERT(nvrc == 0);
2ef9abdc6ea9bad985430325b12b90938a8cd18fjv rc = ddi_strtoull(alg_string, NULL, 0, (u_longlong_t *)&alg);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap if (rc == 0 && alg == 5) {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap /* only MD5 is supported */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap text = alg_string;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap goto alg_selected;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap }
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap alg_choice = idm_get_next_listvalue(nvp, alg_choice);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap }
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap /* none of algorithm is selected */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap alg = 0;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap text = ISCSI_TEXT_REJECT;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapalg_selected:
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap /* save the selected algorithm or zero for none is selected */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client_set_numeric_data(
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap &client->recvKeyBlock,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap AKT_CHAP_A,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap (uint32_t)alg);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap /* add the selected algorithm to the response nvlist */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap nvrc = nvlist_add_string(lsm->icl_response_nvlist,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap ikvx->ik_key_name, text);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap if (alg == 0) {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap kvrc = KV_AUTH_FAILED; /* No algorithm selected */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap } else {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap kvrc = idm_nvstat_to_kvstat(nvrc);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap if (kvrc == 0) {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap kvrc = iscsit_auth_gen_challenge(ict);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap }
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap }
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap return (kvrc);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap}
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap/*
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * Validate and save the the chap name which is sent by initiator
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * and shift the authentication phase to AP_CHAP_R_RCVD.
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap *
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * Note: the CHAP_N, CHAP_R, optionally CHAP_I and CHAP_C key/value
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * pairs need to be received in one packet, we handle each of them
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * separately, in order to track the authentication phase, we set
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * the authentication phase to AP_CHAP_R_RCVD once one of them is
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * handled. So both of AP_CHAP_R_WAITING and AP_CHAP_R_RCVD phases
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * are valid for these keys. The function auth_chap_done is going
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * to detect if any of these keys is missing.
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap/*ARGSUSED*/
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic kv_status_t
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapauth_chap_recv_n(iscsit_conn_t *ict, nvpair_t *nvp,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const idm_kv_xlate_t *ikvx)
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap{
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_conn_login_t *lsm = &ict->ict_login_sm;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_auth_client_t *client = &lsm->icl_auth_client;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap int nvrc;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap char *chap_name;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap nvrc = nvpair_value_string(nvp, &chap_name);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap ASSERT(nvrc == 0);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client_set_string_data(&client->recvKeyBlock,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap AKT_CHAP_N,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap chap_name);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client->phase = AP_CHAP_R_RCVD;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap return (KV_HANDLED);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap}
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap/*
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * Validate and save the the chap response which is sent by initiator
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * and shift the authentication phase to AP_CHAP_R_RCVD.
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap *
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * Note: see function auth_chap_recv_n.
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap/*ARGSUSED*/
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic kv_status_t
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapauth_chap_recv_r(iscsit_conn_t *ict, nvpair_t *nvp,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const idm_kv_xlate_t *ikvx)
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap{
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_conn_login_t *lsm = &ict->ict_login_sm;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_auth_client_t *client = &lsm->icl_auth_client;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap int nvrc;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap unsigned char *chap_resp;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap uint_t len;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap nvrc = nvpair_value_byte_array(nvp, &chap_resp, &len);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap ASSERT(nvrc == 0);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client_set_binary_data(&client->recvKeyBlock,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap AKT_CHAP_R,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap chap_resp, len);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client->phase = AP_CHAP_R_RCVD;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap return (KV_HANDLED);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap}
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap/*
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * Validate and save the the chap identifier which is sent by initiator
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * and shift the authentication phase to AP_CHAP_R_RCVD.
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap *
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * Note: see function auth_chap_recv_n.
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap/*ARGSUSED*/
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic kv_status_t
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapauth_chap_recv_i(iscsit_conn_t *ict, nvpair_t *nvp,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const idm_kv_xlate_t *ikvx)
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap{
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_conn_login_t *lsm = &ict->ict_login_sm;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_auth_client_t *client = &lsm->icl_auth_client;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap int nvrc;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap uint64_t chap_id;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap nvrc = nvpair_value_uint64(nvp, &chap_id);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap ASSERT(nvrc == 0);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client_set_numeric_data(&client->recvKeyBlock,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap AKT_CHAP_I,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap chap_id);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client->phase = AP_CHAP_R_RCVD;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap return (KV_HANDLED);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap}
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap/*
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * Validate and save the the chap challenge which is sent by initiator
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * and shift the authentication phase to AP_CHAP_R_RCVD.
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap *
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * Note: see function auth_chap_recv_n.
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap/*ARGSUSED*/
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic kv_status_t
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapauth_chap_recv_c(iscsit_conn_t *ict, nvpair_t *nvp,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const idm_kv_xlate_t *ikvx)
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap{
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_conn_login_t *lsm = &ict->ict_login_sm;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_auth_client_t *client = &lsm->icl_auth_client;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap int nvrc;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap unsigned char *chap_challenge;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap uint_t len;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap nvrc = nvpair_value_byte_array(nvp, &chap_challenge, &len);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap ASSERT(nvrc == 0);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client_set_binary_data(
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap &client->recvKeyBlock,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap AKT_CHAP_C,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap chap_challenge, len);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client->phase = AP_CHAP_R_RCVD;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap return (KV_HANDLED);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap}
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap/*
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * Shift the authentication phase to AP_CHAP_R_WAITING after target
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * has successfully selected a chap algorithm.
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap/*ARGSUSED*/
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic kv_status_t
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapauth_chap_expect_r(iscsit_conn_t *ict, nvpair_t *nvp,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const idm_kv_xlate_t *ikvx)
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap{
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_conn_login_t *lsm = &ict->ict_login_sm;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_auth_client_t *client = &lsm->icl_auth_client;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap uint32_t alg;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client_get_numeric_data(&client->recvKeyBlock,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap AKT_CHAP_A,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap &alg);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap if (alg != 0) {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client->phase = AP_CHAP_R_WAITING;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap } else {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap /* none of proposed algorithm is supported or understood. */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client->phase = AP_CHAP_A_WAITING;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap }
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap return (KV_HANDLED);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap}
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap/*
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * Initiator does not propose security negotiation, target needs to
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * verify if we can bypass the security negotiation phase or propose
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * a security negotiation for the initiator.
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap/*ARGSUSED*/
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic kv_status_t
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapiscsit_auth_propose(iscsit_conn_t *ict, nvpair_t *nvp,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const idm_kv_xlate_t *ikvx)
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap{
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_conn_login_t *lsm = &ict->ict_login_sm;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap conn_auth_t *auth = &lsm->icl_auth;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_auth_method_t *am_list = &auth->ca_method_valid_list[0];
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_auth_client_t *client = &lsm->icl_auth_client;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap int nvrc;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap kv_status_t kvrc;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const char *am_name;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap if (am_list[0] == AM_NONE || am_list[0] == 0) {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap lsm->icl_auth_pass = 1;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap }
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap if (lsm->icl_auth_pass == 0) {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap /*
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * It should be noted that the negotiation might also
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * be directed by the target if the initiator does
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * support security, but is not ready to direct the
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * negotiation (propose options).
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * - RFC3720 section 5.3.2.
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap am_name = am_id_to_name(am_list[0]);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap nvrc = nvlist_add_string(
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap lsm->icl_response_nvlist,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap "AuthMethod", am_name);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap kvrc = idm_nvstat_to_kvstat(nvrc);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client->phase = AP_AM_PROPOSED;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap } else {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap kvrc = KV_HANDLED;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client->phase = AP_DONE;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap }
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap return (kvrc);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap}
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap/*
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * Shift the authentication phase according to the authentication
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * method once it is selected.
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap/*ARGSUSED*/
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic kv_status_t
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapiscsit_auth_expect_key(iscsit_conn_t *ict, nvpair_t *nvp,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const idm_kv_xlate_t *ikvx)
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap{
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_conn_login_t *lsm = &ict->ict_login_sm;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_auth_client_t *client = &lsm->icl_auth_client;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap if (client->negotiatedMethod != 0) {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap /* Shift security negotiation phase. */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap switch (client->negotiatedMethod) {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap case AM_CHAP:
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client->phase = AP_CHAP_A_WAITING;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap break;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap case AM_NONE:
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client->phase = AP_DONE;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap lsm->icl_auth_pass = 1;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap break;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap default:
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap ASSERT(0);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap break;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap }
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap } else {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap /* None of proposed method is supported or understood. */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client->phase = AP_AM_UNDECIDED;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap }
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap return (KV_HANDLED);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap}
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap/*
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * The last step of the chap authentication. We will validate the
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * chap parameters we received and authenticate the client here.
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap/*ARGSUSED*/
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic kv_status_t
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapauth_chap_done(iscsit_conn_t *ict, nvpair_t *nvp,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap const idm_kv_xlate_t *ikvx)
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap{
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_conn_login_t *lsm = &ict->ict_login_sm;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_auth_client_t *client = &lsm->icl_auth_client;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap kv_status_t kvrc = KV_HANDLED;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap conn_auth_t *auth = &lsm->icl_auth;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap char *username_in;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap uint32_t chap_id;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap unsigned char *chap_challenge;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap unsigned int challenge_len;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap char *chap_name;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap unsigned char *chap_resp;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap unsigned int resp_len;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap int bi_auth;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap username_in = auth->ca_ini_chapuser;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap if (username_in[0] == '\0')
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap return (KV_AUTH_FAILED);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap /*
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * Check if we have received a valid list of response keys.
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap if (!client_auth_key_present(&client->recvKeyBlock, AKT_CHAP_N) ||
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap !client_auth_key_present(&client->recvKeyBlock, AKT_CHAP_R) ||
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap ((bi_auth =
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client_auth_key_present(&client->recvKeyBlock, AKT_CHAP_I)) ^
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client_auth_key_present(&client->recvKeyBlock, AKT_CHAP_C))) {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap return (KV_MISSING_FIELDS);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap }
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client->phase = AP_DONE;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client_get_string_data(&client->recvKeyBlock,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap AKT_CHAP_N,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap &chap_name);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap /* check username */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap if (strcmp(username_in, chap_name) != 0) {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap return (KV_AUTH_FAILED);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap }
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client_get_numeric_data(&client->sendKeyBlock,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap AKT_CHAP_I,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap &chap_id);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client_get_binary_data(&client->sendKeyBlock,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap AKT_CHAP_C,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap &chap_challenge, &challenge_len);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client_get_binary_data(&client->recvKeyBlock,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap AKT_CHAP_R,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap &chap_resp, &resp_len);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap if (iscsit_verify_chap_resp(lsm,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap chap_id, chap_challenge, challenge_len,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap chap_resp, resp_len) != ISCSI_AUTH_PASSED) {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap return (KV_AUTH_FAILED);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap }
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap /* bi-direction authentication is required */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap if (bi_auth != 0) {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap kvrc = iscsit_auth_gen_response(ict);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap }
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap lsm->icl_auth_pass = 1;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap return (kvrc);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap}
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic kv_status_t
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapiscsit_auth_gen_challenge(iscsit_conn_t *ict)
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap{
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_conn_login_t *lsm = &ict->ict_login_sm;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_auth_client_t *client = &lsm->icl_auth_client;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap int nvrc;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap kv_status_t kvrc;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap unsigned char idData[1];
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap unsigned char *bin;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap int len;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap auth_random_set_data(idData, 1);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client_set_numeric_data(&client->sendKeyBlock,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap AKT_CHAP_I,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap idData[0]);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap /* send chap identifier */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap nvrc = nvlist_add_uint64(
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap lsm->icl_response_nvlist,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap "CHAP_I", idData[0]);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap kvrc = idm_nvstat_to_kvstat(nvrc);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap if (kvrc != 0) {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap return (kvrc);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap }
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap bin = &(client->auth_send_binary_block.largeBinary[0]);
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap len = iscsitAuthChapResponseLength;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap auth_random_set_data(bin, len);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client_set_binary_data(&client->sendKeyBlock,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap AKT_CHAP_C,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap bin, len);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap /* send chap challenge */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap nvrc = nvlist_add_byte_array(
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap lsm->icl_response_nvlist,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap "CHAP_C", bin, len);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap kvrc = idm_nvstat_to_kvstat(nvrc);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap return (kvrc);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap}
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapstatic kv_status_t
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlapiscsit_auth_gen_response(iscsit_conn_t *ict)
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap{
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_conn_login_t *lsm = &ict->ict_login_sm;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap iscsit_auth_client_t *client = &lsm->icl_auth_client;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap int nvrc;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap kv_status_t kvrc;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap conn_auth_t *auth = &lsm->icl_auth;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap char *tgt_username;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap uint8_t *tgt_password;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap int tgt_password_length;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap uint32_t chap_id;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap unsigned char *chap_challenge;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap unsigned int challenge_len;
30e7468f8f41aa30ada067b2c1d5d284046514daPeter Dunlap uchar_t resp[iscsitAuthChapResponseLength];
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap tgt_username = auth->ca_tgt_chapuser;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap tgt_password = auth->ca_tgt_chapsecret;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap tgt_password_length = auth->ca_tgt_chapsecretlen;
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap /*
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * We can't know in advance whether the initiator will attempt
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * mutual authentication, so now we need to check whether we
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap * have a target CHAP secret configured.
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap */
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap if (tgt_password_length == 0) {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap return (KV_AUTH_FAILED);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap }
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client_get_numeric_data(&client->recvKeyBlock,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap AKT_CHAP_I,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap &chap_id);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client_get_binary_data(&client->recvKeyBlock,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap AKT_CHAP_C,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap &chap_challenge, &challenge_len);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap client_compute_chap_resp(
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap &resp[0],
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap chap_id,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap tgt_password, tgt_password_length,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap chap_challenge, challenge_len);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap nvrc = nvlist_add_string(
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap lsm->icl_response_nvlist,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap "CHAP_N", tgt_username);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap if (nvrc == 0) {
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap nvrc = nvlist_add_byte_array(
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap lsm->icl_response_nvlist,
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap "CHAP_R", resp, sizeof (resp));
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap }
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap kvrc = idm_nvstat_to_kvstat(nvrc);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap return (kvrc);
a6d42e7d71324c5193c3b94d57d96ba2925d52e1Peter Dunlap}