1 1.15 andvar /* $NetBSD: iscsi_text.c,v 1.15 2024/02/08 19:44:08 andvar 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.14 mlelstv {"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.14 mlelstv text_key_t key; /* the key */ 174 1.14 mlelstv int list_num; /* number of elements in list, doubles as */ 175 1.14 mlelstv /* data size for large numeric values */ 176 1.14 mlelstv bool hex_bignums; /* whether to encode in hex or base64 */ 177 1.1 agc union 178 1.1 agc { 179 1.14 mlelstv uint32_t nval[MAX_LIST];/* numeric or enumeration values */ 180 1.14 mlelstv 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.14 mlelstv 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.14 mlelstv * 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.14 mlelstv 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.14 mlelstv 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.14 mlelstv 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.14 mlelstv 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.14 mlelstv 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.15 andvar /* We shouldn'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.15 andvar /* We shouldn'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.14 mlelstv if (len == 0) { 932 1.14 mlelstv pdu->pdu_temp_data = NULL; 933 1.14 mlelstv pdu->pdu_temp_data_len = 0; 934 1.14 mlelstv return 0; 935 1.14 mlelstv } 936 1.14 mlelstv 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.14 mlelstv 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.14 mlelstv 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.14 mlelstv /* respond in the same format as the challenge */ 1411 1.14 mlelstv 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.14 mlelstv if (response_size != CHAP_MD5_SIZE) { 1441 1.14 mlelstv DEBOUT(("CHAP Response, bad size %d\n", 1442 1.14 mlelstv response_size)); 1443 1.1 agc return ISCSI_STATUS_NEGOTIATION_ERROR; 1444 1.14 mlelstv } 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.14 mlelstv 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.14 mlelstv chap_md5_response(state->temp_buf, identifier, 1477 1.14 mlelstv 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.14 mlelstv if (cpar != NULL) { 1481 1.1 agc cpar->list_num = CHAP_MD5_SIZE; 1482 1.14 mlelstv /* respond in same format as challenge */ 1483 1.14 mlelstv cpar->hex_bignums = challenge_hex; 1484 1.14 mlelstv } 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.14 mlelstv if (cpar != NULL) { 1500 1.1 agc cpar->list_num = CHAP_CHALLENGE_LEN; 1501 1.14 mlelstv /* use same format as target challenge */ 1502 1.14 mlelstv cpar->hex_bignums = challenge_hex; 1503 1.14 mlelstv } 1504 1.14 mlelstv 1505 1.14 mlelstv /* transitional state */ 1506 1.14 mlelstv 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.14 mlelstv state->temp_buf[CHAP_MD5_SIZE], 1520 1.14 mlelstv state->target_password, 1521 1.14 mlelstv &state->temp_buf[CHAP_MD5_SIZE + 1], 1522 1.14 mlelstv CHAP_CHALLENGE_LEN); 1523 1.1 agc 1524 1.14 mlelstv if (response_size > sizeof(state->temp_buf) || 1525 1.14 mlelstv 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.14 mlelstv /* Digests - suggest None,CRC32C unless the user forces a value */ 1558 1.1 agc cpar = set_key_n(state, K_HeaderDigest, 1559 1.14 mlelstv (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.14 mlelstv (lpar->is_present.ErrorRecoveryLevel) ? 1582 1.14 mlelstv lpar->ErrorRecoveryLevel : 2; 1583 1.1 agc /* 1584 1.14 mlelstv * Negotiate InitialR2T to FALSE and ImmediateData to 1585 1.14 mlelstv * TRUE, should be slightly more efficient than the 1586 1.14 mlelstv * 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.14 mlelstv /* We don't really care about this, so don't negotiate 1592 1.14 mlelstv * by default 1593 1.14 mlelstv */ 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.14 mlelstv 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.14 mlelstv 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.14 mlelstv if (put_parameter(buf, len, &par) == 0) { 1748 1.14 mlelstv DEBOUT(("trying to put zero sized buffer\n")); 1749 1.1 agc return ISCSI_STATUS_PARAMETER_INVALID; 1750 1.14 mlelstv } 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