Skip to content
This repository was archived by the owner on Dec 29, 2020. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
209 changes: 209 additions & 0 deletions fw1-loggrabber.c
Original file line number Diff line number Diff line change
Expand Up @@ -4676,6 +4676,10 @@ read_config_file (char *filename, configvalues * cfgvalues)
{
cfgvalues->log_mode = SYSLOG;
}
else if (string_icmp (configvalue, "tcp") == 0)
{
cfgvalues->log_mode = NETTCP;
}
else
{
fprintf (stderr,
Expand All @@ -4694,6 +4698,33 @@ read_config_file (char *filename, configvalues * cfgvalues)
cfgvalues->output_file_rotatesize =
atol (string_trim (configvalue, '"'));
}
else if (strcmp (configparameter, "OUTPUT_TCPLOG_HOST") == 0)
{
cfgvalues->output_tcp_host =
string_duplicate (string_trim (configvalue, '"'));
}
else if (strcmp (configparameter, "OUTPUT_TCPLOG_PORT") == 0)
{
cfgvalues->output_tcp_port =
atol (string_trim (configvalue, '"'));
}
else if (strcmp (configparameter, "OUTPUT_TCPLOG_RETRY_INTERVAL") == 0)
{
int cval = atol (string_trim (configvalue, '"'));
cfgvalues->output_tcp_retry_interval = cval;

if (cval < 1)
{
fprintf (stderr,
"WARNING: Illegal entry in configuration file: %s=%d\n",
configparameter, cval);
}
}
else if (strcmp (configparameter, "OUTPUT_TCPLOG_RETRY_ATTEMPTS") == 0)
{
cfgvalues->output_tcp_retry_attempts =
atol (string_trim (configvalue, '"'));
}
else if (strcmp (configparameter, "SYSLOG_FACILITY") == 0)
{
configvalue = string_duplicate (string_trim (configvalue, '"'));
Expand Down Expand Up @@ -4979,6 +5010,11 @@ logging_init_env (int logging)
submit_log = &submit_syslog;
close_log = &close_syslog;
break;
case NETTCP:
open_log = &open_tcplog;
submit_log = &submit_tcplog;
close_log = &close_tcplog;
break;
default:
open_log = &open_screen;
submit_log = &submit_screen;
Expand Down Expand Up @@ -5112,6 +5148,179 @@ close_screen ()
return;
}

/*
* tcplog initializations
*/
void
open_tcplog()
{
if (cfgvalues.debug_mode >= 2)
{
fprintf (stderr, "DEBUG: function open_tcplog\n");
}

if (cfgvalues.debug_mode)
{
fprintf (stderr, "DEBUG: Open connection to destination server.\n");
}

struct hostent *h_ent;
struct sockaddr_in dst_addr;

if ((h_ent = gethostbyname(cfgvalues.output_tcp_host)) == NULL)
{
perror("gethostbyname");
exit_loggrabber (1);
}

if ((output_tcpfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket");
exit_loggrabber (1);
}

dst_addr.sin_family = AF_INET;
dst_addr.sin_port = htons(cfgvalues.output_tcp_port);
dst_addr.sin_addr = *((struct in_addr *)h_ent->h_addr);
bzero(&(dst_addr.sin_zero), 8);
if (connect(output_tcpfd, (struct sockaddr *)&dst_addr, sizeof(struct sockaddr)) == -1)
{
perror("connect");
exit_loggrabber (1);
}
}

void
submit_tcplog (char *message)
{
if (cfgvalues.debug_mode >= 2)
{
fprintf (stderr, "DEBUG: function submit_tcplog\n");
}

if (cfgvalues.debug_mode)
{
fprintf (stderr, "DEBUG: Sending message to host.\n");
}

char *new_message = (char *)malloc(sizeof(char) * (strlen(message) + 2));
strcpy(new_message, message);
strcat(new_message, "\n");
if (send(output_tcpfd, new_message, strlen(new_message), MSG_NOSIGNAL) == -1)
{
int reconnect_success = 0;
if (cfgvalues.output_tcp_retry_attempts > 0)
{
// if there's a connection drop prior to send()'ing (e.g.; timeout) try to reconnect right away
// if the receiving system is restarting services we'll continue to retry for a time to recover
int max_tries = cfgvalues.output_tcp_retry_attempts;
int cur_tries = 0;
int wait_time = cfgvalues.output_tcp_retry_interval;
while (cur_tries < max_tries)
{
struct hostent *h_ent;
struct sockaddr_in dst_addr;

close(output_tcpfd);

if ((h_ent = gethostbyname(cfgvalues.output_tcp_host)) == NULL)
{
if (cfgvalues.debug_mode >= 2)
{
perror("gethostbyname");
}
exit_loggrabber (1);
}

if ((output_tcpfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
if (cfgvalues.debug_mode >= 2)
{
perror("socket");
}
exit_loggrabber (1);
}

dst_addr.sin_family = AF_INET;
dst_addr.sin_port = htons(cfgvalues.output_tcp_port);
dst_addr.sin_addr = *((struct in_addr *)h_ent->h_addr);
bzero(&(dst_addr.sin_zero), 8);
if ((connect(output_tcpfd, (struct sockaddr *)&dst_addr, sizeof(struct sockaddr))) == -1)
{
if (cfgvalues.debug_mode >= 2)
{
// log reconnect attempts but don't exit
perror("connect");
}
}
else
{
// connected! resend this message and continue as usual
if (send(output_tcpfd, new_message, strlen(new_message), MSG_NOSIGNAL) == -1)
{
if (cfgvalues.debug_mode >= 2)
{
// lost connection immediately after reconnect? time to quit
perror("send");
}
exit_loggrabber (1);
}

// successfully reconnected and sent message,
// set flag and exit while() and continue as usual
reconnect_success = 1;
break;
}
cur_tries++;
sleep(wait_time);
}

if (reconnect_success == 0)
{
fprintf (stderr, "ERROR: Failed to reconnect to host.\n");
}
}

if (reconnect_success == 0)
{
if (cfgvalues.debug_mode >= 2)
{
perror("send");
}
fprintf (stderr, "ERROR: Unable to send message to host, connection lost.\n");
exit_loggrabber (1);
}
}

// update cursor
int nbchar = write_fw1_cursorfile (message, cfgvalues.record_separator);
if (nbchar != (POSITION_MAX_SIZE + 1))
{
fprintf (stderr, "ERROR: Error when updating cursor.\n");
fprintf (stderr, "ERROR: %d characters written instead of %d.\n", nbchar, (POSITION_MAX_SIZE + 1));
exit_loggrabber (1);
}

free (new_message);
}

void
close_tcplog()
{
if (cfgvalues.debug_mode >= 2)
{
fprintf (stderr, "DEBUG: function close_tcplog\n");
}

if (cfgvalues.debug_mode)
{
fprintf (stderr, "DEBUG: Sending message to host.\n");
}

close(output_tcpfd);
output_tcpfd = 0;
}

/*
* log file initializations
*/
Expand Down
14 changes: 13 additions & 1 deletion fw1-loggrabber.conf
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ DATEFORMAT="std"
# IGNORE_FIELDS=<field1;field2;...>
#IGNORE_FIELDS="uuid;__policy_id_tag"

# LOGGING_CONFIGURATION=<screen|file|syslog>
# LOGGING_CONFIGURATION=<screen|file|syslog|tcp>
LOGGING_CONFIGURATION=screen

# OUTPUT_FILE_PREFIX=<Path and Name of outputfile>
Expand All @@ -42,6 +42,18 @@ OUTPUT_FILE_PREFIX="fw1-loggrabber"
OUTPUT_FILE_ROTATESIZE=0
# OUTPUT_FILE_ROTATESIZE=<maximum size of outputfile in bytes>

# if LOGGING_CONFIGURATION=tcp then make sure TCP Host and Port are set correctly
# TCP Host
OUTPUT_TCPLOG_HOST="127.0.0.1"

# TCP Port
OUTPUT_TCPLOG_PORT=5500

# TCP reconnect paramaters
# To disable retries set OUTPUT_TCPLOG_RETRY_INTERVAL=0
OUTPUT_TCPLOG_RETRY_INTERVAL=6
OUTPUT_TCPLOG_RETRY_ATTEMPTS=5

# SYSLOG_FACILITY=<USER|LOCAL0|...|LOCAL7>
SYSLOG_FACILITY="LOCAL1"

Expand Down
26 changes: 26 additions & 0 deletions fw1-loggrabber.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
#include <unistd.h>
#include <endian.h>
#include <syslog.h>
#include <sys/types.h>
#include <netdb.h>

/*
* OPSEC SDK related header files
Expand Down Expand Up @@ -79,6 +81,7 @@
#define SCREEN 0
#define LOGFILE 1
#define SYSLOG 2
#define NETTCP 3

#define INITIAL_CAPACITY 1024
#define CAPACITY_INCREMENT 4096
Expand Down Expand Up @@ -113,6 +116,10 @@ typedef struct configvalues
char *fw1_logfile;
char *output_file_prefix;
long output_file_rotatesize;
char *output_tcp_host;
int output_tcp_port;
int output_tcp_retry_interval;
int output_tcp_retry_attempts;
char *ignore_fields;
int dateformat;
int fw1_filter_count;
Expand Down Expand Up @@ -235,6 +242,13 @@ void read_config_file (char *, struct configvalues *);
*/
void logging_init_env (int);

/*
* client socket initializations
*/
void open_tcplog();
void submit_tcplog(char *);
void close_tcplog();

/*
* syslog initializations
*/
Expand Down Expand Up @@ -349,6 +363,9 @@ char **ignore_fields_array = NULL;
int ignore_attr_id_count = 0;
int ignore_attr_id_array[NUMBER_FIELDS] = { 0 };

// used when LOGFILESWAPON
int log_pointer_index = 1;

/*
* Holds the attribute ID for the "time" field from the ATTRIB_ID databases.
* The value is set in the read_fw1_logfile_dict function
Expand Down Expand Up @@ -400,6 +417,10 @@ configvalues cfgvalues = {
"fw.log", // fw1_logfile
"fw1-loggrabber", // output_file_prefix
1048576, // output_file_rotatesize
"127.0.0.1", // output_tcp_host
5500, // output_tcp_port
6, // output_tcp_retry_interval
5, // output_tcp_retry_attempts
NULL, // ignore_fields
DATETIME_STD, // dateformat
0, // fw1_filter_count
Expand All @@ -413,6 +434,11 @@ configvalues cfgvalues = {
**/
FILE *logstream;

/**
* file descriptor for tcp output
**/
int output_tcpfd = 0;

/**
* The flag, which is used to control whether or not fw1-loggrabber needs to exit
**/
Expand Down