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