Skip to content

Releases: RainbowWizard-coder/hMailServer

hMailServer 6.3.8

Choose a tag to compare

@RainbowWizard-coder RainbowWizard-coder released this 02 Nov 17:03
Immutable release. Only release title and notes can be modified.

Download

Windows, x64 hMailServer-6.3.8-x64.exe: the installer, Authenticode-signed by Progressive Robot Ltd. It installs a new server, or upgrades an existing one in place: read the notes below and back up the database and the data folder first. SHA-256 4b9b9c3102cbed743f6c826289c54cec25c395d02208e55cdd3219187fbf8654.
Windows on ARM64 (preview) hMailServer-6.3.8-arm64.exe, signed the same way. A preview: it has not been run on ARM64 hardware. A new installation is set up against Microsoft SQL Server or PostgreSQL, since SQL Server Compact has no ARM64 build (WindowsOnArm.md). SHA-256 e5ce357b9ca4e013529898c5208d43895fec3a397b1a4defa4cd905ee9b7f27a.
Linux The .deb and .rpm packages for each distribution and the two AppImages, under Assets below, in Packages; hmailserver-linux-6.3.8-SHA256SUMS.txt lists them.
Container image registry.gitlab.com/hmailserver/hmailserver:6.3.8, for linux/amd64 and linux/arm64, pushed by this release's pipeline after the release is published. :6.3 and :latest are moved to it too, unless a later version has either already.
Checking a download Each file the release pipeline made is signed with Sigstore, its bundle beside it as <file>.cosign.bundle, and hmailserver-6.3.8.intoto.sigstore.json is the release's SLSA build provenance (hmailserver-6.3.8.intoto.jsonl is its signed envelope alone, as one line of JSON); Verification, at the end of these notes, gives the identity to check them against (SECURITY.md, "Verifying a release").

hMailServer 6.3.8

Everything that landed on master after the v6.3.7 tag, from 17 October 2026 (compare v6.3.7 with
v6.3.8
). This is Progressive Robot's fork of
hMailServer. 6.3.8 is a security release: it fixes vulnerabilities the project found in its own code, each a work item
with a CVE request through GitLab's CNA, and the four narrower cases of work item 78 that 6.3.7's notes left open.
Between them they reach back to 6.0.0's first beta: upgrade every server running 6.3.7 or earlier. It was first
decided, while releases pause, because the published Helm charts of 6.3.6 and 6.3.7 did not start a server,
which only a release puts right, and that reason stands beside the fixes; it also puts right the container image, which
could not reach a MariaDB database, and the Windows installer, which ran over an installation of the original
hMailServer's 5.7, and it carries the finished work master holds (Why there is a 6.3.8, below). The schema stays at
6108, as 6.3.6 and 6.3.7 have it: 6.3.8 adds no upgrade step. What changes on upgrade without a switch follows the
Security section.

What it fixes, and for whom. Each is in its section below, with what changed and how it is tested. The
vulnerabilities first; their work items are made public, and their advisories published, once 6.3.8 is on the update
feed:

  • The database layer's test for the marker that lets a statement's error be ignored, and the log's and the trace's
    redaction of a statement's literals, read a literal as each engine does

    (work item 100; Security).
  • The auto-ban saves the IP range it adds under a name of its own, so that it bans the address
    (work item 102; Security).
  • A sign-in's name is matched to its account as the per-name lockout and the compromised-account hold count it
    (work item 104; Security).
  • The web services listener (CardDAV, CalDAV, Autodiscover) refuses an address an auto-ban or an IP range bans
    (work item 105; Security).
  • A failed sign-in at the web services listener through a proxy is no longer charged to the proxy's address
    (work item 106; Security).
  • A failed account sign-in at the REST listener through a reverse proxy on the same machine is no longer charged to
    127.0.0.1
    (work item 107; Security).
  • The REST API, and the reader of a report mailed to a domain's report address, read a JSON body in time and memory
    that follow its bytes
    (work item 110;
    work item 111; Security).
  • TlsMode=verify-full on MySQL and MariaDB checks the database server's certificate against the CA file TlsCaFile
    names
    (work item 112; Security). Its entry corrects
    what 6.3.7's notes said of a named TlsCaFile as the mitigation for CVE-2026-107819, MariaDB Connector/C's own flaw.
    On Linux the client is the distribution's, which should be MariaDB Connector/C 3.4.11 or later; where it is older and
    not patched, name the CA in TlsCaFile (DatabaseTls.md).
  • The database client's TlsMode=verify-full check of a database server on this machine, on MySQL and MariaDB
    (work item 113; Security).
  • On Windows the database clients check the database server's certificate against the root certificate file named, or
    refuse its name
    (work item 114; Security).
  • On Windows the files the server hands to OpenSSL by name are read from the file configured, or refused
    (work item 115; Security).
  • On Windows the bundled MySQL and MariaDB client, MariaDB Connector/C, loads its authentication plugins from the
    installation's own plugin folder, or from none

    (work item 116; Security).
  • On Windows, setup makes or hardens the program folder, Bin and ControlPanel before it copies a file or runs a
    program of the installation, and refuses a folder or a link on the way to them, or a program, library or script in
    them, that another account controls
    - the four narrower cases of work item 78 that 6.3.7's notes listed as still
    open (work item 78; Security).
  • Published with it: the advisory for a flaw in the auto-ban on MySQL and MariaDB that 6.3.4 fixed
    (work item 103).

Each was found by the hMailServer project (Progressive Robot Ltd). The other fixes and changes an administrator meets:

  • The Helm chart starts a server (Downloads and the release, Correctness). Installed into a cluster, the charts
    of 6.3.6 and 6.3.7 never started a pod: the image names its user, which Kubernetes cannot hold to the chart's
    runAsNonRoot, and once given the user by number the server stopped at a configuration volume that hid the image's
    settings file. 6.3.8's chart runs the pod as the image's user by number, 999:999, fills new volumes in an init
    container, and secures a new installation at its first start, as the packaged systemd unit does; so does the Compose
    file. The pod sets net.ipv4.ip_unprivileged_port_start to 0 in its own security context, so that the server binds
    the mail ports under containerd 1.7 and CRI-O too. A release of the 6.3.6 or 6.3.7 chart is moved with helm upgrade --reset-then-reuse-values and then kubectl delete pod (Before you upgrade, below).
  • The container image reaches a MariaDB database (Downloads and the release). The images of 6.3.7 and earlier
    carried PostgreSQL's client alone, so a container told HM_DB_TYPE=MySQL stopped at its first start; 6.3.8's
    carries MariaDB Connector/C (libmariadb3), and the release's pipeline starts each platform's pushed image beside
    PostgreSQL and beside MariaDB and asks each for SMTP, the REST API and the schema it laid out. The chart passes a
    database port only when one is set, so a chart told MySQL no longer dials MariaDB on PostgreSQL's port. Found by
    the project's own audit of its listings. The image's entrypoint also secures a new installation by itself, whatever
    the container's command, and takes the database and administrator passwords out of the environment before it runs
    any program (Security).
  • The Windows installer refuses an installation of the original hMailServer's 5.7 (Correctness). Both projects'
    installers register as hMailServer_is1, so the installers of 6.3.7 and earlier took an installation of the
    original's 5.7 builds of August and September 2026 (schema 5709 to 5711, which this fork's upgrade chain has no step
    from) for their own and replaced its programs. 6.3.8's setup asks first, before a page is shown or anything is
    installed or stopped, refuses such an installation with a message that says nothing has been changed, and, silent,
    ends with exit code 1 and writes the reason to its log (/LOG) and to hMailServer-setup-refused.txt in %TEMP%.
    An installation of this fork, or of the original up to 5.6, is upgraded as before. The installers of 6.3.7 and
    earlier do not look: never run one over the original's 5.7.
  • **A host added...
Read more

hMailServer 6.3.7

Choose a tag to compare

@RainbowWizard-coder RainbowWizard-coder released this 18 Oct 05:31
Immutable release. Only release title and notes can be modified.

Re-published on GitHub on 18 October 2026 from the GitLab release v6.3.7 of 2026-10-17. Each file below was checked against the SHA-256 that GitLab's package registry records for it before it was uploaded here.

Download

