From 47a904b4fc0d6644b53fdd41bebd0211b6e32b4a Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 26 Feb 2021 10:18:59 +0100 Subject: [PATCH 01/17] pulled translations from transifex --- src/main/res/values-da-rDK/strings.xml | 84 ++++++++++++++------------ 1 file changed, 45 insertions(+), 39 deletions(-) diff --git a/src/main/res/values-da-rDK/strings.xml b/src/main/res/values-da-rDK/strings.xml index 331a9ffaf..c96561f1f 100644 --- a/src/main/res/values-da-rDK/strings.xml +++ b/src/main/res/values-da-rDK/strings.xml @@ -36,8 +36,8 @@ %d ulæst samtaler - sender... - Dekrypter besked... Vent venligst... + sender… + Dekrypter besked… Vent venligst… OpenPGP krypteret besked Kaldenavn er allerede i brug Ugyldig kaldenavn @@ -56,7 +56,7 @@ Vil du gerne slette %s som et bogmærke? Samtaler med dette bogmærke vil ikke blive slettet. Register ny konto på server Ændr kodeord på server - Del med... + Del med… Start samtale Inviter kontakt Inviter @@ -84,7 +84,7 @@ levering mislykkedes Gør klar til at sende billede Gør klar til at sende billeder - Deler filer. Vent venligst... + Deler filer. Vent venligst… Ryd historik Ryd samtale historik Vil du slette alle beskeder i denne samtale?\n\nAdvarsel:Dette vil ikke påvirke beskeder gemt på andre enheder eller servere. @@ -95,8 +95,8 @@ Send ukrypteret besked Send besked Send besked to %s - Send OMEMO krypteret besked - Send v\\OMEMO krypteret besked + Send OMEMO-krypteret besked + Send v\\OMEMO-krypteret besked Send OpenPGP krypteret besked Nyt kaldenavn i brug Send ukrypteret @@ -106,15 +106,15 @@ Genstart Installer Installer venligst OpenKeychain - tilbyder... - Venter... + tilbyder… + Venter… Ingen Open PGP nøgler fundet Kunne ikke kryptere din besked, fordi din kontakt ikke annoncerer deres offentlige nøgle.\n\n Bed din kontakt om at konfigurere OpenPGP. Ingen OpenPGP nøgler fundet Kunne ikke kryptere din besked, fordi din kontakt ikke annoncerer deres offentlige nøgle.\n\n1Bed dem om at oprette OpenPGP. Generel Accepter filer - Accepter automatisk filer mindre end... + Accepter automatisk filer mindre end… Vedhæftninger Notifikation Vibrer @@ -214,13 +214,13 @@ Krypteret besked. Installer venligst OpenKeychain for dekryptere den? Ny OpenPGP krypteret beskeder fundet OpenPGP nøgle ID - OMEMO fingeraftryk + OMEMO-fingeraftryk v\\OMEMO fingeraftryk - OMEMO fingeraftryk (beskedoprindelse) - v\\OMEMO fingeraftryk (beskedoprindelse) + OMEMO-fingeraftryk (beskedoprindelse) + v\\OMEMO-fingeraftryk (beskedoprindelse) Andre enheder - Stol på OMEMO fingeraftryk - Henter nøgler... + Stol på OMEMO-fingeraftryk + Henter nøgler… Færdig Dekrypter Bogmærker @@ -246,7 +246,7 @@ Kunne ikke slette kanal Rediger titel på gruppechat Emne - Deltager i gruppechat... + Deltager i gruppechat… Forlad Kontakt tilføjede dig til kontaktliste Tilføj tilbage @@ -256,7 +256,7 @@ Alle har læst op til dette punkt Offentliggør Tryk på avatar for at vælge billede fra galleri - Offentliggørelse... + Offentliggørelse… Serveren afviste din offentliggørelse Kunne ikke konverter dit billede Kunne ikke gemme avatar til disk @@ -328,8 +328,8 @@ Opretter backup filer Din backup er oprettet Backup filerne er blevet gem i %s - Gendan sikkerhedskopi - Din sikkerhedskopi er blevet gendannet + Gendan backup + Din backup er blevet gendannet Glem ikke at aktivere kontoen. Vælg fil Modtager %1$s (%2$d%% fuldført) @@ -353,7 +353,7 @@ Ingen gruppechat server fundet Kunne ikke oprette gruppechat Konto avatar - Kopier OMEMO fingeraftryk til udklipsholder + Kopier OMEMO-fingeraftryk til udklipsholder Gendan OMEMO nøgle Ryd enheder Er du sikker på, at du vil rydde alle andre enheder fra OMEMO-meddelelsen? Næste gang dine enheder opretter forbindelse, annoncerer de sig selv, men de modtager muligvis ikke beskeder sendt i mellemtiden. @@ -362,7 +362,7 @@ Noget gik galt Henter historik fra server Ikke mere historik på server - Opdater... + Opdater… Kodeord ændret! Kunne ikke ændre kodeord Ændr kodeord @@ -419,9 +419,9 @@ Sender %s Tilbyder %s Skjul offline - %s skriver... + %s skriver… %s er holdt op med at skrive - %s skriver... + %s skriver… %s har stoppet skrivning Indtastningsnotifikation Lad dine kontakter vide når du skriver beskeder til dem @@ -509,7 +509,8 @@ Giv %1$s adgang til ekstern lagerplads Giv %1$s adgang til kameraet Synkroniser med kontakter -
Vi gemmer ikke en kopi af disse telefonnumre.\n\nFor mere information, læs vores privatlivspolitik.

Du vil bedes nu om at give tilladelse til at få adgang til dine kontakter.]]>
+ %1$s ønsker tilladelse til at få adgang til din adressebog for at matche den med din XMPP-kontaktliste.\nDette viser dine kontakters fulde navne og avatarer.\n\n%1$s læser kun din adressebog og matcher den lokalt uden at uploade noget til din server. +
Vi gemmer ikke en kopi af disse telefonnumre.\n\nFor mere information, læs vores privatlivspolitik.

Du vil bedes nu om at give tilladelse til at få adgang til dine kontakter.]]>
Underret ved alle beskeder Underret kun når nævnt Notifikationer deaktiveret @@ -532,7 +533,8 @@ Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsin Du har deaktiveret denne konto Sikkerhedsfejl: Ugyldig filadgang! Ingen app fundet der kan dele URL - Del URL med... + Del URL med… +
Du tilmelder dig med dit telefonnummer, og Quicksy vil automatisk - baseret på telefonnumre i din adressebog - foreslå mulige kontakter til dig.

Når du tilmelder dig, accepterer du vores privatlispolitik.]]>
Accepter og fortsætte En guide er oprettet til kontooprettelse på conversations.im.¹ \ nNår du vælger conversations.im som udbyder, kan du kommunikere med brugere fra andre udbydere ved at give dem din fulde XMPP-adresse. Din fulde XMPP adresse vil blive: %s @@ -552,7 +554,7 @@ Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsin Registrering mislykkes: Prøv igen senere Registring mislykkes: Adgangskode for svag Vælg deltager - Opretter gruppechat... + Opretter gruppechat… Inviter igen Deaktiver Kort @@ -585,13 +587,14 @@ Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsin Fjernserver timeout Kunne ikke opdatere konto Reporter denne XMPP adresse for spamming. - Slet OMEMO identiteter - Gendan dine OMEMO nøgler. Alle dine kontakter skal bekræfte dig igen. Brug kun dette som en sidste udvej. + Slet OMEMO-identiteter + Gendan dine OMEMO-nøgler. Alle dine kontakter skal bekræfte dig igen. Brug kun dette som en sidste udvej. Slet valgte nøgler Du skal være forbundet for at offentliggøre dit avatar. Vis fejlbesked Fejlbesked Datasparer aktiveret + Dit operativsystem begrænser %1$s adgangen til Internettet i baggrunden. For at modtage notifikationer om nye beskeder, skal du tillade %1$s ubegrænset adgang, når \"Datasparer\" er aktiveret. \n%1$s vil stadig gøre en indsats for at gemme data, når det er muligt. Din enhed understøtter ikke deaktivering af Databesparelse for %1$s. Kunne ikke oprette midlertidig fil Den enhed er blevet bekræftet @@ -614,8 +617,8 @@ Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsin Tøm privat lagerplads Tøm privat lagerplads, hvor filer opbevares (De kan downloades igen fra serveren) Jeg fulgte dette link fra en pålidelig kilde - Du er ved bekræfte OMEMO nøgler af %1$s efter du har klikket på et link. Dette er kun sikkert, hvis du fulgte linket fra troværdig kilde hvor kun %2$s kunne have offentliggjort dette link. - Beskræft OMEMO nøgler + Du er ved bekræfte OMEMO-nøgler af %1$s efter du har klikket på et link. Dette er kun sikkert, hvis du fulgte linket fra troværdig kilde hvor kun %2$s kunne have offentliggjort dette link. + Beskræft OMEMO-nøgler Vis inaktive Skjul inaktive Stol ikke på enhed @@ -695,9 +698,10 @@ Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsin Kunne ikke hente enhedsliste Kunne ikke hente krypteringsnøgler Tip: I nogle tilfælde kan dette løses ved at tilføje hinanden dine kontaktlister. + Er du sikker på, at du vil deaktivere OMEMO-kryptering til denne samtale?\nDette giver din serveradministrator mulighed for at læse dine meddelelser, men det er muligvis den eneste måde at kommunikere med folk, der bruger forældede klienter. Deaktiver nu Udkast: - OMEMO kryptering + OMEMO-kryptering OMEMO vil altid blive brugt for en-til-en og private gruppechats OMEMO vil blive brugt som standard for nye samlater. OMEMO skal være tændt udtrykkeligt for nye samtaler. @@ -710,7 +714,7 @@ Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsin Mellem Stor Besked var ikke krypteret på denne enhed - Dekryptering af OMEMO besked mislykkes. + Dekryptering af OMEMO-besked mislykkes. Fortryd Deling af placering er deaktiveret Fastgør position @@ -722,7 +726,7 @@ Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsin Vis placering Del Kunne ikke starte optagelse - Vent venligst... + Vent venligst… Giv %1$s adgang til mikrofonen Find beskeder GIF @@ -794,8 +798,8 @@ Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsin Er du sikker på at du afbryde registreringsproceduren? Ja Nej - Bekræfter... - Anmoder SMS... + Bekræfter… + Anmoder SMS… Den indtastet pinkode er forkert. Den sendte pinkode er udløbet. Ukendt netværksfejl. @@ -813,7 +817,7 @@ Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsin Du bruger en ældre version af denne app. Opdater Dette telefonnummer er i øjeblikket logget ind med en anden enhed. - Indtast dit navn for at lade folk, der ikke har dig i deres telefonbøger, vide, hvem du er. + Indtast dit navn for at lade folk, der ikke har dig i deres adressebog, vide, hvem du er. Dit navn Indtast dit navn Brug redigeringsknappen for at instille dit navn @@ -824,12 +828,13 @@ Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsin Denne kanal vil offentliggør din XMPP adresse e-bog Original (ukomprimeret) - Åbn med... + Åbn med… Conversations profil billede Vælg konto Gendan backup Gendan - Indtast din adgangskode til kontoen %s for at gendanne sikkerhedskopien. + Indtast din adgangskode til kontoen %s for at gendanne backuppen. + Brug ikke gendannelsessikkerhedsfunktionen i et forsøg på at klone (køre samtidigt) en installation. Gendannelse af en backup er kun beregnet til migreringer, eller hvis du har mistet den originale enhed. Kunne ikke gendan backup Kunne ikke dekryptere backup. Er adgangskoden korrekt? Backup & Gendan @@ -843,7 +848,7 @@ Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsin Angiv venligst et navn til kanalen Angiv venligst en XMPP adresse Dette er en XMPP adresse. Angiv venligst et navn - Opret offentlig kanal... + Opret offentlig kanal… Denne kanal eksister allerede Du sluttede dig til en eksisterende kanal Kunne ikke gemme kanalkonfiguration @@ -865,6 +870,7 @@ Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsin Find kanaler Find kanaler Mulig krænkelse af privatlivet! + search.jabber.network.

