linux/drivers/target/iscsi/iscsi_target_nego.c
<<
>>
Prefs
   1/*******************************************************************************
   2 * This file contains main functions related to iSCSI Parameter negotiation.
   3 *
   4 * \u00a9 Copyright 2007-2011 RisingTide Systems LLC.
   5 *
   6 * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
   7 *
   8 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License as published by
  12 * the Free Software Foundation; either version 2 of the License, or
  13 * (at your option) any later version.
  14 *
  15 * This program is distributed in the hope that it will be useful,
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18 * GNU General Public License for more details.
  19 ******************************************************************************/
  20
  21#include <linux/ctype.h>
  22#include <scsi/iscsi_proto.h>
  23#include <target/target_core_base.h>
  24#include <target/target_core_fabric.h>
  25#include <target/iscsi/iscsi_transport.h>
  26
  27#include "iscsi_target_core.h"
  28#include "iscsi_target_parameters.h"
  29#include "iscsi_target_login.h"
  30#include "iscsi_target_nego.h"
  31#include "iscsi_target_tpg.h"
  32#include "iscsi_target_util.h"
  33#include "iscsi_target.h"
  34#include "iscsi_target_auth.h"
  35
  36#define MAX_LOGIN_PDUS  7
  37#define TEXT_LEN        4096
  38
  39void convert_null_to_semi(char *buf, int len)
  40{
  41        int i;
  42
  43        for (i = 0; i < len; i++)
  44                if (buf[i] == '\0')
  45                        buf[i] = ';';
  46}
  47
  48static int strlen_semi(char *buf)
  49{
  50        int i = 0;
  51
  52        while (buf[i] != '\0') {
  53                if (buf[i] == ';')
  54                        return i;
  55                i++;
  56        }
  57
  58        return -1;
  59}
  60
  61int extract_param(
  62        const char *in_buf,
  63        const char *pattern,
  64        unsigned int max_length,
  65        char *out_buf,
  66        unsigned char *type)
  67{
  68        char *ptr;
  69        int len;
  70
  71        if (!in_buf || !pattern || !out_buf || !type)
  72                return -1;
  73
  74        ptr = strstr(in_buf, pattern);
  75        if (!ptr)
  76                return -1;
  77
  78        ptr = strstr(ptr, "=");
  79        if (!ptr)
  80                return -1;
  81
  82        ptr += 1;
  83        if (*ptr == '0' && (*(ptr+1) == 'x' || *(ptr+1) == 'X')) {
  84                ptr += 2; /* skip 0x */
  85                *type = HEX;
  86        } else
  87                *type = DECIMAL;
  88
  89        len = strlen_semi(ptr);
  90        if (len < 0)
  91                return -1;
  92
  93        if (len > max_length) {
  94                pr_err("Length of input: %d exceeds max_length:"
  95                        " %d\n", len, max_length);
  96                return -1;
  97        }
  98        memcpy(out_buf, ptr, len);
  99        out_buf[len] = '\0';
 100
 101        return 0;
 102}
 103
 104static u32 iscsi_handle_authentication(
 105        struct iscsi_conn *conn,
 106        char *in_buf,
 107        char *out_buf,
 108        int in_length,
 109        int *out_length,
 110        unsigned char *authtype)
 111{
 112        struct iscsi_session *sess = conn->sess;
 113        struct iscsi_node_auth *auth;
 114        struct iscsi_node_acl *iscsi_nacl;
 115        struct iscsi_portal_group *iscsi_tpg;
 116        struct se_node_acl *se_nacl;
 117
 118        if (!sess->sess_ops->SessionType) {
 119                /*
 120                 * For SessionType=Normal
 121                 */
 122                se_nacl = conn->sess->se_sess->se_node_acl;
 123                if (!se_nacl) {
 124                        pr_err("Unable to locate struct se_node_acl for"
 125                                        " CHAP auth\n");
 126                        return -1;
 127                }
 128                iscsi_nacl = container_of(se_nacl, struct iscsi_node_acl,
 129                                se_node_acl);
 130                if (!iscsi_nacl) {
 131                        pr_err("Unable to locate struct iscsi_node_acl for"
 132                                        " CHAP auth\n");
 133                        return -1;
 134                }
 135
 136                if (se_nacl->dynamic_node_acl) {
 137                        iscsi_tpg = container_of(se_nacl->se_tpg,
 138                                        struct iscsi_portal_group, tpg_se_tpg);
 139
 140                        auth = &iscsi_tpg->tpg_demo_auth;
 141                } else {
 142                        iscsi_nacl = container_of(se_nacl, struct iscsi_node_acl,
 143                                                  se_node_acl);
 144
 145                        auth = ISCSI_NODE_AUTH(iscsi_nacl);
 146                }
 147        } else {
 148                /*
 149                 * For SessionType=Discovery
 150                 */
 151                auth = &iscsit_global->discovery_acl.node_auth;
 152        }
 153
 154        if (strstr("CHAP", authtype))
 155                strcpy(conn->sess->auth_type, "CHAP");
 156        else
 157                strcpy(conn->sess->auth_type, NONE);
 158
 159        if (strstr("None", authtype))
 160                return 1;
 161#ifdef CANSRP
 162        else if (strstr("SRP", authtype))
 163                return srp_main_loop(conn, auth, in_buf, out_buf,
 164                                &in_length, out_length);
 165#endif
 166        else if (strstr("CHAP", authtype))
 167                return chap_main_loop(conn, auth, in_buf, out_buf,
 168                                &in_length, out_length);
 169        else if (strstr("SPKM1", authtype))
 170                return 2;
 171        else if (strstr("SPKM2", authtype))
 172                return 2;
 173        else if (strstr("KRB5", authtype))
 174                return 2;
 175        else
 176                return 2;
 177}
 178
 179static void iscsi_remove_failed_auth_entry(struct iscsi_conn *conn)
 180{
 181        kfree(conn->auth_protocol);
 182}
 183
 184int iscsi_target_check_login_request(
 185        struct iscsi_conn *conn,
 186        struct iscsi_login *login)
 187{
 188        int req_csg, req_nsg;
 189        u32 payload_length;
 190        struct iscsi_login_req *login_req;
 191
 192        login_req = (struct iscsi_login_req *) login->req;
 193        payload_length = ntoh24(login_req->dlength);
 194
 195        switch (login_req->opcode & ISCSI_OPCODE_MASK) {
 196        case ISCSI_OP_LOGIN:
 197                break;
 198        default:
 199                pr_err("Received unknown opcode 0x%02x.\n",
 200                                login_req->opcode & ISCSI_OPCODE_MASK);
 201                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
 202                                ISCSI_LOGIN_STATUS_INIT_ERR);
 203                return -1;
 204        }
 205
 206        if ((login_req->flags & ISCSI_FLAG_LOGIN_CONTINUE) &&
 207            (login_req->flags & ISCSI_FLAG_LOGIN_TRANSIT)) {
 208                pr_err("Login request has both ISCSI_FLAG_LOGIN_CONTINUE"
 209                        " and ISCSI_FLAG_LOGIN_TRANSIT set, protocol error.\n");
 210                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
 211                                ISCSI_LOGIN_STATUS_INIT_ERR);
 212                return -1;
 213        }
 214
 215        req_csg = ISCSI_LOGIN_CURRENT_STAGE(login_req->flags);
 216        req_nsg = ISCSI_LOGIN_NEXT_STAGE(login_req->flags);
 217
 218        if (req_csg != login->current_stage) {
 219                pr_err("Initiator unexpectedly changed login stage"
 220                        " from %d to %d, login failed.\n", login->current_stage,
 221                        req_csg);
 222                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
 223                                ISCSI_LOGIN_STATUS_INIT_ERR);
 224                return -1;
 225        }
 226
 227        if ((req_nsg == 2) || (req_csg >= 2) ||
 228           ((login_req->flags & ISCSI_FLAG_LOGIN_TRANSIT) &&
 229            (req_nsg <= req_csg))) {
 230                pr_err("Illegal login_req->flags Combination, CSG: %d,"
 231                        " NSG: %d, ISCSI_FLAG_LOGIN_TRANSIT: %d.\n", req_csg,
 232                        req_nsg, (login_req->flags & ISCSI_FLAG_LOGIN_TRANSIT));
 233                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
 234                                ISCSI_LOGIN_STATUS_INIT_ERR);
 235                return -1;
 236        }
 237
 238        if ((login_req->max_version != login->version_max) ||
 239            (login_req->min_version != login->version_min)) {
 240                pr_err("Login request changed Version Max/Nin"
 241                        " unexpectedly to 0x%02x/0x%02x, protocol error\n",
 242                        login_req->max_version, login_req->min_version);
 243                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
 244                                ISCSI_LOGIN_STATUS_INIT_ERR);
 245                return -1;
 246        }
 247
 248        if (memcmp(login_req->isid, login->isid, 6) != 0) {
 249                pr_err("Login request changed ISID unexpectedly,"
 250                                " protocol error.\n");
 251                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
 252                                ISCSI_LOGIN_STATUS_INIT_ERR);
 253                return -1;
 254        }
 255
 256        if (login_req->itt != login->init_task_tag) {
 257                pr_err("Login request changed ITT unexpectedly to"
 258                        " 0x%08x, protocol error.\n", login_req->itt);
 259                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
 260                                ISCSI_LOGIN_STATUS_INIT_ERR);
 261                return -1;
 262        }
 263
 264        if (payload_length > MAX_KEY_VALUE_PAIRS) {
 265                pr_err("Login request payload exceeds default"
 266                        " MaxRecvDataSegmentLength: %u, protocol error.\n",
 267                                MAX_KEY_VALUE_PAIRS);
 268                return -1;
 269        }
 270
 271        return 0;
 272}
 273
 274static int iscsi_target_check_first_request(
 275        struct iscsi_conn *conn,
 276        struct iscsi_login *login)
 277{
 278        struct iscsi_param *param = NULL;
 279        struct se_node_acl *se_nacl;
 280
 281        login->first_request = 0;
 282
 283        list_for_each_entry(param, &conn->param_list->param_list, p_list) {
 284                if (!strncmp(param->name, SESSIONTYPE, 11)) {
 285                        if (!IS_PSTATE_ACCEPTOR(param)) {
 286                                pr_err("SessionType key not received"
 287                                        " in first login request.\n");
 288                                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
 289                                        ISCSI_LOGIN_STATUS_MISSING_FIELDS);
 290                                return -1;
 291                        }
 292                        if (!strncmp(param->value, DISCOVERY, 9))
 293                                return 0;
 294                }
 295
 296                if (!strncmp(param->name, INITIATORNAME, 13)) {
 297                        if (!IS_PSTATE_ACCEPTOR(param)) {
 298                                if (!login->leading_connection)
 299                                        continue;
 300
 301                                pr_err("InitiatorName key not received"
 302                                        " in first login request.\n");
 303                                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
 304                                        ISCSI_LOGIN_STATUS_MISSING_FIELDS);
 305                                return -1;
 306                        }
 307
 308                        /*
 309                         * For non-leading connections, double check that the
 310                         * received InitiatorName matches the existing session's
 311                         * struct iscsi_node_acl.
 312                         */
 313                        if (!login->leading_connection) {
 314                                se_nacl = conn->sess->se_sess->se_node_acl;
 315                                if (!se_nacl) {
 316                                        pr_err("Unable to locate"
 317                                                " struct se_node_acl\n");
 318                                        iscsit_tx_login_rsp(conn,
 319                                                        ISCSI_STATUS_CLS_INITIATOR_ERR,
 320                                                        ISCSI_LOGIN_STATUS_TGT_NOT_FOUND);
 321                                        return -1;
 322                                }
 323
 324                                if (strcmp(param->value,
 325                                                se_nacl->initiatorname)) {
 326                                        pr_err("Incorrect"
 327                                                " InitiatorName: %s for this"
 328                                                " iSCSI Initiator Node.\n",
 329                                                param->value);
 330                                        iscsit_tx_login_rsp(conn,
 331                                                        ISCSI_STATUS_CLS_INITIATOR_ERR,
 332                                                        ISCSI_LOGIN_STATUS_TGT_NOT_FOUND);
 333                                        return -1;
 334                                }
 335                        }
 336                }
 337        }
 338
 339        return 0;
 340}
 341
 342static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_login *login)
 343{
 344        u32 padding = 0;
 345        struct iscsi_session *sess = conn->sess;
 346        struct iscsi_login_rsp *login_rsp;
 347
 348        login_rsp = (struct iscsi_login_rsp *) login->rsp;
 349
 350        login_rsp->opcode               = ISCSI_OP_LOGIN_RSP;
 351        hton24(login_rsp->dlength, login->rsp_length);
 352        memcpy(login_rsp->isid, login->isid, 6);
 353        login_rsp->tsih                 = cpu_to_be16(login->tsih);
 354        login_rsp->itt                  = login->init_task_tag;
 355        login_rsp->statsn               = cpu_to_be32(conn->stat_sn++);
 356        login_rsp->exp_cmdsn            = cpu_to_be32(conn->sess->exp_cmd_sn);
 357        login_rsp->max_cmdsn            = cpu_to_be32(conn->sess->max_cmd_sn);
 358
 359        pr_debug("Sending Login Response, Flags: 0x%02x, ITT: 0x%08x,"
 360                " ExpCmdSN; 0x%08x, MaxCmdSN: 0x%08x, StatSN: 0x%08x, Length:"
 361                " %u\n", login_rsp->flags, (__force u32)login_rsp->itt,
 362                ntohl(login_rsp->exp_cmdsn), ntohl(login_rsp->max_cmdsn),
 363                ntohl(login_rsp->statsn), login->rsp_length);
 364
 365        padding = ((-login->rsp_length) & 3);
 366
 367        if (conn->conn_transport->iscsit_put_login_tx(conn, login,
 368                                        login->rsp_length + padding) < 0)
 369                return -1;
 370
 371        login->rsp_length               = 0;
 372        mutex_lock(&sess->cmdsn_mutex);
 373        login_rsp->exp_cmdsn            = cpu_to_be32(sess->exp_cmd_sn);
 374        login_rsp->max_cmdsn            = cpu_to_be32(sess->max_cmd_sn);
 375        mutex_unlock(&sess->cmdsn_mutex);
 376
 377        return 0;
 378}
 379
 380static int iscsi_target_do_login_io(struct iscsi_conn *conn, struct iscsi_login *login)
 381{
 382        if (iscsi_target_do_tx_login_io(conn, login) < 0)
 383                return -1;
 384
 385        if (conn->conn_transport->iscsit_get_login_rx(conn, login) < 0)
 386                return -1;
 387
 388        return 0;
 389}
 390
 391/*
 392 *      NOTE: We check for existing sessions or connections AFTER the initiator
 393 *      has been successfully authenticated in order to protect against faked
 394 *      ISID/TSIH combinations.
 395 */
 396static int iscsi_target_check_for_existing_instances(
 397        struct iscsi_conn *conn,
 398        struct iscsi_login *login)
 399{
 400        if (login->checked_for_existing)
 401                return 0;
 402
 403        login->checked_for_existing = 1;
 404
 405        if (!login->tsih)
 406                return iscsi_check_for_session_reinstatement(conn);
 407        else
 408                return iscsi_login_post_auth_non_zero_tsih(conn, login->cid,
 409                                login->initial_exp_statsn);
 410}
 411
 412static int iscsi_target_do_authentication(
 413        struct iscsi_conn *conn,
 414        struct iscsi_login *login)
 415{
 416        int authret;
 417        u32 payload_length;
 418        struct iscsi_param *param;
 419        struct iscsi_login_req *login_req;
 420        struct iscsi_login_rsp *login_rsp;
 421
 422        login_req = (struct iscsi_login_req *) login->req;
 423        login_rsp = (struct iscsi_login_rsp *) login->rsp;
 424        payload_length = ntoh24(login_req->dlength);
 425
 426        param = iscsi_find_param_from_key(AUTHMETHOD, conn->param_list);
 427        if (!param)
 428                return -1;
 429
 430        authret = iscsi_handle_authentication(
 431                        conn,
 432                        login->req_buf,
 433                        login->rsp_buf,
 434                        payload_length,
 435                        &login->rsp_length,
 436                        param->value);
 437        switch (authret) {
 438        case 0:
 439                pr_debug("Received OK response"
 440                " from LIO Authentication, continuing.\n");
 441                break;
 442        case 1:
 443                pr_debug("iSCSI security negotiation"
 444                        " completed successfully.\n");
 445                login->auth_complete = 1;
 446                if ((login_req->flags & ISCSI_FLAG_LOGIN_NEXT_STAGE1) &&
 447                    (login_req->flags & ISCSI_FLAG_LOGIN_TRANSIT)) {
 448                        login_rsp->flags |= (ISCSI_FLAG_LOGIN_NEXT_STAGE1 |
 449                                             ISCSI_FLAG_LOGIN_TRANSIT);
 450                        login->current_stage = 1;
 451                }
 452                return iscsi_target_check_for_existing_instances(
 453                                conn, login);
 454        case 2:
 455                pr_err("Security negotiation"
 456                        " failed.\n");
 457                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
 458                                ISCSI_LOGIN_STATUS_AUTH_FAILED);
 459                return -1;
 460        default:
 461                pr_err("Received unknown error %d from LIO"
 462                                " Authentication\n", authret);
 463                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
 464                                ISCSI_LOGIN_STATUS_TARGET_ERROR);
 465                return -1;
 466        }
 467
 468        return 0;
 469}
 470
 471static int iscsi_target_handle_csg_zero(
 472        struct iscsi_conn *conn,
 473        struct iscsi_login *login)
 474{
 475        int ret;
 476        u32 payload_length;
 477        struct iscsi_param *param;
 478        struct iscsi_login_req *login_req;
 479        struct iscsi_login_rsp *login_rsp;
 480
 481        login_req = (struct iscsi_login_req *) login->req;
 482        login_rsp = (struct iscsi_login_rsp *) login->rsp;
 483        payload_length = ntoh24(login_req->dlength);
 484
 485        param = iscsi_find_param_from_key(AUTHMETHOD, conn->param_list);
 486        if (!param)
 487                return -1;
 488
 489        ret = iscsi_decode_text_input(
 490                        PHASE_SECURITY|PHASE_DECLARATIVE,
 491                        SENDER_INITIATOR|SENDER_RECEIVER,
 492                        login->req_buf,
 493                        payload_length,
 494                        conn);
 495        if (ret < 0)
 496                return -1;
 497
 498        if (ret > 0) {
 499                if (login->auth_complete) {
 500                        pr_err("Initiator has already been"
 501                                " successfully authenticated, but is still"
 502                                " sending %s keys.\n", param->value);
 503                        iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
 504                                        ISCSI_LOGIN_STATUS_INIT_ERR);
 505                        return -1;
 506                }
 507
 508                goto do_auth;
 509        }
 510
 511        if (login->first_request)
 512                if (iscsi_target_check_first_request(conn, login) < 0)
 513                        return -1;
 514
 515        ret = iscsi_encode_text_output(
 516                        PHASE_SECURITY|PHASE_DECLARATIVE,
 517                        SENDER_TARGET,
 518                        login->rsp_buf,
 519                        &login->rsp_length,
 520                        conn->param_list);
 521        if (ret < 0)
 522                return -1;
 523
 524        if (!iscsi_check_negotiated_keys(conn->param_list)) {
 525                if (ISCSI_TPG_ATTRIB(ISCSI_TPG_C(conn))->authentication &&
 526                    !strncmp(param->value, NONE, 4)) {
 527                        pr_err("Initiator sent AuthMethod=None but"
 528                                " Target is enforcing iSCSI Authentication,"
 529                                        " login failed.\n");
 530                        iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
 531                                        ISCSI_LOGIN_STATUS_AUTH_FAILED);
 532                        return -1;
 533                }
 534
 535                if (ISCSI_TPG_ATTRIB(ISCSI_TPG_C(conn))->authentication &&
 536                    !login->auth_complete)
 537                        return 0;
 538
 539                if (strncmp(param->value, NONE, 4) && !login->auth_complete)
 540                        return 0;
 541
 542                if ((login_req->flags & ISCSI_FLAG_LOGIN_NEXT_STAGE1) &&
 543                    (login_req->flags & ISCSI_FLAG_LOGIN_TRANSIT)) {
 544                        login_rsp->flags |= ISCSI_FLAG_LOGIN_NEXT_STAGE1 |
 545                                            ISCSI_FLAG_LOGIN_TRANSIT;
 546                        login->current_stage = 1;
 547                }
 548        }
 549
 550        return 0;
 551do_auth:
 552        return iscsi_target_do_authentication(conn, login);
 553}
 554
 555static int iscsi_target_handle_csg_one(struct iscsi_conn *conn, struct iscsi_login *login)
 556{
 557        int ret;
 558        u32 payload_length;
 559        struct iscsi_login_req *login_req;
 560        struct iscsi_login_rsp *login_rsp;
 561
 562        login_req = (struct iscsi_login_req *) login->req;
 563        login_rsp = (struct iscsi_login_rsp *) login->rsp;
 564        payload_length = ntoh24(login_req->dlength);
 565
 566        ret = iscsi_decode_text_input(
 567                        PHASE_OPERATIONAL|PHASE_DECLARATIVE,
 568                        SENDER_INITIATOR|SENDER_RECEIVER,
 569                        login->req_buf,
 570                        payload_length,
 571                        conn);
 572        if (ret < 0) {
 573                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
 574                                ISCSI_LOGIN_STATUS_INIT_ERR);
 575                return -1;
 576        }
 577
 578        if (login->first_request)
 579                if (iscsi_target_check_first_request(conn, login) < 0)
 580                        return -1;
 581
 582        if (iscsi_target_check_for_existing_instances(conn, login) < 0)
 583                return -1;
 584
 585        ret = iscsi_encode_text_output(
 586                        PHASE_OPERATIONAL|PHASE_DECLARATIVE,
 587                        SENDER_TARGET,
 588                        login->rsp_buf,
 589                        &login->rsp_length,
 590                        conn->param_list);
 591        if (ret < 0) {
 592                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
 593                                ISCSI_LOGIN_STATUS_INIT_ERR);
 594                return -1;
 595        }
 596
 597        if (!login->auth_complete &&
 598             ISCSI_TPG_ATTRIB(ISCSI_TPG_C(conn))->authentication) {
 599                pr_err("Initiator is requesting CSG: 1, has not been"
 600                         " successfully authenticated, and the Target is"
 601                        " enforcing iSCSI Authentication, login failed.\n");
 602                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
 603                                ISCSI_LOGIN_STATUS_AUTH_FAILED);
 604                return -1;
 605        }
 606
 607        if (!iscsi_check_negotiated_keys(conn->param_list))
 608                if ((login_req->flags & ISCSI_FLAG_LOGIN_NEXT_STAGE3) &&
 609                    (login_req->flags & ISCSI_FLAG_LOGIN_TRANSIT))
 610                        login_rsp->flags |= ISCSI_FLAG_LOGIN_NEXT_STAGE3 |
 611                                            ISCSI_FLAG_LOGIN_TRANSIT;
 612
 613        return 0;
 614}
 615
 616static int iscsi_target_do_login(struct iscsi_conn *conn, struct iscsi_login *login)
 617{
 618        int pdu_count = 0;
 619        struct iscsi_login_req *login_req;
 620        struct iscsi_login_rsp *login_rsp;
 621
 622        login_req = (struct iscsi_login_req *) login->req;
 623        login_rsp = (struct iscsi_login_rsp *) login->rsp;
 624
 625        while (1) {
 626                if (++pdu_count > MAX_LOGIN_PDUS) {
 627                        pr_err("MAX_LOGIN_PDUS count reached.\n");
 628                        iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
 629                                        ISCSI_LOGIN_STATUS_TARGET_ERROR);
 630                        return -1;
 631                }
 632
 633                switch (ISCSI_LOGIN_CURRENT_STAGE(login_req->flags)) {
 634                case 0:
 635                        login_rsp->flags &= ~ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK;
 636                        if (iscsi_target_handle_csg_zero(conn, login) < 0)
 637                                return -1;
 638                        break;
 639                case 1:
 640                        login_rsp->flags |= ISCSI_FLAG_LOGIN_CURRENT_STAGE1;
 641                        if (iscsi_target_handle_csg_one(conn, login) < 0)
 642                                return -1;
 643                        if (login_rsp->flags & ISCSI_FLAG_LOGIN_TRANSIT) {
 644                                login->tsih = conn->sess->tsih;
 645                                login->login_complete = 1;
 646                                if (iscsi_target_do_tx_login_io(conn,
 647                                                login) < 0)
 648                                        return -1;
 649                                return 0;
 650                        }
 651                        break;
 652                default:
 653                        pr_err("Illegal CSG: %d received from"
 654                                " Initiator, protocol error.\n",
 655                                ISCSI_LOGIN_CURRENT_STAGE(login_req->flags));
 656                        break;
 657                }
 658
 659                if (iscsi_target_do_login_io(conn, login) < 0)
 660                        return -1;
 661
 662                if (login_rsp->flags & ISCSI_FLAG_LOGIN_TRANSIT) {
 663                        login_rsp->flags &= ~ISCSI_FLAG_LOGIN_TRANSIT;
 664                        login_rsp->flags &= ~ISCSI_FLAG_LOGIN_NEXT_STAGE_MASK;
 665                }
 666        }
 667
 668        return 0;
 669}
 670
 671static void iscsi_initiatorname_tolower(
 672        char *param_buf)
 673{
 674        char *c;
 675        u32 iqn_size = strlen(param_buf), i;
 676
 677        for (i = 0; i < iqn_size; i++) {
 678                c = &param_buf[i];
 679                if (!isupper(*c))
 680                        continue;
 681
 682                *c = tolower(*c);
 683        }
 684}
 685
 686/*
 687 * Processes the first Login Request..
 688 */
 689int iscsi_target_locate_portal(
 690        struct iscsi_np *np,
 691        struct iscsi_conn *conn,
 692        struct iscsi_login *login)
 693{
 694        char *i_buf = NULL, *s_buf = NULL, *t_buf = NULL;
 695        char *tmpbuf, *start = NULL, *end = NULL, *key, *value;
 696        struct iscsi_session *sess = conn->sess;
 697        struct iscsi_tiqn *tiqn;
 698        struct iscsi_login_req *login_req;
 699        u32 payload_length;
 700        int sessiontype = 0, ret = 0;
 701
 702        login_req = (struct iscsi_login_req *) login->req;
 703        payload_length = ntoh24(login_req->dlength);
 704
 705        tmpbuf = kzalloc(payload_length + 1, GFP_KERNEL);
 706        if (!tmpbuf) {
 707                pr_err("Unable to allocate memory for tmpbuf.\n");
 708                return -1;
 709        }
 710
 711        memcpy(tmpbuf, login->req_buf, payload_length);
 712        tmpbuf[payload_length] = '\0';
 713        start = tmpbuf;
 714        end = (start + payload_length);
 715
 716        /*
 717         * Locate the initial keys expected from the Initiator node in
 718         * the first login request in order to progress with the login phase.
 719         */
 720        while (start < end) {
 721                if (iscsi_extract_key_value(start, &key, &value) < 0) {
 722                        ret = -1;
 723                        goto out;
 724                }
 725
 726                if (!strncmp(key, "InitiatorName", 13))
 727                        i_buf = value;
 728                else if (!strncmp(key, "SessionType", 11))
 729                        s_buf = value;
 730                else if (!strncmp(key, "TargetName", 10))
 731                        t_buf = value;
 732
 733                start += strlen(key) + strlen(value) + 2;
 734        }
 735        /*
 736         * See 5.3.  Login Phase.
 737         */
 738        if (!i_buf) {
 739                pr_err("InitiatorName key not received"
 740                        " in first login request.\n");
 741                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
 742                        ISCSI_LOGIN_STATUS_MISSING_FIELDS);
 743                ret = -1;
 744                goto out;
 745        }
 746        /*
 747         * Convert the incoming InitiatorName to lowercase following
 748         * RFC-3720 3.2.6.1. section c) that says that iSCSI IQNs
 749         * are NOT case sensitive.
 750         */
 751        iscsi_initiatorname_tolower(i_buf);
 752
 753        if (!s_buf) {
 754                if (!login->leading_connection)
 755                        goto get_target;
 756
 757                pr_err("SessionType key not received"
 758                        " in first login request.\n");
 759                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
 760                        ISCSI_LOGIN_STATUS_MISSING_FIELDS);
 761                ret = -1;
 762                goto out;
 763        }
 764
 765        /*
 766         * Use default portal group for discovery sessions.
 767         */
 768        sessiontype = strncmp(s_buf, DISCOVERY, 9);
 769        if (!sessiontype) {
 770                conn->tpg = iscsit_global->discovery_tpg;
 771                if (!login->leading_connection)
 772                        goto get_target;
 773
 774                sess->sess_ops->SessionType = 1;
 775                /*
 776                 * Setup crc32c modules from libcrypto
 777                 */
 778                if (iscsi_login_setup_crypto(conn) < 0) {
 779                        pr_err("iscsi_login_setup_crypto() failed\n");
 780                        ret = -1;
 781                        goto out;
 782                }
 783                /*
 784                 * Serialize access across the discovery struct iscsi_portal_group to
 785                 * process login attempt.
 786                 */
 787                if (iscsit_access_np(np, conn->tpg) < 0) {
 788                        iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
 789                                ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE);
 790                        ret = -1;
 791                        goto out;
 792                }
 793                ret = 0;
 794                goto out;
 795        }
 796
 797get_target:
 798        if (!t_buf) {
 799                pr_err("TargetName key not received"
 800                        " in first login request while"
 801                        " SessionType=Normal.\n");
 802                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
 803                        ISCSI_LOGIN_STATUS_MISSING_FIELDS);
 804                ret = -1;
 805                goto out;
 806        }
 807
 808        /*
 809         * Locate Target IQN from Storage Node.
 810         */
 811        tiqn = iscsit_get_tiqn_for_login(t_buf);
 812        if (!tiqn) {
 813                pr_err("Unable to locate Target IQN: %s in"
 814                        " Storage Node\n", t_buf);
 815                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
 816                                ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE);
 817                ret = -1;
 818                goto out;
 819        }
 820        pr_debug("Located Storage Object: %s\n", tiqn->tiqn);
 821
 822        /*
 823         * Locate Target Portal Group from Storage Node.
 824         */
 825        conn->tpg = iscsit_get_tpg_from_np(tiqn, np);
 826        if (!conn->tpg) {
 827                pr_err("Unable to locate Target Portal Group"
 828                                " on %s\n", tiqn->tiqn);
 829                iscsit_put_tiqn_for_login(tiqn);
 830                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
 831                                ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE);
 832                ret = -1;
 833                goto out;
 834        }
 835        pr_debug("Located Portal Group Object: %hu\n", conn->tpg->tpgt);
 836        /*
 837         * Setup crc32c modules from libcrypto
 838         */
 839        if (iscsi_login_setup_crypto(conn) < 0) {
 840                pr_err("iscsi_login_setup_crypto() failed\n");
 841                ret = -1;
 842                goto out;
 843        }
 844        /*
 845         * Serialize access across the struct iscsi_portal_group to
 846         * process login attempt.
 847         */
 848        if (iscsit_access_np(np, conn->tpg) < 0) {
 849                iscsit_put_tiqn_for_login(tiqn);
 850                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
 851                                ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE);
 852                ret = -1;
 853                conn->tpg = NULL;
 854                goto out;
 855        }
 856
 857        /*
 858         * conn->sess->node_acl will be set when the referenced
 859         * struct iscsi_session is located from received ISID+TSIH in
 860         * iscsi_login_non_zero_tsih_s2().
 861         */
 862        if (!login->leading_connection) {
 863                ret = 0;
 864                goto out;
 865        }
 866
 867        /*
 868         * This value is required in iscsi_login_zero_tsih_s2()
 869         */
 870        sess->sess_ops->SessionType = 0;
 871
 872        /*
 873         * Locate incoming Initiator IQN reference from Storage Node.
 874         */
 875        sess->se_sess->se_node_acl = core_tpg_check_initiator_node_acl(
 876                        &conn->tpg->tpg_se_tpg, i_buf);
 877        if (!sess->se_sess->se_node_acl) {
 878                pr_err("iSCSI Initiator Node: %s is not authorized to"
 879                        " access iSCSI target portal group: %hu.\n",
 880                                i_buf, conn->tpg->tpgt);
 881                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
 882                                ISCSI_LOGIN_STATUS_TGT_FORBIDDEN);
 883                ret = -1;
 884                goto out;
 885        }
 886
 887        ret = 0;
 888out:
 889        kfree(tmpbuf);
 890        return ret;
 891}
 892
 893int iscsi_target_start_negotiation(
 894        struct iscsi_login *login,
 895        struct iscsi_conn *conn)
 896{
 897        int ret;
 898
 899        ret = iscsi_target_do_login(conn, login);
 900        if (ret != 0)
 901                iscsi_remove_failed_auth_entry(conn);
 902
 903        iscsi_target_nego_release(conn);
 904        return ret;
 905}
 906
 907void iscsi_target_nego_release(struct iscsi_conn *conn)
 908{
 909        struct iscsi_login *login = conn->conn_login;
 910
 911        if (!login)
 912                return;
 913
 914        kfree(login->req_buf);
 915        kfree(login->rsp_buf);
 916        kfree(login);
 917
 918        conn->conn_login = NULL;
 919}
 920