ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/core/m_server.c
Revision: 3148
Committed: Fri Mar 14 12:34:45 2014 UTC (11 years, 5 months ago) by michael
Content type: text/x-csrc
File size: 15811 byte(s)
Log Message:
- m_server.c:mr_server(): check for bogus server ID

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 *
4 * Copyright (c) 1997-2014 ircd-hybrid development team
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 * USA
20 */
21
22 /*! \file m_server.c
23 * \brief Includes required functions for processing the SERVER/SID command.
24 * \version $Id$
25 */
26
27 #include "stdinc.h"
28 #include "list.h"
29 #include "client.h"
30 #include "event.h"
31 #include "hash.h"
32 #include "irc_string.h"
33 #include "ircd.h"
34 #include "numeric.h"
35 #include "conf.h"
36 #include "log.h"
37 #include "s_serv.h"
38 #include "s_user.h"
39 #include "send.h"
40 #include "parse.h"
41 #include "modules.h"
42
43
44 /* set_server_gecos()
45 *
46 * input - pointer to client
47 * output - NONE
48 * side effects - servers gecos field is set
49 */
50 static void
51 set_server_gecos(struct Client *client_p, const char *info)
52 {
53 const char *s = info;
54
55 /* check for (H) which is a hidden server */
56 if (!strncmp(s, "(H) ", 4))
57 {
58 SetHidden(client_p);
59 s = s + 4;
60 }
61
62 if (!EmptyString(s))
63 strlcpy(client_p->info, s, sizeof(client_p->info));
64 else
65 strlcpy(client_p->info, "(Unknown Location)", sizeof(client_p->info));
66 }
67
68 /* mr_server()
69 * parv[0] = command
70 * parv[1] = servername
71 * parv[2] = hopcount
72 * parv[3] = serverinfo
73 */
74 static int
75 mr_server(struct Client *client_p, struct Client *source_p,
76 int parc, char *parv[])
77 {
78 char *name;
79 struct Client *target_p;
80 int hop;
81
82 if (EmptyString(parv[3]))
83 {
84 sendto_one(client_p, "ERROR :No servername");
85 exit_client(client_p, client_p, "Wrong number of args");
86 return 0;
87 }
88
89 name = parv[1];
90 hop = atoi(parv[2]);
91
92 /*
93 * Reject a direct nonTS server connection if we're TS_ONLY -orabidoo
94 */
95 if (!DoesTS(client_p))
96 {
97 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
98 "Unauthorized server connection attempt from %s: Non-TS server "
99 "for server %s", get_client_name(client_p, HIDE_IP), name);
100 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
101 "Unauthorized server connection attempt from %s: Non-TS server "
102 "for server %s", get_client_name(client_p, MASK_IP), name);
103 exit_client(client_p, client_p, "Non-TS server");
104 return 0;
105 }
106
107 if (!valid_servname(name))
108 {
109 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
110 "Unauthorized server connection attempt from %s: Bogus server name "
111 "for server %s", get_client_name(client_p, HIDE_IP), name);
112 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
113 "Unauthorized server connection attempt from %s: Bogus server name "
114 "for server %s", get_client_name(client_p, MASK_IP), name);
115 exit_client(client_p, client_p, "Bogus server name");
116 return 0;
117 }
118
119 if (!valid_sid(client_p->id))
120 {
121 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
122 "Link %s introduced server with bogus server ID %s",
123 get_client_name(client_p, SHOW_IP), client_p->id);
124 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
125 "Link %s introduced server with bogus server ID %s",
126 get_client_name(client_p, MASK_IP), client_p->id);
127 sendto_one(client_p, "ERROR :Bogus server ID introduced");
128 exit_client(client_p, &me, "Bogus server ID intoduced");
129 return 0;
130 }
131
132 /* Now we just have to call check_server and everything should
133 * be check for us... -A1kmm.
134 */
135 switch (check_server(name, client_p))
136 {
137 case -1:
138 if (ConfigFileEntry.warn_no_nline)
139 {
140 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
141 "Unauthorized server connection attempt from %s: No entry for "
142 "servername %s", get_client_name(client_p, HIDE_IP), name);
143
144 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
145 "Unauthorized server connection attempt from %s: No entry for "
146 "servername %s", get_client_name(client_p, MASK_IP), name);
147 }
148
149 exit_client(client_p, client_p, "No connect{} block.");
150 return 0;
151 /* NOT REACHED */
152 break;
153
154 case -2:
155 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
156 "Unauthorized server connection attempt from %s: Bad password "
157 "for server %s", get_client_name(client_p, HIDE_IP), name);
158
159 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
160 "Unauthorized server connection attempt from %s: Bad password "
161 "for server %s", get_client_name(client_p, MASK_IP), name);
162
163 exit_client(client_p, client_p, "Invalid password.");
164 return 0;
165 /* NOT REACHED */
166 break;
167
168 case -3:
169 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
170 "Unauthorized server connection attempt from %s: Invalid host "
171 "for server %s", get_client_name(client_p, HIDE_IP), name);
172
173 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
174 "Unauthorized server connection attempt from %s: Invalid host "
175 "for server %s", get_client_name(client_p, MASK_IP), name);
176
177 exit_client(client_p, client_p, "Invalid host.");
178 return 0;
179 case -4:
180 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
181 "Unauthorized server connection attempt from %s: Invalid certificate fingerprint "
182 "for server %s", get_client_name(client_p, HIDE_IP), name);
183
184 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
185 "Unauthorized server connection attempt from %s: Invalid certificate fingerprint "
186 "for server %s", get_client_name(client_p, MASK_IP), name);
187
188 exit_client(client_p, client_p, "Invalid certificate fingerprint.");
189 return 0;
190 /* NOT REACHED */
191 break;
192 }
193
194 if ((target_p = hash_find_server(name)))
195 {
196 /* This link is trying feed me a server that I already have
197 * access through another path -- multiple paths not accepted
198 * currently, kill this link immediately!!
199 *
200 * Rather than KILL the link which introduced it, KILL the
201 * youngest of the two links. -avalon
202 *
203 * Definitely don't do that here. This is from an unregistered
204 * connect - A1kmm.
205 */
206 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
207 "Attempt to re-introduce server %s from %s",
208 name, get_client_name(client_p, HIDE_IP));
209 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
210 "Attempt to re-introduce server %s from %s",
211 name, get_client_name(client_p, MASK_IP));
212 sendto_one(client_p, "ERROR :Server already exists.");
213 exit_client(client_p, client_p, "Server already exists");
214 return 0;
215 }
216
217 if ((target_p = hash_find_id(client_p->id)))
218 {
219 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
220 "Attempt to re-introduce server %s SID %s from %s",
221 name, client_p->id,
222 get_client_name(client_p, HIDE_IP));
223 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
224 "Attempt to re-introduce server %s SID %s from %s",
225 name, client_p->id,
226 get_client_name(client_p, MASK_IP));
227 sendto_one(client_p, "ERROR :Server ID already exists.");
228 exit_client(client_p, client_p, "Server ID already exists");
229 return 0;
230 }
231
232 /* XXX If somehow there is a connect in progress and
233 * a connect comes in with same name toss the pending one,
234 * but only if it's not the same client! - Dianora
235 */
236 if ((target_p = find_servconn_in_progress(name)))
237 if (target_p != client_p)
238 exit_client(target_p, &me, "Overridden");
239
240 /* if we are connecting (Handshake), we already have the name from the
241 * connect{} block in client_p->name
242 */
243 strlcpy(client_p->name, name, sizeof(client_p->name));
244 set_server_gecos(client_p, parv[3]);
245 client_p->hopcount = hop;
246 server_estab(client_p);
247 return 0;
248 }
249
250 /* ms_sid()
251 * parv[0] = command
252 * parv[1] = servername
253 * parv[2] = hopcount
254 * parv[3] = sid of new server
255 * parv[4] = serverinfo
256 */
257 static int
258 ms_sid(struct Client *client_p, struct Client *source_p,
259 int parc, char *parv[])
260 {
261 dlink_node *ptr = NULL;
262 struct Client *target_p = NULL;
263 const struct MaskItem *conf = NULL;
264 int hlined = 0;
265 int llined = 0;
266 int hop = 0;
267
268 /* Just to be sure -A1kmm. */
269 if (!IsServer(source_p))
270 return 0;
271
272 if (EmptyString(parv[4]))
273 {
274 sendto_one(client_p, "ERROR :No servername");
275 return 0;
276 }
277
278 hop = atoi(parv[2]);
279
280 if (!valid_servname(parv[1]))
281 {
282 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
283 "Link %s introduced server with bogus server name %s",
284 get_client_name(client_p, SHOW_IP), parv[1]);
285 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
286 "Link %s introduced server with bogus server name %s",
287 get_client_name(client_p, MASK_IP), parv[1]);
288 sendto_one(client_p, "ERROR :Bogus server name introduced");
289 exit_client(client_p, &me, "Bogus server name intoduced");
290 return 0;
291 }
292
293 if (!valid_sid(parv[3]))
294 {
295 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
296 "Link %s introduced server with bogus server ID %s",
297 get_client_name(client_p, SHOW_IP), parv[3]);
298 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
299 "Link %s introduced server with bogus server ID %s",
300 get_client_name(client_p, MASK_IP), parv[3]);
301 sendto_one(client_p, "ERROR :Bogus server ID introduced");
302 exit_client(client_p, &me, "Bogus server ID intoduced");
303 return 0;
304 }
305
306 /* collision on SID? */
307 if ((target_p = hash_find_id(parv[3])))
308 {
309 sendto_one(client_p, "ERROR :SID %s already exists", parv[3]);
310 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
311 "Link %s cancelled, SID %s already exists",
312 get_client_name(client_p, SHOW_IP), parv[3]);
313 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
314 "Link %s cancelled, SID %s already exists",
315 client_p->name, parv[3]);
316 exit_client(client_p, &me, "SID Exists");
317 return 0;
318 }
319
320 /* collision on name? */
321 if ((target_p = hash_find_server(parv[1])))
322 {
323 sendto_one(client_p, "ERROR :Server %s already exists", parv[1]);
324 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
325 "Link %s cancelled, server %s already exists",
326 get_client_name(client_p, SHOW_IP), parv[1]);
327 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
328 "Link %s cancelled, server %s already exists",
329 client_p->name, parv[1]);
330 exit_client(client_p, &me, "Server Exists");
331 return 0;
332 }
333
334 /* XXX If somehow there is a connect in progress and
335 * a connect comes in with same name toss the pending one,
336 * but only if it's not the same client! - Dianora
337 */
338 if ((target_p = find_servconn_in_progress(parv[1])))
339 if (target_p != client_p)
340 exit_client(target_p, &me, "Overridden");
341
342 conf = client_p->localClient->confs.head->data;
343
344 /* See if the newly found server is behind a guaranteed
345 * leaf. If so, close the link.
346 */
347 DLINK_FOREACH(ptr, conf->leaf_list.head)
348 {
349 if (!match(ptr->data, parv[1]))
350 {
351 llined = 1;
352 break;
353 }
354 }
355
356 DLINK_FOREACH(ptr, conf->hub_list.head)
357 {
358 if (!match(ptr->data, parv[1]))
359 {
360 hlined = 1;
361 break;
362 }
363 }
364
365 /* Ok, this way this works is
366 *
367 * A server can have a CONF_HUB allowing it to introduce servers
368 * behind it.
369 *
370 * connect {
371 * name = "irc.bighub.net";
372 * hub_mask="*";
373 * ...
374 *
375 * That would allow "irc.bighub.net" to introduce anything it wanted..
376 *
377 * However
378 *
379 * connect {
380 * name = "irc.somehub.fi";
381 * hub_mask="*";
382 * leaf_mask="*.edu";
383 *...
384 * Would allow this server in finland to hub anything but
385 * .edu's
386 */
387
388 /* Ok, check client_p can hub the new server, and make sure it's not a LL */
389 if (!hlined)
390 {
391 /* OOOPs nope can't HUB */
392 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
393 "Non-Hub link %s introduced %s.",
394 get_client_name(client_p, SHOW_IP), parv[1]);
395 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
396 "Non-Hub link %s introduced %s.",
397 get_client_name(client_p, MASK_IP), parv[1]);
398 exit_client(source_p, &me, "No matching hub_mask.");
399 return 0;
400 }
401
402 /* Check for the new server being leafed behind this HUB */
403 if (llined)
404 {
405 /* OOOPs nope can't HUB this leaf */
406 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
407 "Link %s introduced leafed server %s.",
408 get_client_name(client_p, SHOW_IP), parv[1]);
409 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
410 "Link %s introduced leafed server %s.",
411 get_client_name(client_p, MASK_IP), parv[1]);
412 exit_client(client_p, &me, "Leafed Server.");
413 return 0;
414 }
415
416 target_p = make_client(client_p);
417 make_server(target_p);
418 target_p->hopcount = hop;
419 target_p->servptr = source_p;
420
421 strlcpy(target_p->name, parv[1], sizeof(target_p->name));
422 strlcpy(target_p->id, parv[3], sizeof(target_p->id));
423
424 set_server_gecos(target_p, parv[4]);
425 SetServer(target_p);
426
427 if (HasFlag(source_p, FLAGS_SERVICE) || find_matching_name_conf(CONF_SERVICE, target_p->name, NULL, NULL, 0))
428 AddFlag(target_p, FLAGS_SERVICE);
429
430 dlinkAdd(target_p, &target_p->node, &global_client_list);
431 dlinkAdd(target_p, make_dlink_node(), &global_serv_list);
432 dlinkAdd(target_p, &target_p->lnode, &target_p->servptr->serv->server_list);
433
434 hash_add_client(target_p);
435 hash_add_id(target_p);
436
437 sendto_server(client_p, NOCAPS, NOCAPS, ":%s SID %s %d %s :%s%s",
438 ID_or_name(source_p, client_p), target_p->name, hop + 1,
439 target_p->id, IsHidden(target_p) ? "(H) " : "", target_p->info);
440 sendto_realops_flags(UMODE_EXTERNAL, L_ALL, SEND_NOTICE,
441 "Server %s being introduced by %s",
442 target_p->name, source_p->name);
443 return 0;
444 }
445
446 static struct Message server_msgtab =
447 {
448 "SERVER", 0, 0, 4, MAXPARA, MFLG_SLOW, 0,
449 { mr_server, m_registered, m_ignore, m_ignore, m_registered, m_ignore }
450 };
451
452 static struct Message sid_msgtab =
453 {
454 "SID", 0, 0, 5, MAXPARA, MFLG_SLOW, 0,
455 { m_ignore, m_ignore, ms_sid, m_ignore, m_ignore, m_ignore }
456 };
457
458 static void
459 module_init(void)
460 {
461 mod_add_cmd(&sid_msgtab);
462 mod_add_cmd(&server_msgtab);
463 }
464
465 static void
466 module_exit(void)
467 {
468 mod_del_cmd(&sid_msgtab);
469 mod_del_cmd(&server_msgtab);
470 }
471
472 struct module module_entry =
473 {
474 .node = { NULL, NULL, NULL },
475 .name = NULL,
476 .version = "$Revision$",
477 .handle = NULL,
478 .modinit = module_init,
479 .modexit = module_exit,
480 .flags = MODULE_FLAG_CORE
481 };

Properties

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