make jingle implementation send file hash when using ft5
This commit is contained in:
		
							parent
							
								
									ef78721f94
								
							
						
					
					
						commit
						f47cf7ae67
					
				| @ -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; | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -1,5 +1,6 @@ | ||||
| package eu.siacs.conversations.xmpp.jingle; | ||||
| 
 | ||||
| import android.util.Base64; | ||||
| import android.util.Log; | ||||
| import android.util.Pair; | ||||
| 
 | ||||
| @ -7,6 +8,7 @@ import java.io.FileNotFoundException; | ||||
| import java.io.InputStream; | ||||
| import java.io.OutputStream; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Arrays; | ||||
| import java.util.Iterator; | ||||
| import java.util.List; | ||||
| import java.util.Locale; | ||||
| @ -29,6 +31,7 @@ import eu.siacs.conversations.parser.IqParser; | ||||
| import eu.siacs.conversations.persistance.FileBackend; | ||||
| import eu.siacs.conversations.services.AbstractConnectionManager; | ||||
| import eu.siacs.conversations.services.XmppConnectionService; | ||||
| import eu.siacs.conversations.utils.CryptoHelper; | ||||
| import eu.siacs.conversations.xml.Element; | ||||
| import eu.siacs.conversations.xmpp.OnIqPacketReceived; | ||||
| import eu.siacs.conversations.xmpp.jid.Jid; | ||||
| @ -92,12 +95,24 @@ public class JingleConnection implements Transferable { | ||||
| 			} | ||||
| 		} | ||||
| 	}; | ||||
| 	private byte[] expectedHash = new byte[0]; | ||||
| 
 | ||||
| 	final OnFileTransmissionStatusChanged onFileTransmissionSatusChanged = new OnFileTransmissionStatusChanged() { | ||||
| 	private boolean responding() { | ||||
| 		return responder.equals(account.getJid()); | ||||
| 	} | ||||
| 
 | ||||
| 	private boolean initiating() { | ||||
| 		return initiator.equals(account.getJid()); | ||||
| 	} | ||||
| 
 | ||||
| 	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); | ||||
| @ -111,6 +126,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); | ||||
| 				} | ||||
| @ -118,7 +136,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); | ||||
| 			} | ||||
| @ -145,9 +163,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"); | ||||
| 			} | ||||
| 		} | ||||
| @ -193,6 +211,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")) { | ||||
| @ -499,6 +529,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) { | ||||
| @ -653,7 +689,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 { | ||||
| @ -697,12 +733,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); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| @ -727,7 +763,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; | ||||
| 							} | ||||
| @ -777,7 +813,7 @@ public class JingleConnection implements Transferable { | ||||
| 
 | ||||
| 		@Override | ||||
| 		public void established() { | ||||
| 			JingleConnection.this.transport.send(file, onFileTransmissionSatusChanged); | ||||
| 			JingleConnection.this.transport.send(file, onFileTransmissionStatusChanged); | ||||
| 		} | ||||
| 	}; | ||||
| 
 | ||||
| @ -801,7 +837,7 @@ public class JingleConnection implements Transferable { | ||||
| 		answer.setContent(content); | ||||
| 
 | ||||
| 
 | ||||
| 		if (initiator.equals(account.getJid())) { | ||||
| 		if (initiating()) { | ||||
| 			this.sendJinglePacket(answer, new OnIqPacketReceived() { | ||||
| 				@Override | ||||
| 				public void onIqPacketReceived(Account account, IqPacket packet) { | ||||
| @ -812,7 +848,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) { | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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()); | ||||
|  | ||||
| @ -1,5 +1,7 @@ | ||||
| package eu.siacs.conversations.xmpp.jingle.stanzas; | ||||
| 
 | ||||
| import android.util.Base64; | ||||
| 
 | ||||
| import eu.siacs.conversations.xml.Element; | ||||
| import eu.siacs.conversations.xmpp.jid.Jid; | ||||
| import eu.siacs.conversations.xmpp.stanzas.IqPacket; | ||||
| @ -7,6 +9,7 @@ import eu.siacs.conversations.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)); | ||||
| 	} | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Daniel Gultsch
						Daniel Gultsch