iscsi_text.c revision 1.4 1 /* $NetBSD: iscsi_text.c,v 1.4 2012/06/09 06:19:58 mlelstv Exp $ */
2
3 /*-
4 * Copyright (c) 2005,2006,2011 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Wasabi Systems, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include "iscsi_globals.h"
33 #include "base64.h"
34 #include <sys/md5.h>
35 #include <sys/cprng.h>
36
37 #define isdigit(x) ((x) >= '0' && (x) <= '9')
38 #define toupper(x) ((x) & ~0x20)
39
40 /*****************************************************************************/
41
42 #define MAX_STRING 255 /* Maximum length of parameter value */
43 #define MAX_LIST 4 /* Maximum number of list elements we'll ever send */
44
45 /* Maximum number of negotiation parameters in the operational negotiation phase */
46 /* 48 should be more than enough even with the target defining its own keys */
47 #define MAX_NEG 48
48
49 #define CHAP_CHALLENGE_LEN 32 /* Number of bytes to send in challenge */
50 #define CHAP_MD5_SIZE 16 /* Number of bytes in MD5 hash */
51
52 /*****************************************************************************/
53
54 /* authentication states */
55
56 typedef enum
57 {
58 AUTH_INITIAL, /* sending choice of algorithms */
59 AUTH_METHOD_SELECTED, /* received choice, sending first parameter */
60 /* from here it's alg dependent */
61 AUTH_CHAP_ALG_SENT, /* CHAP: Algorithm selected */
62 AUTH_CHAP_RSP_SENT, /* CHAP: Response sent */
63 /* for all algorithms */
64 AUTH_DONE /* in parameter negotiation stage */
65 } auth_state_t;
66
67
68 /* enumeration of all the keys we know, and a place for the ones we don't */
69
70 typedef enum
71 {
72 K_AuthMethod,
73 K_Auth_CHAP_Algorithm,
74 K_Auth_CHAP_Challenge,
75 K_Auth_CHAP_Identifier,
76 K_Auth_CHAP_Name,
77 K_Auth_CHAP_Response,
78 K_DataDigest,
79 K_DataPDUInOrder,
80 K_DataSequenceInOrder,
81 K_DefaultTime2Retain,
82 K_DefaultTime2Wait,
83 K_ErrorRecoveryLevel,
84 K_FirstBurstLength,
85 K_HeaderDigest,
86 K_IFMarker,
87 K_IFMarkInt,
88 K_ImmediateData,
89 K_InitialR2T,
90 K_InitiatorAlias,
91 K_InitiatorName,
92 K_MaxBurstLength,
93 K_MaxConnections,
94 K_MaxOutstandingR2T,
95 K_MaxRecvDataSegmentLength,
96 K_OFMarker,
97 K_OFMarkInt,
98 K_SendTargets,
99 K_SessionType,
100 K_TargetAddress,
101 K_TargetAlias,
102 K_TargetName,
103 K_TargetPortalGroupTag,
104 K_NotUnderstood
105 } text_key_t;
106
107 /* maximum known key */
108 #define MAX_KEY K_TargetPortalGroupTag
109
110
111 #undef DEBOUT
112 #define DEBOUT(x) printf x
113
114
115
116 /* value types */
117 typedef enum
118 { /* Value is... */
119 T_NUM, /* numeric */
120 T_BIGNUM, /* large numeric */
121 T_STRING, /* string */
122 T_YESNO, /* boolean (Yes or No) */
123 T_AUTH, /* authentication type (CHAP or None for now) */
124 T_DIGEST, /* digest (None or CRC32C) */
125 T_RANGE, /* numeric range */
126 T_SENDT, /* send target options (ALL, target-name, empty) */
127 T_SESS /* session type (Discovery or Normal) */
128 } val_kind_t;
129
130
131 /* table of negotiation key strings with value type and default */
132
133 typedef struct
134 {
135 const uint8_t *name; /* the key name */
136 val_kind_t val; /* the value type */
137 uint32_t defval; /* default value */
138 } key_entry_t;
139
140 STATIC key_entry_t entries[] = {
141 {"AuthMethod", T_AUTH, 0},
142 {"CHAP_A", T_NUM, 5},
143 {"CHAP_C", T_BIGNUM, 0},
144 {"CHAP_I", T_NUM, 0},
145 {"CHAP_N", T_STRING, 0},
146 {"CHAP_R", T_BIGNUM, 0},
147 {"DataDigest", T_DIGEST, 0},
148 {"DataPDUInOrder", T_YESNO, 1},
149 {"DataSequenceInOrder", T_YESNO, 1},
150 {"DefaultTime2Retain", T_NUM, 20},
151 {"DefaultTime2Wait", T_NUM, 2},
152 {"ErrorRecoveryLevel", T_NUM, 0},
153 {"FirstBurstLength", T_NUM, 64 * 1024},
154 {"HeaderDigest", T_DIGEST, 0},
155 {"IFMarker", T_YESNO, 0},
156 {"IFMarkInt", T_RANGE, 2048},
157 {"ImmediateData", T_YESNO, 1},
158 {"InitialR2T", T_YESNO, 1},
159 {"InitiatorAlias", T_STRING, 0},
160 {"InitiatorName", T_STRING, 0},
161 {"MaxBurstLength", T_NUM, 256 * 1024},
162 {"MaxConnections", T_NUM, 1},
163 {"MaxOutstandingR2T", T_NUM, 1},
164 {"MaxRecvDataSegmentLength", T_NUM, 8192},
165 {"OFMarker", T_YESNO, 0},
166 {"OFMarkInt", T_RANGE, 2048},
167 {"SendTargets", T_SENDT, 0},
168 {"SessionType", T_SESS, 0},
169 {"TargetAddress", T_STRING, 0},
170 {"TargetAlias", T_STRING, 0},
171 {"TargetName", T_STRING, 0},
172 {"TargetPortalGroupTag", T_NUM, 0},
173 {NULL, T_STRING, 0}
174 };
175
176 /* a negotiation parameter: key and values (there may be more than 1 for lists) */
177 typedef struct
178 {
179 text_key_t key; /* the key */
180 int list_num; /* number of elements in list, doubles as */
181 /* data size for large numeric values */
182 union
183 {
184 uint32_t nval[MAX_LIST]; /* numeric or enumeration values */
185 uint8_t *sval; /* string or data pointer */
186 } val;
187 } negotiation_parameter_t;
188
189
190 /* Negotiation state flags */
191 #define NS_SENT 0x01 /* key was sent to target */
192 #define NS_RECEIVED 0x02 /* key was received from target */
193
194 typedef struct
195 {
196 negotiation_parameter_t pars[MAX_NEG]; /* the parameters to send */
197 negotiation_parameter_t *cpar; /* the last parameter set */
198 uint16_t num_pars; /* number of parameters to send */
199 auth_state_t auth_state; /* authentication state */
200 iscsi_auth_types_t auth_alg; /* authentication algorithm */
201 uint8_t kflags[MAX_KEY + 2]; /* negotiation flags for each key */
202 uint8_t password[MAX_STRING + 1]; /* authentication secret */
203 uint8_t target_password[MAX_STRING + 1]; /* target authentication secret */
204 uint8_t user_name[MAX_STRING + 1]; /* authentication user ID */
205 uint8_t temp_buf[MAX_STRING + 1]; /* scratch buffer */
206
207 bool HeaderDigest;
208 bool DataDigest;
209 bool InitialR2T;
210 bool ImmediateData;
211 uint32_t ErrorRecoveryLevel;
212 uint32_t MaxRecvDataSegmentLength;
213 uint32_t MaxConnections;
214 uint32_t DefaultTime2Wait;
215 uint32_t DefaultTime2Retain;
216 uint32_t MaxBurstLength;
217 uint32_t FirstBurstLength;
218 uint32_t MaxOutstandingR2T;
219
220 } negotiation_state_t;
221
222
223 #define TX(state, key) (state->kflags [key] & NS_SENT)
224 #define RX(state, key) (state->kflags [key] & NS_RECEIVED)
225
226 /*****************************************************************************/
227
228
229 STATIC void
230 chap_md5_response(uint8_t *buffer, uint8_t identifier, uint8_t *secret,
231 uint8_t *challenge, int challenge_size)
232 {
233 MD5_CTX md5;
234
235 MD5Init(&md5);
236 MD5Update(&md5, &identifier, 1);
237 MD5Update(&md5, secret, strlen(secret));
238 MD5Update(&md5, challenge, challenge_size);
239 MD5Final(buffer, &md5);
240 }
241
242
243 /*****************************************************************************/
244
245 /*
246 * hexdig:
247 * Return value of hex digit.
248 * Note: a null character is acceptable, and returns 0.
249 *
250 * Parameter:
251 * c The character
252 *
253 * Returns: The value, -1 on error.
254 */
255
256 static __inline int
257 hexdig(uint8_t c)
258 {
259
260 if (!c) {
261 return 0;
262 }
263 if (isdigit(c)) {
264 return c - '0';
265 }
266 c = toupper(c);
267 if (c >= 'A' && c <= 'F') {
268 return c - 'A' + 10;
269 }
270 return -1;
271 }
272
273 /*
274 * skiptozero:
275 * Skip to next zero character in buffer.
276 *
277 * Parameter:
278 * buf The buffer pointer
279 *
280 * Returns: The pointer to the character after the zero character.
281 */
282
283 static __inline uint8_t *
284 skiptozero(uint8_t *buf)
285 {
286
287 while (*buf) {
288 buf++;
289 }
290 return buf + 1;
291 }
292
293
294 /*
295 * get_bignumval:
296 * Get a large numeric value.
297 * NOTE: Overwrites source string.
298 *
299 * Parameter:
300 * buf The buffer pointer
301 * par The parameter
302 *
303 * Returns: The pointer to the next parameter, NULL on error.
304 */
305
306 STATIC uint8_t *
307 get_bignumval(uint8_t *buf, negotiation_parameter_t *par)
308 {
309 int val;
310 char c;
311 uint8_t *dp = buf;
312
313 par->val.sval = buf;
314
315 if (buf[0] == '0' && (buf[1] == 'x' || buf[1] == 'X')) {
316 buf += 2;
317 while ((c = *buf) != 0x0) {
318 buf++;
319 val = (hexdig(c) << 4) | hexdig(*buf);
320 if (val < 0) {
321 return NULL;
322 }
323 *dp++ = (uint8_t) val;
324 if (*buf) {
325 buf++;
326 }
327 }
328 buf++;
329 par->list_num = dp - par->val.sval;
330 } else if (buf[0] == '0' && (buf[1] == 'b' || buf[1] == 'B')) {
331 buf = base64_decode(&buf[2], par->val.sval, &par->list_num);
332 } else {
333 DEBOUT(("Ill-formatted large number <%s>\n", buf));
334 return NULL;
335 }
336
337 return buf;
338 }
339
340
341 /*
342 * get_numval:
343 * Get a numeric value.
344 *
345 * Parameter:
346 * buf The buffer pointer
347 * pval The pointer to the result.
348 *
349 * Returns: The pointer to the next parameter, NULL on error.
350 */
351
352 STATIC uint8_t *
353 get_numval(uint8_t *buf, uint32_t *pval)
354 {
355 uint32_t val = 0;
356 char c;
357
358 if (buf[0] == '0' && (buf[1] == 'x' || buf[1] == 'X')) {
359 buf += 2;
360 while (*buf && *buf != '~') {
361 int n;
362
363 if ((n = hexdig(*buf++)) < 0)
364 return NULL;
365 val = (val << 4) | n;
366 }
367 } else
368 while (*buf && *buf != '~') {
369 c = *buf++;
370 if (!isdigit(c))
371 return NULL;
372 val = val * 10 + (c - '0');
373 }
374
375 *pval = val;
376
377 return buf + 1;
378 }
379
380
381 /*
382 * get_range:
383 * Get a numeric range.
384 *
385 * Parameter:
386 * buf The buffer pointer
387 * pval1 The pointer to the first result.
388 * pval2 The pointer to the second result.
389 *
390 * Returns: The pointer to the next parameter, NULL on error.
391 */
392
393 STATIC uint8_t *
394 get_range(uint8_t *buf, uint32_t *pval1, uint32_t *pval2)
395 {
396
397 if ((buf = get_numval(buf, pval1)) == NULL)
398 return NULL;
399 if (!*buf)
400 return NULL;
401 if ((buf = get_numval(buf, pval2)) == NULL)
402 return NULL;
403 return buf;
404 }
405
406
407 /*
408 * get_ynval:
409 * Get a yes/no selection.
410 *
411 * Parameter:
412 * buf The buffer pointer
413 * pval The pointer to the result.
414 *
415 * Returns: The pointer to the next parameter, NULL on error.
416 */
417
418 STATIC uint8_t *
419 get_ynval(uint8_t *buf, uint32_t *pval)
420 {
421
422 if (strcmp(buf, "Yes") == 0)
423 *pval = 1;
424 else if (strcmp(buf, "No") == 0)
425 *pval = 0;
426 else
427 return NULL;
428
429 return skiptozero(buf);
430 }
431
432
433 /*
434 * get_digestval:
435 * Get a digest selection.
436 *
437 * Parameter:
438 * buf The buffer pointer
439 * pval The pointer to the result.
440 *
441 * Returns: The pointer to the next parameter, NULL on error.
442 */
443
444 STATIC uint8_t *
445 get_digestval(uint8_t *buf, uint32_t *pval)
446 {
447
448 if (strcmp(buf, "CRC32C") == 0)
449 *pval = 1;
450 else if (strcmp(buf, "None") == 0)
451 *pval = 0;
452 else
453 return NULL;
454
455 return skiptozero(buf);
456 }
457
458
459 /*
460 * get_authval:
461 * Get an authentication method.
462 *
463 * Parameter:
464 * buf The buffer pointer
465 * pval The pointer to the result.
466 *
467 * Returns: The pointer to the next parameter, NULL on error.
468 */
469
470 STATIC uint8_t *
471 get_authval(uint8_t *buf, uint32_t *pval)
472 {
473
474 if (strcmp(buf, "None") == 0)
475 *pval = ISCSI_AUTH_None;
476 else if (strcmp(buf, "CHAP") == 0)
477 *pval = ISCSI_AUTH_CHAP;
478 else if (strcmp(buf, "KRB5") == 0)
479 *pval = ISCSI_AUTH_KRB5;
480 else if (strcmp(buf, "SRP") == 0)
481 *pval = ISCSI_AUTH_SRP;
482 else
483 return NULL;
484
485 return skiptozero(buf);
486 }
487
488
489 /*
490 * get_strval:
491 * Get a string value (returns pointer to original buffer, not a copy).
492 *
493 * Parameter:
494 * buf The buffer pointer
495 * pval The pointer to the result pointer.
496 *
497 * Returns: The pointer to the next parameter, NULL on error.
498 */
499
500 STATIC uint8_t *
501 get_strval(uint8_t *buf, uint8_t **pval)
502 {
503
504 if (strlen(buf) > MAX_STRING)
505 return NULL;
506
507 *pval = buf;
508
509 return skiptozero(buf);
510 }
511
512
513 /*
514 * get_parameter:
515 * Analyze a key=value string.
516 * NOTE: The string is modified in the process.
517 *
518 * Parameter:
519 * buf The buffer pointer
520 * par The parameter descriptor to be filled in
521 *
522 * Returns: The pointer to the next parameter, NULL on error.
523 */
524
525 STATIC uint8_t *
526 get_parameter(uint8_t *buf, negotiation_parameter_t *par)
527 {
528 uint8_t *bp = buf;
529 int i;
530
531 while (*bp && *bp != '=') {
532 bp++;
533 }
534 if (!*bp) {
535 DEBOUT(("get_parameter: Premature end of parameter\n"));
536 return NULL;
537 }
538
539 *bp++ = 0;
540
541 for (i = 0; i <= MAX_KEY; i++)
542 if (!strcmp(buf, entries[i].name))
543 break;
544
545 par->key = i;
546 par->list_num = 1;
547
548 if (i > MAX_KEY) {
549 DEBOUT(("get_parameter: unrecognized key <%s>\n", buf));
550 if (strlen(buf) > MAX_STRING) {
551 DEBOUT(("get_parameter: key name > MAX_STRING\n"));
552 return NULL;
553 }
554 par->val.sval = buf;
555 return skiptozero(bp);
556 }
557
558 switch (entries[i].val) {
559 case T_NUM:
560 bp = get_numval(bp, &par->val.nval[0]);
561 break;
562
563 case T_BIGNUM:
564 bp = get_bignumval(bp, par);
565 break;
566
567 case T_STRING:
568 bp = get_strval(bp, &par->val.sval);
569 break;
570
571 case T_YESNO:
572 bp = get_ynval(bp, &par->val.nval[0]);
573 break;
574
575 case T_AUTH:
576 bp = get_authval(bp, &par->val.nval[0]);
577 break;
578
579 case T_DIGEST:
580 bp = get_digestval(bp, &par->val.nval[0]);
581 break;
582
583 case T_RANGE:
584 bp = get_range(bp, &par->val.nval[0], &par->val.nval[1]);
585 break;
586
587 default:
588 /* Target sending any other types is wrong */
589 bp = NULL;
590 break;
591 }
592 DEB(10, ("get_par: key <%s>=%d, val=%d, ret %p\n",
593 buf, i, entries[i].val, bp));
594 return bp;
595 }
596
597 /*****************************************************************************/
598
599 /*
600 * my_strcpy:
601 * Replacement for strcpy that returns the end of the result string
602 *
603 * Parameter:
604 * dest The destination buffer pointer
605 * src The source string
606 *
607 * Returns: A pointer to the terminating zero of the result.
608 */
609
610 static __inline unsigned
611 my_strcpy(uint8_t *dest, const uint8_t *src)
612 {
613 unsigned cc;
614
615 for (cc = 0 ; (*dest = *src) != 0x0 ; cc++) {
616 dest++;
617 src++;
618 }
619 return cc;
620 }
621
622
623 /*
624 * put_parameter:
625 * Create a key=value string.
626 *
627 * Parameter:
628 * buf The buffer pointer
629 * par The parameter descriptor
630 *
631 * Returns: The pointer to the next free buffer space, NULL on error.
632 */
633
634 STATIC unsigned
635 put_parameter(uint8_t *buf, unsigned len, negotiation_parameter_t *par)
636 {
637 int i;
638 unsigned cc;
639 const uint8_t *sp;
640
641 if (par->key > MAX_KEY) {
642 return snprintf(buf, len, "%s=NotUnderstood", par->val.sval);
643 }
644
645 cc = snprintf(buf, len, "%s=", entries[par->key].name);
646
647 for (i = 0; i < par->list_num; i++) {
648 switch (entries[par->key].val) {
649 case T_NUM:
650 cc += snprintf(&buf[cc], len - cc, "%d", par->val.nval[i]);
651 break;
652
653 case T_BIGNUM:
654 /* list_num holds value size */
655 cc += base64_encode(par->val.sval, par->list_num, &buf[cc]);
656 i = par->list_num;
657 break;
658
659 case T_STRING:
660 cc += my_strcpy(&buf[cc], par->val.sval);
661 break;
662
663 case T_YESNO:
664 cc += my_strcpy(&buf[cc],
665 (par->val.nval[i]) ? "Yes" : "No");
666 break;
667
668 case T_AUTH:
669 switch (par->val.nval[i]) {
670 case ISCSI_AUTH_CHAP:
671 sp = "CHAP";
672 break;
673 case ISCSI_AUTH_KRB5:
674 sp = "KRB5";
675 break;
676 case ISCSI_AUTH_SRP:
677 sp = "SRP";
678 break;
679 default:
680 sp = "None";
681 break;
682 }
683 cc += my_strcpy(&buf[cc], sp);
684 break;
685
686 case T_DIGEST:
687 cc += my_strcpy(&buf[cc], (par->val.nval[i]) ? "CRC32C" : "None");
688 break;
689
690 case T_RANGE:
691 if ((i + 1) >= par->list_num) {
692 cc += my_strcpy(&buf[cc], "Reject");
693 } else {
694 cc += snprintf(&buf[cc], len - cc,
695 "%d~%d", par->val.nval[i],
696 par->val.nval[i + 1]);
697 i++;
698 }
699 break;
700
701 case T_SENDT:
702 cc += my_strcpy(&buf[cc], par->val.sval);
703 break;
704
705 case T_SESS:
706 cc += my_strcpy(&buf[cc],
707 (par->val.nval[i]) ? "Normal" : "Discovery");
708 break;
709
710 default:
711 /* We should't be here... */
712 DEBOUT(("Invalid type %d in put_parameter!\n",
713 entries[par->key].val));
714 break;
715 }
716 if ((i + 1) < par->list_num) {
717 buf[cc++] = ',';
718 }
719 }
720
721 buf[cc] = 0x0; /* make sure it's terminated */
722 return cc + 1; /* return next place in list */
723 }
724
725
726 /*
727 * put_par_block:
728 * Fill a parameter block
729 *
730 * Parameter:
731 * buf The buffer pointer
732 * pars The parameter descriptor array
733 * n The number of elements
734 *
735 * Returns: result from put_parameter (ptr to buffer, NULL on error)
736 */
737
738 static __inline unsigned
739 put_par_block(uint8_t *buf, unsigned len, negotiation_parameter_t *pars, int n)
740 {
741 unsigned cc;
742 int i;
743
744 for (cc = 0, i = 0; i < n; i++) {
745 cc += put_parameter(&buf[cc], len - cc, pars++);
746 if (cc >= len) {
747 break;
748 }
749 }
750 return cc;
751 }
752
753 /*
754 * parameter_size:
755 * Determine the size of a key=value string.
756 *
757 * Parameter:
758 * par The parameter descriptor
759 *
760 * Returns: The size of the resulting string.
761 */
762
763 STATIC int
764 parameter_size(negotiation_parameter_t *par)
765 {
766 int i, size;
767 char buf[24]; /* max. 2 10-digit numbers + sep. */
768
769 if (par->key > MAX_KEY) {
770 return strlen(par->val.sval) + 15;
771 }
772 /* count '=' and terminal zero */
773 size = strlen(entries[par->key].name) + 2;
774
775 for (i = 0; i < par->list_num; i++) {
776 switch (entries[par->key].val) {
777 case T_NUM:
778 size += snprintf(buf, sizeof(buf), "%d",
779 par->val.nval[i]);
780 break;
781
782 case T_BIGNUM:
783 /* list_num holds value size */
784 size += base64_enclen(par->list_num);
785 i = par->list_num;
786 break;
787
788 case T_STRING:
789 case T_SENDT:
790 size += strlen(par->val.sval);
791 break;
792
793 case T_YESNO:
794 size += (par->val.nval[i]) ? 3 : 2;
795 break;
796
797 case T_AUTH:
798 size += (par->val.nval[i] == ISCSI_AUTH_SRP) ? 3 : 4;
799 break;
800
801 case T_DIGEST:
802 size += (par->val.nval[i]) ? 6 : 4;
803 break;
804
805 case T_RANGE:
806 assert((i + 1) < par->list_num);
807 size += snprintf(buf, sizeof(buf), "%d~%d",
808 par->val.nval[i],
809 par->val.nval[i + 1]);
810 i++;
811 break;
812
813 case T_SESS:
814 size += (par->val.nval[i]) ? 6 : 9;
815 break;
816
817 default:
818 /* We should't be here... */
819 DEBOUT(("Invalid type %d in parameter_size!\n",
820 entries[par->key].val));
821 break;
822 }
823 if ((i + 1) < par->list_num) {
824 size++;
825 }
826 }
827
828 return size;
829 }
830
831
832 /*
833 * total_size:
834 * Determine the size of a negotiation data block
835 *
836 * Parameter:
837 * pars The parameter descriptor array
838 * n The number of elements
839 *
840 * Returns: The size of the block
841 */
842
843 static __inline int
844 total_size(negotiation_parameter_t *pars, int n)
845 {
846 int i, size;
847
848 for (i = 0, size = 0; i < n; i++) {
849 size += parameter_size(pars++);
850 }
851 return size;
852 }
853
854 /*****************************************************************************/
855
856
857 /*
858 * complete_pars:
859 * Allocate space for text parameters, translate parameter values into
860 * text.
861 *
862 * Parameter:
863 * state Negotiation state
864 * pdu The transmit PDU
865 *
866 * Returns: 0 On success
867 * > 0 (an ISCSI error code) if an error occurred.
868 */
869
870 STATIC int
871 complete_pars(negotiation_state_t *state, pdu_t *pdu)
872 {
873 int len;
874 uint8_t *bp;
875 #ifdef ISCSI_TEST_MODE
876 test_pars_t *tp = pdu->connection->test_pars;
877 neg_desc_t *nd = NULL;
878 #endif
879
880 len = total_size(state->pars, state->num_pars);
881
882 #ifdef ISCSI_TEST_MODE
883 if (tp != NULL) {
884 while ((nd = TAILQ_FIRST(&pdu->connection->test_pars->negs)) != NULL &&
885 nd->entry.state < state->auth_state) {
886 TAILQ_REMOVE(&tp->negs, nd, link);
887 free(nd, M_TEMP);
888 }
889 if (nd != NULL && nd->entry.state == state->auth_state) {
890 if (nd->entry.flags & ISCSITEST_NEGOPT_REPLACE)
891 len = 0;
892 len += nd->entry.size;
893 } else
894 nd = NULL;
895 }
896 #endif
897
898 DEB(10, ("complete_pars: n=%d, len=%d\n", state->num_pars, len));
899
900 if ((bp = malloc(len, M_TEMP, M_WAITOK)) == NULL) {
901 DEBOUT(("*** Out of memory in complete_pars\n"));
902 return ISCSI_STATUS_NO_RESOURCES;
903 }
904 pdu->temp_data = bp;
905
906 #ifdef ISCSI_TEST_MODE
907 if (nd == NULL || !(nd->entry.flags & ISCSITEST_NEGOPT_REPLACE))
908 if ((bp = put_par_block(pdu->temp_data, len,
909 state->pars, state->num_pars)) == NULL) {
910 DEBOUT(("Bad parameter in complete_pars\n"));
911 return ISCSI_STATUS_PARAMETER_INVALID;
912 }
913 if (nd != NULL) {
914 memcpy(bp, nd->entry.value, nd->entry.size);
915 TAILQ_REMOVE(&tp->negs, nd, link);
916 free(nd, M_TEMP);
917 }
918 #else
919 if (put_par_block(pdu->temp_data, len, state->pars,
920 state->num_pars) == 0) {
921 DEBOUT(("Bad parameter in complete_pars\n"));
922 return ISCSI_STATUS_PARAMETER_INVALID;
923 }
924 #endif
925
926 pdu->temp_data_len = len;
927 return 0;
928 }
929
930
931 /*
932 * set_key_n:
933 * Initialize a key and its numeric value.
934 *
935 * Parameter:
936 * state Negotiation state
937 * key The key
938 * val The value
939 */
940
941 STATIC negotiation_parameter_t *
942 set_key_n(negotiation_state_t *state, text_key_t key, uint32_t val)
943 {
944 negotiation_parameter_t *par;
945
946 if (state->num_pars >= MAX_NEG) {
947 DEBOUT(("set_key_n: num_pars (%d) >= MAX_NEG (%d)\n",
948 state->num_pars, MAX_NEG));
949 return NULL;
950 }
951 par = &state->pars[state->num_pars];
952 par->key = key;
953 par->list_num = 1;
954 par->val.nval[0] = val;
955 state->num_pars++;
956 state->kflags[key] |= NS_SENT;
957
958 return par;
959 }
960
961 /*
962 * set_key_s:
963 * Initialize a key and its string value.
964 *
965 * Parameter:
966 * state Negotiation state
967 * key The key
968 * val The value
969 */
970
971 STATIC negotiation_parameter_t *
972 set_key_s(negotiation_state_t *state, text_key_t key, uint8_t *val)
973 {
974 negotiation_parameter_t *par;
975
976 if (state->num_pars >= MAX_NEG) {
977 DEBOUT(("set_key_s: num_pars (%d) >= MAX_NEG (%d)\n",
978 state->num_pars, MAX_NEG));
979 return NULL;
980 }
981 par = &state->pars[state->num_pars];
982 par->key = key;
983 par->list_num = 1;
984 par->val.sval = val;
985 state->num_pars++;
986 state->kflags[key] |= NS_SENT;
987
988 return par;
989 }
990
991
992 /*****************************************************************************/
993
994 /*
995 * eval_parameter:
996 * Evaluate a received negotiation value.
997 *
998 * Parameter:
999 * conn The connection
1000 * state The negotiation state
1001 * par The parameter
1002 *
1003 * Returns: 0 on success, else an ISCSI status value.
1004 */
1005
1006 STATIC int
1007 eval_parameter(connection_t *conn, negotiation_state_t *state,
1008 negotiation_parameter_t *par)
1009 {
1010 uint32_t n = par->val.nval[0];
1011 size_t sz;
1012 text_key_t key = par->key;
1013 bool sent = (state->kflags[key] & NS_SENT) != 0;
1014
1015 state->kflags[key] |= NS_RECEIVED;
1016
1017 switch (key) {
1018 /*
1019 * keys connected to security negotiation
1020 */
1021 case K_AuthMethod:
1022 if (n) {
1023 DEBOUT(("eval_par: AuthMethod nonzero (%d)\n", n));
1024 return ISCSI_STATUS_NEGOTIATION_ERROR;
1025 }
1026 break;
1027
1028 case K_Auth_CHAP_Algorithm:
1029 case K_Auth_CHAP_Challenge:
1030 case K_Auth_CHAP_Identifier:
1031 case K_Auth_CHAP_Name:
1032 case K_Auth_CHAP_Response:
1033 DEBOUT(("eval_par: Authorization Key in Operational Phase\n"));
1034 return ISCSI_STATUS_NEGOTIATION_ERROR;
1035
1036 /*
1037 * keys we always send
1038 */
1039 case K_DataDigest:
1040 state->DataDigest = n;
1041 if (!sent)
1042 set_key_n(state, key, n);
1043 break;
1044
1045 case K_HeaderDigest:
1046 state->HeaderDigest = n;
1047 if (!sent)
1048 set_key_n(state, key, n);
1049 break;
1050
1051 case K_ErrorRecoveryLevel:
1052 state->ErrorRecoveryLevel = n;
1053 if (!sent)
1054 set_key_n(state, key, n);
1055 break;
1056
1057 case K_ImmediateData:
1058 state->ImmediateData = n;
1059 if (!sent)
1060 set_key_n(state, key, n);
1061 break;
1062
1063 case K_InitialR2T:
1064 state->InitialR2T = n;
1065 if (!sent)
1066 set_key_n(state, key, n);
1067 break;
1068
1069 case K_MaxRecvDataSegmentLength:
1070 state->MaxRecvDataSegmentLength = n;
1071 /* this is basically declarative, not negotiated */
1072 /* (each side has its own value) */
1073 break;
1074
1075 /*
1076 * keys we don't always send, so we may have to reflect the value
1077 */
1078 case K_DefaultTime2Retain:
1079 state->DefaultTime2Retain = n = min(state->DefaultTime2Retain, n);
1080 if (!sent)
1081 set_key_n(state, key, n);
1082 break;
1083
1084 case K_DefaultTime2Wait:
1085 state->DefaultTime2Wait = n = min(state->DefaultTime2Wait, n);
1086 if (!sent)
1087 set_key_n(state, key, n);
1088 break;
1089
1090 case K_MaxConnections:
1091 if (state->MaxConnections)
1092 state->MaxConnections = n = min(state->MaxConnections, n);
1093 else
1094 state->MaxConnections = n;
1095
1096 if (!sent)
1097 set_key_n(state, key, n);
1098 break;
1099
1100 case K_MaxOutstandingR2T:
1101 state->MaxOutstandingR2T = n;
1102 if (!sent)
1103 set_key_n(state, key, n);
1104 break;
1105
1106 case K_FirstBurstLength:
1107 state->FirstBurstLength = n;
1108 if (!sent)
1109 set_key_n(state, key, n);
1110 break;
1111
1112 case K_MaxBurstLength:
1113 state->MaxBurstLength = n;
1114 if (!sent)
1115 set_key_n(state, key, n);
1116 break;
1117
1118 case K_IFMarker:
1119 case K_OFMarker:
1120 /* not (yet) supported */
1121 if (!sent)
1122 set_key_n(state, key, 0);
1123 break;
1124
1125 case K_IFMarkInt:
1126 case K_OFMarkInt:
1127 /* it's a range, and list_num will be 1, so this will reply "Reject" */
1128 if (!sent)
1129 set_key_n(state, key, 0);
1130 break;
1131
1132 case K_DataPDUInOrder:
1133 case K_DataSequenceInOrder:
1134 /* values are don't care */
1135 if (!sent)
1136 set_key_n(state, key, n);
1137 break;
1138
1139 case K_NotUnderstood:
1140 /* return "NotUnderstood" */
1141 set_key_s(state, key, par->val.sval);
1142 break;
1143
1144 /*
1145 * Declarative keys (no response required)
1146 */
1147 case K_TargetAddress:
1148 /* ignore for now... */
1149 break;
1150
1151 case K_TargetAlias:
1152 if (conn->login_par->is_present.TargetAlias) {
1153 copyoutstr(par->val.sval, conn->login_par->TargetAlias,
1154 ISCSI_STRING_LENGTH - 1, &sz);
1155 /* do anything with return code?? */
1156 }
1157 break;
1158
1159 case K_TargetPortalGroupTag:
1160 /* ignore for now... */
1161 break;
1162
1163 default:
1164 DEBOUT(("eval_par: Invalid parameter type %d\n", par->key));
1165 return ISCSI_STATUS_NEGOTIATION_ERROR;
1166 }
1167 return 0;
1168 }
1169
1170 /*****************************************************************************/
1171
1172
1173 /*
1174 * init_session_parameters:
1175 * Initialize session-related negotiation parameters from existing session
1176 *
1177 * Parameter:
1178 * sess The session
1179 * state The negotiation state
1180 */
1181
1182 STATIC void
1183 init_session_parameters(session_t *sess, negotiation_state_t *state)
1184 {
1185
1186 state->ErrorRecoveryLevel = sess->ErrorRecoveryLevel;
1187 state->InitialR2T = sess->InitialR2T;
1188 state->ImmediateData = sess->ImmediateData;
1189 state->MaxConnections = sess->MaxConnections;
1190 state->DefaultTime2Wait = sess->DefaultTime2Wait;
1191 state->DefaultTime2Retain = sess->DefaultTime2Retain;
1192 state->MaxBurstLength = sess->MaxBurstLength;
1193 state->FirstBurstLength = sess->FirstBurstLength;
1194 state->MaxOutstandingR2T = sess->MaxOutstandingR2T;
1195 }
1196
1197
1198
1199 /*
1200 * assemble_login_parameters:
1201 * Assemble the initial login negotiation parameters.
1202 *
1203 * Parameter:
1204 * conn The connection
1205 * ccb The CCB for the login exchange
1206 * pdu The PDU to use for sending
1207 *
1208 * Returns: < 0 if more security negotiation is required
1209 * 0 if this is the last security negotiation block
1210 * > 0 (an ISCSI error code) if an error occurred.
1211 */
1212
1213 int
1214 assemble_login_parameters(connection_t *conn, ccb_t *ccb, pdu_t *pdu)
1215 {
1216 iscsi_login_parameters_t *par = conn->login_par;
1217 size_t sz;
1218 int rc, i, next;
1219 negotiation_state_t *state;
1220 negotiation_parameter_t *cpar;
1221
1222 state = malloc(sizeof(*state), M_TEMP, M_WAITOK | M_ZERO);
1223 if (state == NULL) {
1224 DEBOUT(("*** Out of memory in assemble_login_params\n"));
1225 return ISCSI_STATUS_NO_RESOURCES;
1226 }
1227 ccb->temp_data = state;
1228
1229 if (!InitiatorName[0]) {
1230 DEBOUT(("No InitiatorName\n"));
1231 return ISCSI_STATUS_PARAMETER_MISSING;
1232 }
1233 set_key_s(state, K_InitiatorName, InitiatorName);
1234
1235 if (InitiatorAlias[0])
1236 set_key_s(state, K_InitiatorAlias, InitiatorAlias);
1237
1238 conn->Our_MaxRecvDataSegmentLength =
1239 (par->is_present.MaxRecvDataSegmentLength)
1240 ? par->MaxRecvDataSegmentLength : DEFAULT_MaxRecvDataSegmentLength;
1241
1242 /* setup some values for authentication */
1243 if (par->is_present.password)
1244 copyinstr(par->password, state->password, MAX_STRING, &sz);
1245 if (par->is_present.target_password)
1246 copyinstr(par->target_password, state->target_password,
1247 MAX_STRING, &sz);
1248 if (par->is_present.user_name)
1249 copyinstr(par->user_name, state->user_name, MAX_STRING, &sz);
1250 else
1251 strlcpy(state->user_name, InitiatorName,
1252 sizeof(state->user_name));
1253
1254 next = TRUE;
1255
1256 set_key_n(state, K_SessionType,
1257 par->login_type > ISCSI_LOGINTYPE_DISCOVERY);
1258
1259 cpar = set_key_n(state, K_AuthMethod, ISCSI_AUTH_None);
1260
1261 if (cpar != NULL && par->is_present.auth_info &&
1262 par->auth_info.auth_number > 0) {
1263 if (par->auth_info.auth_number > ISCSI_AUTH_OPTIONS) {
1264 DEBOUT(("Auth number too big in asm_login\n"));
1265 return ISCSI_STATUS_PARAMETER_INVALID;
1266 }
1267 cpar->list_num = par->auth_info.auth_number;
1268 for (i = 0; i < cpar->list_num; i++) {
1269 cpar->val.nval[i] = par->auth_info.auth_type[i];
1270 if (par->auth_info.auth_type[i])
1271 next = FALSE;
1272 }
1273 }
1274
1275 if (par->is_present.TargetName)
1276 copyinstr(par->TargetName, state->temp_buf, ISCSI_STRING_LENGTH - 1,
1277 &sz);
1278 else {
1279 state->temp_buf[0] = 0;
1280 sz = 0;
1281 }
1282
1283 if ((!sz || !state->temp_buf[0]) &&
1284 par->login_type != ISCSI_LOGINTYPE_DISCOVERY) {
1285 DEBOUT(("No TargetName\n"));
1286 return ISCSI_STATUS_PARAMETER_MISSING;
1287 }
1288
1289 if (state->temp_buf[0]) {
1290 set_key_s(state, K_TargetName, state->temp_buf);
1291 }
1292
1293 if ((rc = complete_pars(state, pdu)) != 0)
1294 return rc;
1295
1296 return (next) ? 0 : -1;
1297 }
1298
1299
1300 /*
1301 * assemble_security_parameters:
1302 * Assemble the security negotiation parameters.
1303 *
1304 * Parameter:
1305 * conn The connection
1306 * rx_pdu The received login response PDU
1307 * tx_pdu The transmit PDU
1308 *
1309 * Returns: < 0 if more security negotiation is required
1310 * 0 if this is the last security negotiation block
1311 * > 0 (an ISCSI error code) if an error occurred.
1312 */
1313
1314 int
1315 assemble_security_parameters(connection_t *conn, ccb_t *ccb, pdu_t *rx_pdu,
1316 pdu_t *tx_pdu)
1317 {
1318 negotiation_state_t *state = (negotiation_state_t *) ccb->temp_data;
1319 iscsi_login_parameters_t *par = conn->login_par;
1320 negotiation_parameter_t rxp, *cpar;
1321 uint8_t *rxpars;
1322 int rc, next;
1323 uint8_t identifier = 0;
1324 uint8_t *challenge = NULL;
1325 int challenge_size = 0;
1326 uint8_t *response = NULL;
1327 int response_size = 0;
1328
1329 state->num_pars = 0;
1330 next = 0;
1331
1332 rxpars = (uint8_t *) rx_pdu->temp_data;
1333 if (rxpars == NULL) {
1334 DEBOUT(("No received parameters!\n"));
1335 return ISCSI_STATUS_NEGOTIATION_ERROR;
1336 }
1337 /* Note: There are always at least 2 extra bytes past temp_data_len */
1338 rxpars[rx_pdu->temp_data_len] = '\0';
1339 rxpars[rx_pdu->temp_data_len + 1] = '\0';
1340
1341 while (*rxpars) {
1342 if ((rxpars = get_parameter(rxpars, &rxp)) == NULL) {
1343 DEBOUT(("get_parameter returned error\n"));
1344 return ISCSI_STATUS_NEGOTIATION_ERROR;
1345 }
1346
1347 state->kflags[rxp.key] |= NS_RECEIVED;
1348
1349 switch (rxp.key) {
1350 case K_AuthMethod:
1351 if (state->auth_state != AUTH_INITIAL) {
1352 DEBOUT(("AuthMethod received, auth_state = %d\n",
1353 state->auth_state));
1354 return ISCSI_STATUS_NEGOTIATION_ERROR;
1355 }
1356
1357 /* Note: if the selection is None, we shouldn't be here,
1358 * the target should have transited the state to op-neg.
1359 */
1360 if (rxp.val.nval[0] != ISCSI_AUTH_CHAP) {
1361 DEBOUT(("AuthMethod isn't CHAP (%d)\n", rxp.val.nval[0]));
1362 return ISCSI_STATUS_NEGOTIATION_ERROR;
1363 }
1364
1365 state->auth_state = AUTH_METHOD_SELECTED;
1366 state->auth_alg = rxp.val.nval[0];
1367 break;
1368
1369 case K_Auth_CHAP_Algorithm:
1370 if (state->auth_state != AUTH_CHAP_ALG_SENT ||
1371 rxp.val.nval[0] != 5) {
1372 DEBOUT(("Bad algorithm, auth_state = %d, alg %d\n",
1373 state->auth_state, rxp.val.nval[0]));
1374 return ISCSI_STATUS_NEGOTIATION_ERROR;
1375 }
1376 break;
1377
1378 case K_Auth_CHAP_Challenge:
1379 if (state->auth_state != AUTH_CHAP_ALG_SENT || !rxp.list_num) {
1380 DEBOUT(("Bad Challenge, auth_state = %d, len %d\n",
1381 state->auth_state, rxp.list_num));
1382 return ISCSI_STATUS_NEGOTIATION_ERROR;
1383 }
1384 challenge = rxp.val.sval;
1385 challenge_size = rxp.list_num;
1386 break;
1387
1388 case K_Auth_CHAP_Identifier:
1389 if (state->auth_state != AUTH_CHAP_ALG_SENT) {
1390 DEBOUT(("Bad ID, auth_state = %d, id %d\n",
1391 state->auth_state, rxp.val.nval[0]));
1392 return ISCSI_STATUS_NEGOTIATION_ERROR;
1393 }
1394 identifier = (uint8_t) rxp.val.nval[0];
1395 break;
1396
1397 case K_Auth_CHAP_Name:
1398 if (state->auth_state != AUTH_CHAP_RSP_SENT) {
1399 DEBOUT(("Bad Name, auth_state = %d, name <%s>\n",
1400 state->auth_state, rxp.val.sval));
1401 return ISCSI_STATUS_NEGOTIATION_ERROR;
1402 }
1403 /* what do we do with the name?? */
1404 break;
1405
1406 case K_Auth_CHAP_Response:
1407 if (state->auth_state != AUTH_CHAP_RSP_SENT) {
1408 DEBOUT(("Bad Response, auth_state = %d, size %d\n",
1409 state->auth_state, rxp.list_num));
1410 return ISCSI_STATUS_NEGOTIATION_ERROR;
1411 }
1412 response = rxp.val.sval;
1413 response_size = rxp.list_num;
1414 if (response_size != CHAP_MD5_SIZE)
1415 return ISCSI_STATUS_NEGOTIATION_ERROR;
1416 break;
1417
1418 default:
1419 rc = eval_parameter(conn, state, &rxp);
1420 if (rc)
1421 return rc;
1422 break;
1423 }
1424 }
1425
1426 switch (state->auth_state) {
1427 case AUTH_INITIAL:
1428 DEBOUT(("Didn't receive Method\n"));
1429 return ISCSI_STATUS_NEGOTIATION_ERROR;
1430
1431 case AUTH_METHOD_SELECTED:
1432 set_key_n(state, K_Auth_CHAP_Algorithm, 5);
1433 state->auth_state = AUTH_CHAP_ALG_SENT;
1434 next = -1;
1435 break;
1436
1437 case AUTH_CHAP_ALG_SENT:
1438 if (!RX(state, K_Auth_CHAP_Algorithm) ||
1439 !RX(state, K_Auth_CHAP_Identifier) ||
1440 !RX(state, K_Auth_CHAP_Challenge)) {
1441 DEBOUT(("Didn't receive all parameters\n"));
1442 return ISCSI_STATUS_NEGOTIATION_ERROR;
1443 }
1444
1445 set_key_s(state, K_Auth_CHAP_Name, state->user_name);
1446
1447 chap_md5_response(state->temp_buf, identifier, state->password,
1448 challenge, challenge_size);
1449
1450 cpar = set_key_s(state, K_Auth_CHAP_Response, state->temp_buf);
1451 if (cpar != NULL)
1452 cpar->list_num = CHAP_MD5_SIZE;
1453
1454 if (par->auth_info.mutual_auth) {
1455 if (!state->target_password[0]) {
1456 DEBOUT(("No target password with mutual authentication!\n"));
1457 return ISCSI_STATUS_PARAMETER_MISSING;
1458 }
1459
1460 cprng_strong(kern_cprng,
1461 &state->temp_buf[CHAP_MD5_SIZE],
1462 CHAP_CHALLENGE_LEN + 1, 0);
1463 set_key_n(state, K_Auth_CHAP_Identifier,
1464 state->temp_buf[CHAP_MD5_SIZE]);
1465 cpar = set_key_s(state, K_Auth_CHAP_Challenge,
1466 &state->temp_buf[CHAP_MD5_SIZE + 1]);
1467 if (cpar != NULL)
1468 cpar->list_num = CHAP_CHALLENGE_LEN;
1469 next = -1;
1470 }
1471 state->auth_state = AUTH_CHAP_RSP_SENT;
1472 break;
1473
1474 case AUTH_CHAP_RSP_SENT:
1475 /* we can only be here for mutual authentication */
1476 if (!par->auth_info.mutual_auth || response == NULL) {
1477 DEBOUT(("Mutual authentication not requested\n"));
1478 return ISCSI_STATUS_NEGOTIATION_ERROR;
1479 }
1480
1481 chap_md5_response(state->temp_buf,
1482 state->temp_buf[CHAP_MD5_SIZE],
1483 state->password,
1484 &state->temp_buf[CHAP_MD5_SIZE + 1],
1485 CHAP_CHALLENGE_LEN);
1486
1487 if (memcmp(state->temp_buf, response, response_size)) {
1488 DEBOUT(("Mutual authentication mismatch\n"));
1489 return ISCSI_STATUS_AUTHENTICATION_FAILED;
1490 }
1491 break;
1492
1493 default:
1494 break;
1495 }
1496
1497 complete_pars(state, tx_pdu);
1498
1499 return next;
1500 }
1501
1502
1503 /*
1504 * set_first_opnegs:
1505 * Set the operational negotiation parameters we want to negotiate in
1506 * the first login request in op_neg phase.
1507 *
1508 * Parameter:
1509 * conn The connection
1510 * state Negotiation state
1511 */
1512
1513 STATIC void
1514 set_first_opnegs(connection_t *conn, negotiation_state_t *state)
1515 {
1516 iscsi_login_parameters_t *lpar = conn->login_par;
1517 negotiation_parameter_t *cpar;
1518
1519 /* Digests - suggest None,CRC32C unless the user forces a value */
1520 cpar = set_key_n(state, K_HeaderDigest,
1521 (lpar->is_present.HeaderDigest) ? lpar->HeaderDigest : 0);
1522 if (cpar != NULL && !lpar->is_present.HeaderDigest) {
1523 cpar->list_num = 2;
1524 cpar->val.nval[1] = 1;
1525 }
1526
1527 cpar = set_key_n(state, K_DataDigest, (lpar->is_present.DataDigest)
1528 ? lpar->DataDigest : 0);
1529 if (cpar != NULL && !lpar->is_present.DataDigest) {
1530 cpar->list_num = 2;
1531 cpar->val.nval[1] = 1;
1532 }
1533
1534 set_key_n(state, K_MaxRecvDataSegmentLength,
1535 conn->Our_MaxRecvDataSegmentLength);
1536 /* This is direction-specific, we may have a different default */
1537 state->MaxRecvDataSegmentLength =
1538 entries[K_MaxRecvDataSegmentLength].defval;
1539
1540 /* First connection only */
1541 if (!conn->session->TSIH) {
1542 state->ErrorRecoveryLevel =
1543 (lpar->is_present.ErrorRecoveryLevel) ? lpar->ErrorRecoveryLevel
1544 : 2;
1545 /*
1546 Negotiate InitialR2T to FALSE and ImmediateData to TRUE, should
1547 be slightly more efficient than the default InitialR2T=TRUE.
1548 */
1549 state->InitialR2T = FALSE;
1550 state->ImmediateData = TRUE;
1551
1552 /* We don't really care about this, so don't negotiate by default */
1553 state->MaxBurstLength = entries[K_MaxBurstLength].defval;
1554 state->FirstBurstLength = entries[K_FirstBurstLength].defval;
1555 state->MaxOutstandingR2T = entries[K_MaxOutstandingR2T].defval;
1556
1557 #ifdef ISCSI_TEST_MODE
1558 if (conn->test_pars != NULL) {
1559 test_pars_t *tp = conn->test_pars;
1560
1561 if (tp->options & ISCSITEST_OVERRIDE_INITIALR2T)
1562 state->InitialR2T = TRUE;
1563 if (tp->options & ISCSITEST_OVERRIDE_IMMDATA)
1564 state->ImmediateData = FALSE;
1565
1566 if (tp->options & ISCSITEST_NEGOTIATE_MAXBURST) {
1567 state->MaxBurstLength = tp->maxburst_val;
1568 set_key_n(state, K_MaxBurstLength, state->MaxBurstLength);
1569 }
1570 if (tp->options & ISCSITEST_NEGOTIATE_FIRSTBURST) {
1571 state->FirstBurstLength = tp->firstburst_val;
1572 set_key_n(state, K_FirstBurstLength, state->FirstBurstLength);
1573 }
1574 if (tp->options & ISCSITEST_NEGOTIATE_R2T) {
1575 state->MaxOutstandingR2T = tp->r2t_val;
1576 set_key_n(state, K_MaxOutstandingR2T, state->MaxOutstandingR2T);
1577 }
1578 }
1579 #endif
1580
1581 set_key_n(state, K_ErrorRecoveryLevel, state->ErrorRecoveryLevel);
1582 set_key_n(state, K_InitialR2T, state->InitialR2T);
1583 set_key_n(state, K_ImmediateData, state->ImmediateData);
1584
1585 if (lpar->is_present.MaxConnections) {
1586 state->MaxConnections = lpar->MaxConnections;
1587 set_key_n(state, K_MaxConnections, lpar->MaxConnections);
1588 }
1589
1590 if (lpar->is_present.DefaultTime2Wait)
1591 set_key_n(state, K_DefaultTime2Wait, lpar->DefaultTime2Wait);
1592 else
1593 state->DefaultTime2Wait = entries[K_DefaultTime2Wait].defval;
1594
1595 if (lpar->is_present.DefaultTime2Retain)
1596 set_key_n(state, K_DefaultTime2Retain, lpar->DefaultTime2Retain);
1597 else
1598 state->DefaultTime2Retain = entries[K_DefaultTime2Retain].defval;
1599 } else
1600 init_session_parameters(conn->session, state);
1601
1602 DEBC(conn, 10, ("SetFirstOpnegs: recover=%d, MRDSL=%d\n",
1603 conn->recover, state->MaxRecvDataSegmentLength));
1604 }
1605
1606
1607 /*
1608 * assemble_negotiation_parameters:
1609 * Assemble any negotiation parameters requested by the other side.
1610 *
1611 * Parameter:
1612 * conn The connection
1613 * ccb The login ccb
1614 * rx_pdu The received login response PDU
1615 * tx_pdu The transmit PDU
1616 *
1617 * Returns: 0 On success
1618 * > 0 (an ISCSI error code) if an error occurred.
1619 */
1620
1621 int
1622 assemble_negotiation_parameters(connection_t *conn, ccb_t *ccb, pdu_t *rx_pdu,
1623 pdu_t *tx_pdu)
1624 {
1625 negotiation_state_t *state = (negotiation_state_t *) ccb->temp_data;
1626 negotiation_parameter_t rxp;
1627 uint8_t *rxpars;
1628 int rc;
1629
1630 state->num_pars = 0;
1631
1632 DEBC(conn, 10, ("AsmNegParams: connState=%d, MRDSL=%d\n",
1633 conn->state, state->MaxRecvDataSegmentLength));
1634
1635 if (conn->state == ST_SEC_NEG) {
1636 conn->state = ST_OP_NEG;
1637 set_first_opnegs(conn, state);
1638 }
1639
1640 rxpars = (uint8_t *) rx_pdu->temp_data;
1641 if (rxpars != NULL) {
1642 /* Note: There are always at least 2 extra bytes past temp_data_len */
1643 rxpars[rx_pdu->temp_data_len] = '\0';
1644 rxpars[rx_pdu->temp_data_len + 1] = '\0';
1645
1646 while (*rxpars) {
1647 if ((rxpars = get_parameter(rxpars, &rxp)) == NULL)
1648 return ISCSI_STATUS_NEGOTIATION_ERROR;
1649
1650 rc = eval_parameter(conn, state, &rxp);
1651 if (rc)
1652 return rc;
1653 }
1654 }
1655
1656 if (tx_pdu == NULL)
1657 return 0;
1658
1659 complete_pars(state, tx_pdu);
1660
1661 return 0;
1662 }
1663
1664 /*
1665 * init_text_parameters:
1666 * Initialize text negotiation.
1667 *
1668 * Parameter:
1669 * conn The connection
1670 * tx_pdu The transmit PDU
1671 *
1672 * Returns: 0 On success
1673 * > 0 (an ISCSI error code) if an error occurred.
1674 */
1675
1676 int
1677 init_text_parameters(connection_t *conn, ccb_t *ccb)
1678 {
1679 negotiation_state_t *state;
1680
1681 state = malloc(sizeof(*state), M_TEMP, M_WAITOK | M_ZERO);
1682 if (state == NULL) {
1683 DEBOUT(("*** Out of memory in init_text_params\n"));
1684 return ISCSI_STATUS_NO_RESOURCES;
1685 }
1686 ccb->temp_data = state;
1687
1688 state->HeaderDigest = conn->HeaderDigest;
1689 state->DataDigest = conn->DataDigest;
1690 state->MaxRecvDataSegmentLength = conn->MaxRecvDataSegmentLength;
1691 init_session_parameters(conn->session, state);
1692
1693 return 0;
1694 }
1695
1696
1697 /*
1698 * assemble_send_targets:
1699 * Assemble send targets request
1700 *
1701 * Parameter:
1702 * pdu The transmit PDU
1703 * val The SendTargets key value
1704 *
1705 * Returns: 0 On success
1706 * > 0 (an ISCSI error code) if an error occurred.
1707 */
1708
1709 int
1710 assemble_send_targets(pdu_t *pdu, uint8_t *val)
1711 {
1712 negotiation_parameter_t par;
1713 uint8_t *buf;
1714 int len;
1715
1716 par.key = K_SendTargets;
1717 par.list_num = 1;
1718 par.val.sval = val;
1719
1720 len = parameter_size(&par);
1721
1722 if ((buf = malloc(len, M_TEMP, M_WAITOK)) == NULL) {
1723 DEBOUT(("*** Out of memory in assemble_send_targets\n"));
1724 return ISCSI_STATUS_NO_RESOURCES;
1725 }
1726 pdu->temp_data = buf;
1727 pdu->temp_data_len = len;
1728
1729 if (put_parameter(buf, len, &par) == 0)
1730 return ISCSI_STATUS_PARAMETER_INVALID;
1731
1732 return 0;
1733 }
1734
1735
1736 /*
1737 * set_negotiated_parameters:
1738 * Copy the negotiated parameters into the connection and session structure.
1739 *
1740 * Parameter:
1741 * ccb The ccb containing the state information
1742 */
1743
1744 void
1745 set_negotiated_parameters(ccb_t *ccb)
1746 {
1747 negotiation_state_t *state = (negotiation_state_t *) ccb->temp_data;
1748 connection_t *conn = ccb->connection;
1749 session_t *sess = ccb->session;
1750
1751 conn->HeaderDigest = state->HeaderDigest;
1752 conn->DataDigest = state->DataDigest;
1753 sess->ErrorRecoveryLevel = state->ErrorRecoveryLevel;
1754 sess->InitialR2T = state->InitialR2T;
1755 sess->ImmediateData = state->ImmediateData;
1756 conn->MaxRecvDataSegmentLength = state->MaxRecvDataSegmentLength;
1757 sess->MaxConnections = state->MaxConnections;
1758 sess->DefaultTime2Wait = conn->Time2Wait = state->DefaultTime2Wait;
1759 sess->DefaultTime2Retain = conn->Time2Retain =
1760 state->DefaultTime2Retain;
1761
1762 /* set idle connection timeout to half the Time2Retain window so we */
1763 /* don't miss it, unless Time2Retain is ridiculously small. */
1764 conn->idle_timeout_val = (conn->Time2Retain >= 10) ?
1765 (conn->Time2Retain / 2) * hz : CONNECTION_IDLE_TIMEOUT;
1766
1767 sess->MaxBurstLength = state->MaxBurstLength;
1768 sess->FirstBurstLength = state->FirstBurstLength;
1769 sess->MaxOutstandingR2T = state->MaxOutstandingR2T;
1770
1771 DEBC(conn, 10,("SetNegPar: MRDSL=%d, MBL=%d, FBL=%d, IR2T=%d, ImD=%d\n",
1772 state->MaxRecvDataSegmentLength, state->MaxBurstLength,
1773 state->FirstBurstLength, state->InitialR2T,
1774 state->ImmediateData));
1775
1776 conn->max_transfer = min(sess->MaxBurstLength, conn->MaxRecvDataSegmentLength);
1777
1778 conn->max_firstimmed = (!sess->ImmediateData) ? 0 :
1779 min(sess->FirstBurstLength, conn->max_transfer);
1780
1781 conn->max_firstdata = (sess->InitialR2T || sess->FirstBurstLength < conn->max_firstimmed) ? 0 :
1782 min(sess->FirstBurstLength - conn->max_firstimmed, conn->max_transfer);
1783
1784 }
1785