001: package org.jgroups.auth;
002:
003: import org.jgroups.util.Util;
004: import org.jgroups.util.HashUtils;
005: import org.jgroups.Message;
006:
007: import java.io.DataOutputStream;
008: import java.io.IOException;
009: import java.io.DataInputStream;
010: import java.util.HashMap;
011: import java.util.Properties;
012: import java.security.NoSuchAlgorithmException;
013: import java.security.MessageDigest;
014:
015: /**
016: * <p>
017: * This is an example of using a preshared token that is encrypted using an MD5/SHA hash for authentication purposes. All members of the group have to have the same string value in the JGroups config.
018: *</p>
019: * <p>
020: * Configuration parameters for this example are shown below:
021: * </p>
022: * <ul>
023: * <li>token_hash (required) = MD5(default)/SHA</li>
024: * <li>auth_value (required) = the string to encrypt</li>
025: * </ul>
026: * @see org.jgroups.auth.AuthToken
027: * @author Chris Mills
028: */
029: public class MD5Token extends AuthToken {
030:
031: public static final String TOKEN_ATTR = "auth_value";
032: public static final String TOKEN_TYPE = "token_hash";
033:
034: private String token = null;
035: private String hash_type = "MD5";
036:
037: public MD5Token() {
038: //need an empty constructor
039: }
040:
041: public MD5Token(String token) {
042: this .token = hash(token);
043: }
044:
045: public MD5Token(String token, String hash_type) {
046: this .token = hash(token);
047: this .hash_type = hash_type;
048: }
049:
050: public void setValue(Properties properties) {
051: this .token = hash((String) properties.get(MD5Token.TOKEN_ATTR));
052: properties.remove(MD5Token.TOKEN_ATTR);
053:
054: if (properties.containsKey(MD5Token.TOKEN_TYPE)) {
055: hash_type = (String) properties.get(MD5Token.TOKEN_TYPE);
056: properties.remove(MD5Token.TOKEN_TYPE);
057: }
058: }
059:
060: public String getName() {
061: return "org.jgroups.auth.MD5Token";
062: }
063:
064: /**
065: * Called during setup to hash the auth_value string in to an MD5/SHA hash
066: * @param token the string to hash
067: * @return the hashed version of the string
068: */
069: private String hash(String token) {
070: //perform the hashing of the token key
071: String hashedToken = null;
072:
073: if (hash_type.equalsIgnoreCase("SHA")) {
074: hashedToken = HashUtils.sha(token);
075: } else {
076: hashedToken = HashUtils.md5(token);
077: }
078:
079: if (hashedToken == null) {
080: //failed to encrypt
081: if (log.isWarnEnabled()) {
082: log
083: .warn("Failed to hash token - sending in clear text");
084: }
085: return token;
086: }
087: return hashedToken;
088: }
089:
090: public boolean authenticate(AuthToken token, Message msg) {
091:
092: if ((token != null) && (token instanceof MD5Token)) {
093: //Found a valid Token to authenticate against
094: MD5Token serverToken = (MD5Token) token;
095:
096: if ((this .token != null) && (serverToken.token != null)
097: && (this .token.equalsIgnoreCase(serverToken.token))) {
098: //validated
099: if (log.isDebugEnabled()) {
100: log.debug("MD5Token match");
101: }
102: return true;
103: } else {
104: if (log.isWarnEnabled()) {
105: log.warn("Authentication failed on MD5Token");
106: }
107: return false;
108: }
109: }
110:
111: if (log.isWarnEnabled()) {
112: log.warn("Invalid AuthToken instance - wrong type or null");
113: }
114: return false;
115: }
116:
117: public void writeTo(DataOutputStream out) throws IOException {
118: if (log.isDebugEnabled()) {
119: log.debug("MD5Token writeTo()");
120: }
121: Util.writeString(this .token, out);
122: }
123:
124: public void readFrom(DataInputStream in) throws IOException,
125: IllegalAccessException, InstantiationException {
126: if (log.isDebugEnabled()) {
127: log.debug("MD5Token readFrom()");
128: }
129: this.token = Util.readString(in);
130: }
131: }
|