From 62faa163f0d5fc2d8d53067cc328f1905d1df370 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 13 Apr 2015 18:18:25 +0200 Subject: fixed typos --- src/main/java/eu/siacs/conversations/utils/GeoHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/GeoHelper.java b/src/main/java/eu/siacs/conversations/utils/GeoHelper.java index f7dda936..b31b9018 100644 --- a/src/main/java/eu/siacs/conversations/utils/GeoHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/GeoHelper.java @@ -20,7 +20,7 @@ public class GeoHelper { } public static ArrayList createGeoIntentsFromMessage(Message message) { - final ArrayList intents = new ArrayList(); + final ArrayList intents = new ArrayList<>(); Matcher matcher = GEO_URI.matcher(message.getBody()); if (!matcher.matches()) { return intents; -- cgit v1.2.3 From c4daa08170f0e468c0407d9db91a0de0415b6bf2 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Thu, 16 Apr 2015 21:55:52 +0200 Subject: fixed a bug in DNS helper code. fixes #1130 --- src/main/java/eu/siacs/conversations/utils/DNSHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index bcb2ca44..42dd1c95 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -121,7 +121,7 @@ public class DNSHelper { while (p > 0) { p -= s.get(i++).getPriority(); } - i--; + if (i>0) i--; // remove is expensive, but we have only a few entries // anyway SRV srv = s.remove(i); -- cgit v1.2.3 From 82daf849aa9b68dbd61f61923d8d618630af50bf Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 25 Apr 2015 14:42:32 +0200 Subject: fixed #1039 --- src/main/java/eu/siacs/conversations/utils/CryptoHelper.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java index eb7e2c3c..466bc409 100644 --- a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java @@ -91,6 +91,9 @@ public final class CryptoHelper { } public static String prettifyFingerprint(String fingerprint) { + if (fingerprint.length() < 40) { + return fingerprint; + } StringBuilder builder = new StringBuilder(fingerprint); builder.insert(8, " "); builder.insert(17, " "); -- cgit v1.2.3 From 4c486f5e583ddfc1f53f296d8a6fa9672981440a Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 10 May 2015 03:12:44 +0200 Subject: paint single unicode hearts as red and slightly larger --- src/main/java/eu/siacs/conversations/utils/UIHelper.java | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index c3195d86..49354753 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -17,6 +17,10 @@ import android.text.format.DateUtils; import android.util.Pair; public class UIHelper { + + public static String BLACK_HEART_SUIT = "\u2665"; + public static String HEAVY_BLACK_HEART_SUIT = "\u2764"; + private static final int SHORT_DATE_FLAGS = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR | DateUtils.FORMAT_ABBREV_ALL; private static final int FULL_DATE_FLAGS = DateUtils.FORMAT_SHOW_TIME -- cgit v1.2.3 From 33d1621e3b2c9a34689dfddc71eeb9ee4d91c348 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 10 May 2015 11:56:23 +0200 Subject: added white heart to new rendering as well --- src/main/java/eu/siacs/conversations/utils/UIHelper.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 49354753..2cfd5823 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -20,6 +20,7 @@ public class UIHelper { public static String BLACK_HEART_SUIT = "\u2665"; public static String HEAVY_BLACK_HEART_SUIT = "\u2764"; + public static String WHITE_HEART_SUIT = "\u2661"; private static final int SHORT_DATE_FLAGS = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR | DateUtils.FORMAT_ABBREV_ALL; -- cgit v1.2.3 From 239e86a98a4af8ab7ce7f6b96bed0bb4dc9e4bb5 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 10 May 2015 12:04:11 +0200 Subject: optimized heart render code a bit --- src/main/java/eu/siacs/conversations/utils/UIHelper.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 2cfd5823..9c62dcbf 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -1,6 +1,8 @@ package eu.siacs.conversations.utils; import java.net.URLConnection; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.Date; @@ -18,9 +20,11 @@ import android.util.Pair; public class UIHelper { - public static String BLACK_HEART_SUIT = "\u2665"; - public static String HEAVY_BLACK_HEART_SUIT = "\u2764"; - public static String WHITE_HEART_SUIT = "\u2661"; + private static String BLACK_HEART_SUIT = "\u2665"; + private static String HEAVY_BLACK_HEART_SUIT = "\u2764"; + private static String WHITE_HEART_SUIT = "\u2661"; + + public static final ArrayList HEARTS = new ArrayList<>(Arrays.asList(BLACK_HEART_SUIT,HEAVY_BLACK_HEART_SUIT,WHITE_HEART_SUIT)); private static final int SHORT_DATE_FLAGS = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR | DateUtils.FORMAT_ABBREV_ALL; -- cgit v1.2.3 From 82878cded1007331e953908dee11c66557e9ae20 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 13 May 2015 16:23:20 +0200 Subject: show location quick action after receiving a question about the users location --- .../eu/siacs/conversations/utils/UIHelper.java | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 9c62dcbf..e289e0e5 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Date; +import java.util.Locale; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Contact; @@ -26,6 +27,19 @@ public class UIHelper { public static final ArrayList HEARTS = new ArrayList<>(Arrays.asList(BLACK_HEART_SUIT,HEAVY_BLACK_HEART_SUIT,WHITE_HEART_SUIT)); + private static final ArrayList LOCATION_QUESTIONS = new ArrayList<>(Arrays.asList( + "where are you?", //en + "where r u?", //en + "whats your 20?", //en + "what is your 20?", //en + "what's your 20?", //en + "whats your twenty?", //en + "what is your twenty?", //en + "what's your twenty?", //en + "wo bist du?", //de + "wo sind sie?" //de + )); + private static final int SHORT_DATE_FLAGS = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR | DateUtils.FORMAT_ABBREV_ALL; private static final int FULL_DATE_FLAGS = DateUtils.FORMAT_SHOW_TIME @@ -234,4 +248,14 @@ public class UIHelper { return counterpart.toString().trim(); } } + + public static boolean receivedLocationQuestion(Message message) { + if (message == null + || message.getStatus() != Message.STATUS_RECEIVED + || message.getType() != Message.TYPE_TEXT) { + return false; + } + String body = message.getBody() == null ? null : message.getBody().trim().toLowerCase(Locale.getDefault()); + return LOCATION_QUESTIONS.contains(body); + } } -- cgit v1.2.3 From 4414cf3b277ec7a0a015e23eab197374f3714da6 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 13 May 2015 17:10:11 +0200 Subject: ignore question marks in location question --- .../eu/siacs/conversations/utils/UIHelper.java | 23 ++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index e289e0e5..51984c91 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -28,16 +28,18 @@ public class UIHelper { public static final ArrayList HEARTS = new ArrayList<>(Arrays.asList(BLACK_HEART_SUIT,HEAVY_BLACK_HEART_SUIT,WHITE_HEART_SUIT)); private static final ArrayList LOCATION_QUESTIONS = new ArrayList<>(Arrays.asList( - "where are you?", //en - "where r u?", //en - "whats your 20?", //en - "what is your 20?", //en - "what's your 20?", //en - "whats your twenty?", //en - "what is your twenty?", //en - "what's your twenty?", //en - "wo bist du?", //de - "wo sind sie?" //de + "where are you", //en + "where r u", //en + "whats your 20", //en + "what is your 20", //en + "what's your 20", //en + "whats your twenty", //en + "what is your twenty", //en + "what's your twenty", //en + "wo bist du", //de + "wo sind sie", //de + "wo seid ihr", //de + "dónde estás" //es )); private static final int SHORT_DATE_FLAGS = DateUtils.FORMAT_SHOW_DATE @@ -256,6 +258,7 @@ public class UIHelper { return false; } String body = message.getBody() == null ? null : message.getBody().trim().toLowerCase(Locale.getDefault()); + body = body.replace("?","").replace("¿",""); return LOCATION_QUESTIONS.contains(body); } } -- cgit v1.2.3 From 8dfa701043d6e442f24edeb4fec48e9d07377a90 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 14 May 2015 12:08:43 +0200 Subject: added a few location questions --- src/main/java/eu/siacs/conversations/utils/UIHelper.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 51984c91..2f96a83a 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -29,7 +29,8 @@ public class UIHelper { private static final ArrayList LOCATION_QUESTIONS = new ArrayList<>(Arrays.asList( "where are you", //en - "where r u", //en + "where are you now", //en + "where are you right now", //en "whats your 20", //en "what is your 20", //en "what's your 20", //en @@ -37,9 +38,13 @@ public class UIHelper { "what is your twenty", //en "what's your twenty", //en "wo bist du", //de - "wo sind sie", //de + "wo bist du jetzt", //de + "wo bist du gerade", //de "wo seid ihr", //de - "dónde estás" //es + "wo seid ihr jetzt", //de + "wo seid ihr gerade", //de + "dónde estás", //es + "donde estas" //es )); private static final int SHORT_DATE_FLAGS = DateUtils.FORMAT_SHOW_DATE -- cgit v1.2.3 From 78847d0749765b7c1e424a8a264d8f23a43170b0 Mon Sep 17 00:00:00 2001 From: "M. Dietrich" Date: Wed, 20 May 2015 11:34:11 +0200 Subject: add extra jid to intend "show location" --- src/main/java/eu/siacs/conversations/utils/GeoHelper.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/GeoHelper.java b/src/main/java/eu/siacs/conversations/utils/GeoHelper.java index b31b9018..dd8ebd3d 100644 --- a/src/main/java/eu/siacs/conversations/utils/GeoHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/GeoHelper.java @@ -54,6 +54,7 @@ public class GeoHelper { Intent locationPluginIntent = new Intent("eu.siacs.conversations.location.show"); locationPluginIntent.putExtra("latitude",latitude); locationPluginIntent.putExtra("longitude",longitude); + locationPluginIntent.putExtra("jid",conversation.getJid().toString()); if (conversation.getMode() == Conversation.MODE_SINGLE && message.getStatus() == Message.STATUS_RECEIVED) { locationPluginIntent.putExtra("name",conversation.getName()); } -- cgit v1.2.3 From 4759607a772642735d57b476c9c474b128695027 Mon Sep 17 00:00:00 2001 From: "M. Dietrich" Date: Wed, 20 May 2015 15:43:45 +0200 Subject: fix to detect the sender jid correctly --- src/main/java/eu/siacs/conversations/utils/GeoHelper.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/GeoHelper.java b/src/main/java/eu/siacs/conversations/utils/GeoHelper.java index dd8ebd3d..74f91a98 100644 --- a/src/main/java/eu/siacs/conversations/utils/GeoHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/GeoHelper.java @@ -54,9 +54,14 @@ public class GeoHelper { Intent locationPluginIntent = new Intent("eu.siacs.conversations.location.show"); locationPluginIntent.putExtra("latitude",latitude); locationPluginIntent.putExtra("longitude",longitude); - locationPluginIntent.putExtra("jid",conversation.getJid().toString()); - if (conversation.getMode() == Conversation.MODE_SINGLE && message.getStatus() == Message.STATUS_RECEIVED) { - locationPluginIntent.putExtra("name",conversation.getName()); + if (conversation.getMode() == Conversation.MODE_SINGLE) { + if (message.getStatus() == Message.STATUS_RECEIVED) { + locationPluginIntent.putExtra("name",conversation.getName()); + locationPluginIntent.putExtra("jid",message.getCounterpart().toString()); + } + else { + locationPluginIntent.putExtra("jid",conversation.getAccount().getJid().toString()); + } } intents.add(locationPluginIntent); -- cgit v1.2.3 From 5373956e19f318551841d59885f4c2567ffd46a3 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 28 May 2015 16:55:48 +0200 Subject: use dns library to resolve missing ipv6 or ipv4 addresses --- .../eu/siacs/conversations/utils/DNSHelper.java | 31 +++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index 42dd1c95..5135acf7 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -142,11 +142,21 @@ public class DNSHelper { for (SRV srv : result) { if (ips6.containsKey(srv.getName())) { values.add(createNamePortBundle(srv.getName(),srv.getPort(),ips6)); + } else { + DNSMessage response = client.query(srv.getName(), TYPE.AAAA, CLASS.IN, dnsServer.getHostAddress()); + if (response.getAnswers().length >= 1) { + values.add(createNamePortBundle(srv.getName(),srv.getPort(),response.getAnswers()[0].getPayload())); + } } if (ips4.containsKey(srv.getName())) { values.add(createNamePortBundle(srv.getName(),srv.getPort(),ips4)); + } else { + DNSMessage response = client.query(srv.getName(), TYPE.A, CLASS.IN, dnsServer.getHostAddress()); + if (response.getAnswers().length >= 1) { + values.add(createNamePortBundle(srv.getName(),srv.getPort(),response.getAnswers()[0].getPayload())); + } } - values.add(createNamePortBundle(srv.getName(),srv.getPort(),null)); + values.add(createNamePortBundle(srv.getName(), srv.getPort())); } bundle.putParcelableArrayList("values", values); } catch (SocketTimeoutException e) { @@ -157,6 +167,13 @@ public class DNSHelper { return bundle; } + private static Bundle createNamePortBundle(String name, int port) { + Bundle namePort = new Bundle(); + namePort.putString("name", name); + namePort.putInt("port", port); + return namePort; + } + private static Bundle createNamePortBundle(String name, int port, TreeMap> ips) { Bundle namePort = new Bundle(); namePort.putString("name", name); @@ -169,6 +186,18 @@ public class DNSHelper { return namePort; } + private static Bundle createNamePortBundle(String name, int port, Data data) { + Bundle namePort = new Bundle(); + namePort.putString("name", name); + namePort.putInt("port", port); + if (data instanceof A) { + namePort.putString("ip", data.toString()); + } else if (data instanceof AAAA) { + namePort.putString("ip","["+data.toString()+"]"); + } + return namePort; + } + final protected static char[] hexArray = "0123456789ABCDEF".toCharArray(); public static String bytesToHex(byte[] bytes) { -- cgit v1.2.3 From a577ec7c318d734de3ed8c2dc5ab1dd4b773b78a Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 28 May 2015 17:31:46 +0200 Subject: let dns library take care of no-srv style hosts as well --- .../eu/siacs/conversations/utils/DNSHelper.java | 25 ++++++++++++++-------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index 5135acf7..e91005a1 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -37,9 +37,6 @@ public class DNSHelper { Bundle b = queryDNS(host, ip); if (b.containsKey("values")) { return b; - } else if (b.containsKey("error") - && "nosrv".equals(b.getString("error", null))) { - return b; } } } @@ -134,26 +131,35 @@ public class DNSHelper { } + ArrayList values = new ArrayList<>(); if (result.size() == 0) { - bundle.putString("error", "nosrv"); + DNSMessage response; + response = client.query(host, TYPE.A, CLASS.IN, dnsServer.getHostAddress()); + for(int i = 0; i < response.getAnswers().length; ++i) { + values.add(createNamePortBundle(host,5222,response.getAnswers()[i].getPayload())); + } + response = client.query(host, TYPE.AAAA, CLASS.IN, dnsServer.getHostAddress()); + for(int i = 0; i < response.getAnswers().length; ++i) { + values.add(createNamePortBundle(host,5222,response.getAnswers()[i].getPayload())); + } + bundle.putParcelableArrayList("values", values); return bundle; } - ArrayList values = new ArrayList<>(); for (SRV srv : result) { if (ips6.containsKey(srv.getName())) { values.add(createNamePortBundle(srv.getName(),srv.getPort(),ips6)); } else { DNSMessage response = client.query(srv.getName(), TYPE.AAAA, CLASS.IN, dnsServer.getHostAddress()); - if (response.getAnswers().length >= 1) { - values.add(createNamePortBundle(srv.getName(),srv.getPort(),response.getAnswers()[0].getPayload())); + for(int i = 0; i < response.getAnswers().length; ++i) { + values.add(createNamePortBundle(host,5222,response.getAnswers()[i].getPayload())); } } if (ips4.containsKey(srv.getName())) { values.add(createNamePortBundle(srv.getName(),srv.getPort(),ips4)); } else { DNSMessage response = client.query(srv.getName(), TYPE.A, CLASS.IN, dnsServer.getHostAddress()); - if (response.getAnswers().length >= 1) { - values.add(createNamePortBundle(srv.getName(),srv.getPort(),response.getAnswers()[0].getPayload())); + for(int i = 0; i < response.getAnswers().length; ++i) { + values.add(createNamePortBundle(host,5222,response.getAnswers()[i].getPayload())); } } values.add(createNamePortBundle(srv.getName(), srv.getPort())); @@ -162,6 +168,7 @@ public class DNSHelper { } catch (SocketTimeoutException e) { bundle.putString("error", "timeout"); } catch (Exception e) { + Log.d(Config.LOGTAG,e.getMessage()); bundle.putString("error", "unhandled"); } return bundle; -- cgit v1.2.3 From 8f07e4c441778e476119f25cc8cac833e0937508 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 4 Jun 2015 02:48:07 +0200 Subject: streamlined dns helper by ignoring weight --- .../eu/siacs/conversations/utils/DNSHelper.java | 65 ++++------------------ 1 file changed, 10 insertions(+), 55 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index e91005a1..7a51c1ce 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -47,88 +47,43 @@ public class DNSHelper { Bundle bundle = new Bundle(); try { String qname = "_xmpp-client._tcp." + host; - Log.d(Config.LOGTAG, - "using dns server: " + dnsServer.getHostAddress() - + " to look up " + host); - DNSMessage message = client.query(qname, TYPE.SRV, CLASS.IN, - dnsServer.getHostAddress()); - - // How should we handle priorities and weight? - // Wikipedia has a nice article about priorities vs. weights: - // https://en.wikipedia.org/wiki/SRV_record#Provisioning_for_high_service_availability - - // we bucket the SRV records based on priority, pick per priority - // a random order respecting the weight, and dump that priority by - // priority + Log.d(Config.LOGTAG, "using dns server: " + dnsServer.getHostAddress() + " to look up " + host); + DNSMessage message = client.query(qname, TYPE.SRV, CLASS.IN, dnsServer.getHostAddress()); TreeMap> priorities = new TreeMap<>(); TreeMap> ips4 = new TreeMap<>(); TreeMap> ips6 = new TreeMap<>(); - for (Record[] rrset : new Record[][] { message.getAnswers(), - message.getAdditionalResourceRecords() }) { + for (Record[] rrset : new Record[][] { message.getAnswers(), message.getAdditionalResourceRecords() }) { for (Record rr : rrset) { Data d = rr.getPayload(); - if (d instanceof SRV - && NameUtil.idnEquals(qname, rr.getName())) { + if (d instanceof SRV && NameUtil.idnEquals(qname, rr.getName())) { SRV srv = (SRV) d; if (!priorities.containsKey(srv.getPriority())) { - priorities.put(srv.getPriority(), - new ArrayList(2)); + priorities.put(srv.getPriority(),new ArrayList()); } priorities.get(srv.getPriority()).add(srv); } if (d instanceof A) { - A arecord = (A) d; + A a = (A) d; if (!ips4.containsKey(rr.getName())) { - ips4.put(rr.getName(), new ArrayList(3)); + ips4.put(rr.getName(), new ArrayList()); } - ips4.get(rr.getName()).add(arecord.toString()); + ips4.get(rr.getName()).add(a.toString()); } if (d instanceof AAAA) { AAAA aaaa = (AAAA) d; if (!ips6.containsKey(rr.getName())) { - ips6.put(rr.getName(), new ArrayList(3)); + ips6.put(rr.getName(), new ArrayList()); } ips6.get(rr.getName()).add("[" + aaaa.toString() + "]"); } } } - Random rnd = new Random(); - ArrayList result = new ArrayList<>( - priorities.size() * 2 + 1); + ArrayList result = new ArrayList<>(); for (ArrayList s : priorities.values()) { - - // trivial case - if (s.size() <= 1) { - result.addAll(s); - continue; - } - - long totalweight = 0l; - for (SRV srv : s) { - totalweight += srv.getWeight(); - } - - while (totalweight > 0l && s.size() > 0) { - long p = (rnd.nextLong() & 0x7fffffffffffffffl) - % totalweight; - int i = 0; - while (p > 0) { - p -= s.get(i++).getPriority(); - } - if (i>0) i--; - // remove is expensive, but we have only a few entries - // anyway - SRV srv = s.remove(i); - totalweight -= srv.getWeight(); - result.add(srv); - } - - Collections.shuffle(s, rnd); result.addAll(s); - } ArrayList values = new ArrayList<>(); -- cgit v1.2.3 From a4e9f0c9c04c5fcc6e9686552a5fcc0198526a49 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 4 Jun 2015 16:26:51 +0200 Subject: fixed obvious bug in dns helper --- src/main/java/eu/siacs/conversations/utils/DNSHelper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index 7a51c1ce..6f414ccc 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -106,7 +106,7 @@ public class DNSHelper { } else { DNSMessage response = client.query(srv.getName(), TYPE.AAAA, CLASS.IN, dnsServer.getHostAddress()); for(int i = 0; i < response.getAnswers().length; ++i) { - values.add(createNamePortBundle(host,5222,response.getAnswers()[i].getPayload())); + values.add(createNamePortBundle(srv.getName(),srv.getPort(),response.getAnswers()[i].getPayload())); } } if (ips4.containsKey(srv.getName())) { @@ -114,7 +114,7 @@ public class DNSHelper { } else { DNSMessage response = client.query(srv.getName(), TYPE.A, CLASS.IN, dnsServer.getHostAddress()); for(int i = 0; i < response.getAnswers().length; ++i) { - values.add(createNamePortBundle(host,5222,response.getAnswers()[i].getPayload())); + values.add(createNamePortBundle(srv.getName(),srv.getPort(),response.getAnswers()[i].getPayload())); } } values.add(createNamePortBundle(srv.getName(), srv.getPort())); -- cgit v1.2.3 From 9d1e8205a2d362a33e142a49db1787fe5145ce3f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 5 Jun 2015 08:46:06 +0200 Subject: made i/o and memory intensive operations execute in serial order --- .../utils/SerialSingleThreadExecutor.java | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/main/java/eu/siacs/conversations/utils/SerialSingleThreadExecutor.java (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/SerialSingleThreadExecutor.java b/src/main/java/eu/siacs/conversations/utils/SerialSingleThreadExecutor.java new file mode 100644 index 00000000..bfb4668d --- /dev/null +++ b/src/main/java/eu/siacs/conversations/utils/SerialSingleThreadExecutor.java @@ -0,0 +1,34 @@ +package eu.siacs.conversations.utils; + +import java.util.ArrayDeque; +import java.util.Queue; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; + +public class SerialSingleThreadExecutor implements Executor { + + final Executor executor = Executors.newSingleThreadExecutor(); + final Queue tasks = new ArrayDeque(); + Runnable active; + + public synchronized void execute(final Runnable r) { + tasks.offer(new Runnable() { + public void run() { + try { + r.run(); + } finally { + scheduleNext(); + } + } + }); + if (active == null) { + scheduleNext(); + } + } + + protected synchronized void scheduleNext() { + if ((active = tasks.poll()) != null) { + executor.execute(active); + } + } +} \ No newline at end of file -- cgit v1.2.3 From 5a48afdd4d44b5865831df470a2c5d00e9cc9599 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 19 Jun 2015 16:25:08 +0200 Subject: don't perform dns lookups on domain parts that obviously look like ip addresses --- .../eu/siacs/conversations/utils/DNSHelper.java | 24 +++++++++++++--------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index 6f414ccc..bb354ae0 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -20,11 +20,19 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Random; import java.util.TreeMap; +import java.util.regex.Pattern; import android.os.Bundle; import android.util.Log; public class DNSHelper { + + public static final Pattern PATTERN_IPV4 = Pattern.compile("\\A(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\z"); + public static final Pattern PATTERN_IPV6_HEX4DECCOMPRESSED = Pattern.compile("\\A((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) ::((?:[0-9A-Fa-f]{1,4}:)*)(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\z"); + public static final Pattern PATTERN_IPV6_6HEX4DEC = Pattern.compile("\\A((?:[0-9A-Fa-f]{1,4}:){6,6})(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\z"); + public static final Pattern PATTERN_IPV6_HEXCOMPRESSED = Pattern.compile("\\A((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)\\z"); + public static final Pattern PATTERN_IPV6 = Pattern.compile("\\A(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\\z"); + protected static Client client = new Client(); public static Bundle getSRVRecord(final Jid jid) throws IOException { @@ -160,15 +168,11 @@ public class DNSHelper { return namePort; } - final protected static char[] hexArray = "0123456789ABCDEF".toCharArray(); - - public static String bytesToHex(byte[] bytes) { - char[] hexChars = new char[bytes.length * 2]; - for (int j = 0; j < bytes.length; j++) { - int v = bytes[j] & 0xFF; - hexChars[j * 2] = hexArray[v >>> 4]; - hexChars[j * 2 + 1] = hexArray[v & 0x0F]; - } - return new String(hexChars); + public static boolean isIp(final String server) { + return PATTERN_IPV4.matcher(server).matches() + || PATTERN_IPV6.matcher(server).matches() + || PATTERN_IPV6_6HEX4DEC.matcher(server).matches() + || PATTERN_IPV6_HEX4DECCOMPRESSED.matcher(server).matches() + || PATTERN_IPV6_HEXCOMPRESSED.matcher(server).matches(); } } -- cgit v1.2.3 From 9eb9a522050589e60bc7c76b2b040b1dadb7fd1d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 28 Jun 2015 11:19:07 +0200 Subject: initial http upload support be careful: little error handling and no encryption --- src/main/java/eu/siacs/conversations/utils/Xmlns.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/Xmlns.java b/src/main/java/eu/siacs/conversations/utils/Xmlns.java index 17fd2d26..de0a29ce 100644 --- a/src/main/java/eu/siacs/conversations/utils/Xmlns.java +++ b/src/main/java/eu/siacs/conversations/utils/Xmlns.java @@ -5,4 +5,5 @@ public final class Xmlns { public static final String ROSTER = "jabber:iq:roster"; public static final String REGISTER = "jabber:iq:register"; public static final String BYTE_STREAMS = "http://jabber.org/protocol/bytestreams"; + public static final String HTTP_UPLOAD = "urn:xmpp:http:upload"; } -- cgit v1.2.3 From 9190e0307694dae6462c8f8f63589a7bab8ae4bc Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 30 Jun 2015 20:11:50 +0200 Subject: changed namespace of the http upload feature --- src/main/java/eu/siacs/conversations/utils/Xmlns.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/Xmlns.java b/src/main/java/eu/siacs/conversations/utils/Xmlns.java index de0a29ce..868566d9 100644 --- a/src/main/java/eu/siacs/conversations/utils/Xmlns.java +++ b/src/main/java/eu/siacs/conversations/utils/Xmlns.java @@ -5,5 +5,5 @@ public final class Xmlns { public static final String ROSTER = "jabber:iq:roster"; public static final String REGISTER = "jabber:iq:register"; public static final String BYTE_STREAMS = "http://jabber.org/protocol/bytestreams"; - public static final String HTTP_UPLOAD = "urn:xmpp:http:upload"; + public static final String HTTP_UPLOAD = "eu:siacs:conversations:http:upload"; } -- cgit v1.2.3 From c20a088ea811ab702244006fa2588cbdf7be0099 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 1 Jul 2015 16:01:18 +0200 Subject: changed mime type handling --- .../eu/siacs/conversations/utils/MimeUtils.java | 487 +++++++++++++++++++++ .../eu/siacs/conversations/utils/UIHelper.java | 11 +- 2 files changed, 488 insertions(+), 10 deletions(-) create mode 100644 src/main/java/eu/siacs/conversations/utils/MimeUtils.java (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/MimeUtils.java b/src/main/java/eu/siacs/conversations/utils/MimeUtils.java new file mode 100644 index 00000000..a9e89d1b --- /dev/null +++ b/src/main/java/eu/siacs/conversations/utils/MimeUtils.java @@ -0,0 +1,487 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package eu.siacs.conversations.utils; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +/** + * Utilities for dealing with MIME types. + * Used to implement java.net.URLConnection and android.webkit.MimeTypeMap. + */ +public final class MimeUtils { + private static final Map mimeTypeToExtensionMap = new HashMap(); + private static final Map extensionToMimeTypeMap = new HashMap(); + static { + // The following table is based on /etc/mime.types data minus + // chemical/* MIME types and MIME types that don't map to any + // file extensions. We also exclude top-level domain names to + // deal with cases like: + // + // mail.google.com/a/google.com + // + // and "active" MIME types (due to potential security issues). + // Note that this list is _not_ in alphabetical order and must not be sorted. + // The "most popular" extension must come first, so that it's the one returned + // by guessExtensionFromMimeType. + add("application/andrew-inset", "ez"); + add("application/dsptype", "tsp"); + add("application/hta", "hta"); + add("application/mac-binhex40", "hqx"); + add("application/mathematica", "nb"); + add("application/msaccess", "mdb"); + add("application/oda", "oda"); + add("application/ogg", "ogg"); + add("application/ogg", "oga"); + add("application/pdf", "pdf"); + add("application/pgp-keys", "key"); + add("application/pgp-signature", "pgp"); + add("application/pics-rules", "prf"); + add("application/pkix-cert", "cer"); + add("application/rar", "rar"); + add("application/rdf+xml", "rdf"); + add("application/rss+xml", "rss"); + add("application/zip", "zip"); + add("application/vnd.android.package-archive", "apk"); + add("application/vnd.cinderella", "cdy"); + add("application/vnd.ms-pki.stl", "stl"); + add("application/vnd.oasis.opendocument.database", "odb"); + add("application/vnd.oasis.opendocument.formula", "odf"); + add("application/vnd.oasis.opendocument.graphics", "odg"); + add("application/vnd.oasis.opendocument.graphics-template", "otg"); + add("application/vnd.oasis.opendocument.image", "odi"); + add("application/vnd.oasis.opendocument.spreadsheet", "ods"); + add("application/vnd.oasis.opendocument.spreadsheet-template", "ots"); + add("application/vnd.oasis.opendocument.text", "odt"); + add("application/vnd.oasis.opendocument.text-master", "odm"); + add("application/vnd.oasis.opendocument.text-template", "ott"); + add("application/vnd.oasis.opendocument.text-web", "oth"); + add("application/vnd.google-earth.kml+xml", "kml"); + add("application/vnd.google-earth.kmz", "kmz"); + add("application/msword", "doc"); + add("application/msword", "dot"); + add("application/vnd.openxmlformats-officedocument.wordprocessingml.document", "docx"); + add("application/vnd.openxmlformats-officedocument.wordprocessingml.template", "dotx"); + add("application/vnd.ms-excel", "xls"); + add("application/vnd.ms-excel", "xlt"); + add("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "xlsx"); + add("application/vnd.openxmlformats-officedocument.spreadsheetml.template", "xltx"); + add("application/vnd.ms-powerpoint", "ppt"); + add("application/vnd.ms-powerpoint", "pot"); + add("application/vnd.ms-powerpoint", "pps"); + add("application/vnd.openxmlformats-officedocument.presentationml.presentation", "pptx"); + add("application/vnd.openxmlformats-officedocument.presentationml.template", "potx"); + add("application/vnd.openxmlformats-officedocument.presentationml.slideshow", "ppsx"); + add("application/vnd.rim.cod", "cod"); + add("application/vnd.smaf", "mmf"); + add("application/vnd.stardivision.calc", "sdc"); + add("application/vnd.stardivision.draw", "sda"); + add("application/vnd.stardivision.impress", "sdd"); + add("application/vnd.stardivision.impress", "sdp"); + add("application/vnd.stardivision.math", "smf"); + add("application/vnd.stardivision.writer", "sdw"); + add("application/vnd.stardivision.writer", "vor"); + add("application/vnd.stardivision.writer-global", "sgl"); + add("application/vnd.sun.xml.calc", "sxc"); + add("application/vnd.sun.xml.calc.template", "stc"); + add("application/vnd.sun.xml.draw", "sxd"); + add("application/vnd.sun.xml.draw.template", "std"); + add("application/vnd.sun.xml.impress", "sxi"); + add("application/vnd.sun.xml.impress.template", "sti"); + add("application/vnd.sun.xml.math", "sxm"); + add("application/vnd.sun.xml.writer", "sxw"); + add("application/vnd.sun.xml.writer.global", "sxg"); + add("application/vnd.sun.xml.writer.template", "stw"); + add("application/vnd.visio", "vsd"); + add("application/x-abiword", "abw"); + add("application/x-apple-diskimage", "dmg"); + add("application/x-bcpio", "bcpio"); + add("application/x-bittorrent", "torrent"); + add("application/x-cdf", "cdf"); + add("application/x-cdlink", "vcd"); + add("application/x-chess-pgn", "pgn"); + add("application/x-cpio", "cpio"); + add("application/x-debian-package", "deb"); + add("application/x-debian-package", "udeb"); + add("application/x-director", "dcr"); + add("application/x-director", "dir"); + add("application/x-director", "dxr"); + add("application/x-dms", "dms"); + add("application/x-doom", "wad"); + add("application/x-dvi", "dvi"); + add("application/x-font", "pfa"); + add("application/x-font", "pfb"); + add("application/x-font", "gsf"); + add("application/x-font", "pcf"); + add("application/x-font", "pcf.Z"); + add("application/x-freemind", "mm"); + // application/futuresplash isn't IANA, so application/x-futuresplash should come first. + add("application/x-futuresplash", "spl"); + add("application/futuresplash", "spl"); + add("application/x-gnumeric", "gnumeric"); + add("application/x-go-sgf", "sgf"); + add("application/x-graphing-calculator", "gcf"); + add("application/x-gtar", "tgz"); + add("application/x-gtar", "gtar"); + add("application/x-gtar", "taz"); + add("application/x-hdf", "hdf"); + add("application/x-ica", "ica"); + add("application/x-internet-signup", "ins"); + add("application/x-internet-signup", "isp"); + add("application/x-iphone", "iii"); + add("application/x-iso9660-image", "iso"); + add("application/x-jmol", "jmz"); + add("application/x-kchart", "chrt"); + add("application/x-killustrator", "kil"); + add("application/x-koan", "skp"); + add("application/x-koan", "skd"); + add("application/x-koan", "skt"); + add("application/x-koan", "skm"); + add("application/x-kpresenter", "kpr"); + add("application/x-kpresenter", "kpt"); + add("application/x-kspread", "ksp"); + add("application/x-kword", "kwd"); + add("application/x-kword", "kwt"); + add("application/x-latex", "latex"); + add("application/x-lha", "lha"); + add("application/x-lzh", "lzh"); + add("application/x-lzx", "lzx"); + add("application/x-maker", "frm"); + add("application/x-maker", "maker"); + add("application/x-maker", "frame"); + add("application/x-maker", "fb"); + add("application/x-maker", "book"); + add("application/x-maker", "fbdoc"); + add("application/x-mif", "mif"); + add("application/x-ms-wmd", "wmd"); + add("application/x-ms-wmz", "wmz"); + add("application/x-msi", "msi"); + add("application/x-ns-proxy-autoconfig", "pac"); + add("application/x-nwc", "nwc"); + add("application/x-object", "o"); + add("application/x-oz-application", "oza"); + add("application/x-pem-file", "pem"); + add("application/x-pkcs12", "p12"); + add("application/x-pkcs12", "pfx"); + add("application/x-pkcs7-certreqresp", "p7r"); + add("application/x-pkcs7-crl", "crl"); + add("application/x-quicktimeplayer", "qtl"); + add("application/x-shar", "shar"); + add("application/x-shockwave-flash", "swf"); + add("application/x-stuffit", "sit"); + add("application/x-sv4cpio", "sv4cpio"); + add("application/x-sv4crc", "sv4crc"); + add("application/x-tar", "tar"); + add("application/x-texinfo", "texinfo"); + add("application/x-texinfo", "texi"); + add("application/x-troff", "t"); + add("application/x-troff", "roff"); + add("application/x-troff-man", "man"); + add("application/x-ustar", "ustar"); + add("application/x-wais-source", "src"); + add("application/x-wingz", "wz"); + add("application/x-webarchive", "webarchive"); + add("application/x-webarchive-xml", "webarchivexml"); + add("application/x-x509-ca-cert", "crt"); + add("application/x-x509-user-cert", "crt"); + add("application/x-x509-server-cert", "crt"); + add("application/x-xcf", "xcf"); + add("application/x-xfig", "fig"); + add("application/xhtml+xml", "xhtml"); + add("audio/3gpp", "3gpp"); + add("audio/aac", "aac"); + add("audio/aac-adts", "aac"); + add("audio/amr", "amr"); + add("audio/amr-wb", "awb"); + add("audio/basic", "snd"); + add("audio/flac", "flac"); + add("application/x-flac", "flac"); + add("audio/imelody", "imy"); + add("audio/midi", "mid"); + add("audio/midi", "midi"); + add("audio/midi", "ota"); + add("audio/midi", "kar"); + add("audio/midi", "rtttl"); + add("audio/midi", "xmf"); + add("audio/mobile-xmf", "mxmf"); + // add ".mp3" first so it will be the default for guessExtensionFromMimeType + add("audio/mpeg", "mp3"); + add("audio/mpeg", "mpga"); + add("audio/mpeg", "mpega"); + add("audio/mpeg", "mp2"); + add("audio/mpeg", "m4a"); + add("audio/mpegurl", "m3u"); + add("audio/prs.sid", "sid"); + add("audio/x-aiff", "aif"); + add("audio/x-aiff", "aiff"); + add("audio/x-aiff", "aifc"); + add("audio/x-gsm", "gsm"); + add("audio/x-matroska", "mka"); + add("audio/x-mpegurl", "m3u"); + add("audio/x-ms-wma", "wma"); + add("audio/x-ms-wax", "wax"); + add("audio/x-pn-realaudio", "ra"); + add("audio/x-pn-realaudio", "rm"); + add("audio/x-pn-realaudio", "ram"); + add("audio/x-realaudio", "ra"); + add("audio/x-scpls", "pls"); + add("audio/x-sd2", "sd2"); + add("audio/x-wav", "wav"); + // image/bmp isn't IANA, so image/x-ms-bmp should come first. + add("image/x-ms-bmp", "bmp"); + add("image/bmp", "bmp"); + add("image/gif", "gif"); + // image/ico isn't IANA, so image/x-icon should come first. + add("image/x-icon", "ico"); + add("image/ico", "cur"); + add("image/ico", "ico"); + add("image/ief", "ief"); + // add ".jpg" first so it will be the default for guessExtensionFromMimeType + add("image/jpeg", "jpg"); + add("image/jpeg", "jpeg"); + add("image/jpeg", "jpe"); + add("image/pcx", "pcx"); + add("image/png", "png"); + add("image/svg+xml", "svg"); + add("image/svg+xml", "svgz"); + add("image/tiff", "tiff"); + add("image/tiff", "tif"); + add("image/vnd.djvu", "djvu"); + add("image/vnd.djvu", "djv"); + add("image/vnd.wap.wbmp", "wbmp"); + add("image/webp", "webp"); + add("image/x-cmu-raster", "ras"); + add("image/x-coreldraw", "cdr"); + add("image/x-coreldrawpattern", "pat"); + add("image/x-coreldrawtemplate", "cdt"); + add("image/x-corelphotopaint", "cpt"); + add("image/x-jg", "art"); + add("image/x-jng", "jng"); + add("image/x-photoshop", "psd"); + add("image/x-portable-anymap", "pnm"); + add("image/x-portable-bitmap", "pbm"); + add("image/x-portable-graymap", "pgm"); + add("image/x-portable-pixmap", "ppm"); + add("image/x-rgb", "rgb"); + add("image/x-xbitmap", "xbm"); + add("image/x-xpixmap", "xpm"); + add("image/x-xwindowdump", "xwd"); + add("model/iges", "igs"); + add("model/iges", "iges"); + add("model/mesh", "msh"); + add("model/mesh", "mesh"); + add("model/mesh", "silo"); + add("text/calendar", "ics"); + add("text/calendar", "icz"); + add("text/comma-separated-values", "csv"); + add("text/css", "css"); + add("text/html", "htm"); + add("text/html", "html"); + add("text/h323", "323"); + add("text/iuls", "uls"); + add("text/mathml", "mml"); + // add ".txt" first so it will be the default for guessExtensionFromMimeType + add("text/plain", "txt"); + add("text/plain", "asc"); + add("text/plain", "text"); + add("text/plain", "diff"); + add("text/plain", "po"); // reserve "pot" for vnd.ms-powerpoint + add("text/richtext", "rtx"); + add("text/rtf", "rtf"); + add("text/text", "phps"); + add("text/tab-separated-values", "tsv"); + add("text/xml", "xml"); + add("text/x-bibtex", "bib"); + add("text/x-boo", "boo"); + add("text/x-c++hdr", "hpp"); + add("text/x-c++hdr", "h++"); + add("text/x-c++hdr", "hxx"); + add("text/x-c++hdr", "hh"); + add("text/x-c++src", "cpp"); + add("text/x-c++src", "c++"); + add("text/x-c++src", "cc"); + add("text/x-c++src", "cxx"); + add("text/x-chdr", "h"); + add("text/x-component", "htc"); + add("text/x-csh", "csh"); + add("text/x-csrc", "c"); + add("text/x-dsrc", "d"); + add("text/x-haskell", "hs"); + add("text/x-java", "java"); + add("text/x-literate-haskell", "lhs"); + add("text/x-moc", "moc"); + add("text/x-pascal", "p"); + add("text/x-pascal", "pas"); + add("text/x-pcs-gcd", "gcd"); + add("text/x-setext", "etx"); + add("text/x-tcl", "tcl"); + add("text/x-tex", "tex"); + add("text/x-tex", "ltx"); + add("text/x-tex", "sty"); + add("text/x-tex", "cls"); + add("text/x-vcalendar", "vcs"); + add("text/x-vcard", "vcf"); + add("video/3gpp", "3gpp"); + add("video/3gpp", "3gp"); + add("video/3gpp2", "3gpp2"); + add("video/3gpp2", "3g2"); + add("video/avi", "avi"); + add("video/dl", "dl"); + add("video/dv", "dif"); + add("video/dv", "dv"); + add("video/fli", "fli"); + add("video/m4v", "m4v"); + add("video/mp2ts", "ts"); + add("video/mpeg", "mpeg"); + add("video/mpeg", "mpg"); + add("video/mpeg", "mpe"); + add("video/mp4", "mp4"); + add("video/mpeg", "VOB"); + add("video/quicktime", "qt"); + add("video/quicktime", "mov"); + add("video/vnd.mpegurl", "mxu"); + add("video/webm", "webm"); + add("video/x-la-asf", "lsf"); + add("video/x-la-asf", "lsx"); + add("video/x-matroska", "mkv"); + add("video/x-mng", "mng"); + add("video/x-ms-asf", "asf"); + add("video/x-ms-asf", "asx"); + add("video/x-ms-wm", "wm"); + add("video/x-ms-wmv", "wmv"); + add("video/x-ms-wmx", "wmx"); + add("video/x-ms-wvx", "wvx"); + add("video/x-sgi-movie", "movie"); + add("video/x-webex", "wrf"); + add("x-conference/x-cooltalk", "ice"); + add("x-epoc/x-sisx-app", "sisx"); + applyOverrides(); + } + private static void add(String mimeType, String extension) { + // If we have an existing x -> y mapping, we do not want to + // override it with another mapping x -> y2. + // If a mime type maps to several extensions + // the first extension added is considered the most popular + // so we do not want to overwrite it later. + if (!mimeTypeToExtensionMap.containsKey(mimeType)) { + mimeTypeToExtensionMap.put(mimeType, extension); + } + if (!extensionToMimeTypeMap.containsKey(extension)) { + extensionToMimeTypeMap.put(extension, mimeType); + } + } + private static InputStream getContentTypesPropertiesStream() { + // User override? + String userTable = System.getProperty("content.types.user.table"); + if (userTable != null) { + File f = new File(userTable); + if (f.exists()) { + try { + return new FileInputStream(f); + } catch (IOException ignored) { + } + } + } + // Standard location? + File f = new File(System.getProperty("java.home"), "lib" + File.separator + "content-types.properties"); + if (f.exists()) { + try { + return new FileInputStream(f); + } catch (IOException ignored) { + } + } + return null; + } + /** + * This isn't what the RI does. The RI doesn't have hard-coded defaults, so supplying your + * own "content.types.user.table" means you don't get any of the built-ins, and the built-ins + * come from "$JAVA_HOME/lib/content-types.properties". + */ + private static void applyOverrides() { + // Get the appropriate InputStream to read overrides from, if any. + InputStream stream = getContentTypesPropertiesStream(); + if (stream == null) { + return; + } + try { + try { + // Read the properties file... + Properties overrides = new Properties(); + overrides.load(stream); + // And translate its mapping to ours... + for (Map.Entry entry : overrides.entrySet()) { + String extension = (String) entry.getKey(); + String mimeType = (String) entry.getValue(); + add(mimeType, extension); + } + } finally { + stream.close(); + } + } catch (IOException ignored) { + } + } + private MimeUtils() { + } + /** + * Returns true if the given MIME type has an entry in the map. + * @param mimeType A MIME type (i.e. text/plain) + * @return True iff there is a mimeType entry in the map. + */ + public static boolean hasMimeType(String mimeType) { + if (mimeType == null || mimeType.isEmpty()) { + return false; + } + return mimeTypeToExtensionMap.containsKey(mimeType); + } + /** + * Returns the MIME type for the given extension. + * @param extension A file extension without the leading '.' + * @return The MIME type for the given extension or null iff there is none. + */ + public static String guessMimeTypeFromExtension(String extension) { + if (extension == null || extension.isEmpty()) { + return null; + } + return extensionToMimeTypeMap.get(extension); + } + /** + * Returns true if the given extension has a registered MIME type. + * @param extension A file extension without the leading '.' + * @return True iff there is an extension entry in the map. + */ + public static boolean hasExtension(String extension) { + if (extension == null || extension.isEmpty()) { + return false; + } + return extensionToMimeTypeMap.containsKey(extension); + } + /** + * Returns the registered extension for the given MIME type. Note that some + * MIME types map to multiple extensions. This call will return the most + * common extension for the given MIME type. + * @param mimeType A MIME type (i.e. text/plain) + * @return The extension for the given MIME type or null iff there is none. + */ + public static String guessExtensionFromMimeType(String mimeType) { + if (mimeType == null || mimeType.isEmpty()) { + return null; + } + return mimeTypeToExtensionMap.get(mimeType); + } +} diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 2f96a83a..19a8653f 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -199,16 +199,7 @@ public class UIHelper { if (message.getType() == Message.TYPE_IMAGE) { return context.getString(R.string.image); } - final String path = message.getRelativeFilePath(); - if (path == null) { - return ""; - } - final String mime; - try { - mime = URLConnection.guessContentTypeFromName(path.replace("#","")); - } catch (final StringIndexOutOfBoundsException ignored) { - return context.getString(R.string.file); - } + final String mime = message.getMimeType(); if (mime == null) { return context.getString(R.string.file); } else if (mime.startsWith("audio/")) { -- cgit v1.2.3 From fc479697413c8b9bc9b8eb228d5c57fb3cdc4548 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 3 Jul 2015 13:07:48 +0200 Subject: added fallback for non-srv dns queries --- src/main/java/eu/siacs/conversations/utils/DNSHelper.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index bb354ae0..06426340 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -105,6 +105,7 @@ public class DNSHelper { for(int i = 0; i < response.getAnswers().length; ++i) { values.add(createNamePortBundle(host,5222,response.getAnswers()[i].getPayload())); } + values.add(createNamePortBundle(host,5222)); bundle.putParcelableArrayList("values", values); return bundle; } -- cgit v1.2.3 From ef1429c9a6983c101da41a277bd9353374dc89e7 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 5 Jul 2015 18:10:18 +0200 Subject: show contacts name in non anonymous mucs. fixes #1213 --- src/main/java/eu/siacs/conversations/utils/UIHelper.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 19a8653f..ddc4781c 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -221,10 +221,14 @@ public class UIHelper { public static String getMessageDisplayName(final Message message) { if (message.getStatus() == Message.STATUS_RECEIVED) { + final Contact contact = message.getContact(); if (message.getConversation().getMode() == Conversation.MODE_MULTI) { - return getDisplayedMucCounterpart(message.getCounterpart()); + if (contact != null) { + return contact.getDisplayName(); + } else { + return getDisplayedMucCounterpart(message.getCounterpart()); + } } else { - final Contact contact = message.getContact(); return contact != null ? contact.getDisplayName() : ""; } } else { -- cgit v1.2.3 From 26044ca229c48dd6e3e9da664ef82813ea69bc7c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 9 Jul 2015 13:40:08 +0200 Subject: print stack trace instead of writing error message to log in case of unknown exception in dnsutil --- src/main/java/eu/siacs/conversations/utils/DNSHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index 06426340..5a47bb3c 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -132,7 +132,7 @@ public class DNSHelper { } catch (SocketTimeoutException e) { bundle.putString("error", "timeout"); } catch (Exception e) { - Log.d(Config.LOGTAG,e.getMessage()); + e.printStackTrace(); bundle.putString("error", "unhandled"); } return bundle; -- cgit v1.2.3 From ce79f4bbe3e6f4254d143125807327ff02f1a29c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 10 Jul 2015 15:11:03 +0200 Subject: renamed downloadable to transferable --- .../java/eu/siacs/conversations/utils/UIHelper.java | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index ddc4781c..8047993a 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -1,6 +1,5 @@ package eu.siacs.conversations.utils; -import java.net.URLConnection; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -10,7 +9,7 @@ import java.util.Locale; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Downloadable; +import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.xmpp.jid.Jid; @@ -142,24 +141,24 @@ public class UIHelper { } public static Pair getMessagePreview(final Context context, final Message message) { - final Downloadable d = message.getDownloadable(); + final Transferable d = message.getTransferable(); if (d != null ) { switch (d.getStatus()) { - case Downloadable.STATUS_CHECKING: + case Transferable.STATUS_CHECKING: return new Pair<>(context.getString(R.string.checking_image),true); - case Downloadable.STATUS_DOWNLOADING: + case Transferable.STATUS_DOWNLOADING: return new Pair<>(context.getString(R.string.receiving_x_file, getFileDescriptionString(context,message), d.getProgress()),true); - case Downloadable.STATUS_OFFER: - case Downloadable.STATUS_OFFER_CHECK_FILESIZE: + case Transferable.STATUS_OFFER: + case Transferable.STATUS_OFFER_CHECK_FILESIZE: return new Pair<>(context.getString(R.string.x_file_offered_for_download, getFileDescriptionString(context,message)),true); - case Downloadable.STATUS_DELETED: + case Transferable.STATUS_DELETED: return new Pair<>(context.getString(R.string.file_deleted),true); - case Downloadable.STATUS_FAILED: + case Transferable.STATUS_FAILED: return new Pair<>(context.getString(R.string.file_transmission_failed),true); - case Downloadable.STATUS_UPLOADING: + case Transferable.STATUS_UPLOADING: if (message.getStatus() == Message.STATUS_OFFERED) { return new Pair<>(context.getString(R.string.offering_x_file, getFileDescriptionString(context, message)), true); -- cgit v1.2.3 From 5dd83a5fe685dd3268986ca0a73f21c4dcbc6af5 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 11 Jul 2015 21:23:58 +0200 Subject: null check otr fingerprint before display --- src/main/java/eu/siacs/conversations/utils/CryptoHelper.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java index 466bc409..2dec203d 100644 --- a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java @@ -91,7 +91,9 @@ public final class CryptoHelper { } public static String prettifyFingerprint(String fingerprint) { - if (fingerprint.length() < 40) { + if (fingerprint==null) { + return ""; + } else if (fingerprint.length() < 40) { return fingerprint; } StringBuilder builder = new StringBuilder(fingerprint); -- cgit v1.2.3 From 7bd66549d87e6c690c115ef3995c4606d0a9415f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 16 Jul 2015 13:25:52 +0200 Subject: made 'check image on http host' message more generic. fixed #1281 --- src/main/java/eu/siacs/conversations/utils/UIHelper.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 8047993a..2e768ad9 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -145,7 +145,8 @@ public class UIHelper { if (d != null ) { switch (d.getStatus()) { case Transferable.STATUS_CHECKING: - return new Pair<>(context.getString(R.string.checking_image),true); + return new Pair<>(context.getString(R.string.checking_x, + getFileDescriptionString(context,message)),true); case Transferable.STATUS_DOWNLOADING: return new Pair<>(context.getString(R.string.receiving_x_file, getFileDescriptionString(context,message), -- cgit v1.2.3 From 8fd46d40d63008e4855c3c1d48c5ac0eafb103d0 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Tue, 7 Jul 2015 19:28:35 +0200 Subject: Adapt prettifyFingerprint() to axolotl FP sizes --- src/main/java/eu/siacs/conversations/utils/CryptoHelper.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java index 2dec203d..c7c9ac42 100644 --- a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java @@ -96,11 +96,10 @@ public final class CryptoHelper { } else if (fingerprint.length() < 40) { return fingerprint; } - StringBuilder builder = new StringBuilder(fingerprint); - builder.insert(8, " "); - builder.insert(17, " "); - builder.insert(26, " "); - builder.insert(35, " "); + StringBuilder builder = new StringBuilder(fingerprint.replaceAll("\\s","")); + for(int i=8;i Date: Mon, 20 Jul 2015 14:26:29 +0200 Subject: Optimize imports --- .../eu/siacs/conversations/utils/DNSHelper.java | 28 +++++++++++----------- .../conversations/utils/ExceptionHandler.java | 4 ++-- .../siacs/conversations/utils/ExceptionHelper.java | 24 +++++++++---------- .../utils/OnPhoneContactsLoadedListener.java | 4 ++-- .../eu/siacs/conversations/utils/PhoneHelper.java | 7 +++--- .../eu/siacs/conversations/utils/UIHelper.java | 12 +++++----- 6 files changed, 39 insertions(+), 40 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index 5a47bb3c..36d03b30 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -1,17 +1,7 @@ package eu.siacs.conversations.utils; -import de.measite.minidns.Client; -import de.measite.minidns.DNSMessage; -import de.measite.minidns.Record; -import de.measite.minidns.Record.TYPE; -import de.measite.minidns.Record.CLASS; -import de.measite.minidns.record.SRV; -import de.measite.minidns.record.A; -import de.measite.minidns.record.AAAA; -import de.measite.minidns.record.Data; -import de.measite.minidns.util.NameUtil; -import eu.siacs.conversations.Config; -import eu.siacs.conversations.xmpp.jid.Jid; +import android.os.Bundle; +import android.util.Log; import java.io.IOException; import java.net.InetAddress; @@ -22,8 +12,18 @@ import java.util.Random; import java.util.TreeMap; import java.util.regex.Pattern; -import android.os.Bundle; -import android.util.Log; +import de.measite.minidns.Client; +import de.measite.minidns.DNSMessage; +import de.measite.minidns.Record; +import de.measite.minidns.Record.CLASS; +import de.measite.minidns.Record.TYPE; +import de.measite.minidns.record.A; +import de.measite.minidns.record.AAAA; +import de.measite.minidns.record.Data; +import de.measite.minidns.record.SRV; +import de.measite.minidns.util.NameUtil; +import eu.siacs.conversations.Config; +import eu.siacs.conversations.xmpp.jid.Jid; public class DNSHelper { diff --git a/src/main/java/eu/siacs/conversations/utils/ExceptionHandler.java b/src/main/java/eu/siacs/conversations/utils/ExceptionHandler.java index 0ad57fe2..4e3ec236 100644 --- a/src/main/java/eu/siacs/conversations/utils/ExceptionHandler.java +++ b/src/main/java/eu/siacs/conversations/utils/ExceptionHandler.java @@ -1,5 +1,7 @@ package eu.siacs.conversations.utils; +import android.content.Context; + import java.io.FileNotFoundException; import java.io.IOException; import java.io.OutputStream; @@ -8,8 +10,6 @@ import java.io.StringWriter; import java.io.Writer; import java.lang.Thread.UncaughtExceptionHandler; -import android.content.Context; - public class ExceptionHandler implements UncaughtExceptionHandler { private UncaughtExceptionHandler defaultHandler; diff --git a/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java b/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java index ee3ea3e1..0f182847 100644 --- a/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java @@ -1,5 +1,17 @@ package eu.siacs.conversations.utils; +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; +import android.content.SharedPreferences; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.preference.PreferenceManager; +import android.text.format.DateUtils; +import android.util.Log; + import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; @@ -15,18 +27,6 @@ import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; -import android.app.AlertDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.SharedPreferences; -import android.content.DialogInterface.OnClickListener; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.preference.PreferenceManager; -import android.text.format.DateUtils; -import android.util.Log; - public class ExceptionHelper { public static void init(Context context) { if (!(Thread.getDefaultUncaughtExceptionHandler() instanceof ExceptionHandler)) { diff --git a/src/main/java/eu/siacs/conversations/utils/OnPhoneContactsLoadedListener.java b/src/main/java/eu/siacs/conversations/utils/OnPhoneContactsLoadedListener.java index 9a689768..f18a4ed8 100644 --- a/src/main/java/eu/siacs/conversations/utils/OnPhoneContactsLoadedListener.java +++ b/src/main/java/eu/siacs/conversations/utils/OnPhoneContactsLoadedListener.java @@ -1,9 +1,9 @@ package eu.siacs.conversations.utils; -import java.util.List; - import android.os.Bundle; +import java.util.List; + public interface OnPhoneContactsLoadedListener { public void onPhoneContactsLoaded(List phoneContacts); } diff --git a/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java b/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java index 99e8ebb8..b90f06ff 100644 --- a/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java @@ -1,9 +1,5 @@ package eu.siacs.conversations.utils; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.RejectedExecutionException; - import android.content.Context; import android.content.CursorLoader; import android.content.Loader; @@ -15,6 +11,9 @@ import android.os.Bundle; import android.provider.ContactsContract; import android.provider.ContactsContract.Profile; +import java.util.List; +import java.util.concurrent.RejectedExecutionException; + public class PhoneHelper { public static void loadPhoneContacts(Context context,final List phoneContacts, final OnPhoneContactsLoadedListener listener) { diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 2e768ad9..cac23f07 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -1,5 +1,10 @@ package eu.siacs.conversations.utils; +import android.content.Context; +import android.text.format.DateFormat; +import android.text.format.DateUtils; +import android.util.Pair; + import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -9,15 +14,10 @@ import java.util.Locale; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.entities.Message; +import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.xmpp.jid.Jid; -import android.content.Context; -import android.text.format.DateFormat; -import android.text.format.DateUtils; -import android.util.Pair; - public class UIHelper { private static String BLACK_HEART_SUIT = "\u2665"; -- cgit v1.2.3 From 9c94c9ad8fe10aa1ffeb122b1db114680a7d95a2 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 24 Jul 2015 19:06:47 +0200 Subject: rewrote dns fallback --- src/main/java/eu/siacs/conversations/utils/DNSHelper.java | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index 36d03b30..60e1f0be 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -38,17 +38,14 @@ public class DNSHelper { public static Bundle getSRVRecord(final Jid jid) throws IOException { final String host = jid.getDomainpart(); String dns[] = client.findDNS(); - - if (dns != null) { - for (String dnsserver : dns) { - InetAddress ip = InetAddress.getByName(dnsserver); - Bundle b = queryDNS(host, ip); - if (b.containsKey("values")) { - return b; - } + for (int i = 0; i < dns.length; ++i) { + InetAddress ip = InetAddress.getByName(dns[i]); + Bundle b = queryDNS(host, ip); + if (b.containsKey("values") || i == dns.length - 1) { + return b; } } - return queryDNS(host, InetAddress.getByName("8.8.8.8")); + return null; } public static Bundle queryDNS(String host, InetAddress dnsServer) { -- cgit v1.2.3 From 8924c448d19d44a3a4a6f09a76d2e09130f22f87 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 28 Jul 2015 22:26:29 +0200 Subject: changed logging. (work around logcat null pointer --- src/main/java/eu/siacs/conversations/utils/DNSHelper.java | 1 - 1 file changed, 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index 60e1f0be..4d0dd3da 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -129,7 +129,6 @@ public class DNSHelper { } catch (SocketTimeoutException e) { bundle.putString("error", "timeout"); } catch (Exception e) { - e.printStackTrace(); bundle.putString("error", "unhandled"); } return bundle; -- cgit v1.2.3 From dad90762b44878a436479a3998fec45111c9af46 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 11 Aug 2015 16:50:00 +0200 Subject: do not touch pictures that are already in the right format fixed #522 --- .../eu/siacs/conversations/utils/FileUtils.java | 144 +++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 src/main/java/eu/siacs/conversations/utils/FileUtils.java (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/FileUtils.java b/src/main/java/eu/siacs/conversations/utils/FileUtils.java new file mode 100644 index 00000000..a13300d4 --- /dev/null +++ b/src/main/java/eu/siacs/conversations/utils/FileUtils.java @@ -0,0 +1,144 @@ +package eu.siacs.conversations.utils; + +import android.annotation.SuppressLint; +import android.content.ContentUris; +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.provider.DocumentsContract; +import android.provider.MediaStore; + +public class FileUtils { + + /** + * Get a file path from a Uri. This will get the the path for Storage Access + * Framework Documents, as well as the _data field for the MediaStore and + * other file-based ContentProviders. + * + * @param context The context. + * @param uri The Uri to query. + * @author paulburke + */ + @SuppressLint("NewApi") + public static String getPath(final Context context, final Uri uri) { + + final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; + + // DocumentProvider + if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { + // ExternalStorageProvider + if (isExternalStorageDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + + if ("primary".equalsIgnoreCase(type)) { + return Environment.getExternalStorageDirectory() + "/" + split[1]; + } + + // TODO handle non-primary volumes + } + // DownloadsProvider + else if (isDownloadsDocument(uri)) { + + final String id = DocumentsContract.getDocumentId(uri); + final Uri contentUri = ContentUris.withAppendedId( + Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); + + return getDataColumn(context, contentUri, null, null); + } + // MediaProvider + else if (isMediaDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + + Uri contentUri = null; + if ("image".equals(type)) { + contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + } else if ("video".equals(type)) { + contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; + } else if ("audio".equals(type)) { + contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; + } + + final String selection = "_id=?"; + final String[] selectionArgs = new String[]{ + split[1] + }; + + return getDataColumn(context, contentUri, selection, selectionArgs); + } + } + // MediaStore (and general) + else if ("content".equalsIgnoreCase(uri.getScheme())) { + return getDataColumn(context, uri, null, null); + } + // File + else if ("file".equalsIgnoreCase(uri.getScheme())) { + return uri.getPath(); + } + + return null; + } + + /** + * Get the value of the data column for this Uri. This is useful for + * MediaStore Uris, and other file-based ContentProviders. + * + * @param context The context. + * @param uri The Uri to query. + * @param selection (Optional) Filter used in the query. + * @param selectionArgs (Optional) Selection arguments used in the query. + * @return The value of the _data column, which is typically a file path. + */ + public static String getDataColumn(Context context, Uri uri, String selection, + String[] selectionArgs) { + + Cursor cursor = null; + final String column = "_data"; + final String[] projection = { + column + }; + + try { + cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, + null); + if (cursor != null && cursor.moveToFirst()) { + final int column_index = cursor.getColumnIndexOrThrow(column); + return cursor.getString(column_index); + } + } finally { + if (cursor != null) + cursor.close(); + } + return null; + } + + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is ExternalStorageProvider. + */ + public static boolean isExternalStorageDocument(Uri uri) { + return "com.android.externalstorage.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is DownloadsProvider. + */ + public static boolean isDownloadsDocument(Uri uri) { + return "com.android.providers.downloads.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is MediaProvider. + */ + public static boolean isMediaDocument(Uri uri) { + return "com.android.providers.media.documents".equals(uri.getAuthority()); + } +} -- cgit v1.2.3 From 9ebd6d503cc6e80383e441171d06730fce52bd9d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 19 Aug 2015 12:24:42 +0200 Subject: catch package manager has died exception --- src/main/java/eu/siacs/conversations/utils/PhoneHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java b/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java index b90f06ff..a37f60a0 100644 --- a/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java @@ -97,7 +97,7 @@ public class PhoneHelper { if (packageName != null) { try { return context.getPackageManager().getPackageInfo(packageName, 0).versionName; - } catch (final PackageManager.NameNotFoundException e) { + } catch (final PackageManager.NameNotFoundException | RuntimeException e) { return "unknown"; } } else { -- cgit v1.2.3 From c19adebaf05e732179e0267427292c408ec7d560 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 23 Aug 2015 21:00:51 +0200 Subject: open files with capital extensions as well. fixes #1354 --- src/main/java/eu/siacs/conversations/utils/MimeUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/MimeUtils.java b/src/main/java/eu/siacs/conversations/utils/MimeUtils.java index a9e89d1b..d4544424 100644 --- a/src/main/java/eu/siacs/conversations/utils/MimeUtils.java +++ b/src/main/java/eu/siacs/conversations/utils/MimeUtils.java @@ -458,7 +458,7 @@ public final class MimeUtils { if (extension == null || extension.isEmpty()) { return null; } - return extensionToMimeTypeMap.get(extension); + return extensionToMimeTypeMap.get(extension.toLowerCase()); } /** * Returns true if the given extension has a registered MIME type. -- cgit v1.2.3 From 25c49d5e34a842ddbe0a7430c87ea46065468245 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 25 Aug 2015 11:12:10 +0200 Subject: catch some db query exceptions --- src/main/java/eu/siacs/conversations/utils/FileUtils.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/FileUtils.java b/src/main/java/eu/siacs/conversations/utils/FileUtils.java index a13300d4..c2984111 100644 --- a/src/main/java/eu/siacs/conversations/utils/FileUtils.java +++ b/src/main/java/eu/siacs/conversations/utils/FileUtils.java @@ -104,15 +104,17 @@ public class FileUtils { }; try { - cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, - null); + cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,null); if (cursor != null && cursor.moveToFirst()) { final int column_index = cursor.getColumnIndexOrThrow(column); return cursor.getString(column_index); } + } catch(Exception e) { + return null; } finally { - if (cursor != null) + if (cursor != null) { cursor.close(); + } } return null; } -- cgit v1.2.3 From 3db70876588ca43687b69a3305a2547270aa0850 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 28 Aug 2015 12:16:28 +0200 Subject: use build in method on >= lolipop devices to discover dns servers --- .../eu/siacs/conversations/utils/DNSHelper.java | 47 ++++++++++++++++++---- 1 file changed, 40 insertions(+), 7 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index 4d0dd3da..889206e0 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -1,13 +1,21 @@ package eu.siacs.conversations.utils; +import android.annotation.TargetApi; +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.LinkProperties; +import android.net.Network; +import android.os.Build; import android.os.Bundle; import android.util.Log; import java.io.IOException; import java.net.InetAddress; import java.net.SocketTimeoutException; +import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collections; +import java.util.List; import java.util.Random; import java.util.TreeMap; import java.util.regex.Pattern; @@ -35,17 +43,42 @@ public class DNSHelper { protected static Client client = new Client(); - public static Bundle getSRVRecord(final Jid jid) throws IOException { + public static Bundle getSRVRecord(final Jid jid, Context context) throws IOException { final String host = jid.getDomainpart(); - String dns[] = client.findDNS(); - for (int i = 0; i < dns.length; ++i) { - InetAddress ip = InetAddress.getByName(dns[i]); - Bundle b = queryDNS(host, ip); - if (b.containsKey("values") || i == dns.length - 1) { + final List servers = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? getDnsServers(context) : getDnsServersPreLolipop(); + Bundle b = null; + for(InetAddress server : servers) { + b = queryDNS(host, server); + if (b.containsKey("values")) { return b; } } - return null; + return b; + } + + @TargetApi(21) + private static List getDnsServers(Context context) { + List servers = new ArrayList<>(); + ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + Network[] networks = connectivityManager.getAllNetworks(); + for(int i = 0; i < networks.length; ++i) { + LinkProperties linkProperties = connectivityManager.getLinkProperties(networks[i]); + servers.addAll(linkProperties.getDnsServers()); + } + return servers.size() > 0 ? servers : getDnsServersPreLolipop(); + } + + private static List getDnsServersPreLolipop() { + List servers = new ArrayList<>(); + String[] dns = client.findDNS(); + for(int i = 0; i < dns.length; ++i) { + try { + servers.add(InetAddress.getByName(dns[i])); + } catch (UnknownHostException e) { + //ignore + } + } + return servers; } public static Bundle queryDNS(String host, InetAddress dnsServer) { -- cgit v1.2.3 From a32a577e3691e20366c89e2c5eec5156d8ae2af9 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 5 Sep 2015 14:26:31 +0200 Subject: ignore timeout exceptions on secondary dns requests --- .../eu/siacs/conversations/utils/DNSHelper.java | 30 +++++++++++++++------- 1 file changed, 21 insertions(+), 9 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index 889206e0..2cde19ae 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -127,13 +127,21 @@ public class DNSHelper { ArrayList values = new ArrayList<>(); if (result.size() == 0) { DNSMessage response; - response = client.query(host, TYPE.A, CLASS.IN, dnsServer.getHostAddress()); - for(int i = 0; i < response.getAnswers().length; ++i) { - values.add(createNamePortBundle(host,5222,response.getAnswers()[i].getPayload())); + try { + response = client.query(host, TYPE.A, CLASS.IN, dnsServer.getHostAddress()); + for (int i = 0; i < response.getAnswers().length; ++i) { + values.add(createNamePortBundle(host, 5222, response.getAnswers()[i].getPayload())); + } + } catch (SocketTimeoutException e) { + Log.d(Config.LOGTAG,"ignoring timeout exception when querying A record on "+dnsServer.getHostAddress()); } - response = client.query(host, TYPE.AAAA, CLASS.IN, dnsServer.getHostAddress()); - for(int i = 0; i < response.getAnswers().length; ++i) { - values.add(createNamePortBundle(host,5222,response.getAnswers()[i].getPayload())); + try { + response = client.query(host, TYPE.AAAA, CLASS.IN, dnsServer.getHostAddress()); + for (int i = 0; i < response.getAnswers().length; ++i) { + values.add(createNamePortBundle(host, 5222, response.getAnswers()[i].getPayload())); + } + } catch (SocketTimeoutException e) { + Log.d(Config.LOGTAG,"ignoring timeout exception when querying AAAA record on "+dnsServer.getHostAddress()); } values.add(createNamePortBundle(host,5222)); bundle.putParcelableArrayList("values", values); @@ -143,9 +151,13 @@ public class DNSHelper { if (ips6.containsKey(srv.getName())) { values.add(createNamePortBundle(srv.getName(),srv.getPort(),ips6)); } else { - DNSMessage response = client.query(srv.getName(), TYPE.AAAA, CLASS.IN, dnsServer.getHostAddress()); - for(int i = 0; i < response.getAnswers().length; ++i) { - values.add(createNamePortBundle(srv.getName(),srv.getPort(),response.getAnswers()[i].getPayload())); + try { + DNSMessage response = client.query(srv.getName(), TYPE.AAAA, CLASS.IN, dnsServer.getHostAddress()); + for (int i = 0; i < response.getAnswers().length; ++i) { + values.add(createNamePortBundle(srv.getName(), srv.getPort(), response.getAnswers()[i].getPayload())); + } + } catch (SocketTimeoutException e) { + Log.d(Config.LOGTAG,"ignoring timeout exception when querying AAAA record on "+dnsServer.getHostAddress()); } } if (ips4.containsKey(srv.getName())) { -- cgit v1.2.3 From 811e2eaeecf868b5d58a5d759d01ed264f5cd0bc Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 10 Sep 2015 10:54:15 +0200 Subject: increased dns timeout --- src/main/java/eu/siacs/conversations/utils/DNSHelper.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index 2cde19ae..70bc7360 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -84,6 +84,7 @@ public class DNSHelper { public static Bundle queryDNS(String host, InetAddress dnsServer) { Bundle bundle = new Bundle(); try { + client.setTimeout(Config.PING_TIMEOUT * 1000); String qname = "_xmpp-client._tcp." + host; Log.d(Config.LOGTAG, "using dns server: " + dnsServer.getHostAddress() + " to look up " + host); DNSMessage message = client.query(qname, TYPE.SRV, CLASS.IN, dnsServer.getHostAddress()); -- cgit v1.2.3 From 8d13a77bc6f569a38b18662da9ca96c8db78c8ea Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 14 Sep 2015 13:22:10 +0200 Subject: changed http upload namespace to reflect the one in the XEP --- src/main/java/eu/siacs/conversations/utils/Xmlns.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/Xmlns.java b/src/main/java/eu/siacs/conversations/utils/Xmlns.java index 868566d9..de0a29ce 100644 --- a/src/main/java/eu/siacs/conversations/utils/Xmlns.java +++ b/src/main/java/eu/siacs/conversations/utils/Xmlns.java @@ -5,5 +5,5 @@ public final class Xmlns { public static final String ROSTER = "jabber:iq:roster"; public static final String REGISTER = "jabber:iq:register"; public static final String BYTE_STREAMS = "http://jabber.org/protocol/bytestreams"; - public static final String HTTP_UPLOAD = "eu:siacs:conversations:http:upload"; + public static final String HTTP_UPLOAD = "urn:xmpp:http:upload"; } -- cgit v1.2.3 From 7e712d9d4cdd7fb8aa6c7ef68ce2d5c39ff1c257 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 17 Sep 2015 13:55:27 +0200 Subject: fixed rare NPE in DnsHelper. fixed spelling and added logging --- .../java/eu/siacs/conversations/utils/DNSHelper.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index 70bc7360..863cfb66 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -45,7 +45,7 @@ public class DNSHelper { public static Bundle getSRVRecord(final Jid jid, Context context) throws IOException { final String host = jid.getDomainpart(); - final List servers = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? getDnsServers(context) : getDnsServersPreLolipop(); + final List servers = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? getDnsServers(context) : getDnsServersPreLollipop(); Bundle b = null; for(InetAddress server : servers) { b = queryDNS(host, server); @@ -60,15 +60,23 @@ public class DNSHelper { private static List getDnsServers(Context context) { List servers = new ArrayList<>(); ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - Network[] networks = connectivityManager.getAllNetworks(); + Network[] networks = connectivityManager == null ? null : connectivityManager.getAllNetworks(); + if (networks == null) { + return getDnsServersPreLollipop(); + } for(int i = 0; i < networks.length; ++i) { LinkProperties linkProperties = connectivityManager.getLinkProperties(networks[i]); - servers.addAll(linkProperties.getDnsServers()); + if (linkProperties != null) { + servers.addAll(linkProperties.getDnsServers()); + } + } + if (servers.size() > 0) { + Log.d(Config.LOGTAG,"used lollipop variant to discover dns servers in "+networks.length+" networks"); } - return servers.size() > 0 ? servers : getDnsServersPreLolipop(); + return servers.size() > 0 ? servers : getDnsServersPreLollipop(); } - private static List getDnsServersPreLolipop() { + private static List getDnsServersPreLollipop() { List servers = new ArrayList<>(); String[] dns = client.findDNS(); for(int i = 0; i < dns.length; ++i) { -- cgit v1.2.3 From b54b4ca78a85055292ea54b5acfaaec25c43f412 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 17 Sep 2015 14:42:50 +0200 Subject: introduced Config variable to use legacy namespace for http upload --- src/main/java/eu/siacs/conversations/utils/Xmlns.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/Xmlns.java b/src/main/java/eu/siacs/conversations/utils/Xmlns.java index de0a29ce..a19ec791 100644 --- a/src/main/java/eu/siacs/conversations/utils/Xmlns.java +++ b/src/main/java/eu/siacs/conversations/utils/Xmlns.java @@ -1,9 +1,11 @@ package eu.siacs.conversations.utils; +import eu.siacs.conversations.Config; + public final class Xmlns { public static final String BLOCKING = "urn:xmpp:blocking"; public static final String ROSTER = "jabber:iq:roster"; public static final String REGISTER = "jabber:iq:register"; public static final String BYTE_STREAMS = "http://jabber.org/protocol/bytestreams"; - public static final String HTTP_UPLOAD = "urn:xmpp:http:upload"; + public static final String HTTP_UPLOAD = Config.LEGACY_NAMESPACE_HTTP_UPLOAD ? "eu:siacs:conversations:http:upload" : "urn:xmpp:http:upload"; } -- cgit v1.2.3 From a954e32b1673f5816f460dc1d434d148f35821ac Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 19 Sep 2015 17:31:24 +0200 Subject: let DnsHelper provide a fallback solution --- src/main/java/eu/siacs/conversations/utils/DNSHelper.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index 863cfb66..f3c4f79a 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -7,6 +7,7 @@ import android.net.LinkProperties; import android.net.Network; import android.os.Build; import android.os.Bundle; +import android.os.Parcelable; import android.util.Log; import java.io.IOException; @@ -46,13 +47,19 @@ public class DNSHelper { public static Bundle getSRVRecord(final Jid jid, Context context) throws IOException { final String host = jid.getDomainpart(); final List servers = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? getDnsServers(context) : getDnsServersPreLollipop(); - Bundle b = null; + Bundle b = new Bundle(); for(InetAddress server : servers) { b = queryDNS(host, server); if (b.containsKey("values")) { return b; } } + if (!b.containsKey("values")) { + Log.d(Config.LOGTAG,"all dns queries failed. provide fallback A record"); + ArrayList values = new ArrayList<>(); + values.add(createNamePortBundle(host,5222)); + b.putParcelableArrayList("values",values); + } return b; } -- cgit v1.2.3 From 7be331bbb2ae2abde55eb031f4fdf4616846360e Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 11 Oct 2015 15:48:58 +0200 Subject: add menu item in account details to renew certificate --- .../eu/siacs/conversations/utils/CryptoHelper.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java index c7c9ac42..e9ad7197 100644 --- a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java @@ -1,6 +1,15 @@ package eu.siacs.conversations.utils; +import android.util.Pair; + +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x500.style.BCStyle; +import org.bouncycastle.asn1.x500.style.IETFUtils; +import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; + import java.security.SecureRandom; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; import java.text.Normalizer; import java.util.Arrays; import java.util.Collection; @@ -9,6 +18,8 @@ import java.util.LinkedHashSet; import java.util.List; import eu.siacs.conversations.Config; +import eu.siacs.conversations.xmpp.jid.InvalidJidException; +import eu.siacs.conversations.xmpp.jid.Jid; public final class CryptoHelper { public static final String FILETRANSFER = "?FILETRANSFERv1:"; @@ -125,4 +136,12 @@ public final class CryptoHelper { } } } + + public static Pair extractJidAndName(X509Certificate certificate) throws CertificateEncodingException, InvalidJidException { + X500Name x500name = new JcaX509CertificateHolder(certificate).getSubject(); + //String xmpp = IETFUtils.valueToString(x500name.getRDNs(new ASN1ObjectIdentifier("1.3.6.1.5.5.7.8.5"))[0].getFirst().getValue()); + String email = IETFUtils.valueToString(x500name.getRDNs(BCStyle.EmailAddress)[0].getFirst().getValue()); + String name = IETFUtils.valueToString(x500name.getRDNs(BCStyle.CN)[0].getFirst().getValue()); + return new Pair<>(Jid.fromString(email),name); + } } -- cgit v1.2.3 From cfeb67d71da01bc95ed713d6591fa6e79fc08dd6 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 16 Oct 2015 23:48:42 +0200 Subject: introduced code to verify omemo device keys with x509 certificates. cleaned up TrustKeysActivity to automatically close if there is nothing to do --- .../eu/siacs/conversations/utils/CryptoHelper.java | 28 ++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java index e9ad7197..8091a996 100644 --- a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java @@ -1,16 +1,21 @@ package eu.siacs.conversations.utils; +import android.util.Log; import android.util.Pair; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.asn1.x500.style.IETFUtils; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; +import org.bouncycastle.jce.PrincipalUtil; import java.security.SecureRandom; import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; +import java.security.cert.X509Extension; import java.text.Normalizer; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; @@ -137,11 +142,26 @@ public final class CryptoHelper { } } - public static Pair extractJidAndName(X509Certificate certificate) throws CertificateEncodingException, InvalidJidException { + public static Pair extractJidAndName(X509Certificate certificate) throws CertificateEncodingException, InvalidJidException, CertificateParsingException { + Collection> alternativeNames = certificate.getSubjectAlternativeNames(); + List emails = new ArrayList<>(); + if (alternativeNames != null) { + for(List san : alternativeNames) { + Integer type = (Integer) san.get(0); + if (type == 1) { + emails.add((String) san.get(1)); + } + } + } X500Name x500name = new JcaX509CertificateHolder(certificate).getSubject(); - //String xmpp = IETFUtils.valueToString(x500name.getRDNs(new ASN1ObjectIdentifier("1.3.6.1.5.5.7.8.5"))[0].getFirst().getValue()); - String email = IETFUtils.valueToString(x500name.getRDNs(BCStyle.EmailAddress)[0].getFirst().getValue()); + if (emails.size() == 0) { + emails.add(IETFUtils.valueToString(x500name.getRDNs(BCStyle.EmailAddress)[0].getFirst().getValue())); + } String name = IETFUtils.valueToString(x500name.getRDNs(BCStyle.CN)[0].getFirst().getValue()); - return new Pair<>(Jid.fromString(email),name); + if (emails.size() >= 1) { + return new Pair<>(Jid.fromString(emails.get(0)), name); + } else { + return null; + } } } -- cgit v1.2.3 From 48f172fc9e9a464ee220afd2a82b719ec5b984e9 Mon Sep 17 00:00:00 2001 From: saqura Date: Mon, 26 Oct 2015 00:59:32 +0100 Subject: Reset the margins manually after rotating --- .../java/eu/siacs/conversations/utils/UIHelper.java | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index cac23f07..8a73d35f 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -3,7 +3,11 @@ package eu.siacs.conversations.utils; import android.content.Context; import android.text.format.DateFormat; import android.text.format.DateUtils; +import android.util.DisplayMetrics; import android.util.Pair; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; import java.util.ArrayList; import java.util.Arrays; @@ -261,4 +265,21 @@ public class UIHelper { body = body.replace("?","").replace("¿",""); return LOCATION_QUESTIONS.contains(body); } + + public static void resetChildMargins(LinearLayout view) { + int childCount = view.getChildCount(); + for (int i = 0; i < childCount; i++) { + UIHelper.resetMargins(view.getChildAt(i)); + } + } + + private static void resetMargins(View view) { + LinearLayout.MarginLayoutParams marginLayoutParams = new LinearLayout.MarginLayoutParams(view.getLayoutParams()); + marginLayoutParams.setMargins(view.getResources().getDimensionPixelSize(R.dimen.activity_horizontal_margin), + view.getResources().getDimensionPixelSize(R.dimen.activity_vertical_margin), + view.getResources().getDimensionPixelSize(R.dimen.activity_horizontal_margin), + view.getResources().getDimensionPixelSize(R.dimen.activity_vertical_margin)); + LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(marginLayoutParams); + view.setLayoutParams(layoutParams); + } } -- cgit v1.2.3 From a7fd629c051a3ba0031fba4e358ba4f3b843283d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 28 Oct 2015 22:40:09 +0100 Subject: show encryption type in warned/red messages --- .../java/eu/siacs/conversations/utils/CryptoHelper.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java index 8091a996..ab407249 100644 --- a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java @@ -23,6 +23,8 @@ import java.util.LinkedHashSet; import java.util.List; import eu.siacs.conversations.Config; +import eu.siacs.conversations.R; +import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; @@ -164,4 +166,17 @@ public final class CryptoHelper { return null; } } + + public static int encryptionTypeToText(int encryption) { + switch (encryption) { + case Message.ENCRYPTION_OTR: + return R.string.encryption_choice_otr; + case Message.ENCRYPTION_AXOLOTL: + return R.string.encryption_choice_omemo; + case Message.ENCRYPTION_NONE: + return R.string.encryption_choice_unencrypted; + default: + return R.string.encryption_choice_pgp; + } + } } -- cgit v1.2.3 From a557d38e4d0bd55442012f7f8a5be62532f7bfe9 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 25 Nov 2015 20:47:02 +0100 Subject: pgp fixes and revert configuration changes --- .../java/eu/siacs/conversations/utils/UIHelper.java | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 8a73d35f..cac23f07 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -3,11 +3,7 @@ package eu.siacs.conversations.utils; import android.content.Context; import android.text.format.DateFormat; import android.text.format.DateUtils; -import android.util.DisplayMetrics; import android.util.Pair; -import android.view.View; -import android.widget.LinearLayout; -import android.widget.RelativeLayout; import java.util.ArrayList; import java.util.Arrays; @@ -265,21 +261,4 @@ public class UIHelper { body = body.replace("?","").replace("¿",""); return LOCATION_QUESTIONS.contains(body); } - - public static void resetChildMargins(LinearLayout view) { - int childCount = view.getChildCount(); - for (int i = 0; i < childCount; i++) { - UIHelper.resetMargins(view.getChildAt(i)); - } - } - - private static void resetMargins(View view) { - LinearLayout.MarginLayoutParams marginLayoutParams = new LinearLayout.MarginLayoutParams(view.getLayoutParams()); - marginLayoutParams.setMargins(view.getResources().getDimensionPixelSize(R.dimen.activity_horizontal_margin), - view.getResources().getDimensionPixelSize(R.dimen.activity_vertical_margin), - view.getResources().getDimensionPixelSize(R.dimen.activity_horizontal_margin), - view.getResources().getDimensionPixelSize(R.dimen.activity_vertical_margin)); - LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(marginLayoutParams); - view.setLayoutParams(layoutParams); - } } -- cgit v1.2.3 From 8ffcc11f278994b5bd2cebe2ee50b78a9d14a985 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 29 Nov 2015 16:31:51 +0100 Subject: refactored socks5 connection code. make jingle transport use that new code --- .../conversations/utils/SocksSocketFactory.java | 52 ++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/main/java/eu/siacs/conversations/utils/SocksSocketFactory.java (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/SocksSocketFactory.java b/src/main/java/eu/siacs/conversations/utils/SocksSocketFactory.java new file mode 100644 index 00000000..6d9340ab --- /dev/null +++ b/src/main/java/eu/siacs/conversations/utils/SocksSocketFactory.java @@ -0,0 +1,52 @@ +package eu.siacs.conversations.utils; + +import android.util.Log; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; + +import eu.siacs.conversations.Config; + +public class SocksSocketFactory { + + public static void createSocksConnection(Socket socket, String destination, int port) throws IOException { + InputStream proxyIs = socket.getInputStream(); + OutputStream proxyOs = socket.getOutputStream(); + proxyOs.write(new byte[]{0x05, 0x01, 0x00}); + byte[] response = new byte[2]; + proxyIs.read(response); + byte[] dest = destination.getBytes(); + ByteBuffer request = ByteBuffer.allocate(7 + dest.length); + request.put(new byte[]{0x05, 0x01, 0x00, 0x03}); + request.put((byte) dest.length); + request.put(dest); + request.putShort((short) port); + proxyOs.write(request.array()); + response = new byte[7 + dest.length]; + proxyIs.read(response); + if (response[1] != 0x00) { + throw new SocksConnectionException(); + } + } + + public static Socket createSocket(InetSocketAddress address, String destination, int port) throws IOException { + Socket socket = new Socket(); + socket.connect(address, Config.CONNECT_TIMEOUT * 1000); + createSocksConnection(socket, destination, port); + return socket; + } + + public static Socket createSocketOverTor(String destination, int port) throws IOException { + return createSocket(new InetSocketAddress(InetAddress.getLocalHost(), 9050), destination, port); + } + + static class SocksConnectionException extends IOException { + + } +} -- cgit v1.2.3 From 2225b0b6d5586d608b15d4e1ac13faa99b8971bf Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 30 Nov 2015 16:01:48 +0100 Subject: add error state for unavailable tor network --- .../eu/siacs/conversations/utils/SocksSocketFactory.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/SocksSocketFactory.java b/src/main/java/eu/siacs/conversations/utils/SocksSocketFactory.java index 6d9340ab..768e9f17 100644 --- a/src/main/java/eu/siacs/conversations/utils/SocksSocketFactory.java +++ b/src/main/java/eu/siacs/conversations/utils/SocksSocketFactory.java @@ -1,14 +1,11 @@ package eu.siacs.conversations.utils; -import android.util.Log; - import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; -import java.net.UnknownHostException; import java.nio.ByteBuffer; import eu.siacs.conversations.Config; @@ -37,7 +34,11 @@ public class SocksSocketFactory { public static Socket createSocket(InetSocketAddress address, String destination, int port) throws IOException { Socket socket = new Socket(); - socket.connect(address, Config.CONNECT_TIMEOUT * 1000); + try { + socket.connect(address, Config.CONNECT_TIMEOUT * 1000); + } catch (IOException e) { + throw new SocksProxyNotFoundException(); + } createSocksConnection(socket, destination, port); return socket; } @@ -49,4 +50,8 @@ public class SocksSocketFactory { static class SocksConnectionException extends IOException { } + + public static class SocksProxyNotFoundException extends IOException { + + } } -- cgit v1.2.3 From 0664d6ac7b8d0cefac8fa92df625fe653d606b1a Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 4 Dec 2015 15:35:22 +0100 Subject: avoid some NPEs --- src/main/java/eu/siacs/conversations/utils/DNSHelper.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index f3c4f79a..e07df627 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -227,10 +227,11 @@ public class DNSHelper { } public static boolean isIp(final String server) { - return PATTERN_IPV4.matcher(server).matches() + return server != null && ( + PATTERN_IPV4.matcher(server).matches() || PATTERN_IPV6.matcher(server).matches() || PATTERN_IPV6_6HEX4DEC.matcher(server).matches() || PATTERN_IPV6_HEX4DECCOMPRESSED.matcher(server).matches() - || PATTERN_IPV6_HEXCOMPRESSED.matcher(server).matches(); + || PATTERN_IPV6_HEXCOMPRESSED.matcher(server).matches()); } } -- cgit v1.2.3 From 739648e909446c83fe1474636b8465a7ef91cce2 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 7 Dec 2015 00:33:50 +0100 Subject: ask for contact permissions when first opening StartConversationActivity --- src/main/java/eu/siacs/conversations/utils/PhoneHelper.java | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java b/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java index a37f60a0..893f9eb8 100644 --- a/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java @@ -1,5 +1,6 @@ package eu.siacs.conversations.utils; +import android.Manifest; import android.content.Context; import android.content.CursorLoader; import android.content.Loader; @@ -7,6 +8,7 @@ import android.content.Loader.OnLoadCompleteListener; import android.content.pm.PackageManager; import android.database.Cursor; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.provider.ContactsContract; import android.provider.ContactsContract.Profile; @@ -17,6 +19,11 @@ import java.util.concurrent.RejectedExecutionException; public class PhoneHelper { public static void loadPhoneContacts(Context context,final List phoneContacts, final OnPhoneContactsLoadedListener listener) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M + && context.checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { + listener.onPhoneContactsLoaded(phoneContacts); + return; + } final String[] PROJECTION = new String[] { ContactsContract.Data._ID, ContactsContract.Data.DISPLAY_NAME, ContactsContract.Data.PHOTO_URI, @@ -74,6 +81,10 @@ public class PhoneHelper { } public static Uri getSefliUri(Context context) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M + && context.checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { + return null; + } String[] mProjection = new String[] { Profile._ID, Profile.PHOTO_URI }; Cursor mProfileCursor = context.getContentResolver().query( Profile.CONTENT_URI, mProjection, null, null, null); -- cgit v1.2.3 From f46cbb38a92ff5281a974ecc0932ba5459c7334e Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 23 Dec 2015 19:18:53 +0100 Subject: show certificate information --- .../eu/siacs/conversations/utils/CryptoHelper.java | 50 ++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java index ab407249..d1b90ab6 100644 --- a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java @@ -1,5 +1,6 @@ package eu.siacs.conversations.utils; +import android.os.Bundle; import android.util.Log; import android.util.Pair; @@ -9,6 +10,7 @@ import org.bouncycastle.asn1.x500.style.IETFUtils; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; import org.bouncycastle.jce.PrincipalUtil; +import java.security.MessageDigest; import java.security.SecureRandom; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateParsingException; @@ -121,6 +123,14 @@ public final class CryptoHelper { return builder.toString(); } + public static String prettifyFingerprintCert(String fingerprint) { + StringBuilder builder = new StringBuilder(fingerprint); + for(int i=2;i < builder.length(); i+=3) { + builder.insert(i,':'); + } + return builder.toString(); + } + public static String[] getOrderedCipherSuites(final String[] platformSupportedCipherSuites) { final Collection cipherSuites = new LinkedHashSet<>(Arrays.asList(Config.ENABLED_CIPHERS)); final List platformCiphers = Arrays.asList(platformSupportedCipherSuites); @@ -167,6 +177,46 @@ public final class CryptoHelper { } } + public static Bundle extractCertificateInformation(X509Certificate certificate) { + Bundle information = new Bundle(); + try { + JcaX509CertificateHolder holder = new JcaX509CertificateHolder(certificate); + X500Name subject = holder.getSubject(); + try { + information.putString("subject_cn", subject.getRDNs(BCStyle.CN)[0].getFirst().getValue().toString()); + } catch (Exception e) { + //ignored + } + try { + information.putString("subject_o",subject.getRDNs(BCStyle.O)[0].getFirst().getValue().toString()); + } catch (Exception e) { + //ignored + } + + X500Name issuer = holder.getIssuer(); + try { + information.putString("issuer_cn", issuer.getRDNs(BCStyle.CN)[0].getFirst().getValue().toString()); + } catch (Exception e) { + //ignored + } + try { + information.putString("issuer_o", issuer.getRDNs(BCStyle.O)[0].getFirst().getValue().toString()); + } catch (Exception e) { + //ignored + } + try { + MessageDigest md = MessageDigest.getInstance("SHA-1"); + byte[] fingerprint = md.digest(certificate.getEncoded()); + information.putString("sha1", prettifyFingerprintCert(bytesToHex(fingerprint))); + } catch (Exception e) { + + } + return information; + } catch (CertificateEncodingException e) { + return information; + } + } + public static int encryptionTypeToText(int encryption) { switch (encryption) { case Message.ENCRYPTION_OTR: -- cgit v1.2.3 From c40372fc0d1bc81650321b0166c06a0be05ac0a2 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 23 Dec 2015 22:30:14 +0100 Subject: code cleanup --- .../eu/siacs/conversations/utils/CryptoHelper.java | 22 ---------------------- 1 file changed, 22 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java index d1b90ab6..5c504e04 100644 --- a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java @@ -1,21 +1,17 @@ package eu.siacs.conversations.utils; import android.os.Bundle; -import android.util.Log; import android.util.Pair; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.asn1.x500.style.IETFUtils; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; -import org.bouncycastle.jce.PrincipalUtil; import java.security.MessageDigest; -import java.security.SecureRandom; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; -import java.security.cert.X509Extension; import java.text.Normalizer; import java.util.ArrayList; import java.util.Arrays; @@ -33,8 +29,6 @@ import eu.siacs.conversations.xmpp.jid.Jid; public final class CryptoHelper { public static final String FILETRANSFER = "?FILETRANSFERv1:"; private final static char[] hexArray = "0123456789abcdef".toCharArray(); - private final static char[] vowels = "aeiou".toCharArray(); - private final static char[] consonants = "bcdfghjklmnpqrstvwxyz".toCharArray(); final public static byte[] ONE = new byte[] { 0, 0, 0, 1 }; public static String bytesToHex(byte[] bytes) { @@ -68,22 +62,6 @@ public final class CryptoHelper { return result; } - public static String randomMucName(SecureRandom random) { - return randomWord(3, random) + "." + randomWord(7, random); - } - - private static String randomWord(int lenght, SecureRandom random) { - StringBuilder builder = new StringBuilder(lenght); - for (int i = 0; i < lenght; ++i) { - if (i % 2 == 0) { - builder.append(consonants[random.nextInt(consonants.length)]); - } else { - builder.append(vowels[random.nextInt(vowels.length)]); - } - } - return builder.toString(); - } - /** * Escapes usernames or passwords for SASL. */ -- cgit v1.2.3 From 703d95fcf84d720567cefe1483695d76f32ebb34 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 27 Dec 2015 18:37:12 +0100 Subject: lower case all fingerprints. fixes #1521 --- src/main/java/eu/siacs/conversations/utils/CryptoHelper.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java index 5c504e04..1ef5fb3f 100644 --- a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java @@ -19,6 +19,7 @@ import java.util.Collection; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; +import java.util.Locale; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; @@ -94,7 +95,7 @@ public final class CryptoHelper { } else if (fingerprint.length() < 40) { return fingerprint; } - StringBuilder builder = new StringBuilder(fingerprint.replaceAll("\\s","")); + StringBuilder builder = new StringBuilder(fingerprint.toLowerCase(Locale.US).replaceAll("\\s", "")); for(int i=8;i Date: Tue, 29 Dec 2015 10:32:54 +0100 Subject: handle null names in getColorForName --- src/main/java/eu/siacs/conversations/utils/UIHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index cac23f07..cf1e0d3b 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -131,7 +131,7 @@ public class UIHelper { } public static int getColorForName(String name) { - if (name.isEmpty()) { + if (name == null || name.isEmpty()) { return 0xFF202020; } int colors[] = {0xFFe91e63, 0xFF9c27b0, 0xFF673ab7, 0xFF3f51b5, -- cgit v1.2.3 From fb97f9d18f4a4152983ffbbfa2bae5881f3f22ce Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 4 Jan 2016 20:14:08 +0100 Subject: null check in getOriginalPath --- src/main/java/eu/siacs/conversations/utils/FileUtils.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/FileUtils.java b/src/main/java/eu/siacs/conversations/utils/FileUtils.java index c2984111..ad8b8640 100644 --- a/src/main/java/eu/siacs/conversations/utils/FileUtils.java +++ b/src/main/java/eu/siacs/conversations/utils/FileUtils.java @@ -23,6 +23,9 @@ public class FileUtils { */ @SuppressLint("NewApi") public static String getPath(final Context context, final Uri uri) { + if (uri == null) { + return null; + } final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; -- cgit v1.2.3 From c296d6f4466e2616432660bb01465f3746e1bb65 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 11 Jan 2016 11:17:45 +0100 Subject: ask to be excluded from battery optimization --- .../siacs/conversations/utils/ExceptionHelper.java | 56 +++++++++++----------- 1 file changed, 29 insertions(+), 27 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java b/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java index 0f182847..8799b4a5 100644 --- a/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/ExceptionHelper.java @@ -24,6 +24,7 @@ import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.ui.ConversationActivity; import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; @@ -35,14 +36,13 @@ public class ExceptionHelper { } } - public static void checkForCrash(Context context, - final XmppConnectionService service) { + public static boolean checkForCrash(ConversationActivity activity, final XmppConnectionService service) { try { final SharedPreferences preferences = PreferenceManager - .getDefaultSharedPreferences(context); + .getDefaultSharedPreferences(activity); boolean neverSend = preferences.getBoolean("never_send", false); if (neverSend) { - return; + return false; } List accounts = service.getAccounts(); Account account = null; @@ -53,24 +53,25 @@ public class ExceptionHelper { } } if (account == null) { - return; + return false; } final Account finalAccount = account; - FileInputStream file = context.openFileInput("stacktrace.txt"); + FileInputStream file = activity.openFileInput("stacktrace.txt"); InputStreamReader inputStreamReader = new InputStreamReader(file); BufferedReader stacktrace = new BufferedReader(inputStreamReader); final StringBuilder report = new StringBuilder(); - PackageManager pm = context.getPackageManager(); + PackageManager pm = activity.getPackageManager(); PackageInfo packageInfo = null; try { - packageInfo = pm.getPackageInfo(context.getPackageName(), 0); + packageInfo = pm.getPackageInfo(activity.getPackageName(), 0); report.append("Version: " + packageInfo.versionName + '\n'); report.append("Last Update: " - + DateUtils.formatDateTime(context, - packageInfo.lastUpdateTime, - DateUtils.FORMAT_SHOW_TIME - | DateUtils.FORMAT_SHOW_DATE) + '\n'); + + DateUtils.formatDateTime(activity, + packageInfo.lastUpdateTime, + DateUtils.FORMAT_SHOW_TIME + | DateUtils.FORMAT_SHOW_DATE) + '\n'); } catch (NameNotFoundException e) { + return false; } String line; while ((line = stacktrace.readLine()) != null) { @@ -78,11 +79,11 @@ public class ExceptionHelper { report.append('\n'); } file.close(); - context.deleteFile("stacktrace.txt"); - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(context.getString(R.string.crash_report_title)); - builder.setMessage(context.getText(R.string.crash_report_message)); - builder.setPositiveButton(context.getText(R.string.send_now), + activity.deleteFile("stacktrace.txt"); + AlertDialog.Builder builder = new AlertDialog.Builder(activity); + builder.setTitle(activity.getString(R.string.crash_report_title)); + builder.setMessage(activity.getText(R.string.crash_report_message)); + builder.setPositiveButton(activity.getText(R.string.send_now), new OnClickListener() { @Override @@ -91,18 +92,18 @@ public class ExceptionHelper { Log.d(Config.LOGTAG, "using account=" + finalAccount.getJid().toBareJid() + " to send in stack trace"); - Conversation conversation = null; - try { - conversation = service.findOrCreateConversation(finalAccount, - Jid.fromString("bugs@siacs.eu"), false); - } catch (final InvalidJidException ignored) { - } - Message message = new Message(conversation, report + Conversation conversation = null; + try { + conversation = service.findOrCreateConversation(finalAccount, + Jid.fromString("bugs@siacs.eu"), false); + } catch (final InvalidJidException ignored) { + } + Message message = new Message(conversation, report .toString(), Message.ENCRYPTION_NONE); service.sendMessage(message); } }); - builder.setNegativeButton(context.getText(R.string.send_never), + builder.setNegativeButton(activity.getText(R.string.send_never), new OnClickListener() { @Override @@ -112,8 +113,9 @@ public class ExceptionHelper { } }); builder.create().show(); + return true; } catch (final IOException ignored) { - } - + return false; + } } } -- cgit v1.2.3 From 217f6603c018ca0d72925f8d8f41f605e9edf4db Mon Sep 17 00:00:00 2001 From: moparisthebest Date: Mon, 11 Jan 2016 17:25:16 -0500 Subject: Implement XEP-0368: SRV records for XMPP over TLS --- .../eu/siacs/conversations/utils/DNSHelper.java | 121 ++++++++++++--------- 1 file changed, 71 insertions(+), 50 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index e07df627..87790d64 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -19,6 +19,7 @@ import java.util.Collections; import java.util.List; import java.util.Random; import java.util.TreeMap; +import java.util.Map; import java.util.regex.Pattern; import de.measite.minidns.Client; @@ -57,7 +58,7 @@ public class DNSHelper { if (!b.containsKey("values")) { Log.d(Config.LOGTAG,"all dns queries failed. provide fallback A record"); ArrayList values = new ArrayList<>(); - values.add(createNamePortBundle(host,5222)); + values.add(createNamePortBundle(host, 5222, false)); b.putParcelableArrayList("values",values); } return b; @@ -96,57 +97,73 @@ public class DNSHelper { return servers; } - public static Bundle queryDNS(String host, InetAddress dnsServer) { - Bundle bundle = new Bundle(); - try { - client.setTimeout(Config.PING_TIMEOUT * 1000); - String qname = "_xmpp-client._tcp." + host; - Log.d(Config.LOGTAG, "using dns server: " + dnsServer.getHostAddress() + " to look up " + host); - DNSMessage message = client.query(qname, TYPE.SRV, CLASS.IN, dnsServer.getHostAddress()); - - TreeMap> priorities = new TreeMap<>(); - TreeMap> ips4 = new TreeMap<>(); - TreeMap> ips6 = new TreeMap<>(); - - for (Record[] rrset : new Record[][] { message.getAnswers(), message.getAdditionalResourceRecords() }) { - for (Record rr : rrset) { - Data d = rr.getPayload(); - if (d instanceof SRV && NameUtil.idnEquals(qname, rr.getName())) { - SRV srv = (SRV) d; - if (!priorities.containsKey(srv.getPriority())) { - priorities.put(srv.getPriority(),new ArrayList()); - } - priorities.get(srv.getPriority()).add(srv); + private static class TlsSrv { + private final SRV srv; + private final boolean tls; + + public TlsSrv(SRV srv, boolean tls) { + this.srv = srv; + this.tls = tls; + } + } + + private static void fillSrvMaps(final String qname, final InetAddress dnsServer, final Map> priorities, final Map> ips4, final Map> ips6, final boolean tls) throws IOException { + final DNSMessage message = client.query(qname, TYPE.SRV, CLASS.IN, dnsServer.getHostAddress()); + for (Record[] rrset : new Record[][] { message.getAnswers(), message.getAdditionalResourceRecords() }) { + for (Record rr : rrset) { + Data d = rr.getPayload(); + if (d instanceof SRV && NameUtil.idnEquals(qname, rr.getName())) { + SRV srv = (SRV) d; + if (!priorities.containsKey(srv.getPriority())) { + priorities.put(srv.getPriority(),new ArrayList()); } - if (d instanceof A) { - A a = (A) d; - if (!ips4.containsKey(rr.getName())) { - ips4.put(rr.getName(), new ArrayList()); - } - ips4.get(rr.getName()).add(a.toString()); + priorities.get(srv.getPriority()).add(new TlsSrv(srv, tls)); + } + if (d instanceof A) { + A a = (A) d; + if (!ips4.containsKey(rr.getName())) { + ips4.put(rr.getName(), new ArrayList()); } - if (d instanceof AAAA) { - AAAA aaaa = (AAAA) d; - if (!ips6.containsKey(rr.getName())) { - ips6.put(rr.getName(), new ArrayList()); - } - ips6.get(rr.getName()).add("[" + aaaa.toString() + "]"); + ips4.get(rr.getName()).add(a.toString()); + } + if (d instanceof AAAA) { + AAAA aaaa = (AAAA) d; + if (!ips6.containsKey(rr.getName())) { + ips6.put(rr.getName(), new ArrayList()); } + ips6.get(rr.getName()).add("[" + aaaa.toString() + "]"); } } + } + } + + public static Bundle queryDNS(String host, InetAddress dnsServer) { + Bundle bundle = new Bundle(); + try { + client.setTimeout(Config.PING_TIMEOUT * 1000); + final String qname = "_xmpp-client._tcp." + host; + final String tlsQname = "_xmpps-client._tcp." + host; + Log.d(Config.LOGTAG, "using dns server: " + dnsServer.getHostAddress() + " to look up " + host); + + final Map> priorities = new TreeMap<>(); + final Map> ips4 = new TreeMap<>(); + final Map> ips6 = new TreeMap<>(); + + fillSrvMaps(qname, dnsServer, priorities, ips4, ips6, false); + fillSrvMaps(tlsQname, dnsServer, priorities, ips4, ips6, true); - ArrayList result = new ArrayList<>(); - for (ArrayList s : priorities.values()) { + final List result = new ArrayList<>(); + for (final List s : priorities.values()) { result.addAll(s); } - ArrayList values = new ArrayList<>(); + final ArrayList values = new ArrayList<>(); if (result.size() == 0) { DNSMessage response; try { response = client.query(host, TYPE.A, CLASS.IN, dnsServer.getHostAddress()); for (int i = 0; i < response.getAnswers().length; ++i) { - values.add(createNamePortBundle(host, 5222, response.getAnswers()[i].getPayload())); + values.add(createNamePortBundle(host, 5222, response.getAnswers()[i].getPayload(), false)); } } catch (SocketTimeoutException e) { Log.d(Config.LOGTAG,"ignoring timeout exception when querying A record on "+dnsServer.getHostAddress()); @@ -154,37 +171,38 @@ public class DNSHelper { try { response = client.query(host, TYPE.AAAA, CLASS.IN, dnsServer.getHostAddress()); for (int i = 0; i < response.getAnswers().length; ++i) { - values.add(createNamePortBundle(host, 5222, response.getAnswers()[i].getPayload())); + values.add(createNamePortBundle(host, 5222, response.getAnswers()[i].getPayload(), false)); } } catch (SocketTimeoutException e) { Log.d(Config.LOGTAG,"ignoring timeout exception when querying AAAA record on "+dnsServer.getHostAddress()); } - values.add(createNamePortBundle(host,5222)); + values.add(createNamePortBundle(host, 5222, false)); bundle.putParcelableArrayList("values", values); return bundle; } - for (SRV srv : result) { + for (final TlsSrv tlsSrv : result) { + final SRV srv = tlsSrv.srv; if (ips6.containsKey(srv.getName())) { - values.add(createNamePortBundle(srv.getName(),srv.getPort(),ips6)); + values.add(createNamePortBundle(srv.getName(),srv.getPort(),ips6, tlsSrv.tls)); } else { try { DNSMessage response = client.query(srv.getName(), TYPE.AAAA, CLASS.IN, dnsServer.getHostAddress()); for (int i = 0; i < response.getAnswers().length; ++i) { - values.add(createNamePortBundle(srv.getName(), srv.getPort(), response.getAnswers()[i].getPayload())); + values.add(createNamePortBundle(srv.getName(), srv.getPort(), response.getAnswers()[i].getPayload(), tlsSrv.tls)); } } catch (SocketTimeoutException e) { Log.d(Config.LOGTAG,"ignoring timeout exception when querying AAAA record on "+dnsServer.getHostAddress()); } } if (ips4.containsKey(srv.getName())) { - values.add(createNamePortBundle(srv.getName(),srv.getPort(),ips4)); + values.add(createNamePortBundle(srv.getName(),srv.getPort(),ips4, tlsSrv.tls)); } else { DNSMessage response = client.query(srv.getName(), TYPE.A, CLASS.IN, dnsServer.getHostAddress()); for(int i = 0; i < response.getAnswers().length; ++i) { - values.add(createNamePortBundle(srv.getName(),srv.getPort(),response.getAnswers()[i].getPayload())); + values.add(createNamePortBundle(srv.getName(),srv.getPort(),response.getAnswers()[i].getPayload(), tlsSrv.tls)); } } - values.add(createNamePortBundle(srv.getName(), srv.getPort())); + values.add(createNamePortBundle(srv.getName(), srv.getPort(), tlsSrv.tls)); } bundle.putParcelableArrayList("values", values); } catch (SocketTimeoutException e) { @@ -195,28 +213,31 @@ public class DNSHelper { return bundle; } - private static Bundle createNamePortBundle(String name, int port) { + private static Bundle createNamePortBundle(String name, int port, final boolean tls) { Bundle namePort = new Bundle(); namePort.putString("name", name); + namePort.putBoolean("tls", tls); namePort.putInt("port", port); return namePort; } - private static Bundle createNamePortBundle(String name, int port, TreeMap> ips) { + private static Bundle createNamePortBundle(String name, int port, Map> ips, final boolean tls) { Bundle namePort = new Bundle(); namePort.putString("name", name); + namePort.putBoolean("tls", tls); namePort.putInt("port", port); if (ips!=null) { - ArrayList ip = ips.get(name); + List ip = ips.get(name); Collections.shuffle(ip, new Random()); namePort.putString("ip", ip.get(0)); } return namePort; } - private static Bundle createNamePortBundle(String name, int port, Data data) { + private static Bundle createNamePortBundle(String name, int port, Data data, final boolean tls) { Bundle namePort = new Bundle(); namePort.putString("name", name); + namePort.putBoolean("tls", tls); namePort.putInt("port", port); if (data instanceof A) { namePort.putString("ip", data.toString()); -- cgit v1.2.3 From 893751a1d24ce59706ac38921e26c7e3f28645d8 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 12 Jan 2016 16:33:15 +0100 Subject: move some ssl socket modifiers into a seperate helper class --- .../siacs/conversations/utils/SSLSocketHelper.java | 62 ++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 src/main/java/eu/siacs/conversations/utils/SSLSocketHelper.java (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/SSLSocketHelper.java b/src/main/java/eu/siacs/conversations/utils/SSLSocketHelper.java new file mode 100644 index 00000000..49e9a81a --- /dev/null +++ b/src/main/java/eu/siacs/conversations/utils/SSLSocketHelper.java @@ -0,0 +1,62 @@ +package eu.siacs.conversations.utils; + +import java.lang.reflect.Method; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedList; + +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; + +public class SSLSocketHelper { + + public static void setSecurity(final SSLSocket sslSocket) throws NoSuchAlgorithmException { + final String[] supportProtocols; + final Collection supportedProtocols = new LinkedList<>( + Arrays.asList(sslSocket.getSupportedProtocols())); + supportedProtocols.remove("SSLv3"); + supportProtocols = supportedProtocols.toArray(new String[supportedProtocols.size()]); + + sslSocket.setEnabledProtocols(supportProtocols); + + final String[] cipherSuites = CryptoHelper.getOrderedCipherSuites( + sslSocket.getSupportedCipherSuites()); + if (cipherSuites.length > 0) { + sslSocket.setEnabledCipherSuites(cipherSuites); + } + } + + public static void setSNIHost(final SSLSocketFactory factory, final SSLSocket socket, final String hostname) { + if (factory instanceof android.net.SSLCertificateSocketFactory && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) { + ((android.net.SSLCertificateSocketFactory) factory).setHostname(socket, hostname); + } else { + try { + socket.getClass().getMethod("setHostname", String.class).invoke(socket, hostname); + } catch (Throwable e) { + // ignore any error, we just can't set the hostname... + } + } + } + + public static void setAlpnProtocol(final SSLSocketFactory factory, final SSLSocket socket, final String protocol) { + try { + if (factory instanceof android.net.SSLCertificateSocketFactory && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) { + // can't call directly because of @hide? + //((android.net.SSLCertificateSocketFactory)factory).setAlpnProtocols(new byte[][]{protocol.getBytes("UTF-8")}); + android.net.SSLCertificateSocketFactory.class.getMethod("setAlpnProtocols", byte[][].class).invoke(socket, new Object[]{new byte[][]{protocol.getBytes("UTF-8")}}); + } else { + final Method method = socket.getClass().getMethod("setAlpnProtocols", byte[].class); + // the concatenation of 8-bit, length prefixed protocol names, just one in our case... + // http://tools.ietf.org/html/draft-agl-tls-nextprotoneg-04#page-4 + final byte[] protocolUTF8Bytes = protocol.getBytes("UTF-8"); + final byte[] lengthPrefixedProtocols = new byte[protocolUTF8Bytes.length + 1]; + lengthPrefixedProtocols[0] = (byte) protocol.length(); // cannot be over 255 anyhow + System.arraycopy(protocolUTF8Bytes, 0, lengthPrefixedProtocols, 1, protocolUTF8Bytes.length); + method.invoke(socket, new Object[]{lengthPrefixedProtocols}); + } + } catch (Throwable e) { + // ignore any error, we just can't set the alpn protocol... + } + } +} -- cgit v1.2.3 From e71acdef2923aafcab8eefbd432dc2f158f4d847 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 20 Jan 2016 16:18:15 +0100 Subject: catch security exception when user prevents access to address book --- .../eu/siacs/conversations/utils/PhoneHelper.java | 72 ++++++++++++++-------- 1 file changed, 45 insertions(+), 27 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java b/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java index 893f9eb8..6c1b4bef 100644 --- a/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java @@ -18,17 +18,17 @@ import java.util.concurrent.RejectedExecutionException; public class PhoneHelper { - public static void loadPhoneContacts(Context context,final List phoneContacts, final OnPhoneContactsLoadedListener listener) { + public static void loadPhoneContacts(Context context, final List phoneContacts, final OnPhoneContactsLoadedListener listener) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context.checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { listener.onPhoneContactsLoaded(phoneContacts); return; } - final String[] PROJECTION = new String[] { ContactsContract.Data._ID, + final String[] PROJECTION = new String[]{ContactsContract.Data._ID, ContactsContract.Data.DISPLAY_NAME, ContactsContract.Data.PHOTO_URI, ContactsContract.Data.LOOKUP_KEY, - ContactsContract.CommonDataKinds.Im.DATA }; + ContactsContract.CommonDataKinds.Im.DATA}; final String SELECTION = "(" + ContactsContract.Data.MIMETYPE + "=\"" + ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE @@ -36,39 +36,39 @@ public class PhoneHelper { + "=\"" + ContactsContract.CommonDataKinds.Im.PROTOCOL_JABBER + "\")"; - CursorLoader mCursorLoader = new CursorLoader(context, + CursorLoader mCursorLoader = new NotThrowCursorLoader(context, ContactsContract.Data.CONTENT_URI, PROJECTION, SELECTION, null, null); mCursorLoader.registerListener(0, new OnLoadCompleteListener() { @Override public void onLoadComplete(Loader arg0, Cursor cursor) { - if (cursor == null) { - return; - } - while (cursor.moveToNext()) { - Bundle contact = new Bundle(); - contact.putInt("phoneid", cursor.getInt(cursor - .getColumnIndex(ContactsContract.Data._ID))); - contact.putString( - "displayname", - cursor.getString(cursor - .getColumnIndex(ContactsContract.Data.DISPLAY_NAME))); - contact.putString("photouri", cursor.getString(cursor - .getColumnIndex(ContactsContract.Data.PHOTO_URI))); - contact.putString("lookup", cursor.getString(cursor - .getColumnIndex(ContactsContract.Data.LOOKUP_KEY))); - - contact.putString( - "jid", - cursor.getString(cursor - .getColumnIndex(ContactsContract.CommonDataKinds.Im.DATA))); - phoneContacts.add(contact); + if (cursor != null) { + while (cursor.moveToNext()) { + Bundle contact = new Bundle(); + contact.putInt("phoneid", cursor.getInt(cursor + .getColumnIndex(ContactsContract.Data._ID))); + contact.putString( + "displayname", + cursor.getString(cursor + .getColumnIndex(ContactsContract.Data.DISPLAY_NAME))); + contact.putString("photouri", cursor.getString(cursor + .getColumnIndex(ContactsContract.Data.PHOTO_URI))); + contact.putString("lookup", cursor.getString(cursor + .getColumnIndex(ContactsContract.Data.LOOKUP_KEY))); + + contact.putString( + "jid", + cursor.getString(cursor + .getColumnIndex(ContactsContract.CommonDataKinds.Im.DATA))); + phoneContacts.add(contact); + } + cursor.close(); } + if (listener != null) { listener.onPhoneContactsLoaded(phoneContacts); } - cursor.close(); } }); try { @@ -80,12 +80,30 @@ public class PhoneHelper { } } + private static class NotThrowCursorLoader extends CursorLoader { + + public NotThrowCursorLoader(Context c, Uri u, String[] p, String s, String[] sa, String so) { + super(c, u, p, s, sa, so); + } + + @Override + public Cursor loadInBackground() { + + try { + return (super.loadInBackground()); + } catch (SecurityException e) { + return(null); + } + } + + } + public static Uri getSefliUri(Context context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context.checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { return null; } - String[] mProjection = new String[] { Profile._ID, Profile.PHOTO_URI }; + String[] mProjection = new String[]{Profile._ID, Profile.PHOTO_URI}; Cursor mProfileCursor = context.getContentResolver().query( Profile.CONTENT_URI, mProjection, null, null, null); -- cgit v1.2.3 From 82870b27edfd4813f6fbf48ec8705f87162d62e1 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 26 Jan 2016 22:46:00 +0100 Subject: prefer dns servers from networsk with the default route --- .../java/eu/siacs/conversations/utils/DNSHelper.java | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/utils') diff --git a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java index 87790d64..306d50c2 100644 --- a/src/main/java/eu/siacs/conversations/utils/DNSHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/DNSHelper.java @@ -5,6 +5,7 @@ import android.content.Context; import android.net.ConnectivityManager; import android.net.LinkProperties; import android.net.Network; +import android.net.RouteInfo; import android.os.Build; import android.os.Bundle; import android.os.Parcelable; @@ -75,15 +76,29 @@ public class DNSHelper { for(int i = 0; i < networks.length; ++i) { LinkProperties linkProperties = connectivityManager.getLinkProperties(networks[i]); if (linkProperties != null) { - servers.addAll(linkProperties.getDnsServers()); + if (hasDefaultRoute(linkProperties)) { + servers.addAll(0, linkProperties.getDnsServers()); + } else { + servers.addAll(linkProperties.getDnsServers()); + } } } if (servers.size() > 0) { - Log.d(Config.LOGTAG,"used lollipop variant to discover dns servers in "+networks.length+" networks"); + Log.d(Config.LOGTAG, "used lollipop variant to discover dns servers in " + networks.length + " networks"); } return servers.size() > 0 ? servers : getDnsServersPreLollipop(); } + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + private static boolean hasDefaultRoute(LinkProperties linkProperties) { + for(RouteInfo route: linkProperties.getRoutes()) { + if (route.isDefaultRoute()) { + return true; + } + } + return false; + } + private static List getDnsServersPreLollipop() { List servers = new ArrayList<>(); String[] dns = client.findDNS(); -- cgit v1.2.3