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