Don't mention fetchmail in the TUTORIAL since fetchmail 7.0.0 hasn't been
[libpwmd.git] / doc / TUTORIAL
blob99826c592eb90e81daba337116d25c9732326a91
1 What is PWMD?
2 -------------
3 Password Manager Daemon (pwmd[1]) is a universal data server. Applications
4 connect to a unix domain socket and send commands to manipulate the data.  It
5 started out as a way to keep track of my passwords for accounts like email,
6 websites, etc. but can really be used to store anything you want.
8 There are other password management tools but PWMD has distinguishing
9 features:
11 - It does not depend on a desktop environment but has the ability for
12   applications to connect to it like a desktop solution provides.
14 - Some portion of a stored data can be "shared" with, or "linked to",
15   another data in the same data file. It's a lot like XML entities if
16   you're familiar with that, but implemented in a different way.
19 Element paths
20 -------------
21 The document is saved as an XML file and manipulated by commands sent from a
22 client. Commands that access elements take what I call an "element path" as an
23 argument. An element path is a character string that contains XML element
24 names representing branches of an element tree. The branches are separated
25 with a TAB (ASCII 0x09) character. Why a TAB? So other characters can be used
26 in the element name. If for example a '/' were used as the separator, then a
27 URL (i.e., http://sf.net/) could not be used as an element name.  In fact, the
28 only restriction of an element name is that it not contain any whitespace
29 characters and not begin with an exclamation point (ASCII 0x21 or !).
31 For the rest of this tutorial, when you see <TAB>, replace it with an actual
32 TAB character. For example, the element path "a<TAB>child<TAB>last" has the
33 following element tree:
35         <a>
36             <child>
37                 <last>
38                     Content or CDATA of the "last" element.
39                 </last>
40             </child>
41         </a>
43 I should say that the XML document that pwmd uses is a little more
44 complicated. It actually looks like the following internally but we will
45 use the above format in this tutorial for simplicity:
47         <element _name="a">
48             <element _name="child">
49                 <element _name="last">
50                     Content or CDATA of the "last" element.
51                 </element>
52             </element>
53         </element>
55 Every element created has an element named "element" with an attribute "_name"
56 associated with it. The value of the "_name" attribute is the what pwmd
57 commands use as the element name. It is done this way so that a wider range of
58 characters can be used in the element name while maintaining valid XML.
60 There is a difference from your normal XML document in that only the first
61 match of an element is considered for the current tree depth. When found, the
62 next element in the element path is searched for beginning at the child node
63 of the matched element. From the example above:
65         <a>
66             <child>
67                 <last>
68                     Content or CDATA of the "last" element.
69                 </last>
70             </child>
71             <child>
72                 This element will never be reached because its name
73                 "child" is the same as the previous or sibling element which
74                 is matched first.
75             </child>
76         </a>
78 The second "child" element is never reached, although an element of a
79 different name may be accessed. The exception to this are the XPATH and
80 XPATHATTR commands which process the entire document and do not use element
81 paths but XPath expressions.
84 Applications
85 ------------
86 Now that the basics of pwmd have been described, you will need a client
87 to send commands to the server to try it all out.
89 If you are making your own application and want to use pwmd or need a simple
90 client to connect to the server, a library called libpwmd[2] is available. It
91 has few dependencies and - as mentioned - includes a client named pwmc. The
92 rest of this tutorial uses pwmc for connecting. It is command-line based and
93 there are not any fancy graphics, but it is good for understanding how
94 commands are processed.
96 If you want a more user friendly client that kind of looks like a file
97 manager and has a point and click interface, try pwmdEdit[3] which is
98 based on the Qt4 toolkit library.
101 Connecting
102 ----------
103 We will be using pwmc as the client which is included with libpwmd. pwmc has
104 two modes that commands are read from: interactive and stdin. The interactive
105 mode uses the readline library and has command history. The default mode can
106 read commands from a pipe or standard input. For the following examples we
107 will be using interactive mode and connecting to the default local unix domain
108 socket that pwmd waits for connections on.  Remote connections are possible
109 over an SSH channel but that is not covered here.  Read the pwmc(1) manual
110 page for how to do that.
112 The example filename we will use is "datafile". Initially it is a non-existent
113 file but it will be created once we have saved to it. Now let us connect to the
114 server and open the new file in interactive mode.
116 $ pwmc --interactive datafile
117 Connected.
118 pwm>
120 The "pwm>" prompt is a readline prompt that has command history and can do
121 filename completion. It also is annoying because as mentioned above, elements
122 in element paths are TAB delimited but command completion in readline uses the
123 TAB character too. So to insert a real TAB character in interactive mode
124 you can do one of two things: either first press CTRL-V then TAB, or disable
125 the readline tab completion entirely by adding the following line to your
126 ~/.inputrc file:
128         set disable-completion on
130 This has the problem of disabling tab completion in all programs that use the
131 readline library. To fix this you can create a special inputrc that only pwmc
132 uses by setting the INPUTRC environment variable to a file that contains only
133 that line before running pwmc. For example:
135 $ INPUTRC=/path/to/pwmc-inputrc pwmc --interactive datafile
137 Now you can insert a TAB character without the readline library interfering.
140 Commands
141 --------
142 To store some data in an element path you will need to think about how you
143 want your data organized as elements in the document. If for example you will
144 be storing account information, then it may be a good idea to categorize what
145 the account is for: email, instant messaging, blogging, etc.
147 In the following example we will create element paths for an email account. An
148 email account usually needs a few details to be useful such as the hostname,
149 port, username and password elements.
151 Let us set up the email server information first:
153 pwm> INQUIRE STORE
155 A note before we continue: The INQUIRE command is a pwmc specific command and
156 only available in interactive mode. It is not a pwmd protocol command. It
157 takes an argument which is the protocol command that uses a server inquire,
158 and in this case, the STORE command. The equivalent to this when not in
159 interactive mode is to use the --inquire command line option. Refer to the
160 documentation of the protocol command to determine if it uses a server inquire
161 or not.
163 pwmc is now waiting for data after entering the above command. It's reading
164 from the standard input and not from the readline prompt so your TAB character
165 should work correctly:
167 email<TAB>isp<TAB>IMAP<TAB>hostname<TAB>imap.server.com<CTRL-D><CTRL-D>
169 Pressing <CTRL-D> sends the current line when non-empty and terminates the
170 INQUIRE when on an empty line. If you were to have pressed <RETURN> before
171 pressing any <CTRL-D> then the entire line would have been sent including the
172 newline character. And since a hostname containing a newline is not a valid
173 hostname, that is not what we want.
175 We have just created an element path whose structure looks like this:
177         <email>
178             <isp>
179                 <IMAP>
180                         <hostname>imap.server.com</hostname>
181                 </IMAP>
182             </isp>
183         </email>
185 It has good structure: the root element tells you what it's for, email in this
186 case. The next element, isp, could be replaced with something that shows what
187 email account this relates to. There are different email protocols like POP3,
188 IMAP and SMTP so creating an IMAP protocol tree makes sense too.
190 When a client needs to retrieve the value for the element path we have just
191 created, it sends the GET command with the element path as the argument:
193 pwm> GET email<TAB>isp<TAB>IMAP<TAB>hostname
194 imap.server.com
196 Remember that in interactive mode you will need to press <CTRL-V> before
197 pressing <TAB> unless you have configured an inputrc. The XFER lines are
198 status messages and can be disabled with the --no-status command line option.
199 They show the current and total length of data transfered in bytes. There are
200 other status messages too and are documented in pwmd. The last line is the
201 value of the element path that we just stored.
203 Let us create the rest of the needed elements:
205 pwm> INQUIRE STORE
206 email<TAB>isp<TAB>IMAP<TAB>port<TAB>993<CTRL-D><CTRL-D>
207 pwm> INQUIRE STORE
208 email<TAB>isp<TAB>username<TAB>myusername<CTRL-D><CTRL-D>
209 pwm> INQUIRE STORE
210 email<TAB>isp<TAB>password<TAB>mypassword<CTRL-D><CTRL-D>
212 Now the element structure for the root "email" element looks like this:
214         <email>
215             <isp>
216                 <IMAP>
217                         <hostname>imap.server.com</hostname>
218                         <port>993</port>
219                 </IMAP>
220                 <username>myusername</username>
221                 <password>mypassword</password>
222             </isp>
223         </email>
225 If you wanted to change your password (after changing it on the mail server of
226 course) just do as you did when initially creating the password element path.
227 The new content will overwrite the existing content:
229 pwm> INQUIRE STORE
230 email<TAB>isp<TAB>password<TAB>newpassword<CTRL-D><CTRL-D>
232 Lets save what we have stored so far. You could send the SAVE protocol command
233 but that may not work correctly depending on a few different things like file
234 cache status, pinentry settings or a remote connection. The best way is to let
235 pwmc do it by sending an EOL (end-of-line) character on an empty line:
237 pwm> <CTRL-D>
239 pwmc uses a pinentry program to ask for a passphrase when the passphrase
240 is not cached in pwmd. If you are using a GUI and have pinentry installed
241 then things are easy. A dialog box will pop up asking for a passphrase
242 then asking you to confirm it. Once done, the data file is encrypted and
243 written to disk and the passphrase is cached in pwmd so you do not need to
244 enter it the next time your data file is opened or saved. There are a
245 few pwmd configuration parameters that affect how this operates. See the
246 pwmd(1) manual page for details.
248 There is a pinentry program for the console, too. It uses the ncurses
249 interface and should work fine when not using the 'screen' program. When
250 in a screen session the pinentry will usually not behave correctly. The
251 solution is to make the pinentry use the terminal that screen was
252 started on rather than the current tty, which is the default. This is
253 done by setting TTYNAME in ~/.pwmd/pinentry.conf. See the pwmc(1) manual
254 page for details.
256 Applications that connect to pwmd by using the libpwmd API will more than
257 likely have different element path requirements. Refer to each application's
258 documentation that supports pwmd for the required elements.
261 Linking elements
262 ----------------
263 One distinguishing feature of pwmd is the ability to share or link to data of
264 one section of the XML document, to another. For example, if your ISP lets you
265 host a blog on their server and you use a blogging client (which uses libpwmd)
266 to edit your posts, you can share authentication information with the email
267 example above provided that the account details are the same.  When element
268 linking is used this avoids the need to change the password for both elements:
269 the email password and the blogging client password.
271 How this is done is by setting a special attribute "target" for an element. If
272 you know anything about HTML then you might know that a "target" attribute can
273 have an anchor pointing to a unique ID which will make the browser "jump" to
274 that position when selected. This is where the attribute name came from,
275 because it reminded me of HTML. :)
277 OK, let's create an example blogging element path:
279 pwm> INQUIRE STORE
280 blog<TAB>isp<TAB>hostname<TAB>blog.myisp.com<CTRL-D><CTRL-D>
281 pwm> ATTR SET target blog<TAB>isp<TAB>username email<TAB>isp<TAB>username
282 pwm> ATTR SET target blog<TAB>isp<TAB>password email<TAB>isp<TAB>password
284 Now each access of the "blog/isp/username" and "blog/isp/password" element
285 paths (which are created if they do not exist) will point to
286 "email/isp/username" and "email/isp/password" respectively. To get the value
287 or content of an element that contains a "target" attribute without following
288 any links, prefix the element with a '!' when specifying it in an element
289 path. For example:
291 pwm> GET blog<TAB>isp<TAB>!password
292 ERR 26: No value
294 Here, it is an error because we have not assigned a value to the literal
295 element. A literal element is an element that either contains no "target"
296 attribute or ignores the "target" attribute by prefixing the element with the
297 mentioned literal '!' character. Let us try storing an example password to the
298 literal element to show usage:
300 pwmd> INQUIRE STORE
301 blog<TAB>isp<TAB>!password<TAB>newpassword<CTRL-D><CTRL-D>
303 Now when we redo the previous GET command:
305 pwm> GET blog<TAB>isp<TAB>!password
306 XFER 0 11
307 XFER 11 11
308 newpassword
310 This is the value of the literal password element of the element path. To
311 follow the element path stored in the "target" attribute, omit the '!' in the
312 password element:
314 pwm> GET blog<TAB>isp<TAB>password
315 XFER 0 10
316 XFER 10 10
317 mypassword
319 "target" attributes may also reference other elements with a "target"
320 attribute. Every "target" attribute will be followed until there are no other
321 links to resolve. To get the real element path and resolve all "target"
322 attributes, use the REALPATH command:
324 pwm> REALPATH blog<TAB>isp<TAB>password
325 !email<TAB>!isp<TAB>!password
327 As you can see each element is prefixed with the literal '!' character meaning
328 that no "target" attribute exists in any element of the resulting element
329 path.
331 Use the LIST command to list the root elements of the document or the entire
332 element tree of an element path:
334 pwm> LIST
335 !email
336 !blog
338 pwm> LIST !blog
339 !blog
340 !blog<TAB>!isp
341 !blog<TAB>!isp<TAB>!username
342 !blog<TAB>!isp<TAB>username
343 !blog<TAB>!isp<TAB>!password
344 !blog<TAB>!isp<TAB>password
346 Notice that there are two username and password elements: each with and
347 without a literal prefix. This shows that the username and password elements
348 have a "target" attribute. If there were child elements of the non-literal
349 username and password elements then they would be shown as children of these
350 elements using the current element path as the prefix.
352 For the final example, we will remove the link or target of the blogging
353 password element:
355 pwm> ATTR DELETE target blog<TAB>isp<TAB>!password
357 If we were to have omitted the '!' from the password element then pwmd would
358 try to remove a "target" attribute of the "email/isp/password" element path
359 and would return an error because that attribute has not been set for that
360 element. Note that the "blog" and "isp" elements have no literal element
361 character prepended to them. It is not needed because they have no link or
362 target attribute set.
364 The best way to get the hang of linking elements is to experiment. Use the
365 LIST and DUMP commands to show the document structure and remember to use the
366 literal prefix '!' when you do not want to follow any links or "target"
367 attributes for element that have them.
370 Ben Kibbey <bjk@luxsci.net>
372 1. http://bjk.sourceforge.net/pwmd/
373 2. http://bjk.sourceforge.net/pwmd/libpwmd/
374 3. http://bjk.sourceforge.net/pwmd/pwmdedit/