Initial import from FreeBSD RELENG_4:
[dragonfly.git] / crypto / kerberosIV / lib / krb / krb_equiv.c
1 /*
2  * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
3  * (Royal Institute of Technology, Stockholm, Sweden).
4  * All rights reserved.
5  * 
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 
17  * 3. Neither the name of the Institute nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  * 
21  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33
34 /*
35  * int krb_equiv(u_int32_t ipaddr_a, u_int32_t ipaddr_b);
36  *
37  * Given two IP adresses return true if they match
38  * or are considered to belong to the same host.
39  *
40  * For example if /etc/krb.equiv looks like
41  *
42  *    130.237.223.3   192.16.126.3    # alv alv1
43  *    130.237.223.4   192.16.126.4    # byse byse1
44  *    130.237.228.152 192.16.126.9    # topsy topsy1
45  *
46  * krb_equiv(alv, alv1) would return true but
47  * krb_equiv(alv, byse1) would not.
48  *
49  * A comment starts with an '#' and ends with '\n'.
50  *
51  */
52 #include "krb_locl.h"
53
54 RCSID("$Id: krb_equiv.c,v 1.15 1999/12/02 16:58:42 joda Exp $");
55
56 int krb_ignore_ip_address = 0;
57
58 int
59 krb_equiv(u_int32_t a, u_int32_t b)
60 {
61   FILE *fil;
62   char line[256];
63   int hit_a, hit_b;
64   int iscomment;
65   
66   if (a == b)                   /* trivial match, also the common case */
67     return 1;
68   
69   if (krb_ignore_ip_address)
70     return 1;                   /* if we have decided not to compare */
71
72   a = ntohl(a);
73   b = ntohl(b);
74
75   fil = fopen(KRB_EQUIV, "r");
76   if (fil == NULL)              /* open failed */
77     return 0;
78   
79   hit_a = hit_b = 0;
80   iscomment = 0;
81   while (fgets(line, sizeof(line)-1, fil) != NULL) /* for each line */
82     {
83       char *t = line;
84       int len = strlen(t);
85       
86       /* for each item on this line */
87       while (*t != 0)           /* more addresses on this line? */
88         if (*t == '\n') {
89           iscomment = hit_a = hit_b = 0;
90           break;
91         } else if (iscomment)
92           t = line + len - 1;
93         else if (*t == '#') {           /* rest is comment */
94           iscomment = 1;
95           ++t;
96         } else if (*t == '\\' ) /* continuation */
97           break;
98         else if (isspace((unsigned char)*t))    /* skip space */
99           t++;
100         else if (isdigit((unsigned char)*t))    /* an address? */
101           {
102             u_int32_t tmp;
103             u_int32_t tmpa, tmpb, tmpc, tmpd;
104             
105             sscanf(t, "%d.%d.%d.%d", &tmpa, &tmpb, &tmpc, &tmpd);
106             tmp = (tmpa << 24) | (tmpb << 16) | (tmpc << 8) | tmpd;
107
108             /* done with this address */
109             while (*t == '.' || isdigit((unsigned char)*t))
110               t++;
111
112             if (tmp != -1) {    /* an address (and not broadcast) */
113               u_int32_t mask = (u_int32_t)~0;
114
115               if (*t == '/') {
116                 ++t;
117                 mask <<= 32 - atoi(t);
118
119                 while(isdigit((unsigned char)*t))
120                   ++t;
121               }
122
123               if ((tmp & mask) == (a & mask))
124                 hit_a = 1;
125               if ((tmp & mask) == (b & mask))
126                 hit_b = 1;
127               if (hit_a && hit_b) {
128                 fclose(fil);
129                 return 1;
130               }
131             }
132           }
133         else
134           ++t;          /* garbage on this line, skip it */
135
136     }
137
138   fclose(fil);
139   return 0;
140 }