Brug af denne funktion sender din IP-adresse og søgetermer til denne service. Se deres Privatlivspolitik for mere information.]]>
Jeg har allerede en konto Tilføj eksisterende konto Registrer ny konto @@ -879,7 +885,7 @@ Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsin Denne konto er allerede oprettet Indtast adgangskoden til denne konto Kunne ikke udføre denne handling - Deltag i offentlig kanal... + Deltag i offentlig kanal… Dele-appen gav ikke tilladelse til at få adgang til denne fil. jabber.netværk From 8a6430ae29a50b0d71ea79884eaac4fe7841bb7d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 2 Mar 2021 21:13:49 +0100 Subject: [PATCH 02/17] ground work for omemo dtls verification --- .../crypto/axolotl/AxolotlService.java | 119 +++++++++++++++++- .../crypto/axolotl/XmppAxolotlMessage.java | 4 +- .../eu/siacs/conversations/xml/Namespace.java | 1 + .../xmpp/jingle/JingleRtpConnection.java | 86 +++++++++++-- .../xmpp/jingle/OmemoVerification.java | 83 ++++++++++++ .../jingle/OmemoVerifiedRtpContentMap.java | 19 +++ .../xmpp/jingle/RtpContentMap.java | 32 ++++- .../jingle/stanzas/IceUdpTransportInfo.java | 2 +- .../OmemoVerifiedIceUdpTransportInfo.java | 27 ++++ .../xmpp/jingle/stanzas/Proceed.java | 34 +++++ 10 files changed, 388 insertions(+), 19 deletions(-) create mode 100644 src/main/java/eu/siacs/conversations/xmpp/jingle/OmemoVerification.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/jingle/OmemoVerifiedRtpContentMap.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/jingle/stanzas/OmemoVerifiedIceUdpTransportInfo.java create mode 100644 src/main/java/eu/siacs/conversations/xmpp/jingle/stanzas/Proceed.java diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java index b43d331c8..57b0a0d43 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java @@ -8,6 +8,8 @@ import android.util.Pair; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.google.common.collect.ImmutableMap; + import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.whispersystems.libsignal.IdentityKey; import org.whispersystems.libsignal.IdentityKeyPair; @@ -49,9 +51,15 @@ import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.SerialSingleThreadExecutor; import eu.siacs.conversations.xml.Element; +import eu.siacs.conversations.xml.Namespace; import eu.siacs.conversations.xmpp.Jid; import eu.siacs.conversations.xmpp.OnAdvancedStreamFeaturesLoaded; import eu.siacs.conversations.xmpp.OnIqPacketReceived; +import eu.siacs.conversations.xmpp.jingle.OmemoVerification; +import eu.siacs.conversations.xmpp.jingle.OmemoVerifiedRtpContentMap; +import eu.siacs.conversations.xmpp.jingle.RtpContentMap; +import eu.siacs.conversations.xmpp.jingle.stanzas.IceUdpTransportInfo; +import eu.siacs.conversations.xmpp.jingle.stanzas.OmemoVerifiedIceUdpTransportInfo; import eu.siacs.conversations.xmpp.pep.PublishOptions; import eu.siacs.conversations.xmpp.stanzas.IqPacket; import eu.siacs.conversations.xmpp.stanzas.MessagePacket; @@ -1198,6 +1206,91 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { }); } + public OmemoVerifiedIceUdpTransportInfo encrypt(final IceUdpTransportInfo element, final XmppAxolotlSession session) throws CryptoFailedException { + final OmemoVerifiedIceUdpTransportInfo transportInfo = new OmemoVerifiedIceUdpTransportInfo(); + transportInfo.setAttributes(element.getAttributes()); + for (final Element child : element.getChildren()) { + if ("fingerprint".equals(child.getName()) && Namespace.JINGLE_APPS_DTLS.equals(child.getNamespace())) { + final Element fingerprint = new Element("fingerprint", Namespace.OMEMO_DTLS_SRTP_VERIFICATION); + fingerprint.setAttribute("setup", child.getAttribute("setup")); + fingerprint.setAttribute("hash", child.getAttribute("hash")); + final XmppAxolotlMessage axolotlMessage = new XmppAxolotlMessage(account.getJid().asBareJid(), getOwnDeviceId()); + final String content = child.getContent(); + axolotlMessage.encrypt(content); + axolotlMessage.addDevice(session); + fingerprint.addChild(axolotlMessage.toElement()); + transportInfo.addChild(fingerprint); + } else { + transportInfo.addChild(child); + } + } + return transportInfo; + } + + + public OmemoVerifiedPayload encrypt(final RtpContentMap rtpContentMap, final Jid jid, final int deviceId) throws CryptoFailedException { + final SignalProtocolAddress address = new SignalProtocolAddress(jid.asBareJid().toString(), deviceId); + final XmppAxolotlSession session = sessions.get(address); + final ImmutableMap.Builder descriptionTransportBuilder = new ImmutableMap.Builder<>(); + final OmemoVerification omemoVerification = new OmemoVerification(); + omemoVerification.setDeviceId(deviceId); + omemoVerification.setSessionFingerprint(session.getFingerprint()); + for (final Map.Entry content : rtpContentMap.contents.entrySet()) { + final RtpContentMap.DescriptionTransport descriptionTransport = content.getValue(); + final OmemoVerifiedIceUdpTransportInfo encryptedTransportInfo = encrypt(descriptionTransport.transport, session); + descriptionTransportBuilder.put( + content.getKey(), + new RtpContentMap.DescriptionTransport(descriptionTransport.description, encryptedTransportInfo) + ); + } + return new OmemoVerifiedPayload<>( + omemoVerification, + new OmemoVerifiedRtpContentMap(rtpContentMap.group, descriptionTransportBuilder.build()) + ); + } + + public OmemoVerifiedPayload decrypt(OmemoVerifiedRtpContentMap omemoVerifiedRtpContentMap, final Jid from) throws CryptoFailedException { + final ImmutableMap.Builder descriptionTransportBuilder = new ImmutableMap.Builder<>(); + final OmemoVerification omemoVerification = new OmemoVerification(); + for (final Map.Entry content : omemoVerifiedRtpContentMap.contents.entrySet()) { + final RtpContentMap.DescriptionTransport descriptionTransport = content.getValue(); + final OmemoVerifiedPayload decryptedTransport = decrypt((OmemoVerifiedIceUdpTransportInfo) descriptionTransport.transport, from); + omemoVerification.setOrEnsureEqual(decryptedTransport); + descriptionTransportBuilder.put( + content.getKey(), + new RtpContentMap.DescriptionTransport(descriptionTransport.description, decryptedTransport.payload) + ); + } + return new OmemoVerifiedPayload<>( + omemoVerification, + new RtpContentMap(omemoVerifiedRtpContentMap.group, descriptionTransportBuilder.build()) + ); + } + + public OmemoVerifiedPayload decrypt(final OmemoVerifiedIceUdpTransportInfo verifiedIceUdpTransportInfo, final Jid from) throws CryptoFailedException { + final IceUdpTransportInfo transportInfo = new IceUdpTransportInfo(); + transportInfo.setAttributes(verifiedIceUdpTransportInfo.getAttributes()); + final OmemoVerification omemoVerification = new OmemoVerification(); + for (final Element child : verifiedIceUdpTransportInfo.getChildren()) { + if ("fingerprint".equals(child.getName()) && Namespace.OMEMO_DTLS_SRTP_VERIFICATION.equals(child.getNamespace())) { + final Element fingerprint = new Element("fingerprint", Namespace.JINGLE_APPS_DTLS); + fingerprint.setAttribute("setup", child.getAttribute("setup")); + fingerprint.setAttribute("hash", child.getAttribute("hash")); + final Element encrypted = child.findChildEnsureSingle(XmppAxolotlMessage.CONTAINERTAG, AxolotlService.PEP_PREFIX); + final XmppAxolotlMessage xmppAxolotlMessage = XmppAxolotlMessage.fromElement(encrypted, from.asBareJid()); + final XmppAxolotlSession session = getReceivingSession(xmppAxolotlMessage); + final XmppAxolotlMessage.XmppAxolotlPlaintextMessage plaintext = xmppAxolotlMessage.decrypt(session, getOwnDeviceId()); + fingerprint.setContent(plaintext.getPlaintext()); + omemoVerification.setDeviceId(session.getRemoteAddress().getDeviceId()); + omemoVerification.setSessionFingerprint(plaintext.getFingerprint()); + transportInfo.addChild(fingerprint); + } else { + transportInfo.addChild(child); + } + } + return new OmemoVerifiedPayload<>(omemoVerification, transportInfo); + } + public void prepareKeyTransportMessage(final Conversation conversation, final OnMessageCreatedCallback onMessageCreatedCallback) { executor.execute(new Runnable() { @Override @@ -1267,7 +1360,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { } catch (final BrokenSessionException e) { throw e; } catch (final OutdatedSenderException e) { - Log.e(Config.LOGTAG,account.getJid().asBareJid()+": "+e.getMessage()); + Log.e(Config.LOGTAG, account.getJid().asBareJid() + ": " + e.getMessage()); throw e; } catch (CryptoFailedException e) { Log.w(Config.LOGTAG, getLogprefix(account) + "Failed to decrypt message from " + message.getFrom(), e); @@ -1565,4 +1658,28 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { } } } + + public static class OmemoVerifiedPayload { + private final int deviceId; + private final String fingerprint; + private final T payload; + + private OmemoVerifiedPayload(OmemoVerification omemoVerification, T payload) { + this.deviceId = omemoVerification.getDeviceId(); + this.fingerprint = omemoVerification.getFingerprint(); + this.payload = payload; + } + + public int getDeviceId() { + return deviceId; + } + + public String getFingerprint() { + return fingerprint; + } + + public T getPayload() { + return payload; + } + } } diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java index 1c9db15f9..bba24d90b 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java @@ -59,7 +59,7 @@ public class XmppAxolotlMessage { switch (keyElement.getName()) { case KEYTAG: try { - Integer recipientId = Integer.parseInt(keyElement.getAttribute(REMOTEID)); + int recipientId = Integer.parseInt(keyElement.getAttribute(REMOTEID)); byte[] key = Base64.decode(keyElement.getContent().trim(), Base64.DEFAULT); boolean isPreKey = keyElement.getAttributeAsBoolean("prekey"); this.keys.add(new XmppAxolotlSession.AxolotlKey(recipientId, key, isPreKey)); @@ -145,7 +145,7 @@ public class XmppAxolotlMessage { return ciphertext != null; } - void encrypt(String plaintext) throws CryptoFailedException { + void encrypt(final String plaintext) throws CryptoFailedException { try { SecretKey secretKey = new SecretKeySpec(innerKey, KEYTYPE); IvParameterSpec ivSpec = new IvParameterSpec(iv); diff --git a/src/main/java/eu/siacs/conversations/xml/Namespace.java b/src/main/java/eu/siacs/conversations/xml/Namespace.java index b65076016..29b4bf395 100644 --- a/src/main/java/eu/siacs/conversations/xml/Namespace.java +++ b/src/main/java/eu/siacs/conversations/xml/Namespace.java @@ -53,4 +53,5 @@ public final class Namespace { public static final String INVITE = "urn:xmpp:invite"; public static final String PARS = "urn:xmpp:pars:0"; public static final String EASY_ONBOARDING_INVITE = "urn:xmpp:invite#invite"; + public static final String OMEMO_DTLS_SRTP_VERIFICATION = "http://gultsch.de/xmpp/drafts/omemo/dlts-srtp-verification"; } diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java index 572c9f766..5d00f0c00 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java @@ -30,6 +30,8 @@ import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import eu.siacs.conversations.Config; +import eu.siacs.conversations.crypto.axolotl.AxolotlService; +import eu.siacs.conversations.crypto.axolotl.CryptoFailedException; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Conversational; @@ -43,6 +45,7 @@ import eu.siacs.conversations.xmpp.Jid; import eu.siacs.conversations.xmpp.jingle.stanzas.Group; import eu.siacs.conversations.xmpp.jingle.stanzas.IceUdpTransportInfo; import eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket; +import eu.siacs.conversations.xmpp.jingle.stanzas.Proceed; import eu.siacs.conversations.xmpp.jingle.stanzas.Propose; import eu.siacs.conversations.xmpp.jingle.stanzas.Reason; import eu.siacs.conversations.xmpp.jingle.stanzas.RtpDescription; @@ -123,6 +126,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web private final WebRTCWrapper webRTCWrapper = new WebRTCWrapper(this); private final ArrayDeque>> pendingIceCandidates = new ArrayDeque<>(); + private final OmemoVerification omemoVerification = new OmemoVerification(); private final Message message; private State state = State.NULL; private StateTransitionException stateTransitionException; @@ -290,6 +294,25 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web } } + private RtpContentMap receiveRtpContentMap(final JinglePacket jinglePacket, final boolean expectVerification) { + final RtpContentMap receivedContentMap = RtpContentMap.of(jinglePacket); + if (receivedContentMap instanceof OmemoVerifiedRtpContentMap) { + final AxolotlService.OmemoVerifiedPayload omemoVerifiedPayload; + try { + omemoVerifiedPayload = id.account.getAxolotlService().decrypt((OmemoVerifiedRtpContentMap) receivedContentMap, id.with); + } catch (final CryptoFailedException e) { + throw new SecurityException("Unable to verify DTLS Fingerprint with OMEMO", e); + } + this.omemoVerification.setOrEnsureEqual(omemoVerifiedPayload); + Log.d(Config.LOGTAG,id.account.getJid().asBareJid()+": received verifiable DTLS fingerprint via "+this.omemoVerification); + return omemoVerifiedPayload.getPayload(); + } else if (expectVerification) { + throw new SecurityException("DTLS fingerprint was unexpectedly not verifiable"); + } else { + return receivedContentMap; + } + } + private void receiveSessionInitiate(final JinglePacket jinglePacket) { if (isInitiator()) { Log.d(Config.LOGTAG, String.format("%s: received session-initiate even though we were initiating", id.account.getJid().asBareJid())); @@ -298,7 +321,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web } final RtpContentMap contentMap; try { - contentMap = RtpContentMap.of(jinglePacket); + contentMap = receiveRtpContentMap(jinglePacket, false); contentMap.requireContentDescriptions(); contentMap.requireDTLSFingerprint(); } catch (final RuntimeException e) { @@ -328,6 +351,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web } if (transition(target, () -> this.initiatorRtpContentMap = contentMap)) { respondOk(jinglePacket); + //TODO Do not push empty set pendingIceCandidates.push(contentMap.contents.entrySet()); if (target == State.SESSION_INITIALIZED_PRE_APPROVED) { Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": automatically accepting session-initiate"); @@ -350,7 +374,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web } final RtpContentMap contentMap; try { - contentMap = RtpContentMap.of(jinglePacket); + contentMap = receiveRtpContentMap(jinglePacket, this.omemoVerification.hasFingerprint()); contentMap.requireContentDescriptions(); contentMap.requireDTLSFingerprint(); } catch (final RuntimeException e) { @@ -469,7 +493,23 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web private void sendSessionAccept(final RtpContentMap rtpContentMap) { this.responderRtpContentMap = rtpContentMap; this.transitionOrThrow(State.SESSION_ACCEPTED); - final JinglePacket sessionAccept = rtpContentMap.toJinglePacket(JinglePacket.Action.SESSION_ACCEPT, id.sessionId); + final RtpContentMap outgoingContentMap; + //TODO do on different thread + if (this.omemoVerification.hasDeviceId()) { + Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": encrypting session-accept"); + try { + final AxolotlService.OmemoVerifiedPayload verifiedPayload = id.account.getAxolotlService().encrypt(rtpContentMap, id.with, omemoVerification.getDeviceId()); + outgoingContentMap = verifiedPayload.getPayload(); + this.omemoVerification.setOrEnsureEqual(verifiedPayload); + } catch (final Exception e) { + //TODO fail application if something goes wrong here + Log.d(Config.LOGTAG, "unable to encrypt", e); + return; + } + } else { + outgoingContentMap = rtpContentMap; + } + final JinglePacket sessionAccept = outgoingContentMap.toJinglePacket(JinglePacket.Action.SESSION_ACCEPT, id.sessionId); send(sessionAccept); } @@ -480,7 +520,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web receivePropose(from, Propose.upgrade(message), serverMessageId, timestamp); break; case "proceed": - receiveProceed(from, serverMessageId, timestamp); + receiveProceed(from, Proceed.upgrade(message), serverMessageId, timestamp); break; case "retract": receiveRetract(from, serverMessageId, timestamp); @@ -621,7 +661,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web } } - private void receiveProceed(final Jid from, final String serverMsgId, final long timestamp) { + private void receiveProceed(final Jid from, final Proceed proceed, final String serverMsgId, final long timestamp) { final Set media = Preconditions.checkNotNull(this.proposedMedia, "Proposed media has to be set before handling proceed"); Preconditions.checkState(media.size() > 0, "Proposed media should not be empty"); if (from.equals(id.with)) { @@ -631,6 +671,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web this.message.setServerMsgId(serverMsgId); } this.message.setTime(timestamp); + this.omemoVerification.setDeviceId(proceed.getDeviceId()); this.sendSessionInitiate(media, State.SESSION_INITIALIZED_PRE_APPROVED); } else { Log.d(Config.LOGTAG, String.format("%s: ignoring proceed because already in %s", id.account.getJid().asBareJid(), this.state)); @@ -716,13 +757,31 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web } } - private void sendSessionInitiate(RtpContentMap rtpContentMap, final State targetState) { + private void sendSessionInitiate(final RtpContentMap rtpContentMap, final State targetState) { this.initiatorRtpContentMap = rtpContentMap; this.transitionOrThrow(targetState); - final JinglePacket sessionInitiate = rtpContentMap.toJinglePacket(JinglePacket.Action.SESSION_INITIATE, id.sessionId); + //TODO do on background thread? + final RtpContentMap outgoingContentMap = encryptSessionInitiate(rtpContentMap); + final JinglePacket sessionInitiate = outgoingContentMap.toJinglePacket(JinglePacket.Action.SESSION_INITIATE, id.sessionId); send(sessionInitiate); } + private RtpContentMap encryptSessionInitiate(final RtpContentMap rtpContentMap) { + if (this.omemoVerification.hasDeviceId()) { + final AxolotlService.OmemoVerifiedPayload verifiedPayload; + try { + verifiedPayload = id.account.getAxolotlService().encrypt(rtpContentMap, id.with, omemoVerification.getDeviceId()); + } catch (final CryptoFailedException e) { + Log.w(Config.LOGTAG,id.account.getJid().asBareJid()+": unable to use OMEMO DTLS verification on outgoing session initiate. falling back", e); + return rtpContentMap; + } + this.omemoVerification.setSessionFingerprint(verifiedPayload.getFingerprint()); + return verifiedPayload.getPayload(); + } else { + return rtpContentMap; + } + } + private void sendSessionTerminate(final Reason reason) { sendSessionTerminate(reason, null); } @@ -1055,12 +1114,17 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web private void sendJingleMessage(final String action, final Jid to) { final MessagePacket messagePacket = new MessagePacket(); - if ("proceed".equals(action)) { - messagePacket.setId(JINGLE_MESSAGE_PROCEED_ID_PREFIX + id.sessionId); - } messagePacket.setType(MessagePacket.TYPE_CHAT); //we want to carbon copy those messagePacket.setTo(to); - messagePacket.addChild(action, Namespace.JINGLE_MESSAGE).setAttribute("id", id.sessionId); + final Element intent = messagePacket.addChild(action, Namespace.JINGLE_MESSAGE).setAttribute("id", id.sessionId); + if ("proceed".equals(action)) { + messagePacket.setId(JINGLE_MESSAGE_PROCEED_ID_PREFIX + id.sessionId); + + //TODO only do this if OMEMO is enable so we have an easy way to opt out + final int deviceId = id.account.getAxolotlService().getOwnDeviceId(); + final Element device = intent.addChild("device", Namespace.OMEMO_DTLS_SRTP_VERIFICATION); + device.setAttribute("id", deviceId); + } messagePacket.addChild("store", "urn:xmpp:hints"); xmppConnectionService.sendMessagePacket(id.account, messagePacket); } diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/OmemoVerification.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/OmemoVerification.java new file mode 100644 index 000000000..0be0f2cf7 --- /dev/null +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/OmemoVerification.java @@ -0,0 +1,83 @@ +package eu.siacs.conversations.xmpp.jingle; + +import com.google.common.base.MoreObjects; +import com.google.common.base.Preconditions; + +import java.util.concurrent.atomic.AtomicBoolean; + +import eu.siacs.conversations.crypto.axolotl.AxolotlService; + +public class OmemoVerification { + + private final AtomicBoolean deviceIdWritten = new AtomicBoolean(false); + private final AtomicBoolean sessionFingerprintWritten = new AtomicBoolean(false); + private Integer deviceId; + private String sessionFingerprint; + + public void setDeviceId(final Integer id) { + if (deviceIdWritten.compareAndSet(false, true)) { + this.deviceId = id; + return; + } + throw new IllegalStateException("Device Id has already been set"); + } + + public int getDeviceId() { + Preconditions.checkNotNull(this.deviceId, "Device ID is null"); + return this.deviceId; + } + + public boolean hasDeviceId() { + return this.deviceId != null; + } + + public void setSessionFingerprint(final String fingerprint) { + Preconditions.checkNotNull(fingerprint, "Session fingerprint must not be null"); + if (sessionFingerprintWritten.compareAndSet(false, true)) { + this.sessionFingerprint = fingerprint; + return; + } + throw new IllegalStateException("Session fingerprint has already been set"); + } + + public String getFingerprint() { + return this.sessionFingerprint; + } + + public void setOrEnsureEqual(AxolotlService.OmemoVerifiedPayload omemoVerifiedPayload) { + setOrEnsureEqual(omemoVerifiedPayload.getDeviceId(), omemoVerifiedPayload.getFingerprint()); + } + + public void setOrEnsureEqual(final int deviceId, final String sessionFingerprint) { + Preconditions.checkNotNull(sessionFingerprint, "Session fingerprint must not be null"); + if (this.deviceIdWritten.get() || this.sessionFingerprintWritten.get()) { + if (this.sessionFingerprint == null) { + throw new IllegalStateException("No session fingerprint has been previously provided"); + } + if (!sessionFingerprint.equals(this.sessionFingerprint)) { + throw new IllegalStateException("Session Fingerprints did not match"); + } + if (this.deviceId == null) { + throw new IllegalStateException("No Device Id has been previously provided"); + } + if (this.deviceId != deviceId) { + throw new IllegalStateException("Device Ids did not match"); + } + } else { + this.setSessionFingerprint(sessionFingerprint); + this.setDeviceId(deviceId); + } + } + + public boolean hasFingerprint() { + return this.sessionFingerprint != null; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("deviceId", deviceId) + .add("fingerprint", sessionFingerprint) + .toString(); + } +} diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/OmemoVerifiedRtpContentMap.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/OmemoVerifiedRtpContentMap.java new file mode 100644 index 000000000..f5e041014 --- /dev/null +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/OmemoVerifiedRtpContentMap.java @@ -0,0 +1,19 @@ +package eu.siacs.conversations.xmpp.jingle; + +import java.util.Map; + +import eu.siacs.conversations.xmpp.jingle.stanzas.Group; +import eu.siacs.conversations.xmpp.jingle.stanzas.OmemoVerifiedIceUdpTransportInfo; + +public class OmemoVerifiedRtpContentMap extends RtpContentMap { + public OmemoVerifiedRtpContentMap(Group group, Map contents) { + super(group, contents); + for(final DescriptionTransport descriptionTransport : contents.values()) { + if (descriptionTransport.transport instanceof OmemoVerifiedIceUdpTransportInfo) { + ((OmemoVerifiedIceUdpTransportInfo) descriptionTransport.transport).ensureNoPlaintextFingerprint(); + continue; + } + throw new IllegalStateException("OmemoVerifiedRtpContentMap contains non-verified transport info"); + } + } +} diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/RtpContentMap.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/RtpContentMap.java index 11ad513b7..38935d8fb 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/RtpContentMap.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/RtpContentMap.java @@ -14,6 +14,7 @@ import com.google.common.collect.Sets; import org.checkerframework.checker.nullness.compatqual.NullableDecl; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; @@ -25,6 +26,7 @@ import eu.siacs.conversations.xmpp.jingle.stanzas.GenericTransportInfo; import eu.siacs.conversations.xmpp.jingle.stanzas.Group; import eu.siacs.conversations.xmpp.jingle.stanzas.IceUdpTransportInfo; import eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket; +import eu.siacs.conversations.xmpp.jingle.stanzas.OmemoVerifiedIceUdpTransportInfo; import eu.siacs.conversations.xmpp.jingle.stanzas.RtpDescription; public class RtpContentMap { @@ -32,13 +34,32 @@ public class RtpContentMap { public final Group group; public final Map contents; - private RtpContentMap(Group group, Map contents) { + public RtpContentMap(Group group, Map contents) { this.group = group; this.contents = contents; } public static RtpContentMap of(final JinglePacket jinglePacket) { - return new RtpContentMap(jinglePacket.getGroup(), DescriptionTransport.of(jinglePacket.getJingleContents())); + final Map contents = DescriptionTransport.of(jinglePacket.getJingleContents()); + if (isOmemoVerified(contents)) { + return new OmemoVerifiedRtpContentMap(jinglePacket.getGroup(), contents); + } else { + return new RtpContentMap(jinglePacket.getGroup(), contents); + } + } + + private static boolean isOmemoVerified(Map contents) { + final Collection values = contents.values(); + if (values.size() == 0) { + return false; + } + for(final DescriptionTransport descriptionTransport : values) { + if (descriptionTransport.transport instanceof OmemoVerifiedIceUdpTransportInfo) { + continue; + } + return false; + } + return true; } public static RtpContentMap of(final SessionDescription sessionDescription) { @@ -123,7 +144,7 @@ public class RtpContentMap { public final RtpDescription description; public final IceUdpTransportInfo transport; - DescriptionTransport(final RtpDescription description, final IceUdpTransportInfo transport) { + public DescriptionTransport(final RtpDescription description, final IceUdpTransportInfo transport) { this.description = description; this.transport = transport; } @@ -146,7 +167,10 @@ public class RtpContentMap { } else { throw new UnsupportedTransportException("Content does not contain ICE-UDP transport"); } - return new DescriptionTransport(rtpDescription, iceUdpTransportInfo); + return new DescriptionTransport( + rtpDescription, + OmemoVerifiedIceUdpTransportInfo.upgrade(iceUdpTransportInfo) + ); } public static DescriptionTransport of(final SessionDescription sessionDescription, final SessionDescription.Media media) { diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/stanzas/IceUdpTransportInfo.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/stanzas/IceUdpTransportInfo.java index e43556d17..022c4d2dd 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/stanzas/IceUdpTransportInfo.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/stanzas/IceUdpTransportInfo.java @@ -22,7 +22,7 @@ import eu.siacs.conversations.xmpp.jingle.SessionDescription; public class IceUdpTransportInfo extends GenericTransportInfo { - private IceUdpTransportInfo() { + public IceUdpTransportInfo() { super("transport", Namespace.JINGLE_TRANSPORT_ICE_UDP); } diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/stanzas/OmemoVerifiedIceUdpTransportInfo.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/stanzas/OmemoVerifiedIceUdpTransportInfo.java new file mode 100644 index 000000000..d59dbbb9a --- /dev/null +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/stanzas/OmemoVerifiedIceUdpTransportInfo.java @@ -0,0 +1,27 @@ +package eu.siacs.conversations.xmpp.jingle.stanzas; + +import eu.siacs.conversations.xml.Namespace; + +public class OmemoVerifiedIceUdpTransportInfo extends IceUdpTransportInfo { + + + public void ensureNoPlaintextFingerprint() { + if (this.findChild("fingerprint", Namespace.JINGLE_APPS_DTLS) != null) { + throw new IllegalStateException("OmemoVerifiedIceUdpTransportInfo contains plaintext fingerprint"); + } + } + + public static IceUdpTransportInfo upgrade(final IceUdpTransportInfo transportInfo) { + if (transportInfo.hasChild("fingerprint", Namespace.JINGLE_APPS_DTLS)) { + return transportInfo; + } + if (transportInfo.hasChild("fingerprint", Namespace.OMEMO_DTLS_SRTP_VERIFICATION)) { + final OmemoVerifiedIceUdpTransportInfo omemoVerifiedIceUdpTransportInfo = new OmemoVerifiedIceUdpTransportInfo(); + omemoVerifiedIceUdpTransportInfo.setAttributes(transportInfo.getAttributes()); + omemoVerifiedIceUdpTransportInfo.setChildren(transportInfo.getChildren()); + return omemoVerifiedIceUdpTransportInfo; + } + return transportInfo; + } + +} diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/stanzas/Proceed.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/stanzas/Proceed.java new file mode 100644 index 000000000..a9c399754 --- /dev/null +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/stanzas/Proceed.java @@ -0,0 +1,34 @@ +package eu.siacs.conversations.xmpp.jingle.stanzas; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; +import com.google.common.primitives.Ints; + +import java.util.List; + +import eu.siacs.conversations.xml.Element; +import eu.siacs.conversations.xml.Namespace; + +public class Proceed extends Element { + private Proceed() { + super("propose", Namespace.JINGLE_MESSAGE); + } + + public static Proceed upgrade(final Element element) { + Preconditions.checkArgument("proceed".equals(element.getName())); + Preconditions.checkArgument(Namespace.JINGLE_MESSAGE.equals(element.getNamespace())); + final Proceed propose = new Proceed(); + propose.setAttributes(element.getAttributes()); + propose.setChildren(element.getChildren()); + return propose; + } + + public Integer getDeviceId() { + final Element device = this.findChild("device"); + final String id = device == null ? null : device.getAttribute("id"); + if (id == null) { + return null; + } + return Ints.tryParse(id); + } +} From e4b2bb4a4209d7a227eb222bcdab1526c69bfad5 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 3 Mar 2021 08:22:21 +0100 Subject: [PATCH 03/17] throw exception when unable to encrypt --- .../conversations/crypto/axolotl/AxolotlService.java | 7 +++++-- .../conversations/xmpp/jingle/JingleRtpConnection.java | 9 +++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java index 57b0a0d43..ce8c3a381 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java @@ -1206,7 +1206,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { }); } - public OmemoVerifiedIceUdpTransportInfo encrypt(final IceUdpTransportInfo element, final XmppAxolotlSession session) throws CryptoFailedException { + private OmemoVerifiedIceUdpTransportInfo encrypt(final IceUdpTransportInfo element, final XmppAxolotlSession session) throws CryptoFailedException { final OmemoVerifiedIceUdpTransportInfo transportInfo = new OmemoVerifiedIceUdpTransportInfo(); transportInfo.setAttributes(element.getAttributes()); for (final Element child : element.getChildren()) { @@ -1231,6 +1231,9 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { public OmemoVerifiedPayload encrypt(final RtpContentMap rtpContentMap, final Jid jid, final int deviceId) throws CryptoFailedException { final SignalProtocolAddress address = new SignalProtocolAddress(jid.asBareJid().toString(), deviceId); final XmppAxolotlSession session = sessions.get(address); + if (session == null) { + throw new CryptoFailedException(String.format("No session found for %d", deviceId)); + } final ImmutableMap.Builder descriptionTransportBuilder = new ImmutableMap.Builder<>(); final OmemoVerification omemoVerification = new OmemoVerification(); omemoVerification.setDeviceId(deviceId); @@ -1267,7 +1270,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { ); } - public OmemoVerifiedPayload decrypt(final OmemoVerifiedIceUdpTransportInfo verifiedIceUdpTransportInfo, final Jid from) throws CryptoFailedException { + private OmemoVerifiedPayload decrypt(final OmemoVerifiedIceUdpTransportInfo verifiedIceUdpTransportInfo, final Jid from) throws CryptoFailedException { final IceUdpTransportInfo transportInfo = new IceUdpTransportInfo(); transportInfo.setAttributes(verifiedIceUdpTransportInfo.getAttributes()); final OmemoVerification omemoVerification = new OmemoVerification(); diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java index 5d00f0c00..68e03f403 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java @@ -494,17 +494,14 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web this.responderRtpContentMap = rtpContentMap; this.transitionOrThrow(State.SESSION_ACCEPTED); final RtpContentMap outgoingContentMap; - //TODO do on different thread if (this.omemoVerification.hasDeviceId()) { - Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": encrypting session-accept"); + final AxolotlService.OmemoVerifiedPayload verifiedPayload; try { - final AxolotlService.OmemoVerifiedPayload verifiedPayload = id.account.getAxolotlService().encrypt(rtpContentMap, id.with, omemoVerification.getDeviceId()); + verifiedPayload = id.account.getAxolotlService().encrypt(rtpContentMap, id.with, omemoVerification.getDeviceId()); outgoingContentMap = verifiedPayload.getPayload(); this.omemoVerification.setOrEnsureEqual(verifiedPayload); } catch (final Exception e) { - //TODO fail application if something goes wrong here - Log.d(Config.LOGTAG, "unable to encrypt", e); - return; + throw new SecurityException("Unable to verify DTLS Fingerprint with OMEMO", e); } } else { outgoingContentMap = rtpContentMap; From 3ee70b1d4834a7e805bd48fee0307bf8721ae29d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 3 Mar 2021 09:41:05 +0100 Subject: [PATCH 04/17] show verified shield in rtp session activity --- .../conversations/ui/RtpSessionActivity.java | 15 +++++++++++ .../xmpp/jingle/JingleRtpConnection.java | 10 ++++++++ src/main/res/layout/activity_rtp_session.xml | 25 ++++++++++--------- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java index fdd73f727..56839d501 100644 --- a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java @@ -389,6 +389,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe if (state != null) { Log.d(Config.LOGTAG, "restored last state from intent extra"); updateButtonConfiguration(state); + updateVerifiedShield(false); updateStateDisplay(state); updateProfilePicture(state); invalidateOptionsMenu(); @@ -558,6 +559,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe } this.rtpConnectionReference = reference; final RtpEndUserState currentState = requireRtpConnection().getEndUserState(); + final boolean verified = requireRtpConnection().isVerified(); if (currentState == RtpEndUserState.ENDED) { reference.get().throwStateTransitionException(); finish(); @@ -573,6 +575,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe binding.with.setText(getWith().getDisplayName()); updateVideoViews(currentState); updateStateDisplay(currentState, media); + updateVerifiedShield(verified && STATES_SHOWING_SWITCH_TO_CHAT.contains(currentState)); updateButtonConfiguration(currentState, media); updateProfilePicture(currentState); invalidateOptionsMenu(); @@ -591,6 +594,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe updateStateDisplay(state); updateProfilePicture(state); updateCallDuration(); + updateVerifiedShield(false); invalidateOptionsMenu(); binding.with.setText(account.getRoster().getContact(with).getDisplayName()); } @@ -672,6 +676,14 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe } } + private void updateVerifiedShield(final boolean verified) { + if (isPictureInPicture()) { + this.binding.verified.setVisibility(View.GONE); + return; + } + this.binding.verified.setVisibility(verified ? View.VISIBLE : View.GONE); + } + private void updateProfilePicture(final RtpEndUserState state) { updateProfilePicture(state, null); } @@ -1075,6 +1087,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe return; } final AbstractJingleConnection.Id id = requireRtpConnection().getId(); + final boolean verified = requireRtpConnection().isVerified(); final Set media = getMedia(); final Contact contact = getWith(); if (account == id.account && id.with.equals(with) && id.sessionId.equals(sessionId)) { @@ -1084,6 +1097,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe } runOnUiThread(() -> { updateStateDisplay(state, media); + updateVerifiedShield(verified && STATES_SHOWING_SWITCH_TO_CHAT.contains(state)); updateButtonConfiguration(state, media); updateVideoViews(state); updateProfilePicture(state, contact); @@ -1133,6 +1147,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe } if (Jid.ofEscaped(withExtra).asBareJid().equals(with)) { runOnUiThread(() -> { + updateVerifiedShield(false); updateStateDisplay(state); updateButtonConfiguration(state); updateProfilePicture(state); diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java index 68e03f403..aff365247 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java @@ -32,6 +32,7 @@ import java.util.concurrent.TimeUnit; import eu.siacs.conversations.Config; import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.crypto.axolotl.CryptoFailedException; +import eu.siacs.conversations.crypto.axolotl.FingerprintStatus; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Conversational; @@ -967,6 +968,15 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web } + public boolean isVerified() { + final String fingerprint = this.omemoVerification.getFingerprint(); + if (fingerprint == null) { + return false; + } + final FingerprintStatus status = id.account.getAxolotlService().getFingerprintTrust(fingerprint); + return status != null && status.getTrust() == FingerprintStatus.Trust.VERIFIED; + } + public synchronized void acceptCall() { switch (this.state) { case PROPOSED: diff --git a/src/main/res/layout/activity_rtp_session.xml b/src/main/res/layout/activity_rtp_session.xml index ccc02259a..f54295866 100644 --- a/src/main/res/layout/activity_rtp_session.xml +++ b/src/main/res/layout/activity_rtp_session.xml @@ -86,17 +86,14 @@ - @@ -106,22 +103,31 @@ android:layout_height="match_parent" android:layout_below="@+id/app_bar_layout" android:layout_alignParentStart="true" - android:layout_alignParentLeft="true" android:layout_alignParentBottom="true" android:visibility="gone" /> + + + android:visibility="gone" + app:tint="@color/white" /> Date: Wed, 3 Mar 2021 09:48:29 +0100 Subject: [PATCH 05/17] pulled translations from transifex --- .../res/values-da-rDK/strings.xml | 12 +- src/main/res/values-da-rDK/strings.xml | 125 +++++++++--------- src/main/res/values-gl/strings.xml | 62 ++++----- src/main/res/values-ru/strings.xml | 2 +- src/quicksy/res/values-da-rDK/strings.xml | 4 +- 5 files changed, 102 insertions(+), 103 deletions(-) diff --git a/src/conversations/res/values-da-rDK/strings.xml b/src/conversations/res/values-da-rDK/strings.xml index 56a1b0315..26c3f2c66 100644 --- a/src/conversations/res/values-da-rDK/strings.xml +++ b/src/conversations/res/values-da-rDK/strings.xml @@ -3,14 +3,14 @@ Vælg din XMPP udbyder Brug conversations.im Opret ny konto - Har du allerede en XMPP-konto? Dette kan være tilfældet, hvis du allerede bruger en anden XMPP-klient eller har brugt Conversations før. Hvis ikke, kan du nu oprette en ny XMPP-konto.\nTip: Nogle e-mail-udbydere leverer også XMPP-konti. - XMPP er et udbyderuafhængigt onlinemeddelelsesnetværk. Du kan bruge denne klient med hvilken XMPP-server du end vælger.\nMen for din nemheds skyld har vi gjort vi det let at oprette en konto på conversations.im¹; en udbyder, der er specielt velegnet til brug med Conversations. - Du er blevet inviteret til %1$s. Vi guider dig gennem processen med at oprette en konto.\nNår du vælger %1$s som udbyder, kan du kommunikere med brugere fra andre udbydere ved at give dem din fulde XMPP-adresse. - Du er blevet inviteret til %1$s. Der er allerede valgt et brugernavn til dig. Vi guider dig gennem processen med at oprette en konto.\nDu vil være i stand til at kommunikere med brugere fra andre udbydere ved at give dem din fulde XMPP-adresse. + Har du allerede en XMPP konto? Dette kan være tilfældet, hvis du allerede bruger en anden XMPP klient eller har brugt Conversations før. Hvis ikke, kan du lige nu oprette en ny XMPP konto.\nTip: Nogle e-mail-udbydere leverer også XMPP konti. + XMPP er et udbyderuafhængigt onlinemeddelelsesnetværk. Du kan bruge denne klient med hvilken XMPP server du end vælger.\nMen for din nemheds skyld har vi gjort vi det let at oprette en konto på conversations.im¹; en udbyder, der er specielt velegnet til brug med Conversations. + Du er blevet inviteret til %1$s. Vi guider dig gennem processen med at oprette en konto.\nNår du vælger %1$s som udbyder, kan du kommunikere med brugere fra andre udbydere ved at give dem din fulde XMPP adresse. + Du er blevet inviteret til %1$s. Der er allerede valgt et brugernavn til dig. Vi guider dig gennem processen med at oprette en konto.\nDu vil være i stand til at kommunikere med brugere fra andre udbydere ved at give dem din fulde XMPP adresse. Din server invitation Forkert formateret klargøringskode Tryk på deleknappen for at sende din kontakt en invitation til %1$s. - Hvis din kontakt er i nærheden, kan de også scanne koden nedenfor for at acceptere din invitation. - Deltag %1$s og chat med mig: %2$s + Hvis din kontakt er i nærheden, kan de også skanne koden nedenfor for at acceptere din invitation. + Deltag med %1$s og chat med mig: %2$s Del invitation med... \ No newline at end of file diff --git a/src/main/res/values-da-rDK/strings.xml b/src/main/res/values-da-rDK/strings.xml index c96561f1f..19c777d41 100644 --- a/src/main/res/values-da-rDK/strings.xml +++ b/src/main/res/values-da-rDK/strings.xml @@ -5,7 +5,7 @@ Håndter konti Håndter konto Afslut samtale - Kontakt deltaljer + Kontaktdeltaljer Gruppechat detaljer Kanal detaljer Tilføj konto @@ -13,11 +13,11 @@ Tilføj til adressebog Slet fra liste Blokerer kontakt - Fjern blokering af kontakt + Frigiv kontakt Blokerer domæne - Fjern blokering af domæne + Frigiv domæne Bloker deltager - Fjern blokering af deltager + Frigiv deltager Håndter konti Indstillinger Del med Conversation @@ -25,7 +25,7 @@ Vælg kontakt Vælg kontakter Del via konto - Bloker liste + Blokeringsliste lige nu 1 minut siden %d minutter siden @@ -47,10 +47,10 @@ Deltager Gæst Vil du gerne fjerne %s fra din kontaktliste? Samtaler med denne kontakt vil ikke blive slettet. - Vil du gerne bloker %s i at sende dig beskeder? - Vil du gerne frigør%s og tillade dem at sende dig beskeder? + Vil du bloker %s i at sende dig beskeder? + Vil du frigive %s og tillade dem at sende dig beskeder? Bloker alle kontakter fra %s? - Fjern blokering af alle kontakter fra %s? + Frigiv alle kontakter fra %s? Kontakt blokeret Blokeret Vil du gerne slette %s som et bogmærke? Samtaler med dette bogmærke vil ikke blive slettet. @@ -68,7 +68,7 @@ Rediger Slet Bloker - Fjern blokering + Frigiv Gem OK %1$s er kørt fast @@ -86,10 +86,10 @@ Gør klar til at sende billeder Deler filer. Vent venligst… Ryd historik - Ryd samtale historik - Vil du slette alle beskeder i denne samtale?\n\nAdvarsel:Dette vil ikke påvirke beskeder gemt på andre enheder eller servere. + Ryd samtalehistorik + Vil du slette alle beskeder i denne samtale?\n\nAdvarsel: Dette vil ikke påvirke beskeder gemt på andre enheder eller servere. Slet fil - Er du sikker på, at du vil slette denne fil?\n\nAdvarsel:Dette sletter ikke kopier af denne fil, der er gemt på andre enheder eller servere. + Er du sikker på, at du vil slette denne fil?\n\nAdvarsel: Dette sletter ikke kopier af denne fil, der er gemt på andre enheder eller servere. Luk efterfølgende denne samtale Vælg enhed Send ukrypteret besked @@ -109,7 +109,7 @@ tilbyder… Venter… Ingen Open PGP nøgler fundet - Kunne ikke kryptere din besked, fordi din kontakt ikke annoncerer deres offentlige nøgle.\n\n Bed din kontakt om at konfigurere OpenPGP. + Kunne ikke kryptere din besked, fordi din kontakt ikke annoncerer deres offentlige nøgle.\n\nBed din kontakt om at konfigurere OpenPGP. Ingen OpenPGP nøgler fundet Kunne ikke kryptere din besked, fordi din kontakt ikke annoncerer deres offentlige nøgle.\n\n1Bed dem om at oprette OpenPGP. Generel @@ -125,7 +125,7 @@ Notifikationslyd Lydnotifikation for nye beskeder Ringetone for indkommende opkald - Grace periode + Fredningsperiode Tidsintervallet hvor notifikationer er lydløs efter at have registreret aktivitet på en af dine andre enheder. Advanceret Send aldrig fejlrapporter @@ -139,7 +139,7 @@ Der er sket en fejl Fejl Din konto - Send nærværelse opdateringer + Send nærværsopdateringer Modtag nærværsopdateringer Bed om nærværsopdateringer Vælg billede @@ -201,7 +201,7 @@ XEP-0163: PEP (Avatars / OMEMO) XEP-0363: HTTP File Upload XEP-0357: Push - Ledig + understøttet Utilgængelig Ingen meddelelser om offentlige nøgler sidst set lige nu @@ -211,7 +211,7 @@ sidst set %d time siden sidst set for en dag siden sidst set %d dage siden - Krypteret besked. Installer venligst OpenKeychain for dekryptere den? + Krypteret besked. Installer venligst OpenKeychain for dekryptere den. Ny OpenPGP krypteret beskeder fundet OpenPGP nøgle ID OMEMO-fingeraftryk @@ -228,8 +228,8 @@ Indtast kontakt Slet kontakt Vis kontaktdetaljer - Blokér kontakt - Løslad kontakt + Bloker kontakt + Frigiv kontakt Opret Vælg Denne kontakt findes allerede @@ -240,7 +240,7 @@ Slet bogmærke Slet gruppechat Slet kanal - Er du sikker på du vil slette denne gruppechat?\n\n Advarsel: Gruppechatten fjernes fuldstændigt på serveren. + Er du sikker på du vil slette denne gruppechat?\n\n Advarsel: Gruppechatten fjernes fuldstændigt på serveren. Er du sikker på, at du vil ødelægge denne offentlige kanal?\n\nAdvarsel: Kanalen fjernes fuldstændigt på serveren. Kunne ikke slette gruppechat Kunne ikke slette kanal @@ -250,10 +250,10 @@ Forlad Kontakt tilføjede dig til kontaktliste Tilføj tilbage - %s har læst op til dette punkt + %s har læst hertil %s har læst hertil %1$s +%2$d andre har læst hertil - Alle har læst op til dette punkt + Alle har læst hertil Offentliggør Tryk på avatar for at vælge billede fra galleri Offentliggørelse… @@ -274,20 +274,20 @@ Aktiver Gruppechat kræver kodeord Indtast kodeord - Bed først om tilstedeværelsesopdateringer fra din kontakt.\n\nDette bruges til at bestemme, hvilken chat-app din kontakt bruger. + Bed først om nærværsopdateringer fra din kontakt.\n\nDette bruges til at bestemme, hvilken chat-app din kontakt bruger. Anmod nu Ignore - Advarsel: Afsendelse af dette uden gensidig nærværsopdatering kan forårsage uventede problemer.\n\n Gå til \"Kontaktoplysninger\" for at bekræfte dine nærværsabonnementer. + Advarsel: Afsendelse af dette uden gensidig nærværsopdatering kan forårsage uventede problemer.\n\nGå til \"Kontaktdetaljer\" for at bekræfte dine nærværsabonnementer. Sikkerhed Tillad rettelse af beskeder - Tillad dine kontakter at redigere deres beskder med tilbagevirkende kraft + Tillad dine kontakter at redigere deres beskeder med tilbagevirkende kraft Ekspert indstillinger - Være venligst forsigtig med disse + Være forsigtig med at ændre i disse Om %s Stilletid - Start tidspunkt - Slut tidspunkt - Aktiver lydløs timer + Starttidspunkt + Sluttidspunkt + Aktiver stilletid Notifikationer vil være lydløs under stilletid Andre Synkroniser med bogmærker @@ -299,13 +299,13 @@ Du er blevet smidt ud af denne gruppechat Gruppechat er lukket ned Du er ikke længere i denne gruppechat - bruger konto %s + anvender konto %s Hostet på %s Tjekker %s på HTTP vært Du er ikke forbundet. Prøv igen senere Tjek %s størrelse Tjek %1$s størrelse pp %2$s - Beskedindstillinger + Beskedvalg Citat Indsæt som citat Kopier original URL @@ -339,7 +339,7 @@ Åben %s Sender (%1$d%% fuldført) Gør klar til at dele fil - %s kan hentes ned + %s kan downloades Annuller overførsel kunne ikke dele fil fil overførsel annulleret @@ -347,8 +347,8 @@ Ingen app fundet der kan åbne filen Ingen app fundet der kan åbne link Ingen app fundet der kan vise kontakt - Dynamisk Mærker - Vis skrivebeskyttede mærker under kontakter + Dynamiske Mærker + Vis skrivebeskyttet mærker under kontakter Aktiver notifikationer Ingen gruppechat server fundet Kunne ikke oprette gruppechat @@ -420,7 +420,7 @@ Tilbyder %s Skjul offline %s skriver… - %s er holdt op med at skrive + %s skriver ikke mere %s skriver… %s har stoppet skrivning Indtastningsnotifikation @@ -465,8 +465,8 @@ Serveren er ikke ansvarlig for dette domæne Brudt Tilgængelighed - Ej tilstede når enhed er låst - Ej tilstede når enheden er låst + Væk når enhed er låst + Væk når enheden er låst Optaget i lydløs tilstand Vis som Optaget når enhed er i lydløs tilstand Behandl vibration som lydløs tilstand @@ -483,7 +483,7 @@ CAPTCHA påkrævet Indtast teksten fra billedet herover Utroværdig certifikatkæde - XMPP-adresse matcher ikke certifikatet + XMPP adresse matcher ikke certifikatet Forny certifikat Fejl ved hentning af OMEMO-nøgle! Bekræftet OMEMO-nøgler med Certifikat! @@ -509,7 +509,7 @@ Giv %1$s adgang til ekstern lagerplads Giv %1$s adgang til kameraet Synkroniser med kontakter - %1$s ønsker tilladelse til at få adgang til din adressebog for at matche den med din XMPP-kontaktliste.\nDette viser dine kontakters fulde navne og avatarer.\n\n%1$s læser kun din adressebog og matcher den lokalt uden at uploade noget til din server. + %1$s ønsker tilladelse til at få adgang til din adressebog for at matche den med din XMPP kontaktliste.\nDette vil vise dine kontakters fulde navne og avatarer.\n\n%1$s læser kun din adressebog og matcher den lokalt uden at uploade noget til din server.
Vi gemmer ikke en kopi af disse telefonnumre.\n\nFor mere information, læs vores privatlivspolitik.

Du vil bedes nu om at give tilladelse til at få adgang til dine kontakter.]]>
Underret ved alle beskeder Underret kun når nævnt @@ -520,9 +520,8 @@ Altid Kun store billeder Batterioptimering aktiveret -   -Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsinkede notifikationer eller endda tab af beskeder.\nDet er anbefalet at slå dem fra. - Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsinkede notifikationer eller endda tab af beskeder.\n\ nDu bliver nu bedt om at deaktivere dem. + Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsinkede notifikationer eller tab af beskeder.\nDet er anbefalet at slå dem fra. + Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsinkede notifikationer eller tab af beskeder.\n\nDu bliver nu bedt om at deaktivere dem. Deaktiver Det valgte område er for stort (Ingen aktiverede konti) @@ -534,19 +533,19 @@ Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsin Sikkerhedsfejl: Ugyldig filadgang! Ingen app fundet der kan dele URL Del URL med… -
Du tilmelder dig med dit telefonnummer, og Quicksy vil automatisk - baseret på telefonnumre i din adressebog - foreslå mulige kontakter til dig.

Når du tilmelder dig, accepterer du vores privatlispolitik.]]>
+
Du tilmelder dig med dit telefonnummer, og Quicksy vil automatisk - baseret på telefonnumre i din adressebog - foreslå mulige kontakter til dig.

Når du tilmelder dig, accepterer du vores privatlispolitik.]]>
Accepter og fortsætte - En guide er oprettet til kontooprettelse på conversations.im.¹ \ nNår du vælger conversations.im som udbyder, kan du kommunikere med brugere fra andre udbydere ved at give dem din fulde XMPP-adresse. + En guide er oprettet til kontooprettelse på conversations.im.¹\nNår du vælger conversations.im som udbyder, kan du kommunikere med brugere fra andre udbydere ved at give dem din fulde XMPP adresse. Din fulde XMPP adresse vil blive: %s Opret konto Brug min egen udbyder Vælg dit brugernavn - Håndter tilgængelighed menuelt - Indstil din tilgængelighed, når du redigerer din statusmeddelelse. - Statusmeddelelse + Håndter tilgængelighed manuelt + Indstil din tilgængelighed, når du redigerer din statusbesked. + Statusbesked Gratis for Chat Online - Ej tilstede + Væk Ikke tilgængelig Optaget Der er genereret en sikker adgangskode @@ -560,7 +559,7 @@ Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsin Kort Mellem Lang - Broadcast brug + Udsend brug af app Lad dine kontakter vide når du bruger Conversations Privatliv Tema @@ -622,7 +621,7 @@ Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsin Vis inaktive Skjul inaktive Stol ikke på enhed - Er du sikker på, at du vil fjerne bekræftelsen på denne enhed? \ Denne enhed og meddelelser fra den vil blive markeret som \"upålidelig\". + Er du sikker på, at du vil fjerne bekræftelsen på denne enhed?\nDenne enhed og meddelelser fra den vil blive markeret som \"upålidelig\". %d sekund %d sekunder @@ -691,8 +690,8 @@ Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsin QR kode skanner kræver adgang til kameraet Rul til bunden Rul ned efter afsendelse af besked - Rediger status besked - Rediger status besked + Rediger statusbesked + Rediger statusbesked Deaktiver kryptering %1$s kan ikke sende krypterede meddelelser til %2$s. Dette kan skyldes din kontakt bruger en forældet server eller klient, der ikke kan håndtere OMEMO. Kunne ikke hente enhedsliste @@ -737,10 +736,10 @@ Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsin Kopier XMPP adresse HTTP fildeling for S3 Direkte søgning - På Skærmbilledet \'Start samtale\' skal du åbne tastaturet og placere markøren i søgefeltet + På skærmbillede \'Start samtale\' skal du åbne tastaturet og placere markøren i søgefeltet Gruppechat avatar Vært understøtter ikke gruppechat avatarer - Kin ejeren kan ændre gruppechat avatar + Kun ejeren kan ændre gruppechat avatar Kontaktnavn Kaldenavn Navn @@ -759,7 +758,7 @@ Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsin Indkommende opkald Udgående opkald Lydløse beskeder - Denne notifikationsgruppe bruges til at vise notifikationer, der ikke bør udløse nogen lyd. For eksempel når du er aktiv på en anden enhed (Grace Periode). + Denne notifikationsgruppe bruges til at vise notifikationer, der ikke bør udløse nogen lyd. For eksempel når du er aktiv på en anden enhed (Fredningsperiode). Mislykkede leverancer Notifikationsindstilling for besked Notifikationsindstilling for indgående opkald @@ -788,12 +787,12 @@ Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsin Bekræft %s %s.]]> Vi har sendt dig en ny SMS med en 6 cifret pinkode. - Indtast venligst den 6 cifret pinkode herunder. + Indtast den 6 cifret pinkode herunder. Send SMS igen Send SMS igen (%s) Vent venligst (%s) Tilbage - Indsat automatisk mulig pinkode fra udklipsholderen. + Indsat automatisk mulig pinkode fra udklipsholder. Indtast venligst din 6 cifret pinkode. Er du sikker på at du afbryde registreringsproceduren? Ja @@ -829,7 +828,7 @@ Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsin e-bog Original (ukomprimeret) Åbn med… - Conversations profil billede + Conversations profilbillede Vælg konto Gendan backup Gendan @@ -869,8 +868,8 @@ Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsin Vedhæft Find kanaler Find kanaler - Mulig krænkelse af privatlivet! - search.jabber.network.

Brug af denne funktion sender din IP-adresse og søgetermer til denne service. Se deres Privatlivspolitik for mere information.]]>
+ Risiko for krænkelse af privatlivet! + søg.jabber.netværk.

