Пример #1
0
main()
{
  char *x;
  int udp53;

  x = env_get("IP");
  if (!x)
    strerr_die2x(111,fatal,"$IP not set");
  if (!ip4_scan(x,ip))
    strerr_die3x(111,fatal,"unable to parse IP address ",x);

  udp53 = socket_udp();
  if (udp53 == -1)
    strerr_die2sys(111,fatal,"unable to create UDP socket: ");
  if (socket_bind4_reuse(udp53,ip,53) == -1)
    strerr_die2sys(111,fatal,"unable to bind UDP socket: ");

  droproot(fatal);

  initialize();
  
  ndelay_off(udp53);
  socket_tryreservein(udp53,65536);

  for (;;) {
    len = socket_recv4(udp53,buf,sizeof buf,ip,&port);
    if (len < 0) continue;
    if (!doit()) continue;
    if (response_len > 512) response_tc();
    socket_send4(udp53,response,response_len,ip,port);
    /* may block for buffer space; if it fails, too bad */
  }
}
Пример #2
0
int
main (int argc, char *argv[])
{
    time_t t = 0;
    char *x = NULL;
    struct sigaction sa;
    iopause_fd *iop = NULL;
    int i = 0, n = 0, *udp53 = NULL;

    prog = strdup ((x = strrchr (argv[0], '/')) != NULL ? x + 1 : argv[0]);

    sa.sa_handler = handle_term;
    sigaction (SIGINT, &sa, NULL);
    sigaction (SIGTERM, &sa, NULL);

    sa.sa_handler = SIG_IGN;
    sigaction (SIGPIPE, &sa, NULL);

    i = check_option (argc, argv);
    argc -= i;
    argv += i;

    if (mode & DAEMON)
    {
        i = fork ();
        if (i == -1)
            err (-1, "could not fork a daemon process");
        if (i > 0)
            return 0;
    }

    time (&t);
    memset (buf, 0, sizeof (buf));
    strftime (buf, sizeof (buf), "%b-%d %Y %T %Z", localtime (&t));
    warnx ("version %s: starting: %s\n", VERSION, buf);

    set_timezone ();
    if (debug_level)
        warnx ("TIMEZONE: %s", env_get ("TZ"));

    initialize ();
    if (!debug_level)
        if ((x = env_get ("DEBUG_LEVEL")))
            debug_level = atol (x);
    warnx ("DEBUG_LEVEL set to `%d'", debug_level);

    if ((x = env_get ("DATALIMIT")))
    {
        struct rlimit r;
        unsigned long dlimit = atol (x);

        if (getrlimit (RLIMIT_DATA,  &r) != 0)
            err (-1, "could not get resource RLIMIT_DATA");

        r.rlim_cur = (dlimit <= r.rlim_max) ? dlimit : r.rlim_max;

        if (setrlimit (RLIMIT_DATA, &r) != 0)
            err (-1, "could not set resource RLIMIT_DATA");

        if (debug_level)
            warnx ("DATALIMIT set to `%ld' bytes", r.rlim_cur);
    }

    if (!(x = env_get ("IP")))
        err (-1, "$IP not set");
    for (i = 0; (unsigned)i < strlen (x); i++)
        n = (x[i] == ',') ? n+1 : n;
    if (!(udp53 = calloc (n+1, sizeof (int))))
        err (-1, "could not allocate enough memory for udp53");
    if (!(iop = calloc (n+1, sizeof (iopause_fd))))
        err (-1, "could not allocate enough memory for iop");

    i = n = 0;
    while (x[i])
    {
        unsigned int l = 0;

        if (!(l = ip4_scan(x+i, ip)))
            errx (-1, "could not parse IP address `%s'", x + i);

        udp53[n] = socket_udp();
        if (udp53[n] == -1)
            errx (-1, "could not open UDP socket");
        if (socket_bind4_reuse (udp53[n], ip, server_port) == -1)
            errx (-1, "could not bind UDP socket");

        ndelay_off (udp53[n]);
        socket_tryreservein (udp53[n], 65536);

        iop[n].fd = udp53[n];
        iop[n].events = IOPAUSE_READ;

        n++;
        i += (x[i + l] == ',') ? l + 1 : l;
    }

    droproot ();
    while (1)
    {
        struct taia stamp;
        struct in_addr odst; /* original destination IP */
        struct taia deadline;

        taia_now (&stamp);
        taia_uint (&deadline, 300);
        taia_add (&deadline, &deadline, &stamp);
        iopause (iop, n, &deadline, &stamp);

        for (i = 0; i < n; i++)
        {
            if (!iop[i].revents)
                continue;

            len = socket_recv4 (udp53[i], buf, sizeof (buf), ip, &port, &odst);
            if (len < 0)
                continue;
            if (!doit ())
                continue;
            if (response_len > 512)
                response_tc ();

            /* may block for buffer space; if it fails, too bad */
            len = socket_send4 (udp53[i], response,
                                response_len, ip, port, &odst);
            if (len < 0)
                continue;
            if (debug_level > 1)
                log_querydone(qnum, response, response_len);
        }
    }

    return 0;
}
Пример #3
0
int
main (int argc, char *argv[])
{
    int i = 0;
    time_t t = 0;
    struct sigaction sa;
    unsigned long cachesize = 0;
    char *x = NULL, char_seed[128];

    sa.sa_handler = handle_term;
    sigaction (SIGINT, &sa, NULL);
    sigaction (SIGTERM, &sa, NULL);

    sa.sa_handler = SIG_IGN;
    sigaction (SIGPIPE, &sa, NULL);

    seed_addtime ();
    seed_adduint32 (getpid ());
    seed_adduint32 (getppid ());
    seed_adduint32 (getuid ());
    seed_adduint32 (getgid ());

    seed_addtime ();
    prog = strdup ((x = strrchr (argv[0], '/')) != NULL ?  x + 1 : argv[0]);
    i = check_option (argc, argv);
    argc -= i;
    argv += i;

    if (mode & DAEMON)
    {
        i = fork ();
        if (i == -1)
            err (-1, "could not fork a daemon process");
        if (i > 0)
            return 0;
    }

    time (&t);
    strftime (char_seed, sizeof (char_seed), "%b-%d %Y %T %Z", localtime (&t));
    warnx ("version %s: starting: %s\n", VERSION, char_seed);

    set_timezone ();
    if (debug_level)
        warnx ("TIMEZONE: %s", env_get ("TZ"));

    read_conf (CFGFILE);
    if (!debug_level)
        if ((x = env_get ("DEBUG_LEVEL")))
            debug_level = atol (x);
    warnx ("DEBUG_LEVEL set to `%d'", debug_level);

    if ((x = env_get ("DATALIMIT")))
    {
        struct rlimit r;
        unsigned long dlimit = atol (x);

        if (getrlimit (RLIMIT_DATA,  &r) != 0)
            err (-1, "could not get resource RLIMIT_DATA");

        r.rlim_cur = (dlimit <= r.rlim_max) ? dlimit : r.rlim_max;

        if (setrlimit (RLIMIT_DATA, &r) != 0)
            err (-1, "could not set resource RLIMIT_DATA");

        if (debug_level)
            warnx ("DATALIMIT set to `%ld' bytes", r.rlim_cur);
    }

    if (!(x = env_get ("IP")))
        err (-1, "$IP not set");
    if (!ip4_scan (x, myipincoming))
        err (-1, "could not parse IP address `%s'", x);

    seed_addtime ();
    udp53 = socket_udp ();
    if (udp53 == -1)
        err (-1, "could not open UDP socket");
    if (socket_bind4_reuse (udp53, myipincoming, 53) == -1)
        err (-1, "could not bind UDP socket");

    seed_addtime ();
    tcp53 = socket_tcp ();
    if (tcp53 == -1)
        err (-1, "could not open TCP socket");
    if (socket_bind4_reuse (tcp53, myipincoming, 53) == -1)
        err (-1, "could not bind TCP socket");

    if (mode & DAEMON)
    {
        /* redirect stdout & stderr to a log file */
        redirect_to_log (LOGFILE, STDOUT_FILENO | STDERR_FILENO);

        write_pid (PIDFILE);
    }

    seed_addtime ();
    droproot ();
    if (mode & DAEMON)
        /* crerate a new session & detach from controlling tty */
        if (setsid () < 0)
            err (-1, "could not start a new session for the daemon");

    seed_addtime ();
    socket_tryreservein (udp53, 131072);

    memset (char_seed, 0, sizeof (char_seed));
    for (i = 0, x = (char *)seed; (unsigned)i < sizeof (char_seed); i++, x++)
        char_seed[i] = *x;
    dns_random_init (char_seed);

    if (!(x = env_get ("IPSEND")))
        err (-1, "$IPSEND not set");
    if (!ip4_scan (x, myipoutgoing))
        err (-1, "could not parse IP address `%s'", x);

    if (!(x = env_get ("CACHESIZE")))
        err (-1, "$CACHESIZE not set");
    scan_ulong (x, &cachesize);
    if (!cache_init (cachesize))
        err (-1, "could not allocate `%ld' bytes for cache", cachesize);

    if (env_get ("HIDETTL"))
        response_hidettl ();
    if (env_get ("FORWARDONLY"))
        query_forwardonly ();
    if (env_get ("MERGEQUERIES"))
        dns_enable_merge (log_merge);
    if (!roots_init ())
        err (-1, "could not read servers");
    if (debug_level > 3)
        roots_display();
    if (socket_listen (tcp53, 20) == -1)
        err (-1, "could not listen on TCP socket");
    if (!dbl_init() && debug_level > 1)
        warnx ("could not read dnsbl.cdb");

    doit ();

    return 0;
}
Пример #4
0
void
process_args(nmsgtool_ctx *c) {
	char *t;
	FILE *fp_pidfile = NULL;
	nmsg_msgmod_t mod = NULL;

	if (c->help)
		usage(NULL);

	if (c->version) {
#ifdef HAVE_LIBXS
		fprintf(stderr, "%s: version %s\n", argv_program, PACKAGE_VERSION);
#else /* HAVE_LIBXS */
		fprintf(stderr, "%s: version %s (without libxs support)\n",
			argv_program, PACKAGE_VERSION);
#endif /* HAVE_LIBXS */
		exit(EXIT_SUCCESS);
	}

	if (c->endline == NULL)
		c->endline_str = strdup("\n");
	else
		c->endline_str = unescape(c->endline);

	if (c->mtu == 0)
		c->mtu = NMSG_WBUFSZ_JUMBO;

	if (c->vname == NULL && c->mname != NULL)
		c->vname = "base";

	if (c->vname != NULL) {
		if (c->mname == NULL)
			usage("-V requires -T");
		c->vid = nmsg_msgmod_vname_to_vid(c->vname);
		if (c->vid == 0)
			usage("invalid vendor ID");
		if (c->debug >= 2)
			fprintf(stderr, "%s: input vendor = %s\n",
				argv_program, c->vname);
	}
	if (c->mname != NULL) {
		if (c->vname == NULL)
			usage("-T requires -V");
		c->msgtype = nmsg_msgmod_mname_to_msgtype(c->vid, c->mname);
		if (c->msgtype == 0)
			usage("invalid message type");
		if (c->debug >= 2)
			fprintf(stderr, "%s: input msgtype = %s\n",
				argv_program, c->mname);
	}
	if (c->debug < 1)
		c->debug = 1;
	if (c->debug > 0)
		nmsg_io_set_debug(c->io, c->debug);
	if (c->count > 0)
		nmsg_io_set_count(c->io, c->count);
	if (c->interval > 0)
		nmsg_io_set_interval(c->io, c->interval);
	if (c->mirror == true)
		nmsg_io_set_output_mode(c->io, nmsg_io_output_mode_mirror);

	/* bpf string */
	if (c->bpfstr == NULL) {
		t = getenv("NMSG_BPF");
		if (t != NULL)
			c->bpfstr = strdup(t);
	}

	/* kicker command */
	if (c->kicker == NULL) {
		t = getenv("NMSG_KICKER");
		if (t != NULL)
			c->kicker = strdup(t);
	}

	/* set source, operator, group */
	if (c->set_source_str != NULL) {
		c->set_source = (unsigned) strtoul(c->set_source_str, &t, 0);
		if (*t != '\0')
			usage("invalid source ID");
		if (c->debug >= 2)
			fprintf(stderr, "%s: nmsg source set to %#.08x\n",
				argv_program, c->set_source);
	}

	if (c->set_operator_str != NULL) {
		c->set_operator = nmsg_alias_by_value(nmsg_alias_operator,
						      c->set_operator_str);
		if (c->set_operator == 0)
			usage("unknown operator name");
		if (c->debug >= 2)
			fprintf(stderr, "%s: nmsg operator set to '%s' (%u)\n",
				argv_program,
				c->set_operator_str,
				c->set_operator);
	}

	if (c->set_group_str != NULL) {
		c->set_group = nmsg_alias_by_value(nmsg_alias_group,
						   c->set_group_str);
		if (c->set_group == 0)
			usage("unknown group name");
		if (c->debug >= 2)
			fprintf(stderr, "%s: nmsg group set to '%s' (%u)\n",
				argv_program,
				c->set_group_str,
				c->set_group);
	}

	/* get source, operator, group */
	if (c->get_source_str != NULL) {
		c->get_source = (unsigned) strtoul(c->get_source_str, &t, 0);
		if (*t != '\0')
			usage("invalid filter source ID");
		if (c->debug >= 2)
			fprintf(stderr, "%s: nmsg source filter set to "
					"%#.08x\n",
				argv_program, c->get_source);
	}

	if (c->get_operator_str != NULL) {
		c->get_operator = nmsg_alias_by_value(nmsg_alias_operator,
						      c->get_operator_str);
		if (c->get_operator == 0)
			usage("unknown filter operator name");
		if (c->debug >= 2)
			fprintf(stderr, "%s: nmsg filter operator set to "
					"'%s' (%u)\n",
				argv_program,
				c->get_operator_str,
				c->get_operator);
	}

	if (c->get_group_str != NULL) {
		c->get_group = nmsg_alias_by_value(nmsg_alias_group,
						   c->get_group_str);
		if (c->get_group == 0)
			usage("unknown filter group name");
		if (c->debug >= 2)
			fprintf(stderr, "%s: nmsg filter group set to "
					"'%s' (%u)\n",
				argv_program,
				c->get_group_str,
				c->get_group);
	}

	/* -V, -T sanity check */
	if (ARGV_ARRAY_COUNT(c->r_pres) > 0 ||
	    ARGV_ARRAY_COUNT(c->r_pcapfile) > 0 ||
	    ARGV_ARRAY_COUNT(c->r_pcapif) > 0)
	{
		if (c->vname == NULL || c->mname == NULL)
			usage("reading presentation or pcap data requires "
			      "-V, -T");
		mod = nmsg_msgmod_lookup(c->vid, c->msgtype);
		if (mod == NULL)
			usage("unknown msgmod");
	}

#define process_args_loop(arry, func) do { \
	for (int i = 0; i < ARGV_ARRAY_COUNT(arry); i++) \
		func(c, *ARGV_ARRAY_ENTRY_P(arry, char *, i)); \
} while(0)

