00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "stdinc.h"
00026 #include "tools.h"
00027 #include "client.h"
00028 #include "channel_mode.h"
00029 #include "common.h"
00030 #include "event.h"
00031 #include "fdlist.h"
00032 #include "hash.h"
00033 #include "irc_string.h"
00034 #include "sprintf_irc.h"
00035 #include "ircd.h"
00036 #include "list.h"
00037 #include "s_gline.h"
00038 #include "numeric.h"
00039 #include "packet.h"
00040 #include "s_auth.h"
00041 #include "s_bsd.h"
00042 #include "s_conf.h"
00043 #include "s_log.h"
00044 #include "s_misc.h"
00045 #include "s_serv.h"
00046 #include "send.h"
00047 #include "whowas.h"
00048 #include "s_user.h"
00049 #include "dbuf.h"
00050 #include "memory.h"
00051 #include "hostmask.h"
00052 #include "balloc.h"
00053 #include "listener.h"
00054 #include "irc_res.h"
00055 #include "userhost.h"
00056
00057 dlink_list listing_client_list = { NULL, NULL, 0 };
00058
00059 dlink_list global_client_list = {NULL, NULL, 0};
00060
00061 dlink_list unknown_list = {NULL, NULL, 0};
00062 dlink_list local_client_list = {NULL, NULL, 0};
00063 dlink_list serv_list = {NULL, NULL, 0};
00064 dlink_list global_serv_list = {NULL, NULL, 0};
00065 dlink_list oper_list = {NULL, NULL, 0};
00066
00067 static EVH check_pings;
00068
00069 static BlockHeap *client_heap = NULL;
00070 static BlockHeap *lclient_heap = NULL;
00071
00072 static dlink_list dead_list = { NULL, NULL, 0};
00073 static dlink_list abort_list = { NULL, NULL, 0};
00074
00075 static dlink_node *eac_next;
00076
00077 static void check_pings_list(dlink_list *);
00078 static void check_unknowns_list(void);
00079 static void ban_them(struct Client *client_p, struct ConfItem *conf);
00080
00081
00082
00083
00084
00085
00086
00087
00088 void
00089 init_client(void)
00090 {
00091
00092
00093
00094 client_heap = BlockHeapCreate("client", sizeof(struct Client), CLIENT_HEAP_SIZE);
00095 lclient_heap = BlockHeapCreate("local client", sizeof(struct LocalUser), LCLIENT_HEAP_SIZE);
00096 eventAdd("check_pings", check_pings, NULL, 5);
00097 }
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 struct Client *
00115 make_client(struct Client *from)
00116 {
00117 struct Client *client_p = BlockHeapAlloc(client_heap);
00118
00119 if (from == NULL)
00120 {
00121 client_p->from = client_p;
00122 client_p->since = client_p->lasttime = client_p->firsttime = CurrentTime;
00123
00124 client_p->localClient = BlockHeapAlloc(lclient_heap);
00125 client_p->localClient->registration = REG_INIT;
00126
00127 dlinkAdd(client_p, make_dlink_node(), &unknown_list);
00128 }
00129 else
00130 client_p->from = from;
00131
00132 client_p->hnext = client_p;
00133 client_p->status = STAT_UNKNOWN;
00134 strcpy(client_p->username, "unknown");
00135
00136 return client_p;
00137 }
00138
00139
00140
00141
00142
00143
00144
00145
00146 static void
00147 free_client(struct Client *client_p)
00148 {
00149 assert(client_p != NULL);
00150 assert(client_p != &me);
00151 assert(client_p->hnext == client_p);
00152 assert(client_p->channel.head == NULL);
00153 assert(dlink_list_length(&client_p->channel) == 0);
00154
00155 MyFree(client_p->away);
00156 MyFree(client_p->serv);
00157
00158 if (MyConnect(client_p))
00159 {
00160 assert(client_p->localClient->invited.head == NULL);
00161 assert(dlink_list_length(&client_p->localClient->invited) == 0);
00162 assert(IsClosing(client_p) && IsDead(client_p));
00163
00164 MyFree(client_p->localClient->response);
00165 MyFree(client_p->localClient->auth_oper);
00166
00167
00168
00169
00170 if (client_p->localClient->listener)
00171 {
00172 assert(0 < client_p->localClient->listener->ref_count);
00173 if (0 == --client_p->localClient->listener->ref_count &&
00174 !client_p->localClient->listener->active)
00175 free_listener(client_p->localClient->listener);
00176 }
00177
00178 dbuf_clear(&client_p->localClient->buf_recvq);
00179 dbuf_clear(&client_p->localClient->buf_sendq);
00180
00181 BlockHeapFree(lclient_heap, client_p->localClient);
00182 }
00183
00184 BlockHeapFree(client_heap, client_p);
00185 }
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 static void
00214 check_pings(void *notused)
00215 {
00216 check_pings_list(&local_client_list);
00217 check_pings_list(&serv_list);
00218 check_unknowns_list();
00219 }
00220
00221
00222
00223
00224
00225
00226
00227 static void
00228 check_pings_list(dlink_list *list)
00229 {
00230 char scratch[32];
00231 struct Client *client_p;
00232 int ping, pingwarn;
00233 dlink_node *ptr, *next_ptr;
00234
00235 DLINK_FOREACH_SAFE(ptr, next_ptr, list->head)
00236 {
00237 client_p = ptr->data;
00238
00239
00240
00241
00242
00243 if (IsDead(client_p))
00244 {
00245
00246 continue;
00247 }
00248
00249 if (client_p->localClient->reject_delay > 0)
00250 {
00251 if (client_p->localClient->reject_delay <= CurrentTime)
00252 exit_client(client_p, &me, "Rejected");
00253 continue;
00254 }
00255
00256 if (GlobalSetOptions.idletime && IsClient(client_p))
00257 {
00258 if (!IsExemptKline(client_p) && !IsOper(client_p) &&
00259 !IsIdlelined(client_p) &&
00260 ((CurrentTime - client_p->localClient->last) > GlobalSetOptions.idletime))
00261 {
00262 struct ConfItem *conf;
00263 struct AccessItem *aconf;
00264
00265 conf = make_conf_item(KLINE_TYPE);
00266 aconf = (struct AccessItem *)map_to_conf(conf);
00267
00268 DupString(aconf->host, client_p->host);
00269 DupString(aconf->reason, "idle exceeder");
00270 DupString(aconf->user, client_p->username);
00271 aconf->hold = CurrentTime + 60;
00272 add_temp_line(conf);
00273
00274 sendto_realops_flags(UMODE_ALL, L_ALL,
00275 "Idle time limit exceeded for %s - temp k-lining",
00276 get_client_name(client_p, HIDE_IP));
00277 exit_client(client_p, &me, aconf->reason);
00278 continue;
00279 }
00280 }
00281
00282 if (!IsRegistered(client_p))
00283 ping = CONNECTTIMEOUT, pingwarn = 0;
00284 else
00285 ping = get_client_ping(client_p, &pingwarn);
00286
00287 if (ping < CurrentTime - client_p->lasttime)
00288 {
00289 if (!IsPingSent(client_p))
00290 {
00291
00292
00293
00294
00295
00296 SetPingSent(client_p);
00297 ClearPingWarning(client_p);
00298 client_p->lasttime = CurrentTime - ping;
00299 sendto_one(client_p, "PING :%s", ID_or_name(&me, client_p));
00300 }
00301 else
00302 {
00303 if (CurrentTime - client_p->lasttime >= 2 * ping)
00304 {
00305
00306
00307
00308
00309 if (IsServer(client_p) || IsHandshake(client_p))
00310 {
00311 sendto_realops_flags(UMODE_ALL, L_ADMIN,
00312 "No response from %s, closing link",
00313 get_client_name(client_p, HIDE_IP));
00314 sendto_realops_flags(UMODE_ALL, L_OPER,
00315 "No response from %s, closing link",
00316 get_client_name(client_p, MASK_IP));
00317 ilog(L_NOTICE, "No response from %s, closing link",
00318 get_client_name(client_p, HIDE_IP));
00319 }
00320
00321 ircsprintf(scratch, "Ping timeout: %d seconds",
00322 (int)(CurrentTime - client_p->lasttime));
00323 exit_client(client_p, &me, scratch);
00324 }
00325 else if (!IsPingWarning(client_p) && pingwarn > 0 &&
00326 (IsServer(client_p) || IsHandshake(client_p)) &&
00327 CurrentTime - client_p->lasttime >= ping + pingwarn)
00328 {
00329
00330
00331
00332
00333 SetPingWarning(client_p);
00334 sendto_realops_flags(UMODE_ALL, L_ADMIN,
00335 "Warning, no response from %s in %d seconds",
00336 get_client_name(client_p, HIDE_IP), pingwarn);
00337 sendto_realops_flags(UMODE_ALL, L_OPER,
00338 "Warning, no response from %s in %d seconds",
00339 get_client_name(client_p, MASK_IP), pingwarn);
00340 ilog(L_NOTICE, "No response from %s in %d seconds",
00341 get_client_name(client_p, HIDE_IP), pingwarn);
00342 }
00343 }
00344 }
00345 }
00346 }
00347
00348
00349
00350
00351
00352
00353
00354 static void
00355 check_unknowns_list(void)
00356 {
00357 dlink_node *ptr, *next_ptr;
00358
00359 DLINK_FOREACH_SAFE(ptr, next_ptr, unknown_list.head)
00360 {
00361 struct Client *client_p = ptr->data;
00362
00363 if (client_p->localClient->reject_delay > 0)
00364 {
00365 if (client_p->localClient->reject_delay <= CurrentTime)
00366 exit_client(client_p, &me, "Rejected");
00367 continue;
00368 }
00369
00370
00371
00372
00373
00374 if (IsAuthFinished(client_p) && (CurrentTime - client_p->firsttime) > 30)
00375 exit_client(client_p, &me, "Registration timed out");
00376 }
00377 }
00378
00379
00380
00381
00382
00383
00384
00385
00386 void
00387 check_conf_klines(void)
00388 {
00389 struct Client *client_p = NULL;
00390 struct AccessItem *aconf = NULL;
00391 struct ConfItem *conf = NULL;
00392 dlink_node *ptr, *next_ptr;
00393
00394 DLINK_FOREACH_SAFE(ptr, next_ptr, local_client_list.head)
00395 {
00396 client_p = ptr->data;
00397
00398
00399
00400 if (IsDead(client_p) || !IsClient(client_p))
00401 continue;
00402
00403
00404 if ((aconf = find_dline_conf(&client_p->localClient->ip,
00405 client_p->localClient->aftype)) != NULL)
00406 {
00407 if (aconf->status & CONF_EXEMPTDLINE)
00408 continue;
00409
00410 conf = unmap_conf_item(aconf);
00411 ban_them(client_p, conf);
00412 continue;
00413 }
00414
00415 if (ConfigFileEntry.glines && (aconf = find_gline(client_p)))
00416 {
00417 if (IsExemptKline(client_p) ||
00418 IsExemptGline(client_p))
00419 {
00420 sendto_realops_flags(UMODE_ALL, L_ALL,
00421 "GLINE over-ruled for %s, client is %sline_exempt",
00422 get_client_name(client_p, HIDE_IP), IsExemptKline(client_p) ? "k" : "g");
00423 continue;
00424 }
00425
00426 conf = unmap_conf_item(aconf);
00427 ban_them(client_p, conf);
00428
00429 continue;
00430 }
00431
00432 if ((aconf = find_kill(client_p)) != NULL)
00433 {
00434
00435
00436 if (IsExemptKline(client_p))
00437 {
00438 sendto_realops_flags(UMODE_ALL, L_ALL,
00439 "KLINE over-ruled for %s, client is kline_exempt",
00440 get_client_name(client_p, HIDE_IP));
00441 continue;
00442 }
00443
00444 conf = unmap_conf_item(aconf);
00445 ban_them(client_p, conf);
00446 continue;
00447 }
00448
00449
00450 if ((conf = find_matching_name_conf(XLINE_TYPE, client_p->info,
00451 NULL, NULL, 0)) != NULL ||
00452 (conf = find_matching_name_conf(RXLINE_TYPE, client_p->info,
00453 NULL, NULL, 0)) != NULL)
00454 {
00455 ban_them(client_p, conf);
00456 continue;
00457 }
00458 }
00459
00460
00461 DLINK_FOREACH_SAFE(ptr, next_ptr, unknown_list.head)
00462 {
00463 client_p = ptr->data;
00464
00465 if ((aconf = find_dline_conf(&client_p->localClient->ip,
00466 client_p->localClient->aftype)))
00467 {
00468 if (aconf->status & CONF_EXEMPTDLINE)
00469 continue;
00470
00471 exit_client(client_p, &me, "D-lined");
00472 }
00473 }
00474 }
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484 static void
00485 ban_them(struct Client *client_p, struct ConfItem *conf)
00486 {
00487 const char *user_reason = NULL;
00488 const char *channel_reason = NULL;
00489 struct AccessItem *aconf = NULL;
00490 struct MatchItem *xconf = NULL;
00491 const char *type_string = NULL;
00492 const char dline_string[] = "D-line";
00493 const char kline_string[] = "K-line";
00494 const char gline_string[] = "G-line";
00495 const char xline_string[] = "X-line";
00496
00497 switch (conf->type)
00498 {
00499 case RKLINE_TYPE:
00500 case KLINE_TYPE:
00501 type_string = kline_string;
00502 aconf = map_to_conf(conf);
00503 break;
00504 case DLINE_TYPE:
00505 type_string = dline_string;
00506 aconf = map_to_conf(conf);
00507 break;
00508 case GLINE_TYPE:
00509 type_string = gline_string;
00510 aconf = map_to_conf(conf);
00511 break;
00512 case RXLINE_TYPE:
00513 case XLINE_TYPE:
00514 type_string = xline_string;
00515 xconf = map_to_conf(conf);
00516 ++xconf->count;
00517 break;
00518 default:
00519 assert(0);
00520 break;
00521 }
00522
00523 if (ConfigFileEntry.kline_with_reason)
00524 {
00525 if (aconf != NULL)
00526 user_reason = aconf->reason ? aconf->reason : type_string;
00527 if (xconf != NULL)
00528 user_reason = xconf->reason ? xconf->reason : type_string;
00529 }
00530 else
00531 user_reason = type_string;
00532
00533 if (ConfigFileEntry.kline_reason != NULL)
00534 channel_reason = ConfigFileEntry.kline_reason;
00535 else
00536 channel_reason = user_reason;
00537
00538 sendto_realops_flags(UMODE_ALL, L_ALL, "%s active for %s",
00539 type_string, get_client_name(client_p, HIDE_IP));
00540
00541 if (IsClient(client_p))
00542 sendto_one(client_p, form_str(ERR_YOUREBANNEDCREEP),
00543 me.name, client_p->name, user_reason);
00544
00545 exit_client(client_p, &me, channel_reason);
00546 }
00547
00548
00549
00550
00551
00552
00553
00554 static void
00555 update_client_exit_stats(struct Client *client_p)
00556 {
00557 if (IsServer(client_p))
00558 {
00559 sendto_realops_flags(UMODE_EXTERNAL, L_ALL,
00560 "Server %s split from %s",
00561 client_p->name, client_p->servptr->name);
00562 }
00563 else if (IsClient(client_p))
00564 {
00565 --Count.total;
00566 if (IsOper(client_p))
00567 --Count.oper;
00568 if (IsInvisible(client_p))
00569 --Count.invisi;
00570 }
00571
00572 if (splitchecking && !splitmode)
00573 check_splitmode(NULL);
00574 }
00575
00576
00577
00578
00579
00580
00581
00582
00583 struct Client *
00584 find_person(const struct Client *client_p, const char *name)
00585 {
00586 struct Client *c2ptr;
00587
00588 if (IsDigit(*name))
00589 {
00590 if ((c2ptr = hash_find_id(name)) != NULL)
00591 {
00592
00593 if (IsInvisible(c2ptr) && !IsServer(client_p))
00594 c2ptr = NULL;
00595 }
00596 }
00597 else
00598 c2ptr = find_client(name);
00599
00600 return ((c2ptr != NULL && IsClient(c2ptr)) ? c2ptr : NULL);
00601 }
00602
00603
00604
00605
00606
00607
00608
00609 struct Client *
00610 find_chasing(struct Client *client_p, struct Client *source_p, const char *user, int *chasing)
00611 {
00612 struct Client *who = find_person(client_p, user);
00613
00614 if (chasing)
00615 *chasing = 0;
00616
00617 if (who)
00618 return(who);
00619
00620 if (IsDigit(*user))
00621 return(NULL);
00622
00623 if ((who = get_history(user,
00624 (time_t)ConfigFileEntry.kill_chase_time_limit))
00625 == NULL)
00626 {
00627 sendto_one(source_p, form_str(ERR_NOSUCHNICK),
00628 me.name, source_p->name, user);
00629 return(NULL);
00630 }
00631
00632 if (chasing)
00633 *chasing = 1;
00634
00635 return(who);
00636 }
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656 const char *
00657 get_client_name(struct Client *client, int showip)
00658 {
00659 static char nbuf[HOSTLEN * 2 + USERLEN + 5];
00660
00661 assert(client != NULL);
00662
00663 if (irccmp(client->name, client->host) == 0)
00664 return(client->name);
00665
00666 if (ConfigServerHide.hide_server_ips)
00667 if (IsServer(client) || IsConnecting(client) || IsHandshake(client))
00668 showip = MASK_IP;
00669
00670 if (ConfigFileEntry.hide_spoof_ips)
00671 if (showip == SHOW_IP && IsIPSpoof(client))
00672 showip = MASK_IP;
00673
00674
00675 switch (showip)
00676 {
00677 case SHOW_IP:
00678 if (MyConnect(client))
00679 {
00680 ircsprintf(nbuf, "%s[%s@%s]", client->name, client->username,
00681 client->sockhost);
00682 break;
00683 }
00684 case MASK_IP:
00685 ircsprintf(nbuf, "%s[%s@255.255.255.255]", client->name,
00686 client->username);
00687 break;
00688 default:
00689 ircsprintf(nbuf, "%s[%s@%s]", client->name, client->username,
00690 client->host);
00691 }
00692
00693 return(nbuf);
00694 }
00695
00696 void
00697 free_exited_clients(void)
00698 {
00699 dlink_node *ptr, *next;
00700 struct Client *target_p;
00701
00702 DLINK_FOREACH_SAFE(ptr, next, dead_list.head)
00703 {
00704 target_p = ptr->data;
00705
00706 if (ptr->data == NULL)
00707 {
00708 sendto_realops_flags(UMODE_ALL, L_ALL,
00709 "Warning: null client on dead_list!");
00710 dlinkDelete(ptr, &dead_list);
00711 free_dlink_node(ptr);
00712 continue;
00713 }
00714
00715 free_client(target_p);
00716 dlinkDelete(ptr, &dead_list);
00717 free_dlink_node(ptr);
00718 }
00719 }
00720
00721
00722
00723
00724
00725
00726
00727 static void
00728 exit_one_client(struct Client *source_p, const char *quitmsg)
00729 {
00730 dlink_node *lp = NULL, *next_lp = NULL;
00731
00732 assert(!IsMe(source_p));
00733
00734 if (IsServer(source_p))
00735 {
00736 dlinkDelete(&source_p->lnode, &source_p->servptr->serv->servers);
00737
00738 if ((lp = dlinkFindDelete(&global_serv_list, source_p)) != NULL)
00739 free_dlink_node(lp);
00740
00741 if (!MyConnect(source_p))
00742 {
00743 source_p->from->serv->dep_servers--;
00744 assert(source_p->from->serv->dep_servers > 0);
00745 }
00746 }
00747 else if (IsClient(source_p))
00748 {
00749 if (source_p->servptr->serv != NULL)
00750 dlinkDelete(&source_p->lnode, &source_p->servptr->serv->users);
00751
00752
00753
00754
00755
00756
00757 sendto_common_channels_local(source_p, 0, ":%s!%s@%s QUIT :%s",
00758 source_p->name, source_p->username,
00759 source_p->host, quitmsg);
00760 DLINK_FOREACH_SAFE(lp, next_lp, source_p->channel.head)
00761 remove_user_from_channel(lp->data);
00762
00763
00764 del_all_accepts(source_p);
00765 add_history(source_p, 0);
00766 off_history(source_p);
00767
00768 if (!MyConnect(source_p))
00769 {
00770 source_p->from->serv->dep_users--;
00771 assert(source_p->from->serv->dep_users >= 0);
00772 }
00773 else
00774 {
00775
00776 DLINK_FOREACH_SAFE(lp, next_lp, source_p->localClient->invited.head)
00777 del_invite(lp->data, source_p);
00778 }
00779 }
00780
00781
00782 if (HasID(source_p))
00783 hash_del_id(source_p);
00784 if (source_p->name[0])
00785 hash_del_client(source_p);
00786
00787 if (IsUserHostIp(source_p))
00788 delete_user_host(source_p->username, source_p->host, !MyConnect(source_p));
00789
00790
00791
00792
00793
00794 if (source_p != NULL && source_p->node.next != NULL)
00795 dlinkDelete(&source_p->node, &global_client_list);
00796
00797 update_client_exit_stats(source_p);
00798
00799
00800 assert(dlinkFind(&dead_list, source_p) == NULL);
00801
00802
00803 SetDead(source_p);
00804 dlinkAdd(source_p, make_dlink_node(), &dead_list);
00805 }
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816 static void
00817 recurse_send_quits(struct Client *original_source_p, struct Client *source_p,
00818 struct Client *from, struct Client *to, const char *comment,
00819 const char *splitstr, const char *myname)
00820 {
00821 dlink_node *ptr, *next;
00822 struct Client *target_p;
00823 int hidden = match(myname, source_p->name);
00824
00825 assert(to != source_p);
00826
00827
00828
00829
00830
00831
00832
00833 if (hidden || !IsCapable(to, CAP_QS))
00834 DLINK_FOREACH_SAFE(ptr, next, source_p->serv->users.head)
00835 {
00836 target_p = ptr->data;
00837 sendto_one(to, ":%s QUIT :%s", target_p->name, splitstr);
00838 }
00839
00840 DLINK_FOREACH_SAFE(ptr, next, source_p->serv->servers.head)
00841 recurse_send_quits(original_source_p, ptr->data, from, to,
00842 comment, splitstr, myname);
00843
00844 if (!hidden && ((source_p == original_source_p && to != from) ||
00845 !IsCapable(to, CAP_QS)))
00846 {
00847
00848
00849 sendto_one(to, "SQUIT %s :%s", ID_or_name(source_p, to), comment);
00850 }
00851 }
00852
00853
00854
00855
00856
00857
00858
00859 static void
00860 recurse_remove_clients(struct Client *source_p, const char *quitmsg)
00861 {
00862 dlink_node *ptr, *next;
00863
00864 DLINK_FOREACH_SAFE(ptr, next, source_p->serv->users.head)
00865 exit_one_client(ptr->data, quitmsg);
00866
00867 DLINK_FOREACH_SAFE(ptr, next, source_p->serv->servers.head)
00868 {
00869 recurse_remove_clients(ptr->data, quitmsg);
00870 exit_one_client(ptr->data, quitmsg);
00871 }
00872
00873 assert(source_p->serv->dep_servers == 1);
00874 assert(source_p->serv->dep_users == 0);
00875 }
00876
00877
00878
00879
00880
00881
00882 static void
00883 remove_dependents(struct Client *source_p, struct Client *from,
00884 const char *comment, const char *splitstr)
00885 {
00886 struct Client *to;
00887 struct ConfItem *conf;
00888 static char myname[HOSTLEN+1];
00889 dlink_node *ptr;
00890
00891 DLINK_FOREACH(ptr, serv_list.head)
00892 {
00893 to = ptr->data;
00894
00895 if ((conf = to->serv->sconf) != NULL)
00896 strlcpy(myname, my_name_for_link(conf), sizeof(myname));
00897 else
00898 strlcpy(myname, me.name, sizeof(myname));
00899 recurse_send_quits(source_p, source_p, from, to,
00900 comment, splitstr, myname);
00901 }
00902
00903 recurse_remove_clients(source_p, splitstr);
00904 }
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924 void
00925 exit_client(struct Client *source_p, struct Client *from, const char *comment)
00926 {
00927 dlink_node *m;
00928
00929 if (MyConnect(source_p))
00930 {
00931
00932
00933
00934 if (IsClosing(source_p))
00935 return;
00936
00937 SetClosing(source_p);
00938
00939 if (IsIpHash(source_p))
00940 remove_one_ip(&source_p->localClient->ip);
00941
00942 delete_auth(source_p);
00943
00944
00945
00946
00947
00948
00949
00950 if (!IsRegistered(source_p))
00951 {
00952 if ((m = dlinkFindDelete(&unknown_list, source_p)) != NULL)
00953 free_dlink_node(m);
00954 }
00955 else if (IsClient(source_p))
00956 {
00957 Count.local--;
00958
00959 if (IsOper(source_p))
00960 {
00961 if ((m = dlinkFindDelete(&oper_list, source_p)) != NULL)
00962 free_dlink_node(m);
00963 }
00964
00965 dlinkDelete(&source_p->localClient->lclient_node, &local_client_list);
00966 if (source_p->localClient->list_task != NULL)
00967 free_list_task(source_p->localClient->list_task, source_p);
00968
00969 sendto_realops_flags(UMODE_CCONN, L_ALL, "Client exiting: %s (%s@%s) [%s] [%s]",
00970 source_p->name, source_p->username, source_p->host, comment,
00971 ConfigFileEntry.hide_spoof_ips && IsIPSpoof(source_p) ?
00972 "255.255.255.255" : source_p->sockhost);
00973 sendto_realops_flags(UMODE_CCONN_FULL, L_ALL, "CLIEXIT: %s %s %s %s 0 %s",
00974 source_p->name,
00975 source_p->username,
00976 source_p->host,
00977
00978 ConfigFileEntry.hide_spoof_ips && IsIPSpoof(source_p) ?
00979 "255.255.255.255" : source_p->sockhost,
00980 comment);
00981 }
00982
00983
00984
00985
00986
00987 if (IsServer(source_p) || IsConnecting(source_p) ||
00988 IsHandshake(source_p))
00989 {
00990 if ((m = dlinkFindDelete(&serv_list, source_p)) != NULL)
00991 {
00992 free_dlink_node(m);
00993 unset_chcap_usage_counts(source_p);
00994 }
00995
00996 if (IsServer(source_p))
00997 {
00998 Count.myserver--;
00999 if (ServerInfo.hub)
01000 remove_lazylink_flags(source_p->localClient->serverMask);
01001 else
01002 uplink = NULL;
01003 }
01004 }
01005
01006 log_user_exit(source_p);
01007
01008 if (!IsDead(source_p))
01009 {
01010 if (IsServer(source_p))
01011 {
01012
01013 sendto_one(source_p, ":%s SQUIT %s :%s",
01014 ID_or_name(from, source_p), me.name, comment);
01015 }
01016
01017 sendto_one(source_p, "ERROR :Closing Link: %s (%s)",
01018 source_p->host, comment);
01019 }
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032 close_connection(source_p);
01033 }
01034
01035 if (IsServer(source_p))
01036 {
01037 char splitstr[HOSTLEN + HOSTLEN + 2];
01038
01039
01040 assert(source_p->serv != NULL && source_p->servptr != NULL);
01041
01042 if (ConfigServerHide.hide_servers)
01043
01044
01045
01046 strcpy(splitstr, "*.net *.split");
01047 else
01048 snprintf(splitstr, sizeof(splitstr), "%s %s",
01049 source_p->servptr->name, source_p->name);
01050
01051 remove_dependents(source_p, from->from, comment, splitstr);
01052
01053 if (source_p->servptr == &me)
01054 {
01055 sendto_realops_flags(UMODE_ALL, L_ALL,
01056 "%s was connected for %d seconds. %llu/%llu sendK/recvK.",
01057 source_p->name, (int)(CurrentTime - source_p->firsttime),
01058 source_p->localClient->send.bytes >> 10,
01059 source_p->localClient->recv.bytes >> 10);
01060 ilog(L_NOTICE, "%s was connected for %d seconds. %llu/%llu sendK/recvK.",
01061 source_p->name, (int)(CurrentTime - source_p->firsttime),
01062 source_p->localClient->send.bytes >> 10,
01063 source_p->localClient->recv.bytes >> 10);
01064 }
01065 }
01066 else if (IsClient(source_p) && !IsKilled(source_p))
01067 {
01068 sendto_server(from->from, source_p, NULL, CAP_TS6, NOCAPS, NOFLAGS,
01069 ":%s QUIT :%s", ID(source_p), comment);
01070 sendto_server(from->from, source_p, NULL, NOCAPS, CAP_TS6, NOFLAGS,
01071 ":%s QUIT :%s", source_p->name, comment);
01072 }
01073
01074
01075 assert(dlinkFind(&unknown_list, source_p) == NULL);
01076 assert(dlinkFind(&local_client_list, source_p) == NULL);
01077 assert(dlinkFind(&serv_list, source_p) == NULL);
01078 assert(dlinkFind(&oper_list, source_p) == NULL);
01079
01080 exit_one_client(source_p, comment);
01081 }
01082
01083
01084
01085
01086
01087 void
01088 dead_link_on_write(struct Client *client_p, int ierrno)
01089 {
01090 dlink_node *ptr;
01091
01092 if (IsDefunct(client_p))
01093 return;
01094
01095 dbuf_clear(&client_p->localClient->buf_recvq);
01096 dbuf_clear(&client_p->localClient->buf_sendq);
01097
01098 assert(dlinkFind(&abort_list, client_p) == NULL);
01099 ptr = make_dlink_node();
01100
01101 dlinkAddTail(client_p, ptr, &abort_list);
01102
01103 if (eac_next == NULL)
01104 eac_next = ptr;
01105
01106 SetDead(client_p);
01107 }
01108
01109
01110
01111
01112
01113 void
01114 dead_link_on_read(struct Client *client_p, int error)
01115 {
01116 char errmsg[255];
01117 int current_error;
01118
01119 if (IsDefunct(client_p))
01120 return;
01121
01122 dbuf_clear(&client_p->localClient->buf_recvq);
01123 dbuf_clear(&client_p->localClient->buf_sendq);
01124
01125 current_error = get_sockerr(client_p->localClient->fd.fd);
01126
01127 if (IsServer(client_p) || IsHandshake(client_p))
01128 {
01129 int connected = CurrentTime - client_p->firsttime;
01130
01131 if (error == 0)
01132 {
01133
01134 sendto_realops_flags(UMODE_ALL, L_ADMIN,
01135 "Server %s closed the connection",
01136 get_client_name(client_p, SHOW_IP));
01137
01138
01139 sendto_realops_flags(UMODE_ALL, L_OPER,
01140 "Server %s closed the connection",
01141 get_client_name(client_p, MASK_IP));
01142
01143 ilog(L_NOTICE, "Server %s closed the connection",
01144 get_client_name(client_p, SHOW_IP));
01145 }
01146 else
01147 {
01148 report_error(L_ADMIN, "Lost connection to %s: %s",
01149 get_client_name(client_p, SHOW_IP), current_error);
01150 report_error(L_OPER, "Lost connection to %s: %s",
01151 get_client_name(client_p, MASK_IP), current_error);
01152 }
01153
01154 sendto_realops_flags(UMODE_ALL, L_ALL,
01155 "%s had been connected for %d day%s, %2d:%02d:%02d",
01156 client_p->name, connected/86400,
01157 (connected/86400 == 1) ? "" : "s",
01158 (connected % 86400) / 3600, (connected % 3600) / 60,
01159 connected % 60);
01160 }
01161
01162 if (error == 0)
01163 strlcpy(errmsg, "Remote host closed the connection",
01164 sizeof(errmsg));
01165 else
01166 ircsprintf(errmsg, "Read error: %s",
01167 strerror(current_error));
01168
01169 exit_client(client_p, &me, errmsg);
01170 }
01171
01172 void
01173 exit_aborted_clients(void)
01174 {
01175 dlink_node *ptr;
01176 struct Client *target_p;
01177 const char *notice;
01178
01179 DLINK_FOREACH_SAFE(ptr, eac_next, abort_list.head)
01180 {
01181 target_p = ptr->data;
01182 eac_next = ptr->next;
01183
01184 if (target_p == NULL)
01185 {
01186 sendto_realops_flags(UMODE_ALL, L_ALL,
01187 "Warning: null client on abort_list!");
01188 dlinkDelete(ptr, &abort_list);
01189 free_dlink_node(ptr);
01190 continue;
01191 }
01192
01193 dlinkDelete(ptr, &abort_list);
01194
01195 if (IsSendQExceeded(target_p))
01196 notice = "Max SendQ exceeded";
01197 else
01198 notice = "Write error: connection closed";
01199
01200 exit_client(target_p, &me, notice);
01201 free_dlink_node(ptr);
01202 }
01203 }
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230 int
01231 accept_message(struct Client *source, struct Client *target)
01232 {
01233 dlink_node *ptr;
01234
01235 DLINK_FOREACH(ptr, target->allow_list.head)
01236 {
01237 struct Client *target_p = ptr->data;
01238
01239 if (source == target_p)
01240 return (1);
01241 }
01242
01243 if (IsSoftCallerId(target))
01244 {
01245 DLINK_FOREACH(ptr, target->channel.head)
01246 if (IsMember(source, ((struct Membership *)ptr->data)->chptr))
01247 return (1);
01248 }
01249
01250 return (0);
01251 }
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263 void
01264 del_from_accept(struct Client *source, struct Client *target)
01265 {
01266 dlink_node *ptr;
01267 dlink_node *ptr2;
01268 dlink_node *next_ptr;
01269 dlink_node *next_ptr2;
01270 struct Client *target_p;
01271
01272 DLINK_FOREACH_SAFE(ptr, next_ptr, target->allow_list.head)
01273 {
01274 target_p = ptr->data;
01275
01276 if (source == target_p)
01277 {
01278 dlinkDelete(ptr, &target->allow_list);
01279 free_dlink_node(ptr);
01280
01281 DLINK_FOREACH_SAFE(ptr2, next_ptr2, source->on_allow_list.head)
01282 {
01283 target_p = ptr2->data;
01284
01285 if (target == target_p)
01286 {
01287 dlinkDelete(ptr2, &source->on_allow_list);
01288 free_dlink_node(ptr2);
01289 }
01290 }
01291 }
01292 }
01293 }
01294
01295
01296
01297
01298
01299
01300
01301
01302 void
01303 del_all_accepts(struct Client *client_p)
01304 {
01305 dlink_node *ptr, *next_ptr;
01306
01307 DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->allow_list.head)
01308 del_from_accept(ptr->data, client_p);
01309
01310 DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->on_allow_list.head)
01311 del_from_accept(client_p, ptr->data);
01312 }
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322 void
01323 del_all_their_accepts(struct Client *client_p)
01324 {
01325 dlink_node *ptr, *next_ptr;
01326
01327 DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->on_allow_list.head)
01328 del_from_accept(client_p, ptr->data);
01329 }
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340 void
01341 set_initial_nick(struct Client *client_p, struct Client *source_p,
01342 const char *nick)
01343 {
01344 char buf[USERLEN + 1];
01345
01346
01347
01348
01349 source_p->tsinfo = CurrentTime;
01350 source_p->localClient->registration &= ~REG_NEED_NICK;
01351
01352 if (source_p->name[0])
01353 hash_del_client(source_p);
01354
01355 strlcpy(source_p->name, nick, sizeof(source_p->name));
01356 hash_add_client(source_p);
01357
01358
01359 fd_note(&client_p->localClient->fd, "Nick: %s", nick);
01360
01361
01362 client_p->llname[0] = '\0';
01363
01364 if (!source_p->localClient->registration)
01365 {
01366 strlcpy(buf, source_p->username, sizeof(buf));
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376 register_local_user(client_p, source_p, nick, buf);
01377 }
01378 }
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388 void
01389 change_local_nick(struct Client *client_p, struct Client *source_p, const char *nick)
01390 {
01391
01392
01393
01394
01395
01396 if ((source_p->localClient->last_nick_change +
01397 ConfigFileEntry.max_nick_time) < CurrentTime)
01398 source_p->localClient->number_of_nick_changes = 0;
01399 source_p->localClient->last_nick_change = CurrentTime;
01400 source_p->localClient->number_of_nick_changes++;
01401
01402 if ((ConfigFileEntry.anti_nick_flood &&
01403 (source_p->localClient->number_of_nick_changes
01404 <= ConfigFileEntry.max_nick_changes)) ||
01405 !ConfigFileEntry.anti_nick_flood ||
01406 (IsOper(source_p) && ConfigFileEntry.no_oper_flood))
01407 {
01408 if (irccmp(source_p->name, nick))
01409 {
01410
01411
01412
01413
01414 del_all_their_accepts(source_p);
01415 source_p->tsinfo = CurrentTime;
01416 clear_ban_cache_client(source_p);
01417 }
01418
01419
01420
01421
01422 sendto_realops_flags(UMODE_NCHANGE, L_ALL, "Nick change: From %s to %s [%s@%s]",
01423 source_p->name, nick, source_p->username, source_p->host);
01424 sendto_common_channels_local(source_p, 1, ":%s!%s@%s NICK :%s",
01425 source_p->name, source_p->username,
01426 source_p->host, nick);
01427 add_history(source_p, 1);
01428
01429
01430
01431
01432
01433
01434
01435
01436 sendto_server(client_p, source_p, NULL, CAP_TS6, NOCAPS, NOFLAGS,
01437 ":%s NICK %s :%lu",
01438 ID(source_p), nick, (unsigned long)source_p->tsinfo);
01439 sendto_server(client_p, source_p, NULL, NOCAPS, CAP_TS6, NOFLAGS,
01440 ":%s NICK %s :%lu",
01441 source_p->name, nick, (unsigned long)source_p->tsinfo);
01442 }
01443 else
01444 {
01445 sendto_one(source_p, form_str(ERR_NICKTOOFAST),
01446 me.name, source_p->name, source_p->name,
01447 nick, ConfigFileEntry.max_nick_time);
01448 return;
01449 }
01450
01451
01452 if (source_p->name[0])
01453 hash_del_client(source_p);
01454
01455 strcpy(source_p->name, nick);
01456 hash_add_client(source_p);
01457
01458
01459 fd_note(&client_p->localClient->fd, "Nick: %s", nick);
01460 }