void Load_Ignore_List ( void ) { FILE *droplist; char droplistbuf[1024] = { 0 }; if ( config->sagan_droplist_flag ) { if (( droplist = fopen(config->sagan_droplistfile, "r" )) == NULL ) { Sagan_Log(1, "[%s, line %d] No drop list/ignore list to load (%s)", __FILE__, __LINE__, config->sagan_droplistfile); config->sagan_droplist_flag=0; } while(fgets(droplistbuf, 1024, droplist) != NULL) { /* Skip comments and blank linkes */ if (droplistbuf[0] == '#' || droplistbuf[0] == 10 || droplistbuf[0] == ';' || droplistbuf[0] == 32) { continue; } else { /* Allocate memory for references, not comments */ SaganDroplist = (_Sagan_Droplist *) realloc(SaganDroplist, (counters->droplist_count+1) * sizeof(_Sagan_Droplist)); snprintf(SaganDroplist[counters->droplist_count].ignore_string, sizeof(SaganDroplist[counters->droplist_count].ignore_string), "%s", Remove_Return(droplistbuf)); counters->droplist_count++; } } } }
void Remove_Lock_File ( void ) { struct stat lckcheck; if ((stat(config->sagan_lockfile, &lckcheck) == 0) && unlink(config->sagan_lockfile) != 0 ) { Sagan_Log(S_ERROR, "[%s, line %d] Cannot remove lock file (%s)\n", __FILE__, __LINE__, config->sagan_lockfile); } }
int Sagan_Search_Load ( int type ) { FILE *search; char searchbuf[1024] = { 0 }; char tmpfile[MAXPATH]; /* Init processor info */ processor_info_search = malloc(sizeof(struct _Sagan_Processor_Info)); memset(processor_info_search, 0, sizeof(_Sagan_Processor_Info)); processor_info_search->processor_name = SEARCH_PROCESSOR_NAME; processor_info_search->processor_generator_id = SEARCH_PROCESSOR_GENERATOR_ID; processor_info_search->processor_name = SEARCH_PROCESSOR_NAME; processor_info_search->processor_facility = SEARCH_PROCESSOR_FACILITY; processor_info_search->processor_priority = SEARCH_PROCESSOR_PRIORITY; processor_info_search->processor_pri = SEARCH_PROCESSOR_PRI; processor_info_search->processor_class = SEARCH_PROCESSOR_CLASS; processor_info_search->processor_tag = SEARCH_PROCESSOR_TAG; processor_info_search->processor_rev = SEARCH_PROCESSOR_REV; if ( type == 1 ) { strlcpy(tmpfile, config->search_nocase_file, sizeof(tmpfile)); } else { strlcpy(tmpfile, config->search_case_file, sizeof(tmpfile)); } if (( search = fopen(tmpfile, "r" )) == NULL ) { Sagan_Log(S_ERROR, "[%s, line %d] No search list to load (%s)", __FILE__, __LINE__, config->search_nocase_file); } while(fgets(searchbuf, 1024, search) != NULL) { /* Skip comments and blank linkes */ if (searchbuf[0] == '#' || searchbuf[0] == 10 || searchbuf[0] == ';' || searchbuf[0] == 32) { continue; } else { if ( type == 1) { SaganNocaseSearchlist = (_Sagan_Nocase_Searchlist *) realloc(SaganNocaseSearchlist, (counters->search_nocase_count+1) * sizeof(_Sagan_Nocase_Searchlist)); strlcpy(SaganNocaseSearchlist[counters->search_nocase_count].search, Remove_Return(searchbuf), sizeof(SaganNocaseSearchlist[counters->search_nocase_count].search)); counters->search_nocase_count++; } else { SaganCaseSearchlist = (_Sagan_Case_Searchlist *) realloc(SaganCaseSearchlist, (counters->search_case_count+1) * sizeof(_Sagan_Case_Searchlist)); strlcpy(SaganCaseSearchlist[counters->search_case_count].search, Remove_Return(searchbuf), sizeof(SaganCaseSearchlist[counters->search_case_count].search)); counters->search_case_count++; } } } return(0); }
void Sagan_Set_Pipe_Size ( FILE *fd ) { int fd_int; int current_fifo_size; int fd_results; if ( config->sagan_fifo_size != 0 ) { fd_int = fileno(fd); current_fifo_size = fcntl(fd_int, F_GETPIPE_SZ); if ( current_fifo_size == config->sagan_fifo_size ) { Sagan_Log(S_NORMAL, "FIFO capacity already set to %d bytes.", config->sagan_fifo_size); } else { Sagan_Log(S_NORMAL, "FIFO capacity is %d bytes. Changing to %d bytes.", current_fifo_size, config->sagan_fifo_size); fd_results = fcntl(fd_int, F_SETPIPE_SZ, config->sagan_fifo_size ); if ( fd_results == -1 ) { Sagan_Log(S_WARN, "FIFO capacity could not be changed. Continuing anyways..."); } if ( fd_results > config->sagan_fifo_size ) { Sagan_Log(S_WARN, "FIFO capacity was rounded up to the next page size of %d bytes.", fd_results); } } } }
sbool Sagan_BroIntel_IPADDR ( uint32_t ip ) { int i; /* If RFC1918, we can short circuit here */ if ( is_rfc1918(ip)) { if ( debug->debugbrointel ) { Sagan_Log(S_DEBUG, "[%s, line %d] %u is RFC1918, link local or invalid.", __FILE__, __LINE__, ip); } return(false); } /* Search array for for the IP address */ for ( i = 0; i < counters->brointel_addr_count; i++) { if ( Sagan_BroIntel_Intel_Addr[i].u32_ip == ip ) { if ( debug->debugbrointel ) { Sagan_Log(S_DEBUG, "[%s, line %d] Found IP %u.", __FILE__, __LINE__, ip); } return(true); } } return(false); }
int DNS_Lookup( char *host, char *str, size_t size ) { char ipstr[INET6_ADDRSTRLEN] = { 0 }; struct addrinfo hints = {0}, *res = NULL; int status; void *addr; /* Short circuit if it's a "localhost" lookup */ if ( !strcmp(host, "localhost" ) ) { snprintf(str, size, "%s", config->sagan_host); return(0); } memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; /* AF_INET or AF_INET6 to force version */ hints.ai_socktype = SOCK_STREAM; if ((status = getaddrinfo(host, NULL, &hints, &res)) != 0) { Sagan_Log(WARN, "%s: %s", gai_strerror(status), host); return -1; } if (res->ai_family == AF_INET) /* IPv4 */ { struct sockaddr_in *ipv4 = (struct sockaddr_in *)res->ai_addr; addr = &(ipv4->sin_addr); } else /* IPv6 */ { struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)res->ai_addr; addr = &(ipv6->sin6_addr); } inet_ntop(res->ai_family, addr, ipstr, sizeof ipstr); freeaddrinfo(res); snprintf(str, size, "%s", ipstr); return 0; }
void Droppriv(void) { struct stat fifocheck; struct passwd *pw = NULL; int ret; pw = getpwnam(config->sagan_runas); if (!pw) { Sagan_Log(ERROR, "Couldn't locate user '%s'. Aborting...", config->sagan_runas); } if ( getuid() == 0 ) { Sagan_Log(NORMAL, "Setting permissions and dropping privileges! [UID: %lu GID: %lu]", (unsigned long)pw->pw_uid, (unsigned long)pw->pw_gid); /* * We chown certain log files to our Sagan user. This is done so no files are "owned" * by "root". This prevents problems in the future when doing things like handling * SIGHUP's and what not. * * Champ Clark (04/14/2015) */ if ( config->sagan_is_file == false ) /* Don't change ownsership/etc if we're processing a file */ { ret = chown(config->sagan_fifo, (unsigned long)pw->pw_uid,(unsigned long)pw->pw_gid); if ( ret < 0 ) { Sagan_Log(ERROR, "[%s, line %d] Cannot change ownership of %s to username \"%s\" - %s", __FILE__, __LINE__, config->sagan_fifo, config->sagan_runas, strerror(errno)); } if (stat(config->sagan_fifo, &fifocheck) != 0 ) { Sagan_Log(ERROR, "[%s, line %d] Cannot open %s FIFO - %s!", __FILE__, __LINE__, config->sagan_fifo, strerror(errno)); } } if (initgroups(pw->pw_name, pw->pw_gid) != 0 || setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) { Sagan_Log(ERROR, "[%s, line %d] Could not drop privileges to uid: %lu gid: %lu - %s!", __FILE__, __LINE__, (unsigned long)pw->pw_uid, (unsigned long)pw->pw_gid, strerror(errno)); } } else { Sagan_Log(NORMAL, "Not dropping privileges. Already running as a non-privileged user"); } }
void Load_Reference( const char *ruleset ) { FILE *reffile; char refbuf[1024]; char *saveptr=NULL; char *firststring=NULL; char *tmptoken=NULL; char *laststring=NULL; int linecount=0; Sagan_Log(S_NORMAL, "Loading references.conf file. [%s]" , ruleset); if (( reffile = fopen(ruleset, "r" )) == NULL ) { Sagan_Log(S_ERROR, "[%s, line %d] Cannot open rule file (%s)", __FILE__, __LINE__, ruleset); } while(fgets(refbuf, 1024, reffile) != NULL) { linecount++; /* Skip comments and blank linkes */ if (refbuf[0] == '#' || refbuf[0] == 10 || refbuf[0] == ';' || refbuf[0] == 32) { continue; } else { /* Allocate memory for references, not comments */ refstruct = (_Ref_Struct *) realloc(refstruct, (counters->refcount+1) * sizeof(_Ref_Struct)); } firststring = strtok_r(refbuf, ":", &saveptr); tmptoken = strtok_r(NULL, " " , &saveptr); laststring = strtok_r(tmptoken, ",", &saveptr); if ( laststring == NULL ) Sagan_Log(S_ERROR, "[%s, line %d] The file %s at line %d is improperly formated. Abort!", __FILE__, __LINE__, ruleset, linecount); strlcpy(refstruct[counters->refcount].s_refid, laststring, sizeof(refstruct[counters->refcount].s_refid)); laststring = strtok_r(NULL, ",", &saveptr); if ( laststring == NULL ) Sagan_Log(S_ERROR, "[%s, line %d] The file %s at line %d is improperly formated. Abort!", __FILE__, __LINE__, ruleset, linecount); strlcpy(refstruct[counters->refcount].s_refurl, laststring, sizeof(refstruct[counters->refcount].s_refurl)); refstruct[counters->refcount].s_refurl[strlen(refstruct[counters->refcount].s_refurl)-1] = '\0'; if (debug->debugload) Sagan_Log(S_DEBUG, "[D-%d] Reference: %s|%s", counters->refcount, refstruct[counters->refcount].s_refid, refstruct[counters->refcount].s_refurl); counters->refcount++; } fclose(reffile); Sagan_Log(S_NORMAL, "%d references loaded.", counters->refcount); }
bool File_Unlock( int fd ) { struct flock fl; fl.l_type = F_UNLCK; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; fl.l_pid = getpid(); if (fcntl(fd, F_SETLK, &fl) == -1) { Sagan_Log(WARN, "[%s, line %d] Unable to get UNLOCK on file. (%s)", __FILE__, __LINE__, strerror(errno)); } return(0); }
void checklockfile ( void ) { char buf[10]; FILE *lck; int pid; struct stat lckcheck; /* Check for lockfile first */ if (stat(config->sagan_lockfile, &lckcheck) == 0 ) { /* Lock file is present, open for read */ if (( lck = fopen(config->sagan_lockfile, "r" )) == NULL ) { Sagan_Log(S_ERROR, "[%s, line %d] Lock file (%s) is present but can't be read", __FILE__, __LINE__, config->sagan_lockfile); } else { if (!fgets(buf, sizeof(buf), lck)) Sagan_Log(S_ERROR, "[%s, line %d] Lock file (%s) is open for reading, but can't read contents.", __FILE__, __LINE__, config->sagan_lockfile); fclose(lck); pid = atoi(buf); if ( pid == 0 ) Sagan_Log(S_ERROR, "[%s, line %d] Lock file read but pid value is zero. Aborting.....", __FILE__, __LINE__); /* Check to see if process is running. We use kill with 0 signal * to determine this. We check this return value. Signal 0 * won't affect running processes */ if ( kill(pid, 0) != -1 ) { Sagan_Log(S_ERROR, "[%s, line %d] It appears that Sagan is already running (pid: %d).", __FILE__, __LINE__, pid); } else { Sagan_Log(S_NORMAL, "[%s, line %d] Lock file is present, but Sagan isn't at pid %d (Removing stale %s file)", __FILE__, __LINE__, pid, config->sagan_lockfile); if (unlink(config->sagan_lockfile)) { Sagan_Log(S_ERROR, "Unable to delete %s. ", config->sagan_lockfile); } } } } else { /* No lock file present, so create it */ if (( lck = fopen(config->sagan_lockfile, "w" )) == NULL ) { Sagan_Log(S_ERROR, "[%s, line %d] Cannot create lock file (%s)", __FILE__, __LINE__, config->sagan_lockfile); } else { fprintf(lck, "%d", getpid() ); fflush(lck); fclose(lck); } } }
sbool Sagan_BroIntel_URL ( char *syslog_message ) { int i; for ( i = 0; i < counters->brointel_url_count; i++) { if ( Sagan_stristr(syslog_message, Sagan_BroIntel_Intel_URL[i].url, false) ) { if ( debug->debugbrointel ) { Sagan_Log(S_DEBUG, "[%s, line %d] Found URL \"%s\".", __FILE__, __LINE__, Sagan_BroIntel_Intel_URL[i].url); } return(true); } } return(false); }
sbool Sagan_BroIntel_CERT_HASH ( char *syslog_message ) { int i; for ( i = 0; i < counters->brointel_cert_hash_count; i++) { if ( Sagan_stristr(syslog_message, Sagan_BroIntel_Intel_Cert_Hash[i].cert_hash, false) ) { if ( debug->debugbrointel ) { Sagan_Log(S_DEBUG, "[%s, line %d] Found the CERT_HASH \"%s\".", __FILE__, __LINE__, Sagan_BroIntel_Intel_Cert_Hash[i].cert_hash); } return(true); } } return(false); }
sbool Sagan_BroIntel_FILE_NAME ( char *syslog_message ) { int i; for ( i = 0; i < counters->brointel_file_name_count; i++) { if ( Sagan_stristr(syslog_message, Sagan_BroIntel_Intel_File_Name[i].file_name, false) ) { if ( debug->debugbrointel ) { Sagan_Log(S_DEBUG, "[%s, line %d] Found the file name \"%s\".", __FILE__, __LINE__, Sagan_BroIntel_Intel_File_Name[i].file_name); } return(true); } } return(false); }
sbool Sagan_BroIntel_EMAIL ( char *syslog_message ) { int i; for ( i = 0; i < counters->brointel_email_count; i++) { if ( Sagan_stristr(syslog_message, Sagan_BroIntel_Intel_Email[i].email, false) ) { if ( debug->debugbrointel ) { Sagan_Log(S_DEBUG, "[%s, line %d] Found e-mail address \"%s\".", __FILE__, __LINE__, Sagan_BroIntel_Intel_Email[i].email); } return(true); } } return(false); }
sbool Sagan_BroIntel_SOFTWARE ( char *syslog_message ) { int i; for ( i = 0; i < counters->brointel_software_count; i++) { if ( Sagan_stristr(syslog_message, Sagan_BroIntel_Intel_Software[i].software, false) ) { if ( debug->debugbrointel ) { Sagan_Log(S_DEBUG, "[%s, line %d] Found software \"%s\".", __FILE__, __LINE__, Sagan_BroIntel_Intel_Software[i].software); } return(true); } } return(false); }
void Sagan_Track_Clients_Init ( void ) { processor_info_track_client = malloc(sizeof(struct _Sagan_Processor_Info)); if ( processor_info_track_client == NULL ) { Sagan_Log(S_ERROR, "[%s, line %d] Failed to allocate memory for processor_info_track_client. Abort!", __FILE__, __LINE__); } memset(processor_info_track_client, 0, sizeof(_Sagan_Processor_Info)); processor_info_track_client->processor_name = PROCESSOR_NAME; processor_info_track_client->processor_generator_id = PROCESSOR_GENERATOR_ID; processor_info_track_client->processor_name = PROCESSOR_NAME; processor_info_track_client->processor_facility = PROCESSOR_FACILITY; processor_info_track_client->processor_priority = PROCESSOR_PRIORITY; processor_info_track_client->processor_pri = PROCESSOR_PRI; processor_info_track_client->processor_class = PROCESSOR_CLASS; processor_info_track_client->processor_tag = PROCESSOR_TAG; processor_info_track_client->processor_rev = PROCESSOR_REV; }
sbool Sagan_BroIntel_FILE_HASH ( char *syslog_message ) { int i; for ( i = 0; i < counters->brointel_file_hash_count; i++) { if ( Sagan_stristr(syslog_message, Sagan_BroIntel_Intel_File_Hash[i].hash, false) ) { if ( debug->debugbrointel ) { Sagan_Log(S_DEBUG, "[%s, line %d] Found file hash %s.", __FILE__, __LINE__, Sagan_BroIntel_Intel_File_Hash[i].hash); } return(true); } } return(false); }
sbool Sagan_BroIntel_DOMAIN ( char *syslog_message ) { int i; for ( i = 0; i < counters->brointel_domain_count; i++) { if ( Sagan_stristr(syslog_message, Sagan_BroIntel_Intel_Domain[i].domain, false) ) { if ( debug->debugbrointel ) { Sagan_Log(S_DEBUG, "[%s, line %d] Found domain %s.", __FILE__, __LINE__, Sagan_BroIntel_Intel_Domain[i].domain); } return(true); } } return(false); }
char *DNS_Lookup( char *host ) { struct addrinfo hints, *res; //,// *p; int status; char ipstr[INET6_ADDRSTRLEN]; char *ret; void *addr; if ( config->disable_dns_warnings == 0 ) { Sagan_Log(S_WARN, "--------------------------------------------------------------------------"); Sagan_Log(S_WARN, "Sagan DNS lookup need for %s.", host); Sagan_Log(S_WARN, "This can affect performance. Please see:" ); Sagan_Log(S_WARN, "https://wiki.quadrantsec.com/bin/view/Main/SaganDNS"); Sagan_Log(S_WARN, "--------------------------------------------------------------------------"); } memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version hints.ai_socktype = SOCK_STREAM; if ((status = getaddrinfo(host, NULL, &hints, &res)) != 0) { Sagan_Log(S_WARN, "%s: %s", gai_strerror(status), host); return "0"; } if (res->ai_family == AF_INET) // IPv4 { struct sockaddr_in *ipv4 = (struct sockaddr_in *)res->ai_addr; addr = &(ipv4->sin_addr); } else // IPv6 { struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)res->ai_addr; addr = &(ipv6->sin6_addr); } inet_ntop(res->ai_family, addr, ipstr, sizeof ipstr); free(res); ret=ipstr; return ret; }
void Load_Config( void ) { FILE *sagancfg; char *filename; char ruleset[MAXPATH]; char normfile[MAXPATH]; char tmpbuf[CONFBUF]; char tmpbuf2[CONFBUF]; char tmpstring[CONFBUF]; char *sagan_option=NULL; char *sagan_var1=NULL; char *sagan_var2=NULL; char *ptmp=NULL; char *tok=NULL; int i,check; /* Set some system defaults */ strlcpy(config->sagan_alert_filepath, ALERTLOG, sizeof(config->sagan_alert_filepath)); strlcpy(config->sagan_lockfile, LOCKFILE, sizeof(config->sagan_lockfile)); strlcpy(config->sagan_log_path, SAGANLOGPATH, sizeof(config->sagan_log_path)); if ( config->sagan_fifo_flag != 1 ) strlcpy(config->sagan_fifo, FIFO, sizeof(config->sagan_fifo)); strlcpy(config->sagan_rule_path, RULE_PATH, sizeof(config->sagan_rule_path)); config->sagan_proto = 17; /* Default to UDP */ config->max_processor_threads = MAX_PROCESSOR_THREADS; /* PLOG defaults */ #ifdef HAVE_LIBPCAP strlcpy(config->plog_interface, PLOG_INTERFACE, sizeof(config->plog_interface)); strlcpy(config->plog_filter, PLOG_FILTER, sizeof(config->plog_filter)); strlcpy(config->plog_logdev, PLOG_LOGDEV, sizeof(config->plog_logdev)); #endif //config->home_any = 0; //config->external_any = 0; /* Start loading configuration */ rulestruct = (_Rule_Struct *) realloc(rulestruct, (counters->rulecount+1) * sizeof(_Rule_Struct)); /* Gather information for the master configuration file */ if ((sagancfg = fopen(config->sagan_config, "r")) == NULL) { fprintf(stderr, "[%s, line %d] Cannot open configuration file (%s)\n", __FILE__, __LINE__, config->sagan_config); exit(1); } while(fgets(tmpbuf, sizeof(tmpbuf), sagancfg) != NULL) { if (tmpbuf[0] == '#') continue; if (tmpbuf[0] == ';') continue; if (tmpbuf[0] == 10 ) continue; if (tmpbuf[0] == 32 ) continue; strlcpy(tmpbuf2, tmpbuf, sizeof(tmpbuf2)); /* Retain a copy of the entire line */ sagan_option = strtok_r(tmpbuf, " ", &tok); if (!strcmp(Remove_Return(sagan_option), "max_processor_threads")) { sagan_var1 = strtok_r(NULL, " ", &tok); config->max_processor_threads = strtoull(sagan_var1, NULL, 10); } if (!strcmp(Remove_Return(sagan_option), "disable_dns_warnings")) { Sagan_Log(S_NORMAL, "Supressing DNS warnings"); config->disable_dns_warnings = 1; } if (!strcmp(Remove_Return(sagan_option), "syslog_src_lookup")) { Sagan_Log(S_NORMAL, "DNS lookup of source address supplied by syslog daemon"); config->syslog_src_lookup = 1; } if (!strcmp(sagan_option, "sagan_host")) strlcpy(config->sagan_host, Remove_Return(strtok_r(NULL, " " , &tok)), sizeof(config->sagan_host)); if (!strcmp(sagan_option, "sagan_port")) { sagan_var1 = strtok_r(NULL, " ", &tok); config->sagan_port = atoi(sagan_var1); } #ifndef HAVE_LIBESMTP if (!strcmp(sagan_option, "send-to") || !strcmp(sagan_option, "min_email_priority")) Sagan_Log(S_ERROR, "\"libesmtp\" support not found. Re-compile with ESMTP support or disable in the sagan.conf."); #endif #ifdef HAVE_LIBESMTP if (!strcmp(sagan_option, "send-to")) { sagan_var1 = strtok_r(NULL, " ", &tok); strlcpy(config->sagan_esmtp_to, Remove_Return(sagan_var1), sizeof(config->sagan_esmtp_to)); config->sagan_esmtp_flag=1; config->sagan_sendto_flag=1; } if (!strcmp(sagan_option, "min_email_priority")) { sagan_var1 = strtok_r(NULL, " ", &tok); config->min_email_priority = atoi(sagan_var1); } #endif #ifndef HAVE_LIBPCAP if (!strcmp(sagan_option, "plog_interface") || !strcmp(sagan_option, "plog_logdev") || !strcmp(sagan_option, "plog_port")) Sagan_Log(S_ERROR, "\"libpcap\" support not found. Re-compile with PCAP support or disable in the sagan.conf."); #endif #ifdef HAVE_LIBPCAP if (!strcmp(sagan_option, "plog_interface")) { strlcpy(config->plog_interface, Remove_Return(strtok_r(NULL, " ", &tok)), sizeof(config->plog_interface)); config->plog_flag=1; } if (!strcmp(sagan_option, "plog_logdev")) { strlcpy(config->plog_logdev, Remove_Return(strtok_r(NULL, " ", &tok)), sizeof(config->plog_logdev)); config->plog_flag=1; } if (!strcmp(sagan_option, "plog_filter")) { strlcpy(config->plog_filter, Remove_Return(Between_Quotes(tmpbuf2)), sizeof(config->plog_filter)); config->plog_flag = 1; } if (!strcmp(sagan_option, "plog_promiscuous")) { config->plog_promiscuous = 1; config->plog_flag = 1; } #endif #ifndef HAVE_LIBLOGNORM if (!strcmp(sagan_option, "normalize:")) { Sagan_Log(S_WARN, "WARNING: Sagan was not compiled with \"liblognorm\" support!"); Sagan_Log(S_WARN, "WARNING: Sagan will continue, but _without_ liblognorm!"); } #endif #ifdef HAVE_LIBLOGNORM /* We load the location for liblognorm's 'rule base/samples'. We don't want to load them quiet yet. We only want to load samples we need, so we do the actual ln_loadSamples() after the configuration file and all rules have been analyzed */ if (!strcmp(sagan_option, "normalize:")) { liblognormstruct = (liblognorm_struct *) realloc(liblognormstruct, (liblognorm_count+1) * sizeof(liblognorm_struct)); sagan_var1 = strtok_r(NULL, ",", &tok); Remove_Spaces(sagan_var1); strlcpy(liblognormstruct[liblognorm_count].type, sagan_var1, sizeof(liblognormstruct[liblognorm_count].type)); strlcpy(tmpstring, strtok_r(NULL, ",", &tok), sizeof(tmpstring)); Remove_Spaces(tmpstring); Remove_Return(tmpstring); strlcpy(normfile, Sagan_Var_To_Value(tmpstring), sizeof(normfile)); Remove_Spaces(normfile); strlcpy(liblognormstruct[liblognorm_count].filepath, normfile, sizeof(liblognormstruct[liblognorm_count].filepath)); liblognorm_count++; } #endif #ifndef HAVE_LIBGEOIP if (!strcmp(sagan_option, "country_database")) { Sagan_Log(S_WARN, "WARNING: Sagan was not compiled with Maxmind \"GeoIP\" support!"); Sagan_Log(S_WARN, "WARNING: Sagan will continue, but _without_ GeoIP enabled!"); } #endif #ifdef HAVE_LIBGEOIP if (!strcmp(sagan_option, "country_database:")) { sagan_var1 = Remove_Return(strtok_r(NULL, " ", &tok)); strlcpy(config->geoip_country_file, sagan_var1, sizeof(config->geoip_country_file)); Sagan_Log(S_NORMAL, "Loading GeoIP database. [%s]", config->geoip_country_file); Sagan_Open_GeoIP_Database(); config->have_geoip = 1; } #endif if (!strcmp(sagan_option, "ignore_list:")) { sagan_var1 = Remove_Return(strtok_r(NULL, " ", &tok)); if ( sagan_var1 == NULL ) Sagan_Log(S_ERROR, "[%s, line %d] No \"ignore file\" specified in the sagan.conf file!", __FILE__, __LINE__); config->sagan_droplist_flag = 1; strlcpy(config->sagan_droplistfile, sagan_var1, sizeof(config->sagan_droplistfile)); } /**************************************************************************** * Processors ****************************************************************************/ if (!strcmp(sagan_option, "processor")) { sagan_var1 = strtok_r(NULL," ", &tok); if (!strcmp(sagan_var1, "sagan-track-clients:")) { sagan_var1 = strtok_r(NULL," ", &tok); if (!strcmp(sagan_var1, "client_timeout")) { sagan_var1 = strtok_r(NULL," ", &tok); config->pp_sagan_track_clients = atoi(sagan_var1); config->sagan_track_clients_flag = 1; } } if (!strcmp(sagan_var1, "blacklist:")) { config->blacklist_flag=1; /* Set defaults */ config->blacklist_priority = BLACKLIST_PROCESSOR_PRI; /* Set default */ config->blacklist_parse_depth = 2; config->blacklist_parse_src = 1; config->blacklist_parse_dst = 2; ptmp = sagan_var1; while (ptmp != NULL ) { if (!strcmp(ptmp, "parse_depth")) { ptmp = strtok_r(NULL, " ", &tok); config->blacklist_parse_depth = atoi(ptmp); } if (!strcmp(ptmp, "blacklist")) { ptmp = strtok_r(NULL, " ", &tok); strlcpy(config->blacklist_file, Remove_Return(ptmp), sizeof(config->blacklist_file)); } if (!strcmp(ptmp, "parse_src")) { ptmp = strtok_r(NULL, " ", &tok); config->blacklist_parse_src = atoi(ptmp); } if (!strcmp(ptmp, "parse_dst")) { ptmp = strtok_r(NULL, " ", &tok); config->blacklist_parse_dst = atoi(ptmp); } if (!strcmp(ptmp, "parse_proto")) { ptmp = strtok_r(NULL, " ", &tok); if (!strcmp(ptmp, "true") || !strcmp(ptmp, "1")) config->blacklist_parse_proto = 1; } if (!strcmp(ptmp, "parse_proto_program")) { ptmp = strtok_r(NULL, " ", &tok); if (!strcmp(ptmp, "true") || !strcmp(ptmp, "1")) config->blacklist_parse_proto_program = 1; } if (!strcmp(ptmp, "lognorm")) { ptmp = strtok_r(NULL, " ", &tok); if (!strcmp(ptmp, "true") || !strcmp(ptmp, "1")) config->blacklist_lognorm = 1; } if (!strcmp(ptmp, "priority")) { ptmp = strtok_r(NULL, " ", &tok); config->blacklist_priority=atoi(ptmp); } ptmp = strtok_r(NULL, "=", &tok); } } if (!strcmp(sagan_var1, "search_nocase:")) { /* Set defaults */ config->search_nocase_flag=1; config->search_nocase_parse_depth=2; config->search_nocase_priority=SEARCH_PROCESSOR_PRI; ptmp = sagan_var1; while (ptmp != NULL ) { if (!strcmp(ptmp, "parse_src")) { ptmp = strtok_r(NULL, " ", &tok); config->search_nocase_parse_src = atoi(ptmp); } if (!strcmp(ptmp, "parse_dst")) { ptmp = strtok_r(NULL, " ", &tok); config->search_nocase_parse_dst = atoi(ptmp); } if (!strcmp(ptmp, "parse_proto")) { ptmp = strtok_r(NULL, " ", &tok); if (!strcmp(ptmp, "true") || !strcmp(ptmp, "1")) config->search_nocase_parse_proto = 1; } if (!strcmp(ptmp, "parse_proto_program")) { ptmp = strtok_r(NULL, " ", &tok); if (!strcmp(ptmp, "true") || !strcmp(ptmp, "1")) config->search_nocase_parse_proto_program = 1; } if (!strcmp(ptmp, "searchlist")) { ptmp = strtok_r(NULL, " ", &tok); strlcpy(config->search_nocase_file, Remove_Return(ptmp), sizeof(config->search_nocase_file)); } if (!strcmp(ptmp, "lognorm")) { ptmp = strtok_r(NULL, " ", &tok); if (!strcmp(ptmp, "true") || !strcmp(ptmp, "1")) config->search_nocase_lognorm = 1; } if (!strcmp(ptmp, "priority")) { ptmp = strtok_r(NULL, " ", &tok); config->search_nocase_priority=atoi(ptmp); } ptmp = strtok_r(NULL, "=", &tok); } } if (!strcmp(sagan_var1, "search_case:")) { config->search_case_flag=1; config->search_case_parse_depth=2; config->search_case_parse_src = 1; config->search_case_parse_src = 2; ptmp = sagan_var1; while (ptmp != NULL ) { if (!strcmp(ptmp, "parse_src")) { ptmp = strtok_r(NULL, " ", &tok); config->search_case_parse_src = atoi(ptmp); } if (!strcmp(ptmp, "parse_dst")) { ptmp = strtok_r(NULL, " ", &tok); config->search_case_parse_dst = atoi(ptmp); } if (!strcmp(ptmp, "parse_proto")) { ptmp = strtok_r(NULL, " ", &tok); if (!strcmp(ptmp, "true") || !strcmp(ptmp, "1")) config->search_case_parse_proto = 1; } if (!strcmp(ptmp, "parse_proto_program")) { ptmp = strtok_r(NULL, " ", &tok); if (!strcmp(ptmp, "true") || !strcmp(ptmp, "1")) config->search_case_parse_proto_program = 1; } if (!strcmp(ptmp, "searchlist")) { ptmp = strtok_r(NULL, " ", &tok); strlcpy(config->search_case_file, Remove_Return(ptmp), sizeof(config->search_case_file)); } if (!strcmp(ptmp, "lognorm")) { ptmp = strtok_r(NULL, " ", &tok); if (!strcmp(ptmp, "true") || !strcmp(ptmp, "1")) config->search_case_lognorm = 1; } if (!strcmp(ptmp, "priority")) { ptmp = strtok_r(NULL, " ", &tok); config->search_case_priority=atoi(ptmp); } ptmp = strtok_r(NULL, "=", &tok); } } #ifdef WITH_WEBSENSE if (!strcmp(sagan_var1, "websense:")) { config->websense_flag=1; /* Set defaults */ config->websense_parse_depth=2; /* default */ strlcpy(config->websense_device_id, "NO_DEVICE_ID", sizeof(config->websense_device_id)); config->websense_parse_src = 1; config->websense_parse_dst = 2; config->websense_priority = WEBSENSE_PROCESSOR_PRI; ptmp = sagan_var1; while (ptmp != NULL ) { if (!strcmp(ptmp, "parse_depth")) { ptmp = strtok_r(NULL, " ", &tok); config->websense_parse_depth = atoi(ptmp); } if (!strcmp(ptmp, "auth")) { ptmp = strtok_r(NULL, " ", &tok); strlcpy(config->websense_auth, Remove_Return(ptmp), sizeof(config->websense_auth)); } if (!strcmp(ptmp, "url")) { ptmp = strtok_r(NULL, " ", &tok); strlcpy(config->websense_url, Remove_Return(ptmp), sizeof(config->websense_url)); } if (!strcmp(ptmp, "max_cache")) { ptmp = strtok_r(NULL, " ", &tok); config->websense_max_cache = strtoull(ptmp, NULL, 10); } if (!strcmp(ptmp, "cache_timeout")) { ptmp = strtok_r(NULL, " ", &tok); config->websense_timeout = atoi(ptmp) * 60; } if (!strcmp(ptmp, "ignore_list")) { ptmp = strtok_r(NULL, " ", &tok); strlcpy(config->websense_ignore_list, Remove_Return(ptmp), sizeof(config->websense_ignore_list)); } if (!strcmp(ptmp, "device_id")) { ptmp = strtok_r(NULL, " ", &tok); strlcpy(config->websense_device_id, Remove_Return(ptmp), sizeof(config->websense_device_id)); } if (!strcmp(ptmp, "parse_src")) { ptmp = strtok_r(NULL, " ", &tok); config->websense_parse_src = atoi(ptmp); } if (!strcmp(ptmp, "parse_dst")) { ptmp = strtok_r(NULL, " ", &tok); config->websense_parse_dst = atoi(ptmp); } if (!strcmp(ptmp, "parse_proto")) { ptmp = strtok_r(NULL, " ", &tok); if (!strcmp(ptmp, "true") || !strcmp(ptmp, "1")) config->websense_parse_proto = 1; } if (!strcmp(ptmp, "parse_proto_program")) { ptmp = strtok_r(NULL, " ", &tok); if (!strcmp(ptmp, "true") || !strcmp(ptmp, "1")) config->websense_parse_proto_program = 1; } if (!strcmp(ptmp, "lognorm")) { ptmp = strtok_r(NULL, " ", &tok); if (!strcmp(ptmp, "true") || !strcmp(ptmp, "1")) config->websense_lognorm = 1; } if (!strcmp(ptmp, "priority")) { ptmp = strtok_r(NULL, " ", &tok); config->websense_priority=atoi(ptmp); } ptmp = strtok_r(NULL, "=", &tok); } } /* ERROR CHECKING HERE? */ #endif } /**************************************************************************** * Output formats ****************************************************************************/ if (!strcmp(sagan_option, "output")) { config->output_thread_flag = 1; sagan_var1 = strtok_r(NULL," ", &tok); if (!strcmp(sagan_var1, "external:")) { config->sagan_ext_flag=1; config->sagan_external_output_flag=1; strlcpy(config->sagan_extern, Remove_Return(strtok_r(NULL, " ", &tok)), sizeof(config->sagan_extern)); if (strstr(strtok_r(NULL, " ", &tok), "parsable")) config->sagan_exttype=1; } #ifdef WITH_SNORTSAM if (!strcmp(sagan_var1, "alert_fwsam:")) { strlcpy(config->sagan_fwsam_info, Remove_Return(strtok_r(NULL, " ", &tok)), sizeof(config->sagan_fwsam_info)); config->sagan_fwsam_flag=1; } #endif #if !defined(HAVE_DNET_H) && !defined(HAVE_DUMBNET_H) if (!strcmp(sagan_var1, "unified2:")) { Sagan_Log(S_WARN,"\"libdnet\" support not found. This is needed for unified2."); Sagan_Log(S_WARN, "Re-compile with libdnet support or disable in the sagan.conf."); } #endif #if defined(HAVE_DNET_H) || defined(HAVE_DUMBNET_H) if (!strcmp(sagan_var1, "unified2:")) { config->sagan_unified2_flag = 1; ptmp = sagan_var1; Remove_Return(ptmp); while (ptmp != NULL ) { if (!strcmp(ptmp, "filename")) { ptmp = strtok_r(NULL, ",", &tok); snprintf(config->unified2_filepath, sizeof(config->unified2_filepath)-1, "%s/%s", config->sagan_log_path, ptmp); } if (!strcmp(ptmp, "limit")) { ptmp = strtok_r(NULL, " ", &tok); config->unified2_limit = atoi(ptmp) * 1024 * 1024; } if (!strcmp(ptmp, "nostamp")) config->unified2_nostamp = 1; ptmp = strtok_r(NULL, " ", &tok); } } #endif #ifdef HAVE_LIBESMTP if (!strcmp(sagan_var1, "email:")) { ptmp = sagan_var1; while (ptmp != NULL ) { if (!strcmp(ptmp, "from")) { ptmp = strtok_r(NULL, " ", &tok); strlcpy(config->sagan_esmtp_from, Remove_Return(ptmp), sizeof(config->sagan_esmtp_from)); } if (!strcmp(ptmp, "smtpserver")) { ptmp = strtok_r(NULL, " ", &tok); strlcpy(config->sagan_esmtp_server, Remove_Return(ptmp), sizeof(config->sagan_esmtp_server)); } ptmp = strtok_r(NULL, "=", &tok); } } #endif } /* var */ if (!strcmp(sagan_option, "var")) { sagan_var1 = strtok_r(NULL, " ", &tok); var = (_SaganVar *) realloc(var, (counters->var_count+1) * sizeof(_SaganVar)); /* Allocate memory */ snprintf(var[counters->var_count].var_name, sizeof(var[counters->var_count].var_name)-1, "$%s", sagan_var1); sagan_var2 = strtok_r(NULL, " ", &tok); /* Move to position of value of var */ strlcpy(var[counters->var_count].var_value, Remove_Return(sagan_var2), sizeof(var[counters->var_count].var_value)); counters->var_count++; /* Required var's - all others are optional */ if (!strcmp(sagan_var1, "FIFO") && config->sagan_fifo_flag != 1) strlcpy(config->sagan_fifo, sagan_var2, sizeof(config->sagan_fifo)); if (!strcmp(sagan_var1, "LOCKFILE" )) strlcpy(config->sagan_lockfile, sagan_var2, sizeof(config->sagan_lockfile)); if (!strcmp(sagan_var1, "ALERTLOG" )) strlcpy(config->sagan_alert_filepath, sagan_var2, sizeof(config->sagan_alert_filepath)); if (!strcmp(sagan_var1, "SAGANLOGPATH" )) strlcpy(config->sagan_log_path, sagan_var2, sizeof(config->sagan_log_path)); /* if (!strcmp(sagan_var1, "HOME_NET" )) { if (strcasestr(sagan_var2, "any" )) config->home_any = 1; } if (!strcmp(sagan_var1, "EXTERNAL_NET" )) { if (strcasestr(sagan_var2, "any" )) config->external_any = 1; } */ } /* "include */ if (!strcmp(sagan_option, "include" )) { strlcpy(tmpstring, Remove_Return(strtok_r(NULL, " ", &tok)), sizeof(tmpstring)); strlcpy(ruleset, Sagan_Var_To_Value(tmpstring), sizeof(ruleset)); Remove_Spaces(ruleset); filename=Get_Filename(ruleset); /* Get the file name to figure out "what" we're loading */ if (!strcmp(filename, "classification.config")) Load_Classifications(ruleset); if (!strcmp(filename, "reference.config")) Load_Reference(ruleset); if (!strcmp(filename, "gen-msg.map")) Load_Gen_Map(ruleset); if (!strcmp(filename, "protocol.map")) Load_Protocol_Map(ruleset); /* It's not reference.config, classification.config, gen-msg.map or protocol.map, it must be a ruleset */ if (strcmp(filename, "reference.config") && strcmp(filename, "classification.config") && strcmp(filename, "gen-msg.map") && strcmp(filename, "protocol.map")) { Load_Rules(ruleset); } } } fclose(sagancfg); /* Check rules for duplicate sid. We can't have that! */ for (i = 0; i < counters->rulecount; i++) { for ( check = i+1; check < counters->rulecount; check ++) { if (!strcmp (rulestruct[check].s_sid, rulestruct[i].s_sid )) Sagan_Log(S_ERROR, "[%s, line %d] Detected duplicate signature id [sid] number %s. Please correct this.", __FILE__, __LINE__, rulestruct[check].s_sid, rulestruct[i].s_sid); } } /* If we have the "send-to" option, verify the configuration has the proper smtpserver, etc. */ #ifdef HAVE_LIBESMTP if (config->sagan_esmtp_flag && !strcmp(config->sagan_esmtp_server, "")) Sagan_Log(S_ERROR, "[%s, line %d] Configuration SMTP 'smtpserver' field is missing! |%s|", __FILE__, __LINE__, config->sagan_esmtp_server); if (config->sagan_esmtp_flag && !strcmp(config->sagan_esmtp_from, "" )) Sagan_Log(S_ERROR, "[%s, line %d] Configuration SMTP 'from' field is missing!", __FILE__, __LINE__); #endif if (!strcmp(config->sagan_fifo, "")) Sagan_Log(S_ERROR, "No FIFO option found which is required! Aborting!"); if (!strcmp(config->sagan_host, "" )) Sagan_Log(S_ERROR, "The 'sagan_host' option was not found and is required."); if ( config->sagan_port == 0 ) Sagan_Log(S_ERROR, "The 'sagan_port' option was not set and is required."); #ifdef HAVE_LIBGEOIP if ( config->have_geoip ) { if ( Sagan_Check_Var("$HOME_COUNTRY") == 0 ) { Sagan_Log(S_ERROR, "[%s, line %d] GeoIP is in use, but $HOME_COUNTRY was never set in your configuration. Abort.", __FILE__, __LINE__); } } #endif }
void Sagan_Ext_Thread ( _SaganEvent *Event, char *execute_script ) { int in[2]; int out[2]; int n, pid; char buf[MAX_SYSLOGMSG]; char data[MAX_SYSLOGMSG]; char *tmpref = NULL; char tmp[6]; if ( debug->debugexternal ) { Sagan_Log(S_WARN, "[%s, line %d] In sagan_ext_thread()", __FILE__, __LINE__); } tmpref = Reference_Lookup( Event->found, 1 ); if ( Event->drop == 1 ) { snprintf(tmp, sizeof(tmp), "True"); } else { snprintf(tmp, sizeof(tmp), "False"); } snprintf(data, sizeof(data), "\n\ ID:%lu:%s\n\ Message:%s\n\ Classification:%s\n\ Drop:%s\n\ Priority:%d\n\ Date:%s\n\ Time:%s\n\ Source:%s\n\ Source Port:%d\n\ Destination:%s\n\ Destination Port:%d\n\ Facility:%s\n\ Syslog Priority:%s\n\ %sSyslog message:%s\n"\ \ ,Event->generatorid\ ,Event->sid,\ Event->f_msg,\ Event->class,\ tmp,\ Event->pri,\ Event->date,\ Event->time,\ Event->ip_src,\ Event->src_port,\ Event->ip_dst,\ Event->dst_port,\ Event->facility,\ Event->priority,\ tmpref,\ Event->message); pthread_mutex_lock( &ext_mutex ); if ( pipe(in) < 0 ) { Remove_Lock_File(); Sagan_Log(S_ERROR, "[%s, line %d] Cannot create input pipe!", __FILE__, __LINE__); } if ( pipe(out) < 0 ) { Remove_Lock_File(); Sagan_Log(S_ERROR, "[%s, line %d] Cannot create output pipe!", __FILE__, __LINE__); } pid=fork(); if ( pid < 0 ) { Sagan_Log(S_ERROR, "[%s, line %d] Cannot create external program process", __FILE__, __LINE__); } else if ( pid == 0 ) { /* Causes problems with alert.log */ close(0); close(1); close(2); dup2(in[0],0); // Stdin.. dup2(out[1],1); dup2(out[1],2); close(in[1]); close(out[0]); //ret=execl(config->sagan_extern, config->sagan_extern, NULL, (char *)NULL); //execl(config->sagan_extern, config->sagan_extern, NULL, (char *)NULL); execl(execute_script, execute_script, NULL, (char *)NULL); Remove_Lock_File(); Sagan_Log(S_WARN, "[%s, line %d] Cannot execute %s", __FILE__, __LINE__, config->sagan_extern); } close(in[0]); close(out[1]); /* Write to child input */ n = write(in[1], data, strlen(data)); close(in[1]); n = read(out[0], buf, sizeof(buf)); close(out[0]); buf[n] = 0; waitpid(pid, NULL, 0); pthread_mutex_unlock( &ext_mutex ); if ( debug->debugexternal == 1 ) { Sagan_Log(S_DEBUG, "[%s, line %d] Executed %s", __FILE__, __LINE__, config->sagan_extern); } }
int Sagan_Flowbit_Condition(int rule_position, char *ip_src_char, char *ip_dst_char ) { time_t t; struct tm *now; char timet[20]; char tmp[128] = { 0 }; char *tmp_flowbit_name = NULL; char *tok = NULL; int i; int a; uint32_t ip_src; uint32_t ip_dst; sbool flowbit_match = 0; int flowbit_total_match = 0; t = time(NULL); now=localtime(&t); strftime(timet, sizeof(timet), "%s", now); ip_src = IP2Bit(ip_src_char); ip_dst = IP2Bit(ip_dst_char); int and_or = 0; Sagan_Flowbit_Cleanup(); for (i = 0; i < rulestruct[rule_position].flowbit_count; i++) { /******************* * ISSET * *******************/ if ( rulestruct[rule_position].flowbit_type[i] == 3 ) { for (a = 0; a < counters_ipc->flowbit_count; a++) { strlcpy(tmp, rulestruct[rule_position].flowbit_name[i], sizeof(tmp)); if (Sagan_strstr(rulestruct[rule_position].flowbit_name[i], "|")) { tmp_flowbit_name = strtok_r(tmp, "|", &tok); and_or = 1; } else { tmp_flowbit_name = strtok_r(tmp, "&", &tok); and_or = 0; /* Need this? */ } while (tmp_flowbit_name != NULL ) { if (!strcmp(tmp_flowbit_name, flowbit_ipc[a].flowbit_name) && flowbit_ipc[a].flowbit_state == 1 ) { /* direction: none */ if ( rulestruct[rule_position].flowbit_direction[i] == 0 ) { if ( debug->debugflowbit) { Sagan_Log(S_DEBUG, "[%s, line %d] \"isset\" flowbit \"%s\" (direction: \"none\"). (any -> any)", __FILE__, __LINE__, flowbit_ipc[a].flowbit_name); } flowbit_total_match++; } /* direction: both */ if ( rulestruct[rule_position].flowbit_direction[i] == 1 && flowbit_ipc[a].ip_src == ip_src && flowbit_ipc[a].ip_dst == ip_dst ) { if ( debug->debugflowbit) { Sagan_Log(S_DEBUG, "[%s, line %d] \"isset\" flowbit \"%s\" (direction: \"both\"). (%s -> %s)", __FILE__, __LINE__, flowbit_ipc[a].flowbit_name, ip_src_char, ip_dst_char); } flowbit_total_match++; } /* direction: by_src */ if ( rulestruct[rule_position].flowbit_direction[i] == 2 && flowbit_ipc[a].ip_src == ip_src ) { if ( debug->debugflowbit) { Sagan_Log(S_DEBUG, "[%s, line %d] \"isset\" flowbit \"%s\" (direction: \"by_src\"). (%s -> any)", __FILE__, __LINE__, flowbit_ipc[a].flowbit_name, ip_src_char); } flowbit_total_match++; } /* direction: by_dst */ if ( rulestruct[rule_position].flowbit_direction[i] == 3 && flowbit_ipc[a].ip_dst == ip_dst ) { if ( debug->debugflowbit) { Sagan_Log(S_DEBUG, "[%s, line %d] \"isset\" flowbit \"%s\" (direction: \"by_dst\"). (any -> %s)", __FILE__, __LINE__, flowbit_ipc[a].flowbit_name, ip_dst_char); } flowbit_total_match++; } /* direction: reverse */ if ( rulestruct[rule_position].flowbit_direction[i] == 4 && flowbit_ipc[a].ip_src == ip_dst && flowbit_ipc[a].ip_dst == ip_src ) { if ( debug->debugflowbit) { Sagan_Log(S_DEBUG, "[%s, line %d] \"isset\" flowbit \"%s\" (direction: \"reverse\"). (%s -> %s)", __FILE__, __LINE__, flowbit_ipc[a].flowbit_name, ip_dst_char, ip_src_char); } flowbit_total_match++; } } /* End of strcmp flowbit_name & flowbit_state = 1 */ if ( and_or == 1) { tmp_flowbit_name = strtok_r(NULL, "|", &tok); } else { tmp_flowbit_name = strtok_r(NULL, "&", &tok); } } /* End of "while tmp_flowbit_name" */ } /* End of "for a" */ } /* End "if" flowbit_type == 3 (ISSET) */ /******************* * ISNOTSET * *******************/ if ( rulestruct[rule_position].flowbit_type[i] == 4 ) { flowbit_match = 0; for (a = 0; a < counters_ipc->flowbit_count; a++) { strlcpy(tmp, rulestruct[rule_position].flowbit_name[i], sizeof(tmp)); if (Sagan_strstr(rulestruct[rule_position].flowbit_name[i], "|")) { tmp_flowbit_name = strtok_r(tmp, "|", &tok); and_or = 1; } else { tmp_flowbit_name = strtok_r(tmp, "&", &tok); and_or = 0; /* Need this? */ } while (tmp_flowbit_name != NULL ) { if (!strcmp(tmp_flowbit_name, flowbit_ipc[a].flowbit_name)) { flowbit_match=1; if ( flowbit_ipc[a].flowbit_state == 0 ) { /* direction: none */ if ( rulestruct[rule_position].flowbit_direction[i] == 0 ) { if ( debug->debugflowbit) { Sagan_Log(S_DEBUG, "[%s, line %d] \"isnotset\" flowbit \"%s\" (direction: \"none\"). (any -> any)", __FILE__, __LINE__, flowbit_ipc[a].flowbit_name); } flowbit_total_match++; } /* direction: both */ if ( rulestruct[rule_position].flowbit_direction[i] == 1 ) { if ( flowbit_ipc[a].ip_src == ip_src && flowbit_ipc[a].ip_dst == ip_dst ) { if ( debug->debugflowbit) { Sagan_Log(S_DEBUG, "[%s, line %d] \"isnotset\" flowbit \"%s\" (direction: \"both\"). (%s -> %s)", __FILE__, __LINE__, flowbit_ipc[a].flowbit_name, ip_src_char, ip_dst_char); } flowbit_total_match++; } } /* direction: by_src */ if ( rulestruct[rule_position].flowbit_direction[i] == 2 ) { if ( flowbit_ipc[a].ip_src == ip_src ) { if ( debug->debugflowbit) { Sagan_Log(S_DEBUG, "[%s, line %d] \"isnotset\" flowbit \"%s\" (direction: \"by_src\"). (%s -> any)", __FILE__, __LINE__, flowbit_ipc[a].flowbit_name, ip_src_char); } flowbit_total_match++; } } /* direction: by_dst */ if ( rulestruct[rule_position].flowbit_direction[i] == 3 ) { if ( flowbit_ipc[a].ip_dst == ip_dst ) { if ( debug->debugflowbit) { Sagan_Log(S_DEBUG, "[%s, line %d] \"isnotset\" flowbit \"%s\" (direction: \"by_dst\"). (any -> %s)", __FILE__, __LINE__, flowbit_ipc[a].flowbit_name, ip_dst_char); } flowbit_total_match++; } } /* direction: reverse */ if ( rulestruct[rule_position].flowbit_direction[i] == 4 ) { if ( flowbit_ipc[a].ip_src == ip_dst && flowbit_ipc[a].ip_dst == ip_src ) { if ( debug->debugflowbit) { Sagan_Log(S_DEBUG, "[%s, line %d] \"isnotset\" flowbit \"%s\" (direction: \"reverse\"). (%s -> %s)", __FILE__, __LINE__, flowbit_ipc[a].flowbit_name, ip_dst_char, ip_src_char); } flowbit_total_match++; } } } /* End flowbit_state == 0 */ } /* End of strcmp flowbit_name */ if ( and_or == 1) { tmp_flowbit_name = strtok_r(NULL, "|", &tok); } else { tmp_flowbit_name = strtok_r(NULL, "&", &tok); } } /* End of "while tmp_flowbit_name" */ } /* End of "for a" */ if ( and_or == 1 && flowbit_match == 1 ) { flowbit_total_match = rulestruct[rule_position].flowbit_condition_count; /* Do we even need this for OR? */ } if ( and_or == 0 && flowbit_match == 0 ) { flowbit_total_match = rulestruct[rule_position].flowbit_condition_count; } } /* End of "flowbit_type[i] == 4" */ } /* End of "for i" */ /* IF we match all criteria for isset/isnotset * * If we match the flowbit_conditon_count (number of concurrent flowbits) * we trigger. It it's an "or" statement, we trigger if any of the * flowbits are set. * */ if ( ( rulestruct[rule_position].flowbit_condition_count == flowbit_total_match ) || ( and_or == 1 && flowbit_total_match != 0 ) ) { if ( debug->debugflowbit) { Sagan_Log(S_DEBUG, "[%s, line %d] Condition of flowbit returning TRUE. %d %d", __FILE__, __LINE__, rulestruct[rule_position].flowbit_condition_count, flowbit_total_match); } return(true); } /* isset/isnotset failed. */ if ( debug->debugflowbit) { Sagan_Log(S_DEBUG, "[%s, line %d] Condition of flowbit returning FALSE. %d %d", __FILE__, __LINE__, rulestruct[rule_position].flowbit_condition_count, flowbit_total_match); } return(false); } /* End of Sagan_Flowbit_Condition(); */
void Sagan_Flowbit_Set(int rule_position, char *ip_src_char, char *ip_dst_char ) { int i = 0; int a = 0; time_t t; struct tm *now; char timet[20]; char tmp[128] = { 0 }; char *tmp_flowbit_name = NULL; char *tok = NULL; sbool flowbit_match = 0; sbool flowbit_unset_match = 0; uint32_t ip_src = 0; uint32_t ip_dst = 0; ip_src = IP2Bit(ip_src_char); ip_dst = IP2Bit(ip_dst_char); t = time(NULL); now=localtime(&t); strftime(timet, sizeof(timet), "%s", now); struct _Sagan_Flowbit_Track *flowbit_track; flowbit_track = malloc(sizeof(_Sagan_Flowbit_Track)); if ( flowbit_track == NULL ) { Sagan_Log(S_ERROR, "[%s, line %d] Failed to allocate memory for flowbit_track. Abort!", __FILE__, __LINE__); } memset(flowbit_track, 0, sizeof(_Sagan_Flowbit_Track)); int flowbit_track_count = 0; Sagan_Flowbit_Cleanup(); for (i = 0; i < rulestruct[rule_position].flowbit_count; i++) { /******************* * UNSET * *******************/ if ( rulestruct[rule_position].flowbit_type[i] == 2 ) { /* Flowbits & (ie - bit1&bit2) */ strlcpy(tmp, rulestruct[rule_position].flowbit_name[i], sizeof(tmp)); tmp_flowbit_name = strtok_r(tmp, "&", &tok); while( tmp_flowbit_name != NULL ) { for (a = 0; a < counters_ipc->flowbit_count; a++) { if ( !strcmp(tmp_flowbit_name, flowbit_ipc[a].flowbit_name )) { /* direction: none */ if ( rulestruct[rule_position].flowbit_direction[i] == 0 ) { if ( debug->debugflowbit) { Sagan_Log(S_DEBUG, "[%s, line %d] \"unset\" flowbit \"%s\" (direction: \"none\"). (any -> any)", __FILE__, __LINE__, flowbit_ipc[a].flowbit_name); } Sagan_File_Lock(config->shm_flowbit); flowbit_ipc[a].flowbit_state = 0; Sagan_File_Unlock(config->shm_flowbit); flowbit_unset_match = 1; } /* direction: both */ if ( rulestruct[rule_position].flowbit_direction[i] == 1 && flowbit_ipc[a].ip_src == ip_src && flowbit_ipc[a].ip_dst == ip_dst ) { if ( debug->debugflowbit) { Sagan_Log(S_DEBUG, "[%s, line %d] \"unset\" flowbit \"%s\" (direction: \"both\"). (%s -> %s)", __FILE__, __LINE__, flowbit_ipc[a].flowbit_name, ip_src_char, ip_dst_char); } Sagan_File_Lock(config->shm_flowbit); flowbit_ipc[a].flowbit_state = 0; Sagan_File_Unlock(config->shm_flowbit); flowbit_unset_match = 1; } /* direction: by_src */ if ( rulestruct[rule_position].flowbit_direction[i] == 2 && flowbit_ipc[a].ip_src == ip_src ) { if ( debug->debugflowbit) { Sagan_Log(S_DEBUG, "[%s, line %d] \"unset\" flowbit \"%s\" (direction: \"by_src\"). (%s -> any)", __FILE__, __LINE__, flowbit_ipc[a].flowbit_name, ip_src_char); } Sagan_File_Lock(config->shm_flowbit); flowbit_ipc[a].flowbit_state = 0; Sagan_File_Unlock(config->shm_flowbit); flowbit_unset_match = 1; } /* direction: by_dst */ if ( rulestruct[rule_position].flowbit_direction[i] == 3 && flowbit_ipc[a].ip_dst == ip_dst ) { if ( debug->debugflowbit) { Sagan_Log(S_DEBUG, "[%s, line %d] \"unset\" flowbit \"%s\" (direction: \"by_dst\"). (any -> %s)", __FILE__, __LINE__, flowbit_ipc[a].flowbit_name, ip_dst_char); } Sagan_File_Lock(config->shm_flowbit); flowbit_ipc[a].flowbit_state = 0; Sagan_File_Unlock(config->shm_flowbit); flowbit_unset_match = 1; } /* direction: reverse */ if ( rulestruct[rule_position].flowbit_direction[i] == 4 && flowbit_ipc[a].ip_dst == ip_src && flowbit_ipc[a].ip_src == ip_dst ) { if ( debug->debugflowbit) { Sagan_Log(S_DEBUG, "[%s, line %d] \"unset\" flowbit \"%s\" (direction: \"reverse\"). (%s -> %s)", __FILE__, __LINE__, flowbit_ipc[a].flowbit_name, ip_dst_char, ip_src_char); } Sagan_File_Lock(config->shm_flowbit); flowbit_ipc[a].flowbit_state = 0; Sagan_File_Unlock(config->shm_flowbit); flowbit_unset_match = 1; } } } if ( debug->debugflowbit && flowbit_unset_match == 0 ) { Sagan_Log(S_DEBUG, "[%s, line %d] No flowbit found to \"unset\" for %s.", __FILE__, __LINE__, tmp_flowbit_name); } tmp_flowbit_name = strtok_r(NULL, "&", &tok); } } /* While & flowbits (ie - bit1&bit2) */ /******************* * SET * *******************/ if ( rulestruct[rule_position].flowbit_type[i] == 1 ) { flowbit_match = 0; /* Flowbits & (ie - bit1&bit2) */ strlcpy(tmp, rulestruct[rule_position].flowbit_name[i], sizeof(tmp)); tmp_flowbit_name = strtok_r(tmp, "&", &tok); while( tmp_flowbit_name != NULL ) { for (a = 0; a < counters_ipc->flowbit_count; a++) { /* Do we have the flowbit already in memory? If so, update the information */ if (!strcmp(flowbit_ipc[a].flowbit_name, tmp_flowbit_name) && flowbit_ipc[a].ip_src == ip_src && flowbit_ipc[a].ip_dst == ip_dst ) { Sagan_File_Lock(config->shm_flowbit); flowbit_ipc[a].flowbit_expire = atol(timet) + rulestruct[rule_position].flowbit_timeout[i]; flowbit_ipc[a].flowbit_state = 1; if ( debug->debugflowbit) { Sagan_Log(S_DEBUG, "[%s, line %d] [%d] Updated via \"set\" for flowbit \"%s\", [%d]. New expire time is %d (%d) [%u -> %u]. ", __FILE__, __LINE__, a, tmp_flowbit_name, i, flowbit_ipc[i].flowbit_expire, rulestruct[rule_position].flowbit_timeout[i], flowbit_ipc[a].ip_src, flowbit_ipc[a].ip_dst); } Sagan_File_Unlock(config->shm_flowbit); flowbit_match = 1; } } /* If the flowbit isn't in memory, store it to be created later */ if ( flowbit_match == 0 ) { flowbit_track = ( _Sagan_Flowbit_Track * ) realloc(flowbit_track, (flowbit_track_count+1) * sizeof(_Sagan_Flowbit_Track)); if ( flowbit_track == NULL ) { Sagan_Log(S_ERROR, "[%s, line %d] Failed to reallocate memory for flow_track. Abort!", __FILE__, __LINE__); } strlcpy(flowbit_track[flowbit_track_count].flowbit_name, tmp_flowbit_name, sizeof(flowbit_track[flowbit_track_count].flowbit_name)); flowbit_track[flowbit_track_count].flowbit_timeout = rulestruct[rule_position].flowbit_timeout[i]; flowbit_track_count++; } tmp_flowbit_name = strtok_r(NULL, "&", &tok); } /* While & flowbits (ie - bit1&bit2) */ } /* if flowbit_type == 1 */ } /* Out of for i loop */ /* Do we have any flowbits in memory that need to be created? */ if ( flowbit_track_count != 0 ) { for (i = 0; i < flowbit_track_count; i++) { if ( Sagan_Clean_IPC_Object(FLOWBIT) == 0 ) { Sagan_File_Lock(config->shm_flowbit); flowbit_ipc[counters_ipc->flowbit_count].ip_src = ip_src; flowbit_ipc[counters_ipc->flowbit_count].ip_dst = ip_dst; flowbit_ipc[counters_ipc->flowbit_count].flowbit_expire = atol(timet) + flowbit_track[i].flowbit_timeout; flowbit_ipc[counters_ipc->flowbit_count].flowbit_state = 1; flowbit_ipc[counters_ipc->flowbit_count].expire = flowbit_track[i].flowbit_timeout; strlcpy(flowbit_ipc[counters_ipc->flowbit_count].flowbit_name, flowbit_track[i].flowbit_name, sizeof(flowbit_ipc[counters_ipc->flowbit_count].flowbit_name)); Sagan_File_Unlock(config->shm_flowbit); Sagan_File_Lock(config->shm_counters); counters_ipc->flowbit_count++; Sagan_File_Unlock(config->shm_counters); if ( debug->debugflowbit) { Sagan_Log(S_DEBUG, "[%s, line %d] [%d] Created flowbit \"%s\" via \"set\" [%s -> %s],", __FILE__, __LINE__, counters_ipc->flowbit_count, flowbit_ipc[counters_ipc->flowbit_count].flowbit_name, ip_src_char, ip_dst_char); } } } } free(flowbit_track); } /* End of Sagan_Flowbit_Set */
void Plog_Handler( void ) { (void)SetThreadName("SaganPlog"); pcap_t *bp; struct bpf_program filtr; char *iface=NULL; char eb[PCAP_ERRBUF_SIZE]; iface = config->plog_interface; Sagan_Log(NORMAL, ""); Sagan_Log(NORMAL, "Initalizing Sagan syslog sniffer thread (PLOG)"); Sagan_Log(NORMAL, "Interface: %s", iface); Sagan_Log(NORMAL, "Packet filter: \"%s\"", config->plog_filter); Sagan_Log(NORMAL, "Log device: %s", config->plog_logdev); if ( config->plog_promiscuous ) { Sagan_Log(NORMAL, "Promiscuous is enabled."); } Sagan_Log(NORMAL, ""); if(iface == (char *)0) { if((iface = pcap_lookupdev(eb)) == (char *)0) Sagan_Log(ERROR, "[%s, line %d] Cannot get device: %s", __FILE__, __LINE__, eb); } bp = pcap_open_live(iface,4096,config->plog_promiscuous,0,eb); if(bp == (pcap_t *)0) { Sagan_Log(ERROR, "[%s, line %d] Cannot open interface %s: %s", __FILE__, __LINE__, iface, eb); } /* Apply user defined filter */ if(pcap_compile(bp,&filtr,config->plog_filter,1,0)) { Sagan_Log(ERROR, "[%s, line %d] Cannot compile filter: %s", __FILE__, __LINE__, eb); } if(pcap_setfilter(bp,&filtr)) { Sagan_Log(ERROR, "[%s, line %d] Cannot install filter in %s: %s", __FILE__, __LINE__, iface, eb); } /* wireup /dev/log; we can't use openlog() because these are going to be raw inputs */ if(wiredevlog(config)) { Remove_Lock_File(); Sagan_Log(ERROR, "[%s, line %d] Cannot open %s (Syslog not using SOCK_DGRAM?)", __FILE__, __LINE__, config->plog_logdev); } /* endless loop */ (void)pcap_loop(bp,-1,logpkt, NULL); pcap_close(bp); exit(0); }
static void logpkt(u_char *pass_args,const struct pcap_pkthdr *p,const u_char *pkt) { struct ether_header *eh; struct ip *ih; struct my_udphdr *u; int off; int len; char *l; if ( config->plog_flag ) { /* crack the ethernet header */ eh = (struct ether_header *)pkt; if(ntohs(eh->ether_type) != ETHERTYPE_IP) goto bad; /* crack the IP header */ ih = (struct ip *)(pkt + sizeof(struct ether_header)); off = ntohs(ih->ip_off); len = ntohs(ih->ip_len); /* short packet */ if(len > p->len) { goto bad; } /* frags we don't deal with */ if((off & 0x1fff) != 0) { goto bad; } /* weird - we ASKED for UDP */ if(ih->ip_p != IPPROTO_UDP) { goto bad; } /* line the UDP header up */ u = (struct my_udphdr *)(pkt + sizeof(struct ether_header) + (ih->ip_hl * 4)); if(ntohs(u->uh_ulen < 8)) { goto bad; } /* our log message ought to be just past the UDP header now... */ l = (char *)u + sizeof(struct udphdr); len = ntohs(u->uh_ulen) - sizeof(struct udphdr); if(debug->debugplog) { int x; /* I can't use Sagan_Log() here, so we dump to strerr. * have the check the tty (isatty()) before dumping or * strange things happen if detached and threaded * - Champ Clark III Jan 7th 2011 */ for(x = 0; x < len; x++) { if(isprint(l[x]) && (isatty(1)) ) fprintf(stderr,"%c",(int)(l[x])); else fprintf(stderr,"[0x%x]",(int)(l[x])); } if (isatty(1)) fprintf(stderr,"\n"); } /* send it! */ if(send(outf,l,len,0) < 0) { Sagan_Log(ERROR, "[%s, line %d] Send error", __FILE__, __LINE__); } return; bad: Sagan_Log(WARN, "[%s, line %d] Malformed packet received.", __FILE__, __LINE__); } }
sbool Sagan_Clean_IPC_Object( int type ) { time_t t; struct tm *now; int i; int utime = 0; int new_count = 0; int old_count = 0; char timet[20]; if ( debug->debugipc ) { Sagan_Log(S_DEBUG, "[%s, %d line] Cleaning IPC data. Type: %d", __FILE__, __LINE__, type); } /* Afterbysrc_IPC */ if ( type == AFTER_BY_SRC && config->max_after_by_src < counters_ipc->after_count_by_src ) { t = time(NULL); now=localtime(&t); strftime(timet, sizeof(timet), "%s", now); utime = atol(timet); Sagan_File_Lock(config->shm_after_by_src); struct after_by_src_ipc *temp_afterbysrc_ipc; temp_afterbysrc_ipc = malloc(sizeof(struct after_by_src_ipc) * config->max_after_by_src); memset(temp_afterbysrc_ipc, 0, sizeof(sizeof(struct after_by_src_ipc) * config->max_after_by_src)); old_count = counters_ipc->after_count_by_src; for (i = 0; i < counters_ipc->after_count_by_src; i++) { if ( (utime - afterbysrc_ipc[i].utime) < afterbysrc_ipc[i].expire ) { if ( debug->debugipc ) { Sagan_Log(S_DEBUG, "[%s, %d line] Afterbysrc_IPC : Keeping %u.", __FILE__, __LINE__, afterbysrc_ipc[i].ipsrc); } temp_afterbysrc_ipc[new_count].ipsrc = afterbysrc_ipc[i].ipsrc; temp_afterbysrc_ipc[new_count].count = afterbysrc_ipc[i].count; temp_afterbysrc_ipc[new_count].utime = afterbysrc_ipc[i].utime; temp_afterbysrc_ipc[new_count].expire = afterbysrc_ipc[i].expire; strlcpy(temp_afterbysrc_ipc[new_count].sid, afterbysrc_ipc[i].sid, sizeof(temp_afterbysrc_ipc[new_count].sid)); new_count++; } } if ( new_count > 0 ) { for ( i = 0; i < new_count; i++ ) { afterbysrc_ipc[i].ipsrc = temp_afterbysrc_ipc[i].ipsrc; afterbysrc_ipc[i].count = temp_afterbysrc_ipc[i].count; afterbysrc_ipc[i].utime = temp_afterbysrc_ipc[i].utime; afterbysrc_ipc[i].expire = temp_afterbysrc_ipc[i].expire; strlcpy(afterbysrc_ipc[i].sid, temp_afterbysrc_ipc[i].sid, sizeof(afterbysrc_ipc[i].sid)); } counters_ipc->after_count_by_src = new_count; } else { Sagan_Log(S_WARN, "[%s, line %d] Could not clean after_by_src. Nothing to remove!", __FILE__, __LINE__); free(temp_afterbysrc_ipc); Sagan_File_Unlock(config->shm_after_by_src); return(1); } Sagan_Log(S_NORMAL, "[%s, line %d] Kept %d elements out of %d for after_by_src", __FILE__, __LINE__, new_count, old_count); free(temp_afterbysrc_ipc); Sagan_File_Unlock(config->shm_after_by_src); return(0); } /* Afterbydst_IPC */ else if ( type == AFTER_BY_DST && config->max_after_by_dst < counters_ipc->after_count_by_dst ) { t = time(NULL); now=localtime(&t); strftime(timet, sizeof(timet), "%s", now); utime = atol(timet); new_count = 0; old_count = 0; Sagan_File_Lock(config->shm_after_by_dst); struct after_by_dst_ipc *temp_afterbydst_ipc; temp_afterbydst_ipc = malloc(sizeof(struct after_by_dst_ipc) * config->max_after_by_dst); memset(temp_afterbydst_ipc, 0, sizeof(sizeof(struct after_by_dst_ipc) * config->max_after_by_dst)); old_count = counters_ipc->after_count_by_dst; for (i = 0; i < counters_ipc->after_count_by_dst; i++) { if ( (utime - afterbydst_ipc[i].utime) < afterbydst_ipc[i].expire ) { if ( debug->debugipc ) { Sagan_Log(S_DEBUG, "[%s, %d line] Afterbydst_IPC : Keeping %u.", __FILE__, __LINE__, afterbydst_ipc[i].ipdst); } temp_afterbydst_ipc[new_count].ipdst = afterbydst_ipc[i].ipdst; temp_afterbydst_ipc[new_count].count = afterbydst_ipc[i].count; temp_afterbydst_ipc[new_count].utime = afterbydst_ipc[i].utime; temp_afterbydst_ipc[new_count].expire = afterbydst_ipc[i].expire; strlcpy(temp_afterbydst_ipc[new_count].sid, afterbydst_ipc[i].sid, sizeof(temp_afterbydst_ipc[new_count].sid)); new_count++; } } if ( new_count > 0 ) { for ( i = 0; i < new_count; i++ ) { afterbydst_ipc[i].ipdst = temp_afterbydst_ipc[i].ipdst; afterbydst_ipc[i].count = temp_afterbydst_ipc[i].count; afterbydst_ipc[i].utime = temp_afterbydst_ipc[i].utime; afterbydst_ipc[i].expire = temp_afterbydst_ipc[i].expire; strlcpy(afterbydst_ipc[i].sid, temp_afterbydst_ipc[i].sid, sizeof(afterbydst_ipc[i].sid)); } counters_ipc->after_count_by_dst = new_count; } else { Sagan_Log(S_WARN, "[%s, line %d] Could not clean after_by_dst. Nothing to remove!", __FILE__, __LINE__); free(temp_afterbydst_ipc); Sagan_File_Unlock(config->shm_after_by_dst); return(1); } Sagan_Log(S_NORMAL, "[%s, line %d] Kept %d elements out of %d for after_by_dst", __FILE__, __LINE__, new_count, old_count); free(temp_afterbydst_ipc); Sagan_File_Unlock(config->shm_after_by_dst); return(0); } /* AfterbyUsername_IPC */ else if ( type == AFTER_BY_USERNAME && config->max_after_by_username < counters_ipc->after_count_by_username ) { t = time(NULL); now=localtime(&t); strftime(timet, sizeof(timet), "%s", now); utime = atol(timet); new_count = 0; old_count = 0; Sagan_File_Lock(config->shm_after_by_username); struct after_by_username_ipc *temp_afterbyusername_ipc; temp_afterbyusername_ipc = malloc(sizeof(struct after_by_username_ipc) * config->max_after_by_username); memset(temp_afterbyusername_ipc, 0, sizeof(sizeof(struct after_by_username_ipc) * config->max_after_by_username)); old_count = counters_ipc->after_count_by_username; for (i = 0; i < counters_ipc->after_count_by_username; i++) { if ( (utime - afterbyusername_ipc[i].utime) < afterbyusername_ipc[i].expire ) { if ( debug->debugipc ) { Sagan_Log(S_DEBUG, "[%s, %d line] Afterbyusername_IPC : Keeping '%s'.", __FILE__, __LINE__, afterbyusername_ipc[i].username); } temp_afterbyusername_ipc[new_count].count = afterbyusername_ipc[i].count; temp_afterbyusername_ipc[new_count].utime = afterbyusername_ipc[i].utime; temp_afterbyusername_ipc[new_count].expire = afterbyusername_ipc[i].expire; strlcpy(temp_afterbyusername_ipc[new_count].sid, afterbyusername_ipc[i].sid, sizeof(temp_afterbyusername_ipc[new_count].sid)); strlcpy(temp_afterbyusername_ipc[new_count].username, afterbyusername_ipc[i].username, sizeof(temp_afterbyusername_ipc[new_count].username)); new_count++; } } if ( new_count > 0 ) { for ( i = 0; i < new_count; i++ ) { afterbyusername_ipc[i].count = temp_afterbyusername_ipc[i].count; afterbyusername_ipc[i].utime = temp_afterbyusername_ipc[i].utime; afterbyusername_ipc[i].expire = temp_afterbyusername_ipc[i].expire; strlcpy(afterbyusername_ipc[i].sid, temp_afterbyusername_ipc[i].sid, sizeof(afterbyusername_ipc[i].sid)); strlcpy(afterbyusername_ipc[i].username, temp_afterbyusername_ipc[i].username, sizeof(afterbyusername_ipc[i].username)); } counters_ipc->after_count_by_username = new_count; } else { Sagan_Log(S_WARN, "[%s, line %d] Could not clean after_by_username. Nothing to remove!", __FILE__, __LINE__); free(temp_afterbyusername_ipc); Sagan_File_Unlock(config->shm_after_by_username); return(1); } Sagan_Log(S_NORMAL, "[%s, line %d] Kept %d elements out of %d for after_by_username", __FILE__, __LINE__, new_count, old_count); free(temp_afterbyusername_ipc); Sagan_File_Unlock(config->shm_after_by_username); return(0); } /* Threshbysrc_IPC */ else if ( type == THRESH_BY_SRC && config->max_threshold_by_src < counters_ipc->thresh_count_by_src ) { t = time(NULL); now=localtime(&t); strftime(timet, sizeof(timet), "%s", now); utime = atol(timet); new_count = 0; old_count = 0; Sagan_File_Lock(config->shm_thresh_by_src); struct thresh_by_src_ipc *temp_threshbysrc_ipc; temp_threshbysrc_ipc = malloc(sizeof(struct thresh_by_src_ipc) * config->max_threshold_by_src); memset(temp_threshbysrc_ipc, 0, sizeof(sizeof(struct thresh_by_src_ipc) * config->max_threshold_by_src)); old_count = counters_ipc->thresh_count_by_src; for (i = 0; i < counters_ipc->thresh_count_by_src; i++) { if ( (utime - threshbysrc_ipc[i].utime) < threshbysrc_ipc[i].expire ) { if ( debug->debugipc ) { Sagan_Log(S_DEBUG, "[%s, %d line] Threshbysrc_IPC : Keeping %u.", __FILE__, __LINE__, threshbysrc_ipc[i].ipsrc); } temp_threshbysrc_ipc[new_count].ipsrc = threshbysrc_ipc[i].ipsrc; temp_threshbysrc_ipc[new_count].count = threshbysrc_ipc[i].count; temp_threshbysrc_ipc[new_count].utime = threshbysrc_ipc[i].utime; temp_threshbysrc_ipc[new_count].expire = threshbysrc_ipc[i].expire; strlcpy(temp_threshbysrc_ipc[new_count].sid, threshbysrc_ipc[i].sid, sizeof(temp_threshbysrc_ipc[new_count].sid)); new_count++; } } if ( new_count > 0 ) { for ( i = 0; i < new_count; i++ ) { threshbysrc_ipc[i].ipsrc = temp_threshbysrc_ipc[i].ipsrc; threshbysrc_ipc[i].count = temp_threshbysrc_ipc[i].count; threshbysrc_ipc[i].utime = temp_threshbysrc_ipc[i].utime; threshbysrc_ipc[i].expire = temp_threshbysrc_ipc[i].expire; strlcpy(threshbysrc_ipc[i].sid, temp_threshbysrc_ipc[i].sid, sizeof(threshbysrc_ipc[i].sid)); } counters_ipc->thresh_count_by_src = new_count; } else { Sagan_Log(S_WARN, "[%s, line %d] Could not clean thresh_by_src. Nothing to remove!", __FILE__, __LINE__); free(temp_threshbysrc_ipc); Sagan_File_Unlock(config->shm_thresh_by_src); return(1); } Sagan_Log(S_NORMAL, "[%s, line %d] Kept %d elements out of %d for thresh_by_src", __FILE__, __LINE__, new_count, old_count); free(temp_threshbysrc_ipc); Sagan_File_Unlock(config->shm_thresh_by_src); return(0); } /* Threshbydst_IPC */ else if ( type == THRESH_BY_SRC && config->max_threshold_by_dst < counters_ipc->thresh_count_by_dst ) { t = time(NULL); now=localtime(&t); strftime(timet, sizeof(timet), "%s", now); utime = atol(timet); new_count = 0; old_count = 0; Sagan_File_Lock(config->shm_thresh_by_dst); struct thresh_by_dst_ipc *temp_threshbydst_ipc; temp_threshbydst_ipc = malloc(sizeof(struct thresh_by_dst_ipc) * config->max_threshold_by_dst); memset(temp_threshbydst_ipc, 0, sizeof(sizeof(struct thresh_by_dst_ipc) * config->max_threshold_by_dst)); old_count = counters_ipc->thresh_count_by_dst; for (i = 0; i < counters_ipc->thresh_count_by_dst; i++) { if ( (utime - threshbydst_ipc[i].utime) < threshbydst_ipc[i].expire ) { if ( debug->debugipc ) { Sagan_Log(S_DEBUG, "[%s, %d line] Threshbydst_IPC : Keeping %u.", __FILE__, __LINE__, threshbydst_ipc[i].ipdst); } temp_threshbydst_ipc[new_count].ipdst = threshbydst_ipc[i].ipdst; temp_threshbydst_ipc[new_count].count = threshbydst_ipc[i].count; temp_threshbydst_ipc[new_count].utime = threshbydst_ipc[i].utime; temp_threshbydst_ipc[new_count].expire = threshbydst_ipc[i].expire; strlcpy(temp_threshbydst_ipc[new_count].sid, threshbydst_ipc[i].sid, sizeof(temp_threshbydst_ipc[new_count].sid)); new_count++; } } if ( new_count > 0 ) { for ( i = 0; i < new_count; i++ ) { threshbydst_ipc[i].ipdst = temp_threshbydst_ipc[i].ipdst; threshbydst_ipc[i].count = temp_threshbydst_ipc[i].count; threshbydst_ipc[i].utime = temp_threshbydst_ipc[i].utime; threshbydst_ipc[i].expire = temp_threshbydst_ipc[i].expire; strlcpy(threshbydst_ipc[i].sid, temp_threshbydst_ipc[i].sid, sizeof(threshbydst_ipc[i].sid)); } counters_ipc->thresh_count_by_dst = new_count; } else { Sagan_Log(S_WARN, "[%s, line %d] Could not clean thresh_by_dst. Nothing to remove!", __FILE__, __LINE__); free(temp_threshbydst_ipc); Sagan_File_Unlock(config->shm_thresh_by_dst); return(1); } Sagan_Log(S_NORMAL, "[%s, line %d] Kept %d elements out of %d for thresh_by_dst", __FILE__, __LINE__, new_count, old_count); free(temp_threshbydst_ipc); Sagan_File_Unlock(config->shm_thresh_by_dst); return(0); } /* ThreshbyUsername_IPC */ else if ( type == THRESH_BY_USERNAME && config->max_threshold_by_username < counters_ipc->thresh_count_by_username ) { t = time(NULL); now=localtime(&t); strftime(timet, sizeof(timet), "%s", now); utime = atol(timet); new_count = 0; old_count = 0; Sagan_File_Lock(config->shm_thresh_by_username); struct thresh_by_username_ipc *temp_threshbyusername_ipc; temp_threshbyusername_ipc = malloc(sizeof(struct thresh_by_username_ipc) * config->max_threshold_by_username); memset(temp_threshbyusername_ipc, 0, sizeof(sizeof(struct thresh_by_username_ipc) * config->max_threshold_by_username)); old_count = counters_ipc->thresh_count_by_username; for (i = 0; i < counters_ipc->thresh_count_by_username; i++) { if ( (utime - threshbyusername_ipc[i].utime) < threshbyusername_ipc[i].expire ) { if ( debug->debugipc ) { Sagan_Log(S_DEBUG, "[%s, %d line] Afterbyusername_IPC : Keeping '%s'.", __FILE__, __LINE__, threshbyusername_ipc[i].username); } temp_threshbyusername_ipc[new_count].count = threshbyusername_ipc[i].count; temp_threshbyusername_ipc[new_count].utime = threshbyusername_ipc[i].utime; temp_threshbyusername_ipc[new_count].expire = threshbyusername_ipc[i].expire; strlcpy(temp_threshbyusername_ipc[new_count].sid, threshbyusername_ipc[i].sid, sizeof(temp_threshbyusername_ipc[new_count].sid)); strlcpy(temp_threshbyusername_ipc[new_count].username, threshbyusername_ipc[i].username, sizeof(temp_threshbyusername_ipc[new_count].username)); new_count++; } } if ( new_count > 0 ) { for ( i = 0; i < new_count; i++ ) { threshbyusername_ipc[i].count = temp_threshbyusername_ipc[i].count; threshbyusername_ipc[i].utime = temp_threshbyusername_ipc[i].utime; threshbyusername_ipc[i].expire = temp_threshbyusername_ipc[i].expire; strlcpy(threshbyusername_ipc[i].sid, temp_threshbyusername_ipc[i].sid, sizeof(threshbyusername_ipc[i].sid)); strlcpy(threshbyusername_ipc[i].username, temp_threshbyusername_ipc[i].username, sizeof(threshbyusername_ipc[i].username)); } counters_ipc->thresh_count_by_username = new_count; } else { Sagan_Log(S_WARN, "[%s, line %d] Could not clean thresh_by_username. Nothing to remove!", __FILE__, __LINE__); free(temp_threshbyusername_ipc); Sagan_File_Unlock(config->shm_thresh_by_username); return(1); } Sagan_Log(S_NORMAL, "[%s, line %d] Kept %d elements out of %d for thresh_by_username", __FILE__, __LINE__, new_count, old_count); free(temp_threshbyusername_ipc); Sagan_File_Unlock(config->shm_thresh_by_username); return(0); } /* Flowbit_IPC */ else if ( type == FLOWBIT && config->max_flowbits < counters_ipc->flowbit_count ) { t = time(NULL); now=localtime(&t); strftime(timet, sizeof(timet), "%s", now); utime = atol(timet); new_count = 0; old_count = 0; Sagan_File_Lock(config->shm_flowbit); struct _Sagan_IPC_Flowbit *temp_flowbit_ipc; temp_flowbit_ipc = malloc(sizeof(struct _Sagan_IPC_Flowbit) * config->max_flowbits); memset(temp_flowbit_ipc, 0, sizeof(sizeof(struct _Sagan_IPC_Flowbit) * config->max_flowbits)); old_count = counters_ipc->flowbit_count; for (i = 0; i < counters_ipc->flowbit_count; i++) { if ( (utime - flowbit_ipc[i].flowbit_expire) < flowbit_ipc[i].expire ) { if ( debug->debugipc ) { Sagan_Log(S_DEBUG, "[%s, %d line] Flowbot_IPC : Keeping '%s'.", __FILE__, __LINE__, flowbit_ipc[i].ip_src, flowbit_ipc[i].ip_dst); } temp_flowbit_ipc[new_count].flowbit_state = flowbit_ipc[i].flowbit_state; temp_flowbit_ipc[new_count].ip_src = flowbit_ipc[i].ip_src; temp_flowbit_ipc[new_count].ip_dst = flowbit_ipc[i].ip_dst; temp_flowbit_ipc[new_count].flowbit_expire = flowbit_ipc[i].flowbit_expire; temp_flowbit_ipc[new_count].expire = flowbit_ipc[i].expire; strlcpy(temp_flowbit_ipc[new_count].flowbit_name, flowbit_ipc[i].flowbit_name, sizeof(temp_flowbit_ipc[new_count].flowbit_name)); new_count++; } } if ( new_count > 0 ) { for ( i = 0; i < new_count; i++ ) { flowbit_ipc[i].flowbit_state = temp_flowbit_ipc[i].flowbit_state; flowbit_ipc[i].ip_src = temp_flowbit_ipc[i].ip_src; flowbit_ipc[i].ip_dst = temp_flowbit_ipc[i].ip_dst; flowbit_ipc[i].flowbit_expire = temp_flowbit_ipc[i].flowbit_expire; flowbit_ipc[i].expire = temp_flowbit_ipc[i].expire; strlcpy(flowbit_ipc[i].flowbit_name, temp_flowbit_ipc[i].flowbit_name, sizeof(flowbit_ipc[i].flowbit_name)); } counters_ipc->flowbit_count = new_count; } else { Sagan_Log(S_WARN, "[%s, line %d] Could not clean _Sagan_IPC_Flowbit. Nothing to remove!", __FILE__, __LINE__); free(temp_flowbit_ipc); Sagan_File_Unlock(config->shm_flowbit); return(1); } Sagan_Log(S_NORMAL, "[%s, line %d] Kept %d elements out of %d for _Sagan_IPC_Flowbit.", __FILE__, __LINE__, new_count, old_count); free(temp_flowbit_ipc); Sagan_File_Unlock(config->shm_flowbit); return(0); } return(0); }
void Load_Config( void ) { FILE *sagancfg; char *filename; char ruleset[MAXPATH]; char normfile[MAXPATH]; char tmpbuf[CONFBUF]; char tmpbuf2[CONFBUF]; char tmpstring[CONFBUF]; char *sagan_option=NULL; char *sagan_var1=NULL; char *sagan_var2=NULL; char *sagan_var3=NULL; char *ptmp=NULL; char *tok=NULL; char *tok2=NULL; int i,check; /* Set some system defaults */ strlcpy(config->sagan_alert_filepath, ALERTLOG, sizeof(config->sagan_alert_filepath)); strlcpy(config->sagan_lockfile, LOCKFILE, sizeof(config->sagan_lockfile)); strlcpy(config->sagan_log_path, SAGANLOGPATH, sizeof(config->sagan_log_path)); strlcpy(config->sagan_rule_path, RULE_PATH, sizeof(config->sagan_rule_path)); config->sagan_fifo[0] = '\0'; config->sagan_host[0] = '\0'; config->sagan_port = 514; #if defined(F_GETPIPE_SZ) && defined(F_SETPIPE_SZ) config->sagan_fifo_size = MAX_FIFO_SIZE; #endif if ( config->sagan_fifo_flag != 1 ) { strlcpy(config->sagan_fifo, FIFO, sizeof(config->sagan_fifo)); } #ifdef HAVE_LIBESMTP strlcpy(config->sagan_email_subject, DEFAULT_SMTP_SUBJECT, sizeof(config->sagan_email_subject)); #endif config->sagan_proto = 17; /* Default to UDP */ config->max_processor_threads = MAX_PROCESSOR_THREADS; /* PLOG defaults */ #ifdef HAVE_LIBPCAP strlcpy(config->plog_interface, PLOG_INTERFACE, sizeof(config->plog_interface)); strlcpy(config->plog_filter, PLOG_FILTER, sizeof(config->plog_filter)); strlcpy(config->plog_logdev, PLOG_LOGDEV, sizeof(config->plog_logdev)); #endif //config->home_any = 0; //config->external_any = 0; /* Start loading configuration */ rulestruct = (_Rule_Struct *) realloc(rulestruct, (counters->rulecount+1) * sizeof(_Rule_Struct)); /* Gather information for the master configuration file */ if ((sagancfg = fopen(config->sagan_config, "r")) == NULL) { fprintf(stderr, "[%s, line %d] Cannot open configuration file (%s)\n", __FILE__, __LINE__, config->sagan_config); exit(1); } while(fgets(tmpbuf, sizeof(tmpbuf), sagancfg) != NULL) { if (tmpbuf[0] == '#') continue; if (tmpbuf[0] == ';') continue; if (tmpbuf[0] == 10 ) continue; if (tmpbuf[0] == 32 ) continue; strlcpy(tmpbuf2, tmpbuf, sizeof(tmpbuf2)); /* Retain a copy of the entire line */ sagan_option = strtok_r(tmpbuf, " ", &tok); if (!strcmp(Remove_Return(sagan_option), "max_processor_threads")) { sagan_var1 = strtok_r(NULL, " ", &tok); if ( sagan_var1 == NULL ) { Sagan_Log(S_ERROR, "[%s, line %d] \"max_processor_threads\" is incomplete!", __FILE__, __LINE__); } config->max_processor_threads = strtoull(sagan_var1, NULL, 10); } if (!strcmp(Remove_Return(sagan_option), "disable_dns_warnings")) { Sagan_Log(S_NORMAL, "Supressing DNS warnings"); config->disable_dns_warnings = 1; } if (!strcmp(Remove_Return(sagan_option), "syslog_src_lookup")) { Sagan_Log(S_NORMAL, "DNS lookup of source address supplied by syslog daemon"); config->syslog_src_lookup = 1; } if (!strcmp(Remove_Return(sagan_option), "sagan_host")) { sagan_var1 = Remove_Return(strtok_r(NULL, " ", &tok)); if ( sagan_var1 == NULL ) { Sagan_Log(S_ERROR, "[%s, line %d] \"sagan_host\" is incomplete!", __FILE__, __LINE__); } strlcpy(config->sagan_host, sagan_var1, sizeof(config->sagan_host)); } if (!strcmp(sagan_option, "sagan_port")) { sagan_var1 = strtok_r(NULL, " ", &tok); if ( sagan_var1 == NULL ) { Sagan_Log(S_ERROR, "[%s, line %d] \"sagan_port\" is incomplete!", __FILE__, __LINE__); } config->sagan_port = atoi(sagan_var1); } #if defined(F_GETPIPE_SZ) && defined(F_SETPIPE_SZ) if (!strcmp(sagan_option, "sagan_fifo_size")) { sagan_var1 = strtok_r(NULL, " ", &tok); if ( sagan_var1 == NULL ) { Sagan_Log(S_ERROR, "[%s, line %d] \"sagan_fifo_size\" is incomplete!", __FILE__, __LINE__); } config->sagan_fifo_size = atoi(sagan_var1); } #endif #ifndef HAVE_LIBESMTP if (!strcmp(sagan_option, "send-to") || !strcmp(sagan_option, "min_email_priority")) { Sagan_Log(S_ERROR, "[%s, line %d] \"libesmtp\" support not found. Re-compile with ESMTP support or disable in the sagan.conf.", __FILE__, __LINE__); } #endif #ifdef HAVE_LIBESMTP if (!strcmp(sagan_option, "send-to")) { sagan_var1 = strtok_r(NULL, " ", &tok); if ( sagan_var1 == NULL ) { Sagan_Log(S_ERROR, "[%s, line %d] \"send-to\" is incomplete!", __FILE__, __LINE__); } strlcpy(config->sagan_esmtp_to, Remove_Return(sagan_var1), sizeof(config->sagan_esmtp_to)); config->sagan_esmtp_flag=1; config->sagan_sendto_flag=1; } if (!strcmp(sagan_option, "min_email_priority")) { sagan_var1 = strtok_r(NULL, " ", &tok); if ( sagan_var1 == NULL ) { Sagan_Log(S_ERROR, "[%s, line %d] \"min_email_priority\" is incomplete!", __FILE__, __LINE__); } config->min_email_priority = atoi(sagan_var1); } if (!strcmp(sagan_option, "email_subject")) { sagan_var1 = strtok_r(NULL, " ", &tok); if ( sagan_var1 == NULL ) { Sagan_Log(S_ERROR, "[%s, line %d] \email_subject\" is incomplete!", __FILE__, __LINE__); } strlcpy(config->sagan_email_subject, Remove_Return(Between_Quotes(tmpbuf2)), sizeof(config->sagan_email_subject)); }
void Sagan_Open_Log_File( sbool state, int type ) { struct passwd *pw = NULL; int ret; pw = getpwnam(config->sagan_runas); if ( type == SAGAN_LOG || type == ALL_LOGS ) { /* For SIGHUP */ if ( state == REOPEN ) { fclose(config->sagan_log_stream); } if ((config->sagan_log_stream = fopen(config->sagan_log_filepath, "a")) == NULL) { fprintf(stderr, "[E] [%s, line %d] Cannot open %s - %s!\n", __FILE__, __LINE__, config->sagan_log_filepath, strerror(errno)); exit(1); } /* Chown the log files in case we get a SIGHUP or whatnot later (due to Sagan_Chroot()) */ ret = chown(config->sagan_log_filepath, (unsigned long)pw->pw_uid,(unsigned long)pw->pw_gid); if ( ret < 0 ) { Sagan_Log(S_ERROR, "[%s, line %d] Cannot change ownership of %s to username %s - %s", __FILE__, __LINE__, config->sagan_log_filepath, config->sagan_runas, strerror(errno)); } } if ( type == ALERT_LOG || type == ALL_LOGS ) { /* For SIGHUP */ if ( state == REOPEN ) { fclose(config->sagan_alert_stream); } if (( config->sagan_alert_stream = fopen(config->sagan_alert_filepath, "a" )) == NULL ) { Remove_Lock_File(); Sagan_Log(S_ERROR, "[%s, line %d] Can't open %s - %s!", __FILE__, __LINE__, config->sagan_alert_filepath, strerror(errno)); } /* Chown the log files in case we get a SIGHUP or whatnot later (due to Sagan_Chroot()) */ ret = chown(config->sagan_alert_filepath, (unsigned long)pw->pw_uid,(unsigned long)pw->pw_gid); if ( ret < 0 ) { Sagan_Log(S_ERROR, "[%s, line %d] Cannot change ownership of %s to username %s - %s", __FILE__, __LINE__, config->sagan_alert_filepath, config->sagan_runas, strerror(errno)); } } }
void Load_Protocol_Map( const char *map ) { FILE *mapfile; char mapbuf[1024]; char *saveptr=NULL; char *map1=NULL; char *map2=NULL; char *map3=NULL; char *map4=NULL; Sagan_Log(S_NORMAL, "Loading protocol map file. [%s]", map); counters->mapcount=0; if (( mapfile = fopen(map, "r" )) == NULL ) { Sagan_Log(S_ERROR, "[%s, line %d] Cannot open protocol map file (%s)", __FILE__, __LINE__, map); } while(fgets(mapbuf, 1024, mapfile) != NULL) { /* Skip comments and blank linkes */ if (mapbuf[0] == '#' || mapbuf[0] == 10 || mapbuf[0] == ';' || mapbuf[0] == 32) { continue; } else { /* Allocate memory for references, not comments */ map1 = Remove_Spaces(Remove_Return(strtok_r(mapbuf, "|", &saveptr))); map2 = Remove_Spaces(Remove_Return(strtok_r(NULL, "|", &saveptr))); map3 = Remove_Spaces(Remove_Return(strtok_r(NULL, "|", &saveptr))); map4 = Remove_Return(strtok_r(NULL, "|", &saveptr)); if ( map1 == NULL || map2 == NULL || map3 == NULL || map4 == NULL) { Sagan_Log(S_ERROR, "%s is incorrect or not correctly formated", map); } if (!strcmp(map1, "message")) { map_message = (_Sagan_Protocol_Map_Message *) realloc(map_message, (counters->mapcount_message+1) * sizeof(_Sagan_Protocol_Map_Message)); if ( map_message == NULL ) { Sagan_Log(S_ERROR, "[%s, line %d] Failed to reallocate memory for map_message. Abort!", __FILE__, __LINE__); } map_message[counters->mapcount_message].proto = atoi(map2); if (!strcmp(map3, "nocase")) map_message[counters->mapcount_message].nocase = 1; strlcpy(map_message[counters->mapcount_message].search, map4, sizeof(map_message[counters->mapcount_message].search)); counters->mapcount_message++; } if (!strcmp(map1, "program")) { map_program = (_Sagan_Protocol_Map_Program *) realloc(map_program, (counters->mapcount_program+1) * sizeof(_Sagan_Protocol_Map_Program)); if ( map_program == NULL ) { Sagan_Log(S_ERROR, "[%s, line %d] Failed to reallocate memory for map_program. Abort!", __FILE__, __LINE__); } map_program[counters->mapcount_program].proto = atoi(map2); if (!strcmp(map3, "nocase")) map_program[counters->mapcount_program].nocase = 1; strlcpy(map_program[counters->mapcount_program].program, map4, sizeof(map_program[counters->mapcount_program].program)); counters->mapcount_program++; } counters->mapcount++; } } fclose(mapfile); Sagan_Log(S_NORMAL, "%d protocols loaded [Message search: %d|Program search: %d]", counters->mapcount, counters->mapcount_message, counters->mapcount_program); }
void Sagan_IPC_Init(void) { /* If we have a "new" counters shared memory object, but other "old" data, we need to remove * the "old" data! The counters need to stay in sync with the other data objects! */ sbool new_counters = 0; sbool new_object = 0; int i; char tmp_object_check[255]; /* For convert 32 bit IP to octet */ struct in_addr ip_addr_src; struct in_addr ip_addr_dst; Sagan_Log(S_NORMAL, "Initializing shared memory objects."); Sagan_Log(S_NORMAL, "---------------------------------------------------------------------------"); /* Init counters first. Need to track all other share memory objects */ snprintf(tmp_object_check, sizeof(tmp_object_check) - 1, "%s/%s", config->ipc_directory, COUNTERS_IPC_FILE); if ((config->shm_counters = open(tmp_object_check, (O_CREAT | O_EXCL | O_RDWR), (S_IREAD | S_IWRITE))) > 0 ) { Sagan_Log(S_NORMAL, "+ Counters shared object (new)."); new_counters = 1; } else if ((config->shm_counters = open(tmp_object_check, (O_CREAT | O_RDWR), (S_IREAD | S_IWRITE))) < 0 ) { Sagan_Log(S_ERROR, "[%s, line %d] Cannot open() for counters. [%s:%s]", __FILE__, __LINE__, tmp_object_check, strerror(errno)); } else { Sagan_Log(S_NORMAL, "- Counters shared object (reload)"); } if ( ftruncate(config->shm_counters, sizeof(_Sagan_IPC_Counters)) != 0 ) { Sagan_Log(S_ERROR, "[%s, line %d] Failed to ftruncate counters. [%s]", __FILE__, __LINE__, strerror(errno)); } if (( counters_ipc = mmap(0, sizeof(_Sagan_IPC_Counters), (PROT_READ | PROT_WRITE), MAP_SHARED, config->shm_counters, 0)) == MAP_FAILED ) { Sagan_Log(S_ERROR, "[%s, line %d] Error allocating memory for counters object! [%s]", __FILE__, __LINE__, strerror(errno)); } /* Flowbit memory object */ snprintf(tmp_object_check, sizeof(tmp_object_check) - 1, "%s/%s", config->ipc_directory, FLOWBIT_IPC_FILE); Sagan_IPC_Check_Object(tmp_object_check, new_counters, "flowbit"); if ((config->shm_flowbit = open(tmp_object_check, (O_CREAT | O_EXCL | O_RDWR), (S_IREAD | S_IWRITE))) > 0 ) { Sagan_Log(S_NORMAL, "+ Flowbit shared object (new)."); new_object=1; } else if ((config->shm_flowbit = open(tmp_object_check, (O_CREAT | O_RDWR), (S_IREAD | S_IWRITE))) < 0 ) { Sagan_Log(S_ERROR, "[%s, line %d] Cannot open() for flowbit (%s:%s)", __FILE__, __LINE__, tmp_object_check, strerror(errno)); } if ( ftruncate(config->shm_flowbit, sizeof(_Sagan_IPC_Flowbit) * config->max_flowbits ) != 0 ) { Sagan_Log(S_ERROR, "[%s, line %d] Failed to ftruncate flowbit. [%s]", __FILE__, __LINE__, strerror(errno)); } if (( flowbit_ipc = mmap(0, sizeof(_Sagan_IPC_Flowbit) * config->max_flowbits, (PROT_READ | PROT_WRITE), MAP_SHARED, config->shm_flowbit, 0)) == MAP_FAILED ) { Sagan_Log(S_ERROR, "[%s, line %d] Error allocating memory for flowbit object! [%s]", __FILE__, __LINE__, strerror(errno)); } if ( new_object == 0) { Sagan_Log(S_NORMAL, "- Flowbit shared object reloaded (%d flowbits loaded / max: %d).", counters_ipc->flowbit_count, config->max_flowbits); } new_object = 0; if ( debug->debugipc && counters_ipc->flowbit_count >= 1 ) { Sagan_Log(S_DEBUG, ""); Sagan_Log(S_DEBUG, "*** Flowbits ***"); Sagan_Log(S_DEBUG, "------------------------------------------------------------------------------------------------"); Sagan_Log(S_DEBUG, "%-2s| %-25s| %-16s| %-16s| %-21s| %s", "S", "Flowbit name", "SRC IP", "DST IP", "Date added/modified", "Expire"); Sagan_Log(S_DEBUG, "------------------------------------------------------------------------------------------------"); for (i= 0; i < counters_ipc->flowbit_count; i++ ) { ip_addr_src.s_addr = htonl(flowbit_ipc[i].ip_src); ip_addr_dst.s_addr = htonl(flowbit_ipc[i].ip_dst); if ( flowbit_ipc[i].flowbit_state == 1 ) { Sagan_Log(S_DEBUG, "%-2d| %-25s| %-16s| %-16s| %-21s| %d", flowbit_ipc[i].flowbit_state, flowbit_ipc[i].flowbit_name, inet_ntoa(ip_addr_src), inet_ntoa(ip_addr_dst), Sagan_u32_Time_To_Human(flowbit_ipc[i].flowbit_expire), flowbit_ipc[i].expire ); } } Sagan_Log(S_DEBUG, ""); } /* Threshold by source */ snprintf(tmp_object_check, sizeof(tmp_object_check) - 1, "%s/%s", config->ipc_directory, THRESH_BY_SRC_IPC_FILE); Sagan_IPC_Check_Object(tmp_object_check, new_counters, "thresh_by_src"); if ((config->shm_thresh_by_src = open(tmp_object_check, (O_CREAT | O_EXCL | O_RDWR), (S_IREAD | S_IWRITE))) > 0 ) { Sagan_Log(S_NORMAL, "+ Thresh_by_src shared object (new)."); new_object=1; } else if ((config->shm_thresh_by_src = open(tmp_object_check, (O_CREAT | O_RDWR), (S_IREAD | S_IWRITE))) < 0 ) { Sagan_Log(S_ERROR, "[%s, line %d] Cannot open() for thresh_by_src (%s:%s)", __FILE__, __LINE__, tmp_object_check, strerror(errno)); } if ( ftruncate(config->shm_thresh_by_src, sizeof(thresh_by_src_ipc) * config->max_threshold_by_src ) != 0 ) { Sagan_Log(S_ERROR, "[%s, line %d] Failed to ftruncate thresh_by_src. [%s]", __FILE__, __LINE__, strerror(errno)); } if (( threshbysrc_ipc = mmap(0, sizeof(thresh_by_src_ipc) * config->max_threshold_by_src, (PROT_READ | PROT_WRITE), MAP_SHARED, config->shm_thresh_by_src, 0)) == MAP_FAILED ) { Sagan_Log(S_ERROR, "[%s, line %d] Error allocating memory for thresh_by_src object! [%s]", __FILE__, __LINE__, strerror(errno)); } if ( new_object == 0) { Sagan_Log(S_NORMAL, "- Thresh_by_src shared object reloaded (%d sources loaded / max: %d).", counters_ipc->thresh_count_by_src, config->max_threshold_by_src); } new_object = 0; if ( debug->debugipc && counters_ipc->thresh_count_by_src >= 1 ) { Sagan_Log(S_DEBUG, ""); Sagan_Log(S_DEBUG, "*** Threshold by source ***"); Sagan_Log(S_DEBUG, "--------------------------------------------------------------------------------------"); Sagan_Log(S_DEBUG, "%-16s| %-11s| %-21s| %-11s| %s", "SRC IP", "Counter","Date added/modified", "SID", "Expire" ); Sagan_Log(S_DEBUG, "--------------------------------------------------------------------------------------"); for ( i = 0; i < counters_ipc->thresh_count_by_src; i++) { ip_addr_src.s_addr = htonl(threshbysrc_ipc[i].ipsrc); Sagan_Log(S_DEBUG, "%-16s| %-11d| %-21s| %-11s| %d", inet_ntoa(ip_addr_src), threshbysrc_ipc[i].count, Sagan_u32_Time_To_Human(threshbysrc_ipc[i].utime), threshbysrc_ipc[i].sid, threshbysrc_ipc[i].expire); } Sagan_Log(S_DEBUG, ""); } /* Threshold by destination */ snprintf(tmp_object_check, sizeof(tmp_object_check) - 1, "%s/%s", config->ipc_directory, THRESH_BY_DST_IPC_FILE); Sagan_IPC_Check_Object(tmp_object_check, new_counters, "thresh_by_dst"); if ((config->shm_thresh_by_dst = open(tmp_object_check, (O_CREAT | O_EXCL | O_RDWR), (S_IREAD | S_IWRITE))) > 0 ) { Sagan_Log(S_NORMAL, "+ Thresh_by_dst shared object (new)."); new_object=1; } else if ((config->shm_thresh_by_dst = open(tmp_object_check, (O_CREAT | O_RDWR), (S_IREAD | S_IWRITE))) < 0 ) { Sagan_Log(S_ERROR, "[%s, line %d] Cannot open() for thresh_by_dst (%s:%s)", __FILE__, __LINE__, tmp_object_check, strerror(errno)); } if ( ftruncate(config->shm_thresh_by_dst, sizeof(thresh_by_dst_ipc) * config->max_threshold_by_dst) != 0 ) { Sagan_Log(S_ERROR, "[%s, line %d] Failed to ftruncate thresh_by_dst. [%s]", __FILE__, __LINE__, strerror(errno)); } if (( threshbydst_ipc = mmap(0, sizeof(thresh_by_dst_ipc) * config->max_threshold_by_dst, (PROT_READ | PROT_WRITE), MAP_SHARED, config->shm_thresh_by_dst, 0)) == MAP_FAILED ) { Sagan_Log(S_ERROR, "[%s, line %d] Error allocating memory for thresh_by_dst object! [%s]", __FILE__, __LINE__, strerror(errno)); } if ( new_object == 0) { Sagan_Log(S_NORMAL, "- Thresh_by_dst shared object reloaded (%d destinations loaded / max: %d).", counters_ipc->thresh_count_by_dst, config->max_threshold_by_dst); } new_object = 0; if ( debug->debugipc && counters_ipc->thresh_count_by_dst >= 1 ) { Sagan_Log(S_DEBUG, ""); Sagan_Log(S_DEBUG, "*** Threshold by destination ***"); Sagan_Log(S_DEBUG, "--------------------------------------------------------------------------------------"); Sagan_Log(S_DEBUG, "%-16s| %-11s| %-21s| %-11s| %s", "DST IP", "Counter","Date added/modified", "SID", "Expire" ); Sagan_Log(S_DEBUG, "--------------------------------------------------------------------------------------"); for ( i = 0; i < counters_ipc->thresh_count_by_dst; i++) { ip_addr_dst.s_addr = htonl(threshbydst_ipc[i].ipdst); Sagan_Log(S_DEBUG, "%-16s| %-11d| %-21s| %-11s| %d", inet_ntoa(ip_addr_dst), threshbydst_ipc[i].count, Sagan_u32_Time_To_Human(threshbydst_ipc[i].utime), threshbydst_ipc[i].sid, threshbydst_ipc[i].expire); } Sagan_Log(S_DEBUG, ""); } /* Threshold by username */ snprintf(tmp_object_check, sizeof(tmp_object_check) - 1, "%s/%s", config->ipc_directory, THRESH_BY_USERNAME_IPC_FILE); Sagan_IPC_Check_Object(tmp_object_check, new_counters, "thresh_by_username"); if ((config->shm_thresh_by_username = open(tmp_object_check, (O_CREAT | O_EXCL | O_RDWR), (S_IREAD | S_IWRITE))) > 0 ) { Sagan_Log(S_NORMAL, "+ Thresh_by_username shared object (new)."); new_object=1; } else if ((config->shm_thresh_by_username = open(tmp_object_check, (O_CREAT | O_RDWR), (S_IREAD | S_IWRITE))) < 0 ) { Sagan_Log(S_ERROR, "[%s, line %d] Cannot open() for thresh_by_username (%s:%s)", __FILE__, __LINE__, tmp_object_check, strerror(errno)); } if ( ftruncate(config->shm_thresh_by_username, sizeof(thresh_by_username_ipc) * config->max_threshold_by_username ) != 0 ) { Sagan_Log(S_ERROR, "[%s, line %d] Failed to ftruncate thresh_by_username. [%s]", __FILE__, __LINE__, strerror(errno)); } if (( threshbyusername_ipc = mmap(0, sizeof(thresh_by_username_ipc) * config->max_threshold_by_username, (PROT_READ | PROT_WRITE), MAP_SHARED, config->shm_thresh_by_username, 0)) == MAP_FAILED ) { Sagan_Log(S_ERROR, "[%s, line %d] Error allocating memory for thresh_by_username object! [%s]", __FILE__, __LINE__, strerror(errno)); } if ( new_object == 0 ) { Sagan_Log(S_NORMAL, "- Thresh_by_username shared object reloaded (%d usernames loaded / max: %d).", counters_ipc->thresh_count_by_username, config->max_threshold_by_username); } new_object = 0; if ( debug->debugipc && counters_ipc->thresh_count_by_username >= 1 ) { Sagan_Log(S_DEBUG, ""); Sagan_Log(S_DEBUG, "*** Threshold by username ***"); Sagan_Log(S_DEBUG, "--------------------------------------------------------------------------------------"); Sagan_Log(S_DEBUG, "%-16s| %-11s| %-21s| %-11s| %s", "Username", "Counter","Date added/modified", "SID", "Expire" ); Sagan_Log(S_DEBUG, "--------------------------------------------------------------------------------------"); for ( i = 0; i < counters_ipc->thresh_count_by_username; i++) { Sagan_Log(S_DEBUG, "%-16s| %-11d| %-21s| %-11s| %d", threshbyusername_ipc[i].username, threshbyusername_ipc[i].count, Sagan_u32_Time_To_Human(threshbyusername_ipc[i].utime), threshbyusername_ipc[i].sid, threshbyusername_ipc[i].expire); } } /* After by source */ snprintf(tmp_object_check, sizeof(tmp_object_check) - 1, "%s/%s", config->ipc_directory, AFTER_BY_SRC_IPC_FILE); Sagan_IPC_Check_Object(tmp_object_check, new_counters, "after_by_src"); if ((config->shm_after_by_src = open(tmp_object_check, (O_CREAT | O_EXCL | O_RDWR), (S_IREAD | S_IWRITE))) > 0 ) { Sagan_Log(S_NORMAL, "+ After_by_src shared object (new)."); new_object=1; } else if ((config->shm_after_by_src = open(tmp_object_check, (O_CREAT | O_RDWR), (S_IREAD | S_IWRITE))) < 0 ) { Sagan_Log(S_ERROR, "[%s, line %d] Cannot open() for after_by_src (%s:%s)", __FILE__, __LINE__, tmp_object_check, strerror(errno)); } if ( ftruncate(config->shm_after_by_src, sizeof(after_by_src_ipc) * config->max_after_by_src ) != 0 ) { Sagan_Log(S_ERROR, "[%s, line %d] Failed to ftruncate after_by_src. [%s]", __FILE__, __LINE__, strerror(errno)); } if (( afterbysrc_ipc = mmap(0, sizeof(after_by_src_ipc) * config->max_after_by_src, (PROT_READ | PROT_WRITE), MAP_SHARED, config->shm_after_by_src, 0)) == MAP_FAILED ) { Sagan_Log(S_ERROR, "[%s, line %d] Error allocating memory for after_by_src object! [%s]", __FILE__, __LINE__, strerror(errno)); } if ( new_object == 0 ) { Sagan_Log(S_NORMAL, "- After_by_src shared object reloaded (%d sources loaded / max: %d).", counters_ipc->after_count_by_src, config->max_after_by_src); } new_object = 0; if ( debug->debugipc && counters_ipc->after_count_by_src >= 1 ) { Sagan_Log(S_DEBUG, ""); Sagan_Log(S_DEBUG, "*** After by source ***"); Sagan_Log(S_DEBUG, "--------------------------------------------------------------------------------------"); Sagan_Log(S_DEBUG, "%-16s| %-11s| %-21s| %-11s| %s", "SRC IP", "Counter","Date added/modified", "SID", "Expire" ); Sagan_Log(S_DEBUG, "--------------------------------------------------------------------------------------"); for ( i = 0; i < counters_ipc->after_count_by_src; i++ ) { ip_addr_src.s_addr = htonl(afterbysrc_ipc[i].ipsrc); Sagan_Log(S_DEBUG, "%-16s| %-11d| %-21s| %-11s| %d", inet_ntoa(ip_addr_src), afterbysrc_ipc[i].count, Sagan_u32_Time_To_Human(afterbysrc_ipc[i].utime), afterbysrc_ipc[i].sid, afterbysrc_ipc[i].expire); } Sagan_Log(S_DEBUG, ""); } /* After by destination */ snprintf(tmp_object_check, sizeof(tmp_object_check) - 1, "%s/%s", config->ipc_directory, AFTER_BY_DST_IPC_FILE); Sagan_IPC_Check_Object(tmp_object_check, new_counters, "after_by_dst"); if ((config->shm_after_by_dst = open(tmp_object_check, (O_CREAT | O_EXCL | O_RDWR), (S_IREAD | S_IWRITE))) > 0 ) { Sagan_Log(S_NORMAL, "+ After_by_dst shared object (new)."); new_object=1; } else if ((config->shm_after_by_dst = open(tmp_object_check, (O_CREAT | O_RDWR), (S_IREAD | S_IWRITE))) < 0 ) { Sagan_Log(S_ERROR, "[%s, line %d] Cannot open() for after_by_dst (%s:%s)", __FILE__, __LINE__, tmp_object_check, strerror(errno)); } if ( ftruncate(config->shm_after_by_dst, sizeof(after_by_dst_ipc) * config->max_after_by_dst) != 0 ) { Sagan_Log(S_ERROR, "[%s, line %d] Failed to ftruncate after_by_dst. [%s]", __FILE__, __LINE__, strerror(errno)); } if (( afterbydst_ipc = mmap(0, sizeof(after_by_dst_ipc) * config->max_after_by_dst, (PROT_READ | PROT_WRITE), MAP_SHARED, config->shm_after_by_dst, 0)) == MAP_FAILED ) { Sagan_Log(S_ERROR, "[%s, line %d] Error allocating memory for after_by_src object! [%s]", __FILE__, __LINE__, strerror(errno)); } if ( new_object == 0 ) { Sagan_Log(S_NORMAL, "- After_by_dst shared object reloaded (%d destinations loaded / max: %d).", counters_ipc->after_count_by_dst, config->max_after_by_dst); } new_object = 0; if ( debug->debugipc && counters_ipc->after_count_by_dst >= 1 ) { Sagan_Log(S_DEBUG, ""); Sagan_Log(S_DEBUG, "*** After by destination ***"); Sagan_Log(S_DEBUG, "--------------------------------------------------------------------------------------"); Sagan_Log(S_DEBUG, "%-16s| %-11s| %-21s| %-11s| %s", "DST IP", "Counter","Date added/modified", "SID", "Expire" ); Sagan_Log(S_DEBUG, "--------------------------------------------------------------------------------------"); for ( i = 0; i < counters_ipc->after_count_by_dst; i++) { ip_addr_dst.s_addr = htonl(afterbydst_ipc[i].ipdst); Sagan_Log(S_DEBUG, "%-16s| %-11d| %-21s| %-11s| %d", inet_ntoa(ip_addr_dst), afterbydst_ipc[i].count, Sagan_u32_Time_To_Human(afterbydst_ipc[i].utime), afterbydst_ipc[i].sid, afterbydst_ipc[i].expire); } Sagan_Log(S_DEBUG, ""); } /* After by username */ snprintf(tmp_object_check, sizeof(tmp_object_check) - 1, "%s/%s", config->ipc_directory, AFTER_BY_USERNAME_IPC_FILE); Sagan_IPC_Check_Object(tmp_object_check, new_counters, "after_by_username"); if ((config->shm_after_by_username = open(tmp_object_check, (O_CREAT | O_EXCL | O_RDWR), (S_IREAD | S_IWRITE))) > 0 ) { Sagan_Log(S_NORMAL, "+ After_by_username shared object (new)."); new_object=1; } else if ((config->shm_after_by_username = open(tmp_object_check, (O_CREAT | O_RDWR), (S_IREAD | S_IWRITE))) < 0 ) { Sagan_Log(S_ERROR, "[%s, line %d] Cannot open() for after_by_username (%s:%s)", __FILE__, __LINE__, tmp_object_check, strerror(errno)); } if ( ftruncate(config->shm_after_by_username, sizeof(after_by_username_ipc) * config->max_after_by_username ) != 0 ) { Sagan_Log(S_ERROR, "[%s, line %d] Failed to ftruncate after_by_username. [%s]", __FILE__, __LINE__, strerror(errno)); } if (( afterbyusername_ipc = mmap(0, sizeof(after_by_username_ipc) * config->max_after_by_username, (PROT_READ | PROT_WRITE), MAP_SHARED, config->shm_after_by_username, 0)) == MAP_FAILED ) { Sagan_Log(S_ERROR, "[%s, line %d] Error allocating memory for after_by_src object! [%s]", __FILE__, __LINE__, strerror(errno)); } if ( new_object == 0 ) { Sagan_Log(S_NORMAL, "- After_by_username shared object reloaded (%d usernames loaded / max: %d).", counters_ipc->after_count_by_username, config->max_after_by_username); } new_object = 0; if ( debug->debugipc && counters_ipc->after_count_by_username >= 1 ) { Sagan_Log(S_DEBUG, ""); Sagan_Log(S_DEBUG, "*** After by username ***"); Sagan_Log(S_DEBUG, "--------------------------------------------------------------------------------------"); Sagan_Log(S_DEBUG, "%-16s| %-11s| %-21s| %-11s| %s", "Username", "Counter","Date added/modified", "SID", "Expire" ); Sagan_Log(S_DEBUG, "--------------------------------------------------------------------------------------"); for ( i = 0; i < counters_ipc->after_count_by_username; i++) { Sagan_Log(S_DEBUG, "%-16s| %-11d| %-21s| %-11s| %d", afterbyusername_ipc[i].username, afterbyusername_ipc[i].count, Sagan_u32_Time_To_Human(afterbyusername_ipc[i].utime), afterbyusername_ipc[i].sid, afterbyusername_ipc[i].expire); } Sagan_Log(S_DEBUG, ""); } /* Client tracking */ if ( config->sagan_track_clients_flag ) { snprintf(tmp_object_check, sizeof(tmp_object_check) - 1, "%s/%s", config->ipc_directory, CLIENT_TRACK_IPC_FILE); Sagan_IPC_Check_Object(tmp_object_check, new_counters, "_Sagan_Track_Clients_IPC"); if ((config->shm_track_clients = open(tmp_object_check, (O_CREAT | O_EXCL | O_RDWR), (S_IREAD | S_IWRITE))) > 0 ) { Sagan_Log(S_NORMAL, "+ Sagan_track_clients shared object (new)."); new_object=1; /* Reset any track_clients_client_count's to 0! */ Sagan_File_Lock(config->shm_counters); counters_ipc->track_clients_client_count = 0; counters_ipc->track_clients_down = 0; Sagan_File_Unlock(config->shm_counters); } else if ((config->shm_track_clients = open(tmp_object_check, (O_CREAT | O_RDWR), (S_IREAD | S_IWRITE))) < 1 ) { Sagan_Log(S_ERROR, "[%s, line %d] Cannot open() for Sagan_track_clients (%s:%s)", __FILE__, __LINE__, tmp_object_check, strerror(errno)); } if ( ftruncate(config->shm_track_clients, sizeof(_Sagan_Track_Clients_IPC) * config->max_track_clients ) != 0 ) { Sagan_Log(S_ERROR, "[%s, line %d] Failed to ftruncate _Sagan_Track_Clients_IPC. [%s]", __FILE__, __LINE__, strerror(errno)); } if (( SaganTrackClients_ipc = mmap(0, sizeof(_Sagan_Track_Clients_IPC) * config->max_track_clients, (PROT_READ | PROT_WRITE), MAP_SHARED, config->shm_track_clients, 0)) == MAP_FAILED ) { Sagan_Log(S_ERROR, "[%s, line %d] Error allocating memory for _Sagan_Track_Clients_IPC! [%s]", __FILE__, __LINE__, strerror(errno)); } if ( new_object == 0 ) { Sagan_Log(S_NORMAL, "- Sagan_track_clients shared object reloaded (%d clients loaded / max: %d).", counters_ipc->track_clients_client_count, config->max_track_clients); } new_object = 0; /* if ( debug->debugipc && counters_ipc->track_client_count >= 1 ) { Sagan_Log(S_DEBUG, ""); Sagan_Log(S_DEBUG, "*** After by username ***"); Sagan_Log(S_DEBUG, "--------------------------------------------------------------------------------------"); Sagan_Log(S_DEBUG, "%-16s| %-11s| %-21s| %-11s| %s", "Username", "Counter","Date added/modified", "SID", "Expire" ); Sagan_Log(S_DEBUG, "--------------------------------------------------------------------------------------"); for ( i = 0; i < counters_ipc->after_count_by_username; i++) { Sagan_Log(S_DEBUG, "%-16s| %-11d| %-21s| %-11s| %d", afterbyusername_ipc[i].username, afterbyusername_ipc[i].count, Sagan_u32_Time_To_Human(afterbyusername_ipc[i].utime), afterbyusername_ipc[i].sid, afterbyusername_ipc[i].expire); } Sagan_Log(S_DEBUG, ""); } */ } }