From 5dcfbec6497e6b11aff12b7c1a1e187f3b6b30fb Mon Sep 17 00:00:00 2001 From: =?utf8?q?Felix=20D=C3=B6rre?= Date: Wed, 27 Aug 2014 17:57:08 +0200 Subject: [PATCH] Remove command invocations of "dig" --- config/test.properties.template | 2 +- src/org/cacert/gigi/email/EmailProvider.java | 28 +++---- src/org/cacert/gigi/ping/DNSPinger.java | 80 ++++++++------------ src/org/cacert/gigi/util/DNSUtil.java | 77 +++++++++++++++++++ tests/org/cacert/gigi/ping/TestDNS.java | 23 +++--- 5 files changed, 129 insertions(+), 81 deletions(-) create mode 100644 src/org/cacert/gigi/util/DNSUtil.java diff --git a/config/test.properties.template b/config/test.properties.template index 354b3f21..bc8d3355 100644 --- a/config/test.properties.template +++ b/config/test.properties.template @@ -26,4 +26,4 @@ sql.password= domain.dnsmanage=http://you-installation-of-the/index.php domain.dnstest=the.dns.zone -domain.dnsns=the.authorativ.ns.for.domain.dnstest +domain.testns=the.authorativ.ns.for.domain.dnstest diff --git a/src/org/cacert/gigi/email/EmailProvider.java b/src/org/cacert/gigi/email/EmailProvider.java index e82a44d7..8e188133 100644 --- a/src/org/cacert/gigi/email/EmailProvider.java +++ b/src/org/cacert/gigi/email/EmailProvider.java @@ -12,12 +12,14 @@ import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.sql.PreparedStatement; import java.sql.SQLException; -import java.util.LinkedList; import java.util.Properties; import java.util.regex.Pattern; +import javax.naming.NamingException; + import org.cacert.gigi.crypto.SMIME; import org.cacert.gigi.database.DatabaseConnection; +import org.cacert.gigi.util.DNSUtil; public abstract class EmailProvider { @@ -68,7 +70,12 @@ public abstract class EmailProvider { String[] parts = address.split("@", 2); String domain = parts[1]; - LinkedList mxhosts = getMxHosts(domain); + String[] mxhosts; + try { + mxhosts = DNSUtil.getMXEntries(domain); + } catch (NamingException e1) { + return "MX lookup for your hostname failed."; + } for (String host : mxhosts) { try (Socket s = new Socket(host, 25); BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); PrintWriter pw = new PrintWriter(s.getOutputStream())) { @@ -134,21 +141,4 @@ public abstract class EmailProvider { return FAIL; } - private static LinkedList getMxHosts(String domain) throws IOException { - LinkedList mxhosts = new LinkedList(); - Process dig = Runtime.getRuntime().exec(new String[] { - "dig", "+short", "MX", domain - }); - try (BufferedReader br = new BufferedReader(new InputStreamReader(dig.getInputStream()))) { - String line; - while ((line = br.readLine()) != null) { - String[] mxparts = line.split(" ", 2); - if (mxparts.length != 2) { - continue; - } - mxhosts.add(mxparts[1].substring(0, mxparts[1].length() - 1)); - } - } - return mxhosts; - } } diff --git a/src/org/cacert/gigi/ping/DNSPinger.java b/src/org/cacert/gigi/ping/DNSPinger.java index a611a239..5e735e09 100644 --- a/src/org/cacert/gigi/ping/DNSPinger.java +++ b/src/org/cacert/gigi/ping/DNSPinger.java @@ -1,72 +1,56 @@ package org.cacert.gigi.ping; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; import java.util.Arrays; -import java.util.LinkedList; +import java.util.List; + +import javax.naming.NamingException; import org.cacert.gigi.Domain; import org.cacert.gigi.User; +import org.cacert.gigi.util.DNSUtil; public class DNSPinger extends DomainPinger { @Override public String ping(Domain domain, String expToken, User u) { + String[] tokenParts = expToken.split(":", 2); + List nameservers; try { - String[] tokenParts = expToken.split(":", 2); - - Process p = Runtime.getRuntime().exec(new String[] { - "dig", "+short", "NS", domain.getSuffix() - }); - BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())); - String line; - LinkedList nameservers = new LinkedList(); - while ((line = br.readLine()) != null) { - nameservers.add(line); - } - p.destroy(); - StringBuffer result = new StringBuffer(); - result.append("failed: "); - boolean failed = nameservers.isEmpty(); - nameservers: - for (String NS : nameservers) { - String[] call = new String[] { - "dig", "@" + NS, "+short", "TXT", "cacert-" + tokenParts[0] + "." + domain.getSuffix() - }; - System.out.println(Arrays.toString(call)); - p = Runtime.getRuntime().exec(call); - br = new BufferedReader(new InputStreamReader(p.getInputStream())); - String token = null; - boolean found = false; - while ((line = br.readLine()) != null) { - if (line.isEmpty()) { + nameservers = Arrays.asList(DNSUtil.getNSNames(domain.getSuffix())); + } catch (NamingException e) { + return "No authorative nameserver found."; + } + StringBuffer result = new StringBuffer(); + result.append("failed: "); + boolean failed = nameservers.isEmpty(); + nameservers: + for (String NS : nameservers) { + boolean found = false; + try { + for (String token : DNSUtil.getTXTEntries("cacert-" + tokenParts[0] + "." + domain.getSuffix(), NS)) { + if (token.isEmpty()) { continue; } found = true; - token = line.substring(1, line.length() - 1); if (token.equals(tokenParts[1])) { continue nameservers; } } - p.destroy(); - result.append(NS); - if (found) { - result.append(" DIFFER;"); - } else { - result.append(" EMPTY;"); - } - failed = true; - + } catch (NamingException e) { + found = false; } - if ( !failed) { - return PING_SUCCEDED; + result.append(NS); + if (found) { + result.append(" DIFFER;"); + } else { + result.append(" EMPTY;"); } - return result.toString(); - } catch (IOException e) { - e.printStackTrace(); - return "Connection closed"; + failed = true; + } + if ( !failed) { + return PING_SUCCEDED; + } + return result.toString(); } - } diff --git a/src/org/cacert/gigi/util/DNSUtil.java b/src/org/cacert/gigi/util/DNSUtil.java new file mode 100644 index 00000000..e8a3a40d --- /dev/null +++ b/src/org/cacert/gigi/util/DNSUtil.java @@ -0,0 +1,77 @@ +package org.cacert.gigi.util; + +import java.util.Arrays; +import java.util.Hashtable; + +import javax.naming.Context; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; +import javax.naming.directory.InitialDirContext; + +public class DNSUtil { + + private static InitialDirContext context; + static { + Hashtable env = new Hashtable(); + env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory"); + // env.put(Context.AUTHORITATIVE, "true"); + // env.put(Context.PROVIDER_URL, "dns://ns.dyn.dogcraft.de"); + try { + context = new InitialDirContext(env); + } catch (NamingException e) { + e.printStackTrace(); + } + + } + + public static String[] getNSNames(String name) throws NamingException { + Attributes dnsLookup = context.getAttributes(name, new String[] { + "NS" + }); + return extractTextEntries(dnsLookup.get("NS")); + } + + public static String[] getTXTEntries(String name, String server) throws NamingException { + Hashtable env = new Hashtable(); + 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); + + Attributes dnsLookup = context.getAttributes(name, new String[] { + "TXT" + }); + + return extractTextEntries(dnsLookup.get("TXT")); + } + + private static String[] extractTextEntries(Attribute nsRecords) throws NamingException { + if (nsRecords == null) { + return new String[] {}; + } + String[] result = new String[nsRecords.size()]; + for (int i = 0; i < result.length; i++) { + result[i] = (String) nsRecords.get(i); + } + return result; + } + + public static String[] getMXEntries(String domain) throws NamingException { + Attributes dnsLookup = context.getAttributes(domain, new String[] { + "MX" + }); + return extractTextEntries(dnsLookup.get("MX")); + } + + public static void main(String[] args) throws NamingException { + if (args[0].equals("MX")) { + System.out.println(Arrays.toString(getMXEntries(args[1]))); + } else if (args[0].equals("NS")) { + System.out.println(Arrays.toString(getNSNames(args[1]))); + } else if (args[0].equals("TXT")) { + System.out.println(Arrays.toString(getTXTEntries(args[1], args[2]))); + } + } + +} diff --git a/tests/org/cacert/gigi/ping/TestDNS.java b/tests/org/cacert/gigi/ping/TestDNS.java index 0a284911..e6c53f16 100644 --- a/tests/org/cacert/gigi/ping/TestDNS.java +++ b/tests/org/cacert/gigi/ping/TestDNS.java @@ -14,32 +14,32 @@ import java.sql.SQLException; import java.util.regex.Matcher; import java.util.regex.Pattern; +import javax.naming.NamingException; + import org.cacert.gigi.database.DatabaseConnection; import org.cacert.gigi.pages.account.DomainOverview; import org.cacert.gigi.testUtils.IOUtils; import org.cacert.gigi.testUtils.ManagedTest; import org.cacert.gigi.testUtils.TestEmailReciever.TestMail; +import org.cacert.gigi.util.DNSUtil; import org.cacert.gigi.util.RandomToken; import org.junit.Test; public class TestDNS extends ManagedTest { @Test - public void testDNSSanity() throws IOException { + public void testDNSSanity() throws IOException, NamingException { String token = RandomToken.generateToken(16); String value = RandomToken.generateToken(16); - Process p = updateDNS(token, value); - String reRead = new String(IOUtils.readURL(p.getInputStream())); - reRead = reRead.trim(); - reRead = reRead.substring(1, reRead.length() - 1); + String reRead = updateDNS(token, value); assertEquals(value, reRead); } @Test - public void testEmailAndDNS() throws IOException, InterruptedException, SQLException { + public void testEmailAndDNS() throws IOException, InterruptedException, SQLException, NamingException { String email = createUniqueName() + "@example.org"; int uid = createVerifiedUser("a", "b", email, TEST_PASSWORD); String cookie = login(email, TEST_PASSWORD); @@ -96,17 +96,14 @@ public class TestDNS extends ManagedTest { assertTrue(newcontent, pat.matcher(newcontent).find()); } - private Process updateDNS(String token, String value) throws IOException, MalformedURLException { + private String updateDNS(String token, String value) throws IOException, MalformedURLException, NamingException { String test = getTestProps().getProperty("domain.dnstest"); String targetDomain = "cacert-" + token + "." + test; String manage = getTestProps().getProperty("domain.dnsmanage"); String url = manage + "t1=" + token + "&t2=" + value; assertEquals(200, ((HttpURLConnection) new URL(url).openConnection()).getResponseCode()); - - Process p = Runtime.getRuntime().exec(new String[] { - "dig", "@" + getTestProps().getProperty("domain.testns"), "+short", "TXT", targetDomain - }); - return p; + String[] data = DNSUtil.getTXTEntries(targetDomain, getTestProps().getProperty("domain.testns")); + assertEquals(1, data.length); + return data[0]; } - } -- 2.39.2