haraka / Haraka

A fast, highly extensible, and event driven SMTP server
https://haraka.github.io
MIT License
4.95k stars 657 forks source link

Fix underscore issues in docs #1475

Closed baudehlo closed 7 years ago

baudehlo commented 8 years ago

Markdown treats underscore as emphasis ( in HTML). We don't escape it well enough in our .md files. We should fix that.

baudehlo commented 8 years ago

A basic search for the problems - note a LOT of these are probably false positives:

$ ack '[^\\]_' docs
docs/Config.md
30:See the [File Formats](#file_formats) section below for a more detailed
45:    cfg = plugin.config.get('my_plugin.ini', function () {
46:        // This closure will be run for each detected update of my_plugin.ini
53:exports.hook_connect = function (next, connection) {
60:* `no_watch` (default: false) - prevents Haraka from watching for updates.
61:* `no_cache` (default: false) - prevents Haraka from caching the file. This
83:that loads a `list` config from their own `config/plugin_name` file, can
84:be completely overridden by a file called `config/plugin_name` in your
87:Alternatively, a plugin using default config from `config/plugin_name.ini`
89:`plugin_name.ini` might contain:
99:And your local `plugin_name.ini` might contain:
122:<a name="file_formats">File Formats</a>
133:    first_name=Matt
134:    last_name=Sergeant
150:        first_name: 'Matt',
151:        last_name: 'Sergeant'
176:    { booleans: ['reject','some_true_value'] }
199:    hosts[] = first_host
200:    hosts[] = second_host
201:    hosts[] = third_host
205:    ['first_host', 'second_host', 'third_host']
277:var cfg = configfile.read_config('/path/to/file', type);
280:`read_config()` handles the caching for you and will return cached values
287:var cfg = configfile.read_config('/path/to/file', type, function() {

docs/CoreConfig.md
17:* log_timestamps
87:  Note also that each plugin can have a `config/<plugin_name>.timeout`
92:  in the equivalent path e.g. the queue/smtp_forward would need a timeout file in
93:  `config/queue/smtp_forward.timeout`
121:  `transaction.notes.data_line_length_exceeded` is set to `true`.
149:  to enable:   `echo 1 > /path/to/haraka/config/strict_rfc1869`
150:  to disable:  `echo 0 > /path/to/haraka/config/strict_rfc1869`

docs/CustomReturnCodes.md
38: return next(DENY, DSN.no_such_user());
83:  <td>addr_unspecified</td>
89:  <td>addr_bad_dest_mailbox</td>
95:  <td>addr_bad_dest_system</td>
101:  <td>addr_bad_dest_syntax</td>
107:  <td>addr_dest_ambigous</td>
113:  <td>addr_rcpt_ok</td>
119:  <td>addr_mbox_mobed</td>
125:  <td>addr_bad_from_syntax</td>
131:  <td>addr_bad_from_system</td>
140:  <td>mbox_unspecified</td>
146:  <td>mbox_disabled</td>
152:  <td>mbox_full</td>
158:  <td>mbox_msg_too_long</td>
164:  <td>mbox_list_expansion_problem</td>
173:  <td>sys_unspecified</td>
179:  <td>sys_disk_full</td>
185:  <td>sys_not_accepting_mail</td>
191:  <td>sys_not_supported</td>
197:  <td>sys_msg_too_big</td>
203:  <td>sys_incorrectly_configured</td>
212:  <td>net_unspecified</td>
218:  <td>net_no_answer</td>
224:  <td>net_bad_connection</td>
230:  <td>net_directory_server_failed</td>
236:  <td>net_unable_to_route</td>
242:  <td>net_system_congested</td>
248:  <td>net_routing_loop</td>
254:  <td>net_delivery_time_expired</td>
263:  <td>proto_unspecified</td>
269:  <td>proto_invalid_command</td>
275:  <td>proto_syntax_error</td>
281:  <td>proto_too_many_recipients</td>
287:  <td>proto_invalid_cmd_args</td>
293:  <td>proto_wrong_version</td>
302:  <td>media_unspecified</td>
308:  <td>media_unsupported</td>
314:  <td>media_conv_prohibited</td>
320:  <td>media_conv_unsupported</td>
326:  <td>media_conv_lossy</td>
332:  <td>media_conv_failed</td>
341:  <td>sec_unspecified</td>
347:  <td>sec_unauthorized</td>
353:  <td>sec_list_expn_prohibited</td>
359:  <td>sec_conv_failed</td>
365:  <td>sec_feature_unsupported</td>
371:  <td>sec_crypto_failure</td>
377:  <td>sec_crypto_algo_unsupported</td>
383:  <td>sec_msg_integrity_failure</td>
392:  <td>no_such_user</td>
398:  <td>temp_resolver_failed</td>
404:  <td>too_many_hops</td>
410:  <td>bad_sender_ip</td>
416:  <td>relaying_denied</td>

docs/HAProxy.md
14:To enable support for PROXY you must create a `haproxy_hosts` configuration
20:`haproxy_hosts` file - a banner is not sent, instead Haraka waits for the

docs/Header.md
31:`transaction.remove_header(key)` which will also correct the data part of
38:`transaction.add_header(key, value)` which will add the header to the data

docs/Net_Utils.md
8:    var net_utils = require('./net_utils');
10:### ip_to_long
13:    var long = net_utils.ip_to_long('11.22.33.44');  // 185999660
15:### long_to_ip
18:    var ip = net_utils.long_to_ip(185999660);  // 11.22.33.44
20:### dec_to_hex
23:    var hex = net_utils.dec_to_hex(20111104);  // 132df00
25:### hex_to_dec
28:    var dec = net_utils.hex_to_dec('132df00');  // 20111104
30:### is_local_ipv4
33:    net_utils.is_local_ipv4('127.0.0.200');   // true (localhost)
34:    net_utils.is_local_ipv4('169.254.0.0');   // true (link local)
35:    net_utils.is_local_ipv4('226.0.0.1');     // false
37:### is_private_ipv4
40:    net_utils.is_private_ipv4('10.0.0.0');       // true
41:    net_utils.is_private_ipv4('192.168.0.0');    // true
42:    net_utils.is_private_ipv4('172.16.0.0');     // true
44:### is_local_ipv6
47:    net_utils.is_local_ipv6('::1');           // true (localhost)
48:    net_utils.is_local_ipv6('fe80::')         // true (link local)
49:    net_utils.is_local_ipv6('fc00::')         // true (unique local)
50:    net_utils.is_local_ipv6('fd00::')         // true (unique local)
52:### is_private_ip
55:    // For IPv4, returns true if is_private_ipv4 or is_local_ipv4 are true
56:    // For IPv6, returns true if is_local_ipv6 is true

docs/Outbound.md
11:AUTH, and have the client authenticate. For example using the `auth/flat_file`
14:For statistics on outbound mail use the `process_title` plugin. See the
31:* `concurrency_max`
37:* `enable_tls`
42:This uses the same `tls_key.pem` and `tls_cert.pem` files that the `tls`
56:* `ipv6_enabled`
61:* `always_split`
65:session. When `always_split` is enabled, each recipient gets a queue entry and
69:* `received_header`
90:* num_failures - the number of times this mail has been temp failed
101:* rcpt_to - an Array of Address objects - the rfc.2821 recipients of this mail
102:* mail_from - an Address object - the rfc.2821 sender of this mail
103:* domain - the domain this mail is going to (see `always_split` above)
106:** outbound_ip - the IP address to bind to (note do not set this manually,
107:  use the `get_mx` hook)
108:** outbound_helo - the EHLO domain to use (again, do not set manually)
109:* queue_time - the epoch milliseconds time when this mail was queued
118:`queue_outbound` hook. Only if all these hooks return `CONT` (or if there are
130:Respond with `next(DELAY, delay_seconds)` to defer sending the email at this time.
136:Upon starting delivery the `get_mx` hook is called, with the parameter set to
138:`get_mx` hook with `(next, hmail, domain)` as parameters). This is to allow
154:       * `bind_helo` to specify an outbound helo for IP address to bind to
155:       * `using_lmtp` boolean to specify that delivery should be attempted using 
157:       *  `auth_user` to specify an AUTH username (required if AUTH is desired)
158:       *  `auth_pass` to specify an AUTH password (required if AUTH is desired)
159:       *  `auth_type` to specify an AUTH type that should be used with the MX.
174:If you want to change the delay, then call `next(DENYSOFT, delay_in_seconds)`.
176:`hmail.num_failures`.
188:* deferred_rcpt - the deferred recipients that eventually bounced
189:* bounced_rcpt - the bounced recipients
198:Params is a list of: `[host, ip, response, delay, port, mode, ok_recips, secured]`
212:* `ok_recips` - an Address array containing all of the recipients that were
228:and also the outbound helo for the IP can be set using the `bind_ehlo` 
229:parameter returned my the `get_mx` hook or during the reception of the message 
234:connection.transaction.notes.outbound_ip = '1.2.3.4';
235:connection.transaction.notes.outbound_helo = 'mail-2.example.com';
238:Note: if the `get_mx` hook returns a `bind` and `bind_helo` parameter, then
246:then you can use the `get_mx` hook documented above to do this by supplying
247:both `auth_user` and `auth_pass` properties in an MX object.
258:`config/outbound.bounce_message`. If you look at this file you will see it
310:    outbound.send_email(from, to, contents, outnext);
312:The callback on `send_email()` is passed `OK` if the mail is successfully
320:    outbound.send_email(from, to, contents);
326:```dot_stuffed: true``` option, like so:
328:    outbound.send_email(from, to, contents, outnext, { dot_stuffed: true });
331:In case you need notes in the new transaction that `send_email()` creates, you should pass the
334:    outbound.send_email(from, to, contents, outnext, { notes: transaction.notes });

docs/plugins/access.md
13:With **any**, just drop the offending domain name into the _access.domains_ file
17:The **any** blacklist matches only on the [Organizational Domain](#Organizational Domain) name (see NOTES below). Entries placed in the _access.domains_ file are automatically reduced to the OD. Examples:
24:_access.domains_ file with a ! prefix. Whitelist entries can be email addresses
80:add this section to _config/access.ini_:
122:    [deny_msg]

docs/plugins/auth/auth_bridge.md
8:This plugin is meant to be used with the plugin `queue/smtp_bridge`.
10:It is different than `auth/auth_proxy` because it doesn't require
19:Configuration is stored in `config/smtp_bridge.ini` and uses the INI
26:    #auth_type=
36:The options `auth_type` and `priority` will be used by `queue/smtp_bridge`

docs/plugins/auth/auth_ldap.md
4:The `auth/auth_ldap` plugin uses an LDAP bind to authenticate a user. Currently
11:Configuration is stored in `config/auth_ldap.ini` and uses the INI

docs/plugins/auth/auth_proxy.md
25:Configuration is stored in `config/auth_proxy.ini` and uses the INI

docs/plugins/auth/auth_vpopmaild.md
9:Configuration is stored in `config/auth_vpopmaild.ini` and uses INI

docs/plugins/auth/flat_file.md
4:The `auth/flat_file` plugin allows you to create a file containing username
20:Configuration is stored in `config/auth_flat_file.ini` and uses the INI

docs/plugins/avg.md
3:Implement virus scanning with AVG's TCPD daemon, available for Linux/FreeBSD. AVG linux is [free for personal or commercial use](http://www.avg.com/gb-en/faq.pnuid-faq_v3_linux) and can be downloaded from [free.avg.com](http://free.avg.com/gb-en/download.prd-alf).

docs/plugins/block_me.md
6:from address to the `mail_from.blocklist` config file.
16:* `config/block_me.recipient` - a file containing the address to email to
19:* `config/block_me.senders` - a file containing a list of email addresses

docs/plugins/bounce.md
13:    reject_all=false
14:    single_recipient=true
15:    empty_return_path=true
16:    bad_rcpt=true
17:    bounce_spf=true
18:    non_local_msgid=true
21:    single_recipient=true
22:    empty_return_path=true
23:    bounce_spf=false
24:    non_local_msgid=false
53:Disallow bounces to email addresses listed in `config/bounce_bad_rcpt`.

docs/plugins/clamd.md
113:!*.TestSig_*

docs/plugins/connect.asn.md
6:The AS Number is the [Autonomous System Number](http://en.wikipedia.org/wiki/Autonomous_System_(Internet))

docs/plugins/connect.fcrdns.md
21:        if (connection.results.has('connect.fcrdns', 'fail', /^is_generic/) {
44:    no_rdns=false
47:    no_fcrdns=false
50:    invalid_tld=false
55:    generic_rdns=false

docs/plugins/connect.geoip.md
49:be the IP that Haraka is bound to. If not, make sure that `utils.get_public_ip`
62:config/smtp.ini and set `public_ip`.
75:- [asn]report_as

docs/plugins/connect.p0f.md
7:This plugin inserts a _p0f_ connection note with information deduced
23:the _p0f_ connection note:
25:    magic, status, first_seen, last_seen, total_conn, uptime_min, up_mod_days, last_nat, last_chg, distance, bad_sw, os_match_q, os_name, os_flavor, http_name, http_flavor, link_type, and language.
36:    /usr/local/bin/p0f -u smtpd -d -s /tmp/.p0f_socket 'dst port 25 or dst port 587'
37:    chown smtpd /tmp/.p0f_socket

docs/plugins/data.headers.md
39:    date_future_days=2
40:    date_past_days=15
80:    duplicate_singular=true
81:    missing_required=true
82:    invalid_return_path=true
83:    invalid_date=true
84:    user_agent=true
85:    direct_to_mx=true
86:    from_match=true
87:    mailing_list=true
97:    missing_required=false

docs/plugins/dcc.md
20:`connection.transaction.notes.training_mode = 'spam'`

docs/plugins/dkim_sign.md
1:# `dkim_sign`
17:    ./dkim_key_gen.sh example.org
19:Peek into the `dkim_key_gen.sh` shell script to see the commands used to
34:    may2013._domainkey TXT "v=DKIM1;p=[public key stripped of whitespace];"
48:The default key size created by `dkim_key_gen.sh` is 2048. As of mid-2014, there are some DNS providers that do not support key sizes that long.
63:This plugin uses the configuration `dkim_sign.ini` in INI format.
95:        <selector>._domainkey.<domain>

docs/plugins/dkim_verify.md
1:dkim_verify

docs/plugins/dnsbl.md
56:    7) "AVG_RT"

docs/plugins/dnswl.md
61:    7) "AVG_RT"

docs/plugins/esets.md
7:and it will scan each message using the "esets_cli" command which defaults to
8:/opt/eset/esets/bin/esets_cli.

docs/plugins/greylist.md
9:The so-called _tuple_ consists of the following:
11:* First subdomain of rDNS is stripped off (but no shorter than the domain boundary). This is considered a _hostid_.
12:* Envelope sender is the _sender_.
13:* RCPT TO would supply the _recipient_.
15:_hostid_ in above notation is chosen unless:
28:* _black_:  between first connect and start of _gray_. Defer.
29:* _gray_:   between _black_ and start of _white_. Allow. Host must re-try within this window.
30:* _white_:  comes after _gray_. Allow up until the end of period, then let the record expire in case no connections were made
37:  * Party sends _recipient_
39:        * Check _tuple_ color (compare current TS against record creation TS)
40:            * _black_?
42:            * _gray_?
43:                * Allow. Promote record to _white_ status.
44:            * _white_?
46:  * In special case, _data_ hook runs above algo for all recipients. If any matched, all inherit the action.
58:For _white_:
60:    { first_connect: TS, whitelisted: TS, updated: TS, lifetime: TTL, tried: Integer, tried_when_greylisted: Integer }
63:    _first_connect_: TS of first connection (sender)
64:    _whitelisted_: basically the TS of this entry creation
65:    _updated_: last update TS
66:    _lifetime_: seconds for this entry to exist (== TTL)
67:    _tried_: number of checks against this entry
68:    _tried_when_greylisted_: number of checks while the host was +grey+ (sender).
70:For _grey_:
75:    _created_: TS of first connection (copied to _first_connect_ of _white_ after promotion)
76:    _updated_: last update TS
77:    _lifetime_: seconds for this entry to exist (== TTL)
78:    _tried_: number of checks against this entry (copied to _tried_when_greylisted_ of _white_ after promotion)

docs/plugins/helo.checks.md
20:    if (connection.results.has('helo.checks','pass', /^forward_dns/) {
104:    proto_mismatch=false
105:    rdns_match=false
107:    bare_ip=false
108:    literal_mismatch=false
109:    valid_hostname=false
110:    forward_dns=false
111:    big_company=false

docs/plugins/karma.md
20:Karma takes a holistic view of **connections**. During the connection, karma collects these results and applies the [result_awards](#awards) defined in `karma.ini`. Once a connection/message exceeds the threshold.negative score (default: -8), karma rejects it at the next [deny]hook.
97:* [IP Reputation](#IP_Reputation)
98:* [ASN reputation](#Neighbor_Reputation)
101:* [malformed envelope addresses](#malformed_env)
109:### <a name="IP_Reputation"></a>IP Reputation
126:If an IP has at least 5 connections and all are good or bad, and `all_good` or
127:`all_bad` result will be added to the `pass` or `fail` test list. This are
130:### <a name="Neighbor_Reputation"></a>ASN / Network Neighborhood Reputation
134:    report_as
143:Store the ASN results as another plugin. Example: I set `report_as=connect.asn`, so that karma history for an ASN is reported with the ASN plugin data. A practical consequence of changing report_as is that the award location in karma.ini would need to change from:
145:    NNN karma | pass | equals | asn_all_good |  2
146:    NNN karma | fail | equals | asn_all_bad  | -3
150:    NNN connect.asn | pass | equals | asn_all_good |  2
151:    NNN connect.asn | fail | equals | asn_all_bad  | -3
153:### <a name="malformed_env"></a>Malformed Envelope Addresses

docs/plugins/limit.md
9:When `[concurrency]max` is defined, it limits the maximum number of simultaneous connections per IP address. Connection attempts in excess of the limit are delayed for `disconnect_delay` seconds (default: 3) before being disconnected.
25:## unrecognized_commands
27:When `[unrecognized_commands]max` is set, a connection that exceeeds the limit is disconnected.
39:The unrecognized_command hook is used by the `tls` and `auth` plugins, so

docs/plugins/log.elasticsearch.md
33:By default, all plugin results are presented as `$plugin_name: { ... }`, at
35:object `$obj: { $plugin_name: { ...}`, set pluginObject to that object's key name
40:* [ignore_hosts]
66:curl -XPUT localhost:9200/_template/haraka_results -d '
71:            "dynamic_templates" : [
72:                { "fail_results" : {
75:                            "type" : "string", "index" : "not_analyzed"
79:                { "pass_results" : {
82:                            "type" : "string", "index" : "not_analyzed"
86:                { "skip_results" : {
89:                            "type" : "string", "index" : "not_analyzed"
93:                { "msg_results" : {
96:                            "type" : "string", "index" : "not_analyzed"
100:                { "err_results" : {
103:                            "type" : "string", "index" : "not_analyzed"
107:                { "ip_addrs" : {
115:                            "type" : "string", "index" : "not_analyzed"
125:                                "org" : { "type" : "string", "index" : "not_analyzed" },
126:                                "asn_good"        : { "type" : "double" },
127:                                "asn_bad"         : { "type" : "double" },
128:                                "asn_score"       : { "type" : "double" },
129:                                "asn_connections" : { "type" : "double" }
134:                                "org"      : { "type" : "string", "index" : "not_analyzed" },
135:                                "ll"       : { "type" : "geo_point" },
141:                                "ips"      : { "type" : "string", "index" : "not_analyzed" }
146:                                "fcrdns"    : { "type" : "string", "index" : "not_analyzed" },
147:                                "other_ips" : { "type" : "string", "index" : "not_analyzed" },
148:                                "ptr_names" : { "type" : "string", "index" : "not_analyzed" }
153:                                "os_flavor" : { "type" : "string", "index" : "not_analyzed" }
158:                                "emails"   : { "type" : "string", "index" : "not_analyzed" },
159:                                "urls"     : { "type" : "string", "index" : "not_analyzed" },
160:                                "messages" : { "type" : "string", "index" : "not_analyzed" }
171:                                "total_connects" : { "type" : "double" },
179:                                        "report" : { "type" : "string", "index" : "not_analyzed" },
180:                                        "Status" : { "type" : "string", "index" : "not_analyzed" }
183:                                "line0" : { "type" : "string", "index" : "not_analyzed" },
186:                                "tests" : { "type" : "string", "index" : "not_analyzed" }
191:                                "domain" : { "type" : "string", "index" : "not_analyzed" }
201:                                "sender" : { "type" : "string", "index" : "not_analyzed" },
204:                                        "action"  : { "type" : "string", "index" : "not_analyzed" },
205:                                        "address" : { "type" : "string", "index" : "not_analyzed" }
212:                                "from"         : { "type" : "string", "index" : "not_analyzed" },
213:                                "to"           : { "type" : "string", "index" : "not_analyzed" },
214:                                "subject"      : { "type" : "string", "index" : "not_analyzed" },
215:                                "message-id"   : { "type" : "string", "index" : "not_analyzed" },
216:                                "date"         : { "type" : "string", "index" : "not_analyzed" },
217:                                "reply-to"     : { "type" : "string", "index" : "not_analyzed" },
218:                                "resent-from"  : { "type" : "string", "index" : "not_analyzed" },
219:                                "resent-header": { "type" : "string", "index" : "not_analyzed" },
220:                                "sender"       : { "type" : "string", "index" : "not_analyzed" }
230:                                        "md5"   : { "type" : "string", "index": "not_analyzed" }

docs/plugins/max_unrecognized_commands.md
12:runs after any plugins that use the unrecognized_command hook to implement

docs/plugins/prevent_credential_leaks.md
24:file.  It should be added before any other plugins that run on hook_data_post

docs/plugins/queue/discard.md
9:It uses the 'queue' hook, so it runs after all the plugins that hook on `data_post`.

docs/plugins/queue/lmtp.md
11:    Syntax is equal to that used in the config of the queue/smtp_forward plugin.

docs/plugins/queue/qmail-queue.md
16:    * enable_outbound=true

docs/plugins/queue/quarantine.md
16:It uses the 'queue' hook, so that it runs after all the 'data_post' plugins
24:The temporary directory is 'quarantine_path/tmp' which defaults to: 
82:connection.notes.quarantine_action = [ OK, 'Message quarantined' ];
83:connection.transaction.notes.quarantine_action = [ DENY, 'Message rejected' ];
90:connection.notes.quarantine_action = OK;
91:connection.transaction.notes.quarantine_action = DENY;

docs/plugins/queue/rabbitmq.md
19:        server_ip = localhost
20:        server_port = 5672

docs/plugins/queue/rabbitmq_amqplib.md
1:queue/rabbitmq_amqplib
13:* `config/rabbitmq_amqplib.ini` - Connection, exchange and queue settings
25:     exchangeName  = email_messages

docs/plugins/queue/smtp_bridge.md
7:This plugin is meant to be used with the plugin `auth/auth_bridge`.
9:It is different than `queue/smtp_proxy` or `queue/smpt_forward` because
17:Configuration is stored in `config/smtp_bridge.ini` and uses the INI
24:    #auth_type=
33:* auth_type: default to empty and Haraka will try to pick an appropriate method.

docs/plugins/queue/smtp_forward.md
8:In comparison to `queue/smtp_proxy`, this plugin waits until queue time to
74:    # auth_type=plain
75:    # auth_user=user
76:    # auth_user=pass
80:    # auth_type=plain
81:    # auth_user=user
82:    # auth_pass=pass

docs/plugins/queue/smtp_proxy.md
8:In comparison to `queue/smtp_forward`, this plugin makes a connection at

docs/plugins/rcpt_to.ldap.md
1:# `rcpt_to.ldap.js`
7:configurable using the `config/rcpt_to.ldap.ini` file.
12:    present in `host_list`)

docs/plugins/rcpt_to.qmail_deliverable.md
15:altering the contents of `config/rcpt_to.qmail_deliverable.ini`
21:* `check_outbound`=true
23:When `check_outbound` is enabled, and a connection has relay privileges, the

docs/plugins/rcpt_to.routes.md
1:# `rcpt_to.routes`
8:`config/rcpt_to.routes.ini` or in Redis. If Redis is available, it is checked
28:addresses, you must set the preference `always_split=true` in
31:Each entry in the [routes] section of `config/rcpt_to.routes.ini` or in Redis
32:must specify a MX record. The MX record is the same format as _outbound.js_.
43:The following options can be specified in `config/rcpt_to.routes.ini`:

docs/plugins/record_envelope_addresses.md
1:record_envelope_addresses

docs/plugins/redis.md
41:    exports.results_init = function (next, connection) {
43:        plugin.redis_subscribe(connection, function () {
45:                plugin.do_something_with_message(message, ...);
51:    exports.hook_disconnect = function (next, connection) {
52:        this.redis_unsubscribe(connection);

docs/plugins/relay.md
3:[MTAs](http://en.wikipedia.org/wiki/Mail_transfer_agent) generally only accept mail for _local_ domains they can deliver to. In Haraka, the `rcpt_to.*` plugins usually decide which domains and/or email addresses are deliverable. By default, everything else is rejected.
5:**Relaying** is when a MTA accepts mail that is destined elsewhere. Back in the day (1980s), most MTAs permitted open relaying. Soon spammers abused our open relays (1990s) and left us with soiled mail queues. Now nearly all MTAs have relaying disabled and [MUAs](http://en.wikipedia.org/wiki/Mail_user_agent) are required to use a [MSA](http://en.wikipedia.org/wiki/Message_submission_agent) to relay. Most MTAs (including Haraka) have MSA features and can serve both purposes.
11:One way to enable relaying is [authentication](http://haraka.github.io/manual.html) via the auth plugins. Successful authentication enables relaying during _that_ SMTP connection. To securely offer SMTP AUTH, the [tls](http://haraka.github.io/manual/plugins/tls.html) plugin and at least one auth plugin must be enabled and properly configured. When that requirement is met, the AUTH SMTP extension will be advertised to SMTP clients.
27:    % openssl s_client -connect mail.example.com:587 -starttls smtp
42:To avoid port 25 restrictions, in 1998 we developed [SMTP submission](http://tools.ietf.org/html/rfc2476) on port 587. For optimal security and reliability, [MUAs](http://en.wikipedia.org/wiki/Mail_user_agent) should be configured to send mail to port 587 with TLS/SSL and AUTH enabled.
56:* `config/relay_acl_allow`
64:add IP allocations to `relay_acl_allow` like so:
66:    echo 'N.N.N.N/24' >> /path/to/haraka/config/relay_acl_allow
74:of the corporate firewall to `config/relay_acl_allow`:
76:    echo 'N.N.N.N/32' >> /path/to/haraka/config/relay_acl_allow
85:    force_routing=false  (default: false)
86:    dest_domains=false   (default: false)
90:* `config/relay_dest_domains.ini`
121:I think of *accept* as the equivalent of qmail's *rcpthosts*, or a misplaced Haraka `rcpt_to.*` plugin. The *accept* mechanism is another way to tell Haraka that a particular domain is one we accept mail for. The difference between this and and the [rcpt_to.in_host_list](http://haraka.github.io/manual/plugins/rcpt_to.in_host_list.html) plugin is that this one also enables relaying.

docs/plugins/relay_acl.md
10:* `config/relay_acl_allow`
15:* `config/relay_dest_domains.ini`

docs/plugins/relay_force_routing.md
10:* `config/relay_dest_domains.ini`

docs/plugins/reseed_rng.md
14:This plugin uses David Bao's reseed.js (see http://davidbau.com/archives/2010/01/30/random_seeds_coded_hints_and_quintillions.html)

docs/plugins/spamassassin.md
27:    1. `connection.transaction.notes.spamd_user` in another plugin.
29:    2. The special username: _first-recipient_. The first envelope recipient
32:    3. the special username _all-recipients_ may eventually be supported. See
33:       the get_spamd_username function in the plugin.
57:    If this is not set, then the `reject_thresold` value is used.
116:    add_header all Checker-Version SpamAssassin _VERSION_ (_SUBVERSION_) on _HOSTNAME_
117:    add_header spam Flag _YESNOCAPS_
118:    add_header all Level _STARS(\*)_
119:    add_header all Status "_YESNO_, score=_SCORE_ required=_REQD_ tests=_TESTS_ autolearn=_AUTOLEARN_ version=_VERSION_"
123:    add_header all DCC _DCCB_: _DCCR_
124:    add_header all Tests _TESTS_

docs/plugins/spf.md
5:See the [Wikipedia article on SPF](http://en.wikipedia.org/wiki/Sender_Policy_Framework) for details.
9:`[deny]helo_fail` and `[deny]mfrom_fail` are the closest match for the intent
49:* The only deny option most sites should consider is `mfrom_fail`. That will
58:    helo_temperror
59:    mfrom_temperror
62:    helo_softfail
63:    helo_fail
64:    helo_permerror
66:    mfrom_softfail
67:    mfrom_fail
68:    mfrom_permerror
71:    [defer_relay]
72:    helo_temperror
73:    mfrom_temperror
75:    [deny_relay]
76:    helo_softfail
77:    helo_fail
78:    helo_permerror
80:    mfrom_softfail
81:    mfrom_fail
82:    mfrom_permerror

docs/plugins/tls.md
9:    config/tls_key.pem
10:    config/tls_cert.pem
23:    cat mail.example.com.crt intermediary_cert.crt ca-cert.crt > config/tls_cert.pem
33:            -keyout config/tls_key.pem -out config/tls_cert.pem
43:### `no_tls_hosts`
48:    [no_tls_hosts]
78:using `smtp_forward`, `smtp_proxy` or plain outbound mail heading to
82:SMTP tls for queueing such as `smtp_proxy` and `smtp_forward` can

docs/plugins/xclient.md
4:Implements the [XCLIENT](http://www.postfix.org/XCLIENT_README.html) protocol.

docs/Plugins.md
25:Alternatively they can be npm-style node_modules in either the core node_modules
35:1. The `register_hook` function in register():
38:        this.register_hook('rcpt', 'my_rcpt_validate');
41:    exports.my_rcpt_validate = function (next, connection, params) {
46:2. The hook_[$name] syntax:
48:    exports.hook_rcpt = function (next, connection, params) {
55:To register the same hook more than once, call `register_hook()` multiple times with the same hook name:
58:        this.register_hook('queue', 'try_queue_my_way');
59:        this.register_hook('queue', 'try_queue_highway');
62:When `try_queue_my_way()` calls `next()`, the next function registered on hook *queue* will be called, in this case, `try_queue_highway()`.
70:        this.register_hook('rcpt',    'my_rcpt');
71:        this.register_hook('rcpt_ok', 'my_rcpt');
74:    exports.my_rcpt = function (next, connection, params) {
75:        var hook_name = connection.hook; // rcpt or rcpt_ok
116:    * connect_init and disconnect hooks are **always called**.
122:  HOOK_NEXT is only available on the `unrecognized_command` hook. It instructs Haraka to run a different plugin hook. The `msg` argument must be set to the name of the hook to be run. Ex: `next(HOOK_NEXT, 'rcpt_ok');`
131:* init_wss - called after init_http
158:* delivered (hmail, [host, ip, response, delay, port, mode, ok_recips, secured, authenticated]) - called when outbound mail is delivered
165:When **connection.relaying == false** (the default, to avoid being an open relay), a rcpt plugin MUST return `next(OK)` or the sender will receive the error message "I cannot deliver for that user". The default *rcpt* plugin  is **rcpt_to.in_host_list**, which lists the domains for which to accept email.
167:After a *rcpt* plugin calls `next(OK)`, the *rcpt_ok* hook is run.
171:### connect_init
173:The `connect_init` hook is unique in that all return codes are ignored. This is so that plugins that need to do initialization for every connection can be assured they will run. Return values are ignored.
175:### hook_init_http (next, Server)
179:### hook_init_wss (next, Server)
190:- hook_connect_init
191:- hook_lookup_rdns
192:- hook_connect
193:- hook_helo **OR** hook_ehlo (EHLO is sent when ESMTP is desired which allows extensions
195:    - hook_helo
196:    - hook_ehlo
197:      - hook_capabilities
198:      - *hook_unrecognized_command* is run for each ESMTP extension the client requests
200:  - hook_mail
201:  - hook_rcpt (once per-recipient)
202:  - hook_rcpt_ok (for every recipient that hook_rcpt returned `next(OK)` for)
203:  - hook_data
205:  - hook_data_post
206:  - hook_queue **OR** hook_queue_outbound
207:  - hook_queue_ok (called if hook_queue or hook_queue_outbound returns `next(OK)`)
208:- hook_quit **OR** hook_rset **OR** hook_helo **OR** hook_ehlo (after a message has been sent or rejected, the client can disconnect or start a new transaction with RSET, EHLO or HELO)
209:  - hook_reset_transaction
210:- hook_disconnect
215:mechanism. The Outbound queue is used when `connection.relaying = true` is set during the  transaction and `hook_queue_outbound` is called to queue the message.
217:The Outbound hook ordering mirrors the Inbound hook order above until after `hook_queue_outbound`, which is followed by:
219:- hook_send_email
220:- hook_get_mx
222:  - hook_delivered  (once per delivery domain with at least one successfull recipient)
223:  - hook_deferred  (once per delivery domain where at least one recipient or connection was deferred)
224:  - hook_bounce  (once per delivery domain where the recipient(s) or message was rejected by the destination)
228:Plugins are run on each hook in the order that they are specified in `config/plugins`. When a plugin returns anything other than `next()` on a hook, all subsequent plugins due to run on that hook are skipped (exceptions: connect_init, disconnect).
232:If you are writing a complex plugin, you may have to split it into multiple plugins to run in a specific order e.g. you want hook_deny to run last after all other plugins and hook_lookup_rdns to run first, then you can explicitly register your hooks and provide a `priority` value which is an integer between -100 (highest priority) to 100 (lowest priority) which defaults to 0 (zero) if not supplied.  You can apply a priority to your hook in the following way:
237:    plugin.register_hook('connect',  'hook_connect', -100);
241:This would ensure that your hook_connect function will run before any other
323:a core Haraka module you will have to use `this.core_require('name')`. Note that

docs/Results.md
14:    exports.my_first_hook = function(next, connection) {
45:    [plugin_name]
73:    c.results.add(plugin, {pass: 'null_sender'});
74:    c.results.add(plugin, {fail: 'single_recipient'});
75:    c.results.add(plugin, {skip: 'valid_bounce'};
82:    results.add(plugin, {my_result: 'anything I want'});
94:    c.results.incr(plugin, {unrecognized_commands: 1});
106:    c.results.push(plugin, {dns_recs: 'name1'});
107:    c.results.push(plugin, {dns_recs: 'name2'});
140:    results.has('plugin_name', 'result_name', 'search_term');
149:    r.add(plugin, {pass: 'some_test'});
150:    r.add(plugin, {pass: 'some_test(with reason)'});
154:    if (r.get('plugin_name').pass.indexOf('some_test') !== -1) {
155:        // some_test passed (1x)
160:    if (r.has('plugin_name', 'pass', 'some_test')) {
161:        // some_test passed (1x)
171:    if (r.has('plugin_name', 'pass', /^some_test/)) {
172:        // some_test passed (2x)
178:human_html output, prefix the name of the key with an underscore.
183:connection.results.add(plugin, { _hidden: 'some data' });
194:This is from the karma plugin, subscribing on the `connect_init` hook.
200:exports.hook_connect_init = function (next, connection) {
202:    plugin.redis_subscribe(connection, function () {
216:    exports.hook_disconnect = function (next, connection) {
217:        this.redis_unsubscribe(connection);

docs/Transaction.md
28:    transaction.message_stream.pipe(WritableStream, options)
36:    * line_endings (default: "\r\n")
37:    * dot_stuffing (default: false)
38:    * ending_dot   (default: false)
40:    * buffer_size  (default: 65535)
41:    * clamd_style  (default: false)
45:    transaction.message_stream.pipe(socket, { dot_stuffing: true, ending_dot: true });
63:very specific cases.  Most people will want to use `add_header()` instead.
84:The body of the email if you set `parse_body` above. See `Body Object`.
88:Sets a callback for when we see an attachment if `parse_body` has been set.
90:The `start` event will receive `(content_type, filename, body, stream)` as
101:    exports.hook_data = function (next, connection) {
103:        connection.transaction.parse_body = 1;
104:        connection.transaction.attachment_hooks(
106:                start_att(connection, ct, fn, body, stream)
112:    function start_att (connection, ct, fn, body, stream) {
113:        connection.loginfo("Got attachment: " + ct + ", " + fn + " for user id: " + connection.transaction.notes.hubdoc_user.email);
114:        connection.transaction.notes.attachment_count++;
151:* transaction.add\_body\_filter(ct_match, filter)
156:called when each body part matching ct_match is complete.  It receives three

docs/Tutorial.md
49:    $ haraka -i /path/to/new_project
55:    $ haraka -c /path/to/new_project -p rcpt_to.disposable
59:    Plugin rcpt_to.disposable created
60: Now edit javascript in:    /path/to/new_project/plugins/rcpt_to.disposable.js
61: Add the plugin to config:  /path/to/new_project/config/plugins
62: And edit documentation in: /path/to/new_project/docs/plugins/rcpt_to.disposable.md
66:`rcpt_to.in_host_list` and add in our new plugin, and change the queue
67:plugin to `test_queue`. The final file should look like this:
80: # block mail from known bad email addresses you put in config/mail_from.blocklist
81: #mail_from.blocklist
84: #mail_from.is_resolvable
87: rcpt_to.disposable
90: rcpt_to.in_host_list
95: test_queue
98:before `rcpt_to.in_host_list`.
101:the `plugins/rcpt_to.disposable.js` file:
103:    exports.hook_rcpt = function (next, connection, params) {
114:    $ echo myserver.com >> config/host_list
115:    $ sudo haraka -c /path/to/new_project
124:    [INFO] [rcpt_to.disposable] Got recipient: <booya@myserver.com>
135:    exports.hook_rcpt = function (next, connection, params) {
146:        var expiry_date = new Date(match[2], match[3]-1, match[4]);
148:        this.loginfo("Email expires on: " + expiry_date);
160:    [INFO] [rcpt_to.disposable] Got recipient: <booya-20120101@myserver.com>
161:    [INFO] [rcpt_to.disposable] Email expires on: Sun, 01 Jan 2012 05:00:00 GMT
172:    exports.hook_rcpt = function (next, connection, params) {
183:        var expiry_date = new Date(match[2], match[3]-1, match[4]);
185:        this.loginfo("Email expires on: " + expiry_date);
189:        if (expiry_date < today) {
228:    exports.hook_rcpt = function (next, connection, params) {
239:        var expiry_date = new Date(match[2], match[3]-1, match[4]);
241:        this.loginfo("Email expires on: " + expiry_date);
245:        if (expiry_date < today) {
264:    [INFO] [rcpt_to.disposable] Got recipient: <booya-20120101@haraka.local>
265:    [INFO] [rcpt_to.disposable] Email expires on: Sun Jan 01 2012 00:00:00 GMT-0500 (EST)
266:    [INFO] [rcpt_to.disposable] Email address now: <booya@haraka.local>

docs/tutorials/Migrating_from_v1_to_v2.md
17:to configure `spool_dir` and `spool_after` in `config/smtp.ini`. However if
25:for you, look for instances of `data_lines` in your plugins.
29:for you, look for instances of `attachment_hooks` in your plugins.
35:stream. The stream is called `transaction.message_stream`.
42:In v1.x Haraka populated the `transaction.data_lines` array for each line of 
47:    var data_marker = 0;
48:    var in_data = false;
49:    var end_pending = true;
50:    var send_data = function () {
51:        in_data = true;
52:        var wrote_all = true;
53:        while (wrote_all && (data_marker < connection.transaction.data_lines.length)) {
54:            var line = connection.transaction.data_lines[data_marker];
55:            data_marker++;
56:            wrote_all = socket.write(new Buffer(line.replace(/^\./, '..').replace(/\r?\n/g, '\r\n')), 'binary');
57:            if (!wrote_all) return;
59:        // we get here if wrote_all still true, and we got to end of data_lines
60:        if (end_pending) {
61:            end_pending = false;
63:            socket.send_command('dot');
67:        if (end_pending && in_data) {
68:            process.nextTick(function () { send_data() });
74:    connection.transaction.message_stream.pipe(socket, {dot_stuffing: true, ending_dot: true});
81:extract the lines from the stream of data.  See `plugins/dkim_sign.js` for 
87:For v1.x you passed in functions to `transaction.attachment_hooks()` as
90:    transaction.attachment_hooks(
98:    transaction.attachment_hooks(
111:    transaction.attachment_hooks(
baudehlo commented 8 years ago

If someone dives in to fix these, reference the file against the same file on https://haraka.github.io/manual/

msimerson commented 8 years ago

Hey @baudehlo , has this been addressed with the switch to Jekyll?

baudehlo commented 8 years ago

No I think there's still a couple of places that don't escape them right. It's hard to find them. I have a branch with one fix currently. Working on it.

On Jul 20, 2016, at 8:32 PM, Matt Simerson notifications@github.com wrote:

Hey @baudehlo , has this been addressed with the switch to Jekyll?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.