Browse Source

Moved iSCSI Name validation methods to a separate class

Tal Aloni 8 years ago
parent
commit
1e7a0ad04d
3 changed files with 135 additions and 117 deletions
  1. 1 0
      ISCSIConsole/ISCSIConsole.csproj
  2. 132 0
      ISCSIConsole/ISCSINameHelper.cs
  3. 2 117
      ISCSIConsole/Program.AttachCommand.cs

+ 1 - 0
ISCSIConsole/ISCSIConsole.csproj

@@ -33,6 +33,7 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Disks\VolumeDisk.cs" />
+    <Compile Include="ISCSINameHelper.cs" />
     <Compile Include="OfflineCommand.cs" />
     <Compile Include="Program.AttachCommand.cs" />
     <Compile Include="Program.CreateCommand.cs" />

+ 132 - 0
ISCSIConsole/ISCSINameHelper.cs

@@ -0,0 +1,132 @@
+/* Copyright (C) 2012-2016 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
+ * 
+ * You can redistribute this program and/or modify it under the terms of
+ * the GNU Lesser Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ */
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Utilities;
+
+namespace ISCSIConsole
+{
+    public class ISCSINameHelper
+    {
+        /// <summary>
+        /// Check if a name is a valid initiator or target name (a.k.a. iSCSI name)
+        /// </summary>
+        public static bool IsValidISCSIName(string name)
+        {
+            if (name.ToLower().StartsWith("iqn."))
+            {
+                return IsValidIQN(name);
+            }
+            else
+            {
+                return IsValidEUI(name);
+            }
+        }
+
+        public static bool IsValidIQN(string name)
+        {
+            if (name.ToLower().StartsWith("iqn."))
+            {
+                if (name.Length > 12 && name[8] == '-' && name[11] == '.')
+                {
+                    int year = Conversion.ToInt32(name.Substring(4, 4), -1);
+                    int month = Conversion.ToInt32(name.Substring(9, 2), -1);
+                    if (year != -1 && (month >= 1 && month <= 12))
+                    {
+                        string reversedDomain;
+                        string subQualifier = String.Empty;
+                        int index = name.IndexOf(":");
+                        if (index >= 12) // index cannot be non-negative and < 12
+                        {
+                            reversedDomain = name.Substring(12, index - 12);
+                            subQualifier = name.Substring(index + 1);
+                            return IsValidReversedDomainName(reversedDomain) && IsValidSubQualifier(subQualifier);
+                        }
+                        else
+                        {
+                            reversedDomain = name.Substring(12);
+                            return IsValidReversedDomainName(reversedDomain);
+                        }
+                    }
+                }
+
+            }
+            return false;
+        }
+
+        public static bool IsValidReversedDomainName(string name)
+        {
+            string[] components = name.Split('.');
+            if (components.Length < 1)
+            {
+                return false;
+            }
+
+            foreach (string component in components)
+            {
+                if (component.Length == 0 || component.StartsWith("-") || component.EndsWith("-"))
+                {
+                    return false;
+                }
+
+                for (int index = 0; index < component.Length; index++)
+                {
+                    bool isValid = (component[index] >= '0' && component[index] <= '9') ||
+                                   (component[index] >= 'a' && component[index] <= 'z') ||
+                                   (component[index] >= 'A' && component[index] <= 'Z') ||
+                                   (component[index] == '-');
+
+                    if (!isValid)
+                    {
+                        return false;
+                    }
+                }
+            }
+            return true;
+        }
+
+        public static bool IsValidSubQualifier(string subQualifier)
+        {
+            // RFC 3720: The owner of the domain name can assign everything after the reversed domain name as desired.
+            // RFC 3720: iSCSI names are composed only of displayable characters.
+            // RFC 3720: No whitespace characters are used in iSCSI names.
+            // Note: String.Empty is a valid sub-qualifier.
+            if (subQualifier.Contains(" "))
+            {
+                return false;
+            }
+            return true;
+        }
+
+        public static bool IsValidEUI(string name)
+        {
+            if (name.ToLower().StartsWith("eui.") && name.Length == 20)
+            {
+                string identifier = name.Substring(5);
+                return OnlyHexChars(identifier);
+            }
+            return false;
+        }
+
+        public static bool OnlyHexChars(string value)
+        {
+            for (int index = 0; index < value.Length; index++)
+            {
+                bool isValid = (value[index] >= '0' && value[index] <= '9') ||
+                               (value[index] >= 'a' && value[index] <= 'f') ||
+                               (value[index] >= 'A' && value[index] <= 'F');
+
+                if (!isValid)
+                {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+}

+ 2 - 117
ISCSIConsole/Program.AttachCommand.cs

@@ -221,11 +221,11 @@ namespace ISCSIConsole
                 if (parameters.ContainsKey("target"))
                 {
                     string name = parameters.ValueOf("target");
-                    if (IsValidISCSIName(name))
+                    if (ISCSINameHelper.IsValidISCSIName(name))
                     {
                         targetName = name;
                     }
-                    else if (IsValidStorageTargetName(name))
+                    else if (ISCSINameHelper.IsValidSubQualifier(name))
                     {
                         targetName = DefaultTargetIQN + ":" + name;
                     }
@@ -274,120 +274,5 @@ namespace ISCSIConsole
             }
             return null;
         }
-
-        /// <summary>
-        /// Check if a name is a valid initiator or target name (a.k.a. iSCSI name)
-        /// </summary>
-        public static bool IsValidISCSIName(string name)
-        {
-            if (name.ToLower().StartsWith("iqn."))
-            {
-                return IsValidIQN(name);
-            }
-            else
-            {
-                return IsValidEUI(name);
-            }
-        }
-
-        public static bool IsValidIQN(string name)
-        {
-            if (name.ToLower().StartsWith("iqn."))
-            {
-                if (name.Length > 12 && name[8] == '-' && name[11] == '.')
-                {
-                    int year = Conversion.ToInt32(name.Substring(4, 4), -1);
-                    int month = Conversion.ToInt32(name.Substring(9, 2), -1);
-                    if (year != -1 && (month >= 1 && month <= 12))
-                    {
-                        string reversedDomain;
-                        string storageTargetName = String.Empty;
-                        int index = name.IndexOf(":");
-                        if (index >= 12) // index cannot be < 12
-                        {
-                            reversedDomain = name.Substring(12, index - 12);
-                            storageTargetName = name.Substring(index + 1);
-                            return IsValidReversedDomainName(reversedDomain) && IsValidStorageTargetName(storageTargetName);
-                        }
-                        else
-                        {
-                            reversedDomain = name.Substring(12);
-                            return IsValidReversedDomainName(reversedDomain);
-                        }
-                    }
-                }
-
-            }
-            return false;
-        }
-
-        public static bool IsValidReversedDomainName(string name)
-        {
-            string[] components = name.Split('.');
-            if (components.Length < 1)
-            {
-                return false;
-            }
-
-            foreach (string component in components)
-            {
-                if (component.Length == 0 || component.StartsWith("-") || component.EndsWith("-"))
-                {
-                    return false;
-                }
-
-                for (int index = 0; index < component.Length; index++)
-                {
-                    bool isValid = (component[index] >= '0' && component[index] <= '9') ||
-                                   (component[index] >= 'a' && component[index] <= 'z') ||
-                                   (component[index] >= 'A' && component[index] <= 'Z') ||
-                                   (component[index] == '-');
-
-                    if (!isValid)
-                    {
-                        return false;
-                    }
-                }
-            }
-            return true;
-        }
-
-        public static bool IsValidStorageTargetName(string name)
-        {
-            // With the exception of the colon prefix, the owner of the domain name can assign everything after the reversed domain name as desired
-            // No whitespace characters are used in iSCSI names
-            // Note: String.Empty is a valid storage target name
-            if (name.StartsWith(":") || name.Contains(" "))
-            {
-                return false;
-            }
-            return true;
-        }
-
-        public static bool IsValidEUI(string name)
-        {
-            if (name.ToLower().StartsWith("eui.") && name.Length == 20)
-            {
-                string identifier = name.Substring(5);
-                return OnlyHexChars(identifier);
-            }
-            return false;
-        }
-
-        public static bool OnlyHexChars(string value)
-        {
-            for (int index = 0; index < value.Length; index++)
-            {
-                bool isValid = (value[index] >= '0' && value[index] <= '9') ||
-                               (value[index] >= 'a' && value[index] <= 'f') ||
-                               (value[index] >= 'A' && value[index] <= 'F');
-
-                if (!isValid)
-                {
-                    return false;
-                }
-            }
-            return true;
-        }
     }
 }