]>
Commit | Line | Data |
---|---|---|
2b0cc3d3 EM |
1 | /* authd/providers/rdns.c - rDNS lookup provider for authd |
2 | * Copyright (c) 2016 Elizabeth Myers <elizabeth@interlinked.me> | |
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 "stdinc.h" | |
22 | #include "rb_commio.h" | |
23 | #include "authd.h" | |
24 | #include "provider.h" | |
db821ee9 | 25 | #include "notice.h" |
2b0cc3d3 EM |
26 | #include "res.h" |
27 | #include "dns.h" | |
28 | ||
29 | struct user_query | |
30 | { | |
2b0cc3d3 EM |
31 | struct dns_query *query; /* Pending DNS query */ |
32 | time_t timeout; /* When the request times out */ | |
33 | }; | |
34 | ||
35 | /* Goinked from old s_auth.c --Elizabeth */ | |
36 | static const char *messages[] = | |
37 | { | |
38 | "*** Looking up your hostname...", | |
39 | "*** Found your hostname", | |
40 | "*** Couldn't look up your hostname", | |
41 | "*** Your hostname is too long, ignoring hostname", | |
42 | }; | |
43 | ||
44 | typedef enum | |
45 | { | |
46 | REPORT_LOOKUP, | |
47 | REPORT_FOUND, | |
48 | REPORT_FAIL, | |
49 | REPORT_TOOLONG, | |
50 | } dns_message; | |
51 | ||
3e875f62 EM |
52 | static void client_fail(struct auth_client *auth, dns_message message); |
53 | static void client_success(struct auth_client *auth); | |
410fcc23 | 54 | static void dns_answer_callback(const char *res, bool status, query_type type, void *data); |
2b0cc3d3 EM |
55 | |
56 | static struct ev_entry *timeout_ev; | |
57 | static EVH timeout_dns_queries_event; | |
14505c84 | 58 | static int rdns_timeout = 15; |
2b0cc3d3 EM |
59 | |
60 | ||
61 | bool client_dns_init(void) | |
62 | { | |
14505c84 | 63 | timeout_ev = rb_event_addish("timeout_dns_queries_event", timeout_dns_queries_event, NULL, 1); |
2b0cc3d3 EM |
64 | return (timeout_ev != NULL); |
65 | } | |
66 | ||
67 | void client_dns_destroy(void) | |
68 | { | |
3e875f62 | 69 | struct auth_client *auth; |
aba29d5a | 70 | rb_dictionary_iter iter; |
2b0cc3d3 | 71 | |
ab33d608 | 72 | RB_DICTIONARY_FOREACH(auth, &iter, auth_clients) |
2b0cc3d3 | 73 | { |
3e875f62 EM |
74 | if(auth->data[PROVIDER_RDNS] != NULL) |
75 | client_fail(auth, REPORT_FAIL); | |
2b0cc3d3 EM |
76 | } |
77 | ||
78 | rb_event_delete(timeout_ev); | |
79 | } | |
80 | ||
81 | bool client_dns_start(struct auth_client *auth) | |
82 | { | |
83 | struct user_query *query = rb_malloc(sizeof(struct user_query)); | |
84 | ||
2b0cc3d3 EM |
85 | query->timeout = rb_current_time() + rdns_timeout; |
86 | ||
3e875f62 EM |
87 | auth->data[PROVIDER_RDNS] = query; |
88 | ||
410fcc23 | 89 | query->query = lookup_hostname(auth->c_ip, dns_answer_callback, auth); |
2b0cc3d3 | 90 | |
db821ee9 | 91 | notice_client(auth->cid, messages[REPORT_LOOKUP]); |
a7d5aea1 | 92 | set_provider_on(auth, PROVIDER_RDNS); |
2b0cc3d3 EM |
93 | return true; |
94 | } | |
95 | ||
96 | void client_dns_cancel(struct auth_client *auth) | |
97 | { | |
3e875f62 | 98 | struct user_query *query = auth->data[PROVIDER_RDNS]; |
2b0cc3d3 | 99 | |
3e875f62 EM |
100 | if(query != NULL) |
101 | client_fail(auth, REPORT_FAIL); | |
2b0cc3d3 EM |
102 | } |
103 | ||
104 | static void | |
410fcc23 | 105 | dns_answer_callback(const char *res, bool status, query_type type, void *data) |
2b0cc3d3 | 106 | { |
3e875f62 EM |
107 | struct auth_client *auth = data; |
108 | struct user_query *query = auth->data[PROVIDER_RDNS]; | |
2b0cc3d3 | 109 | |
3e875f62 EM |
110 | if(query == NULL || res == NULL || status == false) |
111 | client_fail(auth, REPORT_FAIL); | |
2b0cc3d3 | 112 | else if(strlen(res) > HOSTLEN) |
3e875f62 EM |
113 | client_fail(auth, REPORT_TOOLONG); |
114 | else | |
2b0cc3d3 | 115 | { |
3e875f62 EM |
116 | rb_strlcpy(auth->hostname, res, HOSTLEN + 1); |
117 | client_success(auth); | |
2b0cc3d3 EM |
118 | } |
119 | } | |
120 | ||
121 | /* Timeout outstanding queries */ | |
122 | static void timeout_dns_queries_event(void *notused) | |
123 | { | |
3e875f62 | 124 | struct auth_client *auth; |
aba29d5a | 125 | rb_dictionary_iter iter; |
2b0cc3d3 | 126 | |
ab33d608 | 127 | RB_DICTIONARY_FOREACH(auth, &iter, auth_clients) |
2b0cc3d3 | 128 | { |
3e875f62 | 129 | struct user_query *query = auth->data[PROVIDER_RDNS]; |
2b0cc3d3 | 130 | |
3e875f62 | 131 | if(query != NULL && query->timeout < rb_current_time()) |
2b0cc3d3 | 132 | { |
3e875f62 | 133 | client_fail(auth, REPORT_FAIL); |
2b0cc3d3 EM |
134 | return; |
135 | } | |
136 | } | |
137 | } | |
138 | ||
3e875f62 | 139 | static void client_fail(struct auth_client *auth, dns_message report) |
2b0cc3d3 | 140 | { |
3e875f62 EM |
141 | struct user_query *query = auth->data[PROVIDER_RDNS]; |
142 | ||
143 | if(query == NULL) | |
144 | return; | |
2b0cc3d3 EM |
145 | |
146 | rb_strlcpy(auth->hostname, "*", sizeof(auth->hostname)); | |
3e875f62 | 147 | |
db821ee9 | 148 | notice_client(auth->cid, messages[report]); |
2b0cc3d3 | 149 | cancel_query(query->query); |
3e875f62 EM |
150 | |
151 | rb_free(query); | |
152 | auth->data[PROVIDER_RDNS] = NULL; | |
153 | ||
2b0cc3d3 EM |
154 | provider_done(auth, PROVIDER_RDNS); |
155 | } | |
156 | ||
3e875f62 | 157 | static void client_success(struct auth_client *auth) |
2b0cc3d3 | 158 | { |
3e875f62 | 159 | struct user_query *query = auth->data[PROVIDER_RDNS]; |
2b0cc3d3 | 160 | |
db821ee9 | 161 | notice_client(auth->cid, messages[REPORT_FOUND]); |
2b0cc3d3 | 162 | cancel_query(query->query); |
3e875f62 EM |
163 | |
164 | rb_free(query); | |
165 | auth->data[PROVIDER_RDNS] = NULL; | |
166 | ||
2b0cc3d3 EM |
167 | provider_done(auth, PROVIDER_RDNS); |
168 | } | |
169 | ||
170 | struct auth_provider rdns_provider = | |
171 | { | |
172 | .id = PROVIDER_RDNS, | |
173 | .init = client_dns_init, | |
174 | .destroy = client_dns_destroy, | |
175 | .start = client_dns_start, | |
176 | .cancel = client_dns_cancel, | |
177 | .completed = NULL, | |
178 | }; |