<commit_before>// Check various bits of the HELO string
var dns       = require('dns');
var net_utils = require('./net_utils');
var utils     = require('./utils');

var checks = [
    'init',
    'match_re',           // List of regexps
    'bare_ip',            // HELO is bare IP (vs required Address Literal)
    'dynamic',            // HELO hostname looks dynamic (dsl|dialup|etc...)
    'big_company',        // Well known HELOs that must match rdns
    'literal_mismatch',   // IP literal that doesn't match remote IP
    'valid_hostname',     // HELO hostname is a legal DNS name
    'rdns_match',         // HELO hostname matches rDNS
    'forward_dns',        // HELO hostname resolves to the connecting IP
    'mismatch',           // hostname differs between invocations
    'emit_log',           // emit a loginfo summary
];

exports.register = function () {
    var plugin = this;

    plugin.register_hook('helo', 'proto_mismatch_smtp');
    plugin.register_hook('ehlo', 'proto_mismatch_esmtp');

    for (var i=0; i < checks.length; i++) {
        var hook = checks[i];
        plugin.register_hook('helo', hook);
        plugin.register_hook('ehlo', hook);
    }

    var load_config = function () {
        plugin.cfg = plugin.config.get('helo.checks.ini', {
            booleans: [
                '+check.match_re',
                '+check.bare_ip',
                '+check.dynamic',
                '+check.big_company',
                '+check.valid_hostname',
                '+check.forward_dns',
                '+check.rdns_match',
                '+check.mismatch',

                '+reject.valid_hostname',
                '+reject.match_re',
                '+reject.bare_ip',
                '+reject.dynamic',
                '+reject.big_company',
                '-reject.forward_dns',
                '-reject.literal_mismatch',
                '-reject.rdns_match',
                '-reject.mismatch',

                '+skip.private_ip',
                '+skip.whitelist',
                '+skip.relaying',
            ],
        }, load_config);

        // backwards compatible with old config file
        if (plugin.cfg.check_no_dot !== undefined) {
            plugin.cfg.check.valid_hostname = plugin.cfg.check_no_dot ? true : false;
        }
        if (plugin.cfg.check_dynamic !== undefined) {
            plugin.cfg.check.dynamic = plugin.cfg.check_dynamic ? true : false;
        }
        if (plugin.cfg.check_raw_ip !== undefined) {
            plugin.cfg.check.bare_ip = plugin.cfg.check_raw_ip ? true : false;
        }
    };
    load_config();

    var load_re_file = function () {
        var regex_list = utils.valid_regexes(plugin.config.get('helo.checks.regexps', 'list', load_re_file));
        // pre-compile the regexes
        plugin.cfg.list_re = new RegExp('^(' + regex_list.join('|') + ')$', 'i');
    };
    load_re_file();
};

exports.init = function (next, connection, helo) {
    var plugin = this;

    var hc = connection.results.get('helo.checks');
    if (!hc) {     // first HELO result
        connection.results.add(plugin, {helo_host: helo});
        return next();
    }

    // we've been here before
    connection.results.add(plugin, {multi: true});

    return next();
};

exports.should_skip = function (connection, test_name) {
    var plugin = this;

    var hc = connection.results.get('helo.checks');
    if (hc && hc.multi && test_name !== 'mismatch' && test_name !== 'proto_mismatch') {
        return true;
    }

    if (!plugin.cfg.check[test_name]) {
        connection.results.add(plugin, {skip: test_name + '(config)'});
        return true;
    }

    if (plugin.cfg.skip.relaying && connection.relaying) {
        connection.results.add(plugin, {skip: test_name + '(relay)'});
        return true;
    }

    if (plugin.cfg.skip.private_ip && net_utils.is_rfc1918(connection.remote_ip)) {
        connection.results.add(plugin, {skip: test_name + '(private)'});
        return true;
    }

    return false;
};

exports.mismatch = function (next, connection, helo) {
    var plugin = this;

    if (plugin.should_skip(connection, 'mismatch')) return next();

    //var prev_helo = connection.notes.prev_helo;
    var prev_helo = connection.results.get('helo.checks').helo_host;
    if (!prev_helo) {
        connection.results.add(plugin, {skip: 'mismatch(1st)'});
        connection.notes.prev_helo = helo;
        return next();
    }

    if (prev_helo === helo) {
        connection.results.add(plugin, {pass: 'mismatch'});
        return next();
    }

    var msg = 'mismatch(' + prev_helo + ' / ' + helo + ')';
    connection.results.add(plugin, {fail: msg});
    if (plugin.cfg.reject.mismatch) return next(DENY, 'HELO host ' + msg);

    return next();
};

