k...@munnari.oz.au (Robert Elz) writes:

>  | The address parser looks broken.
>It certainly is, it is horrid.

>and the relevant function is get_address()

Maybe the patch below. It's still a bit naive (you can bracket anything,
not just ipv6 literals).

The address string is later used in iscsid_driverif.c, a name
is resolved with gethostbyname(), so while an ipv6 address might
be accepted, the code lacks ipv6 support.


Index: sbin/iscsictl/iscsic_parse.c
===================================================================
RCS file: /cvsroot/src/sbin/iscsictl/iscsic_parse.c,v
retrieving revision 1.4
diff -p -u -r1.4 iscsic_parse.c
--- sbin/iscsictl/iscsic_parse.c        3 Dec 2021 13:27:38 -0000       1.4
+++ sbin/iscsictl/iscsic_parse.c        18 Nov 2023 10:35:17 -0000
@@ -48,50 +48,55 @@
 STATIC void
 get_address(iscsi_portal_address_t * portal, char *str, char *arg)
 {
-       char *sp, *sp2;
+       char *sp;
        int val;
 
        if (!str || !*str)
                arg_error(arg, "Address is missing");
 
-       /* is there a port? don't check inside square brackets (IPv6 addr) */
-       for (sp = str + 1, val = 0; *sp && (*sp != ':' || val); sp++) {
-               if (*sp == '[')
-                       val = 1;
-               else if (*sp == ']')
-                       val = 0;
-       }
-
-       /* */
-       if (*sp) {
-               for (sp2 = sp + 1; *sp2 && *sp2 != ':'; sp2++);
-               /* if there's a second colon, assume it's an unbracketed IPv6 
address */
-               if (!*sp2) {
-                       /* truncate source, that's the address */
-                       *sp++ = '\0';
-                       if (sscanf(sp, "%d", &val) != 1)
-                               arg_error(arg, "Bad address format: Expected 
port number");
-                       if (val < 0 || val > 0xffff)
-                               arg_error(arg, "Bad address format: Port number 
out of range");
-                       portal->port = (uint16_t) val;
-               }
-               /* is there a group tag? */
-               for (; isdigit((unsigned char)*sp); sp++);
-               if (*sp && *sp != ',')
-                       arg_error(arg, "Bad address format: Extra character(s) 
'%c'", *sp);
-       } else
-               for (sp = str + 1; *sp && *sp != ','; sp++);
-
-       if (*sp) {
+       /* parse and strip trailing group tag */
+       sp = strchr(str, ',');
+       if (sp != NULL) {
                if (sscanf(sp + 1, "%d", &val) != 1)
                        arg_error(arg, "Bad address format: Expected group 
tag");
                if (val < 0 || val > 0xffff)
                        arg_error(arg, "Bad address format: Group tag out of 
range");
                portal->group_tag = (uint16_t) val;
-               /* truncate source, that's the address */
                *sp = '\0';
        }
-       /* only check length, don't verify correct format (too many 
possibilities) */
+
+       /* parse and strip trailing port number */
+       sp = strchr(str, ':');
+       if (sp != NULL) {
+               if (strchr(sp + 1, ':') != NULL) {
+                       /*
+                        * if there's a second colon, assume
+                        * it's an unbracketed IPv6 address.
+                        */
+                       portal->port = 0;
+               } else {
+                       if (sscanf(sp + 1, "%d", &val) != 1)
+                               arg_error(arg, "Bad address format: Expected 
port number");
+                       if (val < 0 || val > 0xffff)
+                               arg_error(arg, "Bad address format: Port number 
out of range");
+                       portal->port = (uint16_t) val;
+                       *sp = '\0';
+               }
+       }
+
+       /* remove brackets */
+       if (*str == '[') {
+               sp = strchr(str, ']');
+               if (sp != NULL && !*(sp+1)) {
+                       str = str + 1;
+                       *sp = '\0';
+               }
+       }
+
+       /*
+        * only check length, don't verify correct format
+        * (too many possibilities)
+        */
        if (strlen(str) >= sizeof(portal->address))
                arg_error(arg, "Bad address format: Address string too long");
 

Reply via email to