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