diff options
author | lookshe <github@lookshe.org> | 2016-03-06 19:42:55 +0100 |
---|---|---|
committer | lookshe <github@lookshe.org> | 2016-03-06 19:42:55 +0100 |
commit | 3c400703e082a1b180b35d891b8fb3460c7d5b87 (patch) | |
tree | 28738dd90fc41b4ab71897f38d324828778ad2e3 /src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java | |
parent | 72114d732427266024cdd6e27cd8d1aa60afae2f (diff) | |
parent | f28d77dc42f6bac5a026e0b1c78562dee8de45ac (diff) |
Merge branch 'trz/rebase' into trz/rename
Diffstat (limited to 'src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java')
-rw-r--r-- | src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java | 168 |
1 files changed, 121 insertions, 47 deletions
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java index 7885cc0f..c4ceeb4e 100644 --- a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java @@ -1,5 +1,12 @@ package de.thedevstack.conversationsplus.xmpp.jingle; +import android.content.Intent; +import android.net.Uri; +import android.util.Pair; + +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.io.OutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; @@ -8,22 +15,23 @@ import java.util.Locale; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; -import android.content.Intent; -import android.net.Uri; -import android.os.SystemClock; - import de.thedevstack.android.logcat.Logging; -import de.thedevstack.conversationsplus.Config; import de.thedevstack.conversationsplus.ConversationsPlusPreferences; +import de.thedevstack.conversationsplus.utils.MessageUtil; +import de.thedevstack.conversationsplus.utils.StreamUtil; +import de.thedevstack.conversationsplus.Config; +import de.thedevstack.conversationsplus.crypto.axolotl.AxolotlService; +import de.thedevstack.conversationsplus.crypto.axolotl.OnMessageCreatedCallback; +import de.thedevstack.conversationsplus.crypto.axolotl.XmppAxolotlMessage; import de.thedevstack.conversationsplus.entities.Account; import de.thedevstack.conversationsplus.entities.Conversation; -import de.thedevstack.conversationsplus.entities.Transferable; import de.thedevstack.conversationsplus.entities.DownloadableFile; -import de.thedevstack.conversationsplus.entities.TransferablePlaceholder; import de.thedevstack.conversationsplus.entities.Message; +import de.thedevstack.conversationsplus.entities.Transferable; +import de.thedevstack.conversationsplus.entities.TransferablePlaceholder; import de.thedevstack.conversationsplus.persistance.FileBackend; +import de.thedevstack.conversationsplus.services.AbstractConnectionManager; import de.thedevstack.conversationsplus.services.XmppConnectionService; -import de.thedevstack.conversationsplus.utils.MessageUtil; import de.thedevstack.conversationsplus.xml.Element; import de.thedevstack.conversationsplus.xmpp.OnIqPacketReceived; import de.thedevstack.conversationsplus.xmpp.jid.Jid; @@ -63,20 +71,24 @@ public class JingleConnection implements Transferable { private String contentCreator; private int mProgress = 0; - private long mLastGuiRefresh = 0; private boolean receivedCandidate = false; private boolean sentCandidate = false; private boolean acceptedAutomatically = false; + private XmppAxolotlMessage mXmppAxolotlMessage; + private JingleTransport transport = null; + private OutputStream mFileOutputStream; + private InputStream mFileInputStream; + private OnIqPacketReceived responseListener = new OnIqPacketReceived() { @Override public void onIqPacketReceived(Account account, IqPacket packet) { - if (packet.getType() == IqPacket.TYPE.ERROR) { + if (packet.getType() != IqPacket.TYPE.RESULT) { fail(); } } @@ -88,15 +100,13 @@ public class JingleConnection implements Transferable { public void onFileTransmitted(DownloadableFile file) { if (responder.equals(account.getJid())) { sendSuccess(); + MessageUtil.updateFileParams(message); + mXmppConnectionService.databaseBackend.createMessage(message); + mXmppConnectionService.markMessage(message,Message.STATUS_RECEIVED); if (acceptedAutomatically) { message.markUnread(); - JingleConnection.this.mXmppConnectionService - .getNotificationService().push(message); + JingleConnection.this.mXmppConnectionService.getNotificationService().push(message); } - MessageUtil.updateFileParams(message); - mXmppConnectionService.databaseBackend.createMessage(message); - mXmppConnectionService.markMessage(message, - Message.STATUS_RECEIVED); } else { if (message.getEncryption() == Message.ENCRYPTION_PGP || message.getEncryption() == Message.ENCRYPTION_DECRYPTED) { file.delete(); @@ -107,6 +117,8 @@ public class JingleConnection implements Transferable { Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); intent.setData(Uri.fromFile(file)); mXmppConnectionService.sendBroadcast(intent); + } else { + account.getPgpDecryptionService().add(message); } } @@ -117,6 +129,14 @@ public class JingleConnection implements Transferable { } }; + public InputStream getFileInputStream() { + return this.mFileInputStream; + } + + public OutputStream getFileOutputStream() { + return this.mFileOutputStream; + } + private OnProxyActivated onProxyActivated = new OnProxyActivated() { @Override @@ -198,7 +218,26 @@ public class JingleConnection implements Transferable { mXmppConnectionService.sendIqPacket(account,response,null); } - public void init(Message message) { + public void init(final Message message) { + if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL) { + Conversation conversation = message.getConversation(); + conversation.getAccount().getAxolotlService().prepareKeyTransportMessage(conversation.getContact(), new OnMessageCreatedCallback() { + @Override + public void run(XmppAxolotlMessage xmppAxolotlMessage) { + if (xmppAxolotlMessage != null) { + init(message, xmppAxolotlMessage); + } else { + fail(); + } + } + }); + } else { + init(message, null); + } + } + + private void init(Message message, XmppAxolotlMessage xmppAxolotlMessage) { + this.mXmppAxolotlMessage = xmppAxolotlMessage; this.contentCreator = "initiator"; this.contentName = this.mJingleConnectionManager.nextRandomId(); this.message = message; @@ -271,13 +310,16 @@ public class JingleConnection implements Transferable { this.contentCreator = content.getAttribute("creator"); this.contentName = content.getAttribute("name"); this.transportId = content.getTransportId(); - this.mergeCandidates(JingleCandidate.parse(content.socks5transport() - .getChildren())); + this.mergeCandidates(JingleCandidate.parse(content.socks5transport().getChildren())); this.fileOffer = packet.getJingleContent().getFileOffer(); mXmppConnectionService.sendIqPacket(account,packet.generateResponse(IqPacket.TYPE.RESULT),null); if (fileOffer != null) { + Element encrypted = fileOffer.findChild("encrypted", AxolotlService.PEP_PREFIX); + if (encrypted != null) { + this.mXmppAxolotlMessage = XmppAxolotlMessage.fromElement(encrypted, packet.getFrom().toBareJid()); + } Element fileSize = fileOffer.findChild("size"); Element fileNameElement = fileOffer.findChild("name"); if (fileNameElement != null) { @@ -323,10 +365,9 @@ public class JingleConnection implements Transferable { message.setBody(Long.toString(size)); conversation.add(message); mXmppConnectionService.updateConversationUi(); - if (size <= ConversationsPlusPreferences.autoAcceptFileSize() - && mXmppConnectionService.isDownloadAllowedInConnection()) { - Logging.d(Config.LOGTAG, "auto accepting file from " - + packet.getFrom()); + if (mJingleConnectionManager.hasStoragePermission() + && size < ConversationsPlusPreferences.autoAcceptFileSize()) { + Logging.d(Config.LOGTAG, "auto accepting file from "+ packet.getFrom()); this.acceptedAutomatically = true; this.sendAccept(); } else { @@ -336,21 +377,36 @@ public class JingleConnection implements Transferable { + size + " allowed size:" + ConversationsPlusPreferences.autoAcceptFileSize()); - this.mXmppConnectionService.getNotificationService() - .push(message); + this.mXmppConnectionService.getNotificationService().push(message); } this.file = FileBackend.getFile(message, false); - if (message.getEncryption() == Message.ENCRYPTION_OTR) { + if (mXmppAxolotlMessage != null) { + XmppAxolotlMessage.XmppAxolotlKeyTransportMessage transportMessage = account.getAxolotlService().processReceivingKeyTransportMessage(mXmppAxolotlMessage); + if (transportMessage != null) { + message.setEncryption(Message.ENCRYPTION_AXOLOTL); + this.file.setKey(transportMessage.getKey()); + this.file.setIv(transportMessage.getIv()); + message.setAxolotlFingerprint(transportMessage.getFingerprint()); + } else { + Logging.d(Config.LOGTAG,"could not process KeyTransportMessage"); + } + } else if (message.getEncryption() == Message.ENCRYPTION_OTR) { byte[] key = conversation.getSymmetricKey(); if (key == null) { this.sendCancel(); this.fail(); return; } else { - this.file.setKey(key); + this.file.setKeyAndIv(key); } } - this.file.setExpectedSize(size); + this.mFileOutputStream = AbstractConnectionManager.createOutputStream(this.file,message.getEncryption() == Message.ENCRYPTION_AXOLOTL); + if (message.getEncryption() == Message.ENCRYPTION_OTR && Config.REPORT_WRONG_FILESIZE_IN_OTR_JINGLE) { + this.file.setExpectedSize((size / 16 + 1) * 16); + } else { + this.file.setExpectedSize(size); + } + Logging.d(Config.LOGTAG, "receiving file: expecting size of " + this.file.getExpectedSize()); } else { this.sendCancel(); this.fail(); @@ -367,17 +423,34 @@ public class JingleConnection implements Transferable { if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE) { content.setTransportId(this.transportId); this.file = FileBackend.getFile(message, false); - if (message.getEncryption() == Message.ENCRYPTION_OTR) { - Conversation conversation = this.message.getConversation(); - if (!this.mXmppConnectionService.renewSymmetricKey(conversation)) { - Logging.d(Config.LOGTAG,account.getJid().toBareJid()+": could not set symmetric key"); - cancel(); + Pair<InputStream,Integer> pair; + try { + if (message.getEncryption() == Message.ENCRYPTION_OTR) { + Conversation conversation = this.message.getConversation(); + if (!this.mXmppConnectionService.renewSymmetricKey(conversation)) { + Logging.d(Config.LOGTAG, account.getJid().toBareJid() + ": could not set symmetric key"); + cancel(); + } + this.file.setKeyAndIv(conversation.getSymmetricKey()); + pair = AbstractConnectionManager.createInputStream(this.file, false); + this.file.setExpectedSize(pair.second); + content.setFileOffer(this.file, true); + } else if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL) { + this.file.setKey(mXmppAxolotlMessage.getInnerKey()); + this.file.setIv(mXmppAxolotlMessage.getIV()); + pair = AbstractConnectionManager.createInputStream(this.file, true); + this.file.setExpectedSize(pair.second); + content.setFileOffer(this.file, false).addChild(mXmppAxolotlMessage.toElement()); + } else { + pair = AbstractConnectionManager.createInputStream(this.file, false); + this.file.setExpectedSize(pair.second); + content.setFileOffer(this.file, false); } - content.setFileOffer(this.file, true); - this.file.setKey(conversation.getSymmetricKey()); - } else { - content.setFileOffer(this.file, false); + } catch (FileNotFoundException e) { + cancel(); + return; } + this.mFileInputStream = pair.first; this.transportId = this.mJingleConnectionManager.nextRandomId(); content.setTransportId(this.transportId); content.socks5transport().setChildren(getCandidatesAsElements()); @@ -386,7 +459,7 @@ public class JingleConnection implements Transferable { @Override public void onIqPacketReceived(Account account, IqPacket packet) { - if (packet.getType() != IqPacket.TYPE.ERROR) { + if (packet.getType() == IqPacket.TYPE.RESULT) { Logging.d(Config.LOGTAG,account.getJid().toBareJid()+": other party received offer"); mJingleStatus = JINGLE_STATUS_INITIATED; mXmppConnectionService.markMessage(message, Message.STATUS_OFFERED); @@ -571,12 +644,11 @@ public class JingleConnection implements Transferable { @Override public void onIqPacketReceived(Account account, IqPacket packet) { - if (packet.getType() == IqPacket.TYPE.ERROR) { + if (packet.getType() != IqPacket.TYPE.RESULT) { onProxyActivated.failed(); } else { onProxyActivated.success(); - sendProxyActivated(connection - .getCandidate().getCid()); + sendProxyActivated(connection.getCandidate().getCid()); } } }); @@ -675,8 +747,7 @@ public class JingleConnection implements Transferable { JinglePacket answer = bootstrapPacket("transport-accept"); Content content = new Content("initiator", "a-file-offer"); content.setTransportId(this.transportId); - content.ibbTransport().setAttribute("block-size", - Integer.toString(this.ibbBlockSize)); + content.ibbTransport().setAttribute("block-size",this.ibbBlockSize); answer.setContent(content); this.sendJinglePacket(answer); return true; @@ -749,6 +820,8 @@ public class JingleConnection implements Transferable { if (this.transport != null && this.transport instanceof JingleInbandTransport) { this.transport.disconnect(); } + StreamUtil.close(mFileInputStream); + StreamUtil.close(mFileOutputStream); if (this.message != null) { if (this.responder.equals(account.getJid())) { this.message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_FAILED)); @@ -902,10 +975,7 @@ public class JingleConnection implements Transferable { public void updateProgress(int i) { this.mProgress = i; - if (SystemClock.elapsedRealtime() - this.mLastGuiRefresh > Config.PROGRESS_UI_UPDATE_INTERVAL) { - this.mLastGuiRefresh = SystemClock.elapsedRealtime(); - mXmppConnectionService.updateConversationUi(); - } + mXmppConnectionService.updateConversationUi(); } interface OnProxyActivated { @@ -957,4 +1027,8 @@ public class JingleConnection implements Transferable { public int getProgress() { return this.mProgress; } + + public AbstractConnectionManager getConnectionManager() { + return this.mJingleConnectionManager; + } } |