1 Introduction
2 ------------
3
4 MoinMessage provides a library for creating, signing, encrypting, decrypting,
5 and verifying PGP/GPG content in Python along with mechanisms for updating
6 MoinMoin wiki instances with such content such that contributors can be
7 identified from their PGP signatures and such details used to authenticate
8 their contributions. It also permits PGP/GPG content to be stored in dedicated
9 message stores when received, enabling further processing of received content
10 and other means of perusal of such content.
11
12 Configuring GPG for a Wiki
13 --------------------------
14
15 Initialise a homedir for GPG and configure it using filesystem ACL (access
16 control list) properties:
17
18 ./scripts/init_wiki_keyring.sh WIKI WEBUSER
19
20 Here, WIKI should be replaced by the top-level wiki instance directory, and
21 WEBUSER should be the name of the user under which the Web server operates.
22
23 Note that this script may need re-running after the homedir has been changed
24 by gpg operations as gpg likes to remove permissions from various files.
25
26 To be in any way useful, signing keys must be made available within this
27 homedir so that incoming messages can have their senders verified.
28
29 To see the keys available to you in your own environment:
30
31 gpg --list-keys --with-fingerprint
32
33 The full fingerprints are used when defining a user mapping in the wiki, and
34 the --with-fingerprint option is used to show them. Otherwise, only the last
35 eight characters of the fingerprints are shown.
36
37 Export the public key used when signing messages from your own environment:
38
39 gpg --armor --output 1C1AAF83.asc --export 1C1AAF83
40
41 Import the key into the wiki's GPG homedir:
42
43 gpg --homedir wiki/gnupg --import 1C1AAF83.asc
44
45 For the wiki to receive encrypted data, a key for the wiki must be created:
46
47 gpg --homedir wiki/gnupg --gen-key
48
49 For the wiki environment to be able to use the key, password access must be
50 disabled. This can be done by either not specifying a password or by removing
51 it later using the --edit-key option:
52
53 gpg --homedir wiki/gnupg --edit-key 0891463A
54 passwd
55
56 Export the wiki's key for encrypting messages sent to the wiki:
57
58 gpg --homedir wiki/gnupg --armor --output 0891463A.asc --export 0891463A
59
60 This exported key can now be imported into your own environment:
61
62 gpg --import 0891463A.asc
63
64 Configuring the Wiki
65 --------------------
66
67 In the wiki configuration, define the following settings:
68
69 moinmessage_gpg_homedir
70 This sets the path to the homedir initialised above.
71
72 moinmessage_gpg_users_page (optional, default is MoinMessageUserDict)
73 This provides a mapping from key fingerprints to Moin usernames.
74
75 moinmessage_gpg_signing_users_page (optional, default is MoinMessageSigningUserDict)
76 This provides a mapping from Moin usernames to key fingerprints.
77
78 moinmessage_gpg_recipients_page (optional, default is MoinMessageRecipientsDict)
79 This provides a mapping from recipients to remote URLs and key fingerprints.
80 Each user can define the named page as a subpage of their own home page.
81 If no such personal mapping exists, a common mapping exists relative to the
82 site root.
83
84 moinmessage_reject_messages_without_dates (optional, default is True)
85 This causes messages sent to a wiki using the PostMessage action to be
86 rejected if date information is missing.
87
88 moinmessage_static_files (optional, may refer to the built-in htdocs directory)
89 This explicitly defines the path to static resources used by Moin, enabling
90 such resources to be attached to messages. When set, the path must refer to
91 the htdocs directory (possibly renamed) containing the different theme
92 resource directories, together with the robots.txt and favicon.ico files.)
93
94 For signature verification to function, the following needs to be added:
95
96 from MoinMoin.auth.pgp import PGPAuth
97
98 This should import an authentication handler installed when the MoinMessage
99 software is installed as an extension package.
100
101 Within the configuration class itself, the auth setting needs to be updated to
102 include PGPAuth in the list of registered handlers. For example:
103
104 auth = [MoinAuth(), PGPAuth()]
105
106 This would permit the traditional Moin authentication and add signature-based
107 authentication so that messages can be accepted by the wiki.
108
109 Fingerprints and Keys
110 ---------------------
111
112 All fingerprints mentioned in the various configuration pages must exclude
113 space characters - that is, the letters and digits must appear together in a
114 continuous block of text - and refer to keys available in the wiki homedir.
115
116 The Fingerprint-to-Username Mapping
117 -----------------------------------
118
119 The mapping from fingerprints to usernames typically defined by the
120 MoinMessageUserDict page is a WikiDict having the following general format:
121
122 fingerprint:: username
123
124 Each fingerprint corresponds to a key used by a person wanting to send
125 messages to the wiki to sign such messages.
126
127 Each username must correspond to a registered user in the wiki.
128
129 The Username-to-Signing Key Mapping
130 -----------------------------------
131
132 The mapping from usernames to fingerprints typically defined by the
133 MoinMessageSigningUserDict page is a WikiDict having the following general
134 format:
135
136 username:: fingerprint
137
138 Each fingerprint corresponds to a key available in the wiki's GPG homedir
139 generated for the purpose of signing the specified user's messages. Such a key
140 is not the same as one used by a person to send messages to the wiki since
141 only the public key is available to the wiki when verifying such messages,
142 whereas the signing of messages requires access to a private key. Thus, the
143 signing process employs a special private key known to the wiki for a user.
144
145 The Recipients Mapping
146 ----------------------
147
148 The mapping from recipients to remote URLs and fingerprints typically defined
149 by the MoinMessageRecipientsDict page is a WikiDict having the following
150 general format:
151
152 recipient:: type location [ fingerprint ]
153
154 Where the type is "page", the accompanying location must be a page name
155 indicating a page that provides a message store that will accept messages.
156 The affected page resides on the same wiki and is thus a bare page name, not
157 the URL of a page on the same or another wiki.
158
159 Where the type is "url", the accompanying location must be a URL that must
160 itself refer to a resource that can accept MoinMessage content.
161
162 Where a type of "url" has been given, a fingerprint must accompany this
163 information in order to encrypt messages sent to the specified resource.
164
165 Each fingerprint corresponds to a key used by the wiki to encrypt messages and
166 by the remote site (as identified by the URL) to decrypt messages.
167
168 Each wiki user can have their own recipients mapping by making a page, called
169 MoinMessageRecipientsDict unless overridden by the configuration, as a subpage
170 of their own home page.
171
172 Quick Start: Signing, Encrypting and Sending Messages
173 -----------------------------------------------------
174
175 To send a message signed and encrypted to a resource on localhost:
176
177 python tests/test_send.py 1C1AAF83 0891463A http://localhost/wiki/ShareTest \
178 collection update 'An update to the wiki.' 'Another update.'
179
180 Here, the first identifier is a reference to the signing key (over which you
181 have complete control), and the second identifier is a reference to the
182 encryption key (which is a public key published for the wiki).
183
184 This needs password protection to be removed from the secret key in the Web
185 server environment. It also uses a modified trust model when invoking gpg in
186 order to avoid complaints about the identity of the sender during encryption.
187
188 To sign the encrypted message for forwarding, the above command is modified:
189
190 python tests/test_send.py 1C1AAF83 0891463A --forward 1C1AAF83 \
191 http://localhost/wiki/ShareTest \
192 collection update 'An update to the wiki.' 'Another update.'
193
194 Below, the mechanisms employed are illustrated through the use of the other
195 test programs.
196
197 Signing
198 -------
199
200 Prepare a message signed with a "detached signature" (note that this does not
201 seem to be what gpg calls a detached signature with the --detach-sig option):
202
203 python tests/test_message.py collection update 'An update to the wiki.' \
204 'Another update.' \
205 | python tests/test_sign.py 1C1AAF83
206
207 The complicated recipe based on the individual operations is as follows:
208
209 python tests/test_message.py collection update 'An update to the wiki.' \
210 'Another update.' \
211 > test.txt \
212 && cat test.txt \
213 | gpg --armor -u 1C1AAF83 --detach-sig \
214 | python tests/test_sign_wrap.py test.txt
215
216 Encryption
217 ----------
218
219 Prepare a message with an encrypted payload using the above key:
220
221 python tests/test_message.py collection update 'An update to the wiki.' \
222 'Another update.' \
223 | python tests/test_encrypt.py 0891463A
224
225 The complicated recipe based on the individual operations is as follows:
226
227 python tests/test_message.py collection update 'An update to the wiki.' \
228 'Another update.' \
229 > test.txt \
230 && cat test.txt \
231 | gpg --armor -r 0891463A --encrypt --trust-model always \
232 | python tests/test_encrypt_wrap.py
233
234 Note that "--trust-model always" is used only to avoid prompting issues.
235
236 Signing and Encrypting
237 ----------------------
238
239 Sign and encrypt a message:
240
241 python tests/test_message.py collection update 'An update to the wiki.' \
242 'Another update.' \
243 | python tests/test_sign.py 1C1AAF83 \
244 | python tests/test_encrypt.py 0891463A
245
246 The complicated recipe based on the individual operations is as follows:
247
248 python tests/test_message.py collection update 'An update to the wiki.' \
249 'Another update.' \
250 > test.txt \
251 && cat test.txt \
252 | gpg --armor -u 1C1AAF83 --detach-sig \
253 | python tests/test_sign_wrap.py test.txt \
254 | gpg --armor -r 0891463A --encrypt --trust-model always \
255 | python tests/test_encrypt_wrap.py
256
257 Signing and Encrypting then Signing
258 -----------------------------------
259
260 Where a message is to be forwarded and not decrypted, it will be signed by the
261 author, encrypted, but then signed by the forwarder (perhaps initially the
262 author):
263
264 python tests/test_message.py collection update 'An update to the wiki.' \
265 'Another update.' \
266 | python tests/test_sign.py 1C1AAF83 \
267 | python tests/test_encrypt.py 0891463A \
268 | python tests/test_sign.py 1C1AAF83
269
270 The complicated recipe based on the individual operations is as follows:
271
272 python tests/test_message.py collection update 'An update to the wiki.' \
273 'Another update.' \
274 > test.txt \
275 && cat test.txt \
276 | gpg --armor -u 1C1AAF83 --detach-sig \
277 | python tests/test_sign_wrap.py test.txt \
278 | gpg --armor -r 0891463A --encrypt --trust-model always \
279 | python tests/test_encrypt_wrap.py \
280 > test2.txt \
281 && cat test2.txt \
282 | gpg --armor -u 1C1AAF83 --detach-sig \
283 | python tests/test_sign_wrap.py test2.txt
284
285 Posting a Message
286 -----------------
287
288 To post a signed and/or encrypted message, output from the above activities
289 can be piped into the following command:
290
291 python tests/test_post.py http://localhost/wiki/ShareTest
292
293 Here, the resource "/wiki/ShareTest" on localhost is presented with the
294 message.
295
296 Fetching Messages
297 -----------------
298
299 To fetch messages from a message store associated with a page, the following
300 command can be used:
301
302 python tests/test_fetch.py 1C1AAF83 0891463A http://localhost/wiki/ShareTest \
303 RETR
304
305 This should retrieve all messages from the store associated with the
306 "/wiki/ShareTest" resource on localhost.
307
308 The Message Format
309 ------------------
310
311 Messages are MIME-encoded and consist of one or more update fragments. Where
312 the "Update-Type" header is present and set to a value of "collection", a
313 multipart message describes as many updates as there are parts. Otherwise,
314 only a single update is described by the message.
315
316 For each update, the "Update-Action" header indicates the action to be taken
317 with the update content. Where it is absent, the content is inserted into the
318 wiki page specified in the request; where it is present and set to "replace",
319 the content replaces all content on the wiki page; where it is set to "store",
320 the content is stored in a message store associated with the wiki page.
321
322 Each update may describe multiple representations of some content by employing
323 a multipart/alternative section containing parts for each of the
324 representations. Alternatively, a single message part may describe a single
325 representation.
326
327 HTTP Methods
328 ------------
329
330 Since MoinMoin seems to reserve POST methods for request/entity bodies that
331 contain HTML form data, it is necessary to use alternative methods to post
332 messages to a site served by MoinMoin and to fetch messages from such a site.
333 Consequently, MoinMessage uses PUT to post and fetch messages. Unfortunately,
334 MoinMoin 1.9 prevents the use of GET with request/entity bodies, and so the
335 natural usage of GET to fetch messages cannot be employed.
336
337 Contact, Copyright and Licence Information
338 ------------------------------------------
339
340 See the following Web page for more information about this work:
341
342 http://moinmo.in/ActionMarket/MoinMessage
343
344 The author can be contacted at the following e-mail address:
345
346 paul@boddie.org.uk
347
348 Copyright and licence information can be found in the docs directory - see
349 docs/COPYING.txt and docs/LICENCE.txt for more information.
350
351 Dependencies
352 ------------
353
354 MoinMessage has the following basic dependencies:
355
356 Packages Release Information
357 -------- -------------------
358
359 MoinSupport Tested with 0.4
360 Source: http://hgweb.boddie.org.uk/MoinSupport