summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorderaadt <>1996-09-26 09:13:21 +0000
committerderaadt <>1996-09-26 09:13:21 +0000
commite670b7aa4096c71b072c7956579fc5ae9d554414 (patch)
tree609b9a0ea57107827e5dfde83bd85ded55c32bf6 /src
parentc9867c321dc15643dd6a2b49e79105fcab56c6f3 (diff)
downloadopenbsd-e670b7aa4096c71b072c7956579fc5ae9d554414.tar.gz
openbsd-e670b7aa4096c71b072c7956579fc5ae9d554414.tar.bz2
openbsd-e670b7aa4096c71b072c7956579fc5ae9d554414.zip
be safer about spoofed hostnames; thanks to bitblt and oliver for help with these ideas
Diffstat (limited to 'src')
-rw-r--r--src/lib/libc/net/gethostnamadr.c64
1 files changed, 50 insertions, 14 deletions
diff --git a/src/lib/libc/net/gethostnamadr.c b/src/lib/libc/net/gethostnamadr.c
index 62e14693a4..29fbedc594 100644
--- a/src/lib/libc/net/gethostnamadr.c
+++ b/src/lib/libc/net/gethostnamadr.c
@@ -52,7 +52,7 @@
52 */ 52 */
53 53
54#if defined(LIBC_SCCS) && !defined(lint) 54#if defined(LIBC_SCCS) && !defined(lint)
55static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.8 1996/09/15 10:09:12 tholo Exp $"; 55static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.9 1996/09/26 09:13:21 deraadt Exp $";
56#endif /* LIBC_SCCS and not lint */ 56#endif /* LIBC_SCCS and not lint */
57 57
58#include <sys/param.h> 58#include <sys/param.h>
@@ -101,15 +101,40 @@ typedef union {
101} querybuf; 101} querybuf;
102 102
103typedef union { 103typedef union {
104 int32_t al; 104 int32_t al;
105 char ac; 105 char ac;
106} align; 106} align;
107 107
108static int qcomp __P((struct in_addr **, struct in_addr **)); 108static int qcomp __P((struct in_addr **, struct in_addr **));
109static struct hostent *getanswer __P((querybuf *, int, int)); 109static struct hostent *getanswer __P((querybuf *, int, int));
110static int hbadchar __P((char *));
110 111
111extern int h_errno; 112extern int h_errno;
112 113
114static int
115hbadchar(p)
116 char *p;
117{
118 char c;
119
120 /*
121 * Many people do not obey RFC 822 and 1035. The valid
122 * characters are a-z, A-Z, 0-9, '-' and . But the others
123 * tested for below can happen, and we must be more permissive
124 * until those idiots clean up their act.
125 */
126 while ((c = *p++)) {
127 if (('a' >= c && c <= 'z') ||
128 ('A' >= c && c <= 'Z') ||
129 ('0' >= c && c <= '9'))
130 continue;
131 if (strchr("-_/.[]\\", c) ||
132 (c == '.' && p[1] == '.'))
133 return 1;
134 }
135 return 0;
136}
137
113static struct hostent * 138static struct hostent *
114getanswer(answer, anslen, iquery) 139getanswer(answer, anslen, iquery)
115 querybuf *answer; 140 querybuf *answer;
@@ -124,6 +149,7 @@ getanswer(answer, anslen, iquery)
124 int type, class, buflen, ancount, qdcount; 149 int type, class, buflen, ancount, qdcount;
125 int haveanswer, getclass = C_ANY; 150 int haveanswer, getclass = C_ANY;
126 char **hap; 151 char **hap;
152 int good = 1;
127 153
128 eom = answer->buf + anslen; 154 eom = answer->buf + anslen;
129 /* 155 /*
@@ -200,7 +226,7 @@ getanswer(answer, anslen, iquery)
200 n = strlen(host.h_name); 226 n = strlen(host.h_name);
201 if (n >= MAXHOSTNAMELEN) 227 if (n >= MAXHOSTNAMELEN)
202 host.h_name[MAXHOSTNAMELEN-1] = '\0'; 228 host.h_name[MAXHOSTNAMELEN-1] = '\0';
203 return(&host); 229 goto gotent;
204 } 230 }
205 if (iquery || type != T_A) { 231 if (iquery || type != T_A) {
206#ifdef DEBUG 232#ifdef DEBUG
@@ -224,6 +250,8 @@ getanswer(answer, anslen, iquery)
224 host.h_length = n; 250 host.h_length = n;
225 getclass = class; 251 getclass = class;
226 host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC; 252 host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC;
253 if (host.h_addrtype == AF_INET)
254 host.h_length = sizeof(struct in_addr);
227 if (!iquery) { 255 if (!iquery) {
228 host.h_name = bp; 256 host.h_name = bp;
229 if (strlen(bp) >= MAXHOSTNAMELEN) 257 if (strlen(bp) >= MAXHOSTNAMELEN)
@@ -248,19 +276,27 @@ getanswer(answer, anslen, iquery)
248 cp += n; 276 cp += n;
249 haveanswer++; 277 haveanswer++;
250 } 278 }
251 if (haveanswer) { 279 if (!haveanswer) {
252 *ap = NULL;
253 *hap = NULL;
254 if (_res.nsort) {
255 qsort(host.h_addr_list, haveanswer,
256 sizeof(struct in_addr),
257 (int (*)__P((const void *, const void *)))qcomp);
258 }
259 return (&host);
260 } else {
261 h_errno = TRY_AGAIN; 280 h_errno = TRY_AGAIN;
262 return ((struct hostent *) NULL); 281 return ((struct hostent *) NULL);
263 } 282 }
283 *ap = NULL;
284 *hap = NULL;
285 if (_res.nsort) {
286 qsort(host.h_addr_list, haveanswer,
287 sizeof(struct in_addr),
288 (int (*)__P((const void *, const void *)))qcomp);
289 }
290gotent:
291 if (hbadchar(host.h_name))
292 good = 0;
293 for (ap = host_aliases; good && *ap; ap++)
294 if (hbadchar(*ap))
295 good = 0;
296 if (good)
297 return (&host);
298 h_errno = NO_RECOVERY;
299 return ((struct hostent *) NULL);
264} 300}
265 301
266struct hostent * 302struct hostent *