+ *
+ ***********************************************************************/
+
+package com.novell.casa.authserver;
+
+import java.io.ByteArrayInputStream;
+
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+
+/*
+ * AuthToken Class.
+ *
+ * This class constructs authentication tokens that clients can present
+ * to services for authentication. The format of the authentication token
+ * is as follows:
+ *
+ *
+ *
+ * signature value
+ * lifetime value
+ * Identity Token typeidentity token data
+ *
+ *
+ */
+public class AuthToken {
+
+ private String m_token;
+ private String m_lifetime;
+ private String m_identityTokenType;
+ private StringBuffer m_identityToken;
+ private String m_signature;
+
+ /*
+ * Class for handling parsing events.
+ */
+ private class SAXHandler extends org.xml.sax.helpers.DefaultHandler
+ {
+ private final static int AWAITING_ROOT_ELEMENT_START = 0;
+ private final static int AWAITING_ROOT_ELEMENT_END = 1;
+ private final static int AWAITING_SIGNATURE_ELEMENT_START = 2;
+ private final static int AWAITING_SIGNATURE_ELEMENT_END = 3;
+ private final static int AWAITING_SIGNATURE_DATA = 4;
+ private final static int AWAITING_LIFETIME_ELEMENT_START = 5;
+ private final static int AWAITING_LIFETIME_ELEMENT_END = 6;
+ private final static int AWAITING_LIFETIME_DATA = 7;
+ private final static int AWAITING_IDENT_TOKEN_ELEMENT_START = 8;
+ private final static int AWAITING_IDENT_TOKEN_ELEMENT_END = 9;
+ private final static int AWAITING_IDENT_TOKEN_DATA = 10;
+ private final static int AWAITING_TYPE_ELEMENT_START = 11;
+ private final static int AWAITING_TYPE_ELEMENT_END = 12;
+ private final static int AWAITING_TYPE_DATA = 13;
+ private final static int DONE_PARSING = 14;
+
+ private AuthToken m_AuthToken;
+ private int m_state;
+
+ /*
+ * Constructor
+ */
+ public SAXHandler (AuthToken AuthToken)
+ {
+ super();
+
+ // Initialize our members
+ m_AuthToken = AuthToken;
+ m_state = AWAITING_ROOT_ELEMENT_START;
+ }
+
+ /*
+ * endDocument() implementation.
+ */
+ public void endDocument () throws SAXException
+ {
+ // Verify that we obtained all of the required elements
+ if (m_state != DONE_PARSING)
+ {
+ System.err.println("AuthToken SAXHandler.endDocument()- Missing element");
+ throw new SAXException("Missing element");
+ }
+ }
+
+ /*
+ * startElement() implementation.
+ */
+ public void startElement (String uri, String name, String qName, org.xml.sax.Attributes atts) throws SAXException
+ {
+ // Proceed based on our state
+ switch (m_state) {
+
+ case AWAITING_ROOT_ELEMENT_START:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.authTokenElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_SIGNATURE_ELEMENT_START;
+ }
+ else
+ {
+ System.err.println("AuthToken SAXHandler.startElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_SIGNATURE_ELEMENT_START:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.signatureElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_SIGNATURE_DATA;
+ }
+ else
+ {
+ System.err.println("AuthToken SAXHandler.startElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_LIFETIME_ELEMENT_START:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.lifetimeElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_LIFETIME_DATA;
+ }
+ else
+ {
+ System.err.println("AuthToken SAXHandler.startElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+
+ break;
+
+ case AWAITING_IDENT_TOKEN_ELEMENT_START:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.identTokenElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_TYPE_ELEMENT_START;
+ }
+ else
+ {
+ System.err.println("AuthToken SAXHandler.startElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_TYPE_ELEMENT_START:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.typeElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_TYPE_DATA;
+ }
+ else
+ {
+ System.err.println("AuthToken SAXHandler.startElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ default:
+ System.err.println("AuthToken SAXHandler.startElement()- State error");
+ throw new SAXException("State error");
+ }
+ }
+
+ /*
+ * endElement() immplementation.
+ */
+ public void endElement (String uri, String name, String qName) throws SAXException
+ {
+ // Proceed based on our state
+ switch (m_state) {
+
+ case AWAITING_ROOT_ELEMENT_END:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.authTokenElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = DONE_PARSING;
+ }
+ else
+ {
+ System.err.println("AuthToken SAXHandler.endElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_SIGNATURE_ELEMENT_END:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.signatureElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_LIFETIME_ELEMENT_START;
+ }
+ else
+ {
+ System.err.println("AuthToken SAXHandler.endElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_LIFETIME_ELEMENT_END:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.lifetimeElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_IDENT_TOKEN_ELEMENT_START;
+ }
+ else
+ {
+ System.err.println("AuthToken SAXHandler.endElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_TYPE_ELEMENT_END:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.typeElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_IDENT_TOKEN_DATA;
+ }
+ else
+ {
+ System.err.println("AuthToken SAXHandler.endElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_IDENT_TOKEN_ELEMENT_END:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.identTokenElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_ROOT_ELEMENT_END;
+ }
+ else
+ {
+ System.err.println("AuthToken SAXHandler.endElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ default:
+ System.err.println("AuthToken SAXHandler.startElement()- State error");
+ throw new SAXException("State error");
+ }
+ }
+
+ /*
+ * character() implementation.
+ */
+ public void characters (char ch[], int start, int length) throws SAXException
+ {
+ // Proceed based on our state
+ switch (m_state) {
+
+ case AWAITING_SIGNATURE_DATA:
+ // Consume the data
+ m_AuthToken.m_signature = new String(ch, start, length);
+
+ // Advance to the next state
+ m_state = AWAITING_SIGNATURE_ELEMENT_END;
+ break;
+
+ case AWAITING_LIFETIME_DATA:
+ // Consume the data
+ m_AuthToken.m_lifetime = new String(ch, start, length);
+
+ // Advance to the next state
+ m_state = AWAITING_LIFETIME_ELEMENT_END;
+ break;
+
+ case AWAITING_TYPE_DATA:
+ // Consume the data
+ m_AuthToken.m_identityTokenType = new String(ch, start, length);
+
+ // Advance to the next state
+ m_state = AWAITING_TYPE_ELEMENT_END;
+ break;
+
+ case AWAITING_IDENT_TOKEN_DATA:
+ case AWAITING_IDENT_TOKEN_ELEMENT_END:
+ // Consume the data
+ m_AuthToken.m_identityToken.append(ch, start, length);
+
+ // Advance to the next state
+ m_state = AWAITING_IDENT_TOKEN_ELEMENT_END;
+ break;
+
+ default:
+ // Do nothing
+ break;
+ }
+ }
+ }
+
+ /*
+ * Constructor.
+ */
+ public AuthToken (
+ String identityId,
+ String realm,
+ String targetService,
+ String targetHost) throws Exception
+ {
+ try
+ {
+ // Verify that we have support for the specified service.
+ // tbd
+
+ // For now lets use the services of the only IdentityToken provider
+ // that we have.
+ //
+ // tbd - Add code to allow for the consumption of tokens
+ // from different providers.
+ CasaIdentityToken identityToken = new CasaIdentityToken();
+ identityToken.initialize(identityId,
+ realm,
+ targetService,
+ targetHost);
+
+ m_identityToken = new StringBuffer();
+ m_identityToken.append(identityToken.getEncodedToken());
+ m_identityTokenType = identityToken.getProviderType();
+
+ m_lifetime = "tbd";
+
+ // Generate a signature
+ // tbd - Over identToken, identToken type, and lifetime data.
+ m_signature = "tbd";
+
+ // Get a StringBuffer to help us with the construction of the token
+ StringBuffer sb = new StringBuffer();
+
+ // Start building the message
+ sb.append(ProtoDefs.xmlDeclaration + "\r\n");
+ sb.append("<" + ProtoDefs.authTokenElementName + ">" + "\r\n");
+ sb.append("<" + ProtoDefs.signatureElementName + ">" + m_signature + "" + ProtoDefs.signatureElementName + ">" + "\r\n");
+ sb.append("<" + ProtoDefs.lifetimeElementName + ">" + m_lifetime + "" + ProtoDefs.lifetimeElementName + ">" + "\r\n");
+ sb.append("<" + ProtoDefs.identTokenElementName + " mode=\"escaped\">"
+ + "<" + ProtoDefs.typeElementName + ">" + m_identityTokenType + "" + ProtoDefs.typeElementName + ">"
+ + "" + "" + ProtoDefs.identTokenElementName + ">" + "\r\n");
+ sb.append("" + ProtoDefs.authTokenElementName + ">" + "\r\n");
+
+ // Save the token
+ m_token = sb.toString();
+ }
+ catch (Exception e)
+ {
+ // tbd
+ System.err.println("AuthToken()- Exception: " + e.toString());
+ }
+ }
+
+ /*
+ * Constructor given an authentication token string. The constructor
+ * validates the token as part of its processing.
+ */
+ public AuthToken(String token) throws Exception
+ {
+ // Decode the token string
+ m_token = Base64Coder.decode(token);
+
+ // Instantiate string buffer for the identity token
+ m_identityToken = new StringBuffer();
+
+ // Now parse the token into its elements
+ try
+ {
+ // Parse the AuthToken
+ XMLReader xr = XMLReaderFactory.createXMLReader();
+ SAXHandler handler = new SAXHandler(this);
+ xr.setContentHandler(handler);
+ xr.setErrorHandler(handler);
+
+ ByteArrayInputStream inStream = new ByteArrayInputStream(m_token.getBytes());
+ InputSource source = new InputSource(inStream);
+ xr.parse(source);
+
+ // Verify the signature
+ // tbd
+
+ // Verify that the token has not expired
+ // tbd
+ }
+ catch (SAXException e)
+ {
+ System.err.println("AuthToken()- Parse exception: " + e.toString());
+ throw new Exception("Protocol error");
+ }
+ }
+
+ /*
+ * Returns a string containing the Base64 encode token.
+ */
+ public String toString()
+ {
+ return Base64Coder.encode(m_token);
+ }
+
+ /*
+ * Returns the lifetime of the token.
+ */
+ public String getLifetime()
+ {
+ // tbd
+ return "60";
+ }
+
+ /*
+ * Returns the identity token.
+ */
+ public String getIdentityToken()
+ {
+ return m_identityToken.toString();
+ }
+ /*
+ * Returns the identity token provider type.
+ */
+ public String getIdentityTokenProviderType()
+ {
+ return m_identityTokenType;
+ }
+}
diff --git a/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/Base64Coder.java b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/Base64Coder.java
new file mode 100644
index 00000000..9573ba44
--- /dev/null
+++ b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/Base64Coder.java
@@ -0,0 +1,121 @@
+/**************************************************************************
+*
+* A Base64 Encoder/Decoder.
+*
+* This class is used to encode and decode data in Base64 format
+* as described in RFC 1521.
+*
+*
+* Copyright 2003: Christian d'Heureuse, Inventec Informatik AG, Switzerland.
+* License: This is "Open Source" software and released under the GNU/LGPL license.
+* It is provided "as is" without warranty of any kind. Please contact the author for other licensing arrangements.
+* Home page: www.source-code.biz
+*
+*
+* Version history:
+* 2003-07-22 Christian d'Heureuse (chdh): Module created.
+* 2005-08-11 chdh: Lincense changed from GPL to LGPL.
+*
+**************************************************************************/
+
+package com.novell.casa.authserver;
+
+public class Base64Coder {
+
+// Mapping table from 6-bit nibbles to Base64 characters.
+private static char[] map1 = new char[64];
+ static {
+ int i=0;
+ for (char c='A'; c<='Z'; c++) map1[i++] = c;
+ for (char c='a'; c<='z'; c++) map1[i++] = c;
+ for (char c='0'; c<='9'; c++) map1[i++] = c;
+ map1[i++] = '+'; map1[i++] = '/'; }
+
+// Mapping table from Base64 characters to 6-bit nibbles.
+private static byte[] map2 = new byte[128];
+ static {
+ for (int i=0; i>> 2;
+ int o1 = ((i0 & 3) << 4) | (i1 >>> 4);
+ int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6);
+ int o3 = i2 & 0x3F;
+ out[op++] = map1[o0];
+ out[op++] = map1[o1];
+ out[op] = op < oDataLen ? map1[o2] : '='; op++;
+ out[op] = op < oDataLen ? map1[o3] : '='; op++; }
+ return out; }
+
+/**
+* Decodes a Base64 string.
+* @param s a Base64 String to be decoded.
+* @return A String containing the decoded data.
+* @throws IllegalArgumentException if the input is not valid Base64 encoded data.
+*/
+public static String decode (String s) {
+ return new String(decode(s.toCharArray())); }
+
+/**
+* Decodes Base64 data.
+* No blanks or line breaks are allowed within the Base64 encoded data.
+* @param in a character array containing the Base64 encoded data.
+* @return An array containing the decoded data bytes.
+* @throws IllegalArgumentException if the input is not valid Base64 encoded data.
+*/
+public static byte[] decode (char[] in) {
+ int iLen = in.length;
+ if (iLen%4 != 0) throw new IllegalArgumentException ("Length of Base64 encoded input string is not a multiple of 4.");
+ while (iLen > 0 && in[iLen-1] == '=') iLen--;
+ int oLen = (iLen*3) / 4;
+ byte[] out = new byte[oLen];
+ int ip = 0;
+ int op = 0;
+ while (ip < iLen) {
+ int i0 = in[ip++];
+ int i1 = in[ip++];
+ int i2 = ip < iLen ? in[ip++] : 'A';
+ int i3 = ip < iLen ? in[ip++] : 'A';
+ if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127)
+ throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
+ int b0 = map2[i0];
+ int b1 = map2[i1];
+ int b2 = map2[i2];
+ int b3 = map2[i3];
+ if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0)
+ throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
+ int o0 = ( b0 <<2) | (b1>>>4);
+ int o1 = ((b1 & 0xf)<<4) | (b2>>>2);
+ int o2 = ((b2 & 3)<<6) | b3;
+ out[op++] = (byte)o0;
+ if (op
+ *
+ ***********************************************************************/
+
+package com.novell.casa.authserver;
+
+import java.io.ByteArrayInputStream;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Set;
+
+import javax.naming.Context;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.InitialDirContext;
+
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+
+/*
+ * CasaIdentityToken Class.
+ *
+ * This class constructs Casa Identity tokens.
+ *
+ * A Casa Identity Token is a simple XML Document
+ * with information about an identity in the form
+ * of:
+ *
+ *
+ *
+ * identity id
+ * identity data source name
+ * identity data source url
+ * target service name
+ * target host name
+ *
+ * attribute value
+ * attribute2 value
+ * ...
+ *
+ *
+ *
+ *
+ * attribute/values pairs. The attribute names
+ * being the XML elements of the documents.
+ *
+ */
+public class CasaIdentityToken implements IdentityToken
+{
+ /*
+ * XML Element Name Constants for the documents exchanged between the
+ * Casa Client and the Casa Server.
+ */
+ private final static String casaIdentTokElementName = "casa_ident_tok";
+ private final static String idElementName = "id";
+ private final static String sourceNameElementName = "source_name";
+ private final static String sourceUrlElementName = "source_url";
+ private final static String targetServiceElementName = "target_service";
+ private final static String targetHostElementName = "target_host";
+ private final static String attributesElementName = "attributes";
+
+
+ private String m_identityId = null;
+ private String m_sourceName = null;
+ private String m_sourceUrl = null;
+ private String m_service = null;
+ private String m_host = null;
+ private String m_token = null;
+ private javax.naming.directory.Attributes m_attributes = null;
+
+ /*
+ * Class for handling Authentication Request parsing events.
+ */
+ private class SAXHandler extends org.xml.sax.helpers.DefaultHandler
+ {
+ private final static int AWAITING_ROOT_ELEMENT_START = 0;
+ private final static int AWAITING_ROOT_ELEMENT_END = 1;
+ private final static int AWAITING_ID_ELEMENT_START = 2;
+ private final static int AWAITING_ID_ELEMENT_END = 3;
+ private final static int AWAITING_ID_DATA = 4;
+ private final static int AWAITING_SOURCE_NAME_ELEMENT_START = 5;
+ private final static int AWAITING_SOURCE_NAME_ELEMENT_END = 6;
+ private final static int AWAITING_SOURCE_NAME_DATA = 7;
+ private final static int AWAITING_SOURCE_URL_ELEMENT_START = 8;
+ private final static int AWAITING_SOURCE_URL_ELEMENT_END = 9;
+ private final static int AWAITING_SOURCE_URL_DATA = 10;
+ private final static int AWAITING_TARGET_SERVICE_ELEMENT_START = 11;
+ private final static int AWAITING_TARGET_SERVICE_ELEMENT_END = 12;
+ private final static int AWAITING_TARGET_SERVICE_DATA = 13;
+ private final static int AWAITING_TARGET_HOST_ELEMENT_START = 14;
+ private final static int AWAITING_TARGET_HOST_ELEMENT_END = 15;
+ private final static int AWAITING_TARGET_HOST_DATA = 16;
+ private final static int AWAITING_ATTRIBUTES_ELEMENT_START = 17;
+ private final static int AWAITING_ATTRIBUTE_START = 18;
+ private final static int AWAITING_ATTRIBUTE_END = 19;
+ private final static int AWAITING_ATTRIBUTE_DATA = 20;
+ private final static int DONE_PARSING = 21;
+
+ private CasaIdentityToken m_casaIdentToken;
+ private int m_state;
+ private String m_currAttribute;
+ private boolean m_encryptedAttrs;
+
+ /*
+ * Constructor
+ */
+ public SAXHandler (CasaIdentityToken casaIdentityToken)
+ {
+ super();
+
+ // Initialize our members
+ m_casaIdentToken = casaIdentityToken;
+ m_state = AWAITING_ROOT_ELEMENT_START;
+ }
+
+ /*
+ * endDocument() implementation.
+ */
+ public void endDocument () throws SAXException
+ {
+ // Verify that we obtained all of the required elements
+ if (m_state != DONE_PARSING)
+ {
+ System.err.println("CasaIdentityToken SAXHandler.endDocument()- Missing element");
+ throw new SAXException("Missing element");
+ }
+ }
+
+ /*
+ *
+ * startElement() implementation.
+ */
+ public void startElement (String uri, String name, String qName, org.xml.sax.Attributes atts) throws SAXException
+ {
+ // Proceed based on our state
+ switch (m_state) {
+
+ case AWAITING_ROOT_ELEMENT_START:
+ // Verify that we are processing the expected tag
+ if (casaIdentTokElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_ID_ELEMENT_START;
+ }
+ else
+ {
+ System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_ID_ELEMENT_START:
+ // Verify that we are processing the expected tag
+ if (idElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_ID_DATA;
+ }
+ else
+ {
+ System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_SOURCE_NAME_ELEMENT_START:
+ // Verify that we are processing the expected tag
+ if (sourceNameElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_SOURCE_NAME_DATA;
+ }
+ else
+ {
+ System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+
+ break;
+
+ case AWAITING_SOURCE_URL_ELEMENT_START:
+ // Verify that we are processing the expected tag
+ if (sourceUrlElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_SOURCE_URL_DATA;
+ }
+ else
+ {
+ System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_TARGET_SERVICE_ELEMENT_START:
+ // Verify that we are processing the expected tag
+ if (targetServiceElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_TARGET_SERVICE_DATA;
+ }
+ else
+ {
+ System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_TARGET_HOST_ELEMENT_START:
+ // Verify that we are processing the expected tag
+ if (targetHostElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_TARGET_HOST_DATA;
+ }
+ else
+ {
+ System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_ATTRIBUTES_ELEMENT_START:
+ // Verify that we are processing the expected tag
+ if (attributesElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_ATTRIBUTE_START;
+ }
+ else
+ {
+ System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_ATTRIBUTE_START:
+ // Save the element name as the current attribute
+ m_currAttribute = qName;
+
+ // Advance to the next state
+ m_state = AWAITING_ATTRIBUTE_DATA;
+ break;
+
+ default:
+ System.err.println("CasaIdentityToken SAXHandler.startElement()- State error");
+ throw new SAXException("State error");
+ }
+ }
+
+ /*
+ * endElement() immplementation.
+ */
+ public void endElement (String uri, String name, String qName) throws SAXException
+ {
+ // Proceed based on our state
+ switch (m_state) {
+
+ case AWAITING_ROOT_ELEMENT_END:
+ // Verify that we are processing the expected tag
+ if (casaIdentTokElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = DONE_PARSING;
+ }
+ else
+ {
+ System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_ID_ELEMENT_END:
+ // Verify that we are processing the expected tag
+ if (idElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_SOURCE_NAME_ELEMENT_START;
+ }
+ else
+ {
+ System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_SOURCE_NAME_ELEMENT_END:
+ // Verify that we are processing the expected tag
+ if (sourceNameElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_SOURCE_URL_ELEMENT_START;
+ }
+ else
+ {
+ System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_SOURCE_URL_ELEMENT_END:
+ // Verify that we are processing the expected tag
+ if (sourceUrlElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_TARGET_SERVICE_ELEMENT_START;
+ }
+ else
+ {
+ System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_TARGET_SERVICE_ELEMENT_END:
+ // Verify that we are processing the expected tag
+ if (targetServiceElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_TARGET_HOST_ELEMENT_START;
+ }
+ else
+ {
+ System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_TARGET_HOST_ELEMENT_END:
+ // Verify that we are processing the expected tag
+ if (targetHostElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_ATTRIBUTES_ELEMENT_START;
+ }
+ else
+ {
+ System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_ATTRIBUTE_END:
+ // Advance to the next state
+ m_state = AWAITING_ATTRIBUTE_START;
+ break;
+
+ case AWAITING_ATTRIBUTE_START:
+ // Verify that we are processing the expected tag
+ if (attributesElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_ROOT_ELEMENT_END;
+ }
+ else
+ {
+ System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ default:
+ System.err.println("CasaIdentityToken SAXHandler.startElement()- State error");
+ throw new SAXException("State error");
+ }
+ }
+
+ /*
+ * character() implementation.
+ */
+ public void characters (char ch[], int start, int length) throws SAXException
+ {
+ // Proceed based on our state
+ switch (m_state) {
+
+ case AWAITING_ID_DATA:
+ // Consume the data
+ m_casaIdentToken.m_identityId = new String(ch, start, length);
+
+ // Advance to the next state
+ m_state = AWAITING_ID_ELEMENT_END;
+ break;
+
+ case AWAITING_SOURCE_NAME_DATA:
+ // Consume the data
+ m_casaIdentToken.m_sourceName = new String(ch, start, length);
+
+ // Advance to the next state
+ m_state = AWAITING_SOURCE_NAME_ELEMENT_END;
+ break;
+
+ case AWAITING_SOURCE_URL_DATA:
+ // Consume the data
+ m_casaIdentToken.m_sourceUrl = new String(ch, start, length);
+
+ // Advance to the next state
+ m_state = AWAITING_SOURCE_URL_ELEMENT_END;
+ break;
+
+ case AWAITING_TARGET_SERVICE_DATA:
+ // Consume the data
+ m_casaIdentToken.m_service = new String(ch, start, length);
+
+ // Advance to the next state
+ m_state = AWAITING_TARGET_SERVICE_ELEMENT_END;
+ break;
+
+ case AWAITING_TARGET_HOST_DATA:
+ // Consume the data
+ m_casaIdentToken.m_host = new String(ch, start, length);
+
+ // At this point we now have the target service and host names,
+ // check if our configuration says that the attributes have been
+ // encrypted.
+ m_encryptedAttrs = EncryptAttributes(m_service, m_host);
+
+ // Advance to the next state
+ m_state = AWAITING_TARGET_HOST_ELEMENT_END;
+ break;
+
+ case AWAITING_ATTRIBUTE_DATA:
+ // Consume the data
+ //
+ // Decrypt the attribute data if necessary
+ if (m_encryptedAttrs)
+ {
+ // tbd - Decrypt the attribute key and value with the private key of the service
+ // using the configured mechanism.
+ m_casaIdentToken.m_attributes.put(m_currAttribute, new String(ch, start, length));
+ }
+ else
+ {
+ m_casaIdentToken.m_attributes.put(m_currAttribute, new String(ch, start, length));
+ }
+
+ // Advance to the next state
+ m_state = AWAITING_ATTRIBUTE_END;
+ break;
+
+ default:
+ // Do nothing
+ break;
+ }
+ }
+ }
+
+ /*
+ * Constructor.
+ */
+ public CasaIdentityToken ()
+ {
+ // Initialize our members
+ m_token = null;
+ m_attributes = new javax.naming.directory.BasicAttributes();
+ }
+
+ /*
+ * Initialize with parameters.
+ */
+ public void initialize (
+ String identityId,
+ String sourceName,
+ String targetService,
+ String targetHost) throws Exception
+ {
+ // Save input parameters
+ m_identityId = identityId;
+ m_sourceName = sourceName;
+ m_sourceUrl = "ldap://jcserver.provo.novell.com:389"; // tbd - Obtain from config or Higgins
+ m_service = targetService;
+ m_host = targetHost;
+
+ try
+ {
+ // tbd - Read parameters from configuration and leverage Higgins.
+ //
+ // Open a directory context and use it to read the identity attributes.
+ Hashtable env = new Hashtable();
+ env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+ env.put(Context.PROVIDER_URL, "ldap://jcserver.provo.novell.com:389");
+ env.put(Context.SECURITY_AUTHENTICATION, "simple");
+ env.put(Context.SECURITY_PRINCIPAL, "cn=admin,o=novell");
+ env.put(Context.SECURITY_CREDENTIALS, "novell");
+
+ DirContext ctx = new InitialDirContext(env);
+
+ // Setup a string buffer for building the IdentityToken, notice for now
+ // we are not going to wrap the identity token.
+ StringBuffer sb = new StringBuffer();
+ sb.append(ProtoDefs.xmlDeclaration + "\r\n");
+ sb.append("<" + casaIdentTokElementName + ">" + "\r\n");
+ sb.append("<" + idElementName + ">" + identityId + "" + idElementName + ">\r\n");
+ sb.append("<" + sourceNameElementName + ">" + sourceName + "" + sourceNameElementName + ">\r\n");
+ sb.append("<" + sourceUrlElementName + ">" + m_sourceUrl + "" + sourceUrlElementName + ">\r\n");
+ sb.append("<" + targetServiceElementName + ">" + m_service + "" + targetServiceElementName + ">\r\n");
+ sb.append("<" + targetHostElementName + ">" + m_host + "" + targetHostElementName + ">\r\n");
+ sb.append("<" + attributesElementName + ">" + "\r\n");
+
+ // Get the necessary attributes of the specified services in the identity token
+ Set attributesNeeded = getAttributesNeededByService(m_service, m_host);
+ boolean encryptAttributes = EncryptAttributes(m_service, m_host);
+ Attributes attrs = ctx.getAttributes(identityId);
+ for (NamingEnumeration ae = attrs.getAll(); ae.hasMore();)
+ {
+ javax.naming.directory.Attribute attr = (javax.naming.directory.Attribute) ae.next();
+
+ // Append the attribute if it is one that we want.
+ // tbd - This needs to be customized on a per service basis.
+ if (attributesNeeded.contains(attr.getID()))
+ {
+ NamingEnumeration enumeration = attr.getAll();
+ while (enumeration.hasMore())
+ {
+ String attrValue = (String) enumeration.next();
+ m_attributes.put(attr.getID(), attrValue);
+
+ // Encrypt the attribute if necessary
+ if (encryptAttributes == true)
+ {
+ // tbd - Encrypt the attributes using the services public key, let the mechanism
+ // be configurable.
+ sb.append("<" + attr.getID() + ">" + attrValue + "" + attr.getID() + ">" + "\r\n");
+ }
+ else
+ {
+ sb.append("<" + attr.getID() + ">" + attrValue + "" + attr.getID() + ">" + "\r\n");
+ }
+ }
+ }
+ }
+ sb.append("" + attributesElementName + ">" + "\r\n");
+ sb.append("" + casaIdentTokElementName + ">" + "\r\n");
+
+ m_token = sb.toString();
+ }
+ catch (NamingException e)
+ {
+ // tbd - Log the event???
+ System.err.println("CasaIdentityToken.initialize()- Naming Exception on Proxy User: " + e.getExplanation());
+ }
+ catch (Exception e)
+ {
+ // tbd
+ System.err.println("CasaIdentityToken.initialize()- Exception: " + e.toString());
+ }
+ }
+
+ /*
+ * Initialize the token object with an ecoded token string.
+ */
+ public void initialize (String encodedToken) throws Exception
+ {
+ // Save copy of the token
+ m_token = Base64Coder.decode(encodedToken);
+
+ // Now parse the token into its elements
+ try
+ {
+ // Parse the AuthReqMsg
+ XMLReader xr = XMLReaderFactory.createXMLReader();
+ SAXHandler handler = new SAXHandler(this);
+ xr.setContentHandler(handler);
+ xr.setErrorHandler(handler);
+
+
+ ByteArrayInputStream inStream = new ByteArrayInputStream(m_token.getBytes());
+ InputSource source = new InputSource(inStream);
+ xr.parse(source);
+ }
+ catch (SAXException e)
+ {
+ // tbd - Log this.
+ System.err.println("CasaIdentityToken()- Parse exception: " + e.toString());
+ throw new Exception("Token error");
+ }
+ }
+
+ /*
+ * Return the attributes needed by the service.
+ */
+ private Set getAttributesNeededByService(String serviceName, String hostName)
+ {
+ // tbd - Read the following from configuration
+ HashSet attributesNeeded = new HashSet();
+ attributesNeeded.add("sn");
+ attributesNeeded.add("groupMembership");
+ attributesNeeded.add("securityEquals");
+ attributesNeeded.add("uid");
+ attributesNeeded.add("uidNumber");
+ attributesNeeded.add("gidNumber");
+
+ return attributesNeeded;
+ }
+
+ /*
+ * Return indication of whether or not the identity attributes must be encrypted.
+ */
+ private boolean EncryptAttributes(String serviceName, String hostName)
+ {
+ // tbd - Based return value based on the configuration for the service.
+ // Default is "false".
+ return false;
+ }
+
+ /*
+ * Returns encoded token string.
+ *
+ * IMPORTANT: The token string can not contain the substring "]]>"
+ * within it.
+ */
+ public String getEncodedToken() throws Exception
+ {
+ if (m_token != null)
+ {
+ return Base64Coder.encode(m_token);
+ }
+ else
+ {
+ System.err.println("CasaIdentityToken.toString()- Not initialized");
+ throw new Exception("Not initialized");
+ }
+ }
+
+ /*
+ * Returns a string containing our type of identity token provider.
+ */
+ public String getProviderType() throws Exception
+ {
+ // tbd - Change to a GUID
+ return "CasaIdentityToken";
+ }
+
+ /*
+ * Returns a string containing the identity id.
+ */
+ public String getIdentityId() throws Exception
+ {
+ if (m_identityId != null)
+ return m_identityId;
+ else
+ {
+ System.err.println("CasaIdentityToken.getIdentityId()- Not initialized");
+ throw new Exception("Not initialized");
+ }
+ }
+
+ /*
+ * Returns a string containing the name associated with the
+ * identity source.
+ */
+ public String getSourceName() throws Exception
+ {
+ if (m_sourceName != null)
+ return m_sourceName;
+ else
+ {
+ System.err.println("CasaIdentityToken.getSourceName()- Not initialized");
+ throw new Exception("Not initialized");
+ }
+ }
+
+ /*
+ * Returns a string containing the url associated with the
+ * identity source.
+ */
+ public String getSourceUrl() throws Exception
+ {
+ if (m_sourceUrl != null)
+ return m_sourceUrl;
+ else
+ {
+ System.err.println("CasaIdentityToken.getSourceUrl()- Not initialized");
+ throw new Exception("Not initialized");
+ }
+ }
+
+ /*
+ * Returns a string containing the name of the targeted service.
+ */
+ public String getTargetService() throws Exception
+ {
+ if (m_service != null)
+ return m_service;
+ else
+ {
+ System.err.println("CasaIdentityToken.getTargetService()- Not initialized");
+ throw new Exception("Not initialized");
+ }
+ }
+
+ /*
+ * Returns a string containig the name of the host where the
+ * targeted service resides.
+ */
+ public String getTargetHost() throws Exception
+ {
+ if (m_host != null)
+ return m_host;
+ else
+ {
+ System.err.println("CasaIdentityToken.getTargetHost()- Not initialized");
+ throw new Exception("Not initialized");
+ }
+ }
+
+ /*
+ * Returns the attributes of the identity.
+ */
+ public javax.naming.directory.Attributes getAttributes() throws Exception
+ {
+ if (m_attributes != null)
+ return m_attributes;
+ else
+ {
+ System.err.println("CasaIdentityToken.getIdentityAttributes()- Not initialized");
+ throw new Exception("Not initialized");
+ }
+ }
+}
diff --git a/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthPolicy.java b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthPolicy.java
new file mode 100644
index 00000000..6ee066d2
--- /dev/null
+++ b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthPolicy.java
@@ -0,0 +1,137 @@
+/***********************************************************************
+ *
+ * Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail,
+ * you may find current contact information at www.novell.com.
+ *
+ * Author: Juan Carlos Luciani
+ *
+ ***********************************************************************/
+
+package com.novell.casa.authserver;
+
+import java.io.*;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+
+/**
+ * GetAuthPolicy Servlet Class.
+ *
+ * This class processes authentication policy requests for a particular
+ * service.
+ *
+ */
+ public class GetAuthPolicy extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet
+ {
+ private static final long serialVersionUID = -8264027868130334613L;
+
+ /*
+ * Constructor.
+ */
+ public GetAuthPolicy()
+ {
+ super();
+ }
+
+ /*
+ * doGet() implementation.
+ */
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+
+ doPost(request, response);
+ }
+
+ /*
+ * doPost() implementation.
+ */
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ // Get ready to send back a reply
+ response.setContentType("text/html");
+ PrintWriter out = response.getWriter();
+
+ try
+ {
+ // Read and parse the GetAuthPolicyReqMsg sent from the client
+ InputStream inStream = request.getInputStream();
+ GetAuthPolicyReqMsg getAuthPolicyReqMsg = new GetAuthPolicyReqMsg(inStream);
+
+ // Get the auth policy for the service
+ byte[] authPolicy = getAuthPolicyFileData(getAuthPolicyReqMsg.getServiceName(),
+ getAuthPolicyReqMsg.getHostName());
+
+ // Write out the response
+ GetAuthPolicyRespMsg getAuthPolicyRespMsg = new GetAuthPolicyRespMsg(ProtoDefs.httpOkStatusMsg,
+ ProtoDefs.httpOkStatusCode,
+ new String(Base64Coder.encode(authPolicy)));
+ out.println(getAuthPolicyRespMsg.toString());
+ }
+ catch (Exception e)
+ {
+ // tbd
+ System.err.println("GetAuthPolicy.doPost()- Exception caught: " + e.toString());
+
+ // Write out the response
+ try
+ {
+ GetAuthPolicyRespMsg getAuthPolicyRespMsg = new GetAuthPolicyRespMsg(ProtoDefs.httpServerErrorStatusMsg,
+ ProtoDefs.httpServerErrorStatusCode);
+ out.println(getAuthPolicyRespMsg.toString());
+ }
+ catch (Exception e2)
+ {
+ System.err.println("GetAuthPolicy.doPost()- Exception trying to construct response msg: " + e2.toString());
+ }
+ }
+
+ // Done sending out the reply
+ out.close();
+ }
+
+ /*
+ * Returns the data associated with the authentication policy file
+ * associated with the specified service.
+ */
+ private byte[] getAuthPolicyFileData(String serviceName, String hostName)
+ {
+ // tdb - Read the file associated with the specified service
+ StringBuffer sb = new StringBuffer();
+
+ // Start building the policy data
+ sb.append(ProtoDefs.xmlDeclaration + "\r\n");
+ sb.append("<" + ProtoDefs.authPolicyElementName + ">" + "\r\n");
+ sb.append("<" + ProtoDefs.authSourceElementName + ">" + "\r\n");
+ sb.append("<" + ProtoDefs.realmElementName + ">" + "jctree" + "" + ProtoDefs.realmElementName + ">" + "\r\n");
+ sb.append("<" + ProtoDefs.mechanismElementName + ">" + "Krb5Authenticate" + "" + ProtoDefs.mechanismElementName + ">" + "\r\n");
+ sb.append("<" + ProtoDefs.mechanismInfoElementName + ">" + "host/jcstation.dnsdhcp.provo.novell.com" + "" + ProtoDefs.mechanismInfoElementName + ">" + "\r\n");
+ sb.append("" + ProtoDefs.authSourceElementName + ">" + "\r\n");
+ sb.append("<" + ProtoDefs.authSourceElementName + ">" + "\r\n");
+ sb.append("<" + ProtoDefs.realmElementName + ">" + "jctree" + "" + ProtoDefs.realmElementName + ">" + "\r\n");
+ sb.append("<" + ProtoDefs.mechanismElementName + ">" + "PwdAuthenticate" + "" + ProtoDefs.mechanismElementName + ">" + "\r\n");
+ sb.append("<" + ProtoDefs.mechanismInfoElementName + ">" + "" + "" + ProtoDefs.mechanismInfoElementName + ">" + "\r\n");
+ sb.append("" + ProtoDefs.authSourceElementName + ">" + "\r\n");
+ sb.append("" + ProtoDefs.authPolicyElementName + ">" + "\r\n");
+ String s = sb.toString();
+ return s.getBytes();
+ }
+ }
+
\ No newline at end of file
diff --git a/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthPolicyReqMsg.java b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthPolicyReqMsg.java
new file mode 100644
index 00000000..24014bf5
--- /dev/null
+++ b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthPolicyReqMsg.java
@@ -0,0 +1,278 @@
+/***********************************************************************
+ *
+ * Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail,
+ * you may find current contact information at www.novell.com.
+ *
+ * Author: Juan Carlos Luciani
+ *
+ ***********************************************************************/
+
+package com.novell.casa.authserver;
+
+import java.io.InputStream;
+
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+/**
+ * GetAuthPolicyReqMsg Class.
+ *
+ * This class deals with the message sent by Casa Client when requesting
+ * authenication policy to authenticate an entity to a particular service.
+ * The format of the the message is as follows:
+ *
+ *
+ *
+ * service name
+ * host name
+ *
+ *
+ */
+public class GetAuthPolicyReqMsg {
+
+ protected String m_serviceName = null;
+ protected String m_hostName = null;
+
+ /*
+ * Class for handling GetAuthPolicyReq msg parsing events.
+ */
+ private class SAXHandler extends org.xml.sax.helpers.DefaultHandler
+ {
+ private final static int AWAITING_ROOT_ELEMENT_START = 0;
+ private final static int AWAITING_ROOT_ELEMENT_END = 1;
+ private final static int AWAITING_SERVICE_ELEMENT_START = 2;
+ private final static int AWAITING_SERVICE_ELEMENT_END = 3;
+ private final static int AWAITING_SERVICE_DATA = 4;
+ private final static int AWAITING_HOST_ELEMENT_START = 5;
+ private final static int AWAITING_HOST_ELEMENT_END = 6;
+ private final static int AWAITING_HOST_DATA = 7;
+ private final static int DONE_PARSING = 8;
+
+ private GetAuthPolicyReqMsg m_GetAuthPolicyReqMsg;
+ private int m_state;
+
+ /*
+ * Constructor
+ */
+ public SAXHandler (GetAuthPolicyReqMsg GetAuthPolicyReqMsg)
+ {
+ super();
+
+ // Initialize our members
+ m_GetAuthPolicyReqMsg = GetAuthPolicyReqMsg;
+ m_state = AWAITING_ROOT_ELEMENT_START;
+ }
+
+ /*
+ * endDocument() implementation.
+ */
+ public void endDocument () throws SAXException
+ {
+ // Verify that we obtained all of the required elements
+ if (m_state != DONE_PARSING)
+ {
+ System.err.println("GetAuthPolicyReqMsg SAXHandler.endDocument()- Missing element");
+ throw new SAXException("Missing element");
+ }
+ }
+
+ /*
+ * startElement() implementation.
+ */
+ public void startElement (String uri, String name, String qName, org.xml.sax.Attributes atts) throws SAXException
+ {
+ // Proceed based on our state
+ switch (m_state) {
+
+ case AWAITING_ROOT_ELEMENT_START:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.getAuthPolicyRequestElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_SERVICE_ELEMENT_START;
+ }
+ else
+ {
+ System.err.println("GetAuthPolicyReqMsg SAXHandler.startElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_SERVICE_ELEMENT_START:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.serviceElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_SERVICE_DATA;
+ }
+ else
+ {
+ System.err.println("GetAuthPolicyReqMsg SAXHandler.startElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_HOST_ELEMENT_START:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.hostElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_HOST_DATA;
+ }
+ else
+ {
+ System.err.println("GetAuthPolicyReqMsg SAXHandler.startElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+
+ break;
+
+ default:
+ System.err.println("GetAuthPolicyReqMsg SAXHandler.startElement()- State error");
+ throw new SAXException("State error");
+ }
+ }
+
+ /*
+ * endElement() immplementation.
+ */
+ public void endElement (String uri, String name, String qName) throws SAXException
+ {
+ // Proceed based on our state
+ switch (m_state) {
+
+ case AWAITING_ROOT_ELEMENT_END:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.getAuthPolicyRequestElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = DONE_PARSING;
+ }
+ else
+ {
+ System.err.println("GetAuthPolicyReqMsg SAXHandler.endElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_SERVICE_ELEMENT_END:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.serviceElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_HOST_ELEMENT_START;
+ }
+ else
+ {
+ System.err.println("GetAuthPolicyReqMsg SAXHandler.endElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_HOST_ELEMENT_END:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.hostElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_ROOT_ELEMENT_END;
+ }
+ else
+ {
+ System.err.println("GetAuthPolicyReqMsg SAXHandler.endElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ default:
+ System.err.println("GetAuthPolicyReqMsg SAXHandler.startElement()- State error");
+ throw new SAXException("State error");
+ }
+ }
+
+ /*
+ * character() implementation.
+ */
+ public void characters (char ch[], int start, int length) throws SAXException
+ {
+ // Proceed based on our state
+ switch (m_state) {
+
+ case AWAITING_SERVICE_DATA:
+ // Consume the data
+ m_GetAuthPolicyReqMsg.m_serviceName = new String(ch, start, length);
+
+ // Advance to the next state
+ m_state = AWAITING_SERVICE_ELEMENT_END;
+ break;
+
+ case AWAITING_HOST_DATA:
+ // Consume the data
+ m_GetAuthPolicyReqMsg.m_hostName = new String(ch, start, length);
+
+ // Advance to the next state
+ m_state = AWAITING_HOST_ELEMENT_END;
+ break;
+
+ default:
+ // Do nothing
+ break;
+ }
+ }
+ }
+
+ /*
+ * Constructor
+ */
+ public GetAuthPolicyReqMsg (InputStream inStream) throws Exception
+ {
+ try
+ {
+ // Parse the GetAuthPolicyReqMsg
+ XMLReader xr = XMLReaderFactory.createXMLReader();
+ SAXHandler handler = new SAXHandler(this);
+ xr.setContentHandler(handler);
+ xr.setErrorHandler(handler);
+
+ InputSource source = new InputSource(inStream);
+ xr.parse(source);
+ }
+ catch (SAXException e)
+ {
+ System.err.println("GetAuthPolicyReqMsg()- Parse exception: " + e.toString());
+ throw new Exception("Protocol error");
+ }
+ }
+
+ /*
+ * Method to get the service name.
+ */
+ public String getServiceName() throws Exception
+ {
+ return m_serviceName;
+ }
+
+ /*
+ * Method to get the host name.
+ */
+ public String getHostName() throws Exception
+ {
+ return m_hostName;
+ }
+}
diff --git a/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthPolicyRespMsg.java b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthPolicyRespMsg.java
new file mode 100644
index 00000000..09b73688
--- /dev/null
+++ b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthPolicyRespMsg.java
@@ -0,0 +1,110 @@
+/***********************************************************************
+ *
+ * Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail,
+ * you may find current contact information at www.novell.com.
+ *
+ * Author: Juan Carlos Luciani
+ *
+ ***********************************************************************/
+
+package com.novell.casa.authserver;
+
+/**
+ * GetAuthPolicyRespMsg Class.
+ *
+ * This class deals with the message sent to the Casa Client as a
+ * response to a get authentication token request. The format of
+ * the message is as follows when the response includes an
+ * authentication token:
+ *
+ *
+ *
+ * OK200
+ * authentication policy data
+ *
+ *
+ * The format of the message is as follows when the response does not
+ * include an authentication token.
+ *
+ *
+ *
+ * status descriptionstatus code
+ *
+ *
+ * Plase note that the protocol utilizes the status codes defined
+ * in the HTTP 1.1 Specification.
+ *
+ */
+public class GetAuthPolicyRespMsg {
+
+ String m_msg;
+
+ /*
+ * Constructor for a msg that does not include the authentication policy.
+ */
+ public GetAuthPolicyRespMsg (
+ String statusDescription,
+ String statusCode) throws Exception
+ {
+ // Get a StringBuffer to help us with the construction of the message
+ StringBuffer sb = new StringBuffer();
+
+ // Start building the message
+ sb.append(ProtoDefs.xmlDeclaration + "\r\n");
+ sb.append("<" + ProtoDefs.getAuthPolicyResponseElementName + ">" + "\r\n");
+ sb.append("<" + ProtoDefs.statusElementName + ">"
+ + "<" + ProtoDefs.descriptionElementName + ">" + statusDescription + "" + ProtoDefs.descriptionElementName + ">"
+ + statusCode + "" + ProtoDefs.statusElementName + ">" + "\r\n");
+ sb.append("" + ProtoDefs.getAuthPolicyResponseElementName + ">" + "\r\n");
+
+ // The message has now been built, save it.
+ m_msg = sb.toString();
+ }
+
+ /*
+ * Constructor for a msg that includes the authentication policy.
+ */
+ public GetAuthPolicyRespMsg (
+ String statusDescription,
+ String statusCode,
+ String authPolicy) throws Exception
+ {
+ // Get a StringBuffer to help us with the construction of the message
+ StringBuffer sb = new StringBuffer();
+
+ // Start building the message
+ sb.append(ProtoDefs.xmlDeclaration + "\r\n");
+ sb.append("<" + ProtoDefs.getAuthPolicyResponseElementName + ">" + "\r\n");
+ sb.append("<" + ProtoDefs.statusElementName + ">"
+ + "<" + ProtoDefs.descriptionElementName + ">" + ProtoDefs.httpOkStatusMsg + "" + ProtoDefs.descriptionElementName + ">"
+ + ProtoDefs.httpOkStatusCode + "" + ProtoDefs.statusElementName + ">" + "\r\n");
+ sb.append("<" + ProtoDefs.authPolicyElementName + ">" + authPolicy + "" + ProtoDefs.authPolicyElementName + ">" + "\r\n");
+ sb.append("" + ProtoDefs.getAuthPolicyResponseElementName + ">" + "\r\n");
+
+ // The message has now been built, save it.
+ m_msg = sb.toString();
+ }
+
+ /*
+ * Returns a string containing the GetAuthPolicyRespMsg.
+ */
+ public String toString()
+ {
+ return m_msg;
+ }
+}
diff --git a/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthTokReqMsg.java b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthTokReqMsg.java
new file mode 100644
index 00000000..6991d02e
--- /dev/null
+++ b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthTokReqMsg.java
@@ -0,0 +1,327 @@
+/***********************************************************************
+ *
+ * Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail,
+ * you may find current contact information at www.novell.com.
+ *
+ * Author: Juan Carlos Luciani
+ *
+ ***********************************************************************/
+
+package com.novell.casa.authserver;
+
+import java.io.InputStream;
+
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+/**
+ * GetAuthTokReqMsg Class.
+ *
+ * This class deals with the message sent by Casa Client when requesting
+ * a token to authenticate an entity to a particular service. The format of
+ * the message is as follows:
+ *
+ *
+ *
+ * service name
+ * host name
+ * session token data
+ *
+ *
+ */
+public class GetAuthTokReqMsg {
+
+ protected String m_serviceName = null;
+ protected String m_hostName = null;
+ protected String m_sessionToken = null;
+
+ /*
+ * Class for handling GetAuthTokReq msg parsing events.
+ */
+ private class SAXHandler extends org.xml.sax.helpers.DefaultHandler
+ {
+ private final static int AWAITING_ROOT_ELEMENT_START = 0;
+ private final static int AWAITING_ROOT_ELEMENT_END = 1;
+ private final static int AWAITING_SERVICE_ELEMENT_START = 2;
+ private final static int AWAITING_SERVICE_ELEMENT_END = 3;
+ private final static int AWAITING_SERVICE_DATA = 4;
+ private final static int AWAITING_HOST_ELEMENT_START = 5;
+ private final static int AWAITING_HOST_ELEMENT_END = 6;
+ private final static int AWAITING_HOST_DATA = 7;
+ private final static int AWAITING_SESSION_TOKEN_ELEMENT_START = 8;
+ private final static int AWAITING_SESSION_TOKEN_ELEMENT_END = 9;
+ private final static int AWAITING_SESSION_TOKEN_DATA = 10;
+ private final static int DONE_PARSING = 11;
+
+ private GetAuthTokReqMsg m_GetAuthTokReqMsg;
+ private int m_state;
+
+ /*
+ * Constructor
+ */
+ public SAXHandler (GetAuthTokReqMsg GetAuthTokReqMsg)
+ {
+ super();
+
+ // Initialize our members
+ m_GetAuthTokReqMsg = GetAuthTokReqMsg;
+ m_state = AWAITING_ROOT_ELEMENT_START;
+ }
+
+ /*
+ * endDocument() implementation.
+ */
+ public void endDocument () throws SAXException
+ {
+ // Verify that we obtained all of the required elements
+ if (m_state != DONE_PARSING)
+ {
+ System.err.println("GetAuthTokReqMsg SAXHandler.endDocument()- Missing element");
+ throw new SAXException("Missing element");
+ }
+ }
+
+ /*
+ * startElement() implementation.
+ */
+ public void startElement (String uri, String name, String qName, org.xml.sax.Attributes atts) throws SAXException
+ {
+ // Proceed based on our state
+ switch (m_state) {
+
+ case AWAITING_ROOT_ELEMENT_START:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.getAuthTokRequestElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_SERVICE_ELEMENT_START;
+ }
+ else
+ {
+ System.err.println("GetAuthTokReqMsg SAXHandler.startElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_SERVICE_ELEMENT_START:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.serviceElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_SERVICE_DATA;
+ }
+ else
+ {
+ System.err.println("GetAuthTokReqMsg SAXHandler.startElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_HOST_ELEMENT_START:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.hostElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_HOST_DATA;
+ }
+ else
+ {
+ System.err.println("GetAuthTokReqMsg SAXHandler.startElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+
+ break;
+
+ case AWAITING_SESSION_TOKEN_ELEMENT_START:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.sessionTokenElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_SESSION_TOKEN_DATA;
+ }
+ else
+ {
+ System.err.println("GetAuthTokReqMsg SAXHandler.startElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ default:
+ System.err.println("GetAuthTokReqMsg SAXHandler.startElement()- State error");
+ throw new SAXException("State error");
+ }
+ }
+
+ /*
+ * endElement() immplementation.
+ */
+ public void endElement (String uri, String name, String qName) throws SAXException
+ {
+ // Proceed based on our state
+ switch (m_state) {
+
+ case AWAITING_ROOT_ELEMENT_END:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.getAuthTokRequestElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = DONE_PARSING;
+ }
+ else
+ {
+ System.err.println("GetAuthTokReqMsg SAXHandler.endElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_SERVICE_ELEMENT_END:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.serviceElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_HOST_ELEMENT_START;
+ }
+ else
+ {
+ System.err.println("GetAuthTokReqMsg SAXHandler.endElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_HOST_ELEMENT_END:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.hostElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_SESSION_TOKEN_ELEMENT_START;
+ }
+ else
+ {
+ System.err.println("GetAuthTokReqMsg SAXHandler.endElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_SESSION_TOKEN_ELEMENT_END:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.sessionTokenElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_ROOT_ELEMENT_END;
+ }
+ else
+ {
+ System.err.println("GetAuthTokReqMsg SAXHandler.endElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ default:
+ System.err.println("GetAuthTokReqMsg SAXHandler.startElement()- State error");
+ throw new SAXException("State error");
+ }
+ }
+
+ /*
+ * character() implementation.
+ */
+ public void characters (char ch[], int start, int length) throws SAXException
+ {
+ // Proceed based on our state
+ switch (m_state) {
+
+ case AWAITING_SERVICE_DATA:
+ // Consume the data
+ m_GetAuthTokReqMsg.m_serviceName = new String(ch, start, length);
+
+ // Advance to the next state
+ m_state = AWAITING_SERVICE_ELEMENT_END;
+ break;
+
+ case AWAITING_HOST_DATA:
+ // Consume the data
+ m_GetAuthTokReqMsg.m_hostName = new String(ch, start, length);
+
+ // Advance to the next state
+ m_state = AWAITING_HOST_ELEMENT_END;
+ break;
+
+ case AWAITING_SESSION_TOKEN_DATA:
+ // Consume the data
+ m_GetAuthTokReqMsg.m_sessionToken = new String(ch, start, length);
+
+ // Advance to the next state
+ m_state = AWAITING_SESSION_TOKEN_ELEMENT_END;
+ break;
+
+ default:
+ // Do nothing
+ break;
+ }
+ }
+ }
+
+ /*
+ * Constructor
+ */
+ public GetAuthTokReqMsg (InputStream inStream) throws Exception
+ {
+ try
+ {
+ // Parse the GetAuthTokReqMsg
+ XMLReader xr = XMLReaderFactory.createXMLReader();
+ SAXHandler handler = new SAXHandler(this);
+ xr.setContentHandler(handler);
+ xr.setErrorHandler(handler);
+
+ InputSource source = new InputSource(inStream);
+ xr.parse(source);
+ }
+ catch (SAXException e)
+ {
+ System.err.println("GetAuthTokReqMsg()- Parse exception: " + e.toString());
+ throw new Exception("Protocol error");
+ }
+ }
+
+ /*
+ * Method to get the service name.
+ */
+ public String getServiceName() throws Exception
+ {
+ return m_serviceName;
+ }
+
+ /*
+ * Method to get the host name.
+ */
+ public String getHostName() throws Exception
+ {
+ return m_hostName;
+ }
+
+ /*
+ * Method to get the session token.
+ */
+ public String getSessionToken() throws Exception
+ {
+ return m_sessionToken;
+ }
+}
diff --git a/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthTokRespMsg.java b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthTokRespMsg.java
new file mode 100644
index 00000000..da78e433
--- /dev/null
+++ b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthTokRespMsg.java
@@ -0,0 +1,114 @@
+/***********************************************************************
+ *
+ * Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail,
+ * you may find current contact information at www.novell.com.
+ *
+ * Author: Juan Carlos Luciani
+ *
+ ***********************************************************************/
+
+package com.novell.casa.authserver;
+
+/**
+ * GetAuthTokRespMsg Class.
+ *
+ * This class deals with the message sent to the Casa Client as a
+ * response to a get authentication token request. The format of
+ * the message is as follows when the response includes an
+ * authentication token:
+ *
+ *
+ *
+ * OK200
+ * lifetime valueauthentication token data
+ *
+ *
+ * The format of the message is as follows when the response does not
+ * include an authentication token.
+ *
+ *
+ *
+ * status descriptionstatus code
+ *
+ *
+ * Plase note that the protocol utilizes the status codes defined
+ * in the HTTP 1.1 Specification.
+ *
+ */
+public class GetAuthTokRespMsg {
+
+ String m_msg;
+
+ /*
+ * Constructor for a msg that does not include the authentication token.
+ */
+ public GetAuthTokRespMsg (
+ String statusDescription,
+ String statusCode) throws Exception
+ {
+ // Get a StringBuffer to help us with the construction of the message
+ StringBuffer sb = new StringBuffer();
+
+ // Start building the message
+ sb.append(ProtoDefs.xmlDeclaration + "\r\n");
+ sb.append("<" + ProtoDefs.getAuthTokResponseElementName + ">" + "\r\n");
+ sb.append("<" + ProtoDefs.statusElementName + ">"
+ + "<" + ProtoDefs.descriptionElementName + ">" + statusDescription + "" + ProtoDefs.descriptionElementName + ">"
+ + statusCode + "" + ProtoDefs.statusElementName + ">" + "\r\n");
+ sb.append("" + ProtoDefs.getAuthTokResponseElementName + ">" + "\r\n");
+
+ // The message has now been built, save it.
+ m_msg = sb.toString();
+ }
+
+ /*
+ * Constructor for a msg that includes the authentication token.
+ */
+ public GetAuthTokRespMsg (
+ String statusDescription,
+ String statusCode,
+ String authToken,
+ String authTokenLifetime) throws Exception
+ {
+ // Get a StringBuffer to help us with the construction of the message
+ StringBuffer sb = new StringBuffer();
+
+ // Start building the message
+ sb.append(ProtoDefs.xmlDeclaration + "\r\n");
+ sb.append("<" + ProtoDefs.getAuthTokResponseElementName + ">" + "\r\n");
+ sb.append("<" + ProtoDefs.statusElementName + ">"
+ + "<" + ProtoDefs.descriptionElementName + ">" + ProtoDefs.httpOkStatusMsg + "" + ProtoDefs.descriptionElementName + ">"
+ + ProtoDefs.httpOkStatusCode + "" + ProtoDefs.statusElementName + ">" + "\r\n");
+ sb.append("<" + ProtoDefs.authTokenElementName + ">"
+ + "<" + ProtoDefs.lifetimeElementName + ">" + authTokenLifetime + "" + ProtoDefs.lifetimeElementName + ">"
+ + authToken + "" + ProtoDefs.authTokenElementName + ">" + "\r\n");
+ sb.append("" + ProtoDefs.getAuthTokResponseElementName + ">" + "\r\n");
+
+ // The message has now been built, save it.
+ m_msg = sb.toString();
+ }
+
+ /*
+ * Returns a string containing the GetAuthTokRespMsg.
+ */
+ public String toString()
+ {
+ return m_msg;
+ }
+}
+
diff --git a/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthToken.java b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthToken.java
new file mode 100644
index 00000000..e9a59962
--- /dev/null
+++ b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/GetAuthToken.java
@@ -0,0 +1,135 @@
+/***********************************************************************
+ *
+ * Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail,
+ * you may find current contact information at www.novell.com.
+ *
+ * Author: Juan Carlos Luciani
+ *
+ ***********************************************************************/
+
+package com.novell.casa.authserver;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * GetAuthToken Servlet Class.
+ *
+ * This class processes requests for tokens to authenticate an entity
+ * to a particular service.
+ *
+ */
+ public class GetAuthToken extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet
+ {
+ private static final long serialVersionUID = -5792862615065914894L;
+
+ /*
+ * Constructor.
+ */
+ public GetAuthToken()
+ {
+ super();
+ }
+
+ /*
+ * doGet() implementation.
+ */
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ // Just let doPost() handle it.
+ doPost(request, response);
+ }
+
+ /*
+ * doPost() implementation.
+ */
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ // Get ready to send back a reply
+ response.setContentType("text/html");
+ PrintWriter out = response.getWriter();
+
+ try
+ {
+ // Read and parse the GetAuthTokReqMsg sent from the client
+ InputStream inStream = request.getInputStream();
+ GetAuthTokReqMsg getAuthTokReqMsg = new GetAuthTokReqMsg(inStream);
+
+ // Now create a session token (This validates the session token provided).
+ SessionToken sessionToken = new SessionToken(getAuthTokReqMsg.getSessionToken());
+
+ try
+ {
+ // Create the Authentication Token
+ AuthToken authToken = new AuthToken(sessionToken.getIdentId(),
+ sessionToken.getRealm(),
+ getAuthTokReqMsg.getServiceName(),
+ getAuthTokReqMsg.getHostName());
+
+ // Write out the response
+ GetAuthTokRespMsg getAuthTokRespMsg = new GetAuthTokRespMsg(ProtoDefs.httpOkStatusMsg,
+ ProtoDefs.httpOkStatusCode,
+ authToken.toString(),
+ authToken.getLifetime());
+ out.println(getAuthTokRespMsg.toString());
+ }
+ catch (Exception e)
+ {
+ // tbd, use a custom exception and then set the status based
+ // on the type of exeption cached.
+
+ // Write out the response
+ try
+ {
+ GetAuthTokRespMsg getAuthTokRespMsg = new GetAuthTokRespMsg(ProtoDefs.httpServerErrorStatusMsg,
+ ProtoDefs.httpUnauthorizedStatusCode);
+ out.println(getAuthTokRespMsg.toString());
+ }
+ catch (Exception e2)
+ {
+ System.err.println("GetAuthToken.doPost()- Exception trying to construct response msg: " + e2.toString());
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ // tbd
+ System.err.println("GetAuthToken.doPost()- Exception caught: " + e.toString());
+
+ // Write out the response
+ try
+ {
+ GetAuthTokRespMsg getAuthTokRespMsg = new GetAuthTokRespMsg(ProtoDefs.httpServerErrorStatusMsg,
+ ProtoDefs.httpServerErrorStatusCode);
+ out.println(getAuthTokRespMsg.toString());
+ }
+ catch (Exception e2)
+ {
+ System.err.println("GetAuthToken.doPost()- Exception trying to construct response msg: " + e2.toString());
+ }
+ }
+
+ // Done sending out the reply
+ out.close();
+ }
+}
\ No newline at end of file
diff --git a/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/IdentityToken.java b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/IdentityToken.java
new file mode 100644
index 00000000..e9c5d49b
--- /dev/null
+++ b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/IdentityToken.java
@@ -0,0 +1,93 @@
+/***********************************************************************
+ *
+ * Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail,
+ * you may find current contact information at www.novell.com.
+ *
+ * Author: Juan Carlos Luciani
+ *
+ ***********************************************************************/
+
+package com.novell.casa.authserver;
+
+/*
+ * IdentityTokenProvider Interface.
+ *
+ * This is the interface to Identity Token Providers.
+ */
+public interface IdentityToken {
+
+ /*
+ * Initialize the token with parameters.
+ */
+ void initialize (
+ String identityId,
+ String sourceName,
+ String targetService,
+ String targetHost) throws Exception;
+
+ /*
+ * Initialize the token object with encoded token string.
+ */
+ void initialize (String encodedToken) throws Exception;
+
+ /*
+ * Returns encoded token string.
+ *
+ * IMPORTANT: The token string can not contain the substring "]]>"
+ * within it.
+ */
+ String getEncodedToken() throws Exception;
+
+ /*
+ * Returns a string containing the identity token provider type.
+ */
+ String getProviderType() throws Exception;
+
+ /*
+ * Returns a string containing the identity id.
+ */
+ String getIdentityId() throws Exception;
+
+ /*
+ * Returns a string containing the name associated with the
+ * identity source.
+ */
+ String getSourceName() throws Exception;
+
+ /*
+ * Returns a string containing the url associated with the
+ * identity source.
+ */
+ String getSourceUrl() throws Exception;
+
+ /*
+ * Returns a string containing the name of the targeted service.
+ */
+ String getTargetService() throws Exception;
+
+ /*
+ * Returns a string containig the name of the host where the
+ * targeted service resides.
+ */
+ String getTargetHost() throws Exception;
+
+ /*
+ * Returns the attributes of the identity.
+ */
+ javax.naming.directory.Attributes getAttributes() throws Exception;
+}
diff --git a/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/Krb5Authenticate.java b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/Krb5Authenticate.java
new file mode 100644
index 00000000..c6dde7d8
--- /dev/null
+++ b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/Krb5Authenticate.java
@@ -0,0 +1,279 @@
+/***********************************************************************
+ *
+ * Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail,
+ * you may find current contact information at www.novell.com.
+ *
+ * Author: Juan Carlos Luciani
+ *
+ ***********************************************************************/
+
+package com.novell.casa.authserver;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.util.Hashtable;
+
+import javax.naming.Context;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.InitialDirContext;
+import javax.naming.directory.SearchResult;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSCredential;
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.GSSManager;
+import org.ietf.jgss.GSSName;
+import org.ietf.jgss.Oid;
+
+
+/**
+ * Krb5Authenticate Servlet Class.
+ *
+ * This class processes authentication requests utilizing a kerberos-V token.
+ *
+ */
+ public class Krb5Authenticate extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet
+ {
+ private static final long serialVersionUID = 7247746330553668339L;
+
+ /*
+ * tbd - This needs to be somewhere else so that the same parameter
+ * can be accessed by other authentication mechanisms.
+ *
+ * Configurable operating parameters
+ *
+ */
+ public String sessionTokenLifetime = "360";
+
+ /*
+ * GSS Long Lived variables
+ */
+ protected GSSManager m_manager;
+ protected Oid m_krb5;
+ protected GSSName m_svcName;
+ protected GSSCredential m_credential;
+
+ /*
+ * Krb5 Token Class.
+ */
+ private class Krb5Token
+ {
+ private String m_principalName = "";
+
+ /*
+ * The format of the Krb5 token is as follows:
+ *
+ * Base64.encode(GSS-API Token data));
+ */
+ public Krb5Token(String encodedToken, Krb5Authenticate parent) throws Exception
+ {
+ // Decode the token
+ char[] tokenChars = new char[encodedToken.length()];
+ encodedToken.getChars(0, tokenChars.length, tokenChars, 0);
+ byte[] tokenBytes = Base64Coder.decode(tokenChars);
+
+ try
+ {
+ // Create a context and validate the token
+ GSSContext context = parent.m_manager.createContext(parent.m_credential);
+ System.err.println("tokenLength = " + tokenBytes.length);
+ context.acceptSecContext(tokenBytes, 0, tokenBytes.length);
+
+ // Save the principal name of the authenticated entity
+ GSSName principalName = context.getSrcName();
+ m_principalName = principalName.toString();
+
+ // Clean up
+ context.dispose();
+ }
+ catch(GSSException e)
+ {
+ System.err.println("Krb5Authenticate Krb5Token()- GSS Exception caught: " + e.getLocalizedMessage());
+ throw new Exception("Authentication Failure");
+ }
+ }
+
+ /*
+ * Returns the name of the authenticated principal
+ */
+ public String getPrincipalName()
+ {
+ return m_principalName;
+ }
+ }
+
+ /*
+ * Constructor
+ */
+ public Krb5Authenticate() throws Exception
+ {
+ super();
+
+ try
+ {
+ // Initalize our GSS variables
+ //
+ // Get an instance of the default GSSManager
+ m_manager = GSSManager.getInstance();
+
+ // Create an OID specifying the Krb5 mechanism
+ m_krb5 = new Oid("1.2.840.113554.1.2.2");
+
+ // Create our host based service name
+ // tbd - obtain the service name from configuration
+ //GSSName svcName = manager.createName(ourServiceName, GSSName.NT_HOSTBASED_SERVICE, krb5);
+ m_svcName = m_manager.createName("host@jcstation.dnsdhcp.provo.novell.com",
+ GSSName.NT_HOSTBASED_SERVICE,
+ m_krb5);
+
+ // Now acquire our credentials
+ m_credential = m_manager.createCredential(m_svcName,
+ GSSCredential.INDEFINITE_LIFETIME,
+ m_krb5,
+ GSSCredential.ACCEPT_ONLY);
+ }
+ catch(GSSException e)
+ {
+ System.err.println("Krb5Authenticate()- GSS Exception caught: " + e.getLocalizedMessage());
+ throw new Exception("Failed to instantiate needed GSS objects");
+ }
+ }
+
+ /*
+ * doGet() implementation.
+ */
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ doPost(request, response);
+ }
+
+ /*
+ * doPost() implementation.
+ */
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ // Get ready to send back a reply
+ response.setContentType("text/html");
+ PrintWriter out = response.getWriter();
+
+ try
+ {
+ // Read and parse the AuthReqMsg sent from the client
+ InputStream inStream = request.getInputStream();
+ AuthReqMsg authReqMsg = new AuthReqMsg(inStream);
+
+ // Now parse the PW Token
+ Krb5Token krb5Token = new Krb5Token(authReqMsg.getAuthMechToken(), this);
+
+ // Open a directory context and use it to identify the users
+ // associated with the specified surname.
+ Hashtable env = new Hashtable();
+ env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+ env.put(Context.PROVIDER_URL, "ldap://jcserver.provo.novell.com:389");
+ env.put(Context.SECURITY_AUTHENTICATION, "simple");
+ env.put(Context.SECURITY_PRINCIPAL, "cn=admin,o=novell");
+ env.put(Context.SECURITY_CREDENTIALS, "novell");
+
+ DirContext ctx = new InitialDirContext(env);
+
+ // Now search for a user with a matching kerberos principal name
+ Attributes matchAttrs = new BasicAttributes(true); // ignore attribute name case
+ matchAttrs.put(new BasicAttribute("krbPrincipalName", krb5Token.getPrincipalName()));
+
+ NamingEnumeration answer = ctx.search("o=novell", matchAttrs);
+
+ // Proceed based on the result of the search
+ String identId = null;
+ if (answer.hasMore())
+ {
+ // The search succeeded, set the identity id.
+ SearchResult sr = (SearchResult)answer.next();
+ identId = sr.getName() + ",o=novell";
+ }
+
+ // Create response based on the identity resolution results
+ if (identId != null)
+ {
+ // An identity was resolved, get a SessionToken for it.
+ SessionToken sessionToken = new SessionToken(identId, authReqMsg.getRealm(), sessionTokenLifetime);
+
+ // Write out the response
+ AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpOkStatusMsg,
+ ProtoDefs.httpOkStatusCode,
+ sessionToken.toString(),
+ sessionTokenLifetime);
+ out.println(authRespMsg.toString());
+ }
+ else
+ {
+ // Write out the response
+ AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpUnauthorizedStatusMsg,
+ ProtoDefs.httpUnauthorizedStatusCode);
+ out.println(authRespMsg.toString());
+ }
+
+ }
+ catch (NamingException e)
+ {
+ // tbd
+ // Log the error
+ System.err.println("Krb5Authenticate.doPost()- Naming Exception on Proxy User: " + e.getExplanation());
+
+ // Write out the response
+ try
+ {
+ AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpServerErrorStatusMsg,
+ ProtoDefs.httpServerErrorStatusCode);
+ out.println(authRespMsg.toString());
+ }
+ catch (Exception e2)
+ {
+ System.err.println("Krb5Authenticate.doPost()- Exception trying to construct response msg: " + e2.toString());
+ }
+ }
+ catch (Exception e)
+ {
+ // tbd
+ System.err.println("Krb5Authenticate.doPost()- Exception caught: " + e.toString());
+
+ // Write out the response
+ try
+ {
+ AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpServerErrorStatusMsg,
+ ProtoDefs.httpServerErrorStatusCode);
+ out.println(authRespMsg.toString());
+ }
+ catch (Exception e2)
+ {
+ System.err.println("Krb5Authenticate.doPost()- Exception trying to construct response msg: " + e2.toString());
+ }
+ }
+
+ // Done sending out the reply
+ out.close();
+ }
+}
\ No newline at end of file
diff --git a/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/ProtoDefs.java b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/ProtoDefs.java
new file mode 100644
index 00000000..c5786e21
--- /dev/null
+++ b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/ProtoDefs.java
@@ -0,0 +1,83 @@
+/***********************************************************************
+ *
+ * Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail,
+ * you may find current contact information at www.novell.com.
+ *
+ * Author: Juan Carlos Luciani
+ *
+ ***********************************************************************/
+
+package com.novell.casa.authserver;
+
+/*
+ * ProDefs Class.
+ *
+ * This class contains constants utilized in the Casa Client/Server
+ * protocol.
+ *
+ */
+public class ProtoDefs {
+
+ /*
+ * XML Declaration used in the Casa Client/Server protocol
+ */
+ public final static String xmlDeclaration = "";
+
+ /*
+ * XML Element Name Constants for the documents exchanged between the
+ * Casa Client and the Casa Server.
+ */
+ public final static String authRequestElementName = "auth_req";
+ public final static String authResponseElementName = "auth_resp";
+ public final static String getAuthPolicyRequestElementName = "get_auth_policy_req";
+ public final static String getAuthPolicyResponseElementName = "get_auth_policy_resp";
+ public final static String getAuthTokRequestElementName = "get_auth_tok_req";
+ public final static String getAuthTokResponseElementName = "get_auth_tok_resp";
+ public final static String authMechTokenElementName = "auth_mech_token";
+ public final static String statusElementName = "status";
+ public final static String sessionTokenElementName = "session_token";
+ public final static String authTokenElementName = "auth_token";
+ public final static String authPolicyElementName = "auth_policy";
+ public final static String identTokenElementName = "ident_token";
+ public final static String lifetimeElementName = "lifetime";
+ public final static String signatureElementName = "signature";
+ public final static String typeElementName = "type";
+ public final static String descriptionElementName = "description";
+ public final static String serviceElementName = "service";
+ public final static String hostElementName = "host";
+ public final static String identIdElementName = "ident_id";
+ public final static String realmElementName = "realm";
+ public final static String authSourceElementName = "auth_source";
+ public final static String mechanismElementName = "mechanism";
+ public final static String mechanismInfoElementName = "mechanism_info";
+
+ /*
+ * Configurable operating parameters
+ */
+ public String sessionTokenLifetime = "360";
+
+ /*
+ * HTTP Status Codes and Messages
+ */
+ public final static String httpOkStatusCode = "200";
+ public final static String httpOkStatusMsg = "OK";
+ public final static String httpUnauthorizedStatusCode = "401";
+ public final static String httpUnauthorizedStatusMsg = "Unauthorized";
+ public final static String httpServerErrorStatusCode = "500";
+ public final static String httpServerErrorStatusMsg = "Internal Server Error";
+}
diff --git a/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/PwdAuthenticate.java b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/PwdAuthenticate.java
new file mode 100644
index 00000000..d0fa2c4f
--- /dev/null
+++ b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/PwdAuthenticate.java
@@ -0,0 +1,258 @@
+/***********************************************************************
+ *
+ * Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail,
+ * you may find current contact information at www.novell.com.
+ *
+ * Author: Juan Carlos Luciani
+ *
+ ***********************************************************************/
+
+package com.novell.casa.authserver;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.util.Hashtable;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import javax.naming.Context;
+import javax.naming.NamingEnumeration;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.InitialDirContext;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.SearchResult;
+import javax.naming.NamingException;
+
+
+/**
+ * PwdAuthenticate Servlet Class.
+ *
+ * This class processes authentication requests utilizing username and
+ * password materials.
+ *
+ */
+ public class PwdAuthenticate extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet
+ {
+
+ private static final long serialVersionUID = 3710685782114934264L;
+
+ /*
+ * tbd - This needs to be somewhere else so that the same parameter
+ * can be accessed by other authentication mechanisms.
+ *
+ * Configurable operating parameters
+ *
+ */
+ public String sessionTokenLifetime = "360";
+
+ /*
+ * Password Token Class.
+ */
+ private class PwToken
+ {
+ private String m_username = "";
+ private String m_password = "";
+
+ /*
+ * The format of the Pw token is as follows:
+ *
+ * Base64.encode(new String("username\r\n" + "password\r\n"));
+ */
+ public PwToken(String encodedToken) throws IOException
+ {
+ // Decode the token
+ String token = Base64Coder.decode(encodedToken);
+
+ BufferedReader tokenReader = new BufferedReader(new StringReader(token));
+
+ // The second line contains the "username"
+ m_username = tokenReader.readLine();
+
+ // The third line contains the "password"
+ m_password = tokenReader.readLine();
+ }
+
+ /*
+ * Returns the username
+ */
+ public String getUsername()
+ {
+ return m_username;
+ }
+
+ /*
+ * Returns the password
+ */
+ public String getPassword()
+ {
+ return m_password;
+ }
+ }
+
+ /*
+ * Constructor
+ */
+ public PwdAuthenticate()
+ {
+ super();
+ }
+
+ /*
+ * doGet() implementation.
+ */
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ // Just let doPost() handle it.
+ doPost(request, response);
+ }
+
+ /*
+ * doPost() implementation.
+ */
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ // Get ready to send back a reply
+ response.setContentType("text/html");
+ PrintWriter out = response.getWriter();
+
+ try
+ {
+ // Read and parse the AuthReqMsg sent from the client
+ InputStream inStream = request.getInputStream();
+ AuthReqMsg authReqMsg = new AuthReqMsg(inStream);
+
+ // Now parse the PW Token
+ PwToken pwToken = new PwToken(authReqMsg.getAuthMechToken());
+
+ // Open a directory context and use it to identify the users
+ // associated with the specified surname.
+ Hashtable env = new Hashtable();
+ env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+ env.put(Context.PROVIDER_URL, "ldap://jcserver.provo.novell.com:389");
+ env.put(Context.SECURITY_AUTHENTICATION, "simple");
+ env.put(Context.SECURITY_PRINCIPAL, "cn=admin,o=novell");
+ env.put(Context.SECURITY_CREDENTIALS, "novell");
+
+ DirContext ctx = new InitialDirContext(env);
+
+ // Now search for a user with a matching surname
+ Attributes matchAttrs = new BasicAttributes(true); // ignore attribute name case
+ matchAttrs.put(new BasicAttribute("cn", pwToken.getUsername()));
+
+ NamingEnumeration answer = ctx.search("o=novell", matchAttrs);
+
+ // Enumerate through the users returned checking the password
+ String identId = null;
+ while (answer.hasMore())
+ {
+ SearchResult sr = (SearchResult)answer.next();
+
+ System.err.println(sr.getName());
+
+ // Open a directory context for the user as a way of verifying its password
+ try
+ {
+ Hashtable env2 = new Hashtable();
+ env2.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+ env2.put(Context.PROVIDER_URL, "ldap://jcserver.provo.novell.com:389");
+ env2.put(Context.SECURITY_AUTHENTICATION, "simple");
+ env2.put(Context.SECURITY_PRINCIPAL, sr.getName() + ",o=novell");
+ env2.put(Context.SECURITY_CREDENTIALS, pwToken.getPassword());
+
+ if ((new InitialDirContext(env2)) != null)
+ {
+ // The password must be valid, set the identity Id.
+ identId = sr.getName() + ",o=novell";
+ break;
+ }
+ }
+ catch (NamingException e)
+ {
+ System.err.println("PwdAuthenticate.doPost()- Naming Exception: " + e.getExplanation());
+ }
+ }
+
+ // Create response based on the identity resolution results
+ if (identId != null)
+ {
+ // An identity was resolved, get a SessionToken for it.
+ SessionToken sessionToken = new SessionToken(identId, authReqMsg.getRealm(), sessionTokenLifetime);
+
+ // Write out the response
+ AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpOkStatusMsg,
+ ProtoDefs.httpOkStatusCode,
+ sessionToken.toString(),
+ sessionTokenLifetime);
+ out.println(authRespMsg.toString());
+ }
+ else
+ {
+ // Write out the response
+ AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpUnauthorizedStatusMsg,
+ ProtoDefs.httpUnauthorizedStatusCode);
+ out.println(authRespMsg.toString());
+ }
+
+ }
+ catch (NamingException e)
+ {
+ // tbd
+ // Log the error
+ System.err.println("PwdAuthenticate.doPost()- Naming Exception on Proxy User: " + e.getExplanation());
+
+ // Write out the response
+ try
+ {
+ AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpServerErrorStatusMsg,
+ ProtoDefs.httpServerErrorStatusCode);
+ out.println(authRespMsg.toString());
+ }
+ catch (Exception e2)
+ {
+ System.err.println("PwdAuthenticate.doPost()- Exception trying to construct response msg: " + e2.toString());
+ }
+ }
+ catch (Exception e)
+ {
+ // tbd
+ System.err.println("PwdAuthenticate.doPost()- Naming Exception on Proxy User: " + e.toString());
+
+ // Write out the response
+ try
+ {
+ AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpServerErrorStatusMsg,
+ ProtoDefs.httpServerErrorStatusCode);
+ out.println(authRespMsg.toString());
+ }
+ catch (Exception e2)
+ {
+ System.err.println("PwdAuthenticate.doPost()- Exception trying to construct response msg: " + e2.toString());
+ }
+ }
+
+ // Done sending out the reply
+ out.close();
+ }
+}
\ No newline at end of file
diff --git a/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/SessionToken.java b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/SessionToken.java
new file mode 100644
index 00000000..b570cdd4
--- /dev/null
+++ b/auth_token/server/CasaAuthServer/src/com/novell/casa/authserver/SessionToken.java
@@ -0,0 +1,412 @@
+/***********************************************************************
+ *
+ * Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail,
+ * you may find current contact information at www.novell.com.
+ *
+ * Author: Juan Carlos Luciani
+ *
+ ***********************************************************************/
+
+package com.novell.casa.authserver;
+
+import java.io.ByteArrayInputStream;
+
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+
+/*
+* SessionToken class.
+*
+* This class constructs session tokens that Casa clients can present to
+* the Casa server to prove that an entity has been authenticated to
+* a particular realm. The format of the session token is as follows:
+*
+*
+*
+* signature value
+* lifetime value
+* realm value
+* identity id value
+*
+*
+*/
+public class SessionToken {
+
+ private String m_id;
+ private String m_realm;
+ private String m_lifetime;
+ private String m_signature;
+ private String m_token;
+
+ /*
+ * Class for handling parsing events.
+ */
+ private class SAXHandler extends org.xml.sax.helpers.DefaultHandler
+ {
+ private final static int AWAITING_ROOT_ELEMENT_START = 0;
+ private final static int AWAITING_ROOT_ELEMENT_END = 1;
+ private final static int AWAITING_SIGNATURE_ELEMENT_START = 2;
+ private final static int AWAITING_SIGNATURE_ELEMENT_END = 3;
+ private final static int AWAITING_SIGNATURE_DATA = 4;
+ private final static int AWAITING_LIFETIME_ELEMENT_START = 5;
+ private final static int AWAITING_LIFETIME_ELEMENT_END = 6;
+ private final static int AWAITING_LIFETIME_DATA = 7;
+ private final static int AWAITING_REALM_ELEMENT_START = 8;
+ private final static int AWAITING_REALM_ELEMENT_END = 9;
+ private final static int AWAITING_REALM_DATA = 10;
+ private final static int AWAITING_IDENT_ID_ELEMENT_START = 11;
+ private final static int AWAITING_IDENT_ID_ELEMENT_END = 12;
+ private final static int AWAITING_IDENT_ID_DATA = 13;
+ private final static int DONE_PARSING = 14;
+
+ private SessionToken m_SessionToken;
+ private int m_state;
+
+ /*
+ * Constructor
+ */
+ public SAXHandler (SessionToken SessionToken)
+ {
+ super();
+
+ // Initialize our members
+ m_SessionToken = SessionToken;
+ m_state = AWAITING_ROOT_ELEMENT_START;
+ }
+
+ /*
+ * endDocument() implementation.
+ */
+ public void endDocument () throws SAXException
+ {
+ // Verify that we obtained all of the required elements
+ if (m_state != DONE_PARSING)
+ {
+ System.err.println("SessionToken SAXHandler.endDocument()- Missing element");
+ throw new SAXException("Missing element");
+ }
+ }
+
+ /*
+ * startElement() implementation.
+ */
+ public void startElement (String uri, String name, String qName, org.xml.sax.Attributes atts) throws SAXException
+ {
+ // Proceed based on our state
+ switch (m_state) {
+
+ case AWAITING_ROOT_ELEMENT_START:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.sessionTokenElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_SIGNATURE_ELEMENT_START;
+ }
+ else
+ {
+ System.err.println("SessionToken SAXHandler.startElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_SIGNATURE_ELEMENT_START:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.signatureElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_SIGNATURE_DATA;
+ }
+ else
+ {
+ System.err.println("SessionToken SAXHandler.startElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_LIFETIME_ELEMENT_START:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.lifetimeElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_LIFETIME_DATA;
+ }
+ else
+ {
+ System.err.println("SessionToken SAXHandler.startElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+
+ break;
+
+ case AWAITING_REALM_ELEMENT_START:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.realmElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_REALM_DATA;
+ }
+ else
+ {
+ System.err.println("SessionToken SAXHandler.startElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_IDENT_ID_ELEMENT_START:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.identIdElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_IDENT_ID_DATA;
+ }
+ else
+ {
+ System.err.println("SessionToken SAXHandler.startElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ default:
+ System.err.println("SessionToken SAXHandler.startElement()- State error");
+ throw new SAXException("State error");
+ }
+ }
+
+ /*
+ * endElement() immplementation.
+ */
+ public void endElement (String uri, String name, String qName) throws SAXException
+ {
+ // Proceed based on our state
+ switch (m_state) {
+
+ case AWAITING_ROOT_ELEMENT_END:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.sessionTokenElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = DONE_PARSING;
+ }
+ else
+ {
+ System.err.println("SessionToken SAXHandler.endElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_SIGNATURE_ELEMENT_END:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.signatureElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_LIFETIME_ELEMENT_START;
+ }
+ else
+ {
+ System.err.println("SessionToken SAXHandler.endElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_LIFETIME_ELEMENT_END:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.lifetimeElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_REALM_ELEMENT_START;
+ }
+ else
+ {
+ System.err.println("SessionToken SAXHandler.endElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_REALM_ELEMENT_END:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.realmElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_IDENT_ID_ELEMENT_START;
+ }
+ else
+ {
+ System.err.println("SessionToken SAXHandler.endElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ case AWAITING_IDENT_ID_ELEMENT_END:
+ // Verify that we are processing the expected tag
+ if (ProtoDefs.identIdElementName.equals(qName))
+ {
+ // Advance to the next state
+ m_state = AWAITING_ROOT_ELEMENT_END;
+ }
+ else
+ {
+ System.err.println("SessionToken SAXHandler.endElement()- Un-expected element");
+ throw new SAXException("Un-expected element");
+ }
+ break;
+
+ default:
+ System.err.println("SessionToken SAXHandler.startElement()- State error");
+ throw new SAXException("State error");
+ }
+ }
+
+ /*
+ * character() implementation.
+ */
+ public void characters (char ch[], int start, int length) throws SAXException
+ {
+ // Proceed based on our state
+ switch (m_state) {
+
+ case AWAITING_SIGNATURE_DATA:
+ // Consume the data
+ m_SessionToken.m_signature = new String(ch, start, length);
+
+ // Advance to the next state
+ m_state = AWAITING_SIGNATURE_ELEMENT_END;
+ break;
+
+ case AWAITING_LIFETIME_DATA:
+ // Consume the data
+ m_SessionToken.m_lifetime = new String(ch, start, length);
+
+ // Advance to the next state
+ m_state = AWAITING_LIFETIME_ELEMENT_END;
+ break;
+
+ case AWAITING_REALM_DATA:
+ // Consume the data
+ m_SessionToken.m_realm = new String(ch, start, length);
+
+ // Advance to the next state
+ m_state = AWAITING_REALM_ELEMENT_END;
+ break;
+
+ case AWAITING_IDENT_ID_DATA:
+ // Consume the data
+ m_SessionToken.m_id = new String(ch, start, length);
+
+ // Advance to the next state
+ m_state = AWAITING_IDENT_ID_ELEMENT_END;
+ break;
+
+ default:
+ // Do nothing
+ break;
+ }
+ }
+ }
+
+ /*
+ * Constructor
+ */
+ public SessionToken(String id, String realm, String lifetime) throws Exception
+ {
+ // Save copies of the input parameters
+ m_id = id;
+ m_realm = realm;
+ m_lifetime = lifetime;
+
+ // Generate a signature
+ // tbd - Over id, realm, and lifetime data.
+ m_signature = "tbd";
+
+ // Get a StringBuffer to help us with the construction of the token
+ StringBuffer sb = new StringBuffer();
+
+ // Start building the message
+ sb.append(ProtoDefs.xmlDeclaration + "\r\n");
+ sb.append("<" + ProtoDefs.sessionTokenElementName + ">" + "\r\n");
+ sb.append("<" + ProtoDefs.signatureElementName + ">" + m_signature + "" + ProtoDefs.signatureElementName + ">" + "\r\n");
+ sb.append("<" + ProtoDefs.lifetimeElementName + ">" + m_lifetime + "" + ProtoDefs.lifetimeElementName + ">" + "\r\n");
+ sb.append("<" + ProtoDefs.realmElementName + ">" + m_realm + "" + ProtoDefs.realmElementName + ">" + "\r\n");
+ sb.append("<" + ProtoDefs.identIdElementName + ">" + m_id + "" + ProtoDefs.identIdElementName + ">" + "\r\n");
+ sb.append("" + ProtoDefs.sessionTokenElementName + ">" + "\r\n");
+
+ // Save the token
+ m_token = sb.toString();
+ }
+
+ /*
+ * Constructor given a session token string. The constructor
+ * validates the token as part of its processing.
+ */
+ public SessionToken(String token) throws Exception
+ {
+ // Decode the token string
+ m_token = Base64Coder.decode(token);
+
+ // Now parse the token into its elements
+ try
+ {
+ // Parse the SessionToken
+ XMLReader xr = XMLReaderFactory.createXMLReader();
+ SAXHandler handler = new SAXHandler(this);
+ xr.setContentHandler(handler);
+ xr.setErrorHandler(handler);
+
+ ByteArrayInputStream inStream = new ByteArrayInputStream(m_token.getBytes());
+ InputSource source = new InputSource(inStream);
+ xr.parse(source);
+
+ // Verify the signature
+ // tbd
+
+ // Verify that the token has not expired
+ // tbd
+ }
+ catch (SAXException e)
+ {
+ System.err.println("SessionToken()- Parse exception: " + e.toString());
+ throw new Exception("Protocol error");
+ }
+ }
+
+ /*
+ * Returns a string containing the session token.
+ */
+ public String toString()
+ {
+ return Base64Coder.encode(m_token);
+ }
+
+ /*
+ * Method to get the Identity Id
+ */
+ public String getIdentId() throws Exception
+ {
+ return m_id;
+ }
+
+ /*
+ * Method to get the Identity Repository Reference (Realm).
+ */
+ public String getRealm() throws Exception
+ {
+ return m_realm;
+ }
+}
diff --git a/auth_token/server/CasaJaasSupport/.classpath b/auth_token/server/CasaJaasSupport/.classpath
new file mode 100644
index 00000000..60dd0413
--- /dev/null
+++ b/auth_token/server/CasaJaasSupport/.classpath
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/auth_token/server/CasaJaasSupport/.project b/auth_token/server/CasaJaasSupport/.project
new file mode 100644
index 00000000..cdeff8ac
--- /dev/null
+++ b/auth_token/server/CasaJaasSupport/.project
@@ -0,0 +1,17 @@
+
+
+ CasaJaasSupport
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/CasaLoginModule.java b/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/CasaLoginModule.java
new file mode 100644
index 00000000..7883d669
--- /dev/null
+++ b/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/CasaLoginModule.java
@@ -0,0 +1,256 @@
+/***********************************************************************
+ *
+ * Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail,
+ * you may find current contact information at www.novell.com.
+ *
+ * Author: Juan Carlos Luciani
+ *
+ ***********************************************************************/
+
+package com.novell.casa.jaas;
+
+import java.util.Map;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.login.FailedLoginException;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+
+import com.novell.casa.authserver.AuthToken;
+import com.novell.casa.authserver.CasaIdentityToken;
+
+/*
+ * CasaLoginModule Class.
+ *
+ * This class implements a LoginModule which performs
+ * authentication via the Casa Authentication Token
+ * infrastructure.
+ *
+ */
+public class CasaLoginModule implements LoginModule
+{
+ private final static String casaUsername = "CasaIdentityUser";
+
+ private Subject m_subject = null;
+ private CasaPrincipal m_principal = null;
+ private CallbackHandler m_callbackHandler = null;
+ private Map m_sharedState = null;
+ private Map m_options = null;
+
+ /*
+ * (non-Javadoc)
+ * @see javax.security.auth.spi.LoginModule#abort()
+ */
+ public boolean abort() throws LoginException
+ {
+ // Clear out all of our state
+ m_subject = null;
+ m_principal = null;
+ m_callbackHandler = null;
+ m_sharedState = null;
+ m_options = null;
+
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see javax.security.auth.spi.LoginModule#commit()
+ */
+ public boolean commit() throws LoginException
+ {
+ // Check if we instantiated a principal to associate
+ // with the subject.
+ if (m_principal != null)
+ {
+ try
+ {
+ // Add our principal to the set associated with
+ // the subject.
+ m_subject.getPrincipals().add(m_principal);
+ return true;
+ }
+ catch (Exception e)
+ {
+ System.err.println("CasaLoginModule.commit()- Exception caught associating principal, msg: " + e.getMessage());
+ throw new LoginException("Error encountered");
+ }
+ }
+ else
+ {
+ // Allways return since authentication failed or was not
+ // performed by us.
+ return false;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see javax.security.auth.spi.LoginModule#login()
+ */
+ public boolean login() throws LoginException
+ {
+ // Verify that a CallbackHandler was specified
+ if (m_callbackHandler == null)
+ {
+ System.err.println("CasaLoginModule.login()- Null CallbackHandler");
+ throw new LoginException("Null CallbackHandler");
+ }
+
+ // Perform the username check unless configured to skip it.
+ boolean skipUsernameCheck = false;
+ if (m_options != null
+ && m_options.containsKey((String) "skipUsernameCheck") == true)
+ {
+ String keyVal = (String) m_options.get("skipUsernameCheck");
+ if (keyVal == null || keyVal.equals("true"))
+ skipUsernameCheck = true;
+ }
+ if (!skipUsernameCheck)
+ {
+ // Verify that the username is CasaIdentityUser, for this
+ // we first need to obtain it.
+ //
+ // Try to obtain the user name from the shared state
+ String username = (String) m_sharedState.get("javax.security.auth.login.name");
+ if (username == null)
+ {
+ // The usename was not stored in the shared state, request it.
+ try
+ {
+ NameCallback nameCallback = new NameCallback("Enter username:");
+ Callback[] callbacks = new Callback[1];
+ callbacks[0] = nameCallback;
+ m_callbackHandler.handle(callbacks);
+ username = nameCallback.getName();
+ }
+ catch (Exception e)
+ {
+ System.err.println("CasaLoginModule.login()- Exception caught during nameCallback, msg: " + e.getMessage());
+ }
+
+ // Check the username
+ if (username == null)
+ return false;
+ else
+ {
+ // Save the retrieved username in the shared state and then check it.
+ m_sharedState.put("javax.security.auth.login.name" , username);
+ if (username.equals(casaUsername) == false)
+ return false;
+ }
+ }
+ else
+ {
+ // Check the username
+ if (username.equals(casaUsername) == false)
+ return false;
+ }
+ }
+
+ // Obtain the CasaAuthenticationToken
+ char[] authTokenChars = null;
+ try
+ {
+ PasswordCallback passwordCallback = new PasswordCallback("Enter CasaAuthenticationToken:", false);
+ Callback[] callbacks = new Callback[1];
+ callbacks[0] = passwordCallback;
+ m_callbackHandler.handle(callbacks);
+ authTokenChars = passwordCallback.getPassword();
+ }
+ catch (Exception e)
+ {
+ System.err.println("CasaLoginModule.login()- Exception caught during passwordCallback, msg: " + e.getMessage());
+ }
+
+ // Check the CasaAuthenticationToken
+ if (authTokenChars != null)
+ {
+ // Instantiate the AuthToken, this validates the token itself.
+ try
+ {
+ AuthToken authToken = new AuthToken(new String(authTokenChars));
+
+ // Instantiate the appropriate IdentityToken based on the IdentityTokenProvider type
+ // tbd - For now use the CasaIdentityToken
+ CasaIdentityToken identityToken = new CasaIdentityToken();
+ identityToken.initialize(authToken.getIdentityToken());
+
+ // Now instantiate the CasaPrincipal
+ m_principal = new CasaPrincipal(identityToken);
+ }
+ catch (Exception e)
+ {
+ // The validation of one of the tokens failed
+ // tbd - Log
+ System.err.println("CasaLoginModule.login()- Exception caught during token processing, msg: " + e.getMessage());
+ throw new FailedLoginException("Token validation failed");
+ }
+ }
+ else
+ {
+ // Token not provided
+ // tbd - Log
+ System.err.println("CasaLoginModule.login()- Token not provided");
+ throw new FailedLoginException("CasaAuthenticationToken not obtained");
+ }
+
+ // User validated
+ // tbd - Log
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see javax.security.auth.spi.LoginModule#logout()
+ */
+ public boolean logout() throws LoginException
+ {
+ // Check if we must try to remove our principal
+ // from the associated subject.
+ if (m_principal != null
+ && m_subject.isReadOnly() == false)
+ {
+ Set principalSet = m_subject.getPrincipals();
+ principalSet.remove(m_principal);
+ }
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see javax.security.auth.spi.LoginModule#initialize(javax.security.auth.Subject, javax.security.auth.callback.CallbackHandler, java.util.Map, java.util.Map)
+ */
+ public void initialize(
+ Subject subject,
+ CallbackHandler callbackHandler,
+ Map sharedState,
+ Map options)
+ {
+ // Save the input parameters for later use
+ m_subject = subject;
+ m_callbackHandler = callbackHandler;
+ m_sharedState = sharedState;
+ m_options = options;
+ }
+}
diff --git a/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/CasaPrincipal.java b/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/CasaPrincipal.java
new file mode 100644
index 00000000..1c74dea6
--- /dev/null
+++ b/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/CasaPrincipal.java
@@ -0,0 +1,86 @@
+/***********************************************************************
+ *
+ * Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail,
+ * you may find current contact information at www.novell.com.
+ *
+ ***********************************************************************/
+
+package com.novell.casa.jaas;
+
+import java.security.Principal;
+
+import com.novell.casa.authserver.IdentityToken;
+
+/*
+ * CasaPrincipal class.
+ *
+ * This class implements the principal class for
+ * identities authenticated by Casa.
+ *
+ */
+public class CasaPrincipal implements Principal
+{
+ private String m_name;
+ private String m_realm;
+ private String m_identStoreUrl;
+ private javax.naming.directory.Attributes m_attributes;
+
+ /*
+ * Constructor
+ */
+ public CasaPrincipal(IdentityToken identityToken) throws Exception
+ {
+ // Get the necessary information from the identity token
+ m_name = identityToken.getIdentityId();
+ m_realm = identityToken.getSourceName();
+ m_identStoreUrl = identityToken.getSourceUrl();
+ m_attributes = identityToken.getAttributes();
+ }
+ /*
+ * (non-Javadoc)
+ * @see java.security.Principal#getName()
+ */
+ public String getName()
+ {
+ return m_name;
+ }
+
+ /*
+ * Returns the name associated with the source of the identity data.
+ */
+ public String getRealm()
+ {
+ return m_realm;
+ }
+
+ /*
+ * Returns the url associated with the source of the identity data.
+ */
+ public String getIdentStoreUrl()
+ {
+ return m_identStoreUrl;
+ }
+
+ /*
+ * Returns the identity attributes.
+ */
+ public javax.naming.directory.Attributes getAttributes()
+ {
+ return m_attributes;
+ }
+}
diff --git a/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/SampleApp.conf b/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/SampleApp.conf
new file mode 100644
index 00000000..a1c76192
--- /dev/null
+++ b/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/SampleApp.conf
@@ -0,0 +1,3 @@
+SampleApp {
+ com.novell.casa.jaas.CasaLoginModule Required debug=true;
+};
\ No newline at end of file
diff --git a/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/SampleApp.java b/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/SampleApp.java
new file mode 100644
index 00000000..29e602ff
--- /dev/null
+++ b/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/SampleApp.java
@@ -0,0 +1,174 @@
+/***********************************************************************
+ *
+ * Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail,
+ * you may find current contact information at www.novell.com.
+ *
+ * Author: Juan Carlos Luciani
+ *
+ ***********************************************************************/
+
+package com.novell.casa.jaas;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.naming.NamingEnumeration;
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+
+
+/*
+ * This is a sample application which demonstrates the use of
+ * JAAS and Casa to authenticate a connection.
+ */
+public class SampleApp
+{
+ /**
+ * @param args
+ */
+ public static void main(String[] args)
+ {
+ Socket sock = null;
+ ServerSocket listenSock = null;
+
+ try
+ {
+ // Create a socket to listen for connections
+ int port = 4444;
+ int queueLen = 6;
+ listenSock = new ServerSocket(port, queueLen);
+
+ // Service connections
+ while (true)
+ {
+ BufferedReader in = null;
+ try
+ {
+ // Wait for the next connection
+ System.out.println("Waiting for connection");
+ sock = listenSock.accept();
+ System.out.println();
+ System.out.println("********Connection received*********");
+
+ // Get socket I/O streams
+ in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
+ //PrintStream out = new PrintStream(sock.getOutputStream());
+
+ // Get the authentication token from the client
+ String authToken = in.readLine();
+ //System.out.println("Token received from client, length = " + authToken.length());
+
+ // Authenticate the token and print out the information available to our service
+ // about the authenticated identity.
+
+ try
+ {
+ LoginContext lc = new LoginContext("SampleApp", new SampleAppCallbackHandler(authToken));
+ System.out.println("Authenticating the user");
+ lc.login();
+
+ System.out.println(" Authentication succeeded");
+
+ // Now get the subject associated with the context
+ Subject subject = lc.getSubject();
+
+ // Now get the CasaPrincipals that represent the authenticated
+ // identity or identities.
+ Set principalSet = subject.getPrincipals(CasaPrincipal.class);
+ //System.out.println("The number of CasaPrincipals is: " + principalSet.size());
+ Iterator principalIter = principalSet.iterator();
+ System.out.println();
+ System.out.println("Authenticated Identity Information");
+ System.out.println();
+ while (principalIter.hasNext() == true)
+ {
+ CasaPrincipal principal = (CasaPrincipal) principalIter.next();
+
+ // Print out information about the principal
+ System.out.println(" Source of the identity information: " + principal.getIdentStoreUrl());
+ System.out.println(" Realm name associated with identity source: " + principal.getRealm());
+ System.out.println(" Principal name (unique within identity source realm): " + principal.getName());
+ System.out.println();
+ System.out.println("Authenticated Identity Attributes");
+ System.out.println();
+ javax.naming.directory.Attributes attrs = principal.getAttributes();
+ for (NamingEnumeration ae = attrs.getAll(); ae.hasMore();)
+ {
+ javax.naming.directory.Attribute attr = (javax.naming.directory.Attribute) ae.next();
+
+ NamingEnumeration enumeration = attr.getAll();
+ while (enumeration.hasMore())
+ {
+ System.out.print(" Attribute Name: " + attr.getID());
+ System.out.println(" :: Attribute Value: " + (String) enumeration.next());
+ }
+ }
+ }
+ System.out.println();
+ }
+ catch (LoginException e)
+ {
+ System.out.println(" Authentication failed");
+ }
+ }
+ finally
+ {
+ if (sock != null)
+ {
+ sock.close();
+ sock = null;
+ }
+ if (in != null)
+ in.close();
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ System.out.println("IOException: " + e.getMessage());
+ }
+ catch (Exception e)
+ {
+ System.out.println("Exception: " + e.getMessage());
+ }
+ finally
+ {
+ try
+ {
+ if (sock != null)
+ {
+ sock.close();
+ }
+ if (listenSock != null)
+ {
+ listenSock.close();
+ }
+ }
+ catch (Exception e)
+ {
+ System.out.println("Exception: " + e.getMessage());
+ }
+ }
+ }
+}
diff --git a/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/SampleAppCallbackHandler.java b/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/SampleAppCallbackHandler.java
new file mode 100644
index 00000000..a8b1304e
--- /dev/null
+++ b/auth_token/server/CasaJaasSupport/src/com/novell/casa/jaas/SampleAppCallbackHandler.java
@@ -0,0 +1,71 @@
+/***********************************************************************
+ *
+ * Copyright (C) 2006 Novell, Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, Novell, Inc.
+ *
+ * To contact Novell about this file by physical or electronic mail,
+ * you may find current contact information at www.novell.com.
+ *
+ * Author: Juan Carlos Luciani
+ *
+ ***********************************************************************/
+
+package com.novell.casa.jaas;
+
+import java.io.IOException;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+
+public class SampleAppCallbackHandler implements CallbackHandler
+{
+ private String m_authToken;
+
+ /*
+ * Constructor
+ *
+ */
+ public SampleAppCallbackHandler(String authToken)
+ {
+ m_authToken = authToken;
+ }
+
+ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
+ {
+ for (int i = 0; i < callbacks.length; i++)
+ {
+ if (callbacks[i] instanceof NameCallback) {
+ NameCallback nc = (NameCallback) callbacks[i];
+ nc.setName("CasaIdentityUser");
+ } else if (callbacks[i] instanceof PasswordCallback) {
+ PasswordCallback pc = (PasswordCallback) callbacks[i];
+ //System.out.println("SampleAppCallbackHandler.handle()- Token length = " + m_authToken.length());
+ char[] allChars = m_authToken.toCharArray();
+
+ // Remove the null terminator
+ char[] tokenChars = new char[allChars.length - 1];
+ for (int ii = 0; ii < tokenChars.length; ii++)
+ tokenChars[ii] = allChars[ii];
+ pc.setPassword(tokenChars);
+ } else {
+ throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
+ }
+ }
+ }
+}