Author: Anders Berggren

Implementing SMTP LANG with proxy script

The upcoming Halon 5.1 release introduces a new SMTP server proxy script. It’s configured to be executed before specific (or all) SMTP commands, even command which isn’t recognised by the SMTP server. In this blog we’ll describe how to implement our proposed SMTP LANG extension using this new script hook. First of all, we announce the LANG extension and the languages supported in the HELO script:

$announce =  [...$arguments["extensions"], "LANG SE"];
Accept(["extensions" => $announce]);

Next, we configure to proxy script to hook onto the new “BREV”, “INNEHÅLL” and “HEJDÅ” commands:

Finally, we setup the proxy script to translate the international (Swedish, in this case) commands with their standard SMTP respective:

$cmd = str_upper($arguments["command"]);
if ($cmd[0:11] == "BREV FRÅN:") { // MAIL FROM
    $realcmd = "MAIL FROM:" + $arguments["command"][11:];
    Pass(["command" => $realcmd]);
if ($cmd == "HEJDÅ") { // QUIT
    $codes = ["code" => 221, "enhanced" => [2, 0, 0]];
    Reply("Ha det bra", ["reply_codes" => $codes, "disconnect" => true]);
// etc...

The proxy script and the corresponding xtext functions can be used for many other things, like custom XCLIENT implementations. More information on the 5.1 will be released later this month.

Speaking at M3AAWG #45 in San Francisco

As a supporting member, we’re happy to be participating in our 7th meeting on February 18-21. M3AAWG meetings are an exceptional opportunity to discuss the latest in messaging security with other professionals in a focused environment of working sessions and educational panels.

We would be delighted if you joined the transport encryption session that I’m speaking at, on Wednesday. Also, if you want to meet up, just get in touch! We’re all around; product, sales and engineering.

Halon 5.0 “tidy” with new REST API

Photo by Steve Hodgson

We celebrate the new year with news on the upcoming release, which bundles many exciting features.

First and foremost, the new RESTful API with an OpenAPI specification makes integration into various development and deployment toolchains much more enjoyable. Since most of our customers already integrate Halon into their directories and control panels by making REST queries from Halon, it makes perfect sense that Halon can be provisioned in the same way.

$ curl https://halon1/api/1.0.0/email/queue
   -d '{"filter": "ip=", "fields": {"transport": "srv2"}}'
   -u username:password
    "affected": 10

Secondly, we’re introducing a new end-of-DATA script that’s executed once per message, as opposed to the per-recipient DATA script. Whereas the per-recipient version is convenient when you want to treat each recipient individually and let the Halon software take care of queueing and consolidating the respective actions into an SMTP response, the per-message version gives you maximum flexibility and control over execution. The $transaction variable is populated gradually during the SMTP conversation with sender information, and an array with recipients accepted by each RCPT TO command. To then relay a message to its recipients, you call Queue() for each $transaction["recipients"] and then Accept(). Making per-recipient message modifications using the MIME() class is now easier thanks to the new snapshot() and restore() methods.

The code editor’s built-in CSV editor now supports custom form controls, defined like a “schema” on a per-file basis using a JSON format. You can use checkboxes for booleans, select controllers for enumerated types, and input fields with validation for things like dates, email addresses or any regular expression you like. It makes it much more convenient and safe to create and edit lists and settings that you want to have in your Halon configuration file.

There’s a new LDAP() class that replaces the previous ldap_ functions and LDAP settings in the configuration. It provides greater flexibility, and an improved usage pattern using an iterable LDAP result object.

Finally, there are massive under-the-hood improvements. There’s a new on-disk YAML configurations with JSON schemas and Protobuf control sockets, which is used by the componentised Linux package’s new Visual Studio Code plugin and command line tools. The integrated package is built on FreeBSD 12, which ships with OpenSSL 1.1 and thus TLS 1.3 support. It was published as a standard by IETF in August last year, and is much anticipated as it contains many security improvements over previous TLS versions. The queue database is now using the latest and greatest PostgreSQL version 11.1, and the queue is automatically migrated on boot as usual.

We have that you’ll like this new release as much as we do! Check out the full changelog on GitHub for more information, and familiarise yourself with the important changes outlined in the release notes document before upgrading.

Meet Halon at Smau Milano 2018

Halon are going to Smau 2018 in Milan on October 23-25, with our new distributor AnswerVAD. We have had the fortune to be introduced to this big Italian event through Massimo, the CEO of AnswerVAD. This is an innovation event, and a great place to be for announcing our presence in the region. We will be in a booth together with AnswerVAD. If you are interested of going there but don’t have a ticket, don’t hesitate to contact us and we will sign you up for free. Hope to se you in Milan!

Halon 4.7 “ahoy” and 4.8 “truly” with live debugging and HELO script

Halon 4.0 introduced a feature we call “live staging” where you can deploy multiple running configurations at the same time, with per-connection conditions. It allows you to reliably rollout changes or new features to a production system for only a few testing IPs, or a select percentage of the traffic. With Halon 4.7, we proudly present “live debugging” using which you can add logpoints to your scripts. It enables you to inspect the full context of SMTP transactions in real-time, using the live staging conditions as connection selector.

Those points are added directly to the Monaco-based IDE, and results are inspected on a per-connection basis. You can create multiple points, triggered by multiple messages, and jump back and forth between them.

We’ve also added a HELO/EHLO phase script, support for ARC in DKIMSign() and a full implementation of draft 18 on Github, EdDSA (ed25519) and a native boolean type with corresponding strict comparison operator. The standard library have many new functions such as rsa_sign() and verify, idna_encode() and decode, aes_encrypt() and decrypt.

We hope that the live debugging will come handy! Please see the changelog on Github for a full list of improvements and changes, or get in touch with us if you want more detailed information.

Using ARC to work around DMARC’s forwarder issues

Authenticated Received Chain (ARC) is a proposed standard that have been developed to help address issues with DMARC and certain forwarders, such as mailing lists. It defines a standard for how to pass authentication results from one intermediary to another, making this information available to the recipient system. It works even in the case of multiple intermediaries, a.k.a. a chain

DMARC verifies the sender authenticity, as specified by the RFC5322.From header domain name, using SPF and DKIM. Certain indirect email flows such as mailing lists break this by altering the message, while maintaining the original From header. It causes issues for both senders that publish a DMARC policy, and receivers that verify DMARC. The two large mailbox providers AOL and Yahoo published a p=reject DMARC policy for their domains in 2014, causing some disruption for senders on those domains. It occurred when emailing recipients on mailbox services that verifies DMARC via for example mailing lists. This was, and still is, remedied by ad-hoc solutions.

ARC in itself isn’t a reputation system. The specification doesn’t define how the reputation of intermediates should be tracked, nor how public lists should be operated. In other words, as a recipient mailbox provider you still have to operate such systems in order to make use of the information that ARC provides. announced ARC at a M3AAWG meeting in Atlanta, 2015, where it’s been a frequent topic ever since.

include "authentication.header";
include "authentication.arc";

$chain = ARC::chainValidate();
if ($chain["status"] == "pass" or $chain["status"] == "none")
			"201805", "", "pki:arc",
				->SPF(["smtp.client-ip" => $senderip])
				->addMethod("arc", $chain["status"], ["header.oldest-pass" => $chain["oldestpass"] ?? "0"])


We have just released an implementation for ARC (draft 14) on Github, which supports both verification and (re)sealing. It’s written in Halon script, and we’re using it on our own domain to start with. If you’re interested in taking it for a spin, just let us know.

Halon 4.6 “curry” with outbound anti-spam

You probably know from before that Halon’s scriptable SMTP server enable email providers to avoid blacklisting and increase deliverability. The 4.6 release, “curry”, contains Cyren’s outbound anti-spam (OAS). In combination with our cluster-synchronised rate limit function, it provides incredibly effective and accurate abuse prevention. Just like their Cyren’s inbound anti-spam, OAS uses a hash-sharing technology called recurrent pattern detection (RPD) that identifies outbreak patterns. It’s designed to detect spam from internal sources rather than external, and doesn’t report/contribute any signatures since it could blacklist your own infrastructure.

With the flexibility of scripting you can determine customer/sender identities accurately even in mixed traffic. This is used as identifier for rate limits based on classifiers such as Cyren’s OAS, delivery failure rate, queue size, etc. By using IP source hashing and alternative IPs for suspicious traffic, deferring obvious abuse and controlling connection concurrency, you can achieve high deliverability with minimal administration.

The 4.6 release comes with many additional features and improvements. It adds SNI support to the TLS functions. The Monaco-based code editor now have additional code completion, built-in documentation, tabs, and a mini-map.

For more information on the release, see the full changelog on GitHub. If you want to try Cyren’s outbound anti-spam, contact our sales team.

Halon 4.6 “funny” supporting our SMTP LANG extension

In the beginning, everything was ASCII and English. Since then, we’ve seen Unicode (international character sets) and IDN (international domains names) become widely adopted. Last year we implemented SMTPUTF8 that enables international mailboxes.

So why not support other languages in text-based protocols? We give to you “The SMTP Service Extension for Protocol Internationalization” RFC draft, introducing the EHLO keyword LANG. It will be the first SMTP software to support our to-be submitted RFC draft. Initially it will support Swedish, Spanish and Australian, and will default to Swedish when talking to supported systems.

250 Ok
250 Tack
BREV TILL:<hå[email protected]ä>
250 Tack
Subject: asdf

250 Togs emot
250 Vi ses!

If you made it this far, April fool! We will publish information on the upcoming 4.6 release some time after the 1st of April.

Happy easter!

Halon 4.1 “teamy” with scripting modules

We’ve shipped the 4.1 “teamy” release, and we’re happy to see that the majority of our users have already updated. The 4.0 release brought several major changes, and 4.1 includes many improvements to it. The web administration in general, and the script editor in particular, have received lots of attention. The new live staging functionality that was introduced in 4.0 now extends to queue (pre- and post-delivery) scripts as well, using the _stageid metadata field. You can employ even more aggressive caching now that the API includes a hslCacheClear() function, and we’re opened up a wide range of possibilities via the new setBody function in the DATA script’s MIME class, such as URL rewriting.

The most anticipated addition however, is a new language feature often referred to as modules. The Halon scripting language is highly email-centric. We strive towards keeping it as simple as possible, which is a great recipe for stability and high, predictable performance. At the same time, we’re designing it after the principle of least astonishment, and consequently it shares many characteristics with established languages. Having researched both namespaces (found in languages such as C++ and PHP) and modules (found in for example Python and Perl), we decided that modules was the best fit for our language and its users. It’s great when working in larger teams, since it introduces file-wide symbol (variable and function) scoping. Modules are regular script files, which becomes modules the moment you import them. It’s similar to include, except an imported file has its own scope. You explicitly choose which symbols to “import” to the parent file using the syntax

import { Foo as X, $bar as $y } from "test";

Variables are imported by reference, hence all changes to the variable in the module will be reflected by the imported variable. As modules have their own global scope, variables referenced in a module’s function by global or closure points at the module’s scope, as per the example below

$x = "hello";
function foo($bar) {
    global $x;
    echo $x;

imported by

import { foo } from "test";
$x = "world";
echo foo(function() closure ($x) { echo $x; });

which will echo


We hope that the modules concept will be helpful in both smaller and larger projects, and we promise that much more is to come as Halon 4.2 “classy” hits the servers.

Live staging and SMTPUTF8 coming up in Halon 4.0

Halon 4.0 a.k.a. “forty” is around the corner, and it has a strong focus on developer friendliness and deployment. Let’s take a peek on what’s about to happen!

Most of the work has gone into the SMTP server. Most notably, it now supports running two different configurations, complete with compiled scripts, in parallel. We refer to it as “live staging”, since it allows you to try out new code on a production host, for only some select traffic, based on conditions, such as IP address. We’ve also introduced a new persistent connection $context variable to all the SMTP server’s scripts, including the new MAIL FROM script, which can be used to pass data between SMTP stages or even RSETs, like

$context[$messageid][$recipient] = lookup($recipient, ...

since $messageid is regenerated with each RSET. Another major feature is SMTPUTF8, which allows for international (and emoji!) email addresses.

The scripting language itself has a new resource value type, used by the Socket() networking class which, in turn, is used to implement various extensions such as a memcached client. Another new scripting features is bitwise operators, which you can see in action by viewing the TOTP example’s code.

In addition to the live staging, management is significantly more distinct and reassuring thanks to a checkout/commit pattern, and a more expressive configuration format. As you begin to make changes, already tested using the live staging, as larger commits with descriptive messages, browsing the configuration revision history will become much more enjoyable. It also supports larger teams much better.

Halon 4.0 user interface

As usual, it’s based on the latest FreeBSD version; 11.0 in this case. It features LLVM’s LLDB, Receive Side Scaling (RSS) in some Intel network drivers, unmapped IO in Xen and VirtIO, Amazon AWS SR-IOV networking, Tx/Rx multiqueue in VMware VMXNET3, and much more.

Check out the changelog for more detailed information, and try out the new web interface at!