17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5a574db85Sraf * Common Development and Distribution License (the "License"). 6a574db85Sraf * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 21a574db85Sraf 227c478bd9Sstevel@tonic-gate /* 23*870ad75aSSean Wilcox * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #include <repcache_protocol.h> 287c478bd9Sstevel@tonic-gate #include "scf_type.h" 297c478bd9Sstevel@tonic-gate #include <errno.h> 307c478bd9Sstevel@tonic-gate #include <libgen.h> 317c478bd9Sstevel@tonic-gate #include <libscf_priv.h> 327c478bd9Sstevel@tonic-gate #include <stdlib.h> 337c478bd9Sstevel@tonic-gate #include <string.h> 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate #define UTF8_TOP_N(n) \ 367c478bd9Sstevel@tonic-gate (0xff ^ (0xff >> (n))) /* top N bits set */ 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate #define UTF8_BOTTOM_N(n) \ 397c478bd9Sstevel@tonic-gate ((1 << (n)) - 1) /* bottom N bits set */ 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate /* 427c478bd9Sstevel@tonic-gate * The first byte of an n-byte UTF8 encoded character looks like: 437c478bd9Sstevel@tonic-gate * 447c478bd9Sstevel@tonic-gate * n bits 457c478bd9Sstevel@tonic-gate * 467c478bd9Sstevel@tonic-gate * 1 0xxxxxxx 477c478bd9Sstevel@tonic-gate * 2 110xxxxx 487c478bd9Sstevel@tonic-gate * 3 1110xxxx 497c478bd9Sstevel@tonic-gate * 4 11110xxx 507c478bd9Sstevel@tonic-gate * 5 111110xx 517c478bd9Sstevel@tonic-gate * 6 1111110x 527c478bd9Sstevel@tonic-gate * 537c478bd9Sstevel@tonic-gate * Continuation bytes are 01xxxxxx. 547c478bd9Sstevel@tonic-gate */ 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate #define UTF8_MAX_BYTES 6 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate /* 597c478bd9Sstevel@tonic-gate * number of bits in an n-byte UTF-8 encoding. for multi-byte encodings, 607c478bd9Sstevel@tonic-gate * You get (7 - n) bits in the first byte, and 6 bits for each additional byte. 617c478bd9Sstevel@tonic-gate */ 627c478bd9Sstevel@tonic-gate #define UTF8_BITS(n) /* 1 <= n <= 6 */ \ 637c478bd9Sstevel@tonic-gate ((n) == 1)? 7 : \ 647c478bd9Sstevel@tonic-gate (7 - (n) + 6 * ((n) - 1)) 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate #define UTF8_SINGLE_BYTE(c) \ 677c478bd9Sstevel@tonic-gate (((c) & UTF8_TOP_N(1)) == 0) /* 0xxxxxxx */ 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate #define UTF8_HEAD_CHECK(c, n) /* 2 <= n <= 6 */ \ 707c478bd9Sstevel@tonic-gate (((c) & UTF8_TOP_N((n) + 1)) == UTF8_TOP_N(n)) 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate #define UTF8_HEAD_VALUE(c, n) /* 2 <= n <= 6 */ \ 737c478bd9Sstevel@tonic-gate ((c) & UTF8_BOTTOM_N(7 - (n))) /* 'x' mask */ 747c478bd9Sstevel@tonic-gate 757c478bd9Sstevel@tonic-gate #define UTF8_CONT_CHECK(c) \ 767c478bd9Sstevel@tonic-gate (((c) & UTF8_TOP_N(2)) == UTF8_TOP_N(1)) /* 10xxxxxx */ 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate /* 797c478bd9Sstevel@tonic-gate * adds in the 6 new bits from a continuation byte 807c478bd9Sstevel@tonic-gate */ 817c478bd9Sstevel@tonic-gate #define UTF8_VALUE_UPDATE(v, c) \ 827c478bd9Sstevel@tonic-gate (((v) << 6) | ((c) & UTF8_BOTTOM_N(6))) 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate /* 857c478bd9Sstevel@tonic-gate * URI components 867c478bd9Sstevel@tonic-gate */ 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate #define URI_COMPONENT_COUNT 5 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate enum { 917c478bd9Sstevel@tonic-gate URI_SCHEME = 0x0, /* URI scheme */ 927c478bd9Sstevel@tonic-gate URI_AUTHORITY, /* URI authority */ 937c478bd9Sstevel@tonic-gate URI_PATH, /* URI path */ 947c478bd9Sstevel@tonic-gate URI_QUERY, /* URI query */ 957c478bd9Sstevel@tonic-gate URI_FRAGMENT /* URI fragment */ 967c478bd9Sstevel@tonic-gate }; 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate static int 997c478bd9Sstevel@tonic-gate valid_utf8(const char *str_arg) 1007c478bd9Sstevel@tonic-gate { 1017c478bd9Sstevel@tonic-gate const char *str = str_arg; 1027c478bd9Sstevel@tonic-gate uint_t c; 1037c478bd9Sstevel@tonic-gate uint32_t v; 1047c478bd9Sstevel@tonic-gate int i, n; 1057c478bd9Sstevel@tonic-gate 1067c478bd9Sstevel@tonic-gate while ((c = *str++) != 0) { 1077c478bd9Sstevel@tonic-gate if (UTF8_SINGLE_BYTE(c)) 1087c478bd9Sstevel@tonic-gate continue; /* ascii */ 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate for (n = 2; n <= UTF8_MAX_BYTES; n++) 1117c478bd9Sstevel@tonic-gate if (UTF8_HEAD_CHECK(c, n)) 1127c478bd9Sstevel@tonic-gate break; 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate if (n > UTF8_MAX_BYTES) 1157c478bd9Sstevel@tonic-gate return (0); /* invalid head byte */ 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate v = UTF8_HEAD_VALUE(c, n); 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate for (i = 1; i < n; i++) { 1207c478bd9Sstevel@tonic-gate c = *str++; 1217c478bd9Sstevel@tonic-gate if (!UTF8_CONT_CHECK(c)) 1227c478bd9Sstevel@tonic-gate return (0); /* invalid byte */ 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate v = UTF8_VALUE_UPDATE(v, c); 1257c478bd9Sstevel@tonic-gate } 1267c478bd9Sstevel@tonic-gate 1277c478bd9Sstevel@tonic-gate /* 1287c478bd9Sstevel@tonic-gate * if v could have been encoded in the next smallest 1297c478bd9Sstevel@tonic-gate * encoding, the string is not well-formed UTF-8. 1307c478bd9Sstevel@tonic-gate */ 1317c478bd9Sstevel@tonic-gate if ((v >> (UTF8_BITS(n - 1))) == 0) 1327c478bd9Sstevel@tonic-gate return (0); 1337c478bd9Sstevel@tonic-gate } 1347c478bd9Sstevel@tonic-gate 1357c478bd9Sstevel@tonic-gate /* 1367c478bd9Sstevel@tonic-gate * we've reached the end of the string -- make sure it is short enough 1377c478bd9Sstevel@tonic-gate */ 1387c478bd9Sstevel@tonic-gate return ((str - str_arg) < REP_PROTOCOL_VALUE_LEN); 1397c478bd9Sstevel@tonic-gate } 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate static int 1427c478bd9Sstevel@tonic-gate valid_string(const char *str) 1437c478bd9Sstevel@tonic-gate { 1447c478bd9Sstevel@tonic-gate return (strlen(str) < REP_PROTOCOL_VALUE_LEN); 1457c478bd9Sstevel@tonic-gate } 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate static int 1487c478bd9Sstevel@tonic-gate valid_opaque(const char *str_arg) 1497c478bd9Sstevel@tonic-gate { 1507c478bd9Sstevel@tonic-gate const char *str = str_arg; 1517c478bd9Sstevel@tonic-gate uint_t c; 1527c478bd9Sstevel@tonic-gate ptrdiff_t len; 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate while ((c = *str++) != 0) 1557c478bd9Sstevel@tonic-gate if ((c < '0' || c > '9') && (c < 'a' || c > 'f') && 1567c478bd9Sstevel@tonic-gate (c < 'A' || c > 'F')) 1577c478bd9Sstevel@tonic-gate return (0); /* not hex digit */ 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate len = (str - str_arg) - 1; /* not counting NIL byte */ 1607c478bd9Sstevel@tonic-gate return ((len % 2) == 0 && len / 2 < REP_PROTOCOL_VALUE_LEN); 1617c478bd9Sstevel@tonic-gate } 1627c478bd9Sstevel@tonic-gate 1637c478bd9Sstevel@tonic-gate /* 1647c478bd9Sstevel@tonic-gate * Return 1 if the supplied parameter is a conformant URI (as defined 1657c478bd9Sstevel@tonic-gate * by RFC 2396), 0 otherwise. 1667c478bd9Sstevel@tonic-gate */ 1677c478bd9Sstevel@tonic-gate static int 1687c478bd9Sstevel@tonic-gate valid_uri(const char *str) 1697c478bd9Sstevel@tonic-gate { 1707c478bd9Sstevel@tonic-gate /* 1717c478bd9Sstevel@tonic-gate * URI Regular Expression. Compiled with regcmp(1). 1727c478bd9Sstevel@tonic-gate * 1737c478bd9Sstevel@tonic-gate * ^(([^:/?#]+:){0,1})$0(//([^/?#]*)$1){0,1}([^?#]*)$2 1747c478bd9Sstevel@tonic-gate * (?([^#]*)$3){0,1}(#(.*)$4){0,1} 1757c478bd9Sstevel@tonic-gate */ 1767c478bd9Sstevel@tonic-gate char exp[] = { 1777c478bd9Sstevel@tonic-gate 040, 074, 00, 060, 012, 0126, 05, 072, 057, 077, 043, 024, 1787c478bd9Sstevel@tonic-gate 072, 057, 00, 00, 01, 014, 00, 00, 060, 020, 024, 057, 1797c478bd9Sstevel@tonic-gate 024, 057, 074, 01, 0125, 04, 057, 077, 043, 014, 01, 01, 1807c478bd9Sstevel@tonic-gate 057, 01, 00, 01, 074, 02, 0125, 03, 077, 043, 014, 02, 1817c478bd9Sstevel@tonic-gate 02, 060, 014, 024, 077, 074, 03, 0125, 02, 043, 014, 03, 1827c478bd9Sstevel@tonic-gate 03, 057, 02, 00, 01, 060, 012, 024, 043, 074, 04, 021, 1837c478bd9Sstevel@tonic-gate 014, 04, 04, 057, 03, 00, 01, 064, 00, 1847c478bd9Sstevel@tonic-gate 0}; 1857c478bd9Sstevel@tonic-gate char uri[URI_COMPONENT_COUNT][REP_PROTOCOL_VALUE_LEN]; 1867c478bd9Sstevel@tonic-gate 1877c478bd9Sstevel@tonic-gate /* 1887c478bd9Sstevel@tonic-gate * If the string is too long, then the URI cannot be valid. Also, 1897c478bd9Sstevel@tonic-gate * this protects against buffer overflow attacks on the uri array. 1907c478bd9Sstevel@tonic-gate */ 1917c478bd9Sstevel@tonic-gate if (strlen(str) >= REP_PROTOCOL_VALUE_LEN) 1927c478bd9Sstevel@tonic-gate return (0); 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate if (regex(exp, str, uri[URI_SCHEME], uri[URI_AUTHORITY], uri[URI_PATH], 195a574db85Sraf uri[URI_QUERY], uri[URI_FRAGMENT]) == NULL) { 1967c478bd9Sstevel@tonic-gate return (0); 1977c478bd9Sstevel@tonic-gate } 1987c478bd9Sstevel@tonic-gate /* 1997c478bd9Sstevel@tonic-gate * To be a valid URI, the length of the URI_PATH must not be zero 2007c478bd9Sstevel@tonic-gate */ 2017c478bd9Sstevel@tonic-gate if (strlen(uri[URI_PATH]) == 0) { 2027c478bd9Sstevel@tonic-gate return (0); 2037c478bd9Sstevel@tonic-gate } 2047c478bd9Sstevel@tonic-gate return (1); 2057c478bd9Sstevel@tonic-gate } 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate /* 2087c478bd9Sstevel@tonic-gate * Return 1 if the supplied parameter is a conformant fmri, 0 2097c478bd9Sstevel@tonic-gate * otherwise. 2107c478bd9Sstevel@tonic-gate */ 2117c478bd9Sstevel@tonic-gate static int 2127c478bd9Sstevel@tonic-gate valid_fmri(const char *str) 2137c478bd9Sstevel@tonic-gate { 2147c478bd9Sstevel@tonic-gate int ret; 2157c478bd9Sstevel@tonic-gate char fmri[REP_PROTOCOL_VALUE_LEN] = { 0 }; 2167c478bd9Sstevel@tonic-gate 2177c478bd9Sstevel@tonic-gate /* 2187c478bd9Sstevel@tonic-gate * Try to parse the fmri, if we can parse it then it 2197c478bd9Sstevel@tonic-gate * must be syntactically correct. Work on a copy of 2207c478bd9Sstevel@tonic-gate * the fmri since the parsing process can modify the 2217c478bd9Sstevel@tonic-gate * supplied string. 2227c478bd9Sstevel@tonic-gate */ 2237c478bd9Sstevel@tonic-gate if (strlcpy(fmri, str, sizeof (fmri)) >= sizeof (fmri)) 2247c478bd9Sstevel@tonic-gate return (0); 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate ret = ! scf_parse_fmri(fmri, NULL, NULL, NULL, NULL, NULL, NULL); 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate return (ret); 2297c478bd9Sstevel@tonic-gate } 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate rep_protocol_value_type_t 2327c478bd9Sstevel@tonic-gate scf_proto_underlying_type(rep_protocol_value_type_t t) 2337c478bd9Sstevel@tonic-gate { 2347c478bd9Sstevel@tonic-gate switch (t) { 2357c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_BOOLEAN: 2367c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_COUNT: 2377c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_INTEGER: 2387c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_TIME: 2397c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_STRING: 2407c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_OPAQUE: 2417c478bd9Sstevel@tonic-gate return (t); 2427c478bd9Sstevel@tonic-gate 2437c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_USTRING: 2447c478bd9Sstevel@tonic-gate return (REP_PROTOCOL_TYPE_STRING); 2457c478bd9Sstevel@tonic-gate 2467c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_URI: 2477c478bd9Sstevel@tonic-gate return (REP_PROTOCOL_SUBTYPE_USTRING); 2487c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_FMRI: 2497c478bd9Sstevel@tonic-gate return (REP_PROTOCOL_SUBTYPE_URI); 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_HOST: 2527c478bd9Sstevel@tonic-gate return (REP_PROTOCOL_SUBTYPE_USTRING); 2537c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_HOSTNAME: 2547c478bd9Sstevel@tonic-gate return (REP_PROTOCOL_SUBTYPE_HOST); 2557c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_NETADDR_V4: 2567c478bd9Sstevel@tonic-gate return (REP_PROTOCOL_SUBTYPE_HOST); 2577c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_NETADDR_V6: 2587c478bd9Sstevel@tonic-gate return (REP_PROTOCOL_SUBTYPE_HOST); 2597c478bd9Sstevel@tonic-gate 2607c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_INVALID: 2617c478bd9Sstevel@tonic-gate default: 2627c478bd9Sstevel@tonic-gate return (REP_PROTOCOL_TYPE_INVALID); 2637c478bd9Sstevel@tonic-gate } 2647c478bd9Sstevel@tonic-gate } 2657c478bd9Sstevel@tonic-gate 2667c478bd9Sstevel@tonic-gate int 267*870ad75aSSean Wilcox scf_is_compatible_protocol_type(rep_protocol_value_type_t base, 2687c478bd9Sstevel@tonic-gate rep_protocol_value_type_t new) 2697c478bd9Sstevel@tonic-gate { 2707c478bd9Sstevel@tonic-gate rep_protocol_value_type_t t, cur; 2717c478bd9Sstevel@tonic-gate 2727c478bd9Sstevel@tonic-gate if (base == REP_PROTOCOL_TYPE_INVALID) 2737c478bd9Sstevel@tonic-gate return (0); 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate if (base == new) 2767c478bd9Sstevel@tonic-gate return (1); 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate for (t = new; t != (cur = scf_proto_underlying_type(t)); t = cur) { 2797c478bd9Sstevel@tonic-gate if (cur == REP_PROTOCOL_TYPE_INVALID) 2807c478bd9Sstevel@tonic-gate return (0); 2817c478bd9Sstevel@tonic-gate if (cur == base) 2827c478bd9Sstevel@tonic-gate return (1); /* base is parent of new */ 2837c478bd9Sstevel@tonic-gate } 2847c478bd9Sstevel@tonic-gate return (0); 2857c478bd9Sstevel@tonic-gate } 2867c478bd9Sstevel@tonic-gate 2877c478bd9Sstevel@tonic-gate static int 2887c478bd9Sstevel@tonic-gate valid_encoded_value(rep_protocol_value_type_t t, const char *v) 2897c478bd9Sstevel@tonic-gate { 2907c478bd9Sstevel@tonic-gate char *p; 2917c478bd9Sstevel@tonic-gate ulong_t ns; 2927c478bd9Sstevel@tonic-gate 2937c478bd9Sstevel@tonic-gate switch (t) { 2947c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_BOOLEAN: 2957c478bd9Sstevel@tonic-gate return ((*v == '0' || *v == '1') && v[1] == 0); 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_COUNT: 2987c478bd9Sstevel@tonic-gate errno = 0; 2997c478bd9Sstevel@tonic-gate if (strtoull(v, &p, 10) != 0 && *v == '0') 3007c478bd9Sstevel@tonic-gate return (0); 3017c478bd9Sstevel@tonic-gate return (errno == 0 && p != v && *p == 0); 3027c478bd9Sstevel@tonic-gate 3037c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_INTEGER: 3047c478bd9Sstevel@tonic-gate errno = 0; 3057c478bd9Sstevel@tonic-gate if (strtoll(v, &p, 10) != 0 && *v == '0') 3067c478bd9Sstevel@tonic-gate return (0); 3077c478bd9Sstevel@tonic-gate return (errno == 0 && p != v && *p == 0); 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_TIME: 3107c478bd9Sstevel@tonic-gate errno = 0; 3117c478bd9Sstevel@tonic-gate (void) strtoll(v, &p, 10); 3127c478bd9Sstevel@tonic-gate if (errno != 0 || p == v || (*p != 0 && *p != '.')) 3137c478bd9Sstevel@tonic-gate return (0); 3147c478bd9Sstevel@tonic-gate if (*p == '.') { 3157c478bd9Sstevel@tonic-gate v = p + 1; 3167c478bd9Sstevel@tonic-gate errno = 0; 3177c478bd9Sstevel@tonic-gate ns = strtoul(v, &p, 10); 3187c478bd9Sstevel@tonic-gate 3197c478bd9Sstevel@tonic-gate /* must be exactly 9 digits */ 3207c478bd9Sstevel@tonic-gate if ((p - v) != 9 || errno != 0 || *p != 0) 3217c478bd9Sstevel@tonic-gate return (0); 3227c478bd9Sstevel@tonic-gate if (ns >= NANOSEC) 3237c478bd9Sstevel@tonic-gate return (0); 3247c478bd9Sstevel@tonic-gate } 3257c478bd9Sstevel@tonic-gate return (1); 3267c478bd9Sstevel@tonic-gate 3277c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_STRING: 3287c478bd9Sstevel@tonic-gate return (valid_string(v)); 3297c478bd9Sstevel@tonic-gate 3307c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_OPAQUE: 3317c478bd9Sstevel@tonic-gate return (valid_opaque(v)); 3327c478bd9Sstevel@tonic-gate 3337c478bd9Sstevel@tonic-gate /* 3347c478bd9Sstevel@tonic-gate * The remaining types are subtypes -- because of the way 3357c478bd9Sstevel@tonic-gate * scf_validate_encoded_value() works, we can rely on the fact 3367c478bd9Sstevel@tonic-gate * that v is a valid example of our base type. We only have to 3377c478bd9Sstevel@tonic-gate * check our own additional restrictions. 3387c478bd9Sstevel@tonic-gate */ 3397c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_USTRING: 3407c478bd9Sstevel@tonic-gate return (valid_utf8(v)); 3417c478bd9Sstevel@tonic-gate 3427c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_URI: 3437c478bd9Sstevel@tonic-gate return (valid_uri(v)); 3447c478bd9Sstevel@tonic-gate 3457c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_FMRI: 3467c478bd9Sstevel@tonic-gate return (valid_fmri(v)); 3477c478bd9Sstevel@tonic-gate 3487c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_HOST: 3497c478bd9Sstevel@tonic-gate return (valid_encoded_value(REP_PROTOCOL_SUBTYPE_HOSTNAME, v) || 3507c478bd9Sstevel@tonic-gate valid_encoded_value(REP_PROTOCOL_SUBTYPE_NETADDR_V4, v) || 3517c478bd9Sstevel@tonic-gate valid_encoded_value(REP_PROTOCOL_SUBTYPE_NETADDR_V6, v)); 3527c478bd9Sstevel@tonic-gate 3537c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_HOSTNAME: 3547c478bd9Sstevel@tonic-gate /* XXX check for valid hostname */ 3557c478bd9Sstevel@tonic-gate return (valid_utf8(v)); 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_NETADDR_V4: 3587c478bd9Sstevel@tonic-gate case REP_PROTOCOL_SUBTYPE_NETADDR_V6: 3597c478bd9Sstevel@tonic-gate /* XXX check for valid netaddr */ 3607c478bd9Sstevel@tonic-gate return (valid_utf8(v)); 3617c478bd9Sstevel@tonic-gate 3627c478bd9Sstevel@tonic-gate case REP_PROTOCOL_TYPE_INVALID: 3637c478bd9Sstevel@tonic-gate default: 3647c478bd9Sstevel@tonic-gate return (0); 3657c478bd9Sstevel@tonic-gate } 3667c478bd9Sstevel@tonic-gate } 3677c478bd9Sstevel@tonic-gate 3687c478bd9Sstevel@tonic-gate int 3697c478bd9Sstevel@tonic-gate scf_validate_encoded_value(rep_protocol_value_type_t t, const char *v) 3707c478bd9Sstevel@tonic-gate { 3717c478bd9Sstevel@tonic-gate rep_protocol_value_type_t base, cur; 3727c478bd9Sstevel@tonic-gate 3737c478bd9Sstevel@tonic-gate base = scf_proto_underlying_type(t); 3747c478bd9Sstevel@tonic-gate while ((cur = scf_proto_underlying_type(base)) != base) 3757c478bd9Sstevel@tonic-gate base = cur; 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate if (base != t && !valid_encoded_value(base, v)) 3787c478bd9Sstevel@tonic-gate return (0); 3797c478bd9Sstevel@tonic-gate 3807c478bd9Sstevel@tonic-gate return (valid_encoded_value(t, v)); 3817c478bd9Sstevel@tonic-gate } 382