Brug af denne funktion sender din IP-adresse og søgetermer til denne service. Se deres Privatlivspolitik for mere information.]]>
Jeg har allerede en konto Tilføj eksisterende konto Registrer ny konto @@ -890,8 +889,8 @@ Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsin jabber.netværk Lokal server - De fleste brugere bør vælge \'jabber.network\' for bedst mulige forslag fra hele det offentlige XMPP-økosystem. - Kanal søgningsmetode + De fleste brugere bør vælge \'jabber.netværk\' for bedst mulige forslag fra hele det offentlige XMPP økosystem. + Metode for kanalsøgning Backup Om Aktiver venligst en konto @@ -954,7 +953,7 @@ Din enhed anvender kraftig batterioptimeringer for %1$s som kan føre til forsin Nogle beskeder kunne ikke leveres
Mislykkede leverancer - Flere muligheder + Flere valg Intet program fundet Inviter til Conversations Kunne ikke analysere invitation diff --git a/src/main/res/values-gl/strings.xml b/src/main/res/values-gl/strings.xml index 588243a6b..c10556b5a 100644 --- a/src/main/res/values-gl/strings.xml +++ b/src/main/res/values-gl/strings.xml @@ -7,7 +7,7 @@ Pechar conversa Detalles do contacto Detalles da conversa de grupo - Detalles do canal + Detalles da canle Engadir conta Editar contacto Engadir a libreta de enderezos @@ -234,16 +234,16 @@ Selecionar Xa existe o contacto Unirse - canal@sala.exemplo.com/alcume - canal@sala.exemplo.com + canle@sala.exemplo.com/alcume + canle@sala.exemplo.com Gardar como marcador Eliminar marcador Destruír a conversa en grupo - Eliminar canal + Eliminar canle Está segura de querer destruír esta conversa en grupo?\n\nAviso: A conversa en grupo será totalmente eliminada do servidor. - Está segura de que quere eliminar o canal?\n\nAviso: O canal eliminarase completamente do servidor. + Tes a certeza de querer eliminar a canle?\n\nAviso: A canle será eliminada completamente do servidor. Non se desfixo a conversa en grupo - Non se puido eliminar o canal + Non se puido eliminar a canle Editar o tema da conversa en grupo Asunto Entrando na conversa en grupo @@ -384,18 +384,18 @@ Conceder privilexios de propiedade Retirar privilexios de propiedade Eliminar da conversa en grupo - Retirar do canal + Retirar da canle Non se puido mudar a afiliación de %s Prohibición da conversa en grupo - Prohibir no canal - Estás a intentar eliminar %s dun canal público. O único xeito de facelo é prohibíndolle o acceso para sempre. + Vetar na canle + Estás a intentar eliminar a %s dunha canle pública. O único xeito de facelo é prohibíndolle o acceso para sempre. Rexeitar agora Non se puido mudar o rol de %s Configuración do grupo privado de conversa - Configuración do canal público + Configuración da canle pública Privada, só para membros Facer os enderezos XMPP visibles para calquera - Establecer canal como moderado + Establecer canle como moderada Non estás a participar ¡Opcións da conversa en grupo modificadas! Non se puideron modificar as opcións da conversa en grupo @@ -431,7 +431,7 @@ Localización Pechouse a conversa Deixar o grupo de conversa privada - Deixar o canal público + Deixar a canle pública Non confiar nas CAs do sistema Todos os certificados deberán ser aprobados manualmente Eliminar certificados @@ -510,7 +510,7 @@ Permitir que %1$s acceda á cámara Sincronice con todos os contactos %1$s quere ter permiso para acceder á túa libreta de enderezos para comparala coa lista de contactos XMPP.\nDeste xeito poderá mostrar o nome completo e avatares dos teus contactos.\n\n%1$s só utilizará de xeito local a túa lista de contactos, sen subila a ningún servidor. -
Non gardaremos unha copia de esos números de teléfono.\n\nPara máis información lea a nosa política de intimidade.

