1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <repcache_protocol.h> 30*7c478bd9Sstevel@tonic-gate #include "scf_type.h" 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate #include <errno.h> 33*7c478bd9Sstevel@tonic-gate #include <libgen.h> 34*7c478bd9Sstevel@tonic-gate #include <libscf_priv.h> 35*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 36*7c478bd9Sstevel@tonic-gate #include <string.h> 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate #define UTF8_TOP_N(n) \ 39*7c478bd9Sstevel@tonic-gate (0xff ^ (0xff >> (n))) /* top N bits set */ 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate #define UTF8_BOTTOM_N(n) \ 42*7c478bd9Sstevel@tonic-gate ((1 << (n)) - 1) /* bottom N bits set */ 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate /* 45*7c478bd9Sstevel@tonic-gate * The first byte of an n-byte UTF8 encoded character looks like: 46*7c478bd9Sstevel@tonic-gate * 47*7c478bd9Sstevel@tonic-gate * n bits 48*7c478bd9Sstevel@tonic-gate * 49*7c478bd9Sstevel@tonic-gate * 1 0xxxxxxx 50*7c478bd9Sstevel@tonic-gate * 2 110xxxxx 51*7c478bd9Sstevel@tonic-gate * 3 1110xxxx 52*7c478bd9Sstevel@tonic-gate * 4 11110xxx 53*7c478bd9Sstevel@tonic-gate * 5 111110xx 54*7c478bd9Sstevel@tonic-gate * 6 1111110x 55*7c478bd9Sstevel@tonic-gate * 56*7c478bd9Sstevel@tonic-gate * Continuation bytes are 01xxxxxx. 57*7c478bd9Sstevel@tonic-gate */ 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate #define UTF8_MAX_BYTES 6 60*7c478bd9Sstevel@tonic-gate 61*7c478bd9Sstevel@tonic-gate /* 62*7c478bd9Sstevel@tonic-gate * number of bits in an n-byte UTF-8 encoding. for multi-byte encodings, 63*7c478bd9Sstevel@tonic-gate * You get (7 - n) bits in the first byte, and 6 bits for each additional byte. 64*7c478bd9Sstevel@tonic-gate */ 65*7c478bd9Sstevel@tonic-gate #define UTF8_BITS(n) /* 1 <= n <= 6 */ \ 66*7c478bd9Sstevel@tonic-gate ((n) == 1)? 7 : \ 67*7c478bd9Sstevel@tonic-gate (7 - (n) + 6 * ((n) - 1)) 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate #define UTF8_SINGLE_BYTE(c) \ 70*7c478bd9Sstevel@tonic-gate (((c) & UTF8_TOP_N(1)) == 0) /* 0xxxxxxx */ 71*7c478bd9Sstevel@tonic-gate 72*7c478bd9Sstevel@tonic-gate #define UTF8_HEAD_CHECK(c, n) /* 2 <= n <= 6 */ \ 73*7c478bd9Sstevel@tonic-gate (((c) & UTF8_TOP_N((n) + 1)) == UTF8_TOP_N(n)) 74*7c478bd9Sstevel@tonic-gate 75*7c478bd9Sstevel@tonic-gate #define UTF8_HEAD_VALUE(c, n) /* 2 <= n <= 6 */ \ 76*7c478bd9Sstevel@tonic-gate ((c) & UTF8_BOTTOM_N(7 - (n))) /* 'x' mask */ 77*7c478bd9Sstevel@tonic-gate 78*7c478bd9Sstevel@tonic-gate #define UTF8_CONT_CHECK(c) \ 79*7c478bd9Sstevel@tonic-gate (((c) & UTF8_TOP_N(2)) == UTF8_TOP_N(1)) /* 10xxxxxx */ 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate /* 82*7c478bd9Sstevel@tonic-gate * adds in the 6 new bits from a continuation byte 83*7c478bd9Sstevel@tonic-gate */ 84*7c478bd9Sstevel@tonic-gate #define UTF8_VALUE_UPDATE(v, c) \ 85*7c478bd9Sstevel@tonic-gate (((v) << 6) | ((c) & UTF8_BOTTOM_N(6))) 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate /* 88*7c478bd9Sstevel@tonic-gate * URI components 89*7c478bd9Sstevel@tonic-gate */ 90*7c478bd9Sstevel@tonic-gate 91*7c478bd9Sstevel@tonic-gate #define URI_COMPONENT_COUNT 5 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate enum { 94*7c478bd9Sstevel@tonic-gate URI_SCHEME = 0x0, /* URI scheme */ 95*7c478bd9Sstevel@tonic-gate URI_AUTHORITY, /* URI authority */ 96*7c478bd9Sstevel@tonic-gate URI_PATH, /* URI path */ 97*7c478bd9Sstevel@tonic-gate URI_QUERY, /* URI query */ 98*7c478bd9Sstevel@tonic-gate URI_FRAGMENT /* URI fragment */ 99*7c478bd9Sstevel@tonic-gate }; 100*7c478bd9Sstevel@tonic-gate 101*7c478bd9Sstevel@tonic-gate static int 102*7c478bd9Sstevel@tonic-gate valid_utf8(const char *str_arg) 103*7c478bd9Sstevel@tonic-gate { 104*7c478bd9Sstevel@tonic-gate const char *str = str_arg; 105*7c478bd9Sstevel@tonic-gate uint_t c; 106*7c478bd9Sstevel@tonic-gate uint32_t v; 107*7c478bd9Sstevel@tonic-gate int i, n; 108*7c478bd9Sstevel@tonic-gate 109*7c478bd9Sstevel@tonic-gate while ((c = *str++) != 0) { 110*7c478bd9Sstevel@tonic-gate if (UTF8_SINGLE_BYTE(c)) 111*7c478bd9Sstevel@tonic-gate continue; /* ascii */ 112*7c478bd9Sstevel@tonic-gate 113*7c478bd9Sstevel@tonic-gate for (n = 2; n <= UTF8_MAX_BYTES; n++) 114*7c478bd9Sstevel@tonic-gate if (UTF8_HEAD_CHECK(c, n)) 115*7c478bd9Sstevel@tonic-gate break; 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate if (n > UTF8_MAX_BYTES) 118*7c478bd9Sstevel@tonic-gate return (0); /* invalid head byte */ 119*7c478bd9Sstevel@tonic-gate 120*7c478bd9Sstevel@tonic-gate v = UTF8_HEAD_VALUE(c, n); 121*7c478bd9Sstevel@tonic-gate 122*7c478bd9Sstevel@tonic-gate for (i = 1; i < n; i++) { 123*7c478bd9Sstevel@tonic-gate c = *str++; 124*7c478bd9Sstevel@tonic-gate if (!UTF8_CONT_CHECK(c)) 125*7c478bd9Sstevel@tonic-gate return (0); /* invalid byte */ 126*7c478bd9Sstevel@tonic-gate 127*7c478bd9Sstevel@tonic-gate v = UTF8_VALUE_UPDATE(v, c); 128*7c478bd9Sstevel@tonic-gate } 129*7c478bd9Sstevel@tonic-gate 130*7c478bd9Sstevel@tonic-gate /* 131*7c478bd9Sstevel@tonic-gate * if v could have been encoded in the next smallest 132*7c478bd9Sstevel@tonic-gate * encoding, the string is not well-formed UTF-8. 133*7c478bd9Sstevel@tonic-gate */ 134*7c478bd9Sstevel@tonic-gate if ((v >> (UTF8_BITS(n - 1))) == 0) 135*7c478bd9Sstevel@tonic-gate return (0); 136*7c478bd9Sstevel@tonic-gate } 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate /* 139*7c478bd9Sstevel@tonic-gate * we've reached the end of the string -- make sure it is short enough 140*7c478bd9Sstevel@tonic-gate */ 141*7c478bd9Sstevel@tonic-gate return ((str - str_arg) < REP_PROTOCOL_VALUE_LEN); 142*7c478bd9Sstevel@tonic-gate } 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate static int 145*7c478bd9Sstevel@tonic-gate valid_string(const char *str) 146*7c478bd9Sstevel@tonic-gate { 147*7c478bd9Sstevel@tonic-gate return (strlen(str) < REP_PROTOCOL_VALUE_LEN); 148*7c478bd9Sstevel@tonic-gate } 149*7c478bd9Sstevel@tonic-gate 150*7c478bd9Sstevel@tonic-gate static int 151*7c478bd9Sstevel@tonic-gate valid_opaque(const char *str_arg) 152*7c478bd9Sstevel@tonic-gate { 153*7c478bd9Sstevel@tonic-gate const char *str = str_arg; 154*7c478bd9Sstevel@tonic-gate uint_t c; 155*7c478bd9Sstevel@tonic-gate ptrdiff_t len; 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate while ((c = *str++) != 0) 158*7c478bd9Sstevel@tonic-gate if ((c < '0' || c > '9') && (c < 'a' || c > 'f') && 159*7c478bd9Sstevel@tonic-gate (c < 'A' || c > 'F')) 160*7c478bd9Sstevel@tonic-gate return (0); /* not hex digit */ 161*7c478bd9Sstevel@tonic-gate 162*7c478bd9Sstevel@tonic-gate len = (str - str_arg) - 1; /* not counting NIL byte */ 163*7c478bd9Sstevel@tonic-gate return ((len % 2) == 0 && len / 2 < REP_PROTOCOL_VALUE_LEN); 164*7c478bd9Sstevel@tonic-gate } 165*7c478bd9Sstevel@tonic-gate 166*7c478bd9Sstevel@tonic-gate /* 167*7c478bd9Sstevel@tonic-gate * Return 1 if the supplied parameter is a conformant URI (as defined 168*7c478bd9Sstevel@tonic-gate * by RFC 2396), 0 otherwise. 169*7c478bd9Sstevel@tonic-gate */ 170*7c478bd9Sstevel@tonic-gate static int 171*7c478bd9Sstevel@tonic-gate valid_uri(const char *str) 172*7c478bd9Sstevel@tonic-gate { 173*7c478bd9Sstevel@tonic-gate /* 174*7c478bd9Sstevel@tonic-gate * URI Regular Expression. Compiled with regcmp(1). 175*7c478bd9Sstevel@tonic-gate * 176*7c478bd9Sstevel@tonic-gate * ^(([^:/?#]+:){0,1})$0(//([^/?#]*)$1){0,1}([^?#]*)$2 177*7c478bd9Sstevel@tonic-gate * (?([^#]*)$3){0,1}(#(.*)$4){0,1} 178*7c478bd9Sstevel@tonic-gate */ 179*7c478bd9Sstevel@tonic-gate char exp[] = { 180*7c478bd9Sstevel@tonic-gate 040, 074, 00, 060, 012, 0126, 05, 072, 057, 077, 043, 024, 181*7c478bd9Sstevel@tonic-gate 072, 057, 00, 00, 01, 014, 00, 00, 060, 020, 024, 057, 182*7c478bd9Sstevel@tonic-gate 024, 057, 074, 01, 0125, 04, 057, 077, 043, 014, 01, 01, 183*7c478bd9Sstevel@tonic-gate 057, 01, 00, 01, 074, 02, 0125, 03, 077, 043, 014, 02, 184*7c478bd9Sstevel@tonic-gate 02, 060, 014, 024, 077, 074, 03, 0125, 02, 043, 014, 03, 185*7c478bd9Sstevel@tonic-gate 03, 057, 02, 00, 01, 060, 012, 024, 043, 074, 04, 021, 186*7c478bd9Sstevel@tonic-gate 014, 04, 04, 057, 03, 00, 01, 064, 00, 187*7c478bd9Sstevel@tonic-gate 0}; 188*7c478bd9Sstevel@tonic-gate char uri[URI_COMPONENT_COUNT][REP_PROTOCOL_VALUE_LEN]; 189*7c478bd9Sstevel@tonic-gate 190*7c478bd9Sstevel@tonic-gate /* 191*7c478bd9Sstevel@tonic-gate * If the string is too long, then the URI cannot be valid. Also, 192*7c478bd9Sstevel@tonic-gate * this protects against buffer overflow attacks on the uri array. 193*7c478bd9Sstevel@tonic-gate */ 194*7c478bd9Sstevel@tonic-gate if (strlen(str) >= REP_PROTOCOL_VALUE_LEN) 195*7c478bd9Sstevel@tonic-gate return (0); 196*7c478bd9Sstevel@tonic-gate 197*7c478bd9Sstevel@tonic-gate if (regex(exp, str, uri[URI_SCHEME], uri[URI_AUTHORITY], uri[URI_PATH], 198*7c478bd9Sstevel@tonic-gate uri[URI_QUERY], uri[URI_FRAGMENT]) == NULL) { 199*7c478bd9Sstevel@tonic-gate return (0); 200*7c478bd9Sstevel@tonic-gate } 201*7c478bd9Sstevel@tonic-gate /* 202*7c478bd9Sstevel@tonic-gate * To be a valid URI, the length of the URI_PATH must not be zero 203*7c478bd9Sstevel@tonic-gate */ 204*7c478bd9Sstevel@tonic-gate if (strlen(uri[URI_PATH]) == 0) { 205*7c478bd9Sstevel@tonic-gate return (0); 206*7c478bd9Sstevel@tonic-gate } 207*7c478bd9Sstevel@tonic-gate return (1); 208*7c478bd9Sstevel@tonic-gate } 209*7c478bd9Sstevel@tonic-gate 210*7c478bd9Sstevel@tonic-gate /* 211*7c478bd9Sstevel@tonic-gate * Return 1 if the supplied parameter is a conformant fmri, 0 212*7c478bd9Sstevel@tonic-gate * otherwise. 213*7c478bd9Sstevel@tonic-gate */ 214*7c478bd9Sstevel@tonic-gate static int 215*7c478bd9Sstevel@tonic-gate valid_fmri(const char *str) 216*7c478bd9Sstevel@tonic-gate { 217*7c478bd9Sstevel@tonic-gate int ret; 218*7c478bd9Sstevel@tonic-gate char fmri[REP_PROTOCOL_VALUE_LEN] = { 0 }; 219*7c478bd9Sstevel@tonic-gate 220*7c478bd9Sstevel@tonic-gate /* 221*7c478bd9Sstevel@tonic-gate * Try to parse the fmri, if we can parse it then it 222*7c478bd9Sstevel@tonic-gate * must be syntactically correct. Work on a copy of 223*7c478bd9Sstevel@tonic-gate * the fmri since the parsing process can modify the 224*7c478bd9Sstevel@tonic-gate * supplied string. 225*7c478bd9Sstevel@tonic-gate */ 226*7c478bd9Sstevel@tonic-gate if (strlcpy(fmri, str, sizeof (fmri)) >= sizeof (fmri)) 227*7c478bd9Sstevel@tonic-gate return (0); 228*7c478bd9Sstevel@tonic-gate 229*7c478bd9Sstevel@tonic-gate ret = ! scf_parse_fmri(fmri, NULL, NULL, NULL, NULL, NULL, NULL); 230*7c478bd9Sstevel@tonic-gate 231*7c478bd9Sstevel@tonic-gate return (ret); 232*7c478bd9Sstevel@tonic-gate } 233*7c478bd9Sstevel@tonic-gate 234*7c478bd9Sstevel@tonic-gate rep_protocol_value_type_t 235*7c478bd9Sstevel@tonic-gate scf_proto_underlying_type(rep_protocol_value_type_t t) 236*7c478bd9Sstevel@tonic-gate { 237*7c478bd9Sstevel@tonic-gate switch (t) { 238*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_BOOLEAN: 239*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_COUNT: 240*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_INTEGER: 241*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_TIME: 242*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_STRING: 243*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_OPAQUE: 244*7c478bd9Sstevel@tonic-gate return (t); 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_USTRING: 247*7c478bd9Sstevel@tonic-gate return (REP_PROTOCOL_TYPE_STRING); 248*7c478bd9Sstevel@tonic-gate 249*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_URI: 250*7c478bd9Sstevel@tonic-gate return (REP_PROTOCOL_SUBTYPE_USTRING); 251*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_FMRI: 252*7c478bd9Sstevel@tonic-gate return (REP_PROTOCOL_SUBTYPE_URI); 253*7c478bd9Sstevel@tonic-gate 254*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_HOST: 255*7c478bd9Sstevel@tonic-gate return (REP_PROTOCOL_SUBTYPE_USTRING); 256*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_HOSTNAME: 257*7c478bd9Sstevel@tonic-gate return (REP_PROTOCOL_SUBTYPE_HOST); 258*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_NETADDR_V4: 259*7c478bd9Sstevel@tonic-gate return (REP_PROTOCOL_SUBTYPE_HOST); 260*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_NETADDR_V6: 261*7c478bd9Sstevel@tonic-gate return (REP_PROTOCOL_SUBTYPE_HOST); 262*7c478bd9Sstevel@tonic-gate 263*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_INVALID: 264*7c478bd9Sstevel@tonic-gate default: 265*7c478bd9Sstevel@tonic-gate return (REP_PROTOCOL_TYPE_INVALID); 266*7c478bd9Sstevel@tonic-gate } 267*7c478bd9Sstevel@tonic-gate } 268*7c478bd9Sstevel@tonic-gate 269*7c478bd9Sstevel@tonic-gate int 270*7c478bd9Sstevel@tonic-gate scf_is_compatible_type(rep_protocol_value_type_t base, 271*7c478bd9Sstevel@tonic-gate rep_protocol_value_type_t new) 272*7c478bd9Sstevel@tonic-gate { 273*7c478bd9Sstevel@tonic-gate rep_protocol_value_type_t t, cur; 274*7c478bd9Sstevel@tonic-gate 275*7c478bd9Sstevel@tonic-gate if (base == REP_PROTOCOL_TYPE_INVALID) 276*7c478bd9Sstevel@tonic-gate return (0); 277*7c478bd9Sstevel@tonic-gate 278*7c478bd9Sstevel@tonic-gate if (base == new) 279*7c478bd9Sstevel@tonic-gate return (1); 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate for (t = new; t != (cur = scf_proto_underlying_type(t)); t = cur) { 282*7c478bd9Sstevel@tonic-gate if (cur == REP_PROTOCOL_TYPE_INVALID) 283*7c478bd9Sstevel@tonic-gate return (0); 284*7c478bd9Sstevel@tonic-gate if (cur == base) 285*7c478bd9Sstevel@tonic-gate return (1); /* base is parent of new */ 286*7c478bd9Sstevel@tonic-gate } 287*7c478bd9Sstevel@tonic-gate return (0); 288*7c478bd9Sstevel@tonic-gate } 289*7c478bd9Sstevel@tonic-gate 290*7c478bd9Sstevel@tonic-gate static int 291*7c478bd9Sstevel@tonic-gate valid_encoded_value(rep_protocol_value_type_t t, const char *v) 292*7c478bd9Sstevel@tonic-gate { 293*7c478bd9Sstevel@tonic-gate char *p; 294*7c478bd9Sstevel@tonic-gate ulong_t ns; 295*7c478bd9Sstevel@tonic-gate 296*7c478bd9Sstevel@tonic-gate switch (t) { 297*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_BOOLEAN: 298*7c478bd9Sstevel@tonic-gate return ((*v == '0' || *v == '1') && v[1] == 0); 299*7c478bd9Sstevel@tonic-gate 300*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_COUNT: 301*7c478bd9Sstevel@tonic-gate errno = 0; 302*7c478bd9Sstevel@tonic-gate if (strtoull(v, &p, 10) != 0 && *v == '0') 303*7c478bd9Sstevel@tonic-gate return (0); 304*7c478bd9Sstevel@tonic-gate return (errno == 0 && p != v && *p == 0); 305*7c478bd9Sstevel@tonic-gate 306*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_INTEGER: 307*7c478bd9Sstevel@tonic-gate errno = 0; 308*7c478bd9Sstevel@tonic-gate if (strtoll(v, &p, 10) != 0 && *v == '0') 309*7c478bd9Sstevel@tonic-gate return (0); 310*7c478bd9Sstevel@tonic-gate return (errno == 0 && p != v && *p == 0); 311*7c478bd9Sstevel@tonic-gate 312*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_TIME: 313*7c478bd9Sstevel@tonic-gate errno = 0; 314*7c478bd9Sstevel@tonic-gate (void) strtoll(v, &p, 10); 315*7c478bd9Sstevel@tonic-gate if (errno != 0 || p == v || (*p != 0 && *p != '.')) 316*7c478bd9Sstevel@tonic-gate return (0); 317*7c478bd9Sstevel@tonic-gate if (*p == '.') { 318*7c478bd9Sstevel@tonic-gate v = p + 1; 319*7c478bd9Sstevel@tonic-gate errno = 0; 320*7c478bd9Sstevel@tonic-gate ns = strtoul(v, &p, 10); 321*7c478bd9Sstevel@tonic-gate 322*7c478bd9Sstevel@tonic-gate /* must be exactly 9 digits */ 323*7c478bd9Sstevel@tonic-gate if ((p - v) != 9 || errno != 0 || *p != 0) 324*7c478bd9Sstevel@tonic-gate return (0); 325*7c478bd9Sstevel@tonic-gate if (ns >= NANOSEC) 326*7c478bd9Sstevel@tonic-gate return (0); 327*7c478bd9Sstevel@tonic-gate } 328*7c478bd9Sstevel@tonic-gate return (1); 329*7c478bd9Sstevel@tonic-gate 330*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_STRING: 331*7c478bd9Sstevel@tonic-gate return (valid_string(v)); 332*7c478bd9Sstevel@tonic-gate 333*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_OPAQUE: 334*7c478bd9Sstevel@tonic-gate return (valid_opaque(v)); 335*7c478bd9Sstevel@tonic-gate 336*7c478bd9Sstevel@tonic-gate /* 337*7c478bd9Sstevel@tonic-gate * The remaining types are subtypes -- because of the way 338*7c478bd9Sstevel@tonic-gate * scf_validate_encoded_value() works, we can rely on the fact 339*7c478bd9Sstevel@tonic-gate * that v is a valid example of our base type. We only have to 340*7c478bd9Sstevel@tonic-gate * check our own additional restrictions. 341*7c478bd9Sstevel@tonic-gate */ 342*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_USTRING: 343*7c478bd9Sstevel@tonic-gate return (valid_utf8(v)); 344*7c478bd9Sstevel@tonic-gate 345*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_URI: 346*7c478bd9Sstevel@tonic-gate return (valid_uri(v)); 347*7c478bd9Sstevel@tonic-gate 348*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_FMRI: 349*7c478bd9Sstevel@tonic-gate return (valid_fmri(v)); 350*7c478bd9Sstevel@tonic-gate 351*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_HOST: 352*7c478bd9Sstevel@tonic-gate return (valid_encoded_value(REP_PROTOCOL_SUBTYPE_HOSTNAME, v) || 353*7c478bd9Sstevel@tonic-gate valid_encoded_value(REP_PROTOCOL_SUBTYPE_NETADDR_V4, v) || 354*7c478bd9Sstevel@tonic-gate valid_encoded_value(REP_PROTOCOL_SUBTYPE_NETADDR_V6, v)); 355*7c478bd9Sstevel@tonic-gate 356*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_HOSTNAME: 357*7c478bd9Sstevel@tonic-gate /* XXX check for valid hostname */ 358*7c478bd9Sstevel@tonic-gate return (valid_utf8(v)); 359*7c478bd9Sstevel@tonic-gate 360*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_NETADDR_V4: 361*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_NETADDR_V6: 362*7c478bd9Sstevel@tonic-gate /* XXX check for valid netaddr */ 363*7c478bd9Sstevel@tonic-gate return (valid_utf8(v)); 364*7c478bd9Sstevel@tonic-gate 365*7c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_INVALID: 366*7c478bd9Sstevel@tonic-gate default: 367*7c478bd9Sstevel@tonic-gate return (0); 368*7c478bd9Sstevel@tonic-gate } 369*7c478bd9Sstevel@tonic-gate } 370*7c478bd9Sstevel@tonic-gate 371*7c478bd9Sstevel@tonic-gate int 372*7c478bd9Sstevel@tonic-gate scf_validate_encoded_value(rep_protocol_value_type_t t, const char *v) 373*7c478bd9Sstevel@tonic-gate { 374*7c478bd9Sstevel@tonic-gate rep_protocol_value_type_t base, cur; 375*7c478bd9Sstevel@tonic-gate 376*7c478bd9Sstevel@tonic-gate base = scf_proto_underlying_type(t); 377*7c478bd9Sstevel@tonic-gate while ((cur = scf_proto_underlying_type(base)) != base) 378*7c478bd9Sstevel@tonic-gate base = cur; 379*7c478bd9Sstevel@tonic-gate 380*7c478bd9Sstevel@tonic-gate if (base != t && !valid_encoded_value(base, v)) 381*7c478bd9Sstevel@tonic-gate return (0); 382*7c478bd9Sstevel@tonic-gate 383*7c478bd9Sstevel@tonic-gate return (valid_encoded_value(t, v)); 384*7c478bd9Sstevel@tonic-gate } 385