diff --git a/upassword b/upassword index 5e2d363..080068e 100755 --- a/upassword +++ b/upassword @@ -63,6 +63,29 @@ public class upassword { return sb.toString(); } + public static final boolean isHex(String str) { + int l = str.length(); + if (l % 2 != 0) return false; + for (int i = 0; i < l; i++) { + char c = str.charAt(i); + if (!(c >= '0' && c <= '9' || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f')) { + return false; + } + } + return true; + } + + public static final byte[] fromHex(String str) { + if (str == null) return null; + int l = str.length(); + byte[] ba = new byte[l / 2]; + int j = 0; + for (int i = 0; i < l; i += 2) { + byte b = (byte)Short.parseShort(str.substring(i, i + 2), 16); + ba[j++] = b; + } + return ba; + } public static final boolean strIsempty(String str) { return str == null || str.length() == 0; } @@ -3728,6 +3751,57 @@ public class upassword { SHA, SSHA}); + private static final Pattern NORMALIZED_FORMAT = Pattern.compile("\\{.+\\}.+"); + + public static final boolean isNormalizedFormat(String pw) { + return NORMALIZED_FORMAT.matcher(pw).matches(); + } + + public static final String getNormalizedScheme(String pw) { + if (pw == null) return null; + if (isNormalizedFormat(pw)) { + int p = pw.indexOf('}'); + return strSubstr(pw, 1, p).toUpperCase(); + } else { + return CLEARTEXT; + } + } + + public static final String getNormalizedPassword(String pw) { + if (pw == null) return null; + if (isNormalizedFormat(pw)) { + int p = pw.indexOf('}'); + return strSubstr(pw, p + 1); + } else { + return pw; + } + } + + public static final boolean isClearScheme(String pw) { + String scheme = getNormalizedScheme(pw); + return strIsempty(scheme) || CLEARTEXT.equals(scheme); + } + + public static final boolean isCryptScheme(String pw) { + return CRYPT.equals(getNormalizedScheme(pw)); + } + + public static final boolean isMd5Scheme(String pw) { + return MD5.equals(getNormalizedScheme(pw)); + } + + public static final boolean isSmd5Scheme(String pw) { + return SMD5.equals(getNormalizedScheme(pw)); + } + + public static final boolean isShaScheme(String pw) { + return SHA.equals(getNormalizedScheme(pw)); + } + + public static final boolean isSshaScheme(String pw) { + return SSHA.equals(getNormalizedScheme(pw)); + } + public static final boolean validate(String clear, String normalized) { return new Password(normalized).validate(clear); } @@ -3957,12 +4031,6 @@ public class upassword { return getNormalized(); } - private static final Pattern NORMALIZED_FORMAT = Pattern.compile("\\{.+\\}.+"); - - private boolean isNormalizedFormat(String pw) { - return NORMALIZED_FORMAT.matcher(pw).matches(); - } - public Password setNormalized(String pw) { reset(true); if (pw == null) { @@ -4476,32 +4544,42 @@ public class upassword { // ------------------------------------------------------------------------ - private String cryptSalt; - - private byte[] sshaSalt; - - private byte[] smd5Salt; - - private Password getPassword(String clear, String scheme, final String anySalt) { + private Password getPasswordAnySalt(String clear, String scheme, final String anySalt) { return new Password(clear, scheme) { @Override protected String randomCryptSalt() { String salt = Salt.getCryptSalt(anySalt); - if (salt != null) cryptSalt = salt; - else salt = super.randomCryptSalt(); + if (salt == null) salt = super.randomCryptSalt(); return salt; } @Override protected byte[] randomBinarySalt() { byte[] salt = null; - if (isSshaScheme()) { - salt = Salt.getSshaSalt(anySalt); - if (salt != null) sshaSalt = salt; - } else if (isSmd5Scheme()) { - salt = Salt.getSmd5Salt(anySalt); - if (salt != null) smd5Salt = salt; - } + if (isSshaScheme()) salt = Salt.getSshaSalt(anySalt); + else if (isSmd5Scheme()) salt = Salt.getSmd5Salt(anySalt); + if (salt == null) salt = super.randomBinarySalt(); + return salt; + } + }; + } + + private Password getPasswordCryptSalt(String clear, String scheme, final String cryptSalt) { + return new Password(clear, scheme) { + @Override + protected String randomCryptSalt() { + String salt = cryptSalt; + if (salt == null) salt = super.randomCryptSalt(); + return salt; + } + }; + } + + private Password getPasswordBinarySalt(String clear, String scheme, final byte[] binarySalt) { + return new Password(clear, scheme) { + @Override + protected byte[] randomBinarySalt() { + byte[] salt = binarySalt; if (salt == null) salt = super.randomBinarySalt(); return salt; } @@ -4510,44 +4588,85 @@ public class upassword { private void run(String[] args) { if (args.length == 1 && strEquals(args[0], "--help")) { - println("USAGE: upassword [clear [salt]]"); + println("USAGE: upassword [clear [salts...]]"); System.exit(0); } - PasswordGenerator pg = new PasswordGenerator(); - Password p; String clear = null; if (args.length > 0) clear = args[0]; String salt = null; if (args.length > 1) salt = args[1]; - if (clear == null) clear = pg.generate(); - p = getPassword(clear, null, null); - String lm = null; - String ntlm = null; - try { - lm = p.getLmHash(); - ntlm = p.getNtlmHash(); - } catch (Password.NotAvailableException e) { + + if (clear == null) { + PasswordGenerator pg = new PasswordGenerator(); + clear = pg.generate(); + } + + if (salt == null) { + // Pas de salt, afficher simplement les versions cryptées des mots + // de passe pour tous les schemes + Password p = getPasswordAnySalt(clear, null, null); + String lm = null; + String ntlm = null; + try { + lm = p.getLmHash(); + ntlm = p.getNtlmHash(); + } catch (Password.NotAvailableException e) { + } + String crypt = getPasswordAnySalt(clear, Password.CRYPT, salt).getNormalized(); + String sha = getPasswordAnySalt(clear, Password.SHA, salt).getNormalized(); + String ssha = getPasswordAnySalt(clear, Password.SSHA, salt).getNormalized(); + String md5 = getPasswordAnySalt(clear, Password.MD5, salt).getNormalized(); + String smd5 = getPasswordAnySalt(clear, Password.SMD5, salt).getNormalized(); + + println("clear: " + clear); + println("lm: " + lm); + println("ntlm: " + ntlm); + println("crypt: " + crypt); + println("sha: " + sha); + println("ssha: " + ssha); + println("md5: " + md5); + println("smd5: " + smd5); + } else { + println("clear: " + clear); + int i = 1, max = args.length; + while (i < max) { + salt = args[i++]; + if (Password.isNormalizedFormat(salt)) { + if (Password.isCryptScheme(salt)) { + String cryptSalt = Salt.getCryptSalt(salt); + String crypt = getPasswordCryptSalt(clear, Password.CRYPT, cryptSalt).getNormalized(); + println("salt: " + cryptSalt); + println("crypt: " + crypt); + } else if (Password.isSshaScheme(salt)) { + byte[] sshaSalt = Salt.getSshaSalt(salt); + String ssha = getPasswordBinarySalt(clear, Password.SSHA, sshaSalt).getNormalized(); + println("salt: " + toHex(sshaSalt)); + println("ssha: " + ssha); + } else if (Password.isSmd5Scheme(salt)) { + byte[] smd5Salt = Salt.getSmd5Salt(salt); + String smd5 = getPasswordBinarySalt(clear, Password.SMD5, smd5Salt).getNormalized(); + println("salt: " + toHex(smd5Salt)); + println("smd5: " + smd5); + } else { + println("salt: " + salt + " !not supported"); + } + } else if (isHex(salt)) { + byte[] binarySalt = fromHex(salt); + String ssha = getPasswordBinarySalt(clear, Password.SSHA, binarySalt).getNormalized(); + String smd5 = getPasswordBinarySalt(clear, Password.SMD5, binarySalt).getNormalized(); + println("salt: " + toHex(binarySalt)); + println("ssha: " + ssha); + println("smd5: " + smd5); + + } else { + String cryptSalt = Salt.getCryptSalt(salt); + String crypt = getPasswordCryptSalt(clear, Password.CRYPT, cryptSalt).getNormalized(); + println("salt: " + cryptSalt); + println("crypt: " + crypt); + } + } } - String crypt = getPassword(clear, Password.CRYPT, salt).getNormalized(); - String cryptSalt = this.cryptSalt; - String sha = getPassword(clear, Password.SHA, salt).getNormalized(); - String ssha = getPassword(clear, Password.SSHA, salt).getNormalized(); - String sshaSalt = toHex(this.sshaSalt); - String md5 = getPassword(clear, Password.MD5, salt).getNormalized(); - String smd5 = getPassword(clear, Password.SMD5, salt).getNormalized(); - String smd5Salt = toHex(this.smd5Salt); - println("clear: " + clear); - println("lm: " + lm); - println("ntlm: " + ntlm); - println("crypt: " + crypt); - if (cryptSalt != null) println("cryptSalt: " + cryptSalt); - println("sha: " + sha); - println("ssha: " + ssha); - if (sshaSalt != null) println("sshaSalt: " + sshaSalt); - println("md5: " + md5); - println("smd5: " + smd5); - if (smd5Salt != null) println("smd5Salt: " + smd5Salt); System.out.flush(); }