User: starksm
Date: 01/11/09 02:21:46
Modified: src/main/org/jboss/security Tag: Branch_2_4
ClientLoginModule.java Util.java
Log:
Cleanup formatting and logging
Revision Changes Path
No revision
No revision
1.1.4.1 +138 -124 jbosssx/src/main/org/jboss/security/ClientLoginModule.java
Index: ClientLoginModule.java
===================================================================
RCS file: /cvsroot/jboss/jbosssx/src/main/org/jboss/security/ClientLoginModule.java,v
retrieving revision 1.1
retrieving revision 1.1.4.1
diff -u -r1.1 -r1.1.4.1
--- ClientLoginModule.java 2001/03/05 09:53:26 1.1
+++ ClientLoginModule.java 2001/11/09 10:21:46 1.1.4.1
@@ -4,7 +4,7 @@
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
-
+
package org.jboss.security;
@@ -18,137 +18,151 @@
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
+import org.jboss.security.Logger;
+
/** A simple implementation of LoginModule for use by JBoss clients for
-the establishment of the caller identity and credentials. This simply sets
-the SecurityAssociation principal to the value of the NameCallback
-filled in by the CallbackHandler, and the SecurityAssociation credential
-to the value of the PasswordCallback filled in by the CallbackHandler.
-
-It has the following options:
-<ul>
-<li>multi-threaded=[true|false]
-When the multi-threaded option is set to true, the SecurityAssociation.setServer()
-so that each login thread has its own principal and credential storage.
-<li>password-stacking=tryFirstPass|useFirstPass
-When password-stacking option is set, this module first looks for a shared
-username and password using "javax.security.auth.login.name" and
-"javax.security.auth.login.password" respectively. This allows a module configured
-prior to this one to establish a valid username and password that should be passed
-to JBoss.
-</ul>
-
-@author <a href="mailto:[EMAIL PROTECTED]">Oleg Nitz</a>
-@author [EMAIL PROTECTED]
-*/
+ the establishment of the caller identity and credentials. This simply sets
+ the SecurityAssociation principal to the value of the NameCallback
+ filled in by the CallbackHandler, and the SecurityAssociation credential
+ to the value of the PasswordCallback filled in by the CallbackHandler.
+
+ It has the following options:
+ <ul>
+ <li>multi-threaded=[true|false]
+ When the multi-threaded option is set to true, the SecurityAssociation.setServer()
+ so that each login thread has its own principal and credential storage.
+ <li>password-stacking=tryFirstPass|useFirstPass
+ When password-stacking option is set, this module first looks for a shared
+ username and password using "javax.security.auth.login.name" and
+ "javax.security.auth.login.password" respectively. This allows a module configured
+ prior to this one to establish a valid username and password that should be passed
+ to JBoss.
+ </ul>
+
+ @author <a href="mailto:[EMAIL PROTECTED]">Oleg Nitz</a>
+ @author [EMAIL PROTECTED]
+ */
public class ClientLoginModule implements LoginModule
{
- private CallbackHandler _callbackHandler;
- /** Shared state between login modules */
- private Map _sharedState;
- /** Flag indicating if the shared password should be used */
- private boolean _useFirstPass;
-
- /**
- * Initialize this LoginModule.
- */
- public void initialize(Subject subject, CallbackHandler callbackHandler,
- Map sharedState, Map options)
- {
- this._callbackHandler = callbackHandler;
- this._sharedState = sharedState;
- // Check for multi-threaded option
- String mt = (String) options.get("multi-threaded");
- if( mt != null && Boolean.valueOf(mt).booleanValue() == true )
- { /* Turn on the server mode which uses thread local storage for
+ private CallbackHandler _callbackHandler;
+ /** Shared state between login modules */
+ private Map _sharedState;
+ /** Flag indicating if the shared password should be used */
+ private boolean _useFirstPass;
+ /** An interface into log4j */
+ private Logger log;
+
+ /**
+ * Initialize this LoginModule.
+ */
+ public void initialize(Subject subject, CallbackHandler callbackHandler,
+ Map sharedState, Map options)
+ {
+ this._callbackHandler = callbackHandler;
+ this._sharedState = sharedState;
+ // Check for multi-threaded option
+ String mt = (String) options.get("multi-threaded");
+ if( mt != null && Boolean.valueOf(mt).booleanValue() == true )
+ { /* Turn on the server mode which uses thread local storage for
the principal information.
- */
- SecurityAssociation.setServer();
- }
-
+ */
+ SecurityAssociation.setServer();
+ }
+
/* Check for password sharing options. Any non-null value for
password_stacking sets useFirstPass as this module has no way to
validate any shared password.
*/
- String passwordStacking = (String) options.get("password-stacking");
- _useFirstPass = passwordStacking != null;
- }
-
- /**
- * Method to authenticate a Subject (phase 1).
- */
- public boolean login() throws LoginException
- {
- // If useFirstPass is true, look for the shared password
- if( _useFirstPass == true )
- {
- try
- {
- String username = (String)
_sharedState.get("javax.security.auth.login.name");
- Object credential =
_sharedState.get("javax.security.auth.login.password");
- SecurityAssociation.setPrincipal(new SimplePrincipal(username));
- SecurityAssociation.setCredential(credential);
- return true;
- }
- catch(Exception e)
- { // Dump the exception and continue
- e.printStackTrace();
- }
- }
-
+ String passwordStacking = (String) options.get("password-stacking");
+ _useFirstPass = passwordStacking != null;
+ log = Logger.getInstance(getClass());
+ }
+
+ /**
+ * Method to authenticate a Subject (phase 1).
+ */
+ public boolean login() throws LoginException
+ {
+ // If useFirstPass is true, look for the shared password
+ if( _useFirstPass == true )
+ {
+ try
+ {
+ String username = (String)
_sharedState.get("javax.security.auth.login.name");
+ Object credential =
_sharedState.get("javax.security.auth.login.password");
+ SecurityAssociation.setPrincipal(new SimplePrincipal(username));
+ SecurityAssociation.setCredential(credential);
+ return true;
+ }
+ catch(Exception e)
+ { // Dump the exception and continue
+ log.warn("Failed to setup SecurityAssociation from sharedState", e);
+ }
+ }
+
/* There is no password sharing or we are the first login module. Get
the username and password from the callback hander.
- */
- if (_callbackHandler == null)
- throw new LoginException("Error: no CallbackHandler available " +
- "to garner authentication information from the user");
-
- PasswordCallback pc = new PasswordCallback("Password: ", false);
- NameCallback nc = new NameCallback("User name: ", "guest");
- Callback[] callbacks = {nc, pc};
- try {
- String username;
- char[] password = null;
- char[] tmpPassword;
-
- _callbackHandler.handle(callbacks);
- username = nc.getName();
- SecurityAssociation.setPrincipal(new SimplePrincipal(username));
- tmpPassword = pc.getPassword();
- if (tmpPassword != null) {
- password = new char[tmpPassword.length];
- System.arraycopy(tmpPassword, 0, password, 0, tmpPassword.length);
- pc.clearPassword();
- }
- SecurityAssociation.setCredential(password);
- } catch (java.io.IOException ioe) {
- throw new LoginException(ioe.toString());
- } catch (UnsupportedCallbackException uce) {
- throw new LoginException("Error: " + uce.getCallback().toString() +
- " not available to garner authentication information " +
- "from the user");
- }
- return true;
- }
-
- /**
- * Method to commit the authentication process (phase 2).
- */
- public boolean commit() throws LoginException {
- return true;
- }
-
- /**
- * Method to abort the authentication process (phase 2).
- */
- public boolean abort() throws LoginException {
- SecurityAssociation.setPrincipal(null);
- SecurityAssociation.setCredential(null);
- return true;
- }
-
- public boolean logout() throws LoginException {
- SecurityAssociation.setPrincipal(null);
- SecurityAssociation.setCredential(null);
- return true;
- }
+ */
+ if (_callbackHandler == null)
+ throw new LoginException("Error: no CallbackHandler available " +
+ "to garner authentication information from the user");
+
+ PasswordCallback pc = new PasswordCallback("Password: ", false);
+ NameCallback nc = new NameCallback("User name: ", "guest");
+ Callback[] callbacks = {nc, pc};
+ try
+ {
+ String username;
+ char[] password = null;
+ char[] tmpPassword;
+
+ _callbackHandler.handle(callbacks);
+ username = nc.getName();
+ SecurityAssociation.setPrincipal(new SimplePrincipal(username));
+ tmpPassword = pc.getPassword();
+ if (tmpPassword != null)
+ {
+ password = new char[tmpPassword.length];
+ System.arraycopy(tmpPassword, 0, password, 0, tmpPassword.length);
+ pc.clearPassword();
+ }
+ SecurityAssociation.setCredential(password);
+ }
+ catch (java.io.IOException ioe)
+ {
+ throw new LoginException(ioe.toString());
+ }
+ catch (UnsupportedCallbackException uce)
+ {
+ throw new LoginException("Error: " + uce.getCallback().toString() +
+ " not available to garner authentication information " +
+ "from the user");
+ }
+ return true;
+ }
+
+ /**
+ * Method to commit the authentication process (phase 2).
+ */
+ public boolean commit() throws LoginException
+ {
+ return true;
+ }
+
+ /**
+ * Method to abort the authentication process (phase 2).
+ */
+ public boolean abort() throws LoginException
+ {
+ SecurityAssociation.setPrincipal(null);
+ SecurityAssociation.setCredential(null);
+ return true;
+ }
+
+ public boolean logout() throws LoginException
+ {
+ SecurityAssociation.setPrincipal(null);
+ SecurityAssociation.setCredential(null);
+ return true;
+ }
}
1.1.4.1 +336 -316 jbosssx/src/main/org/jboss/security/Util.java
Index: Util.java
===================================================================
RCS file: /cvsroot/jboss/jbosssx/src/main/org/jboss/security/Util.java,v
retrieving revision 1.1
retrieving revision 1.1.4.1
diff -u -r1.1 -r1.1.4.1
--- Util.java 2001/03/05 09:53:28 1.1
+++ Util.java 2001/11/09 10:21:46 1.1.4.1
@@ -14,332 +14,352 @@
import java.util.Random;
/** Various security related utilities like MessageDigest
-factories, SecureRandom access,
-
-This product includes software developed by Tom Wu and Eugene
-Jhong for the SRP Distribution (http://srp.stanford.edu/srp/).
-
-@author [EMAIL PROTECTED]
-@version $Revision: 1.1 $
-*/
+ factories, SecureRandom access,
+
+ This product includes software developed by Tom Wu and Eugene
+ Jhong for the SRP Distribution (http://srp.stanford.edu/srp/).
+
+ @author [EMAIL PROTECTED]
+ @version $Revision: 1.1.4.1 $
+ */
public class Util
{
- private static final int HASH_LEN = 20;
- private static final char[] base64Table =
-
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./".toCharArray();
- private static SecureRandom psuedoRng;
- private static MessageDigest sha1Digest;
- private static boolean initialized;
-
- public static void init() throws NoSuchAlgorithmException
- {
- if( initialized )
- return;
- init(null);
- }
- public static void init(byte[] prngSeed) throws NoSuchAlgorithmException
- {
- // Get an instance of the SHA-1 digest
- sha1Digest = MessageDigest.getInstance("SHA");
- // Get a cryptographically strong pseudo-random generator
- psuedoRng = SecureRandom.getInstance("SHA1PRNG");
- if( prngSeed != null )
- psuedoRng.setSeed(prngSeed);
- initialized = true;
- }
-
- public static MessageDigest newDigest()
- {
- MessageDigest md = null;
- try
- {
- md = (MessageDigest) sha1Digest.clone();
- }
- catch(CloneNotSupportedException e)
- {
- }
- return md;
- }
- public static MessageDigest copy(MessageDigest md)
- {
- MessageDigest copy = null;
- try
- {
- copy = (MessageDigest) md.clone();
- }
- catch(CloneNotSupportedException e)
- {
- }
- return copy;
- }
-
- public static Random getPRNG()
- {
- return psuedoRng;
- }
- /** Returns the next pseudorandom, uniformly distributed double value
- between 0.0 and 1.0 from this random number generator's sequence.
+ private static final int HASH_LEN = 20;
+ private static final char[] base64Table =
+ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./".toCharArray();
+ private static SecureRandom psuedoRng;
+ private static MessageDigest sha1Digest;
+ private static boolean initialized;
+
+ public static void init() throws NoSuchAlgorithmException
+ {
+ if( initialized )
+ return;
+ init(null);
+ }
+ public static void init(byte[] prngSeed) throws NoSuchAlgorithmException
+ {
+ // Get an instance of the SHA-1 digest
+ sha1Digest = MessageDigest.getInstance("SHA");
+ // Get a cryptographically strong pseudo-random generator
+ psuedoRng = SecureRandom.getInstance("SHA1PRNG");
+ if( prngSeed != null )
+ psuedoRng.setSeed(prngSeed);
+ initialized = true;
+ }
+
+ public static MessageDigest newDigest()
+ {
+ MessageDigest md = null;
+ try
+ {
+ md = (MessageDigest) sha1Digest.clone();
+ }
+ catch(CloneNotSupportedException e)
+ {
+ }
+ return md;
+ }
+ public static MessageDigest copy(MessageDigest md)
+ {
+ MessageDigest copy = null;
+ try
+ {
+ copy = (MessageDigest) md.clone();
+ }
+ catch(CloneNotSupportedException e)
+ {
+ }
+ return copy;
+ }
+
+ public static Random getPRNG()
+ {
+ return psuedoRng;
+ }
+ /** Returns the next pseudorandom, uniformly distributed double value
+ between 0.0 and 1.0 from this random number generator's sequence.
*/
- public static double nextDouble()
- {
- return psuedoRng.nextDouble();
- }
- /** Returns the next pseudorandom, uniformly distributed long value from
- this random number generator's sequence. The general contract of
- nextLong is that one long value is pseudorandomly generated and
- returned. All 264 possible long values are produced with
- (approximately) equal probability.
- */
- public static long nextLong()
- {
- return psuedoRng.nextLong();
- }
- /** Generates random bytes and places them into a user-supplied byte
- array. The number of random bytes produced is equal to the length
- of the byte array.
- */
- public static void nextBytes(byte[] bytes)
- {
- psuedoRng.nextBytes(bytes);
- }
- /** Returns the given number of seed bytes, computed using the seed
- generation algorithm that this class uses to seed itself. This call
- may be used to seed other random number generators.
+ public static double nextDouble()
+ {
+ return psuedoRng.nextDouble();
+ }
+ /** Returns the next pseudorandom, uniformly distributed long value from
+ this random number generator's sequence. The general contract of
+ nextLong is that one long value is pseudorandomly generated and
+ returned. All 264 possible long values are produced with
+ (approximately) equal probability.
*/
- public static byte[] generateSeed(int numBytes)
- {
- return psuedoRng.generateSeed(numBytes);
- }
-
- public static byte[] calculatePasswordHash(String username, String password,
- byte[] salt, BigInteger N, BigInteger g)
- {
- // Calculate x = H(s | H(U | ':' | password))
- MessageDigest xd = newDigest();
- // Try to convert the username, password to a byte[] using UTF-8
- byte[] user = null;
- byte[] pass = null;
- try
- {
- user = username.getBytes("UTF-8");
- pass = password.getBytes("UTF-8");
- }
- catch(UnsupportedEncodingException e)
- {
- // Use the default platform encoding
- user = username.getBytes();
- pass = password.getBytes();
- }
- xd.update(user);
- xd.update(":".getBytes());
- xd.update(pass);
- byte[] h = xd.digest();
- xd.reset();
- xd.update(salt);
- xd.update(h);
- byte[] xb = xd.digest();
- // Calculate the password verfier v
- BigInteger x = new BigInteger(1, xb);
- return x.toByteArray();
- }
-
- /** Calculate x = H(s | H(U | ':' | password)) verifier
- described in RFC2945.
- */
- public static byte[] calculateVerifier(String username, String password,
- byte[] salt, byte[] Nb, byte[] gb)
- {
- BigInteger g = new BigInteger(1, gb);
- BigInteger N = new BigInteger(1, Nb);
- return calculateVerifier(username, password, salt, N, g);
- }
- /**
+ public static long nextLong()
+ {
+ return psuedoRng.nextLong();
+ }
+ /** Generates random bytes and places them into a user-supplied byte
+ array. The number of random bytes produced is equal to the length
+ of the byte array.
*/
- public static byte[] calculateVerifier(String username, String password,
- byte[] salt, BigInteger N, BigInteger g)
- {
- byte[] xb = calculatePasswordHash(username, password, salt, N, g);
- BigInteger x = new BigInteger(1, xb);
- BigInteger v = g.modPow(x, N);
- return v.toByteArray();
- }
-
- /** Perform an interleaved even-odd hash on the byte string
+ public static void nextBytes(byte[] bytes)
+ {
+ psuedoRng.nextBytes(bytes);
+ }
+ /** Returns the given number of seed bytes, computed using the seed
+ generation algorithm that this class uses to seed itself. This call
+ may be used to seed other random number generators.
*/
- public static byte[] sessionKeyHash(byte[] number)
- {
- int i, offset;
-
- for(offset = 0; offset < number.length && number[offset] == 0; ++offset)
- ;
-
- byte[] key = new byte[2 * HASH_LEN];
- byte[] hout;
-
- int klen = (number.length - offset) / 2;
- byte[] hbuf = new byte[klen];
-
- for(i = 0; i < klen; ++i)
- hbuf[i] = number[number.length - 2 * i - 1];
- hout = newDigest().digest(hbuf);
- for(i = 0; i < HASH_LEN; ++i)
- key[2 * i] = hout[i];
-
- for(i = 0; i < klen; ++i)
- hbuf[i] = number[number.length - 2 * i - 2];
- hout = newDigest().digest(hbuf);
- for(i = 0; i < HASH_LEN; ++i)
- key[2 * i + 1] = hout[i];
-
- return key;
- }
-
- /** Treat the input as the MSB representation of a number,
- and lop off leading zero elements. For efficiency, the
- input is simply returned if no leading zeroes are found.
- */
- public static byte[] trim(byte[] in)
- {
- if(in.length == 0 || in[0] != 0)
- return in;
-
- int len = in.length;
- int i = 1;
- while(in[i] == 0 && i < len)
- ++i;
- byte[] ret = new byte[len - i];
- System.arraycopy(in, i, ret, 0, len - i);
- return ret;
- }
-
- public static byte[] xor(byte[] b1, byte[] b2, int length)
- {
- byte[] result = new byte[length];
- for(int i = 0; i < length; ++i)
- result[i] = (byte) (b1[i] ^ b2[i]);
- return result;
- }
-
- // These functions assume that the byte array has MSB at 0, LSB at end.
- // Reverse the byte array (not the String) if this is not the case.
- // All base64 strings are in natural order, least significant digit last.
-
- public static String tob64(byte[] buffer) {
- boolean notleading = false;
- int len = buffer.length, pos = len % 3, c;
- byte b0 = 0, b1 = 0, b2 = 0;
- StringBuffer sb = new StringBuffer();
-
- switch(pos) {
- case 1:
- b2 = buffer[0];
- break;
- case 2:
- b1 = buffer[0];
- b2 = buffer[1];
- break;
- }
- do {
- c = (b0 & 0xfc) >>> 2;
- if(notleading || c != 0) {
- sb.append(base64Table[c]);
- notleading = true;
- }
- c = ((b0 & 3) << 4) | ((b1 & 0xf0) >>> 4);
- if(notleading || c != 0) {
- sb.append(base64Table[c]);
- notleading = true;
+ public static byte[] generateSeed(int numBytes)
+ {
+ return psuedoRng.generateSeed(numBytes);
+ }
+
+ public static byte[] calculatePasswordHash(String username, String password,
+ byte[] salt)
+ {
+ // Calculate x = H(s | H(U | ':' | password))
+ MessageDigest xd = newDigest();
+ // Try to convert the username, password to a byte[] using UTF-8
+ byte[] user = null;
+ byte[] pass = null;
+ try
+ {
+ user = username.getBytes("UTF-8");
+ pass = password.getBytes("UTF-8");
}
- c = ((b1 & 0xf) << 2) | ((b2 & 0xc0) >>> 6);
- if(notleading || c != 0) {
- sb.append(base64Table[c]);
- notleading = true;
+ catch(UnsupportedEncodingException e)
+ {
+ e.printStackTrace();
+ // Use the default platform encoding
+ user = username.getBytes();
+ pass = password.getBytes();
}
- c = b2 & 0x3f;
- if(notleading || c != 0) {
- sb.append(base64Table[c]);
- notleading = true;
+ xd.update(user);
+ xd.update(":".getBytes());
+ xd.update(pass);
+ byte[] h = xd.digest();
+ xd.reset();
+ xd.update(salt);
+ xd.update(h);
+ byte[] xb = xd.digest();
+ return xb;
+ }
+
+ /** Calculate x = H(s | H(U | ':' | password)) verifier
+ v = g^x % N
+ described in RFC2945.
+ */
+ public static byte[] calculateVerifier(String username, String password,
+ byte[] salt, byte[] Nb, byte[] gb)
+ {
+ BigInteger g = new BigInteger(1, gb);
+ BigInteger N = new BigInteger(1, Nb);
+ return calculateVerifier(username, password, salt, N, g);
+ }
+ /** Calculate x = H(s | H(U | ':' | password)) verifier
+ v = g^x % N
+ described in RFC2945.
+ */
+ public static byte[] calculateVerifier(String username, String password,
+ byte[] salt, BigInteger N, BigInteger g)
+ {
+ byte[] xb = calculatePasswordHash(username, password, salt);
+ BigInteger x = new BigInteger(1, xb);
+ BigInteger v = g.modPow(x, N);
+ return v.toByteArray();
+ }
+
+ /** Perform an interleaved even-odd hash on the byte string
+ */
+ public static byte[] sessionKeyHash(byte[] number)
+ {
+ int i, offset;
+
+ for(offset = 0; offset < number.length && number[offset] == 0; ++offset)
+ ;
+
+ byte[] key = new byte[2 * HASH_LEN];
+ byte[] hout;
+
+ int klen = (number.length - offset) / 2;
+ byte[] hbuf = new byte[klen];
+
+ for(i = 0; i < klen; ++i)
+ hbuf[i] = number[number.length - 2 * i - 1];
+ hout = newDigest().digest(hbuf);
+ for(i = 0; i < HASH_LEN; ++i)
+ key[2 * i] = hout[i];
+
+ for(i = 0; i < klen; ++i)
+ hbuf[i] = number[number.length - 2 * i - 2];
+ hout = newDigest().digest(hbuf);
+ for(i = 0; i < HASH_LEN; ++i)
+ key[2 * i + 1] = hout[i];
+
+ return key;
+ }
+
+ /** Treat the input as the MSB representation of a number,
+ and lop off leading zero elements. For efficiency, the
+ input is simply returned if no leading zeroes are found.
+ */
+ public static byte[] trim(byte[] in)
+ {
+ if(in.length == 0 || in[0] != 0)
+ return in;
+
+ int len = in.length;
+ int i = 1;
+ while(in[i] == 0 && i < len)
+ ++i;
+ byte[] ret = new byte[len - i];
+ System.arraycopy(in, i, ret, 0, len - i);
+ return ret;
+ }
+
+ public static byte[] xor(byte[] b1, byte[] b2, int length)
+ {
+ byte[] result = new byte[length];
+ for(int i = 0; i < length; ++i)
+ result[i] = (byte) (b1[i] ^ b2[i]);
+ return result;
+ }
+
+ // These functions assume that the byte array has MSB at 0, LSB at end.
+ // Reverse the byte array (not the String) if this is not the case.
+ // All base64 strings are in natural order, least significant digit last.
+
+ public static String tob64(byte[] buffer)
+ {
+ boolean notleading = false;
+ int len = buffer.length, pos = len % 3, c;
+ byte b0 = 0, b1 = 0, b2 = 0;
+ StringBuffer sb = new StringBuffer();
+
+ switch(pos)
+ {
+ case 1:
+ b2 = buffer[0];
+ break;
+ case 2:
+ b1 = buffer[0];
+ b2 = buffer[1];
+ break;
}
- if(pos >= len)
- break;
+ do
+ {
+ c = (b0 & 0xfc) >>> 2;
+ if(notleading || c != 0)
+ {
+ sb.append(base64Table[c]);
+ notleading = true;
+ }
+ c = ((b0 & 3) << 4) | ((b1 & 0xf0) >>> 4);
+ if(notleading || c != 0)
+ {
+ sb.append(base64Table[c]);
+ notleading = true;
+ }
+ c = ((b1 & 0xf) << 2) | ((b2 & 0xc0) >>> 6);
+ if(notleading || c != 0)
+ {
+ sb.append(base64Table[c]);
+ notleading = true;
+ }
+ c = b2 & 0x3f;
+ if(notleading || c != 0)
+ {
+ sb.append(base64Table[c]);
+ notleading = true;
+ }
+ if(pos >= len)
+ break;
+ else
+ try
+ {
+ b0 = buffer[pos++];
+ b1 = buffer[pos++];
+ b2 = buffer[pos++];
+ } catch(ArrayIndexOutOfBoundsException e)
+ { break; }
+ } while(true);
+
+ if(notleading)
+ return sb.toString();
else
- try {
- b0 = buffer[pos++];
- b1 = buffer[pos++];
- b2 = buffer[pos++];
- } catch(ArrayIndexOutOfBoundsException e) { break; }
- } while(true);
-
- if(notleading)
- return sb.toString();
- else
- return "0";
- }
-
- public static byte[] fromb64(String str) throws NumberFormatException {
- int len = str.length();
- if(len == 0)
- throw new NumberFormatException("Empty Base64 string");
-
- byte[] a = new byte[len + 1];
- char c;
- int i, j;
-
- for(i = 0; i < len; ++i) {
- c = str.charAt(i);
- try {
- for(j = 0; c != base64Table[j]; ++j)
- ;
- } catch(Exception e) {
- throw new NumberFormatException("Illegal Base64 character");
+ return "0";
+ }
+
+ public static byte[] fromb64(String str) throws NumberFormatException
+ {
+ int len = str.length();
+ if(len == 0)
+ throw new NumberFormatException("Empty Base64 string");
+
+ byte[] a = new byte[len + 1];
+ char c;
+ int i, j;
+
+ for(i = 0; i < len; ++i)
+ {
+ c = str.charAt(i);
+ try
+ {
+ for(j = 0; c != base64Table[j]; ++j)
+ ;
+ } catch(Exception e)
+ {
+ throw new NumberFormatException("Illegal Base64 character");
+ }
+ a[i] = (byte) j;
}
- a[i] = (byte) j;
- }
-
- i = len - 1;
- j = len;
- try {
- while(true) {
- a[j] = a[i];
- if(--i < 0)
- break;
- a[j] |= (a[i] & 3) << 6;
- --j;
- a[j] = (byte) ((a[i] & 0x3c) >>> 2);
- if(--i < 0)
- break;
- a[j] |= (a[i] & 0xf) << 4;
- --j;
- a[j] = (byte) ((a[i] & 0x30) >>> 4);
- if(--i < 0)
- break;
- a[j] |= (a[i] << 2);
-
- // Nasty, evil bug in Microsloth's Java interpreter under
- // Netscape: The following three lines of code are supposed
- // to be equivalent, but under the Windows NT VM (Netscape3.0)
- // using either of the two commented statements would cause
- // the zero to be placed in a[j] *before* decrementing j.
- // Weeeeird.
- a[j-1] = 0; --j;
- // a[--j] = 0;
- // --j; a[j] = 0;
-
- if(--i < 0)
- break;
+
+ i = len - 1;
+ j = len;
+ try
+ {
+ while(true)
+ {
+ a[j] = a[i];
+ if(--i < 0)
+ break;
+ a[j] |= (a[i] & 3) << 6;
+ --j;
+ a[j] = (byte) ((a[i] & 0x3c) >>> 2);
+ if(--i < 0)
+ break;
+ a[j] |= (a[i] & 0xf) << 4;
+ --j;
+ a[j] = (byte) ((a[i] & 0x30) >>> 4);
+ if(--i < 0)
+ break;
+ a[j] |= (a[i] << 2);
+
+ // Nasty, evil bug in Microsloth's Java interpreter under
+ // Netscape: The following three lines of code are supposed
+ // to be equivalent, but under the Windows NT VM (Netscape3.0)
+ // using either of the two commented statements would cause
+ // the zero to be placed in a[j] *before* decrementing j.
+ // Weeeeird.
+ a[j-1] = 0; --j;
+ // a[--j] = 0;
+ // --j; a[j] = 0;
+
+ if(--i < 0)
+ break;
+ }
+ } catch(Exception e)
+ {}
+
+ try
+ {
+ while(a[j] == 0)
+ ++j;
+ } catch(Exception e)
+ {
+ return new byte[1];
}
- } catch(Exception e) {}
-
- try {
- while(a[j] == 0)
- ++j;
- } catch(Exception e) {
- return new byte[1];
- }
-
- byte[] result = new byte[len - j + 1];
- System.arraycopy(a, j, result, 0, len - j + 1);
- return result;
- }
-
+
+ byte[] result = new byte[len - j + 1];
+ System.arraycopy(a, j, result, 0, len - j + 1);
+ return result;
+ }
+
}
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development