
/******************************************************************************
**
**  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:    osiris.h
**  Date:    April 8, 2002
**
**  Author:  Brian Wotring
**  Purpose: cli management application
**
******************************************************************************/

#ifndef OSIRIS_H_
#define OSIRIS_H_

#define PATH_TTY                    "/dev/tty" 

#ifdef WIN32
#define PATH_DEFAULT_EDITOR         "notepad.exe"
#define NAME_DEFAULT_EDITOR         ""
#else
#define PATH_DEFAULT_EDITOR         "/usr/bin/vi"
#define NAME_DEFAULT_EDITOR         "vi"
#endif

#define STDIN_FILENO                0
#define STDOUT_FILENO               1
#define STDERR_FILENO               2

#define PROMPT_USERNAME             "User: "
#define PROMPT_PASSWORD             "Password: "

#define MAX_COMMAND_LENGTH          1024
#define MAX_TOKEN_LENGTH            255

#define PROGRAM_NAME                "Osiris command line management utility"
#define PROGRAM_VERSION             "2.0.0"

#define COMMAND_NONE                   -1
#define COMMAND_UNKNOWN                 0
#define COMMAND_STATUS_REQUEST          1
#define COMMAND_START_SCAN              2
#define COMMAND_STOP_SCAN               3
#define COMMAND_PUSH_CONFIG             4
#define COMMAND_IMPORT_CONFIG           5
#define COMMAND_VERSION                 6
#define COMMAND_EXIT                    7
#define COMMAND_HELP                    8
#define COMMAND_HOST                    9
#define COMMAND_MANAGEMENT_HOST         10
#define COMMAND_LIST_HOSTS              11
#define COMMAND_LIST_CONFIGS            12
#define COMMAND_LIST_DATABASES          13
#define COMMAND_LIST_LOGS               14
#define COMMAND_PRINT_DB                15
#define COMMAND_PRINT_CONFIG            16
#define COMMAND_HOST_DETAILS            17
#define COMMAND_NEW_HOST                18
#define COMMAND_EDIT_HOST               19
#define COMMAND_DROP_CONFIG             20
#define COMMAND_PRINT_DB_ERRORS         21
#define COMMAND_PRINT_SSL               22
#define COMMAND_PRINT_HOST_CONFIG       23
#define COMMAND_PRINT_MANAGEMENT_CONFIG 24
#define COMMAND_SET_BASE_DB             25
#define COMMAND_SHOW_BASE_DB            26
#define COMMAND_WATCH_HOST              27
#define COMMAND_PRINT_LOG               28
#define COMMAND_ENABLE_HOST             29
#define COMMAND_DISABLE_HOST            30
#define COMMAND_EDIT_USER               31
#define COMMAND_NEW_USER                32
#define COMMAND_LIST_USERS              33
#define COMMAND_DELETE_USER             34
#define COMMAND_INITIALIZE_HOST         35
#define COMMAND_EDIT_MHOST_CONFIG       36
#define COMMAND_EDIT_CONFIG             37
#define COMMAND_EDIT_FILTERS            38
#define COMMAND_PRINT_FILTERS           39
#define COMMAND_SEND_NOTIFY_TEST        40

/* default paths and files for root cert.  We use the home directory */
/* of the current user as the default path for certs.                */

#define FILE_ROOT_CERT            "osiris_root.pem"

#ifdef WIN32

#define PATH_USER_DIR             ".osiris"
#define PATH_SYSTEM_DIR           "\\WINNT\\osiris"

#define PATH_SYSTEM_ROOT_CERT_FILE    PATH_SYSTEM_DIR "\\" FILE_ROOT_CERT

#else

#define PATH_USER_DIR             ".osiris"
#define PATH_SYSTEM_DIR           "/usr/local/osiris"

#define PATH_SYSTEM_ROOT_CERT_FILE    PATH_SYSTEM_DIR "/" FILE_ROOT_CERT

#endif

#define FILE_TEMP_CONFIG            "config.temp"

char root_cert_file[MAX_PATH_LENGTH]  = "";

char editor_path[MAX_PATH_LENGTH]     = "";
char editor_name[MAX_PATH_LENGTH]     = "";

#define ROOT_CERT_PERMISSIONS         0600

#define DEFAULT_SCAN_PERIOD_VALUE     1440

struct c_keywords
{
    char *word;
    int  type;
};


/* commands associated with their keywords, to add   */
/* an alias, just make sure it doesn't exist and     */
/* add it to this array with the appropriate command */
/* value ( e.g. hosts=list-hosts ).                  */

