<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="http://commons.oreilly.com/wiki/skins/common/feed.css?97"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://commons.oreilly.com/wiki/index.php?title=JabChapter_7&amp;action=history&amp;feed=atom</id>
		<title>JabChapter 7 - Revision history</title>
		<link rel="self" type="application/atom+xml" href="http://commons.oreilly.com/wiki/index.php?title=JabChapter_7&amp;action=history&amp;feed=atom"/>
		<link rel="alternate" type="text/html" href="http://commons.oreilly.com/wiki/index.php?title=JabChapter_7&amp;action=history"/>
		<updated>2013-05-19T03:25:29Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.11.0</generator>

	<entry>
		<id>http://commons.oreilly.com/wiki/index.php?title=JabChapter_7&amp;diff=25622&amp;oldid=prev</id>
		<title>Uncopy: content navi added</title>
		<link rel="alternate" type="text/html" href="http://commons.oreilly.com/wiki/index.php?title=JabChapter_7&amp;diff=25622&amp;oldid=prev"/>
				<updated>2009-09-18T14:22:44Z</updated>
		
		<summary type="html">&lt;p&gt;content navi added&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 14:22, 18 September 2009&lt;/td&gt;
			&lt;/tr&gt;
		&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;{{Content Programming Jabber}}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;=User Registration and Authorization=&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;=User Registration and Authorization=&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;br&amp;gt;With all of Jabber's building blocks at&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;br&amp;gt;With all of Jabber's building blocks at&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;!-- diff cache key wikicontent:diff:version:1.11a:oldid:1741:newid:25622 --&gt;
&lt;/table&gt;</summary>
		<author><name>Uncopy</name></author>	</entry>

	<entry>
		<id>http://commons.oreilly.com/wiki/index.php?title=JabChapter_7&amp;diff=1741&amp;oldid=prev</id>
		<title>Mikeh at 02:39, 16 September 2006</title>
		<link rel="alternate" type="text/html" href="http://commons.oreilly.com/wiki/index.php?title=JabChapter_7&amp;diff=1741&amp;oldid=prev"/>
				<updated>2006-09-16T02:39:16Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;=User Registration and Authorization=&lt;br /&gt;
