X-Git-Url: https://code.wpia.club/?p=gigi.git;a=blobdiff_plain;f=lib%2Fjetty%2Forg%2Feclipse%2Fjetty%2Futil%2Fsecurity%2FPassword.java;fp=lib%2Fjetty%2Forg%2Feclipse%2Fjetty%2Futil%2Fsecurity%2FPassword.java;h=13160c1d3dee6d75fd0f90924a0455338feea17f;hp=0000000000000000000000000000000000000000;hb=73ef54a38e3930a1a789cdc6b5fa23cdd4c9d086;hpb=515007c7c1351045420669d65b59c08fa46850f2 diff --git a/lib/jetty/org/eclipse/jetty/util/security/Password.java b/lib/jetty/org/eclipse/jetty/util/security/Password.java new file mode 100644 index 00000000..13160c1d --- /dev/null +++ b/lib/jetty/org/eclipse/jetty/util/security/Password.java @@ -0,0 +1,267 @@ +// +// ======================================================================== +// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.util.security; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; + +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; + +/* ------------------------------------------------------------ */ +/** + * Password utility class. + * + * This utility class gets a password or pass phrase either by: + * + *
+ *  + Password is set as a system property.
+ *  + The password is prompted for and read from standard input
+ *  + A program is run to get the password.
+ * 
+ * + * Passwords that begin with OBF: are de obfuscated. Passwords can be obfuscated + * by run org.eclipse.util.Password as a main class. Obfuscated password are + * required if a system needs to recover the full password (eg. so that it may + * be passed to another system). They are not secure, but prevent casual + * observation. + *

+ * Passwords that begin with CRYPT: are oneway encrypted with UnixCrypt. The + * real password cannot be retrieved, but comparisons can be made to other + * passwords. A Crypt can be generated by running org.eclipse.util.UnixCrypt as + * a main class, passing password and then the username. Checksum passwords are + * a secure(ish) way to store passwords that only need to be checked rather than + * recovered. Note that it is not strong security - specially if simple + * passwords are used. + * + * + */ +public class Password extends Credential +{ + private static final Logger LOG = Log.getLogger(Password.class); + + private static final long serialVersionUID = 5062906681431569445L; + + public static final String __OBFUSCATE = "OBF:"; + + private String _pw; + + /* ------------------------------------------------------------ */ + /** + * Constructor. + * + * @param password The String password. + */ + public Password(String password) + { + _pw = password; + + // expand password + while (_pw != null && _pw.startsWith(__OBFUSCATE)) + _pw = deobfuscate(_pw); + } + + /* ------------------------------------------------------------ */ + @Override + public String toString() + { + return _pw; + } + + /* ------------------------------------------------------------ */ + public String toStarString() + { + return "*****************************************************".substring(0, _pw.length()); + } + + /* ------------------------------------------------------------ */ + @Override + public boolean check(Object credentials) + { + if (this == credentials) return true; + + if (credentials instanceof Password) return credentials.equals(_pw); + + if (credentials instanceof String) return credentials.equals(_pw); + + if (credentials instanceof char[]) return Arrays.equals(_pw.toCharArray(), (char[]) credentials); + + if (credentials instanceof Credential) return ((Credential) credentials).check(_pw); + + return false; + } + + /* ------------------------------------------------------------ */ + @Override + public boolean equals(Object o) + { + if (this == o) + return true; + + if (null == o) + return false; + + if (o instanceof Password) + { + Password p = (Password) o; + //noinspection StringEquality + return p._pw == _pw || (null != _pw && _pw.equals(p._pw)); + } + + if (o instanceof String) + return o.equals(_pw); + + return false; + } + + /* ------------------------------------------------------------ */ + @Override + public int hashCode() + { + return null == _pw ? super.hashCode() : _pw.hashCode(); + } + + /* ------------------------------------------------------------ */ + public static String obfuscate(String s) + { + StringBuilder buf = new StringBuilder(); + byte[] b = s.getBytes(StandardCharsets.UTF_8); + + buf.append(__OBFUSCATE); + for (int i = 0; i < b.length; i++) + { + byte b1 = b[i]; + byte b2 = b[b.length - (i + 1)]; + if (b1<0 || b2<0) + { + int i0 = (0xff&b1)*256 + (0xff&b2); + String x = Integer.toString(i0, 36).toLowerCase(); + buf.append("U0000",0,5-x.length()); + buf.append(x); + } + else + { + int i1 = 127 + b1 + b2; + int i2 = 127 + b1 - b2; + int i0 = i1 * 256 + i2; + String x = Integer.toString(i0, 36).toLowerCase(); + + int j0 = Integer.parseInt(x, 36); + int j1 = (i0 / 256); + int j2 = (i0 % 256); + byte bx = (byte) ((j1 + j2 - 254) / 2); + + buf.append("000",0,4-x.length()); + buf.append(x); + } + + } + return buf.toString(); + + } + + /* ------------------------------------------------------------ */ + public static String deobfuscate(String s) + { + if (s.startsWith(__OBFUSCATE)) s = s.substring(4); + + byte[] b = new byte[s.length() / 2]; + int l = 0; + for (int i = 0; i < s.length(); i += 4) + { + if (s.charAt(i)=='U') + { + i++; + String x = s.substring(i, i + 4); + int i0 = Integer.parseInt(x, 36); + byte bx = (byte)(i0>>8); + b[l++] = bx; + } + else + { + String x = s.substring(i, i + 4); + int i0 = Integer.parseInt(x, 36); + int i1 = (i0 / 256); + int i2 = (i0 % 256); + byte bx = (byte) ((i1 + i2 - 254) / 2); + b[l++] = bx; + } + } + + return new String(b, 0, l,StandardCharsets.UTF_8); + } + + /* ------------------------------------------------------------ */ + /** + * Get a password. A password is obtained by trying + *

+ * + * @param realm The realm name for the password, used as a SystemProperty + * name. + * @param dft The default password. + * @param promptDft The default to use if prompting for the password. + * @return Password + */ + public static Password getPassword(String realm, String dft, String promptDft) + { + String passwd = System.getProperty(realm, dft); + if (passwd == null || passwd.length() == 0) + { + try + { + System.out.print(realm + ((promptDft != null && promptDft.length() > 0) ? " [dft]" : "") + " : "); + System.out.flush(); + byte[] buf = new byte[512]; + int len = System.in.read(buf); + if (len > 0) passwd = new String(buf, 0, len).trim(); + } + catch (IOException e) + { + LOG.warn(Log.EXCEPTION, e); + } + if (passwd == null || passwd.length() == 0) passwd = promptDft; + } + return new Password(passwd); + } + + /* ------------------------------------------------------------ */ + /** + * @param arg + */ + public static void main(String[] arg) + { + if (arg.length != 1 && arg.length != 2) + { + System.err.println("Usage - java org.eclipse.jetty.security.Password [] "); + System.err.println("If the password is ?, the user will be prompted for the password"); + System.exit(1); + } + String p = arg[arg.length == 1 ? 0 : 1]; + Password pw = new Password(p); + System.err.println(pw.toString()); + System.err.println(obfuscate(pw.toString())); + System.err.println(Credential.MD5.digest(p)); + if (arg.length == 2) System.err.println(Credential.Crypt.crypt(arg[0], pw.toString())); + } +}