Windows, x64 hMailServer-6.3.7-x64.exe: the installer, Authenticode-signed by Progressive Robot Ltd. It installs a new server, or upgrades an existing one in place: read the notes below and back up the database and the data folder first. SHA-256 dcae96bd75d6cae8e5a910d15940567067539ed99db5aeed40a815added4d85f.
Windows on ARM64 (preview) hMailServer-6.3.7-arm64.exe, signed the same way. A preview: it has not been run on ARM64 hardware. A new installation is set up against Microsoft SQL Server or PostgreSQL, since SQL Server Compact has no ARM64 build (WindowsOnArm.md). SHA-256 56a5425bd4e50e6dc79a02c6b79ff0f6bcc4e88ef59d457652efcaaac67601dd.
Linux The .deb and .rpm packages for each distribution and the two AppImages, under Assets below, in Packages; hmailserver-linux-6.3.7-SHA256SUMS.txt lists them.
Container image registry.gitlab.com/hmailserver/hmailserver:6.3.7, for linux/amd64 and linux/arm64, pushed by this release's pipeline after the release is published. :6.3 and :latest are moved to it too, unless a later version has either already.
Checking a download Each file the release pipeline made is signed with Sigstore, its bundle beside it as <file>.cosign.bundle, and hmailserver-6.3.7.intoto.sigstore.json is the release's SLSA build provenance; Verification, at the end of these notes, gives the identity to check them against (SECURITY.md, "Verifying a release").

hMailServer 6.3.7

Everything that landed on master after the v6.3.6 tag, from 6 October 2026 (compare v6.3.6 with
v6.3.7
). It is the first security release
made while releases pause (SECURITY.md, "While releases pause"), and it fixes vulnerabilities in every
earlier version: upgrade every server running 6.3.6 or earlier. The schema stays at 6108, as 6.3.6 has it:
6.3.7 adds no upgrade step (below). The security notes come first, then what changes on upgrade without a switch.

What it fixes, and who found it. Each is under Security below, with what changed and how it is tested.

  • Programs that any user could replace, on a Windows server installed at the root of a drive
    (work item 78, CVE-2026-107571). Where the program
    folder took its permissions from the root of a drive, any account that could sign in to the computer could replace
    the programs the service runs, in every release from 6.0.0 to 6.3.6; the default folder under Program Files was
    never affected. hMailServer.exe /ProtectFolders, which setup runs at every installation and upgrade, now hardens
    the program folder, Bin and ControlPanel. Four narrower cases are not fixed in this release (What 6.3.7 does
    not fix
    , below). Found by the project's own review.
  • Mail sent, and signed, in the name of a domain hosted here. Mail from outside whose From named a hosted domain
    was signed with that domain's DKIM key, and so was every forward and copy of it, in every version that signs; and an
    authenticated submission was signed as whatever hosted domain its From named, which 6.3.7 does only where the
    account may send as that address (work item 84,
    CVE-2026-107567). An account's Sieve notify was sent from whatever its :from said
    (work item 82, CVE-2026-107568), and its editheader
    could rewrite who a message was from ahead of a redirect
    (work item 83, CVE-2026-107566), both from 6.2.22; a
    domain's or an account's rule had the same gap in every version - a Reply from an address its owner may not send as,
    a Set header value of From, Sender, the Resent- pair or DKIM-Signature - and is held the same way, under the
    same two work items. A forward, a redirect, a list's copy or an alias's copy of mail from outside - a forward of a
    message downloaded from an external account among them - is given an envelope sender, or for a null one is sent under
    a host name, in the organisation of a domain its From names only when the message passed DMARC for it on arrival
    (work items 90 and 91; CVE-2026-114478 and CVE-2026-114474). Without a CVE request, as hardening: an ARC seal this server makes attests its
    own SPF result, is made by the domain that relayed the message, and names the domains its results are for. All found
    by the project's own review.
  • The rule loop limit (work item 81,
    CVE-2026-107569). Any sender could lift the limit off a message, an account's own Sieve script or rule could reset
    it, and a Sieve notify did not consult it, so that a loop of generated mail could run without bound, in every
    version. Found by the project's own review.
  • What a credential confined to named domains may change, over the REST and the COM APIs. On a server with several
    tenants, such a credential could make a few changes that reach beyond its domains, and could read the server-wide
    metric history; over COM an account given the serveradmin role with a list of domains was the server's
    administrator, its list aside, and over both a role could be taken away from an account by a credential that does not
    hold what the account's admin level then gives it; a browser that held a REST credential could be made to send a
    state-changing request from another site; and the ACME challenge responder served one connection at a time, so that
    idle clients could make a certificate's renewal fail (work items 86, 87, 88, 89, 93, 96 and 97; CVE-2026-114489, CVE-2026-114490, CVE-2026-114476, CVE-2026-114475, CVE-2026-114470, CVE-2026-114477 and CVE-2026-114472). Found
    by the project's own reviews.
  • The anti-virus action that removes attachments delivered a message whose one part is an attachment, and an S/MIME
    message signed as one part, as they arrived, with what the scanner had found in them, in every version; 6.3.7 replaces
    each with the action's note, and deletes a message the server cannot read (work item 92; CVE-2026-114479). The default
    action, which deletes the message, was never affected. Found by the project's review of this release.
  • Keys left in memory. --import-stored-secrets-key, and the reading of the stored-secrets key from its line,
    left copies of the key in memory freed without being written over, from 6.3.4 (found by the project's own review);
    and a mailbox key encrypted at rest stayed open past MailboxKeyIdleMinutes for as long as the scheduled tasks held
    up their minute, from 6.3.4 (found by the batch's regression gate).
  • Found by upstream hMailServer, in code this project shares with it: with SRS on, mail to an SRS address this
    server had handed out was not held to the relay rules, from 6.2.1 (work item 94; CVE-2026-114473), and an SRS address or
    a BATV tag almost a whole cycle old was taken for fresh (upstream PR 649); a SASL PLAIN client that asked to act as
    another account was signed in as itself and told it had succeeded (upstream issue 652); and the SMTP log wrote some
    credentials in the clear (upstream issue 654; work item 95; CVE-2026-114471).
  • What the Windows installers carry. The .NET Desktop Runtime 10.0.13, Microsoft's security release of 13 October
    2026, where the installers of 6.3.4 to 6.3.6 carried 10.0.12 (The .NET 10 Desktop Runtime, below); and, as the
    MySQL and MariaDB client, MariaDB Connector/C 3.4.11, where 6.2.3 to 6.3.6 carried 3.4.9, which has CVE-2026-107819.

Reported from outside and fixed besides: the Control Panel's IP ranges page, which could show no list of ranges at
all (work item 79, ThiagoES84); mail to a DNSSEC-signed domain whose MX answer came compressed, live.com among
them, which DANE enforcement deferred (work item 80, ThiagoES84); and classic Outlook's POP3 downloads, which
stopped at the UTF8 it sends after the login (work item 85, ciprianbalus). Thank you.

A security release, and more than fixes. A security release during the pause is cut from master with the
finished work master holds then, as SECURITY.md, "What is supported, and for how long", now says;
until this release it said "6.3.6 with fixes", and the five places that said so are reworded (Documentation). 6.3.7
carries the work that was under way on 13 October 2026, which the owner decided that day to finish and fold into one
batch: the Control Panel's corrections to its pages, texts, translations and keyboard and screen-reader behaviour,
and its regrouped sidebar (Control Panel); IMAP and POP3 taking the client's address from a PROXY header (IMAP,
POP3 and the webmail
); a link's host that is not ASCII read by UTS 46 (Anti-spam, anti-virus and mail flow
rules
); the first units of the active-active work, which is still not built
(ActiveActive.md); and the Windows suite run in two halves on two benches, with
GitLab's hosted runners ava...

Read more

build-inputs-2: MariaDB Connector/C 3.4.11, built from source

Choose a tag to compare

Re-published on GitHub on 18 October 2026 from the GitLab release build-inputs-2 of 2026-10-06. Each file below was checked against the SHA-256 that GitLab's package registry records for it before it was uploaded here.

MariaDB Connector/C 3.4.11, the first release MariaDB published with the fix for CVE-2026-107819 (fixed by CONC-846 in 3.4.10, a version MariaDB tagged and never released), built from MariaDB's signed source by libraries/build-mariadb-connector-c.ps1, reproducibly. It replaces the 3.4.9 client (MariaDB Server 12.3.2's build) that build-inputs-1 carried; build-inputs-1's SQL Server Compact runtime is still used. Not a server release. SHA-256 of the archive and of every file in it: hmailserver/docs/third-party-binaries.json; how it is built: hmailserver/docs/ThirdPartyBinaries.md, 'Connector/C 3.4.11, built from MariaDB's source'. Dated 6 October 2026, the day MariaDB published the 3.4.11 source, so that it does not take over the project's latest-release link.

hMailServer 6.3.6

Choose a tag to compare

@RainbowWizard-coder RainbowWizard-coder released this 18 Oct 05:26
Immutable release. Only release title and notes can be modified.

Re-published on GitHub on 18 October 2026 from the GitLab release v6.3.6 of 2026-10-06. Each file below was checked against the SHA-256 that GitLab's package registry records for it before it was uploaded here.

Download

