1/*-
2 * Copyright (c) 2012 The FreeBSD Foundation
3 * All rights reserved.
4 *
5 * This software was developed by Edward Tomasz Napierala under sponsorship
6 * from the FreeBSD Foundation.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 */
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD$");
33
34#include <assert.h>
35#include <stdbool.h>
36#include <stdint.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
40#include <unistd.h>
41#include <netinet/in.h>
42#include <openssl/err.h>
43#include <openssl/md5.h>
44#include <openssl/rand.h>
45
46#include "ctld.h"
47#include "iscsi_proto.h"
48
49static void login_send_error(struct pdu *request,
50    char class, char detail);
51
52static void
53login_set_nsg(struct pdu *response, int nsg)
54{
55	struct iscsi_bhs_login_response *bhslr;
56
57	assert(nsg == BHSLR_STAGE_SECURITY_NEGOTIATION ||
58	    nsg == BHSLR_STAGE_OPERATIONAL_NEGOTIATION ||
59	    nsg == BHSLR_STAGE_FULL_FEATURE_PHASE);
60
61	bhslr = (struct iscsi_bhs_login_response *)response->pdu_bhs;
62
63	bhslr->bhslr_flags &= 0xFC;
64	bhslr->bhslr_flags |= nsg;
65}
66
67static int
68login_csg(const struct pdu *request)
69{
70	struct iscsi_bhs_login_request *bhslr;
71
72	bhslr = (struct iscsi_bhs_login_request *)request->pdu_bhs;
73
74	return ((bhslr->bhslr_flags & 0x0C) >> 2);
75}
76
77static void
78login_set_csg(struct pdu *response, int csg)
79{
80	struct iscsi_bhs_login_response *bhslr;
81
82	assert(csg == BHSLR_STAGE_SECURITY_NEGOTIATION ||
83	    csg == BHSLR_STAGE_OPERATIONAL_NEGOTIATION ||
84	    csg == BHSLR_STAGE_FULL_FEATURE_PHASE);
85
86	bhslr = (struct iscsi_bhs_login_response *)response->pdu_bhs;
87
88	bhslr->bhslr_flags &= 0xF3;
89	bhslr->bhslr_flags |= csg << 2;
90}
91
92static struct pdu *
93login_receive(struct connection *conn, bool initial)
94{
95	struct pdu *request;
96	struct iscsi_bhs_login_request *bhslr;
97
98	request = pdu_new(conn);
99	pdu_receive(request);
100	if ((request->pdu_bhs->bhs_opcode & ~ISCSI_BHS_OPCODE_IMMEDIATE) !=
101	    ISCSI_BHS_OPCODE_LOGIN_REQUEST) {
102		/*
103		 * The first PDU in session is special - if we receive any PDU
104		 * different than login request, we have to drop the connection
105		 * without sending response ("A target receiving any PDU
106		 * except a Login request before the Login Phase is started MUST
107		 * immediately terminate the connection on which the PDU
108		 * was received.")
109		 */
110		if (initial == false)
111			login_send_error(request, 0x02, 0x0b);
112		log_errx(1, "protocol error: received invalid opcode 0x%x",
113		    request->pdu_bhs->bhs_opcode);
114	}
115	bhslr = (struct iscsi_bhs_login_request *)request->pdu_bhs;
116	/*
117	 * XXX: Implement the C flag some day.
118	 */
119	if ((bhslr->bhslr_flags & BHSLR_FLAGS_CONTINUE) != 0) {
120		login_send_error(request, 0x03, 0x00);
121		log_errx(1, "received Login PDU with unsupported \"C\" flag");
122	}
123	if (bhslr->bhslr_version_max != 0x00) {
124		login_send_error(request, 0x02, 0x05);
125		log_errx(1, "received Login PDU with unsupported "
126		    "Version-max 0x%x", bhslr->bhslr_version_max);
127	}
128	if (bhslr->bhslr_version_min != 0x00) {
129		login_send_error(request, 0x02, 0x05);
130		log_errx(1, "received Login PDU with unsupported "
131		    "Version-min 0x%x", bhslr->bhslr_version_min);
132	}
133	if (ntohl(bhslr->bhslr_cmdsn) < conn->conn_cmdsn) {
134		login_send_error(request, 0x02, 0x05);
135		log_errx(1, "received Login PDU with decreasing CmdSN: "
136		    "was %d, is %d", conn->conn_cmdsn,
137		    ntohl(bhslr->bhslr_cmdsn));
138	}
139	if (initial == false &&
140	    ntohl(bhslr->bhslr_expstatsn) != conn->conn_statsn) {
141		login_send_error(request, 0x02, 0x05);
142		log_errx(1, "received Login PDU with wrong ExpStatSN: "
143		    "is %d, should be %d", ntohl(bhslr->bhslr_expstatsn),
144		    conn->conn_statsn);
145	}
146	conn->conn_cmdsn = ntohl(bhslr->bhslr_cmdsn);
147
148	return (request);
149}
150
151static struct pdu *
152login_new_response(struct pdu *request)
153{
154	struct pdu *response;
155	struct connection *conn;
156	struct iscsi_bhs_login_request *bhslr;
157	struct iscsi_bhs_login_response *bhslr2;
158
159	bhslr = (struct iscsi_bhs_login_request *)request->pdu_bhs;
160	conn = request->pdu_connection;
161
162	response = pdu_new_response(request);
163	bhslr2 = (struct iscsi_bhs_login_response *)response->pdu_bhs;
164	bhslr2->bhslr_opcode = ISCSI_BHS_OPCODE_LOGIN_RESPONSE;
165	login_set_csg(response, BHSLR_STAGE_SECURITY_NEGOTIATION);
166	memcpy(bhslr2->bhslr_isid,
167	    bhslr->bhslr_isid, sizeof(bhslr2->bhslr_isid));
168	bhslr2->bhslr_initiator_task_tag = bhslr->bhslr_initiator_task_tag;
169	bhslr2->bhslr_statsn = htonl(conn->conn_statsn++);
170	bhslr2->bhslr_expcmdsn = htonl(conn->conn_cmdsn);
171	bhslr2->bhslr_maxcmdsn = htonl(conn->conn_cmdsn);
172
173	return (response);
174}
175
176static void
177login_send_error(struct pdu *request, char class, char detail)
178{
179	struct pdu *response;
180	struct iscsi_bhs_login_response *bhslr2;
181
182	log_debugx("sending Login Response PDU with failure class 0x%x/0x%x; "
183	    "see next line for reason", class, detail);
184	response = login_new_response(request);
185	bhslr2 = (struct iscsi_bhs_login_response *)response->pdu_bhs;
186	bhslr2->bhslr_status_class = class;
187	bhslr2->bhslr_status_detail = detail;
188
189	pdu_send(response);
190	pdu_delete(response);
191}
192
193static int
194login_list_contains(const char *list, const char *what)
195{
196	char *tofree, *str, *token;
197
198	tofree = str = checked_strdup(list);
199
200	while ((token = strsep(&str, ",")) != NULL) {
201		if (strcmp(token, what) == 0) {
202			free(tofree);
203			return (1);
204		}
205	}
206	free(tofree);
207	return (0);
208}
209
210static int
211login_list_prefers(const char *list,
212    const char *choice1, const char *choice2)
213{
214	char *tofree, *str, *token;
215
216	tofree = str = checked_strdup(list);
217
218	while ((token = strsep(&str, ",")) != NULL) {
219		if (strcmp(token, choice1) == 0) {
220			free(tofree);
221			return (1);
222		}
223		if (strcmp(token, choice2) == 0) {
224			free(tofree);
225			return (2);
226		}
227	}
228	free(tofree);
229	return (-1);
230}
231
232static int
233login_hex2int(const char hex)
234{
235	switch (hex) {
236	case '0':
237		return (0x00);
238	case '1':
239		return (0x01);
240	case '2':
241		return (0x02);
242	case '3':
243		return (0x03);
244	case '4':
245		return (0x04);
246	case '5':
247		return (0x05);
248	case '6':
249		return (0x06);
250	case '7':
251		return (0x07);
252	case '8':
253		return (0x08);
254	case '9':
255		return (0x09);
256	case 'a':
257	case 'A':
258		return (0x0a);
259	case 'b':
260	case 'B':
261		return (0x0b);
262	case 'c':
263	case 'C':
264		return (0x0c);
265	case 'd':
266	case 'D':
267		return (0x0d);
268	case 'e':
269	case 'E':
270		return (0x0e);
271	case 'f':
272	case 'F':
273		return (0x0f);
274	default:
275		return (-1);
276	}
277}
278
279/*
280 * XXX: Review this _carefully_.
281 */
282static int
283login_hex2bin(const char *hex, char **binp, size_t *bin_lenp)
284{
285	int i, hex_len, nibble;
286	bool lo = true; /* As opposed to 'hi'. */
287	char *bin;
288	size_t bin_off, bin_len;
289
290	if (strncasecmp(hex, "0x", strlen("0x")) != 0) {
291		log_warnx("malformed variable, should start with \"0x\"");
292		return (-1);
293	}
294
295	hex += strlen("0x");
296	hex_len = strlen(hex);
297	if (hex_len < 1) {
298		log_warnx("malformed variable; doesn't contain anything "
299		    "but \"0x\"");
300		return (-1);
301	}
302
303	bin_len = hex_len / 2 + hex_len % 2;
304	bin = calloc(bin_len, 1);
305	if (bin == NULL)
306		log_err(1, "calloc");
307
308	bin_off = bin_len - 1;
309	for (i = hex_len - 1; i >= 0; i--) {
310		nibble = login_hex2int(hex[i]);
311		if (nibble < 0) {
312			log_warnx("malformed variable, invalid char \"%c\"",
313			    hex[i]);
314			return (-1);
315		}
316
317		assert(bin_off < bin_len);
318		if (lo) {
319			bin[bin_off] = nibble;
320			lo = false;
321		} else {
322			bin[bin_off] |= nibble << 4;
323			bin_off--;
324			lo = true;
325		}
326	}
327
328	*binp = bin;
329	*bin_lenp = bin_len;
330	return (0);
331}
332
333static char *
334login_bin2hex(const char *bin, size_t bin_len)
335{
336	unsigned char *hex, *tmp, ch;
337	size_t hex_len;
338	size_t i;
339
340	hex_len = bin_len * 2 + 3; /* +2 for "0x", +1 for '\0'. */
341	hex = malloc(hex_len);
342	if (hex == NULL)
343		log_err(1, "malloc");
344
345	tmp = hex;
346	tmp += sprintf(tmp, "0x");
347	for (i = 0; i < bin_len; i++) {
348		ch = bin[i];
349		tmp += sprintf(tmp, "%02x", ch);
350	}
351
352	return (hex);
353}
354
355static void
356login_compute_md5(const char id, const char *secret,
357    const void *challenge, size_t challenge_len, void *response,
358    size_t response_len)
359{
360	MD5_CTX ctx;
361	int rv;
362
363	assert(response_len == MD5_DIGEST_LENGTH);
364
365	MD5_Init(&ctx);
366	MD5_Update(&ctx, &id, sizeof(id));
367	MD5_Update(&ctx, secret, strlen(secret));
368	MD5_Update(&ctx, challenge, challenge_len);
369	rv = MD5_Final(response, &ctx);
370	if (rv != 1)
371		log_errx(1, "MD5_Final");
372}
373
374#define	LOGIN_CHALLENGE_LEN	1024
375
376static struct pdu *
377login_receive_chap_a(struct connection *conn)
378{
379	struct pdu *request;
380	struct keys *request_keys;
381	const char *chap_a;
382
383	request = login_receive(conn, false);
384	request_keys = keys_new();
385	keys_load(request_keys, request);
386
387	chap_a = keys_find(request_keys, "CHAP_A");
388	if (chap_a == NULL) {
389		login_send_error(request, 0x02, 0x07);
390		log_errx(1, "received CHAP Login PDU without CHAP_A");
391	}
392	if (login_list_contains(chap_a, "5") == 0) {
393		login_send_error(request, 0x02, 0x01);
394		log_errx(1, "received CHAP Login PDU with unsupported CHAP_A "
395		    "\"%s\"", chap_a);
396	}
397	keys_delete(request_keys);
398
399	return (request);
400}
401
402static void
403login_send_chap_c(struct pdu *request, const unsigned char id,
404    const void *challenge, const size_t challenge_len)
405{
406	struct pdu *response;
407	struct keys *response_keys;
408	char *chap_c, chap_i[4];
409
410	chap_c = login_bin2hex(challenge, challenge_len);
411	snprintf(chap_i, sizeof(chap_i), "%d", id);
412
413	response = login_new_response(request);
414	response_keys = keys_new();
415	keys_add(response_keys, "CHAP_A", "5");
416	keys_add(response_keys, "CHAP_I", chap_i);
417	keys_add(response_keys, "CHAP_C", chap_c);
418	free(chap_c);
419	keys_save(response_keys, response);
420	pdu_send(response);
421	pdu_delete(response);
422	keys_delete(response_keys);
423}
424
425static struct pdu *
426login_receive_chap_r(struct connection *conn,
427    struct auth_group *ag, const unsigned char id, const void *challenge,
428    const size_t challenge_len, const struct auth **cap)
429{
430	struct pdu *request;
431	struct keys *request_keys;
432	const char *chap_n, *chap_r;
433	char *response_bin, expected_response_bin[MD5_DIGEST_LENGTH];
434	size_t response_bin_len;
435	const struct auth *auth;
436	int error;
437
438	request = login_receive(conn, false);
439	request_keys = keys_new();
440	keys_load(request_keys, request);
441
442	chap_n = keys_find(request_keys, "CHAP_N");
443	if (chap_n == NULL) {
444		login_send_error(request, 0x02, 0x07);
445		log_errx(1, "received CHAP Login PDU without CHAP_N");
446	}
447	chap_r = keys_find(request_keys, "CHAP_R");
448	if (chap_r == NULL) {
449		login_send_error(request, 0x02, 0x07);
450		log_errx(1, "received CHAP Login PDU without CHAP_R");
451	}
452	error = login_hex2bin(chap_r, &response_bin, &response_bin_len);
453	if (error != 0) {
454		login_send_error(request, 0x02, 0x07);
455		log_errx(1, "received CHAP Login PDU with malformed CHAP_R");
456	}
457
458	/*
459	 * Verify the response.
460	 */
461	assert(ag->ag_type == AG_TYPE_CHAP ||
462	    ag->ag_type == AG_TYPE_CHAP_MUTUAL);
463	auth = auth_find(ag, chap_n);
464	if (auth == NULL) {
465		login_send_error(request, 0x02, 0x01);
466		log_errx(1, "received CHAP Login with invalid user \"%s\"",
467		    chap_n);
468	}
469
470	assert(auth->a_secret != NULL);
471	assert(strlen(auth->a_secret) > 0);
472	login_compute_md5(id, auth->a_secret, challenge,
473	    challenge_len, expected_response_bin,
474	    sizeof(expected_response_bin));
475
476	if (memcmp(response_bin, expected_response_bin,
477	    sizeof(expected_response_bin)) != 0) {
478		login_send_error(request, 0x02, 0x01);
479		log_errx(1, "CHAP authentication failed for user \"%s\"",
480		    auth->a_user);
481	}
482
483	keys_delete(request_keys);
484	free(response_bin);
485
486	*cap = auth;
487	return (request);
488}
489
490static void
491login_send_chap_success(struct pdu *request,
492    const struct auth *auth)
493{
494	struct pdu *response;
495	struct keys *request_keys, *response_keys;
496	struct iscsi_bhs_login_response *bhslr2;
497	const char *chap_i, *chap_c;
498	char *chap_r, *challenge, response_bin[MD5_DIGEST_LENGTH];
499	size_t challenge_len;
500	unsigned char id;
501	int error;
502
503	response = login_new_response(request);
504	bhslr2 = (struct iscsi_bhs_login_response *)response->pdu_bhs;
505	bhslr2->bhslr_flags |= BHSLR_FLAGS_TRANSIT;
506	login_set_nsg(response, BHSLR_STAGE_OPERATIONAL_NEGOTIATION);
507
508	/*
509	 * Actually, one more thing: mutual authentication.
510	 */
511	request_keys = keys_new();
512	keys_load(request_keys, request);
513	chap_i = keys_find(request_keys, "CHAP_I");
514	chap_c = keys_find(request_keys, "CHAP_C");
515	if (chap_i != NULL || chap_c != NULL) {
516		if (chap_i == NULL) {
517			login_send_error(request, 0x02, 0x07);
518			log_errx(1, "initiator requested target "
519			    "authentication, but didn't send CHAP_I");
520		}
521		if (chap_c == NULL) {
522			login_send_error(request, 0x02, 0x07);
523			log_errx(1, "initiator requested target "
524			    "authentication, but didn't send CHAP_C");
525		}
526		if (auth->a_auth_group->ag_type != AG_TYPE_CHAP_MUTUAL) {
527			login_send_error(request, 0x02, 0x01);
528			log_errx(1, "initiator requests target authentication "
529			    "for user \"%s\", but mutual user/secret "
530			    "is not set", auth->a_user);
531		}
532
533		id = strtoul(chap_i, NULL, 10);
534		error = login_hex2bin(chap_c, &challenge, &challenge_len);
535		if (error != 0) {
536			login_send_error(request, 0x02, 0x07);
537			log_errx(1, "received CHAP Login PDU with malformed "
538			    "CHAP_C");
539		}
540
541		log_debugx("performing mutual authentication as user \"%s\"",
542		    auth->a_mutual_user);
543		login_compute_md5(id, auth->a_mutual_secret, challenge,
544		    challenge_len, response_bin, sizeof(response_bin));
545
546		chap_r = login_bin2hex(response_bin,
547		    sizeof(response_bin));
548		response_keys = keys_new();
549		keys_add(response_keys, "CHAP_N", auth->a_mutual_user);
550		keys_add(response_keys, "CHAP_R", chap_r);
551		free(chap_r);
552		keys_save(response_keys, response);
553		keys_delete(response_keys);
554	} else {
555		log_debugx("initiator did not request target authentication");
556	}
557
558	keys_delete(request_keys);
559	pdu_send(response);
560	pdu_delete(response);
561}
562
563static void
564login_chap(struct connection *conn, struct auth_group *ag)
565{
566	const struct auth *auth;
567	struct pdu *request;
568	char challenge_bin[LOGIN_CHALLENGE_LEN];
569	unsigned char id;
570	int rv;
571
572	/*
573	 * Receive CHAP_A PDU.
574	 */
575	log_debugx("beginning CHAP authentication; waiting for CHAP_A");
576	request = login_receive_chap_a(conn);
577
578	/*
579	 * Generate the challenge.
580	 */
581	rv = RAND_bytes(challenge_bin, sizeof(challenge_bin));
582	if (rv != 1) {
583		login_send_error(request, 0x03, 0x02);
584		log_errx(1, "RAND_bytes failed: %s",
585		    ERR_error_string(ERR_get_error(), NULL));
586	}
587	rv = RAND_bytes(&id, sizeof(id));
588	if (rv != 1) {
589		login_send_error(request, 0x03, 0x02);
590		log_errx(1, "RAND_bytes failed: %s",
591		    ERR_error_string(ERR_get_error(), NULL));
592	}
593
594	/*
595	 * Send the challenge.
596	 */
597	log_debugx("sending CHAP_C, binary challenge size is %zd bytes",
598	    sizeof(challenge_bin));
599	login_send_chap_c(request, id, challenge_bin,
600	    sizeof(challenge_bin));
601	pdu_delete(request);
602
603	/*
604	 * Receive CHAP_N/CHAP_R PDU and authenticate.
605	 */
606	log_debugx("waiting for CHAP_N/CHAP_R");
607	request = login_receive_chap_r(conn, ag, id, challenge_bin,
608	    sizeof(challenge_bin), &auth);
609
610	/*
611	 * Yay, authentication succeeded!
612	 */
613	log_debugx("authentication succeeded for user \"%s\"; "
614	    "transitioning to Negotiation Phase", auth->a_user);
615	login_send_chap_success(request, auth);
616	pdu_delete(request);
617}
618
619static void
620login_negotiate_key(struct pdu *request, const char *name,
621    const char *value, bool skipped_security, struct keys *response_keys)
622{
623	int which, tmp;
624	struct connection *conn;
625
626	conn = request->pdu_connection;
627
628	if (strcmp(name, "InitiatorName") == 0) {
629		if (!skipped_security)
630			log_errx(1, "initiator resent InitiatorName");
631	} else if (strcmp(name, "SessionType") == 0) {
632		if (!skipped_security)
633			log_errx(1, "initiator resent SessionType");
634	} else if (strcmp(name, "TargetName") == 0) {
635		if (!skipped_security)
636			log_errx(1, "initiator resent TargetName");
637	} else if (strcmp(name, "InitiatorAlias") == 0) {
638		if (conn->conn_initiator_alias != NULL)
639			free(conn->conn_initiator_alias);
640		conn->conn_initiator_alias = checked_strdup(value);
641	} else if (strcmp(value, "Irrelevant") == 0) {
642		/* Ignore. */
643	} else if (strcmp(name, "HeaderDigest") == 0) {
644		/*
645		 * We don't handle digests for discovery sessions.
646		 */
647		if (conn->conn_session_type == CONN_SESSION_TYPE_DISCOVERY) {
648			log_debugx("discovery session; digests disabled");
649			keys_add(response_keys, name, "None");
650			return;
651		}
652
653		which = login_list_prefers(value, "CRC32C", "None");
654		switch (which) {
655		case 1:
656			log_debugx("initiator prefers CRC32C "
657			    "for header digest; we'll use it");
658			conn->conn_header_digest = CONN_DIGEST_CRC32C;
659			keys_add(response_keys, name, "CRC32C");
660			break;
661		case 2:
662			log_debugx("initiator prefers not to do "
663			    "header digest; we'll comply");
664			keys_add(response_keys, name, "None");
665			break;
666		default:
667			log_warnx("initiator sent unrecognized "
668			    "HeaderDigest value \"%s\"; will use None", value);
669			keys_add(response_keys, name, "None");
670			break;
671		}
672	} else if (strcmp(name, "DataDigest") == 0) {
673		if (conn->conn_session_type == CONN_SESSION_TYPE_DISCOVERY) {
674			log_debugx("discovery session; digests disabled");
675			keys_add(response_keys, name, "None");
676			return;
677		}
678
679		which = login_list_prefers(value, "CRC32C", "None");
680		switch (which) {
681		case 1:
682			log_debugx("initiator prefers CRC32C "
683			    "for data digest; we'll use it");
684			conn->conn_data_digest = CONN_DIGEST_CRC32C;
685			keys_add(response_keys, name, "CRC32C");
686			break;
687		case 2:
688			log_debugx("initiator prefers not to do "
689			    "data digest; we'll comply");
690			keys_add(response_keys, name, "None");
691			break;
692		default:
693			log_warnx("initiator sent unrecognized "
694			    "DataDigest value \"%s\"; will use None", value);
695			keys_add(response_keys, name, "None");
696			break;
697		}
698	} else if (strcmp(name, "MaxConnections") == 0) {
699		keys_add(response_keys, name, "1");
700	} else if (strcmp(name, "InitialR2T") == 0) {
701		keys_add(response_keys, name, "Yes");
702	} else if (strcmp(name, "ImmediateData") == 0) {
703		if (conn->conn_session_type == CONN_SESSION_TYPE_DISCOVERY) {
704			log_debugx("discovery session; ImmediateData irrelevant");
705			keys_add(response_keys, name, "Irrelevant");
706		} else {
707			if (strcmp(value, "Yes") == 0) {
708				conn->conn_immediate_data = true;
709				keys_add(response_keys, name, "Yes");
710			} else {
711				conn->conn_immediate_data = false;
712				keys_add(response_keys, name, "No");
713			}
714		}
715	} else if (strcmp(name, "MaxRecvDataSegmentLength") == 0) {
716		tmp = strtoul(value, NULL, 10);
717		if (tmp <= 0) {
718			login_send_error(request, 0x02, 0x00);
719			log_errx(1, "received invalid "
720			    "MaxRecvDataSegmentLength");
721		}
722		if (tmp > MAX_DATA_SEGMENT_LENGTH) {
723			log_debugx("capping MaxRecvDataSegmentLength "
724			    "from %d to %d", tmp, MAX_DATA_SEGMENT_LENGTH);
725			tmp = MAX_DATA_SEGMENT_LENGTH;
726		}
727		conn->conn_max_data_segment_length = tmp;
728		keys_add_int(response_keys, name, tmp);
729	} else if (strcmp(name, "MaxBurstLength") == 0) {
730		tmp = strtoul(value, NULL, 10);
731		if (tmp <= 0) {
732			login_send_error(request, 0x02, 0x00);
733			log_errx(1, "received invalid MaxBurstLength");
734		}
735		if (tmp > MAX_BURST_LENGTH) {
736			log_debugx("capping MaxBurstLength from %d to %d",
737			    tmp, MAX_BURST_LENGTH);
738			tmp = MAX_BURST_LENGTH;
739		}
740		conn->conn_max_burst_length = tmp;
741		keys_add(response_keys, name, value);
742	} else if (strcmp(name, "FirstBurstLength") == 0) {
743		tmp = strtoul(value, NULL, 10);
744		if (tmp <= 0) {
745			login_send_error(request, 0x02, 0x00);
746			log_errx(1, "received invalid "
747			    "FirstBurstLength");
748		}
749		if (tmp > MAX_DATA_SEGMENT_LENGTH) {
750			log_debugx("capping FirstBurstLength from %d to %d",
751			    tmp, MAX_DATA_SEGMENT_LENGTH);
752			tmp = MAX_DATA_SEGMENT_LENGTH;
753		}
754		/*
755		 * We don't pass the value to the kernel; it only enforces
756		 * hardcoded limit anyway.
757		 */
758		keys_add_int(response_keys, name, tmp);
759	} else if (strcmp(name, "DefaultTime2Wait") == 0) {
760		keys_add(response_keys, name, value);
761	} else if (strcmp(name, "DefaultTime2Retain") == 0) {
762		keys_add(response_keys, name, "0");
763	} else if (strcmp(name, "MaxOutstandingR2T") == 0) {
764		keys_add(response_keys, name, "1");
765	} else if (strcmp(name, "DataPDUInOrder") == 0) {
766		keys_add(response_keys, name, "Yes");
767	} else if (strcmp(name, "DataSequenceInOrder") == 0) {
768		keys_add(response_keys, name, "Yes");
769	} else if (strcmp(name, "ErrorRecoveryLevel") == 0) {
770		keys_add(response_keys, name, "0");
771	} else if (strcmp(name, "OFMarker") == 0) {
772		keys_add(response_keys, name, "No");
773	} else if (strcmp(name, "IFMarker") == 0) {
774		keys_add(response_keys, name, "No");
775	} else {
776		log_debugx("unknown key \"%s\"; responding "
777		    "with NotUnderstood", name);
778		keys_add(response_keys, name, "NotUnderstood");
779	}
780}
781
782static void
783login_negotiate(struct connection *conn, struct pdu *request)
784{
785	struct pdu *response;
786	struct iscsi_bhs_login_response *bhslr2;
787	struct keys *request_keys, *response_keys;
788	char *portal_group_tag;
789	int i, rv;
790	bool skipped_security;
791
792	if (request == NULL) {
793		log_debugx("beginning operational parameter negotiation; "
794		    "waiting for Login PDU");
795		request = login_receive(conn, false);
796		skipped_security = false;
797	} else
798		skipped_security = true;
799
800	request_keys = keys_new();
801	keys_load(request_keys, request);
802
803	response = login_new_response(request);
804	bhslr2 = (struct iscsi_bhs_login_response *)response->pdu_bhs;
805	bhslr2->bhslr_flags |= BHSLR_FLAGS_TRANSIT;
806	bhslr2->bhslr_tsih = htons(0xbadd);
807	login_set_csg(response, BHSLR_STAGE_OPERATIONAL_NEGOTIATION);
808	login_set_nsg(response, BHSLR_STAGE_FULL_FEATURE_PHASE);
809	response_keys = keys_new();
810
811	if (skipped_security &&
812	    conn->conn_session_type == CONN_SESSION_TYPE_NORMAL) {
813		if (conn->conn_target->t_alias != NULL)
814			keys_add(response_keys,
815			    "TargetAlias", conn->conn_target->t_alias);
816		rv = asprintf(&portal_group_tag, "%d",
817		    conn->conn_portal->p_portal_group->pg_tag);
818		if (rv <= 0)
819			log_err(1, "asprintf");
820		keys_add(response_keys,
821		    "TargetPortalGroupTag", portal_group_tag);
822		free(portal_group_tag);
823	}
824
825	for (i = 0; i < KEYS_MAX; i++) {
826		if (request_keys->keys_names[i] == NULL)
827			break;
828
829		login_negotiate_key(request, request_keys->keys_names[i],
830		    request_keys->keys_values[i], skipped_security,
831		    response_keys);
832	}
833
834	log_debugx("operational parameter negotiation done; "
835	    "transitioning to Full Feature Phase");
836
837	keys_save(response_keys, response);
838	pdu_send(response);
839	pdu_delete(response);
840	keys_delete(response_keys);
841	pdu_delete(request);
842	keys_delete(request_keys);
843}
844
845void
846login(struct connection *conn)
847{
848	struct pdu *request, *response;
849	struct iscsi_bhs_login_request *bhslr;
850	struct iscsi_bhs_login_response *bhslr2;
851	struct keys *request_keys, *response_keys;
852	struct auth_group *ag;
853	const char *initiator_name, *initiator_alias, *session_type,
854	    *target_name, *auth_method;
855	char *portal_group_tag;
856	int rv;
857
858	/*
859	 * Handle the initial Login Request - figure out required authentication
860	 * method and either transition to the next phase, if no authentication
861	 * is required, or call appropriate authentication code.
862	 */
863	log_debugx("beginning Login Phase; waiting for Login PDU");
864	request = login_receive(conn, true);
865	bhslr = (struct iscsi_bhs_login_request *)request->pdu_bhs;
866	if (bhslr->bhslr_tsih != 0) {
867		login_send_error(request, 0x02, 0x0a);
868		log_errx(1, "received Login PDU with non-zero TSIH");
869	}
870
871	memcpy(conn->conn_initiator_isid, bhslr->bhslr_isid,
872	    sizeof(conn->conn_initiator_isid));
873
874	/*
875	 * XXX: Implement the C flag some day.
876	 */
877	request_keys = keys_new();
878	keys_load(request_keys, request);
879
880	assert(conn->conn_initiator_name == NULL);
881	initiator_name = keys_find(request_keys, "InitiatorName");
882	if (initiator_name == NULL) {
883		login_send_error(request, 0x02, 0x07);
884		log_errx(1, "received Login PDU without InitiatorName");
885	}
886	if (valid_iscsi_name(initiator_name) == false) {
887		login_send_error(request, 0x02, 0x00);
888		log_errx(1, "received Login PDU with invalid InitiatorName");
889	}
890	conn->conn_initiator_name = checked_strdup(initiator_name);
891	log_set_peer_name(conn->conn_initiator_name);
892	/*
893	 * XXX: This doesn't work (does nothing) because of Capsicum.
894	 */
895	setproctitle("%s (%s)", conn->conn_initiator_addr, conn->conn_initiator_name);
896
897	initiator_alias = keys_find(request_keys, "InitiatorAlias");
898	if (initiator_alias != NULL)
899		conn->conn_initiator_alias = checked_strdup(initiator_alias);
900
901	assert(conn->conn_session_type == CONN_SESSION_TYPE_NONE);
902	session_type = keys_find(request_keys, "SessionType");
903	if (session_type != NULL) {
904		if (strcmp(session_type, "Normal") == 0) {
905			conn->conn_session_type = CONN_SESSION_TYPE_NORMAL;
906		} else if (strcmp(session_type, "Discovery") == 0) {
907			conn->conn_session_type = CONN_SESSION_TYPE_DISCOVERY;
908		} else {
909			login_send_error(request, 0x02, 0x00);
910			log_errx(1, "received Login PDU with invalid "
911			    "SessionType \"%s\"", session_type);
912		}
913	} else
914		conn->conn_session_type = CONN_SESSION_TYPE_NORMAL;
915
916	assert(conn->conn_target == NULL);
917	if (conn->conn_session_type == CONN_SESSION_TYPE_NORMAL) {
918		target_name = keys_find(request_keys, "TargetName");
919		if (target_name == NULL) {
920			login_send_error(request, 0x02, 0x07);
921			log_errx(1, "received Login PDU without TargetName");
922		}
923
924		conn->conn_target =
925		    target_find(conn->conn_portal->p_portal_group->pg_conf,
926		    target_name);
927		if (conn->conn_target == NULL) {
928			login_send_error(request, 0x02, 0x03);
929			log_errx(1, "requested target \"%s\" not found",
930			    target_name);
931		}
932	}
933
934	/*
935	 * At this point we know what kind of authentication we need.
936	 */
937	if (conn->conn_session_type == CONN_SESSION_TYPE_NORMAL) {
938		ag = conn->conn_target->t_auth_group;
939		if (ag->ag_name != NULL) {
940			log_debugx("initiator requests to connect "
941			    "to target \"%s\"; auth-group \"%s\"",
942			    conn->conn_target->t_name,
943			    conn->conn_target->t_auth_group->ag_name);
944		} else {
945			log_debugx("initiator requests to connect "
946			    "to target \"%s\"", conn->conn_target->t_name);
947		}
948	} else {
949		assert(conn->conn_session_type == CONN_SESSION_TYPE_DISCOVERY);
950		ag = conn->conn_portal->p_portal_group->pg_discovery_auth_group;
951		if (ag->ag_name != NULL) {
952			log_debugx("initiator requests "
953			    "discovery session; auth-group \"%s\"", ag->ag_name);
954		} else {
955			log_debugx("initiator requests discovery session");
956		}
957	}
958
959	/*
960	 * Enforce initiator-name and initiator-portal.
961	 */
962	if (auth_name_defined(ag)) {
963		if (auth_name_find(ag, initiator_name) == NULL) {
964			login_send_error(request, 0x02, 0x02);
965			log_errx(1, "initiator does not match allowed "
966			    "initiator names");
967		}
968		log_debugx("initiator matches allowed initiator names");
969	} else {
970		log_debugx("auth-group does not define initiator name "
971		    "restrictions");
972	}
973
974	if (auth_portal_defined(ag)) {
975		if (auth_portal_find(ag, &conn->conn_initiator_sa) == NULL) {
976			login_send_error(request, 0x02, 0x02);
977			log_errx(1, "initiator does not match allowed "
978			    "initiator portals");
979		}
980		log_debugx("initiator matches allowed initiator portals");
981	} else {
982		log_debugx("auth-group does not define initiator portal "
983		    "restrictions");
984	}
985
986	/*
987	 * Let's see if the initiator intends to do any kind of authentication
988	 * at all.
989	 */
990	if (login_csg(request) == BHSLR_STAGE_OPERATIONAL_NEGOTIATION) {
991		if (ag->ag_type != AG_TYPE_NO_AUTHENTICATION) {
992			login_send_error(request, 0x02, 0x01);
993			log_errx(1, "initiator skipped the authentication, "
994			    "but authentication is required");
995		}
996
997		keys_delete(request_keys);
998
999		log_debugx("initiator skipped the authentication, "
1000		    "and we don't need it; proceeding with negotiation");
1001		login_negotiate(conn, request);
1002		return;
1003	}
1004
1005	if (ag->ag_type == AG_TYPE_NO_AUTHENTICATION) {
1006		/*
1007		 * Initiator might want to to authenticate,
1008		 * but we don't need it.
1009		 */
1010		log_debugx("authentication not required; "
1011		    "transitioning to operational parameter negotiation");
1012
1013		if ((bhslr->bhslr_flags & BHSLR_FLAGS_TRANSIT) == 0)
1014			log_warnx("initiator did not set the \"T\" flag; "
1015			    "transitioning anyway");
1016
1017		response = login_new_response(request);
1018		bhslr2 = (struct iscsi_bhs_login_response *)response->pdu_bhs;
1019		bhslr2->bhslr_flags |= BHSLR_FLAGS_TRANSIT;
1020		login_set_nsg(response,
1021		    BHSLR_STAGE_OPERATIONAL_NEGOTIATION);
1022		response_keys = keys_new();
1023		/*
1024		 * Required by Linux initiator.
1025		 */
1026		auth_method = keys_find(request_keys, "AuthMethod");
1027		if (auth_method != NULL &&
1028		    login_list_contains(auth_method, "None"))
1029			keys_add(response_keys, "AuthMethod", "None");
1030
1031		if (conn->conn_session_type == CONN_SESSION_TYPE_NORMAL) {
1032			if (conn->conn_target->t_alias != NULL)
1033				keys_add(response_keys,
1034				    "TargetAlias", conn->conn_target->t_alias);
1035			rv = asprintf(&portal_group_tag, "%d",
1036			    conn->conn_portal->p_portal_group->pg_tag);
1037			if (rv <= 0)
1038				log_err(1, "asprintf");
1039			keys_add(response_keys,
1040			    "TargetPortalGroupTag", portal_group_tag);
1041			free(portal_group_tag);
1042		}
1043		keys_save(response_keys, response);
1044		pdu_send(response);
1045		pdu_delete(response);
1046		keys_delete(response_keys);
1047		pdu_delete(request);
1048		keys_delete(request_keys);
1049
1050		login_negotiate(conn, NULL);
1051		return;
1052	}
1053
1054	if (ag->ag_type == AG_TYPE_DENY) {
1055		login_send_error(request, 0x02, 0x01);
1056		log_errx(1, "auth-type is \"deny\"");
1057	}
1058
1059	if (ag->ag_type == AG_TYPE_UNKNOWN) {
1060		/*
1061		 * This can happen with empty auth-group.
1062		 */
1063		login_send_error(request, 0x02, 0x01);
1064		log_errx(1, "auth-type not set, denying access");
1065	}
1066
1067	log_debugx("CHAP authentication required");
1068
1069	auth_method = keys_find(request_keys, "AuthMethod");
1070	if (auth_method == NULL) {
1071		login_send_error(request, 0x02, 0x07);
1072		log_errx(1, "received Login PDU without AuthMethod");
1073	}
1074	/*
1075	 * XXX: This should be Reject, not just a login failure (5.3.2).
1076	 */
1077	if (login_list_contains(auth_method, "CHAP") == 0) {
1078		login_send_error(request, 0x02, 0x01);
1079		log_errx(1, "initiator requests unsupported AuthMethod \"%s\" "
1080		    "instead of \"CHAP\"", auth_method);
1081	}
1082
1083	response = login_new_response(request);
1084
1085	response_keys = keys_new();
1086	keys_add(response_keys, "AuthMethod", "CHAP");
1087	if (conn->conn_session_type == CONN_SESSION_TYPE_NORMAL) {
1088		if (conn->conn_target->t_alias != NULL)
1089			keys_add(response_keys,
1090			    "TargetAlias", conn->conn_target->t_alias);
1091		rv = asprintf(&portal_group_tag, "%d",
1092		    conn->conn_portal->p_portal_group->pg_tag);
1093		if (rv <= 0)
1094			log_err(1, "asprintf");
1095		keys_add(response_keys,
1096		    "TargetPortalGroupTag", portal_group_tag);
1097		free(portal_group_tag);
1098	}
1099	keys_save(response_keys, response);
1100
1101	pdu_send(response);
1102	pdu_delete(response);
1103	keys_delete(response_keys);
1104	pdu_delete(request);
1105	keys_delete(request_keys);
1106
1107	login_chap(conn, ag);
1108
1109	login_negotiate(conn, NULL);
1110}
1111