mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-23 20:42:06 +01:00
Work on Jingle Encrypted Transfers
This commit is contained in:
parent
1dbdafe28c
commit
c82b25ea09
11 changed files with 210 additions and 96 deletions
|
@ -17,31 +17,22 @@
|
||||||
package org.jivesoftware.smackx.jet;
|
package org.jivesoftware.smackx.jet;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.security.SecureRandom;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import javax.crypto.Cipher;
|
|
||||||
import javax.crypto.CipherInputStream;
|
|
||||||
import javax.crypto.KeyGenerator;
|
|
||||||
import javax.crypto.SecretKey;
|
|
||||||
import javax.crypto.spec.IvParameterSpec;
|
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
|
||||||
|
|
||||||
import org.jivesoftware.smack.Manager;
|
import org.jivesoftware.smack.Manager;
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
import org.jivesoftware.smack.packet.ExtensionElement;
|
import org.jivesoftware.smackx.jet.internal.JetSecurity;
|
||||||
import org.jivesoftware.smack.util.StringUtils;
|
|
||||||
import org.jivesoftware.smackx.jet.element.JetSecurityElement;
|
|
||||||
import org.jivesoftware.smackx.jft.controller.OutgoingFileOfferController;
|
import org.jivesoftware.smackx.jft.controller.OutgoingFileOfferController;
|
||||||
import org.jivesoftware.smackx.jft.element.JingleFileTransferChildElement;
|
|
||||||
import org.jivesoftware.smackx.jft.element.JingleFileTransferElement;
|
|
||||||
import org.jivesoftware.smackx.jft.internal.JingleOutgoingFileOffer;
|
import org.jivesoftware.smackx.jft.internal.JingleOutgoingFileOffer;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionChildElement;
|
import org.jivesoftware.smackx.jingle.JingleManager;
|
||||||
|
import org.jivesoftware.smackx.jingle.JingleTransportManager;
|
||||||
|
import org.jivesoftware.smackx.jingle.components.JingleContent;
|
||||||
|
import org.jivesoftware.smackx.jingle.components.JingleSession;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleContentElement;
|
import org.jivesoftware.smackx.jingle.element.JingleContentElement;
|
||||||
|
import org.jivesoftware.smackx.jingle.util.Role;
|
||||||
|
|
||||||
import org.jxmpp.jid.FullJid;
|
import org.jxmpp.jid.FullJid;
|
||||||
|
|
||||||
|
@ -56,8 +47,11 @@ public final class JetManager extends Manager {
|
||||||
|
|
||||||
private static final Map<String, JingleEncryptionMethod> encryptionMethods = new HashMap<>();
|
private static final Map<String, JingleEncryptionMethod> encryptionMethods = new HashMap<>();
|
||||||
|
|
||||||
|
private final JingleManager jingleManager;
|
||||||
|
|
||||||
private JetManager(XMPPConnection connection) {
|
private JetManager(XMPPConnection connection) {
|
||||||
super(connection);
|
super(connection);
|
||||||
|
this.jingleManager = JingleManager.getInstanceFor(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JetManager getInstanceFor(XMPPConnection connection) {
|
public static JetManager getInstanceFor(XMPPConnection connection) {
|
||||||
|
@ -72,85 +66,24 @@ public final class JetManager extends Manager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public OutgoingFileOfferController sendEncryptedFile(FullJid recipient, File file, String encryptionMethodNamespace) throws Exception {
|
public OutgoingFileOfferController sendEncryptedFile(FullJid recipient, File file, String encryptionMethodNamespace) throws Exception {
|
||||||
|
if (file == null || !file.exists()) {
|
||||||
JingleEncryptionMethod encryptionMethod = getEncryptionMethod(encryptionMethodNamespace);
|
throw new IllegalArgumentException("File MUST NOT be null and MUST exist.");
|
||||||
if (encryptionMethod == null) {
|
|
||||||
throw new IllegalStateException("No encryption method with namespace " + encryptionMethodNamespace + " registered.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int keyLength = 256;
|
JingleSession session = jingleManager.createSession(Role.initiator, recipient);
|
||||||
String keyType = "AES";
|
|
||||||
String cipherMode = "AES/GCM/NoPadding";
|
|
||||||
|
|
||||||
KeyGenerator keyGenerator = KeyGenerator.getInstance(keyType);
|
JingleContent content = new JingleContent(JingleContentElement.Creator.initiator, JingleContentElement.Senders.initiator);
|
||||||
keyGenerator.init(keyLength);
|
session.addContent(content);
|
||||||
byte[] key = keyGenerator.generateKey().getEncoded();
|
|
||||||
|
|
||||||
SecureRandom secureRandom = new SecureRandom();
|
|
||||||
byte[] iv = new byte[keyLength];
|
|
||||||
secureRandom.nextBytes(iv);
|
|
||||||
|
|
||||||
byte[] keyAndIv = new byte[2 * keyLength];
|
|
||||||
System.arraycopy(key, 0, keyAndIv, 0, keyLength);
|
|
||||||
System.arraycopy(iv, 0, keyAndIv, keyLength, keyLength);
|
|
||||||
|
|
||||||
SecretKey secretKey = new SecretKeySpec(key, keyType);
|
|
||||||
IvParameterSpec ivSpec = new IvParameterSpec(iv);
|
|
||||||
Cipher cipher = Cipher.getInstance(cipherMode, "BC");
|
|
||||||
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
|
|
||||||
|
|
||||||
Exception ioe = null;
|
|
||||||
byte[] fileBuf = null;
|
|
||||||
|
|
||||||
FileInputStream fi = null;
|
|
||||||
CipherInputStream ci = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
fi = new FileInputStream(file);
|
|
||||||
ci = new CipherInputStream(fi, cipher);
|
|
||||||
|
|
||||||
fileBuf = new byte[(int) file.length()];
|
|
||||||
ci.read(fileBuf);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
ioe = e;
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
|
|
||||||
if (ci != null) {
|
|
||||||
ci.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fi != null) {
|
|
||||||
fi.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ioe != null) {
|
|
||||||
throw ioe;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fileBuf == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
String contentName = StringUtils.randomString(24);
|
|
||||||
|
|
||||||
ExtensionElement encryptionExtension = encryptionMethod.encryptJingleTransfer(recipient, keyAndIv);
|
|
||||||
JetSecurityElement securityElement = new JetSecurityElement(contentName, encryptionExtension);
|
|
||||||
|
|
||||||
JingleOutgoingFileOffer offer = new JingleOutgoingFileOffer(file);
|
JingleOutgoingFileOffer offer = new JingleOutgoingFileOffer(file);
|
||||||
|
content.setDescription(offer);
|
||||||
|
|
||||||
JingleFileTransferChildElement fileTransferChild = JingleFileTransferChildElement.getBuilder().setFile(file).build();
|
JingleTransportManager transportManager = jingleManager.getBestAvailableTransportManager();
|
||||||
JingleFileTransferElement fileTransfer = new JingleFileTransferElement(Collections.<JingleContentDescriptionChildElement>singletonList(fileTransferChild));
|
content.setTransport(transportManager.createTransport(content));
|
||||||
|
|
||||||
JingleContentElement content = JingleContentElement.getBuilder()
|
JetSecurity security = new JetSecurity(encryptionMethodNamespace, connection());
|
||||||
.setCreator(JingleContentElement.Creator.initiator)
|
content.setSecurity(security);
|
||||||
.setName(contentName)
|
session.initiate(connection());
|
||||||
//.setTransport(offer.getTransportSession().createTransport())
|
|
||||||
.setSecurity(securityElement)
|
|
||||||
.setDescription(fileTransfer)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
return offer;
|
return offer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,25 @@
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smackx.jet.internal;
|
package org.jivesoftware.smackx.jet.internal;
|
||||||
|
|
||||||
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.NoSuchProviderException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.KeyGenerator;
|
||||||
|
import javax.crypto.NoSuchPaddingException;
|
||||||
|
import javax.crypto.SecretKey;
|
||||||
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
import org.jivesoftware.smack.packet.ExtensionElement;
|
import org.jivesoftware.smack.packet.ExtensionElement;
|
||||||
|
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
|
||||||
|
import org.jivesoftware.smackx.jet.JetManager;
|
||||||
|
import org.jivesoftware.smackx.jet.JingleEncryptionMethod;
|
||||||
import org.jivesoftware.smackx.jet.element.JetSecurityElement;
|
import org.jivesoftware.smackx.jet.element.JetSecurityElement;
|
||||||
|
import org.jivesoftware.smackx.jingle.callbacks.JingleSecurityCallback;
|
||||||
import org.jivesoftware.smackx.jingle.components.JingleSecurity;
|
import org.jivesoftware.smackx.jingle.components.JingleSecurity;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleContentSecurityInfoElement;
|
import org.jivesoftware.smackx.jingle.element.JingleContentSecurityInfoElement;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleElement;
|
import org.jivesoftware.smackx.jingle.element.JingleElement;
|
||||||
|
@ -30,8 +47,53 @@ public class JetSecurity extends JingleSecurity<JetSecurityElement> {
|
||||||
public static final String NAMESPACE_V0 = "urn:xmpp:jingle:jet:0";
|
public static final String NAMESPACE_V0 = "urn:xmpp:jingle:jet:0";
|
||||||
public static final String NAMESPACE = NAMESPACE_V0;
|
public static final String NAMESPACE = NAMESPACE_V0;
|
||||||
|
|
||||||
|
private final String methodNamespace;
|
||||||
|
|
||||||
|
private final Cipher cipher;
|
||||||
|
|
||||||
private ExtensionElement child;
|
private ExtensionElement child;
|
||||||
|
|
||||||
|
public JetSecurity(Cipher cipher, ExtensionElement child) {
|
||||||
|
super();
|
||||||
|
this.cipher = cipher;
|
||||||
|
this.child = child;
|
||||||
|
this.methodNamespace = child.getNamespace();
|
||||||
|
}
|
||||||
|
|
||||||
|
public JetSecurity(String methodNamespace, XMPPConnection connection)
|
||||||
|
throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,
|
||||||
|
InvalidAlgorithmParameterException, InvalidKeyException {
|
||||||
|
this.methodNamespace = methodNamespace;
|
||||||
|
|
||||||
|
JetManager jetManager = JetManager.getInstanceFor(connection);
|
||||||
|
JingleEncryptionMethod encryptionMethod = jetManager.getEncryptionMethod(methodNamespace);
|
||||||
|
if (encryptionMethod == null) {
|
||||||
|
throw new IllegalStateException("No encryption method with namespace " + methodNamespace + " registered.");
|
||||||
|
}
|
||||||
|
|
||||||
|
//Create key and cipher
|
||||||
|
int keyLength = 256;
|
||||||
|
String keyType = "AES";
|
||||||
|
String cipherMode = "AES/GCM/NoPadding";
|
||||||
|
|
||||||
|
KeyGenerator keyGenerator = KeyGenerator.getInstance(keyType);
|
||||||
|
keyGenerator.init(keyLength);
|
||||||
|
byte[] key = keyGenerator.generateKey().getEncoded();
|
||||||
|
|
||||||
|
SecureRandom secureRandom = new SecureRandom();
|
||||||
|
byte[] iv = new byte[keyLength];
|
||||||
|
secureRandom.nextBytes(iv);
|
||||||
|
|
||||||
|
byte[] keyAndIv = new byte[2 * keyLength];
|
||||||
|
System.arraycopy(key, 0, keyAndIv, 0, keyLength);
|
||||||
|
System.arraycopy(iv, 0, keyAndIv, keyLength, keyLength);
|
||||||
|
|
||||||
|
SecretKey secretKey = new SecretKeySpec(key, keyType);
|
||||||
|
IvParameterSpec ivSpec = new IvParameterSpec(iv);
|
||||||
|
cipher = Cipher.getInstance(cipherMode, "BC");
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JetSecurityElement getElement() {
|
public JetSecurityElement getElement() {
|
||||||
return new JetSecurityElement(getParent().getName(), child);
|
return new JetSecurityElement(getParent().getName(), child);
|
||||||
|
@ -41,4 +103,16 @@ public class JetSecurity extends JingleSecurity<JetSecurityElement> {
|
||||||
public JingleElement handleSecurityInfo(JingleContentSecurityInfoElement element, JingleElement wrapping) {
|
public JingleElement handleSecurityInfo(JingleContentSecurityInfoElement element, JingleElement wrapping) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decryptIncomingBytestream(BytestreamSession bytestreamSession, JingleSecurityCallback callback) {
|
||||||
|
JetSecurityBytestreamSession securityBytestreamSession = new JetSecurityBytestreamSession(bytestreamSession, cipher);
|
||||||
|
callback.onSecurityReady(securityBytestreamSession);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encryptIncomingBytestream(BytestreamSession bytestreamSession, JingleSecurityCallback callback) {
|
||||||
|
JetSecurityBytestreamSession securityBytestreamSession = new JetSecurityBytestreamSession(bytestreamSession, cipher);
|
||||||
|
callback.onSecurityReady(securityBytestreamSession);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 2017 Paul Schaub
|
||||||
|
*
|
||||||
|
* 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.jet.internal;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.CipherInputStream;
|
||||||
|
import javax.crypto.CipherOutputStream;
|
||||||
|
|
||||||
|
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
|
||||||
|
import org.jivesoftware.smackx.jingle.components.JingleSecurityBytestreamSession;
|
||||||
|
|
||||||
|
public class JetSecurityBytestreamSession extends JingleSecurityBytestreamSession {
|
||||||
|
private final Cipher cipher;
|
||||||
|
|
||||||
|
public JetSecurityBytestreamSession(BytestreamSession session, Cipher cipher) {
|
||||||
|
super(session);
|
||||||
|
this.cipher = cipher;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getInputStream() throws IOException {
|
||||||
|
return new CipherInputStream(wrapped.getInputStream(), cipher);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OutputStream getOutputStream() throws IOException {
|
||||||
|
return new CipherOutputStream(wrapped.getOutputStream(), cipher);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
wrapped.close();
|
||||||
|
}
|
||||||
|
}
|
|
@ -55,7 +55,7 @@ public class JingleIncomingFileOffer extends AbstractJingleFileOffer<RemoteFile>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTransportReady(BytestreamSession bytestreamSession) {
|
public void onBytestreamReady(BytestreamSession bytestreamSession) {
|
||||||
LOGGER.log(Level.INFO, "Receive file to " + target.getAbsolutePath());
|
LOGGER.log(Level.INFO, "Receive file to " + target.getAbsolutePath());
|
||||||
File mFile = target;
|
File mFile = target;
|
||||||
if (!mFile.exists()) {
|
if (!mFile.exists()) {
|
||||||
|
|
|
@ -55,7 +55,7 @@ public class JingleIncomingFileRequest extends AbstractJingleFileRequest<RemoteF
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTransportReady(BytestreamSession bytestreamSession) {
|
public void onBytestreamReady(BytestreamSession bytestreamSession) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ public class JingleOutgoingFileOffer extends AbstractJingleFileOffer<LocalFile>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTransportReady(BytestreamSession bytestreamSession) {
|
public void onBytestreamReady(BytestreamSession bytestreamSession) {
|
||||||
File mFile = ((LocalFile) file).getFile();
|
File mFile = ((LocalFile) file).getFile();
|
||||||
OutputStream outputStream = null;
|
OutputStream outputStream = null;
|
||||||
InputStream inputStream = null;
|
InputStream inputStream = null;
|
||||||
|
|
|
@ -47,7 +47,7 @@ public class JingleOutgoingFileRequest extends AbstractJingleFileRequest<RemoteF
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTransportReady(BytestreamSession bytestreamSession) {
|
public void onBytestreamReady(BytestreamSession bytestreamSession) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 2017 Paul Schaub
|
||||||
|
*
|
||||||
|
* 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.jingle.callbacks;
|
||||||
|
|
||||||
|
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback used to signal success/failure of Jingle Security components.
|
||||||
|
*/
|
||||||
|
public interface JingleSecurityCallback {
|
||||||
|
|
||||||
|
void onSecurityReady(BytestreamSession bytestreamSession);
|
||||||
|
|
||||||
|
void onSecurityFailed(Exception e);
|
||||||
|
}
|
|
@ -37,6 +37,7 @@ import org.jivesoftware.smackx.jingle.JingleTransportManager;
|
||||||
import org.jivesoftware.smackx.jingle.adapter.JingleDescriptionAdapter;
|
import org.jivesoftware.smackx.jingle.adapter.JingleDescriptionAdapter;
|
||||||
import org.jivesoftware.smackx.jingle.adapter.JingleSecurityAdapter;
|
import org.jivesoftware.smackx.jingle.adapter.JingleSecurityAdapter;
|
||||||
import org.jivesoftware.smackx.jingle.adapter.JingleTransportAdapter;
|
import org.jivesoftware.smackx.jingle.adapter.JingleTransportAdapter;
|
||||||
|
import org.jivesoftware.smackx.jingle.callbacks.JingleSecurityCallback;
|
||||||
import org.jivesoftware.smackx.jingle.callbacks.JingleTransportCallback;
|
import org.jivesoftware.smackx.jingle.callbacks.JingleTransportCallback;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionElement;
|
import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionElement;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleContentElement;
|
import org.jivesoftware.smackx.jingle.element.JingleContentElement;
|
||||||
|
@ -48,7 +49,7 @@ import org.jivesoftware.smackx.jingle.element.JingleReasonElement;
|
||||||
/**
|
/**
|
||||||
* Internal class that holds the state of a content in a modifiable form.
|
* Internal class that holds the state of a content in a modifiable form.
|
||||||
*/
|
*/
|
||||||
public class JingleContent implements JingleTransportCallback {
|
public class JingleContent implements JingleTransportCallback, JingleSecurityCallback {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(JingleContent.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(JingleContent.class.getName());
|
||||||
|
|
||||||
|
@ -131,7 +132,7 @@ public class JingleContent implements JingleTransportCallback {
|
||||||
return new JingleContent(description, transport, security, content.getName(), content.getDisposition(), content.getCreator(), content.getSenders());
|
return new JingleContent(description, transport, security, content.getName(), content.getDisposition(), content.getCreator(), content.getSenders());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* HANDLEXYZ */
|
/* HANDLE_XYZ */
|
||||||
|
|
||||||
public IQ handleJingleRequest(JingleElement request, XMPPConnection connection) {
|
public IQ handleJingleRequest(JingleElement request, XMPPConnection connection) {
|
||||||
switch (request.getAction()) {
|
switch (request.getAction()) {
|
||||||
|
@ -334,7 +335,17 @@ public class JingleContent implements JingleTransportCallback {
|
||||||
throw new AssertionError("bytestreamSession MUST NOT be null at this point.");
|
throw new AssertionError("bytestreamSession MUST NOT be null at this point.");
|
||||||
}
|
}
|
||||||
|
|
||||||
description.onTransportReady(bytestreamSession);
|
if (security != null) {
|
||||||
|
if (isReceiving()) {
|
||||||
|
LOGGER.log(Level.INFO, "Decrypt incoming Bytestream.");
|
||||||
|
getSecurity().decryptIncomingBytestream(bytestreamSession, this);
|
||||||
|
} else if (isSending()) {
|
||||||
|
LOGGER.log(Level.INFO, "Encrypt outgoing Bytestream.");
|
||||||
|
getSecurity().encryptIncomingBytestream(bytestreamSession, this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
description.onBytestreamReady(bytestreamSession);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -352,6 +363,16 @@ public class JingleContent implements JingleTransportCallback {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSecurityReady(BytestreamSession bytestreamSession) {
|
||||||
|
getDescription().onBytestreamReady(bytestreamSession);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSecurityFailed(Exception e) {
|
||||||
|
LOGGER.log(Level.SEVERE, "Security failed: " + e, e);
|
||||||
|
}
|
||||||
|
|
||||||
private void replaceTransport(Set<String> blacklist, XMPPConnection connection)
|
private void replaceTransport(Set<String> blacklist, XMPPConnection connection)
|
||||||
throws SmackException.NotConnectedException, InterruptedException,
|
throws SmackException.NotConnectedException, InterruptedException,
|
||||||
XMPPException.XMPPErrorException, SmackException.NoResponseException {
|
XMPPException.XMPPErrorException, SmackException.NoResponseException {
|
||||||
|
|
|
@ -42,7 +42,7 @@ public abstract class JingleDescription<D extends JingleContentDescriptionElemen
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void onTransportReady(BytestreamSession bytestreamSession);
|
public abstract void onBytestreamReady(BytestreamSession bytestreamSession);
|
||||||
|
|
||||||
public abstract String getNamespace();
|
public abstract String getNamespace();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smackx.jingle.components;
|
package org.jivesoftware.smackx.jingle.components;
|
||||||
|
|
||||||
|
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
|
||||||
|
import org.jivesoftware.smackx.jingle.callbacks.JingleSecurityCallback;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleContentSecurityElement;
|
import org.jivesoftware.smackx.jingle.element.JingleContentSecurityElement;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleContentSecurityInfoElement;
|
import org.jivesoftware.smackx.jingle.element.JingleContentSecurityInfoElement;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleElement;
|
import org.jivesoftware.smackx.jingle.element.JingleElement;
|
||||||
|
@ -40,4 +42,8 @@ public abstract class JingleSecurity<D extends JingleContentSecurityElement> {
|
||||||
public JingleContent getParent() {
|
public JingleContent getParent() {
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract void decryptIncomingBytestream(BytestreamSession bytestreamSession, JingleSecurityCallback callback);
|
||||||
|
|
||||||
|
public abstract void encryptIncomingBytestream(BytestreamSession bytestreamSession, JingleSecurityCallback callbacks);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue