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