From nobody Wed Dec 22 18:43:35 2021 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 263CF1909AD5; Wed, 22 Dec 2021 18:43:36 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4JK2K36CR1z3vQF; Wed, 22 Dec 2021 18:43:35 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id B4CAB220C1; Wed, 22 Dec 2021 18:43:35 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 1BMIhZC8089816; Wed, 22 Dec 2021 18:43:35 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 1BMIhZs4089815; Wed, 22 Dec 2021 18:43:35 GMT (envelope-from git) Date: Wed, 22 Dec 2021 18:43:35 GMT Message-Id: <202112221843.1BMIhZs4089815@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: John Baldwin Subject: git: 6378393308bc - main - Add an internal libiscsiutil library. List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: jhb X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 6378393308bc6bd81fb871dacf6b03cf1a390d8b Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1640198615; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=ZQ4rszxjjBVj28w0G5pjvM81emp5t7cWS6TNGW9cRS4=; b=pm2IzK/IsERZDV5jNSyPeFzo1y6wI4u4gE5NrX6rT4E9gEhIsL5d+BQoS1db7944JfBR2a IZgxSjUdagEiHA4G0YbXHW51B81vUBaekx6qCaOSP1p1htBh/d98KO7V/C4Z3eSSZXbeSt 4gkBqeTgsFN4iFmu5SJ7IV2SicSO4x/YHiOwVKGStVt7qRuVty74HRECL9TDqDcgDzsgp2 kjdF7BxQBAgcBwD3zSxwYsvRbo9GbTS18bSDxWRxbmeVF8mOb0obsVCEEVyA9o2P+iTtDA W7cT7KLGNiNGYbsZVHeliztvktZmtkY0z3fTmG8DA6b60HHg1k2q2uAtzpkBKw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1640198615; a=rsa-sha256; cv=none; b=qOsHbp39lCfNbaOm1qU1Pvt8HEjtNNl/fPSbmo2sol73E1qqHQ3AoBALTvmnyY/9LDDVha L6JKnVka4MuZztFxU9Wq5wx4T5bFQarko7C+bSAZwdRGT60Z69vtKslEG+ZRv3DD478TYj CqJ1DQmm5UvZ/M82P9USrixePHUiJTQ1zNmtA7M3Jnmm0FjALTeqkpTp0fEoNemyn62A6m Raka56zdKK8GQ7dZhspN6/Lca8r7y/bM8XfVIXVPUYN04UUpVn4/dMY52H1fUUyX0EspnG B1ubxP/eIAL7jOBdqsbafAAK1Pn03hWetMQSvCERgKbapAguoI3weOghsIsl9w== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=6378393308bc6bd81fb871dacf6b03cf1a390d8b commit 6378393308bc6bd81fb871dacf6b03cf1a390d8b Author: John Baldwin AuthorDate: 2021-12-22 18:35:46 +0000 Commit: John Baldwin CommitDate: 2021-12-22 18:43:11 +0000 Add an internal libiscsiutil library. Move some of the code duplicated between ctld(8) and iscsid(8) into a libiscsiutil library. Sharing the low-level PDU code did require having a 'struct connection' base class with a method table to permit separate initiator vs target behavior (e.g. in handling proxy PDUs). Reviewed by: mav, emaste Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D33544 --- lib/Makefile | 1 + lib/libiscsiutil/Makefile | 10 + {usr.sbin/ctld => lib/libiscsiutil}/chap.c | 6 +- lib/libiscsiutil/connection.c | 53 ++++ {usr.sbin/ctld => lib/libiscsiutil}/keys.c | 6 +- lib/libiscsiutil/libiscsiutil.h | 148 ++++++++++ {usr.sbin/ctld => lib/libiscsiutil}/log.c | 6 +- {usr.sbin/ctld => lib/libiscsiutil}/pdu.c | 96 ++----- lib/libiscsiutil/utils.c | 44 +++ rescue/rescue/Makefile | 3 + share/mk/bsd.libnames.mk | 1 + share/mk/src.libnames.mk | 4 + usr.sbin/ctld/Makefile | 7 +- usr.sbin/ctld/ctld.c | 86 ++++-- usr.sbin/ctld/ctld.h | 102 +------ usr.sbin/ctld/discovery.c | 8 +- usr.sbin/ctld/kernel.c | 27 +- usr.sbin/ctld/login.c | 51 ++-- usr.sbin/iscsid/Makefile | 5 +- usr.sbin/iscsid/chap.c | 423 ----------------------------- usr.sbin/iscsid/discovery.c | 14 +- usr.sbin/iscsid/iscsid.c | 173 ++++++++---- usr.sbin/iscsid/iscsid.h | 97 +------ usr.sbin/iscsid/keys.c | 199 -------------- usr.sbin/iscsid/log.c | 202 -------------- usr.sbin/iscsid/login.c | 74 ++--- usr.sbin/iscsid/pdu.c | 309 --------------------- 27 files changed, 583 insertions(+), 1572 deletions(-) diff --git a/lib/Makefile b/lib/Makefile index bd28b974c673..43c345daf356 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -63,6 +63,7 @@ SUBDIR= ${SUBDIR_BOOTSTRAP} \ libgeom \ libifconfig \ libipsec \ + libiscsiutil \ libjail \ libkiconv \ libkvm \ diff --git a/lib/libiscsiutil/Makefile b/lib/libiscsiutil/Makefile new file mode 100644 index 000000000000..9ec625970eae --- /dev/null +++ b/lib/libiscsiutil/Makefile @@ -0,0 +1,10 @@ +LIB= iscsiutil +INTERNALLIB= +PACKAGE= iscsi + +INCS= libiscsiutil.h + +SRCS= chap.c connection.c keys.c log.c pdu.c utils.c +CFLAGS+= -I${SRCTOP}/sys/dev/iscsi + +.include diff --git a/usr.sbin/ctld/chap.c b/lib/libiscsiutil/chap.c similarity index 99% rename from usr.sbin/ctld/chap.c rename to lib/libiscsiutil/chap.c index 7b57b7080c97..b33fef220106 100644 --- a/usr.sbin/ctld/chap.c +++ b/lib/libiscsiutil/chap.c @@ -26,12 +26,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * */ -#include -__FBSDID("$FreeBSD$"); - #include #include #include @@ -39,7 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include -#include "ctld.h" +#include "libiscsiutil.h" static void chap_compute_md5(const char id, const char *secret, diff --git a/lib/libiscsiutil/connection.c b/lib/libiscsiutil/connection.c new file mode 100644 index 000000000000..7dc50574644c --- /dev/null +++ b/lib/libiscsiutil/connection.c @@ -0,0 +1,53 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2012 The FreeBSD Foundation + * + * This software was developed by Edward Tomasz Napierala under sponsorship + * from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "libiscsiutil.h" + +void +connection_init(struct connection *conn, const struct connection_ops *ops, + bool use_proxy) +{ + memset(conn, 0, sizeof(*conn)); + conn->conn_ops = ops; + conn->conn_use_proxy = use_proxy; + + /* + * Default values, from RFC 3720, section 12. + */ + conn->conn_header_digest = CONN_DIGEST_NONE; + conn->conn_data_digest = CONN_DIGEST_NONE; + conn->conn_immediate_data = true; + conn->conn_max_recv_data_segment_length = 8192; + conn->conn_max_send_data_segment_length = 8192; + conn->conn_max_burst_length = 262144; + conn->conn_first_burst_length = 65536; +} diff --git a/usr.sbin/ctld/keys.c b/lib/libiscsiutil/keys.c similarity index 98% rename from usr.sbin/ctld/keys.c rename to lib/libiscsiutil/keys.c index f28e333bcd81..8011b0a25329 100644 --- a/usr.sbin/ctld/keys.c +++ b/lib/libiscsiutil/keys.c @@ -26,18 +26,14 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * */ -#include -__FBSDID("$FreeBSD$"); - #include #include #include #include -#include "ctld.h" +#include "libiscsiutil.h" struct keys * keys_new(void) diff --git a/lib/libiscsiutil/libiscsiutil.h b/lib/libiscsiutil/libiscsiutil.h new file mode 100644 index 000000000000..79c79872b2e6 --- /dev/null +++ b/lib/libiscsiutil/libiscsiutil.h @@ -0,0 +1,148 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2012 The FreeBSD Foundation + * + * This software was developed by Edward Tomasz Napierala under sponsorship + * from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __LIBISCSIUTIL_H__ +#define __LIBISCSIUTIL_H__ + +#include +#include + +struct connection_ops; + +#define CONN_DIGEST_NONE 0 +#define CONN_DIGEST_CRC32C 1 + +struct connection { + const struct connection_ops *conn_ops; + int conn_socket; + uint8_t conn_isid[6]; + uint16_t conn_tsih; + uint32_t conn_cmdsn; + uint32_t conn_statsn; + int conn_header_digest; + int conn_data_digest; + bool conn_immediate_data; + bool conn_use_proxy; + int conn_max_recv_data_segment_length; + int conn_max_send_data_segment_length; + int conn_max_burst_length; + int conn_first_burst_length; +}; + +struct pdu { + struct connection *pdu_connection; + struct iscsi_bhs *pdu_bhs; + char *pdu_data; + size_t pdu_data_len; +}; + +struct connection_ops { + bool (*timed_out)(void); + void (*pdu_receive_proxy)(struct pdu *); + void (*pdu_send_proxy)(struct pdu *); + void (*fail)(const struct connection *, const char *); +}; + +#define KEYS_MAX 1024 + +struct keys { + char *keys_names[KEYS_MAX]; + char *keys_values[KEYS_MAX]; + char *keys_data; + size_t keys_data_len; +}; + +#define CHAP_CHALLENGE_LEN 1024 +#define CHAP_DIGEST_LEN 16 /* Equal to MD5 digest size. */ + +struct chap { + unsigned char chap_id; + char chap_challenge[CHAP_CHALLENGE_LEN]; + char chap_response[CHAP_DIGEST_LEN]; +}; + +struct rchap { + char *rchap_secret; + unsigned char rchap_id; + void *rchap_challenge; + size_t rchap_challenge_len; +}; + +struct chap *chap_new(void); +char *chap_get_id(const struct chap *chap); +char *chap_get_challenge(const struct chap *chap); +int chap_receive(struct chap *chap, const char *response); +int chap_authenticate(struct chap *chap, + const char *secret); +void chap_delete(struct chap *chap); + +struct rchap *rchap_new(const char *secret); +int rchap_receive(struct rchap *rchap, + const char *id, const char *challenge); +char *rchap_get_response(struct rchap *rchap); +void rchap_delete(struct rchap *rchap); + +struct keys *keys_new(void); +void keys_delete(struct keys *key); +void keys_load(struct keys *keys, const struct pdu *pdu); +void keys_save(struct keys *keys, struct pdu *pdu); +const char *keys_find(struct keys *keys, const char *name); +void keys_add(struct keys *keys, + const char *name, const char *value); +void keys_add_int(struct keys *keys, + const char *name, int value); + +struct pdu *pdu_new(struct connection *ic); +struct pdu *pdu_new_response(struct pdu *request); +int pdu_ahs_length(const struct pdu *pdu); +int pdu_data_segment_length(const struct pdu *pdu); +void pdu_set_data_segment_length(struct pdu *pdu, + uint32_t len); +void pdu_receive(struct pdu *request); +void pdu_send(struct pdu *response); +void pdu_delete(struct pdu *ip); + +void connection_init(struct connection *conn, + const struct connection_ops *ops, bool use_proxy); + +void log_init(int level); +void log_set_peer_name(const char *name); +void log_set_peer_addr(const char *addr); +void log_err(int, const char *, ...) + __dead2 __printflike(2, 3); +void log_errx(int, const char *, ...) + __dead2 __printflike(2, 3); +void log_warn(const char *, ...) __printflike(1, 2); +void log_warnx(const char *, ...) __printflike(1, 2); +void log_debugx(const char *, ...) __printflike(1, 2); + +char *checked_strdup(const char *); + +#endif /* !__LIBISCSIUTIL_H__ */ diff --git a/usr.sbin/ctld/log.c b/lib/libiscsiutil/log.c similarity index 98% rename from usr.sbin/ctld/log.c rename to lib/libiscsiutil/log.c index 94e014293a61..7d7a13bb11f2 100644 --- a/usr.sbin/ctld/log.c +++ b/lib/libiscsiutil/log.c @@ -26,12 +26,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * */ -#include -__FBSDID("$FreeBSD$"); - #include #include #include @@ -40,7 +36,7 @@ __FBSDID("$FreeBSD$"); #include #include -#include "ctld.h" +#include "libiscsiutil.h" static int log_level = 0; static char *peer_name = NULL; diff --git a/usr.sbin/ctld/pdu.c b/lib/libiscsiutil/pdu.c similarity index 77% rename from usr.sbin/ctld/pdu.c rename to lib/libiscsiutil/pdu.c index 04691556b997..ed5ee5b71766 100644 --- a/usr.sbin/ctld/pdu.c +++ b/lib/libiscsiutil/pdu.c @@ -35,26 +35,22 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include +#include #include -#include "ctld.h" -#include "iscsi_proto.h" +#include +#include "libiscsiutil.h" -#ifdef ICL_KERNEL_PROXY -#include -#endif - -extern bool proxy_mode; - -static int +int pdu_ahs_length(const struct pdu *pdu) { return (pdu->pdu_bhs->bhs_total_ahs_len * 4); } -static int +int pdu_data_segment_length(const struct pdu *pdu) { uint32_t len = 0; @@ -68,7 +64,7 @@ pdu_data_segment_length(const struct pdu *pdu) return (len); } -static void +void pdu_set_data_segment_length(struct pdu *pdu, uint32_t len) { @@ -102,40 +98,6 @@ pdu_new_response(struct pdu *request) return (pdu_new(request->pdu_connection)); } -#ifdef ICL_KERNEL_PROXY - -static void -pdu_receive_proxy(struct pdu *pdu) -{ - struct connection *conn; - size_t len; - - assert(proxy_mode); - conn = pdu->pdu_connection; - - kernel_receive(pdu); - - len = pdu_ahs_length(pdu); - if (len > 0) - log_errx(1, "protocol error: non-empty AHS"); - - len = pdu_data_segment_length(pdu); - assert(len <= (size_t)conn->conn_max_recv_data_segment_length); - pdu->pdu_data_len = len; -} - -static void -pdu_send_proxy(struct pdu *pdu) -{ - - assert(proxy_mode); - - pdu_set_data_segment_length(pdu, pdu->pdu_data_len); - kernel_send(pdu); -} - -#endif /* ICL_KERNEL_PROXY */ - static size_t pdu_padding(const struct pdu *pdu) { @@ -147,18 +109,24 @@ pdu_padding(const struct pdu *pdu) } static void -pdu_read(int fd, char *data, size_t len) +pdu_read(const struct connection *conn, char *data, size_t len) { ssize_t ret; while (len > 0) { - ret = read(fd, data, len); + ret = read(conn->conn_socket, data, len); if (ret < 0) { - if (timed_out()) + if (conn->conn_ops->timed_out()) { + conn->conn_ops->fail(conn, + "Login Phase timeout"); log_errx(1, "exiting due to timeout"); + } + conn->conn_ops->fail(conn, strerror(errno)); log_err(1, "read"); - } else if (ret == 0) + } else if (ret == 0) { + conn->conn_ops->fail(conn, "connection lost"); log_errx(1, "read: connection lost"); + } len -= ret; data += ret; } @@ -171,16 +139,11 @@ pdu_receive(struct pdu *pdu) size_t len, padding; char dummy[4]; -#ifdef ICL_KERNEL_PROXY - if (proxy_mode) - return (pdu_receive_proxy(pdu)); -#endif - - assert(proxy_mode == false); conn = pdu->pdu_connection; + if (conn->conn_use_proxy) + return (conn->conn_ops->pdu_receive_proxy(pdu)); - pdu_read(conn->conn_socket, (char *)pdu->pdu_bhs, - sizeof(*pdu->pdu_bhs)); + pdu_read(conn, (char *)pdu->pdu_bhs, sizeof(*pdu->pdu_bhs)); len = pdu_ahs_length(pdu); if (len > 0) @@ -199,13 +162,12 @@ pdu_receive(struct pdu *pdu) if (pdu->pdu_data == NULL) log_err(1, "malloc"); - pdu_read(conn->conn_socket, (char *)pdu->pdu_data, - pdu->pdu_data_len); + pdu_read(conn, (char *)pdu->pdu_data, pdu->pdu_data_len); padding = pdu_padding(pdu); if (padding != 0) { assert(padding < sizeof(dummy)); - pdu_read(conn->conn_socket, (char *)dummy, padding); + pdu_read(conn, (char *)dummy, padding); } } } @@ -213,18 +175,16 @@ pdu_receive(struct pdu *pdu) void pdu_send(struct pdu *pdu) { + struct connection *conn; ssize_t ret, total_len; size_t padding; uint32_t zero = 0; struct iovec iov[3]; int iovcnt; -#ifdef ICL_KERNEL_PROXY - if (proxy_mode) - return (pdu_send_proxy(pdu)); -#endif - - assert(proxy_mode == false); + conn = pdu->pdu_connection; + if (conn->conn_use_proxy) + return (conn->conn_ops->pdu_send_proxy(pdu)); pdu_set_data_segment_length(pdu, pdu->pdu_data_len); iov[0].iov_base = pdu->pdu_bhs; @@ -248,9 +208,9 @@ pdu_send(struct pdu *pdu) } } - ret = writev(pdu->pdu_connection->conn_socket, iov, iovcnt); + ret = writev(conn->conn_socket, iov, iovcnt); if (ret < 0) { - if (timed_out()) + if (conn->conn_ops->timed_out()) log_errx(1, "exiting due to timeout"); log_err(1, "writev"); } diff --git a/lib/libiscsiutil/utils.c b/lib/libiscsiutil/utils.c new file mode 100644 index 000000000000..1e04490c477c --- /dev/null +++ b/lib/libiscsiutil/utils.c @@ -0,0 +1,44 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2012 The FreeBSD Foundation + * + * This software was developed by Edward Tomasz Napierala under sponsorship + * from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "libiscsiutil.h" + +char * +checked_strdup(const char *s) +{ + char *c; + + c = strdup(s); + if (c == NULL) + log_err(1, "strdup"); + return (c); +} diff --git a/rescue/rescue/Makefile b/rescue/rescue/Makefile index 90aaea3cb709..783b5bbd7721 100644 --- a/rescue/rescue/Makefile +++ b/rescue/rescue/Makefile @@ -236,6 +236,9 @@ CRUNCH_LIBS+= -lm .if ${MK_ISCSI} != "no" CRUNCH_PROGS_usr.bin+= iscsictl CRUNCH_PROGS_usr.sbin+= iscsid + +CRUNCH_LIBS+= ${OBJTOP}/lib/libiscsiutil/libiscsiutil.a +CRUNCH_BUILDOPTS+= CRUNCH_CFLAGS+=-I${OBJTOP}/lib/libiscsiutil .endif .include diff --git a/share/mk/bsd.libnames.mk b/share/mk/bsd.libnames.mk index f71664bf5858..45710b203ddc 100644 --- a/share/mk/bsd.libnames.mk +++ b/share/mk/bsd.libnames.mk @@ -83,6 +83,7 @@ LIBIBVERBS?= ${LIBDESTDIR}${LIBDIR_BASE}/libibverbs.a LIBICP?= ${LIBDESTDIR}${LIBDIR_BASE}/libicp.a LIBIPSEC?= ${LIBDESTDIR}${LIBDIR_BASE}/libipsec.a LIBIPT?= ${LIBDESTDIR}${LIBDIR_BASE}/libipt.a +LIBISCSIUTIL?= ${LIBDESTDIR}${LIBDIR_BASE}/libiscsiutil.a LIBJAIL?= ${LIBDESTDIR}${LIBDIR_BASE}/libjail.a LIBKADM5CLNT?= ${LIBDESTDIR}${LIBDIR_BASE}/libkadm5clnt.a LIBKADM5SRV?= ${LIBDESTDIR}${LIBDIR_BASE}/libkadm5srv.a diff --git a/share/mk/src.libnames.mk b/share/mk/src.libnames.mk index 385e8616a82d..cf6c41887791 100644 --- a/share/mk/src.libnames.mk +++ b/share/mk/src.libnames.mk @@ -44,6 +44,7 @@ _INTERNALLIBS= \ fifolog \ ifconfig \ ipf \ + iscsiutil \ lpr \ lua \ lutok \ @@ -556,6 +557,9 @@ LIBIFCONFIG?= ${LIBIFCONFIGDIR}/libifconfig${PIE_SUFFIX}.a LIBIPFDIR= ${_LIB_OBJTOP}/sbin/ipf/libipf LIBIPF?= ${LIBIPFDIR}/libipf${PIE_SUFFIX}.a +LIBISCSIUTILDIR= ${_LIB_OBJTOP}/lib/libiscsiutil +LIBISCSIUTIL?= ${LIBISCSIUTILDIR}/libiscsiutil${PIE_SUFFIX}.a + LIBTELNETDIR= ${_LIB_OBJTOP}/lib/libtelnet LIBTELNET?= ${LIBTELNETDIR}/libtelnet${PIE_SUFFIX}.a diff --git a/usr.sbin/ctld/Makefile b/usr.sbin/ctld/Makefile index ec207f024ab1..5f80ba026204 100644 --- a/usr.sbin/ctld/Makefile +++ b/usr.sbin/ctld/Makefile @@ -7,16 +7,17 @@ CFLAGS+=-I${SRCTOP}/contrib/libucl/include PACKAGE= iscsi PROG= ctld -SRCS= chap.c ctld.c discovery.c isns.c kernel.c keys.c log.c -SRCS+= login.c parse.y pdu.c token.l y.tab.h uclparse.c +SRCS= ctld.c discovery.c isns.c kernel.c +SRCS+= login.c parse.y token.l y.tab.h uclparse.c CFLAGS+= -I${.CURDIR} CFLAGS+= -I${SRCTOP}/sys CFLAGS+= -I${SRCTOP}/sys/cam/ctl CFLAGS+= -I${SRCTOP}/sys/dev/iscsi +CFLAGS+= -I${SRCTOP}/lib/libiscsiutil #CFLAGS+= -DICL_KERNEL_PROXY MAN= ctld.8 ctl.conf.5 -LIBADD= bsdxml md sbuf util ucl m nv +LIBADD= bsdxml iscsiutil md sbuf util ucl m nv YFLAGS+= -v CLEANFILES= y.tab.c y.tab.h y.output diff --git a/usr.sbin/ctld/ctld.c b/usr.sbin/ctld/ctld.c index c37181ff00d0..3f4bca632512 100644 --- a/usr.sbin/ctld/ctld.c +++ b/usr.sbin/ctld/ctld.c @@ -54,6 +54,13 @@ __FBSDID("$FreeBSD$"); #include "ctld.h" #include "isns.h" +static bool timed_out(void); +#ifdef ICL_KERNEL_PROXY +static void pdu_receive_proxy(struct pdu *pdu); +static void pdu_send_proxy(struct pdu *pdu); +#endif /* ICL_KERNEL_PROXY */ +static void pdu_fail(const struct connection *conn, const char *reason); + bool proxy_mode = false; static volatile bool sighup_received = false; @@ -63,6 +70,15 @@ static volatile bool sigalrm_received = false; static int nchildren = 0; static uint16_t last_portal_group_tag = 0xff; +static struct connection_ops conn_ops = { + .timed_out = timed_out, +#ifdef ICL_KERNEL_PROXY + .pdu_receive_proxy = pdu_receive_proxy, + .pdu_send_proxy = pdu_send_proxy, +#endif + .fail = pdu_fail, +}; + static void usage(void) { @@ -72,17 +88,6 @@ usage(void) exit(1); } -char * -checked_strdup(const char *s) -{ - char *c; - - c = strdup(s); - if (c == NULL) - log_err(1, "strdup"); - return (c); -} - struct conf * conf_new(void) { @@ -1632,29 +1637,60 @@ option_set(struct option *o, const char *value) o->o_value = checked_strdup(value); } -static struct connection * +#ifdef ICL_KERNEL_PROXY + +static void +pdu_receive_proxy(struct pdu *pdu) +{ + struct connection *conn; + size_t len; + + assert(proxy_mode); + conn = pdu->pdu_connection; + + kernel_receive(pdu); + + len = pdu_ahs_length(pdu); + if (len > 0) + log_errx(1, "protocol error: non-empty AHS"); + + len = pdu_data_segment_length(pdu); + assert(len <= (size_t)conn->conn_max_recv_data_segment_length); + pdu->pdu_data_len = len; +} + +static void +pdu_send_proxy(struct pdu *pdu) +{ + + assert(proxy_mode); + + pdu_set_data_segment_length(pdu, pdu->pdu_data_len); + kernel_send(pdu); +} + +#endif /* ICL_KERNEL_PROXY */ + +static void +pdu_fail(const struct connection *conn __unused, const char *reason __unused) +{ +} + +static struct ctld_connection * connection_new(struct portal *portal, int fd, const char *host, const struct sockaddr *client_sa) { - struct connection *conn; + struct ctld_connection *conn; conn = calloc(1, sizeof(*conn)); if (conn == NULL) log_err(1, "calloc"); + connection_init(&conn->conn, &conn_ops, proxy_mode); + conn->conn.conn_socket = fd; conn->conn_portal = portal; - conn->conn_socket = fd; conn->conn_initiator_addr = checked_strdup(host); memcpy(&conn->conn_initiator_sa, client_sa, client_sa->sa_len); - /* - * Default values, from RFC 3720, section 12. - */ - conn->conn_max_recv_data_segment_length = 8192; - conn->conn_max_send_data_segment_length = 8192; - conn->conn_max_burst_length = 262144; - conn->conn_first_burst_length = 65536; - conn->conn_immediate_data = true; - return (conn); } @@ -2296,7 +2332,7 @@ conf_apply(struct conf *oldconf, struct conf *newconf) return (cumulated_error); } -bool +static bool timed_out(void) { @@ -2407,7 +2443,7 @@ static void handle_connection(struct portal *portal, int fd, const struct sockaddr *client_sa, bool dont_fork) { - struct connection *conn; + struct ctld_connection *conn; int error; pid_t pid; char host[NI_MAXHOST + 1]; diff --git a/usr.sbin/ctld/ctld.h b/usr.sbin/ctld/ctld.h index 4ff8f0e638ac..293f5378592f 100644 --- a/usr.sbin/ctld/ctld.h +++ b/usr.sbin/ctld/ctld.h @@ -39,6 +39,7 @@ #endif #include #include +#include #include #define DEFAULT_CONFIG_PATH "/etc/ctl.conf" @@ -229,83 +230,25 @@ struct conf { #define CONN_SESSION_TYPE_DISCOVERY 1 #define CONN_SESSION_TYPE_NORMAL 2 -#define CONN_DIGEST_NONE 0 -#define CONN_DIGEST_CRC32C 1 - -struct connection { +struct ctld_connection { + struct connection conn; struct portal *conn_portal; struct port *conn_port; struct target *conn_target; - int conn_socket; int conn_session_type; char *conn_initiator_name; char *conn_initiator_addr; char *conn_initiator_alias; uint8_t conn_initiator_isid[6]; struct sockaddr_storage conn_initiator_sa; - uint32_t conn_cmdsn; - uint32_t conn_statsn; int conn_max_recv_data_segment_limit; int conn_max_send_data_segment_limit; int conn_max_burst_limit; int conn_first_burst_limit; - int conn_max_recv_data_segment_length; - int conn_max_send_data_segment_length; - int conn_max_burst_length; - int conn_first_burst_length; - int conn_immediate_data; - int conn_header_digest; - int conn_data_digest; const char *conn_user; struct chap *conn_chap; }; -struct pdu { - struct connection *pdu_connection; - struct iscsi_bhs *pdu_bhs; - char *pdu_data; - size_t pdu_data_len; -}; - -#define KEYS_MAX 1024 - -struct keys { - char *keys_names[KEYS_MAX]; - char *keys_values[KEYS_MAX]; - char *keys_data; - size_t keys_data_len; -}; - -#define CHAP_CHALLENGE_LEN 1024 -#define CHAP_DIGEST_LEN 16 /* Equal to MD5 digest size. */ - -struct chap { - unsigned char chap_id; - char chap_challenge[CHAP_CHALLENGE_LEN]; - char chap_response[CHAP_DIGEST_LEN]; -}; - -struct rchap { - char *rchap_secret; - unsigned char rchap_id; - void *rchap_challenge; - size_t rchap_challenge_len; -}; - -struct chap *chap_new(void); -char *chap_get_id(const struct chap *chap); -char *chap_get_challenge(const struct chap *chap); -int chap_receive(struct chap *chap, const char *response); -int chap_authenticate(struct chap *chap, - const char *secret); -void chap_delete(struct chap *chap); - -struct rchap *rchap_new(const char *secret); -int rchap_receive(struct rchap *rchap, - const char *id, const char *challenge); -char *rchap_get_response(struct rchap *rchap); -void rchap_delete(struct rchap *rchap); - int parse_conf(struct conf *conf, const char *path); int uclparse_conf(struct conf *conf, const char *path); @@ -412,7 +355,7 @@ void kernel_init(void); int kernel_lun_add(struct lun *lun); int kernel_lun_modify(struct lun *lun); int kernel_lun_remove(struct lun *lun); -void kernel_handoff(struct connection *conn); +void kernel_handoff(struct ctld_connection *conn); void kernel_limits(const char *offload, int *max_recv_data_segment_length, int *max_send_data_segment_length, @@ -433,40 +376,11 @@ void kernel_send(struct pdu *pdu); void kernel_receive(struct pdu *pdu); #endif -struct keys *keys_new(void); -void keys_delete(struct keys *keys); -void keys_load(struct keys *keys, const struct pdu *pdu); -void keys_save(struct keys *keys, struct pdu *pdu); -const char *keys_find(struct keys *keys, const char *name); -void keys_add(struct keys *keys, - const char *name, const char *value); -void keys_add_int(struct keys *keys, - const char *name, int value); - -struct pdu *pdu_new(struct connection *conn); -struct pdu *pdu_new_response(struct pdu *request); -void pdu_delete(struct pdu *pdu); -void pdu_receive(struct pdu *request); -void pdu_send(struct pdu *response); - -void login(struct connection *conn); - -void discovery(struct connection *conn); - -void log_init(int level); -void log_set_peer_name(const char *name); -void log_set_peer_addr(const char *addr); -void log_err(int, const char *, ...) - __dead2 __printflike(2, 3); -void log_errx(int, const char *, ...) - __dead2 __printflike(2, 3); -void log_warn(const char *, ...) __printflike(1, 2); -void log_warnx(const char *, ...) __printflike(1, 2); -void log_debugx(const char *, ...) __printflike(1, 2); - -char *checked_strdup(const char *); +void login(struct ctld_connection *conn); + +void discovery(struct ctld_connection *conn); + bool valid_iscsi_name(const char *name); void set_timeout(int timeout, int fatal); -bool timed_out(void); #endif /* !CTLD_H */ diff --git a/usr.sbin/ctld/discovery.c b/usr.sbin/ctld/discovery.c *** 2321 LINES SKIPPED ***