ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/src/conf/auth.c
Revision: 729
Committed: Mon Jul 17 12:52:05 2006 UTC (20 years ago) by adx
Content type: text/x-csrc
File size: 8399 byte(s)
Log Message:
+ implemented auth{}

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * auth.c: Defines the auth{} block of ircd.conf.
4 *
5 * Copyright (C) 2006 by the Hybrid Development Team.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 * USA
21 *
22 * $Id$
23 */
24
25 #include "stdinc.h"
26 #include "conf/conf.h"
27 #include "client.h"
28 #include "numeric.h"
29 #include "send.h"
30
31 static unsigned int acb_type_auth;
32 static struct AuthConf tmpauth = {{0}, 0};
33 static dlink_list tmpuh = {0};
34
35 static const struct FlagMapping {
36 char letter;
37 const char *name;
38 unsigned int flag;
39 } flag_mappings[] = {
40 {'-', "no_tilde", AUTH_FLAG_NO_TILDE},
41 {'+', "have_ident", AUTH_FLAG_NEED_IDENT},
42 {'&', "need_password", AUTH_FLAG_NEED_PASSWORD},
43 {'$', "resv_exempt", AUTH_FLAG_RESV_EXEMPT},
44 {'=', "spoof_notice", AUTH_FLAG_SPOOF_NOTICE},
45 {'^', "kline_exempt", AUTH_FLAG_KLINE_EXEMPT},
46 {'_', "gline_exempt", AUTH_FLAG_GLINE_EXEMPT},
47 {'>', "exceed_limit", AUTH_FLAG_EXCEED_LIMIT},
48 {'<', "can_idle", AUTH_FLAG_CAN_IDLE},
49 {'|', "can_flood", AUTH_FLAG_CAN_FLOOD},
50 {0, "encrypted", AUTH_FLAG_ENCRYPTED},
51 {0, NULL, 0}
52 };
53
54 static int do_report_auth(struct AuthConf *, struct Client *);
55 static int check_auth_passwd(struct AuthConf *, const char *);
56
57 /*
58 * free_iline()
59 *
60 * Frees an auth{} block.
61 *
62 * inputs: pointer to struct AuthConf
63 * output: none
64 */
65 static void
66 free_iline(struct AuthConf *conf)
67 {
68 unref_class(conf->class_ptr);
69 MyFree(conf->spoof);
70 MyFree(conf->password);
71 MyFree(conf->redirserv);
72 acb_generic_free(&conf->access);
73 }
74
75 /*
76 * before_iline()
77 *
78 * Called before parsing a single auth{} block.
79 * Frees all temporary storage.
80 *
81 * inputs: none
82 * output: none
83 */
84 static void
85 before_iline(void)
86 {
87 while (tmpuh.head != NULL)
88 {
89 struct split_nuh_item *nuh = tmpuh.head->data;
90
91 dlinkDelete(&nuh->node, &tmpuh);
92
93 MyFree(nuh->userptr);
94 MyFree(nuh->hostptr);
95 MyFree(nuh);
96 }
97
98 MyFree(tmpauth.access.user);
99 MyFree(tmpauth.access.host);
100 MyFree(tmpauth.spoof);
101 MyFree(tmpauth.password);
102 MyFree(tmpauth.redirserv);
103
104 if (tmpauth.class_ptr != NULL)
105 unref_class(tmpauth.class_ptr);
106
107 memset(&tmpauth, 0, sizeof(tmpauth));
108 }
109
110 /*
111 * iline_user()
112 *
113 * Handles the "user=" field.
114 *
115 * inputs: the value
116 * output: none
117 */
118 static void
119 iline_user(void *value, void *unused)
120 {
121 struct split_nuh_item nuh, *uh;
122 char userbuf[USERLEN + 1];
123 char hostbuf[HOSTLEN + 1];
124
125 nuh.nuhmask = (char *) value;
126 nuh.nickptr = NULL;
127 nuh.userptr = userbuf;
128 nuh.hostptr = hostbuf;
129
130 nuh.nicksize = 0;
131 nuh.usersize = sizeof(userbuf);
132 nuh.hostsize = sizeof(hostbuf);
133
134 split_nuh(&nuh);
135
136 uh = MyMalloc(sizeof(*uh));
137 DupString(uh->userptr, userbuf);
138 DupString(uh->hostptr, hostbuf);
139 dlinkAddTail(uh, &uh->node, &tmpuh);
140 }
141
142 /*
143 * iline_class()
144 *
145 * Handles the "class=" field.
146 *
147 * inputs: the value
148 * output: none
149 */
150 static void
151 iline_class(void *value, void *unused)
152 {
153 if (tmpauth.class_ptr != NULL)
154 unref_class(tmpauth.class_ptr);
155
156 tmpauth.class_ptr = ref_class_by_name(value);
157 }
158
159 /*
160 * iline_flags()
161 *
162 * Handles the "flags=" list.
163 *
164 * inputs: pointer to a dlink_list of flag names
165 * output: none
166 */
167 static void
168 iline_flags(void *list, void *unused)
169 {
170 const struct FlagMapping *p;
171 int errors = NO;
172 dlink_node *ptr;
173
174 tmpauth.flags = 0;
175
176 DLINK_FOREACH(ptr, ((dlink_list *)list)->head)
177 {
178 const char *str = ptr->data;
179 int found = NO;
180
181 for (p = flag_mappings; p->name; ++p)
182 if (!irccmp(str, p->name))
183 {
184 found = YES;
185 tmpauth.flags |= p->flag;
186 break;
187 }
188
189 if (!found)
190 errors = YES;
191 }
192
193 if (errors)
194 parse_error("Invalid auth flags encountered, check your syntax");
195 }
196
197 /*
198 * iline_flag()
199 *
200 * Parses an old-style switch.
201 *
202 * inputs:
203 * state - YES/NO casted to void
204 * flag - flag value casted to void
205 * output: none
206 */
207 static void
208 iline_flag(void *state, void *flag)
209 {
210 if (state)
211 tmpauth.flags |= (unsigned long) flag;
212 else
213 tmpauth.flags &= ~((unsigned long) flag);
214 }
215
216 /*
217 * after_iline()
218 *
219 * Called after parsing a single auth{} block.
220 *
221 * inputs: none
222 * output: none
223 */
224 static void
225 after_iline(void)
226 {
227 if (tmpauth.class_ptr == NULL)
228 parse_error("Invalid or non-existant class in auth{}");
229 else if (dlink_list_length(&tmpuh) == 0)
230 parse_error("Incomplete operator{} block");
231 else
232 while (tmpuh.head != NULL)
233 {
234 struct split_nuh_item *nuh = tmpuh.head->data;
235 struct AuthConf *conf = MyMalloc(sizeof(struct AuthConf));
236 memcpy(conf, &tmpauth, sizeof(*conf));
237
238 conf->access.user = nuh->userptr;
239 conf->access.host = nuh->hostptr;
240 ref_class_by_ptr(conf->class_ptr);
241
242 if (tmpauth.spoof)
243 DupString(conf->spoof, tmpauth.spoof);
244 if (tmpauth.password)
245 DupString(conf->password, tmpauth.password);
246 if (tmpauth.redirserv)
247 DupString(conf->redirserv, tmpauth.redirserv);
248
249 add_access_conf(&conf->access);
250
251 dlinkDelete(&nuh->node, &tmpuh);
252 MyFree(nuh);
253 }
254
255 before_iline();
256 }
257
258 /*
259 * find_iline()
260 *
261 * Returns an auth entry matching the given user@host/ip.
262 *
263 * inputs:
264 * user - username part, can be NULL
265 * host - hostname part, can be NULL
266 * ip - IP address (with ss.sin_family set), can be NULL
267 * pwd - password given by the client
268 * output: pointer to AuthConf
269 */
270 struct AuthConf *
271 find_iline(const char *user, const char *host, const struct irc_ssaddr *ip,
272 const char *pwd)
273 {
274 return (struct AuthConf *) find_access_conf(acb_type_auth, user, host, ip,
275 (ACB_EXAMINE_HANDLER *) check_auth_passwd, (void *) pwd);
276 }
277
278 static int
279 check_auth_passwd(struct AuthConf *conf, const char *pwd)
280 {
281 if ((conf->flags & AUTH_FLAG_NEED_PASSWORD) || EmptyString(conf->password))
282 return YES;
283 return EmptyString(pwd) ? NO : !strcmp(conf->password, pwd);
284 }
285
286 /*
287 * report_auth()
288 *
289 * Execute a /STATS I request.
290 *
291 * inputs: a client to send to
292 * output: none
293 */
294 void
295 report_auth(struct Client *source_p)
296 {
297 enum_access_confs((ACB_EXAMINE_HANDLER *) do_report_auth, source_p);
298 }
299
300 static int
301 do_report_auth(struct AuthConf *conf, struct Client *source_p)
302 {
303 const struct FlagMapping *m;
304 char prefix[sizeof(flag_mappings) / sizeof(flag_mappings[0])];
305 char *p = prefix;
306
307 if (conf->access.type != acb_type_auth ||
308 (!MyOper(source_p) && conf->spoof))
309 return 0;
310
311 for (m = flag_mappings; m->name; m++)
312 if ((conf->flags & m->flag))
313 *p++ = m->letter;
314 *p = 0;
315
316 sendto_one(source_p, form_str(RPL_STATSILINE), me.name, source_p->name,
317 'I', conf->spoof ? conf->spoof : "*", prefix, conf->access.user,
318 (General.hide_spoof_ips && conf->spoof) ? "255.255.255.255" :
319 conf->access.host, conf->redirport, conf->class_ptr->name);
320 return 0;
321 }
322
323 /*
324 * init_ilines()
325 *
326 * Defines the auth{} conf section.
327 *
328 * inputs: none
329 * output: none
330 */
331 void
332 init_ilines(void)
333 {
334 struct ConfSection *s = add_conf_section("auth", 2);
335 const struct FlagMapping *p;
336
337 acb_type_auth = register_acb_type(free_iline);
338
339 s->before = before_iline;
340
341 s->def_field = add_conf_field(s, "user", CT_STRING, iline_user, NULL);
342 add_conf_field(s, "password", CT_STRING, NULL, &tmpauth.password);
343 add_conf_field(s, "class", CT_STRING, iline_class, NULL);
344 add_conf_field(s, "spoof", CT_STRING, NULL, &tmpauth.spoof);
345 add_conf_field(s, "redirserv", CT_STRING, NULL, &tmpauth.redirserv);
346 add_conf_field(s, "redirport", CT_NUMBER, NULL, &tmpauth.redirport);
347
348 add_conf_field(s, "flags", CT_LIST, iline_flags, NULL);
349 for (p = flag_mappings; p->name; ++p)
350 add_conf_field(s, p->name, CT_BOOL, iline_flag,
351 (void *) (unsigned long) p->flag);
352
353 s->after = after_iline;
354 }

Properties

Name Value
svn:eol-style native
svn:keywords "Id Revision"