All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.jetty.util.security.Password Maven / Gradle / Ivy

There is a newer version: 12.1.0.alpha0
Show newest version
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package org.eclipse.jetty.util.security;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Locale;

import org.eclipse.jetty.util.StringUtil;

/**
 * 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 { // NOTE: DO NOT INTRODUCE LOGGING TO THIS 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 stringEquals(_pw, (String)credentials); if (credentials instanceof char[]) return stringEquals(_pw, new String((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) return stringEquals(_pw, ((Password)o)._pw); if (o instanceof String) return stringEquals(_pw, (String)o); 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(Locale.ENGLISH); 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(Locale.ENGLISH); 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 *

    *
  • Calling System.getProperty(realm,dft) *
  • Prompting for a password *
  • Using promptDft if nothing was entered. *
* * @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) { // only seen with command line input style System.err.println("ERROR: Bad/Invalid password."); e.printStackTrace(); } if (passwd == null || passwd.length() == 0) passwd = promptDft; } return new Password(passwd); } public static void main(String[] args) throws IOException { boolean promptArgs = false; String argUser = null; String argPassword = null; for (String arg: args) { if (arg.equals("--prompt")) { promptArgs = true; // ignore any other args break; } if (argUser == null) { argUser = arg; promptArgs = true; } else { if (!arg.equals("?")) promptArgs = false; argPassword = arg; } } if (promptArgs) { System.out.print("Username"); if (StringUtil.isNotBlank(argUser)) System.out.printf("[%s]", argUser); System.out.print(": "); BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); String inputUser = input.readLine(); if (StringUtil.isNotBlank(inputUser)) argUser = inputUser; System.out.print("Password: "); argPassword = input.readLine(); if (StringUtil.isBlank(argPassword)) { System.err.println("ERROR: blank passwords not supported"); System.exit(1); } } else if (StringUtil.isBlank(argUser)) { System.err.printf("Usage - java %s [] [] --prompt%n", Password.class.getName()); System.err.printf("Argument options:%n"); System.err.printf(" %s%n", Password.class.getName()); System.err.printf(" No arguments, will show this help%n"); System.err.printf(" %s %n", Password.class.getName()); System.err.printf(" username only, will prompt for arguments%n"); System.err.printf(" %s ?%n", Password.class.getName()); System.err.printf(" username with question mark password, will prompt for arguments%n"); System.err.printf(" %s %n", Password.class.getName()); System.err.printf(" username with password, will produce obfuscation results%n"); System.err.printf(" %s --prompt%n", Password.class.getName()); System.err.printf(" will prompt for arguments%n"); System.exit(1); } Password pw = new Password(argPassword); System.err.println(obfuscate(pw.toString())); System.err.println(Credential.MD5.digest(argPassword)); if (StringUtil.isNotBlank(argUser)) System.err.println(Credential.Crypt.crypt(argUser, pw.toString())); System.exit(0); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy