Annotation of embedaddon/dhcp/minires/ns_samedomain.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (c) 2004,2009 by Internet Systems Consortium, Inc. ("ISC")
! 3: * Copyright (c) 1995-2003 by Internet Software Consortium
! 4: *
! 5: * Permission to use, copy, modify, and distribute this software for any
! 6: * purpose with or without fee is hereby granted, provided that the above
! 7: * copyright notice and this permission notice appear in all copies.
! 8: *
! 9: * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
! 10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
! 11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
! 12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
! 13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
! 14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
! 15: * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
! 16: *
! 17: * Internet Systems Consortium, Inc.
! 18: * 950 Charter Street
! 19: * Redwood City, CA 94063
! 20: * <info@isc.org>
! 21: * https://www.isc.org/
! 22: */
! 23:
! 24: #ifndef lint
! 25: static const char rcsid[] = "$Id: ns_samedomain.c,v 1.4.786.2 2009-07-24 22:04:52 sar Exp $";
! 26: #endif
! 27:
! 28: #include <sys/types.h>
! 29: #include <errno.h>
! 30: #include <string.h>
! 31:
! 32: #include <netinet/in.h>
! 33: #include <sys/socket.h>
! 34:
! 35: #include "minires/minires.h"
! 36: #include "arpa/nameser.h"
! 37:
! 38: /*
! 39: * int
! 40: * ns_samedomain(a, b)
! 41: * Check whether a name belongs to a domain.
! 42: * Inputs:
! 43: * a - the domain whose ancestory is being verified
! 44: * b - the potential ancestor we're checking against
! 45: * Return:
! 46: * boolean - is a at or below b?
! 47: * Notes:
! 48: * Trailing dots are first removed from name and domain.
! 49: * Always compare complete subdomains, not only whether the
! 50: * domain name is the trailing string of the given name.
! 51: *
! 52: * "host.foobar.top" lies in "foobar.top" and in "top" and in ""
! 53: * but NOT in "bar.top"
! 54: */
! 55:
! 56: int
! 57: ns_samedomain(const char *a, const char *b) {
! 58: size_t la, lb;
! 59: int diff, i, escaped;
! 60: const char *cp;
! 61:
! 62: la = strlen(a);
! 63: lb = strlen(b);
! 64:
! 65: /* Ignore a trailing label separator (i.e. an unescaped dot) in 'a'. */
! 66: if (la != 0 && a[la - 1] == '.') {
! 67: escaped = 0;
! 68: /* Note this loop doesn't get executed if la==1. */
! 69: for (i = la - 2; i >= 0; i--)
! 70: if (a[i] == '\\') {
! 71: if (escaped)
! 72: escaped = 0;
! 73: else
! 74: escaped = 1;
! 75: } else
! 76: break;
! 77: if (!escaped)
! 78: la--;
! 79: }
! 80:
! 81: /* Ignore a trailing label separator (i.e. an unescaped dot) in 'b'. */
! 82: if (lb != 0 && b[lb - 1] == '.') {
! 83: escaped = 0;
! 84: /* note this loop doesn't get executed if lb==1 */
! 85: for (i = lb - 2; i >= 0; i--)
! 86: if (b[i] == '\\') {
! 87: if (escaped)
! 88: escaped = 0;
! 89: else
! 90: escaped = 1;
! 91: } else
! 92: break;
! 93: if (!escaped)
! 94: lb--;
! 95: }
! 96:
! 97: /* lb == 0 means 'b' is the root domain, so 'a' must be in 'b'. */
! 98: if (lb == 0)
! 99: return (1);
! 100:
! 101: /* 'b' longer than 'a' means 'a' can't be in 'b'. */
! 102: if (lb > la)
! 103: return (0);
! 104:
! 105: /* 'a' and 'b' being equal at this point indicates sameness. */
! 106: if (lb == la)
! 107: return (strncasecmp(a, b, lb) == 0);
! 108:
! 109: /* Ok, we know la > lb. */
! 110:
! 111: diff = la - lb;
! 112:
! 113: /*
! 114: * If 'a' is only 1 character longer than 'b', then it can't be
! 115: * a subdomain of 'b' (because of the need for the '.' label
! 116: * separator).
! 117: */
! 118: if (diff < 2)
! 119: return (0);
! 120:
! 121: /*
! 122: * If the character before the last 'lb' characters of 'b'
! 123: * isn't '.', then it can't be a match (this lets us avoid
! 124: * having "foobar.com" match "bar.com").
! 125: */
! 126: if (a[diff - 1] != '.')
! 127: return (0);
! 128:
! 129: /*
! 130: * We're not sure about that '.', however. It could be escaped
! 131: * and thus not a really a label separator.
! 132: */
! 133: escaped = 0;
! 134: for (i = diff - 2; i >= 0; i--)
! 135: if (a[i] == '\\') {
! 136: if (escaped)
! 137: escaped = 0;
! 138: else
! 139: escaped = 1;
! 140: } else
! 141: break;
! 142: if (escaped)
! 143: return (0);
! 144:
! 145: /* Now compare aligned trailing substring. */
! 146: cp = a + diff;
! 147: return (strncasecmp(cp, b, lb) == 0);
! 148: }
! 149:
! 150: /*
! 151: * int
! 152: * ns_subdomain(a, b)
! 153: * is "a" a subdomain of "b"?
! 154: */
! 155: int
! 156: ns_subdomain(const char *a, const char *b) {
! 157: return (ns_samename(a, b) != 1 && ns_samedomain(a, b));
! 158: }
! 159:
! 160: /*
! 161: * int
! 162: * ns_makecanon(src, dst, dstsize)
! 163: * make a canonical copy of domain name "src"
! 164: * notes:
! 165: * foo -> foo.
! 166: * foo. -> foo.
! 167: * foo.. -> foo.
! 168: * foo\. -> foo\..
! 169: * foo\\. -> foo\\.
! 170: */
! 171:
! 172: isc_result_t
! 173: ns_makecanon(const char *src, char *dst, size_t dstsize) {
! 174: size_t n = strlen(src);
! 175:
! 176: if (n + sizeof "." > dstsize) {
! 177: return ISC_R_NOSPACE;
! 178: }
! 179: strcpy(dst, src);
! 180: while (n > 0 && dst[n - 1] == '.') /* Ends in "." */
! 181: if (n > 1 && dst[n - 2] == '\\' && /* Ends in "\." */
! 182: (n < 2 || dst[n - 3] != '\\')) /* But not "\\." */
! 183: break;
! 184: else
! 185: dst[--n] = '\0';
! 186: dst[n++] = '.';
! 187: dst[n] = '\0';
! 188: return ISC_R_SUCCESS;
! 189: }
! 190:
! 191: /*
! 192: * int
! 193: * ns_samename(a, b)
! 194: * determine whether domain name "a" is the same as domain name "b"
! 195: * return:
! 196: * -1 on error
! 197: * 0 if names differ
! 198: * 1 if names are the same
! 199: */
! 200:
! 201: int
! 202: ns_samename(const char *a, const char *b) {
! 203: char ta[NS_MAXDNAME], tb[NS_MAXDNAME];
! 204: isc_result_t status;
! 205:
! 206: status = ns_makecanon(a, ta, sizeof ta);
! 207: if (status != ISC_R_SUCCESS)
! 208: return status;
! 209: status = ns_makecanon(b, tb, sizeof tb);
! 210: if (status != ISC_R_SUCCESS)
! 211: return (-1);
! 212: if (strcasecmp(ta, tb) == 0)
! 213: return (1);
! 214: else
! 215: return (0);
! 216: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>