mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-25 07:42:06 +01:00
Add support for XEP-0418: DNS Queries over XMPP (DoX)
Fixes SMACK-862.
This commit is contained in:
parent
75b1d8ce13
commit
62fd897cf7
20 changed files with 564 additions and 6 deletions
|
@ -103,6 +103,7 @@ Experimental Smack Extensions and currently supported XEPs of smack-experimental
|
||||||
| [OMEMO Multi End Message and Object Encryption](omemo.md) | [XEP-0384](https://xmpp.org/extensions/xep-0384.html) | n/a | Encrypt messages using OMEMO encryption (currently only with smack-omemo-signal -> GPLv3). |
|
| [OMEMO Multi End Message and Object Encryption](omemo.md) | [XEP-0384](https://xmpp.org/extensions/xep-0384.html) | n/a | Encrypt messages using OMEMO encryption (currently only with smack-omemo-signal -> GPLv3). |
|
||||||
| [Consistent Color Generation](consistent_colors.md) | [XEP-0392](https://xmpp.org/extensions/xep-0392.html) | 0.4.0 | Generate consistent colors for identifiers like usernames to provide a consistent user experience. |
|
| [Consistent Color Generation](consistent_colors.md) | [XEP-0392](https://xmpp.org/extensions/xep-0392.html) | 0.4.0 | Generate consistent colors for identifiers like usernames to provide a consistent user experience. |
|
||||||
| [Message Markup](messagemarkup.md) | [XEP-0394](https://xmpp.org/extensions/xep-0394.html) | 0.1.0 | Style message bodies while keeping body and markup information separated. |
|
| [Message Markup](messagemarkup.md) | [XEP-0394](https://xmpp.org/extensions/xep-0394.html) | 0.1.0 | Style message bodies while keeping body and markup information separated. |
|
||||||
|
| DNS Queries over XMPP (DoX) | [XEP-0418](https://xmpp.org/extensions/xep-0418.html) | 0.1.0 | Send DNS queries and responses over XMPP. |
|
||||||
|
|
||||||
Unofficial XMPP Extensions
|
Unofficial XMPP Extensions
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
|
@ -12,6 +12,7 @@ include 'smack-core',
|
||||||
'smack-debug-slf4j',
|
'smack-debug-slf4j',
|
||||||
'smack-resolver-dnsjava',
|
'smack-resolver-dnsjava',
|
||||||
'smack-resolver-minidns',
|
'smack-resolver-minidns',
|
||||||
|
'smack-resolver-minidns-dox',
|
||||||
'smack-resolver-javax',
|
'smack-resolver-javax',
|
||||||
'smack-sasl-javax',
|
'smack-sasl-javax',
|
||||||
'smack-sasl-provided',
|
'smack-sasl-provided',
|
||||||
|
|
|
@ -46,6 +46,11 @@ public final class AndroidBase64Encoder implements org.jivesoftware.smack.util.s
|
||||||
return Base64.encodeToString(input, BASE64_ENCODER_FLAGS);
|
return Base64.encodeToString(input, BASE64_ENCODER_FLAGS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String encodeToStringWithoutPadding(byte[] input) {
|
||||||
|
return Base64.encodeToString(input, BASE64_ENCODER_FLAGS | Base64.NO_PADDING);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] encode(byte[] input) {
|
public byte[] encode(byte[] input) {
|
||||||
return Base64.encode(input, BASE64_ENCODER_FLAGS);
|
return Base64.encode(input, BASE64_ENCODER_FLAGS);
|
||||||
|
|
|
@ -43,4 +43,8 @@ public class RandomUtil {
|
||||||
public static int nextSecureRandomInt(int bound) {
|
public static int nextSecureRandomInt(int bound) {
|
||||||
return SECURE_RANDOM.get().nextInt(bound);
|
return SECURE_RANDOM.get().nextInt(bound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int nextSecureRandomInt() {
|
||||||
|
return SECURE_RANDOM.get().nextInt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,18 +39,17 @@ public class Base64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String encodeToString(byte[] input) {
|
public static final String encodeToString(byte[] input) {
|
||||||
byte[] bytes = encode(input);
|
return base64encoder.encodeToString(input);
|
||||||
try {
|
|
||||||
return new String(bytes, StringUtils.USASCII);
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
throw new AssertionError(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String encodeToString(byte[] input, int offset, int len) {
|
public static final String encodeToString(byte[] input, int offset, int len) {
|
||||||
return encodeToString(slice(input, offset, len));
|
return encodeToString(slice(input, offset, len));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final String encodeToStringWithoutPadding(byte[] input) {
|
||||||
|
return base64encoder.encodeToStringWithoutPadding(input);
|
||||||
|
}
|
||||||
|
|
||||||
public static final byte[] encode(byte[] input) {
|
public static final byte[] encode(byte[] input) {
|
||||||
return base64encoder.encode(input);
|
return base64encoder.encode(input);
|
||||||
}
|
}
|
||||||
|
@ -103,6 +102,8 @@ public class Base64 {
|
||||||
|
|
||||||
String encodeToString(byte[] input);
|
String encodeToString(byte[] input);
|
||||||
|
|
||||||
|
String encodeToStringWithoutPadding(byte[] input);
|
||||||
|
|
||||||
byte[] encode(byte[] input);
|
byte[] encode(byte[] input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,11 @@ public class SmackTestSuite {
|
||||||
return Base64.getEncoder().encodeToString(input);
|
return Base64.getEncoder().encodeToString(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String encodeToStringWithoutPadding(byte[] input) {
|
||||||
|
return Base64.getEncoder().withoutPadding().encodeToString(input);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] encode(byte[] input) {
|
public byte[] encode(byte[] input) {
|
||||||
return Base64.getEncoder().encode(input);
|
return Base64.getEncoder().encode(input);
|
||||||
|
|
|
@ -0,0 +1,164 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 2019 Florian Schmaus
|
||||||
|
*
|
||||||
|
* 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 org.jivesoftware.smackx.dox;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.Manager;
|
||||||
|
import org.jivesoftware.smack.SmackException.NoResponseException;
|
||||||
|
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
||||||
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
|
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
||||||
|
import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler;
|
||||||
|
import org.jivesoftware.smack.iqrequest.IQRequestHandler.Mode;
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.packet.StanzaError;
|
||||||
|
import org.jivesoftware.smack.packet.StanzaError.Condition;
|
||||||
|
import org.jivesoftware.smack.packet.StanzaError.Type;
|
||||||
|
import org.jivesoftware.smack.util.RandomUtil;
|
||||||
|
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
||||||
|
import org.jivesoftware.smackx.dox.element.DnsIq;
|
||||||
|
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
import org.minidns.dnsmessage.DnsMessage;
|
||||||
|
import org.minidns.dnsmessage.Question;
|
||||||
|
|
||||||
|
public final class DnsOverXmppManager extends Manager {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(DnsOverXmppManager.class.getName());
|
||||||
|
|
||||||
|
private static final Map<XMPPConnection, DnsOverXmppManager> INSTANCES = new WeakHashMap<>();
|
||||||
|
|
||||||
|
public static synchronized DnsOverXmppManager getInstanceFor(XMPPConnection connection) {
|
||||||
|
DnsOverXmppManager manager = INSTANCES.get(connection);
|
||||||
|
if (manager == null) {
|
||||||
|
manager = new DnsOverXmppManager(connection);
|
||||||
|
INSTANCES.put(connection, manager);
|
||||||
|
}
|
||||||
|
return manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String NAMESPACE = DnsIq.NAMESPACE;
|
||||||
|
|
||||||
|
private static DnsOverXmppResolver defaultResolver;
|
||||||
|
|
||||||
|
public void setDefaultDnsOverXmppResolver(DnsOverXmppResolver resolver) {
|
||||||
|
defaultResolver = resolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final ServiceDiscoveryManager serviceDiscoveryManager;
|
||||||
|
|
||||||
|
private DnsOverXmppResolver resolver = defaultResolver;
|
||||||
|
|
||||||
|
private boolean enabled;
|
||||||
|
|
||||||
|
private final AbstractIqRequestHandler dnsIqRequestHandler = new AbstractIqRequestHandler(
|
||||||
|
DnsIq.ELEMENT, DnsIq.NAMESPACE, IQ.Type.get, Mode.async) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IQ handleIQRequest(IQ iqRequest) {
|
||||||
|
DnsOverXmppResolver resolver = DnsOverXmppManager.this.resolver;
|
||||||
|
if (resolver == null) {
|
||||||
|
LOGGER.info("Resolver was null while attempting to handle " + iqRequest);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
DnsIq dnsIqRequest = (DnsIq) iqRequest;
|
||||||
|
DnsMessage query = dnsIqRequest.getDnsMessage();
|
||||||
|
|
||||||
|
DnsMessage response;
|
||||||
|
try {
|
||||||
|
response = resolver.resolve(query);
|
||||||
|
} catch (IOException exception) {
|
||||||
|
StanzaError.Builder errorBuilder = StanzaError.getBuilder()
|
||||||
|
.setType(Type.CANCEL)
|
||||||
|
.setCondition(Condition.internal_server_error)
|
||||||
|
.setDescriptiveEnText("Exception while resolving your DNS query", exception)
|
||||||
|
;
|
||||||
|
|
||||||
|
IQ errorResponse = IQ.createErrorResponse(iqRequest, errorBuilder);
|
||||||
|
return errorResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
DnsIq dnsIqResult = new DnsIq(response);
|
||||||
|
dnsIqResult.setType(IQ.Type.result);
|
||||||
|
return dnsIqResult;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private DnsOverXmppManager(XMPPConnection connection) {
|
||||||
|
super(connection);
|
||||||
|
this.serviceDiscoveryManager = ServiceDiscoveryManager.getInstanceFor(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void setDnsOverXmppResolver(DnsOverXmppResolver resolver) {
|
||||||
|
this.resolver = resolver;
|
||||||
|
if (resolver == null) {
|
||||||
|
disable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void enable() {
|
||||||
|
if (enabled) return;
|
||||||
|
|
||||||
|
if (resolver == null) {
|
||||||
|
throw new IllegalStateException("No DnsOverXmppResolver configured");
|
||||||
|
}
|
||||||
|
|
||||||
|
XMPPConnection connection = connection();
|
||||||
|
if (connection == null) return;
|
||||||
|
|
||||||
|
connection.registerIQRequestHandler(dnsIqRequestHandler);
|
||||||
|
serviceDiscoveryManager.addFeature(NAMESPACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void disable() {
|
||||||
|
if (!enabled) return;
|
||||||
|
|
||||||
|
XMPPConnection connection = connection();
|
||||||
|
if (connection == null) return;
|
||||||
|
|
||||||
|
serviceDiscoveryManager.removeFeature(NAMESPACE);
|
||||||
|
connection.unregisterIQRequestHandler(dnsIqRequestHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSupported(Jid jid)
|
||||||
|
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||||
|
return serviceDiscoveryManager.supportsFeature(jid, NAMESPACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DnsMessage query(Jid jid, Question question) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||||
|
DnsMessage queryMessage = DnsMessage.builder()
|
||||||
|
.addQuestion(question)
|
||||||
|
.setId(RandomUtil.nextSecureRandomInt())
|
||||||
|
.setRecursionDesired(true)
|
||||||
|
.build();
|
||||||
|
return query(jid, queryMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DnsMessage query(Jid jid, DnsMessage query)
|
||||||
|
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||||
|
DnsIq queryIq = new DnsIq(query, jid);
|
||||||
|
|
||||||
|
DnsIq responseIq = connection().sendIqRequestAndWaitForResponse(queryIq);
|
||||||
|
|
||||||
|
return responseIq.getDnsMessage();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 2019 Florian Schmaus
|
||||||
|
*
|
||||||
|
* 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 org.jivesoftware.smackx.dox;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.minidns.dnsmessage.DnsMessage;
|
||||||
|
|
||||||
|
public interface DnsOverXmppResolver {
|
||||||
|
|
||||||
|
DnsMessage resolve(DnsMessage query) throws IOException;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 2019 Florian Schmaus
|
||||||
|
*
|
||||||
|
* 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 org.jivesoftware.smackx.dox.element;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.util.stringencoder.Base64;
|
||||||
|
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
import org.minidns.dnsmessage.DnsMessage;
|
||||||
|
|
||||||
|
public class DnsIq extends IQ {
|
||||||
|
|
||||||
|
public static final String ELEMENT = "dns";
|
||||||
|
public static final String NAMESPACE = "urn:xmpp:dox:0";
|
||||||
|
|
||||||
|
private final DnsMessage dnsMessage;
|
||||||
|
|
||||||
|
private String base64DnsMessage;
|
||||||
|
|
||||||
|
public DnsIq(String base64DnsMessage) throws IOException {
|
||||||
|
this(Base64.decode(base64DnsMessage));
|
||||||
|
this.base64DnsMessage = base64DnsMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DnsIq(byte[] dnsMessage) throws IOException {
|
||||||
|
this(new DnsMessage(dnsMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
public DnsIq(DnsMessage dnsQuery, Jid to) {
|
||||||
|
this(dnsQuery);
|
||||||
|
setTo(to);
|
||||||
|
setType(Type.get);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DnsIq(DnsMessage dnsMessage) {
|
||||||
|
super(ELEMENT, NAMESPACE);
|
||||||
|
this.dnsMessage = dnsMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DnsMessage getDnsMessage() {
|
||||||
|
return dnsMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("ByteBufferBackingArray")
|
||||||
|
public String getDnsMessageBase64Encoded() {
|
||||||
|
if (base64DnsMessage == null) {
|
||||||
|
ByteBuffer byteBuffer = dnsMessage.getInByteBuffer();
|
||||||
|
byte[] bytes = byteBuffer.array();
|
||||||
|
base64DnsMessage = Base64.encodeToStringWithoutPadding(bytes);
|
||||||
|
}
|
||||||
|
return base64DnsMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) {
|
||||||
|
xml.rightAngleBracket();
|
||||||
|
|
||||||
|
xml.escape(getDnsMessageBase64Encoded());
|
||||||
|
|
||||||
|
return xml;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 2019 Florian Schmaus
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XEP-0418: DNS Queries over XMPP (DoX) XML providers.
|
||||||
|
*/
|
||||||
|
package org.jivesoftware.smackx.dox.element;
|
|
@ -0,0 +1,21 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 2019 Florian Schmaus
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smack's API for XEP-0418: DNS Queries over XMPP (Dox).
|
||||||
|
*/
|
||||||
|
package org.jivesoftware.smackx.dox;
|
|
@ -0,0 +1,38 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 2019 Florian Schmaus
|
||||||
|
*
|
||||||
|
* 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 org.jivesoftware.smackx.dox.provider;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.XmlEnvironment;
|
||||||
|
import org.jivesoftware.smack.parsing.SmackParsingException;
|
||||||
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
import org.jivesoftware.smackx.dox.element.DnsIq;
|
||||||
|
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
|
public class DnsIqProvider extends IQProvider<DnsIq> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DnsIq parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment)
|
||||||
|
throws XmlPullParserException, IOException, SmackParsingException {
|
||||||
|
String base64DnsMessage = parser.nextText();
|
||||||
|
return new DnsIq(base64DnsMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 2019 Florian Schmaus
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XEP-0418: DNS Queries over XMPP (DoX) XML providers.
|
||||||
|
*/
|
||||||
|
package org.jivesoftware.smackx.dox.provider;
|
|
@ -317,4 +317,11 @@
|
||||||
<className>org.jivesoftware.smackx.message_markup.provider.MarkupElementProvider</className>
|
<className>org.jivesoftware.smackx.message_markup.provider.MarkupElementProvider</className>
|
||||||
</extensionProvider>
|
</extensionProvider>
|
||||||
|
|
||||||
|
<!-- XEP-0418: DNS Queries over XMPP (DoX) -->
|
||||||
|
<iqProvider>
|
||||||
|
<elementName>dns</elementName>
|
||||||
|
<namespace>urn:xmpp:dox:0</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.dox.provider.DnsIqProvider</className>
|
||||||
|
</iqProvider>
|
||||||
|
|
||||||
</smackProviders>
|
</smackProviders>
|
||||||
|
|
|
@ -27,10 +27,13 @@ public final class Java7Base64Encoder implements org.jivesoftware.smack.util.str
|
||||||
private static final Java7Base64Encoder instance = new Java7Base64Encoder();
|
private static final Java7Base64Encoder instance = new Java7Base64Encoder();
|
||||||
|
|
||||||
private final Base64.Encoder encoder;
|
private final Base64.Encoder encoder;
|
||||||
|
private final Base64.Encoder encoderWithoutPadding;
|
||||||
|
|
||||||
private final Base64.Decoder decoder;
|
private final Base64.Decoder decoder;
|
||||||
|
|
||||||
private Java7Base64Encoder() {
|
private Java7Base64Encoder() {
|
||||||
encoder = Base64.getEncoder();
|
encoder = Base64.getEncoder();
|
||||||
|
encoderWithoutPadding = encoder.withoutPadding();
|
||||||
decoder = Base64.getDecoder();
|
decoder = Base64.getDecoder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +51,11 @@ public final class Java7Base64Encoder implements org.jivesoftware.smack.util.str
|
||||||
return encoder.encodeToString(input);
|
return encoder.encodeToString(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String encodeToStringWithoutPadding(byte[] input) {
|
||||||
|
return encoderWithoutPadding.encodeToString(input);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] encode(byte[] input) {
|
public byte[] encode(byte[] input) {
|
||||||
return encoder.encode(input);
|
return encoder.encode(input);
|
||||||
|
|
|
@ -14,6 +14,7 @@ dependencies {
|
||||||
compile project(':smack-bosh')
|
compile project(':smack-bosh')
|
||||||
compile project(':smack-java7')
|
compile project(':smack-java7')
|
||||||
compile project(':smack-resolver-minidns')
|
compile project(':smack-resolver-minidns')
|
||||||
|
compile project(':smack-resolver-minidns-dox')
|
||||||
compile project(':smack-extensions')
|
compile project(':smack-extensions')
|
||||||
compile project(':smack-experimental')
|
compile project(':smack-experimental')
|
||||||
compile project(':smack-legacy')
|
compile project(':smack-legacy')
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 2019 Florian Schmaus
|
||||||
|
*
|
||||||
|
* 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 org.igniterealtime.smack.smackrepl;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.SmackConfiguration;
|
||||||
|
import org.jivesoftware.smack.SmackException;
|
||||||
|
import org.jivesoftware.smack.XMPPException;
|
||||||
|
import org.jivesoftware.smack.debugger.ConsoleDebugger;
|
||||||
|
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
|
||||||
|
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
|
||||||
|
import org.jivesoftware.smackx.dox.DnsOverXmppManager;
|
||||||
|
import org.jivesoftware.smackx.dox.resolver.minidns.DnsOverXmppMiniDnsResolver;
|
||||||
|
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
import org.jxmpp.jid.impl.JidCreate;
|
||||||
|
import org.minidns.dnsmessage.DnsMessage;
|
||||||
|
import org.minidns.dnsmessage.Question;
|
||||||
|
import org.minidns.record.Record;
|
||||||
|
|
||||||
|
public class DoX {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws XMPPException, SmackException, IOException, InterruptedException {
|
||||||
|
SmackConfiguration.DEBUG = true;
|
||||||
|
|
||||||
|
XMPPTCPConnection connection = new XMPPTCPConnection(args[0], args[1]);
|
||||||
|
connection.setReplyTimeout(60000);
|
||||||
|
|
||||||
|
connection.connect().login();
|
||||||
|
|
||||||
|
DnsOverXmppManager dox = DnsOverXmppManager.getInstanceFor(connection);
|
||||||
|
|
||||||
|
Jid target = JidCreate.from("dns@moparisthebest.com/listener");
|
||||||
|
Question question = new Question("geekplace.eu", Record.TYPE.A);
|
||||||
|
|
||||||
|
DnsMessage response = dox.query(target, question);
|
||||||
|
|
||||||
|
// CHECKSTYLE:OFF
|
||||||
|
System.out.println(response);
|
||||||
|
// CHECKSTYLE:ON
|
||||||
|
|
||||||
|
connection.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static XMPPTCPConnection runDoxResolver(String jid, String password)
|
||||||
|
throws XMPPException, SmackException, IOException, InterruptedException {
|
||||||
|
XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder()
|
||||||
|
.setXmppAddressAndPassword(jid, password)
|
||||||
|
.setResource("dns")
|
||||||
|
.setDebuggerFactory(ConsoleDebugger.Factory.INSTANCE)
|
||||||
|
.build();
|
||||||
|
XMPPTCPConnection connection = new XMPPTCPConnection(config);
|
||||||
|
|
||||||
|
connection.connect().login();
|
||||||
|
|
||||||
|
DnsOverXmppManager dox = DnsOverXmppManager.getInstanceFor(connection);
|
||||||
|
dox.setDnsOverXmppResolver(DnsOverXmppMiniDnsResolver.INSTANCE);
|
||||||
|
|
||||||
|
dox.enable();
|
||||||
|
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
}
|
7
smack-resolver-minidns-dox/build.gradle
Normal file
7
smack-resolver-minidns-dox/build.gradle
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
description = """\
|
||||||
|
DNS over XMPP (DoX) support using MiniDNS."""
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile project(path: ':smack-resolver-minidns')
|
||||||
|
compile project(path: ':smack-experimental')
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 2019 Florian Schmaus
|
||||||
|
*
|
||||||
|
* 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 org.jivesoftware.smackx.dox.resolver.minidns;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.jivesoftware.smackx.dox.DnsOverXmppResolver;
|
||||||
|
|
||||||
|
import org.minidns.DnsClient;
|
||||||
|
import org.minidns.dnsmessage.DnsMessage;
|
||||||
|
import org.minidns.dnsmessage.Question;
|
||||||
|
import org.minidns.dnsqueryresult.DnsQueryResult;
|
||||||
|
|
||||||
|
public class DnsOverXmppMiniDnsResolver implements DnsOverXmppResolver {
|
||||||
|
|
||||||
|
public static final DnsOverXmppMiniDnsResolver INSTANCE = new DnsOverXmppMiniDnsResolver(new DnsClient());
|
||||||
|
|
||||||
|
private final DnsClient dnsClient;
|
||||||
|
|
||||||
|
public DnsOverXmppMiniDnsResolver(DnsClient dnsClient) {
|
||||||
|
this.dnsClient = dnsClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DnsMessage resolve(DnsMessage query) throws IOException {
|
||||||
|
Question question = query.getQuestion();
|
||||||
|
|
||||||
|
DnsQueryResult dnsQueryResult = dnsClient.query(question);
|
||||||
|
|
||||||
|
return dnsQueryResult.response;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 2019 Florian Schmaus
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XEP-0418: DNS Queries over XMPP (Dox) using MiniDNS.
|
||||||
|
*/
|
||||||
|
package org.jivesoftware.smackx.dox.resolver.minidns;
|
Loading…
Reference in a new issue