static struct c_keywords command_keywords[] =
{
    { "status", COMMAND_STATUS_REQUEST },
    { "start-scan", COMMAND_START_SCAN },
    { "scan-host", COMMAND_START_SCAN },
    { "scan", COMMAND_START_SCAN },
    { "stop-scan", COMMAND_STOP_SCAN },
    { "push-config", COMMAND_PUSH_CONFIG },
    { "import-config", COMMAND_IMPORT_CONFIG },
    { "edit-config", COMMAND_EDIT_CONFIG },

    { "modify-user", COMMAND_EDIT_USER },
    { "edit-user", COMMAND_EDIT_USER },
    { "password", COMMAND_EDIT_USER },
    { "passwd", COMMAND_EDIT_USER },

    { "new-user", COMMAND_NEW_USER },
    { "add-user", COMMAND_NEW_USER },

    { "initialize-host", COMMAND_INITIALIZE_HOST },
    { "init-host", COMMAND_INITIALIZE_HOST },
    { "init", COMMAND_INITIALIZE_HOST },

    { "delete-user", COMMAND_DELETE_USER },
    { "del-user", COMMAND_DELETE_USER },
    { "kill-user", COMMAND_DELETE_USER },
    { "whack-user", COMMAND_DELETE_USER },

    { "list-users", COMMAND_LIST_USERS },
    { "users", COMMAND_LIST_USERS },

    { "watch-host", COMMAND_WATCH_HOST },
    { "watch", COMMAND_WATCH_HOST },

    { "list-hosts", COMMAND_LIST_HOSTS },
    { "hosts", COMMAND_LIST_HOSTS },
    { "host-details", COMMAND_HOST_DETAILS },
    { "details", COMMAND_HOST_DETAILS },

    { "list-configs", COMMAND_LIST_CONFIGS },
    { "configs", COMMAND_LIST_CONFIGS },

    { "list-db", COMMAND_LIST_DATABASES },
    { "list-databases", COMMAND_LIST_DATABASES },
    { "databases", COMMAND_LIST_DATABASES },

    { "list-logs", COMMAND_LIST_LOGS },
    { "logs", COMMAND_LIST_LOGS },

    { "print-db", COMMAND_PRINT_DB },
    { "print-database", COMMAND_PRINT_DB },

    { "print-config", COMMAND_PRINT_CONFIG },
    { "print-cfg", COMMAND_PRINT_CONFIG },

    { "print-db-errors", COMMAND_PRINT_DB_ERRORS },
    { "print-database-errors", COMMAND_PRINT_DB_ERRORS },

    { "enable-host", COMMAND_ENABLE_HOST },
    { "enable", COMMAND_ENABLE_HOST },
    
    { "disable-host", COMMAND_DISABLE_HOST },
    { "disable", COMMAND_DISABLE_HOST },

    { "print-log", COMMAND_PRINT_LOG },
    
    { "print-host-config", COMMAND_PRINT_HOST_CONFIG },
    { "host-config", COMMAND_PRINT_HOST_CONFIG },
    
    { "print-mhost-config", COMMAND_PRINT_MANAGEMENT_CONFIG },
    { "mhost-config", COMMAND_PRINT_MANAGEMENT_CONFIG },

    { "edit-mhost-config", COMMAND_EDIT_MHOST_CONFIG },
    { "edit-mhost", COMMAND_EDIT_MHOST_CONFIG },

    { "edit-filters", COMMAND_EDIT_FILTERS },
    { "edit-filter", COMMAND_EDIT_FILTERS },
    { "new-filter", COMMAND_EDIT_FILTERS },

    { "print-filters", COMMAND_PRINT_FILTERS },
    { "filters", COMMAND_PRINT_FILTERS },
    { "print-filter", COMMAND_PRINT_FILTERS },

    { "test-notify", COMMAND_SEND_NOTIFY_TEST },

    { "print-ssl", COMMAND_PRINT_SSL },
    { "ssl", COMMAND_PRINT_SSL },

    { "host", COMMAND_HOST },
    { "mhost", COMMAND_MANAGEMENT_HOST },

    { "new-host", COMMAND_NEW_HOST },
    { "add-host", COMMAND_NEW_HOST },

    { "edit-host", COMMAND_EDIT_HOST },
    { "modify-host", COMMAND_EDIT_HOST },
    { "edit", COMMAND_EDIT_HOST },
    { "modify", COMMAND_EDIT_HOST },

    { "set-base-db", COMMAND_SET_BASE_DB },
    { "set-base-database", COMMAND_SET_BASE_DB },

    { "show-base-db", COMMAND_SHOW_BASE_DB },
    { "show-base-database", COMMAND_SHOW_BASE_DB },
    { "base-db", COMMAND_SHOW_BASE_DB },
    { "base-database", COMMAND_SHOW_BASE_DB },

    { "drop-config", COMMAND_DROP_CONFIG },

    { "help", COMMAND_HELP },
    { "h", COMMAND_HELP },
    { "?", COMMAND_HELP },