#define process_args_loop_mod(arry, func, mod) do { \
	for (int i = 0; i < ARGV_ARRAY_COUNT(arry); i++) \
		func(c, mod, *ARGV_ARRAY_ENTRY_P(arry, char *, i)); \
} while(0)

	/* pcap interface inputs */
	process_args_loop_mod(c->r_pcapif, add_pcapif_input, mod);

	/* open pidfile if necessary */
	if (c->pidfile != NULL)
		fp_pidfile = pidfile_open(c->pidfile);
	else
		fp_pidfile = NULL;

	/* drop privileges */
	if (c->username != NULL)
		droproot(c, fp_pidfile);

	/* pcap file inputs */
	process_args_loop_mod(c->r_pcapfile, add_pcapfile_input, mod);

	/* XS context */
	if (ARGV_ARRAY_COUNT(c->r_xsock) > 0 ||
	    ARGV_ARRAY_COUNT(c->w_xsock) > 0 ||
	    ARGV_ARRAY_COUNT(c->r_xchannel) > 0)
	{
#ifdef HAVE_LIBXS
		c->xs_ctx = xs_init();
		if (c->xs_ctx == NULL) {
			fprintf(stderr, "%s: xs_init() failed: %s\n",
				argv_program, strerror(errno));
			exit(EXIT_FAILURE);
		}
#else /* HAVE_LIBXS */
		fprintf(stderr, "%s: Error: compiled without libxs support\n",
			argv_program);
		exit(EXIT_FAILURE);
#endif /* HAVE_LIBXS */
	}

	/* nmsg inputs and outputs */
	process_args_loop(c->r_sock, add_sock_input);
	process_args_loop(c->w_sock, add_sock_output);
	process_args_loop(c->r_xsock, add_xsock_input);
	process_args_loop(c->w_xsock, add_xsock_output);
	process_args_loop(c->r_nmsg, add_file_input);
	process_args_loop(c->w_nmsg, add_file_output);

	for (int i = 0; i < ARGV_ARRAY_COUNT(c->r_channel); i++) {
		char *ch;
		char **alias = NULL;
		int num_aliases;

		ch = *ARGV_ARRAY_ENTRY_P(c->r_channel, char *, i);
		if (c->debug >= 2)
			fprintf(stderr, "%s: looking up channel '%s'\n", argv_program, ch);
		num_aliases = nmsg_chalias_lookup(ch, &alias);
		if (num_aliases <= 0)
			usage("channel alias lookup failed");
		for (int j = 0; j < num_aliases; j++) {
			if (strstr(alias[j], "://"))
				usage("channel alias appears to be an xchannel");
			add_sock_input(c, alias[j]);
		}
		nmsg_chalias_free(&alias);
	}

	for (int i = 0; i < ARGV_ARRAY_COUNT(c->r_xchannel); i++) {
		char *ch;
		char **alias = NULL;
		int num_aliases;

		ch = *ARGV_ARRAY_ENTRY_P(c->r_xchannel, char *, i);
		if (c->debug >= 2)
			fprintf(stderr, "%s: looking up xchannel '%s'\n", argv_program, ch);
		num_aliases = nmsg_chalias_lookup(ch, &alias);
		if (num_aliases <= 0)
			usage("xchannel alias lookup failed");
		for (int j = 0; j < num_aliases; j++)
			add_xsock_input(c, alias[j]);
		nmsg_chalias_free(&alias);
	}

	/* pres inputs and outputs */
	process_args_loop_mod(c->r_pres, add_pres_input, mod);
	process_args_loop(c->w_pres, add_pres_output);

