From 452fabac62eb764fe8590f1b1031342999a864c1 Mon Sep 17 00:00:00 2001 From: Juan Carlos Luciani Date: Wed, 24 May 2006 00:53:03 +0000 Subject: [PATCH] Changes to fix problems found while testing with the sample application. Also added a shell script to allow us to build and run the test application. --- auth_token/server/JaasSupport/TODO | 3 +- .../server/JaasSupport/make_and_run_test.sh | 17 + .../com/novell/casa/jaas/CasaLoginModule.java | 400 +++++++++--------- .../com/novell/casa/jaas/CasaPrincipal.java | 93 ++-- .../novell/casa/jaas/sample/SampleApp.conf | 2 +- .../novell/casa/jaas/sample/SampleApp.java | 251 +++++------ 6 files changed, 392 insertions(+), 374 deletions(-) create mode 100755 auth_token/server/JaasSupport/make_and_run_test.sh diff --git a/auth_token/server/JaasSupport/TODO b/auth_token/server/JaasSupport/TODO index dce480d7..87b7c803 100644 --- a/auth_token/server/JaasSupport/TODO +++ b/auth_token/server/JaasSupport/TODO @@ -10,5 +10,4 @@ This file contains a list of the items still outstanding for JaasSupport. OUTSTANDING ITEMS -- Change the username that the login module checks to be CasaPrincipal. -- Change the setting for checking usernames to be PerformUsernameCheck. +- Change printfs used for debugging into a suitable mechanism. diff --git a/auth_token/server/JaasSupport/make_and_run_test.sh b/auth_token/server/JaasSupport/make_and_run_test.sh new file mode 100755 index 00000000..5b1a233b --- /dev/null +++ b/auth_token/server/JaasSupport/make_and_run_test.sh @@ -0,0 +1,17 @@ +#!/bin/bash +if [ ! -d build-test ]; then + mkdir build-test + mkdir build-test/classes +else + if [ ! -d build-test/classes ]; then + mkdir build-test/classes + fi +fi +echo "*** Compiling the test application ***" +javac -sourcepath src -classpath ../../../lib/java/CasaJaasSupport.jar:../../../lib/java/CasaAuthToken.jar -d build-test/classes src/com/novell/casa/jaas/sample/SampleApp.java src/com/novell/casa/jaas/sample/SampleAppCallbackHandler.java +echo "*** Done compiling ***" +echo "" +echo "*** Starting the test application ***" +java -classpath build-test/classes:../../../lib/java/CasaJaasSupport.jar:../../../lib/java/CasaAuthToken.jar:/usr/share/java/xerces-j2.jar -Dorg.xml.sax.driver=org.apache.xerces.parsers.SAXParser -Djava.security.auth.login.config=src/com/novell/casa/jaas/sample/SampleApp.conf com.novell.casa.jaas.sample.SampleApp +#jdb -sourcepath src:../AuthTokenSvc/src -classpath build-test/classes:../../../lib/java/CasaJaasSupport.jar:../../../lib/java/CasaAuthToken.jar:/usr/share/java/xerces-j2.jar -Dorg.xml.sax.driver=org.apache.xerces.parsers.SAXParser -Djava.security.auth.login.config=src/com/novell/casa/jaas/sample/SampleApp.conf com.novell.casa.jaas.sample.SampleApp + diff --git a/auth_token/server/JaasSupport/src/com/novell/casa/jaas/CasaLoginModule.java b/auth_token/server/JaasSupport/src/com/novell/casa/jaas/CasaLoginModule.java index 9cbaf5eb..51db3a0d 100644 --- a/auth_token/server/JaasSupport/src/com/novell/casa/jaas/CasaLoginModule.java +++ b/auth_token/server/JaasSupport/src/com/novell/casa/jaas/CasaLoginModule.java @@ -49,209 +49,209 @@ import com.novell.casa.authtoksvc.CasaIdentityToken; */ 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; - } + 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#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"); - } - - // Do not perform the username check unless configured to do it. - boolean performUsernameCheck = false; - if (m_options != null - && m_options.containsKey((String) "performUsernameCheck") == true) - { - String keyVal = (String) m_options.get("performUsernameCheck"); - if (keyVal != null && keyVal.equals("true")) - performUsernameCheck = true; - } - - if (performUsernameCheck) - { - // 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"); - } + /* + * (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"); + } + + // Do not perform the username check unless configured to do it. + boolean performUsernameCheck = false; + if (m_options != null + && m_options.containsKey((String) "PerformUsernameCheck") == true) + { + String keyVal = (String) m_options.get("PerformUsernameCheck"); + if (keyVal != null && keyVal.equals("true")) + performUsernameCheck = true; + } + + if (performUsernameCheck) + { + // 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; - } + // 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#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; - } + /* + * (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/JaasSupport/src/com/novell/casa/jaas/CasaPrincipal.java b/auth_token/server/JaasSupport/src/com/novell/casa/jaas/CasaPrincipal.java index 7f3e35f8..ef97808e 100644 --- a/auth_token/server/JaasSupport/src/com/novell/casa/jaas/CasaPrincipal.java +++ b/auth_token/server/JaasSupport/src/com/novell/casa/jaas/CasaPrincipal.java @@ -35,52 +35,53 @@ import com.novell.casa.authtoksvc.IdentityToken; */ 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; - } + 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(); + } - /* - * Returns the url associated with the source of the identity data. - */ - public String getIdentStoreUrl() - { - return m_identStoreUrl; - } + /* + * (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 identity attributes. - */ - public javax.naming.directory.Attributes getAttributes() - { - return m_attributes; - } + /* + * 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/JaasSupport/src/com/novell/casa/jaas/sample/SampleApp.conf b/auth_token/server/JaasSupport/src/com/novell/casa/jaas/sample/SampleApp.conf index a1c76192..c2fb8fc9 100644 --- a/auth_token/server/JaasSupport/src/com/novell/casa/jaas/sample/SampleApp.conf +++ b/auth_token/server/JaasSupport/src/com/novell/casa/jaas/sample/SampleApp.conf @@ -1,3 +1,3 @@ -SampleApp { +testService { com.novell.casa.jaas.CasaLoginModule Required debug=true; }; \ No newline at end of file diff --git a/auth_token/server/JaasSupport/src/com/novell/casa/jaas/sample/SampleApp.java b/auth_token/server/JaasSupport/src/com/novell/casa/jaas/sample/SampleApp.java index 563cf098..7fd1a437 100644 --- a/auth_token/server/JaasSupport/src/com/novell/casa/jaas/sample/SampleApp.java +++ b/auth_token/server/JaasSupport/src/com/novell/casa/jaas/sample/SampleApp.java @@ -46,130 +46,131 @@ import com.novell.casa.jaas.CasaPrincipal; */ 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); + /** + * @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; + System.out.println("Listen port = " + port); + 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("testService", 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()); - } - } - } + // 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. + LoginContext lc = new LoginContext("testService", new SampleAppCallbackHandler(authToken)); + try + { + 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, LoginException: " + e.getMessage()); + } + } + 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()); + } + } + } }