END_TEST START_TEST(test_udpv6) { int server_socket, client_socket; char buffer[BUFFERSIZE]; char *msg; ck_assert_int_ge((server_socket = OS_Bindportudp(PORT, IPV6, 1)), 0); ck_assert_int_ge((client_socket = OS_ConnectUDP(PORT, IPV6, 1, NULL)) , 0); //TODO: ck_assert_int_eq(OS_SendUDP(client_socket, SENDSTRING), 0); ck_assert_int_eq(OS_SendUDPbySize(client_socket, strlen(SENDSTRING), SENDSTRING), 0); //TODO: not null-terminated ck_assert_int_eq(OS_RecvConnUDP(server_socket, buffer, BUFFERSIZE), strlen(SENDSTRING)); ck_assert_str_eq(buffer, SENDSTRING); ck_assert_int_eq(OS_SendUDPbySize(client_socket, 5, SENDSTRING), 0); ck_assert_ptr_ne((msg = OS_RecvUDP(server_socket, BUFFERSIZE)), NULL); ck_assert_str_eq(msg, "Hello"); /* only 5 bytes send */ free(msg); OS_CloseSocket(client_socket); OS_CloseSocket(server_socket); }
END_TEST START_TEST(test_udpinvalidsockets) { char buffer[BUFFERSIZE]; //TODO: ck_assert_int_eq(OS_SendUDP(-1, SENDSTRING), OS_SOCKTERR); ck_assert_int_eq(OS_SendUDPbySize(-1, strlen(SENDSTRING), SENDSTRING), OS_SOCKTERR); ck_assert_ptr_eq(OS_RecvUDP(-1, BUFFERSIZE), NULL); ck_assert_int_eq(OS_RecvConnUDP(-1, buffer, BUFFERSIZE), 0); }
/* Sends a message to the server */ int send_msg(int agentid, char *msg) { int msg_size; char crypt_msg[OS_MAXSTR +1]; msg_size = CreateSecMSG(&keys, msg, crypt_msg, agentid); if(msg_size == 0) { merror(SEC_ERROR,ARGV0); return(-1); } /* Send msg_size of crypt_msg */ if(OS_SendUDPbySize(agt->sock, msg_size, crypt_msg) < 0) { merror(SEND_ERROR,ARGV0, "server"); sleep(1); return(-1); } return(0); }
/** int OS_Alert_SendSyslog * Sends an alert via syslog. * Returns 1 on success or 0 on error. */ int OS_Alert_SendSyslog(alert_data *al_data, SyslogConfig *syslog_config) { char *tstamp; char syslog_msg[OS_SIZE_2048]; /* padding value */ int padding = 0; /* Invalid socket. */ if(syslog_config->socket < 0) { return(0); } /* Clearing the memory before insert */ memset(syslog_msg, '\0', OS_SIZE_2048); /* Looking if location is set */ if(syslog_config->location) { if(!OSMatch_Execute(al_data->location, strlen(al_data->location), syslog_config->location)) { return(0); } } /* Looking for the level */ if(syslog_config->level) { if(al_data->level < syslog_config->level) { return(0); } } /* Looking for rule id */ if(syslog_config->rule_id) { int id_i = 0; while(syslog_config->rule_id[id_i] != 0) { if(syslog_config->rule_id[id_i] == al_data->rule) { break; } id_i++; } /* If we found, id is going to be a valid rule */ if(!syslog_config->rule_id[id_i]) { return(0); } } /* Looking for the group */ if(syslog_config->group) { if(!OSMatch_Execute(al_data->group, strlen(al_data->group), syslog_config->group)) { return(0); } } /* Fixing the timestamp to be syslog compatible. * We have 2008 Jul 10 10:11:23 * Should be: Jul 10 10:11:23 */ tstamp = al_data->date; if(strlen(al_data->date) > 14) { tstamp+=5; /* Fixing first digit if the day is < 10 */ if(tstamp[4] == '0') tstamp[4] = ' '; } /* Inserting data */ if(syslog_config->format == DEFAULT_CSYSLOG) { /* Building syslog message. */ snprintf(syslog_msg, OS_SIZE_2048, "<%d>%s %s ossec: Alert Level: %d; Rule: %d - %s; Location: %s;", syslog_config->priority, tstamp, __shost, al_data->level, al_data->rule, al_data->comment, al_data->location ); field_add_string(syslog_msg, OS_SIZE_2048, " srcip: %s;", al_data->srcip ); #ifdef GEOIP field_add_string(syslog_msg, OS_SIZE_2048, " srccity: %s;", al_data->geoipdatasrc ); field_add_string(syslog_msg, OS_SIZE_2048, " dstcity: %s;", al_data->geoipdatadst ); #endif field_add_string(syslog_msg, OS_SIZE_2048, " dstip: %s;", al_data->dstip ); field_add_string(syslog_msg, OS_SIZE_2048, " user: %s;", al_data->user ); field_add_string(syslog_msg, OS_SIZE_2048, " Previous MD5: %s;", al_data->old_md5 ); field_add_string(syslog_msg, OS_SIZE_2048, " Current MD5: %s;", al_data->new_md5 ); field_add_string(syslog_msg, OS_SIZE_2048, " Previous SHA1: %s;", al_data->old_sha1 ); field_add_string(syslog_msg, OS_SIZE_2048, " Current SHA1: %s;", al_data->new_sha1 ); field_add_truncated(syslog_msg, OS_SIZE_2048, " %s", al_data->log[0], 2 ); } else if(syslog_config->format == CEF_CSYSLOG) { snprintf(syslog_msg, OS_SIZE_2048, "<%d>%s CEF:0|%s|%s|%s|%d|%s|%d|dvc=%s cs2=%s cs2Label=Location", syslog_config->priority, tstamp, __author, __ossec_name, __version, al_data->rule, al_data->comment, (al_data->level > 10) ? 10 : al_data->level, __shost, al_data->location); field_add_string(syslog_msg, OS_SIZE_2048, " src=%s", al_data->srcip ); field_add_string(syslog_msg, OS_SIZE_2048, " dpt=%s", al_data->dstport ); field_add_string(syslog_msg, OS_SIZE_2048, " spt=%s", al_data->srcport ); field_add_string(syslog_msg, OS_SIZE_2048, " fname=%s", al_data->filename ); field_add_string(syslog_msg, OS_SIZE_2048, " dhost=%s", al_data->dstip ); field_add_string(syslog_msg, OS_SIZE_2048, " shost=%s", al_data->srcip ); field_add_string(syslog_msg, OS_SIZE_2048, " suser=%s", al_data->user ); field_add_string(syslog_msg, OS_SIZE_2048, " dst=%s", al_data->dstip ); #ifdef GEOIP field_add_string(syslog_msg, OS_SIZE_2048, " cs3Label=SrcCity cs3=%s", al_data->geoipdatasrc ); field_add_string(syslog_msg, OS_SIZE_2048, " cs4Label=DstCity cs4=%s", al_data->geoipdatadst ); #endif field_add_string(syslog_msg, OS_SIZE_2048, " suser=%s", al_data->user ); field_add_string(syslog_msg, OS_SIZE_2048, " dst=%s", al_data->dstip ); field_add_truncated(syslog_msg, OS_SIZE_2048, " msg=%s", al_data->log[0], 2 ); if (al_data->new_md5 && al_data->new_sha1) { field_add_string(syslog_msg, OS_SIZE_2048, " cs1Label=OldMD5 cs1=%s", al_data->old_md5); field_add_string(syslog_msg, OS_SIZE_2048, " cs2Label=NewMDG cs2=%s", al_data->new_md5); field_add_string(syslog_msg, OS_SIZE_2048, " oldFileHash=%s", al_data->old_sha1 ); field_add_string(syslog_msg, OS_SIZE_2048, " fhash=%s", al_data->new_sha1 ); field_add_string(syslog_msg, OS_SIZE_2048, " fileHash=%s", al_data->new_sha1 ); } } else if(syslog_config->format == JSON_CSYSLOG) { /* Build a JSON Object for logging */ cJSON *root; char *json_string; root = cJSON_CreateObject(); // Data guaranteed to be there cJSON_AddNumberToObject(root, "crit", al_data->level); cJSON_AddNumberToObject(root, "id", al_data->rule); cJSON_AddStringToObject(root, "component", al_data->location); // Rule Meta Data if (al_data->group) cJSON_AddStringToObject(root, "classification", al_data->group); if (al_data->comment) cJSON_AddStringToObject(root, "description", al_data->comment); // Raw log message generating event if (al_data->log && al_data->log[0]) cJSON_AddStringToObject(root, "message", al_data->log[0]); // Add data if it exists if (al_data->user) cJSON_AddStringToObject(root, "acct", al_data->user); if (al_data->srcip) cJSON_AddStringToObject(root, "src_ip", al_data->srcip); if (al_data->srcport) cJSON_AddNumberToObject(root, "src_port", al_data->srcport); if (al_data->dstip) cJSON_AddStringToObject(root, "dst_ip", al_data->dstip); if (al_data->dstport) cJSON_AddNumberToObject(root, "dst_port", al_data->dstport); if (al_data->filename) cJSON_AddStringToObject(root, "file", al_data->filename); if (al_data->old_md5) cJSON_AddStringToObject(root, "md5_old", al_data->old_md5); if (al_data->new_md5) cJSON_AddStringToObject(root, "md5_new", al_data->new_md5); if (al_data->old_sha1) cJSON_AddStringToObject(root, "sha1_old", al_data->old_sha1); if (al_data->new_sha1) cJSON_AddStringToObject(root, "sha1_new", al_data->new_sha1); #ifdef GEOIP if (al_data->geoipdatasrc) cJSON_AddStringToObject(root, "src_city", al_data->geoipdatasrc); if (al_data->geoipdatadst) cJSON_AddStringToObject(root, "dst_city", al_data->geoipdatadst); #endif // Create the JSON String json_string = cJSON_PrintUnformatted(root); // Create the syslog message snprintf(syslog_msg, OS_SIZE_2048 - padding, "<%d>%s %s ossec: %s", /* syslog header */ syslog_config->priority, tstamp, __shost, /* JSON Encoded Data */ json_string ); // Cleanup the memory for the JSON Structure free(json_string); cJSON_Delete(root); } else if(syslog_config->format == SPLUNK_CSYSLOG) { /* Build a Splunk Style Key/Value string for logging */ snprintf(syslog_msg, OS_SIZE_2048, "<%d>%s %s ossec: crit=%d id=%d description=\"%s\" component=\"%s\",", /* syslog header */ syslog_config->priority, tstamp, __shost, /* OSSEC metadata */ al_data->level, al_data->rule, al_data->comment, al_data->location ); /* Event specifics */ field_add_string(syslog_msg, OS_SIZE_2048, " classification=\"%s\",", al_data->group ); if( field_add_string(syslog_msg, OS_SIZE_2048, " src_ip=\"%s\",", al_data->srcip ) > 0 ) field_add_int(syslog_msg, OS_SIZE_2048, " src_port=%d,", al_data->srcport ); #ifdef GEOIP field_add_string(syslog_msg, OS_SIZE_2048, " src_city=\"%s\",", al_data->geoipdatasrc ); field_add_string(syslog_msg, OS_SIZE_2048, " dst_city=\"%s\",", al_data->geoipdatadst ); #endif if( field_add_string(syslog_msg, OS_SIZE_2048, " dst_ip=\"%s\",", al_data->dstip ) > 0 ) field_add_int(syslog_msg, OS_SIZE_2048, " dst_port=%d,", al_data->dstport ); field_add_string(syslog_msg, OS_SIZE_2048, " file=\"%s\",", al_data->filename ); field_add_string(syslog_msg, OS_SIZE_2048, " acct=\"%s\",", al_data->user ); field_add_string(syslog_msg, OS_SIZE_2048, " md5_old=\"%s\",", al_data->old_md5 ); field_add_string(syslog_msg, OS_SIZE_2048, " md5_new=\"%s\",", al_data->new_md5 ); field_add_string(syslog_msg, OS_SIZE_2048, " sha1_old=\"%s\",", al_data->old_sha1 ); field_add_string(syslog_msg, OS_SIZE_2048, " sha1_new=\"%s\",", al_data->new_sha1 ); /* Message */ field_add_truncated(syslog_msg, OS_SIZE_2048, " message=\"%s\"", al_data->log[0], 2 ); } OS_SendUDPbySize(syslog_config->socket, strlen(syslog_msg), syslog_msg); return(1); }
/** int OS_Alert_SendSyslog * Sends an alert via syslog. * Returns 1 on success or 0 on error. */ int OS_Alert_SendSyslog(alert_data *al_data, SyslogConfig *syslog_config) { char *tstamp; char user_msg[256]; char srcip_msg[256]; char syslog_msg[OS_SIZE_2048 +1]; /* Invalid socket. */ if(syslog_config->socket < 0) { return(0); } /* Clearing the memory before insert */ memset(syslog_msg, '\0', OS_SIZE_2048 +1); /* Looking if location is set */ if(syslog_config->location) { if(!OSMatch_Execute(al_data->location, strlen(al_data->location), syslog_config->location)) { return(0); } } /* Looking for the level */ if(syslog_config->level) { if(al_data->level < syslog_config->level) { return(0); } } /* Looking for rule id */ if(syslog_config->rule_id) { int id_i = 0; while(syslog_config->rule_id[id_i] != 0) { if(syslog_config->rule_id[id_i] == al_data->rule) { break; } id_i++; } /* If we found, id is going to be a valid rule */ if(!syslog_config->rule_id[id_i]) { return(0); } } /* Looking for the group */ if(syslog_config->group) { if(!OSMatch_Execute(al_data->group, strlen(al_data->group), syslog_config->group)) { return(0); } } /* Fixing the timestamp to be syslog compatible. * We have 2008 Jul 10 10:11:23 * Should be: Jul 10 10:11:23 */ tstamp = al_data->date; if(strlen(al_data->date) > 14) { tstamp+=5; /* Fixing first digit if the day is < 10 */ if(tstamp[4] == '0') tstamp[4] = ' '; } /* Adding source ip. */ if(!al_data->srcip || ((al_data->srcip[0] == '(') && (al_data->srcip[1] == 'n') && (al_data->srcip[2] == 'o'))) { srcip_msg[0] = '\0'; } else { snprintf(srcip_msg, 255, " srcip: %s;", al_data->srcip); } /* Adding username. */ if(!al_data->user || ((al_data->user[0] == '(') && (al_data->user[1] == 'n') && (al_data->user[2] == 'o'))) { user_msg[0] = '\0'; } else { snprintf(user_msg, 255, " user: %s;", al_data->user); } /* Inserting data */ if(syslog_config->format == DEFAULT_CSYSLOG) { /* Building syslog message. */ snprintf(syslog_msg, OS_SIZE_2048, "<%d>%s %s ossec: Alert Level: %d; Rule: %d - %s; " "Location: %s;%s%s %s", syslog_config->priority, tstamp, __shost, al_data->level, al_data->rule, al_data->comment, al_data->location, /* Source ip. */ srcip_msg, user_msg, al_data->log[0]); } OS_SendUDPbySize(syslog_config->socket, strlen(syslog_msg), syslog_msg); return(1); }
/* Send win32 info to server */ void send_win32_info(time_t curr_time) { int msg_size; char tmp_msg[OS_MAXSTR +2]; char crypt_msg[OS_MAXSTR +2]; tmp_msg[OS_MAXSTR +1] = '\0'; crypt_msg[OS_MAXSTR +1] = '\0'; debug1("%s: DEBUG: Sending keep alive message.", ARGV0); verbose("%s Sending keep alive message....", ARGV0); /* fixing time */ __win32_curr_time = curr_time; /* Getting uname. */ if(!__win32_uname) { __win32_uname = getuname(); if(!__win32_uname) { merror("%s: Error generating system information.", ARGV0); os_strdup("Microsoft Windows - Unknown (unable to get system info)", __win32_uname); } } /* Getting shared files list -- every 30 seconds only. */ if((__win32_curr_time - __win32_shared_time) > 30) { if(__win32_shared) { free(__win32_shared); __win32_shared = NULL; } __win32_shared_time = __win32_curr_time; } /* get shared files */ if(!__win32_shared) { __win32_shared = getsharedfiles(); if(!__win32_shared) { __win32_shared = strdup("\0"); if(!__win32_shared) { merror(MEM_ERROR, ARGV0); return; } } } /* creating message */ if(File_DateofChange(AGENTCONFIGINT) > 0) { os_md5 md5sum; if(OS_MD5_File(AGENTCONFIGINT, md5sum) != 0) { snprintf(tmp_msg, OS_SIZE_1024, "#!-%s\n%s", __win32_uname, __win32_shared); } else { snprintf(tmp_msg, OS_SIZE_1024, "#!-%s / %s\n%s", __win32_uname, md5sum, __win32_shared); } } else { snprintf(tmp_msg, OS_SIZE_1024, "#!-%s\n%s", __win32_uname, __win32_shared); } /* creating message */ debug1("%s: DEBUG: Sending keep alive: %s", ARGV0, tmp_msg); msg_size = CreateSecMSG(&keys, tmp_msg, crypt_msg, 0); if(msg_size == 0) { merror(SEC_ERROR, ARGV0); return; } /* Sending UDP message */ if(OS_SendUDPbySize(logr->sock, msg_size, crypt_msg) < 0) { merror(SEND_ERROR, ARGV0, "server"); sleep(1); } return; }
/* SendMSG for windows */ int SendMSG(int queue, char *message, char *locmsg, char loc) { int _ssize; time_t cu_time; char *pl; char tmpstr[OS_MAXSTR+2]; char crypt_msg[OS_MAXSTR +2]; DWORD dwWaitResult; tmpstr[OS_MAXSTR +1] = '\0'; crypt_msg[OS_MAXSTR +1] = '\0'; debug2("%s: DEBUG: Attempting to send message to server.", ARGV0); /* Using a mutex to synchronize the writes */ while(1) { dwWaitResult = WaitForSingleObject(hMutex, 1000000L); if(dwWaitResult != WAIT_OBJECT_0) { switch(dwWaitResult) { case WAIT_TIMEOUT: merror("%s: Error waiting mutex (timeout).", ARGV0); sleep(5); continue; case WAIT_ABANDONED: merror("%s: Error waiting mutex (abandoned).", ARGV0); return(0); default: merror("%s: Error waiting mutex.", ARGV0); return(0); } } else { /* Lock acquired */ break; } } /*end - while for mutex...*/ cu_time = time(0); #ifndef ONEWAY /* Check if the server has responded */ if((cu_time - available_server) > logr->notify_time) { debug1("%s: DEBUG: Sending info to server (c1)...", ARGV0); verbose("%s More than %d seconds without server response...sending win32info", ARGV0,logr->notify_time); send_win32_info(cu_time); /* Attempting to send message again. */ if((cu_time - available_server) > logr->notify_time) { /* Try again... */ sleep(1); send_win32_info(cu_time); sleep(1); if((cu_time - available_server) > logr->notify_time) { send_win32_info(cu_time); } } /* If we reached here, the server is unavailable for a while. */ if((cu_time - available_server) > logr->max_time_reconnect_try) { int wi = 1; verbose("%s More than %d seconds without server response...is server alive? and Is there connection?", ARGV0,logr->max_time_reconnect_try); /* Last attempt before going into reconnect mode. */ debug1("%s: DEBUG: Sending info to server (c3)...", ARGV0); sleep(1); send_win32_info(cu_time); if((cu_time - available_server) > logr->max_time_reconnect_try) { sleep(1); send_win32_info(cu_time); sleep(1); } /* Checking and generating log if unavailable. */ cu_time = time(0); if((cu_time - available_server) > logr->max_time_reconnect_try) { int global_sleep = 1; int mod_sleep = 12; /* If response is not available, set lock and * wait for it. */ verbose(SERVER_UNAV, ARGV0); /* Going into reconnect mode. */ while((cu_time - available_server) > logr->max_time_reconnect_try) { /* Sending information to see if server replies */ if(logr->sock != -1) { send_win32_info(cu_time); } sleep(wi); cu_time = time(0); if(wi < 20) { wi++; } else { global_sleep++; } /* If we have more than one server, try all. */ if(wi > 12 && logr->rip[1]) { int curr_rip = logr->rip_id; merror("%s: INFO: Trying next server ip in " "line: '%s'.", ARGV0, logr->rip[logr->rip_id + 1] != NULL? logr->rip[logr->rip_id + 1]: logr->rip[0]); connect_server(logr->rip_id +1); if(logr->rip_id != curr_rip) { wi = 1; } } else if(global_sleep == 2 || ((global_sleep % mod_sleep) == 0) || (logr->sock == -1)) { connect_server(logr->rip_id +1); if(logr->sock == -1) { sleep(wi + global_sleep); } else { sleep(global_sleep); } if(global_sleep > 30) { mod_sleep = 50; } } } verbose(AG_CONNECTED, ARGV0, logr->rip[logr->rip_id], logr->port); verbose(SERVER_UP, ARGV0); } } } #else if(0) { } #endif /* Send notification */ else if((cu_time - __win32_curr_time) > (NOTIFY_TIME - 200)) { debug1("%s: DEBUG: Sending info to server (ctime2)...", ARGV0); send_win32_info(cu_time); } /* locmsg cannot have the C:, as we use it as delimiter */ pl = strchr(locmsg, ':'); if(pl) { /* Setting pl after the ":" if it exists. */ pl++; } else { pl = locmsg; } debug2("%s: DEBUG: Sending message to server: '%s'", ARGV0, message); snprintf(tmpstr,OS_MAXSTR,"%c:%s:%s", loc, pl, message); _ssize = CreateSecMSG(&keys, tmpstr, crypt_msg, 0); /* Returns NULL if can't create encrypted message */ if(_ssize == 0) { merror(SEC_ERROR,ARGV0); if(!ReleaseMutex(hMutex)) { merror("%s: Error releasing mutex.", ARGV0); } return(-1); } /* Send _ssize of crypt_msg */ if(OS_SendUDPbySize(logr->sock, _ssize, crypt_msg) < 0) { merror(SEND_ERROR,ARGV0, "server"); sleep(1); } if(!ReleaseMutex(hMutex)) { merror("%s: Error releasing mutex.", ARGV0); } return(0); }
/** int OS_Alert_SendSyslog * Sends an alert via syslog. * Returns 1 on success or 0 on error. */ int OS_Alert_SendSyslog(alert_data *al_data, SyslogConfig *syslog_config) { char *tstamp; char syslog_msg[OS_SIZE_2048]; /* These will be Malloc'd, so no need to predeclare size, just remember to free! */ char *json_safe_comment; char *json_safe_message; /* padding value */ int padding = 0; /* Invalid socket. */ if(syslog_config->socket < 0) { return(0); } /* Clearing the memory before insert */ memset(syslog_msg, '\0', OS_SIZE_2048); /* Looking if location is set */ if(syslog_config->location) { if(!OSMatch_Execute(al_data->location, strlen(al_data->location), syslog_config->location)) { return(0); } } /* Looking for the level */ if(syslog_config->level) { if(al_data->level < syslog_config->level) { return(0); } } /* Looking for rule id */ if(syslog_config->rule_id) { int id_i = 0; while(syslog_config->rule_id[id_i] != 0) { if(syslog_config->rule_id[id_i] == al_data->rule) { break; } id_i++; } /* If we found, id is going to be a valid rule */ if(!syslog_config->rule_id[id_i]) { return(0); } } /* Looking for the group */ if(syslog_config->group) { if(!OSMatch_Execute(al_data->group, strlen(al_data->group), syslog_config->group)) { return(0); } } /* Fixing the timestamp to be syslog compatible. * We have 2008 Jul 10 10:11:23 * Should be: Jul 10 10:11:23 */ tstamp = al_data->date; if(strlen(al_data->date) > 14) { tstamp+=5; /* Fixing first digit if the day is < 10 */ if(tstamp[4] == '0') tstamp[4] = ' '; } /* Remove the double quotes from "dangerous" fields */ if( (json_safe_comment = os_strip_char(al_data->comment, '"')) == NULL ) { return(0); } if( (json_safe_message = os_strip_char(al_data->log[0], '"')) == NULL ) { return(0); } /* Inserting data */ if(syslog_config->format == DEFAULT_CSYSLOG) { /* Building syslog message. */ snprintf(syslog_msg, OS_SIZE_2048, "<%d>%s %s ossec: Alert Level: %d; Rule: %d - %s; Location: %s;", syslog_config->priority, tstamp, __shost, al_data->level, al_data->rule, al_data->comment, al_data->location ); field_add_string(syslog_msg, OS_SIZE_2048, " srcip: %s;", al_data->srcip ); #ifdef GEOIP field_add_string(syslog_msg, OS_SIZE_2048, " srccity: %s;", al_data->geoipdatasrc ); field_add_string(syslog_msg, OS_SIZE_2048, " dstcity: %s;", al_data->geoipdatadst ); #endif field_add_string(syslog_msg, OS_SIZE_2048, " dstip: %s;", al_data->dstip ); field_add_string(syslog_msg, OS_SIZE_2048, " user: %s;", al_data->user ); field_add_string(syslog_msg, OS_SIZE_2048, " Previous MD5: %s;", al_data->old_md5 ); field_add_string(syslog_msg, OS_SIZE_2048, " Current MD5: %s;", al_data->new_md5 ); field_add_string(syslog_msg, OS_SIZE_2048, " Previous SHA1: %s;", al_data->old_sha1 ); field_add_string(syslog_msg, OS_SIZE_2048, " Current SHA1: %s;", al_data->new_sha1 ); field_add_truncated(syslog_msg, OS_SIZE_2048, " %s", al_data->log[0], 2 ); } else if(syslog_config->format == CEF_CSYSLOG) { snprintf(syslog_msg, OS_SIZE_2048, "<%d>%s CEF:0|%s|%s|%s|%d|%s|%d|dvc=%s cs2=%s cs2Label=Location", syslog_config->priority, tstamp, __author, __ossec_name, __version, al_data->rule, al_data->comment, (al_data->level > 10) ? 10 : al_data->level, __shost, al_data->location); field_add_string(syslog_msg, OS_SIZE_2048, " src=%s", al_data->srcip ); #ifdef GEOIP field_add_string(syslog_msg, OS_SIZE_2048, " cs3Label=SrcCity cs3=%s", al_data->geoipdatasrc ); field_add_string(syslog_msg, OS_SIZE_2048, " cs4Label=DstCity cs4=%s", al_data->geoipdatadst ); #endif field_add_string(syslog_msg, OS_SIZE_2048, " suser=%s", al_data->user ); field_add_string(syslog_msg, OS_SIZE_2048, " dst=%s", al_data->dstip ); field_add_truncated(syslog_msg, OS_SIZE_2048, " msg=%s", al_data->log[0], 2 ); if (al_data->new_md5 && al_data->new_sha1) { field_add_string(syslog_msg, OS_SIZE_2048, " Previous MD5: %s", al_data->old_md5 ); field_add_string(syslog_msg, OS_SIZE_2048, " Current MD5: %s", al_data->new_md5 ); field_add_string(syslog_msg, OS_SIZE_2048, " Previous SHA1: %s", al_data->old_sha1 ); field_add_string(syslog_msg, OS_SIZE_2048, " Current SHA1: %s", al_data->new_sha1 ); } } else if(syslog_config->format == JSON_CSYSLOG) { // Padding is two to make sure we can fit closign bracket padding = 2; /* Build a JSON Object for logging */ snprintf(syslog_msg, OS_SIZE_2048 - padding, "<%d>%s %s ossec: { \"crit\": %d, \"id\": %d, \"description\": \"%s\", \"component\": \"%s\",", /* syslog header */ syslog_config->priority, tstamp, __shost, /* OSSEC metadata */ al_data->level, al_data->rule, json_safe_comment, al_data->location ); /* Event specifics */ field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"classification\": \"%s\",", al_data->group ); if( field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"src_ip\": \"%s\",", al_data->srcip ) > 0 ) field_add_int(syslog_msg, OS_SIZE_2048 - padding, " \"src_port\": %d,", al_data->srcport ); #ifdef GEOIP field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"src_city\": \"%s\",", al_data->geoipdatasrc ); field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"dst_city\": \"%s\",", al_data->geoipdatadst ); #endif if ( field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"dst_ip\": \"%s\",", al_data->dstip ) > 0 ) field_add_int(syslog_msg, OS_SIZE_2048 - padding, " \"dst_port\": %d,", al_data->dstport ); field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"file\": \"%s\",", al_data->filename ); field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"acct\": \"%s\",", al_data->user ); field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"md5_old\": \"%s\",", al_data->old_md5 ); field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"md5_new\": \"%s\",", al_data->new_md5 ); field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"sha1_old\": \"%s\",", al_data->old_sha1 ); field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"sha1_new\": \"%s\",", al_data->new_sha1 ); /* Message */ field_add_truncated(syslog_msg, OS_SIZE_2048 - padding, " \"message\": \"%s\"", json_safe_message, 2 ); /* Closing brace */ field_add_string(syslog_msg, OS_SIZE_2048, " }", "" ); } else if(syslog_config->format == SPLUNK_CSYSLOG) { /* Build a Splunk Style Key/Value string for logging */ snprintf(syslog_msg, OS_SIZE_2048, "<%d>%s %s ossec: crit=%d id=%d description=\"%s\" component=\"%s\",", /* syslog header */ syslog_config->priority, tstamp, __shost, /* OSSEC metadata */ al_data->level, al_data->rule, json_safe_comment, al_data->location ); /* Event specifics */ field_add_string(syslog_msg, OS_SIZE_2048, " classification=\"%s\",", al_data->group ); if( field_add_string(syslog_msg, OS_SIZE_2048, " src_ip=\"%s\",", al_data->srcip ) > 0 ) field_add_int(syslog_msg, OS_SIZE_2048, " src_port=%d,", al_data->srcport ); #ifdef GEOIP field_add_string(syslog_msg, OS_SIZE_2048, " src_city=\"%s\",", al_data->geoipdatasrc ); field_add_string(syslog_msg, OS_SIZE_2048, " dst_city=\"%s\",", al_data->geoipdatadst ); #endif if( field_add_string(syslog_msg, OS_SIZE_2048, " dst_ip=\"%s\",", al_data->dstip ) > 0 ) field_add_int(syslog_msg, OS_SIZE_2048, " dst_port=%d,", al_data->dstport ); field_add_string(syslog_msg, OS_SIZE_2048, " file=\"%s\",", al_data->filename ); field_add_string(syslog_msg, OS_SIZE_2048, " acct=\"%s\",", al_data->user ); field_add_string(syslog_msg, OS_SIZE_2048, " md5_old=\"%s\",", al_data->old_md5 ); field_add_string(syslog_msg, OS_SIZE_2048, " md5_new=\"%s\",", al_data->new_md5 ); field_add_string(syslog_msg, OS_SIZE_2048, " sha1_old=\"%s\",", al_data->old_sha1 ); field_add_string(syslog_msg, OS_SIZE_2048, " sha1_new=\"%s\",", al_data->new_sha1 ); /* Message */ field_add_truncated(syslog_msg, OS_SIZE_2048, " message=\"%s\"", json_safe_message, 2 ); } OS_SendUDPbySize(syslog_config->socket, strlen(syslog_msg), syslog_msg); /* Free the malloc'd variables */ free(json_safe_comment); free(json_safe_message); return(1); }
/* Send an alert via syslog * Returns 1 on success or 0 on error */ int OS_Alert_SendSyslog(alert_data *al_data, const SyslogConfig *syslog_config) { char *tstamp; char *hostname; char syslog_msg[OS_SIZE_2048]; /* Invalid socket */ if (syslog_config->socket < 0) { return (0); } /* Clear the memory before insert */ memset(syslog_msg, '\0', OS_SIZE_2048); /* Look if location is set */ if (syslog_config->location) { if (!OSMatch_Execute(al_data->location, strlen(al_data->location), syslog_config->location)) { return (0); } } /* Look for the level */ if (syslog_config->level) { if (al_data->level < syslog_config->level) { return (0); } } /* Look for rule id */ if (syslog_config->rule_id) { int id_i = 0; while (syslog_config->rule_id[id_i] != 0) { if (syslog_config->rule_id[id_i] == al_data->rule) { break; } id_i++; } /* If we found, id is going to be a valid rule */ if (!syslog_config->rule_id[id_i]) { return (0); } } /* Look for the group */ if (syslog_config->group) { if (!OSMatch_Execute(al_data->group, strlen(al_data->group), syslog_config->group)) { return (0); } } /* Fix the timestamp to be syslog compatible * We have 2008 Jul 10 10:11:23 * Should be: Jul 10 10:11:23 */ tstamp = al_data->date; if (strlen(al_data->date) > 14) { tstamp += 5; /* Fix first digit if the day is < 10 */ if (tstamp[4] == '0') { tstamp[4] = ' '; } } if (syslog_config->use_fqdn) { hostname = __shost_long; } else { hostname = __shost; } /* Insert data */ if (syslog_config->format == DEFAULT_CSYSLOG) { /* Build syslog message */ snprintf(syslog_msg, OS_SIZE_2048, "<%u>%s %s ossec: Alert Level: %u; Rule: %u - %s; Location: %s;", syslog_config->priority, tstamp, hostname, al_data->level, al_data->rule, al_data->comment, al_data->location ); field_add_string(syslog_msg, OS_SIZE_2048, " classification: %s;", al_data->group ); field_add_string(syslog_msg, OS_SIZE_2048, " srcip: %s;", al_data->srcip ); #ifdef LIBGEOIP_ENABLED field_add_string(syslog_msg, OS_SIZE_2048, " srccity: %s;", al_data->srcgeoip ); field_add_string(syslog_msg, OS_SIZE_2048, " dstcity: %s;", al_data->dstgeoip ); #endif field_add_string(syslog_msg, OS_SIZE_2048, " dstip: %s;", al_data->dstip ); field_add_string(syslog_msg, OS_SIZE_2048, " user: %s;", al_data->user ); field_add_string(syslog_msg, OS_SIZE_2048, " Previous MD5: %s;", al_data->old_md5 ); field_add_string(syslog_msg, OS_SIZE_2048, " Current MD5: %s;", al_data->new_md5 ); field_add_string(syslog_msg, OS_SIZE_2048, " Previous SHA1: %s;", al_data->old_sha1 ); field_add_string(syslog_msg, OS_SIZE_2048, " Current SHA1: %s;", al_data->new_sha1 ); /* "9/19/2016 - Sivakumar Nellurandi - parsing additions" */ field_add_string(syslog_msg, OS_SIZE_2048, " Size changed: from %s;", al_data->file_size ); field_add_string(syslog_msg, OS_SIZE_2048, " User ownership: was %s;", al_data->owner_chg ); field_add_string(syslog_msg, OS_SIZE_2048, " Group ownership: was %s;", al_data->group_chg ); field_add_string(syslog_msg, OS_SIZE_2048, " Permissions changed: from %s;", al_data->perm_chg ); /* "9/19/2016 - Sivakumar Nellurandi - parsing additions" */ field_add_truncated(syslog_msg, OS_SIZE_2048, " %s", al_data->log[0], 2 ); } else if (syslog_config->format == CEF_CSYSLOG) { snprintf(syslog_msg, OS_SIZE_2048, "<%u>%s CEF:0|%s|%s|%s|%u|%s|%u|dvc=%s cs1=%s cs1Label=Location", syslog_config->priority, tstamp, __author, __ossec_name, __version, al_data->rule, al_data->comment, (al_data->level > 10) ? 10 : al_data->level, hostname, al_data->location); field_add_string(syslog_msg, OS_SIZE_2048, " classification=%s", al_data->group ); field_add_string(syslog_msg, OS_SIZE_2048, " src=%s", al_data->srcip ); field_add_int(syslog_msg, OS_SIZE_2048, " dpt=%d", al_data->dstport ); field_add_int(syslog_msg, OS_SIZE_2048, " spt=%d", al_data->srcport ); field_add_string(syslog_msg, OS_SIZE_2048, " fname=%s", al_data->filename ); field_add_string(syslog_msg, OS_SIZE_2048, " dhost=%s", al_data->dstip ); field_add_string(syslog_msg, OS_SIZE_2048, " shost=%s", al_data->srcip ); field_add_string(syslog_msg, OS_SIZE_2048, " suser=%s", al_data->user ); field_add_string(syslog_msg, OS_SIZE_2048, " dst=%s", al_data->dstip ); #ifdef LIBGEOIP_ENABLED field_add_string(syslog_msg, OS_SIZE_2048, " cs4Label=SrcCity cs4=%s", al_data->srcgeoip ); field_add_string(syslog_msg, OS_SIZE_2048, " cs5Label=DstCity cs5=%s", al_data->dstgeoip ); #endif field_add_string(syslog_msg, OS_SIZE_2048, " suser=%s", al_data->user ); field_add_string(syslog_msg, OS_SIZE_2048, " dst=%s", al_data->dstip ); field_add_truncated(syslog_msg, OS_SIZE_2048, " msg=%s", al_data->log[0], 2 ); if (al_data->new_md5 && al_data->new_sha1) { field_add_string(syslog_msg, OS_SIZE_2048, " cs2Label=OldMD5 cs2=%s", al_data->old_md5); field_add_string(syslog_msg, OS_SIZE_2048, " cs3Label=NewMD5 cs3=%s", al_data->new_md5); field_add_string(syslog_msg, OS_SIZE_2048, " oldFileHash=%s", al_data->old_sha1 ); field_add_string(syslog_msg, OS_SIZE_2048, " fhash=%s", al_data->new_sha1 ); field_add_string(syslog_msg, OS_SIZE_2048, " fileHash=%s", al_data->new_sha1 ); } } else if (syslog_config->format == JSON_CSYSLOG) { /* Build a JSON Object for logging */ cJSON *root; char *json_string; root = cJSON_CreateObject(); /* Data guaranteed to be there */ cJSON_AddNumberToObject(root, "crit", al_data->level); cJSON_AddNumberToObject(root, "id", al_data->rule); cJSON_AddStringToObject(root, "component", al_data->location); /* Rule Meta Data */ if (al_data->group) { cJSON_AddStringToObject(root, "classification", al_data->group); } if (al_data->comment) { cJSON_AddStringToObject(root, "description", al_data->comment); } /* Raw log message generating event */ if (al_data->log && al_data->log[0]) { cJSON_AddStringToObject(root, "message", al_data->log[0]); } /* Add data if it exists */ if (al_data->user) { cJSON_AddStringToObject(root, "acct", al_data->user); } if (al_data->srcip) { cJSON_AddStringToObject(root, "src_ip", al_data->srcip); } if (al_data->srcport) { cJSON_AddNumberToObject(root, "src_port", al_data->srcport); } if (al_data->dstip) { cJSON_AddStringToObject(root, "dst_ip", al_data->dstip); } if (al_data->dstport) { cJSON_AddNumberToObject(root, "dst_port", al_data->dstport); } if (al_data->filename) { cJSON_AddStringToObject(root, "file", al_data->filename); } if (al_data->old_md5) { cJSON_AddStringToObject(root, "md5_old", al_data->old_md5); } if (al_data->new_md5) { cJSON_AddStringToObject(root, "md5_new", al_data->new_md5); } if (al_data->old_sha1) { cJSON_AddStringToObject(root, "sha1_old", al_data->old_sha1); } if (al_data->new_sha1) { cJSON_AddStringToObject(root, "sha1_new", al_data->new_sha1); } #ifdef LIBGEOIP_ENABLED if (al_data->srcgeoip) { cJSON_AddStringToObject(root, "src_city", al_data->srcgeoip); } if (al_data->dstgeoip) { cJSON_AddStringToObject(root, "dst_city", al_data->dstgeoip); } #endif /* Create the JSON string */ json_string = cJSON_PrintUnformatted(root); /* Create the syslog message */ snprintf(syslog_msg, OS_SIZE_2048, "<%u>%s %s ossec: %s", /* syslog header */ syslog_config->priority, tstamp, hostname, /* JSON Encoded Data */ json_string ); /* Clean up the memory for the JSON structure */ free(json_string); cJSON_Delete(root); } else if (syslog_config->format == SPLUNK_CSYSLOG) { /* Build a Splunk Style Key/Value string for logging */ snprintf(syslog_msg, OS_SIZE_2048, "<%u>%s %s ossec: crit=%u id=%u description=\"%s\" component=\"%s\",", /* syslog header */ syslog_config->priority, tstamp, hostname, /* OSSEC metadata */ al_data->level, al_data->rule, al_data->comment, al_data->location ); /* Event specifics */ field_add_string(syslog_msg, OS_SIZE_2048, " classification=\"%s\",", al_data->group ); if ( field_add_string(syslog_msg, OS_SIZE_2048, " src_ip=\"%s\",", al_data->srcip ) > 0 ) { field_add_int(syslog_msg, OS_SIZE_2048, " src_port=%d,", al_data->srcport ); } #ifdef LIBGEOIP_ENABLED field_add_string(syslog_msg, OS_SIZE_2048, " src_city=\"%s\",", al_data->srcgeoip ); field_add_string(syslog_msg, OS_SIZE_2048, " dst_city=\"%s\",", al_data->dstgeoip ); #endif if ( field_add_string(syslog_msg, OS_SIZE_2048, " dst_ip=\"%s\",", al_data->dstip ) > 0 ) { field_add_int(syslog_msg, OS_SIZE_2048, " dst_port=%d,", al_data->dstport ); } field_add_string(syslog_msg, OS_SIZE_2048, " file=\"%s\",", al_data->filename ); field_add_string(syslog_msg, OS_SIZE_2048, " acct=\"%s\",", al_data->user ); field_add_string(syslog_msg, OS_SIZE_2048, " md5_old=\"%s\",", al_data->old_md5 ); field_add_string(syslog_msg, OS_SIZE_2048, " md5_new=\"%s\",", al_data->new_md5 ); field_add_string(syslog_msg, OS_SIZE_2048, " sha1_old=\"%s\",", al_data->old_sha1 ); field_add_string(syslog_msg, OS_SIZE_2048, " sha1_new=\"%s\",", al_data->new_sha1 ); /* Message */ field_add_truncated(syslog_msg, OS_SIZE_2048, " message=\"%s\"", al_data->log[0], 2 ); } OS_SendUDPbySize(syslog_config->socket, strlen(syslog_msg), syslog_msg); return (1); }