ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/core/m_server.c
Revision: 3192
Committed: Sun Mar 23 19:46:39 2014 UTC (11 years, 5 months ago) by michael
Content type: text/x-csrc
File size: 15606 byte(s)
Log Message:
- Fixed compile error in ms_sid()
- Cleaned up find_chasing(). Removed useless third 'chasing' argument.

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 *source_p, int parc, char *parv[])
76 {
77 char *name;
78 struct Client *target_p;
79
80 if (EmptyString(parv[3]))
81 {
82 sendto_one(source_p, "ERROR :No servername");
83 exit_client(source_p, "Wrong number of args");
84 return 0;
85 }
86
87 name = parv[1];
88
89 /*
90 * Reject a direct nonTS server connection if we're TS_ONLY -orabidoo
91 */
92 if (!DoesTS(source_p))
93 {
94 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
95 "Unauthorized server connection attempt from %s: Non-TS server "
96 "for server %s", get_client_name(source_p, HIDE_IP), name);
97 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
98 "Unauthorized server connection attempt from %s: Non-TS server "
99 "for server %s", get_client_name(source_p, MASK_IP), name);
100 exit_client(source_p, "Non-TS server");
101 return 0;
102 }
103
104 if (!valid_servname(name))
105 {
106 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
107 "Unauthorized server connection attempt from %s: Bogus server name "
108 "for server %s", get_client_name(source_p, HIDE_IP), name);
109 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
110 "Unauthorized server connection attempt from %s: Bogus server name "
111 "for server %s", get_client_name(source_p, MASK_IP), name);
112 exit_client(source_p, "Bogus server name");
113 return 0;
114 }
115
116 if (!valid_sid(source_p->id))
117 {
118 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
119 "Link %s introduced server with bogus server ID %s",
120 get_client_name(source_p, SHOW_IP), source_p->id);
121 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
122 "Link %s introduced server with bogus server ID %s",
123 get_client_name(source_p, MASK_IP), source_p->id);
124 sendto_one(source_p, "ERROR :Bogus server ID introduced");
125 exit_client(source_p, "Bogus server ID intoduced");
126 return 0;
127 }
128
129 /* Now we just have to call check_server and everything should
130 * be check for us... -A1kmm.
131 */
132 switch (check_server(name, source_p))
133 {
134 case -1:
135 if (ConfigFileEntry.warn_no_nline)
136 {
137 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
138 "Unauthorized server connection attempt from %s: No entry for "
139 "servername %s", get_client_name(source_p, HIDE_IP), name);
140
141 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
142 "Unauthorized server connection attempt from %s: No entry for "
143 "servername %s", get_client_name(source_p, MASK_IP), name);
144 }
145
146 exit_client(source_p, "No connect{} block.");
147 return 0;
148 /* NOT REACHED */
149 break;
150
151 case -2:
152 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
153 "Unauthorized server connection attempt from %s: Bad password "
154 "for server %s", get_client_name(source_p, HIDE_IP), name);
155
156 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
157 "Unauthorized server connection attempt from %s: Bad password "
158 "for server %s", get_client_name(source_p, MASK_IP), name);
159
160 exit_client(source_p, "Invalid password.");
161 return 0;
162 /* NOT REACHED */
163 break;
164
165 case -3:
166 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
167 "Unauthorized server connection attempt from %s: Invalid host "
168 "for server %s", get_client_name(source_p, HIDE_IP), name);
169
170 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
171 "Unauthorized server connection attempt from %s: Invalid host "
172 "for server %s", get_client_name(source_p, MASK_IP), name);
173
174 exit_client(source_p, "Invalid host.");
175 return 0;
176 case -4:
177 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
178 "Unauthorized server connection attempt from %s: Invalid certificate fingerprint "
179 "for server %s", get_client_name(source_p, HIDE_IP), name);
180
181 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
182 "Unauthorized server connection attempt from %s: Invalid certificate fingerprint "
183 "for server %s", get_client_name(source_p, MASK_IP), name);
184
185 exit_client(source_p, "Invalid certificate fingerprint.");
186 return 0;
187 /* NOT REACHED */
188 break;
189 }
190
191 if ((target_p = hash_find_server(name)))
192 {
193 /* This link is trying feed me a server that I already have
194 * access through another path -- multiple paths not accepted
195 * currently, kill this link immediately!!
196 *
197 * Rather than KILL the link which introduced it, KILL the
198 * youngest of the two links. -avalon
199 *
200 * Definitely don't do that here. This is from an unregistered
201 * connect - A1kmm.
202 */
203 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
204 "Attempt to re-introduce server %s from %s",
205 name, get_client_name(source_p, HIDE_IP));
206 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
207 "Attempt to re-introduce server %s from %s",
208 name, get_client_name(source_p, MASK_IP));
209 sendto_one(source_p, "ERROR :Server already exists.");
210 exit_client(source_p, "Server already exists");
211 return 0;
212 }
213
214 if ((target_p = hash_find_id(source_p->id)))
215 {
216 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
217 "Attempt to re-introduce server %s SID %s from %s",
218 name, source_p->id,
219 get_client_name(source_p, HIDE_IP));
220 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
221 "Attempt to re-introduce server %s SID %s from %s",
222 name, source_p->id,
223 get_client_name(source_p, MASK_IP));
224 sendto_one(source_p, "ERROR :Server ID already exists.");
225 exit_client(source_p, "Server ID already exists");
226 return 0;
227 }
228
229 /* XXX If somehow there is a connect in progress and
230 * a connect comes in with same name toss the pending one,
231 * but only if it's not the same client! - Dianora
232 */
233 if ((target_p = find_servconn_in_progress(name)))
234 if (target_p != source_p)
235 exit_client(target_p, "Overridden");
236
237 /* if we are connecting (Handshake), we already have the name from the
238 * connect{} block in source_p->name
239 */
240 strlcpy(source_p->name, name, sizeof(source_p->name));
241 set_server_gecos(source_p, parv[3]);
242 source_p->hopcount = atoi(parv[2]);
243 server_estab(source_p);
244 return 0;
245 }
246
247 /* ms_sid()
248 * parv[0] = command
249 * parv[1] = servername
250 * parv[2] = hopcount
251 * parv[3] = sid of new server
252 * parv[4] = serverinfo
253 */
254 static int
255 ms_sid(struct Client *source_p, int parc, char *parv[])
256 {
257 dlink_node *ptr = NULL;
258 struct Client *target_p = NULL;
259 struct Client *client_p = source_p->from; /* XXX */
260 const struct MaskItem *conf = NULL;
261 int hlined = 0;
262 int llined = 0;
263
264 /* Just to be sure -A1kmm. */
265 if (!IsServer(source_p))
266 return 0;
267
268 if (EmptyString(parv[4]))
269 {
270 sendto_one(client_p, "ERROR :No servername");
271 return 0;
272 }
273
274 if (!valid_servname(parv[1]))
275 {
276 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
277 "Link %s introduced server with bogus server name %s",
278 get_client_name(client_p, SHOW_IP), parv[1]);
279 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
280 "Link %s introduced server with bogus server name %s",
281 get_client_name(client_p, MASK_IP), parv[1]);
282 sendto_one(client_p, "ERROR :Bogus server name introduced");
283 exit_client(client_p, "Bogus server name intoduced");
284 return 0;
285 }
286
287 if (!valid_sid(parv[3]))
288 {
289 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
290 "Link %s introduced server with bogus server ID %s",
291 get_client_name(client_p, SHOW_IP), parv[3]);
292 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
293 "Link %s introduced server with bogus server ID %s",
294 get_client_name(client_p, MASK_IP), parv[3]);
295 sendto_one(client_p, "ERROR :Bogus server ID introduced");
296 exit_client(client_p, "Bogus server ID intoduced");
297 return 0;
298 }
299
300 /* collision on SID? */
301 if ((target_p = hash_find_id(parv[3])))
302 {
303 sendto_one(client_p, "ERROR :SID %s already exists", parv[3]);
304 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
305 "Link %s cancelled, SID %s already exists",
306 get_client_name(client_p, SHOW_IP), parv[3]);
307 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
308 "Link %s cancelled, SID %s already exists",
309 client_p->name, parv[3]);
310 exit_client(client_p, "SID Exists");
311 return 0;
312 }
313
314 /* collision on name? */
315 if ((target_p = hash_find_server(parv[1])))
316 {
317 sendto_one(client_p, "ERROR :Server %s already exists", parv[1]);
318 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
319 "Link %s cancelled, server %s already exists",
320 get_client_name(client_p, SHOW_IP), parv[1]);
321 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
322 "Link %s cancelled, server %s already exists",
323 client_p->name, parv[1]);
324 exit_client(client_p, "Server Exists");
325 return 0;
326 }
327
328 /* XXX If somehow there is a connect in progress and
329 * a connect comes in with same name toss the pending one,
330 * but only if it's not the same client! - Dianora
331 */
332 if ((target_p = find_servconn_in_progress(parv[1])))
333 if (target_p != client_p)
334 exit_client(target_p, "Overridden");
335
336 conf = client_p->localClient->confs.head->data;
337
338 /* See if the newly found server is behind a guaranteed
339 * leaf. If so, close the link.
340 */
341 DLINK_FOREACH(ptr, conf->leaf_list.head)
342 {
343 if (!match(ptr->data, parv[1]))
344 {
345 llined = 1;
346 break;
347 }
348 }
349
350 DLINK_FOREACH(ptr, conf->hub_list.head)
351 {
352 if (!match(ptr->data, parv[1]))
353 {
354 hlined = 1;
355 break;
356 }
357 }
358
359 /* Ok, this way this works is
360 *
361 * A server can have a CONF_HUB allowing it to introduce servers
362 * behind it.
363 *
364 * connect {
365 * name = "irc.bighub.net";
366 * hub_mask="*";
367 * ...
368 *
369 * That would allow "irc.bighub.net" to introduce anything it wanted..
370 *
371 * However
372 *
373 * connect {
374 * name = "irc.somehub.fi";
375 * hub_mask="*";
376 * leaf_mask="*.edu";
377 *...
378 * Would allow this server in finland to hub anything but
379 * .edu's
380 */
381
382 /* Ok, check client_p can hub the new server, and make sure it's not a LL */
383 if (!hlined)
384 {
385 /* OOOPs nope can't HUB */
386 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
387 "Non-Hub link %s introduced %s.",
388 get_client_name(client_p, SHOW_IP), parv[1]);
389 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
390 "Non-Hub link %s introduced %s.",
391 get_client_name(client_p, MASK_IP), parv[1]);
392 exit_client(source_p, "No matching hub_mask.");
393 return 0;
394 }
395
396 /* Check for the new server being leafed behind this HUB */
397 if (llined)
398 {
399 /* OOOPs nope can't HUB this leaf */
400 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
401 "Link %s introduced leafed server %s.",
402 get_client_name(client_p, SHOW_IP), parv[1]);
403 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
404 "Link %s introduced leafed server %s.",
405 get_client_name(client_p, MASK_IP), parv[1]);
406 exit_client(client_p, "Leafed Server.");
407 return 0;
408 }
409
410 target_p = make_client(client_p);
411 make_server(target_p);
412 target_p->hopcount = atoi(parv[2]);
413 target_p->servptr = source_p;
414
415 strlcpy(target_p->name, parv[1], sizeof(target_p->name));
416 strlcpy(target_p->id, parv[3], sizeof(target_p->id));
417
418 set_server_gecos(target_p, parv[4]);
419 SetServer(target_p);
420
421 if (HasFlag(source_p, FLAGS_SERVICE) || find_matching_name_conf(CONF_SERVICE, target_p->name, NULL, NULL, 0))
422 AddFlag(target_p, FLAGS_SERVICE);
423
424 dlinkAdd(target_p, &target_p->node, &global_client_list);
425 dlinkAdd(target_p, make_dlink_node(), &global_serv_list);
426 dlinkAdd(target_p, &target_p->lnode, &target_p->servptr->serv->server_list);
427
428 hash_add_client(target_p);
429 hash_add_id(target_p);
430
431 sendto_server(client_p, NOCAPS, NOCAPS, ":%s SID %s %d %s :%s%s",
432 source_p->id, target_p->name, target_p->hopcount + 1,
433 target_p->id, IsHidden(target_p) ? "(H) " : "", target_p->info);
434 sendto_realops_flags(UMODE_EXTERNAL, L_ALL, SEND_NOTICE,
435 "Server %s being introduced by %s",
436 target_p->name, source_p->name);
437 return 0;
438 }
439
440 static struct Message server_msgtab =
441 {
442 "SERVER", 0, 0, 4, MAXPARA, MFLG_SLOW, 0,
443 { mr_server, m_registered, m_ignore, m_ignore, m_registered, m_ignore }
444 };
445
446 static struct Message sid_msgtab =
447 {
448 "SID", 0, 0, 5, MAXPARA, MFLG_SLOW, 0,
449 { m_ignore, m_ignore, ms_sid, m_ignore, m_ignore, m_ignore }
450 };
451
452 static void
453 module_init(void)
454 {
455 mod_add_cmd(&sid_msgtab);
456 mod_add_cmd(&server_msgtab);
457 }
458
459 static void
460 module_exit(void)
461 {
462 mod_del_cmd(&sid_msgtab);
463 mod_del_cmd(&server_msgtab);
464 }
465
466 struct module module_entry =
467 {
468 .node = { NULL, NULL, NULL },
469 .name = NULL,
470 .version = "$Revision$",
471 .handle = NULL,
472 .modinit = module_init,
473 .modexit = module_exit,
474 .flags = MODULE_FLAG_CORE
475 };

Properties

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