/* 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); }
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; }
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); }