Example #1
0
/* magic main */
int main(int argc, char *argv[])
{
    int ch = 0; // verbose_already = 0;
    int daemon = 0;
    memset(&config, 0, sizeof(globalconfig));
    //set_default_config_options();
    config.inpacket = config.intr_flag = 0;
    config.dnslastchk = 0;
    //char *pconfile;
#define BPFF "port 53"
    config.bpff = BPFF;
    config.logfile = "/var/log/passivedns.log";
    config.logfile_nxd = "/var/log/passivedns.log";
    config.pidfile = "/var/run/passivedns.pid";
    config.mem_limit_max = (256 * 1024 * 1024); // 256 MB - default try to limit dns caching to this
    config.dnsprinttime = DNSPRINTTIME;
    config.dnscachetimeout =  DNSCACHETIMEOUT;
    config.dnsf = 0;
    config.dnsf |= DNS_CHK_A;
    config.dnsf |= DNS_CHK_AAAA;
    config.dnsf |= DNS_CHK_PTR;
    config.dnsf |= DNS_CHK_CNAME;
    config.dnsf |= DNS_CHK_DNAME;
    config.dnsf |= DNS_CHK_NAPTR;
    config.dnsf |= DNS_CHK_RP;
    config.dnsf |= DNS_CHK_SRV;
//    config.dnsf |= DNS_CHK_TXT;
//    config.dnsf |= DNS_CHK_SOA;
//    config.dnsf |= DNS_CHK_NS;
//    config.dnsf |= DNS_CHK_MX;
//    config.dnsf |= DNS_CHK_NXDOMAIN;

    signal(SIGTERM, game_over);
    signal(SIGINT, game_over);
    signal(SIGQUIT, game_over);
    signal(SIGALRM, sig_alarm_handler);

#define ARGS "i:r:l:L:hb:Dp:C:P:S:X:u:g:T:"

    while ((ch = getopt(argc, argv, ARGS)) != -1)
        switch (ch) {
        case 'i':
            config.dev = strdup(optarg);
            break;
        case 'r':
            config.pcap_file = strdup(optarg);
            break;
        case 'L':
            config.logfile_nxd = strdup(optarg);
            break;
        case 'l':
            config.logfile = strdup(optarg);
            break;
        case 'b':
            config.bpff = strdup(optarg);
            break;
        case 'p':
            config.pidfile = strdup(optarg);
            break;
        case 'C':
            config.dnscachetimeout = strtol(optarg, NULL, 0);
            break;
        case 'P':
            config.dnsprinttime = strtol(optarg, NULL, 0);
            break;
        case 'S':
            config.mem_limit_max = (strtol(optarg, NULL, 0) * 1024 * 1024);
            break;
        case 'X':
            parse_dns_flags(optarg);
            break;
        case 'D':
            daemon = 1;
            break;
        case 'T':
            config.chroot_dir = strdup(optarg);
            config.chroot_flag = 1;
            break;
        case 'u':
            config.user_name = strdup(optarg);
            config.drop_privs_flag = 1;
            break;
        case 'g':
            config.group_name = strdup(optarg);
            config.drop_privs_flag = 1;
            break;
        case 'h':
            usage();
            exit(0);
            break;
        case '?':
            elog("unrecognized argument: '%c'\n", optopt);
            break;
        default:
            elog("Did not recognize argument '%c'\n", ch);
        }

    olog("\n[*] Running passivedns %s\n", VERSION);
    olog("    Using %s\n", pcap_lib_version());

    if (config.pcap_file) {
        /* Read from PCAP file specified by '-r' switch. */
        olog("[*] Reading from file %s\n", config.pcap_file);
        if (!(config.handle = pcap_open_offline(config.pcap_file, config.errbuf))) {
            olog("[*] Unable to open %s.  (%s)", config.pcap_file, config.errbuf);
        }

    } else {

        /* * look up an available device if non specified */
        if (config.dev == 0x0)
            config.dev = pcap_lookupdev(config.errbuf);
        olog("[*] Device: %s\n", config.dev);

        if ((config.handle = pcap_open_live(config.dev, SNAPLENGTH, 1, 500, config.errbuf)) == NULL) {
            olog("[*] Error pcap_open_live: %s \n", config.errbuf);
            exit(1);
        }
        /* * B0rk if we see an error... */
        if (strlen(config.errbuf) > 0) {
            elog("[*] Error errbuf: %s \n", config.errbuf);
            exit(1);
        }

        if(config.chroot_dir){
            olog("[*] Chrooting to dir '%s'..\n", config.chroot_dir);
            if(set_chroot()){
                elog("[!] failed to chroot\n");
                exit(1);
            }
        }

        if (config.drop_privs_flag) {
            olog("[*] Dropping privs...\n");
            drop_privs();
        }

        if (daemon) {
            if (!is_valid_path(config.pidfile))
                elog("[*] Unable to create pidfile '%s'\n", config.pidfile);
            openlog("passivedns", LOG_PID | LOG_CONS, LOG_DAEMON);
            olog("[*] Daemonizing...\n\n");
            daemonize();
        }

    }

    if (config.handle == NULL) {
       game_over();
       return (1);
    }

    /** segfaults on empty pcap! */
    if ((pcap_compile(config.handle, &config.cfilter, config.bpff, 1, config.net_mask)) == -1) {
            olog("[*] Error pcap_compile user_filter: %s\n", pcap_geterr(config.handle));
            exit(1);
    }

    if (pcap_setfilter(config.handle, &config.cfilter)) {
            olog("[*] Unable to set pcap filter!  %s", pcap_geterr(config.handle));
    }

    alarm(TIMEOUT);

    olog("[*] Sniffing...\n\n");
    pcap_loop(config.handle, -1, got_packet, NULL);

    game_over();
    return (0);
}
Example #2
0
int main(int argc, char *argv[]) {

   int ch, fromfile, setfilter, version, drop_privs_flag, daemon_flag, chroot_flag;
   char *bpff, errbuf[PCAP_ERRBUF_SIZE];
   extern char *optarg;
   char roll_metric = 0;
   char roll_type = GIGABYTES;
   size_t roll_point = 2;
   roll_size = roll_point * GIGABYTE;

   int long_option_index = 0;
   static struct option long_options[] = {
     {"help", 0, NULL, '?'},
     {"interface", 1, NULL, 'i'},
     {"format", 1, NULL, 'f'},
     {"bpf", 1, NULL, 'b'},
     {"log-dir", 1, NULL, 'd'},
     {"daemonize", 0, NULL, 'D'},
     {"user", 1, NULL, 'u'},
     {"group", 1, NULL, 'g'},
     {"chroot-dir", 1, NULL, 'T'},
     {"pid-file", 1, NULL, 'p'},
     {"pcap-file", 1, NULL, 'r'},
     {0, 0, 0, 0}
   };


   bpf_u_int32 net_mask = 0;
   ch = fromfile = setfilter = version = drop_privs_flag = daemon_flag = 0;
   dev = "eth0";
   bpff = "";
   chroot_dir = "/tmp/";
   output_format = "sguil";
   cxtbuffer = NULL;
   cxtrackerid  = 0;
   dump_with_flush = inpacket = intr_flag = chroot_flag = 0;
   mode = 0;

   signal(SIGTERM, game_over);
   signal(SIGINT,  game_over);
   signal(SIGQUIT, game_over);
   signal(SIGHUP,  dump_active);
   signal(SIGALRM, set_end_sessions);

   while( (ch=getopt_long(argc, argv, "?b:d:DT:f:g:i:p:P:r:u:vw:s:t:", long_options, &long_option_index)) != EOF )
     switch (ch) {
      case 'i':
         dev = strdup(optarg);
         mode |= MODE_DEV;
         break;
      case 'b':
         bpff = strdup(optarg);
         break;
      case 'v':
         verbose = 1;
         break;
      case 'f':
         output_format = strdup(optarg);
         break;
      case 'd':
         snprintf(dpath, STDBUF, "%s", optarg);

         // normalise the directory path to ensure it's slash terminated
         if( dpath[strlen(dpath)-1] != '/' )
            strncat(dpath, "/", STDBUF);
         break;
      case '?':
         usage(argv[0]);
         exit_clean(0);
         break;
      case 'D':
         daemon_flag = 1;
         break;
      case 'T':
         chroot_flag = 1;
         break;
      case 'u':
         user_name = strdup(optarg);
         drop_privs_flag = 1;
         break;
      case 'g':
         group_name = strdup(optarg);
         drop_privs_flag = 1;
         break;
      case 'p':
         pidfile = strdup(optarg);
         break;
      case 'P':
         pidpath = strdup(optarg);
         break;
      case 'r':
         read_file = strdup(optarg);
         mode |= MODE_FILE;
         dev = NULL;
         break;
      case 'w':
         dump_file_prefix = strdup(optarg);
         mode |= MODE_DUMP;
         break;
      case 'F':
         dump_with_flush = 1;
         break;
      case 's':
         sscanf(optarg, "%zu%c", &roll_point, &roll_metric);

         switch( tolower(roll_metric) ) {
            case 'k':
               roll_size = roll_point * KILOBYTE;
               roll_type = KILOBYTES;
               break;
            case 'm':
               roll_size = roll_point * MEGABYTE;
               roll_type = MEGABYTES;
               break;
            case 'g':
               roll_size = roll_point * GIGABYTE;
               roll_type = GIGABYTES;
               break;
            case 't':
               roll_size = roll_point * TERABYTE;
               roll_type = TERABYTES;
               break;
            default:
               printf("[*] Invalid size metric: %c\n", roll_metric ? roll_metric : '-');
               break;
         }

         break;
      case 't':
         sscanf(optarg, "%zu%c", &roll_point, &roll_metric);

         switch( tolower(roll_metric) ) {
            case 's':
               roll_time = roll_point;
               roll_type = SECONDS;
               break;
            case 'm':
               roll_time = roll_point * 60;
               roll_type = MINUTES;
               break;
            case 'h':
               roll_time = roll_point * 60 * 60;
               roll_type = HOURS;
               break;
            case 'd':
               roll_time = roll_point * 60 * 60 * 24;
               roll_type = DAYS;
               break;
            default:
               printf("[*] Invalid size metric: %c\n", roll_metric ? roll_metric : '-');
               break;
         }

         break;
      default:
         exit_clean(1);
         break;
   }

   errbuf[0] = '\0';

   // validate the output format string
   format_validate(output_format);

   // specify reading from a device OR a file and not both
   if ( (mode & MODE_DEV) && (mode & MODE_FILE) )
   {
      printf("[!] You must specify a device OR file to read from, not both.\n");
      usage(argv[0]);
      exit_clean(1);
   }
   else if ( (mode & MODE_FILE) && read_file) {
      /* Read from PCAP file specified by '-r' switch. */
      printf("[*] Reading from file %s", read_file);
      if (!(handle = pcap_open_offline(read_file, errbuf))) {
         printf("\n");
         printf("[*] Unable to open %s. (%s)\n", read_file, errbuf);
         exit_clean(1);
      } else {
         printf(" - OK\n");
      }

      // in pcap_open_offline(), libpcap appears to use a static buffer
      // for reading in the file. we must use memcpy's to ensure data
      // persists as expected
      if ( ip_init(&ip_config, IP_SET_MEMCPY) )
      {
        printf("[!] Unable to initialise the IP library.\n");
        exit_clean(1);
      }
      else
        printf("[*] IP library using \"memcpy\" set.\n");
   }
   else if ( (mode & MODE_DEV) && dev) {
      if (getuid()) {
         printf("[*] You must be root..\n");
         exit_clean(1);
      }

      printf("[*] Running cxtracker %s\n",VERSION);

      //errbuf[0] = '\0';
      /* look up an availible device if non specified */
      if (dev == 0x0) dev = pcap_lookupdev(errbuf);
      printf("[*] Device: %s\n", dev);

      if ((handle = pcap_open_live(dev, SNAPLENGTH, 1, 500, errbuf)) == NULL) {
         printf("[*] Error pcap_open_live: %s \n", errbuf);
         exit_clean(1);
      }

      // in pcap_open_live(), libpcap maintains a heap allocated buffer
      // for reading off the wire. we can use pointer copies here for 
      // improved speed
      if ( ip_init(&ip_config, IP_SET_MEMCPY) )
      {
        printf("[*] Unable to initialise the IP library.\n");
        exit_clean(1);
      }
      else
        printf("[*] IP library using \"memcpy\" set.\n");

      if ( chroot_flag == 1 ) {
         set_chroot();
      }

      if(daemon_flag) {
         if(!is_valid_path(pidpath))
            printf("[*] PID path \"%s\" is bad, check privilege.",pidpath);
            openlog("cxtracker", LOG_PID | LOG_CONS, LOG_DAEMON);
            printf("[*] Daemonizing...\n\n");
            go_daemon();
      }
   }
   else
   {
      printf("[*] You must specify where to read from.\n");
      exit_clean(1);
   }

   if ((pcap_compile(handle, &cfilter, bpff, 1 ,net_mask)) == -1) {
      printf("[*] Error pcap_compile user_filter: %s\n", pcap_geterr(handle));
      exit_clean(1);
   }

   if (pcap_setfilter(handle, &cfilter)) {
      printf("[*] Unable to set pcap filter!  (%s)\n", pcap_geterr(handle));
   } else {
      pcap_freecode(&cfilter); // filter code not needed after setfilter
   }

   // set up dump mode now as appropriate
   if (mode & MODE_DUMP ) {
      printf("[*] Writing traffic to %s%s.*, rolling every %d %s\n",
          dpath, dump_file_prefix, (int)roll_point, rollover_names[(int)roll_type]);
      dump_file_open();
   }

   /* B0rk if we see an error... */
   if (strlen(errbuf) > 0) {
      printf("[*] Error errbuf: %s \n", errbuf);
      exit_clean(1);
   }

   if(drop_privs_flag) {
      printf("[*] Dropping privs...\n\n");
      drop_privs();
   }

   bucket_keys_NULL();

   alarm(TIMEOUT);
   if (read_file) {
      printf("[*] Reading packets...\n");
   } else {
      printf("[*] Sniffing...\n");
   }

   roll_time_last = time(NULL);
   pcap_loop(handle,-1,got_packet,NULL);

   game_over();

   return 0;
}
Example #3
0
int start_threaded_server ( OCSPD_CONFIG * ocspd_conf )
{
	int i = 0;
	int rv = 0;

	struct sockaddr_in cliaddr;
	socklen_t cliaddrlen;

	struct sigaction sa;

	// Just print a nice log message when exits
	atexit(close_server);

	if( ocspd_conf->token ) {

		if( PKI_TOKEN_init(ocspd_conf->token, 
				ocspd_conf->token_config_dir, ocspd_conf->token_name)
								== PKI_ERR)
		{
			PKI_log_err( "Can not load default token (%s/%s)",
				ocspd_conf->cnf_filename, ocspd_conf->token_name );
			exit(1);
		}

		PKI_TOKEN_cred_set_cb ( ocspd_conf->token, NULL, NULL);

		if (PKI_TOKEN_login ( ocspd_conf->token ) != PKI_OK)
		{
			PKI_log_debug("Can not login into token!");
			exit(1);
		}

		rv = PKI_TOKEN_check(ocspd_conf->token);
		if (rv & (PKI_TOKEN_STATUS_KEYPAIR_ERR |
							PKI_TOKEN_STATUS_CERT_ERR |
							PKI_TOKEN_STATUS_CACERT_ERR))
		{
			if (rv & PKI_TOKEN_STATUS_KEYPAIR_ERR) PKI_ERROR(PKI_ERR_TOKEN_KEYPAIR_LOAD, NULL);
			if (rv & PKI_TOKEN_STATUS_CERT_ERR) PKI_ERROR(PKI_ERR_TOKEN_CERT_LOAD, NULL);
			if (rv & PKI_TOKEN_STATUS_CACERT_ERR) PKI_ERROR(PKI_ERR_TOKEN_CACERT_LOAD, NULL);

			PKI_log_err("Token Configuration Fatal Error (%d)", rv);
			exit(rv);
		}
	}

	/* Initialize all the tokens configured for the single CA entries */
	for (i = 0; i < PKI_STACK_elements(ocspd_conf->ca_list); i++)
	{
		CA_LIST_ENTRY *ca = NULL;

		if ((ca = PKI_STACK_get_num( ocspd_conf->ca_list, i )) == NULL)
			continue;

		if (ca->token_name == NULL)
			continue;

		if ((ca->token = PKI_TOKEN_new_null()) == NULL)
		{
			PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
			exit (1);
		}

		PKI_TOKEN_cred_set_cb ( ocspd_conf->token, NULL, NULL);

		rv = PKI_TOKEN_init(ca->token, ca->token_config_dir, ca->token_name);
		if (rv != PKI_OK)
		{
			PKI_ERROR(rv, NULL);
			PKI_log_err ( "Can not load token %s for CA %s (%s)",
				ca->token_name, ca->ca_id, ca->token_config_dir );
			exit (rv);
		}

		rv = PKI_TOKEN_login(ca->token);
		if (rv != PKI_OK)
		{
			PKI_log_err("Can not login into token (%s)!", ca->ca_id);
			exit(rv);
		}

		rv = PKI_TOKEN_check(ca->token);
		if ( rv & (PKI_TOKEN_STATUS_KEYPAIR_ERR |
							 PKI_TOKEN_STATUS_CERT_ERR |
							 PKI_TOKEN_STATUS_CACERT_ERR))
		{
			if (rv & PKI_TOKEN_STATUS_KEYPAIR_ERR) PKI_ERROR(PKI_TOKEN_STATUS_KEYPAIR_ERR, NULL);
			if (rv & PKI_TOKEN_STATUS_CERT_ERR) PKI_ERROR(PKI_TOKEN_STATUS_CERT_ERR, NULL);
			if (rv & PKI_TOKEN_STATUS_CACERT_ERR) PKI_ERROR(PKI_TOKEN_STATUS_CACERT_ERR, NULL);

			PKI_log_err ( "Token Configuration Fatal Error (%d) for ca %s", rv, ca->ca_id);
			exit(rv);
		}
	}

	if((ocspd_conf->listenfd = PKI_NET_listen (ocspd_conf->bindUrl->addr,
					ocspd_conf->bindUrl->port, PKI_NET_SOCK_STREAM )) == PKI_ERR ) {
		PKI_log_err ("Can not bind to [%s],[%d]",
			ocspd_conf->bindUrl->addr, ocspd_conf->bindUrl->port);
		exit(101);
	}

	// Now Chroot the application
	if ((ocspd_conf->chroot_dir) && (set_chroot( ocspd_conf ) < 1))
	{
		PKI_log_err ("Can not chroot, exiting!");
		exit(204);
	}

	// Set privileges
	if (set_privileges(ocspd_conf) < 1)
	{
		if (ocspd_conf->chroot_dir != NULL)
		{
			PKI_log(PKI_LOG_ALWAYS, "SECURITY:: Can not drop privileges! [203]");
			PKI_log(PKI_LOG_ALWAYS, "SECURITY:: Continuing because chrooted");
		}
		else
		{
			PKI_log(PKI_LOG_ALWAYS, "SECURITY:: Can not drop privileges! [204]");
			PKI_log(PKI_LOG_ALWAYS, "SECURITY:: Check User/Group in config file!");
			exit(204);
		}
	}

	if((ocspd_conf->threads_list = calloc ( (size_t) ocspd_conf->nthreads, 
					sizeof(Thread))) == NULL )
	{
		PKI_log_err ("Memory allocation failed");
		exit(79);
	}

	// Creates the Threads
	for (i = 0; i < ocspd_conf->nthreads; i++)
	{
		if (thread_make(i) != 0)
		{
			PKI_log_err ("Can not create thread (%d)\n", i );
			exit(80);
		}
	}

	// Register the alarm handler
	set_alrm_handler();

	// Just print a nice log message when killed
	signal(SIGTERM, handle_sigterm );
	signal(SIGABRT, handle_sigabrt );

	// Setting the SIGHUP in order to reload the CRLs
	// sa.sa_handler = auto_crl_check;
	sa.sa_handler = force_crl_reload;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = SA_RESTART;

	if (sigaction(SIGHUP, &sa, NULL) == -1)
	{
		PKI_log_err("Error during setting sig_handler");
		exit(1);
	}

	cliaddrlen = sizeof( cliaddr );
	for ( ; ; ) 
	{
		// Acquires the Mutex for handling the ocspd_conf->connfd
		PKI_MUTEX_acquire ( &ocspd_conf->mutexes[CLIFD_MUTEX] );
		if ((ocspd_conf->connfd = PKI_NET_accept(ocspd_conf->listenfd, 0)) == -1)
		{
			// Provides some information about the error
			if (ocspd_conf->verbose || ocspd_conf->debug)
			{
				char err_str[512];
				PKI_log_err("Network Error [%d::%s]", errno,
						strerror_r(errno, err_str, sizeof(err_str)));
			}

			// Returns the connfd MUTEX and restart from the top of the cycle
			PKI_MUTEX_release(&ocspd_conf->mutexes[CLIFD_MUTEX]);
			continue;
		}

		// Some debugging information
		if (ocspd_conf->debug)
		{
			if (getpeername(ocspd_conf->connfd, (struct sockaddr*)&cliaddr, &cliaddrlen) == -1)
			{
				char err_str[512];
				PKI_log_err("Network Error [%d::%s] in getpeername", errno,
					strerror_r(errno, err_str, sizeof(err_str)));
			}

			PKI_log(PKI_LOG_INFO, "Connection from [%s]",
	 			inet_ntoa(cliaddr.sin_addr));
		}

		// Communicate that there is a good socket waiting for a thread to pickup
		PKI_COND_broadcast ( &ocspd_conf->condVars[CLIFD_COND] );
		PKI_MUTEX_release ( &ocspd_conf->mutexes[CLIFD_MUTEX] );

		// Waits for a thread to successfully pickup the socket
		PKI_MUTEX_acquire ( &ocspd_conf->mutexes[SRVFD_MUTEX] );
		while (ocspd_conf->connfd > 2)
		{
			PKI_COND_wait ( &ocspd_conf->condVars[SRVFD_COND],
				&ocspd_conf->mutexes[SRVFD_MUTEX] );
		}
		PKI_MUTEX_release ( &ocspd_conf->mutexes[SRVFD_MUTEX] );
	}

	return(0);
}