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