1<!-- saved from url=(0022)http://internet.e-mail -->
2<html>
3<head>
4<title>Untitled Document</title>
5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6</head>
7
8<body bgcolor="#ffffff" text="#000000">
9<p align="center"><b><font face="Georgia, Times New Roman, Times, serif" size="5">README
10 for the BEEPLib SASL Profiles</font></b></p>
11<p><font face="Georgia, Times New Roman, Times, serif">This BEEP library comes
12 equipped with two SASL profiles, corresponding to the Anonymous and OTP SASL
13 mechanisms. Example code for the use of both mechanisms has been included in
14 the distribution in org.beepcore.beep.example.SASLExample. This document will
15 describe this example and extrapolate from it to assist in the development and
16 deployment of other BEEP-based applications that wish to take advanatage of
17 the SASL mechanisms provided.</font></p>
18<p><font face="Georgia, Times New Roman, Times, serif"><b><i>An explicit explanation
19 of the SASLExample:</i></b></font></p>
20<p><font face="Georgia, Times New Roman, Times, serif">The code that follows has
21 been edited slightly to focus on the important points. Commentary can be found
22 in <b>bold</b> and preceeds the logic it's describing.</font></p>
23<p><font face="Courier New, Courier, mono">public class SASLExample</font></p>
24<p><font face="Courier New, Courier, mono">{<br>
25 </font></p>
26<p><font face="Courier New, Courier, mono"><b>/* Package and import directives
27 omitted for brevity</b></font><b><font face="Courier New, Courier, mono">. Local
28 constants denoted in UPPER_CASE</font></b><b><font face="Courier New, Courier, mono">*/</font></b></p>
29<blockquote>
30 <p><font face="Courier New, Courier, mono">public static void main(String argv[])<br>
31 {</font></p>
32 <blockquote>
33 <p><b><font face="Courier New, Courier, mono">/* BEEPLib's Logging facility
34 is initialized here, </font></b><b><font face="Courier New, Courier, mono">we
35 use the default console log (maps to System.out)</font></b><b><font face="Courier New, Courier, mono">.
36 */</font></b> <font face="Courier New, Courier, mono"><br>
37 ConsoleLog log = new ConsoleLog();<br>
38 log.setSeverity(Log.SEV_DEBUG_VERBOSE);<br>
39 Log.setLogService(log);</font></p>
40 <p><font face="Courier New, Courier, mono">try <br>
41 {</font></p>
42 <p><font face="Courier New, Courier, mono"><b>/* ProfileRegistry is a helpful
43 class. It allows a BEEP Peer </b></font><b><font face="Courier New, Courier, mono">to
44 register various classes (implementations of the class <i>ChannelControlListener</i>)
45 to process StartChannel requests for a given profile. In this case, we're
46 creating and initializing instances of our two SASL profiles, Anonymous
47 and OTP. We then register these profiles (which are their own <i>Channel
48 Control Listeners</i>) as the class to be called if a start channel request is
49 received. We also register the EchoProfile (for reasons we'll show later).
50 We register CCLs for each profile with the
51 <EM>addChannelControlListener</EM>
52 call
53 </font></b><font face="Courier New, Courier, mono"><b>*/</b><br>
54 // Set up our profile registry<br>
55 ProfileRegistry reg = new ProfileRegistry();<br>
56 SASLAnonymousProfile anon = new SASLAnonymousProfile();<br>
57 SASLOTPProfile otp = new SASLOTPProfile();<br>
58 anon.init(new ProfileConfiguration());<br>
59 otp.init(new ProfileConfiguration());<br>
60 <br>
61 reg.addChannelControlListener(SASLOTPProfile.uri, otp);<br>
62 reg.addChannelControlListener(SASLAnonymousProfile.uri, anon);<br>
63 reg.addChannelControlListener(EchoProfile.uri,<br>
64 new SASLExample().getCCL());</font></p>
65 <p><b><font face="Courier New, Courier, mono">/* If the command line arguments
66 specify to make this a 'listener' then we proceed to set ourselves up appropriately.
67 We have provided a simple stub routine to generate OTP databases for some
68 sample users (which are IW_User and IW_User2) to allow the example to function
69 correctly.*/</font></b></p>
70 <P><font face="Courier New, Courier, mono">// If we're a listener, then create
71 sessions by 'listening' on the<br>
72 // static AutomatedTCPSessionCreator methods<br>
73 if (argv[2].charAt(0) == 'l') {<br>
74 InetAddress addr = null;</font></P>
75 <P><FONT face="Courier New"><STRONG>/* This bit is a little inane, it simple
76 creates a couple of OTP database files for IW_User and IW_User2. After
77 running this in listening mode, you can see this files locally. I
78 suggest you take a look at them. It is our intention to write an
79 interface through which other storage mechanisms can hook in to store these
80 things - so that the profile can be used without being extended.
81 That's rife with security issues however, so this is what is available for
82 now.*/</STRONG></FONT></P>
83 <P><font face="Courier New, Courier, mono"> // Creates stub accts for the
84 users in this example<br>
85 try<br>
86 {<br>
87 UserDatabasePool.populateUserDatabases();<br>
88 }<br>
89 catch(BEEPException ex)<br>
90 {<br>
91 ex.printStackTrace();<br>
92 }</font></P>
93 <P><FONT face="Courier New"></FONT> </P>
94 <P><FONT face="Courier New"><STRONG>/* This is where we bind to an
95 address/port combination and begin to listen for connections. If
96 another peer connects to our port and sends us a greeting, a new session is
97 created.*/</STRONG></FONT></P>
98 <p><font face="Courier New, Courier, mono"> try {<br>
99 addr =
100 InetAddress.getByName(argv[1]);<br>
101 } catch (Exception x) {<br>
102 addr = InetAddress.getLocalHost();<br>
103 }</font></p>
104 <p><font face="Courier New, Courier, mono"> System.out.println("Listening
105 on " + addr.toString() + ":"<br>
106 + argv[1]);</font></p>
107 <P><font face="Courier New, Courier, mono"> while (true)
108 {</font><FONT face="Courier New, Courier, mono"> <br>
109 Session newSession =
110 AutomatedTCPSessionCreator.listen(addr, <br>
111 Integer.parseInt(argv[1]), <br>
112 reg);</FONT></P>
113 <P><FONT face="Courier New, Courier, mono">}</FONT><FONT
114 face="Courier New, Courier, mono">
115 <br>
116 }</FONT></P>
117 <P><FONT face="Courier New"><STRONG>/* This is the initiator path
118 */</STRONG></FONT></P>
119 <P><font face="Courier New, Courier, mono"> // Otherwise we're initiating.<br>
120 else if (argv[2].charAt(0) == 'i') <br>
121 {<br>
122 Channel echoChannel = null; <br>
123 Log.logEntry(Log.SEV_DEBUG,"Initiating..."<br>
124 + InetAddress.getByName(argv[0]).toString()<br>
125 + ":" + argv[1]);<br>
126 </font></P>
127 <P><FONT face="Courier New, Courier, mono"><STRONG>/* We create a Session by
128 connecting to the host/port where we know another BEEP peer is
129 listening. The peers exchange greetings, and a reference to the
130 Session is returned to us */</STRONG></FONT></P>
131 <P><FONT face="Courier New, Courier, mono">Session session =
132 AutomatedTCPSessionCreator.initiate(InetAddress.getByName(argv[0]),
133 <br>
134 Integer.parseInt(argv[1]), <br>
135 reg);</FONT></P><FONT
136 face="Courier New, Courier, mono"></FONT>
137 </blockquote>
138 <BLOCKQUOTE><FONT face="Courier New, Courier, mono">
139 <P><STRONG>/* The routine used below, <EM>AuthenticateSASLAnonymous </EM>is
140 provided as a convenience routine. All you have to do is provide it
141 with your session (the first argument) and some sort of identifier for
142 yourself (the second argument, in this case, the 'anonymous' string
143 constant) and go. The return value is another Session reference.
144 In this case, this will be the same session - although this isn't always the
145 case.*/</STRONG>
146 <br>
147 if(argv[3].charAt(0) == 'a')<br>
148 {<br>
149 session =
150 SASLAnonymousProfile.AuthenticateSASLAnonymous(session,<br>
151 SASLAnonymousProfile.ANONYMOUS);<br>
152 }</P>
153 <P><STRONG>/* This is the OTP convenience routine. The arguments are,
154 first, the session you wish to Authenticate on, second the Authorization
155 ID you wish to use (this is who you are authorized to act as, which is different
156 than who you authenticate as - see the OTP spec for a more extensive explanation),
157 third, the identity you're authenticating as, fourth, the passphrase you
158 use to secure yourself.*/</STRONG> <br>
159 else if(argv[3].charAt(0) == 'o')<br>
160 {<br>
161 session =
162 (TCPSession)SASLOTPProfile.AuthenticateSASLOTP(session,<br>
163 null, // No Authorization ID<br>
164 SAMPLE_OTP_USER,<br>
165 SAMPLE_OTP_PASSPHRASE );<br>
166 }</P>
167 <P><STRONG>/* When either SASL authentication routine succeeds without throwing
168 a SASLException, you're homefree! We can examine the new credentials
169 we have by calling <EM>session</EM>-><EM>getMyCredentials</EM>() which
170 returns a <EM>SessionCredential</EM> object, whose <EM>toString</EM>() method
171 prettyily prints all its attributes.*/</STRONG></P>
172 <P><STRONG>/* What we're going to do now shows us who we are as far as our
173 peer is concerned. We're going to start up an ECHO profile on BEEP (a
174 profile that simply echos back what we type) only it has a twist. The
175 ECHO profile this time (since we're running our example) echoes back what we
176 sent them AND includes credential information indicating who we have
177 authenticated as - from their point of view. This shows how the
178 credential exists on both sides.*/</STRONG>
179 <br>
180 echoChannel = session.startChannel(EchoProfile.uri);<br>
181 String temp = "Hi There!";<br>
182 ReplyListener idiot = null;<br>
183 echoChannel.sendMSG(new StringDataStream(temp),idiot);<br>
184 Utility.delay(500); <br>
185 }<br>
186 else <br>
187 {<br>
188 System.out.println(USAGE);<br>
189 return;<br>
190 }<br>
191 } catch (Exception x) {<br>
192 x.printStackTrace();<br>
193 Log.logEntry(Log.SEV_ERROR,"SASL Example Failed. Exiting.");<br>
194 return;<br>
195 }<br>
196 Log.logEntry(Log.SEV_DEBUG,"SASL Example Succeeded. Exiting");</P>
197 </FONT></BLOCKQUOTE>
198 <p><font face="Courier New, Courier, mono">}<br>
199 <b> /* The funky echo described above is implemented in the SASLExample source
200 code. You can examine it there if you like, but it is merely a distraction
201 here. */</b></font><font face="Courier New, Courier, mono"><br>
202 </font> </p>
203 </blockquote>
204<p><font face="Georgia, Times New Roman, Times, serif"><b><i>To use the existing
205 SASLAnonymous and SASLOTP Profiles:</i></b></font></p>
206<p><font face="Georgia, Times New Roman, Times, serif">Simply <i>initiate</i>
207 using the various <i>Authenticate </i>routines in the profiles, or <i> listen
208 </i>using an <i>org.beepcore.beep.core.ProfileRegistry</i> which registers the
209 included implmentations of SASLOTP and SASLAnonymous as the CCLs (<i>ChannelControlListener</i>s)
210 for the uri's corresponding to the two SASL Profiles. The specific classes are
211 o<i>rg.beepcore.profile.sasl.anonymous.SASLAnonymousProfile </i>and <i>org.beepcore.profile.sasl.otp.SASLOTPProfile
212 </i>of course.</font></p>
213<p><font face="Georgia, Times New Roman, Times, serif">Example:</font></p>
214<p></p>
215<p><font face="Georgia, Times New Roman, Times, serif"><i><b>To Authenticate to
216 another BEEP peer using Anonymous SASL:</b></i></font></p>
217<p><font face="Georgia, Times New Roman, Times, serif">simply call <i>AuthenticateSASLAnonymous
218 </i>in<i> or</i></font><i><font face="Georgia, Times New Roman, Times, serif">g.beepcore.profile.sasl.anonymous.SASLAnonymousProfile
219 </font></i><font face="Georgia, Times New Roman, Times, serif">with an existing
220 session, such as is done below.</font></p>
221<p><font face="Georgia, Times New Roman, Times, serif">// We have a valid Session
222 'mySession'</font></p>
223<p><font face="Georgia, Times New Roman, Times, serif">mySession = SASLAnonymousProfile.AuthenticateSASLAnonymous(
224 mySession, null, "Bob", "Bob's_password");</font></p>
225<p><font face="Georgia, Times New Roman, Times, serif"><b><i>To Authenticate to
226 another BEEP peer using OTP SASL:</i></b></font></p>
227<p><font face="Georgia, Times New Roman, Times, serif">The OTP case is very similar
228 to the Anonymous one</font></p>
229<p><font face="Georgia, Times New Roman, Times, serif">// We have a valid Session
230 'mySession'</font></p>
231<p><font face="Georgia, Times New Roman, Times, serif">mySession = SASLAnonymousProfile.AuthenticateSASLOTP(
232 mySession, null, "Bob", "Bob's_password");</font></p>
233<p><font face="Georgia, Times New Roman, Times, serif"><b><i>To access the Credentials
234 associated ith a given Session:</i></b></font></p>
235<p><font face="Georgia, Times New Roman, Times, serif">SessionCredential myCredentials
236 = mySession.getLocalCredential();</font></p>
237<p><font face="Georgia, Times New Roman, Times, serif">SessionCredential myPeersCredentials
238 = mySession.getPeerCredential();</font></p>
239<p><font face="Georgia, Times New Roman, Times, serif">System.out.println("My
240 credentials are "+myCredentials.toString());</font></p>
241<p><font face="Georgia, Times New Roman, Times, serif">System.out.println("My
242 peer's credentials are "+myPeersCredentials.toString());</font></p>
243<p></p>
244<p></p>
245<p></p>
246<p></p>
247<p></p>
248<p></p>
249<p></p>
250<p></p>
251<p></p>
252<p></p>
253<p></p>
254<p>Note: The <i>SessionCredential</i> class has several data members, each of
255 which can be accessed as outlined in the documentation for <i>org.beepcore.beep.core.SessionCredential.</i></p>
256<p><font face="Georgia, Times New Roman, Times, serif"><i><b>To generate a sequence
257 of One-Time Passwords</b></i></font></p>
258<p><font face="Georgia, Times New Roman, Times, serif">A utility class <i>org.beepcore.beep.profile.sasl.otp.Generator
259 </i>has been provided for the</font><font face="Georgia, Times New Roman, Times, serif">purpose
260 of generating OTP databases for individual users. These databases take the form
261 of flat files that are the serialized output of the java.util.Properties class.
262 The library does not make an effort to modify or maintain any sort of access
263 control for the generated files. It is up to the application or the individual
264 user to protect access to the generated file. It will disallow the generation
265 of a user otp database file on top of a previously generated one.</font></p>
266<p><font face="Georgia, Times New Roman, Times, serif">To use: simply run java
267 org.beepcore.beep.profile.sasl.otp.Generator. This will bring up a series of
268 questions and prompts that will allow the user to enter enough information to
269 create an OTP database. The generated file will then be produced in the local
270 directory. It is the responsiblity of the user to ensure that the generated
271 file is accessible by listening BEEP peers in order to facilitate OTP authentication.</font></p>
272<p><font face="Georgia, Times New Roman, Times, serif">The 'clean' way to renew
273 or alter them is to use the <i>AuthenticateSASLOTPWithInit </i>call in <i>org.beepcore.beep.profile.sasl.otp.SASLOTPProfile
274 </i>which is identical to the other OTP authentication calls, except that it
275 tells the server to create a record for this user. If you have access to the
276 test directory, OTPTest shows how to do this too.</font></p>
277<p><font face="Georgia, Times New Roman, Times, serif">Note however that the whole
278 issue of how the user information for OTP is stored and propagated is all very
279 murky. The <i>org.beepcore.beep.profile.sasl.otp.UserDatabase </i>interface
280 is designed to kind of provide room for expansion in this area, considering
281 the ability to create or delete user OTP databases, and the like. We will eventually
282 have to provide some sort of facility for this in the BEEP libraries, not in
283 core, but in lib perhaps. Until then, look to <i>UserDatabaseManager</i> and
284 its implementation in <i>UserDatabasePool </i>as the prototype. </font></p>
285</body>
286</html>
287