/* See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * Esri Inc. licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.esri.gpt.framework.security.credentials; import com.esri.gpt.framework.util.Val; import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Random; import sun.misc.BASE64Encoder; /** * Stores username/password credentials. */ public class UsernamePasswordCredentials extends Credentials { // class variables ============================================================= private static Random RANDOM = new Random(System.currentTimeMillis()); // instance variables ========================================================== private String _confirmationPassword = ""; private String _distinguishedName = ""; private String _password = ""; private String _targetedGroupDN = ""; private String _username = ""; // constructors ================================================================ /** Default constructor. */ public UsernamePasswordCredentials() { super(); } /** * Constructs with a supplied username and password. * @param username the username * @param password the password */ public UsernamePasswordCredentials(String username, String password) { super(); setUsername(username); setPassword(password); } // properties ================================================================== /** * Gets the confirmation password. * <br/>A confirmation password is typically used when a someone is creating * a new, or modifying an existing password. They are asked to enter the * new password twice in an attempt to avoid a typographical error. * @return the confirmation password */ public String getConfirmationPassword() { return _confirmationPassword; } /** * Sets the confirmation password. * <br/>A confirmation password is typically used when a someone is creating * a new, or modifying an existing password. They are asked to enter the * new password twice in an attempt to avoid a typographical error. * @param password the confirmation password */ public void setConfirmationPassword(String password) { if (password == null) password = ""; _confirmationPassword = password; } /** * Gets the distinguished name for this user. * <br/>The distinguished name is typically used for an LDAP reference. * @return the distinguished name */ public String getDistinguishedName() { return _distinguishedName; } /** * Sets the distinguished name for this user. * <br/>The distinguished name is typically used for an LDAP reference. * <br/>The name is trimmed and stored in lower-case. * @param name the distinguished name */ public void setDistinguishedName(String name) { _distinguishedName = Val.chkStr(name).toLowerCase(); } /** * Gets the password. * @return the password */ public String getPassword() { return _password; } /** * Sets the password. * @param password the password */ public void setPassword(String password) { if (password == null) password = ""; _password = password; } /** * Gets the targeted group DN. * <br/>In some cases the user may wish to target a metadata management * group upon login. The convention is to supply the targeted group * name within the username as: myName@@someMetadataManagementGroupname * @return the targeted group DN */ public String getTargetedGroupDN() { return _targetedGroupDN; } /** * Sets the targeted group DN. * <br/>In some cases the user may wish to target a metadata management * group upon login. The convention is to supply the targeted group * name within the username as: myName@@someMetadataManagementGroupname * @param groupDN the targettd group DN */ public void setTargetedGroupDN(String groupDN) { _targetedGroupDN = Val.chkStr(groupDN).toLowerCase(); } /** * Gets the username. * @return the username */ public String getUsername() { return _username; } /** * Sets the username. * @param username the username */ public void setUsername(String username) { _username = Val.chkStr(username); } // methods ===================================================================== /** * Encrypts a password according to the algorithm specified. * @param algorithm the algorithm (SHA or MD5) * @return the encrypted password */ public String encryptLdapPassword(String algorithm) { String sEncrypted = _password; if ((_password != null) && (_password.length() > 0)) { algorithm = Val.chkStr(algorithm); boolean bMD5 = algorithm.equalsIgnoreCase("MD5"); boolean bSHA = algorithm.equalsIgnoreCase("SHA") || algorithm.equalsIgnoreCase("SHA1") || algorithm.equalsIgnoreCase("SHA-1"); if (bSHA || bMD5) { String sAlgorithm = "MD5"; if (bSHA) { sAlgorithm = "SHA"; } try { MessageDigest md = MessageDigest.getInstance(sAlgorithm); md.update(getPassword().getBytes("UTF-8")); sEncrypted = "{"+sAlgorithm+"}"+(new BASE64Encoder()).encode(md.digest()); } catch (NoSuchAlgorithmException e) { sEncrypted = null; e.printStackTrace(System.err); } catch (UnsupportedEncodingException e) { sEncrypted = null; e.printStackTrace(System.err); } } } return sEncrypted; } /** * Generates and sets random password. */ public void generatePassword() { int nAlpha = 0; String aAlpha[] = {"a","b","c","d","e","f","g","h","i","j","k","l","m", "n","o","p","q","r","s","t","u","v","w","x","y","z"}; String aSpecial[] = {"#","$","_","@"}; // generate a random digit string BigInteger iA = new BigInteger("3781927463263421"); BigInteger iC = new BigInteger("2113248654051873"); BigInteger iM = new BigInteger("10000000000000000"); String sStart = ""+RANDOM.nextLong(); BigInteger iS = new BigInteger(sStart); String sPwd = iS.multiply(iA).add(iC).mod(iM).toString(); // prefix with alpha characters to ensure 16 characters while(sPwd.length() < 16) { sPwd = aAlpha[nAlpha] + sPwd; nAlpha++; } // ensure a special character within the first seven characters int nSpecIdx = RANDOM.nextInt(aSpecial.length); int nSpecPIdx = RANDOM.nextInt(7); sPwd = sPwd.substring(0,nSpecPIdx) + aSpecial[nSpecIdx] + sPwd.substring(nSpecPIdx+1); // ensure an upper case alpha character int nAlphaIdx = RANDOM.nextInt(aAlpha.length); int nAlphaPIdx = RANDOM.nextInt(16); if (nAlphaPIdx == nSpecPIdx) { nAlphaPIdx++; } sPwd = sPwd.substring(0,nAlphaPIdx) + aAlpha[nAlphaIdx].toUpperCase() + sPwd.substring(nAlphaPIdx+1); // ensure that 3 characters in a row are not the same String aThree[] = {"","",""}; for (int i=0;i<sPwd.length();i++) { aThree[2] = aThree[1]; aThree[1] = aThree[0]; aThree[0] = ""+sPwd.charAt(i); if (aThree[0].equalsIgnoreCase(aThree[1]) && aThree[0].equalsIgnoreCase(aThree[2])) { aThree[0] = aAlpha[nAlpha]; sPwd = sPwd.substring(0,i) + aThree[0] + sPwd.substring(i+1); nAlpha++; } } setPassword(sPwd); } }