# Copyright (c) 2010 Flowerfire, Inc. All Rights Reserved. hurricane_mta = { plugin_version = "2.4" info.1.manufacturer = "SocketLabs" info.1.device = "Hurricane MTA" info.1.version.1 = "" # 2012-04-03 - 1.0 - MSG - Initial creation # 2013-05-21 - 2.0 - GMF - Enhanced to use collect/accept for standard mail server analysis (sender/recipient with messages processed/delivered). Added mail_server_reports. # 2013-06-07 - 2.1 - GMF - Added messages_failed and error_message # 2013-10-22 - 2.3 - MSG - Made leading > optional in Handle RCPT TO lines. # 2013-11-26 - 2.3 - GMF - Added parsing of response to HELO/EHLO, into the response_message field # 2014-06-03 - 2.4 - GMF - Keyed parsing of response to the message ID instead of requiring literal last line to be EHLO. # The name of the log format log.format.format_label = "Hurricane MTA" log.miscellaneous.log_data_type = "mail" log.miscellaneous.log_format_type = "mail_server" # The log is in this format if any of the first ten lines match this regular expression # log.format.autodetect_regular_expression = "^[0-9]?[0-9]/[0-9]?[0-9]/[0-9][0-9][0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]|[0-9a-f]+|[0-9.:]+" log.format.autodetect_regular_expression = "Hurricane Server" # Use comma as the field separator log.format.field_separator = "|" log.format.ignore_format_lines = "true" log.format.parse_only_with_filters = "true" # The format of dates and times in this log # log.format.date_format = "m/d/yyyy" # log.format.time_format = "hh:mm:ss" # Log fields log.fields = { date = "" time = "" connectionid.index = 2 ip.index = 3 data.index = 4 sender = "" recipient = "" error_message = "" response_message = "" messages_processed = "" messages_delivered = "" messages_failed = "" last_line_was_helo = "" } # log.fields # Database fields database.fields = { date_time = "" day_of_week = "" hour_of_day = "" # connectionid = "" ip = "" # data = "" sender = "" recipient = "" error_message = "" response_message = "" } # database.fields # log.filter_initialization = ` #bool last_line_was_helo = false; #` log.parsing_filters.parse = ` v.data = ''; if (matches_regular_expression(current_log_line(), '(^[0-9]?[0-9]/[0-9]?[0-9]/[0-9][0-9][0-9][0-9]) ([0-9][0-9]:[0-9][0-9]:[0-9][0-9])[|]([^|]+)[|]([^|]+)[|](.*)$')) then ( connectionid = $3; set_collected_field(connectionid, 'date', $1); set_collected_field(connectionid, 'time', $2); set_collected_field(connectionid, 'ip', $4); v.data = $5; ); # Remember the EHLO response in response_message (ThreadID:1297405). if (get_collected_field(connectionid, "last_line_was_helo") and matches_regular_expression(v.data, '^<(2[0-9][0-9].*)$')) then ( set_collected_field(connectionid, 'response_message', $1); ); if (matches_regular_expression(v.data, '^>[EH][HE]LO ')) then set_collected_field(connectionid, 'last_line_was_helo', true); # last_line_was_helo = true; else set_collected_field(connectionid, 'last_line_was_helo', false); # last_line_was_helo = false; while (matches_regular_expression(v.data, '^([^{]*)[{]CRLF[}](.*)$') or matches_regular_expression(v.data, '^(.+)()$')) ( v.line = $1; v.data = $2; # MAIL FROM if (matches_regular_expression(v.line, '^>[Mm][Aa][Ii][Ll] [Ff][Rr][Oo][Mm]:(.*)$')) then ( v.sender = $1; if (matches_regular_expression(v.sender, '^<([^>]+)>')) then v.sender = $1; set_collected_field(connectionid, 'sender', v.sender); set_collected_field(connectionid, 'messages_processed', 1); set_collected_field(connectionid, 'messages_delivered', 0); set_collected_field(connectionid, 'messages_failed', 0); accept_collected_entry(connectionid, true); ); # Handle RCPT TO else if (matches_regular_expression(v.line, '^>?[Rr][Cc][Pp][Tt] [Tt][Oo]:(.*)$')) then ( v.recipient = $1; if (matches_regular_expression(v.recipient, '^<([^>]+)>')) then v.recipient = $1; set_collected_field(connectionid, 'recipient', v.recipient); ); # Handle error lines else if (matches_regular_expression(v.line, '^<(4[0-9][0-9] .*)$')) then ( set_collected_field(connectionid, 'error_message', $1); set_collected_field(connectionid, 'messages_processed', 0); set_collected_field(connectionid, 'messages_delivered', 0); set_collected_field(connectionid, 'messages_failed', 1); accept_collected_entry(connectionid, true); ); # Handle delivery lines #5/21/2013 00:00:28|7b0000000663da|12.34.56.78:25|Message 7b00000005d499:-:- delivered.^M else if (matches_regular_expression(v.line, '^Message .* delivered')) then ( set_collected_field(connectionid, 'error_message', $1); set_collected_field(connectionid, 'messages_processed', 0); set_collected_field(connectionid, 'messages_delivered', 1); set_collected_field(connectionid, 'messages_failed', 0); accept_collected_entry(connectionid, true); ); ); # while lines ` # Log Filters log.filters = { # mark_entry = { # label = '$lang_admin.log_filters.mark_entry_label' # comment = '$lang_admin.log_filters.mark_entry_comment' # value = 'events = 1;' # } # mark_entry } # log.filters # log.field_options = { # # sessions_page_field = "target" # sessions_visitor_id_field = "c_ip" # sessions_event_field = "transfers" # sessions_id_field = "session_id" # # } # log.field_options database.numerical_fields = { messages_delivered.default = true messages_processed.default = true messages_failed.default = true } # database.numerical_fields create_profile_wizard_options = { # This shows which numerical fields are related to which non-numerical fields. database_field_associations = { # Virtual IP appears only in "flow" events, so it shouldn't be associated with "tunnel" fields error_message = { messages_failed = true } } # database_field_associations # How the reports should be grouped in the report menu report_groups = { date_time_group = "" } # report_groups snapons = { # Attach a mail_server_reports snapon mail_server_reports = { snapon = "mail_server_reports" name = "mail_server_reports" label = "$lang_admin.snapons.mail_server_reports.label" parameters = { sender_field.parameter_value = "sender" recipient_field.parameter_value = "recipient" messages_processed_field.parameter_value = "messages_processed" have_messages_delivered_field.parameter_value = true messages_delivered_field.parameter_value = "messages_delivered" } # parameters } # mail_server_reports # Add the standard reports add_standard_reports = { name = "add_standard_reports" label = "add_standard_reports" snapon = "add_standard_reports" } # add_standard_reports } # snapons } # create_profile_wizard_options } # hurricane_mta