win32/compat/resolv.c
46bd6382
 /*
c442ca9c
  *  Copyright (C) 2013-2019 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
  *  Copyright (C) 2009-2013 Sourcefire, Inc.
46bd6382
  *
  *  Authors: aCaB <acab@clamav.net>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2 as
  *  published by the Free Software Foundation.
  *
  *  This program is distributed in the hope that it will be useful,
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  *  MA 02110-1301, USA.
  */
 
 /* a fake libresolv-like res_query interface */
 
 #include "resolv.h"
 
 int res_init(void) {
     return 0;
 }
 
 int res_query(const char *dname, int class, int type, unsigned char *answer, int anslen) {
     DNS_RECORD *rrs, *rr;
     DNS_STATUS s;
     HEADER *h = (HEADER *)answer;
     int ret = -1;
 
     if(anslen <= sizeof(HEADER))
 	return -1;
 
     s = DnsQuery(dname, (WORD)type, DNS_QUERY_BYPASS_CACHE | DNS_QUERY_NO_HOSTS_FILE | DNS_QUERY_DONT_RESET_TTL_VALUES, NULL, &rrs, NULL);
     if(s)
 	return -1;
 
     /* We don't use the header data */
     h->id = 1;
     answer += sizeof(HEADER);
     anslen -= sizeof(HEADER);
 
     rr = rrs;
     do {
03bf6658
 	if(rr->wType == (WORD)type && rr->wDataLength > sizeof(DWORD) && rr->Data.TXT.dwStringCount && rr->Data.TXT.pStringArray[0]) {
46bd6382
 	    unsigned int len = strlen(dname), txtlen = strlen(rr->Data.TXT.pStringArray[0]);
 	    if(txtlen > 255) continue;
 	    len++;
 	    if(len*2 + txtlen + 15 > anslen) break;
 	    memcpy(answer, dname, len);
 	    answer += len;
 	    answer[0] = type >> 8; /* type */
 	    answer[1] = type;
 	    answer[2] = class >> 8; /* class */
 	    answer[3] = class & 0xff;
 	    answer += 4;
 	    memcpy(answer, dname, len);
 	    answer += len;
 	    answer[0] = type >> 8; /* type */
 	    answer[1] = type;
 	    answer[2] = class >> 8; /* class */
 	    answer[3] = class & 0xff;
 	    answer[4] = rr->dwTtl >> 24;
 	    answer[5] = rr->dwTtl >> 16;
 	    answer[6] = rr->dwTtl >> 8;
 	    answer[7] = rr->dwTtl;
 	    answer[8] = (txtlen+1) >> 8; /* rdata len */
 	    answer[9] = txtlen+1;
 	    answer[10] = txtlen;
 	    memcpy(&answer[11], rr->Data.TXT.pStringArray[0], txtlen);
 	    ret = len*2 + txtlen + 15 + sizeof(HEADER);
 	    break;
 	}
     } while ((rr = rr->pNext));
 
     DnsRecordListFree(rrs, DnsFreeRecordList);
     return ret;
 }
 
 int dn_expand(unsigned char *msg, unsigned char *eomorig, unsigned char *comp_dn, char *exp_dn, int length) {
     int len, maxlen;
 
     /* names are simple C strings, not compressed not len encoded */
     if(comp_dn < msg || comp_dn >= eomorig)
 	return -1;
     maxlen = eomorig - comp_dn;
     len = strnlen(comp_dn, maxlen) + 1;
     if(len > maxlen || len > length)
 	return -1;
     memcpy(exp_dn, msg, len);
     return len;
 }