1 /*
2  *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3  *
4  *  Copyright (c) 1997-2021 ircd-hybrid development team
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
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, MA 02110-1301
19  *  USA
20  */
21 
22 /*! \file res.c
23  * \brief ircd resolver functions
24  * \version $Id: res.c 9874 2021-01-04 11:46:16Z michael $
25  */
26 
27 /*
28  * A rewrite of Darren Reed's original res.c As there is nothing
29  * left of Darren's original code, this is now licensed by the hybrid group.
30  * (Well, some of the function names are the same, and bits of the structs..)
31  * You can use it where it is useful, free even. Buy us a beer and stuff.
32  *
33  * The authors takes no responsibility for any damage or loss
34  * of property which results from the use of this software.
35  *
36  * July 1999 - Rewrote a bunch of stuff here. Change hostent builder code,
37  *     added callbacks and reference counting of returned hostents.
38  *     --Bleep (Thomas Helvey <tomh@inxpress.net>)
39  *
40  * This was all needlessly complicated for irc. Simplified. No more hostent
41  * All we really care about is the IP -> hostname mappings. That's all.
42  *
43  * Apr 28, 2003 --cryogen and Dianora
44  */
45 
46 #include "stdinc.h"
47 #include "list.h"
48 #include "event.h"
49 #include "irc_string.h"
50 #include "ircd.h"
51 #include "rng_mt.h"
52 #include "fdlist.h"
53 #include "s_bsd.h"
54 #include "misc.h"
55 #include "res.h"
56 #include "reslib.h"
57 #include "memory.h"
58 #include "conf.h"
59 #include "hostmask.h"
60 
61 #if (CHAR_BIT != 8)
62 #error this code needs to be able to address individual octets
63 #endif
64 
65 static void res_readreply(fde_t *, void *);
66 
67 #define MAXPACKET      1024  /**< rfc says 512 but we expand names so ... */
68 #define AR_TTL         600   /**< TTL in seconds for dns cache entries */
69 
70 /*
71  * RFC 1104/1105 wasn't very helpful about what these fields
72  * should be named, so for now, we'll just name them this way.
73  * We probably should look at what named calls them or something.
74  */
75 #define TYPE_SIZE         (size_t)2
76 #define CLASS_SIZE        (size_t)2
77 #define TTL_SIZE          (size_t)4
78 #define RDLENGTH_SIZE     (size_t)2
79 #define ANSWER_FIXED_SIZE (TYPE_SIZE + CLASS_SIZE + TTL_SIZE + RDLENGTH_SIZE)
80 
81 struct reslist
82 {
83   dlink_node node;                           /**< Doubly linked list node. */
84   unsigned int id;                           /**< Request ID (from request header). */
85   char type;                                 /**< Current request type. */
86   char retries;                              /**< Retry counter */
87   unsigned int sends;                        /**< Number of sends (>1 means resent). */
88   uintmax_t sentat;                          /**< Timestamp we last sent this request. */
89   uintmax_t timeout;                         /**< When this request times out. */
90   struct irc_ssaddr addr;                    /**< Address for this request. */
91   char name[RFC1035_MAX_DOMAIN_LENGTH + 1];  /**< Hostname for this request. */
92   size_t namelength;                         /**< Actual hostname length. */
93   dns_callback_fnc callback;                 /**< Callback function on completion. */
94   void *callback_ctx;                        /**< Context pointer for callback. */
95 };
96 
97 static fde_t *ResolverFileDescriptor;
98 static dlink_list request_list;
99 
100 
101 /*
102  * rem_request - remove a request from the list.
103  * This must also free any memory that has been allocated for
104  * temporary storage of DNS results.
105  */
106 static void
rem_request(struct reslist * request)107 rem_request(struct reslist *request)
108 {
109   dlinkDelete(&request->node, &request_list);
110   xfree(request);
111 }
112 
113 /*
114  * make_request - Create a DNS request record for the server.
115  */
116 static struct reslist *
make_request(dns_callback_fnc callback,void * ctx)117 make_request(dns_callback_fnc callback, void *ctx)
118 {
119   struct reslist *request = xcalloc(sizeof(*request));
120 
121   request->sentat = event_base->time.sec_monotonic;
122   request->retries = 2;
123   request->timeout = 4;  /* Start at 4 and exponential inc. */
124   request->callback = callback;
125   request->callback_ctx = ctx;
126 
127   dlinkAdd(request, &request->node, &request_list);
128   return request;
129 }
130 
131 /*
132  * int
133  * res_ourserver(inp)
134  *      looks up "inp" in irc_nsaddr_list[]
135  * returns:
136  *      0  : not found
137  *      >0 : found
138  * author:
139  *      paul vixie, 29may94
140  *      revised for ircd, cryogen(stu) may03
141  */
142 static bool
res_ourserver(const struct irc_ssaddr * inp)143 res_ourserver(const struct irc_ssaddr *inp)
144 {
145   for (unsigned int i = 0; i < irc_nscount; ++i)
146     if (address_compare(inp, &irc_nsaddr_list[i], true, true, 0) == true)
147       return true;
148 
149   return false;
150 }
151 
152 /*
153  * start_resolver - do everything we need to read the resolv.conf file
154  * and initialize the resolver file descriptor if needed
155  */
156 static void
start_resolver(void)157 start_resolver(void)
158 {
159   irc_res_init();
160 
161   if (ResolverFileDescriptor == NULL)
162   {
163     int fd = comm_socket(irc_nsaddr_list[0].ss.ss_family, SOCK_DGRAM, 0);
164     if (fd == -1)
165       return;
166 
167     ResolverFileDescriptor = fd_open(fd, true, "UDP resolver socket");
168 
169     /* At the moment, the resolver FD data is global .. */
170     comm_setselect(ResolverFileDescriptor, COMM_SELECT_READ, res_readreply, NULL, 0);
171   }
172 }
173 
174 /*
175  * restart_resolver - reread resolv.conf, reopen socket
176  */
177 void
restart_resolver(void)178 restart_resolver(void)
179 {
180   if (ResolverFileDescriptor)
181   {
182     fd_close(ResolverFileDescriptor);
183     ResolverFileDescriptor = NULL;
184   }
185 
186   start_resolver();
187 }
188 
189 /*
190  * delete_resolver_queries - cleanup outstanding queries
191  * for which there no longer exist clients or conf lines.
192  */
193 void
delete_resolver_queries(const void * vptr)194 delete_resolver_queries(const void *vptr)
195 {
196   dlink_node *node, *node_next;
197 
198   DLINK_FOREACH_SAFE(node, node_next, request_list.head)
199   {
200     struct reslist *request = node->data;
201 
202     if (request->callback_ctx == vptr)
203       rem_request(request);
204   }
205 }
206 
207 /*
208  * send_res_msg - sends msg to all nameservers found in the "_res" structure.
209  * This should reflect /etc/resolv.conf. We will get responses
210  * which arent needed but is easier than checking to see if nameserver
211  * isn't present. Returns number of messages successfully sent to
212  * nameservers or -1 if no successful sends.
213  */
214 static void
send_res_msg(const unsigned char * msg,int len,unsigned int rcount)215 send_res_msg(const unsigned char *msg, int len, unsigned int rcount)
216 {
217   unsigned int max_queries = IRCD_MIN(irc_nscount, rcount);
218 
219   /* RES_PRIMARY option is not implemented
220    * if (res.options & RES_PRIMARY || 0 == max_queries)
221    */
222   if (max_queries == 0)
223     max_queries = 1;
224 
225   for (unsigned int i = 0; i < max_queries; ++i)
226     sendto(ResolverFileDescriptor->fd, msg, len, 0,
227            (struct sockaddr *)&irc_nsaddr_list[i], irc_nsaddr_list[i].ss_len);
228 }
229 
230 /*
231  * find_id - find a dns request id (id is determined by dn_mkquery)
232  */
233 static struct reslist *
find_id(unsigned int id)234 find_id(unsigned int id)
235 {
236   dlink_node *node;
237 
238   DLINK_FOREACH(node, request_list.head)
239   {
240     struct reslist *request = node->data;
241 
242     if (request->id == id)
243       return request;
244   }
245 
246   return NULL;
247 }
248 
249 /*
250  * query_name - generate a query based on class, type and name.
251  */
252 static void
query_name(const char * name,int query_class,int type,struct reslist * request)253 query_name(const char *name, int query_class, int type, struct reslist *request)
254 {
255   unsigned char buf[MAXPACKET];
256 
257   memset(buf, 0, sizeof(buf));
258 
259   int request_len = irc_res_mkquery(name, query_class, type, buf, sizeof(buf));
260   if (request_len > 0)
261   {
262     HEADER *header = (HEADER *)buf;
263 
264     /*
265      * Generate an unique id.
266      * NOTE: we don't have to worry about converting this to and from
267      * network byte order, the nameserver does not interpret this value
268      * and returns it unchanged.
269      */
270     do
271       header->id = (header->id + genrand_int32()) & 0xFFFF;
272     while (find_id(header->id));
273 
274     request->id = header->id;
275     ++request->sends;
276 
277     send_res_msg(buf, request_len, request->sends);
278   }
279 }
280 
281 /*
282  * do_query_name - nameserver lookup name
283  */
284 static void
do_query_name(dns_callback_fnc callback,void * ctx,const char * name,struct reslist * request,int type)285 do_query_name(dns_callback_fnc callback, void *ctx, const char *name,
286               struct reslist *request, int type)
287 {
288   char host_name[RFC1035_MAX_DOMAIN_LENGTH + 1];
289 
290   strlcpy(host_name, name, sizeof(host_name));
291 
292   if (request == NULL)
293   {
294     request = make_request(callback, ctx);
295     request->type = type;
296     request->namelength = strlcpy(request->name, host_name, sizeof(request->name));
297   }
298 
299   request->type = type;
300   query_name(host_name, C_IN, type, request);
301 }
302 
303 /*
304  * do_query_number - Use this to do reverse IP# lookups.
305  */
306 static void
do_query_number(dns_callback_fnc callback,void * ctx,const struct irc_ssaddr * addr,struct reslist * request)307 do_query_number(dns_callback_fnc callback, void *ctx,
308                 const struct irc_ssaddr *addr,
309                 struct reslist *request)
310 {
311   char ipbuf[128] = "";
312 
313   if (addr->ss.ss_family == AF_INET)
314   {
315     const struct sockaddr_in *v4 = (const struct sockaddr_in *)addr;
316     const unsigned char *cp = (const unsigned char *)&v4->sin_addr.s_addr;
317 
318     snprintf(ipbuf, sizeof(ipbuf), "%u.%u.%u.%u.in-addr.arpa.",
319              (unsigned int)(cp[3]), (unsigned int)(cp[2]),
320              (unsigned int)(cp[1]), (unsigned int)(cp[0]));
321   }
322   else if (addr->ss.ss_family == AF_INET6)
323   {
324     const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *)addr;
325     const unsigned char *cp = (const unsigned char *)&v6->sin6_addr.s6_addr;
326 
327     snprintf(ipbuf, sizeof(ipbuf),
328              "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x."
329              "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa.",
330              (unsigned int)(cp[15] & 0xf), (unsigned int)(cp[15] >> 4),
331              (unsigned int)(cp[14] & 0xf), (unsigned int)(cp[14] >> 4),
332              (unsigned int)(cp[13] & 0xf), (unsigned int)(cp[13] >> 4),
333              (unsigned int)(cp[12] & 0xf), (unsigned int)(cp[12] >> 4),
334              (unsigned int)(cp[11] & 0xf), (unsigned int)(cp[11] >> 4),
335              (unsigned int)(cp[10] & 0xf), (unsigned int)(cp[10] >> 4),
336              (unsigned int)(cp[9] & 0xf), (unsigned int)(cp[9] >> 4),
337              (unsigned int)(cp[8] & 0xf), (unsigned int)(cp[8] >> 4),
338              (unsigned int)(cp[7] & 0xf), (unsigned int)(cp[7] >> 4),
339              (unsigned int)(cp[6] & 0xf), (unsigned int)(cp[6] >> 4),
340              (unsigned int)(cp[5] & 0xf), (unsigned int)(cp[5] >> 4),
341              (unsigned int)(cp[4] & 0xf), (unsigned int)(cp[4] >> 4),
342              (unsigned int)(cp[3] & 0xf), (unsigned int)(cp[3] >> 4),
343              (unsigned int)(cp[2] & 0xf), (unsigned int)(cp[2] >> 4),
344              (unsigned int)(cp[1] & 0xf), (unsigned int)(cp[1] >> 4),
345              (unsigned int)(cp[0] & 0xf), (unsigned int)(cp[0] >> 4));
346   }
347 
348   if (request == NULL)
349   {
350     request = make_request(callback, ctx);
351     request->type = T_PTR;
352     request->addr = *addr;
353   }
354 
355   query_name(ipbuf, C_IN, T_PTR, request);
356 }
357 
358 /*
359  * gethost_byname_type - get host address from name
360  *
361  */
362 void
gethost_byname_type(dns_callback_fnc callback,void * ctx,const char * name,int type)363 gethost_byname_type(dns_callback_fnc callback, void *ctx, const char *name, int type)
364 {
365   assert(name);
366   do_query_name(callback, ctx, name, NULL, type);
367 }
368 
369 /*
370  * gethost_byaddr - get host name from address
371  */
372 void
gethost_byaddr(dns_callback_fnc callback,void * ctx,const struct irc_ssaddr * addr)373 gethost_byaddr(dns_callback_fnc callback, void *ctx, const struct irc_ssaddr *addr)
374 {
375   do_query_number(callback, ctx, addr, NULL);
376 }
377 
378 static void
resend_query(struct reslist * request)379 resend_query(struct reslist *request)
380 {
381   switch (request->type)
382   {
383     case T_PTR:
384       do_query_number(NULL, NULL, &request->addr, request);
385       break;
386     case T_A:
387     case T_AAAA:
388       do_query_name(NULL, NULL, request->name, request, request->type);
389       break;
390     default:
391       break;
392   }
393 }
394 
395 /*
396  * proc_answer - process name server reply
397  */
398 static bool
proc_answer(struct reslist * request,HEADER * header,unsigned char * buf,unsigned char * eob)399 proc_answer(struct reslist *request, HEADER *header, unsigned char *buf, unsigned char *eob)
400 {
401   char hostbuf[RFC1035_MAX_DOMAIN_LENGTH + 100]; /* working buffer */
402   unsigned char *current = buf + sizeof(HEADER); /* current position in buf */
403   unsigned int type = 0;       /* answer type */
404   unsigned int rd_length = 0;
405   struct sockaddr_in *v4;      /* conversion */
406   struct sockaddr_in6 *v6;
407 
408   for (; header->qdcount > 0; --header->qdcount)
409   {
410     int n = irc_dn_skipname(current, eob);
411     if (n < 0)
412       break;
413 
414     current += (size_t)n + QFIXEDSZ;
415   }
416 
417   /*
418    * Process each answer sent to us blech.
419    */
420   while (header->ancount > 0 && current < eob)
421   {
422     --header->ancount;
423 
424     int n = irc_dn_expand(buf, eob, current, hostbuf, sizeof(hostbuf));
425     if (n < 0  /* Broken message */ || n == 0  /* No more answers left */)
426       return false;
427 
428     hostbuf[RFC1035_MAX_DOMAIN_LENGTH] = '\0';
429 
430     /*
431      * With Address arithmetic you have to be very anal
432      * this code was not working on alpha due to that
433      * (spotted by rodder/jailbird/dianora)
434      */
435     current += (size_t)n;
436 
437     if (!((current + ANSWER_FIXED_SIZE) < eob))
438       break;
439 
440     type = irc_ns_get16(current);
441     current += TYPE_SIZE;
442     current += CLASS_SIZE;
443     current += TTL_SIZE;
444     rd_length = irc_ns_get16(current);
445     current += RDLENGTH_SIZE;
446 
447     /*
448      * Wait to set request->type until we verify this structure
449      */
450     switch (type)
451     {
452       case T_A:
453         if (request->type != T_A)
454           return false;
455 
456         /*
457          * Check for invalid rd_length or too many addresses
458          */
459         if (rd_length != sizeof(struct in_addr))
460           return false;
461 
462         request->addr.ss_len = sizeof(struct sockaddr_in);
463         v4 = (struct sockaddr_in *)&request->addr;
464         v4->sin_family = AF_INET;
465         memcpy(&v4->sin_addr, current, sizeof(struct in_addr));
466         return true;
467         break;
468 
469       case T_AAAA:
470         if (request->type != T_AAAA)
471           return false;
472 
473         if (rd_length != sizeof(struct in6_addr))
474           return false;
475 
476         request->addr.ss_len = sizeof(struct sockaddr_in6);
477         v6 = (struct sockaddr_in6 *)&request->addr;
478         v6->sin6_family = AF_INET6;
479         memcpy(&v6->sin6_addr, current, sizeof(struct in6_addr));
480         return true;
481         break;
482 
483       case T_PTR:
484         if (request->type != T_PTR)
485           return false;
486 
487         n = irc_dn_expand(buf, eob, current, hostbuf, sizeof(hostbuf));
488         if (n < 0  /* Broken message */ || n == 0  /* No more answers left */)
489           return false;
490 
491         request->namelength = strlcpy(request->name, hostbuf, sizeof(request->name));
492         return true;
493         break;
494 
495       case T_CNAME:
496         current += rd_length;
497         break;
498 
499       default:
500         return false;
501         break;
502     }
503   }
504 
505   return false;
506 }
507 
508 /*
509  * res_readreply - read a dns reply from the nameserver and process it.
510  */
511 static void
res_readreply(fde_t * F,void * data)512 res_readreply(fde_t *F, void *data)
513 {
514   unsigned char buf[sizeof(HEADER) + MAXPACKET];
515   ssize_t rc;
516   socklen_t len = sizeof(struct irc_ssaddr);
517   struct irc_ssaddr lsin;
518 
519   while ((rc = recvfrom(F->fd, buf, sizeof(buf), 0, (struct sockaddr *)&lsin, &len)) != -1)
520   {
521     if (rc <= (ssize_t)sizeof(HEADER))
522       continue;
523 
524     /*
525      * Check against possibly fake replies
526      */
527     if (res_ourserver(&lsin) == false)
528       continue;
529 
530     /*
531      * Convert DNS reply reader from Network byte order to CPU byte order.
532      */
533     HEADER *header = (HEADER *)buf;
534     header->ancount = ntohs(header->ancount);
535     header->qdcount = ntohs(header->qdcount);
536     header->nscount = ntohs(header->nscount);
537     header->arcount = ntohs(header->arcount);
538 
539     /*
540      * Response for an id which we have already received an answer for
541      * just ignore this response.
542      */
543     struct reslist *request = find_id(header->id);
544     if (request == NULL)
545       continue;
546 
547     if (header->rcode != NO_ERRORS || header->ancount == 0)
548     {
549       /*
550        * If a bad error was returned, stop here and don't send
551        * any more (no retries granted).
552        */
553       (*request->callback)(request->callback_ctx, NULL, NULL, 0);
554       rem_request(request);
555       continue;
556     }
557 
558     /*
559      * If this fails there was an error decoding the received packet.
560      * We only give it one shot. If it fails, just leave the client
561      * unresolved.
562      */
563     if (proc_answer(request, header, buf, buf + rc) == false)
564     {
565       (*request->callback)(request->callback_ctx, NULL, NULL, 0);
566       rem_request(request);
567       continue;
568     }
569 
570     if (request->type == T_PTR)
571     {
572       if (request->namelength == 0)
573       {
574         /*
575          * Got a PTR response with no name, something bogus is happening
576          * don't bother trying again, the client address doesn't resolve
577          */
578         (*request->callback)(request->callback_ctx, NULL, NULL, 0);
579         rem_request(request);
580         continue;
581       }
582 
583       /*
584        * Lookup the 'authoritative' name that we were given for the ip#.
585        */
586       if (request->addr.ss.ss_family == AF_INET6)
587         gethost_byname_type(request->callback, request->callback_ctx, request->name, T_AAAA);
588       else
589         gethost_byname_type(request->callback, request->callback_ctx, request->name, T_A);
590 
591       rem_request(request);
592     }
593     else
594     {
595       /*
596        * Got a name and address response, client resolved
597        */
598       (*request->callback)(request->callback_ctx, &request->addr, request->name, request->namelength);
599       rem_request(request);
600     }
601   }
602 
603   comm_setselect(F, COMM_SELECT_READ, res_readreply, NULL, 0);
604 }
605 
606 /*
607  * timeout_query_list - Remove queries from the list which have been
608  * there too long without being resolved.
609  */
610 static void
resolver_timeout(void * unused)611 resolver_timeout(void *unused)
612 {
613   dlink_node *node, *node_next;
614 
615   DLINK_FOREACH_SAFE(node, node_next, request_list.head)
616   {
617     struct reslist *request = node->data;
618     uintmax_t timeout = request->sentat + request->timeout;
619 
620     if (event_base->time.sec_monotonic >= timeout)
621     {
622       if (--request->retries <= 0)
623       {
624         (*request->callback)(request->callback_ctx, NULL, NULL, 0);
625         rem_request(request);
626       }
627       else
628       {
629         request->sentat = event_base->time.sec_monotonic;
630         request->timeout += request->timeout;
631         resend_query(request);
632       }
633     }
634   }
635 }
636 
637 /*
638  * resolver_init - initialize resolver and resolver library
639  */
640 void
resolver_init(void)641 resolver_init(void)
642 {
643   static struct event resolver_timeout_event =
644   {
645     .name = "resolver_timeout",
646     .handler = resolver_timeout,
647     .when = 1
648   };
649 
650   start_resolver();
651   event_add(&resolver_timeout_event, NULL);
652 }
653