    { "version", COMMAND_VERSION },
    { "ver", COMMAND_VERSION },

    { "exit", COMMAND_EXIT },
    { "quit", COMMAND_EXIT },
    { "asta", COMMAND_EXIT },
    { "bye", COMMAND_EXIT },
    { "q", COMMAND_EXIT },

    { NULL, 0 }
};

CTL_CONTEXT ctl_context;

/* paramaters for SSL */

#define OSIRIS_CIPHER_LIST              "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"
#define OSIRIS_SERVER_CERT_CHAIN_DEPTH  4
#define OSIRIS_SSL_OPTIONS              ( SSL_OP_ALL|SSL_OP_NO_SSLv2 )


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


/* state variables. */

osi_bool continue_polling = FALSE;

unsigned int command      = COMMAND_NONE;
unsigned int help_command = COMMAND_NONE;

char current_user[MAX_AUTH_USERNAME_LENGTH] = "";
char name[MAX_COMMAND_LENGTH] = "";

char mhost[MAX_HOSTNAME_LENGTH] = "localhost";
char host[MAX_HOSTNAME_LENGTH]  = "";


/* function prototypes. */

void init();
void locate_editor();

void initialize_ssl();
void shutdown_ssl();

int ssl_verify_callback( int ok, X509_STORE_CTX *store );

void initialize_signals();
void signal_handler( int signal );

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

void locate_root_cert_file();

int get_user_input( char *buffer, int buffer_size );
int get_password_input( char *buffer, int buffer_size, char *prompt );

int read_and_parse_command();
int determine_command_type( const char *buffer );

osi_bool connect_to_management_host();
osi_bool disconnect_from_management_host();
osi_bool reconnect_to_management_host();
osi_bool get_peer_certificate();

void process_command();
void run_editor( const char *filepath );

void print_current_host();
void print_current_mhost();
void print_mhost_response( OSI_HELLO_RESPONSE *response );

void print_numbered_mhost_allow_list( OSI_MANAGEMENT_CONFIG *cfg );
void print_mhost_allow_list( OSI_MANAGEMENT_CONFIG *cfg );

void print_numbered_filter_list( osi_list filters );
void print_notify_filters_list( osi_list filters );

void print_prompt();
void print_version();
void print_usage();
void print_commands();
void print_ssl();

void prompt_for_new_host_information( CTL_CONTEXT *context );
void prompt_for_edit_host_information( CTL_CONTEXT *context );
void prompt_for_import_config_information( CTL_CONTEXT *context );
void prompt_for_config_information();
void prompt_for_set_base_db_information();
void prompt_for_scheduling_information( CTL_CONTEXT *context );
void prompt_for_edit_mhost_config_information( CTL_CONTEXT *context );
void prompt_for_notify_filter_information( CTL_CONTEXT *context );

void prompt_for_user_information();
void prompt_for_mhost_auth_information();

void print_command_usage( int command );
void halt( int code );

void process_quit();
void process_host();
void process_mhost();
void process_hello_mhost();
void process_status_request();
void process_new_user();
void process_edit_user();
void process_delete_user();
void process_list_users();
void process_start_scan();
void process_stop_scan();
void process_push_config();
void process_import_config();
void process_edit_config();
void process_list_hosts();
void process_list_configs();
void process_list_databases();
void process_list_logs();
void process_print_db();
void process_print_log();
void process_print_db_errors();
void process_print_config();
void process_print_host_config();
void process_print_mhost_config();
void process_edit_mhost_config();
void process_host_details();
void process_new_host();
void process_edit_host();
void process_enable_host();
void process_disable_host();
void process_initialize_host();
void process_drop_config();
void process_set_base_db();
void process_show_base_db();
void process_watch_host();
void process_edit_filters();
void process_print_filters();
void process_send_notify_test();
void process_help();


void print_context_error( CTL_CONTEXT *context );

void print_host_config( OSI_HOST_CONFIG *config );
void print_mhost_config( OSI_MANAGEMENT_CONFIG *config );

void print_host_brief( OSI_HOST_BRIEF *host );
void print_host_brief_expanded( OSI_HOST_BRIEF *host );
void print_host_brief_overview( OSI_HOST_BRIEF *host );

void print_config_brief( OSI_CONFIG_BRIEF *config );
void print_log_brief( OSI_LOG_BRIEF *log );

void print_log_file( string_list *log_data );

void print_database_brief( OSI_DATABASE_BRIEF *database );
void print_database_brief_expanded( OSI_DATABASE_BRIEF *database );

void print_status( OSI_STATUS *status );
void print_config( configuration *cfg );

osi_bool get_base_db_name_for_host( char *name, int name_length,
                                    const char *host );

#endif
