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