diff -ruN barnyard-0.2.0/etc/barnyard.conf barnyard-0.2.0-cef/etc/barnyard.conf --- barnyard-0.2.0/etc/barnyard.conf 2004-05-01 11:43:29.000000000 -0500 +++ barnyard-0.2.0-cef/etc/barnyard.conf 2008-01-31 20:01:40.000000000 -0600 @@ -137,3 +137,10 @@ +# alert_cef +#------------------------------- +# Generates an ArcSight CEF syslog alert. +# Details at: http://www.arcsight.com/solutions_cef.htm +# +# output alert_cef: facility LOCAL4, severity ALERT, \ +# syslog_host localhost, syslog_port 514 diff -ruN barnyard-0.2.0/src/output-plugins/Makefile.am barnyard-0.2.0-cef/src/output-plugins/Makefile.am --- barnyard-0.2.0/src/output-plugins/Makefile.am 2004-03-27 18:10:31.000000000 -0600 +++ barnyard-0.2.0-cef/src/output-plugins/Makefile.am 2008-01-31 20:01:40.000000000 -0600 @@ -7,6 +7,7 @@ op_alert_csv.c op_alert_csv.h \ op_sguil.c op_sguil.h \ op_alert_syslog2.c op_alert_syslog2.h \ -op_alert_console.c op_alert_console.h +op_alert_console.c op_alert_console.h \ +op_alert_cef.c op_alert_cef.h INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src @extra_incl@ diff -ruN barnyard-0.2.0/src/output-plugins/Makefile.in barnyard-0.2.0-cef/src/output-plugins/Makefile.in --- barnyard-0.2.0/src/output-plugins/Makefile.in 2004-05-01 11:52:16.000000000 -0500 +++ barnyard-0.2.0-cef/src/output-plugins/Makefile.in 2008-01-31 20:01:40.000000000 -0600 @@ -71,7 +71,7 @@ AUTOMAKE_OPTIONS = foreign no-dependencies noinst_LIBRARIES = libop.a -libop_a_SOURCES = op_decode.c op_fast.c op_plugbase.c op_logdump.c op_decode.h op_fast.h op_plugbase.h op_logdump.h op_alert_syslog.c op_alert_syslog.h op_log_pcap.c op_log_pcap.h op_acid_db.c op_acid_db.h op_alert_csv.c op_alert_csv.h op_sguil.c op_sguil.h op_alert_syslog2.c op_alert_syslog2.h op_alert_console.c op_alert_console.h +libop_a_SOURCES = op_decode.c op_fast.c op_plugbase.c op_logdump.c op_decode.h op_fast.h op_plugbase.h op_logdump.h op_alert_syslog.c op_alert_syslog.h op_log_pcap.c op_log_pcap.h op_acid_db.c op_acid_db.h op_alert_csv.c op_alert_csv.h op_sguil.c op_sguil.h op_alert_syslog2.c op_alert_syslog2.h op_alert_console.c op_alert_console.h op_alert_cef.c op_alert_cef.h INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src @extra_incl@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs @@ -87,7 +87,7 @@ libop_a_LIBADD = libop_a_OBJECTS = op_decode.o op_fast.o op_plugbase.o op_logdump.o \ op_alert_syslog.o op_log_pcap.o op_acid_db.o op_alert_csv.o op_sguil.o \ -op_alert_syslog2.o op_alert_console.o +op_alert_syslog2.o op_alert_console.o op_alert_cef.o AR = ar CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) diff -ruN barnyard-0.2.0/src/output-plugins/op_alert_cef.c barnyard-0.2.0-cef/src/output-plugins/op_alert_cef.c --- barnyard-0.2.0/src/output-plugins/op_alert_cef.c 1969-12-31 18:00:00.000000000 -0600 +++ barnyard-0.2.0-cef/src/output-plugins/op_alert_cef.c 2008-01-31 20:05:20.000000000 -0600 @@ -0,0 +1,668 @@ +/* +** Copyright (C) 2008 Colin Grady +** Copyright (C) 2003 Sourcefire, Inc. (www.sourcefire.com) +** Copyright (C) 2001-2002 Andrew R. Baker +** +** This program is distributed under the terms of version 1.0 of the +** Q Public License. See LICENSE.QPL for further details. +** +** 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. +** +** Author(s): Colin Grady +** +** Based on op_alert_syslog2.c +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +extern int h_errno; +#include +#include + +#include "output-plugins/op_plugbase.h" +#include "util.h" +#include "barnyard.h" +#include "input-plugins/dp_alert.h" +#include "mstring.h" +#include "classification.h" +#include "sid.h" + +#define MODULE_NAME "alert_cef" + +typedef struct _OpAlertCef_Data +{ + /* Runtime configuration */ + char *message_buffer; + int header_length; + int month_offset; + int timestamp_offset; + int socket; + struct sockaddr_in sin; + u_int8_t priority; + + /* Configuration arguments */ + char *hostname; + char *syslog_host; + int facility; + int severity; + int syslog_port; +} OpAlertCef_Data; + +#define MESSAGE_LENGTH 1024 +#define MONTH_LENGTH 3 +#define TIMESTAMP_LENGTH 11 + +/* Message Template: + * + * xxx xx xx:xx:xx xxxxxxxx xxxxx[xxxxx]: + * + * template len - the length of the template + * month offset - the offset where the month begins + * month length - the length of bytes for the month + * timestamp offset - the offset where the timestamp begins + * timestamp length - the length of bytes for the timestamp + * msg offset + */ + +/* Values to use for the month portion of the message. We cannot use + * strftime for this + */ +char *cef_month_values[] = +{ + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec" +}; + +/* Plugin entry functions */ +static int OpAlertCef_Setup(OutputPlugin *, char *args); +static int OpAlertCef_Exit(OutputPlugin *); +static int OpAlertCef_Start(OutputPlugin *, void *); +static int OpAlertCef_Stop(OutputPlugin *); +static int OpAlertCef(void *, void *); +static int OpAlertCef_LogConfig(OutputPlugin *); + +static OpAlertCef_Data *OpAlertCef_ParseArgs(char *args); + +static int IsValidHostname(char *hostname); + +struct cef_keyword_value +{ + char *keyword; + int value; +}; + +struct cef_keyword_value cef_facility_map[] = +{ + { "KERN", 0 }, + { "USER", 1 }, + { "MAIL", 2 }, + { "DAEMON", 3 }, + { "AUTH", 4 }, + { "SYSLOG", 5 }, + { "LPR", 6 }, + { "NEWS", 7 }, + { "UUCP", 8 }, + { "CRON", 9 }, + { "AUTHPRIV", 10 }, + { "FTP", 11 }, + { "NTP", 12 }, + { "AUDIT", 13 }, + { "ALERT", 14 }, + { "CLOCK", 15 }, + { "LOCAL0", 16 }, + { "LOCAL1", 17 }, + { "LOCAL2", 18 }, + { "LOCAL3", 19 }, + { "LOCAL4", 20 }, + { "LOCAL5", 21 }, + { "LOCAL6", 22 }, + { "LOCAL7", 23 }, + { NULL, -1 } +}; + +#define DEFAULT_FACILITY 23 +#define MAX_FACILITY 23 + +struct cef_keyword_value cef_severity_map[] = +{ + { "EMERG", 0 }, + { "ALERT", 1 }, + { "CRIT", 2 }, + { "ERROR", 3 }, + { "WARN", 4 }, + { "NOTICE", 5 }, + { "INFO", 6 }, + { "DEBUG", 7 }, + { NULL, -1 } +}; + +#define DEFAULT_SEVERITY 5 +#define MAX_SEVERITY 7 + +#define DEFAULT_SYSLOG_PORT 514 +#define DEFAULT_SYSLOG_HOST "localhost" + +/* init routine makes this processor available for dataprocessor directives */ +void OpAlertCef_Init() +{ + OutputPlugin *outputPlugin; + + /* Register the output plugin */ + outputPlugin = RegisterOutputPlugin(MODULE_NAME, "alert"); + + /* Set the functions */ + outputPlugin->setupFunc = OpAlertCef_Setup; + outputPlugin->exitFunc = OpAlertCef_Exit; + outputPlugin->startFunc = OpAlertCef_Start; + outputPlugin->stopFunc = OpAlertCef_Stop; + outputPlugin->outputFunc = OpAlertCef; + outputPlugin->logConfigFunc = OpAlertCef_LogConfig; +} + +static int OpAlertCef_LogConfig(OutputPlugin *outputPlugin) +{ + OpAlertCef_Data *data = NULL; + + if(!outputPlugin || !outputPlugin->data) + return -1; + + data = (OpAlertCef_Data *)outputPlugin->data; + + LogMessage("OpAlertCef configured\n"); + LogMessage(" Syslog Host/Port: %s:%u/udp\n", data->syslog_host, + data->syslog_port); + LogMessage(" Syslog Facility: %s(%i)\n", cef_facility_map[data->facility], + data->facility); + LogMessage(" Syslog Severity: %s(%i)\n", cef_severity_map[data->severity], + data->severity); + LogMessage(" Hostname: %s\n", data->hostname); + + return 0; +} + +/* Instantiate the output plugin */ +static int OpAlertCef_Setup(OutputPlugin *outputPlugin, char *args) +{ + /* setup the run time context for this output plugin */ + if(!(outputPlugin->data = OpAlertCef_ParseArgs(args))) + { + FatalError("Failed to setup %s output plugin\n", MODULE_NAME); + return -1; /* XXX Eventually we will look at these result codes */ + } + + return 0; +} + +/* Destructor function */ +static int OpAlertCef_Exit(OutputPlugin *outputPlugin) +{ + OpAlertCef_Data *data = (OpAlertCef_Data *)outputPlugin->data; + + /* free that context data */ + if(data) + { + if(data->message_buffer) + free(data->message_buffer); + data->message_buffer = NULL; + + if(data->hostname) + free(data->hostname); + data->hostname = NULL; + + if(data->syslog_host) + free(data->syslog_host); + data->syslog_host = NULL; + + free(data); + } + data = NULL; + outputPlugin->data = NULL; + + return 0; +} + +/* Start function */ +static int OpAlertCef_Start(OutputPlugin *outputPlugin, void *spool_header) +{ + OpAlertCef_Data *data = (OpAlertCef_Data *)outputPlugin->data; + struct hostent *host_entry = NULL; + + if(data == NULL) + FatalError("ERROR: Unable to find context for %s\n", MODULE_NAME); + + if(pv.verbose >= 2) + OpAlertCef_LogConfig(outputPlugin); + + + /* Lookup the remote host */ + if(inet_aton(data->syslog_host, &data->sin.sin_addr) == 0) + { + if(!(host_entry = gethostbyname(data->syslog_host))) + FatalError("%s: Unable to lookup remote host '%s': %s\n", + MODULE_NAME, data->syslog_host, hstrerror(h_errno)); + memcpy(&data->sin.sin_addr, host_entry->h_addr, + sizeof(data->sin.sin_addr)); + } + data->sin.sin_family = AF_INET; + data->sin.sin_port = htons(data->syslog_port); + + /* open a socket to the remote syslog host */ + if((data->socket = socket(PF_INET, SOCK_DGRAM, 0)) == -1) + FatalError("%s: Unable to create socket: %s\n", MODULE_NAME, + strerror(errno)); + + return 0; +} + + +/* Stop function */ +static int OpAlertCef_Stop(OutputPlugin *outputPlugin) +{ + OpAlertCef_Data *data = (OpAlertCef_Data *)outputPlugin->data; + + if(data == NULL) + FatalError("ERROR: Unable to find context for %s\n", MODULE_NAME); + + /* close the socket */ + if(data->socket != -1) + close(data->socket); + data->socket = -1; + + return 0; +} + + +/* output function */ +static int OpAlertCef(void *context, void *data) +{ + UnifiedAlertRecord *record; + OpAlertCef_Data *op_data; + struct tm *tm; + char src[16]; + char dest[16]; + ClassType *class_type = NULL; + Sid *sid = NULL; + int length; + int rval; + int severity; + + + if(!data || !context) + return -1; + + record = (UnifiedAlertRecord *)data; + op_data = (OpAlertCef_Data *)context; + + sid = GetSid(record->event.sig_generator, record->event.sig_id); + class_type = GetClassType(record->event.classification); + + /* convert alert timestamp to struct tm using gmtime */ + if(pv.localtime) + tm = localtime(&record->ts.tv_sec); + else + tm = gmtime(&record->ts.tv_sec); + +/* + * + * Example CEF message: + * Sep 19 08:26:10 zurich CEF:0|security|threatmanager|1.0|100|worm successfully stopped|10|src=10.0.0.1 dst=2.1.2.2 spt=1232 + * + * Notice the lack of a tag and PID after the hostname. + * + */ + + memcpy(op_data->message_buffer + op_data->month_offset, + cef_month_values[tm->tm_mon], MONTH_LENGTH); + + strftime(op_data->message_buffer + op_data->timestamp_offset, + TIMESTAMP_LENGTH + 1, "%e %H:%M:%S", tm); + + op_data->message_buffer[op_data->timestamp_offset + TIMESTAMP_LENGTH] = ' '; + + + snprintf(src, 16, "%u.%u.%u.%u", (record->sip & 0xff000000) >> 24, + (record->sip & 0x00ff0000) >> 16, (record->sip & 0x0000ff00) >> 8, + record->sip & 0x000000ff); + snprintf(dest, 16, "%u.%u.%u.%u", (record->dip & 0xff000000) >> 24, + (record->dip & 0x00ff0000) >> 16, (record->dip & 0x0000ff00) >> 8, + record->dip & 0x000000ff); + + + severity = abs(0 - 11 + record->event.priority); + if(severity < 0) + severity = 0; + else if(severity > 10) + severity = 10; + + switch(record->protocol) + { + case IPPROTO_TCP: + case IPPROTO_UDP: + length = snprintf(op_data->message_buffer + op_data->header_length, + MESSAGE_LENGTH - op_data->header_length, + "CEF:0|snort|barnyard|%s|%d:%d:%d|%s|%d|src=%s dst=%s spt=%d dpt=%d proto=%s", + VERSION, record->event.sig_generator, record->event.sig_id, + record->event.sig_rev, sid != NULL ? sid->msg : "ALERT", severity, + src, dest, record->sp, record->dp, protocol_names[record->protocol]); + break; + default: + length = snprintf(op_data->message_buffer + op_data->header_length, + MESSAGE_LENGTH - op_data->header_length, + "CEF:0|snort|barnyard|%s|%d:%d:%d|%s|%d|src=%s dst=%s proto=%s", + VERSION, record->event.sig_generator, record->event.sig_id, + record->event.sig_rev, sid != NULL ? sid->msg : "ALERT", severity, + src, dest, protocol_names[record->protocol]); + break; + } + + if((rval = sendto(op_data->socket, op_data->message_buffer, + op_data->header_length + length, 0, + (struct sockaddr *)&op_data->sin, + sizeof(op_data->sin))) == -1) + LogMessage("%s: sendto error %u: %s\n", errno, strerror(errno)); + + return 0; +} + +/* initialize the output processor for this particular instantiation */ +OpAlertCef_Data *OpAlertCef_ParseArgs(char *args) +{ + OpAlertCef_Data *data; + char **toks; + int num_toks; + int i; + int header_length = -1; + char *index; + + if(pv.verbose) + LogMessage("Parsing %s arguments: %s\n", MODULE_NAME, args); + + if(!(data = (OpAlertCef_Data *)calloc(1, sizeof(OpAlertCef_Data)))) + { + FatalError("Out of memory creating %s configuration\n", MODULE_NAME); + return NULL; + } + data->facility = -1; + data->severity = -1; + data->socket = -1; + + if(args) + { + toks = mSplit(args, ",", 8, &num_toks, 0); + /* XXX error check */ + + for(i = 0; i < num_toks; i++) + { + char *token = toks[i]; + char **subtoks; + int num_subtoks; + long value; + StripWhitespace(&token); + if(*token == '\0') + continue; + /* split the token on ' ' */ + subtoks = mSplit(token, " ", 2, &num_subtoks, 0); + /* XXX error check */ + + if(strcasecmp("facility", subtoks[0]) == 0) + { + if(data->facility >= 0) + { + FatalError("%s: Multiple %s arguments\n", + MODULE_NAME, subtoks[0]); + } + /* Process facility Argument */ + if(num_subtoks != 2) + { + FatalError("%s: Invalid %s argument: %s\n", + MODULE_NAME, subtoks[0], subtoks[1]); + } + + if(String2Long(subtoks[1], &value) == 0) + { + if(value > MAX_FACILITY) + FatalError("%s: Invalid %s argument: %s\n" + MODULE_NAME, subtoks[0], subtoks[1]); + else + data->facility = value; + } + else + { + /* search for match in facility map */ + int j = 0; + while(cef_facility_map[j].keyword) + { + if(strcasecmp(cef_facility_map[j].keyword, subtoks[1]) == 0) + { + data->facility = cef_facility_map[j].value; + break; + } + j++; + } + if(data->facility < 0) + { + FatalError("%s: Invalid %s argument: %s\n", + MODULE_NAME, subtoks[0], subtoks[1]); + } + } + } + else if(strcasecmp("severity", subtoks[0]) == 0) + { + if(data->severity >= 0) + { + FatalError("%s: Multiple %s arguments\n", + MODULE_NAME, subtoks[0]); + } + /* Process severity Argument */ + if(num_subtoks != 2) + { + FatalError("%s: Invalid %s argument: %s\n", + MODULE_NAME, subtoks[0], subtoks[1]); + } + + if(String2Long(subtoks[1], &value) == 0) + { + if(value > MAX_FACILITY) + FatalError("%s: Invalid %s argument: %s\n" + MODULE_NAME, subtoks[0], subtoks[1]); + else + data->severity = value; + } + else + { + /* search for match in severity map */ + int j = 0; + while(cef_severity_map[j].keyword) + { + if(strcasecmp(cef_severity_map[j].keyword, subtoks[1]) == 0) + { + data->severity = cef_severity_map[j].value; + break; + } + j++; + } + if(data->severity < 0) + { + FatalError("%s: Invalid %s argument: %s\n", + MODULE_NAME, subtoks[0], subtoks[1]); + } + } + } + else if(strcasecmp("hostname", subtoks[0]) == 0) + { + if(data->hostname) + { + FatalError("%s: Multiple %s arguments\n", + MODULE_NAME, subtoks[0]); + } + /* Must be < 255 bytes and must contain only alphanumeric + * names and embedded '-'s */ + if(IsValidHostname(subtoks[1]) != 1) + FatalError("%s: %s argument is not a valid hostname: %s\n", + MODULE_NAME, subtoks[0], subtoks[1]); + + if(!(data->hostname = strdup(subtoks[1]))) + FatalError("%s: Out of memory processing config\n"); + } + else if(strcasecmp("syslog_host", subtoks[0]) == 0) + { + if(data->syslog_host) + { + FatalError("%s: Multiple %s arguments\n", + MODULE_NAME, subtoks[0]); + } + if(!(data->syslog_host = strdup(subtoks[1]))) + FatalError("%s: Out of memory processing config\n"); + } + else if(strcasecmp("syslog_port", subtoks[0]) == 0) + { + if(data->syslog_port > 0) + { + FatalError("%s: Multiple %s arguments\n", + MODULE_NAME, subtoks[0]); + } + if(String2Long(subtoks[1], &value) != 0) + FatalError("%s: Invalid %s argument: %s\n", + MODULE_NAME, subtoks[0], subtoks[1]); + + if(value < 1 || value > 65535) + FatalError("%s: Invalid %s argument: %s\n", + MODULE_NAME, subtoks[0], subtoks[1]); + + data->syslog_port = value; + + } + else + { + FatalError("%s: Unknown argument: %s\n", + MODULE_NAME, subtoks[0]); + } + + FreeToks(subtoks, num_subtoks); + } + + FreeToks(toks, num_toks); + } + + if(data->facility == -1) + data->facility = DEFAULT_FACILITY; + if(data->severity == -1) + data->severity = DEFAULT_SEVERITY; + if(!data->hostname) + { + char hostname[255]; + char *index; + if(gethostname(hostname, 255) != 0) + FatalError("%s: Unable to get hostname\n"); + /* since we may get a FQDN, munge the hostname */ + if((index = strchr(hostname, '.'))) + *index = '\0'; + + if(!(data->hostname = strdup(hostname))) + FatalError("%s: Out of memory processing config\n"); + } + if(!data->syslog_host) + { + if(!(data->syslog_host = strdup(DEFAULT_SYSLOG_HOST))) + FatalError("%s: Out of memory processing config\n"); + } + if(data->syslog_port == 0) + data->syslog_port = DEFAULT_SYSLOG_PORT; + + /* calculate the syslog priority */ + data->priority = data->facility * 8 + data->severity; + + /* allocate the message buffer */ + if(!(data->message_buffer = calloc(MESSAGE_LENGTH, sizeof(char)))) + FatalError("%s: Out of memory starting output plugin\n"); + + /* copy in the basic string */ + header_length = snprintf(data->message_buffer, MESSAGE_LENGTH, + "<%u>XXX XX XX:XX:XX %s ", + data->priority, data->hostname); + + if(header_length > MESSAGE_LENGTH) + FatalError("%s: Message header length is too long: %i\n", + header_length); + + data->header_length = header_length; + + if(!(index = strchr(data->message_buffer, '>'))) + FatalError("%s: Error calculating priority field length\n"); + + data->month_offset = index - data->message_buffer + 1; + data->timestamp_offset = data->month_offset + 4; + + + if(pv.verbose) + { + } + + return data; +} + +static int IsValidHostname(char *hostname) +{ + char *index; + int firstchar = 1; + int lastdash = 0; + + + if(!hostname) + return 0; + + if(strlen(hostname) > 254) + return 0; + + /* check characters */ + index = hostname; + while(*index) + { + if(!isalnum(*index)) + { + /* check for '-' */ + if(*index == '-') + { + if(firstchar) + return 0; + lastdash = 1; + } + else + return 0; + } + else + { + lastdash = 0; + firstchar = 0; + } + index++; + } + + if(firstchar || lastdash) + return 0; + + return 1; +} diff -ruN barnyard-0.2.0/src/output-plugins/op_alert_cef.h barnyard-0.2.0-cef/src/output-plugins/op_alert_cef.h --- barnyard-0.2.0/src/output-plugins/op_alert_cef.h 1969-12-31 18:00:00.000000000 -0600 +++ barnyard-0.2.0-cef/src/output-plugins/op_alert_cef.h 2008-01-31 20:01:40.000000000 -0600 @@ -0,0 +1,19 @@ +/* +** Copyright (C) 2008 Colin Grady +** Copyright (C) 2003 Sourcefire, Inc. (www.sourcefire.com) +** +** This program is distributed under the terms of version 1.0 of the +** Q Public License. See LICENSE.QPL for further details. +** +** 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. +** +*/ + +#ifndef __OP_ALERT_CEF_H__ +#define __OP_ALERT_CEF_H__ + +void OpAlertCef_Init(); + +#endif /* __OP_ALERT_CEF_H__ */ diff -ruN barnyard-0.2.0/src/output-plugins/op_plugbase.c barnyard-0.2.0-cef/src/output-plugins/op_plugbase.c --- barnyard-0.2.0/src/output-plugins/op_plugbase.c 2004-03-28 18:14:19.000000000 -0600 +++ barnyard-0.2.0-cef/src/output-plugins/op_plugbase.c 2008-01-31 20:01:40.000000000 -0600 @@ -33,6 +33,7 @@ #include "op_alert_csv.h" #include "op_alert_syslog2.h" #include "op_alert_console.h" +#include "op_alert_cef.h" /* ----------------------- Global Data --------------------------*/ OutputPluginListNode *outputPlugins = NULL; @@ -53,6 +54,7 @@ OpAlertCSV_Init(); OpAlertSyslog2_Init(); OpAlertConsole_Init(); + OpAlertCef_Init(); return; }