source: trunk/libs/newlib/src/newlib/libc/sys/linux/net/ns_samedomain.c

Last change on this file was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

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