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 Configuring GPG: Signing Keys
27 -----------------------------
28
29 For a wiki to be able to receive content, signing keys must be made available
30 within the wiki's GPG homedir so that incoming messages can have their senders
31 verified.
32
33 Consider the need to send content to a wiki yourself. To see the keys
34 available to you in your own environment:
35
36 gpg --list-keys --with-fingerprint
37
38 The full fingerprints are used when defining a user mapping in the wiki, and
39 the --with-fingerprint option is used to show them. Otherwise, only the last
40 eight characters of the fingerprints are shown.
41
42 Export the public key used when signing messages from your own environment:
43
44 gpg --armor --output 1C1AAF83.asc --export 1C1AAF83
45
46 Import the key into the wiki's GPG homedir:
47
48 gpg --homedir WIKI/gnupg --import 1C1AAF83.asc
49
50 Signing keys can also be used in the authoring of messages within a wiki, and
51 this is discussed in "The Username-to-Signing-Key Mapping" section below.
52
53 Configuring GPG: Encryption Keys
54 --------------------------------
55
56 For the wiki to receive and decrypt encrypted data, a key for the wiki must be
57 created:
58
59 gpg --homedir WIKI/gnupg --gen-key
60
61 For the wiki environment to be able to use the key, password access must be
62 disabled. This can be done by either not specifying a password or by removing
63 it later using the --edit-key option:
64
65 gpg --homedir WIKI/gnupg --edit-key 0891463A
66 passwd
67
68 Export the wiki's key for encrypting messages sent to the wiki:
69
70 gpg --homedir WIKI/gnupg --armor --output 0891463A.asc --export 0891463A
71
72 This exported key can now be imported into your own environment:
73
74 gpg --import 0891463A.asc
75
76 This key can also be used to sign relayed messages within the wiki, and this
77 is described in more detail in "The Username-to-Signing-Key Mapping" section
78 below.
79
80 Configuring the Wiki
81 --------------------
82
83 In the wiki configuration, define the following settings:
84
85 moinmessage_gpg_homedir
86 This sets the path to the homedir initialised above.
87
88 moinmessage_gpg_users_page (optional, default is MoinMessageUserDict)
89 This provides a mapping from key fingerprints to Moin usernames.
90
91 moinmessage_gpg_signing_users_page (optional, default is MoinMessageSigningUserDict)
92 This provides a mapping from Moin usernames to key fingerprints.
93
94 moinmessage_gpg_relaying_user (optional)
95 This specifies the username of a special user who will sign relayed
96 messages. Partner wikis will need to record the details of this user in
97 their fingerprint-to-user mapping (see moinmessage_gpg_users_page) to be
98 able to receive messages from this wiki.
99
100 moinmessage_gpg_relays_page (optional, default is MoinMessageRelayDict)
101 Where message relaying is specified for a recipient, the relay name will be
102 looked up in the dictionary provided by this page.
103
104 moinmessage_gpg_recipients_page (optional, default is MoinMessageRecipientsDict)
105 This provides a mapping from recipients to remote URLs and key fingerprints.
106 Each user can define the named page as a subpage of their own home page.
107 If no such personal mapping exists, a common mapping exists relative to the
108 site root.
109
110 moinmessage_reject_messages_without_dates (optional, default is True)
111 This causes messages sent to a wiki using the PostMessage action to be
112 rejected if date information is missing.
113
114 moinmessage_static_files (optional, may refer to the built-in htdocs directory)
115 This explicitly defines the path to static resources used by Moin, enabling
116 such resources to be attached to messages. When set, the path must refer to
117 the htdocs directory (possibly renamed) containing the different theme
118 resource directories, together with the robots.txt and favicon.ico files.
119
120 For signature verification to function, the following needs to be added:
121
122 from MoinMoin.auth.pgp import PGPAuth
123
124 This should import an authentication handler installed when the MoinMessage
125 software is installed as an extension package.
126
127 Within the configuration class itself, the auth setting needs to be updated to
128 include PGPAuth in the list of registered handlers. For example:
129
130 auth = [MoinAuth(), PGPAuth()]
131
132 This would permit the traditional Moin authentication and add signature-based
133 authentication so that messages can be accepted by the wiki.
134
135 Fingerprints and Keys
136 ---------------------
137
138 All fingerprints mentioned in the various configuration pages must exclude
139 space characters - that is, the letters and digits must appear together in a
140 continuous block of text - and refer to keys available in the wiki homedir.
141
142 The Fingerprint-to-Username Mapping
143 -----------------------------------
144
145 The mapping from fingerprints to usernames typically defined by the
146 MoinMessageUserDict page is a WikiDict having the following general format:
147
148 fingerprint:: username
149
150 Each fingerprint corresponds to a key used by a person wanting to send
151 messages to the wiki to sign such messages.
152
153 Each username must correspond to a registered user in the wiki.
154
155 If a wiki is to perform message relaying, receiving messages from partner
156 wikis and sending them on, a user is required for this purpose. You could
157 create such a user as follows:
158
159 moin --config-dir=WIKI account create --name=RelayingUser --email=messagerelay
160
161 (You may need to run this command as the Web server user to be able to change
162 the wiki installation, as well as indicating the full path to the moin program
163 either as the program name or by setting the PATH.)
164
165 After doing this, you could define an entry for the relaying user as follows:
166
167 fingerprint:: RelayingUser
168
169 Here, "fingerprint" should be substituted for a key fingerprint used by a
170 partner wiki to sign messages that it then sends to this wiki. See the next
171 section for more information on signing keys and identities.
172
173 It may very well be the case that more than one partner wiki will be sending
174 messages to this wiki: the signing key fingerprint of each partner wiki can be
175 added to this mapping and specify the same relaying user; there is no
176 restriction on each fingerprint needing to map to a different user.
177
178 The Username-to-Signing-Key Mapping
179 -----------------------------------
180
181 The mapping from usernames to fingerprints typically defined by the
182 MoinMessageSigningUserDict page is a WikiDict having the following general
183 format:
184
185 username:: fingerprint
186
187 Each fingerprint corresponds to a key available in the wiki's GPG homedir
188 generated for the purpose of signing the specified user's messages. Such a key
189 is not the same as one used by a person to send messages to the wiki since
190 only the public key is available to the wiki when verifying such messages,
191 whereas the signing of messages requires access to a private key. Thus, the
192 signing process employs a special private key known to the wiki for a user.
193
194 To create such a key, the following command can be used:
195
196 gpg --homedir WIKI/gnupg --gen-key
197
198 This is just like creating a key for the wiki itself (see "Configuring GPG for
199 a Wiki" above), but you will label the key appropriately for the user and
200 associate the key with the user in the mapping described above. Remember to
201 remove the passphrase so that the wiki can access the key.
202
203 If a wiki is to perform message relaying, the special relaying user must be
204 defined in this mapping together with an appropriate key fingerprint. You can
205 use the key generated during the wiki's configuration (see "Configuring GPG
206 for a Wiki" above) for this purpose. This fingerprint can then be used by
207 partner wikis in their fingerprint-to-user mapping in order to verify incoming
208 messages and to process them as relayed messages.
209
210 All signing keys must be made available in their public form to partner and
211 recipient wikis so that they are able to verify signed content. This can be
212 done as follows:
213
214 gpg --homedir=WIKI/gnupg --armor --output 3FDDF29E.asc --export 3FDDF29E
215
216 They are imported into partner and recipient wikis as follows:
217
218 gpg --homedir=WIKI/gnupg --import 3FDDF29E.asc
219
220 The Recipients Mapping
221 ----------------------
222
223 The mapping from recipients to remote URLs and fingerprints typically defined
224 by the MoinMessageRecipientsDict page is a WikiDict having the following
225 general format:
226
227 recipient:: type location [ fingerprint ]
228
229 Where the type is "page", the accompanying location must be a page name
230 indicating a page that provides a message store that will accept messages.
231 The affected page resides on the same wiki and is thus a bare page name, not
232 the URL of a page on the same or another wiki.
233
234 Where the type is "url", the accompanying location must be a URL that must
235 itself refer to a resource that can accept MoinMessage content.
236
237 Where the type is "relay", the accompanying location is an identifier that
238 must be defined in the relays mapping (see below) and yield a URL that can
239 accept MoinMessage content.
240
241 Where a type of "url" or "relay" has been given, a fingerprint must accompany
242 this information in order to encrypt messages sent to the specified resource.
243
244 Each fingerprint corresponds to a key used by the wiki to encrypt messages and
245 by the remote site (as identified by the URL) to decrypt messages.
246
247 Each wiki user can have their own recipients mapping by making a page, called
248 MoinMessageRecipientsDict unless overridden by the configuration, as a subpage
249 of their own home page.
250
251 The Relays Mapping
252 ------------------
253
254 The mapping from relay identifiers to remote URLs defined by the
255 MoinMessageRelayDict page is a WikiDict having the following general format:
256
257 relay:: url
258
259 The URL must be able to accept MoinMessage content, and it will typically be
260 configured so that the user or entity accepting relayed content on the remote
261 site can store such content for later propagation or retrieval.
262
263 Quick Start: Signing, Encrypting and Sending Messages
264 -----------------------------------------------------
265
266 To send a message signed and encrypted to a resource on localhost:
267
268 python tests/test_send.py 1C1AAF83 0891463A http://localhost/wiki/ShareTest \
269 collection update 'An update to the wiki.' 'Another update.'
270
271 Here, the first identifier is a reference to the signing key (over which you
272 have complete control), and the second identifier is a reference to the
273 encryption key (which is a public key published for the wiki).
274
275 This needs password protection to be removed from the secret key in the Web
276 server environment. It also uses a modified trust model when invoking gpg in
277 order to avoid complaints about the identity of the sender during encryption.
278
279 To sign the encrypted message for forwarding, the above command is modified:
280
281 python tests/test_send.py 1C1AAF83 0891463A --forward 1C1AAF83 \
282 http://localhost/wiki/ShareTest \
283 collection update 'An update to the wiki.' 'Another update.'
284
285 Below, the mechanisms employed are illustrated through the use of the other
286 test programs.
287
288 Signing
289 -------
290
291 Prepare a message signed with a "detached signature" (note that this does not
292 seem to be what gpg calls a detached signature with the --detach-sig option):
293
294 python tests/test_message.py collection update 'An update to the wiki.' \
295 'Another update.' \
296 | python tests/test_sign.py 1C1AAF83
297
298 The complicated recipe based on the individual operations is as follows:
299
300 python tests/test_message.py collection update 'An update to the wiki.' \
301 'Another update.' \
302 > test.txt \
303 && cat test.txt \
304 | gpg --armor -u 1C1AAF83 --detach-sig \
305 | python tests/test_sign_wrap.py test.txt
306
307 Encryption
308 ----------
309
310 Prepare a message with an encrypted payload using the above key:
311
312 python tests/test_message.py collection update 'An update to the wiki.' \
313 'Another update.' \
314 | python tests/test_encrypt.py 0891463A
315
316 The complicated recipe based on the individual operations is as follows:
317
318 python tests/test_message.py collection update 'An update to the wiki.' \
319 'Another update.' \
320 > test.txt \
321 && cat test.txt \
322 | gpg --armor -r 0891463A --encrypt --trust-model always \
323 | python tests/test_encrypt_wrap.py
324
325 Note that "--trust-model always" is used only to avoid prompting issues.
326
327 Signing and Encrypting
328 ----------------------
329
330 Sign and encrypt a message:
331
332 python tests/test_message.py collection update 'An update to the wiki.' \
333 'Another update.' \
334 | python tests/test_sign.py 1C1AAF83 \
335 | python tests/test_encrypt.py 0891463A
336
337 The complicated recipe based on the individual operations is as follows:
338
339 python tests/test_message.py collection update 'An update to the wiki.' \
340 'Another update.' \
341 > test.txt \
342 && cat test.txt \
343 | gpg --armor -u 1C1AAF83 --detach-sig \
344 | python tests/test_sign_wrap.py test.txt \
345 | gpg --armor -r 0891463A --encrypt --trust-model always \
346 | python tests/test_encrypt_wrap.py
347
348 Signing and Encrypting then Signing
349 -----------------------------------
350
351 Where a message is to be forwarded and not decrypted, it will be signed by the
352 author, encrypted, but then signed by the forwarder (perhaps initially the
353 author):
354
355 python tests/test_message.py collection update 'An update to the wiki.' \
356 'Another update.' \
357 | python tests/test_sign.py 1C1AAF83 \
358 | python tests/test_encrypt.py 0891463A \
359 | python tests/test_sign.py 1C1AAF83
360
361 The complicated recipe based on the individual operations is as follows:
362
363 python tests/test_message.py collection update 'An update to the wiki.' \
364 'Another update.' \
365 > test.txt \
366 && cat test.txt \
367 | gpg --armor -u 1C1AAF83 --detach-sig \
368 | python tests/test_sign_wrap.py test.txt \
369 | gpg --armor -r 0891463A --encrypt --trust-model always \
370 | python tests/test_encrypt_wrap.py \
371 > test2.txt \
372 && cat test2.txt \
373 | gpg --armor -u 1C1AAF83 --detach-sig \
374 | python tests/test_sign_wrap.py test2.txt
375
376 Posting a Message
377 -----------------
378
379 To post a signed and/or encrypted message, output from the above activities
380 can be piped into the following command:
381
382 python tests/test_post.py http://localhost/wiki/ShareTest
383
384 Here, the resource "/wiki/ShareTest" on localhost is presented with the
385 message.
386
387 Fetching Messages
388 -----------------
389
390 To fetch messages from a message store associated with a page, the following
391 command can be used:
392
393 python tests/test_fetch.py 1C1AAF83 0891463A http://localhost/wiki/ShareTest \
394 RETR
395
396 This should retrieve all messages from the store associated with the
397 "/wiki/ShareTest" resource on localhost.
398
399 Exporting and Sending Keys
400 --------------------------
401
402 To export a public key, the following command can be used:
403
404 python tests/text_export.py 1C1AAF83
405
406 This will output a public key block in a MIME message part suitable for
407 incorporation into a larger message or signing. Signing a message containing
408 such a key can be done as follows:
409
410 python tests/text_export.py 1C1AAF83 \
411 | python tests/test_sign.py 1C1AAF83
412
413 Obviously, this does not provide any additional reassurance about the nature
414 of the exported key other than the originator was able to sign it with the
415 same keypair information.
416
417 The Message Format
418 ------------------
419
420 Messages are MIME-encoded and consist of one or more update fragments. Where
421 the "Update-Type" header is present and set to a value of "collection", a
422 multipart message describes as many updates as there are parts. Otherwise,
423 only a single update is described by the message.
424
425 For each update, the "Update-Action" header indicates the action to be taken
426 with the update content. Where it is absent, the content is inserted into the
427 wiki page specified in the request; where it is present and set to "replace",
428 the content replaces all content on the wiki page; where it is set to "store",
429 the content is stored in a message store associated with the wiki page.
430
431 Each update may describe multiple representations of some content by employing
432 a multipart/alternative section containing parts for each of the
433 representations. Alternatively, a single message part may describe a single
434 representation.
435
436 HTTP Methods
437 ------------
438
439 Since MoinMoin seems to reserve POST methods for request/entity bodies that
440 contain HTML form data, it is necessary to use alternative methods to post
441 messages to a site served by MoinMoin and to fetch messages from such a site.
442 Consequently, MoinMessage uses PUT to post and fetch messages. Unfortunately,
443 MoinMoin 1.9 prevents the use of GET with request/entity bodies, and so the
444 natural usage of GET to fetch messages cannot be employed.
445
446 Contact, Copyright and Licence Information
447 ------------------------------------------
448
449 See the following Web page for more information about this work:
450
451 http://moinmo.in/ActionMarket/MoinMessage
452
453 The author can be contacted at the following e-mail address:
454
455 paul@boddie.org.uk
456
457 Copyright and licence information can be found in the docs directory - see
458 docs/COPYING.txt and docs/LICENCE.txt for more information.
459
460 Dependencies
461 ------------
462
463 MoinMessage has the following basic dependencies:
464
465 Packages Release Information
466 -------- -------------------
467
468 MoinSupport Tested with 0.5
469 Source: http://hgweb.boddie.org.uk/MoinSupport