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"); }