Example #1
0
/*
 * Writes a G-Line to the appropriate file.
 */
void
gs_write(int f, char type, struct userBan *ub)
{
    char outbuf[1024];
    char cidr[4] = "";
    time_t expiretime = 0;
    char *user = "******";
    char *reason = "";
    char *host = ub->h;
    int len;

    /* userban.c */
    unsigned int netmask_to_cidr(unsigned int);

    if (ub->flags & UBAN_TEMPORARY)
        expiretime = ub->timeset + ub->duration;

    if (ub->u)
        user = ub->u;

    if (ub->reason)
        reason = ub->reason;

    if (ub->flags & (UBAN_CIDR4|UBAN_CIDR4BIG))
    {
        host = inetntoa((char *)&ub->cidr4ip);
        ircsprintf(cidr, "/%d", netmask_to_cidr(ntohl(ub->cidr4mask)));
    }

    if (type == '+')
        len = ircsprintf(outbuf, "%c %d %s %s%s %s\n", type, (int)expiretime,
                         user, host, cidr, reason);
    else
        len = ircsprintf(outbuf, "%c %s %s%s\n", type, user, host, cidr);

    write(f, outbuf, len);
}
Example #2
0
static int route_print_cb (void *ctx, struct route_entry *e)
{
	FILE *f = ctx;
	struct in_addr dst, gw;

	dst.s_addr = e->dst;
	gw.s_addr  = e->gw;

	if (dst.s_addr == INADDR_ANY)
		fprintf (f, "default");
	else {
		fprintf (f, "%s", inet_ntoa (dst));

		if (e->mask != INADDR_BROADCAST)
			fprintf (f, "/%d", netmask_to_cidr (e->mask));
	}

	if (gw.s_addr != INADDR_ANY)
		fprintf (f, " via %s", inet_ntoa (gw));

	fprintf (f, " dev %s\n", e->dev);

	return 1;
}
Example #3
0
/**
 * Load bogons data from the supplied FILE.
 *
 * @returns the amount of entries loaded.
 */
static G_GNUC_COLD int
bogons_load(FILE *f)
{
	char line[1024];
	uint32 ip, netmask;
	int linenum = 0;
	int bits;
	iprange_err_t error;
	filestat_t buf;

	bogons_db = iprange_new();
	if (-1 == fstat(fileno(f), &buf)) {
		g_warning("cannot stat %s: %m", bogons_file);
	} else {
		bogons_mtime = buf.st_mtime;
	}

	while (fgets(line, sizeof line, f)) {
		linenum++;

		/*
		 * Remove all trailing spaces in string.
		 * Otherwise, lines which contain only spaces would cause a warning.
		 */

		if (!file_line_chomp_tail(line, sizeof line, NULL)) {
			g_warning("%s, line %d: too long a line", bogons_file, linenum);
			break;
		}

		if (file_line_is_skipable(line))
			continue;

		if (!string_to_ip_and_mask(line, &ip, &netmask)) {
			g_warning("%s, line %d: invalid IP or netmask \"%s\"",
				bogons_file, linenum, line);
			continue;
		}

		bits = netmask_to_cidr(netmask);
		error = iprange_add_cidr(bogons_db, ip, bits, 1);

		switch (error) {
		case IPR_ERR_OK:
			break;
			/* FALL THROUGH */
		default:
			g_warning("%s, line %d: rejected entry \"%s\" (%s/%d): %s",
				bogons_file, linenum, line, ip_to_string(ip), bits,
				iprange_strerror(error));
			continue;
		}
	}

	iprange_sync(bogons_db);

	if (GNET_PROPERTY(reload_debug)) {
		g_debug("loaded %u bogus IP ranges (%u hosts)",
			iprange_get_item_count(bogons_db),
			iprange_get_host_count4(bogons_db));
	}

	return iprange_get_item_count(bogons_db);
}
Example #4
0
/**
 * Loads the whitelist into memory.
 */
