summaryrefslogtreecommitdiffstats
path: root/crypto/heimdal/lib/roken/resolve.c
diff options
context:
space:
mode:
authornectar <nectar@FreeBSD.org>2002-08-30 21:23:27 +0000
committernectar <nectar@FreeBSD.org>2002-08-30 21:23:27 +0000
commita77dba08ca7d8ad2f2dcd653974ac66df78cfa49 (patch)
tree6015f89700252fb05eb8fa267c46dba41913e9d8 /crypto/heimdal/lib/roken/resolve.c
parent69a91bec14ec3ad49d1c8a82c40a796755f9e4a3 (diff)
downloadFreeBSD-src-a77dba08ca7d8ad2f2dcd653974ac66df78cfa49.zip
FreeBSD-src-a77dba08ca7d8ad2f2dcd653974ac66df78cfa49.tar.gz
Import of Heimdal Kerberos from KTH repository circa 2002/08/29.
Diffstat (limited to 'crypto/heimdal/lib/roken/resolve.c')
-rw-r--r--crypto/heimdal/lib/roken/resolve.c82
1 files changed, 65 insertions, 17 deletions
diff --git a/crypto/heimdal/lib/roken/resolve.c b/crypto/heimdal/lib/roken/resolve.c
index eddaa7d..f17ae4c 100644
--- a/crypto/heimdal/lib/roken/resolve.c
+++ b/crypto/heimdal/lib/roken/resolve.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
+ * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -45,7 +45,7 @@
#include <assert.h>
-RCSID("$Id: resolve.c,v 1.30 2001/10/02 15:39:41 joda Exp $");
+RCSID("$Id: resolve.c,v 1.33 2002/08/28 20:07:24 joda Exp $");
#if defined(HAVE_RES_SEARCH) && defined(HAVE_DN_EXPAND)
@@ -113,10 +113,10 @@ dns_free_data(struct dns_reply *r)
static struct dns_reply*
parse_reply(unsigned char *data, int len)
{
- unsigned char *p;
+ const unsigned char *p;
char host[128];
int status;
-
+ const unsigned char *end_data = data + len;
struct dns_reply *r;
struct resource_record **rr;
@@ -133,7 +133,7 @@ parse_reply(unsigned char *data, int len)
memcpy(&r->h, p, 12); /* XXX this will probably be mostly garbage */
p += 12;
#endif
- status = dn_expand(data, data + len, p, host, sizeof(host));
+ status = dn_expand(data, end_data, p, host, sizeof(host));
if(status < 0){
dns_free_data(r);
return NULL;
@@ -143,19 +143,27 @@ parse_reply(unsigned char *data, int len)
dns_free_data(r);
return NULL;
}
+ if (p + status + 4 > end_data) {
+ dns_free_data(r);
+ return NULL;
+ }
p += status;
r->q.type = (p[0] << 8 | p[1]);
p += 2;
r->q.class = (p[0] << 8 | p[1]);
p += 2;
rr = &r->head;
- while(p < data + len){
+ while(p < end_data){
int type, class, ttl, size;
- status = dn_expand(data, data + len, p, host, sizeof(host));
+ status = dn_expand(data, end_data, p, host, sizeof(host));
if(status < 0){
dns_free_data(r);
return NULL;
}
+ if (p + status + 10 > end_data) {
+ dns_free_data(r);
+ return NULL;
+ }
p += status;
type = (p[0] << 8) | p[1];
p += 2;
@@ -165,6 +173,12 @@ parse_reply(unsigned char *data, int len)
p += 4;
size = (p[0] << 8) | p[1];
p += 2;
+
+ if (p + size > end_data) {
+ dns_free_data(r);
+ return NULL;
+ }
+
*rr = (struct resource_record*)calloc(1,
sizeof(struct resource_record));
if(*rr == NULL) {
@@ -184,7 +198,7 @@ parse_reply(unsigned char *data, int len)
case T_NS:
case T_CNAME:
case T_PTR:
- status = dn_expand(data, data + len, p, host, sizeof(host));
+ status = dn_expand(data, end_data, p, host, sizeof(host));
if(status < 0){
dns_free_data(r);
return NULL;
@@ -197,11 +211,16 @@ parse_reply(unsigned char *data, int len)
break;
case T_MX:
case T_AFSDB:{
- status = dn_expand(data, data + len, p + 2, host, sizeof(host));
+ status = dn_expand(data, end_data, p + 2, host, sizeof(host));
if(status < 0){
dns_free_data(r);
return NULL;
}
+ if (status + 2 > size) {
+ dns_free_data(r);
+ return NULL;
+ }
+
(*rr)->u.mx = (struct mx_record*)malloc(sizeof(struct mx_record) +
strlen(host));
if((*rr)->u.mx == NULL) {
@@ -213,11 +232,16 @@ parse_reply(unsigned char *data, int len)
break;
}
case T_SRV:{
- status = dn_expand(data, data + len, p + 6, host, sizeof(host));
+ status = dn_expand(data, end_data, p + 6, host, sizeof(host));
if(status < 0){
dns_free_data(r);
return NULL;
}
+ if (status + 6 > size) {
+ dns_free_data(r);
+ return NULL;
+ }
+
(*rr)->u.srv =
(struct srv_record*)malloc(sizeof(struct srv_record) +
strlen(host));
@@ -244,6 +268,11 @@ parse_reply(unsigned char *data, int len)
case T_KEY : {
size_t key_len;
+ if (size < 4) {
+ dns_free_data (r);
+ return NULL;
+ }
+
key_len = size - 4;
(*rr)->u.key = malloc (sizeof(*(*rr)->u.key) + key_len - 1);
if ((*rr)->u.key == NULL) {
@@ -261,11 +290,16 @@ parse_reply(unsigned char *data, int len)
case T_SIG : {
size_t sig_len;
- status = dn_expand (data, data + len, p + 18, host, sizeof(host));
+ status = dn_expand (data, end_data, p + 18, host, sizeof(host));
if (status < 0) {
dns_free_data (r);
return NULL;
}
+ if (status + 18 > size) {
+ dns_free_data(r);
+ return NULL;
+ }
+
sig_len = len - 18 - status;
(*rr)->u.sig = malloc(sizeof(*(*rr)->u.sig)
+ strlen(host) + sig_len);
@@ -293,6 +327,11 @@ parse_reply(unsigned char *data, int len)
case T_CERT : {
size_t cert_len;
+ if (size < 5) {
+ dns_free_data(r);
+ return NULL;
+ }
+
cert_len = size - 5;
(*rr)->u.cert = malloc (sizeof(*(*rr)->u.cert) + cert_len - 1);
if ((*rr)->u.cert == NULL) {
@@ -327,24 +366,32 @@ dns_lookup_int(const char *domain, int rr_class, int rr_type)
{
unsigned char reply[1024];
int len;
- struct dns_reply *r = NULL;
+#ifdef HAVE__RES
u_long old_options = 0;
+#endif
if (_resolve_debug) {
+#ifdef HAVE__RES
old_options = _res.options;
_res.options |= RES_DEBUG;
+#endif
fprintf(stderr, "dns_lookup(%s, %d, %s)\n", domain,
rr_class, dns_type_to_string(rr_type));
}
len = res_search(domain, rr_class, rr_type, reply, sizeof(reply));
if (_resolve_debug) {
+#ifdef HAVE__RES
_res.options = old_options;
+#endif
fprintf(stderr, "dns_lookup(%s, %d, %s) --> %d\n",
domain, rr_class, dns_type_to_string(rr_type), len);
}
- if (len >= 0)
- r = parse_reply(reply, len);
- return r;
+ if(len < 0) {
+ return NULL;
+ } else {
+ len = min(len, sizeof(reply));
+ return parse_reply(reply, len);
+ }
}
struct dns_reply *
@@ -385,7 +432,8 @@ dns_srv_order(struct dns_reply *r)
int num_srv = 0;
#if defined(HAVE_INITSTATE) && defined(HAVE_SETSTATE)
- char state[256], *oldstate;
+ int state[256 / sizeof(int)];
+ char *oldstate;
#endif
for(rr = r->head; rr; rr = rr->next)
@@ -414,7 +462,7 @@ dns_srv_order(struct dns_reply *r)
qsort(srvs, num_srv, sizeof(*srvs), compare_srv);
#if defined(HAVE_INITSTATE) && defined(HAVE_SETSTATE)
- oldstate = initstate(time(NULL), state, sizeof(state));
+ oldstate = initstate(time(NULL), (char*)state, sizeof(state));
#endif
headp = &r->head;
OpenPOWER on IntegriCloud