git: dd3603749cb7 - main - iscsi: Move valid_iscsi_name to libiscsiutil
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 24 Jan 2025 14:54:39 UTC
The branch main has been updated by jhb:
URL: https://cgit.FreeBSD.org/src/commit/?id=dd3603749cb7f20a628f04d595b105962b21a3d2
commit dd3603749cb7f20a628f04d595b105962b21a3d2
Author: John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2025-01-24 14:52:10 +0000
Commit: John Baldwin <jhb@FreeBSD.org>
CommitDate: 2025-01-24 14:53:22 +0000
iscsi: Move valid_iscsi_name to libiscsiutil
While here, use isxdigit(3) instead of a home-rolled version.
Reviewed by: mav, asomers
Sponsored by: Chelsio Communications
Differential Revision: https://reviews.freebsd.org/D48593
---
lib/libiscsiutil/libiscsiutil.h | 3 ++
lib/libiscsiutil/utils.c | 71 ++++++++++++++++++++++++++
usr.bin/iscsictl/Makefile | 3 +-
usr.bin/iscsictl/iscsictl.c | 107 ++--------------------------------------
usr.bin/iscsictl/iscsictl.h | 3 --
usr.sbin/ctld/ctld.c | 103 +-------------------------------------
usr.sbin/ctld/ctld.h | 2 -
usr.sbin/ctld/login.c | 2 +-
8 files changed, 82 insertions(+), 212 deletions(-)
diff --git a/lib/libiscsiutil/libiscsiutil.h b/lib/libiscsiutil/libiscsiutil.h
index bf26a5b8ed66..8da6ead73fce 100644
--- a/lib/libiscsiutil/libiscsiutil.h
+++ b/lib/libiscsiutil/libiscsiutil.h
@@ -154,6 +154,9 @@ void text_send_response(struct pdu *request,
void connection_init(struct connection *conn,
const struct connection_ops *ops, bool use_proxy);
+bool valid_iscsi_name(const char *name,
+ void (*warn_fn)(const char *, ...));
+
void log_init(int level);
void log_set_peer_name(const char *name);
void log_set_peer_addr(const char *addr);
diff --git a/lib/libiscsiutil/utils.c b/lib/libiscsiutil/utils.c
index e078c7a53a17..ef2d67106da5 100644
--- a/lib/libiscsiutil/utils.c
+++ b/lib/libiscsiutil/utils.c
@@ -28,10 +28,13 @@
* SUCH DAMAGE.
*/
+#include <ctype.h>
#include <string.h>
#include "libiscsiutil.h"
+#define MAX_NAME_LEN 223
+
char *
checked_strdup(const char *s)
{
@@ -42,3 +45,71 @@ checked_strdup(const char *s)
log_err(1, "strdup");
return (c);
}
+
+bool
+valid_iscsi_name(const char *name, void (*warn_fn)(const char *, ...))
+{
+ int i;
+
+ if (strlen(name) >= MAX_NAME_LEN) {
+ warn_fn("overlong name for target \"%s\"; max length allowed "
+ "by iSCSI specification is %d characters",
+ name, MAX_NAME_LEN);
+ return (false);
+ }
+
+ /*
+ * In the cases below, we don't return an error, just in case the admin
+ * was right, and we're wrong.
+ */
+ if (strncasecmp(name, "iqn.", strlen("iqn.")) == 0) {
+ for (i = strlen("iqn."); name[i] != '\0'; i++) {
+ /*
+ * XXX: We should verify UTF-8 normalisation, as defined
+ * by 3.2.6.2: iSCSI Name Encoding.
+ */
+ if (isalnum(name[i]))
+ continue;
+ if (name[i] == '-' || name[i] == '.' || name[i] == ':')
+ continue;
+ warn_fn("invalid character \"%c\" in target name "
+ "\"%s\"; allowed characters are letters, digits, "
+ "'-', '.', and ':'", name[i], name);
+ break;
+ }
+ /*
+ * XXX: Check more stuff: valid date and a valid reversed domain.
+ */
+ } else if (strncasecmp(name, "eui.", strlen("eui.")) == 0) {
+ if (strlen(name) != strlen("eui.") + 16)
+ warn_fn("invalid target name \"%s\"; the \"eui.\" "
+ "should be followed by exactly 16 hexadecimal "
+ "digits", name);
+ for (i = strlen("eui."); name[i] != '\0'; i++) {
+ if (!isxdigit(name[i])) {
+ warn_fn("invalid character \"%c\" in target "
+ "name \"%s\"; allowed characters are 1-9 "
+ "and A-F", name[i], name);
+ break;
+ }
+ }
+ } else if (strncasecmp(name, "naa.", strlen("naa.")) == 0) {
+ if (strlen(name) > strlen("naa.") + 32)
+ warn_fn("invalid target name \"%s\"; the \"naa.\" "
+ "should be followed by at most 32 hexadecimal "
+ "digits", name);
+ for (i = strlen("naa."); name[i] != '\0'; i++) {
+ if (!isxdigit(name[i])) {
+ warn_fn("invalid character \"%c\" in target "
+ "name \"%s\"; allowed characters are 1-9 "
+ "and A-F", name[i], name);
+ break;
+ }
+ }
+ } else {
+ warn_fn("invalid target name \"%s\"; should start with "
+ "either \"iqn.\", \"eui.\", or \"naa.\"",
+ name);
+ }
+ return (true);
+}
diff --git a/usr.bin/iscsictl/Makefile b/usr.bin/iscsictl/Makefile
index 6c09faa3d915..c47b28e7be5e 100644
--- a/usr.bin/iscsictl/Makefile
+++ b/usr.bin/iscsictl/Makefile
@@ -3,9 +3,10 @@ PROG= iscsictl
SRCS= iscsictl.c periphs.c parse.y token.l y.tab.h
CFLAGS+= -I${.CURDIR}
CFLAGS+= -I${SRCTOP}/sys/dev/iscsi
+CFLAGS+= -I${SRCTOP}/lib/libiscsiutil
MAN= iscsi.conf.5 iscsictl.8
-LIBADD= util xo
+LIBADD= iscsiutil util xo
YFLAGS+= -v
LFLAGS+= -i
diff --git a/usr.bin/iscsictl/iscsictl.c b/usr.bin/iscsictl/iscsictl.c
index 922e9ed9ebea..f78e47d226bf 100644
--- a/usr.bin/iscsictl/iscsictl.c
+++ b/usr.bin/iscsictl/iscsictl.c
@@ -42,6 +42,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <libiscsiutil.h>
#include <libxo/xo.h>
#include <iscsi_ioctl.h>
@@ -122,38 +123,6 @@ default_initiator_name(void)
return (name);
}
-static bool
-valid_hex(const char ch)
-{
- switch (ch) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case 'a':
- case 'A':
- case 'b':
- case 'B':
- case 'c':
- case 'C':
- case 'd':
- case 'D':
- case 'e':
- case 'E':
- case 'f':
- case 'F':
- return (true);
- default:
- return (false);
- }
-}
-
int
parse_enable(const char *enable)
{
@@ -171,74 +140,6 @@ parse_enable(const char *enable)
return (ENABLE_UNSPECIFIED);
}
-bool
-valid_iscsi_name(const char *name)
-{
- int i;
-
- if (strlen(name) >= MAX_NAME_LEN) {
- xo_warnx("overlong name for \"%s\"; max length allowed "
- "by iSCSI specification is %d characters",
- name, MAX_NAME_LEN);
- return (false);
- }
-
- /*
- * In the cases below, we don't return an error, just in case the admin
- * was right, and we're wrong.
- */
- if (strncasecmp(name, "iqn.", strlen("iqn.")) == 0) {
- for (i = strlen("iqn."); name[i] != '\0'; i++) {
- /*
- * XXX: We should verify UTF-8 normalisation, as defined
- * by 3.2.6.2: iSCSI Name Encoding.
- */
- if (isalnum(name[i]))
- continue;
- if (name[i] == '-' || name[i] == '.' || name[i] == ':')
- continue;
- xo_warnx("invalid character \"%c\" in iSCSI name "
- "\"%s\"; allowed characters are letters, digits, "
- "'-', '.', and ':'", name[i], name);
- break;
- }
- /*
- * XXX: Check more stuff: valid date and a valid reversed domain.
- */
- } else if (strncasecmp(name, "eui.", strlen("eui.")) == 0) {
- if (strlen(name) != strlen("eui.") + 16)
- xo_warnx("invalid iSCSI name \"%s\"; the \"eui.\" "
- "should be followed by exactly 16 hexadecimal "
- "digits", name);
- for (i = strlen("eui."); name[i] != '\0'; i++) {
- if (!valid_hex(name[i])) {
- xo_warnx("invalid character \"%c\" in iSCSI "
- "name \"%s\"; allowed characters are 1-9 "
- "and A-F", name[i], name);
- break;
- }
- }
- } else if (strncasecmp(name, "naa.", strlen("naa.")) == 0) {
- if (strlen(name) > strlen("naa.") + 32)
- xo_warnx("invalid iSCSI name \"%s\"; the \"naa.\" "
- "should be followed by at most 32 hexadecimal "
- "digits", name);
- for (i = strlen("naa."); name[i] != '\0'; i++) {
- if (!valid_hex(name[i])) {
- xo_warnx("invalid character \"%c\" in ISCSI "
- "name \"%s\"; allowed characters are 1-9 "
- "and A-F", name[i], name);
- break;
- }
- }
- } else {
- xo_warnx("invalid iSCSI name \"%s\"; should start with "
- "either \".iqn\", \"eui.\", or \"naa.\"",
- name);
- }
- return (true);
-}
-
void
conf_verify(struct conf *conf)
{
@@ -257,7 +158,7 @@ conf_verify(struct conf *conf)
xo_errx(1, "cannot specify TargetName for discovery "
"sessions for target \"%s\"", targ->t_nickname);
if (targ->t_name != NULL) {
- if (valid_iscsi_name(targ->t_name) == false)
+ if (valid_iscsi_name(targ->t_name, xo_warnx) == false)
xo_errx(1, "invalid target name \"%s\"",
targ->t_name);
}
@@ -268,7 +169,7 @@ conf_verify(struct conf *conf)
targ->t_nickname);
if (targ->t_initiator_name == NULL)
targ->t_initiator_name = default_initiator_name();
- if (valid_iscsi_name(targ->t_initiator_name) == false)
+ if (valid_iscsi_name(targ->t_initiator_name, xo_warnx) == false)
xo_errx(1, "invalid initiator name \"%s\"",
targ->t_initiator_name);
if (targ->t_header_digest == DIGEST_UNSPECIFIED)
@@ -1014,7 +915,7 @@ main(int argc, char **argv)
user, secret, enable);
} else {
if (Aflag != 0 && target != NULL) {
- if (valid_iscsi_name(target) == false)
+ if (valid_iscsi_name(target, xo_warnx) == false)
xo_errx(1, "invalid target name \"%s\"", target);
}
conf = conf_new();
diff --git a/usr.bin/iscsictl/iscsictl.h b/usr.bin/iscsictl/iscsictl.h
index 3bc69e4877a9..dea1a6712dd8 100644
--- a/usr.bin/iscsictl/iscsictl.h
+++ b/usr.bin/iscsictl/iscsictl.h
@@ -40,8 +40,6 @@
#define ISCSICTL_XO_VERSION "1"
-#define MAX_NAME_LEN 223
-
#define AUTH_METHOD_UNSPECIFIED 0
#define AUTH_METHOD_NONE 1
#define AUTH_METHOD_CHAP 2
@@ -103,7 +101,6 @@ void target_delete(struct target *ic);
void print_periphs(int session_id);
-bool valid_iscsi_name(const char *name);
int parse_enable(const char *enable);
#endif /* !ISCSICTL_H */
diff --git a/usr.sbin/ctld/ctld.c b/usr.sbin/ctld/ctld.c
index 3136a5d4b7cb..93a749b9109a 100644
--- a/usr.sbin/ctld/ctld.c
+++ b/usr.sbin/ctld/ctld.c
@@ -1072,106 +1072,6 @@ portal_group_set_redirection(struct portal_group *pg, const char *addr)
return (0);
}
-static bool
-valid_hex(const char ch)
-{
- switch (ch) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case 'a':
- case 'A':
- case 'b':
- case 'B':
- case 'c':
- case 'C':
- case 'd':
- case 'D':
- case 'e':
- case 'E':
- case 'f':
- case 'F':
- return (true);
- default:
- return (false);
- }
-}
-
-bool
-valid_iscsi_name(const char *name)
-{
- int i;
-
- if (strlen(name) >= MAX_NAME_LEN) {
- log_warnx("overlong name for target \"%s\"; max length allowed "
- "by iSCSI specification is %d characters",
- name, MAX_NAME_LEN);
- return (false);
- }
-
- /*
- * In the cases below, we don't return an error, just in case the admin
- * was right, and we're wrong.
- */
- if (strncasecmp(name, "iqn.", strlen("iqn.")) == 0) {
- for (i = strlen("iqn."); name[i] != '\0'; i++) {
- /*
- * XXX: We should verify UTF-8 normalisation, as defined
- * by 3.2.6.2: iSCSI Name Encoding.
- */
- if (isalnum(name[i]))
- continue;
- if (name[i] == '-' || name[i] == '.' || name[i] == ':')
- continue;
- log_warnx("invalid character \"%c\" in target name "
- "\"%s\"; allowed characters are letters, digits, "
- "'-', '.', and ':'", name[i], name);
- break;
- }
- /*
- * XXX: Check more stuff: valid date and a valid reversed domain.
- */
- } else if (strncasecmp(name, "eui.", strlen("eui.")) == 0) {
- if (strlen(name) != strlen("eui.") + 16)
- log_warnx("invalid target name \"%s\"; the \"eui.\" "
- "should be followed by exactly 16 hexadecimal "
- "digits", name);
- for (i = strlen("eui."); name[i] != '\0'; i++) {
- if (!valid_hex(name[i])) {
- log_warnx("invalid character \"%c\" in target "
- "name \"%s\"; allowed characters are 1-9 "
- "and A-F", name[i], name);
- break;
- }
- }
- } else if (strncasecmp(name, "naa.", strlen("naa.")) == 0) {
- if (strlen(name) > strlen("naa.") + 32)
- log_warnx("invalid target name \"%s\"; the \"naa.\" "
- "should be followed by at most 32 hexadecimal "
- "digits", name);
- for (i = strlen("naa."); name[i] != '\0'; i++) {
- if (!valid_hex(name[i])) {
- log_warnx("invalid character \"%c\" in target "
- "name \"%s\"; allowed characters are 1-9 "
- "and A-F", name[i], name);
- break;
- }
- }
- } else {
- log_warnx("invalid target name \"%s\"; should start with "
- "either \"iqn.\", \"eui.\", or \"naa.\"",
- name);
- }
- return (true);
-}
-
struct pport *
pport_new(struct kports *kports, const char *name, uint32_t ctl_port)
{
@@ -1389,8 +1289,7 @@ target_new(struct conf *conf, const char *name)
log_warnx("duplicated target \"%s\"", name);
return (NULL);
}
- if (valid_iscsi_name(name) == false) {
- log_warnx("target name \"%s\" is invalid", name);
+ if (valid_iscsi_name(name, log_warnx) == false) {
return (NULL);
}
targ = calloc(1, sizeof(*targ));
diff --git a/usr.sbin/ctld/ctld.h b/usr.sbin/ctld/ctld.h
index 3f4b653d6896..88490a94464e 100644
--- a/usr.sbin/ctld/ctld.h
+++ b/usr.sbin/ctld/ctld.h
@@ -46,7 +46,6 @@
#define DEFAULT_CD_BLOCKSIZE 2048
#define MAX_LUNS 1024
-#define MAX_NAME_LEN 223
#define MAX_DATA_SEGMENT_LENGTH (128 * 1024)
#define SOCKBUF_SIZE 1048576
@@ -387,7 +386,6 @@ 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);
#endif /* !CTLD_H */
diff --git a/usr.sbin/ctld/login.c b/usr.sbin/ctld/login.c
index afd3210a828a..f57582f4e62f 100644
--- a/usr.sbin/ctld/login.c
+++ b/usr.sbin/ctld/login.c
@@ -874,7 +874,7 @@ login(struct ctld_connection *conn)
login_send_error(request, 0x02, 0x07);
log_errx(1, "received Login PDU without InitiatorName");
}
- if (valid_iscsi_name(initiator_name) == false) {
+ if (valid_iscsi_name(initiator_name, log_warnx) == false) {
login_send_error(request, 0x02, 0x00);
log_errx(1, "received Login PDU with invalid InitiatorName");
}