The branch main has been updated by jhb:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=dd3603749cb7f20a628f04d595b105962b21a3d2

commit dd3603749cb7f20a628f04d595b105962b21a3d2
Author:     John Baldwin <j...@freebsd.org>
AuthorDate: 2025-01-24 14:52:10 +0000
Commit:     John Baldwin <j...@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");
        }

Reply via email to