/* Copyright 2005 The JA-SIG Collaborative. All rights reserved. * See license distributed with this file and * available online at http://www.uportal.org/license.html */ package org.jasig.portal.channels.cusermanager.provider; import java.io.*; import java.util.Date; import java.security.*; import org.jasig.portal.security.provider.AccountStoreFactory; /** *

A utility class that demonstrates changing and locking md5 passwords in * the UP_PERSON_DIR table. The program accepts two optional flags -c * causes the user to be created if he/she doesn't exist. The -l * flag causes the specified user's account to be locked.

* * copied from uportal package path to correct it for use * @author smb1@cornell.edu * @author Andrew Newman, newman@yale.edu (heavily modified by smb1@cornell.edu) * @version $Revision: 1.4 $ */ class Md5passwd { public static final String ACCOUNTLOCK = "*LCK*"; /** * Returns the MD5 encoded password. * @param ProposedPassword * @return * @throws IOException * @throws NoSuchAlgorithmException * @throws SQLException */ protected static String encode( String ProposedPassword ) throws IOException, NoSuchAlgorithmException { byte[] hash, rnd = new byte[8], fin = new byte[24]; Long date = new Long((new Date()).getTime()); SecureRandom r = new SecureRandom((date.toString()).getBytes()); MessageDigest md = MessageDigest.getInstance("MD5"); // Create a password for this user if( !ProposedPassword.equals( ACCOUNTLOCK )) { r.nextBytes(rnd); md.update(rnd); hash = md.digest( ProposedPassword.getBytes()); System.arraycopy(rnd, 0, fin, 0, 8); System.arraycopy(hash, 0, fin, 8, 16); }else fin = ACCOUNTLOCK.getBytes(); return "(MD5)" + encodeRaw(fin); }// Encode /** * Check entered password against stored password * @param uid * @param EnteredPassword * @return * @throws Exception */ protected static boolean verifyPassword( String uid, String EnteredPassword ) throws Exception { boolean isauth = false; try { String acct[] = AccountStoreFactory.getAccountStoreImpl().getUserAccountInformation( uid ); if( acct[0] != null && !acct[0].equals("")) { byte[] whole, salt = new byte[8], compare = new byte[16], dgx; whole = decode( acct[0].substring(5) ); if (whole.length == 24) { System.arraycopy(whole, 0, salt, 0, 8); System.arraycopy(whole, 8, compare, 0, 16); MessageDigest md = MessageDigest.getInstance("MD5"); md.update(salt); dgx = md.digest( EnteredPassword.getBytes() ); int i; for (i = 0; i < dgx.length; i++) { if (dgx[i] != compare[i]) { isauth = false; break; }//if isauth = true; }// for }// if, 24.length }// if !null } catch (Exception e) { throw (e); } return isauth; }// verifyPassword // // This was originally Jonathan B. Knudsen's Example from his book // Java Cryptography published by O'Reilly Associates (1st Edition 1998) // private static String encodeRaw(byte[] raw) { StringBuffer encoded = new StringBuffer(); for (int i = 0; i < raw.length; i += 3) { encoded.append(encodeBlock(raw, i)); } return encoded.toString(); } private static char[] encodeBlock(byte[] raw, int offset) { int block = 0; int slack = raw.length - offset - 1; int end = (slack >= 2) ? 2 : slack; for (int i = 0; i <= end; i++) { byte b = raw[offset + i]; int neuter = (b < 0) ? b + 256 : b; block += neuter << (8 * (2 - i)); } char[] base64 = new char[4]; for (int i = 0; i < 4; i++) { int sixbit = (block >>> (6 * (3 - i))) & 0x3f; base64[i] = getChar(sixbit); } if (slack < 1) base64[2] = '='; if (slack < 2) base64[3] = '='; return base64; } private static char getChar(int sixBit) { if (sixBit >= 0 && sixBit <= 25) return (char)('A' + sixBit); if (sixBit >= 26 && sixBit <= 51) return (char)('a' + (sixBit - 26)); if (sixBit >= 52 && sixBit <= 61) return (char)('0' + (sixBit - 52)); if (sixBit == 62) return '+'; if (sixBit == 63) return '/'; return '?'; } // // This was originally Jonathan B. Knudsen's Example from his book // Java Cryptography published by O'Reilly Associates (1st Edition 1998) // protected static byte[] decode(String base64) { int pad = 0; for (int i = base64.length() - 1; base64.charAt(i) == '='; i--) pad++; int length = base64.length()*6/8 - pad; byte[] raw = new byte[length]; int rawIndex = 0; for (int i = 0; i < base64.length(); i += 4) { int block = (getValue(base64.charAt(i)) << 18) + (getValue(base64.charAt(i + 1)) << 12) + (getValue(base64.charAt( i + 2)) << 6) + (getValue(base64.charAt(i + 3))); for (int j = 0; j < 3 && rawIndex + j < raw.length; j++) raw[rawIndex + j] = (byte)((block >> (8*(2 - j))) & 0xff); rawIndex += 3; } return raw; } protected static int getValue(char c) { if (c >= 'A' && c <= 'Z') return c - 'A'; if (c >= 'a' && c <= 'z') return c - 'a' + 26; if (c >= '0' && c <= '9') return c - '0' + 52; if (c == '+') return 62; if (c == '/') return 63; if (c == '=') return 0; return -1; } }// eoc