]> jfr.im git - solanum.git/blame - authd/dns.c
Really fix the help index.
[solanum.git] / authd / dns.c
CommitLineData
8cf45447
AC
1/* authd/dns.h - header for authd DNS functions
2 * Copyright (c) 2016 William Pitcock <nenolod@dereferenced.org>
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice is present in all copies.
7 *
8 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
9 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
11 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
12 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
14 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
15 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
16 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
17 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
18 * POSSIBILITY OF SUCH DAMAGE.
19 */
20
21#include "authd.h"
22#include "dns.h"
394b8dde 23#include "res.h"
8cf45447
AC
24
25static void
26submit_dns_answer(void *userdata, struct DNSReply *reply)
27{
28 struct dns_request *req = userdata;
29 char response[64] = "*";
30 char status = 'E';
31
32 if (reply == NULL)
33 {
c7c009b5 34 rb_helper_write(authd_helper, "E %s E %c *", req->reqid, req->type);
8cf45447
AC
35 goto cleanup;
36 }
37
38 switch (req->type)
39 {
40 case '4':
41 if (GET_SS_FAMILY(&reply->addr) == AF_INET)
42 {
43 status = 'O';
44 rb_inet_ntop_sock((struct sockaddr *) &reply->addr, response, sizeof(response));
45 }
46 break;
47#ifdef RB_IPV6
48 case '6':
49 if (GET_SS_FAMILY(&reply->addr) == AF_INET6)
50 {
51 char tmpres[63];
52 rb_inet_ntop_sock((struct sockaddr *) &reply->addr, tmpres, sizeof(tmpres));
53
54 if (*tmpres == ':')
55 {
56 rb_strlcpy(response, "0", sizeof(response));
57 rb_strlcat(response, tmpres, sizeof(response));
58 }
59 else
60 rb_strlcpy(response, tmpres, sizeof(response));
61
62 status = 'O';
63 }
64 break;
65#endif
66 case 'R':
67 {
68 struct sockaddr_in *ip, *ip_fwd;
69 ip = (struct sockaddr_in *) &req->addr;
70 ip_fwd = (struct sockaddr_in *) &reply->addr;
71
72 if(ip->sin_addr.s_addr == ip_fwd->sin_addr.s_addr && strlen(reply->h_name) < 63)
73 {
74 rb_strlcpy(response, reply->h_name, sizeof(response));
75 status = 'O';
76 }
77 }
78 break;
79#ifdef RB_IPV6
80 case 'S':
81 {
82 struct sockaddr_in6 *ip, *ip_fwd;
83 ip = (struct sockaddr_in6 *) &req->addr;
84 ip_fwd = (struct sockaddr_in6 *) &reply->addr;
85
86 if(memcmp(&ip->sin6_addr, &ip_fwd->sin6_addr, sizeof(struct in6_addr)) == 0 && strlen(reply->h_name) < 63)
87 {
88 rb_strlcpy(response, reply->h_name, sizeof(response));
89 status = 'O';
90 }
91 }
92 break;
93#endif
94 default:
95 exit(7);
96 }
97
c7c009b5 98 rb_helper_write(authd_helper, "E %s %c %c %s", req->reqid, status, req->type, response);
8cf45447
AC
99cleanup:
100 rb_free(req);
101}
102
103void
104resolve_dns(int parc, char *parv[])
105{
106 struct dns_request *req;
107 char *requestid = parv[1];
108 char *qtype = parv[2];
109 char *rec = parv[3];
110 int type;
111
112 req = rb_malloc(sizeof(*req));
113 rb_strlcpy(req->reqid, requestid, sizeof(req->reqid));
114 req->type = *qtype;
115
116 switch (req->type)
117 {
118 case '4':
119 type = T_A;
8cf45447
AC
120 break;
121 case '6':
122 type = T_AAAA;
8cf45447
AC
123 break;
124 case 'R':
125 case 'S':
fa43f559
AC
126 if(!rb_inet_pton_sock(rec, (struct sockaddr *) &req->addr))
127 exit(6);
8cf45447
AC
128 type = T_PTR;
129 break;
130 }
131
132 req->query.ptr = req;
133 req->query.callback = submit_dns_answer;
134
fa43f559
AC
135 if (type != T_PTR)
136 gethost_byname_type(rec, &req->query, type);
137 else
138 gethost_byaddr(&req->addr, &req->query);
8cf45447 139}
394b8dde
EM
140
141void
142enumerate_nameservers(const char *rid, const char letter)
143{
144 char buf[40 * IRCD_MAXNS]; /* Plenty */
145 char *c = buf;
146 int i;
147
148 if (!irc_nscount)
149 {
150 /* Shouldn't happen */
151 rb_helper_write(authd_helper, "X %s %c NONAMESERVERS", rid, letter);
152 return;
153 }
154
155 for(i = 0; i < irc_nscount; i++)
156 {
157 char addr[40];
158 int ret;
159
160 rb_inet_ntop_sock((struct sockaddr *)&irc_nsaddr_list[i], addr, sizeof(addr));
161
162 if (!addr[0])
163 {
164 /* Shouldn't happen */
165 rb_helper_write(authd_helper, "X %s %c INVALIDNAMESERVER", rid, letter);
166 return;
167 }
168
169 ret = snprintf(c, 40, "%s ", addr);
170 c += (size_t)ret;
171 }
172
173 *(--c) = '\0';
174
175 rb_helper_write(authd_helper, "Y %s %c %s", rid, letter, buf);
176}
6445c1cf
EM
177
178void
179reload_nameservers(const char letter)
180{
181 /* Not a whole lot to it */
182 restart_resolver();
183}