diff options
author | deraadt <> | 1996-09-26 09:13:21 +0000 |
---|---|---|
committer | deraadt <> | 1996-09-26 09:13:21 +0000 |
commit | e670b7aa4096c71b072c7956579fc5ae9d554414 (patch) | |
tree | 609b9a0ea57107827e5dfde83bd85ded55c32bf6 /src | |
parent | c9867c321dc15643dd6a2b49e79105fcab56c6f3 (diff) | |
download | openbsd-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.c | 64 |
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) |
55 | static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.8 1996/09/15 10:09:12 tholo Exp $"; | 55 | static 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 | ||
103 | typedef union { | 103 | typedef union { |
104 | int32_t al; | 104 | int32_t al; |
105 | char ac; | 105 | char ac; |
106 | } align; | 106 | } align; |
107 | 107 | ||
108 | static int qcomp __P((struct in_addr **, struct in_addr **)); | 108 | static int qcomp __P((struct in_addr **, struct in_addr **)); |
109 | static struct hostent *getanswer __P((querybuf *, int, int)); | 109 | static struct hostent *getanswer __P((querybuf *, int, int)); |
110 | static int hbadchar __P((char *)); | ||
110 | 111 | ||
111 | extern int h_errno; | 112 | extern int h_errno; |
112 | 113 | ||
114 | static int | ||
115 | hbadchar(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 | |||
113 | static struct hostent * | 138 | static struct hostent * |
114 | getanswer(answer, anslen, iquery) | 139 | getanswer(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 | } | ||
290 | gotent: | ||
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 | ||
266 | struct hostent * | 302 | struct hostent * |