X-Git-Url: https://code.wpia.club/?p=gigi.git;a=blobdiff_plain;f=src%2Fclub%2Fwpia%2Fgigi%2FGigi.java;h=e76c51710e6c1c664d19c72c176d238f9f05c2ee;hp=15a52143e745394df63b579e7dedb1ac2c14e003;hb=8bb6a6f9dd49888a07b0588ae9773cc52d51cdb5;hpb=985d31f75a724d141ff37bb678c28aaa474d5915 diff --git a/src/club/wpia/gigi/Gigi.java b/src/club/wpia/gigi/Gigi.java index 15a52143..e76c5171 100644 --- a/src/club/wpia/gigi/Gigi.java +++ b/src/club/wpia/gigi/Gigi.java @@ -4,7 +4,12 @@ import java.io.IOException; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.math.BigInteger; +import java.nio.channels.FileChannel; +import java.nio.file.FileSystems; +import java.nio.file.NoSuchFileException; import java.security.KeyStore; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.security.cert.X509Certificate; import java.util.Calendar; import java.util.Collections; @@ -78,6 +83,10 @@ import club.wpia.gigi.pages.statistics.StatisticsRoles; import club.wpia.gigi.pages.wot.Points; import club.wpia.gigi.pages.wot.RequestTTPPage; import club.wpia.gigi.pages.wot.VerifyPage; +import club.wpia.gigi.passwords.DelegatingPasswordChecker; +import club.wpia.gigi.passwords.PasswordChecker; +import club.wpia.gigi.passwords.PasswordHashChecker; +import club.wpia.gigi.passwords.PasswordStrengthChecker; import club.wpia.gigi.ping.PingerDaemon; import club.wpia.gigi.util.AuthorizationContext; import club.wpia.gigi.util.DomainAssessment; @@ -245,6 +254,8 @@ public final class Gigi extends HttpServlet { private static Gigi instance; + private static PasswordChecker passwordChecker; + private static final Template baseTemplate = new Template(Gigi.class.getResource("Gigi.templ")); private PingerDaemon pinger; @@ -273,6 +284,46 @@ public final class Gigi extends HttpServlet { this.truststore = truststore; pinger = new PingerDaemon(truststore); pinger.start(); + Gigi.passwordChecker = getPasswordChecker(conf); + } + } + + private PasswordChecker getPasswordChecker(Properties conf) { + final String knownPasswordHashesPath; + final boolean knownPasswordHashesRequired; + String knownPasswordHashesConfig = conf.getProperty("knownPasswordHashes"); + if (knownPasswordHashesConfig != null) { + knownPasswordHashesPath = knownPasswordHashesConfig; + knownPasswordHashesRequired = true; + } else { + knownPasswordHashesPath = "/usr/share/pwned-passwords/pwned-passwords.bin"; + knownPasswordHashesRequired = false; + } + + final MessageDigest sha1; + try { + sha1 = MessageDigest.getInstance("SHA-1"); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + + try { + final FileChannel knownPasswordHashesFile = FileChannel.open( + FileSystems.getDefault().getPath(knownPasswordHashesPath)); + return new DelegatingPasswordChecker(new PasswordChecker[] { + new PasswordStrengthChecker(), + new PasswordHashChecker(knownPasswordHashesFile, sha1) + }); + } catch (IOException e) { + if (knownPasswordHashesRequired) { + throw new RuntimeException("Error while opening password hash database, refusing startup", e); + } else { + System.err.println("Warning: A problem was encountered while opening the password hash database, passwords will be checked only by strength."); + if ( !(e instanceof NoSuchFileException)) { + e.printStackTrace(); + } + return new PasswordStrengthChecker(); + } } } @@ -521,4 +572,15 @@ public final class Gigi extends HttpServlet { instance.pinger.interrupt(); } + public static PasswordChecker getPasswordChecker() { + if (passwordChecker == null) { + throw new IllegalStateException("Not yet initialized!"); + } + return passwordChecker; + } + + public static void setPasswordChecker(PasswordChecker passwordChecker) { + Gigi.passwordChecker = passwordChecker; + } + }