haul 2003/01/17 03:31:55 Modified: src/java/org/apache/cocoon/components/modules/input DigestMetaModule.java Log: Additional encodings Revision Changes Path 1.12 +113 -20 xml-cocoon2/src/java/org/apache/cocoon/components/modules/input/DigestMetaModule.java Index: DigestMetaModule.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/modules/input/DigestMetaModule.java,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- DigestMetaModule.java 15 Jan 2003 15:55:13 -0000 1.11 +++ DigestMetaModule.java 17 Jan 2003 11:31:55 -0000 1.12 @@ -54,20 +54,26 @@ import org.apache.avalon.framework.configuration.ConfigurationException; import org.apache.avalon.framework.thread.ThreadSafe; +import org.apache.cocoon.util.HashMap; + import java.net.URLEncoder; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.util.Iterator; import java.util.Map; +import java.io.UnsupportedEncodingException; /** Meta module that obtains values from other module and returns * message digest of value. Very useful for storing and checking * passwords. Input module configured through nested element * "input-module", message digest algorithm, security provider, salt, - * and URL encoded output configurable through attributes - * "algorithm", "provider", "salt", "encode" of configuration root - * element. Defaults are "sha", null, "salt", and "false". + * and URL encoded output configurable through attributes "algorithm", + * "provider", "salt", "encode" of configuration root + * element. Defaults are "sha", null, "salt", and "false". Available + * value for encode are "none" (returns byte[]), "string" (return hash + * as string), "url" (returns url encoded string), "hex" (returns + * string of hex values). * * @author <a href="mailto:[EMAIL PROTECTED]">Christian Haul</a> * @version CVS $Id$ @@ -77,7 +83,31 @@ private String defaultAlgorithm = "SHA"; private String defaultProvider = null; private String defaultSalt = "salt"; - private boolean defaultEncode = false; + private String defaultEncode = "false"; + + /** output encoding none */ + static final int ENCODING_NONE = 0; + /** output encoding url encoding */ + static final int ENCODING_STR = 1; + /** output encoding hex */ + static final int ENCODING_URL = 2; + /** output encoding hex */ + static final int ENCODING_HEX = 3; + + private static final HashMap encodingNames; + /** setup mapping tables */ + static { + HashMap names = new HashMap(); + names.put("false", new Integer(ENCODING_NONE)); + names.put("no", new Integer(ENCODING_NONE)); + names.put("none", new Integer(ENCODING_NONE)); + names.put("string", new Integer(ENCODING_STR)); + names.put("yes", new Integer(ENCODING_URL)); + names.put("true", new Integer(ENCODING_URL)); + names.put("hex", new Integer(ENCODING_HEX)); + encodingNames = names; + names = null; + } public void configure(Configuration config) throws ConfigurationException { @@ -87,7 +117,12 @@ this.defaultAlgorithm = this.inputConf.getAttribute("algorithm",this.defaultAlgorithm); this.defaultProvider = this.inputConf.getAttribute("provider",this.defaultProvider); this.defaultSalt = this.inputConf.getAttribute("salt",this.defaultSalt); - this.defaultEncode = this.inputConf.getAttributeAsBoolean("encode",this.defaultEncode); + this.defaultEncode = this.inputConf.getAttribute("encode","false"); + if (this.encodingNames.get(this.defaultEncode) == null) { + if (getLogger().isErrorEnabled()) + getLogger().error("Requested encoding is unknown: "+this.defaultEncode); + this.defaultEncode="false"; + } } @@ -110,7 +145,7 @@ String algorithm = this.defaultAlgorithm; String provider = this.defaultProvider; String salt = this.defaultSalt; - boolean encode = this.defaultEncode; + int encode = ((Integer) encodingNames.get(this.defaultEncode)).intValue(); if (modeConf!=null) { inputName = modeConf.getChild("input-module").getAttribute("name",null); if (inputName != null) { @@ -120,7 +155,7 @@ algorithm = modeConf.getAttribute("algorithm", algorithm); provider = modeConf.getAttribute("provider" , provider ); salt = modeConf.getAttribute("salt" , salt ); - encode = modeConf.getAttributeAsBoolean("encode" , encode ); + encode = ((Integer) encodingNames.get(modeConf.getAttribute("encode" , this.defaultEncode))).intValue(); } @@ -137,11 +172,8 @@ MessageDigest.getInstance(algorithm,provider)); md.update((salt+(value instanceof String? (String)value : value.toString())).getBytes()); - if (encode) { - return URLEncoder.encode(new String(md.digest())); - } else { - return md.digest(); - } + return encodeByteArray(md.digest(),encode); + } catch (NoSuchAlgorithmException nsae) { if (getLogger().isWarnEnabled()) getLogger().warn("A problem occurred acquiring digest algorithm '" + algorithm @@ -212,7 +244,7 @@ String algorithm = this.defaultAlgorithm; String provider = this.defaultProvider; String salt = this.defaultSalt; - boolean encode = this.defaultEncode; + int encode = ((Integer) encodingNames.get(this.defaultEncode)).intValue(); if (modeConf!=null) { inputName = modeConf.getChild("input-module").getAttribute("name",null); if (inputName != null) { @@ -222,7 +254,7 @@ algorithm = modeConf.getAttribute("algorithm", algorithm); provider = modeConf.getAttribute("provider" , provider ); salt = modeConf.getAttribute("salt" , salt ); - encode = modeConf.getAttributeAsBoolean("encode" , encode ); + encode = ((Integer) encodingNames.get(modeConf.getAttribute("encode" , this.defaultEncode))).intValue(); } Object[] values = getValues(name, objectModel, @@ -239,11 +271,7 @@ for (int i=0; i<values.length; i++) { md.update((salt + (values[i] instanceof String? (String)values[i] : values[i].toString())).getBytes()); - if (encode) { - result[i] = URLEncoder.encode(new String(md.digest())); - } else { - result[i] = md.digest(); - } + result[i] = encodeByteArray(md.digest(), encode); } return result; } catch (NoSuchAlgorithmException nsae) { @@ -258,5 +286,70 @@ } return result; } + + + /** + * Create the output representation. + * @param b a <code>byte[]</code> + * @param encode an <code>int</code>, one of {@link ENCODING_NONE},{@link ENCODING_URL},{@link ENCODING_HEX} + * @return an <code>Object</code> + */ + Object encodeByteArray(byte[] b, int encode) { + Object result = null; + switch(encode) { + case ENCODING_HEX: + result = byte2Hex(b); + break; + case ENCODING_STR: + try { + result = new String(b, "UTF-8"); + } catch (UnsupportedEncodingException uee) { + if (getLogger().isErrorEnabled()) + getLogger().error("UTF-8 not supported -- cannot convert message digest to String."); + } + break; + case ENCODING_URL: + try { + String str = new String(b, "UTF-8"); + result = URLEncoder.encode(str); + } catch (UnsupportedEncodingException uee) { + if (getLogger().isErrorEnabled()) + getLogger().error("UTF-8 not supported -- cannot convert message digest to String."); + } + break; + case ENCODING_NONE: + // nothing to do + break; + default: + // should not happen + } + return result; + } + + /** + * Create a hex representation of a byte array. + * + * @param b a <code>byte[]</code> value + * @return a <code>String</code> value + */ + static String byte2Hex ( byte[] b ) { + StringBuffer sb = new StringBuffer( b.length * 2 ); + for ( int i=0 ; i < b.length ; i++ ) { + sb.append( hexChar [ ( b[i] & 0xf0 ) >>> 4 ] ) ; + sb.append( hexChar [ ( b[i] & 0x0f ) ] ) ; + } + return sb.toString() ; + } + + + /** + * hex digits lookup table + */ + static char[] hexChar = { + '0' , '1' , '2' , '3' , + '4' , '5' , '6' , '7' , + '8' , '9' , 'a' , 'b' , + 'c' , 'd' , 'e' , 'f' + }; }
---------------------------------------------------------------------- In case of troubles, e-mail: [EMAIL PROTECTED] To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]