163783933SJohn Baldwin /*- 24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 363783933SJohn Baldwin * 463783933SJohn Baldwin * Copyright (c) 2012 The FreeBSD Foundation 563783933SJohn Baldwin * 663783933SJohn Baldwin * This software was developed by Edward Tomasz Napierala under sponsorship 763783933SJohn Baldwin * from the FreeBSD Foundation. 863783933SJohn Baldwin * 963783933SJohn Baldwin * Redistribution and use in source and binary forms, with or without 1063783933SJohn Baldwin * modification, are permitted provided that the following conditions 1163783933SJohn Baldwin * are met: 1263783933SJohn Baldwin * 1. Redistributions of source code must retain the above copyright 1363783933SJohn Baldwin * notice, this list of conditions and the following disclaimer. 1463783933SJohn Baldwin * 2. Redistributions in binary form must reproduce the above copyright 1563783933SJohn Baldwin * notice, this list of conditions and the following disclaimer in the 1663783933SJohn Baldwin * documentation and/or other materials provided with the distribution. 1763783933SJohn Baldwin * 1863783933SJohn Baldwin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1963783933SJohn Baldwin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2063783933SJohn Baldwin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2163783933SJohn Baldwin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2263783933SJohn Baldwin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2363783933SJohn Baldwin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2463783933SJohn Baldwin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2563783933SJohn Baldwin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2663783933SJohn Baldwin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2763783933SJohn Baldwin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2863783933SJohn Baldwin * SUCH DAMAGE. 2963783933SJohn Baldwin */ 3063783933SJohn Baldwin 31*dd360374SJohn Baldwin #include <ctype.h> 3263783933SJohn Baldwin #include <string.h> 3363783933SJohn Baldwin 3463783933SJohn Baldwin #include "libiscsiutil.h" 3563783933SJohn Baldwin 36*dd360374SJohn Baldwin #define MAX_NAME_LEN 223 37*dd360374SJohn Baldwin 3863783933SJohn Baldwin char * 3963783933SJohn Baldwin checked_strdup(const char *s) 4063783933SJohn Baldwin { 4163783933SJohn Baldwin char *c; 4263783933SJohn Baldwin 4363783933SJohn Baldwin c = strdup(s); 4463783933SJohn Baldwin if (c == NULL) 4563783933SJohn Baldwin log_err(1, "strdup"); 4663783933SJohn Baldwin return (c); 4763783933SJohn Baldwin } 48*dd360374SJohn Baldwin 49*dd360374SJohn Baldwin bool 50*dd360374SJohn Baldwin valid_iscsi_name(const char *name, void (*warn_fn)(const char *, ...)) 51*dd360374SJohn Baldwin { 52*dd360374SJohn Baldwin int i; 53*dd360374SJohn Baldwin 54*dd360374SJohn Baldwin if (strlen(name) >= MAX_NAME_LEN) { 55*dd360374SJohn Baldwin warn_fn("overlong name for target \"%s\"; max length allowed " 56*dd360374SJohn Baldwin "by iSCSI specification is %d characters", 57*dd360374SJohn Baldwin name, MAX_NAME_LEN); 58*dd360374SJohn Baldwin return (false); 59*dd360374SJohn Baldwin } 60*dd360374SJohn Baldwin 61*dd360374SJohn Baldwin /* 62*dd360374SJohn Baldwin * In the cases below, we don't return an error, just in case the admin 63*dd360374SJohn Baldwin * was right, and we're wrong. 64*dd360374SJohn Baldwin */ 65*dd360374SJohn Baldwin if (strncasecmp(name, "iqn.", strlen("iqn.")) == 0) { 66*dd360374SJohn Baldwin for (i = strlen("iqn."); name[i] != '\0'; i++) { 67*dd360374SJohn Baldwin /* 68*dd360374SJohn Baldwin * XXX: We should verify UTF-8 normalisation, as defined 69*dd360374SJohn Baldwin * by 3.2.6.2: iSCSI Name Encoding. 70*dd360374SJohn Baldwin */ 71*dd360374SJohn Baldwin if (isalnum(name[i])) 72*dd360374SJohn Baldwin continue; 73*dd360374SJohn Baldwin if (name[i] == '-' || name[i] == '.' || name[i] == ':') 74*dd360374SJohn Baldwin continue; 75*dd360374SJohn Baldwin warn_fn("invalid character \"%c\" in target name " 76*dd360374SJohn Baldwin "\"%s\"; allowed characters are letters, digits, " 77*dd360374SJohn Baldwin "'-', '.', and ':'", name[i], name); 78*dd360374SJohn Baldwin break; 79*dd360374SJohn Baldwin } 80*dd360374SJohn Baldwin /* 81*dd360374SJohn Baldwin * XXX: Check more stuff: valid date and a valid reversed domain. 82*dd360374SJohn Baldwin */ 83*dd360374SJohn Baldwin } else if (strncasecmp(name, "eui.", strlen("eui.")) == 0) { 84*dd360374SJohn Baldwin if (strlen(name) != strlen("eui.") + 16) 85*dd360374SJohn Baldwin warn_fn("invalid target name \"%s\"; the \"eui.\" " 86*dd360374SJohn Baldwin "should be followed by exactly 16 hexadecimal " 87*dd360374SJohn Baldwin "digits", name); 88*dd360374SJohn Baldwin for (i = strlen("eui."); name[i] != '\0'; i++) { 89*dd360374SJohn Baldwin if (!isxdigit(name[i])) { 90*dd360374SJohn Baldwin warn_fn("invalid character \"%c\" in target " 91*dd360374SJohn Baldwin "name \"%s\"; allowed characters are 1-9 " 92*dd360374SJohn Baldwin "and A-F", name[i], name); 93*dd360374SJohn Baldwin break; 94*dd360374SJohn Baldwin } 95*dd360374SJohn Baldwin } 96*dd360374SJohn Baldwin } else if (strncasecmp(name, "naa.", strlen("naa.")) == 0) { 97*dd360374SJohn Baldwin if (strlen(name) > strlen("naa.") + 32) 98*dd360374SJohn Baldwin warn_fn("invalid target name \"%s\"; the \"naa.\" " 99*dd360374SJohn Baldwin "should be followed by at most 32 hexadecimal " 100*dd360374SJohn Baldwin "digits", name); 101*dd360374SJohn Baldwin for (i = strlen("naa."); name[i] != '\0'; i++) { 102*dd360374SJohn Baldwin if (!isxdigit(name[i])) { 103*dd360374SJohn Baldwin warn_fn("invalid character \"%c\" in target " 104*dd360374SJohn Baldwin "name \"%s\"; allowed characters are 1-9 " 105*dd360374SJohn Baldwin "and A-F", name[i], name); 106*dd360374SJohn Baldwin break; 107*dd360374SJohn Baldwin } 108*dd360374SJohn Baldwin } 109*dd360374SJohn Baldwin } else { 110*dd360374SJohn Baldwin warn_fn("invalid target name \"%s\"; should start with " 111*dd360374SJohn Baldwin "either \"iqn.\", \"eui.\", or \"naa.\"", 112*dd360374SJohn Baldwin name); 113*dd360374SJohn Baldwin } 114*dd360374SJohn Baldwin return (true); 115*dd360374SJohn Baldwin } 116