Windows, x64 hMailServer-6.3.6-x64.exe: the installer, Authenticode-signed by Progressive Robot Ltd. It installs a new server, or upgrades an existing one (6.3.5, 6.2 or older) in place: read the notes below and back up the database and the data folder first. SHA-256 2f673913e5f127d688090e98f6001ca567cd45560d452aebc74421b5533cfe53.
Windows on ARM64 (preview) hMailServer-6.3.6-arm64.exe, signed the same way. A preview: it has not run on ARM64 hardware, and a new installation is set up against Microsoft SQL Server or PostgreSQL, since SQL Server Compact has no ARM64 build. SHA-256 59f8edd259bdef2e31dd83da152c3f748d67a27a19e6c3c8f5a2ade2ff84227c.
Linux The .deb and .rpm packages for each distribution and the two AppImages, under Assets below, in Packages; hmailserver-linux-6.3.6-SHA256SUMS.txt lists them.
Container image registry.gitlab.com/hmailserver/hmailserver:6.3.6, for linux/amd64 and linux/arm64.
Checking a download Each file the release pipeline made is signed with Sigstore, its bundle beside it as <file>.cosign.bundle; Verification, at the end of these notes, gives the identity to check it against.

hMailServer 6.3.6

Everything that landed on master after the v6.3.5 tag, from 29 September 2026 (compare v6.3.5 with
v6.3.6
). It is the last release for the
time being: after it the project makes security releases only, and the 6.3 line receives security fixes until 30
September 2027 (below). 6.3.6 fixes the security flaws the project's own reviews of the code found, CVE-2026-103011
among them, and takes OpenSSL 4.0.3 into the Windows installers (both below), fixes what 6.3.5's release and the first
live updates from 6.3.4 found, replaces with the project's own code the last code in the server whose licence a
distribution would have had to settle, and carries every file the release pipeline makes, the ARM64 Windows installer
among them. The schema moves to 6108 in three steps: 6106, which changes no column, gives every external account's
days to keep messages the one meaning both fetchers now read, keeping each account doing what it did or stopping it
deleting (What changes on upgrade without a switch, item 22); 6107 finishes the greylisting key schema 6072 began
(item 23); and 6108 adds the never-ban list by reverse name and, for each SMTP listener, what it does with AUTH, On
for every listener an upgrade finds (item 25). The security notes come first, then what changes on upgrade without a
switch. The operator documents named below are in hmailserver/docs, which has twelve more of them than it had at
6.3.5.

Releases pause after this one. 6.3.6 is the last release for the time being, by the owner's decision of 28
September 2026, and no feature release follows it until the maintainers say otherwise in SECURITY.md,
"While releases pause". A confirmed vulnerability still ships, in a release of its own that is 6.3.6 with fixes -
6.3.7, 6.3.8 and so on - on the targets SECURITY.md gives: a critical or high one as soon as its fix has passed the
gates, and none held past 90 days. Other defects are fixed on master and ship with the next security release, or
when releases resume. The 6.3 line receives security fixes until 30 September 2027; before that date the
maintainers write in SECURITY.md whether support continues, and if nothing is written, it ends then. There are
still no maintenance branches: an installation of 6.3.5, 6.2 or anything older is upgraded in place to the newest
release.

What the release carries: 62 files and 160 links (ContinuousIntegration.md, "What a release carries"). Beside
the x64 installer is hMailServer-6.3.6-arm64.exe, for Windows on ARM, Authenticode-signed like it. It is a
preview: the ARM64 build is cross-compiled on the project's x64 Windows runner and has never run on ARM64 hardware,
so read it as built to work (WindowsOnArm.md). If you install it on an ARM64
machine, please say how it went, working or not, in an issue:
the project has no ARM64 machine of its own. SQL Server Compact has no ARM64 build, so a new ARM64 installation is
set up against SQL Server or PostgreSQL, and a silent one is given its database on the command line. For Linux the
release carries the generic .deb and .rpm for x86-64 and, for the first time since 6.3.3, for AArch64 -
cross-compiled and tested under emulation, since no AArch64 machine has run them - and each Debian 12 and 13, Ubuntu
24.04, Fedora 44 and 43, EL 10 and 9, openSUSE Leap 16.0 and Tumbleweed release's own package for both
architectures. It also carries both AppImages, with the source of the libraries they carry and of those their
runtime links; the source tarball, hmailserver-6.3.6.tar.gz, reproducible and with nothing non-free in it, from
which the Debian source package and the RPM spec in the tree build the server as a distribution does
(SourceTarball.md, SourcePackages.md);
and the Helm chart. Every file has a Sigstore bundle beside it, every compiled file and the tarball an SBOM, and
SLSA build provenance names every file by its SHA-256 (SECURITY.md, "Verifying a release" and
"Build provenance"). The apt and dnf repositories and the other channels publish from master once their keys and
accounts exist; none is live as this release is made (Channels.md).

The first container image: registry.gitlab.com/hmailserver/hmailserver:6.3.6, also tagged 6.3 and latest,
one index over linux/amd64 and linux/arm64, each platform's image built from this release's .deb of its
architecture. It is pushed from this release's own pipeline once the release is published, by a job started by
hand, signed with cosign as that pipeline, each platform's image with its SBOM attested to it; until then the
registry holds no image. In the container the update check names the image to pull and installs nothing
(ContainerImage.md).

A Nix flake and Alpine Linux: a Nix flake of the project's own at the repository's root, with a NixOS module
(services.hmailserver), and an APKBUILD and an OpenRC service for Alpine Linux, on whose musl the server now
builds and runs; both are built without the live update and name the command that updates them, and neither is in
a distribution's archive yet (Nix.md, Alpine.md).

Signing, and who installs this release by the live update. Every file is signed with Sigstore as this
release's own pipeline at the group's path,
https://gitlab.com/hmailserver/hmailserver//.gitlab-ci.yml@refs/tags/v6.3.6, issuer https://gitlab.com, with the
project's id, 86730559, in the certificate: the first release signed there since the project moved into the group
hmailserver on 29 September 2026. Every server from 6.3.4 on has that signer compiled in and requires the id for
it, so a server on 6.3.4 or 6.3.5 installed from the x64 installer or the release's x86-64 .deb or .rpm is built
to install this release by its live update: from 6.3.5 with 6.3.5's own file as its rollback image, and from 6.3.4,
which carries no Sigstore bundle, without one. No live update had installed a release signed at the group's path
when these notes were written. The update is applied by the version already installed, so three things of 6.3.4
and 6.3.5 still hold for it:

  • a Windows service running as NT SERVICE\hMailServer downloads and verifies the installer, then leaves the
    install to an administrator (HM7463), whose Install update on 6.3.4 and 6.3.5 cannot do it: install this
    release by hand, once, as the next paragraph says, and every release after it with one click;
  • on Linux, a backup destination inside /var/lib/hmailserver fails the backup taken before an unattended apply
    (HM5014), and the apply is refused until the destination is moved or the release installed by hand
    (UpdateFeed.md, "From 6.3.4 on, by the live update");
  • a server whose UpdateSigningIdentity, UpdateSigningIssuer and UpdateSourceRepository still name the path
    the project began at - set so that a server from 6.2.28 to 6.3.3 could install 6.3.5 - trusts that path alone and
    refuses this release. Clear the three first - in the Control Panel, with DELETE /api/v1/settings/ini/<name>, or
    on Linux with hmailserver --set-setting <name>= - and not in the file, which 6.3.4 and 6.3.5 put back.

A server from 6.2.28 to 6.3.3 trusts only the GitHub workflow that signed the releases up to 6.3.3, and is upgraded
to this release by hand, once, after the backup Upgrading.md describes; so is a
server installed from an AArch64 package or an AppImage, whose last release was 6.3.3. One pointed at this
project's feed with UpdateFeedUrl downloads the installer at every check and refuses it, so keep
UpdateAutoDownload off there until then. The three settings that let such a server install 6.3.5 do not reach
6.3.6, and must never name the group's path (UpdateFeed.md, "A server from
6.2.28 to 6.3.3"). No release before this one carried the ARM64 installer, so no ARM64 Windows...

Read more

hMailServer 6.3.5

Choose a tag to compare

@RainbowWizard-coder RainbowWizard-coder released this 18 Oct 05:24

Re-published on GitHub on 18 October 2026 from the GitLab release v6.3.5 of 2026-09-29. Each file below was checked against the SHA-256 that GitLab's package registry records for it before it was uploaded here.

hMailServer 6.3.5

Everything that landed on master after the v6.3.4 tag, from 27 September 2026 (compare v6.3.4 with
v6.3.5
). The schema moves from 6104
to 6105 in one step
, which adds a column to the quarantine's table, hm_quarantine.quarantinehelo. What changes
on upgrade without a switch comes first. The operator documents named below are in hmailserver/docs, which has
five more of them than it had at 6.3.4.

