From: Felix Dörre Date: Wed, 22 Mar 2017 19:05:59 +0000 (+0100) Subject: Merge "add: natives/README.md" X-Git-Url: https://code.wpia.club/?p=gigi.git;a=commitdiff_plain;h=687e008f75331588c64cd3b4ca00ca224b1eaff1;hp=b05a221b086e27b7fc1b7a39942cf772f9e2f5f1 Merge "add: natives/README.md" --- diff --git a/src/club/wpia/gigi/util/DNSUtil.java b/src/club/wpia/gigi/util/DNSUtil.java index af664359..64a20964 100644 --- a/src/club/wpia/gigi/util/DNSUtil.java +++ b/src/club/wpia/gigi/util/DNSUtil.java @@ -38,17 +38,17 @@ public class DNSUtil { env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory"); env.put(Context.AUTHORITATIVE, "true"); env.put(Context.PROVIDER_URL, "dns://" + server); + InitialDirContext context = new InitialDirContext(env); try { - Attributes dnsLookup = context.getAttributes(name, new String[] { "TXT" }); + return extractTextEntries(dnsLookup.get("TXT")); } finally { context.close(); } - } private static String[] extractTextEntries(Attribute nsRecords) throws NamingException { @@ -72,27 +72,35 @@ public class DNSUtil { public static CAARecord[] getCAAEntries(String domain) throws NamingException { Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory"); + InitialDirContext context = new InitialDirContext(env); - Attributes dnsLookup; try { - dnsLookup = context.getAttributes(domain, new String[] { + Attributes dnsLookup; + try { + dnsLookup = context.getAttributes(domain, new String[] { "257" - }); - } catch (NameNotFoundException e) { - // We treat non-existing names as names without CAA-records - return new CAARecord[0]; - } - Attribute nsRecords = dnsLookup.get("257"); - if (nsRecords == null) { - return new CAARecord[] {}; - } - CAA.CAARecord[] result = new CAA.CAARecord[nsRecords.size()]; - for (int i = 0; i < result.length; i++) { - byte[] rec = (byte[]) nsRecords.get(i); + }); + } catch (NameNotFoundException e) { + // We treat non-existing names as names without CAA-records + return new CAARecord[0]; + } + + Attribute nsRecords = dnsLookup.get("257"); + if (nsRecords == null) { + return new CAARecord[] {}; + } + + CAA.CAARecord[] result = new CAA.CAARecord[nsRecords.size()]; + for (int i = 0; i < result.length; i++) { + byte[] rec = (byte[]) nsRecords.get(i); - result[i] = new CAA.CAARecord(rec); + result[i] = new CAA.CAARecord(rec); + } + + return result; + } finally { + context.close(); } - return result; } public static void main(String[] args) throws NamingException { diff --git a/src/club/wpia/gigi/util/DomainAssessment.java b/src/club/wpia/gigi/util/DomainAssessment.java index d24404ed..e17f2eea 100644 --- a/src/club/wpia/gigi/util/DomainAssessment.java +++ b/src/club/wpia/gigi/util/DomainAssessment.java @@ -148,11 +148,14 @@ public class DomainAssessment { public static void init(Properties conf) { String financialName = conf.getProperty("highFinancialValue"); + if (financialName == null) { throw new Error("No property highFinancialValue was configured"); } - try { - financial = new DomainSet(new InputStreamReader(new FileInputStream(new File(financialName)), "UTF-8")); + + try (FileInputStream fis = new FileInputStream(new File(financialName)); // + InputStreamReader isr = new InputStreamReader(fis, "UTF-8")) { + financial = new DomainSet(isr); } catch (IOException e) { throw new Error(e); } diff --git a/src/club/wpia/gigi/util/PasswordHash.java b/src/club/wpia/gigi/util/PasswordHash.java index 51dffb70..7d2cb334 100644 --- a/src/club/wpia/gigi/util/PasswordHash.java +++ b/src/club/wpia/gigi/util/PasswordHash.java @@ -1,8 +1,5 @@ package club.wpia.gigi.util; -import java.io.UnsupportedEncodingException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.util.Properties; import com.lambdaworks.crypto.SCryptUtil; @@ -29,6 +26,7 @@ public class PasswordHash { if (password == null || password.isEmpty()) { return null; } + if (hash.contains("$")) { if (SCryptUtil.check(password, hash)) { return hash; @@ -36,36 +34,8 @@ public class PasswordHash { return null; } } - String newhash = sha1(password); - boolean match = true; - if (newhash.length() != hash.length()) { - match = false; - } - for (int i = 0; i < newhash.length(); i++) { - match &= newhash.charAt(i) == hash.charAt(i); - } - if (match) { - return hash(password); - } else { - return null; - } - } - public static String sha1(String password) { - try { - MessageDigest md = MessageDigest.getInstance("SHA1"); - byte[] digest = md.digest(password.getBytes("UTF-8")); - StringBuffer res = new StringBuffer(digest.length * 2); - for (int i = 0; i < digest.length; i++) { - res.append(Integer.toHexString((digest[i] & 0xF0) >> 4)); - res.append(Integer.toHexString(digest[i] & 0xF)); - } - return res.toString(); - } catch (NoSuchAlgorithmException e) { - throw new Error(e); - } catch (UnsupportedEncodingException e) { - throw new Error(e); - } + return null; } public static String hash(String password) { diff --git a/tests/club/wpia/gigi/util/TestPasswordMigration.java b/tests/club/wpia/gigi/util/TestPasswordMigration.java index 17544a0b..1ad8ae8a 100644 --- a/tests/club/wpia/gigi/util/TestPasswordMigration.java +++ b/tests/club/wpia/gigi/util/TestPasswordMigration.java @@ -12,29 +12,39 @@ import club.wpia.gigi.database.GigiPreparedStatement; import club.wpia.gigi.database.GigiResultSet; import club.wpia.gigi.testUtils.ManagedTest; import club.wpia.gigi.testUtils.RegisteredUser; -import club.wpia.gigi.util.PasswordHash; public class TestPasswordMigration extends ManagedTest { @Rule public RegisteredUser ru = new RegisteredUser(); + /** + * Gigi used to support plain SHA-1 password hashes, for compatibility with + * legacy software. Since there currently is only one accepted hash format, + * this test now verifies that plain SHA-1 hashes are no longer accepted nor + * migrated to more recent hash formats. + * + * @see PasswordHash.verifyHash + * @see PasswordHash.hash + * @throws IOException + */ @Test - public void testPasswordMigration() throws IOException { + public void testNoSHA1PasswordMigration() throws IOException { try (GigiPreparedStatement stmt = new GigiPreparedStatement("UPDATE users SET `password`=? WHERE id=?")) { - stmt.setString(1, PasswordHash.sha1("a")); + stmt.setString(1, "86f7e437faa5a7fce15d1ddcb9eaeaea377667b8"); // sha1("a") stmt.setInt(2, ru.getUser().getId()); stmt.execute(); } + String cookie = login(ru.getUser().getEmail(), "a"); - assertTrue(isLoggedin(cookie)); + assertFalse(isLoggedin(cookie)); try (GigiPreparedStatement stmt = new GigiPreparedStatement("SELECT `password` FROM users WHERE id=?")) { stmt.setInt(1, ru.getUser().getId()); GigiResultSet res = stmt.executeQuery(); assertTrue(res.next()); String newHash = res.getString(1); - assertThat(newHash, containsString("$")); + assertThat(newHash, not(containsString("$"))); } } } diff --git a/util-testing/club/wpia/gigi/pages/Manager.java b/util-testing/club/wpia/gigi/pages/Manager.java index b33d52c4..f0991aac 100644 --- a/util-testing/club/wpia/gigi/pages/Manager.java +++ b/util-testing/club/wpia/gigi/pages/Manager.java @@ -27,6 +27,7 @@ import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import sun.security.x509.X509Key; import club.wpia.gigi.Gigi; import club.wpia.gigi.GigiApiException; import club.wpia.gigi.crypto.SPKAC; @@ -47,6 +48,7 @@ import club.wpia.gigi.dbObjects.NamePart.NamePartType; import club.wpia.gigi.dbObjects.User; import club.wpia.gigi.dbObjects.Verification.VerificationType; import club.wpia.gigi.email.DelegateMailProvider; +import club.wpia.gigi.email.EmailProvider; import club.wpia.gigi.localisation.Language; import club.wpia.gigi.output.template.IterableDataset; import club.wpia.gigi.output.template.Template; @@ -55,10 +57,10 @@ import club.wpia.gigi.ping.DomainPinger; import club.wpia.gigi.ping.PingerDaemon; import club.wpia.gigi.util.AuthorizationContext; import club.wpia.gigi.util.DayDate; +import club.wpia.gigi.util.DomainAssessment; import club.wpia.gigi.util.HTMLEncoder; import club.wpia.gigi.util.Notary; import club.wpia.gigi.util.TimeConditions; -import sun.security.x509.X509Key; public class Manager extends Page { @@ -297,8 +299,27 @@ public class Manager extends Page { @Override public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { if (req.getParameter("create") != null) { - batchCreateUsers(req.getParameter("prefix"), req.getParameter("suffix"), Integer.parseInt(req.getParameter("amount")), resp.getWriter()); - resp.getWriter().println("User batch created."); + String prefix = req.getParameter("prefix"); + String domain = req.getParameter("suffix"); + try { + if (null == prefix) { + throw new GigiApiException("No prefix given."); + } + if (null == domain) { + throw new GigiApiException("No domain given."); + } + + DomainAssessment.checkCertifiableDomain(domain, false, true); + + if ( !EmailProvider.isValidMailAddress(prefix + "@" + domain)) { + throw new GigiApiException("Invalid email address template."); + } + + batchCreateUsers(prefix, domain, Integer.parseInt(req.getParameter("amount")), resp.getWriter()); + resp.getWriter().println("User batch created."); + } catch (GigiApiException e) { + throw new Error(e); + } } else if (req.getParameter("addpriv") != null || req.getParameter("delpriv") != null) { User u = User.getByEmail(req.getParameter("email")); if (u == null) {