1 /******************************************************************************* 2 * This file contains main functions related to iSCSI Parameter negotiation. 3 * 4 * (c) Copyright 2007-2013 Datera, Inc. 5 * 6 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 ******************************************************************************/ 18 19 #include <linux/ctype.h> 20 #include <linux/kthread.h> 21 #include <scsi/iscsi_proto.h> 22 #include <target/target_core_base.h> 23 #include <target/target_core_fabric.h> 24 #include <target/iscsi/iscsi_transport.h> 25 26 #include <target/iscsi/iscsi_target_core.h> 27 #include "iscsi_target_parameters.h" 28 #include "iscsi_target_login.h" 29 #include "iscsi_target_nego.h" 30 #include "iscsi_target_tpg.h" 31 #include "iscsi_target_util.h" 32 #include "iscsi_target.h" 33 #include "iscsi_target_auth.h" 34 35 #define MAX_LOGIN_PDUS 7 36 #define TEXT_LEN 4096 37 38 void convert_null_to_semi(char *buf, int len) 39 { 40 int i; 41 42 for (i = 0; i < len; i++) 43 if (buf[i] == '\0') 44 buf[i] = ';'; 45 } 46 47 static int strlen_semi(char *buf) 48 { 49 int i = 0; 50 51 while (buf[i] != '\0') { 52 if (buf[i] == ';') 53 return i; 54 i++; 55 } 56 57 return -1; 58 } 59 60 int extract_param( 61 const char *in_buf, 62 const char *pattern, 63 unsigned int max_length, 64 char *out_buf, 65 unsigned char *type) 66 { 67 char *ptr; 68 int len; 69 70 if (!in_buf || !pattern || !out_buf || !type) 71 return -1; 72 73 ptr = strstr(in_buf, pattern); 74 if (!ptr) 75 return -1; 76 77 ptr = strstr(ptr, "="); 78 if (!ptr) 79 return -1; 80 81 ptr += 1; 82 if (*ptr == '0' && (*(ptr+1) == 'x' || *(ptr+1) == 'X')) { 83 ptr += 2; /* skip 0x */ 84 *type = HEX; 85 } else 86 *type = DECIMAL; 87 88 len = strlen_semi(ptr); 89 if (len < 0) 90 return -1; 91 92 if (len >= max_length) { 93 pr_err("Length of input: %d exceeds max_length:" 94 " %d\n", len, max_length); 95 return -1; 96 } 97 memcpy(out_buf, ptr, len); 98 out_buf[len] = '\0'; 99 100 return 0; 101 } 102 103 static u32 iscsi_handle_authentication( 104 struct iscsi_conn *conn, 105 char *in_buf, 106 char *out_buf, 107 int in_length, 108 int *out_length, 109 unsigned char *authtype) 110 { 111 struct iscsi_session *sess = conn->sess; 112 struct iscsi_node_auth *auth; 113 struct iscsi_node_acl *iscsi_nacl; 114 struct iscsi_portal_group *iscsi_tpg; 115 struct se_node_acl *se_nacl; 116 117 if (!sess->sess_ops->SessionType) { 118 /* 119 * For SessionType=Normal 120 */ 121 se_nacl = conn->sess->se_sess->se_node_acl; 122 if (!se_nacl) { 123 pr_err("Unable to locate struct se_node_acl for" 124 " CHAP auth\n"); 125 return -1; 126 } 127 iscsi_nacl = container_of(se_nacl, struct iscsi_node_acl, 128 se_node_acl); 129 if (!iscsi_nacl) { 130 pr_err("Unable to locate struct iscsi_node_acl for" 131 " CHAP auth\n"); 132 return -1; 133 } 134 135 if (se_nacl->dynamic_node_acl) { 136 iscsi_tpg = container_of(se_nacl->se_tpg, 137 struct iscsi_portal_group, tpg_se_tpg); 138 139 auth = &iscsi_tpg->tpg_demo_auth; 140 } else { 141 iscsi_nacl = container_of(se_nacl, struct iscsi_node_acl, 142 se_node_acl); 143 144 auth = &iscsi_nacl->node_auth; 145 } 146 } else { 147 /* 148 * For SessionType=Discovery 149 */ 150 auth = &iscsit_global->discovery_acl.node_auth; 151 } 152 153 if (strstr("CHAP", authtype)) 154 strcpy(conn->sess->auth_type, "CHAP"); 155 else 156 strcpy(conn->sess->auth_type, NONE); 157 158 if (strstr("None", authtype)) 159 return 1; 160 #ifdef CANSRP 161 else if (strstr("SRP", authtype)) 162 return srp_main_loop(conn, auth, in_buf, out_buf, 163 &in_length, out_length); 164 #endif 165 else if (strstr("CHAP", authtype)) 166 return chap_main_loop(conn, auth, in_buf, out_buf, 167 &in_length, out_length); 168 else if (strstr("SPKM1", authtype)) 169 return 2; 170 else if (strstr("SPKM2", authtype)) 171 return 2; 172 else if (strstr("KRB5", authtype)) 173 return 2; 174 else 175 return 2; 176 } 177 178 static void iscsi_remove_failed_auth_entry(struct iscsi_conn *conn) 179 { 180 kfree(conn->auth_protocol); 181 } 182 183 int iscsi_target_check_login_request( 184 struct iscsi_conn *conn, 185 struct iscsi_login *login) 186 { 187 int req_csg, req_nsg; 188 u32 payload_length; 189 struct iscsi_login_req *login_req; 190 191 login_req = (struct iscsi_login_req *) login->req; 192 payload_length = ntoh24(login_req->dlength); 193 194 switch (login_req->opcode & ISCSI_OPCODE_MASK) { 195 case ISCSI_OP_LOGIN: 196 break; 197 default: 198 pr_err("Received unknown opcode 0x%02x.\n", 199 login_req->opcode & ISCSI_OPCODE_MASK); 200 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, 201 ISCSI_LOGIN_STATUS_INIT_ERR); 202 return -1; 203 } 204 205 if ((login_req->flags & ISCSI_FLAG_LOGIN_CONTINUE) && 206 (login_req->flags & ISCSI_FLAG_LOGIN_TRANSIT)) { 207 pr_err("Login request has both ISCSI_FLAG_LOGIN_CONTINUE" 208 " and ISCSI_FLAG_LOGIN_TRANSIT set, protocol error.\n"); 209 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, 210 ISCSI_LOGIN_STATUS_INIT_ERR); 211 return -1; 212 } 213 214 req_csg = ISCSI_LOGIN_CURRENT_STAGE(login_req->flags); 215 req_nsg = ISCSI_LOGIN_NEXT_STAGE(login_req->flags); 216 217 if (req_csg != login->current_stage) { 218 pr_err("Initiator unexpectedly changed login stage" 219 " from %d to %d, login failed.\n", login->current_stage, 220 req_csg); 221 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, 222 ISCSI_LOGIN_STATUS_INIT_ERR); 223 return -1; 224 } 225 226 if ((req_nsg == 2) || (req_csg >= 2) || 227 ((login_req->flags & ISCSI_FLAG_LOGIN_TRANSIT) && 228 (req_nsg <= req_csg))) { 229 pr_err("Illegal login_req->flags Combination, CSG: %d," 230 " NSG: %d, ISCSI_FLAG_LOGIN_TRANSIT: %d.\n", req_csg, 231 req_nsg, (login_req->flags & ISCSI_FLAG_LOGIN_TRANSIT)); 232 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, 233 ISCSI_LOGIN_STATUS_INIT_ERR); 234 return -1; 235 } 236 237 if ((login_req->max_version != login->version_max) || 238 (login_req->min_version != login->version_min)) { 239 pr_err("Login request changed Version Max/Nin" 240 " unexpectedly to 0x%02x/0x%02x, protocol error\n", 241 login_req->max_version, login_req->min_version); 242 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, 243 ISCSI_LOGIN_STATUS_INIT_ERR); 244 return -1; 245 } 246 247 if (memcmp(login_req->isid, login->isid, 6) != 0) { 248 pr_err("Login request changed ISID unexpectedly," 249 " protocol error.\n"); 250 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, 251 ISCSI_LOGIN_STATUS_INIT_ERR); 252 return -1; 253 } 254 255 if (login_req->itt != login->init_task_tag) { 256 pr_err("Login request changed ITT unexpectedly to" 257 " 0x%08x, protocol error.\n", login_req->itt); 258 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, 259 ISCSI_LOGIN_STATUS_INIT_ERR); 260 return -1; 261 } 262 263 if (payload_length > MAX_KEY_VALUE_PAIRS) { 264 pr_err("Login request payload exceeds default" 265 " MaxRecvDataSegmentLength: %u, protocol error.\n", 266 MAX_KEY_VALUE_PAIRS); 267 return -1; 268 } 269 270 return 0; 271 } 272 EXPORT_SYMBOL(iscsi_target_check_login_request); 273 274 static 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 342 static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_login *login) 343 { 344 u32 padding = 0; 345 struct iscsi_login_rsp *login_rsp; 346 347 login_rsp = (struct iscsi_login_rsp *) login->rsp; 348 349 login_rsp->opcode = ISCSI_OP_LOGIN_RSP; 350 hton24(login_rsp->dlength, login->rsp_length); 351 memcpy(login_rsp->isid, login->isid, 6); 352 login_rsp->tsih = cpu_to_be16(login->tsih); 353 login_rsp->itt = login->init_task_tag; 354 login_rsp->statsn = cpu_to_be32(conn->stat_sn++); 355 login_rsp->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); 356 login_rsp->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn)); 357 358 pr_debug("Sending Login Response, Flags: 0x%02x, ITT: 0x%08x," 359 " ExpCmdSN; 0x%08x, MaxCmdSN: 0x%08x, StatSN: 0x%08x, Length:" 360 " %u\n", login_rsp->flags, (__force u32)login_rsp->itt, 361 ntohl(login_rsp->exp_cmdsn), ntohl(login_rsp->max_cmdsn), 362 ntohl(login_rsp->statsn), login->rsp_length); 363 364 padding = ((-login->rsp_length) & 3); 365 /* 366 * Before sending the last login response containing the transition 367 * bit for full-feature-phase, go ahead and start up TX/RX threads 368 * now to avoid potential resource allocation failures after the 369 * final login response has been sent. 370 */ 371 if (login->login_complete) { 372 int rc = iscsit_start_kthreads(conn); 373 if (rc) { 374 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, 375 ISCSI_LOGIN_STATUS_NO_RESOURCES); 376 return -1; 377 } 378 } 379 380 if (conn->conn_transport->iscsit_put_login_tx(conn, login, 381 login->rsp_length + padding) < 0) 382 goto err; 383 384 login->rsp_length = 0; 385 386 return 0; 387 388 err: 389 if (login->login_complete) { 390 if (conn->rx_thread && conn->rx_thread_active) { 391 send_sig(SIGINT, conn->rx_thread, 1); 392 complete(&conn->rx_login_comp); 393 kthread_stop(conn->rx_thread); 394 } 395 if (conn->tx_thread && conn->tx_thread_active) { 396 send_sig(SIGINT, conn->tx_thread, 1); 397 kthread_stop(conn->tx_thread); 398 } 399 spin_lock(&iscsit_global->ts_bitmap_lock); 400 bitmap_release_region(iscsit_global->ts_bitmap, conn->bitmap_id, 401 get_order(1)); 402 spin_unlock(&iscsit_global->ts_bitmap_lock); 403 } 404 return -1; 405 } 406 407 static void iscsi_target_sk_data_ready(struct sock *sk) 408 { 409 struct iscsi_conn *conn = sk->sk_user_data; 410 bool rc; 411 412 pr_debug("Entering iscsi_target_sk_data_ready: conn: %p\n", conn); 413 414 write_lock_bh(&sk->sk_callback_lock); 415 if (!sk->sk_user_data) { 416 write_unlock_bh(&sk->sk_callback_lock); 417 return; 418 } 419 if (!test_bit(LOGIN_FLAGS_READY, &conn->login_flags)) { 420 write_unlock_bh(&sk->sk_callback_lock); 421 pr_debug("Got LOGIN_FLAGS_READY=0, conn: %p >>>>\n", conn); 422 return; 423 } 424 if (test_bit(LOGIN_FLAGS_CLOSED, &conn->login_flags)) { 425 write_unlock_bh(&sk->sk_callback_lock); 426 pr_debug("Got LOGIN_FLAGS_CLOSED=1, conn: %p >>>>\n", conn); 427 return; 428 } 429 if (test_and_set_bit(LOGIN_FLAGS_READ_ACTIVE, &conn->login_flags)) { 430 write_unlock_bh(&sk->sk_callback_lock); 431 pr_debug("Got LOGIN_FLAGS_READ_ACTIVE=1, conn: %p >>>>\n", conn); 432 return; 433 } 434 435 rc = schedule_delayed_work(&conn->login_work, 0); 436 if (!rc) { 437 pr_debug("iscsi_target_sk_data_ready, schedule_delayed_work" 438 " got false\n"); 439 } 440 write_unlock_bh(&sk->sk_callback_lock); 441 } 442 443 static void iscsi_target_sk_state_change(struct sock *); 444 445 static void iscsi_target_set_sock_callbacks(struct iscsi_conn *conn) 446 { 447 struct sock *sk; 448 449 if (!conn->sock) 450 return; 451 452 sk = conn->sock->sk; 453 pr_debug("Entering iscsi_target_set_sock_callbacks: conn: %p\n", conn); 454 455 write_lock_bh(&sk->sk_callback_lock); 456 sk->sk_user_data = conn; 457 conn->orig_data_ready = sk->sk_data_ready; 458 conn->orig_state_change = sk->sk_state_change; 459 sk->sk_data_ready = iscsi_target_sk_data_ready; 460 sk->sk_state_change = iscsi_target_sk_state_change; 461 write_unlock_bh(&sk->sk_callback_lock); 462 463 sk->sk_sndtimeo = TA_LOGIN_TIMEOUT * HZ; 464 sk->sk_rcvtimeo = TA_LOGIN_TIMEOUT * HZ; 465 } 466 467 static void iscsi_target_restore_sock_callbacks(struct iscsi_conn *conn) 468 { 469 struct sock *sk; 470 471 if (!conn->sock) 472 return; 473 474 sk = conn->sock->sk; 475 pr_debug("Entering iscsi_target_restore_sock_callbacks: conn: %p\n", conn); 476 477 write_lock_bh(&sk->sk_callback_lock); 478 if (!sk->sk_user_data) { 479 write_unlock_bh(&sk->sk_callback_lock); 480 return; 481 } 482 sk->sk_user_data = NULL; 483 sk->sk_data_ready = conn->orig_data_ready; 484 sk->sk_state_change = conn->orig_state_change; 485 write_unlock_bh(&sk->sk_callback_lock); 486 487 sk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT; 488 sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT; 489 } 490 491 static int iscsi_target_do_login(struct iscsi_conn *, struct iscsi_login *); 492 493 static bool iscsi_target_sk_state_check(struct sock *sk) 494 { 495 if (sk->sk_state == TCP_CLOSE_WAIT || sk->sk_state == TCP_CLOSE) { 496 pr_debug("iscsi_target_sk_state_check: TCP_CLOSE_WAIT|TCP_CLOSE," 497 "returning FALSE\n"); 498 return false; 499 } 500 return true; 501 } 502 503 static void iscsi_target_login_drop(struct iscsi_conn *conn, struct iscsi_login *login) 504 { 505 struct iscsi_np *np = login->np; 506 bool zero_tsih = login->zero_tsih; 507 508 iscsi_remove_failed_auth_entry(conn); 509 iscsi_target_nego_release(conn); 510 iscsi_target_login_sess_out(conn, np, zero_tsih, true); 511 } 512 513 static void iscsi_target_login_timeout(unsigned long data) 514 { 515 struct iscsi_conn *conn = (struct iscsi_conn *)data; 516 517 pr_debug("Entering iscsi_target_login_timeout >>>>>>>>>>>>>>>>>>>\n"); 518 519 if (conn->login_kworker) { 520 pr_debug("Sending SIGINT to conn->login_kworker %s/%d\n", 521 conn->login_kworker->comm, conn->login_kworker->pid); 522 send_sig(SIGINT, conn->login_kworker, 1); 523 } 524 } 525 526 static void iscsi_target_do_login_rx(struct work_struct *work) 527 { 528 struct iscsi_conn *conn = container_of(work, 529 struct iscsi_conn, login_work.work); 530 struct iscsi_login *login = conn->login; 531 struct iscsi_np *np = login->np; 532 struct iscsi_portal_group *tpg = conn->tpg; 533 struct iscsi_tpg_np *tpg_np = conn->tpg_np; 534 struct timer_list login_timer; 535 int rc, zero_tsih = login->zero_tsih; 536 bool state; 537 538 pr_debug("entering iscsi_target_do_login_rx, conn: %p, %s:%d\n", 539 conn, current->comm, current->pid); 540 541 spin_lock(&tpg->tpg_state_lock); 542 state = (tpg->tpg_state == TPG_STATE_ACTIVE); 543 spin_unlock(&tpg->tpg_state_lock); 544 545 if (!state) { 546 pr_debug("iscsi_target_do_login_rx: tpg_state != TPG_STATE_ACTIVE\n"); 547 iscsi_target_restore_sock_callbacks(conn); 548 iscsi_target_login_drop(conn, login); 549 iscsit_deaccess_np(np, tpg, tpg_np); 550 return; 551 } 552 553 if (conn->sock) { 554 struct sock *sk = conn->sock->sk; 555 556 read_lock_bh(&sk->sk_callback_lock); 557 state = iscsi_target_sk_state_check(sk); 558 read_unlock_bh(&sk->sk_callback_lock); 559 560 if (!state) { 561 pr_debug("iscsi_target_do_login_rx, TCP state CLOSE\n"); 562 iscsi_target_restore_sock_callbacks(conn); 563 iscsi_target_login_drop(conn, login); 564 iscsit_deaccess_np(np, tpg, tpg_np); 565 return; 566 } 567 } 568 569 conn->login_kworker = current; 570 allow_signal(SIGINT); 571 572 init_timer(&login_timer); 573 login_timer.expires = (get_jiffies_64() + TA_LOGIN_TIMEOUT * HZ); 574 login_timer.data = (unsigned long)conn; 575 login_timer.function = iscsi_target_login_timeout; 576 add_timer(&login_timer); 577 pr_debug("Starting login_timer for %s/%d\n", current->comm, current->pid); 578 579 rc = conn->conn_transport->iscsit_get_login_rx(conn, login); 580 del_timer_sync(&login_timer); 581 flush_signals(current); 582 conn->login_kworker = NULL; 583 584 if (rc < 0) { 585 iscsi_target_restore_sock_callbacks(conn); 586 iscsi_target_login_drop(conn, login); 587 iscsit_deaccess_np(np, tpg, tpg_np); 588 return; 589 } 590 591 pr_debug("iscsi_target_do_login_rx after rx_login_io, %p, %s:%d\n", 592 conn, current->comm, current->pid); 593 594 rc = iscsi_target_do_login(conn, login); 595 if (rc < 0) { 596 iscsi_target_restore_sock_callbacks(conn); 597 iscsi_target_login_drop(conn, login); 598 iscsit_deaccess_np(np, tpg, tpg_np); 599 } else if (!rc) { 600 if (conn->sock) { 601 struct sock *sk = conn->sock->sk; 602 603 write_lock_bh(&sk->sk_callback_lock); 604 clear_bit(LOGIN_FLAGS_READ_ACTIVE, &conn->login_flags); 605 write_unlock_bh(&sk->sk_callback_lock); 606 } 607 } else if (rc == 1) { 608 iscsi_target_nego_release(conn); 609 iscsi_post_login_handler(np, conn, zero_tsih); 610 iscsit_deaccess_np(np, tpg, tpg_np); 611 } 612 } 613 614 static void iscsi_target_do_cleanup(struct work_struct *work) 615 { 616 struct iscsi_conn *conn = container_of(work, 617 struct iscsi_conn, login_cleanup_work.work); 618 struct sock *sk = conn->sock->sk; 619 struct iscsi_login *login = conn->login; 620 struct iscsi_np *np = login->np; 621 struct iscsi_portal_group *tpg = conn->tpg; 622 struct iscsi_tpg_np *tpg_np = conn->tpg_np; 623 624 pr_debug("Entering iscsi_target_do_cleanup\n"); 625 626 cancel_delayed_work_sync(&conn->login_work); 627 conn->orig_state_change(sk); 628 629 iscsi_target_restore_sock_callbacks(conn); 630 iscsi_target_login_drop(conn, login); 631 iscsit_deaccess_np(np, tpg, tpg_np); 632 633 pr_debug("iscsi_target_do_cleanup done()\n"); 634 } 635 636 static void iscsi_target_sk_state_change(struct sock *sk) 637 { 638 struct iscsi_conn *conn; 639 void (*orig_state_change)(struct sock *); 640 bool state; 641 642 pr_debug("Entering iscsi_target_sk_state_change\n"); 643 644 write_lock_bh(&sk->sk_callback_lock); 645 conn = sk->sk_user_data; 646 if (!conn) { 647 write_unlock_bh(&sk->sk_callback_lock); 648 return; 649 } 650 orig_state_change = conn->orig_state_change; 651 652 if (!test_bit(LOGIN_FLAGS_READY, &conn->login_flags)) { 653 pr_debug("Got LOGIN_FLAGS_READY=0 sk_state_change conn: %p\n", 654 conn); 655 write_unlock_bh(&sk->sk_callback_lock); 656 orig_state_change(sk); 657 return; 658 } 659 if (test_bit(LOGIN_FLAGS_READ_ACTIVE, &conn->login_flags)) { 660 pr_debug("Got LOGIN_FLAGS_READ_ACTIVE=1 sk_state_change" 661 " conn: %p\n", conn); 662 write_unlock_bh(&sk->sk_callback_lock); 663 orig_state_change(sk); 664 return; 665 } 666 if (test_and_set_bit(LOGIN_FLAGS_CLOSED, &conn->login_flags)) { 667 pr_debug("Got LOGIN_FLAGS_CLOSED=1 sk_state_change conn: %p\n", 668 conn); 669 write_unlock_bh(&sk->sk_callback_lock); 670 orig_state_change(sk); 671 return; 672 } 673 674 state = iscsi_target_sk_state_check(sk); 675 write_unlock_bh(&sk->sk_callback_lock); 676 677 pr_debug("iscsi_target_sk_state_change: state: %d\n", state); 678 679 if (!state) { 680 pr_debug("iscsi_target_sk_state_change got failed state\n"); 681 schedule_delayed_work(&conn->login_cleanup_work, 0); 682 return; 683 } 684 orig_state_change(sk); 685 } 686 687 /* 688 * NOTE: We check for existing sessions or connections AFTER the initiator 689 * has been successfully authenticated in order to protect against faked 690 * ISID/TSIH combinations. 691 */ 692 static int iscsi_target_check_for_existing_instances( 693 struct iscsi_conn *conn, 694 struct iscsi_login *login) 695 { 696 if (login->checked_for_existing) 697 return 0; 698 699 login->checked_for_existing = 1; 700 701 if (!login->tsih) 702 return iscsi_check_for_session_reinstatement(conn); 703 else 704 return iscsi_login_post_auth_non_zero_tsih(conn, login->cid, 705 login->initial_exp_statsn); 706 } 707 708 static int iscsi_target_do_authentication( 709 struct iscsi_conn *conn, 710 struct iscsi_login *login) 711 { 712 int authret; 713 u32 payload_length; 714 struct iscsi_param *param; 715 struct iscsi_login_req *login_req; 716 struct iscsi_login_rsp *login_rsp; 717 718 login_req = (struct iscsi_login_req *) login->req; 719 login_rsp = (struct iscsi_login_rsp *) login->rsp; 720 payload_length = ntoh24(login_req->dlength); 721 722 param = iscsi_find_param_from_key(AUTHMETHOD, conn->param_list); 723 if (!param) 724 return -1; 725 726 authret = iscsi_handle_authentication( 727 conn, 728 login->req_buf, 729 login->rsp_buf, 730 payload_length, 731 &login->rsp_length, 732 param->value); 733 switch (authret) { 734 case 0: 735 pr_debug("Received OK response" 736 " from LIO Authentication, continuing.\n"); 737 break; 738 case 1: 739 pr_debug("iSCSI security negotiation" 740 " completed successfully.\n"); 741 login->auth_complete = 1; 742 if ((login_req->flags & ISCSI_FLAG_LOGIN_NEXT_STAGE1) && 743 (login_req->flags & ISCSI_FLAG_LOGIN_TRANSIT)) { 744 login_rsp->flags |= (ISCSI_FLAG_LOGIN_NEXT_STAGE1 | 745 ISCSI_FLAG_LOGIN_TRANSIT); 746 login->current_stage = 1; 747 } 748 return iscsi_target_check_for_existing_instances( 749 conn, login); 750 case 2: 751 pr_err("Security negotiation" 752 " failed.\n"); 753 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, 754 ISCSI_LOGIN_STATUS_AUTH_FAILED); 755 return -1; 756 default: 757 pr_err("Received unknown error %d from LIO" 758 " Authentication\n", authret); 759 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, 760 ISCSI_LOGIN_STATUS_TARGET_ERROR); 761 return -1; 762 } 763 764 return 0; 765 } 766 767 static int iscsi_target_handle_csg_zero( 768 struct iscsi_conn *conn, 769 struct iscsi_login *login) 770 { 771 int ret; 772 u32 payload_length; 773 struct iscsi_param *param; 774 struct iscsi_login_req *login_req; 775 struct iscsi_login_rsp *login_rsp; 776 777 login_req = (struct iscsi_login_req *) login->req; 778 login_rsp = (struct iscsi_login_rsp *) login->rsp; 779 payload_length = ntoh24(login_req->dlength); 780 781 param = iscsi_find_param_from_key(AUTHMETHOD, conn->param_list); 782 if (!param) 783 return -1; 784 785 ret = iscsi_decode_text_input( 786 PHASE_SECURITY|PHASE_DECLARATIVE, 787 SENDER_INITIATOR|SENDER_RECEIVER, 788 login->req_buf, 789 payload_length, 790 conn); 791 if (ret < 0) 792 return -1; 793 794 if (ret > 0) { 795 if (login->auth_complete) { 796 pr_err("Initiator has already been" 797 " successfully authenticated, but is still" 798 " sending %s keys.\n", param->value); 799 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, 800 ISCSI_LOGIN_STATUS_INIT_ERR); 801 return -1; 802 } 803 804 goto do_auth; 805 } else if (!payload_length) { 806 pr_err("Initiator sent zero length security payload," 807 " login failed\n"); 808 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, 809 ISCSI_LOGIN_STATUS_AUTH_FAILED); 810 return -1; 811 } 812 813 if (login->first_request) 814 if (iscsi_target_check_first_request(conn, login) < 0) 815 return -1; 816 817 ret = iscsi_encode_text_output( 818 PHASE_SECURITY|PHASE_DECLARATIVE, 819 SENDER_TARGET, 820 login->rsp_buf, 821 &login->rsp_length, 822 conn->param_list); 823 if (ret < 0) 824 return -1; 825 826 if (!iscsi_check_negotiated_keys(conn->param_list)) { 827 if (conn->tpg->tpg_attrib.authentication && 828 !strncmp(param->value, NONE, 4)) { 829 pr_err("Initiator sent AuthMethod=None but" 830 " Target is enforcing iSCSI Authentication," 831 " login failed.\n"); 832 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, 833 ISCSI_LOGIN_STATUS_AUTH_FAILED); 834 return -1; 835 } 836 837 if (conn->tpg->tpg_attrib.authentication && 838 !login->auth_complete) 839 return 0; 840 841 if (strncmp(param->value, NONE, 4) && !login->auth_complete) 842 return 0; 843 844 if ((login_req->flags & ISCSI_FLAG_LOGIN_NEXT_STAGE1) && 845 (login_req->flags & ISCSI_FLAG_LOGIN_TRANSIT)) { 846 login_rsp->flags |= ISCSI_FLAG_LOGIN_NEXT_STAGE1 | 847 ISCSI_FLAG_LOGIN_TRANSIT; 848 login->current_stage = 1; 849 } 850 } 851 852 return 0; 853 do_auth: 854 return iscsi_target_do_authentication(conn, login); 855 } 856 857 static int iscsi_target_handle_csg_one(struct iscsi_conn *conn, struct iscsi_login *login) 858 { 859 int ret; 860 u32 payload_length; 861 struct iscsi_login_req *login_req; 862 struct iscsi_login_rsp *login_rsp; 863 864 login_req = (struct iscsi_login_req *) login->req; 865 login_rsp = (struct iscsi_login_rsp *) login->rsp; 866 payload_length = ntoh24(login_req->dlength); 867 868 ret = iscsi_decode_text_input( 869 PHASE_OPERATIONAL|PHASE_DECLARATIVE, 870 SENDER_INITIATOR|SENDER_RECEIVER, 871 login->req_buf, 872 payload_length, 873 conn); 874 if (ret < 0) { 875 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, 876 ISCSI_LOGIN_STATUS_INIT_ERR); 877 return -1; 878 } 879 880 if (login->first_request) 881 if (iscsi_target_check_first_request(conn, login) < 0) 882 return -1; 883 884 if (iscsi_target_check_for_existing_instances(conn, login) < 0) 885 return -1; 886 887 ret = iscsi_encode_text_output( 888 PHASE_OPERATIONAL|PHASE_DECLARATIVE, 889 SENDER_TARGET, 890 login->rsp_buf, 891 &login->rsp_length, 892 conn->param_list); 893 if (ret < 0) { 894 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, 895 ISCSI_LOGIN_STATUS_INIT_ERR); 896 return -1; 897 } 898 899 if (!login->auth_complete && 900 conn->tpg->tpg_attrib.authentication) { 901 pr_err("Initiator is requesting CSG: 1, has not been" 902 " successfully authenticated, and the Target is" 903 " enforcing iSCSI Authentication, login failed.\n"); 904 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, 905 ISCSI_LOGIN_STATUS_AUTH_FAILED); 906 return -1; 907 } 908 909 if (!iscsi_check_negotiated_keys(conn->param_list)) 910 if ((login_req->flags & ISCSI_FLAG_LOGIN_NEXT_STAGE3) && 911 (login_req->flags & ISCSI_FLAG_LOGIN_TRANSIT)) 912 login_rsp->flags |= ISCSI_FLAG_LOGIN_NEXT_STAGE3 | 913 ISCSI_FLAG_LOGIN_TRANSIT; 914 915 return 0; 916 } 917 918 static int iscsi_target_do_login(struct iscsi_conn *conn, struct iscsi_login *login) 919 { 920 int pdu_count = 0; 921 struct iscsi_login_req *login_req; 922 struct iscsi_login_rsp *login_rsp; 923 924 login_req = (struct iscsi_login_req *) login->req; 925 login_rsp = (struct iscsi_login_rsp *) login->rsp; 926 927 while (1) { 928 if (++pdu_count > MAX_LOGIN_PDUS) { 929 pr_err("MAX_LOGIN_PDUS count reached.\n"); 930 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, 931 ISCSI_LOGIN_STATUS_TARGET_ERROR); 932 return -1; 933 } 934 935 switch (ISCSI_LOGIN_CURRENT_STAGE(login_req->flags)) { 936 case 0: 937 login_rsp->flags &= ~ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK; 938 if (iscsi_target_handle_csg_zero(conn, login) < 0) 939 return -1; 940 break; 941 case 1: 942 login_rsp->flags |= ISCSI_FLAG_LOGIN_CURRENT_STAGE1; 943 if (iscsi_target_handle_csg_one(conn, login) < 0) 944 return -1; 945 if (login_rsp->flags & ISCSI_FLAG_LOGIN_TRANSIT) { 946 login->tsih = conn->sess->tsih; 947 login->login_complete = 1; 948 iscsi_target_restore_sock_callbacks(conn); 949 if (iscsi_target_do_tx_login_io(conn, 950 login) < 0) 951 return -1; 952 return 1; 953 } 954 break; 955 default: 956 pr_err("Illegal CSG: %d received from" 957 " Initiator, protocol error.\n", 958 ISCSI_LOGIN_CURRENT_STAGE(login_req->flags)); 959 break; 960 } 961 962 if (iscsi_target_do_tx_login_io(conn, login) < 0) 963 return -1; 964 965 if (login_rsp->flags & ISCSI_FLAG_LOGIN_TRANSIT) { 966 login_rsp->flags &= ~ISCSI_FLAG_LOGIN_TRANSIT; 967 login_rsp->flags &= ~ISCSI_FLAG_LOGIN_NEXT_STAGE_MASK; 968 } 969 break; 970 } 971 972 if (conn->sock) { 973 struct sock *sk = conn->sock->sk; 974 bool state; 975 976 read_lock_bh(&sk->sk_callback_lock); 977 state = iscsi_target_sk_state_check(sk); 978 read_unlock_bh(&sk->sk_callback_lock); 979 980 if (!state) { 981 pr_debug("iscsi_target_do_login() failed state for" 982 " conn: %p\n", conn); 983 return -1; 984 } 985 } 986 987 return 0; 988 } 989 990 static void iscsi_initiatorname_tolower( 991 char *param_buf) 992 { 993 char *c; 994 u32 iqn_size = strlen(param_buf), i; 995 996 for (i = 0; i < iqn_size; i++) { 997 c = ¶m_buf[i]; 998 if (!isupper(*c)) 999 continue; 1000 1001 *c = tolower(*c); 1002 } 1003 } 1004 1005 /* 1006 * Processes the first Login Request.. 1007 */ 1008 int iscsi_target_locate_portal( 1009 struct iscsi_np *np, 1010 struct iscsi_conn *conn, 1011 struct iscsi_login *login) 1012 { 1013 char *i_buf = NULL, *s_buf = NULL, *t_buf = NULL; 1014 char *tmpbuf, *start = NULL, *end = NULL, *key, *value; 1015 struct iscsi_session *sess = conn->sess; 1016 struct iscsi_tiqn *tiqn; 1017 struct iscsi_tpg_np *tpg_np = NULL; 1018 struct iscsi_login_req *login_req; 1019 struct se_node_acl *se_nacl; 1020 u32 payload_length, queue_depth = 0; 1021 int sessiontype = 0, ret = 0, tag_num, tag_size; 1022 1023 INIT_DELAYED_WORK(&conn->login_work, iscsi_target_do_login_rx); 1024 INIT_DELAYED_WORK(&conn->login_cleanup_work, iscsi_target_do_cleanup); 1025 iscsi_target_set_sock_callbacks(conn); 1026 1027 login->np = np; 1028 1029 login_req = (struct iscsi_login_req *) login->req; 1030 payload_length = ntoh24(login_req->dlength); 1031 1032 tmpbuf = kzalloc(payload_length + 1, GFP_KERNEL); 1033 if (!tmpbuf) { 1034 pr_err("Unable to allocate memory for tmpbuf.\n"); 1035 return -1; 1036 } 1037 1038 memcpy(tmpbuf, login->req_buf, payload_length); 1039 tmpbuf[payload_length] = '\0'; 1040 start = tmpbuf; 1041 end = (start + payload_length); 1042 1043 /* 1044 * Locate the initial keys expected from the Initiator node in 1045 * the first login request in order to progress with the login phase. 1046 */ 1047 while (start < end) { 1048 if (iscsi_extract_key_value(start, &key, &value) < 0) { 1049 ret = -1; 1050 goto out; 1051 } 1052 1053 if (!strncmp(key, "InitiatorName", 13)) 1054 i_buf = value; 1055 else if (!strncmp(key, "SessionType", 11)) 1056 s_buf = value; 1057 else if (!strncmp(key, "TargetName", 10)) 1058 t_buf = value; 1059 1060 start += strlen(key) + strlen(value) + 2; 1061 } 1062 /* 1063 * See 5.3. Login Phase. 1064 */ 1065 if (!i_buf) { 1066 pr_err("InitiatorName key not received" 1067 " in first login request.\n"); 1068 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, 1069 ISCSI_LOGIN_STATUS_MISSING_FIELDS); 1070 ret = -1; 1071 goto out; 1072 } 1073 /* 1074 * Convert the incoming InitiatorName to lowercase following 1075 * RFC-3720 3.2.6.1. section c) that says that iSCSI IQNs 1076 * are NOT case sensitive. 1077 */ 1078 iscsi_initiatorname_tolower(i_buf); 1079 1080 if (!s_buf) { 1081 if (!login->leading_connection) 1082 goto get_target; 1083 1084 pr_err("SessionType key not received" 1085 " in first login request.\n"); 1086 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, 1087 ISCSI_LOGIN_STATUS_MISSING_FIELDS); 1088 ret = -1; 1089 goto out; 1090 } 1091 1092 /* 1093 * Use default portal group for discovery sessions. 1094 */ 1095 sessiontype = strncmp(s_buf, DISCOVERY, 9); 1096 if (!sessiontype) { 1097 conn->tpg = iscsit_global->discovery_tpg; 1098 if (!login->leading_connection) 1099 goto get_target; 1100 1101 sess->sess_ops->SessionType = 1; 1102 /* 1103 * Setup crc32c modules from libcrypto 1104 */ 1105 if (iscsi_login_setup_crypto(conn) < 0) { 1106 pr_err("iscsi_login_setup_crypto() failed\n"); 1107 ret = -1; 1108 goto out; 1109 } 1110 /* 1111 * Serialize access across the discovery struct iscsi_portal_group to 1112 * process login attempt. 1113 */ 1114 if (iscsit_access_np(np, conn->tpg) < 0) { 1115 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, 1116 ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE); 1117 ret = -1; 1118 goto out; 1119 } 1120 ret = 0; 1121 goto alloc_tags; 1122 } 1123 1124 get_target: 1125 if (!t_buf) { 1126 pr_err("TargetName key not received" 1127 " in first login request while" 1128 " SessionType=Normal.\n"); 1129 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, 1130 ISCSI_LOGIN_STATUS_MISSING_FIELDS); 1131 ret = -1; 1132 goto out; 1133 } 1134 1135 /* 1136 * Locate Target IQN from Storage Node. 1137 */ 1138 tiqn = iscsit_get_tiqn_for_login(t_buf); 1139 if (!tiqn) { 1140 pr_err("Unable to locate Target IQN: %s in" 1141 " Storage Node\n", t_buf); 1142 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, 1143 ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE); 1144 ret = -1; 1145 goto out; 1146 } 1147 pr_debug("Located Storage Object: %s\n", tiqn->tiqn); 1148 1149 /* 1150 * Locate Target Portal Group from Storage Node. 1151 */ 1152 conn->tpg = iscsit_get_tpg_from_np(tiqn, np, &tpg_np); 1153 if (!conn->tpg) { 1154 pr_err("Unable to locate Target Portal Group" 1155 " on %s\n", tiqn->tiqn); 1156 iscsit_put_tiqn_for_login(tiqn); 1157 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, 1158 ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE); 1159 ret = -1; 1160 goto out; 1161 } 1162 conn->tpg_np = tpg_np; 1163 pr_debug("Located Portal Group Object: %hu\n", conn->tpg->tpgt); 1164 /* 1165 * Setup crc32c modules from libcrypto 1166 */ 1167 if (iscsi_login_setup_crypto(conn) < 0) { 1168 pr_err("iscsi_login_setup_crypto() failed\n"); 1169 kref_put(&tpg_np->tpg_np_kref, iscsit_login_kref_put); 1170 iscsit_put_tiqn_for_login(tiqn); 1171 conn->tpg = NULL; 1172 ret = -1; 1173 goto out; 1174 } 1175 /* 1176 * Serialize access across the struct iscsi_portal_group to 1177 * process login attempt. 1178 */ 1179 if (iscsit_access_np(np, conn->tpg) < 0) { 1180 kref_put(&tpg_np->tpg_np_kref, iscsit_login_kref_put); 1181 iscsit_put_tiqn_for_login(tiqn); 1182 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, 1183 ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE); 1184 conn->tpg = NULL; 1185 ret = -1; 1186 goto out; 1187 } 1188 1189 /* 1190 * conn->sess->node_acl will be set when the referenced 1191 * struct iscsi_session is located from received ISID+TSIH in 1192 * iscsi_login_non_zero_tsih_s2(). 1193 */ 1194 if (!login->leading_connection) { 1195 ret = 0; 1196 goto out; 1197 } 1198 1199 /* 1200 * This value is required in iscsi_login_zero_tsih_s2() 1201 */ 1202 sess->sess_ops->SessionType = 0; 1203 1204 /* 1205 * Locate incoming Initiator IQN reference from Storage Node. 1206 */ 1207 sess->se_sess->se_node_acl = core_tpg_check_initiator_node_acl( 1208 &conn->tpg->tpg_se_tpg, i_buf); 1209 if (!sess->se_sess->se_node_acl) { 1210 pr_err("iSCSI Initiator Node: %s is not authorized to" 1211 " access iSCSI target portal group: %hu.\n", 1212 i_buf, conn->tpg->tpgt); 1213 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, 1214 ISCSI_LOGIN_STATUS_TGT_FORBIDDEN); 1215 ret = -1; 1216 goto out; 1217 } 1218 se_nacl = sess->se_sess->se_node_acl; 1219 queue_depth = se_nacl->queue_depth; 1220 /* 1221 * Setup pre-allocated tags based upon allowed per NodeACL CmdSN 1222 * depth for non immediate commands, plus extra tags for immediate 1223 * commands. 1224 * 1225 * Also enforce a ISCSIT_MIN_TAGS to prevent unnecessary contention 1226 * in per-cpu-ida tag allocation logic + small queue_depth. 1227 */ 1228 alloc_tags: 1229 tag_num = max_t(u32, ISCSIT_MIN_TAGS, queue_depth); 1230 tag_num = (tag_num * 2) + ISCSIT_EXTRA_TAGS; 1231 tag_size = sizeof(struct iscsi_cmd) + conn->conn_transport->priv_size; 1232 1233 ret = transport_alloc_session_tags(sess->se_sess, tag_num, tag_size); 1234 if (ret < 0) { 1235 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, 1236 ISCSI_LOGIN_STATUS_NO_RESOURCES); 1237 ret = -1; 1238 } 1239 out: 1240 kfree(tmpbuf); 1241 return ret; 1242 } 1243 1244 int iscsi_target_start_negotiation( 1245 struct iscsi_login *login, 1246 struct iscsi_conn *conn) 1247 { 1248 int ret; 1249 1250 if (conn->sock) { 1251 struct sock *sk = conn->sock->sk; 1252 1253 write_lock_bh(&sk->sk_callback_lock); 1254 set_bit(LOGIN_FLAGS_READY, &conn->login_flags); 1255 write_unlock_bh(&sk->sk_callback_lock); 1256 } 1257 1258 ret = iscsi_target_do_login(conn, login); 1259 if (ret < 0) { 1260 cancel_delayed_work_sync(&conn->login_work); 1261 cancel_delayed_work_sync(&conn->login_cleanup_work); 1262 iscsi_target_restore_sock_callbacks(conn); 1263 iscsi_remove_failed_auth_entry(conn); 1264 } 1265 if (ret != 0) 1266 iscsi_target_nego_release(conn); 1267 1268 return ret; 1269 } 1270 1271 void iscsi_target_nego_release(struct iscsi_conn *conn) 1272 { 1273 struct iscsi_login *login = conn->conn_login; 1274 1275 if (!login) 1276 return; 1277 1278 kfree(login->req_buf); 1279 kfree(login->rsp_buf); 1280 kfree(login); 1281 1282 conn->conn_login = NULL; 1283 } 1284