aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/java/sip/communicator/impl/dns
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/java/sip/communicator/impl/dns')
-rw-r--r--src/net/java/sip/communicator/impl/dns/ConfigurableDnssecResolver.java832
-rw-r--r--src/net/java/sip/communicator/impl/dns/DnsUtilActivator.java2
-rw-r--r--src/net/java/sip/communicator/impl/dns/SecureMessage.java183
-rw-r--r--src/net/java/sip/communicator/impl/dns/SecureResolveMode.java76
-rw-r--r--src/net/java/sip/communicator/impl/dns/UnboundApi.java239
-rw-r--r--src/net/java/sip/communicator/impl/dns/UnboundException.java42
-rw-r--r--src/net/java/sip/communicator/impl/dns/UnboundResolver.java410
-rw-r--r--src/net/java/sip/communicator/impl/dns/UnboundResult.java128
-rw-r--r--src/net/java/sip/communicator/impl/dns/dns.manifest.mf2
9 files changed, 591 insertions, 1323 deletions
diff --git a/src/net/java/sip/communicator/impl/dns/ConfigurableDnssecResolver.java b/src/net/java/sip/communicator/impl/dns/ConfigurableDnssecResolver.java
index af8d465..1b23af4 100644
--- a/src/net/java/sip/communicator/impl/dns/ConfigurableDnssecResolver.java
+++ b/src/net/java/sip/communicator/impl/dns/ConfigurableDnssecResolver.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,379 +15,457 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.dns;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.util.*;
-
-import javax.swing.*;
-
-import net.java.sip.communicator.service.dns.*;
-import net.java.sip.communicator.service.notification.*;
-import net.java.sip.communicator.util.Logger;
-import net.java.sip.communicator.plugin.desktoputil.*;
-
-import org.jitsi.service.configuration.*;
-import org.jitsi.service.resources.*;
-import org.jitsi.util.*;
-import org.xbill.DNS.*;
-
-/**
- * Resolver that wraps a DNSSEC capable resolver and handles validation
- * failures according to the user's settings.
- *
- * @author Ingo Bauersachs
- */
-public class ConfigurableDnssecResolver
- extends UnboundResolver
-{
- private final static Logger logger
- = Logger.getLogger(ConfigurableDnssecResolver.class);
-
- /**
- * Name of the property that defines the default DNSSEC validation
- * behavior.
- */
- public final static String PNAME_DNSSEC_VALIDATION_MODE
- = "net.java.sip.communicator.util.dns.DNSSEC_VALIDATION_MODE";
-
- /**
- * Default value of {@link #PNAME_DNSSEC_VALIDATION_MODE}
- */
- public final static String PNAME_BASE_DNSSEC_PIN
- = "net.java.sip.communicator.util.dns.pin";
-
- final static String EVENT_TYPE = "DNSSEC_NOTIFICATION";
-
- private ConfigurationService config
- = DnsUtilActivator.getConfigurationService();
- private ResourceManagementService R
- = DnsUtilActivator.getResources();
- private Map<String, Date> lastNotifications
- = new HashMap<String, Date>();
-
- /**
- * Creates a new instance of this class. Tries to use the system's
- * default forwarders.
- */
- public ConfigurableDnssecResolver()
- {
- super();
- reset();
- Lookup.setDefaultResolver(this);
-
- DnsUtilActivator.getNotificationService().
- registerDefaultNotificationForEvent(
- ConfigurableDnssecResolver.EVENT_TYPE,
- NotificationAction.ACTION_POPUP_MESSAGE,
- null, null);
- }
-
- /**
- * Inspects a DNS answer message and handles validation results according to
- * the user's preferences.
- *
- * @throws DnssecRuntimeException when the validation failed and the user
- * did not choose to ignore it.
- */
- @Override
- protected void validateMessage(SecureMessage msg)
- throws DnssecRuntimeException
- {
- //---------------------------------------------------------------------
- // || 1 | 2 | 3 | 4 | 5
- //---------------------------------------------------------------------
- // Sec. | Bog. || Ign. | Sec.Only | Sec.Or.Unsig | Warn.Bog | WarnAll
- //---------------------------------------------------------------------
- //a) 1 | 0 || ok | ok | ok | ok | ok
- //b) 0 | 1 || ok | nok | nok | ask | ask
- //c) 0 | 0 || ok | nok | ok | ok | ask
- //---------------------------------------------------------------------
-
- String fqdn = msg.getQuestion().getName().toString();
- String type = Type.string(msg.getQuestion().getType());
- String propName = createPropNameUnsigned(fqdn, type);
- SecureResolveMode defaultAction = Enum.valueOf(SecureResolveMode.class,
- config.getString(
- PNAME_DNSSEC_VALIDATION_MODE,
- SecureResolveMode.WarnIfBogus.name()
- )
- );
- SecureResolveMode pinned = Enum.valueOf(SecureResolveMode.class,
- config.getString(
- propName,
- defaultAction.name()
- )
- );
-
- //create default entry
- if(pinned == defaultAction)
- config.setProperty(propName, pinned.name());
-
- //check domain policy
-
- //[abc]1, a[2-5]
- if(pinned == SecureResolveMode.IgnoreDnssec || msg.isSecure())
- return;
-
- if(
- //b2, c2
- (pinned == SecureResolveMode.SecureOnly && !msg.isSecure())
- ||
- //b3
- (pinned == SecureResolveMode.SecureOrUnsigned && msg.isBogus())
- )
- {
- String text = getExceptionMessage(msg);
- Date last = lastNotifications.get(text);
- if(last == null
- //wait at least 5 minutes before showing the same info again
- || last.before(new Date(new Date().getTime() - 1000*60*5)))
- {
- DnsUtilActivator.getNotificationService().fireNotification(
- EVENT_TYPE,
- R.getI18NString("util.dns.INSECURE_ANSWER_TITLE"),
- text,
- null);
- lastNotifications.put(text, new Date());
- }
- throw new DnssecRuntimeException(text);
- }
-
- //c3
- if(pinned == SecureResolveMode.SecureOrUnsigned && !msg.isBogus())
- return;
-
- //c4
- if(pinned == SecureResolveMode.WarnIfBogus && !msg.isBogus())
- return;
-
- //b4, b5, c5
- String reason = msg.isBogus()
- ? R.getI18NString("util.dns.DNSSEC_ADVANCED_REASON_BOGUS",
- new String[]{fqdn, msg.getBogusReason()})
- : R.getI18NString("util.dns.DNSSEC_ADVANCED_REASON_UNSIGNED",
- new String[]{type, fqdn});
- DnssecDialog dlg = new DnssecDialog(fqdn, reason);
- dlg.setVisible(true);
- DnssecDialogResult result = dlg.getResult();
- switch(result)
- {
- case Accept:
- break;
- case Deny:
- throw new DnssecRuntimeException(getExceptionMessage(msg));
- case AlwaysAccept:
- if(msg.isBogus())
- config.setProperty(propName,
- SecureResolveMode.IgnoreDnssec.name());
- else
- config.setProperty(propName,
- SecureResolveMode.WarnIfBogus.name());
- break;
- case AlwaysDeny:
- config.setProperty(propName, SecureResolveMode.SecureOnly);
- throw new DnssecRuntimeException(getExceptionMessage(msg));
- }
- }
-
- /**
- * Defines the return code from the DNSSEC verification dialog.
- */
- private enum DnssecDialogResult
- {
- /** The DNS result shall be accepted. */
- Accept,
- /** The result shall be rejected. */
- Deny,
- /** The result shall be accepted permanently. */
- AlwaysAccept,
- /**
- * The result shall be rejected automatically unless it is valid
- * according to DNSSEC.
- */
- AlwaysDeny
- }
-
- /**
- * Dialog to ask and warn the user if he wants to continue to accept an
- * invalid dnssec result.
- */
- private class DnssecDialog extends SIPCommDialog implements ActionListener
- {
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- //UI controls
- private JPanel pnlAdvanced;
- private JPanel pnlStandard;
- private final String domain;
- private final String reason;
- private JButton cmdAck;
- private JButton cmdShowDetails;
-
- //state
- private DnssecDialogResult result = DnssecDialogResult.Deny;
-
- /**
- * Creates a new instance of this class.
- * @param domain The FQDN of the domain that failed.
- * @param reason String describing why the validation failed.
- */
- public DnssecDialog(String domain, String reason)
- {
- super(false);
- setModal(true);
- this.domain = domain;
- this.reason = reason;
- initComponents();
- }
-
- /**
- * Creates the UI controls
- */
- private void initComponents()
- {
- setLayout(new BorderLayout(15, 15));
- setTitle(R.getI18NString("util.dns.INSECURE_ANSWER_TITLE"));
-
- // warning text
- JLabel imgWarning =
- new JLabel(R.getImage("service.gui.icons.WARNING_ICON"));
- imgWarning.setBorder(BorderFactory
- .createEmptyBorder(10, 10, 10, 10));
- add(imgWarning, BorderLayout.WEST);
- JLabel lblWarning = new JLabel(
- R.getI18NString("util.dns.DNSSEC_WARNING", new String[]{
- R.getSettingsString("service.gui.APPLICATION_NAME"),
- domain
- })
- );
- add(lblWarning, BorderLayout.CENTER);
-
- //standard panel (deny option)
- cmdAck = new JButton(R.getI18NString("service.gui.OK"));
- cmdAck.addActionListener(this);
-
- cmdShowDetails = new JButton(
- R.getI18NString("util.dns.DNSSEC_ADVANCED_OPTIONS"));
- cmdShowDetails.addActionListener(this);
-
- pnlStandard = new TransparentPanel(new BorderLayout());
- pnlStandard.setBorder(BorderFactory
- .createEmptyBorder(10, 10, 10, 10));
- pnlStandard.add(cmdShowDetails, BorderLayout.WEST);
- pnlStandard.add(cmdAck, BorderLayout.EAST);
- add(pnlStandard, BorderLayout.SOUTH);
-
- //advanced panel
- pnlAdvanced = new TransparentPanel(new BorderLayout());
- JPanel pnlAdvancedButtons = new TransparentPanel(
- new FlowLayout(FlowLayout.RIGHT));
- pnlAdvancedButtons.setBorder(BorderFactory
- .createEmptyBorder(10, 10, 10, 10));
- pnlAdvanced.add(pnlAdvancedButtons, BorderLayout.EAST);
- for(DnssecDialogResult r : DnssecDialogResult.values())
- {
- JButton cmd = new JButton(R.getI18NString(
- "net.java.sip.communicator.util.dns."
- + "ConfigurableDnssecResolver$DnssecDialogResult."
- + r.name()));
- cmd.setActionCommand(r.name());
- cmd.addActionListener(this);
- pnlAdvancedButtons.add(cmd);
- }
- JLabel lblReason = new JLabel(reason);
- lblReason.setBorder(BorderFactory
- .createEmptyBorder(10, 10, 10, 10));
- pnlAdvanced.add(lblReason, BorderLayout.NORTH);
- }
-
- /**
- * Handles the events coming from the buttons.
- */
- public void actionPerformed(ActionEvent e)
- {
- if(e.getSource() == cmdAck)
- {
- result = DnssecDialogResult.Deny;
- dispose();
- }
- else if(e.getSource() == cmdShowDetails)
- {
- getContentPane().remove(pnlStandard);
- add(pnlAdvanced, BorderLayout.SOUTH);
- pack();
- }
- else
- {
- result = Enum.valueOf(DnssecDialogResult.class,
- e.getActionCommand());
- dispose();
- }
- }
-
- /**
- * Gets the option that user has chosen.
- * @return the option that user has chosen.
- */
- public DnssecDialogResult getResult()
- {
- return result;
- }
- }
-
- private String getExceptionMessage(SecureMessage msg)
- {
- return msg.getBogusReason() == null
- ? R.getI18NString(
- "util.dns.INSECURE_ANSWER_MESSAGE_NO_REASON",
- new String[]{msg.getQuestion().getName().toString()}
- )
- : R.getI18NString(
- "util.dns.INSECURE_ANSWER_MESSAGE_REASON",
- new String[]{msg.getQuestion().getName().toString(),
- //TODO parse bogus reason text and translate
- msg.getBogusReason()}
- );
- }
-
- private String createPropNameUnsigned(String fqdn, String type)
- {
- return PNAME_BASE_DNSSEC_PIN + "." + fqdn.replace(".", "__");
- }
-
- /**
- * Reloads the configuration of forwarders and trust anchors.
- */
- @Override
- public void reset()
- {
- String forwarders = DnsUtilActivator.getConfigurationService()
- .getString(DnsUtilActivator.PNAME_DNSSEC_NAMESERVERS);
- if(!StringUtils.isNullOrEmpty(forwarders, true))
- {
- if(logger.isTraceEnabled())
- {
- logger.trace("Setting DNSSEC forwarders to: "
- + Arrays.toString(forwarders.split(",")));
- }
- super.setForwarders(forwarders.split(","));
- }
-
- for(int i = 1;;i++)
- {
- String anchor = DnsUtilActivator.getResources().getSettingsString(
- "net.java.sip.communicator.util.dns.DS_ROOT." + i);
- if(anchor == null)
- break;
- clearTrustAnchors();
- addTrustAnchor(anchor);
- if(logger.isTraceEnabled())
- logger.trace("Loaded trust anchor " + anchor);
- }
- }
-}
+package net.java.sip.communicator.impl.dns;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.util.List;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.service.dns.*;
+import net.java.sip.communicator.service.notification.*;
+import net.java.sip.communicator.util.Logger;
+import net.java.sip.communicator.plugin.desktoputil.*;
+
+import org.jitsi.dnssec.validator.ValidatingResolver;
+import org.jitsi.service.configuration.*;
+import org.jitsi.service.resources.*;
+import org.jitsi.util.*;
+import org.xbill.DNS.*;
+
+/**
+ * Resolver that wraps a DNSSEC capable resolver and handles validation
+ * failures according to the user's settings.
+ *
+ * @author Ingo Bauersachs
+ */
+public class ConfigurableDnssecResolver
+ extends ValidatingResolver
+ implements CustomResolver
+{
+ private final static Logger logger
+ = Logger.getLogger(ConfigurableDnssecResolver.class);
+
+ /**
+ * Name of the property that defines the default DNSSEC validation
+ * behavior.
+ */
+ public final static String PNAME_DNSSEC_VALIDATION_MODE
+ = "net.java.sip.communicator.util.dns.DNSSEC_VALIDATION_MODE";
+
+ /**
+ * Default value of {@link #PNAME_DNSSEC_VALIDATION_MODE}
+ */
+ public final static String PNAME_BASE_DNSSEC_PIN
+ = "net.java.sip.communicator.util.dns.pin";
+
+ final static String EVENT_TYPE = "DNSSEC_NOTIFICATION";
+
+ private ConfigurationService config
+ = DnsUtilActivator.getConfigurationService();
+ private ResourceManagementService R
+ = DnsUtilActivator.getResources();
+ private Map<String, Date> lastNotifications
+ = new HashMap<String, Date>();
+
+ private ExtendedResolver headResolver;
+
+ /**
+ * Creates a new instance of this class. Tries to use the system's
+ * default forwarders.
+ */
+ public ConfigurableDnssecResolver(ExtendedResolver headResolver)
+ {
+ super(headResolver);
+
+ List<String> propNames
+ = config.getPropertyNamesByPrefix("org.jitsi.dnssec", false);
+ Properties config = new Properties();
+ for (String propName : propNames)
+ {
+ String value = config.getProperty(propName);
+ if (!StringUtils.isNullOrEmpty(value))
+ {
+ config.put(propName, value);
+ }
+ }
+
+ try
+ {
+ super.init(config);
+ }
+ catch (IOException e)
+ {
+ logger.error("Extended dnssec properties contained an error", e);
+ }
+
+ this.headResolver = headResolver;
+ reset();
+ Lookup.setDefaultResolver(this);
+
+ DnsUtilActivator.getNotificationService().
+ registerDefaultNotificationForEvent(
+ ConfigurableDnssecResolver.EVENT_TYPE,
+ NotificationAction.ACTION_POPUP_MESSAGE,
+ null, null);
+ }
+
+ /**
+ * Inspects a DNS answer message and handles validation results according to
+ * the user's preferences.
+ *
+ * @throws DnssecRuntimeException when the validation failed and the user
+ * did not choose to ignore it.
+ */
+ @Override
+ public Message send(Message query)
+ throws DnssecRuntimeException, IOException
+ {
+ //---------------------------------------------------------------------
+ // || 1 | 2 | 3 | 4 | 5
+ //---------------------------------------------------------------------
+ // Sec. | Bog. || Ign. | Sec.Only | Sec.Or.Unsig | Warn.Bog | WarnAll
+ //---------------------------------------------------------------------
+ //a) 1 | 0 || ok | ok | ok | ok | ok
+ //b) 0 | 1 || ok | nok | nok | ask | ask
+ //c) 0 | 0 || ok | nok | ok | ok | ask
+ //---------------------------------------------------------------------
+
+ SecureMessage msg = new SecureMessage(super.send(query));
+ String fqdn = msg.getQuestion().getName().toString();
+ String type = Type.string(msg.getQuestion().getType());
+ String propName = createPropNameUnsigned(fqdn, type);
+ SecureResolveMode defaultAction = Enum.valueOf(SecureResolveMode.class,
+ config.getString(
+ PNAME_DNSSEC_VALIDATION_MODE,
+ SecureResolveMode.WarnIfBogus.name()
+ )
+ );
+ SecureResolveMode pinned = Enum.valueOf(SecureResolveMode.class,
+ config.getString(
+ propName,
+ defaultAction.name()
+ )
+ );
+
+ //create default entry
+ if(pinned == defaultAction)
+ config.setProperty(propName, pinned.name());
+
+ //check domain policy
+
+ //[abc]1, a[2-5]
+ if(pinned == SecureResolveMode.IgnoreDnssec || msg.isSecure())
+ return msg;
+
+ if(
+ //b2, c2
+ (pinned == SecureResolveMode.SecureOnly && !msg.isSecure())
+ ||
+ //b3
+ (pinned == SecureResolveMode.SecureOrUnsigned && msg.isBogus())
+ )
+ {
+ String text = getExceptionMessage(msg);
+ Date last = lastNotifications.get(text);
+ if(last == null
+ //wait at least 5 minutes before showing the same info again
+ || last.before(new Date(new Date().getTime() - 1000*60*5)))
+ {
+ DnsUtilActivator.getNotificationService().fireNotification(
+ EVENT_TYPE,
+ R.getI18NString("util.dns.INSECURE_ANSWER_TITLE"),
+ text,
+ null);
+ lastNotifications.put(text, new Date());
+ }
+
+ throw new DnssecRuntimeException(text);
+ }
+
+ //c3
+ if(pinned == SecureResolveMode.SecureOrUnsigned && !msg.isBogus())
+ return msg;
+
+ //c4
+ if(pinned == SecureResolveMode.WarnIfBogus && !msg.isBogus())
+ return msg;
+
+ //b4, b5, c5
+ String reason = msg.isBogus()
+ ? R.getI18NString("util.dns.DNSSEC_ADVANCED_REASON_BOGUS",
+ new String[]{fqdn, msg.getBogusReason()})
+ : R.getI18NString("util.dns.DNSSEC_ADVANCED_REASON_UNSIGNED",
+ new String[]{type, fqdn});
+ DnssecDialog dlg = new DnssecDialog(fqdn, reason);
+ dlg.setVisible(true);
+ DnssecDialogResult result = dlg.getResult();
+ switch(result)
+ {
+ case Accept:
+ break;
+ case Deny:
+ throw new DnssecRuntimeException(getExceptionMessage(msg));
+ case AlwaysAccept:
+ if(msg.isBogus())
+ config.setProperty(propName,
+ SecureResolveMode.IgnoreDnssec.name());
+ else
+ config.setProperty(propName,
+ SecureResolveMode.WarnIfBogus.name());
+ break;
+ case AlwaysDeny:
+ config.setProperty(propName, SecureResolveMode.SecureOnly);
+ throw new DnssecRuntimeException(getExceptionMessage(msg));
+ }
+
+ return msg;
+ }
+
+ /**
+ * Defines the return code from the DNSSEC verification dialog.
+ */
+ private enum DnssecDialogResult
+ {
+ /** The DNS result shall be accepted. */
+ Accept,
+ /** The result shall be rejected. */
+ Deny,
+ /** The result shall be accepted permanently. */
+ AlwaysAccept,
+ /**
+ * The result shall be rejected automatically unless it is valid
+ * according to DNSSEC.
+ */
+ AlwaysDeny
+ }
+
+ /**
+ * Dialog to ask and warn the user if he wants to continue to accept an
+ * invalid dnssec result.
+ */
+ private class DnssecDialog extends SIPCommDialog implements ActionListener
+ {
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ //UI controls
+ private JPanel pnlAdvanced;
+ private JPanel pnlStandard;
+ private final String domain;
+ private final String reason;
+ private JButton cmdAck;
+ private JButton cmdShowDetails;
+
+ //state
+ private DnssecDialogResult result = DnssecDialogResult.Deny;
+
+ /**
+ * Creates a new instance of this class.
+ * @param domain The FQDN of the domain that failed.
+ * @param reason String describing why the validation failed.
+ */
+ public DnssecDialog(String domain, String reason)
+ {
+ super(false);
+ setModal(true);
+ this.domain = domain;
+ this.reason = reason;
+ initComponents();
+ }
+
+ /**
+ * Creates the UI controls
+ */
+ private void initComponents()
+ {
+ setLayout(new BorderLayout(15, 15));
+ setTitle(R.getI18NString("util.dns.INSECURE_ANSWER_TITLE"));
+
+ // warning text
+ JLabel imgWarning =
+ new JLabel(R.getImage("service.gui.icons.WARNING_ICON"));
+ imgWarning.setBorder(BorderFactory
+ .createEmptyBorder(10, 10, 10, 10));
+ add(imgWarning, BorderLayout.WEST);
+ JLabel lblWarning = new JLabel(
+ R.getI18NString("util.dns.DNSSEC_WARNING", new String[]{
+ R.getSettingsString("service.gui.APPLICATION_NAME"),
+ domain
+ })
+ );
+ add(lblWarning, BorderLayout.CENTER);
+
+ //standard panel (deny option)
+ cmdAck = new JButton(R.getI18NString("service.gui.OK"));
+ cmdAck.addActionListener(this);
+
+ cmdShowDetails = new JButton(
+ R.getI18NString("util.dns.DNSSEC_ADVANCED_OPTIONS"));
+ cmdShowDetails.addActionListener(this);
+
+ pnlStandard = new TransparentPanel(new BorderLayout());
+ pnlStandard.setBorder(BorderFactory
+ .createEmptyBorder(10, 10, 10, 10));
+ pnlStandard.add(cmdShowDetails, BorderLayout.WEST);
+ pnlStandard.add(cmdAck, BorderLayout.EAST);
+ add(pnlStandard, BorderLayout.SOUTH);
+
+ //advanced panel
+ pnlAdvanced = new TransparentPanel(new BorderLayout());
+ JPanel pnlAdvancedButtons = new TransparentPanel(
+ new FlowLayout(FlowLayout.RIGHT));
+ pnlAdvancedButtons.setBorder(BorderFactory
+ .createEmptyBorder(10, 10, 10, 10));
+ pnlAdvanced.add(pnlAdvancedButtons, BorderLayout.EAST);
+ for(DnssecDialogResult r : DnssecDialogResult.values())
+ {
+ JButton cmd = new JButton(R.getI18NString(
+ "net.java.sip.communicator.util.dns."
+ + "ConfigurableDnssecResolver$DnssecDialogResult."
+ + r.name()));
+ cmd.setActionCommand(r.name());
+ cmd.addActionListener(this);
+ pnlAdvancedButtons.add(cmd);
+ }
+ JLabel lblReason = new JLabel(reason);
+ lblReason.setBorder(BorderFactory
+ .createEmptyBorder(10, 10, 10, 10));
+ pnlAdvanced.add(lblReason, BorderLayout.NORTH);
+ }
+
+ /**
+ * Handles the events coming from the buttons.
+ */
+ public void actionPerformed(ActionEvent e)
+ {
+ if(e.getSource() == cmdAck)
+ {
+ result = DnssecDialogResult.Deny;
+ dispose();
+ }
+ else if(e.getSource() == cmdShowDetails)
+ {
+ getContentPane().remove(pnlStandard);
+ add(pnlAdvanced, BorderLayout.SOUTH);
+ pack();
+ }
+ else
+ {
+ result = Enum.valueOf(DnssecDialogResult.class,
+ e.getActionCommand());
+ dispose();
+ }
+ }
+
+ /**
+ * Gets the option that user has chosen.
+ * @return the option that user has chosen.
+ */
+ public DnssecDialogResult getResult()
+ {
+ return result;
+ }
+ }
+
+ private String getExceptionMessage(SecureMessage msg)
+ {
+ return msg.getBogusReason() == null
+ ? R.getI18NString(
+ "util.dns.INSECURE_ANSWER_MESSAGE_NO_REASON",
+ new String[]{msg.getQuestion().getName().toString()}
+ )
+ : R.getI18NString(
+ "util.dns.INSECURE_ANSWER_MESSAGE_REASON",
+ new String[]{msg.getQuestion().getName().toString(),
+ //TODO parse bogus reason text and translate
+ msg.getBogusReason()}
+ );
+ }
+
+ private String createPropNameUnsigned(String fqdn, String type)
+ {
+ return PNAME_BASE_DNSSEC_PIN + "." + fqdn.replace(".", "__");
+ }
+
+ /**
+ * Reloads the configuration of forwarders and trust anchors.
+ */
+ @Override
+ public void reset()
+ {
+ String forwarders = DnsUtilActivator.getConfigurationService()
+ .getString(DnsUtilActivator.PNAME_DNSSEC_NAMESERVERS);
+ if(!StringUtils.isNullOrEmpty(forwarders, true))
+ {
+ if(logger.isTraceEnabled())
+ {
+ logger.trace("Setting DNSSEC forwarders to: " + forwarders);
+ }
+
+ synchronized (Lookup.class)
+ {
+ Lookup.refreshDefault();
+ String[] fwds = forwarders.split(",");
+ Resolver[] rs = headResolver.getResolvers();
+ for (Resolver r : rs)
+ {
+ headResolver.deleteResolver(r);
+ }
+
+ for (String fwd : fwds)
+ {
+ try
+ {
+ SimpleResolver sr = new SimpleResolver(fwd);
+
+ // these properties are normally set by the
+ // ValidatingResolver in the constructor
+ sr.setEDNS(0, 0, ExtendedFlags.DO, null);
+ sr.setIgnoreTruncation(false);
+ headResolver.addResolver(sr);
+ }
+ catch (UnknownHostException e)
+ {
+ logger.error("Invalid forwarder, ignoring", e);
+ }
+ }
+
+ Lookup.setDefaultResolver(this);
+ }
+ }
+
+ StringBuilder sb = new StringBuilder();
+ for(int i = 1;;i++)
+ {
+ String anchor = DnsUtilActivator.getResources().getSettingsString(
+ "net.java.sip.communicator.util.dns.DS_ROOT." + i);
+ if(anchor == null)
+ {
+ break;
+ }
+
+ sb.append(anchor);
+ sb.append('\n');
+ }
+
+ try
+ {
+ super.loadTrustAnchors(new ByteArrayInputStream(
+ sb.toString().getBytes("ASCII")));
+ }
+ catch (IOException e)
+ {
+ logger.error("Could not load the trust anchors", e);
+ }
+
+ if(logger.isTraceEnabled())
+ logger.trace("Loaded trust anchors " + sb.toString());
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/dns/DnsUtilActivator.java b/src/net/java/sip/communicator/impl/dns/DnsUtilActivator.java
index e8b2e7d..4fc828c 100644
--- a/src/net/java/sip/communicator/impl/dns/DnsUtilActivator.java
+++ b/src/net/java/sip/communicator/impl/dns/DnsUtilActivator.java
@@ -150,7 +150,7 @@ public class DnsUtilActivator
{
bundleContext.registerService(
CustomResolver.class.getName(),
- new ConfigurableDnssecResolver(),
+ new ConfigurableDnssecResolver(new ExtendedResolver()),
null);
logger.info("DnssecResolver ... [REGISTERED]");
}
diff --git a/src/net/java/sip/communicator/impl/dns/SecureMessage.java b/src/net/java/sip/communicator/impl/dns/SecureMessage.java
index 7fe9b68..15f77b0 100644
--- a/src/net/java/sip/communicator/impl/dns/SecureMessage.java
+++ b/src/net/java/sip/communicator/impl/dns/SecureMessage.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,90 +15,97 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.dns;
-
-import java.io.*;
-
-import org.xbill.DNS.*;
-
-/**
- * DNS Message that adds DNSSEC validation information.
- *
- * @author Ingo Bauersachs
- */
-public class SecureMessage
- extends Message
-{
- private boolean secure;
- private boolean bogus;
- private String bogusReason;
-
- /**
- * Creates a new instance of this class based on data received from an
- * Unbound resolve.
- *
- * @param msg The answer of the Unbound resolver.
- * @throws IOException
- */
- public SecureMessage(UnboundResult msg) throws IOException
- {
- super(msg.answerPacket);
- secure = msg.secure;
- bogus = msg.bogus;
- bogusReason = msg.whyBogus;
- }
-
- /**
- * Indicates whether the answer is secure.
- * @return True, if the result is validated securely.
- */
- public boolean isSecure()
- {
- return secure;
- }
-
- /**
- * Indicates if there was a validation failure.
- *
- * @return If the result was not secure (secure == false), and this result
- * is due to a security failure, bogus is true.
- */
- public boolean isBogus()
- {
- return bogus;
- }
-
- /**
- * If the result is bogus this contains a string that describes the failure.
- *
- * @return string that describes the failure.
- */
- public String getBogusReason()
- {
- return bogusReason;
- }
-
- /**
- * Converts the Message to a String. The fields secure, bogus and whyBogus
- * are append as a comment.
- */
- @Override
- public String toString()
- {
- StringBuilder s = new StringBuilder(super.toString());
- s.append('\n');
- s.append(";; Secure: ");
- s.append(secure);
- s.append('\n');
- s.append(";; Bogus: ");
- s.append(bogus);
- s.append('\n');
- if(bogus)
- {
- s.append(";; Reason: ");
- s.append(bogusReason);
- s.append('\n');
- }
- return s.toString();
- }
-}
+package net.java.sip.communicator.impl.dns;
+
+import java.io.*;
+
+import org.jitsi.dnssec.validator.*;
+import org.xbill.DNS.*;
+
+/**
+ * DNS Message that adds DNSSEC validation information.
+ *
+ * @author Ingo Bauersachs
+ */
+public class SecureMessage
+ extends Message
+{
+ private boolean secure;
+ private boolean bogus;
+ private String bogusReason;
+
+ /**
+ * Creates a new instance of this class based on data received from a
+ * dnssecjava resolve.
+ *
+ * @param msg The answer of the dnssecjava resolver.
+ * @throws IOException
+ */
+ public SecureMessage(Message msg) throws IOException
+ {
+ super(msg.toWire());
+ secure = msg.getHeader().getFlag(Flags.AD);
+ bogus = !secure && msg.getRcode() == Rcode.SERVFAIL;
+ for (RRset set : msg.getSectionRRsets(Section.ADDITIONAL)) {
+ if (set.getName().equals(Name.root) && set.getType() == Type.TXT
+ && set.getDClass() == ValidatingResolver.VALIDATION_REASON_QCLASS)
+ {
+ bogusReason = ((TXTRecord)set.first()).getStrings().get(0).toString();
+ }
+ }
+ }
+
+ /**
+ * Indicates whether the answer is secure.
+ * @return True, if the result is validated securely.
+ */
+ public boolean isSecure()
+ {
+ return secure;
+ }
+
+ /**
+ * Indicates if there was a validation failure.
+ *
+ * @return If the result was not secure (secure == false), and this result
+ * is due to a security failure, bogus is true.
+ */
+ public boolean isBogus()
+ {
+ return bogus;
+ }
+
+ /**
+ * If the result is bogus this contains a string that describes the failure.
+ *
+ * @return string that describes the failure.
+ */
+ public String getBogusReason()
+ {
+ return bogusReason;
+ }
+
+ /**
+ * Converts the Message to a String. The fields secure, bogus and whyBogus
+ * are append as a comment.
+ */
+ @Override
+ public String toString()
+ {
+ StringBuilder s = new StringBuilder(super.toString());
+ s.append('\n');
+ s.append(";; Secure: ");
+ s.append(secure);
+ s.append('\n');
+ s.append(";; Bogus: ");
+ s.append(bogus);
+ s.append('\n');
+ if(bogus)
+ {
+ s.append(";; Reason: ");
+ s.append(bogusReason);
+ s.append('\n');
+ }
+ return s.toString();
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/dns/SecureResolveMode.java b/src/net/java/sip/communicator/impl/dns/SecureResolveMode.java
index 8c99836..b74f1c6 100644
--- a/src/net/java/sip/communicator/impl/dns/SecureResolveMode.java
+++ b/src/net/java/sip/communicator/impl/dns/SecureResolveMode.java
@@ -1,4 +1,4 @@
-/*
+/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
@@ -15,40 +15,40 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.java.sip.communicator.impl.dns;
-
-/**
- * Defines how DNSSEC validation errors should be handled.
- *
- * @author Ingo Bauersachs
- */
-public enum SecureResolveMode
-{
- /**
- * Any DNSSEC data is completely ignored.
- */
- IgnoreDnssec,
-
- /**
- * The result of a query is only returned if it validated successfully.
- */
- SecureOnly,
-
- /**
- * The result of a query is returned if it validated successfully or when
- * the zone is unsigned.
- */
- SecureOrUnsigned,
-
- /**
- * If the result of a query is bogus (manipulated, incorrect), the user is
- * to be asked how to proceed.
- */
- WarnIfBogus,
-
- /**
- * If the result of a query is bogus (manipulated, incorrect) or if the zone
- * is unsigned, the user is to be asked how to proceed.
- */
- WarnIfBogusOrUnsigned
-}
+package net.java.sip.communicator.impl.dns;
+
+/**
+ * Defines how DNSSEC validation errors should be handled.
+ *
+ * @author Ingo Bauersachs
+ */
+public enum SecureResolveMode
+{
+ /**
+ * Any DNSSEC data is completely ignored.
+ */
+ IgnoreDnssec,
+
+ /**
+ * The result of a query is only returned if it validated successfully.
+ */
+ SecureOnly,
+
+ /**
+ * The result of a query is returned if it validated successfully or when
+ * the zone is unsigned.
+ */
+ SecureOrUnsigned,
+
+ /**
+ * If the result of a query is bogus (manipulated, incorrect), the user is
+ * to be asked how to proceed.
+ */
+ WarnIfBogus,
+
+ /**
+ * If the result of a query is bogus (manipulated, incorrect) or if the zone
+ * is unsigned, the user is to be asked how to proceed.
+ */
+ WarnIfBogusOrUnsigned
+}
diff --git a/src/net/java/sip/communicator/impl/dns/UnboundApi.java b/src/net/java/sip/communicator/impl/dns/UnboundApi.java
deleted file mode 100644
index 6f35a8b..0000000
--- a/src/net/java/sip/communicator/impl/dns/UnboundApi.java
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.dns;
-
-/**
- * Wrapper for the JUnbound JNI wrapper.
- * <p>
- * The JavaDoc of these methods is directly copied from libunbound, licensed as
- * follows:
- * <p>
- * Copyright (c) 2007, NLnet Labs. All rights reserved.
- *
- * This software is open source.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * Neither the name of the NLNET LABS nor the names of its contributors may be
- * used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Ingo Bauersachs
- */
-public class UnboundApi
-{
- private static boolean isAvailable;
- private static final Object syncRoot = new Object();
-
- static
- {
- tryLoadUnbound();
- }
-
- /**
- * Attempts to load the Unbound native library. When successful,
- * {@link #isAvailable()} returns true.
- */
- public static void tryLoadUnbound()
- {
- synchronized(syncRoot)
- {
- try
- {
- System.loadLibrary("junbound");
- isAvailable = true;
- }
- catch(UnsatisfiedLinkError e)
- {
- isAvailable = false;
- }
- }
- }
-
- /**
- * Indicates whether the Unbound library is loaded.
- * @return True when the JNI wrapper could be loaded, false otherwise.
- */
- public static boolean isAvailable()
- {
- return isAvailable;
- }
-
- /**
- * Set debug verbosity for the context. Output is directed to stderr. Higher
- * debug level gives more output.
- *
- * @param context context.
- * @param level The debug level.
- */
- public static native void setDebugLevel(long context, int level);
-
- /**
- * Create a resolving and validation context.
- * @return a new context. default initialization. returns NULL on error.
- */
- public static native long createContext();
-
- /**
- * Destroy a validation context and free all its resources. Outstanding
- * async queries are killed and callbacks are not called for them.
- *
- * @param context context to delete
- */
- public static native void deleteContext(long context);
-
- /**
- * Set machine to forward DNS queries to, the caching resolver to use.
- * <p>
- * IP4 or IP6 address. Forwards all DNS requests to that machine, which is
- * expected to run a recursive resolver. If the proxy is not DNSSEC-capable,
- * validation may fail. Can be called several times, in that case the
- * addresses are used as backup servers.
- *
- * @param context context. At this time it is only possible to set
- * configuration before the first resolve is done.
- * @param server address, IP4 or IP6 in string format. If the server is
- * NULL, forwarding is disabled.
- */
- public static native void setForwarder(long context, String server);
-
- /**
- * Add a trust anchor to the given context.
- * <p>
- * The trust anchor is a string, on one line, that holds a valid DNSKEY or
- * DS RR.
- *
- * @param context context. At this time it is only possible to add trusted
- * keys before the first resolve is done.
- * @param anchor string, with zone-format RR on one line. [domainname] [TTL
- * optional] [type] [class optional] [rdata contents]
- */
- public static native void addTrustAnchor(long context, String anchor);
-
- /**
- * Perform resolution and validation of the target name.
- *
- * @param context context. The context is finalized, and can no longer
- * accept config changes.
- * @param name domain name in text format (a zero terminated text string).
- * @param rrtype type of RR in host order, 1 is A (address).
- * @param rrclass class of RR in host order, 1 is IN (for internet).
- * @return the result data is returned in a newly allocated result
- * structure. May be NULL on return, return value is set to an error
- * in that case (out of memory).
- * @throws UnboundException when an error occurred.
- */
- public static native UnboundResult resolve(long context, String name,
- int rrtype, int rrclass) throws UnboundException;
-
- /**
- * Perform resolution and validation of the target name.
- * <p>
- * Asynchronous, after a while, the callback will be called with your data
- * and the result.
- *
- * @param context context. If no thread or process has been created yet to
- * perform the work in the background, it is created now. The
- * context is finalized, and can no longer accept config changes.
- * @param name domain name in text format (a string).
- * @param rrtype type of RR in host order, 1 is A.
- * @param rrclass class of RR in host order, 1 is IN (for internet).
- * @param data this data is your own data (you can pass null), and is passed
- * on to the callback function.
- * @param cb this is called on completion of the resolution.
- * @return an identifier number is returned for the query as it is in
- * progress. It can be used to cancel the query.
- * @throws UnboundException when an error occurred.
- */
- public static native int resolveAsync(long context, String name,
- int rrtype, int rrclass, Object data, UnboundCallback cb)
- throws UnboundException;
-
- /**
- * Cancel an async query in progress. Its callback will not be called.
- *
- * @param context context.
- * @param asyncId which query to cancel.
- * @throws UnboundException This routine can error if the async_id passed
- * does not exist or has already been delivered. If another
- * thread is processing results at the same time, the result may
- * be delivered at the same time and the cancel fails with an
- * error. Also the cancel can fail due to a system error, no
- * memory or socket failures.
- */
- public static native void cancelAsync(long context, int asyncId)
- throws UnboundException;
-
- /**
- * Convert error value to a human readable string.
- *
- * @param code error code from one of the Unbound functions.
- * @return text string of the error code.
- */
- public static native String errorCodeToString(int code);
-
- /**
- * Wait for a context to finish with results. Call this routine to continue
- * processing results from the validating resolver. After the wait, there
- * are no more outstanding asynchronous queries.
- *
- * @param context context.
- * @throws UnboundException when an error occurred.
- */
- public static native void processAsync(long context)
- throws UnboundException;
-
- /**
- * Interface for the async resolve callback.
- */
- public interface UnboundCallback
- {
- /**
- * Called on completion of the async resolution.
- *
- * @param data the same object as passed to
- * {@link UnboundApi#resolveAsync(long, String, int, int,
- * Object, UnboundCallback)}
- * @param err 0 when a result has been found, an Unbound error code
- * otherwise
- * @param result a newly allocated result structure. The result may be
- * null, in that case err is set.
- */
- public void UnboundResolveCallback(Object data, int err,
- UnboundResult result);
- }
-}
diff --git a/src/net/java/sip/communicator/impl/dns/UnboundException.java b/src/net/java/sip/communicator/impl/dns/UnboundException.java
deleted file mode 100644
index 3eb2a04..0000000
--- a/src/net/java/sip/communicator/impl/dns/UnboundException.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.dns;
-
-/**
- * Exception that is being thrown when native Unbound code resulted in an error.
- *
- * @author Ingo Bauersachs
- */
-public class UnboundException
- extends Exception
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- /**
- * Creates a new instance of this class.
- *
- * @param message the detail message.
- */
- public UnboundException(String message)
- {
- super(message);
- }
-}
diff --git a/src/net/java/sip/communicator/impl/dns/UnboundResolver.java b/src/net/java/sip/communicator/impl/dns/UnboundResolver.java
deleted file mode 100644
index 309e58e..0000000
--- a/src/net/java/sip/communicator/impl/dns/UnboundResolver.java
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.dns;
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-import java.util.concurrent.*;
-
-import net.java.sip.communicator.service.dns.*;
-import net.java.sip.communicator.util.*;
-
-import org.xbill.DNS.*;
-
-/**
- * Implementation of the {@link Resolver} interface, wrapping the native NLnet
- * Labs Unbound resolver. Only the basic methods for queries are supported.
- *
- * @author Ingo Bauersachs
- */
-public class UnboundResolver
- implements CustomResolver
-{
- private final static Logger logger =
- Logger.getLogger(UnboundResolver.class);
-
- /**
- * Helper class to synchronize on asynchronous queries.
- */
- private static class CallbackData
- {
- /**
- * The resolver consumer that wishes to be informed when the request
- * completed.
- */
- ResolverListener listener;
-
- /**
- * The unbound session context.
- */
- long context;
-
- /**
- * The ID of the unbound async query.
- */
- int asyncId;
-
- /**
- * Java synchronization on top of unbound.
- */
- CountDownLatch sync = new CountDownLatch(1);
- }
-
- /**
- * Timeout for DNS queries.
- */
- private int timeout = 10000;
-
- /**
- * The recursive DNS servers answering our queries.
- */
- private String[] forwarders;
-
- /**
- * DNSSEC trust anchors for signed zones (usually for the root zone).
- */
- private List<String> trustAnchors = new LinkedList<String>();
-
- /**
- * Pool that executes our queries.
- */
- private ExecutorService threadPool;
-
- /**
- * Creates a new instance of this class.
- */
- public UnboundResolver()
- {
- threadPool = Executors.newCachedThreadPool();
- }
-
- /**
- * Sets a list of forwarders to use instead of the system default.
- *
- * @param forwarders list of servers to use for our queries.
- */
- public void setForwarders(String[] forwarders)
- {
- this.forwarders = forwarders;
- }
-
- /**
- * Clears any existing trust anchors previously added.
- */
- public void clearTrustAnchors()
- {
- trustAnchors.clear();
- }
-
- /**
- * Adds a DNSSEC trust anchor validation of the DNSKEYs.
- *
- * @param anchor trust anchor in the form of
- * "'zone' IN DS 'key tag' 'algorithm' 'digest type' 'digest'"
- */
- public void addTrustAnchor(String anchor)
- {
- trustAnchors.add(anchor);
- }
-
- /**
- * {@inheritDoc}
- */
- public SecureMessage send(final Message query) throws IOException
- {
- Future<SecureMessage> future = threadPool.submit(
- new Callable<SecureMessage>()
- {
- public SecureMessage call() throws Exception
- {
- if(logger.isDebugEnabled())
- logger.debug(query);
-
- SecureMessage secureMessage = null;
- final long context = prepareContext();
- try
- {
- UnboundResult result = UnboundApi.resolve(
- context,
- query.getQuestion().getName().toString(),
- query.getQuestion().getType(),
- query.getQuestion().getDClass()
- );
- secureMessage = new SecureMessage(result);
- validateMessage(secureMessage);
- }
- finally
- {
- UnboundApi.deleteContext(context);
- if(logger.isDebugEnabled() && secureMessage != null)
- logger.debug(secureMessage);
- }
-
- return secureMessage;
- }
- });
- try
- {
- return future.get(timeout, TimeUnit.SECONDS);
- }
- catch (InterruptedException e)
- {
- logger.error(e);
- throw new IOException(e.getMessage());
- }
- catch (ExecutionException e)
- {
- if(e.getCause() instanceof DnssecRuntimeException)
- throw new DnssecRuntimeException(e.getCause().getMessage());
- logger.error(e);
- throw new IOException(e.getMessage());
- }
- catch (TimeoutException e)
- {
- throw new SocketTimeoutException(e.getMessage());
- }
- }
-
- /**
- * Method to allow overriders to inspect the message. This class'
- * implementation does nothing.
- *
- * @param msg The message to inspect.
- * @throws DnssecRuntimeException if the inspector does not want the code to
- * continue normal processing of the answer.
- */
- protected void validateMessage(SecureMessage msg)
- throws DnssecRuntimeException
- {
- }
-
- /**
- * Prepares a unbound session context initialized with forwarders and trust
- * anchors.
- *
- * @return The context id
- */
- private long prepareContext()
- {
- final long context = UnboundApi.createContext();
- if(logger.isTraceEnabled())
- UnboundApi.setDebugLevel(context, 100);
- for(String fwd : forwarders == null
- ? ResolverConfig.getCurrentConfig().servers()
- : forwarders)
- {
- fwd = fwd.trim();
- if(NetworkUtils.isValidIPAddress(fwd))
- {
- if(fwd.startsWith("["))
- fwd = fwd.substring(1, fwd.length() - 1);
- UnboundApi.setForwarder(context, fwd);
- }
- }
- for(String anchor : trustAnchors)
- {
- UnboundApi.addTrustAnchor(context, anchor);
- }
- return context;
- }
-
- /**
- * Cleans up an Unbound session context.
- *
- * @param cbData The helper object of the asynchronous call.
- * @param cancelAsync Whether an outstanding asynchronous unbound query
- * should be canceled.
- */
- private static synchronized void deleteContext(CallbackData cbData,
- boolean cancelAsync)
- {
- if(cbData.context == 0)
- return;
-
- if(cancelAsync)
- {
- try
- {
- UnboundApi.cancelAsync(cbData.context, cbData.asyncId);
- }
- catch (UnboundException ignore)
- {}
- }
- UnboundApi.deleteContext(cbData.context);
- cbData.context = 0;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.xbill.DNS.Resolver#sendAsync(org.xbill.DNS.Message,
- * org.xbill.DNS.ResolverListener)
- */
- public CallbackData sendAsync(Message query, ResolverListener listener)
- {
- if(listener == null)
- throw new IllegalArgumentException("listener cannot be null");
-
- final long context = prepareContext();
- final CallbackData cbData = new CallbackData();
- cbData.listener = listener;
- cbData.context = context;
- int asyncId;
- try
- {
- asyncId = UnboundApi.resolveAsync(
- context,
- query.getQuestion().getName().toString(),
- query.getQuestion().getType(),
- query.getQuestion().getDClass(),
- cbData,
- new UnboundApi.UnboundCallback()
- {
- public void UnboundResolveCallback(Object data, int err,
- UnboundResult result)
- {
- CallbackData cbData = (CallbackData)data;
- deleteContext(cbData, false);
-
- ResolverListener l = cbData.listener;
- if(err == 0)
- {
- try
- {
- l.receiveMessage(data,
- new SecureMessage(result));
- }
- catch (IOException e)
- {
- l.handleException(data, e);
- }
- }
- else
- l.handleException(data,
- new Exception(
- UnboundApi.errorCodeToString(err)));
-
- cbData.sync.countDown();
- }
- }
- );
- }
- catch (UnboundException e)
- {
- listener.handleException(null, e);
- return null;
- }
- cbData.asyncId = asyncId;
- threadPool.execute(new Runnable()
- {
- public void run()
- {
- try
- {
- UnboundApi.processAsync(context);
- }
- catch(UnboundException ex)
- {
- cbData.listener.handleException(this, ex);
- deleteContext(cbData, false);
- cbData.sync.countDown();
- }
- }
- });
- return cbData;
- }
-
- /**
- * Not supported.
- * @throws UnsupportedOperationException
- */
- public void setEDNS(int level)
- {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Not supported.
- * @throws UnsupportedOperationException
- */
- @SuppressWarnings("rawtypes")
- public void setEDNS(int level, int payloadSize, int flags, List options)
- {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Not supported.
- * @throws UnsupportedOperationException
- */
- public void setIgnoreTruncation(boolean flag)
- {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Not supported.
- * @throws UnsupportedOperationException
- */
- public void setPort(int port)
- {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Not supported.
- * @throws UnsupportedOperationException
- */
- public void setTCP(boolean flag)
- {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Not supported.
- * @throws UnsupportedOperationException
- */
- public void setTSIGKey(TSIG key)
- {
- throw new UnsupportedOperationException();
- }
-
- /* (non-Javadoc)
- * @see org.xbill.DNS.Resolver#setTimeout(int)
- */
- public void setTimeout(int secs)
- {
- timeout = secs * 1000;
- }
-
- /* (non-Javadoc)
- * @see org.xbill.DNS.Resolver#setTimeout(int, int)
- */
- public void setTimeout(int secs, int msecs)
- {
- timeout = secs * 1000 + msecs;
- }
-
- /**
- * Does nothing.
- */
- public void reset()
- {
- }
-}
diff --git a/src/net/java/sip/communicator/impl/dns/UnboundResult.java b/src/net/java/sip/communicator/impl/dns/UnboundResult.java
deleted file mode 100644
index 85167d0..0000000
--- a/src/net/java/sip/communicator/impl/dns/UnboundResult.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Copyright @ 2015 Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.java.sip.communicator.impl.dns;
-
-/**
- * Class that contains the answer to query processed by the native Unbound
- * resolver. Corresponds to the <a
- * href="http://unbound.net/documentation/doxygen/structub__result.html"
- * >ub_result</a> data structure.
- *
- * The fields {@link #data} and {@link #canonname} are not filled.
- * <p>
- * The JavaDoc of these fields is directly copied from libunbound, licensed as
- * follows:
- * <p>
- * Copyright (c) 2007, NLnet Labs. All rights reserved.
- *
- * This software is open source.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * Neither the name of the NLNET LABS nor the names of its contributors may be
- * used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * @author Ingo Bauersachs
- */
-public class UnboundResult
-{
- /**
- * The original question, name text string.
- */
- String qname;
-
- /**
- * the type asked for
- */
- int qtype;
-
- /**
- * the type asked for
- */
- int qclass;
-
-
- /**
- * a list of network order DNS rdata items, terminated with a NULL pointer,
- * so that data[0] is the first result entry, data[1] the second, and the
- * last entry is NULL.
- */
- byte[][] data;
-
- /**
- * canonical name for the result (the final cname).
- */
- String canonname;
-
- /**
- * DNS RCODE for the result.
- */
- int rcode;
-
- /**
- * The DNS answer packet.
- */
- byte[] answerPacket;
-
-
- /**
- * If there is any data, this is true.
- */
- boolean haveData;
-
- /**
- * If there was no data, and the domain did not exist, this is true.
- */
- boolean nxDomain;
-
- /**
- * True, if the result is validated securely.
- */
- boolean secure;
-
- /**
- * If the result was not secure ({@link #secure} == false), and this result
- * is due to a security failure, bogus is true.
- */
- boolean bogus;
-
- /**
- * If the result is bogus this contains a string (zero terminated) that
- * describes the failure.
- */
- String whyBogus;
-}
diff --git a/src/net/java/sip/communicator/impl/dns/dns.manifest.mf b/src/net/java/sip/communicator/impl/dns/dns.manifest.mf
index 331eba1..33174b5 100644
--- a/src/net/java/sip/communicator/impl/dns/dns.manifest.mf
+++ b/src/net/java/sip/communicator/impl/dns/dns.manifest.mf
@@ -8,6 +8,8 @@ Import-Package: org.jitsi.util,
org.osgi.framework,
net.java.sip.communicator.util,
net.java.sip.communicator.plugin.desktoputil,
+ org.jitsi.dnssec,
+ org.jitsi.dnssec.validator,
org.jitsi.service.resources,
org.jitsi.service.fileaccess,
net.java.sip.communicator.service.resources,