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