static void G_COLD
whitelist_retrieve(void)
{
	char line[1024];
	FILE *f;
	filestat_t st;
	unsigned linenum = 0;
	file_path_t fp[1];

	whitelist_generation++;

	file_path_set(fp, settings_config_dir(), whitelist_file);
	f = file_config_open_read_norename("Host Whitelist", fp, N_ITEMS(fp));
	if (!f)
		return;

	if (fstat(fileno(f), &st)) {
		g_warning("%s(): fstat() failed: %m", G_STRFUNC);
		fclose(f);
		return;
	}

    while (fgets(line, sizeof line, f)) {
		pslist_t *sl_addr, *sl;
		const char *endptr, *start;
		host_addr_t addr;
    	uint16 port;
		uint8 bits;
		bool item_ok;
		bool use_tls;
		char *hname;

        linenum++;

		if (!file_line_chomp_tail(line, sizeof line, NULL)) {
			g_warning("%s(): line %u too long, aborting", G_STRFUNC, linenum);
			break;
		}

        if (file_line_is_skipable(line))
			continue;

		sl_addr = NULL;
		addr = zero_host_addr;
		endptr = NULL;
		hname = NULL;

		endptr = is_strprefix(line, "tls:");
		if (endptr) {
			use_tls = TRUE;
			start = endptr;
		} else {
			use_tls = FALSE;
			start = line;
		}

		port = 0;
		if (string_to_host_addr_port(start, &endptr, &addr, &port)) {
       		sl_addr = name_to_host_addr(host_addr_to_string(addr),
							settings_dns_net());
		} else if (string_to_host_or_addr(start, &endptr, &addr)) {
			uchar c = *endptr;

			switch (c) {
			case '\0':
			case ':':
			case '/':
				break;
			default:
				if (!is_ascii_space(c))
					endptr = NULL;
			}

			if (!endptr) {
				g_warning("%s(): line %d: "
					"expected a hostname or IP address \"%s\"",
					G_STRFUNC, linenum, line);
				continue;
			}

			/* Terminate the string for name_to_host_addr() */
			hname = h_strndup(start, endptr - start);
		} else {
            g_warning("%s(): line %d: expected hostname or IP address \"%s\"",
				G_STRFUNC, linenum, line);
			continue;
		}

       	g_assert(sl_addr != NULL || hname != NULL);
		g_assert(NULL != endptr);
		bits = 0;
		item_ok = TRUE;

		/*
		 * When an explicit address is given (no hostname) and with no
		 * port, one can suffix the address with bits to indicate a CIDR
		 * range of whitelisted addresses.
		 */

		if (0 == port) {
			/* Ignore trailing items separated by a space */
			while ('\0' != *endptr && !is_ascii_space(*endptr)) {
				uchar c = *endptr++;

				if (':' == c) {
					int error;
					uint32 v;

					if (0 != port) {
						g_warning("%s(): line %d: multiple colons after host",
							G_STRFUNC, linenum);
						item_ok = FALSE;
						break;
					}

					v = parse_uint32(endptr, &endptr, 10, &error);
					port = (error || v > 0xffff) ? 0 : v;
					if (0 == port) {
						g_warning("%s(): line %d: "
							"invalid port value after host",
							G_STRFUNC, linenum);
						item_ok = FALSE;
						break;
					}
				} else if ('/' == c) {
					const char *ep;
					uint32 mask;

					if (0 != bits) {
						g_warning("%s(): line %d: "
							"multiple slashes after host", G_STRFUNC, linenum);
						item_ok = FALSE;
						break;
					}

					if (string_to_ip_strict(endptr, &mask, &ep)) {
						if (!host_addr_is_ipv4(addr)) {
							g_warning("%s(): line %d: "
								"IPv4 netmask after non-IPv4 address",
								G_STRFUNC, linenum);
							item_ok = FALSE;
							break;
						}
						endptr = ep;

						if (0 == (bits = netmask_to_cidr(mask))) {
							g_warning("%s(): line %d: "
								"IPv4 netmask after non-IPv4 address",
								G_STRFUNC, linenum);
							item_ok = FALSE;
							break;
						}

					} else {
						int error;
						uint32 v;

						v = parse_uint32(endptr, &endptr, 10, &error);
						if (
							error ||
							0 == v ||
							(v > 32 && host_addr_is_ipv4(addr)) ||
							(v > 128 && host_addr_is_ipv6(addr))
						) {
							g_warning("%s(): line %d: "
								"invalid numeric netmask after host",
								G_STRFUNC, linenum);
							item_ok = FALSE;
							break;
						}
						bits = v;
					}
				} else {
					g_warning("%s(): line %d: "
						"unexpected character after host", G_STRFUNC, linenum);
					item_ok = FALSE;
					break;
				}
			}
		}

		if (item_ok) {
			struct whitelist *item;
			if (hname) {
				item = whitelist_hostname_create(use_tls, hname, port);
				whitelist_dns_resolve(item, FALSE);
			} else {
				PSLIST_FOREACH(sl_addr, sl) {
					host_addr_t *aptr = sl->data;
					g_assert(aptr != NULL);
					item = whitelist_addr_create(use_tls, *aptr, port, bits);
					whitelist_add(item);
				}
			}
		} else {