pwmc: let the -i option have priority over the ssh agent. The --url
[libpwmd.git] / doc / tutorial.sgml
blob554b4ae1fdeac23dd22812fd35112874791f037b
1 <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V4.2//EN"
2 [ <!ENTITY % output.print.png "IGNORE">
3 <!ENTITY % output.print.pdf "IGNORE">
4 <!ENTITY % output.print.eps "IGNORE">
5 <!ENTITY % output.print.bmp "IGNORE">
6 ]>
8 <!-- SGML file was created by LyX 1.6.7
9 See http://www.lyx.org/ for more information -->
10 <article lang="en">
11 <articleinfo>
12 <title>PWMD Tutorial</title>
13 <date>12-31-2010</date><author>
14 Ben Kibbey</author><toc></toc></articleinfo><sect1>
15 <title>Introduction</title>
16 <para>This is a tutorial on how to configure and use the Password Manager Daemon or otherwise known as <emphasis><ulink url="http://pwmd.sourceforge.net/">pwmd</ulink></emphasis>. It also shows how to connect to the server using <emphasis>pwmc</emphasis>, a client included with <emphasis><ulink url="http://libpwmd.sourceforge.net/">libpwmd</ulink></emphasis> and how to use the more basic commands to store and retrieve data.</para></sect1><sect1>
17 <title>What is PWMD?</title>
18 <para>Password Manager Daemon is a universal data server. Applications connect to a unix domain socket and send commands to manipulate the data. It started out as a way to keep track of my passwords for accounts like email, websites, etc. but can really be used to store anything you want.</para>
19 <para>There are other password management tools but pwmd has a couple of distinguishing features:</para><itemizedlist>
20 <listitem><para>It does not depend on a desktop environment but has the ability for applications to connect to it like a desktop solution provides.</para></listitem><listitem><para>Some portion of a stored data can be "shared" with, or "linked to", another data in the same data file. It's a lot like XML entities, or HTML targets if you're familiar with those, but implemented in a different way.</para></listitem></itemizedlist></sect1><sect1>
21 <title>Element paths</title>
22 <para>The document is saved as an XML file and manipulated by commands sent from a client. A command that accesses data in the document take what is called an <emphasis>element path</emphasis> as an argument. An element path is a character string that contains XML element names that represents branches of an element tree. The branches are separated with a TAB (ASCII 0x09) character. Why a TAB? So other characters can be used in the element name. If for example a '/' were used as the separator, then a URL (i.e., http://sf.net/) could not be used as an element name. In fact, the only restriction of an element name is that it not contain any whitespace characters and not begin with an exclamation point (ASCII 0x21 or !). See <emphasis><xref linkend="sec.Linking-elements-1"> </emphasis>for an exception.</para>
23 <para>For the rest of this tutorial, when you see &lt;TAB&gt;, replace it with an actual TAB character. For example, the element path "a&lt;TAB&gt;child&lt;TAB&gt;last" has the following element tree:</para><screen>
24 <![CDATA[<a>
25 <child>
26 <last>
27 Content or CDATA of the "last" element.
28 </last>
29 </child>
30 </a>
31 ]]></screen><para>I should say that the XML document that pwmd uses is a little more complicated. It actually looks like the following internally but we will use the above format in this tutorial for simplicity:</para><screen>
32 <![CDATA[<element _name="a">
33 <element _name="child">
34 <element _name="last">
35 Content or CDATA of the "last" element.
36 </element>
37 </element>
38 </element>
39 ]]></screen><para>Every element created has an element named <emphasis>element</emphasis> with an attribute <emphasis>_name</emphasis> associated with it. The value of the <emphasis>_name</emphasis> attribute is what an element in and element path refers to. It is done this way so that a wider range of characters can be used in an element name while maintaining valid XML.</para>
40 <para>There is a difference from your normal XML document in that only the first match of an element is considered for the current tree depth. When found, the next element in the element path is searched beginning at the child node of the matched element. From the example above:</para><screen>
41 <![CDATA[<a>
42 <child>
43 <last>
44 Content or CDATA of the "last" element.
45 </last>
46 </child>
47 <child>
48 This element will never be reached.
49 </child>
50 </a>
51 ]]></screen><para>The second "child" element is never reached although an element of a different name may be accessed. The exception is when using the XPATH and XPATHATTR commands because they process the entire XML document and do not use element paths but XPath expressions.</para></sect1><sect1>
52 <title>Clients</title>
53 <para>Now that the basics of pwmd have been described, you will need a client to send commands to the server to try it all out. If you are making your own application or need a simple client to connect to the server, a library called libpwmd is available. It has few dependencies and - as mentioned - includes a client named <emphasis>pwmc</emphasis>. The rest of this tutorial uses pwmc for connecting. It is command-line based and there are not any fancy graphics, but it is good for understanding how protocol commands are processed.</para>
54 <para>If you want a more user friendly client that kind of looks like a file manager and has a point and click interface then try <ulink url="http://qpwmc.sourceforge.net/">pwmdEdit</ulink> which is based on the Qt4 toolkit library.</para></sect1><sect1>
55 <title>Connecting</title>
56 <para>We will be using pwmc as the client which is included with libpwmd. pwmc has two modes that commands are read from: interactive and stdin. The interactive mode uses the readline library and has command history. The non-interactive mode reads from standard input makes shell scripting and automation easy.</para>
57 <para>For the following examples we will be connecting to the default local unix domain socket that pwmd waits for connections on. Remote connections are possible over an SSH channel but that is not covered here. Read the pwmc(1) manual page for how to do that.</para>
58 <para>The example filename we will use is "datafile". It is initially a non-existent file but it will be created once we have saved to it. Now let us connect to the server and open the new data file in in interactive mode:</para><screen>
59 <![CDATA[$ pwmc --interactive datafile
60 Connected.
61 pwm>
62 ]]></screen><para>The "pwm&gt;" prompt is a readline prompt that has command history and can do filename completion. It is also annoying because as mentioned above, elements in element paths are TAB delimited but command completion in readline uses the TAB character, too. So to insert a real TAB character in interactive mode you can do one of two things: either first press CTRL-V then TAB, or alternately disable readline tab completion entirely by adding the following line to your <emphasis>~/.inputrc</emphasis> file:</para><screen>
63 <![CDATA[set disable-completion on
64 ]]></screen><para>This has the problem of disabling tab completion in all programs that use the readline library. To fix this you can create a special inputrc that only pwmc uses by setting the INPUTRC environment variable to a file that contains only the above mentioned line before running pwmc. For example:</para><screen>
65 <![CDATA[$ INPUTRC=/path/to/pwmc-inputrc pwmc --interactive datafile
66 ]]></screen><para>You can now insert a TAB character without the readline library interfering. </para></sect1><sect1>
67 <title>Commands</title>
68 <para>To store some data in an element path you will need to think about how you want your data organized as elements in the document. If for example you will be storing account information, then it may be a good idea to categorize what the account is for: email, instant messaging, blogging, etc.</para>
69 <para>In the following example we will create element paths for an email account. An email account usually needs a few details to be useful such as the hostname, port, username and password elements.</para>
70 <para>Let us set up the email server information first:</para><screen>
71 <![CDATA[pwm> INQUIRE STORE
72 ]]></screen><para>A note before we continue: The INQUIRE command is a pwmc specific command and only available in interactive mode. It is not a pwmd protocol command. It takes an argument which is the protocol command that uses a server inquire, and in this case, the STORE command. The equivalent to this when not in interactive mode is to use the --inquire command line option. Refer to the documentation of the protocol command to determine if it uses a server inquire or not. The HELP protocol command may be of use.</para>
73 <para>pwmc is now waiting for data after entering the above command. It is reading from the standard input and not from the readline prompt so your TAB character should work correctly:</para><screen>
74 <![CDATA[email<TAB>isp<TAB>IMAP<TAB>hostname<TAB>imap.server.com<CTRL-D><CTRL-D>
75 ]]></screen><para>Pressing &lt;CTRL-D&gt; sends the current line when non-empty and terminates the INQUIRE when on an empty line. If you were to have pressed &lt;RETURN&gt; before pressing any &lt;CTRL-D&gt; then the entire line would have been sent including the newline character. And since a hostname containing a newline is not a valid hostname, that is not what we want.</para>
76 <para>We have just created an element path whose structure looks like this:</para><screen>
77 <![CDATA[<email>
78 <isp>
79 <IMAP>
80 <hostname>
81 imap.server.com
82 </hostname>
83 </IMAP>
84 </isp>
85 </email>
86 ]]></screen><para>It has good structure: the root element tells you what it's for, email in this case. The next element, isp, could be replaced with something else that shows what email account this relates to; gmail.com for example. There are different email protocols like POP3, IMAP and SMTP so creating an IMAP protocol tree makes sense, too.</para>
87 <para>When a client needs to retrieve the value for the element path we have just created, it sends the GET command with the element path as the argument:</para><screen>
88 <![CDATA[pwm> GET email<TAB>isp<TAB>IMAP<TAB>hostname<ENTER>
89 XFER 0 15
90 XFER 15 15
91 imap.server.com
92 ]]></screen><para>Remember that when in interactive mode you will need to press &lt;CTRL-V&gt; before pressing &lt;TAB&gt; unless you have configured an inputrc. The XFER lines are status messages and can be disabled with the --no-status command line option. They show the current and total length of data transfered in bytes. There are other server status messages and are documented in pwmd. The last line is the value of the element path that we have just stored. As you can see, that last TAB delimited argument is the value of the element path when using the STORE command.</para>
93 <para>Let us create the rest of the needed elements:</para><screen>
94 <![CDATA[pwm> INQUIRE STORE
95 email<TAB>isp<TAB>IMAP<TAB>port<TAB>993<CTRL-D><CTRL-D>
96 pwm> INQUIRE STORE
97 email<TAB>isp<TAB>username<TAB>myusername<CTRL-D><CTRL-D>
98 pwm> INQUIRE STORE
99 email<TAB>isp<TAB>password<TAB>mypassword<CTRL-D><CTRL-D>
100 ]]></screen><para>The element structure for the root "email" element now looks like this:</para><screen>
101 <![CDATA[<email>
102 <isp>
103 <IMAP>
104 <hostname>imap.server.com</hostname>
105 <port>993</port>
106 </IMAP>
107 <username>myusername</username>
108 <password>mypassword</password>
109 </isp>
110 </email>
111 ]]></screen><para>If you wanted to change your password (after changing it on the mail server of course) just do as you did when initially creating the password element path. The new content will overwrite the existing content:</para><screen>
112 <![CDATA[pwm> INQUIRE STORE
113 email<TAB>isp<TAB>password<TAB>newpassword<CTRL-D><CTRL-D>
114 ]]></screen><para>Lets save what we have stored so far. You could send the SAVE protocol command but that may not work correctly depending on a few different things like file cache status, pinentry settings or a remote connection. The best way is to let pwmc do it by sending an EOL (end-of-line) character on an empty line:</para><screen>
115 <![CDATA[pwm> <CTRL-D>
116 ]]></screen><para>pwmc uses a pinentry program to ask for a passphrase when the passphrase is not cached in pwmd. If you are using a GUI and have pinentry installed then things are easy: A dialog box will pop up asking for a passphrase then asking you to confirm it. Once done, the data file is encrypted and written to disk and the passphrase is cached in pwmd so you do not need to enter it the next time your data file is opened or saved. There are a few pwmd configuration parameters that affect how this operates. See the pwmd(1) manual page for details.</para>
117 <para>There is also a pinentry program for the console, too. It uses the ncurses interface and should work fine when not using the 'screen' program. When in a screen session the pinentry will usually not behave correctly. The solution is to make the pinentry use the terminal that screen was started on rather than the current tty, which is the default. This is done by setting TTYNAME in ~/.pwmd/pinentry.conf. See the pwmc(1) manual page for details.</para>
118 <para>If you still cannot get pinentry to work correctly then you can add --no-pinentry to the command line. This will prompt for a passphrase on the current terminal rather than trying to use any pinentry program what-so-ever.</para>
119 <para>Applications that connect to pwmd by using the libpwmd API will more than likely have different element path requirements. Refer to each application's documentation that supports pwmd for the required elements.</para></sect1><sect1 id='sec.Linking-elements-1' >
120 <title><!-- anchor id="sec.Linking-elements-1" -->Linking elements</title>
121 <para>One distinguishing feature of pwmd is the ability to share or link to data of one section of the XML document, to another. For example, if your ISP lets you host a blog on their server and you use a blogging client (which has libpwmd support) to edit your posts, you can share authentication information with the email example above provided that the account details are the same. When element linking is used then this avoids the need to change the password for both the email and blogging password elements.</para>
122 <para>How this is done is by setting a special attribute "target" for an element. If you know anything about HTML then you might know that a "target" attribute can have an anchor pointing to a unique ID which will make the browser "jump" to that position when selected. This is where the attribute name came from, because it reminded me of HTML. :) It is also very similar to how XML entities operate.</para>
123 <para>OK, let's create an example blogging element path:</para><screen>
124 <![CDATA[pwm> INQUIRE STORE
125 blog<TAB>isp<TAB>hostname<TAB>blog.myisp.com<CTRL-D><CTRL-D>
126 pwm> ATTR SET target blog<TAB>isp<TAB>username email<TAB>isp<TAB>username<ENTER>
127 pwm> ATTR SET target blog<TAB>isp<TAB>password email<TAB>isp<TAB>password<ENTER>
128 ]]></screen><para>Each access of the "blog/isp/username" and "blog/isp/password" element paths (which will be automatically created if they do not exist) will point to "email/isp/username" and "email/isp/password", respectively. To get the value or content of an element that contains a "target" attribute without following any links, prefix the element with the literal element character '!' when specifying it in an element path:</para><screen>
129 <![CDATA[pwm> GET blog<TAB>isp<TAB>!password<ENTER>
130 ERR 26: No value
131 ]]></screen><para>It is an error here because we have not assigned a value to the literal element. A literal element is an element that either contains no "target" attribute or ignores the "target" attribute by prefixing the element with the mentioned literal '!' character. Let us try storing an example password to the literal element to show usage:</para><screen>
132 <![CDATA[pwm> INQUIRE STORE
133 blog<TAB>isp<TAB>!password<TAB>newpassword<CTRL-D><CTRL-D>
134 ]]></screen><para>When we redo the previous GET command:</para><screen>
135 <![CDATA[pwm> GET blog<TAB>isp<TAB>!password<ENTER>
136 newpassword
137 ]]></screen><para>the value is of the literal password element and not that of the target. To follow the element path stored in the "target" attribute, omit the '!' in the password element:</para><screen>
138 <![CDATA[pwm> GET blog<TAB>isp<TAB>password<ENTER>
139 mypassword
140 ]]></screen><para>"target" attributes may also refer to other elements with a "target" attribute. Every "target" attribute will be followed until there are no other links to resolve. To get the real element path and resolve all "target" attributes, use the REALPATH command:</para><screen>
141 <![CDATA[pwm> REALPATH blog<TAB>isp<TAB>password<ENTER>
142 !email<TAB>!isp<TAB>!password
143 ]]></screen><para>As you can see each element is prefixed with the literal '!' character meaning that no "target" attribute exists in any element of the resulting element path.</para>
144 <para>Use the LIST command to list the root elements of the document or the entire element tree of an element path:</para><screen>
145 <![CDATA[pwm> LIST<ENTER>
146 !email
147 !blog
148 pwm> LIST !blog<ENTER>
149 !blog
150 !blog<TAB>!isp
151 !blog<TAB>!isp<TAB>!username
152 !blog<TAB>!isp<TAB>username
153 !blog<TAB>!isp<TAB>!password
154 !blog<TAB>!isp<TAB>password
155 ]]></screen><para>Notice that there are two username and password elements: each with and without a literal prefix. This shows that the username and password elements have a "target" attribute. If there were child elements of the non-literal username and password elements then they would be shown as children of these elements using the current element path as the child prefix.</para>
156 <para>For the final example, we will remove the link or target of the blogging password element:</para><screen>
157 <![CDATA[pwm> ATTR DELETE target blog<TAB>isp<TAB>!password<ENTER>
158 ]]></screen><para>If we were to have omitted the '!' from the password element then pwmd would try to remove a "target" attribute from the "email/isp/password" element path and would return an error because that attribute has not been set for that element. Note that the "blog" and "isp" elements have no literal element character prepended to them in the example. It is not needed because they have no link or target attribute set.</para>
159 <para>The best way to get the hang of linking elements is to experiment. Use the LIST and DUMP commands to show the document structure and remember to use the literal prefix '!' when you do not want to follow any links or "target" attributes for element that have them.</para></sect1></article>