This is the first release built to be made by the project's GitLab CI from its tag (RELEASE.md, The
release on GitLab
and On GitLab, from 6.3.5). The tag's pipeline builds the Windows installer on the project's
Windows runner after the whole Windows suite has passed there; once the owner has started the release job, it
Authenticode-signs the installer through Azure Artifact Signing with an RFC 3161 timestamp, signs every file of the
release with Sigstore as that pipeline -
https://gitlab.com/Progressiverobot/hmailserver//.gitlab-ci.yml@refs/tags/v6.3.5, issuer https://gitlab.com -
into a <file>.cosign.bundle beside it, and checks every bundle with the server's own --verify-update before
anything is published. That identity is the one a 6.3.4 server trusts (SigstoreVerifier.cpp, unchanged since
6.3.4, and the verifier that check runs), so the live update of a 6.3.4 server is built to install this release, on
Windows and on Linux. A server from 6.2.28 to 6.3.3 trusts only the GitHub workflow that signed the releases up to
6.3.3, and as it stands its live update refuses this one: install 6.3.4 or this release by hand, and keep
UpdateAutoDownload off until then, or on Windows give it the GitLab signer as
UpdateFeed.md describes. What the release carries, and what the new package jobs
leave in CI only, is under Operations.

What changes on upgrade without a switch

  1. The Control Panel's sidebar is in the order a new administrator needs. Welcome and Dashboard come first,
    then a new group, Set up this server: the Setup checklist, which was External setup under Monitoring &
    troubleshooting, then Setting profiles and DNS records. Two groups are renamed - TLS & certificates is
    Certificates & encryption and Access & abuse protection is Sign-in & access - and Connections &
    protocols gains a Webmail page (Administration, below). The palette (Ctrl+K) still finds the checklist as
    External setup. A page's nav-<key> UI Automation id is unchanged; the navgroup- and navrail- ids of the
    new and the renamed groups follow their new headings, so a UI test that finds a group by its old id must be
    changed.
  2. The quarantine shows the HELO name, and groups. The Control Panel's Quarantine page and the Control Deck's
    Quarantine view gain a HELO column and group the held messages by the sender's domain unless told otherwise.
    Messages held before the upgrade have no HELO name recorded and are grouped with those that have no HELO
    domain. The Deck now asks before a delete with a Yes or No of its own whose default is No, as the Control Panel
    already did; it used the browser's confirm(), whose default is OK. It offers whitelist and blacklist only to a
    credential holding manage_settings, and a held message's headers and preview only to one holding
    view_mailbox, as the server requires (below).
  3. The webmail's keyboard. The message list is one Tab stop, where each row put its box, star and marker in
    the Tab order, and the list's keys reach what a row holds. Enter on a button in the mail view presses the
    button; it used to open the message under the list's cursor. A letter typed into the formatted signature is
    text, where c opened a new message. Escape closes every modal dialogue as its Cancel does and gives the focus
    back to where it was, the page under a dialogue cannot be reached until it closes, and menus close on Escape.
    The event and task editors close when the page changes. The compose window's Plain is Remove formatting,
    its tooltip's words. On a phone a row's importance marker is shown and not pressed; the message's More menu
    marks it.
  4. An invitation sent the way Outlook sends one is shown as an invitation. GET /api/v1/me/messages/{id}
    answers "invitation": true for a text/calendar part whose Content-Type carries parameters and which has no
    .ics name, where it answered false, and the webmail shows the invitation's card with Accept, Maybe and
    Decline (the fix is under IMAP, POP3 and the webmail).
  5. What a script sees. GET /api/v1/quarantine gives each message three more fields - helo,
    sender_domain and helo_domain - and four routes are new. Over COM, Quarantine gains Bulk (dispid 9)
    and QuarantinedMessage gains HeloName, SenderDomain, HeloDomain, ReadHeaders and ReadPreview
    (dispids 11 to 15), added to the existing interfaces; no existing member or dispid changes. A program built
    against 6.3.5's type library that calls one of them needs a 6.3.5 server.

