
/******************************************************************************
**
**  This program is free software; you can redistribute it and/or
**  modify it, however, you cannot sell it.
**
**  This program is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**
**  You should have received a copy of the license attached to the
**  use of this software.  If not, visit www.shmoo.com/osiris for
**  details.
**
******************************************************************************/

/*****************************************************************************
**
**  File:    osirisd.h
**  Date:    February 17, 2002
**
**  Author:  Brian Wotring
**  Purpose: scanning daemon options.
**
******************************************************************************/

#ifndef OSIRISD_H_
#define OSIRISD_H_

/* program version and name. */

#define PROGRAM_NAME     	    "osirisd"
#define PROGRAM_VERSION	        "2.0.0"
#define OSIRIS_USERNAME         "osiris"


/* paramaters for server process. */

#define LISTEN_QUEUE_MAX  5
#define SERVER_PORT       2265


/* exit codes for this daemon. */

#define EXIT_CODE_ERROR  -1
#define EXIT_CODE_NORMAL  0


/* flag for being daemon, used only for windows. */

osi_bool run_as_daemon = FALSE;


/* paramaters for logging. */

int log_level = LOG_LEVEL_DEFAULT;

#ifdef WIN32
HANDLE event_source     = NULL;
HANDLE stop_scan_event  = NULL;
#else

#define SYSLOG_FACILITY   LOG_DAEMON
#define SYSLOG_LEVEL      LOG_INFO

int SYSLOG_OPTIONS    = ( LOG_NDELAY | LOG_PID );
int SYSLOG_PRIORITY   = ( SYSLOG_FACILITY | SYSLOG_LEVEL );

#endif

/* paramaters for SSL */

#define OSIRISD_CIPHER_LIST               "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"
#define OSIRISD_SERVER_CERT_CHAIN_DEPTH   4
#define OSIRISD_SSL_OPTIONS               ( SSL_OP_ALL|SSL_OP_NO_SSLv2 )

#define HOST_SESSION_KEY_LENGTH	     	  64


/* macros for selecting on important sockets. */

#define INCOMING_SERVER_REQUEST()	( FD_ISSET( server_socket, &read_set ) )
#define INCOMING_CONFIG_REQUEST()	( FD_ISSET( config_socket, &read_set ) )


/* server state data. */

#ifdef WIN32
HANDLE scanning_thread_handle   = 0;
unsigned int scanning_pid       = 0;
#else
pid_t child_pid                 = 0;
pid_t root_pid                  = 0;
pid_t scanning_pid		        = 0;
#endif

/* platform specifics. */

char os_name[MAX_STATUS_OS_NAME_LENGTH] = "";
char os_version[MAX_STATUS_OS_VERSION_LENGTH] = "";

#ifdef WIN32
#define THREAD_FUNCTION_TYPE unsigned __stdcall
#define THREAD_FUNCTION_RETURN 0
#else
#define THREAD_FUNCTION_TYPE void
#define THREAD_FUNCTION_RETURN
#endif

/* default path and file for root cert, on windows we actually    */
/* issue an API call to get the right path, this is just a guess. */

#define ROOT_CERT_NAME			"osiris_root.pem"

#ifdef WIN32
char default_root_directory[MAX_PATH_LENGTH] = "\\WINNT\\osiris";
char root_cert_file[MAX_PATH_LENGTH]  = "\\WINNT\\osiris\\osiris_root.pem";
#else
char default_root_directory[MAX_PATH_LENGTH] = "/usr/local/osiris";
char root_cert_file[MAX_PATH_LENGTH]  = "/usr/local/osiris/osiris_root.pem";
#endif

#define ROOT_CERT_PERMISSIONS         0600


fd_set read_set;

/* SSL data. */

SSL_CTX *ssl_context    = NULL;
static BIO *bio_error   = NULL;


int server_socket 	    = 0;
int connection_socket	= 0;
int config_socket	    = 0;
int scan_data_socket	= 0;

#ifdef USE_PRIVSEP
int rootpriv_pipe[2];
int child_pipe[2];
int root_pipe[2];
#endif

SSL *connection_ssl	    = NULL;
SSL *config_ssl	        = NULL;
SSL *scan_data_ssl	    = NULL;

osi_bool save_peer_cert     = FALSE;
osi_bool have_session_key   = FALSE;

osi_bool cert_authentication_failed = FALSE;

unsigned char session_key[HOST_SESSION_KEY_LENGTH] = "\0";
int state = DAEMON_STATE_IDLE;

long start_time;
long current_time;
long config_time;

struct configuration *config = NULL;

/* signal flags. */

int received_sigint = 0;
int received_sigterm = 0;
int received_sigchld = 0;
int received_sigpipe = 0;
int received_sigkill = 0;

int scanner_terminated = 0;
int daemon_terminated = 0;

/* function prototypes. */

void set_platform_info();

THREAD_FUNCTION_TYPE run( void *unused );
void become_windows_service();

void initialize_root_path();
void initialize_priv_pipes();
void initialize_logger();
void initialize_winsock();

void fork_daemons();
void fork_scanning_process();

void initialize_signals();
void initialize_ssl();

void handle_sigint( int signal );
void handle_sigterm( int signal );
void handle_sigchld( int signal );
void handle_sigpipe( int signal );
void handle_sigkill( int signal );

void check_for_signals();
void cleanup_threads();

void start_server();
void close_logger();

void shutdown_server();
void shutdown_ssl();

THREAD_FUNCTION_TYPE run_scanner( void *unused );
void process();

void halt( int code );
osi_bool reset_config();

int ssl_verify_callback( int ok, X509_STORE_CTX *store );

void process_new_request();
void process_config_request();

/* message routines. */

int process_incoming_message( MESSAGE *message );
int process_outgoing_message( MESSAGE *message );

void start_scan();
void stop_scan();

void start_config_push( MESSAGE *message );
void stop_config_push( MESSAGE *message );

void wait_for_data();
void assume_connection_socket( int *new_socket );
void assume_ssl_connection( SSL **new_ssl_connection );

void issue_status_response();
void set_state( int new_state );
void drop_config();

void process_config_data( MESSAGE *message );
void perform_session_key_negotiation();

void parse_arguments( int argument_count, char *argument_list[] );
void print_usage();

#endif