#undef process_args_loop
#undef process_args_loop_mod

	/* validation */
	if (c->n_inputs == 0)
		usage("no data sources specified");
	if (c->n_outputs == 0) {
		/* implicit "-o -" */
		add_pres_output(c, "-");
	}

	/* daemonize if necessary */
	if (c->daemon) {
		if (!daemonize()) {
			fprintf(stderr, "nmsgtool: unable to daemonize: %s\n",
				strerror(errno));
			exit(EXIT_FAILURE);
		}
	}

	/* write pidfile if necessary */
	if (c->pidfile != NULL && fp_pidfile != NULL)
		pidfile_write(fp_pidfile);
}
Пример #5
0
int
main (int argc, char *argv[])
{
    int n = 0;
    time_t t = 0;
    struct sigaction sa;

    char qtype[2];
    char qclass[2];
    char header[12];
    const char *x = NULL;
    unsigned int pos = 0;
    unsigned long long qnum = 0;

    sa.sa_handler = handle_term;
    sigaction (SIGINT, &sa, NULL);
    sigaction (SIGTERM, &sa, NULL);

    sa.sa_handler = SIG_IGN;
    sigaction (SIGPIPE, &sa, NULL);

    prog = strdup ((x = strrchr (argv[0], '/')) != NULL ?  x + 1 : argv[0]);
    n = check_option (argc, argv);
    argc -= n;
    argv += n;

    if (mode & DAEMON)
        /* redirect stderr to a log file */
        redirect_to_log (logfile, STDERR_FILENO);

    time (&t);
    memset (seed, 0, sizeof (seed));
    strftime (seed, sizeof (seed), "%b-%d %Y %T %Z", localtime (&t));
    warnx ("version %s: starting %s\n", VERSION, seed);

    set_timezone ();
    if (debug_level)
        warnx ("TIMEZONE: %s", env_get ("TZ"));

    read_conf (cfgfile);
    if (!debug_level)
        if ((x = env_get ("DEBUG_LEVEL")))
            debug_level = atol (x);
    warnx ("DEBUG_LEVEL set to `%d'", debug_level);

    dns_random_init (seed);

    axfr = env_get ("AXFR");
    if (debug_level)
        warnx ("AXFR set to `%s'", axfr);
    x = env_get ("TCPREMOTEIP");
    if (debug_level)
        warnx ("TCPREMOTEIP set to `%s'", x);
    if (x)
        ip4_scan (x, ip);
    else
        byte_zero (ip, 4);

    x = env_get ("TCPREMOTEPORT");
    if (debug_level)
        warnx ("TCPREMOTEPORT set to `%s'", x);
    if (!x)
        x = "0";
    scan_ulong (x, &port);

    droproot ();
    for (;;)
    {
        netread (tcpheader, 2);
        uint16_unpack_big (tcpheader, &len);
        if (len > 512)
            errx (-1, "excessively large request");
        netread (buf, len);

        pos = dns_packet_copy (buf, len, 0, header, 12);
        if (!pos)
            errx (-1, "truncated request");
        if (header[2] & 254)
            errx (-1, "bogus query");
        if (header[4] || (header[5] != 1))
            errx (-1, "bogus query");

        pos = dns_packet_getname (buf, len, pos, &zone);
        if (!pos)
            errx (-1, "truncated request");
        zonelen = dns_domain_length (zone);
        pos = dns_packet_copy (buf, len, pos, qtype, 2);
        if (!pos)
            errx (-1, "truncated request");
        pos = dns_packet_copy (buf, len, pos, qclass, 2);
        if (!pos)
            errx (-1, "truncated request");

        if (byte_diff(qclass, 2, DNS_C_IN) && byte_diff(qclass, 2, DNS_C_ANY))
            errx (-1, "bogus query: bad class");

        log_query (++qnum, ip, port, header, zone, qtype);
        if (byte_equal(qtype,2,DNS_T_AXFR))
        {
            case_lowerb (zone, zonelen);
            fdcdb = open_read ("data.cdb");
            if (fdcdb == -1)
                errx (-1, "could not read from file `data.cdb'");
            doaxfr (header);
            close (fdcdb);
        }
        else
        {
            if (!response_query (zone, qtype, qclass))
                err (-1, "could not allocate enough memory");
            response[2] |= 4;
            case_lowerb (zone, zonelen);
            response_id (header);
            response[3] &= ~128;
            if (!(header[2] & 1))
                response[2] &= ~1;
            if (!respond (zone, qtype, ip))
                errx (-1, "could not find information in file `data.cdb'");
            print (response, response_len);
        }
    }
}
Пример #6
0
int main()
{
  unsigned char *remotehost, *remoteinfo, *remoteip, *remoteport;
  unsigned char query[256];
  unsigned char clean_query[256];
  unsigned char *qptr, *qptr2;
  int len, query_len;
  int fd, r = 0;
  struct cdb c;
  stralloc answer = {0};
  
  /* chroot() to $ROOT and switch to $UID:$GID */
  droproot("dffingerd: ");

  /* since we run under tcpserver, we can get all info 
     about the remote side from the enviroment */
  remotehost = env_get("TCPREMOTEHOST");
  if (!remotehost) remotehost = "unknown";
  remoteinfo = env_get("TCPREMOTEINFO");
  if (!remoteinfo) remoteinfo = "-";
  remoteip = env_get("TCPREMOTEIP");
  if (!remoteip) remoteip = "unknown";
  remoteport = env_get("TCPREMOTEPORT");
  if (!remoteport) remoteport = "unknown";
  
  /* now: 
     remotehost is the remote hostname or "unknown" 
     remoteinfo is some ident string or "-"
     remoteip is the remote ipadress or "unknown" (?)
  */

  /* Read the request from the client and \0-terminate it */
  /* timeout after 60 seconds */
  query_len = timeoutread(60, stdin, query, sizeof(query) - 1);
  query[query_len] = '\0';
     
  /* Handle RfC 1288 stuff */
  qptr=query;
  if (*qptr==' ') qptr++;
  if (*qptr=='/' 
      && (*(qptr+1)=='W' || *(qptr+1)=='w') 
      && *(qptr+2) == ' ') 
    qptr+=3;
  
  /* \0-terminate query at the first \r or \n */
  for (len = 0; query[len]; len++) 
    {
      if (query[len] == '\r' || query[len] == '\n') 
	{
	  query[len] = '\0';
	  break;
	}
    }          

  /* clean up query string a bit by removing chars witch could 
     clobber logging or so and replace them with _ -> extra Paranoia */
  for(qptr2 = clean_query; *qptr; qptr++)
    {
      if(is_meta (*qptr)) 
	{
	  *qptr2++ = '_';
	}
      else 
	{
	  *qptr2++ = *qptr;
	}
    }
  *qptr2 = '\0';
  
  /* Do logging */
  buffer_puts(buffer_2, remotehost);
  buffer_puts(buffer_2, " [");
  buffer_puts(buffer_2, remoteip);  
  buffer_puts(buffer_2, ":");
  buffer_puts(buffer_2, remoteport);
  buffer_puts(buffer_2, "] ");
  buffer_puts(buffer_2, remoteinfo);
  buffer_puts(buffer_2, " ");
  buffer_puts(buffer_2, clean_query);
  buffer_puts(buffer_2, "\n");
  buffer_flush(buffer_2);


  /* If there was any data we will go on */
  if (query_len > 0)
    {
      /* Open & init our cdb */
      fd = open_read("data.cdb");
      if (fd == -1)
	{
	  /* If opening failed quit */
	  strerr_die2sys(111, FATAL, "can't open data.cdb");
	}      
      cdb_init(&c, fd);
  
      /* Search query for "user" on the database */
      r = cdb_find(&c, clean_query, str_len(clean_query)); 
      if (r == 1)
	{
	  /* read data */
	  stralloc_ready(&answer, cdb_datalen(&c));
	  if (cdb_read(&c, answer.s, cdb_datalen(&c), cdb_datapos(&c)) == -1)
	    {
	      	  strerr_die2sys(111, FATAL, "can't read from data.cdb");
	    }
	  else
	    {
	      answer.len = cdb_datalen(&c);
	    }
	}
      else 
	{
	  /* We didn't find the requested user, try DEFAULTUSER */
	  r = cdb_find(&c,DEFAULTUSER, str_len(DEFAULTUSER)); 
	  if (r == 1)
	    {
	      /* read data */
	      stralloc_ready(&answer, cdb_datalen(&c));
	      if (cdb_read(&c, answer.s ,cdb_datalen(&c) ,cdb_datapos(&c)) == -1)
		{
	      	  strerr_die2sys(111, FATAL, "can't read from data.cdb");
		}
	      else
		{
		  answer.len = cdb_datalen(&c);
		}
	    }
	  else 
	    {
	      /* no data for DEFAULTUSER either, so we don't have any data for the client */
	      stralloc_copys(&answer, NOPE);
	    }
	}      

      /* write to the network with 120s timeout */
      /* I guess the timeout isn't needed on an usual Unix */
      r = timeoutwrite(120, stdout, answer.s, answer.len);
      if (r <= 0)   
	{
	  strerr_die2sys(111, FATAL, "unable to write to network: ");
	}
      
      /* free database */
      cdb_free(&c);
      close(fd);      
    }
  else
    {
      *clean_query = '\0';
    }
  
  return 0;
}
Пример #7
0
int main()
{
  char *x;
  unsigned int i, j, k;
  unsigned long cachesize;
  static stralloc sa = {0};

  x = env_get("INTERFACE");
  if (x) scan_ulong(x,&interface);

  x = env_get("IP");
  if (!x)
    strerr_die2x(111,FATAL,"$IP not set");
  if (!ip6_scan(x,myipincoming))
    strerr_die3x(111,FATAL,"unable to parse IP address ",x);

#if 0
  /* if if IP is a mapped-IPv4 address, disable IPv6 functionality */
  /* this is actually a bad idea */
  if (ip6_isv4mapped(myipincoming))
    noipv6 = 1;
#endif

  udp53 = socket_udp6();
  if (udp53 == -1)
    strerr_die2sys(111,FATAL,"unable to create UDP socket: ");
  if (socket_bind6_reuse(udp53,myipincoming,53,interface) == -1)
    strerr_die2sys(111,FATAL,"unable to bind UDP socket: ");

  tcp53 = socket_tcp6();
  if (tcp53 == -1)
    strerr_die2sys(111,FATAL,"unable to create TCP socket: ");
  if (socket_bind6_reuse(tcp53,myipincoming,53,interface) == -1)
    strerr_die2sys(111,FATAL,"unable to bind TCP socket: ");

  droproot(FATAL);

  socket_tryreservein(udp53,131072);

  byte_zero(seed,sizeof seed);
  read(0,seed,sizeof seed);
  dns_random_init(seed);
  close(0);

  x = env_get("IPSEND");
  if (!x)
    strerr_die2x(111,FATAL,"$IPSEND not set");
  if (!ip6_scan(x,myipoutgoing))
    strerr_die3x(111,FATAL,"unable to parse IP address ",x);

  x = env_get("CACHESIZE");
  if (!x)
    strerr_die2x(111,FATAL,"$CACHESIZE not set");
  scan_ulong(x,&cachesize);
  if (!cache_init(cachesize))
    strerr_die3x(111,FATAL,"not enough memory for cache of size ",x);

  if (openreadclose("ignoreip",&sa,64) < 0) 
    strerr_die2x(111,FATAL,"trouble reading ignoreip");
  for(j = k = i = 0; i < sa.len; i++)
    if (sa.s[i] == '\n')  {
      sa.s[i] = '\0';
      if (!stralloc_readyplus(&ignoreip,16))
	strerr_die2x(111,FATAL,"out of memory parsing ignoreip");
      if (!ip6_scan(sa.s+k,ignoreip.s+j))
        strerr_die3x(111,FATAL,"unable to parse address in ignoreip ",ignoreip.s+k);
      j += 16;
      k = i + 1;
    }
  ignoreip.len = j;

  if (env_get("HIDETTL"))
    response_hidettl();
  if (env_get("FORWARDONLY"))
    query_forwardonly();

  if (!roots_init())
    strerr_die2sys(111,FATAL,"unable to read servers: ");

  if (socket_listen(tcp53,20) == -1)
    strerr_die2sys(111,FATAL,"unable to listen on TCP socket: ");

  log_startup();
  doit();
}
Пример #8
0
int main()
{
  unsigned int pos;
  char header[12];
  char qtype[2];
  char qclass[2];
  const char *x;

  droproot(FATAL);
  dns_random_init(seed);

  axfr = env_get("AXFR");
  
  x = env_get("TCPREMOTEIP");
  if (x && ip6_scan(x,ip))
    ;
  else
    byte_zero(ip,16);

  x = env_get("TCPREMOTEPORT");
  if (!x) x = "0";
  scan_ulong(x,&port);

  for (;;) {
    netread(tcpheader,2);
    uint16_unpack_big(tcpheader,&len);
    if (len > 512) strerr_die2x(111,FATAL,"excessively large request");
    netread(buf,len);

    pos = dns_packet_copy(buf,len,0,header,12); if (!pos) die_truncated();
    if (header[2] & 254) strerr_die2x(111,FATAL,"bogus query");
    if (header[4] || (header[5] != 1)) strerr_die2x(111,FATAL,"bogus query");

    pos = dns_packet_getname(buf,len,pos,&zone); if (!pos) die_truncated();
    zonelen = dns_domain_length(zone);
    pos = dns_packet_copy(buf,len,pos,qtype,2); if (!pos) die_truncated();
    pos = dns_packet_copy(buf,len,pos,qclass,2); if (!pos) die_truncated();

    if (byte_diff(qclass,2,DNS_C_IN) && byte_diff(qclass,2,DNS_C_ANY))
      strerr_die2x(111,FATAL,"bogus query: bad class");

    pos = check_edns0(header, buf, len, pos);
    if (!pos) die_truncated();

    qlog(ip,port,header,zone,qtype," ");

    if (byte_equal(qtype,2,DNS_T_AXFR)) {
      case_lowerb(zone,zonelen);
      fdcdb = open_read("data.cdb");
      if (fdcdb == -1) die_cdbread();
      doaxfr(header);
      close(fdcdb);
    }
    else {
      if (!response_query(zone,qtype,qclass)) nomem();
      response[2] |= 4;
      case_lowerb(zone,zonelen);
      response_id(header);
      response[3] &= ~128;
      if (!(header[2] & 1)) response[2] &= ~1;
      if (!respond(zone,qtype,ip)) die_outside();
      print(response,response_len);
    }
  }
}