&amp;lt;br&amp;gt;With all of Jabber's building blocks at&lt;br /&gt;
our fingertips, we can now take a look at two fundamental processes that&lt;br /&gt;
revolve around Jabber users:&lt;br /&gt;
&lt;br /&gt;
* The registration, or creation, of Jabber user accounts &lt;br /&gt;
* The authentication of a Jabber user account, including the different&lt;br /&gt;
authentication methods These processes involve some of the things we&lt;br /&gt;
learned about in Chapter 5 and Chapter 6, so we'll take a look at them&lt;br /&gt;
again along the way:&lt;br /&gt;
&lt;br /&gt;
* The XML stream header &lt;br /&gt;
* The &amp;lt;tt&amp;gt;jabber:iq:register&amp;lt;/tt&amp;gt; namespace &lt;br /&gt;
* The &amp;lt;tt&amp;gt;jabber:iq:auth&amp;lt;/tt&amp;gt; namespace At the end of this chapter,  we&lt;br /&gt;
will create a small utility program with which we can register users on&lt;br /&gt;
a server. We can then use this utility program to create users as&lt;br /&gt;
required for further recipes in this book.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== XML Stream Flow == &lt;br /&gt;
&amp;lt;br&amp;gt;User registration and user authorization are two&lt;br /&gt;
processes that take place at the start of an XML stream, immediately&lt;br /&gt;
following the XML stream header exchange. The Jabber server is designed&lt;br /&gt;
to check for  and process any user registration request or&lt;br /&gt;
authentication request ''before'' anything else.&lt;br /&gt;
&lt;br /&gt;
This makes sense, as outside of a session (a session is created for a&lt;br /&gt;
user when the authentication completes successfully), any other &lt;br /&gt;
element—a &amp;lt;tt&amp;gt;&amp;amp;lt;message/&amp;amp;gt;&amp;lt;/tt&amp;gt; element, a&lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;amp;lt;presence/&amp;amp;gt;&amp;lt;/tt&amp;gt; element, or an  &amp;lt;tt&amp;gt;&amp;amp;lt;iq/&amp;amp;gt;&amp;lt;/tt&amp;gt; element&lt;br /&gt;
that doesn't contain an extension qualified by the&lt;br /&gt;
&amp;lt;tt&amp;gt;jabber:iq:register&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;jabber:iq:auth&amp;lt;/tt&amp;gt; namespaces—is&lt;br /&gt;
invalid. So if any of these other elements are sent ''before''&lt;br /&gt;
authentication has taken place (that is, before a session has been&lt;br /&gt;
created for that connection), they are queued and processed ''after''&lt;br /&gt;
authentication.&lt;br /&gt;
&lt;br /&gt;
Figure 7-1 shows the general flow within an  XML stream, with regard to&lt;br /&gt;
where the registration and/or authentication steps happen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:jab_0701.png|XML stream flow showing registration and authentication|center|350 px]]&lt;br /&gt;
&amp;lt;br&amp;gt;-&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
== User Registration == &lt;br /&gt;
&amp;lt;br&amp;gt;User registration with a Jabber ''server''&lt;br /&gt;
specifically means the creation (or modification) of a user account for&lt;br /&gt;
the JSM component—the component that provides the basic IM services and&lt;br /&gt;
has a notion of users and user sessions. It takes place at the start of&lt;br /&gt;
a connection to a Jabber server, as does user authentication, as shown&lt;br /&gt;
in Figure 7-1.&lt;br /&gt;
&lt;br /&gt;
Let's take a look at the XML fragments involved in a typical user&lt;br /&gt;
registration process. Example 7-1 shows the XML stream header exchange&lt;br /&gt;
and the IQ packets in the  &amp;lt;tt&amp;gt;jabber:iq:register&amp;lt;/tt&amp;gt; namespace.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''A typical user registration process'' First is the XML stream header&lt;br /&gt;
exchange:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SEND: &amp;amp;lt;?xml version='1.0'?&amp;amp;gt; &amp;amp;lt;stream:stream to='yak'&lt;br /&gt;
xmlns='jabber:client'&lt;br /&gt;
xmlns:stream='http://etherx.jabber.org/streams'&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
RECV: &amp;amp;lt;?xml version='1.0'?&amp;amp;gt; &amp;amp;lt;stream:stream&lt;br /&gt;
xmlns:stream='http://etherx.jabber.org/streams' id='3B2DB1A7'&lt;br /&gt;
xmlns='jabber:client' from='yak'&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then the client sends a request to discover what information must be&lt;br /&gt;
passed to the Jabber server to register a new user:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SEND: &amp;amp;lt;iq type='get'&amp;amp;gt; &amp;amp;lt;query&lt;br /&gt;
xmlns='jabber:iq:register'/&amp;amp;gt; &amp;amp;lt;/iq&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
RECV: &amp;amp;lt;iq type='result'&amp;amp;gt; &amp;amp;lt;query xmlns='jabber:iq:register'&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;instructions&amp;amp;gt; Choose a username and password to register with&lt;br /&gt;
this server. &amp;amp;lt;/instructions&amp;amp;gt; &amp;amp;lt;name/&amp;amp;gt; &amp;amp;lt;email/&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;username/&amp;amp;gt; &amp;amp;lt;password/&amp;amp;gt; &amp;amp;lt;/query&amp;amp;gt; &amp;amp;lt;/iq&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The client does as asked and sends the required information, which&lt;br /&gt;
results in a successful new user registration:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SEND: &amp;amp;lt;iq type='set'&amp;amp;gt; &amp;amp;lt;query&lt;br /&gt;
xmlns='jabber:iq:register'&amp;amp;gt; &amp;amp;lt;username&amp;amp;gt;leslie&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;password&amp;amp;gt;secret&amp;amp;lt;/password&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;email&amp;amp;gt;lel@plevna.com&amp;amp;lt;/email&amp;amp;gt; &amp;amp;lt;name&amp;amp;gt;Leslie&lt;br /&gt;
Hawke&amp;amp;lt;/name&amp;amp;gt; &amp;amp;lt;/query&amp;amp;gt; &amp;amp;lt;/iq&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
RECV: &amp;amp;lt;iq type='result'/&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configuration and Module Load Directives === &lt;br /&gt;
&amp;lt;br&amp;gt;Lets start by reviewing&lt;br /&gt;
the relevant configuration in  jabber.xml. User registration is a JSM&lt;br /&gt;
feature, and we find two places of interest in that component instance&lt;br /&gt;
definition. The first is in that instance's configuration, in the&lt;br /&gt;
section qualified by the &amp;lt;tt&amp;gt;jabber:config:jsm&amp;lt;/tt&amp;gt; namespace:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;amp;lt;register notify=&amp;quot;yes&amp;quot;&amp;amp;gt; &amp;amp;lt;instructions&amp;amp;gt; Choose a&lt;br /&gt;
username and password to register with this server.&lt;br /&gt;
&amp;amp;lt;/instructions&amp;amp;gt; &amp;amp;lt;name/&amp;amp;gt; &amp;amp;lt;email/&amp;amp;gt; &amp;amp;lt;/register&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second is in that instance's connection method, showing the &lt;br /&gt;
''mod_register'' module being loaded. The module plays a major part in&lt;br /&gt;
handling the registration process, but there are others, too, as we will&lt;br /&gt;
see:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;amp;lt;load main=&amp;quot;jsm&amp;quot;&amp;amp;gt; &amp;amp;lt;jsm&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/jsm&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_echo&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_echo&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_roster&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_roster&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_time&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_time&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_vcard&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_vcard&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_last&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_last&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_version&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_version&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_announce&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_announce&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_agents&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_agents&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_browse&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_browse&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_admin&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_admin&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_filter&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_filter&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_offline&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_offline&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_presence&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_presence&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_auth_plain&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_auth_plain&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_auth_digest&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_auth_digest&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_auth_0k&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_auth_0k&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_log&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_log&amp;amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;amp;lt;mod_register&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_register&amp;amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_xml&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_xml&amp;amp;gt; &amp;amp;lt;/load&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;&amp;amp;lt;register/&amp;amp;gt;&amp;lt;/tt&amp;gt; configuration section looks familiar; the&lt;br /&gt;
contents are very similar to the IQ-result returned in response to the&lt;br /&gt;
IQ-get in the &amp;lt;tt&amp;gt;jabber:iq:register&amp;lt;/tt&amp;gt; namespace in Example 7-1.&lt;br /&gt;
Indeed, to respond to an IQ-get, the ''mod_register'' module looks for&lt;br /&gt;
this &amp;lt;tt&amp;gt;&amp;amp;lt;register/&amp;amp;gt;&amp;lt;/tt&amp;gt; section and formulates the contents into&lt;br /&gt;
a reply, making a simple modification as it goes: it appends tags for&lt;br /&gt;
the two fields &amp;amp;lt;username/&amp;amp;gt; and  &amp;amp;lt;password/&amp;amp;gt; as these two are&lt;br /&gt;
''always'' required, regardless of  configuration.&lt;br /&gt;
&lt;br /&gt;
Removing the &amp;lt;tt&amp;gt;&amp;amp;lt;register/&amp;amp;gt;&amp;lt;/tt&amp;gt; section from the configuration&lt;br /&gt;
effectively blocks the registration process and returns an appropriate&lt;br /&gt;
error to the user:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SEND: &amp;amp;lt;iq type='get'&amp;amp;gt; &amp;amp;lt;query&lt;br /&gt;
xmlns='jabber:iq:register'/&amp;amp;gt; &amp;amp;lt;/iq&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
RECV: &amp;amp;lt;iq type='error'&amp;amp;gt; &amp;amp;lt;query xmlns='jabber:iq:register'/&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;error code='501'&amp;amp;gt;Not Implemented&amp;amp;lt;/error&amp;amp;gt; &amp;amp;lt;/iq&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Removing the reference to the ''mod_register'' module from the component&lt;br /&gt;
instance's connection method:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;amp;lt;!-- &amp;amp;lt;mod_register&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_register&amp;amp;gt;&lt;br /&gt;
--&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
has the same effect.&lt;br /&gt;
&lt;br /&gt;
More information on the configuration discussed here can be found in&lt;br /&gt;
Section 4.4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step by Step === &lt;br /&gt;
&amp;lt;br&amp;gt;Taking the stream contents in Example 7-1 step by&lt;br /&gt;
step, what do we see?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== The XML stream header exchange ==== &lt;br /&gt;
&amp;lt;br&amp;gt;Although the XML declaration&lt;br /&gt;
that is sent immediately preceding the opening&lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;amp;lt;stream:stream/&amp;amp;gt;&amp;lt;/tt&amp;gt; root tag is optional, it's not a good&lt;br /&gt;
idea to leave it out. While the Jabber server currently does not enforce&lt;br /&gt;
its presence, future implementations may do so.&amp;lt;ref&amp;gt;That said, for the&lt;br /&gt;
time being, when you're testing against a Jabber server using telnet,&lt;br /&gt;
it's 20 less characters that you have to type every time you create a&lt;br /&gt;
new connection. &amp;lt;/ref&amp;gt;  The Jabber server will always send an XML&lt;br /&gt;
declaration in response. In both cases—in both streamed XML&lt;br /&gt;
documents—the encoding is assumed to be UTF-8.&lt;br /&gt;
&lt;br /&gt;
For the most part, the rest of the &amp;lt;tt&amp;gt;&amp;amp;lt;stream:stream/&amp;amp;gt;&amp;lt;/tt&amp;gt; root&lt;br /&gt;
tag is static. The namespace qualifying the stream content is &lt;br /&gt;
&amp;lt;tt&amp;gt;jabber:client&amp;lt;/tt&amp;gt; (which is the only namespace acceptable when&lt;br /&gt;
making such an XML stream connection to the &lt;br /&gt;
&amp;lt;tt&amp;gt;c2s&amp;lt;/tt&amp;gt;—Client-to-Server—component listening on  port 5222), and&lt;br /&gt;
the namespace qualifying the  stream itself is fixed at&lt;br /&gt;
http://etherx.jabber.org/streams.&amp;lt;ref&amp;gt;The name &amp;quot;etherx&amp;quot; comes from an&lt;br /&gt;
old library that implemented XML streams. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The only thing that is going to be dynamic is the &amp;lt;tt&amp;gt;to&amp;lt;/tt&amp;gt; attribute,&lt;br /&gt;
which is used to specify the Jabber server name. Note that this is the&lt;br /&gt;
''logical'' name, the internal name, of the Jabber server. In our&lt;br /&gt;
example, we've already resolved the physical hostname,  &amp;lt;tt&amp;gt;yak&amp;lt;/tt&amp;gt;,&lt;br /&gt;
and connected to port 5222; the  &amp;lt;tt&amp;gt;to&amp;lt;/tt&amp;gt; attribute is to specify the&lt;br /&gt;
virtual Jabber host,  which in many cases—including an out-of-the-box&lt;br /&gt;
jabber.xml configuration—has the same name as the physical host.&lt;br /&gt;
&lt;br /&gt;
If our Jabber server has just a single virtual host, we can use an&lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;amp;lt;alias/&amp;amp;gt;&amp;lt;/tt&amp;gt; configuration tag in the  &amp;lt;tt&amp;gt;c2s&amp;lt;/tt&amp;gt; component&lt;br /&gt;
instance configuration, as described in Section 4.6.3, to remove the&lt;br /&gt;
requirement of  specifying the &amp;lt;tt&amp;gt;to&amp;lt;/tt&amp;gt; attribute.&lt;br /&gt;
&lt;br /&gt;
Using:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;amp;lt;alias to='yak'/&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
will set the ''default'' alias to &amp;lt;tt&amp;gt;yak&amp;lt;/tt&amp;gt; and indeed override any&lt;br /&gt;
value specified in the &amp;lt;tt&amp;gt;to&amp;lt;/tt&amp;gt; attribute.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== &amp;quot;Required&amp;quot; fields ==== &lt;br /&gt;
&amp;lt;br&amp;gt;The list of fields returned in the response&lt;br /&gt;
to the IQ-get in the  &amp;lt;tt&amp;gt;jabber:iq:register&amp;lt;/tt&amp;gt; namespace is actually&lt;br /&gt;
supposed to be a list of ''mandatory'' fields:&lt;br /&gt;
&lt;br /&gt;
* &amp;amp;lt;name/&amp;amp;gt; * &amp;amp;lt;email/&amp;amp;gt; * &amp;amp;lt;username/&amp;amp;gt; * &amp;amp;lt;password/&amp;amp;gt;&lt;br /&gt;
However, with the current version of the Jabber server (1.4.1,  which is&lt;br /&gt;
our reference version for this book), this is not the case.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;&amp;amp;lt;username/&amp;amp;gt;&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;&amp;amp;lt;password/&amp;amp;gt;&amp;lt;/tt&amp;gt; fields&lt;br /&gt;
''are'' mandatory; not supplying them or supplying an invalid username&lt;br /&gt;
or password will result in an error:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SEND: &amp;amp;lt;iq type='set'&amp;amp;gt; &amp;amp;lt;query&lt;br /&gt;
xmlns='jabber:iq:register'&amp;amp;gt; &amp;amp;lt;username&amp;amp;gt;leslie&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;email&amp;amp;gt;lel@plevna.com&amp;amp;lt;/email&amp;amp;gt; &amp;amp;lt;name&amp;amp;gt;Leslie&lt;br /&gt;
Hawke&amp;amp;lt;/name&amp;amp;gt; &amp;amp;lt;/query&amp;amp;gt; &amp;amp;lt;/iq&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
RECV: &amp;amp;lt;iq type='error'&amp;amp;gt; &amp;amp;lt;query xmlns='jabber:iq:register'&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;username&amp;amp;gt;leslie&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;email&amp;amp;gt;lel@plevna.com&amp;amp;lt;/email&amp;amp;gt; &amp;amp;lt;name&amp;amp;gt;Leslie&lt;br /&gt;
Hawke&amp;amp;lt;/name&amp;amp;gt; &amp;amp;lt;/query&amp;amp;gt; &amp;amp;lt;error code='406'&amp;amp;gt;Not&lt;br /&gt;
Acceptable&amp;amp;lt;/error&amp;amp;gt; &amp;amp;lt;/iq&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, currently, failing to supply any of the other fields—the fields&lt;br /&gt;
that are specified in the &amp;lt;tt&amp;gt;&amp;amp;lt;register/&amp;amp;gt;&amp;lt;/tt&amp;gt; section of the JSM&lt;br /&gt;
instance's configuration—will not result in an  error. This may be fixed&lt;br /&gt;
in a later release. In any case, it's no great loss; the details are&lt;br /&gt;
simply stored in the user's spool file on the  server, and right now&lt;br /&gt;
there's only one situation where this information is subsequently used:&lt;br /&gt;
in answering a browse request made to a user's JID, the server looks up&lt;br /&gt;
the &amp;lt;tt&amp;gt;&amp;amp;lt;name/&amp;amp;gt;&amp;lt;/tt&amp;gt; tag from the registration data stored and&lt;br /&gt;
uses the value there in the browse response:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt; SEND: &amp;amp;lt;iq type='get' to='dj@yak'&amp;amp;gt; &amp;amp;lt;query&lt;br /&gt;
xmlns='jabber:iq:browse'/&amp;amp;gt; &amp;amp;lt;/iq&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
RECV: &amp;amp;lt;iq type='result' from='dj@yak' to='sabine@yak/Work'&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;user &amp;lt;tt&amp;gt;name='DJ Adams'&amp;lt;/tt&amp;gt; xmlns='jabber:iq:browse'&lt;br /&gt;
jid='dj@yak'/&amp;amp;gt; &amp;amp;lt;/iq&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Set without get ==== &lt;br /&gt;
&amp;lt;br&amp;gt;In many of the examples of IQ throughout the&lt;br /&gt;
book, we've seen a standard pattern: IQ-get &amp;lt;tt&amp;gt;-&amp;amp;gt;&amp;lt;/tt&amp;gt; IQ-result&lt;br /&gt;
&amp;lt;tt&amp;gt;-&amp;amp;gt;&amp;lt;/tt&amp;gt; IQ-set &amp;lt;tt&amp;gt;-&amp;amp;gt;&amp;lt;/tt&amp;gt; IQ-result.  This pattern isn't any&lt;br /&gt;
different here, but it's not essential. Bearing  in mind that&lt;br /&gt;
registration field requirements aren't going to change  that often, and&lt;br /&gt;
even if they do, the only ones that are enforced are &lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;amp;lt;username/&amp;amp;gt;&amp;lt;/tt&amp;gt; and  &amp;lt;tt&amp;gt;&amp;amp;lt;password/&amp;amp;gt;&amp;lt;/tt&amp;gt;, you can get&lt;br /&gt;
away with  forgoing the IQ-get and cutting straight to the chase with an&lt;br /&gt;
IQ-set.  This isn't a recommendation to do that, merely an observation,&lt;br /&gt;
as it's always good practice to ask first.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Still no connection ==== &lt;br /&gt;
&amp;lt;br&amp;gt;After registering a new user, note that&lt;br /&gt;
there's still no session. Only  after successful authorization (see&lt;br /&gt;
later in this chapter) is a session created. Although used in&lt;br /&gt;
authentication (and so implicitly in session creation), the value of the&lt;br /&gt;
&amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; attribute in the XML stream header returned by the server&lt;br /&gt;
(which has the value &amp;lt;tt&amp;gt;3B2DB1A7&amp;lt;/tt&amp;gt; in  Example 7-1) is a&lt;br /&gt;
''connection'' ID, not a ''session'' ID.&lt;br /&gt;
&lt;br /&gt;
So, what can we do at this stage? Well, one of two things: register&lt;br /&gt;
another user (yes!) or proceed to the authentication stage. Basically,&lt;br /&gt;
reaching the end of the registration process, we're back where we&lt;br /&gt;
started; a &amp;quot;raw&amp;quot; connection where only one of two sequences is valid:&lt;br /&gt;
the  &amp;lt;tt&amp;gt;jabber:iq:register&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;jabber:iq:auth&amp;lt;/tt&amp;gt; sequence.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== Passwords ==== &lt;br /&gt;
&amp;lt;br&amp;gt;You may be wondering about the plaintext nature of&lt;br /&gt;
the password sent in the registration process. Although the Jabber&lt;br /&gt;
server offers different types of password-based authentication, there's&lt;br /&gt;
a &amp;quot;bootstrap&amp;quot; process required to get the password to the server in the&lt;br /&gt;
first place. There's currently no way around the fact that the server&lt;br /&gt;
must at one time receive the password in all its plaintext glory. After&lt;br /&gt;
receiving it, there are authentication processes that don't  use the&lt;br /&gt;
plaintext password again.&lt;br /&gt;
&lt;br /&gt;
So if you're concerned about the security of this registration phase,&lt;br /&gt;
consider doing it over a secure (SSL) connection to the server.&lt;br /&gt;
&lt;br /&gt;
We will look at the detail of the different authentication mechanisms&lt;br /&gt;
later in this chapter; however, it is worth noting here, in the context&lt;br /&gt;
of the registration process, that the JSM modules that implement the&lt;br /&gt;
mechanism are responsible for storing the password when it's received.&lt;br /&gt;
The ''mod_register'' module actually registers the user, but it is the&lt;br /&gt;
''mod_auth_plain'' and  ''mod_auth_0k'' modules that actually store the&lt;br /&gt;
password when received.&amp;lt;ref&amp;gt;The ''mod_auth_digest'' module doesn't play&lt;br /&gt;
a password-storing role, just a password-checking one, as the mechanism&lt;br /&gt;
it provides uses the plaintext password that is stored by&lt;br /&gt;
''mod_auth_plain''. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Passwords are stored on another occasion—when a user wishes to&lt;br /&gt;
''change'' his password. This procedure is also covered by the&lt;br /&gt;
&amp;lt;tt&amp;gt;jabber:iq:register&amp;lt;/tt&amp;gt; namespace, albeit in a different context—the&lt;br /&gt;
context of a ''session''. While a &amp;lt;tt&amp;gt;jabber:iq:register&amp;lt;/tt&amp;gt;-based IQ&lt;br /&gt;
conversation ''outside'' the context of a session is for registering a&lt;br /&gt;
user, a similar conversation ''within'' the context of a session, that&lt;br /&gt;
is, after a user has authenticated, is used to change the user's&lt;br /&gt;
password and other registration details. Among other reasons, this is&lt;br /&gt;
for security: a session context implies the user has identified and&lt;br /&gt;
authenticated himself, and so has the authority to change the password.&lt;br /&gt;
&lt;br /&gt;
Example 7-2 shows a typical IQ-set to change a  password.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''Changing a password with jabber:iq:register''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SEND: &amp;amp;lt;iq type='set' id='pass_4' to='yak'&amp;amp;gt; &amp;amp;lt;query&lt;br /&gt;
xmlns='jabber:iq:register'&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;password&amp;amp;gt;newsecret&amp;amp;lt;/password&amp;amp;gt; &amp;amp;lt;/query&amp;amp;gt; &amp;amp;lt;/iq&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
RECV: &amp;amp;lt;iq type='result' id='pass_4' from='yak' to='dj@yak/Work'/&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;to&amp;lt;/tt&amp;gt; attribute is required here, to make sure the query is&lt;br /&gt;
handled by the server itself. We can also see evidence that the context&lt;br /&gt;
of this exchange is within a session in the value of the  &amp;lt;tt&amp;gt;to&amp;lt;/tt&amp;gt;&lt;br /&gt;
attribute on the IQ-result packet—the JID &amp;lt;tt&amp;gt;dj@yak/Work&amp;lt;/tt&amp;gt; includes&lt;br /&gt;
a resource suffix, which implies a session (a resource must be specified&lt;br /&gt;
in the authentication process—see later in this chapter). And the&lt;br /&gt;
specification of a &amp;lt;tt&amp;gt;&amp;amp;lt;username/&amp;amp;gt;&amp;lt;/tt&amp;gt; is not necessary, as the&lt;br /&gt;
server will stamp the incoming IQ-set anyway with the JID associated&lt;br /&gt;
with the user's session.&lt;br /&gt;
&lt;br /&gt;
If you had made an IQ-get, as recommended earlier, before doing the&lt;br /&gt;
IQ-set to change the password, the result would have looked like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;RECV: &amp;amp;lt;iq type='result' to='dj@yak/Work' id='pass_2'&lt;br /&gt;
from='yak'&amp;amp;gt; &amp;amp;lt;query xmlns='jabber:iq:register'&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;password/&amp;amp;gt; &amp;amp;lt;instructions&amp;amp;gt; Choose a username and password to&lt;br /&gt;
register with this server. &amp;amp;lt;/instructions&amp;amp;gt; &amp;amp;lt;name/&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;email/&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;key&amp;amp;gt;9a6957b7f69535274afa5c134fb4d916c5d5c20b&amp;amp;lt;/key&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;registered/&amp;amp;gt; &amp;amp;lt;/query&amp;amp;gt; &amp;amp;lt;/iq&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We see that, as in the registration IQ-get outside the session context,&lt;br /&gt;
the contents of the &amp;lt;tt&amp;gt;&amp;amp;lt;register/&amp;amp;gt;&amp;lt;/tt&amp;gt; section of the JSM&lt;br /&gt;
instance's configuration have been inserted (the &lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;amp;lt;instructions/&amp;amp;gt;&amp;lt;/tt&amp;gt;,  &amp;lt;tt&amp;gt;&amp;amp;lt;name/&amp;amp;gt;&amp;lt;/tt&amp;gt;, and&lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;amp;lt;email/&amp;amp;gt;&amp;lt;/tt&amp;gt; tags). Additionally, we have a&lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;amp;lt;key/&amp;amp;gt;&amp;lt;/tt&amp;gt; tag, as a simple security token (described in&lt;br /&gt;
Section 6.2.11) and a &amp;lt;tt&amp;gt;&amp;amp;lt;registered/&amp;amp;gt;&amp;lt;/tt&amp;gt; tag. The &lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;amp;lt;key/&amp;amp;gt;&amp;lt;/tt&amp;gt; is not actually checked in the current&lt;br /&gt;
implementation and therefore does not have to be supplied in the return&lt;br /&gt;
IQ-set packet. And the  &amp;lt;tt&amp;gt;&amp;amp;lt;register/&amp;amp;gt;&amp;lt;/tt&amp;gt; tag is merely a flag&lt;br /&gt;
telling us that the user is already registered.&lt;br /&gt;
&lt;br /&gt;
Use of the &amp;lt;tt&amp;gt;jabber:iq:register&amp;lt;/tt&amp;gt; namespace in conversation with&lt;br /&gt;
the JSM in a session context is not limited to changing passwords; you&lt;br /&gt;
can modify the rest of the registration details supplied when the user&lt;br /&gt;
was created—in this case, the &amp;lt;tt&amp;gt;&amp;amp;lt;name/&amp;amp;gt;&amp;lt;/tt&amp;gt; and&lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;amp;lt;email/&amp;amp;gt;&amp;lt;/tt&amp;gt; information. In fact, with the current&lt;br /&gt;
implementation, because of the lack of checks, you can specify your own&lt;br /&gt;
fields in the &amp;lt;tt&amp;gt;jabber:iq:register&amp;lt;/tt&amp;gt; IQ-set,  in both contexts. But&lt;br /&gt;
don't do it; it's a habit that will probably be impossible to keep up in&lt;br /&gt;
later releases of the server.&amp;lt;ref&amp;gt;And no, you can't spoof someone else&lt;br /&gt;
by specifying the  &amp;lt;tt&amp;gt;&amp;amp;lt;username/&amp;amp;gt;&amp;lt;/tt&amp;gt; tag in a session context&lt;br /&gt;
&amp;lt;tt&amp;gt;jabber:iq:register&amp;lt;/tt&amp;gt; IQ-set; it is ignored, and the correct JID&lt;br /&gt;
is taken from the &amp;lt;tt&amp;gt;from&amp;lt;/tt&amp;gt; attribute stamp made as the packet hits&lt;br /&gt;
the server. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It almost goes without saying that because IQs in the&lt;br /&gt;
&amp;lt;tt&amp;gt;jabber:iq:register&amp;lt;/tt&amp;gt; namespace are handled differently in a&lt;br /&gt;
session context, you can't register a new user once your session  has&lt;br /&gt;
started; you must end it. To end it, the XML stream must be closed with&lt;br /&gt;
a &amp;lt;tt&amp;gt;&amp;amp;lt;/stream:stream&amp;amp;gt;&amp;lt;/tt&amp;gt;, and a new connection and stream must&lt;br /&gt;
then be created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Reversing a user registration ==== &lt;br /&gt;
&amp;lt;br&amp;gt;The opposite of registering a&lt;br /&gt;
user is ''unregistering'' a user. This is not the same as removing that&lt;br /&gt;
user altogether. When the &amp;lt;tt&amp;gt;&amp;amp;lt;remove/&amp;amp;gt;&amp;lt;/tt&amp;gt; tag, described in&lt;br /&gt;
Section 6.2.11, is used in a &amp;lt;tt&amp;gt;jabber:iq:register&amp;lt;/tt&amp;gt;-qualified&lt;br /&gt;
IQ-set during a user session, the user is ''unregistered''. That is, &lt;br /&gt;
all the information held in the user's spool file is removed. But the &lt;br /&gt;
spool file itself is not removed until the Jabber server is shut down.&lt;br /&gt;
This means that even if you &amp;lt;tt&amp;gt;&amp;amp;lt;remove/&amp;amp;gt;&amp;lt;/tt&amp;gt; a user, the&lt;br /&gt;
username will still exist until the server is cycled, causing an error&lt;br /&gt;
if the same username is used in a new registration attempt:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;RECV: &amp;amp;lt;iq type='error'&amp;amp;gt; &amp;amp;lt;query&lt;br /&gt;
xmlns='jabber:iq:register'&amp;amp;gt; &amp;amp;lt;username&amp;amp;gt;dj&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;password&amp;amp;gt;secret&amp;amp;lt;/password&amp;amp;gt; &amp;amp;lt;/query&amp;amp;gt; &amp;amp;lt;error&lt;br /&gt;
code='409'&amp;amp;gt;Username Not Available&amp;amp;lt;/error&amp;amp;gt; &amp;amp;lt;/iq&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This may well be fixed in a later release of the Jabber server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== A note on error messages ==== &lt;br /&gt;
&amp;lt;br&amp;gt;Various errors can occur during user&lt;br /&gt;
registration. They are, on the whole, fairly plain and easy to&lt;br /&gt;
understand. But because of the way the server has been written, you&lt;br /&gt;
might be surprised at  ''what'' error message you receive in certain&lt;br /&gt;
circumstances.&lt;br /&gt;
&lt;br /&gt;
Because the required fields &amp;lt;tt&amp;gt;&amp;amp;lt;username/&amp;amp;gt;&amp;lt;/tt&amp;gt; and&lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;amp;lt;password/&amp;amp;gt;&amp;lt;/tt&amp;gt; are checked ''before'' looking to see whether&lt;br /&gt;
or not there is a &amp;lt;tt&amp;gt;&amp;amp;lt;register/&amp;amp;gt;&amp;lt;/tt&amp;gt; section in the JSM instance&lt;br /&gt;
configuration, you will always receive a ''406 &amp;quot;Not Acceptable&amp;quot;''&lt;br /&gt;
instead of a  ''501 &amp;quot;Not Implemented&amp;quot;'' if you don't supply those&lt;br /&gt;
fields, even if the registration mechanism has been turned off.&lt;br /&gt;
&lt;br /&gt;
Likewise, if you specify a username that already exists, you will&lt;br /&gt;
receive a ''409 &amp;quot;Username Not Available&amp;quot;'' instead of a ''501 &amp;quot;Not&lt;br /&gt;
Implemented.&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
Of course, if you do an IQ-get with the  &amp;lt;tt&amp;gt;jabber:iq:register&amp;lt;/tt&amp;gt;&lt;br /&gt;
namespace beforehand, you  ''will'' receive the &amp;quot;correct&amp;quot; error—good&lt;br /&gt;
practice pays!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Authentication == &lt;br /&gt;
&amp;lt;br&amp;gt;There are similarities between user&lt;br /&gt;
registration and user authentication:&lt;br /&gt;
&lt;br /&gt;
* Authentication must take place outside of a session context (it&lt;br /&gt;
doesn't really makes sense inside a session context, anyway). It is&lt;br /&gt;
perfectly possible to perform a user registration step followed by a&lt;br /&gt;
user  authentication step (for any user) in the same XML stream. * Any&lt;br /&gt;
packets sent before the authentication step (apart from user&lt;br /&gt;
registration packets) are queued until after the authentication step has&lt;br /&gt;
been completed. * The IQ-get in the &amp;lt;tt&amp;gt;jabber:iq:auth&amp;lt;/tt&amp;gt; namespace is&lt;br /&gt;
not  mandatory but is recommended (even more strongly than the&lt;br /&gt;
recommendation for the IQ-get in the &amp;lt;tt&amp;gt;jabber:iq:register&amp;lt;/tt&amp;gt;&lt;br /&gt;
namespace). Example 7-3 shows a typical authentication process,&lt;br /&gt;
including the XML stream header exchange.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''A typical user authentication process'' Here the authentication&lt;br /&gt;
process immediately follows the initial  XML stream header exchange:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SEND: &amp;amp;lt;?xml version='1.0'?&amp;amp;gt; &amp;amp;lt;stream:stream to='yak'&lt;br /&gt;
xmlns='jabber:client'&lt;br /&gt;
xmlns:stream='http://etherx.jabber.org/streams'&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
RECV: &amp;amp;lt;?xml version='1.0'?&amp;amp;gt; &amp;amp;lt;stream:stream&lt;br /&gt;
xmlns:stream='http://etherx.jabber.org/streams' id='1ED34A55'&lt;br /&gt;
xmlns='jabber:client' from='yak'&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We ask the server about the authentication methods available for  our&lt;br /&gt;
specific user:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SEND: &amp;amp;lt;iq type='get'&amp;amp;gt; &amp;amp;lt;query xmlns='jabber:iq:auth'&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;username&amp;amp;gt;dj&amp;amp;lt;/username&amp;amp;gt; &amp;amp;lt;/query&amp;amp;gt; &amp;amp;lt;/iq&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
RECV: &amp;amp;lt;iq type='result'&amp;amp;gt; &amp;amp;lt;query xmlns='jabber:iq:auth'&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;username&amp;amp;gt;dj&amp;amp;lt;/username&amp;amp;gt; &amp;amp;lt;password/&amp;amp;gt; &amp;amp;lt;digest/&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;sequence&amp;amp;gt;496&amp;amp;lt;/sequence&amp;amp;gt; &amp;amp;lt;token&amp;amp;gt;3B2DEEC0&amp;amp;lt;/token&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;resource/&amp;amp;gt; &amp;amp;lt;/query&amp;amp;gt; &amp;amp;lt;/iq&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Because we're connecting here to the server with ''telnet'' and don't&lt;br /&gt;
have any digest utilities handy, we decide to use the  simplest&lt;br /&gt;
authentication method and send our password in plaintext.  The server&lt;br /&gt;
checks the credentials and gives us the thumbs-up.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SEND: &amp;amp;lt;iq type='set'&amp;amp;gt; &amp;amp;lt;query xmlns='jabber:iq:auth'&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;username&amp;amp;gt;dj&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;password&amp;amp;gt;secret&amp;amp;lt;/password&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;resource&amp;amp;gt;laptop&amp;amp;lt;/resource&amp;amp;gt; &amp;amp;lt;/query&amp;amp;gt; &amp;amp;lt;/iq&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
RECV: &amp;amp;lt;iq type='result' id='pthsock_client_auth_ID'/&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this stage, we have a session.&amp;lt;ref&amp;gt;The&lt;br /&gt;
&amp;lt;tt&amp;gt;pthsock_client_auth_ID&amp;lt;/tt&amp;gt; value for the &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; attribute in&lt;br /&gt;
the IQ-result is placed by the JSM as it processes the IQ-set request,&lt;br /&gt;
when a value has not been specified.  &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configuration and Module Load Directives === &lt;br /&gt;
&amp;lt;br&amp;gt;The &amp;lt;tt&amp;gt;c2s&amp;lt;/tt&amp;gt;&lt;br /&gt;
component contains a configuration directive related to the&lt;br /&gt;
authorization process:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;amp;lt;service id=&amp;quot;c2s&amp;quot;&amp;amp;gt; &amp;amp;lt;load&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;pthsock_client&amp;amp;gt;./pthsock/pthsock_client.so&amp;amp;lt;/pthsock_client&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;/load&amp;amp;gt; &amp;amp;lt;pthcsock xmlns='jabber:config:pth-csock'&amp;amp;gt; &amp;amp;lt;alias&lt;br /&gt;
to='yak'/&amp;amp;gt; &amp;lt;tt&amp;gt;&amp;amp;lt;authtime/&amp;amp;gt;&amp;lt;/tt&amp;gt; ... &amp;amp;lt;/pthcsock&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;/service&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This &amp;lt;tt&amp;gt;&amp;amp;lt;authtime/&amp;amp;gt;&amp;lt;/tt&amp;gt; tag is used to  set the time limit, in&lt;br /&gt;
seconds, within which authentication should be completed, starting to&lt;br /&gt;
measure at the time the connection was made.  See Section 4.6.3 for more&lt;br /&gt;
details.&lt;br /&gt;
&lt;br /&gt;
There is also an undocumented tag, &amp;lt;tt&amp;gt;&amp;amp;lt;auth/&amp;amp;gt;&amp;lt;/tt&amp;gt;, which can be&lt;br /&gt;
specified in the JSM instance configuration (for example,  after the&lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;amp;lt;register/&amp;amp;gt;&amp;lt;/tt&amp;gt; section) and with which you can specify an&lt;br /&gt;
external component that is to handle authentication in place of the&lt;br /&gt;
standard JSM modules (''mod_auth_*''). The JSM module load directives&lt;br /&gt;
specify the modules that handle authentication:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;amp;lt;load main=&amp;quot;jsm&amp;quot;&amp;amp;gt; &amp;amp;lt;jsm&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/jsm&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_echo&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_echo&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_roster&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_roster&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_time&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_time&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_vcard&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_vcard&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_last&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_last&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_version&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_version&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_announce&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_announce&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_agents&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_agents&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_browse&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_browse&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_admin&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_admin&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_filter&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_filter&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_offline&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_offline&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_presence&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_presence&amp;amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;amp;lt;mod_auth_plain&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_auth_plain&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_auth_digest&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_auth_digest&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_auth_0k&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_auth_0k&amp;amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_log&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_log&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_register&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_register&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_xml&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_xml&amp;amp;gt; &amp;amp;lt;/load&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Each of these modules, ''mod_auth_plain'',  ''mod_auth_digest'', and&lt;br /&gt;
''mod_auth_0k'' can play a role in the authentication process. As&lt;br /&gt;
mentioned in  Section 4.4.4, they provide different authentication&lt;br /&gt;
methods, these methods being reflected in their names:&lt;br /&gt;
&lt;br /&gt;
* ''mod_auth_plain'': plaintext * ''mod_auth_digest'': digest &lt;br /&gt;
* ''mod_auth_0k'': zero-knowledge You have a certain amount of flexibility&lt;br /&gt;
as administrator to determine what methods are made available on your&lt;br /&gt;
Jabber server. If you want to offer all three, do nothing. If you want&lt;br /&gt;
to offer only the ''zero-knowledge'' method, comment out or otherwise&lt;br /&gt;
remove the other two definitions from the list of module load&lt;br /&gt;
directives:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;amp;lt;!-- &amp;amp;lt;mod_auth_plain&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_auth_plain&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mod_auth_digest&amp;amp;gt;./jsm/jsm.so&amp;amp;lt;/mod_auth_digest&amp;amp;gt; --&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you want to offer the ''digest'' method, you must include the module &lt;br /&gt;
load directives for both ''mod_auth_plain'' and ''mod_auth_digest'', as&lt;br /&gt;
the latter is merely an  extension—a &amp;quot;parasite&amp;quot;—upon the former.&lt;br /&gt;
&lt;br /&gt;
Let's look at each of these authentication methods in turn.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== Plaintext authentication method ==== &lt;br /&gt;
&amp;lt;br&amp;gt;The plaintext authentication&lt;br /&gt;
method works as you would expect and  is the default lowest common&lt;br /&gt;
denominator method supplied with the Jabber server. It is provided by&lt;br /&gt;
the  ''mod_auth_plain'' module.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Method&lt;br /&gt;
: The password is transmitted in the XML stream, inside the&lt;br /&gt;
: &amp;lt;tt&amp;gt;&amp;amp;lt;password/&amp;amp;gt;&amp;lt;/tt&amp;gt; tag in the  &amp;lt;tt&amp;gt;jabber:iq:auth&amp;lt;/tt&amp;gt; IQ-set&lt;br /&gt;
: packet, from the client to the server in plaintext, where it is&lt;br /&gt;
: compared to the password stored, also  in plaintext, on the server. :&lt;br /&gt;
: When a password is changed, using a &amp;lt;tt&amp;gt;jabber:iq:register&amp;lt;/tt&amp;gt; IQ-set&lt;br /&gt;
: as described earlier in this chapter, &amp;lt;tt&amp;gt;mod_auth_plain&amp;lt;/tt&amp;gt; stores&lt;br /&gt;
: the password, as received, in the user's spool file. &lt;br /&gt;
; Advantages&lt;br /&gt;
: This method is by far the simplest to implement on the client side. It&lt;br /&gt;
: is also useful for debugging and testing purposes as it can be used in&lt;br /&gt;
: a  connection &amp;quot;by hand&amp;quot; via telnet, not requiring any extra&lt;br /&gt;
: computation such as the digest and zero-knowledge methods do. &lt;br /&gt;
; Disadvantages&lt;br /&gt;
: It's insecure, on two levels. First, the password is transmitted in &lt;br /&gt;
: plaintext across the wire from client to server. The risk can be&lt;br /&gt;
: minimized by encrypting the whole connection using SSL. Second, the&lt;br /&gt;
: password is stored in plaintext on the server, which may be&lt;br /&gt;
: compromised. &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== Digest authentication method ==== &lt;br /&gt;
&amp;lt;br&amp;gt;The module that provides the&lt;br /&gt;
digest authentication method,  ''mod_auth_digest'', works in conjunction&lt;br /&gt;
with the  plaintext module, ''mod_auth_plain''. It provides a way to&lt;br /&gt;
avoid having to send the plaintext password across the wire.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Method&lt;br /&gt;
: The digest method is similar to the plaintext method, in that the &lt;br /&gt;
: password sent by the client is compared to the password stored on  the&lt;br /&gt;
: server. However, in this case, the password is first encoded using a&lt;br /&gt;
: hashing algorithm. It is encoded by the client before being sent&lt;br /&gt;
: across the wire, and it is encoded by the server (having retrieved it&lt;br /&gt;
: in plaintext) before making the comparison. : The algorithm used is&lt;br /&gt;
: the NIST SHA-1 message digest algorithm.&amp;lt;ref&amp;gt;More information on SHA-1&lt;br /&gt;
: (Secure Hash Algorithm 1) can be obtained at&lt;br /&gt;
: http://www.itl.nist.gov/fipspubs/fip180-1.htm. &amp;lt;/ref&amp;gt;: This algorithm&lt;br /&gt;
: takes arbitrary input and produces a fingerprint or &amp;quot;message digest&amp;quot;&lt;br /&gt;
: of it.&amp;lt;ref&amp;gt;There are different types of message digest that can be&lt;br /&gt;
: produced with  this algorithm: binary, hexadecimal, and base64. The&lt;br /&gt;
: hexadecimal format is used here and elsewhere in Jabber. &amp;lt;/ref&amp;gt;: A&lt;br /&gt;
: random string, shared between the client and the server, is appended&lt;br /&gt;
: to  the password before being passed to the hashing algorithm. This&lt;br /&gt;
: random string is the connection ID—the value of the  &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;&lt;br /&gt;
: attribute in the server's XML stream header response that we saw in&lt;br /&gt;
: Example 7-3: &lt;br /&gt;
&amp;lt;code&amp;gt;RECV: &amp;amp;lt;?xml version='1.0'?&amp;amp;gt; &amp;amp;lt;stream:stream&lt;br /&gt;
xmlns:stream='http://etherx.jabber.org/streams' id='&amp;lt;tt&amp;gt;1ED34A55&amp;lt;/tt&amp;gt;'&lt;br /&gt;
xmlns='jabber:client' from='yak'&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
: which means, in the case where the password is &amp;quot;secret,&amp;quot; the string&lt;br /&gt;
: that will be hashed is: &lt;br /&gt;
&amp;lt;code&amp;gt; secret1ED34A55&amp;lt;/code&amp;gt;&lt;br /&gt;
: which is: &lt;br /&gt;
&amp;lt;code&amp;gt; 03ea09f012493415908d63dcb1f6dbdb9bfc09ba&amp;lt;/code&amp;gt;&lt;br /&gt;
: The digested password is transmitted to the server inside the&lt;br /&gt;
: &amp;lt;tt&amp;gt;&amp;amp;lt;digest/&amp;amp;gt;&amp;lt;/tt&amp;gt; tag. : ''mod_auth_digest'' is unlike the&lt;br /&gt;
: other two modules in that it doesn't take any responsibility for&lt;br /&gt;
: storing passwords; it leaves that to ''mod_auth_plain'', as the&lt;br /&gt;
: plaintext password must be  rehashed with a new random suffix each&lt;br /&gt;
: time. &lt;br /&gt;
; Advantages&lt;br /&gt;
: No plaintext password is transmitted across the wire from client to&lt;br /&gt;
: server,  and only a small amount of computation—a single SHA-1 hash&lt;br /&gt;
: process—is required. &lt;br /&gt;
; Disadvantages&lt;br /&gt;
: The password is still stored in plaintext on the server.  &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== Zero-knowledge authentication method ==== &lt;br /&gt;
&amp;lt;br&amp;gt;The zero-knowledge&lt;br /&gt;
authentication method is so-called as the server requires no knowledge&lt;br /&gt;
of the password in order to check the credentials. It makes use of the&lt;br /&gt;
same hashing algorithm used in the digest authentication method.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Method&lt;br /&gt;
: Just as ''mod_auth_plain'' is responsible for storing the password (in&lt;br /&gt;
: plaintext) when a user is created or when the password is changed, so&lt;br /&gt;
: ''mod_auth_0k'' is responsible for storing  ''its version'' of the&lt;br /&gt;
: password, actually, the information it needs (originally ''based'' on&lt;br /&gt;
: the password) to check the client's credentials in a zero-knowledge&lt;br /&gt;
: authentication process.  : As we know from the user registration and&lt;br /&gt;
: password change processes, any new password is supplied to the server&lt;br /&gt;
: in plaintext. This is where a  secure (SSL) connection is critical for&lt;br /&gt;
: complete security. While the ''mod_auth_plain'' module just stores&lt;br /&gt;
: that password as is, the ''mod_auth_0k'' module stores a sequenced&lt;br /&gt;
: hash of the password instead.  : What does this mean? The server&lt;br /&gt;
: stores a value that  is the password hashed with an arbitrary string&lt;br /&gt;
: token multiple (''N'') times,  recursively.  It doesn't store the&lt;br /&gt;
: password itself. It also remembers how many times it has been hashed&lt;br /&gt;
: (''N''). : Whenever a client wants to authenticate, the server sends&lt;br /&gt;
: the client the string token and the value of ''N''. The client, having&lt;br /&gt;
: obtained the password from the user, performs the same iterative&lt;br /&gt;
: hashing sequence  that the server performed when it was originally&lt;br /&gt;
: given the password  but performs the sequence ''N''-1 times. It passes&lt;br /&gt;
: the result of this  sequence to the server, which does one more hash&lt;br /&gt;
: to go from ''N''-1 to ''N'',  and compares what it gets with what it&lt;br /&gt;
: has stored. If they match, authentication is successful, and the&lt;br /&gt;
: server stores the ''N''-1 hash passed from the client and decrements&lt;br /&gt;
: ''N'', ready for next time.  : The server sends the client the&lt;br /&gt;
: information it needs in two tags: &lt;br /&gt;
; &amp;lt;tt&amp;gt;&amp;amp;lt;sequence&amp;amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
: The value of ''N'' is sent in the &amp;lt;tt&amp;gt;&amp;amp;lt;sequence/&amp;amp;gt;&amp;lt;/tt&amp;gt; tag. &lt;br /&gt;
; &amp;lt;tt&amp;gt;&amp;amp;lt;token&amp;amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
: The arbitrary string token to be hashed with the password is sent in&lt;br /&gt;
: the &amp;lt;tt&amp;gt;&amp;amp;lt;token/&amp;amp;gt;&amp;lt;/tt&amp;gt; tag. : The ''N''-1 hash value is passed by&lt;br /&gt;
: the client to the server in the &amp;lt;tt&amp;gt;&amp;amp;lt;hash/&amp;amp;gt;&amp;lt;/tt&amp;gt; tag. : By way&lt;br /&gt;
: of illustration, Example 7-4 shows a small Perl script that a  Telnet&lt;br /&gt;
: user can use to make the necessary  hashing computations when wishing&lt;br /&gt;
: to authenticate with a Jabber server using the zero-knowledge method. &lt;br /&gt;
''A script implementing the client-side zero-knowledge process''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;#!/usr/bin/perl -w&lt;br /&gt;
&lt;br /&gt;
use strict; use Digest::SHA1 qw(sha1_hex); use Getopt::Std;&lt;br /&gt;
&lt;br /&gt;
our($opt_p, $opt_t, $opt_s); getopt('pts');&lt;br /&gt;
&lt;br /&gt;
unless ($opt_p and $opt_t and $opt_s) { print &amp;quot;Usage: $0 -p&lt;br /&gt;
&amp;amp;lt;password&amp;amp;gt; -t &amp;amp;lt;token&amp;amp;gt; -s &amp;amp;lt;sequence&amp;amp;gt;\n&amp;quot;; exit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Initial hash of password&lt;br /&gt;
my $hash = sha1_hex($opt_p);&lt;br /&gt;
&lt;br /&gt;
# Sequence 0: hash of hashed-password and token&lt;br /&gt;
$hash = sha1_hex($hash.$opt_t);&lt;br /&gt;
&lt;br /&gt;
# Repeat N-1 times&lt;br /&gt;
$hash = sha1_hex($hash) while $opt_s--;&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;$hash\n&amp;quot;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
: To use the script, pass the data via the parameters, using the values &lt;br /&gt;
: obtained from the response to the initial IQ-get. The value that the&lt;br /&gt;
: script produces for the value to send in the  &amp;lt;tt&amp;gt;&amp;amp;lt;hash/&amp;amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
: tag, like this: : &lt;br /&gt;
&amp;lt;code&amp;gt;$ &amp;lt;tt&amp;gt;./0k&amp;lt;/tt&amp;gt; Usage: 0k -p &amp;amp;lt;password&amp;amp;gt; -t &amp;amp;lt;token&amp;amp;gt; -s&lt;br /&gt;
&amp;amp;lt;sequence&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
: &lt;br /&gt;
&amp;lt;code&amp;gt;$ &amp;lt;tt&amp;gt;./0k -p secret -t ABCDE -s 400&amp;lt;/tt&amp;gt;&lt;br /&gt;
01945b9b2c3207c4cce5dc99e50605779f570077 $&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; Advantages&lt;br /&gt;
: No password is stored on the server. No (plaintext) password is&lt;br /&gt;
: transmitted from client to server. &lt;br /&gt;
; Disadvantages&lt;br /&gt;
: This method is slightly more compute-intensive than the other methods.&lt;br /&gt;
: There is still a security weak spot in the procedure, when the&lt;br /&gt;
: password is set or reset, as it must be passed in plaintext. A reset&lt;br /&gt;
: is required when ''N'' reaches 0, which is another disadvantage—a&lt;br /&gt;
: password can be used only ''N'' times before a plaintext reset. &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
=== Choosing the Authentication Method === &lt;br /&gt;
&amp;lt;br&amp;gt;Now that we know a little bit&lt;br /&gt;
about the authentication methods, let's jump back to the initial IQ-get&lt;br /&gt;
query in Example 7-3:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SEND: &amp;amp;lt;iq type='get'&amp;amp;gt; &amp;amp;lt;query xmlns='jabber:iq:auth'&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;username&amp;amp;gt;dj&amp;amp;lt;/username&amp;amp;gt; &amp;amp;lt;/query&amp;amp;gt; &amp;amp;lt;/iq&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
RECV: &amp;amp;lt;iq type='result'&amp;amp;gt; &amp;amp;lt;query xmlns='jabber:iq:auth'&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;username&amp;amp;gt;dj&amp;amp;lt;/username&amp;amp;gt; &amp;amp;lt;password/&amp;amp;gt; &amp;amp;lt;digest/&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;sequence&amp;amp;gt;496&amp;amp;lt;/sequence&amp;amp;gt; &amp;amp;lt;token&amp;amp;gt;3B2DEEC0&amp;amp;lt;/token&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;resource/&amp;amp;gt; &amp;amp;lt;/query&amp;amp;gt; &amp;amp;lt;/iq&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
What we're actually seeing here is the result of the authentication &lt;br /&gt;
modules announcing their readiness to authenticate the user &lt;br /&gt;
&amp;lt;tt&amp;gt;dj&amp;lt;/tt&amp;gt;. The query is passed to each of the modules.&lt;br /&gt;
''mod_auth_plain'' announces its readiness by inserting the&lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;amp;lt;password/&amp;amp;gt;&amp;lt;/tt&amp;gt; flag,  ''mod_auth_digest'' does the same with&lt;br /&gt;
the  &amp;lt;tt&amp;gt;&amp;amp;lt;digest/&amp;amp;gt;&amp;lt;/tt&amp;gt; flag, and  ''mod_auth_0k'' inserts the &lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;amp;lt;sequence/&amp;amp;gt;&amp;lt;/tt&amp;gt; and  &amp;lt;tt&amp;gt;&amp;amp;lt;token/&amp;amp;gt;&amp;lt;/tt&amp;gt; tags and values,&lt;br /&gt;
which is what the client will need if it wishes to authenticate using&lt;br /&gt;
the zero-knowledge method. The &amp;lt;tt&amp;gt;&amp;amp;lt;resource/&amp;amp;gt;&amp;lt;/tt&amp;gt; tag, which is&lt;br /&gt;
required in any authentication, is finally added before the result is&lt;br /&gt;
returned.&lt;br /&gt;
&lt;br /&gt;
This way, the IQ-result can convey which authentication methods are&lt;br /&gt;
available; if the ''mod_auth_plain'' and  ''mod_auth_digest'' modules&lt;br /&gt;
were to be commented out in the module load directive list, as we saw&lt;br /&gt;
earlier, then the IQ-result would look like this without the&lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;amp;lt;password/&amp;amp;gt;&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;&amp;amp;lt;digest/&amp;amp;gt;&amp;lt;/tt&amp;gt; tags:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;RECV: &amp;amp;lt;iq type='result'&amp;amp;gt; &amp;amp;lt;query&lt;br /&gt;
xmlns='jabber:iq:auth'&amp;amp;gt; &amp;amp;lt;username&amp;amp;gt;dj&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;sequence&amp;amp;gt;496&amp;amp;lt;/sequence&amp;amp;gt; &amp;amp;lt;token&amp;amp;gt;3B2DEEC0&amp;amp;lt;/token&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;resource/&amp;amp;gt; &amp;amp;lt;/query&amp;amp;gt; &amp;amp;lt;/iq&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Note|At the beginning of this section, we strongly recommended using&lt;br /&gt;
the IQ-get in the &amp;lt;tt&amp;gt;jabber:iq:auth&amp;lt;/tt&amp;gt; namespace,  before proceeding&lt;br /&gt;
with the IQ-set. This was  primarily to be able to check what&lt;br /&gt;
authentication methods were supported. However, as you can see here, it&lt;br /&gt;
is in fact ''essential'' in the case of the zero-knowledge&lt;br /&gt;
authentication method, because without the  &amp;lt;tt&amp;gt;&amp;amp;lt;sequence/&amp;amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
and  &amp;lt;tt&amp;gt;&amp;amp;lt;token/&amp;amp;gt;&amp;lt;/tt&amp;gt; information, we cannot begin our hashing&lt;br /&gt;
sequence.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
=== Password Errors and Retries === &lt;br /&gt;
&amp;lt;br&amp;gt;If you don't supply all the required&lt;br /&gt;
parameters, you are notified with  a 406 ''&amp;quot;Not Acceptable&amp;quot;'' error:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SEND: &amp;amp;lt;iq type='set'&amp;amp;gt; &amp;amp;lt;query xmlns='jabber:iq:auth'&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;username&amp;amp;gt;dj&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;digest&amp;amp;gt;03ea09f012493415908d63dcb1f6dbdb9bfc09ba&amp;amp;lt;/digest&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;/query&amp;amp;gt; &amp;amp;lt;/iq&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
RECV: &amp;amp;lt;iq type='result' id='pthsock_client_auth_ID'&amp;amp;gt; &amp;amp;lt;query&lt;br /&gt;
xmlns='jabber:iq:auth'&amp;amp;gt; &amp;amp;lt;username&amp;amp;gt;dj&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;digest&amp;amp;gt;03ea09f012493415908d63dcb1f6dbdb9bfc09ba&amp;amp;lt;/digest&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;/query&amp;amp;gt; &amp;amp;lt;error code='406'&amp;amp;gt;Not Acceptable&amp;amp;lt;/error&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;/iq&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In this case, no &amp;lt;tt&amp;gt;&amp;amp;lt;resource/&amp;amp;gt;&amp;lt;/tt&amp;gt;  value was supplied. The&lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;amp;lt;resource/&amp;amp;gt;&amp;lt;/tt&amp;gt; value is required, as it is the key part of&lt;br /&gt;
the JID that is used to distinguish between multiple connections as the&lt;br /&gt;
same user on the same Jabber server.&lt;br /&gt;
&lt;br /&gt;
If you get the password wrong, you receive a 401 ''&amp;quot;Not Authorized&amp;quot;''&lt;br /&gt;
error. There is currently no limit on the number of times an&lt;br /&gt;
authorization attempt can be made, but the &amp;lt;tt&amp;gt;&amp;amp;lt;karma/&amp;amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
limits for the &amp;lt;tt&amp;gt;c2s&amp;lt;/tt&amp;gt; connections (see Chapter 5) may slow the&lt;br /&gt;
attempts down.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Registration Script == &lt;br /&gt;
&amp;lt;br&amp;gt;Currently, the Jabber technology has no&lt;br /&gt;
concept of ''anonymous'' users—users who can connect to the server with&lt;br /&gt;
no previous registration requirement.  Until this is possible, we have&lt;br /&gt;
to make do with creating specific users for specific scenarios.&lt;br /&gt;
&lt;br /&gt;
To this end, it would be useful to be able to run a quick script to&lt;br /&gt;
register a new user, rather than grab an existing client, start it up,&lt;br /&gt;
and go through the process of registering a new user with the Jabber&lt;br /&gt;
server, with whatever window navigation and mouse clicking that might&lt;br /&gt;
entail. All the script must do is  interact with the Jabber server in&lt;br /&gt;
the context of the &amp;lt;tt&amp;gt;jabber:iq:register&amp;lt;/tt&amp;gt; namespace, specifically,&lt;br /&gt;
pre-session. It must be able to make a registration ''inquiry'' by&lt;br /&gt;
sending an IQ-get and returning the fields listed in the result and to&lt;br /&gt;
make a registration ''attempt'', when supplied with values for the&lt;br /&gt;
registration fields.&lt;br /&gt;
&lt;br /&gt;
We should be able to invoke our script,  ''reguser'', in one of two&lt;br /&gt;
ways. The first, specifying merely a hostname (and optional port, which&lt;br /&gt;
will default to 5222 if not specified), implies a registration&lt;br /&gt;
''inquiry'', that we wish to make an inquiry of the Jabber server as to&lt;br /&gt;
(a) whether  registration is possible and (b) if so, what fields are&lt;br /&gt;
required. The second way, specifying not only the host and optional port&lt;br /&gt;
but also a list of field name and value pairs, implies a registration&lt;br /&gt;
''attempt''. Example 7-5 shows both these ways in action.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''Uses of the reguser script''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt; $ &amp;lt;tt&amp;gt;./reguser yak:5222&amp;lt;/tt&amp;gt; [Enquiry] Fields: username&lt;br /&gt;
password email name&lt;br /&gt;
&lt;br /&gt;
$ &amp;lt;tt&amp;gt;./reguser yak username=joseph password=spinach 'name=Joseph Adams'&lt;br /&gt;
email=joseph@yak&amp;lt;/tt&amp;gt; [Attempt] (joseph) Successful registration&lt;br /&gt;
&lt;br /&gt;
$ &amp;lt;tt&amp;gt;./reguser yak username=dj password=secret 'name=DJ Adams'&lt;br /&gt;
email=dj@yak&amp;lt;/tt&amp;gt; [Attempt] (dj) Error: 409 (Username Not Available)&amp;lt;/code&amp;gt;&lt;br /&gt;
As it's our first substantial script, let's take it step by step. It's&lt;br /&gt;
written in Perl and uses the &amp;lt;tt&amp;gt;Net::Jabber&amp;lt;/tt&amp;gt; module:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;#!/usr/bin/perl&lt;br /&gt;
&lt;br /&gt;
use strict; use Net::Jabber 1.0022 qw(Client);&lt;br /&gt;
&lt;br /&gt;
use constant NS_REGISTER =&amp;amp;gt; 'jabber:iq:register';&lt;br /&gt;
&lt;br /&gt;
unless (@ARGV) { print usage(); exit;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We start out with some basic start-of-script housekeeping:  delaring our&lt;br /&gt;
usage of &amp;lt;tt&amp;gt;Net::Jabber&amp;lt;/tt&amp;gt;, setting a constant for the&lt;br /&gt;
&amp;lt;tt&amp;gt;jabber:iq:register&amp;lt;/tt&amp;gt; namespace, and handling the case of being&lt;br /&gt;
&amp;quot;wrongly&amp;quot; invoked by giving some help text from the &amp;lt;tt&amp;gt;usage()&amp;lt;/tt&amp;gt;&lt;br /&gt;
subroutine. The specification of  &amp;lt;tt&amp;gt;Client&amp;lt;/tt&amp;gt; in the line:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;use Net::Jabber 1.0022 qw(Client);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
means that the connection is going to be client-based; in other words,&lt;br /&gt;
the namespace that will be used to qualify the XML stream header that&lt;br /&gt;
&amp;lt;tt&amp;gt;Net::Jabber&amp;lt;/tt&amp;gt; will produce is &amp;lt;tt&amp;gt;jabber:client&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;Net::Jabber&amp;lt;/tt&amp;gt; module has changed as it has matured over the&lt;br /&gt;
recent  versions (1.0020, 1.0021, and 1.0022), and these changes do&lt;br /&gt;
sometimes affect how the scripts that use &amp;lt;tt&amp;gt;Net::Jabber&amp;lt;/tt&amp;gt; should be&lt;br /&gt;
written. So we explicitly specify in the &amp;lt;tt&amp;gt;use&amp;lt;/tt&amp;gt; statement which&lt;br /&gt;
version of &amp;lt;tt&amp;gt;Net::Jabber&amp;lt;/tt&amp;gt; we require, to avoid confusion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;my ($host, $port) = split(&amp;quot;:&amp;quot;, shift @ARGV); $port ||= 5222;&lt;br /&gt;
&lt;br /&gt;
my $c = Net::Jabber::Client-&amp;amp;gt;new();&lt;br /&gt;
&lt;br /&gt;
defined($c-&amp;amp;gt;Connect( hostname =&amp;amp;gt; $host, port     =&amp;amp;gt; $port, ))&lt;br /&gt;
or die &amp;quot;Cannot reach Jabber server at $host:$port\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
my ($iq, $query, $result);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We parse the hostname and port, defaulting the latter to 5222 if it&lt;br /&gt;
wasn't specified. Then we create a new instance of the&lt;br /&gt;
&amp;lt;tt&amp;gt;Net::Jabber::Client&amp;lt;/tt&amp;gt; object. The &amp;lt;tt&amp;gt;Net::Jabber&amp;lt;/tt&amp;gt; family of&lt;br /&gt;
modules presents its collective functions in an object-oriented way. The&lt;br /&gt;
scalar &amp;lt;tt&amp;gt;$c&amp;lt;/tt&amp;gt; represents the  &amp;quot;client&amp;quot; mechanism with which we&lt;br /&gt;
connect to the Jabber server.&lt;br /&gt;
&lt;br /&gt;
With the &amp;lt;tt&amp;gt;Connect()&amp;lt;/tt&amp;gt; method, we make a connection to the Jabber&lt;br /&gt;
server; the namespace of the XML stream for this connection,  sent to&lt;br /&gt;
the Jabber server in the stream header, is  &amp;lt;tt&amp;gt;jabber:client&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;# Registration attempt or inquiry?&lt;br /&gt;
&lt;br /&gt;
if (scalar @ARGV) {&lt;br /&gt;
&lt;br /&gt;
  # Attempt: Send &amp;amp;lt;iq type='set'&amp;amp;gt; &amp;amp;lt;query&lt;br /&gt;
  # xmlns='jabber:iq:register'&amp;amp;gt; &amp;amp;lt;username&amp;amp;gt;...&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
  # &amp;amp;lt;password&amp;amp;gt;...&amp;amp;lt;/password&amp;amp;gt; ... &amp;amp;lt;/query&amp;amp;gt; &amp;amp;lt;/iq&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
  print &amp;quot;[Attempt] &amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  $iq = Net::Jabber::IQ-&amp;amp;gt;new(); $iq-&amp;amp;gt;SetType('set'); $query =&lt;br /&gt;
  $iq-&amp;amp;gt;NewQuery(NS_REGISTER);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We work out what we have to do by looking to see if any extra parameters&lt;br /&gt;
beyond the hostname and port were specified. If there were, we need to&lt;br /&gt;
build an IQ-set in the &amp;lt;tt&amp;gt;jabber:iq:register&amp;lt;/tt&amp;gt; namespace to make a&lt;br /&gt;
registration attempt.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;Net::Jabber::IQ&amp;lt;/tt&amp;gt; module represents the IQ model and provides&lt;br /&gt;
methods to manage IQ packets. With the &amp;lt;tt&amp;gt;new()&amp;lt;/tt&amp;gt; constructor, we&lt;br /&gt;
create a new, empty IQ packet in &amp;lt;tt&amp;gt;$iq&amp;lt;/tt&amp;gt;, and set its &lt;br /&gt;
&amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt; attribute to &amp;lt;tt&amp;gt;set&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
As we know, the &amp;lt;tt&amp;gt;&amp;amp;lt;query/&amp;amp;gt;&amp;lt;/tt&amp;gt; part of an IQ packet is&lt;br /&gt;
contained ''within'' the  &amp;lt;tt&amp;gt;&amp;amp;lt;iq/&amp;amp;gt;&amp;lt;/tt&amp;gt; tag. The&lt;br /&gt;
&amp;lt;tt&amp;gt;NewQuery()&amp;lt;/tt&amp;gt; method, called on an IQ packet, creates a&lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;amp;lt;query/&amp;amp;gt;&amp;lt;/tt&amp;gt; tag as a child of that IQ packet and delivers us&lt;br /&gt;
a handle on that &amp;lt;tt&amp;gt;&amp;amp;lt;query/&amp;amp;gt;&amp;lt;/tt&amp;gt; tag—which we store in &lt;br /&gt;
&amp;lt;tt&amp;gt;$query&amp;lt;/tt&amp;gt;—so that we can manipulate it independently of the IQ&lt;br /&gt;
packet that wraps around it. The &amp;lt;tt&amp;gt;jabber:iq:register&amp;lt;/tt&amp;gt; namespace&lt;br /&gt;
value is passed as a parameter to the &amp;lt;tt&amp;gt;NewQuery()&amp;lt;/tt&amp;gt; call to set&lt;br /&gt;
the correct &amp;lt;tt&amp;gt;xmlns&amp;lt;/tt&amp;gt; namespace attribute.&lt;br /&gt;
&lt;br /&gt;
Figure 7-2 shows what the packet looks like at this stage and how the&lt;br /&gt;
scalar object references &amp;lt;tt&amp;gt;$iq&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;$query&amp;lt;/tt&amp;gt; relate to it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[image:jab_0702.png|An IQ packet under construction by Net::Jabber::IQ|center|350 px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;/code&amp;gt; In our &amp;lt;tt&amp;gt;foreach&amp;lt;/tt&amp;gt;&lt;br /&gt;
loop, we run through the list of  parameters, in the form&lt;br /&gt;
''fieldname=value'', and  call a &amp;lt;tt&amp;gt;Set&amp;lt;/tt&amp;gt; method on the&lt;br /&gt;
&amp;lt;tt&amp;gt;$query&amp;lt;/tt&amp;gt; object (the &amp;lt;tt&amp;gt;&amp;amp;lt;query/&amp;amp;gt;&amp;lt;/tt&amp;gt; packet) to  add&lt;br /&gt;
child tags:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;  foreach my $arg (@ARGV) { my ($field, $value) = split('=&amp;quot;,&lt;br /&gt;
$arg); print &amp;quot;($value) &amp;quot; if $field eq 'username'; eval&lt;br /&gt;
'$query-&amp;amp;gt;Set'.ucfirst($field).'($value)';&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  $result = $c-&amp;amp;gt;SendAndReceiveWithID($iq);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;Net::Jabber::Query&amp;lt;/tt&amp;gt; provides a number of &amp;lt;tt&amp;gt;SetXXXX&amp;lt;/tt&amp;gt;&lt;br /&gt;
methods that are available according to namespace. These &amp;quot;set&amp;quot; methods &lt;br /&gt;
available for the &amp;lt;tt&amp;gt;jabber:iq:register&amp;lt;/tt&amp;gt; namespace are plentiful&lt;br /&gt;
and include &amp;lt;tt&amp;gt;SetName&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;SetEmail&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;SetPhone&amp;lt;/tt&amp;gt;, and&lt;br /&gt;
so on. Each method will create a child tag named after the method (e.g.,&lt;br /&gt;
&amp;lt;tt&amp;gt;SetName&amp;lt;/tt&amp;gt; will create a &amp;lt;tt&amp;gt;&amp;amp;lt;name/&amp;amp;gt;&amp;lt;/tt&amp;gt; tag, and&lt;br /&gt;
&amp;lt;tt&amp;gt;SetPhone&amp;lt;/tt&amp;gt; will create a &amp;lt;tt&amp;gt;&amp;amp;lt;phone/&amp;amp;gt;&amp;lt;/tt&amp;gt; tag) and insert&lt;br /&gt;
the value passed to the method into the tag.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$query-&amp;amp;gt;SetName('DJ Adams');&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
will insert (or amend) a tag in the &amp;lt;tt&amp;gt;&amp;amp;lt;query/&amp;amp;gt;&amp;lt;/tt&amp;gt; thus:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;amp;lt;iq type='set'&amp;amp;gt; &amp;amp;lt;query xmlns='jabber:iq:register'&amp;amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;amp;lt;name&amp;amp;gt;DJ Adams&amp;amp;lt;/name&amp;amp;gt;&amp;lt;/tt&amp;gt; &amp;amp;lt;/query&amp;amp;gt; &amp;amp;lt;/iq&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We use &amp;lt;tt&amp;gt;eval&amp;lt;/tt&amp;gt; to allow us to make our &amp;lt;tt&amp;gt;SetXXXX&amp;lt;/tt&amp;gt; method&lt;br /&gt;
calls dynamically, according to each field name specified.  The&lt;br /&gt;
&amp;lt;tt&amp;gt;ucfirst()&amp;lt;/tt&amp;gt; function is used to change the first character of the&lt;br /&gt;
field name to uppercase, to suit the &amp;lt;tt&amp;gt;SetXXXX&amp;lt;/tt&amp;gt; method naming&lt;br /&gt;
conventions.&lt;br /&gt;
&lt;br /&gt;
Once we've added all the fields, we send the complete packet&lt;br /&gt;
(&amp;lt;tt&amp;gt;$iq&amp;lt;/tt&amp;gt;) to the server using the &amp;lt;tt&amp;gt;SendAndReceiveWithID()&amp;lt;/tt&amp;gt;&lt;br /&gt;
method on the connection (&amp;lt;tt&amp;gt;$c&amp;lt;/tt&amp;gt;) object. This method is extremely&lt;br /&gt;
powerful and  does many things for us. It keeps the process of writing&lt;br /&gt;
small  scripts like this very simple. It adds a unique &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;&lt;br /&gt;
attribute to the &amp;lt;tt&amp;gt;&amp;amp;lt;iq/&amp;amp;gt;&amp;lt;/tt&amp;gt; packet, transmits the packet over&lt;br /&gt;
the XML stream,  ''and waits for a response''.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Hey, what about the event model that we read about?&amp;quot; you might ask. Of &lt;br /&gt;
course, &amp;lt;tt&amp;gt;Net::Jabber&amp;lt;/tt&amp;gt; supports an event-model programming style,&lt;br /&gt;
but for  now we can get away with keeping our code &amp;quot;procedural&amp;quot; (and&lt;br /&gt;
short) using this high-level method that does everything we want. After&lt;br /&gt;
all, in any one execution of the script, we wish to send only one packet&lt;br /&gt;
to the Jabber server and receive one back. Nothing more complicated than&lt;br /&gt;
that.&lt;br /&gt;
&lt;br /&gt;
Recipes in later chapters will demonstrate the event model.&lt;br /&gt;
&lt;br /&gt;
The response is stored in &amp;lt;tt&amp;gt;$result&amp;lt;/tt&amp;gt; and is itself an IQ packet,&lt;br /&gt;
as we expect. So &amp;lt;tt&amp;gt;$result&amp;lt;/tt&amp;gt; is a handle on a&lt;br /&gt;
&amp;lt;tt&amp;gt;Net::Jabber::IQ&amp;lt;/tt&amp;gt; object that we can now manipulate:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;  # Success if ($result-&amp;amp;gt;GetType() eq 'result') { print&lt;br /&gt;
&amp;quot;Successful registration\n&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  # Failure&lt;br /&gt;
  else { print &amp;quot;Error: &amp;quot;, $result-&amp;amp;gt;GetErrorCode(), &amp;quot; (&amp;quot;,&lt;br /&gt;
  $result-&amp;amp;gt;GetError(), &amp;quot;)\n&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We check the type of the IQ returned from the server. If it's a&lt;br /&gt;
&amp;lt;tt&amp;gt;result&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;RECV: &amp;amp;lt;iq type='result' id='1'&amp;amp;gt; &amp;amp;lt;query&lt;br /&gt;
xmlns='jabber:iq:register'/&amp;amp;gt; &amp;amp;lt;/iq&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
then great—the registration was successful. Otherwise, we can grab the&lt;br /&gt;
error code and description from the &amp;lt;tt&amp;gt;&amp;amp;lt;error/&amp;amp;gt;&amp;lt;/tt&amp;gt; element:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;RECV: &amp;amp;lt;iq type='error'&amp;amp;gt; &amp;amp;lt;query&lt;br /&gt;
xmlns='jabber:iq:register'&amp;amp;gt; &amp;amp;lt;username&amp;amp;gt;dj&amp;amp;lt;/username&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;password&amp;amp;gt;secret&amp;amp;lt;/password&amp;amp;gt; &amp;amp;lt;/query&amp;amp;gt; &amp;lt;tt&amp;gt;&amp;amp;lt;error&lt;br /&gt;
code='409'&amp;amp;gt;Username Not Available&amp;amp;lt;/error&amp;amp;gt;&amp;lt;/tt&amp;gt; &amp;amp;lt;/iq&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
using the &amp;lt;tt&amp;gt;GetError()&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;GetErrorCode()&amp;lt;/tt&amp;gt; methods on the&lt;br /&gt;
IQ object.&lt;br /&gt;
&lt;br /&gt;
We go through a similar process if there are no further parameters&lt;br /&gt;
following the &amp;lt;tt&amp;gt;host[:port]&amp;lt;/tt&amp;gt; specification:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;else {&lt;br /&gt;
&lt;br /&gt;
  # Inquiry: Send &amp;amp;lt;iq type='get'&amp;amp;gt;&amp;amp;lt;query&lt;br /&gt;
  # xmlns='jabber:iq:register'/&amp;amp;gt;&amp;amp;lt;/iq&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
  print &amp;quot;[Inquiry] &amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  $iq = Net::Jabber::IQ-&amp;amp;gt;new(); $iq-&amp;amp;gt;SetType('get'); $query =&lt;br /&gt;
  $iq-&amp;amp;gt;NewQuery(NS_REGISTER);&lt;br /&gt;
&lt;br /&gt;
  $result = $c-&amp;amp;gt;SendAndReceiveWithID($iq);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The only difference here is that we set the IQ type to &amp;lt;tt&amp;gt;get&amp;lt;/tt&amp;gt;, not&lt;br /&gt;
&amp;lt;tt&amp;gt;set&amp;lt;/tt&amp;gt;, and we don't insert any tags into the &amp;lt;tt&amp;gt;$query&amp;lt;/tt&amp;gt;&lt;br /&gt;
object,  before sending the packet off and waiting for a response:&lt;br /&gt;
&lt;br /&gt;
If we receive a &amp;lt;tt&amp;gt;result&amp;lt;/tt&amp;gt; type, like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;RECV: &amp;amp;lt;iq type='result'&amp;amp;gt; &amp;amp;lt;query&lt;br /&gt;
xmlns='jabber:iq:register'&amp;amp;gt; &amp;amp;lt;instructions&amp;amp;gt; Choose a username&lt;br /&gt;
and password to register with this server. &amp;amp;lt;/instructions&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;name/&amp;amp;gt; &amp;amp;lt;email/&amp;amp;gt; &amp;amp;lt;username/&amp;amp;gt; &amp;amp;lt;password/&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;/query&amp;amp;gt; &amp;amp;lt;/iq&amp;amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
then we need to extract the fields listed in the &amp;lt;tt&amp;gt;&amp;amp;lt;query/&amp;amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
tag and return them to the user.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;  # Success if ($result-&amp;amp;gt;GetType() eq 'result') { $query =&lt;br /&gt;
$result-&amp;amp;gt;GetQuery();&lt;br /&gt;
&lt;br /&gt;
    my %contents = $query-&amp;amp;gt;GetRegister(); delete&lt;br /&gt;
    $contents{'instructions'}; print &amp;quot;Fields: &amp;quot;, join(', ', keys&lt;br /&gt;
    %contents), &amp;quot;\n&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
While the &amp;lt;tt&amp;gt;NewQuery()&amp;lt;/tt&amp;gt; method creates a new&lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;amp;lt;query/&amp;amp;gt;&amp;lt;/tt&amp;gt; tag inside an IQ object, the &amp;lt;tt&amp;gt;GetQuery()&amp;lt;/tt&amp;gt;&lt;br /&gt;
method retrieves an existing one, in the form of a&lt;br /&gt;
&amp;lt;tt&amp;gt;Net::Jabber::Query&amp;lt;/tt&amp;gt; object whose handle we store in &lt;br /&gt;
&amp;lt;tt&amp;gt;$query&amp;lt;/tt&amp;gt;. We can call the &amp;lt;tt&amp;gt;GetRegister()&amp;lt;/tt&amp;gt; method on this&lt;br /&gt;
query object, which returns a hash of the contents:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;( 'instructions' =&amp;amp;gt; 'Choose a username and password ...',&lt;br /&gt;
'name'         =&amp;amp;gt; undef, 'email'        =&amp;amp;gt; undef, 'username'    &lt;br /&gt;
=&amp;amp;gt; undef, 'password'     =&amp;amp;gt; undef )&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And, after removing the &amp;quot;instructions,&amp;quot; we can display them as the&lt;br /&gt;
result.&lt;br /&gt;
&lt;br /&gt;
When an error is returned in response to the IQ-get (perhaps no&lt;br /&gt;
registrations are allowed), we display the error in the same way as&lt;br /&gt;
before:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;  # Failure else { $query = $result-&amp;amp;gt;GetQuery(); print &amp;quot;Error:&lt;br /&gt;
&amp;quot;, $result-&amp;amp;gt;GetErrorCode(), &amp;quot; (&amp;quot;, $result-&amp;amp;gt;GetError(), &amp;quot;)\n&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When we've finished, we close the connection and exit. Here we also have&lt;br /&gt;
the &amp;lt;tt&amp;gt;usage()&amp;lt;/tt&amp;gt; subroutine defined:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$c-&amp;amp;gt;Disconnect;&lt;br /&gt;
&lt;br /&gt;
exit;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sub usage {&lt;br /&gt;
&lt;br /&gt;
&amp;amp;lt;&amp;amp;lt;EOF Usage: Enquiry: reguser host[:port] Attempt: reguser&lt;br /&gt;
host[:port] field1=value1 [fieldN = valueN] ... EOF&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Using the Script === &lt;br /&gt;
&amp;lt;br&amp;gt;The script is very basic, but it gets the job&lt;br /&gt;
done. It is suitable for calling from another script, for mass user&lt;br /&gt;
generation, although you may wish to modify it so that a connection is&lt;br /&gt;
not created and destroyed for every username that needs to be&lt;br /&gt;
registered.&amp;lt;ref&amp;gt;Otherwise, you may experience socket rating problems.&lt;br /&gt;
See Section 4.13.1 in Chapter 4 for details. &amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It also illustrates how simple a Jabber client can be. In this case, the&lt;br /&gt;
&amp;lt;tt&amp;gt;Net::Jabber&amp;lt;/tt&amp;gt; libraries mask the bulk of the effort (socket&lt;br /&gt;
connection,  XML stream negotiation, XML fragment traffic management,&lt;br /&gt;
and so on).  We'll be making use of this script to create users for our&lt;br /&gt;
recipes later on in the book.&lt;/div&gt;</summary>
		<author><name>Mikeh</name></author>	</entry>

	</feed>