📄 passwordfile.java
字号:
/* PasswordFile.java -- Copyright (C) 2003, 2006 Free Software Foundation, Inc.This file is a part of GNU Classpath.GNU Classpath is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or (atyour option) any later version.GNU Classpath is distributed in the hope that it will be useful, butWITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNUGeneral Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Classpath; if not, write to the Free SoftwareFoundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301USALinking this library statically or dynamically with other modules ismaking a combined work based on this library. Thus, the terms andconditions of the GNU General Public License cover the wholecombination.As a special exception, the copyright holders of this library give youpermission to link this library with independent modules to produce anexecutable, regardless of the license terms of these independentmodules, and to copy and distribute the resulting executable underterms of your choice, provided that you also meet, for each linkedindependent module, the terms and conditions of the license of thatmodule. An independent module is a module which is not derived fromor based on this library. If you modify this library, you may extendthis exception to your version of the library, but you are notobligated to do so. If you do not wish to do so, delete thisexception statement from your version. */package gnu.javax.crypto.sasl.srp;import gnu.java.security.Registry;import gnu.java.security.hash.IMessageDigest;import gnu.java.security.util.Util;import gnu.javax.crypto.key.srp6.SRPAlgorithm;import gnu.javax.crypto.sasl.NoSuchUserException;import gnu.javax.crypto.sasl.UserAlreadyExistsException;import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.InputStream;import java.io.InputStreamReader;import java.io.IOException;import java.io.PrintWriter;import java.io.UnsupportedEncodingException;import java.math.BigInteger;import java.util.HashMap;import java.util.Iterator;import java.util.NoSuchElementException;import java.util.StringTokenizer;/** * <p>The implementation of SRP password files.</p> * * <p>For SRP, there are three (3) files: * <ol> * <li>The password configuration file: tpasswd.conf. It contains the pairs * <N,g> indexed by a number for each pair used for a user. By default, * this file's pathname is constructed from the base password file pathname * by prepending it with the ".conf" suffix.</li> * * <li>The base password file: tpasswd. It contains the related password * entries for all the users with values computed using SRP's default * message digest algorithm: SHA-1 (with 160-bit output block size).</li> * * <li>The extended password file: tpasswd2. Its name, by default, is * constructed by adding the suffix "2" to the fully qualified pathname of * the base password file. It contains, in addition to the same fields as * the base password file, albeit with a different verifier value, an extra * field identifying the message digest algorithm used to compute this * (verifier) value.</li> * </ol></p> * * <p>This implementation assumes the following message digest algorithm codes: * <ul> * <li>0: the default hash algorithm, which is SHA-1 (or its alias SHA-160).</li> * <li>1: MD5.</li> * <li>2: RIPEMD-128.</li> * <li>3: RIPEMD-160.</li> * <li>4: SHA-256.</li> * <li>5: SHA-384.</li> * <li>6: SHA-512.</li> * </ul></p> * * <p><b>IMPORTANT:</b> This method computes the verifiers as described in * RFC-2945, which differs from the description given on the web page for * SRP-6.</p> * * <p>Reference:</p> * <ol> * <li><a href="http://srp.stanford.edu/design.html">SRP Protocol Design</a><br> * Thomas J. Wu.</li> * </ol> */public class PasswordFile{ // Constants and variables // ------------------------------------------------------------------------- // names of property keys used in this class private static final String USER_FIELD = "user"; private static final String VERIFIERS_FIELD = "verifier"; private static final String SALT_FIELD = "salt"; private static final String CONFIG_FIELD = "config"; private static String DEFAULT_FILE; static { DEFAULT_FILE = System.getProperty(SRPRegistry.PASSWORD_FILE, SRPRegistry.DEFAULT_PASSWORD_FILE); } /** The SRP algorithm instances used by this object. */ private static final HashMap srps; static { final HashMap map = new HashMap(SRPRegistry.SRP_ALGORITHMS.length); // The first entry MUST exist. The others are optional. map.put("0", SRP.instance(SRPRegistry.SRP_ALGORITHMS[0])); for (int i = 1; i < SRPRegistry.SRP_ALGORITHMS.length; i++) { try { map.put(String.valueOf(i), SRP.instance(SRPRegistry.SRP_ALGORITHMS[i])); } catch (Exception x) { System.err.println("Ignored: " + x); x.printStackTrace(System.err); } } srps = map; } private String confName, pwName, pw2Name; private File configFile, passwdFile, passwd2File; private long lastmodPasswdFile, lastmodPasswd2File; private HashMap entries = new HashMap(); private HashMap configurations = new HashMap(); // default N values to use when creating a new password.conf file private static final BigInteger[] Nsrp = new BigInteger[] { SRPAlgorithm.N_2048, SRPAlgorithm.N_1536, SRPAlgorithm.N_1280, SRPAlgorithm.N_1024, SRPAlgorithm.N_768, SRPAlgorithm.N_640, SRPAlgorithm.N_512 }; // Constructor(s) // ------------------------------------------------------------------------- public PasswordFile() throws IOException { this(DEFAULT_FILE); } public PasswordFile(final File pwFile) throws IOException { this(pwFile.getAbsolutePath()); } public PasswordFile(final String pwName) throws IOException { this(pwName, pwName + "2", pwName + ".conf"); } public PasswordFile(final String pwName, final String confName) throws IOException { this(pwName, pwName + "2", confName); } public PasswordFile(final String pwName, final String pw2Name, final String confName) throws IOException { super(); this.pwName = pwName; this.pw2Name = pw2Name; this.confName = confName; readOrCreateConf(); update(); } // Class methods // ------------------------------------------------------------------------- /** * <p>Returns a string representing the decimal value of an integer * identifying the message digest algorithm to use for the SRP computations. * </p> * * @param mdName the canonical name of a message digest algorithm. * @return a string representing the decimal value of an ID for that * algorithm. */ private static final String nameToID(final String mdName) { if (Registry.SHA_HASH.equalsIgnoreCase(mdName) || Registry.SHA1_HASH.equalsIgnoreCase(mdName) || Registry.SHA160_HASH.equalsIgnoreCase(mdName)) { return "0"; } else if (Registry.MD5_HASH.equalsIgnoreCase(mdName)) { return "1"; } else if (Registry.RIPEMD128_HASH.equalsIgnoreCase(mdName)) { return "2"; } else if (Registry.RIPEMD160_HASH.equalsIgnoreCase(mdName)) { return "3"; } else if (Registry.SHA256_HASH.equalsIgnoreCase(mdName)) { return "4"; } else if (Registry.SHA384_HASH.equalsIgnoreCase(mdName)) { return "5"; } else if (Registry.SHA512_HASH.equalsIgnoreCase(mdName)) { return "6"; } return "0"; } // SRP password configuration file methods --------------------------------- /** * <p>Checks if the current configuration file contains the <N, g> pair * for the designated <code>index</code>.</p> * * @param index a string representing 1-digit identification of an <N, g> * pair used. * @return <code>true</code> if the designated <code>index</code> is that of * a known <N, g> pair, and <code>false</code> otherwise. * @throws IOException if an exception occurs during the process. * @see SRPRegistry#N_2048_BITS * @see SRPRegistry#N_1536_BITS * @see SRPRegistry#N_1280_BITS * @see SRPRegistry#N_1024_BITS * @see SRPRegistry#N_768_BITS * @see SRPRegistry#N_640_BITS * @see SRPRegistry#N_512_BITS */ public synchronized boolean containsConfig(final String index) throws IOException { checkCurrent(); return configurations.containsKey(index); } /** * <p>Returns a pair of strings representing the pair of <code>N</code> and * <code>g</code> MPIs for the designated <code>index</code>.</p> * * @param index a string representing 1-digit identification of an <N, g> * pair to look up. * @return a pair of strings, arranged in an array, where the first (at index * position #0) is the repesentation of the MPI <code>N</code>, and the * second (at index position #1) is the representation of the MPI * <code>g</code>. If the <code>index</code> refers to an unknown pair, then * an empty string array is returned. * @throws IOException if an exception occurs during the process. */ public synchronized String[] lookupConfig(final String index) throws IOException { checkCurrent(); String[] result = null; if (configurations.containsKey(index)) { result = (String[]) configurations.get(index); } return result; } // SRP base and extended password configuration files methods -------------- public synchronized boolean contains(final String user) throws IOException { checkCurrent(); return entries.containsKey(user); } public synchronized void add(final String user, final String passwd, final byte[] salt, final String index) throws IOException { checkCurrent(); if (entries.containsKey(user)) { throw new UserAlreadyExistsException(user); } final HashMap fields = new HashMap(4); fields.put(USER_FIELD, user); // 0 fields.put(VERIFIERS_FIELD, newVerifiers(user, salt, passwd, index)); // 1 fields.put(SALT_FIELD, Util.toBase64(salt)); // 2 fields.put(CONFIG_FIELD, index); // 3 entries.put(user, fields); savePasswd(); } public synchronized void changePasswd(final String user, final String passwd) throws IOException { checkCurrent(); if (!entries.containsKey(user)) { throw new NoSuchUserException(user); } final HashMap fields = (HashMap) entries.get(user); final byte[] salt; try { salt = Util.fromBase64((String) fields.get(SALT_FIELD)); } catch (NumberFormatException x) { throw new IOException("Password file corrupt"); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -