1 /*
2  *  Copyright (C) 2013-2022 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
3  *  Copyright (C) 2009-2013 Sourcefire, Inc.
4  *
5  *  Authors: aCaB <acab@clamav.net>
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  *  MA 02110-1301, USA.
20  */
21 
22 /* a fake libresolv-like res_query interface */
23 
24 #include <Windows.H>
25 #include "resolv.h"
26 
res_init(void)27 int res_init(void)
28 {
29     return 0;
30 }
31 
res_query(const char * dname,int class,int type,unsigned char * answer,int anslen)32 int res_query(const char *dname, int class, int type, unsigned char *answer, int anslen)
33 {
34     DNS_RECORD *rrs, *rr;
35     DNS_STATUS s;
36     HEADER *h = (HEADER *)answer;
37     int ret   = -1;
38 
39     if (anslen <= sizeof(HEADER))
40         return -1;
41 
42     s = DnsQuery(dname, (WORD)type, DNS_QUERY_BYPASS_CACHE | DNS_QUERY_NO_HOSTS_FILE | DNS_QUERY_DONT_RESET_TTL_VALUES, NULL, &rrs, NULL);
43     if (s)
44         return -1;
45 
46     /* We don't use the header data */
47     h->id = 1;
48     answer += sizeof(HEADER);
49     anslen -= sizeof(HEADER);
50 
51     rr = rrs;
52     do {
53         if (rr->wType == (WORD)type && rr->wDataLength > sizeof(DWORD) && rr->Data.TXT.dwStringCount && rr->Data.TXT.pStringArray[0]) {
54             unsigned int len = strlen(dname), txtlen = strlen(rr->Data.TXT.pStringArray[0]);
55             if (txtlen > 255) continue;
56             len++;
57             if (len * 2 + txtlen + 15 > anslen) break;
58             memcpy(answer, dname, len);
59             answer += len;
60             answer[0] = type >> 8; /* type */
61             answer[1] = type;
62             answer[2] = class >> 8; /* class */
63             answer[3] = class & 0xff;
64             answer += 4;
65             memcpy(answer, dname, len);
66             answer += len;
67             answer[0]  = type >> 8; /* type */
68             answer[1]  = type;
69             answer[2]  = class >> 8; /* class */
70             answer[3]  = class & 0xff;
71             answer[4]  = rr->dwTtl >> 24;
72             answer[5]  = rr->dwTtl >> 16;
73             answer[6]  = rr->dwTtl >> 8;
74             answer[7]  = rr->dwTtl;
75             answer[8]  = (txtlen + 1) >> 8; /* rdata len */
76             answer[9]  = txtlen + 1;
77             answer[10] = txtlen;
78             memcpy(&answer[11], rr->Data.TXT.pStringArray[0], txtlen);
79             ret = len * 2 + txtlen + 15 + sizeof(HEADER);
80             break;
81         }
82     } while ((rr = rr->pNext));
83 
84     DnsRecordListFree(rrs, DnsFreeRecordList);
85     return ret;
86 }
87 
dn_expand(unsigned char * msg,unsigned char * eomorig,unsigned char * comp_dn,char * exp_dn,int length)88 int dn_expand(unsigned char *msg, unsigned char *eomorig, unsigned char *comp_dn, char *exp_dn, int length)
89 {
90     int len, maxlen;
91 
92     /* names are simple C strings, not compressed not len encoded */
93     if (comp_dn < msg || comp_dn >= eomorig)
94         return -1;
95     maxlen = eomorig - comp_dn;
96     len    = strnlen(comp_dn, maxlen) + 1;
97     if (len > maxlen || len > length)
98         return -1;
99     memcpy(exp_dn, msg, len);
100     return len;
101 }
102