static void ms_dline(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { char def_reason[] = CONF_NOREASON; char *dlhost, *reason; const char *creason; const struct Client *target_p = NULL; struct irc_ssaddr daddr; struct MaskItem *conf=NULL; time_t tkline_time=0; int bits = 0, aftype = 0, t = 0; const char *current_date = NULL; time_t cur_time; char hostip[HOSTIPLEN + 1]; char buffer[IRCD_BUFSIZE]; if (parc != 5 || EmptyString(parv[4])) return; /* parv[0] parv[1] parv[2] parv[3] parv[4] */ /* oper target_server tkline_time host reason */ sendto_match_servs(source_p, parv[1], CAP_DLN, "DLINE %s %s %s :%s", parv[1], parv[2], parv[3], parv[4]); if (match(parv[1], me.name)) return; tkline_time = valid_tkline(parv[2], TK_SECONDS); dlhost = parv[3]; reason = parv[4]; if (HasFlag(source_p, FLAGS_SERVICE) || find_matching_name_conf(CONF_ULINE, source_p->servptr->name, source_p->username, source_p->host, SHARED_DLINE)) { if (!IsClient(source_p)) return; if ((t = parse_netmask(dlhost, NULL, &bits)) == HM_HOST) { if ((target_p = find_chasing(client_p, source_p, dlhost, NULL)) == NULL) return; if (!MyConnect(target_p)) { sendto_one(source_p, ":%s NOTICE %s :Can't DLINE nick on another server", me.name, source_p->name); return; } if (IsExemptKline(target_p)) { sendto_one(source_p, ":%s NOTICE %s :%s is E-lined", me.name, source_p->name, target_p->name); return; } getnameinfo((struct sockaddr *)&target_p->localClient->ip, target_p->localClient->ip.ss_len, hostip, sizeof(hostip), NULL, 0, NI_NUMERICHOST); dlhost = hostip; t = parse_netmask(dlhost, NULL, &bits); assert(t == HM_IPV4 || t == HM_IPV6); } if (bits < 8) { sendto_one(source_p, ":%s NOTICE %s :For safety, bitmasks less than 8 require conf access.", me.name, source_p->name); return; } #ifdef IPV6 if (t == HM_IPV6) aftype= AF_INET6; else #endif aftype = AF_INET; parse_netmask(dlhost, &daddr, NULL); if ((conf = find_dline_conf(&daddr, aftype)) != NULL) { creason = conf->reason ? conf->reason : def_reason; if (IsConfExemptKline(conf)) sendto_one(source_p, ":%s NOTICE %s :[%s] is (E)d-lined by [%s] - %s", me.name, source_p->name, dlhost, conf->host, creason); else sendto_one(source_p, ":%s NOTICE %s :[%s] already D-lined by [%s] - %s", me.name, source_p->name, dlhost, conf->host, creason); return; } cur_time = CurrentTime; current_date = smalldate(cur_time); if (!valid_comment(source_p, reason, 1)) return; conf = conf_make(CONF_DLINE); conf->host = xstrdup(dlhost); if (tkline_time != 0) snprintf(buffer, sizeof(buffer), "Temporary D-line %d min. - %s (%s)", (int)(tkline_time/60), reason, current_date); else snprintf(buffer, sizeof(buffer), "%s (%s)", reason, current_date); conf->reason = xstrdup(buffer); apply_dline(source_p, conf, tkline_time); rehashed_klines = 1; } }
/* mo_dline() * * inputs - pointer to server * - pointer to client * - parameter count * - parameter list * output - * side effects - D line is added * */ static void mo_dline(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { char def_reason[] = CONF_NOREASON; char *dlhost = NULL, *reason = NULL; char *target_server = NULL; const char *creason; const struct Client *target_p = NULL; struct irc_ssaddr daddr; struct MaskItem *conf=NULL; time_t tkline_time=0; int bits = 0, aftype = 0, t = 0; const char *current_date = NULL; time_t cur_time; char hostip[HOSTIPLEN + 1]; char buffer[IRCD_BUFSIZE]; if (!HasOFlag(source_p, OPER_FLAG_DLINE)) { sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "dline"); return; } if (parse_aline("DLINE", source_p, parc, parv, AWILD, &dlhost, NULL, &tkline_time, &target_server, &reason) < 0) return; if (target_server != NULL) { if (HasID(source_p)) { sendto_server(NULL, CAP_DLN|CAP_TS6, NOCAPS, ":%s DLINE %s %lu %s :%s", source_p->id, target_server, (unsigned long)tkline_time, dlhost, reason); sendto_server(NULL, CAP_DLN, CAP_TS6, ":%s DLINE %s %lu %s :%s", source_p->name, target_server, (unsigned long)tkline_time, dlhost, reason); } else sendto_server(NULL, CAP_DLN, NOCAPS, ":%s DLINE %s %lu %s :%s", source_p->name, target_server, (unsigned long)tkline_time, dlhost, reason); /* Allow ON to apply local kline as well if it matches */ if (match(target_server, me.name)) return; } else cluster_a_line(source_p, "DLINE", CAP_DLN, SHARED_DLINE, "%d %s :%s", tkline_time, dlhost, reason); if ((t = parse_netmask(dlhost, NULL, &bits)) == HM_HOST) { if ((target_p = find_chasing(client_p, source_p, dlhost, NULL)) == NULL) return; if (!MyConnect(target_p)) { sendto_one(source_p, ":%s NOTICE %s :Can't DLINE nick on another server", me.name, source_p->name); return; } if (IsExemptKline(target_p)) { sendto_one(source_p, ":%s NOTICE %s :%s is E-lined", me.name, source_p->name, target_p->name); return; } getnameinfo((struct sockaddr *)&target_p->localClient->ip, target_p->localClient->ip.ss_len, hostip, sizeof(hostip), NULL, 0, NI_NUMERICHOST); dlhost = hostip; t = parse_netmask(dlhost, NULL, &bits); assert(t == HM_IPV4 || t == HM_IPV6); } if (bits < 8) { sendto_one(source_p, ":%s NOTICE %s :For safety, bitmasks less than 8 require conf access.", me.name, source_p->name); return; } #ifdef IPV6 if (t == HM_IPV6) aftype = AF_INET6; else #endif aftype = AF_INET; parse_netmask(dlhost, &daddr, NULL); if ((conf = find_dline_conf(&daddr, aftype)) != NULL) { creason = conf->reason ? conf->reason : def_reason; if (IsConfExemptKline(conf)) sendto_one(source_p, ":%s NOTICE %s :[%s] is (E)d-lined by [%s] - %s", me.name, source_p->name, dlhost, conf->host, creason); else sendto_one(source_p, ":%s NOTICE %s :[%s] already D-lined by [%s] - %s", me.name, source_p->name, dlhost, conf->host, creason); return; } cur_time = CurrentTime; current_date = smalldate(cur_time); if (!valid_comment(source_p, reason, 1)) return; conf = conf_make(CONF_DLINE); conf->host = xstrdup(dlhost); if (tkline_time != 0) snprintf(buffer, sizeof(buffer), "Temporary D-line %d min. - %s (%s)", (int)(tkline_time/60), reason, current_date); else snprintf(buffer, sizeof(buffer), "%s (%s)", reason, current_date); conf->reason = xstrdup(buffer); apply_dline(source_p, conf, tkline_time); rehashed_klines = 1; }
/* * check_klines * inputs - NONE * output - NONE * side effects - Check all connections for a pending kline against the * client, exit the client if a kline matches. */ void check_klines(void) { struct Client *client_p; /* current local client_p being examined */ struct ConfItem *aconf = (struct ConfItem *)NULL; char *reason; /* pointer to reason string */ dlink_node *ptr, *next_ptr; for (ptr = lclient_list.head; ptr; ptr = next_ptr) { next_ptr = ptr->next; client_p = ptr->data; if (IsMe(client_p)) continue; /* if there is a returned struct ConfItem then kill it */ if ((aconf = find_dline(&client_p->localClient->ip, client_p->localClient->aftype))) { if (aconf->status & CONF_EXEMPTDLINE) continue; sendto_realops_flags(FLAGS_ALL, L_ALL,"DLINE active for %s", get_client_name(client_p, HIDE_IP)); if (ConfigFileEntry.kline_with_connection_closed && ConfigFileEntry.kline_with_reason) { reason = "Connection closed"; if(IsPerson(client_p)) sendto_one(client_p, form_str(ERR_YOUREBANNEDCREEP), me.name, client_p->name, aconf->passwd ? aconf->passwd : "D-lined"); else sendto_one(client_p, "NOTICE DLINE :*** You have been D-lined"); } else { if(ConfigFileEntry.kline_with_connection_closed) reason = "Connection closed"; else if(ConfigFileEntry.kline_with_reason && aconf->passwd) reason = aconf->passwd; else reason = "D-lined"; if(IsPerson(client_p)) sendto_one(client_p, form_str(ERR_YOUREBANNEDCREEP), me.name, client_p->name, reason); else sendto_one(client_p, "NOTICE DLINE :*** You have been D-lined"); } (void)exit_client(client_p, client_p, &me, reason); continue; /* and go examine next fd/client_p */ } if (IsPerson(client_p)) { if (ConfigFileEntry.glines && (aconf = find_gkill(client_p, client_p->username))) { if (IsExemptKline(client_p)) { sendto_realops_flags(FLAGS_ALL, L_ALL, "GLINE over-ruled for %s, client is kline_exempt", get_client_name(client_p, HIDE_IP)); continue; } if (IsExemptGline(client_p)) { sendto_realops_flags(FLAGS_ALL, L_ALL, "GLINE over-ruled for %s, client is gline_exempt", get_client_name(client_p, HIDE_IP)); continue; } sendto_realops_flags(FLAGS_ALL, L_ALL, "GLINE active for %s", get_client_name(client_p, HIDE_IP)); if(ConfigFileEntry.kline_with_connection_closed && ConfigFileEntry.kline_with_reason) { reason = "Connection closed"; sendto_one(client_p, form_str(ERR_YOUREBANNEDCREEP), me.name, client_p->name, aconf->passwd ? aconf->passwd : "G-lined"); } else { if(ConfigFileEntry.kline_with_connection_closed) reason = "Connection closed"; else if(ConfigFileEntry.kline_with_reason && aconf->passwd) reason = aconf->passwd; else reason = "G-lined"; sendto_one(client_p, form_str(ERR_YOUREBANNEDCREEP), me.name, client_p->name, reason); } (void)exit_client(client_p, client_p, &me, reason); /* and go examine next fd/client_p */ continue; } else if((aconf = find_kill(client_p))) { /* if there is a returned struct ConfItem.. then kill it */ if (IsExemptKline(client_p)) { sendto_realops_flags(FLAGS_ALL, L_ALL, "KLINE over-ruled for %s, client is kline_exempt", get_client_name(client_p, HIDE_IP)); continue; } sendto_realops_flags(FLAGS_ALL, L_ALL, "KLINE active for %s", get_client_name(client_p, HIDE_IP)); if(ConfigFileEntry.kline_with_connection_closed && ConfigFileEntry.kline_with_reason) { reason = "Connection closed"; sendto_one(client_p, form_str(ERR_YOUREBANNEDCREEP), me.name, client_p->name, aconf->passwd ? aconf->passwd : "K-lined"); } else { if(ConfigFileEntry.kline_with_connection_closed) reason = "Connection closed"; else if(ConfigFileEntry.kline_with_reason && aconf->passwd) reason = aconf->passwd; else reason = "K-lined"; sendto_one(client_p, form_str(ERR_YOUREBANNEDCREEP), me.name, client_p->name, reason); } (void)exit_client(client_p, client_p, &me, reason); continue; } } } /* also check the unknowns list for new dlines */ for (ptr = unknown_list.head; ptr; ptr = next_ptr) { next_ptr = ptr->next; client_p = ptr->data; if((aconf = find_dline(&client_p->localClient->ip, client_p->localClient->aftype))) { if(aconf->status & CONF_EXEMPTDLINE) continue; sendto_one(client_p, "NOTICE DLINE :*** You have been D-lined"); exit_client(client_p, client_p, &me, "D-lined"); } } }
/* * Check_pings_list() * * inputs - pointer to list to check * output - NONE * side effects - */ static void check_pings_list(dlink_list *list) { char scratch[32]; /* way too generous but... */ struct Client *client_p; /* current local client_p being examined */ int ping = 0; /* ping time value from client */ dlink_node *ptr, *next_ptr; for (ptr = list->head; ptr; ptr = next_ptr) { next_ptr = ptr->next; client_p = ptr->data; /* ** Note: No need to notify opers here. It's ** already done when "FLAGS_DEADSOCKET" is set. */ if (client_p->flags & FLAGS_DEADSOCKET) { /* Ignore it, its been exited already */ continue; } if (IsPerson(client_p)) { if(!IsExemptKline(client_p) && GlobalSetOptions.idletime && !IsOper(client_p) && !IsIdlelined(client_p) && ((CurrentTime - client_p->user->last) > GlobalSetOptions.idletime)) { struct ConfItem *aconf; aconf = make_conf(); aconf->status = CONF_KILL; DupString(aconf->host, client_p->host); DupString(aconf->passwd, "idle exceeder"); DupString(aconf->name, client_p->username); aconf->port = 0; aconf->hold = CurrentTime + 60; add_temp_kline(aconf); sendto_realops_flags(FLAGS_ALL, L_ALL, "Idle time limit exceeded for %s - temp k-lining", get_client_name(client_p, HIDE_IP)); (void)exit_client(client_p, client_p, &me, aconf->passwd); continue; } } if (!IsRegistered(client_p)) ping = CONNECTTIMEOUT; else ping = get_client_ping(client_p); if (ping < (CurrentTime - client_p->lasttime)) { /* * If the client/server hasnt talked to us in 2*ping seconds * and it has a ping time, then close its connection. */ if (((CurrentTime - client_p->lasttime) >= (2 * ping) && (client_p->flags & FLAGS_PINGSENT))) { if (IsServer(client_p) || IsConnecting(client_p) || IsHandshake(client_p)) { sendto_realops_flags(FLAGS_ALL, L_ADMIN, "No response from %s, closing link", get_client_name(client_p, HIDE_IP)); sendto_realops_flags(FLAGS_ALL, L_OPER, "No response from %s, closing link", get_client_name(client_p, MASK_IP)); ilog(L_NOTICE, "No response from %s, closing link", get_client_name(client_p, HIDE_IP)); } (void)ircsprintf(scratch, "Ping timeout: %d seconds", (int)(CurrentTime - client_p->lasttime)); (void)exit_client(client_p, client_p, &me, scratch); continue; } else if ((client_p->flags & FLAGS_PINGSENT) == 0) { /* * if we havent PINGed the connection and we havent * heard from it in a while, PING it to make sure * it is still alive. */ client_p->flags |= FLAGS_PINGSENT; /* not nice but does the job */ client_p->lasttime = CurrentTime - ping; sendto_one(client_p, "PING :%s", me.name); } } /* ping_timeout: */ } }
/* mo_dline() * * inputs - pointer to server * - pointer to client * - parameter count * - parameter list * output - * side effects - D line is added * */ static void mo_dline(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { char def_reason[] = CONF_NOREASON; char *dlhost = NULL, *oper_reason = NULL, *reason = NULL; char *target_server = NULL; const char *creason; const struct Client *target_p = NULL; struct sockaddr_storage daddr; struct AccessItem *aconf = NULL; time_t tkline_time = 0; int bits, t; char hostip[HOSTIPLEN + 1]; if (!HasOFlag(source_p, OPER_FLAG_DLINE)) { sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "dline"); return; } if (parse_aline("DLINE", source_p, parc, parv, AWILD, &dlhost, NULL, &tkline_time, &target_server, &reason) < 0) return; if (target_server != NULL) { if (HasID(source_p)) { sendto_server(NULL, CAP_DLN | CAP_TS6, NOCAPS, ":%s DLINE %s %lu %s :%s", source_p->id, target_server, (unsigned long)tkline_time, dlhost, reason); sendto_server(NULL, CAP_DLN, CAP_TS6, ":%s DLINE %s %lu %s :%s", source_p->name, target_server, (unsigned long)tkline_time, dlhost, reason); } else sendto_server(NULL, CAP_DLN, NOCAPS, ":%s DLINE %s %lu %s :%s", source_p->name, target_server, (unsigned long)tkline_time, dlhost, reason); /* Allow ON to apply local kline as well if it matches */ if (!match(target_server, me.name)) return; } else cluster_a_line(source_p, "DLINE", CAP_DLN, SHARED_DLINE, "%d %s :%s", tkline_time, dlhost, reason); if ((t = parse_netmask(dlhost, NULL, &bits)) == HM_HOST) { if ((target_p = find_chasing(client_p, source_p, dlhost, NULL)) == NULL) return; if (!MyConnect(target_p)) { sendto_one(source_p, ":%s NOTICE %s :Can't DLINE nick on another server", me.name, source_p->name); return; } if (IsExemptKline(target_p)) { sendto_one(source_p, ":%s NOTICE %s :%s is E-lined", me.name, source_p->name, target_p->name); return; } ip_to_string(&target_p->ip, hostip, sizeof(hostip)); dlhost = hostip; t = parse_netmask(dlhost, NULL, &bits); assert(t == HM_IPV4 || t == HM_IPV6); } if (bits < 8) { sendto_one(source_p, ":%s NOTICE %s :For safety, bitmasks less than 8 require conf access.", me.name, source_p->name); return; } if (t == HM_IPV6) t = AF_INET6; else t = AF_INET; parse_netmask(dlhost, &daddr, NULL); if ((aconf = find_dline_conf(&daddr, t)) != NULL) { creason = aconf->reason ? aconf->reason : def_reason; if (IsConfExemptKline(aconf)) sendto_one(source_p, ":%s NOTICE %s :[%s] is (E)d-lined by [%s] - %s", me.name, source_p->name, dlhost, aconf->host, creason); else sendto_one(source_p, ":%s NOTICE %s :[%s] already D-lined by [%s] - %s", me.name, source_p->name, dlhost, aconf->host, creason); return; } /* Look for an oper reason */ if ((oper_reason = strchr(reason, '|')) != NULL) * oper_reason++ = '\0'; if (!valid_comment(source_p, reason, 1)) return; apply_conf_ban(source_p, DLINE_TYPE, NULL, dlhost, reason, oper_reason, tkline_time); }
static void ms_dline(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { char def_reason[] = CONF_NOREASON; char *dlhost, *oper_reason, *reason; const char *creason; const struct Client *target_p = NULL; struct sockaddr_storage daddr; struct AccessItem *aconf = NULL; time_t tkline_time = 0; int bits, t; char hostip[HOSTIPLEN + 1]; if (parc != 5 || EmptyString(parv[4])) return; /* parv[0] parv[1] parv[2] parv[3] parv[4] */ /* oper target_server tkline_time host reason */ sendto_match_servs(source_p, parv[1], CAP_DLN, "DLINE %s %s %s :%s", parv[1], parv[2], parv[3], parv[4]); if (!match(parv[1], me.name)) return; tkline_time = valid_tkline(parv[2], TK_SECONDS); dlhost = parv[3]; reason = parv[4]; if (HasFlag(source_p, FLAGS_SERVICE) || find_matching_name_conf(ULINE_TYPE, source_p->servptr->name, source_p->username, source_p->host, SHARED_DLINE)) { if (!IsClient(source_p)) return; if ((t = parse_netmask(dlhost, NULL, &bits)) == HM_HOST) { if ((target_p = find_chasing(client_p, source_p, dlhost, NULL)) == NULL) return; if (!MyConnect(target_p)) { sendto_one(source_p, ":%s NOTICE %s :Can't DLINE nick on another server", me.name, source_p->name); return; } if (IsExemptKline(target_p)) { sendto_one(source_p, ":%s NOTICE %s :%s is E-lined", me.name, source_p->name, target_p->name); return; } ip_to_string(&target_p->ip, hostip, sizeof(hostip)); dlhost = hostip; t = parse_netmask(dlhost, NULL, &bits); assert(t == HM_IPV4 || t == HM_IPV6); } if (bits < 8) { sendto_one(source_p, ":%s NOTICE %s :For safety, bitmasks less than 8 require conf access.", me.name, source_p->name); return; } if (t == HM_IPV6) t = AF_INET6; else t = AF_INET; parse_netmask(dlhost, &daddr, NULL); if ((aconf = find_dline_conf(&daddr, t)) != NULL) { creason = aconf->reason ? aconf->reason : def_reason; if (IsConfExemptKline(aconf)) sendto_one(source_p, ":%s NOTICE %s :[%s] is (E)d-lined by [%s] - %s", me.name, source_p->name, dlhost, aconf->host, creason); else sendto_one(source_p, ":%s NOTICE %s :[%s] already D-lined by [%s] - %s", me.name, source_p->name, dlhost, aconf->host, creason); return; } /* Look for an oper reason */ if ((oper_reason = strchr(reason, '|')) != NULL) * oper_reason++ = '\0'; if (!valid_comment(source_p, reason, 1)) return; apply_conf_ban(source_p, DLINE_TYPE, NULL, dlhost, reason, oper_reason, tkline_time); } }