A continuación pediráselle permiso para acceder aos contactos.]]>
+
Non gardaremos unha copia desos números de teléfono.\n\nPara máis información le a nosa política de privacidade.

A continuación pediremos permiso para acceder aos contactos.]]>
Notificar todas as mensaxes Notificar só cando é mencionada Notificacións desactivadas @@ -533,7 +533,7 @@ Fallo de seguridade: Acceso non válido ao ficheiro! Non se atopou unha app para compartir URI Compartir URI con... -
Podes rexistrarte co teu número de teléfono e Quicksy suxerillache automáticamente —tomando os números da túa libreta de enderezos como referencia— posibles contactos para ti.

Ao rexistrarte aceptas a nosa política de intimidade.]]>
+
Podes rexistrarte co teu número de teléfono e Quicksy suxerirache automáticamente —tomando os números da túa libreta de enderezos como referencia— posibles contactos para ti.

Ao rexistrarte aceptas a nosa política de privacidade.]]>
Aceptar e continuar Tes unha guía para crear unha conta en conversations.im¹\nAo escoller conversations.im como provedor poderás comunicarte con outras usuarias de outros provedores con só darlles o teu enderezo XMPP completo. O seu enderezo XMPP completo será: %s @@ -561,7 +561,7 @@ Longo Publicar utilización Permitelle aos teus contactos saber cando estás a usar Conversations - Intimidade + Privacidade Decorado Escolle a gama de cores Automático @@ -824,7 +824,7 @@ Instalar Orbot Iniciar Orbot Non ten loxa de aplicacións instalada. - Este canal fará público o seu enderezo XMPP + Esta canle fará público o teu enderezo XMPP e-book Orixinal (non comprimido) Abrir con... @@ -839,18 +839,18 @@ Respaldar & Restaurar Introducir enderezo XMPP Crear grupo de conversa - Unirse a canal público + Unirse a canle pública Crear grupo privado de conversa - Crear canal público - Nome do canal + Crear canle pública + Nome da canle Enderezo XMPP - Por favor, proporcione un nome para o canal + Por favor, escribe un nome para a canle Por favor, proporcione un enderezo XMPP Esto é un enderezo XMPP. Por favor, proporcione un nome. - Creando canal público... - Este canal xa existe - Entrou nun canal existente - Non se gardaron os axustes do canal + Creando canle pública... + Esta canle xa existe + Entraches nunha canle existente + Non se gardaron os axustes da canle Permitir que calquera cambie o asunto Permitir que calquera poida convidar Calquera pode editar o asunto. @@ -860,22 +860,22 @@ Calquera pode convidar a outras. Os enderezos XMPP son visibles para a administración. Os enderezos XMPP son visibles para calquera. - Este canal público non ten participantes. Convida aos teus contactos ou utiliza o botón compartir para distribuír o teu enderezo XMPP. + Esta canle pública non ten participantes. Convida aos teus contactos ou utiliza o botón compartir para distribuír o teu enderezo XMPP. Este grupo privado non ten participantes. Xestionar privilexios Buscar participantes Ficheiro demasiado grande Anexar - Descubrir canales - Buscar canales - Posible intrusión na intimidade! - search.jabber.network.

