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; } }
/*! \brief WEBIRC command handler * * \param source_p Pointer to allocated Client struct from which the message * originally comes from. This can be a local or remote client. * \param parc Integer holding the number of supplied arguments. * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL * pointers. * \note Valid arguments for this command are: * - parv[0] = command * - parv[1] = password * - parv[2] = fake username (we ignore this) * - parv[3] = fake hostname * - parv[4] = fake ip */ static int mr_webirc(struct Client *source_p, int parc, char *parv[]) { struct MaskItem *conf = NULL; struct addrinfo hints, *res; assert(MyConnect(source_p)); if (!valid_hostname(parv[3])) { sendto_one_notice(source_p, &me, ":WEBIRC: Invalid hostname"); return 0; } conf = find_address_conf(source_p->host, IsGotId(source_p) ? source_p->username : "******", &source_p->connection->ip, source_p->connection->aftype, parv[1]); if (conf == NULL || !IsConfClient(conf)) return 0; if (!IsConfWebIRC(conf)) { sendto_one_notice(source_p, &me, ":Not a WEBIRC auth {} block"); return 0; } if (EmptyString(conf->passwd)) { sendto_one_notice(source_p, &me, ":WEBIRC auth {} blocks must have a password"); return 0; } if (!match_conf_password(parv[1], conf)) { sendto_one_notice(source_p, &me, ":WEBIRC password incorrect"); return 0; } memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; if (getaddrinfo(parv[4], NULL, &hints, &res)) { sendto_one_notice(source_p, &me, ":Invalid WEBIRC IP %s", parv[4]); return 0; } assert(res); memcpy(&source_p->connection->ip, res->ai_addr, res->ai_addrlen); source_p->connection->ip.ss_len = res->ai_addrlen; source_p->connection->ip.ss.ss_family = res->ai_family; source_p->connection->aftype = res->ai_family; freeaddrinfo(res); strlcpy(source_p->sockhost, parv[4], sizeof(source_p->sockhost)); strlcpy(source_p->host, parv[3], sizeof(source_p->host)); /* Check dlines now, k-lines will be checked on registration */ if ((conf = find_dline_conf(&source_p->connection->ip, source_p->connection->aftype))) { if (!(conf->type == CONF_EXEMPT)) { exit_client(source_p, "D-lined"); return 0; } } AddUMode(source_p, UMODE_WEBIRC); sendto_one_notice(source_p, &me, ":WEBIRC host/IP set to %s %s", parv[3], parv[4]); return 0; }
/* 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; }
/* * mr_webirc * parv[0] = sender prefix * parv[1] = password * parv[2] = fake username (we ignore this) * parv[3] = fake hostname * parv[4] = fake ip */ static void mr_webirc(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { struct AccessItem *aconf = NULL; struct ConfItem *conf = NULL; char original_sockhost[HOSTIPLEN + 1]; assert(source_p == client_p); if (invalid_hostname(parv[4])) return; aconf = find_address_conf(source_p->host, IsGotId(source_p) ? source_p->username : "******", &source_p->ip, source_p->ip.ss_family, parv[1], source_p->certfp); if (aconf == NULL || !IsConfClient(aconf)) return; conf = unmap_conf_item(aconf); if (!IsConfDoSpoofIp(aconf) || irccmp(conf->name, "webirc.")) { sendto_realops_flags(UMODE_UNAUTH, L_ALL, "Not a CGI:IRC auth block: %s", source_p->sockhost); return; } if (EmptyString(aconf->passwd)) { sendto_realops_flags(UMODE_UNAUTH, L_ALL, "CGI:IRC auth blocks must have a password"); return; } if (!match_conf_password(parv[1], NULL, aconf)) { sendto_realops_flags(UMODE_UNAUTH, L_ALL, "CGI:IRC password incorrect"); return; } string_to_ip(parv[4], 0, &source_p->ip); strlcpy(original_sockhost, source_p->sockhost, sizeof(original_sockhost)); strlcpy(source_p->sockhost, parv[4], sizeof(source_p->sockhost)); if (strlen(parv[3]) <= HOSTLEN) strlcpy(source_p->host, parv[3], sizeof(source_p->host)); else strlcpy(source_p->host, source_p->sockhost, sizeof(source_p->host)); /* Check dlines now, klines will be checked on registration */ if ((aconf = find_dline_conf(&client_p->ip, client_p->ip.ss_family))) { if (!(aconf->status & CONF_EXEMPTDLINE)) { exit_client(client_p, &me, "D-lined"); return; } } sendto_realops_flags(UMODE_CCONN, L_ALL, "CGI:IRC host/IP set %s to %s (%s)", original_sockhost, parv[3], parv[4]); }
/* * mr_webirc * parv[0] = sender prefix * parv[1] = password * parv[2] = fake username (we ignore this) * parv[3] = fake hostname * parv[4] = fake ip */ static void mr_webirc(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { struct AccessItem *aconf = NULL; struct ConfItem *conf = NULL; struct addrinfo hints, *res; char original_sockhost[HOSTIPLEN + 1]; assert(source_p == client_p); if (invalid_hostname(parv[4])) return; aconf = find_address_conf(source_p->host, IsGotId(source_p) ? source_p->username : "******", &source_p->ip, source_p->aftype, parv[1], source_p->certfp); if (aconf == NULL || !IsConfClient(aconf)) return; conf = unmap_conf_item(aconf); if (!IsConfDoSpoofIp(aconf) || irccmp(conf->name, "webirc.")) { sendto_gnotice_flags(UMODE_UNAUTH, L_ALL, me.name, &me, NULL, "Not a CGI:IRC auth block: %s", source_p->sockhost); return; } if (EmptyString(aconf->passwd)) { sendto_gnotice_flags(UMODE_UNAUTH, L_ALL, me.name, &me, NULL, "CGI:IRC auth blocks must have a password"); return; } if (!match_conf_password(parv[1], aconf)) { sendto_gnotice_flags(UMODE_UNAUTH, L_ALL, me.name, &me, NULL, "CGI:IRC password incorrect"); return; } memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; if (getaddrinfo(parv[4], NULL, &hints, &res)) { sendto_gnotice_flags(UMODE_UNAUTH, L_ALL, me.name, &me, NULL, "Inavlid CGI:IRC IP %s", parv[4]); return; } assert(res != NULL); memcpy(&source_p->ip, res->ai_addr, res->ai_addrlen); source_p->ip.ss_len = res->ai_addrlen; source_p->ip.ss.ss_family = res->ai_family; source_p->aftype = res->ai_family; freeaddrinfo(res); strlcpy(original_sockhost, source_p->sockhost, sizeof(original_sockhost)); strlcpy(source_p->sockhost, parv[4], sizeof(source_p->sockhost)); if (strlen(parv[3]) <= HOSTLEN) strlcpy(source_p->host, parv[3], sizeof(source_p->host)); else strlcpy(source_p->host, source_p->sockhost, sizeof(source_p->host)); /* Check dlines now, k/glines will be checked on registration */ if ((aconf = find_dline_conf(&client_p->ip, client_p->aftype))) { if (!(aconf->status & CONF_EXEMPTDLINE)) { exit_client(client_p, &me, "D-lined"); return; } } sendto_gnotice_flags(UMODE_CCONN, L_ALL, me.name, &me, NULL, "CGI:IRC host/IP set %s to %s (%s)", original_sockhost, parv[3], parv[4]); }
/* 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); } }