diff options
author | 2024-08-25 19:57:01 +0200 | |
---|---|---|
committer | 2024-08-25 19:57:01 +0200 | |
commit | 2695fc7b21da70ac48b7eea47f828962f30b377d (patch) | |
tree | 0538dfb9b2780c053b2e9e33ea854134b4bc3180 /docs | |
parent | Fix incorrect module causing crash when copying (diff) |
Document debugging of sieve scripts
Diffstat (limited to 'docs')
-rw-r--r-- | docs/docs/services/email/mail-clients.md | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/docs/docs/services/email/mail-clients.md b/docs/docs/services/email/mail-clients.md index c758316..8c797d0 100644 --- a/docs/docs/services/email/mail-clients.md +++ b/docs/docs/services/email/mail-clients.md @@ -90,6 +90,82 @@ You can find some example scripts to get started There are plenty of resources out there to allow for filtering using Sieve rules. +### Debugging Sieve scripts + +Dovecot ships with a helpful utility called `sieve-test` which allows you to +test the execution of a Sieve script when given an e-mail. You pass it a sieve +script and an e-mail, and (depending on the flags you pass it) it shows you +information on what Dovecot would do with said e-mail. + +Let's take the following Sieve script intended to file away mailing list posts +to the right folders: + +```sieve +require ["fileinto", "subaddress", "variables", "regex", "mailbox"]; + +if header :matches "List-Unsubscribe" "*" { + if header :regex "List-Id" "^<(\w+)\.(example)\.org>$" { + set "list_name" "${1}"; + set "org_name" "${2}"; + + fileinto :create "Lists.${org_name}.${list_name}"; + } else { + fileinto :create "Lists"; + } + stop; +} +``` + +This example has a slight problem. Whilst the e-mail header `List-Id` is being +sent in the form `<group.example.org>`, it does not seem to file it into the +proper place. + +To test it, start by copying a mail you want to test it with (or creating one) +in your home directory. Then run the following: + +``` +sudo -u vmail sieve-test -Tlevel=matching -t - $SIEVE $MAIL +``` + +where `$SIEVE` is the Sieve script you'd like to debug and `$MAIL` is the path +to the e-mail you'd like to test it on. It prints execution information as +follows: + +```sh + ## Started executing script 'sieve' + 3: header test + 3: starting `:matches' match with `i;ascii-casemap' comparator: + 3: extracting `List-Unsubscribe' headers from message + 3: matching value `<mailto:[email protected]?body=unsub%20list>' + 3: with key `*' => 1 + 3: finishing match with result: matched + 3: jump if result is false + 3: not jumping + 4: header test + 4: starting `:regex' match with `i;ascii-casemap' comparator: + 4: extracting `List-Id' headers from message + 4: matching value `<list.example.org>' + 4: with regex `^<(w+).(.*)>$' [id=0] => 0 + 4: finishing match with result: not matched + 4: jump if result is false + 4: jumping to line 9 + 10: fileinto action + 10: store message in mailbox `Lists' + 12: stop command; end all script execution + ## Finished executing script 'sieve' +``` + +Note number `4:` where it says that `finishing match with result: not matched`. +If you look carefully at the Regex pattern, you'll notice that it does not work +look right because the pattern on the left is `(w+)` which would match on +consecutive `w`s as opposed to `\w`. + +In this example, the fix is to simply add another backslash ahead of `\w` to +ensure that the pattern is correctly parsed by Dovecot. To conclude, +`sieve-test` allows you to easily find bugs like this without having to +repeatedly retry script execution with inbound e-mails. + + ## Neomutt via SSH Previously, before we had configured IMAP, local mail delivery was read with |