Ao utilizar esta función transmitirá o teu enderezo IP e termos de busca a ese servizo. Le a súa Política de Privacidade para máis información.]]>
+ Descubrir canles + Buscar canles + Posible intrusión na privacidade! + search.jabber.network.

Ao utilizar esta función transmitirás o teu enderezo IP e termos de busca a ese servizo. Le a súa Política de Privacidade para máis información.]]>
Xa teño unha conta Engadir conta existente Rexistrar unha nova conta Esto semella un enderezo de dominio Engadir igualmente - Esto semella o enderezo de un canal + Esto semella o enderezo dunha canle Compartir ficheiros de apoio Respaldar Conversations Evento @@ -886,7 +886,7 @@ Non se puido completar a acción Unirse a canle pública... A aplicación que comparte non proporciona permiso para acceder ao ficheiro. - + jabber.network Servidor local A maioría das usuarias debería escoller \'jabber.network\' para obter mellores suxestións desde o ecosistema público XMPP. diff --git a/src/main/res/values-ru/strings.xml b/src/main/res/values-ru/strings.xml index c6465cd04..d38aa64c9 100644 --- a/src/main/res/values-ru/strings.xml +++ b/src/main/res/values-ru/strings.xml @@ -411,7 +411,7 @@ Ответить Прочитано Ввод - Отправка по \\"Enter\\" + Отправка по \"Enter\" Отправлять сообщения клавишей Enter. Даже если эта опция отключена, сообщение можно отправить, нажав Ctrl+Enter. Показывать клавишу ввода Поменять кнопку смайликов на кнопку ввода diff --git a/src/quicksy/res/values-da-rDK/strings.xml b/src/quicksy/res/values-da-rDK/strings.xml index 535f78a32..1be0ee176 100644 --- a/src/quicksy/res/values-da-rDK/strings.xml +++ b/src/quicksy/res/values-da-rDK/strings.xml @@ -1,10 +1,10 @@ - Hvor lang tid Quicksy holder stille efter at have set aktivitet på en anden enhed + Hvor lang tid Quicksy er stille efter at have set aktivitet på en anden enhed Ved at indsende \"stack traces\" hjælper du udviklingen af Quicksy Lad alle dine kontakter vide når du bruger Quicksy For at modtage underretninger, selv når skærmen er slukket, skal du tilføje Quicksy til listen over beskyttede apps. - Quicksy profil billede + Quicksy profilbillede Quicksy er ikke tilgængelig i dit land. Kan ikke bekræfte server identitet. Ukendt sikkerhedsfejl. From d52c46d58249feb4a80d1cb81054ae201b1ef623 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 3 Mar 2021 12:55:27 +0100 Subject: [PATCH 06/17] use omemo verification only if omemo is enabled in conversation --- .../xmpp/jingle/JingleRtpConnection.java | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java index aff365247..523d8d5cd 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java @@ -669,7 +669,15 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web this.message.setServerMsgId(serverMsgId); } this.message.setTime(timestamp); - this.omemoVerification.setDeviceId(proceed.getDeviceId()); + final Integer remoteDeviceId = proceed.getDeviceId(); + if (isOmemoEnabled()) { + this.omemoVerification.setDeviceId(remoteDeviceId); + } else { + if (remoteDeviceId != null) { + Log.d(Config.LOGTAG, id.account.getJid().asBareJid()+": remote party signaled support for OMEMO verification but we have OMEMO disabled"); + } + this.omemoVerification.setDeviceId(null); + } this.sendSessionInitiate(media, State.SESSION_INITIALIZED_PRE_APPROVED); } else { Log.d(Config.LOGTAG, String.format("%s: ignoring proceed because already in %s", id.account.getJid().asBareJid(), this.state)); @@ -1126,16 +1134,24 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web final Element intent = messagePacket.addChild(action, Namespace.JINGLE_MESSAGE).setAttribute("id", id.sessionId); if ("proceed".equals(action)) { messagePacket.setId(JINGLE_MESSAGE_PROCEED_ID_PREFIX + id.sessionId); - - //TODO only do this if OMEMO is enable so we have an easy way to opt out - final int deviceId = id.account.getAxolotlService().getOwnDeviceId(); - final Element device = intent.addChild("device", Namespace.OMEMO_DTLS_SRTP_VERIFICATION); - device.setAttribute("id", deviceId); + if (isOmemoEnabled()) { + final int deviceId = id.account.getAxolotlService().getOwnDeviceId(); + final Element device = intent.addChild("device", Namespace.OMEMO_DTLS_SRTP_VERIFICATION); + device.setAttribute("id", deviceId); + } } messagePacket.addChild("store", "urn:xmpp:hints"); xmppConnectionService.sendMessagePacket(id.account, messagePacket); } + private boolean isOmemoEnabled() { + final Conversational conversational = message.getConversation(); + if (conversational instanceof Conversation) { + return ((Conversation) conversational).getNextEncryption() == Message.ENCRYPTION_AXOLOTL; + } + return false; + } + private void acceptCallFromSessionInitialized() { xmppConnectionService.getNotificationService().cancelIncomingCallNotification(); sendSessionAccept(); From c5f801c1fe31b2bfc47d45d33fd4e3f4d42701de Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 3 Mar 2021 13:12:10 +0100 Subject: [PATCH 07/17] do not push empty candidates to backlog --- .../conversations/xmpp/jingle/JingleRtpConnection.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java index 523d8d5cd..ecbf73729 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java @@ -352,8 +352,11 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web } if (transition(target, () -> this.initiatorRtpContentMap = contentMap)) { respondOk(jinglePacket); - //TODO Do not push empty set - pendingIceCandidates.push(contentMap.contents.entrySet()); + + final Set> candidates = contentMap.contents.entrySet(); + if (candidates.size() > 0) { + pendingIceCandidates.push(candidates); + } if (target == State.SESSION_INITIALIZED_PRE_APPROVED) { Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": automatically accepting session-initiate"); sendSessionAccept(); From 5848013a1efff3293171e12cf20f0eae0ca08902 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 3 Mar 2021 14:03:08 +0100 Subject: [PATCH 08/17] handle pre key messages in dtls verification --- src/main/java/eu/siacs/conversations/Config.java | 1 + .../conversations/crypto/axolotl/AxolotlService.java | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index a6a1a2118..96df56b1f 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -102,6 +102,7 @@ public final class Config { public static final boolean REMOVE_BROKEN_DEVICES = false; public static final boolean OMEMO_PADDING = false; public static final boolean PUT_AUTH_TAG_INTO_KEY = true; + public static final boolean AUTOMATICALLY_COMPLETE_SESSIONS = true; public static final boolean USE_BOOKMARKS2 = false; diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java index ce8c3a381..67e8ca5da 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java @@ -1264,6 +1264,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { new RtpContentMap.DescriptionTransport(descriptionTransport.description, decryptedTransport.payload) ); } + processPostponed(); return new OmemoVerifiedPayload<>( omemoVerification, new RtpContentMap(omemoVerifiedRtpContentMap.group, descriptionTransportBuilder.build()) @@ -1283,6 +1284,10 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { final XmppAxolotlMessage xmppAxolotlMessage = XmppAxolotlMessage.fromElement(encrypted, from.asBareJid()); final XmppAxolotlSession session = getReceivingSession(xmppAxolotlMessage); final XmppAxolotlMessage.XmppAxolotlPlaintextMessage plaintext = xmppAxolotlMessage.decrypt(session, getOwnDeviceId()); + final Integer preKeyId = session.getPreKeyIdAndReset(); + if (preKeyId != null) { + postponedSessions.add(session); + } fingerprint.setContent(plaintext.getPlaintext()); omemoVerification.setDeviceId(session.getRemoteAddress().getDeviceId()); omemoVerification.setSessionFingerprint(plaintext.getFingerprint()); @@ -1414,7 +1419,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { } else { Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": nothing to flush. Not republishing key"); } - if (trustedOrPreviouslyResponded(session)) { + if (trustedOrPreviouslyResponded(session) && Config.AUTOMATICALLY_COMPLETE_SESSIONS) { completeSession(session); } } @@ -1429,7 +1434,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { final Iterator iterator = postponedSessions.iterator(); while (iterator.hasNext()) { final XmppAxolotlSession session = iterator.next(); - if (trustedOrPreviouslyResponded(session)) { + if (trustedOrPreviouslyResponded(session) && Config.AUTOMATICALLY_COMPLETE_SESSIONS) { completeSession(session); } iterator.remove(); From 4a175f915df957709b858b5e8706c861498c8a55 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 4 Mar 2021 09:25:20 +0100 Subject: [PATCH 09/17] version bump to 2.9.8-beta --- CHANGELOG.md | 4 ++++ build.gradle | 4 ++-- .../siacs/conversations/services/XmppConnectionService.java | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae837d048..cbf14b739 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +### Version 2.9.8 + +* Verify A/V calls with preexisting OMEMO sessions + ### Version 2.9.7 * Ability to select incoming call ringtone diff --git a/build.gradle b/build.gradle index af488dbbd..0b909ebb0 100644 --- a/build.gradle +++ b/build.gradle @@ -91,8 +91,8 @@ android { defaultConfig { minSdkVersion 21 targetSdkVersion 29 - versionCode 42000 - versionName "2.9.7" + versionCode 42001 + versionName "2.9.8-beta" archivesBaseName += "-$versionName" applicationId "eu.siacs.conversations" resValue "string", "applicationId", applicationId diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 4d100c0a5..ab718a752 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -691,6 +691,7 @@ public class XmppConnectionService extends Service { } case TorServiceUtils.ACTION_STATUS: final String status = intent.getStringExtra(TorServiceUtils.EXTRA_STATUS); + //TODO port and host are in 'extras' - but this may not be a reliable source? if ("ON".equals(status)) { handleOrbotStartedEvent(); return START_STICKY; From ef24d2050bcad1d9497a337d1c95cafde63250d2 Mon Sep 17 00:00:00 2001 From: Christopher Vollick <0@psycoti.ca> Date: Fri, 26 Feb 2021 11:06:03 -0500 Subject: [PATCH 10/17] Remove Renomination from WebRTC Options This is a feature of WebRTC that's [not standardized][1] and only supported by libwebrtc. Since there's no support in jingle for passing this capability from one peer to another, we're currently hard-coding this option into both the local candidate and also the remote candidate so they can use it. But I'm trying to call a user that isn't using WebRTC, and renomination is causing the call to stay in "connecting..." state for 10 or 20 seconds, sometimes longer, while both sides wait for the other to nominate something based on their individual beliefs about the standards they're using. Removing this seems to make connecting relatively instantaneous. If we want to reintroduce this feature, we should probably make a XEP so the peers can negotiate honestly about it, and only use it if both sides truely support the feature. [1]: https://datatracker.ietf.org/doc/html/draft-thatcher-ice-renomination-01 --- .../eu/siacs/conversations/xmpp/jingle/SessionDescription.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/SessionDescription.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/SessionDescription.java index 7c329089a..8f0b0d4fe 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/SessionDescription.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/SessionDescription.java @@ -24,7 +24,7 @@ public class SessionDescription { public final static String LINE_DIVIDER = "\r\n"; private final static String HARDCODED_MEDIA_PROTOCOL = "UDP/TLS/RTP/SAVPF"; //probably only true for DTLS-SRTP aka when we have a fingerprint private final static int HARDCODED_MEDIA_PORT = 9; - private final static String HARDCODED_ICE_OPTIONS = "trickle renomination"; + private final static String HARDCODED_ICE_OPTIONS = "trickle"; private final static String HARDCODED_CONNECTION = "IN IP4 0.0.0.0"; public final int version; From cf68c544aa0497fbb6fbaf60a8ccab0d9d9cc89a Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 6 Mar 2021 08:58:28 +0100 Subject: [PATCH 11/17] pulled translations from transifex --- .../res/values-da-rDK/strings.xml | 10 +- src/main/res/values-da-rDK/strings.xml | 92 +++++++++---------- 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/src/conversations/res/values-da-rDK/strings.xml b/src/conversations/res/values-da-rDK/strings.xml index 26c3f2c66..a55288db9 100644 --- a/src/conversations/res/values-da-rDK/strings.xml +++ b/src/conversations/res/values-da-rDK/strings.xml @@ -1,12 +1,12 @@ - Vælg din XMPP udbyder + Vælg din XMPP-udbyder Brug conversations.im Opret ny konto - Har du allerede en XMPP konto? Dette kan være tilfældet, hvis du allerede bruger en anden XMPP klient eller har brugt Conversations før. Hvis ikke, kan du lige nu oprette en ny XMPP konto.\nTip: Nogle e-mail-udbydere leverer også XMPP konti. - XMPP er et udbyderuafhængigt onlinemeddelelsesnetværk. Du kan bruge denne klient med hvilken XMPP server du end vælger.\nMen for din nemheds skyld har vi gjort vi det let at oprette en konto på conversations.im¹; en udbyder, der er specielt velegnet til brug med Conversations. - Du er blevet inviteret til %1$s. Vi guider dig gennem processen med at oprette en konto.\nNår du vælger %1$s som udbyder, kan du kommunikere med brugere fra andre udbydere ved at give dem din fulde XMPP adresse. - Du er blevet inviteret til %1$s. Der er allerede valgt et brugernavn til dig. Vi guider dig gennem processen med at oprette en konto.\nDu vil være i stand til at kommunikere med brugere fra andre udbydere ved at give dem din fulde XMPP adresse. + Har du allerede en XMPP-konto? Dette kan være tilfældet, hvis du allerede bruger en anden XMPP-klient eller har brugt Conversations før. Hvis ikke, kan du lige nu oprette en ny XMPP-konto.\nTip: Nogle e-mail-udbydere leverer også XMPP-konti. + XMPP er et udbyderuafhængigt onlinemeddelelsesnetværk. Du kan bruge denne klient med hvilken XMPP-server du end vælger.\nMen for din nemhedsskyld har vi gjort vi det let at oprette en konto på conversations.im¹; en udbyder, der er specielt velegnet til brug med Conversations. + Du er blevet inviteret til %1$s. Vi guider dig gennem processen med at oprette en konto.\nNår du vælger %1$s som udbyder, kan du kommunikere med brugere fra andre udbydere ved at give dem din fulde XMPP-adresse. + Du er blevet inviteret til %1$s. Der er allerede valgt et brugernavn til dig. Vi guider dig gennem processen med at oprette en konto.\nDu vil være i stand til at kommunikere med brugere fra andre udbydere ved at give dem din fulde XMPP-adresse. Din server invitation Forkert formateret klargøringskode Tryk på deleknappen for at sende din kontakt en invitation til %1$s. diff --git a/src/main/res/values-da-rDK/strings.xml b/src/main/res/values-da-rDK/strings.xml index 19c777d41..db011c433 100644 --- a/src/main/res/values-da-rDK/strings.xml +++ b/src/main/res/values-da-rDK/strings.xml @@ -7,7 +7,7 @@ Afslut samtale Kontaktdeltaljer Gruppechat detaljer - Kanal detaljer + Kanaldetaljer Tilføj konto Rediger navn Tilføj til adressebog @@ -55,7 +55,7 @@ Blokeret Vil du gerne slette %s som et bogmærke? Samtaler med dette bogmærke vil ikke blive slettet. Register ny konto på server - Ændr kodeord på server + Ændr adgangskode på server Del med… Start samtale Inviter kontakt @@ -72,14 +72,14 @@ Gem OK %1$s er kørt fast - Brugen af din XMPP konto til at sende \"stack traces\" hjælper den løbende udvikling af %1$s. + Brugen af din XMPP-konto til at sende \"stack traces\" hjælper den løbende udvikling af %1$s. Send nu Spørg ikke igen Kunne ikke forbinde til konto Kunne ikke forbinde til flere konti Tryk for at håndter dine konti Vedhæft fil - Tilføj den manglede kontakt til din kontaktliste + Tilføj den manglede kontakt til din kontaktliste? Tilføj kontakt levering mislykkedes Gør klar til at sende billede @@ -94,7 +94,7 @@ Vælg enhed Send ukrypteret besked Send besked - Send besked to %s + Send besked til %s Send OMEMO-krypteret besked Send v\\OMEMO-krypteret besked Send OpenPGP krypteret besked @@ -111,7 +111,7 @@ Ingen Open PGP nøgler fundet Kunne ikke kryptere din besked, fordi din kontakt ikke annoncerer deres offentlige nøgle.\n\nBed din kontakt om at konfigurere OpenPGP. Ingen OpenPGP nøgler fundet - Kunne ikke kryptere din besked, fordi din kontakt ikke annoncerer deres offentlige nøgle.\n\n1Bed dem om at oprette OpenPGP. + Kunne ikke kryptere din besked, fordi din kontakt ikke annoncerer deres offentlige nøgle.\n\n1Bed dem om at opsætte OpenPGP. Generel Accepter filer Accepter automatisk filer mindre end… @@ -148,7 +148,7 @@ Den valgte fil er ikke et billede Kunne ikke konverter billedefil Fil ikke fundet - General I/O fejl. Måske er kørt tør for lagerplads? + General I/O fejl. Måske er du kørt tør for lagerplads? Appen du brugte til at vælge dette billede havde ikke tilstrækkelig tilladelse til at læse filen.\n\nBrug en anden filmanager til at vælge et billede. Ukendt Midlertidigt deaktiveret @@ -183,11 +183,11 @@ Er du sikker? Sletning af din konto sletter hele din samtalehistorik Optag lyd - XMPP adresse - Bloker XMPP adresse + XMPP-adresse + Bloker XMPP-adresse brugernavn@domæne.dk Adgangskode - Dette er ikke en gyldig XMPP adresse + Dette er ikke en gyldig XMPP-adresse Kørt tør for hukommelse. Billedet for stort Vil du tilføje %s til din adressebog? Server info @@ -215,7 +215,7 @@ Ny OpenPGP krypteret beskeder fundet OpenPGP nøgle ID OMEMO-fingeraftryk - v\\OMEMO fingeraftryk + v\\OMEMO-fingeraftryk OMEMO-fingeraftryk (beskedoprindelse) v\\OMEMO-fingeraftryk (beskedoprindelse) Andre enheder @@ -272,8 +272,8 @@ Skip Deaktiver notifikationer Aktiver - Gruppechat kræver kodeord - Indtast kodeord + Gruppechat kræver adgangskode + Indtast adgangskode Bed først om nærværsopdateringer fra din kontakt.\n\nDette bruges til at bestemme, hvilken chat-app din kontakt bruger. Anmod nu Ignore @@ -292,19 +292,19 @@ Andre Synkroniser med bogmærker Deltag automatisk i gruppechat hvis bogmærket tillader det - OMEMO fingeraftryk kopieret til udklipsholder + OMEMO-fingeraftryk kopieret til udklipsholder Du er udelukket fra denne gruppechat Denne gruppechat er kun for medlemmer Ressourcebegrænsning Du er blevet smidt ud af denne gruppechat - Gruppechat er lukket ned + Gruppechatten er lukket ned Du er ikke længere i denne gruppechat anvender konto %s - Hostet på %s + hostet på %s Tjekker %s på HTTP vært Du er ikke forbundet. Prøv igen senere Tjek %s størrelse - Tjek %1$s størrelse pp %2$s + Tjek %1$s størrelse på %2$s Beskedvalg Citat Indsæt som citat @@ -312,7 +312,7 @@ Send igen Fil URL Kopieret URL til udklipsholder - Kopieret XMPP adresse til udklipsholder + Kopieret XMPP-adresse til udklipsholder Kopieret fejlmeddelelse til udklipsholder webadresse Skan 2D stregkode @@ -337,7 +337,7 @@ Slet %s fil Åben %s - Sender (%1$d%% fuldført) + sender (%1$d%% fuldført) Gør klar til at dele fil %s kan downloades Annuller overførsel @@ -354,21 +354,21 @@ Kunne ikke oprette gruppechat Konto avatar Kopier OMEMO-fingeraftryk til udklipsholder - Gendan OMEMO nøgle + Gendan OMEMO-nøgle Ryd enheder Er du sikker på, at du vil rydde alle andre enheder fra OMEMO-meddelelsen? Næste gang dine enheder opretter forbindelse, annoncerer de sig selv, men de modtager muligvis ikke beskeder sendt i mellemtiden. Der er ingen brugbare nøgler til rådighed for denne kontakt.\nKunne ikke hente nye nøgler fra serveren. Måske er der noget galt med din kontakts server? Der er ingen tilgængelige nøgler til denne kontakt.\nSørg for, at I begge har nærværsabonnement. Noget gik galt Henter historik fra server - Ikke mere historik på server + Der er ikke mere historik på server Opdater… - Kodeord ændret! - Kunne ikke ændre kodeord - Ændr kodeord - Nuværende kodeord - Nyt kodeord - Kodeordet kan ikke være tomt + Adgangskode ændret! + Kunne ikke ændre adgangskode + Ændr adgangskode + Nuværende adgangskode + Ny adgangskode + Adgangskode kan ikke være tomt Aktiver alle konti Deaktiver alle konti Udfør handling med @@ -394,7 +394,7 @@ Privat gruppechatkonfiguration Konfiguration af offentlig kanal Privat, kun medlemmer - Gør XMPP adresser synlig for alle + Gør XMPP-adresser synlig for alle Moderere kanal Du deltager ikke Ændrede gruppechat valg! @@ -483,7 +483,7 @@ CAPTCHA påkrævet Indtast teksten fra billedet herover Utroværdig certifikatkæde - XMPP adresse matcher ikke certifikatet + XMPP-adresse matcher ikke certifikatet Forny certifikat Fejl ved hentning af OMEMO-nøgle! Bekræftet OMEMO-nøgler med Certifikat! @@ -535,8 +535,8 @@ Del URL med…
Du tilmelder dig med dit telefonnummer, og Quicksy vil automatisk - baseret på telefonnumre i din adressebog - foreslå mulige kontakter til dig.

