implemented support for for jingle encrypted transports (XEP-0396)
This commit is contained in:
		
							parent
							
								
									ff4d127b6f
								
							
						
					
					
						commit
						7ec1b443ab
					
				|  | @ -101,8 +101,8 @@ public final class Config { | |||
| 
 | ||||
| 
 | ||||
|     public static final boolean DISABLE_PROXY_LOOKUP = false; //useful to debug ibb | ||||
|     public static final boolean USE_DIRECT_JINGLE_CANDIDATES = false; | ||||
|     public static final boolean DISABLE_HTTP_UPLOAD = false; | ||||
|     public static final boolean USE_DIRECT_JINGLE_CANDIDATES = true; | ||||
|     public static final boolean DISABLE_HTTP_UPLOAD = true; | ||||
|     public static final boolean EXTENDED_SM_LOGGING = false; // log stanza counts | ||||
|     public static final boolean BACKGROUND_STANZA_LOGGING = false; //log all stanzas that were received while the app is in background | ||||
|     public static final boolean RESET_ATTEMPT_COUNT_ON_NETWORK_CHANGE = true; //setting to true might increase power consumption | ||||
|  |  | |||
|  | @ -29,6 +29,8 @@ public abstract class AbstractGenerator { | |||
| 			Content.Version.FT_5.getNamespace(), | ||||
| 			Namespace.JINGLE_TRANSPORTS_S5B, | ||||
| 			Namespace.JINGLE_TRANSPORTS_IBB, | ||||
| 			Namespace.JINGLE_ENCRYPTED_TRANSPORT, | ||||
| 			Namespace.JINGLE_ENCRYPTED_TRANSPORT_OMEMO, | ||||
| 			"http://jabber.org/protocol/muc", | ||||
| 			"jabber:x:conference", | ||||
| 			Namespace.OOB, | ||||
|  |  | |||
|  | @ -30,4 +30,6 @@ public final class Namespace { | |||
| 	public static final String PING = "urn:xmpp:ping"; | ||||
| 	public static final String PUSH = "urn:xmpp:push:0"; | ||||
| 	public static final String COMMANDS = "http://jabber.org/protocol/commands"; | ||||
| 	public static final String JINGLE_ENCRYPTED_TRANSPORT = "urn:xmpp:jingle:jet:0"; | ||||
| 	public static final String JINGLE_ENCRYPTED_TRANSPORT_OMEMO = "urn:xmpp:jingle:jet-omemo:0"; | ||||
| } | ||||
|  |  | |||
|  | @ -43,6 +43,8 @@ import rocks.xmpp.addr.Jid; | |||
| 
 | ||||
| public class JingleConnection implements Transferable { | ||||
| 
 | ||||
|     private static final String JET_OMEMO_CIPHER = "urn:xmpp:ciphers:aes-128-gcm-nopadding"; | ||||
| 
 | ||||
|     private static final int JINGLE_STATUS_INITIATED = 0; | ||||
|     private static final int JINGLE_STATUS_ACCEPTED = 1; | ||||
|     private static final int JINGLE_STATUS_FINISHED = 4; | ||||
|  | @ -72,6 +74,7 @@ public class JingleConnection implements Transferable { | |||
|     private String contentName; | ||||
|     private String contentCreator; | ||||
|     private Transport initialTransport; | ||||
|     private boolean remoteSupportsOmemoJet; | ||||
| 
 | ||||
|     private int mProgress = 0; | ||||
| 
 | ||||
|  | @ -295,8 +298,10 @@ public class JingleConnection implements Transferable { | |||
|         this.contentName = this.mJingleConnectionManager.nextRandomId(); | ||||
|         this.message = message; | ||||
|         this.account = message.getConversation().getAccount(); | ||||
|         upgradeNamespace(); | ||||
|         this.initialTransport = getRemoteFeatures().contains(Namespace.JINGLE_TRANSPORTS_S5B) ? Transport.SOCKS : Transport.IBB; | ||||
|         final List<String> remoteFeatures = getRemoteFeatures(); | ||||
|         upgradeNamespace(remoteFeatures); | ||||
|         this.initialTransport = remoteFeatures.contains(Namespace.JINGLE_TRANSPORTS_S5B) ? Transport.SOCKS : Transport.IBB; | ||||
|         this.remoteSupportsOmemoJet = remoteFeatures.contains(Namespace.JINGLE_ENCRYPTED_TRANSPORT_OMEMO); | ||||
|         this.message.setTransferable(this); | ||||
|         this.mStatus = Transferable.STATUS_UPLOADING; | ||||
|         this.initiator = this.account.getJid(); | ||||
|  | @ -356,11 +361,10 @@ public class JingleConnection implements Transferable { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void upgradeNamespace() { | ||||
|         List<String> features = getRemoteFeatures(); | ||||
|         if (features.contains(Content.Version.FT_5.getNamespace())) { | ||||
|     private void upgradeNamespace(List<String> remoteFeatures) { | ||||
|         if (remoteFeatures.contains(Content.Version.FT_5.getNamespace())) { | ||||
|             this.ftVersion = Content.Version.FT_5; | ||||
|         } else if (features.contains(Content.Version.FT_4.getNamespace())) { | ||||
|         } else if (remoteFeatures.contains(Content.Version.FT_4.getNamespace())) { | ||||
|             this.ftVersion = Content.Version.FT_4; | ||||
|         } | ||||
|     } | ||||
|  | @ -430,6 +434,13 @@ public class JingleConnection implements Transferable { | |||
| 
 | ||||
|         if (fileOffer != null) { | ||||
|             Element encrypted = fileOffer.findChild("encrypted", AxolotlService.PEP_PREFIX); | ||||
|             if (encrypted == null) { | ||||
|                 final Element security = content.findChild("security", Namespace.JINGLE_ENCRYPTED_TRANSPORT); | ||||
|                 if (security != null && AxolotlService.PEP_PREFIX.equals(security.getAttribute("type"))) { | ||||
|                     Log.d(Config.LOGTAG, account.getJid().asBareJid()+": received jingle file offer with JET"); | ||||
|                     encrypted = security.findChild("encrypted", AxolotlService.PEP_PREFIX); | ||||
|                 } | ||||
|             } | ||||
|             if (encrypted != null) { | ||||
|                 this.mXmppAxolotlMessage = XmppAxolotlMessage.fromElement(encrypted, packet.getFrom().asBareJid()); | ||||
|             } | ||||
|  | @ -520,7 +531,18 @@ public class JingleConnection implements Transferable { | |||
|                 this.file.setKey(mXmppAxolotlMessage.getInnerKey()); | ||||
|                 this.file.setIv(mXmppAxolotlMessage.getIV()); | ||||
|                 this.file.setExpectedSize(file.getSize() + 16); | ||||
|                 content.setFileOffer(this.file, false, this.ftVersion).addChild(mXmppAxolotlMessage.toElement()); | ||||
|                 final Element file = content.setFileOffer(this.file, false, this.ftVersion); | ||||
|                 if (remoteSupportsOmemoJet) { | ||||
|                     Log.d(Config.LOGTAG, account.getJid().asBareJid()+": remote announced support for JET"); | ||||
|                     final Element security = new Element("security", Namespace.JINGLE_ENCRYPTED_TRANSPORT); | ||||
|                     security.setAttribute("name", this.contentName); | ||||
|                     security.setAttribute("cipher", JET_OMEMO_CIPHER); | ||||
|                     security.setAttribute("type", AxolotlService.PEP_PREFIX); | ||||
|                     security.addChild(mXmppAxolotlMessage.toElement()); | ||||
|                     content.addChild(security); | ||||
|                 } else { | ||||
|                     file.addChild(mXmppAxolotlMessage.toElement()); | ||||
|                 } | ||||
|             } else { | ||||
|                 this.file.setExpectedSize(file.getSize()); | ||||
|                 content.setFileOffer(this.file, false, this.ftVersion); | ||||
|  | @ -754,6 +776,8 @@ public class JingleConnection implements Transferable { | |||
|                 this.sendFallbackToIbb(); | ||||
|             } | ||||
|         } else { | ||||
|             final JingleCandidate candidate = connection.getCandidate(); | ||||
|             Log.d(Config.LOGTAG, account.getJid().asBareJid()+": elected candidate "+candidate.getHost()+":"+candidate.getPort()); | ||||
|             this.mJingleStatus = JINGLE_STATUS_TRANSMITTING; | ||||
|             if (connection.needsActivation()) { | ||||
|                 if (connection.getCandidate().isOurs()) { | ||||
|  |  | |||
|  | @ -16,6 +16,7 @@ import java.security.MessageDigest; | |||
| import java.security.NoSuchAlgorithmException; | ||||
| 
 | ||||
| import eu.siacs.conversations.Config; | ||||
| import eu.siacs.conversations.entities.Account; | ||||
| import eu.siacs.conversations.entities.DownloadableFile; | ||||
| import eu.siacs.conversations.persistance.FileBackend; | ||||
| import eu.siacs.conversations.services.AbstractConnectionManager; | ||||
|  | @ -134,11 +135,14 @@ public class JingleSocks5Transport extends JingleTransport { | |||
|             outputStream.write(response.array()); | ||||
|             outputStream.flush(); | ||||
|             if (success) { | ||||
|                 Log.d(Config.LOGTAG,connection.getAccount().getJid().asBareJid()+": successfully processed connection to candidate "+candidate.getHost()+":"+candidate.getPort()); | ||||
|                 this.socket = socket; | ||||
|                 this.inputStream = inputStream; | ||||
|                 this.outputStream = outputStream; | ||||
|                 this.isEstablished = true; | ||||
|                 FileBackend.close(serverSocket); | ||||
|             } else { | ||||
|                 this.socket.close(); | ||||
|             } | ||||
|         } else { | ||||
|             socket.close(); | ||||
|  | @ -174,6 +178,7 @@ public class JingleSocks5Transport extends JingleTransport { | |||
|         new Thread(() -> { | ||||
|             InputStream fileInputStream = null; | ||||
|             final PowerManager.WakeLock wakeLock = connection.getConnectionManager().createWakeLock("jingle_send_" + connection.getSessionId()); | ||||
|             long transmitted = 0; | ||||
|             try { | ||||
|                 wakeLock.acquire(); | ||||
|                 MessageDigest digest = MessageDigest.getInstance("SHA-1"); | ||||
|  | @ -186,7 +191,6 @@ public class JingleSocks5Transport extends JingleTransport { | |||
|                 } | ||||
|                 final InputStream innerInputStream = AbstractConnectionManager.upgrade(file, fileInputStream); | ||||
|                 long size = file.getExpectedSize(); | ||||
|                 long transmitted = 0; | ||||
|                 int count; | ||||
|                 byte[] buffer = new byte[8192]; | ||||
|                 while ((count = innerInputStream.read(buffer)) > 0) { | ||||
|  | @ -201,7 +205,8 @@ public class JingleSocks5Transport extends JingleTransport { | |||
|                     callback.onFileTransmitted(file); | ||||
|                 } | ||||
|             } catch (Exception e) { | ||||
|                 Log.d(Config.LOGTAG, connection.getAccount().getJid().asBareJid() + ": " + e.getMessage()); | ||||
|                 final Account account = connection.getAccount(); | ||||
|                 Log.d(Config.LOGTAG, account.getJid().asBareJid()+": failed sending file after "+transmitted+"/"+file.getExpectedSize()+" ("+ socket.getInetAddress()+":"+socket.getPort()+")", e); | ||||
|                 callback.onFileTransferAborted(); | ||||
|             } finally { | ||||
|                 FileBackend.close(fileInputStream); | ||||
|  |  | |||
|  | @ -873,4 +873,5 @@ | |||
|   <string name="not_a_backup_file">A kiválasztott fájl nem a Conversations biztonsági mentése</string> | ||||
|   <string name="account_already_setup">Ez a fiók már be lett állítva</string> | ||||
|   <string name="please_enter_password">Kérem, adja meg a fiókhoz tartozó jelszót</string> | ||||
|   <string name="unable_to_perform_this_action">Nem sikerült ezt a cselekvést elvégezni</string> | ||||
| </resources> | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Daniel Gultsch
						Daniel Gultsch