/* clean_host() * * input - host to check * output - 0 if erroneous, else 0 * side effects - */ static int clean_host(const char *host) { int len = 0; const char *last_slash = 0; if (*host == '\0' || *host == ':') return 0; for(; *host; host++) { len++; if(!IsHostChar(*host)) return 0; if(*host == '/') last_slash = host; } if(len > HOSTLEN) return 0; if(last_slash && IsDigit(last_slash[1])) return 0; return 1; }
/* * valid_hostname - check hostname for validity * * Inputs - pointer to user * Output - YES if valid, NO if not * Side effects - NONE * * NOTE: this doesn't allow a hostname to begin with a dot and * will not allow more dots than chars. */ bool valid_hostname(const char *hostname) { const char *p = hostname; int found_sep = 0; s_assert(NULL != p); if(hostname == NULL) return false; if('.' == *p || ':' == *p) return false; while(*p) { if(!IsHostChar(*p)) return false; if(*p == '.' || *p == ':') found_sep++; p++; } if(found_sep == 0) return (false); return (true); }
/* * valid_hostname - check hostname for validity * * Inputs - pointer to user * Output - 1 for valid, 0 for invalid * * NOTE: this doesn't allow a hostname to begin with a dot and * will not allow more dots than chars. */ int irc_IsValidHostname(const char* hostname) { int dots = 0; int chars = 0; const char* p = hostname; assert(0 != p); if ('.' == *p) return 0; while (*p) { if (!IsHostChar(*p)) return 0; if ('.' == *p || ':' == *p) { ++p; ++dots; } else { ++p; ++chars; } } return ( 0 == dots || chars < dots) ? 0 : 1; }
u_short check_hm(user_t *cptr, char *hm) { if (strlen(hm) > HOSTLEN) return (cptr ? reply(OS, cptr->nick, "The hostmask is too long.") : 1); for (; *hm; hm++) if (!IsHostChar(*hm) && *hm != '*' && *hm != '?') return (cptr ? reply(OS, cptr->nick, "The character '%c' is not allowed in your hostmask.", *hm) : 1); return 0; }
int ValidateHostWild( const char *hostname ) { if( hostname == NULL ) return NS_FAILURE; while( *hostname != '\0' ) { if( !IsHostChar( *hostname ) && !IsWildChar( *hostname ) ) return NS_FAILURE; hostname++; } return NS_SUCCESS; }
/* auth_verify_hostname - verify that a hostname is valid, i.e., only * contains characters valid for a hostname and that a hostname is not * too long. */ static int auth_verify_hostname(char *host, int maxlen) { int i; /* Walk through the host name */ for (i = 0; host[i]; i++) /* If it's not a hostname character or if it's too long, return false */ if (!IsHostChar(host[i]) || i >= maxlen) return 0; return 1; /* it's a valid hostname */ }
u_short check_host(user_t *cptr, char *hm) { if (strlen(hm) > HOSTLEN) return (cptr ? reply(OS, cptr->nick, "Your host is too long.") : 1); if (!strchr(hm, '.')) return (cptr ? reply(OS, cptr->nick, "Your host must contain at least one period.") : 1); for (; *hm; hm++) if (!IsHostChar(*hm)) return (cptr ? reply(OS, cptr->nick, "The %s '%c' is not allowed in your hostmask.", ((*hm == '*' || *hm == '?') ? "wildcard" : "character"), *hm) : 1); return 0; }
/* clean_host_name() * input - hostname * output - none * side effects - walks through the hostname, returning 0 if erroneous */ static int clean_host_name(const char *host) { const char *p = host; assert(host && *host); for (; *p; ++p) if (!IsHostChar(*p)) return 0; return p - host <= HOSTLEN; }
int ValidateHost( const char *hostname ) { if( hostname == NULL ) return NS_FAILURE; if( !strchr( hostname, '.' ) ) return NS_FAILURE; while( *hostname != '\0' ) { if( !IsHostChar( *hostname ) ) return NS_FAILURE; hostname++; } return NS_SUCCESS; }
/* clean_host_name() * input - hostname * output - none * side effects - walks through the hostname, returning 0 if erroneous */ static int clean_host_name(char *host) { s_assert(host); if(host == NULL) return 0; for (; *host; host++) { if(!IsHostChar(*host)) return 0; } return 1; }
static int clean_host(const char *host) { int len = 0; for (; *host; host++) { len++; if(!IsHostChar(*host)) return 0; } if(len > HOSTLEN) return 0; return 1; }
static int invalid_hostname(const char *hostname) { const char *p = hostname; unsigned int has_sep = 0; assert(p != NULL); if (*p == '.' || *p == ':') return 1; for (; *p; ++p) { if (!IsHostChar(*p)) return 1; if (*p == '.' || *p == ':') ++has_sep; } return !has_sep; }
static void mo_spoof(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { char *host, *spoof, *password; const char *tmp = NULL; const char *user = NULL; const char *flags = NULL; int i = 0; #ifdef SPOOF_FILE int class_opers; FBFILE *f; char buffer[1024]; struct AddressRec *arec; #endif if (MyConnect(source_p) && !IsOperAdmin(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "SPOOF"); return; } /* check the user@host mask */ if (strchr(parv[1], '!') != NULL) { syntax: if (MyConnect(source_p)) sendto_one(source_p, ":%s NOTICE %s :Syntax: SPOOF <umask@hmask> " "<spoof/-> [flags/- [password]]", me.name, source_p->name); return; } (void) collapse(parv[1]); for (tmp = parv[1]; *tmp; tmp++) if (!IsKWildChar(*tmp)) if (++i >= ConfigFileEntry.min_nonwildcard) break; if (i < ConfigFileEntry.min_nonwildcard) { if (MyConnect(source_p)) sendto_one(source_p, ":%s NOTICE %s :Not enough non-wildcard characters " "in user@host mask", me.name, source_p->name); return; } host = strchr(parv[1], '@'); if (host) { user = parv[1]; *host = '\0'; host++; } else { user = "******"; host = parv[1]; } /* check the spoof field */ spoof = parv[2]; if (spoof == NULL || !*spoof) goto syntax; if (spoof[0] != '-' || spoof[1] != '\0') { for (tmp = spoof; *tmp; tmp++) if (!IsHostChar(*tmp)) { if (MyConnect(source_p)) sendto_one(source_p, ":%s NOTICE %s :The spoof [%s] is invalid", me.name, source_p->name, spoof); return; } if (strlen(spoof) >= HOSTLEN) { if (MyConnect(source_p)) sendto_one(source_p, ":%s NOTICE %s :Spoofs must be less than %d.." "ignoring it", me.name, source_p->name, HOSTLEN); return; } } flags = (parc > 3) ? parv[3] : "-"; password = (parc > 4 && parv[4][0]) ? parv[4] : NULL; #ifdef PROPAGATE_SPOOF sendto_server(client_p, source_p, NULL, NOCAPS, NOCAPS, LL_ICLIENT, ":%s SPOOF %s@%s %s %s :%s", source_p->name, user, host, spoof, flags, password ? password : ""); #endif #ifdef SPOOF_FILE /* Walk through auth {} items and check if we have another auth block * for this hostname */ for (i = 0; i < ATABLE_SIZE; i++) for (arec = atable[i]; arec; arec = arec->next) if (arec->type == CONF_CLIENT && !irccmp(arec->aconf->host, host) && !irccmp(arec->aconf->user, user)) { /* auth entry already exists */ if (MyConnect(source_p)) sendto_one(source_p, ":%s NOTICE %s :auth for %s@%s already exists, you need " "to use /DELSPOOF first", me.name, source_p->name, user, host); #ifdef LOG_SPOOF sendto_realops_flags(UMODE_ALL, L_ALL, "%s attemped to re-add auth for %s@%s " "[spoof: %s, flags: %s]", source_p->name, user, host, spoof, flags); #endif return; } /* Add the spoof to the the spoof file */ if ((f = fbopen(SPOOF_FILE, "a")) == NULL) { sendto_realops_flags(UMODE_ALL, L_ALL, "Could not open %s file, auth for %s@%s " "[spoof: %s, flags: %s, requested by %s] not added", SPOOF_FILE, user, host, spoof, flags, source_p->name); return; } /* write the auth {} block */ fbputs("auth {\n", f, 7); i = ircsprintf(buffer, "\tuser = \"%s@%s\";\n", user, host); fbputs(buffer, f, i); if (spoof[0] != '-' || spoof[1] != '\0') { i = ircsprintf(buffer, "\tspoof = \"%s\";\n", spoof); fbputs(buffer, f, i); } if (password) { i = ircsprintf(buffer, "\tpassword = \"%s\";\n", password); fbputs(buffer, f, i); } /* process given flags */ i = class_opers = 0; for (tmp = flags; *tmp; ++tmp) switch (*tmp) { case 't': i |= CONF_FLAGS_NO_TILDE; /* no_tilde = yes; */ break; case 'i': i |= CONF_FLAGS_NEED_IDENTD; /* need_ident = yes; */ break; case 'k': i |= CONF_FLAGS_EXEMPTKLINE; /* kline_exempt = yes; */ break; case 'g': i |= CONF_FLAGS_EXEMPTGLINE; /* gline_exempt = yes; */ break; case 'l': i |= CONF_FLAGS_NOLIMIT; /* exceed_limit = yes; */ break; case 'o': class_opers = 1; /* class = "opers"; */ break; case 'f': i |= CONF_FLAGS_CAN_FLOOD; /* can_flood = yes; */ break; case 'p': i|= CONF_FLAGS_NEED_PASSWORD; /* need_password = yes; */ } if (i) { fbputs("\tflags = ", f, 9); try_flag(f, &i, CONF_FLAGS_NO_TILDE, "no_tilde"); try_flag(f, &i, CONF_FLAGS_NEED_IDENTD, "need_ident"); try_flag(f, &i, CONF_FLAGS_EXEMPTKLINE, "kline_exempt"); try_flag(f, &i, CONF_FLAGS_EXEMPTGLINE, "gline_exempt"); try_flag(f, &i, CONF_FLAGS_NOLIMIT, "exceed_limit"); try_flag(f, &i, CONF_FLAGS_CAN_FLOOD, "can_flood"); try_flag(f, &i, CONF_FLAGS_NEED_PASSWORD, "need_password"); } if (class_opers) fbputs("\tclass = \"opers\";\n", f, 18); else fbputs("\tclass = \"users\";\n", f, 18); fbputs("};\n\n", f, 4); fbclose(f); rehash(0); #endif #ifdef LOG_SPOOF sendto_realops_flags(UMODE_ALL, L_ALL, "%s added auth for %s@%s [spoof: %s, flags: %s]", source_p->name, user, host, spoof, flags); ilog(L_TRACE, "%s added auth for %s@%s [spoof: %s, flags: %s]", source_p->name, user, host, spoof, flags); #endif }
static void check_new_user(void *vdata) { struct Client *source_p = (void *)vdata; if (!IsIPSpoof(source_p)) return; if (EmptyString(source_p->user->suser)) return; char *accountpart = strstr(source_p->orighost, "account"); if (!accountpart) return; char buf[HOSTLEN]; memset(buf, 0, sizeof(buf)); char *dst = buf; strncpy(buf, source_p->orighost, accountpart - source_p->orighost); dst += accountpart - source_p->orighost; int needhash = 0; for (char *src = source_p->user->suser; *src ; src++ ) { if (dst > buf + sizeof(buf)) { /* Doesn't fit. Warn opers and bail. */ sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "Couldn't fit account name part %s in hostname for %s!%s@%s", source_p->user->suser, source_p->name, source_p->username, source_p->orighost); return; } char c = ToLower(*src); if (IsHostChar(c)) *dst++ = c; else needhash = 1; } if (needhash) { if (dst > buf + sizeof(buf) - 12) /* '/x-' plus eight digit hash plus null terminator */ { /* Doesn't fit. Warn opers and bail. */ sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "Couldn't fit account name part %s in hostname for %s!%s@%s", source_p->user->suser, source_p->name, source_p->username, source_p->orighost); return; } *dst++ = '/'; *dst++ = 'x'; *dst++ = '-'; unsigned int hashval = fnv_hash_string(source_p->user->suser); hashval %= 100000000; // eight digits only please. snprintf(dst, 9, "%08ud", hashval); } /* just in case */ buf[HOSTLEN-1] = '\0'; /* If hostname has been changed already (probably by services cloak on SASL login), then * leave it intact. If not, change it. In either case, update the original hostname. */ if (0 == irccmp(source_p->host, source_p->orighost)) change_nick_user_host(source_p, source_p->name, source_p->username, buf, 0, "Changing host"); strncpy(source_p->orighost, buf, HOSTLEN); }
int eval_host_char(char c) { return (0 != IsHostChar(c)); }