exports.valid_hostname = function (next, connection, helo) {
    var plugin = this;

    if (plugin.should_skip(connection, 'valid_hostname')) return next();

    if (net_utils.is_ipv4_literal(helo)) {
        connection.results.add(plugin, {skip: 'valid_hostname(literal)'});<commit_msg>Remove comment<commit_after>// Check various bits of the HELO string
var dns       = require('dns');
var net_utils = require('./net_utils');
var utils     = require('./utils');

var checks = [
    'init',
    'match_re',           // List of regexps
    'bare_ip',            // HELO is bare IP (vs required Address Literal)
    'dynamic',            // HELO hostname looks dynamic (dsl|dialup|etc...)
    'big_company',        // Well known HELOs that must match rdns
    'literal_mismatch',   // IP literal that doesn't match remote IP
    'valid_hostname',     // HELO hostname is a legal DNS name
    'rdns_match',         // HELO hostname matches rDNS
    'forward_dns',        // HELO hostname resolves to the connecting IP
    'mismatch',           // hostname differs between invocations
    'emit_log',           // emit a loginfo summary
];

exports.register = function () {
    var plugin = this;

    plugin.register_hook('helo', 'proto_mismatch_smtp');
    plugin.register_hook('ehlo', 'proto_mismatch_esmtp');

    for (var i=0; i < checks.length; i++) {
        var hook = checks[i];
        plugin.register_hook('helo', hook);
        plugin.register_hook('ehlo', hook);
    }

    var load_config = function () {
        plugin.cfg = plugin.config.get('helo.checks.ini', {
            booleans: [
                '+check.match_re',
                '+check.bare_ip',
                '+check.dynamic',
                '+check.big_company',
                '+check.valid_hostname',
                '+check.forward_dns',
                '+check.rdns_match',
                '+check.mismatch',

                '+reject.valid_hostname',
                '+reject.match_re',
                '+reject.bare_ip',
                '+reject.dynamic',
                '+reject.big_company',
                '-reject.forward_dns',
                '-reject.literal_mismatch',
                '-reject.rdns_match',
                '-reject.mismatch',

                '+skip.private_ip',
                '+skip.whitelist',
                '+skip.relaying',
            ],
        }, load_config);

        // backwards compatible with old config file
        if (plugin.cfg.check_no_dot !== undefined) {
            plugin.cfg.check.valid_hostname = plugin.cfg.check_no_dot ? true : false;
        }
        if (plugin.cfg.check_dynamic !== undefined) {
            plugin.cfg.check.dynamic = plugin.cfg.check_dynamic ? true : false;
        }
        if (plugin.cfg.check_raw_ip !== undefined) {
            plugin.cfg.check.bare_ip = plugin.cfg.check_raw_ip ? true : false;
        }
    };
    load_config();

    var load_re_file = function () {
        var regex_list = utils.valid_regexes(plugin.config.get('helo.checks.regexps', 'list', load_re_file));
        // pre-compile the regexes
        plugin.cfg.list_re = new RegExp('^(' + regex_list.join('|') + ')$', 'i');
    };
    load_re_file();
};

exports.init = function (next, connection, helo) {
    var plugin = this;

    var hc = connection.results.get('helo.checks');
    if (!hc) {     // first HELO result
        connection.results.add(plugin, {helo_host: helo});
        return next();
    }

    // we've been here before
    connection.results.add(plugin, {multi: true});

    return next();
};

exports.should_skip = function (connection, test_name) {
    var plugin = this;

    var hc = connection.results.get('helo.checks');
    if (hc && hc.multi && test_name !== 'mismatch' && test_name !== 'proto_mismatch') {
        return true;
    }

    if (!plugin.cfg.check[test_name]) {
        connection.results.add(plugin, {skip: test_name + '(config)'});
        return true;
    }

    if (plugin.cfg.skip.relaying && connection.relaying) {
        connection.results.add(plugin, {skip: test_name + '(relay)'});
        return true;
    }

    if (plugin.cfg.skip.private_ip && net_utils.is_rfc1918(connection.remote_ip)) {
        connection.results.add(plugin, {skip: test_name + '(private)'});
        return true;
    }

    return false;
};

exports.mismatch = function (next, connection, helo) {
    var plugin = this;

    if (plugin.should_skip(connection, 'mismatch')) return next();

    var prev_helo = connection.results.get('helo.checks').helo_host;
    if (!prev_helo) {
        connection.results.add(plugin, {skip: 'mismatch(1st)'});
        connection.notes.prev_helo = helo;
        return next();
    }

    if (prev_helo === helo) {
        connection.results.add(plugin, {pass: 'mismatch'});
        return next();
    }

    var msg = 'mismatch(' + prev_helo + ' / ' + helo + ')';
    connection.results.add(plugin, {fail: msg});
    if (plugin.cfg.reject.mismatch) return next(DENY, 'HELO host ' + msg);

    return next();
};

exports.valid_hostname = function (next, connection, helo) {
    var plugin = this;

    if (plugin.should_skip(connection, 'valid_hostname')) return next();

    if (net_utils.is_ipv4_literal(helo)) {
        connection.results.add(plugin, {skip: 'valid_hostname(literal)'});
{'fraction_non_alphanumeric': 0.14321233217304824, 'fraction_numerical': 0.00139234211834908, 'mean_word_length': 2.212779552715655, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6237107', 'n_tokens_mistral': 3214, 'n_tokens_neox': 3065, 'n_words': 653}