Linux-libre 3.6.3-gnu1
[librecmc/linux-libre.git] / drivers / target / iscsi / iscsi_target_nego.c
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
26 #include "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 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 se_node_acl *se_nacl;
115
116         if (!sess->sess_ops->SessionType) {
117                 /*
118                  * For SessionType=Normal
119                  */
120                 se_nacl = conn->sess->se_sess->se_node_acl;
121                 if (!se_nacl) {
122                         pr_err("Unable to locate struct se_node_acl for"
123                                         " CHAP auth\n");
124                         return -1;
125                 }
126                 iscsi_nacl = container_of(se_nacl, struct iscsi_node_acl,
127                                 se_node_acl);
128                 if (!iscsi_nacl) {
129                         pr_err("Unable to locate struct iscsi_node_acl for"
130                                         " CHAP auth\n");
131                         return -1;
132                 }
133
134                 auth = ISCSI_NODE_AUTH(iscsi_nacl);
135         } else {
136                 /*
137                  * For SessionType=Discovery
138                  */
139                 auth = &iscsit_global->discovery_acl.node_auth;
140         }
141
142         if (strstr("CHAP", authtype))
143                 strcpy(conn->sess->auth_type, "CHAP");
144         else
145                 strcpy(conn->sess->auth_type, NONE);
146
147         if (strstr("None", authtype))
148                 return 1;
149 #ifdef CANSRP
150         else if (strstr("SRP", authtype))
151                 return srp_main_loop(conn, auth, in_buf, out_buf,
152                                 &in_length, out_length);
153 #endif
154         else if (strstr("CHAP", authtype))
155                 return chap_main_loop(conn, auth, in_buf, out_buf,
156                                 &in_length, out_length);
157         else if (strstr("SPKM1", authtype))
158                 return 2;
159         else if (strstr("SPKM2", authtype))
160                 return 2;
161         else if (strstr("KRB5", authtype))
162                 return 2;
163         else
164                 return 2;
165 }
166
167 static void iscsi_remove_failed_auth_entry(struct iscsi_conn *conn)
168 {
169         kfree(conn->auth_protocol);
170 }
171
172 static int iscsi_target_check_login_request(
173         struct iscsi_conn *conn,
174         struct iscsi_login *login)
175 {
176         int req_csg, req_nsg;
177         u32 payload_length;
178         struct iscsi_login_req *login_req;
179
180         login_req = (struct iscsi_login_req *) login->req;
181         payload_length = ntoh24(login_req->dlength);
182
183         switch (login_req->opcode & ISCSI_OPCODE_MASK) {
184         case ISCSI_OP_LOGIN:
185                 break;
186         default:
187                 pr_err("Received unknown opcode 0x%02x.\n",
188                                 login_req->opcode & ISCSI_OPCODE_MASK);
189                 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
190                                 ISCSI_LOGIN_STATUS_INIT_ERR);
191                 return -1;
192         }
193
194         if ((login_req->flags & ISCSI_FLAG_LOGIN_CONTINUE) &&
195             (login_req->flags & ISCSI_FLAG_LOGIN_TRANSIT)) {
196                 pr_err("Login request has both ISCSI_FLAG_LOGIN_CONTINUE"
197                         " and ISCSI_FLAG_LOGIN_TRANSIT set, protocol error.\n");
198                 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
199                                 ISCSI_LOGIN_STATUS_INIT_ERR);
200                 return -1;
201         }
202
203         req_csg = (login_req->flags & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK) >> 2;
204         req_nsg = (login_req->flags & ISCSI_FLAG_LOGIN_NEXT_STAGE_MASK);
205
206         if (req_csg != login->current_stage) {
207                 pr_err("Initiator unexpectedly changed login stage"
208                         " from %d to %d, login failed.\n", login->current_stage,
209                         req_csg);
210                 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
211                                 ISCSI_LOGIN_STATUS_INIT_ERR);
212                 return -1;
213         }
214
215         if ((req_nsg == 2) || (req_csg >= 2) ||
216            ((login_req->flags & ISCSI_FLAG_LOGIN_TRANSIT) &&
217             (req_nsg <= req_csg))) {
218                 pr_err("Illegal login_req->flags Combination, CSG: %d,"
219                         " NSG: %d, ISCSI_FLAG_LOGIN_TRANSIT: %d.\n", req_csg,
220                         req_nsg, (login_req->flags & ISCSI_FLAG_LOGIN_TRANSIT));
221                 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
222                                 ISCSI_LOGIN_STATUS_INIT_ERR);
223                 return -1;
224         }
225
226         if ((login_req->max_version != login->version_max) ||
227             (login_req->min_version != login->version_min)) {
228                 pr_err("Login request changed Version Max/Nin"
229                         " unexpectedly to 0x%02x/0x%02x, protocol error\n",
230                         login_req->max_version, login_req->min_version);
231                 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
232                                 ISCSI_LOGIN_STATUS_INIT_ERR);
233                 return -1;
234         }
235
236         if (memcmp(login_req->isid, login->isid, 6) != 0) {
237                 pr_err("Login request changed ISID unexpectedly,"
238                                 " protocol error.\n");
239                 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
240                                 ISCSI_LOGIN_STATUS_INIT_ERR);
241                 return -1;
242         }
243
244         if (login_req->itt != login->init_task_tag) {
245                 pr_err("Login request changed ITT unexpectedly to"
246                         " 0x%08x, protocol error.\n", login_req->itt);
247                 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
248                                 ISCSI_LOGIN_STATUS_INIT_ERR);
249                 return -1;
250         }
251
252         if (payload_length > MAX_KEY_VALUE_PAIRS) {
253                 pr_err("Login request payload exceeds default"
254                         " MaxRecvDataSegmentLength: %u, protocol error.\n",
255                                 MAX_KEY_VALUE_PAIRS);
256                 return -1;
257         }
258
259         return 0;
260 }
261
262 static int iscsi_target_check_first_request(
263         struct iscsi_conn *conn,
264         struct iscsi_login *login)
265 {
266         struct iscsi_param *param = NULL;
267         struct se_node_acl *se_nacl;
268
269         login->first_request = 0;
270
271         list_for_each_entry(param, &conn->param_list->param_list, p_list) {
272                 if (!strncmp(param->name, SESSIONTYPE, 11)) {
273                         if (!IS_PSTATE_ACCEPTOR(param)) {
274                                 pr_err("SessionType key not received"
275                                         " in first login request.\n");
276                                 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
277                                         ISCSI_LOGIN_STATUS_MISSING_FIELDS);
278                                 return -1;
279                         }
280                         if (!strncmp(param->value, DISCOVERY, 9))
281                                 return 0;
282                 }
283
284                 if (!strncmp(param->name, INITIATORNAME, 13)) {
285                         if (!IS_PSTATE_ACCEPTOR(param)) {
286                                 if (!login->leading_connection)
287                                         continue;
288
289                                 pr_err("InitiatorName key not received"
290                                         " in first login request.\n");
291                                 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
292                                         ISCSI_LOGIN_STATUS_MISSING_FIELDS);
293                                 return -1;
294                         }
295
296                         /*
297                          * For non-leading connections, double check that the
298                          * received InitiatorName matches the existing session's
299                          * struct iscsi_node_acl.
300                          */
301                         if (!login->leading_connection) {
302                                 se_nacl = conn->sess->se_sess->se_node_acl;
303                                 if (!se_nacl) {
304                                         pr_err("Unable to locate"
305                                                 " struct se_node_acl\n");
306                                         iscsit_tx_login_rsp(conn,
307                                                         ISCSI_STATUS_CLS_INITIATOR_ERR,
308                                                         ISCSI_LOGIN_STATUS_TGT_NOT_FOUND);
309                                         return -1;
310                                 }
311
312                                 if (strcmp(param->value,
313                                                 se_nacl->initiatorname)) {
314                                         pr_err("Incorrect"
315                                                 " InitiatorName: %s for this"
316                                                 " iSCSI Initiator Node.\n",
317                                                 param->value);
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                 }
325         }
326
327         return 0;
328 }
329
330 static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_login *login)
331 {
332         u32 padding = 0;
333         struct iscsi_session *sess = conn->sess;
334         struct iscsi_login_rsp *login_rsp;
335
336         login_rsp = (struct iscsi_login_rsp *) login->rsp;
337
338         login_rsp->opcode               = ISCSI_OP_LOGIN_RSP;
339         hton24(login_rsp->dlength, login->rsp_length);
340         memcpy(login_rsp->isid, login->isid, 6);
341         login_rsp->tsih                 = cpu_to_be16(login->tsih);
342         login_rsp->itt                  = cpu_to_be32(login->init_task_tag);
343         login_rsp->statsn               = cpu_to_be32(conn->stat_sn++);
344         login_rsp->exp_cmdsn            = cpu_to_be32(conn->sess->exp_cmd_sn);
345         login_rsp->max_cmdsn            = cpu_to_be32(conn->sess->max_cmd_sn);
346
347         pr_debug("Sending Login Response, Flags: 0x%02x, ITT: 0x%08x,"
348                 " ExpCmdSN; 0x%08x, MaxCmdSN: 0x%08x, StatSN: 0x%08x, Length:"
349                 " %u\n", login_rsp->flags, ntohl(login_rsp->itt),
350                 ntohl(login_rsp->exp_cmdsn), ntohl(login_rsp->max_cmdsn),
351                 ntohl(login_rsp->statsn), login->rsp_length);
352
353         padding = ((-login->rsp_length) & 3);
354
355         if (iscsi_login_tx_data(
356                         conn,
357                         login->rsp,
358                         login->rsp_buf,
359                         login->rsp_length + padding) < 0)
360                 return -1;
361
362         login->rsp_length               = 0;
363         login_rsp->tsih                 = be16_to_cpu(login_rsp->tsih);
364         login_rsp->itt                  = be32_to_cpu(login_rsp->itt);
365         login_rsp->statsn               = be32_to_cpu(login_rsp->statsn);
366         mutex_lock(&sess->cmdsn_mutex);
367         login_rsp->exp_cmdsn            = be32_to_cpu(sess->exp_cmd_sn);
368         login_rsp->max_cmdsn            = be32_to_cpu(sess->max_cmd_sn);
369         mutex_unlock(&sess->cmdsn_mutex);
370
371         return 0;
372 }
373
374 static int iscsi_target_do_rx_login_io(struct iscsi_conn *conn, struct iscsi_login *login)
375 {
376         u32 padding = 0, payload_length;
377         struct iscsi_login_req *login_req;
378
379         if (iscsi_login_rx_data(conn, login->req, ISCSI_HDR_LEN) < 0)
380                 return -1;
381
382         login_req = (struct iscsi_login_req *) login->req;
383         payload_length                  = ntoh24(login_req->dlength);
384         login_req->tsih                 = be16_to_cpu(login_req->tsih);
385         login_req->itt                  = be32_to_cpu(login_req->itt);
386         login_req->cid                  = be16_to_cpu(login_req->cid);
387         login_req->cmdsn                = be32_to_cpu(login_req->cmdsn);
388         login_req->exp_statsn           = be32_to_cpu(login_req->exp_statsn);
389
390         pr_debug("Got Login Command, Flags 0x%02x, ITT: 0x%08x,"
391                 " CmdSN: 0x%08x, ExpStatSN: 0x%08x, CID: %hu, Length: %u\n",
392                  login_req->flags, login_req->itt, login_req->cmdsn,
393                  login_req->exp_statsn, login_req->cid, payload_length);
394
395         if (iscsi_target_check_login_request(conn, login) < 0)
396                 return -1;
397
398         padding = ((-payload_length) & 3);
399         memset(login->req_buf, 0, MAX_KEY_VALUE_PAIRS);
400
401         if (iscsi_login_rx_data(
402                         conn,
403                         login->req_buf,
404                         payload_length + padding) < 0)
405                 return -1;
406
407         return 0;
408 }
409
410 static int iscsi_target_do_login_io(struct iscsi_conn *conn, struct iscsi_login *login)
411 {
412         if (iscsi_target_do_tx_login_io(conn, login) < 0)
413                 return -1;
414
415         if (iscsi_target_do_rx_login_io(conn, login) < 0)
416                 return -1;
417
418         return 0;
419 }
420
421 static int iscsi_target_get_initial_payload(
422         struct iscsi_conn *conn,
423         struct iscsi_login *login)
424 {
425         u32 padding = 0, payload_length;
426         struct iscsi_login_req *login_req;
427
428         login_req = (struct iscsi_login_req *) login->req;
429         payload_length = ntoh24(login_req->dlength);
430
431         pr_debug("Got Login Command, Flags 0x%02x, ITT: 0x%08x,"
432                 " CmdSN: 0x%08x, ExpStatSN: 0x%08x, Length: %u\n",
433                 login_req->flags, login_req->itt, login_req->cmdsn,
434                 login_req->exp_statsn, payload_length);
435
436         if (iscsi_target_check_login_request(conn, login) < 0)
437                 return -1;
438
439         padding = ((-payload_length) & 3);
440
441         if (iscsi_login_rx_data(
442                         conn,
443                         login->req_buf,
444                         payload_length + padding) < 0)
445                 return -1;
446
447         return 0;
448 }
449
450 /*
451  *      NOTE: We check for existing sessions or connections AFTER the initiator
452  *      has been successfully authenticated in order to protect against faked
453  *      ISID/TSIH combinations.
454  */
455 static int iscsi_target_check_for_existing_instances(
456         struct iscsi_conn *conn,
457         struct iscsi_login *login)
458 {
459         if (login->checked_for_existing)
460                 return 0;
461
462         login->checked_for_existing = 1;
463
464         if (!login->tsih)
465                 return iscsi_check_for_session_reinstatement(conn);
466         else
467                 return iscsi_login_post_auth_non_zero_tsih(conn, login->cid,
468                                 login->initial_exp_statsn);
469 }
470
471 static int iscsi_target_do_authentication(
472         struct iscsi_conn *conn,
473         struct iscsi_login *login)
474 {
475         int authret;
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         authret = iscsi_handle_authentication(
490                         conn,
491                         login->req_buf,
492                         login->rsp_buf,
493                         payload_length,
494                         &login->rsp_length,
495                         param->value);
496         switch (authret) {
497         case 0:
498                 pr_debug("Received OK response"
499                 " from LIO Authentication, continuing.\n");
500                 break;
501         case 1:
502                 pr_debug("iSCSI security negotiation"
503                         " completed successfully.\n");
504                 login->auth_complete = 1;
505                 if ((login_req->flags & ISCSI_FLAG_LOGIN_NEXT_STAGE1) &&
506                     (login_req->flags & ISCSI_FLAG_LOGIN_TRANSIT)) {
507                         login_rsp->flags |= (ISCSI_FLAG_LOGIN_NEXT_STAGE1 |
508                                              ISCSI_FLAG_LOGIN_TRANSIT);
509                         login->current_stage = 1;
510                 }
511                 return iscsi_target_check_for_existing_instances(
512                                 conn, login);
513         case 2:
514                 pr_err("Security negotiation"
515                         " failed.\n");
516                 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
517                                 ISCSI_LOGIN_STATUS_AUTH_FAILED);
518                 return -1;
519         default:
520                 pr_err("Received unknown error %d from LIO"
521                                 " Authentication\n", authret);
522                 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
523                                 ISCSI_LOGIN_STATUS_TARGET_ERROR);
524                 return -1;
525         }
526
527         return 0;
528 }
529
530 static int iscsi_target_handle_csg_zero(
531         struct iscsi_conn *conn,
532         struct iscsi_login *login)
533 {
534         int ret;
535         u32 payload_length;
536         struct iscsi_param *param;
537         struct iscsi_login_req *login_req;
538         struct iscsi_login_rsp *login_rsp;
539
540         login_req = (struct iscsi_login_req *) login->req;
541         login_rsp = (struct iscsi_login_rsp *) login->rsp;
542         payload_length = ntoh24(login_req->dlength);
543
544         param = iscsi_find_param_from_key(AUTHMETHOD, conn->param_list);
545         if (!param)
546                 return -1;
547
548         ret = iscsi_decode_text_input(
549                         PHASE_SECURITY|PHASE_DECLARATIVE,
550                         SENDER_INITIATOR|SENDER_RECEIVER,
551                         login->req_buf,
552                         payload_length,
553                         conn->param_list);
554         if (ret < 0)
555                 return -1;
556
557         if (ret > 0) {
558                 if (login->auth_complete) {
559                         pr_err("Initiator has already been"
560                                 " successfully authenticated, but is still"
561                                 " sending %s keys.\n", param->value);
562                         iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
563                                         ISCSI_LOGIN_STATUS_INIT_ERR);
564                         return -1;
565                 }
566
567                 goto do_auth;
568         }
569
570         if (login->first_request)
571                 if (iscsi_target_check_first_request(conn, login) < 0)
572                         return -1;
573
574         ret = iscsi_encode_text_output(
575                         PHASE_SECURITY|PHASE_DECLARATIVE,
576                         SENDER_TARGET,
577                         login->rsp_buf,
578                         &login->rsp_length,
579                         conn->param_list);
580         if (ret < 0)
581                 return -1;
582
583         if (!iscsi_check_negotiated_keys(conn->param_list)) {
584                 if (ISCSI_TPG_ATTRIB(ISCSI_TPG_C(conn))->authentication &&
585                     !strncmp(param->value, NONE, 4)) {
586                         pr_err("Initiator sent AuthMethod=None but"
587                                 " Target is enforcing iSCSI Authentication,"
588                                         " login failed.\n");
589                         iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
590                                         ISCSI_LOGIN_STATUS_AUTH_FAILED);
591                         return -1;
592                 }
593
594                 if (ISCSI_TPG_ATTRIB(ISCSI_TPG_C(conn))->authentication &&
595                     !login->auth_complete)
596                         return 0;
597
598                 if (strncmp(param->value, NONE, 4) && !login->auth_complete)
599                         return 0;
600
601                 if ((login_req->flags & ISCSI_FLAG_LOGIN_NEXT_STAGE1) &&
602                     (login_req->flags & ISCSI_FLAG_LOGIN_TRANSIT)) {
603                         login_rsp->flags |= ISCSI_FLAG_LOGIN_NEXT_STAGE1 |
604                                             ISCSI_FLAG_LOGIN_TRANSIT;
605                         login->current_stage = 1;
606                 }
607         }
608
609         return 0;
610 do_auth:
611         return iscsi_target_do_authentication(conn, login);
612 }
613
614 static int iscsi_target_handle_csg_one(struct iscsi_conn *conn, struct iscsi_login *login)
615 {
616         int ret;
617         u32 payload_length;
618         struct iscsi_login_req *login_req;
619         struct iscsi_login_rsp *login_rsp;
620
621         login_req = (struct iscsi_login_req *) login->req;
622         login_rsp = (struct iscsi_login_rsp *) login->rsp;
623         payload_length = ntoh24(login_req->dlength);
624
625         ret = iscsi_decode_text_input(
626                         PHASE_OPERATIONAL|PHASE_DECLARATIVE,
627                         SENDER_INITIATOR|SENDER_RECEIVER,
628                         login->req_buf,
629                         payload_length,
630                         conn->param_list);
631         if (ret < 0)
632                 return -1;
633
634         if (login->first_request)
635                 if (iscsi_target_check_first_request(conn, login) < 0)
636                         return -1;
637
638         if (iscsi_target_check_for_existing_instances(conn, login) < 0)
639                 return -1;
640
641         ret = iscsi_encode_text_output(
642                         PHASE_OPERATIONAL|PHASE_DECLARATIVE,
643                         SENDER_TARGET,
644                         login->rsp_buf,
645                         &login->rsp_length,
646                         conn->param_list);
647         if (ret < 0)
648                 return -1;
649
650         if (!login->auth_complete &&
651              ISCSI_TPG_ATTRIB(ISCSI_TPG_C(conn))->authentication) {
652                 pr_err("Initiator is requesting CSG: 1, has not been"
653                          " successfully authenticated, and the Target is"
654                         " enforcing iSCSI Authentication, login failed.\n");
655                 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
656                                 ISCSI_LOGIN_STATUS_AUTH_FAILED);
657                 return -1;
658         }
659
660         if (!iscsi_check_negotiated_keys(conn->param_list))
661                 if ((login_req->flags & ISCSI_FLAG_LOGIN_NEXT_STAGE3) &&
662                     (login_req->flags & ISCSI_FLAG_LOGIN_TRANSIT))
663                         login_rsp->flags |= ISCSI_FLAG_LOGIN_NEXT_STAGE3 |
664                                             ISCSI_FLAG_LOGIN_TRANSIT;
665
666         return 0;
667 }
668
669 static int iscsi_target_do_login(struct iscsi_conn *conn, struct iscsi_login *login)
670 {
671         int pdu_count = 0;
672         struct iscsi_login_req *login_req;
673         struct iscsi_login_rsp *login_rsp;
674
675         login_req = (struct iscsi_login_req *) login->req;
676         login_rsp = (struct iscsi_login_rsp *) login->rsp;
677
678         while (1) {
679                 if (++pdu_count > MAX_LOGIN_PDUS) {
680                         pr_err("MAX_LOGIN_PDUS count reached.\n");
681                         iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
682                                         ISCSI_LOGIN_STATUS_TARGET_ERROR);
683                         return -1;
684                 }
685
686                 switch ((login_req->flags & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK) >> 2) {
687                 case 0:
688                         login_rsp->flags |= (0 & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK);
689                         if (iscsi_target_handle_csg_zero(conn, login) < 0)
690                                 return -1;
691                         break;
692                 case 1:
693                         login_rsp->flags |= ISCSI_FLAG_LOGIN_CURRENT_STAGE1;
694                         if (iscsi_target_handle_csg_one(conn, login) < 0)
695                                 return -1;
696                         if (login_rsp->flags & ISCSI_FLAG_LOGIN_TRANSIT) {
697                                 login->tsih = conn->sess->tsih;
698                                 if (iscsi_target_do_tx_login_io(conn,
699                                                 login) < 0)
700                                         return -1;
701                                 return 0;
702                         }
703                         break;
704                 default:
705                         pr_err("Illegal CSG: %d received from"
706                                 " Initiator, protocol error.\n",
707                                 (login_req->flags & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK)
708                                 >> 2);
709                         break;
710                 }
711
712                 if (iscsi_target_do_login_io(conn, login) < 0)
713                         return -1;
714
715                 if (login_rsp->flags & ISCSI_FLAG_LOGIN_TRANSIT) {
716                         login_rsp->flags &= ~ISCSI_FLAG_LOGIN_TRANSIT;
717                         login_rsp->flags &= ~ISCSI_FLAG_LOGIN_NEXT_STAGE_MASK;
718                 }
719         }
720
721         return 0;
722 }
723
724 static void iscsi_initiatorname_tolower(
725         char *param_buf)
726 {
727         char *c;
728         u32 iqn_size = strlen(param_buf), i;
729
730         for (i = 0; i < iqn_size; i++) {
731                 c = &param_buf[i];
732                 if (!isupper(*c))
733                         continue;
734
735                 *c = tolower(*c);
736         }
737 }
738
739 /*
740  * Processes the first Login Request..
741  */
742 static int iscsi_target_locate_portal(
743         struct iscsi_np *np,
744         struct iscsi_conn *conn,
745         struct iscsi_login *login)
746 {
747         char *i_buf = NULL, *s_buf = NULL, *t_buf = NULL;
748         char *tmpbuf, *start = NULL, *end = NULL, *key, *value;
749         struct iscsi_session *sess = conn->sess;
750         struct iscsi_tiqn *tiqn;
751         struct iscsi_login_req *login_req;
752         u32 payload_length;
753         int sessiontype = 0, ret = 0;
754
755         login_req = (struct iscsi_login_req *) login->req;
756         payload_length = ntoh24(login_req->dlength);
757
758         login->first_request    = 1;
759         login->leading_connection = (!login_req->tsih) ? 1 : 0;
760         login->current_stage    =
761                 (login_req->flags & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK) >> 2;
762         login->version_min      = login_req->min_version;
763         login->version_max      = login_req->max_version;
764         memcpy(login->isid, login_req->isid, 6);
765         login->cmd_sn           = login_req->cmdsn;
766         login->init_task_tag    = login_req->itt;
767         login->initial_exp_statsn = login_req->exp_statsn;
768         login->cid              = login_req->cid;
769         login->tsih             = login_req->tsih;
770
771         if (iscsi_target_get_initial_payload(conn, login) < 0)
772                 return -1;
773
774         tmpbuf = kzalloc(payload_length + 1, GFP_KERNEL);
775         if (!tmpbuf) {
776                 pr_err("Unable to allocate memory for tmpbuf.\n");
777                 return -1;
778         }
779
780         memcpy(tmpbuf, login->req_buf, payload_length);
781         tmpbuf[payload_length] = '\0';
782         start = tmpbuf;
783         end = (start + payload_length);
784
785         /*
786          * Locate the initial keys expected from the Initiator node in
787          * the first login request in order to progress with the login phase.
788          */
789         while (start < end) {
790                 if (iscsi_extract_key_value(start, &key, &value) < 0) {
791                         ret = -1;
792                         goto out;
793                 }
794
795                 if (!strncmp(key, "InitiatorName", 13))
796                         i_buf = value;
797                 else if (!strncmp(key, "SessionType", 11))
798                         s_buf = value;
799                 else if (!strncmp(key, "TargetName", 10))
800                         t_buf = value;
801
802                 start += strlen(key) + strlen(value) + 2;
803         }
804
805         /*
806          * See 5.3.  Login Phase.
807          */
808         if (!i_buf) {
809                 pr_err("InitiatorName key not received"
810                         " in first login request.\n");
811                 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
812                         ISCSI_LOGIN_STATUS_MISSING_FIELDS);
813                 ret = -1;
814                 goto out;
815         }
816         /*
817          * Convert the incoming InitiatorName to lowercase following
818          * RFC-3720 3.2.6.1. section c) that says that iSCSI IQNs
819          * are NOT case sensitive.
820          */
821         iscsi_initiatorname_tolower(i_buf);
822
823         if (!s_buf) {
824                 if (!login->leading_connection)
825                         goto get_target;
826
827                 pr_err("SessionType key not received"
828                         " in first login request.\n");
829                 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
830                         ISCSI_LOGIN_STATUS_MISSING_FIELDS);
831                 ret = -1;
832                 goto out;
833         }
834
835         /*
836          * Use default portal group for discovery sessions.
837          */
838         sessiontype = strncmp(s_buf, DISCOVERY, 9);
839         if (!sessiontype) {
840                 conn->tpg = iscsit_global->discovery_tpg;
841                 if (!login->leading_connection)
842                         goto get_target;
843
844                 sess->sess_ops->SessionType = 1;
845                 /*
846                  * Setup crc32c modules from libcrypto
847                  */
848                 if (iscsi_login_setup_crypto(conn) < 0) {
849                         pr_err("iscsi_login_setup_crypto() failed\n");
850                         ret = -1;
851                         goto out;
852                 }
853                 /*
854                  * Serialize access across the discovery struct iscsi_portal_group to
855                  * process login attempt.
856                  */
857                 if (iscsit_access_np(np, conn->tpg) < 0) {
858                         iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
859                                 ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE);
860                         ret = -1;
861                         goto out;
862                 }
863                 ret = 0;
864                 goto out;
865         }
866
867 get_target:
868         if (!t_buf) {
869                 pr_err("TargetName key not received"
870                         " in first login request while"
871                         " SessionType=Normal.\n");
872                 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
873                         ISCSI_LOGIN_STATUS_MISSING_FIELDS);
874                 ret = -1;
875                 goto out;
876         }
877
878         /*
879          * Locate Target IQN from Storage Node.
880          */
881         tiqn = iscsit_get_tiqn_for_login(t_buf);
882         if (!tiqn) {
883                 pr_err("Unable to locate Target IQN: %s in"
884                         " Storage Node\n", t_buf);
885                 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
886                                 ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE);
887                 ret = -1;
888                 goto out;
889         }
890         pr_debug("Located Storage Object: %s\n", tiqn->tiqn);
891
892         /*
893          * Locate Target Portal Group from Storage Node.
894          */
895         conn->tpg = iscsit_get_tpg_from_np(tiqn, np);
896         if (!conn->tpg) {
897                 pr_err("Unable to locate Target Portal Group"
898                                 " on %s\n", tiqn->tiqn);
899                 iscsit_put_tiqn_for_login(tiqn);
900                 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
901                                 ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE);
902                 ret = -1;
903                 goto out;
904         }
905         pr_debug("Located Portal Group Object: %hu\n", conn->tpg->tpgt);
906         /*
907          * Setup crc32c modules from libcrypto
908          */
909         if (iscsi_login_setup_crypto(conn) < 0) {
910                 pr_err("iscsi_login_setup_crypto() failed\n");
911                 ret = -1;
912                 goto out;
913         }
914         /*
915          * Serialize access across the struct iscsi_portal_group to
916          * process login attempt.
917          */
918         if (iscsit_access_np(np, conn->tpg) < 0) {
919                 iscsit_put_tiqn_for_login(tiqn);
920                 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
921                                 ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE);
922                 ret = -1;
923                 conn->tpg = NULL;
924                 goto out;
925         }
926
927         /*
928          * conn->sess->node_acl will be set when the referenced
929          * struct iscsi_session is located from received ISID+TSIH in
930          * iscsi_login_non_zero_tsih_s2().
931          */
932         if (!login->leading_connection) {
933                 ret = 0;
934                 goto out;
935         }
936
937         /*
938          * This value is required in iscsi_login_zero_tsih_s2()
939          */
940         sess->sess_ops->SessionType = 0;
941
942         /*
943          * Locate incoming Initiator IQN reference from Storage Node.
944          */
945         sess->se_sess->se_node_acl = core_tpg_check_initiator_node_acl(
946                         &conn->tpg->tpg_se_tpg, i_buf);
947         if (!sess->se_sess->se_node_acl) {
948                 pr_err("iSCSI Initiator Node: %s is not authorized to"
949                         " access iSCSI target portal group: %hu.\n",
950                                 i_buf, conn->tpg->tpgt);
951                 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
952                                 ISCSI_LOGIN_STATUS_TGT_FORBIDDEN);
953                 ret = -1;
954                 goto out;
955         }
956
957         ret = 0;
958 out:
959         kfree(tmpbuf);
960         return ret;
961 }
962
963 struct iscsi_login *iscsi_target_init_negotiation(
964         struct iscsi_np *np,
965         struct iscsi_conn *conn,
966         char *login_pdu)
967 {
968         struct iscsi_login *login;
969
970         login = kzalloc(sizeof(struct iscsi_login), GFP_KERNEL);
971         if (!login) {
972                 pr_err("Unable to allocate memory for struct iscsi_login.\n");
973                 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
974                                 ISCSI_LOGIN_STATUS_NO_RESOURCES);
975                 return NULL;
976         }
977
978         login->req = kmemdup(login_pdu, ISCSI_HDR_LEN, GFP_KERNEL);
979         if (!login->req) {
980                 pr_err("Unable to allocate memory for Login Request.\n");
981                 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
982                                 ISCSI_LOGIN_STATUS_NO_RESOURCES);
983                 goto out;
984         }
985
986         login->req_buf = kzalloc(MAX_KEY_VALUE_PAIRS, GFP_KERNEL);
987         if (!login->req_buf) {
988                 pr_err("Unable to allocate memory for response buffer.\n");
989                 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
990                                 ISCSI_LOGIN_STATUS_NO_RESOURCES);
991                 goto out;
992         }
993         /*
994          * SessionType: Discovery
995          *
996          *      Locates Default Portal
997          *
998          * SessionType: Normal
999          *
1000          *      Locates Target Portal from NP -> Target IQN
1001          */
1002         if (iscsi_target_locate_portal(np, conn, login) < 0) {
1003                 pr_err("iSCSI Login negotiation failed.\n");
1004                 goto out;
1005         }
1006
1007         return login;
1008 out:
1009         kfree(login->req);
1010         kfree(login->req_buf);
1011         kfree(login);
1012
1013         return NULL;
1014 }
1015
1016 int iscsi_target_start_negotiation(
1017         struct iscsi_login *login,
1018         struct iscsi_conn *conn)
1019 {
1020         int ret = -1;
1021
1022         login->rsp = kzalloc(ISCSI_HDR_LEN, GFP_KERNEL);
1023         if (!login->rsp) {
1024                 pr_err("Unable to allocate memory for"
1025                                 " Login Response.\n");
1026                 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
1027                                 ISCSI_LOGIN_STATUS_NO_RESOURCES);
1028                 ret = -1;
1029                 goto out;
1030         }
1031
1032         login->rsp_buf = kzalloc(MAX_KEY_VALUE_PAIRS, GFP_KERNEL);
1033         if (!login->rsp_buf) {
1034                 pr_err("Unable to allocate memory for"
1035                         " request buffer.\n");
1036                 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
1037                                 ISCSI_LOGIN_STATUS_NO_RESOURCES);
1038                 ret = -1;
1039                 goto out;
1040         }
1041
1042         ret = iscsi_target_do_login(conn, login);
1043 out:
1044         if (ret != 0)
1045                 iscsi_remove_failed_auth_entry(conn);
1046
1047         iscsi_target_nego_release(login, conn);
1048         return ret;
1049 }
1050
1051 void iscsi_target_nego_release(
1052         struct iscsi_login *login,
1053         struct iscsi_conn *conn)
1054 {
1055         kfree(login->req);
1056         kfree(login->rsp);
1057         kfree(login->req_buf);
1058         kfree(login->rsp_buf);
1059         kfree(login);
1060 }