Documentation and usage example for sieve script
This commit is contained in:
parent
99bc6b7429
commit
7a999292fd
3 changed files with 92 additions and 0 deletions
|
@ -4,6 +4,10 @@ version = "0.1.0"
|
|||
edition = "2021"
|
||||
|
||||
rust-version = "1.68.2"
|
||||
description = "Convert an alias file to a sieve script for stalwart-mail"
|
||||
readme = "README.md"
|
||||
license = " AGPL-3.0-only"
|
||||
keywords = ["mail", "sieve", "alias", "stalwart"]
|
||||
|
||||
[dependencies]
|
||||
fqdn = {version = "0.4.2", features = ["domain-label-length-limited-to-63", "domain-name-without-special-chars"]}
|
||||
|
|
80
packages/alias-to-sieve/README.md
Normal file
80
packages/alias-to-sieve/README.md
Normal file
|
@ -0,0 +1,80 @@
|
|||
This script converts an alias file to a sieve script for [stalwart-mail](https://stalw.art/).
|
||||
|
||||
## Usage
|
||||
Given an alias file [`testdata/example.aliases`](testdata/example.aliases) that contains lines of redirects of the form localpart with optional `@fqdn` followed by a space followed by a list (space or comma+space separated) list of destinations that consist of a localpart and optionally an `@fqdn`.
|
||||
If you don't define a fqdn along any of the addresses, the default domain from your commandline input will be appended.
|
||||
|
||||
An example using the testdata directory of this repository:
|
||||
```shell
|
||||
$ ./alias_to_sieve testdata/example.aliases example.com
|
||||
```
|
||||
```sieve
|
||||
require ["variables", "copy", "vnd.stalwart.expressions", "envelope", "editheader"];
|
||||
|
||||
let "i" "0";
|
||||
while "i < count(envelope.to)" {
|
||||
let "redirected" "false";
|
||||
if eval "eq_ignore_case(envelope.to[i], 'cali@example.com')" {
|
||||
addheader "Delivered-To" "cali@example.com";
|
||||
redirect :copy "camilia@example.com";
|
||||
|
||||
deleteheader :index 1 :is "Delivered-To" "cali@example.com";
|
||||
let "redirected" "true";
|
||||
}
|
||||
if eval "eq_ignore_case(envelope.to[i], 'camila@example.com')" {
|
||||
addheader "Delivered-To" "camila@example.com";
|
||||
redirect :copy "camila@example.edu";
|
||||
|
||||
deleteheader :index 1 :is "Delivered-To" "camila@example.com";
|
||||
let "redirected" "true";
|
||||
}
|
||||
if eval "eq_ignore_case(envelope.to[i], 'jaiden@example.com')" {
|
||||
addheader "Delivered-To" "jaiden@example.com";
|
||||
redirect :copy "jaiden@example.edu";
|
||||
|
||||
deleteheader :index 1 :is "Delivered-To" "jaiden@example.com";
|
||||
let "redirected" "true";
|
||||
}
|
||||
if eval "eq_ignore_case(envelope.to[i], 'priscilla@example.com')" {
|
||||
addheader "Delivered-To" "priscilla@example.com";
|
||||
redirect :copy "baldwin@example.org";
|
||||
|
||||
deleteheader :index 1 :is "Delivered-To" "priscilla@example.com";
|
||||
let "redirected" "true";
|
||||
}
|
||||
if eval "eq_ignore_case(envelope.to[i], 'root@example.com')" {
|
||||
addheader "Delivered-To" "root@example.com";
|
||||
redirect :copy "baldwin@example.org";
|
||||
redirect :copy "jaiden@example.edu";
|
||||
|
||||
deleteheader :index 1 :is "Delivered-To" "root@example.com";
|
||||
let "redirected" "true";
|
||||
}
|
||||
if eval "eq_ignore_case(envelope.to[i], 'webteam@example.com')" {
|
||||
addheader "Delivered-To" "webteam@example.com";
|
||||
redirect :copy "baldwin@example.org";
|
||||
redirect :copy "camilia@example.com";
|
||||
redirect :copy "jaiden@example.edu";
|
||||
|
||||
deleteheader :index 1 :is "Delivered-To" "webteam@example.com";
|
||||
let "redirected" "true";
|
||||
}
|
||||
if eval "!redirected" {
|
||||
let "destination" "envelope.to[i]";
|
||||
redirect :copy "${destination}";
|
||||
}
|
||||
let "i" "i+1";
|
||||
}
|
||||
discard;
|
||||
```
|
||||
|
||||
If you have multiple domains with multiple alias files, pass them all in one run: `$ ./alias_to_sieve simple.aliases example.com example.aliases example.org`.
|
||||
|
||||
## Limitations
|
||||
You cannot use apostrophes (') in any mail addresses although allowed by [RFC 5322](https://www.rfc-editor.org/rfc/rfc5322) since they would break termination of strings in sieve.
|
||||
|
||||
This parser is not designed with security in mind. While the above gives some basic protection against code injection, I have no idea whether sieve has other pitfalls that might allow them.
|
||||
|
||||
This is my first rust project, consume the code with care.
|
||||
|
||||
The generated code is specific to stalwart-mail and contains non-standard sieve features.
|
8
packages/alias-to-sieve/testdata/example.aliases
vendored
Normal file
8
packages/alias-to-sieve/testdata/example.aliases
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
priscilla baldwin@example.org
|
||||
jaiden jaiden@example.edu
|
||||
camila camila@example.edu
|
||||
|
||||
cali camilia
|
||||
|
||||
webteam root, camilia
|
||||
root priscilla jaiden
|
Loading…
Add table
Add a link
Reference in a new issue