1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
|
% Test environment setup
% [Guilhem Moulin](mailto:guilhem@fripost.org)
Introduction
============
This document describes how to create dummy mail storage for
[`interimap`(1)] and/or [`pullimap`(1)] development, using [Dovecot] as
[IMAP4rev1] server. Start by creating a new temporary directory:
$ BASEDIR="$(mktemp --tmpdir --directory)"
Dovecot configuration
=====================
Create a file `$BASEDIR/dovecot.conf`, which will be used as
configuration for the various Dovecot 2.4 commands (the system
configuration will be skipped).
$ cat >"$BASEDIR/dovecot.conf" <<-EOF
dovecot_config_version = 2.4.0
dovecot_storage_version = 2.4.0
log_path = "$BASEDIR/dovecot.log"
ssl = no
mail_home = "$BASEDIR/%{user | username | lower}"
mail_driver = maildir
mail_path = ~/Mail
EOF
Here are some details on the above:
`log_path`
: Dovecot [logs to syslog][Dovecot Logging] by default. It's annoying
to clutter syslog with test entries, so instead we make it log to a
file under `$BASEDIR`.
`mail_home`
: Dovecot needs the name of the user to (pre-)authenticate. It is shown
in the greeting line, and also used in [settings variables] expansion.
Several [`doveadm`(1)] sub-commands have a `-u` (or `-d`) option which
can be used to determine the username. To avoid performing the userdb
lookup one can pass `--no-userdb-lookup` instead, in which case the
username is taken from the `USER` environment variable.
Similarly, the user's home directory is used in (`~`- and)
[settings variables] expansion. It's taken from the `HOME`
environment variable when the `mail_home` setting is left unset in
the Dovecot configuration (and not overridden by the
[user database][User Databases].
`mail_home` can therefore be left unset if the `HOME` environment
variable is consistently set to `$BASEDIR/$USER`. However it's
safer to explicitly set it in the configuration file: otherwise a
command run in a non-curated environment might mess up with your own
mail storage…
`mail_driver`
: Use the [Maildir] format for mail storage..
`mail_path`:
: The user's mail storage resides in a directory `Mail` under their
home directory. This is enough if you're fine with the default IMAP
hierarchy delimiter (which depends on the mail format) is used, and
if you need a single [IMAP namespace][RFC 2342]. For more complex
setups you'll need one or more [`namespace {…}` block][Dovecot Namespaces].
Mail storage access
===================
Feel free to point a mail client at the dummy mail storage. To start a
pre-authenticated [IMAP4rev1] in the test environment for username
`testuser`, list mailboxes, and exit, run:
$ env -i PATH="/usr/bin:/bin" USER="testuser" \
doveadm -c "$BASEDIR/dovecot.conf" exec imap
S: * PREAUTH [CAPABILITY IMAP4rev1 …] Logged in as testuser
C: a LIST "" "*"
S: * LIST (\HasNoChildren) "." INBOX
S: a OK List completed (0.002 + 0.000 + 0.001 secs).
C: q LOGOUT
S: * BYE Logging out
S: q OK Logout completed (0.001 + 0.000 secs).
For mailbox (create, delete, rename) and message (add, flag update)
manipulation you can use your mail client, the relevant [IMAP4rev1]
commands, or simply the [`doveadm`(1)] tools. Here is an example using
the latter to create a mailbox `foo`, add a sample message to it, and
finally mark it as `\Seen`.
$ env -i PATH="/usr/bin:/bin" USER="testuser" \
doveadm -c "$BASEDIR/dovecot.conf" mailbox create --no-userdb-lookup "foo"
<!-- -->
$ env -i PATH="/usr/bin:/bin" USER="testuser" HOME="$BASEDIR/testuser" \
doveadm -c "$BASEDIR/dovecot.conf" exec dovecot-lda -e -m "foo" <<-EOF
From: <sender@example.net>
To: <recipient@example.net>
Subject: Hello world!
Date: $(date -R)
Message-ID: <$(</proc/sys/kernel/random/uuid)@example.net>
Hello world!
EOF
<!-- -->
$ env -i PATH="/usr/bin:/bin" USER="testuser" \
doveadm -c "$BASEDIR/dovecot.conf" flags add --no-userdb-lookup "\\Seen" mailbox "foo" "*"
Normally [`dovecot-lda`(1)][Dovecot LDA] tries to do a userdb lookup in
order to determine the user's home directory. Since we didn't configure
a user database we need to explicitly set the `HOME` environment
variable.
InterIMAP configuration and test
================================
In this example the peers to synchronize are sharing the same Dovecot
configuration file `$BASEDIR/dovecot.conf`. Of course, it's also
possible to use a different configuration on each “server”, for instance
in order to specify different hierarchy delimiters, namespaces, or mail
storage format.
Create an [`interimap`(1)] configuration file to synchronize the `local`
and `remote` accounts.
$ cat >"$BASEDIR/interimap.conf" <<-EOF
database = $BASEDIR/interimap.db
[local]
type = tunnel
command = env -i PATH="$PATH" USER="local" doveadm -c "$BASEDIR/dovecot.conf" exec imap
[remote]
type = tunnel
command = env -i PATH="$PATH" USER="remote" doveadm -c "$BASEDIR/dovecot.conf" exec imap
EOF
Run [`interimap`(1)] without `--watch` in order to create the database.
$ env -i PATH="$PATH" perl -T ./interimap --config="$BASEDIR/interimap.conf"
Creating new schema in database file …/interimap.db
database: Created mailbox INBOX
[…]
You can now run [`interimap`(1)] with `--watch` set, here to one second
to observe synchronization steps early.
$ env -i PATH="$PATH" perl -T ./interimap --config="$BASEDIR/interimap.conf" \
--watch=1 --debug
Use instructions from the [previous section][Mail storage access]
(substituting `testuser` with `local` or `remote`) in order to simulate
activity on either end to synchronize. If you run these commands in
another shell, then make sure to re-set the `BASEDIR` environment
variable!
PullIMAP configuration and test
===============================
Create a [`pullimap`(1)] configuration file with as section `[foo]`.
$ cat >"$BASEDIR/pullimap.conf" <<-EOF
[foo]
type = tunnel
command = env -i PATH="$PATH" USER="testuser" doveadm -c "$BASEDIR/dovecot.conf" exec imap
statefile = $BASEDIR/pullimap.foo
EOF
Run [`pullimap`(1)] without `--idle` in order to create the state file.
$ env -i PATH="$PATH" perl -T ./pullimap --config="$BASEDIR/pullimap.conf" \
--no-delivery foo
You can now run [`pullimap`(1)] with `--idle` set.
$ env -i PATH="$PATH" perl -T ./pullimap --config="$BASEDIR/pullimap.conf" \
--no-delivery --idle --debug foo
Use instructions from the [previous section][Mail storage access]
in order to simulate activity on the “remote” server (in the relevant
mailbox — `INBOX` by default). If you run these commands in another
shell, then make sure to re-set the `BASEDIR` environment variable!
Cleanup
=======
To remove temporary directories and the message they contain, simply
recursively remove the directory `$BASEDIR`.
$ rm -rf -- "$BASEDIR"
[IMAP4rev1]: https://tools.ietf.org/html/rfc3501
[Dovecot]: https://dovecot.org
[Dovecot Logging]: https://doc.dovecot.org/latest/core/admin/logging.html#dovecot-logging
[Dovecot LDA]: https://doc.dovecot.org/latest/core/config/delivery/lda.html
[User Databases]: https://doc.dovecot.org/latest/core/config/auth/userdb.html
[Maildir]: https://doc.dovecot.org/latest/core/config/mailbox_formats/maildir.html
[RFC 2342]: https://tools.ietf.org/html/rfc2342
[Dovecot Namespaces]: https://doc.dovecot.org/latest/core/config/namespaces.html
[`interimap`(1)]: interimap.1.html
[`pullimap`(1)]: pullimap.1.html
[`doveadm`(1)]: https://doc.dovecot.org/latest/core/man/doveadm.1.html
[settings variables]: https://doc.dovecot.org/latest/core/settings/variables.html
|