Når du tilmelder dig, accepterer du vores privatlispolitik.]]>
Accepter og fortsætte - En guide er oprettet til kontooprettelse på conversations.im.¹\nNår du vælger conversations.im som udbyder, kan du kommunikere med brugere fra andre udbydere ved at give dem din fulde XMPP adresse. - Din fulde XMPP adresse vil blive: %s + En guide er oprettet til kontooprettelse på conversations.im.¹\nNår du vælger conversations.im som udbyder, kan du kommunikere med brugere fra andre udbydere ved at give dem din fulde XMPP-adresse. + Din fulde XMPP-adresse vil blive: %s Opret konto Brug min egen udbyder Vælg dit brugernavn @@ -585,7 +585,7 @@ Fjernserver ikke fundet Fjernserver timeout Kunne ikke opdatere konto - Reporter denne XMPP adresse for spamming. + Reporter denne XMPP-adresse for spamming. Slet OMEMO-identiteter Gendan dine OMEMO-nøgler. Alle dine kontakter skal bekræfte dig igen. Brug kun dette som en sidste udvej. Slet valgte nøgler @@ -598,7 +598,7 @@ Kunne ikke oprette midlertidig fil Den enhed er blevet bekræftet Kopier fingeraftryk - Du har bekræftet alle OMEMO nøglerne i din besiddelse + Du har bekræftet alle OMEMO-nøglerne i din besiddelse Stregkoden indeholder ingen fingeraftryk for denne samtale. Bekræft fingeraftryk Brug kameraet til at skanne en kontakt\'s stregkode @@ -671,7 +671,7 @@ I går Bekræft værtsnavn med DNSSEC Servercertifikater, der indeholder det validerede værtsnavn, betragtes som bekræftede - Certifikat indeholder ikke en XMPP adresse + Certifikat indeholder ikke en XMPP-adresse delvis Optag video Kopier til udklipsholder @@ -712,9 +712,9 @@ Lille Mellem Stor - Besked var ikke krypteret på denne enhed + Besked var ikke krypteret på denne enhed. Dekryptering af OMEMO-besked mislykkes. - Fortryd + fortryd Deling af placering er deaktiveret Fastgør position Frigør position @@ -733,7 +733,7 @@ Del placeringsplugin Brug Plugin for delingsplacering i stedet for det indbyggede kort Kopier webadresse - Kopier XMPP adresse + Kopier XMPP-adresse HTTP fildeling for S3 Direkte søgning På skærmbillede \'Start samtale\' skal du åbne tastaturet og placere markøren i søgefeltet @@ -824,7 +824,7 @@ Installer Orbot Start Orbot Ingen markedsapp installeret. - Denne kanal vil offentliggør din XMPP adresse + Denne kanal vil offentliggør din XMPP-adresse e-bog Original (ukomprimeret) Åbn med… @@ -837,16 +837,16 @@ Kunne ikke gendan backup Kunne ikke dekryptere backup. Er adgangskoden korrekt? Backup & Gendan - Indtast XMPP adresse + Indtast XMPP-adresse Opret gruppechat Deltag i offentlig kanal Opret privat gruppechat Opret offentlig kanal Kanalnavn - XMPP adresse + XMPP-adresse Angiv venligst et navn til kanalen - Angiv venligst en XMPP adresse - Dette er en XMPP adresse. Angiv venligst et navn + Angiv venligst en XMPP-adresse + Dette er en XMPP-adresse. Angiv venligst et navn Opret offentlig kanal… Denne kanal eksister allerede Du sluttede dig til en eksisterende kanal @@ -858,9 +858,9 @@ Administrator kan redigere emnet. Ejere kan invitere andre. Alle kan invitere andre. - XMPP adresser er synlig for administratorerne. - XMPP adresser er synlige for alle. - Denne offentlige kanal har ingen deltagere. Inviter dine kontakter eller brug deleknappen til distribuere dens XMPP adresse + XMPP-adresser er synlig for administratorerne. + XMPP-adresser er synlige for alle. + Denne offentlige kanal har ingen deltagere. Inviter dine kontakter eller brug deleknappen til distribuere dens XMPP-adresse Denne private gruppechat har ingen medlemmer. Administrer rettigheder Find deltagere @@ -889,7 +889,7 @@ jabber.netværk Lokal server - De fleste brugere bør vælge \'jabber.netværk\' for bedst mulige forslag fra hele det offentlige XMPP økosystem. + De fleste brugere bør vælge \'jabber.netværk\' for bedst mulige forslag fra hele det offentlige XMPP-økosystem. Metode for kanalsøgning Backup Om From b8c61b795e2827b3717e69fb5e3a98d326ef997a Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 6 Mar 2021 09:45:13 +0100 Subject: [PATCH 12/17] use different top margin for vert and land for duration display --- src/main/res/layout/activity_rtp_session.xml | 4 ++-- src/main/res/values-land/dimens.xml | 1 + src/main/res/values/dimens.xml | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/res/layout/activity_rtp_session.xml b/src/main/res/layout/activity_rtp_session.xml index f54295866..a14e899c7 100644 --- a/src/main/res/layout/activity_rtp_session.xml +++ b/src/main/res/layout/activity_rtp_session.xml @@ -73,7 +73,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" - android:layout_margin="24dp" + android:layout_marginTop="@dimen/rtp_session_duration_top_margin" android:textAppearance="@style/TextAppearance.Conversations.Title.Monospace" tools:text="01:23" /> @@ -112,8 +112,8 @@ android:layout_height="wrap_content" android:layout_below="@+id/app_bar_layout" android:layout_alignParentStart="true" - android:layout_marginTop="24dp" android:layout_marginStart="16dp" + android:layout_marginTop="@dimen/rtp_session_duration_top_margin" android:alpha="0.7" android:src="@drawable/ic_verified_fingerprint" /> diff --git a/src/main/res/values-land/dimens.xml b/src/main/res/values-land/dimens.xml index ecdfd32f2..73ac76ef7 100644 --- a/src/main/res/values-land/dimens.xml +++ b/src/main/res/values-land/dimens.xml @@ -1,4 +1,5 @@ 96dp 128dp + 16dp \ No newline at end of file diff --git a/src/main/res/values/dimens.xml b/src/main/res/values/dimens.xml index fba306510..baa9d4ea9 100644 --- a/src/main/res/values/dimens.xml +++ b/src/main/res/values/dimens.xml @@ -43,4 +43,5 @@ 128dp 96dp + 24dp
From b34f6e072014d0cf2385a7a32a466478266c651b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 6 Mar 2021 09:45:42 +0100 Subject: [PATCH 13/17] null check weak reference value --- .../eu/siacs/conversations/ui/RtpSessionActivity.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java index 56839d501..7f046def8 100644 --- a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java @@ -149,7 +149,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe @Override public boolean onKeyDown(final int keyCode, final KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN){ + if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { if (xmppConnectionService != null) { if (xmppConnectionService.getNotificationService().stopSoundAndVibration()) { return true; @@ -489,8 +489,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe return; } //TODO apparently this method is not getting called on Android 10 when using the task switcher - final boolean emptyReference = rtpConnectionReference == null || rtpConnectionReference.get() == null; - if (emptyReference && xmppConnectionService != null) { + if (emptyReference(rtpConnectionReference) && xmppConnectionService != null) { retractSessionProposal(); } } @@ -1077,7 +1076,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe updateRtpSessionProposalState(account, with, state); return; } - if (this.rtpConnectionReference == null) { + if (emptyReference(this.rtpConnectionReference)) { if (END_CARD.contains(state)) { Log.d(Config.LOGTAG, "not reinitializing session"); return; @@ -1175,4 +1174,8 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe intent.putExtra(EXTRA_LAST_ACTION, media.contains(Media.VIDEO) ? ACTION_MAKE_VIDEO_CALL : ACTION_MAKE_VOICE_CALL); setIntent(intent); } + + private static boolean emptyReference(final WeakReference weakReference) { + return weakReference == null || weakReference.get() == null; + } } From e947a3f808a994324bb5e6e6f0e7b45565b7df2d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 6 Mar 2021 12:43:59 +0100 Subject: [PATCH 14/17] modify boyy on muc reflection --- .../conversations/parser/MessageParser.java | 10 +++----- .../services/XmppConnectionService.java | 25 ++++++++++++++++--- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 17e00a975..dae71abda 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -384,7 +384,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece return; } } else if (query != null) { - Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": received mam result with invalid from ("+original.getFrom()+") or queryId ("+queryId+")"); + Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": received mam result with invalid from (" + original.getFrom() + ") or queryId (" + queryId + ")"); return; } else if (original.fromServer(account)) { Pair f; @@ -488,13 +488,11 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece if (conversation.getMucOptions().isSelf(counterpart)) { status = Message.STATUS_SEND_RECEIVED; isCarbon = true; //not really carbon but received from another resource - //TODO this would be the place to change the body after something like mod_pastebin - if (mXmppConnectionService.markMessage(conversation, remoteMsgId, status, serverMsgId)) { + if (mXmppConnectionService.markMessage(conversation, remoteMsgId, status, serverMsgId, body)) { return; } else if (remoteMsgId == null || Config.IGNORE_ID_REWRITE_IN_MUC) { - LocalizedContent localizedBody = packet.getBody(); - if (localizedBody != null) { - Message message = conversation.findSentMessageWithBody(localizedBody.content); + if (body != null) { + Message message = conversation.findSentMessageWithBody(body.content); if (message != null) { mXmppConnectionService.markMessage(message, status); return; diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index ab718a752..9cd3e2627 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -136,6 +136,7 @@ import eu.siacs.conversations.utils.TorServiceUtils; import eu.siacs.conversations.utils.WakeLockHelper; import eu.siacs.conversations.utils.XmppUri; import eu.siacs.conversations.xml.Element; +import eu.siacs.conversations.xml.LocalizedContent; import eu.siacs.conversations.xml.Namespace; import eu.siacs.conversations.xmpp.Jid; import eu.siacs.conversations.xmpp.OnBindListener; @@ -3950,16 +3951,28 @@ public class XmppConnectionService extends Service { return null; } - public boolean markMessage(Conversation conversation, String uuid, int status, String serverMessageId) { + public boolean markMessage(final Conversation conversation, final String uuid, final int status, final String serverMessageId) { + return markMessage(conversation, uuid, status, serverMessageId, null); + } + + public boolean markMessage(final Conversation conversation, final String uuid, final int status, final String serverMessageId, final LocalizedContent body) { if (uuid == null) { return false; } else { - Message message = conversation.findSentMessageWithUuid(uuid); + final Message message = conversation.findSentMessageWithUuid(uuid); if (message != null) { if (message.getServerMsgId() == null) { message.setServerMsgId(serverMessageId); } - markMessage(message, status); + if (body != null && body.content != null && !body.content.equals(message.getBody())) { + message.setBody(body.content); + if (body.count > 1) { + message.setBodyLanguage(body.language); + } + markMessage(message, status, null, true); + } else { + markMessage(message, status); + } return true; } else { return false; @@ -3973,6 +3986,10 @@ public class XmppConnectionService extends Service { public void markMessage(final Message message, final int status, final String errorMessage) { + markMessage(message, status, errorMessage, false); + } + + public void markMessage(final Message message, final int status, final String errorMessage, final boolean includeBody) { final int oldStatus = message.getStatus(); if (status == Message.STATUS_SEND_FAILED && (oldStatus == Message.STATUS_SEND_RECEIVED || oldStatus == Message.STATUS_SEND_DISPLAYED)) { return; @@ -3982,7 +3999,7 @@ public class XmppConnectionService extends Service { } message.setErrorMessage(errorMessage); message.setStatus(status); - databaseBackend.updateMessage(message, false); + databaseBackend.updateMessage(message, includeBody); updateConversationUi(); if (oldStatus != status && status == Message.STATUS_SEND_FAILED) { mNotificationService.pushFailedDelivery(message); From 0fa06d65b59f13bae8174e85186fa1d66f464c1b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 7 Mar 2021 09:59:09 +0100 Subject: [PATCH 15/17] overwrite body for plaintext group chat messages only --- .../conversations/services/XmppConnectionService.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 9cd3e2627..5880dfa56 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -3964,7 +3964,7 @@ public class XmppConnectionService extends Service { if (message.getServerMsgId() == null) { message.setServerMsgId(serverMessageId); } - if (body != null && body.content != null && !body.content.equals(message.getBody())) { + if (message.getEncryption() == Message.ENCRYPTION_NONE && isBodyModified(message, body)) { message.setBody(body.content); if (body.count > 1) { message.setBodyLanguage(body.language); @@ -3980,6 +3980,13 @@ public class XmppConnectionService extends Service { } } + private static boolean isBodyModified(final Message message, final LocalizedContent body) { + if (body == null || body.content == null) { + return false; + } + return !body.content.equals(message.getBody()); + } + public void markMessage(Message message, int status) { markMessage(message, status, null); } From 813b07e18dbb1e853a101bef20d0b6ce39a16e18 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 9 Mar 2021 09:58:33 +0100 Subject: [PATCH 16/17] pulled translations from transifex --- src/main/res/values-da-rDK/strings.xml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/res/values-da-rDK/strings.xml b/src/main/res/values-da-rDK/strings.xml index db011c433..73dc7022e 100644 --- a/src/main/res/values-da-rDK/strings.xml +++ b/src/main/res/values-da-rDK/strings.xml @@ -37,7 +37,7 @@ sender… - Dekrypter besked… Vent venligst… + Dekrypter besked. Vent venligst… OpenPGP krypteret besked Kaldenavn er allerede i brug Ugyldig kaldenavn @@ -107,7 +107,7 @@ Installer Installer venligst OpenKeychain tilbyder… - Venter… + venter… Ingen Open PGP nøgler fundet Kunne ikke kryptere din besked, fordi din kontakt ikke annoncerer deres offentlige nøgle.\n\nBed din kontakt om at konfigurere OpenPGP. Ingen OpenPGP nøgler fundet @@ -202,7 +202,7 @@ XEP-0363: HTTP File Upload XEP-0357: Push understøttet - Utilgængelig + utilgængelig Ingen meddelelser om offentlige nøgler sidst set lige nu sidst set for et minut siden @@ -241,7 +241,7 @@ Slet gruppechat Slet kanal Er du sikker på du vil slette denne gruppechat?\n\n Advarsel: Gruppechatten fjernes fuldstændigt på serveren. - Er du sikker på, at du vil ødelægge denne offentlige kanal?\n\nAdvarsel: Kanalen fjernes fuldstændigt på serveren. + Er du sikker på, at du vil slette denne offentlige kanal?\n\nAdvarsel: Kanalen fjernes fuldstændigt på serveren. Kunne ikke slette gruppechat Kunne ikke slette kanal Rediger titel på gruppechat @@ -466,7 +466,7 @@ Brudt Tilgængelighed Væk når enhed er låst - Væk når enheden er låst + Vis som Væk når enheden er låst Optaget i lydløs tilstand Vis som Optaget når enhed er i lydløs tilstand Behandl vibration som lydløs tilstand @@ -493,7 +493,7 @@ Send alle forbindelser gennem Tor-netværket. Kræver Orbot Værtsnavn Port - server- eller onion-adresse + Server- eller onion-adresse Dette er ikke en gyldigt port-nummer Dette er ikke et gyldigt værtsnavn %1$d af %2$d konti forbundet @@ -601,7 +601,7 @@ Du har bekræftet alle OMEMO-nøglerne i din besiddelse Stregkoden indeholder ingen fingeraftryk for denne samtale. Bekræft fingeraftryk - Brug kameraet til at skanne en kontakt\'s stregkode + Brug kameraet til at skanne en kontakt’s stregkode Vent til nøglerne hentes Del som stregkode Del som XMPP URL @@ -702,7 +702,7 @@ Udkast: OMEMO-kryptering OMEMO vil altid blive brugt for en-til-en og private gruppechats - OMEMO vil blive brugt som standard for nye samlater. + OMEMO vil blive brugt som standard for nye samtaler. OMEMO skal være tændt udtrykkeligt for nye samtaler. Opret genvej Skriftstørrelse @@ -772,7 +772,7 @@ Lavere kvalitet betyder mindre filer Mellem (360p) Høj (720p) - Annulleret + annulleret Du er allerede ved at udarbejde en besked. Funktionen ikke implementeret Ugyldig landekode From ddb54bb2224a6b215dd497eeddb88d7dd75c5cdf Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 11 Mar 2021 10:37:29 +0100 Subject: [PATCH 17/17] version bump to 2.9.8 + changelog --- CHANGELOG.md | 1 + build.gradle | 6 +++--- fastlane/metadata/android/en-US/changelogs/42006.txt | 2 ++ 3 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/42006.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index cbf14b739..bf0934a2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Version 2.9.8 * Verify A/V calls with preexisting OMEMO sessions +* Improve compatibility with non libwebrtc WebRTC implementations ### Version 2.9.7 diff --git a/build.gradle b/build.gradle index 0b909ebb0..7ab020371 100644 --- a/build.gradle +++ b/build.gradle @@ -66,7 +66,7 @@ dependencies { implementation "com.wefika:flowlayout:0.4.1" implementation 'net.ypresto.androidtranscoder:android-transcoder:0.3.0' implementation 'org.jxmpp:jxmpp-jid:0.6.4' - implementation 'org.osmdroid:osmdroid-android:6.1.5' + implementation 'org.osmdroid:osmdroid-android:6.1.10' implementation 'org.hsluv:hsluv:0.2' implementation 'org.conscrypt:conscrypt-android:2.2.1' implementation 'me.drakeet.support:toastcompat:1.1.0' @@ -91,8 +91,8 @@ android { defaultConfig { minSdkVersion 21 targetSdkVersion 29 - versionCode 42001 - versionName "2.9.8-beta" + versionCode 42006 + versionName "2.9.8" archivesBaseName += "-$versionName" applicationId "eu.siacs.conversations" resValue "string", "applicationId", applicationId diff --git a/fastlane/metadata/android/en-US/changelogs/42006.txt b/fastlane/metadata/android/en-US/changelogs/42006.txt new file mode 100644 index 000000000..91e2b904f --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/42006.txt @@ -0,0 +1,2 @@ +* Verify A/V calls with preexisting OMEMO sessions +* Improve compatibility with non libwebrtc WebRTC implementations