1 /*:ts=8*/
2 /*****************************************************************************
3  * FIDOGATE --- Gateway software UNIX <-> FIDO
4  *
5  *
6  * Parsing and conversion for FIDO and RFC addresses
7  *
8  *****************************************************************************
9  * Copyright (C) 1990-2002
10  *  _____ _____
11  * |	 |___  |   Martin Junius	     FIDO:	2:2452/110
12  * | | | |   | |   Radiumstr. 18  	     Internet:	mj@fidogate.org
13  * |_|_|_|@home|   D-51069 Koeln, Germany
14  *
15  * This file is part of FIDOGATE.
16  *
17  * FIDOGATE is free software; you can redistribute it and/or modify it
18  * under the terms of the GNU General Public License as published by the
19  * Free Software Foundation; either version 2, or (at your option) any
20  * later version.
21  *
22  * FIDOGATE is distributed in the hope that it will be useful, but
23  * WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
25  * General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with FIDOGATE; see the file COPYING.  If not, write to the Free
29  * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
30  *****************************************************************************/
31 
32 #include "fidogate.h"
33 
34 /*
35  * Local prototypes
36  */
37 static int try_pfnz(Node *, char *, char *, char *);
38 
39 /*
40  * Address parsing error message
41  */
42 char address_error[ADDRESS_ERROR_SIZE];
43 
44 static char **addr_is_local_pats = NULL;
45 
46 /*
47  * str_ftn_to_inet(): convert FTN address to Internet address
48  *
49  * force==TRUE: generate `pX.' point address even if `-p' is not
50  *              specified in HOSTS.
51  */
str_ftn_to_inet(char * buf,size_t len,Node * node,int force)52 char *str_ftn_to_inet(char *buf, size_t len, Node * node, int force)
53 {
54 
55     Host *h;
56     int point;
57 
58     h = hosts_lookup(node, NULL);
59 
60     if (h) {                    /* Address found in HOSTS */
61         point = h->flags & HOST_POINT ? TRUE : force;
62         if (h->name) {
63             if (point && node->point > 0 && !h->node.point)
64                 str_printf(buf, len, "p%d.%s", node->point, h->name);
65             else
66                 str_printf(buf, len, "%s", h->name);
67         } else
68             str_printf(buf, len, "%s%s", node_to_pfnz(node), cf_hostsdomain());
69     } else
70         str_printf(buf, len, "%s%s", node_to_pfnz(node),
71                    cf_zones_inet_domain(node->zone));
72 
73     return buf;
74 }
75 
76 /*
77  * s_ftn_to_inet(): convert FTN address to Internet address
78  */
s_ftn_to_inet(Node * node)79 char *s_ftn_to_inet(Node * node)
80 {
81     TmpS *s;
82 
83     s = tmps_alloc(MAXINETADDR);
84     str_ftn_to_inet(s->s, s->len, node, TRUE);
85     return s->s;
86 }
87 
88 #ifdef AI_1
89 /*
90  * verify_host_flag(): Verify FTN host flag
91  *
92  */
verify_host_flag(Node * node,int flag)93 int verify_host_flag(Node * node, int flag)
94 {
95     Host *h;
96     char HOST_ADDR;
97 
98     h = hosts_lookup(node, NULL);
99     if (h && h->flags & flag)   /* Address found in HOSTS */
100         return TRUE;
101     return FALSE;
102 }
103 #endif
104 
105 /*
106  * inet_to_ftn(): convert Internet address to FTN address
107  */
try_pfnz(Node * node,char * addr,char * dot,char * domain)108 static int try_pfnz(Node * node, char *addr, char *dot, char *domain)
109 {
110     char dom[MAXINETADDR];
111     char adr[MAXINETADDR];
112 
113     int len = strlen(addr);
114     int dlen = strlen(dot) + strlen(domain);
115 
116     BUF_COPY(adr, addr);
117     BUF_COPY2(dom, dot, domain);
118 
119     if (len > dlen && !stricmp(adr + len - dlen, dom)) {
120         adr[len - dlen] = 0;
121         if (pfnz_to_node(adr, node) == OK)
122             return TRUE;
123     }
124 
125     return FALSE;
126 }
127 
inet_to_ftn(char * addr)128 Node *inet_to_ftn(char *addr)
129 {
130 
131     char buf[MAXINETADDR];
132     static Node node;
133     Host *host;
134     char *p, *pn;
135     int point = -1;
136 
137     /*
138      * Look for optional point addressing in front of host name
139      */
140     p = addr;
141     if (*p == 'p' || *p == 'P') {
142         p++;
143         pn = p;
144         while (*p && is_digit(*p))
145             p++;
146         if (*p == '.') {        /* Must end with '.' */
147             p++;
148             point = atoi(pn);   /* Point number */
149         } else
150             p = addr;           /* No pX. */
151     }
152 
153     /*
154      * 1. Lookup in HOSTS
155      */
156     if ((host = hosts_lookup(NULL, p))) {
157         node = host->node;
158         if (!node.point && point != -1)
159             node.point = point;
160         return &node;
161     }
162 
163     /*
164      * 2. Add domainname and lookup in HOSTS
165      */
166     BUF_COPY2(buf, p, cf_domainname());
167     if ((host = hosts_lookup(NULL, buf))) {
168         node = host->node;
169         if (!node.point && point != -1)
170             node.point = point;
171         return &node;
172     }
173 
174     /*
175      * 2a. Add hosts domainname and lookup in HOSTS
176      */
177     BUF_COPY2(buf, p, cf_hostsdomain());
178     if ((host = hosts_lookup(NULL, buf))) {
179         node = host->node;
180         if (!node.point && point != -1)
181             node.point = point;
182         return &node;
183     }
184 
185     BUF_COPY(buf, addr);
186 
187     /*
188      * 3. Try p.f.n.z
189      */
190     if (try_pfnz(&node, buf, "", ""))
191         return &node;
192 
193     /*
194      * 4. Try p.f.n.z.HOSTNAME
195      */
196     if (try_pfnz(&node, buf, ".", cf_hostname()))
197         return &node;
198 
199     /*
200      * 5. Try p.f.n.z.HOSTNAME.DOMAIN
201      */
202     if (try_pfnz(&node, buf, ".", cf_fqdn()))
203         return &node;
204 
205     /*
206      * 6. Try p.f.n.z.DOMAIN
207      */
208     if (try_pfnz(&node, buf, "", cf_domainname()))
209         return &node;
210 
211     /*
212      * 6a. Try p.f.n.z.HOSTSDOMAIN
213      */
214     if (try_pfnz(&node, buf, "", cf_hostsdomain()))
215         return &node;
216 
217     /*
218      * 7. Try FTN domains from CONFIG
219      */
220     for (p = cf_zones_trav(TRUE); p; p = cf_zones_trav(FALSE))
221         if (try_pfnz(&node, buf, "", p))
222             return &node;
223 
224     /*
225      * Everything failed - not an FTN address
226      */
227     return NULL;
228 }
229 
230 /*
231  * Check for local RFC address, i.e. "user@HOSTNAME.DOMAIN (Full Name)"
232  * or "user (Full Name)"
233  */
addr_is_local(char * addr)234 int addr_is_local(char *addr)
235 {
236 
237     RFCAddr rfc;
238 
239     if (!addr)
240         return FALSE;
241 
242     rfc = rfcaddr_from_rfc(addr);
243 
244     debug(7, "addr_is_local(): From=%s FQDN=%s",
245           s_rfcaddr_to_asc(&rfc, TRUE), cf_fqdn());
246     return rfc.addr[0] == '\0' || stricmp(rfc.addr, cf_fqdn()) == 0;
247 }
248 
addr_is_local_xpost_init(char * addr)249 void addr_is_local_xpost_init(char *addr)
250 {
251     list_init(&addr_is_local_pats, addr);
252 }
253 
addr_is_local_xpost(char * addr)254 int addr_is_local_xpost(char *addr)
255 {
256 
257     RFCAddr rfc;
258     char ailx;
259     char **addr_list = NULL;
260 
261     if (!addr)
262         return FALSE;
263 
264     rfc = rfcaddr_from_rfc(addr);
265 
266     debug(7, "addr_is_local_xpost(): From=%s FQDN=%s",
267           s_rfcaddr_to_asc(&rfc, TRUE), cf_fqdn());
268     ailx = rfc.addr[0] == '\0' || stricmp(rfc.addr, cf_fqdn()) == 0;
269     if (!ailx) {
270         list_init(&addr_list, addr);
271         ailx = list_match(addr_is_local_pats, addr_list);
272         list_free(addr_list);
273     }
274     return ailx;
275 }
276 
277 /*
278  * Check for address in local domain, i.e. "user@*DOMAIN (Full Name)"
279  * or "user (Full Name)"
280  */
addr_is_domain(char * addr)281 int addr_is_domain(char *addr)
282 {
283 
284     RFCAddr rfc;
285     char *d;
286     int l, ld, ret = TRUE;
287 
288     if (addr) {
289 
290         rfc = rfcaddr_from_rfc(addr);
291 
292         d = cf_domainname();
293         ld = strlen(d);
294         l = strlen(rfc.addr);
295 
296         debug(7, "addr_is_domain(): From=%s domain=%s",
297               s_rfcaddr_to_asc(&rfc, TRUE), d);
298 
299         if (rfc.addr[0] == '\0') ;
300         /* user@DOMAIN */
301         else if (*d == '.' && stricmp(rfc.addr, d + 1) == 0) ;
302         else if (stricmp(rfc.addr, d) == 0) ;
303         /* user@*.DOMAIN */
304         else if (ld > l)
305             ret = FALSE;
306         else
307             ret = stricmp(rfc.addr + l - ld, d) == 0;
308     }
309     return ret;
310 }
311