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.
9
10 Configuring GPG for a Wiki
11 --------------------------
12
13 Initialise a homedir for GPG and configure it using ACL (access control list)
14 properties:
15
16 ./scripts/init_wiki_keyring.sh WIKI WEBUSER
17
18 Here, WIKI should be replaced by the top-level Wiki instance directory, and
19 WEBUSER should be the name of the user under which the Web server operates.
20
21 Note that this script may need re-running after the homedir has been changed
22 by gpg operations as gpg likes to remove permissions from various files.
23
24 To be in any way useful, signing keys must be made available within this
25 homedir so that incoming messages can have their senders verified.
26
27 To see the keys available to you in your own environment:
28
29 gpg --list-keys --with-fingerprint
30
31 The full fingerprints are used when defining a user mapping in the Wiki, and
32 the --with-fingerprint option is used to show them. Otherwise, only the last
33 eight characters of the fingerprints are shown.
34
35 Export the public key used when signing messages from your own environment:
36
37 gpg --armor --output 1C1AAF83.asc --export 1C1AAF83
38
39 Import the key into the Wiki's GPG homedir:
40
41 gpg --homedir wiki/gnupg --import 1C1AAF83.asc
42
43 For the Wiki to receive encrypted data, a key for the Wiki must be created:
44
45 gpg --homedir wiki/gnupg --gen-key
46
47 For the Wiki environment to be able to use the key, password access must be
48 disabled. This can be done by either not specifying a password or by removing
49 it later using the --edit-key option.
50
51 Export the Wiki's key for encrypting messages sent to the Wiki:
52
53 gpg --homedir wiki/gnupg --armor --output 0891463A.asc --export 0891463A
54
55 This exported key can now be imported into your own environment:
56
57 gpg --import 0891463A.asc
58
59 Configuring the Wiki
60 --------------------
61
62 In the Wiki configuration, define the following settings:
63
64 moinmessage_gpg_homedir
65 This sets the path to the homedir initialised above.
66
67 moinmessage_gpg_users_page (optional, default is MoinMessageUserDict)
68 This provides a mapping from key fingerprints to Moin usernames.
69
70 moinmessage_gpg_signing_users_page (optional, default is MoinMessageSigningUserDict)
71 This provides a mapping from Moin usernames to key fingerprints.
72
73 moinmessage_gpg_recipients_page (optional, default is MoinMessageRecipientsDict)
74 This provides a mapping from recipients to remote URLs and key fingerprints.
75
76 moinmessage_reject_messages_without_dates (optional, default is True)
77 This causes messages sent to a Wiki using the PostMessage action to be
78 rejected if date information is missing.
79
80 Fingerprints and Keys
81 ---------------------
82
83 All fingerprints mentioned in the various configuration pages must exclude
84 space characters - that is, the letters and digits must appear together in a
85 continuous block of text - and refer to keys available in the Wiki homedir.
86
87 The Fingerprint-to-Username Mapping
88 -----------------------------------
89
90 The mapping from fingerprints to usernames typically defined by the
91 MoinMessageUserDict page is a WikiDict having the following general format:
92
93 fingerprint:: username
94
95 Each fingerprint corresponds to a key used by a person wanting to send
96 messages to the Wiki to sign such messages.
97
98 Each username must correspond to a registered user in the Wiki.
99
100 The Username-to-Signing Key Mapping
101 -----------------------------------
102
103 The mapping from usernames to fingerprints typically defined by the
104 MoinMessageSigningUserDict page is a WikiDict having the following general
105 format:
106
107 username:: fingerprint
108
109 Each fingerprint corresponds to a key available in the Wiki's GPG homedir
110 generated for the purpose of signing the specified user's messages. Such a key
111 is not the same as one used by a person to send messages to the Wiki since
112 only the public key used to verify such messages should be known to the Wiki.
113
114 The Recipients Mapping
115 ----------------------
116
117 The mapping from recipients to remote URLs and fingerprints typically defined
118 by the MoinMessageRecipientsDict page is a WikiDict having the following
119 general format:
120
121 recipient:: URL fingerprint
122
123 Each URL must refer to a resource that can accept MoinMessage content.
124
125 Each fingerprint corresponds to a key used by the remote site (as identified
126 by the URL) for the decryption of messages.
127
128 Quick Start: Signing, Encrypting and Sending Messages
129 -----------------------------------------------------
130
131 To send a message signed and encrypted to a resource on localhost:
132
133 python tests/test_send.py 1C1AAF83 0891463A http://localhost/wiki/ShareTest \
134 collection update 'An update to the Wiki.' 'Another update.'
135
136 Here, the first identifier is a reference to the signing key (over which you
137 have complete control), and the second identifier is a reference to the
138 encryption key (which is a public key published for the Wiki).
139
140 This needs password protection to be removed from the secret key in the Web
141 server environment. It also uses a modified trust model when invoking gpg in
142 order to avoid complaints about the identity of the sender during encryption.
143
144 Below, the mechanisms employed are illustrated through the use of the other
145 test programs.
146
147 Signing
148 -------
149
150 Prepare a message signed with a "detached signature" (note that this does not
151 seem to be what gpg calls a detached signature with the --detach-sig option):
152
153 python tests/test_message.py collection update 'An update to the Wiki.' \
154 'Another update.' \
155 | python tests/test_sign.py 1C1AAF83
156
157 The complicated recipe based on the individual operations is as follows:
158
159 python tests/test_message.py collection update 'An update to the Wiki.' \
160 'Another update.' \
161 > test.txt \
162 && cat test.txt \
163 | gpg --armor -u 1C1AAF83 --detach-sig \
164 | python tests/test_sign_wrap.py test.txt
165
166 Encryption
167 ----------
168
169 Prepare a message with an encrypted payload using the above key:
170
171 python tests/test_message.py collection update 'An update to the Wiki.' \
172 'Another update.' \
173 | python tests/test_encrypt.py 0891463A
174
175 The complicated recipe based on the individual operations is as follows:
176
177 python tests/test_message.py collection update 'An update to the Wiki.' \
178 'Another update.' \
179 > test.txt \
180 && cat test.txt \
181 | gpg --armor -r 0891463A --encrypt --trust-model always \
182 | python tests/test_encrypt_wrap.py
183
184 Note that "--trust-model always" is used only to avoid prompting issues.
185
186 Signing and Encrypting
187 ----------------------
188
189 Sign and encrypt a message:
190
191 python tests/test_message.py collection update 'An update to the Wiki.' \
192 'Another update.' \
193 | python tests/test_sign.py 1C1AAF83 \
194 | python tests/test_encrypt.py 0891463A
195
196 The complicated recipe based on the individual operations is as follows:
197
198 python tests/test_message.py collection update 'An update to the Wiki.' \
199 'Another update.' \
200 > test.txt \
201 && cat test.txt \
202 | gpg --armor -u 1C1AAF83 --detach-sig \
203 | python tests/test_sign_wrap.py test.txt \
204 | gpg --armor -r 0891463A --encrypt --trust-model always \
205 | python tests/test_encrypt_wrap.py
206
207 Posting a Message
208 -----------------
209
210 To post a signed and/or encrypted message, output from the above activities
211 can be piped into the following command:
212
213 python tests/test_post.py http://localhost/wiki/ShareTest
214
215 Here, the resource "/wiki/ShareTest" on localhost is presented with the
216 message.
217
218 The Message Format
219 ------------------
220
221 Messages are MIME-encoded and consist of one or more update fragments. Where
222 the "Update-Type" header is present and set to a value of "collection", a
223 multipart message describes as many updates as there are parts. Otherwise,
224 only a single update is described by the message.
225
226 For each update, the "Update-Action" header indicates the action to be taken
227 with the update content. Where it is absent, the content is inserted into the
228 Wiki page specified in the request; where it is present and set to "replace",
229 the content replaces all content on the Wiki page; where it is set to "store",
230 the content is stored in a message store associated with the Wiki page.
231
232 Each update may describe multiple representations of some content by employing
233 a multipart section containing parts for each of the representations.
234 Alternatively, a single message part may describe a single representation.