aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Schneppe <christian@pix-art.de>2017-05-09 21:14:35 +0200
committerChristian Schneppe <christian@pix-art.de>2017-05-09 21:14:35 +0200
commite803f3ffa5ab1d451a30164f23c1d2cc3cb147b0 (patch)
treedc17ed0828c4c27c30d2ab365c34919577f03420
parent39d48e727039bc6c81ab04694fb7929f8414df8d (diff)
make jingle implementation send file hash when using ft5
-rw-r--r--src/main/java/de/pixart/messenger/entities/DownloadableFile.java6
-rw-r--r--src/main/java/de/pixart/messenger/xmpp/jingle/JingleConnection.java100
-rw-r--r--src/main/java/de/pixart/messenger/xmpp/jingle/JingleInbandTransport.java6
-rw-r--r--src/main/java/de/pixart/messenger/xmpp/jingle/JingleSocks5Transport.java4
-rw-r--r--src/main/java/de/pixart/messenger/xmpp/jingle/stanzas/JinglePacket.java19
5 files changed, 93 insertions, 42 deletions
diff --git a/src/main/java/de/pixart/messenger/entities/DownloadableFile.java b/src/main/java/de/pixart/messenger/entities/DownloadableFile.java
index ee0694196..f0a3aa00c 100644
--- a/src/main/java/de/pixart/messenger/entities/DownloadableFile.java
+++ b/src/main/java/de/pixart/messenger/entities/DownloadableFile.java
@@ -9,7 +9,7 @@ public class DownloadableFile extends File {
private static final long serialVersionUID = 2247012619505115863L;
private long expectedSize = 0;
- private String sha1sum;
+ private byte[] sha1sum;
private byte[] aeskey;
private byte[] iv = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
@@ -42,11 +42,11 @@ public class DownloadableFile extends File {
this.expectedSize = size;
}
- public String getSha1Sum() {
+ public byte[] getSha1Sum() {
return this.sha1sum;
}
- public void setSha1Sum(String sum) {
+ public void setSha1Sum(byte[] sum) {
this.sha1sum = sum;
}
diff --git a/src/main/java/de/pixart/messenger/xmpp/jingle/JingleConnection.java b/src/main/java/de/pixart/messenger/xmpp/jingle/JingleConnection.java
index 1ca924834..bf92a2c30 100644
--- a/src/main/java/de/pixart/messenger/xmpp/jingle/JingleConnection.java
+++ b/src/main/java/de/pixart/messenger/xmpp/jingle/JingleConnection.java
@@ -1,5 +1,6 @@
package de.pixart.messenger.xmpp.jingle;
+import android.util.Base64;
import android.util.Log;
import android.util.Pair;
@@ -8,6 +9,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
@@ -31,6 +33,7 @@ import de.pixart.messenger.parser.IqParser;
import de.pixart.messenger.persistance.FileBackend;
import de.pixart.messenger.services.AbstractConnectionManager;
import de.pixart.messenger.services.XmppConnectionService;
+import de.pixart.messenger.utils.CryptoHelper;
import de.pixart.messenger.xml.Element;
import de.pixart.messenger.xmpp.OnIqPacketReceived;
import de.pixart.messenger.xmpp.jid.Jid;
@@ -95,12 +98,16 @@ public class JingleConnection implements Transferable {
}
}
};
+ private byte[] expectedHash = new byte[0];
- final OnFileTransmissionStatusChanged onFileTransmissionSatusChanged = new OnFileTransmissionStatusChanged() {
+ final OnFileTransmissionStatusChanged onFileTransmissionStatusChanged = new OnFileTransmissionStatusChanged() {
@Override
public void onFileTransmitted(DownloadableFile file) {
- if (responder.equals(account.getJid())) {
+ if (responding()) {
+ if (expectedHash.length > 0 && !Arrays.equals(expectedHash, file.getSha1Sum())) {
+ Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": hashes did not match");
+ }
sendSuccess();
mXmppConnectionService.getFileBackend().updateFileParams(message);
mXmppConnectionService.databaseBackend.createMessage(message);
@@ -114,6 +121,9 @@ public class JingleConnection implements Transferable {
}
}
} else {
+ if (ftVersion == Content.Version.FT_5) { //older Conversations will break when receiving a session-info
+ sendHash();
+ }
if (message.getEncryption() == Message.ENCRYPTION_PGP) {
account.getPgpDecryptionService().decrypt(message, false);
}
@@ -121,7 +131,7 @@ public class JingleConnection implements Transferable {
file.delete();
}
}
- Log.d(Config.LOGTAG, "successfully transmitted file:" + file.getAbsolutePath() + " (" + file.getSha1Sum() + ")");
+ Log.d(Config.LOGTAG, "successfully transmitted file:" + file.getAbsolutePath() + " (" + CryptoHelper.bytesToHex(file.getSha1Sum()) + ")");
if (message.getEncryption() != Message.ENCRYPTION_PGP) {
mXmppConnectionService.getFileBackend().updateMediaScanner(file);
}
@@ -134,6 +144,14 @@ public class JingleConnection implements Transferable {
}
};
+ private boolean responding() {
+ return responder.equals(account.getJid());
+ }
+
+ private boolean initiating() {
+ return initiator.equals(account.getJid());
+ }
+
public InputStream getFileInputStream() {
return this.mFileInputStream;
}
@@ -148,9 +166,9 @@ public class JingleConnection implements Transferable {
public void success() {
if (initiator.equals(account.getJid())) {
Log.d(Config.LOGTAG, "we were initiating. sending file");
- transport.send(file, onFileTransmissionSatusChanged);
+ transport.send(file, onFileTransmissionStatusChanged);
} else {
- transport.receive(file, onFileTransmissionSatusChanged);
+ transport.receive(file, onFileTransmissionStatusChanged);
Log.d(Config.LOGTAG, "we were responding. receiving file");
}
}
@@ -196,6 +214,18 @@ public class JingleConnection implements Transferable {
}
} else if (packet.isAction("session-accept")) {
returnResult = receiveAccept(packet);
+ } else if (packet.isAction("session-info")) {
+ returnResult = true;
+ Element checksum = packet.getChecksum();
+ Element file = checksum == null ? null : checksum.findChild("file");
+ Element hash = file == null ? null : file.findChild("hash", "urn:xmpp:hashes:2");
+ if (hash != null && "sha-1".equalsIgnoreCase(hash.getAttribute("algo"))) {
+ try {
+ this.expectedHash = Base64.decode(hash.getContent(), Base64.DEFAULT);
+ } catch (Exception e) {
+ this.expectedHash = new byte[0];
+ }
+ }
} else if (packet.isAction("transport-info")) {
returnResult = receiveTransportInfo(packet);
} else if (packet.isAction("transport-replace")) {
@@ -503,6 +533,12 @@ public class JingleConnection implements Transferable {
}
}
+ private void sendHash() {
+ JinglePacket packet = this.bootstrapPacket("session-info");
+ packet.addChecksum(file.getSha1Sum(), ftVersion.getNamespace());
+ this.sendJinglePacket(packet);
+ }
+
private List<Element> getCandidatesAsElements() {
List<Element> elements = new ArrayList<>();
for (JingleCandidate c : this.candidates) {
@@ -657,7 +693,7 @@ public class JingleConnection implements Transferable {
if (connection == null) {
Log.d(Config.LOGTAG, "could not find suitable candidate");
this.disconnectSocks5Connections();
- if (this.initiator.equals(account.getJid())) {
+ if (initiating()) {
this.sendFallbackToIbb();
}
} else {
@@ -701,12 +737,12 @@ public class JingleConnection implements Transferable {
+ " was a proxy. waiting for other party to activate");
}
} else {
- if (initiator.equals(account.getJid())) {
+ if (initiating()) {
Log.d(Config.LOGTAG, "we were initiating. sending file");
- connection.send(file, onFileTransmissionSatusChanged);
+ connection.send(file, onFileTransmissionStatusChanged);
} else {
Log.d(Config.LOGTAG, "we were responding. receiving file");
- connection.receive(file, onFileTransmissionSatusChanged);
+ connection.receive(file, onFileTransmissionStatusChanged);
}
}
}
@@ -731,7 +767,7 @@ public class JingleConnection implements Transferable {
} else if (connection.getCandidate().getPriority() == currentConnection
.getCandidate().getPriority()) {
// Log.d(Config.LOGTAG,"found two candidates with same priority");
- if (initiator.equals(account.getJid())) {
+ if (initiating()) {
if (currentConnection.getCandidate().isOurs()) {
connection = currentConnection;
}
@@ -781,7 +817,7 @@ public class JingleConnection implements Transferable {
@Override
public void established() {
- JingleConnection.this.transport.send(file, onFileTransmissionSatusChanged);
+ JingleConnection.this.transport.send(file, onFileTransmissionStatusChanged);
}
};
@@ -802,7 +838,7 @@ public class JingleConnection implements Transferable {
content.setTransportId(this.transportId);
content.ibbTransport().setAttribute("block-size", this.ibbBlockSize);
answer.setContent(content);
- if (initiator.equals(account.getJid())) {
+ if (initiating()) {
this.sendJinglePacket(answer, new OnIqPacketReceived() {
@Override
public void onIqPacketReceived(Account account, IqPacket packet) {
@@ -813,7 +849,7 @@ public class JingleConnection implements Transferable {
}
});
} else {
- this.transport.receive(file, onFileTransmissionSatusChanged);
+ this.transport.receive(file, onFileTransmissionStatusChanged);
this.sendJinglePacket(answer);
}
return true;
@@ -831,10 +867,10 @@ public class JingleConnection implements Transferable {
}
this.transport = new JingleInbandTransport(this, this.transportId, this.ibbBlockSize);
//might be receive instead if we are not initiating
- if (initiator.equals(account.getJid())) {
+ if (initiating()) {
this.transport.connect(onIbbTransportConnected);
} else {
- this.transport.receive(file, onFileTransmissionSatusChanged);
+ this.transport.receive(file, onFileTransmissionStatusChanged);
}
return true;
} else {
@@ -843,14 +879,18 @@ public class JingleConnection implements Transferable {
}
private void receiveSuccess() {
- this.mJingleStatus = JINGLE_STATUS_FINISHED;
- this.mXmppConnectionService.markMessage(this.message, Message.STATUS_SEND_RECEIVED);
- this.disconnectSocks5Connections();
- if (this.transport != null && this.transport instanceof JingleInbandTransport) {
- this.transport.disconnect();
+ if (initiating()) {
+ this.mJingleStatus = JINGLE_STATUS_FINISHED;
+ this.mXmppConnectionService.markMessage(this.message, Message.STATUS_SEND_RECEIVED);
+ this.disconnectSocks5Connections();
+ if (this.transport != null && this.transport instanceof JingleInbandTransport) {
+ this.transport.disconnect();
+ }
+ this.message.setTransferable(null);
+ this.mJingleConnectionManager.finishConnection(this);
+ } else {
+ Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": received session-terminate/success while responding");
}
- this.message.setTransferable(null);
- this.mJingleConnectionManager.finishConnection(this);
}
public void cancel() {
@@ -860,7 +900,7 @@ public class JingleConnection implements Transferable {
}
this.sendCancel();
this.mJingleConnectionManager.finishConnection(this);
- if (this.responder.equals(account.getJid())) {
+ if (responding()) {
this.message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_FAILED));
if (this.file != null) {
file.delete();
@@ -886,7 +926,7 @@ public class JingleConnection implements Transferable {
FileBackend.close(mFileInputStream);
FileBackend.close(mFileOutputStream);
if (this.message != null) {
- if (this.responder.equals(account.getJid())) {
+ if (responding()) {
this.message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_FAILED));
if (this.file != null) {
file.delete();
@@ -992,14 +1032,6 @@ public class JingleConnection implements Transferable {
this.sendJinglePacket(packet);
}
- public Jid getInitiator() {
- return this.initiator;
- }
-
- public Jid getResponder() {
- return this.responder;
- }
-
public int getJingleStatus() {
return this.mJingleStatus;
}
@@ -1051,9 +1083,9 @@ public class JingleConnection implements Transferable {
}
interface OnProxyActivated {
- public void success();
+ void success();
- public void failed();
+ void failed();
}
public boolean hasTransportId(String sid) {
diff --git a/src/main/java/de/pixart/messenger/xmpp/jingle/JingleInbandTransport.java b/src/main/java/de/pixart/messenger/xmpp/jingle/JingleInbandTransport.java
index fbf494295..33750c16a 100644
--- a/src/main/java/de/pixart/messenger/xmpp/jingle/JingleInbandTransport.java
+++ b/src/main/java/de/pixart/messenger/xmpp/jingle/JingleInbandTransport.java
@@ -166,7 +166,7 @@ public class JingleInbandTransport extends JingleTransport {
int count = fileInputStream.read(buffer);
if (count == -1) {
sendClose();
- file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest()));
+ file.setSha1Sum(digest.digest());
this.onFileTransmissionStatusChanged.onFileTransmitted(file);
fileInputStream.close();
return;
@@ -193,7 +193,7 @@ public class JingleInbandTransport extends JingleTransport {
connection.updateProgress((int) ((((double) (this.fileSize - this.remainingSize)) / this.fileSize) * 100));
} else {
sendClose();
- file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest()));
+ file.setSha1Sum(digest.digest());
this.onFileTransmissionStatusChanged.onFileTransmitted(file);
fileInputStream.close();
}
@@ -214,7 +214,7 @@ public class JingleInbandTransport extends JingleTransport {
this.fileOutputStream.write(buffer);
this.digest.update(buffer);
if (this.remainingSize <= 0) {
- file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest()));
+ file.setSha1Sum(digest.digest());
fileOutputStream.flush();
fileOutputStream.close();
this.onFileTransmissionStatusChanged.onFileTransmitted(file);
diff --git a/src/main/java/de/pixart/messenger/xmpp/jingle/JingleSocks5Transport.java b/src/main/java/de/pixart/messenger/xmpp/jingle/JingleSocks5Transport.java
index 57d1afeba..aa30d69a5 100644
--- a/src/main/java/de/pixart/messenger/xmpp/jingle/JingleSocks5Transport.java
+++ b/src/main/java/de/pixart/messenger/xmpp/jingle/JingleSocks5Transport.java
@@ -112,7 +112,7 @@ public class JingleSocks5Transport extends JingleTransport {
connection.updateProgress((int) ((((double) transmitted) / size) * 100));
}
outputStream.flush();
- file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest()));
+ file.setSha1Sum(digest.digest());
if (callback != null) {
callback.onFileTransmitted(file);
}
@@ -168,7 +168,7 @@ public class JingleSocks5Transport extends JingleTransport {
}
fileOutputStream.flush();
fileOutputStream.close();
- file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest()));
+ file.setSha1Sum(digest.digest());
callback.onFileTransmitted(file);
} catch (Exception e) {
Log.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": " + e.getMessage());
diff --git a/src/main/java/de/pixart/messenger/xmpp/jingle/stanzas/JinglePacket.java b/src/main/java/de/pixart/messenger/xmpp/jingle/stanzas/JinglePacket.java
index de856772a..3f7cc8e5b 100644
--- a/src/main/java/de/pixart/messenger/xmpp/jingle/stanzas/JinglePacket.java
+++ b/src/main/java/de/pixart/messenger/xmpp/jingle/stanzas/JinglePacket.java
@@ -1,5 +1,7 @@
package de.pixart.messenger.xmpp.jingle.stanzas;
+import android.util.Base64;
+
import de.pixart.messenger.xml.Element;
import de.pixart.messenger.xmpp.jid.Jid;
import de.pixart.messenger.xmpp.stanzas.IqPacket;
@@ -7,6 +9,7 @@ import de.pixart.messenger.xmpp.stanzas.IqPacket;
public class JinglePacket extends IqPacket {
Content content = null;
Reason reason = null;
+ Element checksum = null;
Element jingle = new Element("jingle");
@Override
@@ -24,6 +27,7 @@ public class JinglePacket extends IqPacket {
this.reason.setChildren(reasonElement.getChildren());
this.reason.setAttributes(reasonElement.getAttributes());
}
+ this.checksum = child.findChild("checksum");
this.jingle.setAttributes(child.getAttributes());
}
return child;
@@ -50,6 +54,10 @@ public class JinglePacket extends IqPacket {
return this.reason;
}
+ public Element getChecksum() {
+ return this.checksum;
+ }
+
private void build() {
this.children.clear();
this.jingle.clearChildren();
@@ -60,6 +68,9 @@ public class JinglePacket extends IqPacket {
if (this.reason != null) {
jingle.addChild(this.reason);
}
+ if (this.checksum != null) {
+ jingle.addChild(checksum);
+ }
this.children.add(jingle);
this.setAttribute("type", "set");
}
@@ -93,4 +104,12 @@ public class JinglePacket extends IqPacket {
public boolean isAction(String action) {
return action.equalsIgnoreCase(this.getAction());
}
+
+ public void addChecksum(byte[] sha1Sum, String namespace) {
+ this.checksum = new Element("checksum", namespace);
+ checksum.setAttribute("creator", "initiator");
+ checksum.setAttribute("name", "a-file-offer");
+ Element hash = checksum.addChild("file").addChild("hash", "urn:xmpp:hashes:2");
+ hash.setAttribute("algo", "sha-1").setContent(Base64.encodeToString(sha1Sum, Base64.NO_WRAP));
+ }
}