Anti-spam, anti-virus and mail flow rules

  • Reviewing the quarantine (schema 6105; GitLab issue #1):
    • The HELO name the client gave is stored with each held message. A message held during the SMTP
      conversation records the session's own; one held later, at delivery - by a rule, a block list, an account's
      own threshold, the sandbox or impersonation protection - takes it from the Received header this server wrote
      when it accepted the message, and only when that header names this server, so a Received line the sender
      wrote is never read. Empty for a client that gave none, for a message that did not arrive over SMTP and for
      every message held before the upgrade.
    • Grouping: by the sender's domain, by the HELO name's domain or not at all, each group folding, the group
      with the newest message first, and every column sorting the messages inside the groups. The domain is the
      organization's - the registrable domain by the Public Suffix List - which the server works out, so that every
      page groups a message the same way.
    • Many at once: a box on every message, every group and the header, and four actions on a message, a group
      or the checked messages - release; delete; whitelist, then release; blacklist, then delete. Whitelist and
      blacklist write the lists that already exist and no third one: the sender's address on the server's allow
      and block list (the default), or the organization's domain as .example.com on the domain white and black
      list, matched on the envelope sender, or on the HELO name when the page is grouped by HELO domain. Several
      messages from one sender or domain make one entry, and an entry already there is changed rather than
      doubled. The dialogue first shows what the server would write (a dry run); a domain that is itself a public
      suffix (co.uk, a HELO of localhost) is written only after a box is ticked, and without it the server
      refuses with 409 and changes nothing. The entries are written before any message is acted on, so a message
      whose entry could not be written - the null sender, no HELO recorded, a full list - is left in the
      quarantine with the reason.
    • The headers and a plain-text preview of a held message, read without releasing it: the headers up to
      65,536 characters, and the preview up to 16,384, the text part or the HTML part with its markup, style sheets
      and scripts taken out. Nothing is rendered as HTML.
    • The Control Deck is level with the Control Panel: the same groups, columns, boxes, icons and dialogues, one
      request for the checked messages, a delete dialogue of its own with No as the default, and Remove expired.
      Against a server from before this release, the Control Panel releases and deletes one message at a time, and
      its whitelist and blacklist say the server needs upgrading.
    • REST: POST /api/v1/quarantine/bulk (1 to 1,000 ids and one action, with dry_run and
      confirm_public_suffix), POST /api/v1/quarantine/expire, and GET /api/v1/quarantine/{id}/headers and
      /preview. The list, the headers and the preview need view_quarantine, and the headers and the preview
      view_mailbox beside it, since they are the mail itself; bulk and expire need manage_quarantine, and a
      bulk that allows or blocks needs manage_settings beside it, since it changes who is let in for everyone.
      Every one of them is refused to a credential confined to named domains, as the quarantine's other routes are.
      COM: Quarantine.Bulk takes and answers the same JSON, and each QuarantinedMessage has HeloName,
      SenderDomain, HeloDomain, ReadHeaders() and ReadPreview(); Bulk, ReadHeaders() and
      ReadPreview() are the server administrator's, as the rest of the quarantine is over COM
      (SenderListsAndDigests.md).
  • A HELO that is an address has no domain. A client that says HELO 192.0.2.7, bracketed or not, and a sender
    someone@192.0.2.7, have no organization's domain: helo_domain and sender_domain over REST, and HeloDomain
    and SenderDomain over COM, are empty, the message is grouped with those that have none, and whitelisting or
    blacklisting it by domain leaves it where it is and says why: "The HELO name is an address, which the domain list
    does not name." for the HELO, and "The sender's address has no d...
Read more

hMailServer 6.3.4

Choose a tag to compare

@RainbowWizard-coder RainbowWizard-coder released this 18 Oct 05:24

Re-published on GitHub on 18 October 2026 from the GitLab release v6.3.4 of 2026-09-27. Each file below was checked against the SHA-256 that GitLab's package registry records for it before it was uploaded here.

hMailServer 6.3.4

The largest release this project has made: everything from 15 to 27 September 2026 - calendars, contacts and
passkeys in the webmail, administrator roles and an audit trail, eDiscovery and legal holds, PST import, mailbox
encryption at rest, storage compression and object storage, event scripts on Linux - with a fix for a password
that could run code on a Windows server with JScript event scripts, and fixes for the 52 defects an audit of the
server found before this release. Most of what is new is off until you switch it on. 6.3.4 is also the first
release built after GitHub suspended the project's account, and it has to be installed by hand.

Before you upgrade

  • The database moves from schema 6040 to 6104, in 64 one-way steps. Back up the database and the data
    directory first (Upgrading.md, Backup.md).
    Step 6101 adds two columns to the table that has a row for every stored message, which on a large store is not
    instant on every backend. On MySQL and MariaDB, step 6102 rebuilds every table as utf8mb4, which takes time on a
    large database. Steps 6041, 6101 and 6102 need MySQL 5.7.9 or MariaDB 10.2.2 or later and the ALTER privilege
    on the database; on an older server the upgrade stops at step 6041 with error 1071, having changed nothing. Two
    rows the old collation told apart and the new one does not - on MySQL 8.4, two names that differ only in an
    emoji; on MariaDB 11.8, two names in one address book that differ only where one has a German sharp s and the
    other an s - stop step 6102 with error 1062 until one of them is removed, and a step stopped part of the way is
    finished by running it again.

  • Change hMailServer.ini's [Settings] after the upgrade, not to prepare it. From 6.3.4 the settings the
    database holds win over the file: at the first start, a line changed since the old server last started is taken
    for an edit and put back (HM5804).

  • Install 6.3.4 by hand, on every server. Its installer carries an Authenticode signature but no Sigstore
    bundle: it was built and signed by hand, off GitHub, before the GitLab pipeline's release jobs have run. That
    pipeline is to sign the releases from 6.3.5. A server's live update, of any version, that is offered 6.3.4 says
    it "carries no Sigstore bundle for its installer, so it cannot be verified", and downloads nothing. On Windows run
    hMailServer-6.3.4-x64.exe. On Linux (x86-64 only) install the .deb with apt on Ubuntu 26.04, where it is
    built, or Ubuntu 24.04, or the .rpm with dnf on Fedora 43 or 44 or Enterprise Linux 10. The .deb asks for
    glibc 2.38 or later, so it does not install on Debian 12; the .rpm does not install on Enterprise Linux 9,
    whose glibc and libstdc++ are older than it asks for.

  • Set again every password with a character above U+00FF. Before 6.3.4 a password of Cyrillic, Greek or CJK
    letters, say, was hashed over NUL bytes (Windows) or question marks (Linux), so any other password of its length
    and shape opened the account. 6.3.4 hashes over UTF-8 and refuses such a stored hash, to its own password too, on
    every password sign-in; the application log names the account when its user tries ("its stored password hash
    was made before 6.3.4 from a password with a character above U+00FF"). Set those passwords again soon after the
    upgrade - in the Control Panel, over COM or REST, and the administrator's own with
    hMailServer.exe --set-admin-password (hmailserver --set-admin-password on Linux); the webmail's own
    password change asks for the old password and is refused as a sign-in is. Until then a SCRAM-SHA-256 client
    that derives its key from those NUL bytes or question marks still opens a PBKDF2 one, and on Linux the password
    with ? for each of those characters still opens it on any path. A password whose characters are all in
    Latin-1 but not all ASCII signs in as before by PLAIN, LOGIN and the other password sign-ins, and the first such
    sign-in makes its hash again over UTF-8; until then it does not serve SCRAM-SHA-256. ASCII passwords are unchanged
    (SecretsAtRest.md, "A password outside Latin-1").

  • A server on 6.2.28 to 6.3.3 still looks for updates at GitHub, which has answered 404 since
    18 September 2026. For as long as it stays on that version, add this under [Settings] in its
    hMailServer.ini, then restart the service, and its update check works again:

    UpdateFeedUrl=https://updates.progressiverobot.com/releases.json

    Keep UpdateAutoDownload off on such a server until it has 6.3.4: once a release signed on GitLab exists, it
    would download that installer at every check and refuse it. Once 6.3.4 is installed the server reads that feed
    without being told; the line can then go, cleared in the Control Panel, with
    DELETE /api/v1/settings/ini/UpdateFeedUrl or, on Linux, with hmailserver --set-setting UpdateFeedUrl=, not in
    the file. 6.3.4 trusts both the old GitHub signer (for releases up to 6.3.3) and this project's GitLab pipeline - at
    the project's present path, and at the group hmailserver/hmailserver it is to move to, where the certificate
    must carry the project's id whatever the settings say - so from 6.3.5 its live update can work again, before the
    move and after it; a server left on 6.3.3 or older cannot install a GitLab-signed release by its live update
    unless it is given the override, on Windows only, and its costs, that the feed's document describes
    (UpdateFeed.md).

What changes without a switch, in short (the full list is the first part of 6.3.4's section in
CHANGELOG.md):

  • The database becomes the settings store: the [Settings] section of hMailServer.ini is taken in at the
    first start, and from then on a line edited in the file is put back (HM5804). Change settings in the
    Control Panel, over COM or REST, or with hmailserver --set-setting on Linux.
  • SPF is RFC 7208: mail from 127.0.0.0/8 and ::1 no longer passes unconditionally, so a content filter that
    hands mail back to the server should authenticate, or connect from an IP range with anti-spam off.
  • The audit trail and the alerts are on (nothing is mailed until a recipient is set); compromised-account
    detection runs in watch mode; a destination that asks the server to slow down is paused.
  • MySQL and MariaDB connections use TLS whenever the database server offers it, and SQL Server sessions are
    encrypted through the Microsoft OLE DB Driver 18 or later (MSOLEDBSQL) and, beside a failover partner, SQL
    Server Native Client (SQLNCLI), both without checking the certificate unless [Database] TlsMode=verify-full;
    through the older SQLOLEDB, used where that driver is not installed and no failover partner is set, only the
    login is encrypted unless TlsMode is require or verify-full
    (DatabaseTls.md).
  • The administrator password is hashed again as PBKDF2 at the first sign-in; the installer had written an
    unsalted MD5.
  • A one-time code is taken once, over COM and REST. A script that sent the administrator's password and a code
    with every REST request now signs in once (POST /api/v1/session) or uses an API key; otherwise only its first
    request in each half minute is accepted.
  • A route or the SMTP relay whose host is on OutboundOAuth2Hosts sends the server's token (AUTH XOAUTH2) over
    TLS only: without TLS the delivery fails with a temporary 450 4.7.0, and HM5912 says to require TLS or
    STARTTLS.
  • A COM change to a route, relay, DNS black list, SURBL server, remote-domain policy, server message, blocked
    attachment, SSL certificate or group is in effect only after Save(). Scripts that relied on the old way
    must save.
  • IMAP follows the RFCs where Dovecot's imaptest found it did not: some answers change from BAD to NO, and
    an APPEND stores the literal byte for byte.
  • A restore refuses an archive with an absolute path, a .. or a link in it; the installer's 7-Zip is 26.03.
  • A rule's Run function action must name a plain function; ISO-8859-1 mail is decoded as windows-1252.
  • Addresses collected from what a person sends are suggestions, under Other contacts in the webmail, and CardDAV
    serves only the contacts a person kept.
  • A domain may no longer be named as one of the directories the server keeps its own files in (protected,
    confidential, recoverable, discovery, quarantine, files, lists, blobs and the rest); one that
    already is is reported at every start as HM7597 and on the setup checklist: rename it
    (SetupChecklist.md).
  • Only a new installation gets STARTTLS on 25, 587, 110 and 143 with a self-signed certificate, TLS
    required for sign-in from outside, the Windows service as NT SERVICE\hMailServer, and a stored-secrets
    key. An upgrade keeps its listeners, its service account and its secrets as they were; sealing the stored
    secrets starts once an administrator runs --create-stored-secrets-key, which the setup checklist offers
    ([SecureDefaults.md](https://gitlab.com/Progressiverobot/h...
Read more

hMailServer 6.3.3

Choose a tag to compare

@RainbowWizard-coder RainbowWizard-coder released this 18 Oct 05:23

Re-published on GitHub on 18 October 2026 from the GitLab release v6.3.3 of 2026-09-15. Each file below was checked against the SHA-256 that GitLab's package registry records for it before it was uploaded here.

Re-published on GitLab on 24 September 2026 from the GitHub release of 15 September 2026 (2026-09-15 01:02:52 UTC). Issue, pull request and discussion numbers below are GitHub's.

hMailServer 6.3.3

A message larger than 60,000 bytes sent with CHUNKING to Gmail, iCloud, Outlook.com or Postfix stalled after its first buffer and the remote timed out - every such message since outbound BDAT arrived - and does not now; the webmail was rebuilt to the shape of Gmail and Outlook.com and gained tabs, mute, pop-out windows, search history and twelve more search operators; the account's address book is served over CardDAV to phones and desktop clients; the browser Control Deck is measured against the desktop Control Panel and moved a long way toward it; the Linux regression suite's route backlog is largely lifted; and a live update started from an open Control Panel no longer fails on its own files.

Read this first if you are upgrading from anything older than 6.3.1 (GitHub issue 263). 6.3.2 could not upgrade a database whose schema was older than its own: the guard added in 6.3.2, which makes a database the server has refused answer COM with the refusal instead of crashing, covered the whole Settings object, and DBUpdater reads the script directory from it before it runs the first script - so every upgrade from 5.x or 6.2.x stopped with "The server has not loaded its configuration" and left the database untouched. 6.3.3 upgrades such a database in one go; nothing in the database was changed by the failed attempt. The settings object answers its directories on a refused database again, everything that lives in the configuration is refused with the reason, DBUpdater derives the script directory from its own location if the server cannot answer, and a regression test walks DBUpdater's path over COM against a database the server has refused.

Read this too if you run 6.3.1 or 6.3.2 and use the Control Panel's live update. The first real update, 6.3.1 to 6.3.2, failed with the installer's exit code 5 because the Control Panel that started it kept its own files open. That is fixed here - but the helper that runs a live update is the one already installed, so an installation on 6.3.1 or 6.3.2 has to be updated by hand once: close the Control Panel, run this installer. Live updates work from then on.

Delivery

An outbound BDAT chunk larger than one send buffer no longer stalls (GitHub issue 261). The connection sends a message 60,000 bytes at a time; the SMTP client armed the read for the reply as soon as the BDAT command - or, with PIPELINING, the envelope - had been queued, and the second buffer of the chunk was then queued behind that read in the connection's operation queue, which starts only the operation at its head. The read could not complete while the remote waited for the bytes behind it, so nothing sent them, and the remote gave up after its own timeout (iCloud's 421 after five minutes, in the report). Every message over 60,000 bytes to a server advertising CHUNKING has stalled this way since outbound BDAT arrived in 6.2.28; a message that fit one buffer went, which is why short ones did; DATA never met it, because its body streams only after the 354. The operation queue runs once more after a read has started, so a write behind it goes at once. Two regression tests relay a 222 KB message over BDAT, with the envelope pipelined and without. Until you upgrade, OutboundChunking=0 in hMailServer.ini is the workaround.

The full-text indexer no longer reports an error for a message deleted before its terms were saved. On PostgreSQL the foreign key refuses the terms of a row that is gone (SQL Server Compact accepted them); the message is logged at debug level and skipped, since there is nothing left to index.

The webmail

Rebuilt to the shape of Gmail and Outlook.com. The page is real files now (Portal.html, Portal.js), embedded into the binary at build time. A top bar with one search box and its options panel; a navigation column with the system folders by their designation, then the account's folders, labels, Held mail, Contacts, Scheduled and the storage meter; a list whose row is a checkbox, a star, an avatar, the sender's name, the subject and the first line of the text, an attachment mark and a time, with archive, delete and mark-read under the pointer; a reading pane on the right, below, or off; a toast with Undo after every move; the keys a mail client has (c, r, a, f, s, o, u, /); settings behind the gear; the same page on a phone; light and dark.

Writing. The compose window docks at the bottom right, minimises to its bar or opens full; a reply, reply to all or forward is written under the message it answers, with the earlier messages of the conversation above it as cards. An attachment reminder asks once before a send whose text speaks of an attachment and carries none. A message, or the message being written, pops out into a window of its own.

The list. A row dragged onto a folder, with undo. A right-click menu on a row (open, archive, junk, delete, read, star, pin, block, sweep). A pin keeps a message at the top of its list (the $Pinned keyword, the way every mail program sees it). Block this sender writes a rule that files the sender into Junk; Delete all from this sender sweeps the folder. Shift-click selects a range and ctrl-click one row, as every desktop client has them. A selection can take in every message of the folder, or of the open tab.

Mute, and the inbox in tabs. A muted conversation leaves the inbox, its messages carry $Muted, and a rule the page writes files whatever answers any of them into the archive; Undo takes all of it back. The inbox comes in tabs - Primary, Social, Promotions, Updates and Forums the way Gmail sorts them, or Focused and Other the way Outlook does, or one list - the server saying which from the headers alone (the sender's domain, List-Post, List-Unsubscribe, Precedence, Auto-Submitted), the reader overruling it per sender from the row's menu.

Search. The last ten searches are offered under the empty box (kept in this browser, forgotten at sign-out), and a contact's name typed there completes to from:<address> from the address book. Fourteen more operators, parsed by the server beside the ones it had: cc:, bcc:, filename:, larger:, smaller:, older_than:, newer_than:, is:muted, is:pinned, category:, has:link, in_reply_to:, a -word to exclude, and OR. The reference is hmailserver/docs/WebmailShortcuts.md.

Follow-up, nudges, quick steps, clean-up. A flag can carry a due date - today, tomorrow, next week or a date - kept as $FollowUp and a $Due-YYYY-MM-DD keyword on the message itself, so other clients still see a flag and a move keeps the date; the row shows it, the Starred view sorts by it, and a reminder comes once a day. Nudges say "Received N days ago. Reply?" on a message that asked and "Sent N days ago. Follow up?" on one nothing answered; a preference turns them off. Quick steps are buttons a reader defines - move, mark read, label, forward, in one press, on the digit keys. Clean up conversation deletes the messages whose every line a later message quotes, keeping the newest, the unread, the starred and those with attachments, with Undo.

Everything above is in the twenty languages the page speaks, and the harness that executes the page's script runs 224 checks on it in CI.

CardDAV

The account's address book, on phones and desktop clients (RFC 6352). On the web services listener: /.well-known/carddav redirects to /dav/, a PROPFIND there answers the principal, the principal the address-book home, and the home holds one book, Contacts - the address book the webmail keeps and completes recipients from. The card a client sends is the card it reads back: the card itself is stored beside the contact (schema 6040), vCard 3.0 or 4.0, both advertised, and an edit made in the webmail is written into the stored card with the UID and the telephone number the phone gave it left alone. HTTP Basic as the account or an application password, over HTTPS only, with the IMAP logon's lockout and auto-ban; addressbook-query, addressbook-multiget and sync-collection reports; ETags with If-Match and If-None-Match. iOS, macOS Contacts, DAVx5 and Thunderbird speak it. The web services HTTPS listener has to be on (WebServicesHttpsPort).

The Linux control panel

Measured. build/check-deck-parity.py counts every field the desktop Control Panel writes against the REST API and the browser Control Deck, from the sources; hmailserver/docs/DeckParity.md is its report. Of 330 properties, 240 were writable over REST and 153 reachable from a Deck view at the start of 14 September; 328 and 322 by its end, the two not writable being groups and their members.

Moved. New write routes: the anti-virus settings as a group (/api/v1/settings/antivirus), sixteen more account fields and nine more domain fields on their PUTs, the distribution list's settings and a PUT for it, DNS blacklists, SURBL servers, white-list addresses, blocked senders, incoming relays, blocked attachments and the greylisting white list as resources, the cache group's eight ceilings and lives, an IP range's expiry, abort_spam_flagged on a rule's forward and reply, user_interface_language, and - under an account's address, for the administrator - its application passwords, its folders' permissions and its messages. The Deck gained a harness of its own (build/check-deck-script.py, 292 checks, in CI), full domain editing, an IP-ranges view with expiry, fetch-account and backup views, the account editor in f...

Read more

hMailServer 6.3.2

Choose a tag to compare

@RainbowWizard-coder RainbowWizard-coder released this 18 Oct 05:23

Re-published on GitHub on 18 October 2026 from the GitLab release v6.3.2 of 2026-09-13. Each file below was checked against the SHA-256 that GitLab's package registry records for it before it was uploaded here.

Re-published on GitLab on 24 September 2026 from the GitHub release of 13 September 2026 (2026-09-13 08:22:25 UTC). Issue, pull request and discussion numbers below are GitHub's.

hMailServer 6.3.2

The webmail became a client people would choose, Kerberos single sign-on arrived on all three protocols, an auto-ban now reaches the operating system's firewall, the Linux packages install on the next distribution release, and thirty-seven binaries left the repository. Every change below went in through a pull request with the full Windows regression suite run on the built server, and the Linux build compiled every translation unit on every push.

The webmail

The self-service portal at /portal shipped in 6.3.0 with a mailbox page. Fifteen waves later it is a mail client. Everything it does is over /api/v1/me, answers to the account's own credentials and to nothing else, and is described in the OpenAPI document at /api/v1/openapi.json.

Reading. Conversations grouped by thread. Archive, Junk and Trash as one-key actions (e, !, #), with a move into or out of Junk taking the same path as an IMAP MOVE, so the spam filter learns from it. A search written the way a reader writes one: words that must all be found, quoted phrases, from:, to:, subject:, has:attachment, before:, after:, in:, is:unread, is:flagged and the rest, and label: for labels. Labels are IMAP keywords: the server stores them (schema 6036), STORE, FETCH, SEARCH, APPEND, COPY and a Sieve addflag all carry them, and every IMAP client sees the same labels the page shows in colour. Image attachments are shown under the message and a PDF is previewed in a frame of its own, from bytes the page fetched itself. A warning sits above a message whose link text names one site and goes to another, or whose sender is named like a contact but writes from another address. Shared and public folders appear under a heading naming their owner.

Writing. A formatting bar and an editor whose HTML is rebuilt from an allowed subset before it goes, so a message is sent as text beside HTML. A From picker offering exactly the addresses the server would accept from the account - its own, its aliases, and the accounts whose INBOX grants it the post right - checked by the same rule SMTP submission applies. A signature. Templates with {first_name}, {subject} and {date} filled in. Undo send, for up to thirty seconds. Read receipts asked for and answered (RFC 8098). One-click unsubscribe (RFC 8058), made only to a public address: the server resolves the list's host and refuses loopback, private, link-local and every other non-public address before it connects. Send later, and snooze until a time, both kept on the server (schema 6034) and run by a task every minute. To, Cc and Bcc complete from an address book (schema 6032) that collects every recipient the account writes to once. A file above the size the domain allows goes as a link that expires and can take a password, uploaded in chunks and served from /files/{token} (schema 6035); an administrator sets the threshold and the lifetime server-wide or per domain.

S/MIME, in the browser. The page signs, verifies, encrypts and decrypts with the Web Crypto API and nothing else. A certificate and its key come in from PEM, DER or a PKCS#12; the private key is wrapped in the browser under a key derived from the account password and stored on the server so wrapped (schema 6037) - the server cannot open it. The certificates of correspondents are kept from the signed messages they send. A signed message shows a badge beside the SPF, DKIM and DMARC ones; the chain is checked against the system's roots (the Windows ROOT and CA stores, the distribution's bundle on Linux). What the page signs is what arrives: the entity goes to the server byte for byte under the server's own headers. Proven against OpenSSL in both directions on every push. Not in this release, and said so where it is met: 3DES content, EC key agreement for encryption, legacy PKCS#12 encryption, OpenPGP.

The pages. Settings - name, signature, theme, density, notifications, and the language: the seventeen the Control Panel speaks, and Greek, Korean and European Portuguese besides, beside English. The keyboard map (?) lists every key the page answers, l for the Label menu included, and the keys and the search operators are documented on one page, hmailserver/docs/WebmailShortcuts.md; README shows the inbox, a message open, and the Control Panel's Welcome page. Away - out of office, forwarding, and what is waiting to be sent later or to come back from snooze. Filters - a rules editor that writes Sieve, or the script by hand, left alone when it was written by hand. Contacts. Storage - the quota, every folder's size, the largest messages, and a clean-up of Trash and Junk by age. Files - the links sent, their downloads, their expiry. Security - app passwords, made only after the account's own password is given again; browser sessions, ended one at a time or all but this one; support access an administrator may be allowed for a while, off unless the user turns it on, with every request of it logged as the administrator acting as the user; and the S/MIME key store.

The page itself. It installs as an app, keeps the inbox listing and the last thirty opened messages for reading without a connection, and queues a send that fails for want of one. An administrator gives it a name, a logo and an announcement, server-wide or per domain (PUT /api/v1/portal/branding). It imports .eml files and exports a folder as mbox. It is worked with a screen reader: landmarks, a skip link, focus that follows a change of address. It sends the password once, holds nothing in memory and allows no inline script.

Authentication

SASL GSSAPI (RFC 4752) on SMTP, IMAP and POP3, on Windows. A Kerberos client presents a ticket for this server's service principal, the server proves itself back, and the client's principal names the account - the one an administrator linked to that directory user, else the one addressed user@realm. Off unless GssapiEnabled=1 in [Settings]; the credentials are the process's own on a domain-joined host, or a service account named by GssapiServiceAccount and GssapiServicePassword. Proven end to end against a Windows Server domain controller: SMTP AUTH GSSAPI accepted and a message queued, IMAP AUTHENTICATE GSSAPI accepted and the message read back.

An auto-ban reaches the operating system's firewall. Until now a banned address was a row the listeners consulted at accept time: the operating system accepted the connection and the server dropped it. With AutoBanFirewall=1, Windows gets an inbound block rule per banned address in Windows Defender Firewall, in a rule group of its own; Linux gets a packaged hook that keeps an nftables set, and a fail2ban filter and jail. AutoBanCommand runs anything else, and AutoBanNeverBan lists the addresses that are never banned. All three are off as shipped.

Making an app password proves the person, not the request. The request carries the account's own password, and an app password is never accepted for it.

A SURBL server's answers are judged the way a DNSBL's are. Each SURBL server has an expected result (SURBLServer.ExpectedResult, the Control Panel's SURBL editor; schema 6038) in the DNSBL syntax - 127.0.1.0-255, 127.0.0.2*, ranges and wildcards - and only an answer it names is a listing. With none set, any answer counts except the codes in 127.255.255.0/24, with which the Spamhaus zones refuse a query - from a public resolver, or too many of them - and which were taken as listings until now: a server resolving through 8.8.8.8 tagged every message carrying a link as spam (GitHub discussion 167). The debug log says what the zone answered and what was made of it.

Linux

The packages install on the next distribution release. The 6.3.1 .deb depended on the builder's exact Boost sonames and would not install on Ubuntu 26.04. Boost is linked statically now (Boost.Regex header-only, so no ICU dependency comes with it), and the package-install job installs the .deb on Ubuntu 26.04 in a container on every run.

A container image on GHCR from every tag. The run's own .deb on ubuntu:24.04 pinned by digest, run as its own user with cap_net_bind_service on the binary. The entrypoint writes the database section, the REST listener and the administrator password from the environment (with _FILE variants for the two secrets), creates or upgrades the database, and starts the server. The image is smoke-tested beside a PostgreSQL over TLS before it is pushed.

The Linux build is green on every push again. Three functions the webmail waves used on Windows only - _wtoi, wide-path file streams, _mkgmtime - have POSIX counterparts now, and the translation-unit census runs before every wave's pull request.

Database

The 6029 to 6030 upgrade step sweeps parents before children. 6.3.1 named this as known and unfixed: on a database holding orphaned rows, the step could re-orphan rows it had already cleaned and then refuse its own foreign keys. It is fixed in all four backends, and the reason it could ship at all is gone: a gate now executes a schema upgrade on a seeded database on every push, winding a created database back to 6029 by undoing every later step and upgrading it forward again.

The fresh-schema create scripts drop dependent tables before hm_accounts in every dialect, so recreating a database that already holds them no longer fails on the foreign keys; and the contacts index is unique on (account, address), so two requests rac...

Read more

hMailServer 6.3.1

Choose a tag to compare

@RainbowWizard-coder RainbowWizard-coder released this 18 Oct 05:22

Re-published on GitHub on 18 October 2026 from the GitLab release v6.3.1 of 2026-09-11. Each file below was checked against the SHA-256 that GitLab's package registry records for it before it was uploaded here.

Re-published on GitLab on 24 September 2026 from the GitHub release of 11 September 2026 (2026-09-11 03:44:22 UTC). Issue, pull request and discussion numbers below are GitHub's.

hMailServer 6.3.1

This is the first release of this project to carry an Authenticode signature. The Windows elevation prompt names Progressive Robot Ltd instead of Unknown publisher, and an enterprise policy that refuses unsigned binaries outright stops being a wall.

Nothing in the server changes. The compiled server differs from 6.3.0 by its version stamp and one comment line; everything else in this release is the path a release travels - the workflows that sign and verify it, found wanting while preparing to use the certificate for the first time - and three documentation corrections.


The installer is signed

The installer is signed with Azure Artifact Signing, against a certificate profile issued to Progressive Robot Ltd after Microsoft's identity validation. The account, the validation and the profile were arranged on 10 September 2026, after 6.3.0 had shipped. A published release here is immutable, so 6.3.0 could not be signed retroactively and never will be.

What it changes. The elevation prompt reads the publisher's name. And for administrators on managed estates - a great many of this server's users - a policy that refuses unsigned binaries no longer refuses this one.

What it does not change, said plainly: SmartScreen still warns. Microsoft's own comparison puts a signed installer in the same row as an unsigned one, flagged as unrecognised until reputation accumulates, and reputation attaches to a file that does not change - which a new 80 MB installer every few weeks never is. An EV certificate would not help; Microsoft removed EV's SmartScreen bypass in 2024. Expect the same Windows protected your PC screen, now with the publisher's real name on it.

Only the Windows installer is Authenticode-signed. There is no Authenticode for a .deb, an .rpm or an AppImage. Sigstore is unchanged and remains the check that means something for every asset on the release: each carries a .cosign.bundle beside it, and cosign verify-blob against that bundle verifies it.

One setting becomes usable. UpdateRequireAuthenticode=1 has existed since 6.2.28 and, until now, made the server's own update path refuse every release of this project, because none carried a signature: the check is WinVerifyTrust on the downloaded installer, and an unsigned file is refused with the file carries no Authenticode signature. From 6.3.1 the installer it downloads carries one. The check is Windows-only: on Linux there is no Authenticode to verify, the server says so rather than reporting a pass, and updating is the package manager's job.

The release path

Releases here are immutable, so each of these could have put out a permanently wrong release.

  • The Authenticode gate was checking the wrong four of the six settings it guards. It asked for the three Azure secrets and ARTIFACT_SIGNING_ACCOUNT - the one input the signing action marks optional - and never asked about ARTIFACT_SIGNING_ENDPOINT or ARTIFACT_SIGNING_PROFILE, the two it marks required. Five half-configured states got through, each a state somebody passes through while filling in three repository variables one at a time; the action throws on an empty endpoint, and the cosign job declares a dependency on this one, so a release that tripped it would have got no Authenticode signature and no Sigstore bundle on any of its twenty assets. There are three outcomes now: none of the six set is the ordinary case and stays a silent no-op, all six signs, and anything in between stops and names what is missing while the release can still be fixed. The six values, and the tag, reach the shell through the environment rather than being pasted into the script text, because an expression pasted into a script is executed as syntax if it holds a quote.
  • The release is verified as it is attached, not as it was signed. The old check looked only at the job's own copies. A draft stays mutable afterwards, and four things upload over it with --clobber: a re-run of the Linux publish job, the SBOM workflow, a second Authenticode run, and the hand-recovery commands the Linux job prints into its own log. The workflow now ends by re-downloading the release exactly as it stands and verifying every asset against its attached bundle, in both directions - an asset with no bundle, and a bundle whose asset has gone.
  • What a release must carry is asserted before a certificate is spent on it. The only completeness check was "did we sign at least one thing", and the SBOMs were named nowhere but in comments - which is how 6.2.22-pre4 came to be published with an installer and no SBOM at all. Both SBOMs are a hard failure now, in the Authenticode job rather than the signing job, so an incomplete release stops before a code-signing certificate has been spent on it. The Linux sums file and the four package names stay warnings, deliberately: a Linux packaging failure must not hold back the Windows installer every server in the field is waiting for.
  • An RFC3161 countersignature is required, and is checked. These certificates live about seventy-two hours. Get-AuthenticodeSignature answers Valid for a signature carrying no timestamp for as long as the certificate has not expired, which it never has seconds after signing - so an untimestamped installer would look perfect on the day and stop verifying on every machine in the field three days later, on a release that cannot be corrected. The countersignature is proved before the release asset is replaced, so a timestamping failure costs a re-dispatch and nothing else.
  • Verification can no longer pass vacuously. A glob that matched nothing used to verify nothing and succeed. Both verification steps now refuse to pass having checked zero assets, and compare what they verified against what the signing step reported.
  • Runs are serialised per tag. Two dispatches for one tag could interleave, and one run's bundle could end up describing bytes the other had already replaced. They queue now, and are not cancelled: a run stopped between signing and uploading would leave assets with no signature at all.
  • The SBOM workflow refuses to overwrite an SBOM that has already been signed, because cosign signs the bytes attached when it runs and Syft writes a fresh document identifier every time, so a re-upload after signing leaves a signature that verifies against nothing. It also proves the tree it describes is the tag's own commit before Syft runs - a bill of materials describing a tree the release was not built from is the one thing an SBOM must never do.
  • The installer smoke test can read a draft release, which is the only kind it is ever pointed at. It asked for contents: read, and GitHub shows an unpublished release only to a token with push access, so every dispatch against a draft answered "release not found" - which made the documented order, green before publication, impossible rather than merely awkward. It asks for contents: write now, and writes nothing.
  • The Linux package-install check runs under sudo, like every other command in its step. The package makes /etc/hmailserver 0750 root:hmailserver on purpose, because the configuration holds credentials, so a bare stat answered "Permission denied" and under set -e took the job with it. That is why 6.3.0's tagged run attached no Linux packages and they had to be attached by hand.

All of the above was verified by executing the real run bodies against the live 6.3.0 asset list with gh and cosign stubbed - the twenty-asset release, a re-run over already-attached bundles, a Windows-only release, a pre-release tag, the hand-recovery shape, a release with no SBOMs, an orphaned bundle, an asset excluded from signing by design, and an empty download - and the gate across fifteen configurations, including whitespace-only values and five hostile ones, none of which executed anything. The Authenticode path itself was rehearsed end to end on a throwaway copy of the 6.3.0 installer before this tag was cut: a valid, countersigned signature naming Progressive Robot Ltd, attached to nothing.

Documentation

  • The README offers the Linux packages on its download line, where a reader looks for a download, rather than 140 lines further on in the Linux section. The headline of 6.3.0 was that this server runs on Linux at all.
  • Two files named 6.2.29, a version that does not exist and never will: the [Directories] header comment in the server source, and the relocating guide's note about when a relative path began to resolve against the program folder. Both features shipped in 6.3.0 and both now say so. Comment and prose only.
  • The release checklist gives ARTIFACT_SIGNING_ENDPOINT as a full URI rather than a bare host, which is the form the signing action documents and one of the two values that used to pass the old gate and then fail inside the action, and it says the six settings are required together.

Known, and not fixed here

The orphan sweep in the 6029 to 6030 upgrade step runs children before parents. Before that step adds seventeen foreign keys, it deletes rows whose parent is gone. Three of the parent tables are themselves pruned by those deletes, and each one's children are cleaned earlier, against a parent that has not yet lost its rows - so pruning an orphaned account, fetch account or distribution list re-orphans rows nothing revisits, and the constraint that follows is refused. It affects only an upgrade from a schema below 6030 on a da...

Read more

build-inputs-1: third-party build inputs (not a server release)

Choose a tag to compare

Re-published on GitHub on 18 October 2026 from the GitLab release build-inputs-1 of 2026-09-11. Each file below was checked against the SHA-256 that GitLab's package registry records for it before it was uploaded here.

Re-published on GitLab on 24 September 2026 from the GitHub release of 11 September 2026 (2026-09-11 04:26:16 UTC). Issue, pull request and discussion numbers below are GitHub's.

Third-party binaries the build fetches instead of carrying in git. Each is the exact file that was committed until 11 September 2026, recorded by SHA-256 in hmailserver/docs/third-party-binaries.json, which is also where its provenance, licence and use are written down. build/get-installer-binaries.ps1 downloads these, verifies them against that manifest, and places them where the installer script expects them; the same script gathers the MSVC runtime from the build machine's Visual Studio. A release rather than a URL at the vendor, because two of the three have no stable first-party download left: Microsoft withdrew SQL Server Compact 4.0 SP1 from the Download Center, and 7-Zip's standalone console ships only inside a .7z archive that needs 7-Zip to open.

Asset SHA-256 What it is
7za-19.00.exe 8117e40ee7f824f63373a4f5625bb62749f69159d0c449b3ce2f35aad3b83549 7-Zip 19.00 standalone console, Igor Pavlov, LGPL-2.1-or-later; from https://www.7-zip.org/a/7z1900-extra.7z
mariadb-connector-c-3.4.9-win64-client.zip a23e96857e7e02fd26c9317638655c4d3da3f11d0ac2f40ae310842a5169cc8d MariaDB Connector/C 3.4.9 client (libmysql.dll) and its ten authentication plugins, MariaDB Corporation AB, LGPL-2.1-or-later; the per-file hashes are in the manifest
SSCERuntime_x64-ENU.msi b2d2aba2102d0fa8915421b1e0b850f7c538983eed06e89c358cc2a0c578f958 Microsoft SQL Server Compact 4.0 SP1 x64 runtime (MSI built 2012-04-06), redistributable under its licence; the installer's built-in database option

This release is immutable, like every release here: a changed or added input goes into build-inputs-2.


Assets

File Size SHA-256
7za-19.00.exe 1,152,000 8117e40ee7f824f63373a4f5625bb62749f69159d0c449b3ce2f35aad3b83549
Progressiverobot-hmailserver-attestation-46764040.sigstore.json 3,417 4d58475f49eac111919c67a29bff14545c77990868799454dd6ce89a9533b19b
SSCERuntime_x64-ENU.msi 10,609,664 b2d2aba2102d0fa8915421b1e0b850f7c538983eed06e89c358cc2a0c578f958
mariadb-connector-c-3.4.9-win64-client.zip 300,212 a23e96857e7e02fd26c9317638655c4d3da3f11d0ac2f40ae310842a5169cc8d

These are the files published with the GitHub release, byte for byte, re-hosted in this project's package registry. The hashes above were computed from them on 24 September 2026. The Windows installer of this release was not Authenticode-signed (Authenticode signing began with 6.3.1). GitHub made no signature for releases before 6.2.19, so there is no independent record of these bytes beyond this table.