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-Actions Mapping
179 -------------------------------
180
181 Each user may have a set of permitted actions defined for them so that they
182 may perform these actions by sending an incoming message to the wiki. This
183 mapping is typically defined by the MoinMessageUserActionsDict page as a
184 WikiDict having the following general format:
185
186 username:: permitted-action ...
187
188 To add content to a page, an entry of the following form would be used:
189
190 username:: Update:SomePage
191
192 Similarly, to allow an incoming message to replace a page's content, the
193 following would be used:
194
195 username:: Replace:SomePage
196
197 And to be able to add messages to a page's message store, the following would
198 be used:
199
200 username:: Store:SomePage
201
202 Multiple actions can be given in a space-separated list, with shell-like
203 quoting used for names containing spaces (and quote characters). For example:
204
205 username:: Store:"Some user's special page"
206
207 Without an entry in this mapping, messages may not perform content
208 modification or storage actions in the wiki.
209
210 The Username-to-Signing-Key Mapping
211 -----------------------------------
212
213 The mapping from usernames to fingerprints typically defined by the
214 MoinMessageSigningUserDict page is a WikiDict having the following general
215 format:
216
217 username:: fingerprint
218
219 Each fingerprint corresponds to a key available in the wiki's GPG homedir
220 generated for the purpose of signing the specified user's messages. Such a key
221 is not the same as one used by a person to send messages to the wiki since
222 only the public key is available to the wiki when verifying such messages,
223 whereas the signing of messages requires access to a private key. Thus, the
224 signing process employs a special private key known to the wiki for a user.
225
226 To create such a key, the following command can be used:
227
228 gpg --homedir WIKI/gnupg --gen-key
229
230 This is just like creating a key for the wiki itself (see "Configuring GPG for
231 a Wiki" above), but you will label the key appropriately for the user and
232 associate the key with the user in the mapping described above. Remember to
233 remove the passphrase so that the wiki can access the key.
234
235 If a wiki is to perform message relaying, the special relaying user must be
236 defined in this mapping together with an appropriate key fingerprint. You can
237 use the key generated during the wiki's configuration (see "Configuring GPG
238 for a Wiki" above) for this purpose. This fingerprint can then be used by
239 partner wikis in their fingerprint-to-user mapping in order to verify incoming
240 messages and to process them as relayed messages.
241
242 All signing keys must be made available in their public form to partner and
243 recipient wikis so that they are able to verify signed content. This can be
244 done as follows:
245
246 gpg --homedir=WIKI/gnupg --armor --output 3FDDF29E.asc --export 3FDDF29E
247
248 They are imported into partner and recipient wikis as follows:
249
250 gpg --homedir=WIKI/gnupg --import 3FDDF29E.asc
251
252 The Recipients Mapping
253 ----------------------
254
255 The mapping from recipients to remote URLs and fingerprints typically defined
256 by the MoinMessageRecipientsDict page is a WikiDict having the following
257 general format:
258
259 recipient:: type location [ fingerprint ]
260
261 Where the type is "page", the accompanying location must be a page name
262 indicating a page that provides a message store that will accept messages.
263 The affected page resides on the same wiki and is thus a bare page name, not
264 the URL of a page on the same or another wiki.
265
266 Where the type is "url", the accompanying location must be a URL that must
267 itself refer to a resource that can accept MoinMessage content.
268
269 Where the type is "relay", the accompanying location is an identifier that
270 must be defined in the relays mapping (see below) and yield a URL that can
271 accept MoinMessage content.
272
273 Where the type is "none" or omitted completely, the recipient is any user that
274 is allowed to fetch messages from the wiki.
275
276 Where a type of "url", "relay" or "none" has been given (or if the type is
277 omitted), a fingerprint must accompany this information in order to encrypt
278 messages sent to the specified resource.
279
280 Each fingerprint corresponds to a key used by the wiki to encrypt messages and
281 by the remote site (as identified by the URL) to decrypt messages.
282
283 Each wiki user can have their own recipients mapping by making a page, called
284 MoinMessageRecipientsDict unless overridden by the configuration, as a subpage
285 of their own home page.
286
287 The Relays Mapping
288 ------------------
289
290 The mapping from relay identifiers to remote URLs defined by the
291 MoinMessageRelayDict page is a WikiDict having the following general format:
292
293 relay:: url
294
295 The URL must be able to accept MoinMessage content, and it will typically be
296 configured so that the user or entity accepting relayed content on the remote
297 site can store such content for later propagation or retrieval.
298
299 Quick Start: Signing, Encrypting and Sending Messages
300 -----------------------------------------------------
301
302 To send a message signed and encrypted to a resource on localhost:
303
304 python tests/test_send.py 1C1AAF83 0891463A http://localhost/wiki/ShareTest \
305 collection update 'An update to the wiki.' 'Another update.'
306
307 Here, the first identifier is a reference to the signing key (over which you
308 have complete control), and the second identifier is a reference to the
309 encryption key (which is a public key published for the wiki).
310
311 This needs password protection to be removed from the secret key in the Web
312 server environment. It also uses a modified trust model when invoking gpg in
313 order to avoid complaints about the identity of the sender during encryption.
314
315 To sign the encrypted message for forwarding, the above command is modified:
316
317 python tests/test_send.py 1C1AAF83 0891463A --forward 1C1AAF83 \
318 http://localhost/wiki/ShareTest \
319 collection update 'An update to the wiki.' 'Another update.'
320
321 Explicit recipient information can be provided for routing purposes:
322
323 python tests/test_send.py 1C1AAF83 0891463A --to PaulBoddie \
324 --forward 1C1AAF83 \
325 http://localhost/wiki/ShareTest \
326 collection update 'An update to the wiki.' 'Another update.'
327
328 Below, the mechanisms employed are illustrated through the use of the other
329 test programs.
330
331 Signing
332 -------
333
334 Prepare a message signed with a "detached signature" (note that this does not
335 seem to be what gpg calls a detached signature with the --detach-sig option):
336
337 python tests/test_message.py collection update 'An update to the wiki.' \
338 'Another update.' \
339 | python tests/test_sign.py 1C1AAF83
340
341 The complicated recipe based on the individual operations is as follows:
342
343 python tests/test_message.py collection update 'An update to the wiki.' \
344 'Another update.' \
345 > test.txt \
346 && cat test.txt \
347 | gpg --armor -u 1C1AAF83 --detach-sig \
348 | python tests/test_sign_wrap.py test.txt
349
350 Encryption
351 ----------
352
353 Prepare a message with an encrypted payload using the above key:
354
355 python tests/test_message.py collection update 'An update to the wiki.' \
356 'Another update.' \
357 | python tests/test_encrypt.py 0891463A
358
359 The complicated recipe based on the individual operations is as follows:
360
361 python tests/test_message.py collection update 'An update to the wiki.' \
362 'Another update.' \
363 > test.txt \
364 && cat test.txt \
365 | gpg --armor -r 0891463A --encrypt --trust-model always \
366 | python tests/test_encrypt_wrap.py
367
368 Note that "--trust-model always" is used only to avoid prompting issues.
369
370 Signing and Encrypting
371 ----------------------
372
373 Sign and encrypt a message:
374
375 python tests/test_message.py collection update 'An update to the wiki.' \
376 'Another update.' \
377 | python tests/test_sign.py 1C1AAF83 \
378 | python tests/test_encrypt.py 0891463A
379
380 The complicated recipe based on the individual operations is as follows:
381
382 python tests/test_message.py collection update 'An update to the wiki.' \
383 'Another update.' \
384 > test.txt \
385 && cat test.txt \
386 | gpg --armor -u 1C1AAF83 --detach-sig \
387 | python tests/test_sign_wrap.py test.txt \
388 | gpg --armor -r 0891463A --encrypt --trust-model always \
389 | python tests/test_encrypt_wrap.py
390
391 Signing and Encrypting then Signing
392 -----------------------------------
393
394 Where a message is to be forwarded and not decrypted, it will be signed by the
395 author, encrypted, but then signed by the forwarder (perhaps initially the
396 author):
397
398 python tests/test_message.py collection update 'An update to the wiki.' \
399 'Another update.' \
400 | python tests/test_sign.py 1C1AAF83 \
401 | python tests/test_encrypt.py 0891463A \
402 | python tests/test_sign.py 1C1AAF83
403
404 The complicated recipe based on the individual operations is as follows:
405
406 python tests/test_message.py collection update 'An update to the wiki.' \
407 'Another update.' \
408 > test.txt \
409 && cat test.txt \
410 | gpg --armor -u 1C1AAF83 --detach-sig \
411 | python tests/test_sign_wrap.py test.txt \
412 | gpg --armor -r 0891463A --encrypt --trust-model always \
413 | python tests/test_encrypt_wrap.py \
414 > test2.txt \
415 && cat test2.txt \
416 | gpg --armor -u 1C1AAF83 --detach-sig \
417 | python tests/test_sign_wrap.py test2.txt
418
419 Posting a Message
420 -----------------
421
422 To post a signed and/or encrypted message, output from the above activities
423 can be piped into the following command:
424
425 python tests/test_post.py http://localhost/wiki/ShareTest
426
427 Here, the resource "/wiki/ShareTest" on localhost is presented with the
428 message.
429
430 Fetching Messages
431 -----------------
432
433 To fetch messages from a message store associated with a page, the following
434 command can be used:
435
436 python tests/test_fetch.py 1C1AAF83 0891463A http://localhost/wiki/ShareTest \
437 RETR
438
439 This should retrieve all messages from the store associated with the
440 "/wiki/ShareTest" resource on localhost.
441
442 Exporting and Sending Keys
443 --------------------------
444
445 To export a public key, the following command can be used:
446
447 python tests/text_export.py 1C1AAF83
448
449 This will output a public key block in a MIME message part suitable for
450 incorporation into a larger message or signing. Signing a message containing
451 such a key can be done as follows:
452
453 python tests/text_export.py 1C1AAF83 \
454 | python tests/test_sign.py 1C1AAF83
455
456 Obviously, this does not provide any additional reassurance about the nature
457 of the exported key other than the originator was able to sign it with the
458 same keypair information.
459
460 The Message Format
461 ------------------
462
463 Messages are MIME-encoded and consist of one or more update fragments. Where
464 the "Update-Type" header is present and set to a value of "collection", a
465 multipart message describes as many updates as there are parts. Otherwise,
466 only a single update is described by the message.
467
468 For each update, the "Update-Action" header indicates the action to be taken
469 with the update content. Where it is absent, the content is inserted into the
470 wiki page specified in the request; where it is present and set to "replace",
471 the content replaces all content on the wiki page; where it is set to "store",
472 the content is stored in a message store associated with the wiki page.
473
474 Each update may describe multiple representations of some content by employing
475 a multipart/alternative section containing parts for each of the
476 representations. Alternatively, a single message part may describe a single
477 representation.
478
479 HTTP Methods
480 ------------
481
482 Since MoinMoin seems to reserve POST methods for request/entity bodies that
483 contain HTML form data, it is necessary to use alternative methods to post
484 messages to a site served by MoinMoin and to fetch messages from such a site.
485 Consequently, MoinMessage uses PUT to post and fetch messages. Unfortunately,
486 MoinMoin 1.9 prevents the use of GET with request/entity bodies, and so the
487 natural usage of GET to fetch messages cannot be employed.
488
489 Contact, Copyright and Licence Information
490 ------------------------------------------
491
492 See the following Web page for more information about this work:
493
494 http://moinmo.in/ActionMarket/MoinMessage
495
496 The author can be contacted at the following e-mail address:
497
498 paul@boddie.org.uk
499
500 Copyright and licence information can be found in the docs directory - see
501 docs/COPYING.txt and docs/LICENCE.txt for more information.
502
503 Dependencies
504 ------------
505
506 MoinMessage has the following basic dependencies:
507
508 Packages Release Information
509 -------- -------------------
510
511 MoinSupport Tested with 0.5
512 Source: http://hgweb.boddie.org.uk/MoinSupport