~ubuntu-branches/ubuntu/utopic/clamav/utopic-security

« back to all changes in this revision

Viewing changes to freshclam/dns.c

  • Committer: Package Import Robot
  • Author(s): Scott Kitterman
  • Date: 2014-02-01 11:06:17 UTC
  • mfrom: (0.35.37 sid)
  • Revision ID: package-import@ubuntu.com-20140201110617-33h2xxk09dep0ui4
Tags: 0.98.1+dfsg-1ubuntu1
* Merge from Debian unstable.  Remaining changes:
  - Drop build-dep on electric-fence (in Universe)
  - Add apparmor profiles for clamd and freshclam along with maintainer
    script changes
  - Add autopkgtest

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
#define PACKETSZ 512
42
42
#endif
43
43
 
44
 
char *dnsquery(const char *domain, int qtype, unsigned int *ttl)
 
44
char *
 
45
dnsquery (const char *domain, int qtype, unsigned int *ttl)
45
46
{
46
 
        unsigned char answer[PACKETSZ], *answend, *pt;
47
 
        char *txt, host[128];
48
 
        int len, type;
49
 
        unsigned int cttl, size, txtlen = 0;
50
 
 
51
 
 
52
 
    if(ttl)
53
 
        *ttl = 0;
54
 
    if(res_init() < 0) {
55
 
        logg("^res_init failed\n");
56
 
        return NULL;
 
47
    unsigned char answer[PACKETSZ], *answend, *pt;
 
48
    char *txt, host[128];
 
49
    int len, type;
 
50
    unsigned int cttl, size, txtlen = 0;
 
51
 
 
52
 
 
53
    if (ttl)
 
54
        *ttl = 0;
 
55
    if (res_init () < 0)
 
56
    {
 
57
        logg ("^res_init failed\n");
 
58
        return NULL;
57
59
    }
58
60
 
59
 
    logg("*Querying %s\n", domain);
 
61
    logg ("*Querying %s\n", domain);
60
62
 
61
 
    memset(answer, 0, PACKETSZ);
62
 
    if((len = res_query(domain, C_IN, qtype, answer, PACKETSZ)) < 0 || len > PACKETSZ) {
 
63
    memset (answer, 0, PACKETSZ);
 
64
    if ((len = res_query (domain, C_IN, qtype, answer, PACKETSZ)) < 0
 
65
        || len > PACKETSZ)
 
66
    {
63
67
#ifdef FRESHCLAM_DNS_FIX
64
 
        /*  The DNS server in the SpeedTouch Alcatel 510 modem can't
65
 
         *  handle a TXT-query, but it can resolve an ANY-query to a
66
 
         *  TXT-record, so we try an ANY-query now.  The thing we try
67
 
         *  to resolve normally only has a TXT-record anyway.  
68
 
         */
69
 
        memset(answer, 0, PACKETSZ);
70
 
        if(qtype == T_TXT)
71
 
            qtype = T_ANY;
72
 
        if((len = res_query(domain, C_IN, qtype, answer, PACKETSZ)) < 0) {
73
 
            logg("%cCan't query %s\n", (qtype == T_TXT || qtype == T_ANY) ? '^' : '*', domain);
74
 
            return NULL;
75
 
        }
 
68
        /*  The DNS server in the SpeedTouch Alcatel 510 modem can't
 
69
         *  handle a TXT-query, but it can resolve an ANY-query to a
 
70
         *  TXT-record, so we try an ANY-query now.  The thing we try
 
71
         *  to resolve normally only has a TXT-record anyway.  
 
72
         */
 
73
        memset (answer, 0, PACKETSZ);
 
74
        if (qtype == T_TXT)
 
75
            qtype = T_ANY;
 
76
        if ((len = res_query (domain, C_IN, qtype, answer, PACKETSZ)) < 0)
 
77
        {
 
78
            logg ("%cCan't query %s\n",
 
79
                  (qtype == T_TXT || qtype == T_ANY) ? '^' : '*', domain);
 
80
            return NULL;
 
81
        }
76
82
#else
77
 
        logg("%cCan't query %s\n", (qtype == T_TXT) ? '^' : '*', domain);
78
 
        return NULL;
 
83
        logg ("%cCan't query %s\n", (qtype == T_TXT) ? '^' : '*', domain);
 
84
        return NULL;
79
85
#endif
80
86
    }
81
 
    if(qtype != T_TXT && qtype != T_ANY) {
82
 
        if(ttl)
83
 
            *ttl = 2;
84
 
        return NULL;
 
87
    if (qtype != T_TXT && qtype != T_ANY)
 
88
    {
 
89
        if (ttl)
 
90
            *ttl = 2;
 
91
        return NULL;
85
92
    }
86
93
 
87
94
    answend = answer + len;
88
 
    pt = answer + sizeof(HEADER);
 
95
    pt = answer + sizeof (HEADER);
89
96
 
90
 
    if((len = dn_expand(answer, answend, pt, host, sizeof(host))) < 0) {
91
 
        logg("^dn_expand failed\n");
92
 
        return NULL;
 
97
    if ((len = dn_expand (answer, answend, pt, host, sizeof (host))) < 0)
 
98
    {
 
99
        logg ("^dn_expand failed\n");
 
100
        return NULL;
93
101
    }
94
102
 
95
103
    pt += len;
96
 
    if(pt > answend-4) {
97
 
        logg("^Bad (too short) DNS reply\n");
98
 
        return NULL;
99
 
    }
100
 
 
101
 
    GETSHORT(type, pt);
102
 
    if(type != qtype) {
103
 
        logg("^Broken DNS reply.\n");
104
 
        return NULL;
105
 
    }
106
 
 
107
 
    pt += INT16SZ; /* class */
 
104
    if (pt > answend - 4)
 
105
    {
 
106
        logg ("^Bad (too short) DNS reply\n");
 
107
        return NULL;
 
108
    }
 
109
 
 
110
    GETSHORT (type, pt);
 
111
    if (type != qtype)
 
112
    {
 
113
        logg ("^Broken DNS reply.\n");
 
114
        return NULL;
 
115
    }
 
116
 
 
117
    pt += INT16SZ;              /* class */
108
118
    size = 0;
109
 
    do { /* recurse through CNAME rr's */
110
 
        pt += size;
111
 
        if((len = dn_expand(answer, answend, pt, host, sizeof(host))) < 0) {
112
 
            logg("^second dn_expand failed\n");
113
 
            return NULL;
114
 
        }
115
 
        pt += len;
116
 
        if(pt > answend-10) {
117
 
            logg("^Bad (too short) DNS reply\n");
118
 
            return NULL;
119
 
        }
120
 
        GETSHORT(type, pt);
121
 
        pt += INT16SZ; /* class */
122
 
        GETLONG(cttl, pt);
123
 
        GETSHORT(size, pt);
124
 
        if(pt + size < answer || pt + size > answend) {
125
 
            logg("^DNS rr overflow\n");
126
 
            return NULL;
127
 
        }
128
 
    } while(type == T_CNAME);
129
 
 
130
 
    if(type != T_TXT) {
131
 
        logg("^Not a TXT record\n");
132
 
        return NULL;
133
 
    }
134
 
 
135
 
    if(!size || (txtlen = *pt) >= size || !txtlen) {
136
 
        logg("^Broken TXT record (txtlen = %d, size = %d)\n", txtlen, size);
137
 
        return NULL;
138
 
    }
139
 
 
140
 
    if(!(txt = (char *) malloc(txtlen + 1)))
141
 
        return NULL;
142
 
 
143
 
    memcpy(txt, pt+1, txtlen);
 
119
    do
 
120
    {                           /* recurse through CNAME rr's */
 
121
        pt += size;
 
122
        if ((len = dn_expand (answer, answend, pt, host, sizeof (host))) < 0)
 
123
        {
 
124
            logg ("^second dn_expand failed\n");
 
125
            return NULL;
 
126
        }
 
127
        pt += len;
 
128
        if (pt > answend - 10)
 
129
        {
 
130
            logg ("^Bad (too short) DNS reply\n");
 
131
            return NULL;
 
132
        }
 
133
        GETSHORT (type, pt);
 
134
        pt += INT16SZ;          /* class */
 
135
        GETLONG (cttl, pt);
 
136
        GETSHORT (size, pt);
 
137
        if (pt + size < answer || pt + size > answend)
 
138
        {
 
139
            logg ("^DNS rr overflow\n");
 
140
            return NULL;
 
141
        }
 
142
    }
 
143
    while (type == T_CNAME);
 
144
 
 
145
    if (type != T_TXT)
 
146
    {
 
147
        logg ("^Not a TXT record\n");
 
148
        return NULL;
 
149
    }
 
150
 
 
151
    if (!size || (txtlen = *pt) >= size || !txtlen)
 
152
    {
 
153
        logg ("^Broken TXT record (txtlen = %d, size = %d)\n", txtlen, size);
 
154
        return NULL;
 
155
    }
 
156
 
 
157
    if (!(txt = (char *) malloc (txtlen + 1)))
 
158
        return NULL;
 
159
 
 
160
    memcpy (txt, pt + 1, txtlen);
144
161
    txt[txtlen] = 0;
145
 
    if(ttl)
146
 
        *ttl = cttl;
 
162
    if (ttl)
 
163
        *ttl = cttl;
147
164
 
148
165
    return txt;
149
166
}
150
167
 
151
168
#else
152
169
 
153
 
char *dnsquery(const char *domain, int qtype, unsigned int *ttl)
 
170
char *
 
171
dnsquery (const char *domain, int qtype, unsigned int *ttl)
154
172
{
155
 
    if(ttl)
156
 
        *ttl = 1;  /* ttl of 1 combined with a NULL return distinguishes a failed lookup from DNS queries not being available */
 
173
    if (ttl)
 
174
        *ttl = 1;               /* ttl of 1 combined with a NULL return distinguishes a failed lookup from DNS queries not being available */
157
175
    return NULL;
158
176
}
159
177