aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitmodules2
-rw-r--r--AndroidManifest.xml2
-rw-r--r--README.md335
m---------libs/MemorizingTrustManager0
-rw-r--r--res/values-fr/strings.xml65
-rw-r--r--res/values/strings.xml9
-rw-r--r--res/xml/preferences.xml5
-rw-r--r--src/eu/siacs/conversations/entities/Conversation.java30
-rw-r--r--src/eu/siacs/conversations/entities/Downloadable.java1
-rw-r--r--src/eu/siacs/conversations/http/HttpConnection.java62
-rw-r--r--src/eu/siacs/conversations/parser/MessageParser.java2
-rw-r--r--src/eu/siacs/conversations/persistance/DatabaseBackend.java10
-rw-r--r--src/eu/siacs/conversations/services/XmppConnectionService.java6
-rw-r--r--src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java2
-rw-r--r--src/eu/siacs/conversations/ui/adapter/MessageAdapter.java7
-rw-r--r--src/eu/siacs/conversations/xmpp/XmppConnection.java81
-rw-r--r--src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java4
17 files changed, 419 insertions, 204 deletions
diff --git a/.gitmodules b/.gitmodules
index d0f56166..7ddaefe6 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -7,4 +7,4 @@
url = https://github.com/open-keychain/openpgp-api-lib.git
[submodule "libs/MemorizingTrustManager"]
path = libs/MemorizingTrustManager
- url = https://github.com/ge0rg/MemorizingTrustManager
+ url = https://github.com/iNPUTmice/MemorizingTrustManager.git
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 3263cdd6..d65f747e 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
package="eu.siacs.conversations"
android:versionCode="31"
android:versionName="0.7.3" >
@@ -22,6 +23,7 @@
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
+ tools:replace="android:label"
android:theme="@style/ConversationsTheme" >
<service android:name="eu.siacs.conversations.services.XmppConnectionService" />
diff --git a/README.md b/README.md
index 9fc74fdd..c28d7e42 100644
--- a/README.md
+++ b/README.md
@@ -1,19 +1,22 @@
-#Conversations
-Conversations - the very last word in instant messaging
+# Conversations
+
+Conversations: the very last word in instant messaging
[![Google Play](http://developer.android.com/images/brand/en_generic_rgb_wo_45.png)](https://play.google.com/store/apps/details?id=eu.siacs.conversations)
![screenshots](https://raw.githubusercontent.com/siacs/Conversations/master/screenshots.png)
-##Design principles
+## Design principles
+
* Be as beautiful and easy to use as possible without sacrificing security or
privacy
* Rely on existing, well established protocols (XMPP)
* Do not require a Google Account or specifically Google Cloud Messaging (GCM)
-* Require as little permissons as possible
+* Require as few permissions as possible
+
+## Features
-##Features
-* End-to-end encryption with either OTR or openPGP
+* End-to-end encryption with either [OTR](https://otr.cypherpunks.ca/) or [OpenPGP](http://www.openpgp.org/about_openpgp/)
* Sending and receiving images
* Indication when your contact has read your message
* Intuitive UI that follows Android Design guidelines
@@ -21,47 +24,56 @@ Conversations - the very last word in instant messaging
* Syncs with desktop client
* Conferences (with support for bookmarks)
* Address book integration
-* Multiple Accounts / unified inbox
+* Multiple accounts / unified inbox
* Very low impact on battery life
-###XMPP Features
-Conversations works with every XMPP server out there. However XMPP is an extensible
-protocol. These extensions are standardized as well in so called XEP’s.
-Conversations supports a couple of those to make the overall user experience better. There is a
-chance that your current XMPP server does not support these extensions.
-Therefore to get the most out of Conversations you should consider either switching to an
-XMPP server that does or - even better - run your own XMPP server for you and
-your friends.
-These XEPs are - as of now:
-* XEP-0065: SOCKS5 Bytestreams - or rather mod_proxy65. Will be used to transfer files if both parties are behind a firewall (NAT).
+### XMPP Features
+
+Conversations works with every XMPP server out there. However XMPP is an
+extensible protocol. These extensions are standardized as well in so called
+XEP's. Conversations supports a couple of these to make the overall user
+experience better. There is a chance that your current XMPP server does not
+support these extensions; therefore to get the most out of Conversations you
+should consider either switching to an XMPP server that does or — even better —
+run your own XMPP server for you and your friends. These XEP's are:
+
+* XEP-0065: SOCKS5 Bytestreams (or mod_proxy65). Will be used to transfer
+ files if both parties are behind a firewall (NAT).
* XEP-0138: Stream Compression saves bandwidth
* XEP-0163: Personal Eventing Protocol for avatars
-* XEP-0198: Stream Management allows XMPP to survive small network outages and changes of the underlying TCP connection.
+* XEP-0198: Stream Management allows XMPP to survive small network outages and
+ changes of the underlying TCP connection.
* XEP-0280: Message Carbons which automatically syncs the messages you send to
your desktop client and thus allows you to switch seamlessly from your mobile
client to your desktop client and back within one conversation.
* XEP-0237: Roster Versioning mainly to save bandwidth on poor mobile connections
* XEP-0352: Client State Indication let the server know whether or not
Conversations is in the background. Allows the server to save bandwidth by
- withholding unimportent packages.
+ withholding unimportant packages.
+
+## Team
+
+#### Head of Development
-##Team
-####Head of Development
* [Daniel Gultsch](https://github.com/inputmice)
-####Code Contributions
+#### Code Contributions
+
(In order of appearance)
+
* [Rene Treffer](https://github.com/rtreffer)
* [Andreas Straub](https://github.com/strb)
* [Alethea Butler](https://github.com/alethea)
* [M. Dietrich](https://github.com/emdete)
* [betheg](https://github.com/betheg)
-####Logo
+#### Logo
+
* [Diego Turtulici](http://efesto.eigenlab.org/~diesys)
-####Translations
+#### Translations
+
* [Sergio Cárdenas](https://github.com/kruks23) (Spanish)
* [Benoit Bouvarel](https://github.com/BenoitBouvarel) (French)
* [Daniel Gultsch](https://github.com/iNPUTmice) (German)
@@ -71,180 +83,215 @@ These XEPs are - as of now:
* [Anders Sandblad](https://github.com/andersruneson) (Swedish)
* [Aizaz AZ](http://www.linkedin.com/in/aizazhaider) (Chinese)
-##FAQ
-###General
-####How do I install Conversations?
+## FAQ
+
+### General
+
+#### How do I install Conversations?
+
Conversations is entirely open source and licensed under GPLv3. So if you are a
-software developer you can check out the sources from github and use ant to
+software developer you can check out the sources from GitHub and use ant to
build your apk file.
-The more convenient way - which not only gives you automatic updates but also
-supports the further development of Conversations - is to buy the App in the Google
-[Play Store](https://play.google.com/store/apps/details?id=eu.siacs.conversations).
-####I don't have a Google Account but I would still like to make a contribution
-I accept donations over PayPal, BitCoin and Flattr. For donations via PayPal you can use the email address donate@siacs.eu or the button below.
+The more convenient way — which not only gives you automatic updates but also
+supports the further development of Conversations - is to buy the App in the
+Google [Play Store](https://play.google.com/store/apps/details?id=eu.siacs.conversations).
+
+#### I don't have a Google Account but I would still like to make a contribution
+
+I accept donations over PayPal, Bitcoin and Flattr. For donations via PayPal you
+can use the email address `donate@siacs.eu` or the button below.
[![Donate with PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=CW3SYT3KG5PDL)
-**Disclaimer:** I'm not a huge fan of PayPal and their business policies. For larger
-contributions please get in touch with me beforehand and we can talk about bank
-transfer (SEPA).
+**Disclaimer:** I'm not a huge fan of PayPal and their business policies. For
+larger contributions please get in touch with me beforehand and we can talk
+about bank transfer (SEPA).
-My Bitcoin Address is: 1NxSU1YxYzJVDpX1rcESAA3NJki7kRgeeu
+My Bitcoin Address is: `1NxSU1YxYzJVDpX1rcESAA3NJki7kRgeeu`
[![Flattr this!](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=inputmice&url=http%3A%2F%2Fconversations.siacs.eu&title=Conversations&tags=github&category=software)
-####How do I create an account?
-XMPP like email for example is a federated protocol which means that there is
-not one company you can create your 'official xmpp account' with but there are
-hundreds or even thousands of provider out there. To find one use a web search
-engine of your choice. Or maybe your university has one. Or you can run your own.
-Or ask a friend to run one. Once you found one you can use Conversations to
-create an account. Just select 'register new account on server' within the
-create account dialog.
-
-####Conversations doesn't work for me. Where can I get help?
-You can join our conference room on conversations@conference.siacs.eu A lot of
+#### How do I create an account?
+
+XMPP, like email, is a federated protocol which means that there is not one
+company you can create an 'official XMPP account' with. Instead there are
+hundreds, or even thousands, of provider out there. To find one use a web search
+engine of your choice. Or maybe your university has one. Or you can run your
+own. Or ask a friend to run one. Once you've found one, you can use
+Conversations to create an account. Just select 'register new account on server'
+within the create account dialog.
+
+#### Conversations doesn't work for me. Where can I get help?
+
+You can join our conference room on `conversations@conference.siacs.eu` A lot of
people in there are able to answer basic questions about the usage of
Conversations or can provide you with tips on running your own XMPP server. If
you found a bug or your app crashes please read the Developer / Report Bugs
section of this document.
-####I need professional support with Conversations or setting up my server
-I'm available for hire. Contact me at inputmice@siacs.eu
+#### I need professional support with Conversations or setting up my server
+
+I'm available for hire. Contact me at `inputmice@siacs.eu`.
+
+#### How does the address book integration work?
-####How does the address book integration work?
-The address bock integration was designed to protect your privacy. Conversations
+The address book integration was designed to protect your privacy. Conversations
neither uploads contacts from your address book to your server nor fills your
address book with unnecessary contacts from your online roster. If you manually
add a Jabber ID to your phones address book Conversations will use the name and
the profile picture of this contact. To make the process of adding Jabber IDs to
your address book easier you can click on the profile picture in the contact
-details within Conversations. This will start an add to address book intent with the jabber ID
-as payload. This doesn’t require Conversations to have write permissions on your
-address book but also doesn’t require you to copy past Jabber ID from one app to
-another.
-
-####I get 'delivery failed' on my messages
-If you get delivery failed on images it’s probably because the recipient lost
-network connectivity during recepiton. In that case you can try it again at a
+details within Conversations. This will start an "add to address book" intent
+with the JID as the payload. This doesn't require Conversations to have write
+permissions on your address book but also doesn't require you to copy/paste a
+JID from one app to another.
+
+#### I get 'delivery failed' on my messages
+
+If you get delivery failed on images it's probably because the recipient lost
+network connectivity during reception. In that case you can try it again at a
later time.
For text messages the answer to your question is a little bit more complex.
-'delivery failed' on text messages is always something that is being reported by
-the server. The most common reason for this is that the recipient failed to
-resume a connection. When a client loses connectivity for a short time the client
-usually has a five minute window to pick up that connection again. When the
-client fails to do so because the network connectivity is out for longer than
-that all messages sent to that client will be returned to the sender resulting
-in a delivery failed.
-
-Other less common reasons are that the message you sent didn’t meet some
-criterias enforced by the server. (Too large, too many) Another reason could be
-that the recipient is offline and the server doesn’t provide offline storage.
+When you see 'delivery failed' on text messages, it is always something that is
+being reported by the server. The most common reason for this is that the
+recipient failed to resume a connection. When a client loses connectivity for a
+short time the client usually has a five minute window to pick up that
+connection again. When the client fails to do so because the network
+connectivity is out for longer than that all messages sent to that client will
+be returned to the sender resulting in a delivery failed.
+
+Other less common reasons are that the message you sent didn't meet some
+criteria enforced by the server (too large, too many). Another reason could be
+that the recipient is offline and the server doesn't provide offline storage.
Usually you are able to distinguish between these two groups in the fact that
the first one happens always after some time and the second one happens almost
instantly.
-####Where can I see the status of my contacts? How can I set a status or priority
-Status are a horrible metric. Setting them manually to a proper value rarely
+#### Where can I see the status of my contacts? How can I set a status or priority?
+
+Statuses are a horrible metric. Setting them manually to a proper value rarely
works because users are either lazy or just forget about them. Setting them
automatically does not provide quality results either. Keyboard or mouse
activity as indicator for example fails when the user is just looking at
something (reading an article, watching a movie). Furthermore automatic setting
-of status always implies an impact on your privacy. (Are you sure you want
+of status always implies an impact on your privacy (are you sure you want
everybody in your contact list to know that you have been using your computer at
-4am?!)
+4am‽).
In the past status has been used to judge the likelihood of whether or not your
messages are being read. This is no longer necessary. With Chat Markers
(XEP-0333, supported by Conversations since 0.4) we have the ability to **know**
-whether or not your messages are being read.
-Similar things can be said for priorities. In the past priorities have been used
-(By servers, not by clients!) to route your messages to one specific client.
-With carbon messages (XEP-0280, supported by Conversations since 0.1) this is no
-longer necessary. Using priorities to route OTR messages isn't pratical either
-because they are not changeable on the fly. Metrics like last active client
-(the client which sent the last message) are much better.
+whether or not your messages are being read. Similar things can be said for
+priorities. In the past priorities have been used (by servers, not by clients!)
+to route your messages to one specific client. With carbon messages (XEP-0280,
+supported by Conversations since 0.1) this is no longer necessary. Using
+priorities to route OTR messages isn't practical either because they are not
+changeable on the fly. Metrics like last active client (the client which sent
+the last message) are much better.
Unfortunately these modern replacements for legacy XMPP features are not widely
adopted. However Conversations should be an instant messenger for the future and
instead of making Conversations compatible with the past we should work on
-implementing new, improved technologies into other XMPP clients as well.
+implementing new, improved technologies and getting them into other XMPP clients
+as well.
Making these status and priority optional isn't a solution either because
Conversations is trying to get rid of old behaviours and set an example for
other clients.
-####Conversations is missing a certain feature
-I'm open for new feature suggestions. You can use the issue tracker on github.
-Please take some time to browse through the issues to see if someone else
-already suggested it. Be assured that I read each and every ticket. If I like it
-I will leave it open until it's implemented. If I don't like it I will close
-it. (Usually with a short comment). If I don't comment on an feature request
-that's probably a good sign because this means I agree with you. Commenting with
-+1 on either open or closed issues won't change my mind nor will it accelerate the
-development.
-
-####You closed my feature request but I want it really really badly
+#### Conversations is missing a certain feature
+
+I'm open for new feature suggestions. You can use the [issue tracker][issues] on
+GitHub. Please take some time to browse through the issues to see if someone
+else already suggested it. Be assured that I read each and every ticket. If I
+like it I will leave it open until it's implemented. If I don't like it I will
+close it (usually with a short comment). If I don't comment on an feature
+request that's probably a good sign because this means I agree with you.
+Commenting with +1 on either open or closed issues won't change my mind, nor
+will it accelerate the development.
+
+#### You closed my feature request but I want it really really badly
+
Just write it yourself and send me a pull request. If I like it I will happily
merge it if I don't at least you and like minded people get to enjoy it.
-####I need a feature and I need it now!
-I am available for hire. Contact me JID: inputmice@siacs.eu
-
-###Security
-####Why are there two end-to-end encryption methods and which one should I choose?
-In most cases OTR should be the encryption method of choice. It works out of the box with most contacts as long as they are online.
-However PGP can be in some cases (carbonated messages to multiple clients) be
-more flexible.
-####How do I use openPGP
-Before you continue reading you should notice that the openPGP support in
-Conversations is marked as experimental. This is not because it will make the app
-unstable but because the fundamental concepts of PGP aren't ready for a
-widespread use. The way PGP works is that you trust Key IDs instead of XMPP- or email addresses. So in theory your contact list should consist of Public-Key-IDs instead of email addresses. But of course no email or xmpp client out there implements these concepts. Plus PGP in the context of instant messaging has a couple of downsides. It is vulnerable to replay attacks, it is rather verbose, and decrypting and encrypting takes longer than OTR. It is however asynchronous and works well with carbonated messages.
-
-To use openpgp you have to install the opensource app OpenKeychain (www.openkeychain.org) and then long press on the account in manage accounts and choose renew PGP announcement from the contextual menu.
-####How does the encryption for conferences work?
-For conferences the only supported encryption method is OpenPGP. (OTR does not
-work with multiple participants.) Every participant has to announce their
-OpenPGP key. (See answer above). If you would like to send encrypted messages to
+#### I need a feature and I need it now!
+
+I am available for hire. Contact me via XMPP: `inputmice@siacs.eu`
+
+### Security
+
+#### Why are there two end-to-end encryption methods and which one should I choose?
+
+In most cases OTR should be the encryption method of choice. It works out of the
+box with most contacts as long as they are online. However PGP can, in some
+cases, (message carbons to multiple clients) be more flexible.
+
+#### How do I use OpenPGP
+
+Before you continue reading you should note that the OpenPGP support in
+Conversations is experimental. This is not because it will make the app unstable
+but because the fundamental concepts of PGP aren't ready for widespread use.
+The way PGP works is that you trust Key IDs instead of JID's or email addresses.
+So in theory your contact list should consist of Public-Key-IDs instead of
+JID's. But of course no email or XMPP client out there implements these
+concepts. Plus PGP in the context of instant messaging has a couple of
+downsides: It is vulnerable to replay attacks, it is rather verbose, and
+decrypting and encrypting takes longer than OTR. It is however asynchronous and
+works well with message carbons.
+
+To use OpenPGP you have to install the open source app
+[OpenKeychain](www.openkeychain.org) and then long press on the account in
+manage accounts and choose renew PGP announcement from the contextual menu.
+
+#### How does the encryption for conferences work?
+
+For conferences the only supported encryption method is OpenPGP (OTR does not
+work with multiple participants). Every participant has to announce their
+OpenPGP key (see answer above). If you would like to send encrypted messages to
a conference you have to make sure that you have every participant's public key
in your OpenKeychain. Right now there is no check in Conversations to ensure
that. You have to take care of that yourself. Go to the conference details and
touch every key id (The hexadecimal number below a contact). This will send you
-to OpenKeychain which will assist you on adding the key.
-This works best in very small conferences with contacts you are already using
-OpenPGP with. This feature is regarded experimental. Conversations is the only
-client that uses XEP-0027 with conferences. (The XEP neither specifically allows
-nor disallows this.)
-###Development
-####How do I build Conversations
+to OpenKeychain which will assist you on adding the key. This works best in
+very small conferences with contacts you are already using OpenPGP with. This
+feature is regarded experimental. Conversations is the only client that uses
+XEP-0027 with conferences. (The XEP neither specifically allows nor disallows
+this.)
+
+### Development
+
+#### How do I build Conversations
+
Make sure to have ANDROID_HOME point to your Android SDK
-```
-git clone https://github.com/siacs/Conversations.git
-cd Conversations
-git submodule update --init --recursive
-ant clean
-ant debug
-```
-####How do I debug Conversations
+
+ git clone https://github.com/siacs/Conversations.git
+ cd Conversations
+ git submodule update --init --recursive
+ ant clean
+ ant debug
+
+#### How do I debug Conversations
+
If something goes wrong Conversations usually exposes very little information in
-the UI. (Other than the fact that something didn't work)
-However with adb (android debug bridge) you squeeze some more information out of
-Conversations. These information are especially useful if you are experiencing
-troubles with your connection or with file transfer.
-````
-adb -d logcat -v time -s conversations
-````
-####I found a bug
-Please report it to our issue tracker. If your app crashes please provide a
-stack trace. If you are experiencing missbehaviour please provide detailed
-steps to reproduce.
-Always mention whether you are running the latest Play Store version or the
-current HEAD.
-If you are having problems connecting to your XMPP server your file transfer
-doesn’t work as expected please always include a logcat debug output with your
-issue. (See above)
+the UI (other than the fact that something didn't work). However with adb
+(android debug bridge) you squeeze some more information out of Conversations.
+These information are especially useful if you are experiencing trouble with
+your connection or with file transfer.
+
+ adb -d logcat -v time -s conversations
+
+#### I found a bug
+
+Please report it to our [issue tracker][issues]. If your app crashes please
+provide a stack trace. If you are experiencing misbehaviour please provide
+detailed steps to reproduce. Always mention whether you are running the latest
+Play Store version or the current HEAD. If you are having problems connecting to
+your XMPP server your file transfer doesn’t work as expected please always
+include a logcat debug output with your issue (see above).
+
+[issues]: https://github.com/siacs/Conversations/issues
diff --git a/libs/MemorizingTrustManager b/libs/MemorizingTrustManager
-Subproject 3f67eba2e4663841dd0024908f8ffb261307814
+Subproject fad835037adc1bd313bb56b694426fca4eb6734
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index e15ef416..e1db316d 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -87,6 +87,7 @@
<string name="encrypted_message_received"><i>Message chiffré reçu. Appuyez pour le déchiffrer.</i></string>
<string name="encrypted_image_received"><i>Image chiffrée reçue. Appuyez pour la déchiffrer.</i></string>
<string name="image_file"><i>Image reçue. Appuyez pour visualiser.</i></string>
+ <string name="pref_general">Général</string>
<string name="pref_xmpp_resource">Ressource XMPP</string>
<string name="pref_xmpp_resource_summary">Nom permettant d\'identifier ce client XMPP</string>
<string name="pref_accept_files">Accepter les fichiers</string>
@@ -107,6 +108,7 @@
<string name="pref_never_send_crash_summary">En envoyant des logs vous aidez au développement de Conversations.</string>
<string name="pref_confirm_messages">Confirmation de lecture</string>
<string name="pref_confirm_messages_summary">Informer l\'expéditeur d\'un message de sa bonne réception.</string>
+ <string name="pref_ui_options">Options d\'affichage</string>
<string name="openpgp_error">Une erreur s\'est produite via OpenKeychain</string>
<string name="error_decrypting_file">Erreur d\'E/S lors du déchiffrement du fichier</string>
<string name="accept">Accepter</string>
@@ -145,6 +147,8 @@
<string name="mgmt_account_edit">Modifier le compte</string>
<string name="mgmt_account_delete">Supprimer</string>
<string name="mgmt_account_disable">Désactiver temporairement</string>
+ <string name="mgmt_account_publish_avatar">Publier un avatar</string>
+ <string name="mgmt_account_publish_pgp">Publier la clef publique OpenPGP</string>
<string name="mgmt_account_enable">Activer</string>
<string name="mgmt_account_are_you_sure">Êtes-vous sûr?</string>
<string name="mgmt_account_delete_confirm_text">En supprimant votre compte, votre historique de conversations sera perdu!</string>
@@ -169,6 +173,9 @@
<string name="muc_details_other_members">Autres membres</string>
<string name="server_info_carbon_messages">Copies carbone</string>
<string name="server_info_stream_management">Gestion des flux</string>
+ <string name="server_info_pep">XEP-0163: PEP (Avatars)</string>
+ <string name="server_info_available">disponible</string>
+ <string name="server_info_unavailable">indisponible</string>
<string name="missing_public_keys">Aucune annonce de clef publique</string>
<string name="last_seen_now">en ligne à l\'instant</string>
<string name="last_seen_min">en ligne il y a 1 minute</string>
@@ -207,6 +214,60 @@
<string name="contact_added_you">Votre correspondant vous a ajouté dans sa liste de contacts</string>
<string name="add_back">Ajouter également</string>
<string name="contact_has_read_up_to_this_point">%s a lu les messages précédents.</string>
- <string name="pref_ui_options">Options d\'affichage</string>
+ <string name="publish">Publier</string>
+ <string name="touch_to_choose_picture">Toucher l\'avatar pour choisir une image depuis la galerie.</string>
+ <string name="publish_avatar_explanation">Nota Bene: Les personnes ayant activé les mises jour de présence verront cette image.</string>
+ <string name="publishing">Mise à jour&#8230;</string>
+ <string name="error_publish_avatar_server_reject">Le serveur a rejeté votre envoi d\'image</string>
+ <string name="error_publish_avatar_converting">Une erreur s\'est produite pendant la conversion de votre image.</string>
+ <string name="error_saving_avatar">Impossible de stocker l\'image sur le disque</string>
+ <string name="or_long_press_for_default">(Un appui long réinitialise le paramètre par defaut)</string>
+ <string name="error_publish_avatar_no_server_support">Votre serveur n\'autorise pas l\'envoi d\'avatars</string>
+ <string name="private_message">chuchoté</string>
+ <string name="private_message_to">pour %s</string>
+ <string name="send_private_message_to">Envoyer un message privé à %s</string>
+ <string name="connect">Se connecter</string>
+ <string name="account_already_exists">Ce compte existe déjà</string>
+ <string name="next">suivant</string>
+ <string name="server_info_session_established">Session établie</string>
+ <string name="additional_information">Informations supplémentaires</string>
+ <string name="skip">Passer</string>
+ <string name="disable_notifications">Désactiver les notifications</string>
+ <string name="disable_notifications_for_this_conversation">Désactiver les notifications pour cette conversation</string>
+ <string name="notifications_disabled">Notifications are Désactivées</string>
+ <string name="enable">Activer</string>
+ <string name="conference_requires_password">La conférence necessite un mot de passe</string>
+ <string name="enter_password">Entrer le mot de passe</string>
+ <string name="missing_presence_updates">Mise à jour de présence non connue</string>
+ <string name="request_presence_updates">Merci de demander à votre contact de fournir les mises à jour de présence.\n\n<small>Cela permettra de savoir quel matériel utilise votre contact.</small></string>
+ <string name="request_now">Demander maintenant</string>
+ <string name="delete_fingerprint">Supprimer l\'empreinte</string>
+ <string name="sure_delete_fingerprint">Etes-vous sûr de vouloir supprimer l\'empreinte?</string>
+ <string name="ignore">Ignorer</string>
+ <string name="without_mutual_presence_updates"><b>Attention:</b> Ceci peut poser problème si l\'un des deux correspondants n\'a pas activé les mises à jour de présence.\n\n<small>Go to contact details to verify your presence subscriptions.</small></string>
+ <string name="pref_encryption_settings">Paramètres de chiffrement</string>
+ <string name="pref_force_encryption">Forcer le chiffrement de bout en bout</string>
+ <string name="pref_force_encryption_summary">Toujours envoyer des messages chiffrés (sauf pour les conférences)</string>
+ <string name="pref_dont_save_encrypted">Ne pas sauvegarder les messages chiffrés</string>
+ <string name="pref_dont_save_encrypted_summary">Attention: Celà peut mener à une perte de messages</string>
+ <string name="pref_expert_options">Options avancées</string>
+ <string name="pref_expert_options_summary">A utiliser avec précautions</string>
+ <string name="pref_use_larger_font">Augmenter la taille du texte</string>
+ <string name="pref_use_larger_font_summary">Augmenter la taille du texte partout dans l\'application</string>
+ <string name="pref_use_send_button_to_indicate_status">Le bouton Envoyer permet d\'indiquer le statut</string>
+ <string name="pref_use_indicate_received">Accusé de reception</string>
+ <string name="pref_use_indicate_received_summary">Les messages recus seront marqués d\'une coche verte si disponible</string>
+ <string name="pref_use_send_button_to_indicate_status_summary">Adapter la couleur du bouton Envoyer pour indiquer le statut</string>
+ <string name="pref_expert_options_other">Autres</string>
+ <string name="pref_conference_name">Nom de la conférence </string>
+ <string name="pref_conference_name_summary">Identifier la conférence par son nom plutot que par son JID</string>
+ <string name="toast_message_otr_fingerprint">Empreinte OTR copiée dans le presse-papier!</string>
+ <string name="conference_banned">Vous êtes interdit de cette conférence</string>
+ <string name="conference_members_only">Cette conférence est réservée aux membres</string>
+ <string name="conference_kicked">Vous avez été éjecté de cette conférence</string>
+ <string name="using_account">utiliser le compte %s</string>
+ <string name="checking_image">Vérification de l\'image</string>
+ <string name="image_file_deleted">L\'image a été suprimée</string>
+ <string name="not_connected_try_again">Vous n\'êtes pas connecté. Merci de retenter plus tard.</string>
-</resources> \ No newline at end of file
+</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index b08b793e..3862bb7b 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -249,9 +249,11 @@
<string name="pref_force_encryption">Force end-to-end encryption</string>
<string name="pref_force_encryption_summary">Always send messages encrypted (except for conferences)</string>
<string name="pref_dont_save_encrypted">Don’t save encrypted messages</string>
- <string name="pref_dont_save_encrypted_summary">Warning: This could lead to message loss</string>
- <string name="pref_expert_options">Expert options</string>
- <string name="pref_expert_options_summary">Please be very careful with those</string>
+ <string name="pref_dont_save_encrypted_summary">Warning: This could lead to message loss</string>
+ <string name="pref_enable_legacy_ssl">Enable legacy SSL</string>
+ <string name="pref_enable_legacy_ssl_summary">Enables SSLv3 support for legacy servers. Warning: SSLv3 is considered insecure.</string>
+ <string name="pref_expert_options">Expert options</string>
+ <string name="pref_expert_options_summary">Please be careful with these</string>
<string name="pref_use_larger_font">Increase font size</string>
<string name="pref_use_larger_font_summary">Use larger font sizes across the entire app</string>
<string name="pref_use_send_button_to_indicate_status">Send button indicates status</string>
@@ -269,5 +271,6 @@
<string name="checking_image">Checking image on HTTP host</string>
<string name="image_file_deleted">The image file has been deleted</string>
<string name="not_connected_try_again">You are not connected. Try again later</string>
+ <string name="check_image_filesize">Check image file size</string>
</resources>
diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml
index 3bbb7663..06ab7560 100644
--- a/res/xml/preferences.xml
+++ b/res/xml/preferences.xml
@@ -89,6 +89,11 @@
android:key="dont_save_encrypted"
android:summary="@string/pref_dont_save_encrypted_summary"
android:title="@string/pref_dont_save_encrypted" />
+ <CheckBoxPreference
+ android:defaultValue="false"
+ android:key="enable_legacy_ssl"
+ android:summary="@string/pref_enable_legacy_ssl_summary"
+ android:title="@string/pref_enable_legacy_ssl" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/pref_expert_options_other" >
<CheckBoxPreference
diff --git a/src/eu/siacs/conversations/entities/Conversation.java b/src/eu/siacs/conversations/entities/Conversation.java
index c984933f..600b9d38 100644
--- a/src/eu/siacs/conversations/entities/Conversation.java
+++ b/src/eu/siacs/conversations/entities/Conversation.java
@@ -1,8 +1,8 @@
package eu.siacs.conversations.entities;
import java.security.interfaces.DSAPublicKey;
+import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
import org.json.JSONException;
import org.json.JSONObject;
@@ -57,7 +57,7 @@ public class Conversation extends AbstractEntity {
private String nextPresence;
- private transient CopyOnWriteArrayList<Message> messages = null;
+ private transient ArrayList<Message> messages = new ArrayList<Message>();
private transient Account account = null;
private transient SessionImpl otrSession;
@@ -104,17 +104,6 @@ public class Conversation extends AbstractEntity {
}
public List<Message> getMessages() {
- if (messages == null) {
- this.messages = new CopyOnWriteArrayList<Message>(); // prevent null
- // pointer
- }
-
- // populate with Conversation (this)
-
- for (Message msg : messages) {
- msg.setConversation(this);
- }
-
return messages;
}
@@ -165,7 +154,7 @@ public class Conversation extends AbstractEntity {
}
}
- public void setMessages(CopyOnWriteArrayList<Message> msgs) {
+ public void setMessages(ArrayList<Message> msgs) {
this.messages = msgs;
}
@@ -507,4 +496,17 @@ public class Conversation extends AbstractEntity {
}
}
}
+
+ public void add(Message message) {
+ message.setConversation(this);
+ synchronized (this.messages) {
+ this.messages.add(message);
+ }
+ }
+
+ public void addAll(int index, List<Message> messages) {
+ synchronized (this.messages) {
+ this.messages.addAll(index, messages);
+ }
+ }
}
diff --git a/src/eu/siacs/conversations/entities/Downloadable.java b/src/eu/siacs/conversations/entities/Downloadable.java
index 36584ab0..70516b20 100644
--- a/src/eu/siacs/conversations/entities/Downloadable.java
+++ b/src/eu/siacs/conversations/entities/Downloadable.java
@@ -11,6 +11,7 @@ public interface Downloadable {
public static final int STATUS_OFFER = 0x203;
public static final int STATUS_DOWNLOADING = 0x204;
public static final int STATUS_DELETED = 0x205;
+ public static final int STATUS_OFFER_CHECK_FILESIZE = 0x206;
public boolean start();
diff --git a/src/eu/siacs/conversations/http/HttpConnection.java b/src/eu/siacs/conversations/http/HttpConnection.java
index 0254dc2f..3eb8bb84 100644
--- a/src/eu/siacs/conversations/http/HttpConnection.java
+++ b/src/eu/siacs/conversations/http/HttpConnection.java
@@ -6,15 +6,18 @@ import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.X509TrustManager;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.net.Uri;
-import android.util.Log;
-import eu.siacs.conversations.Config;
import eu.siacs.conversations.entities.Downloadable;
import eu.siacs.conversations.entities.DownloadableFile;
import eu.siacs.conversations.entities.Message;
@@ -39,8 +42,12 @@ public class HttpConnection implements Downloadable {
@Override
public boolean start() {
if (mXmppConnectionService.hasInternetConnection()) {
- changeStatus(STATUS_DOWNLOADING);
- new Thread(new FileDownloader()).start();
+ if (this.mStatus == STATUS_OFFER_CHECK_FILESIZE) {
+ checkFileSize(true);
+ } else {
+ changeStatus(STATUS_DOWNLOADING);
+ new Thread(new FileDownloader()).start();
+ }
return true;
} else {
return false;
@@ -52,18 +59,18 @@ public class HttpConnection implements Downloadable {
this.message.setDownloadable(this);
try {
mUrl = new URL(message.getBody());
- this.file = mXmppConnectionService.getFileBackend()
- .getFile(message, false);
+ this.file = mXmppConnectionService.getFileBackend().getFile(
+ message, false);
this.mAutostart = true;
- checkFileSize();
+ checkFileSize(false);
} catch (MalformedURLException e) {
this.cancel();
}
}
- private void checkFileSize() {
+ private void checkFileSize(boolean interactive) {
changeStatus(STATUS_CHECKING);
- new Thread(new FileSizeChecker()).start();
+ new Thread(new FileSizeChecker(interactive)).start();
}
public void cancel() {
@@ -84,33 +91,62 @@ public class HttpConnection implements Downloadable {
this.mStatus = status;
mXmppConnectionService.updateConversationUi();
}
+
+ private void setupTrustManager(HttpsURLConnection connection, boolean interactive) {
+ X509TrustManager trustManager;
+ if (interactive) {
+ trustManager = mXmppConnectionService.getMemorizingTrustManager();
+ } else {
+ trustManager = mXmppConnectionService.getMemorizingTrustManager().getNonInteractive();
+ }
+ try {
+ SSLContext sc = SSLContext.getInstance("TLS");
+ sc.init(null,new X509TrustManager[] { trustManager },mXmppConnectionService.getRNG());
+ connection.setSSLSocketFactory(sc.getSocketFactory());
+ } catch (KeyManagementException e) {
+ return;
+ } catch (NoSuchAlgorithmException e) {
+ return;
+ }
+ }
private class FileSizeChecker implements Runnable {
+
+ private boolean interactive = false;
+
+ public FileSizeChecker(boolean interactive) {
+ this.interactive = interactive;
+ }
@Override
public void run() {
long size;
try {
size = retrieveFileSize();
+ } catch (SSLHandshakeException e) {
+ changeStatus(STATUS_OFFER_CHECK_FILESIZE);
+ return;
} catch (IOException e) {
cancel();
return;
}
file.setExpectedSize(size);
- if (size <= mHttpConnectionManager.getAutoAcceptFileSize() && mAutostart) {
+ if (size <= mHttpConnectionManager.getAutoAcceptFileSize()
+ && mAutostart) {
start();
} else {
changeStatus(STATUS_OFFER);
}
}
- private long retrieveFileSize() throws IOException {
+ private long retrieveFileSize() throws IOException, SSLHandshakeException {
HttpURLConnection connection = (HttpURLConnection) mUrl
.openConnection();
connection.setRequestMethod("HEAD");
if (connection instanceof HttpsURLConnection) {
-
+ setupTrustManager((HttpsURLConnection) connection, interactive);
}
+ connection.connect();
String contentLength = connection.getHeaderField("Content-Length");
if (contentLength == null) {
throw new IOException();
@@ -141,7 +177,7 @@ public class HttpConnection implements Downloadable {
HttpURLConnection connection = (HttpURLConnection) mUrl
.openConnection();
if (connection instanceof HttpsURLConnection) {
-
+ setupTrustManager((HttpsURLConnection) connection, true);
}
BufferedInputStream is = new BufferedInputStream(
connection.getInputStream());
diff --git a/src/eu/siacs/conversations/parser/MessageParser.java b/src/eu/siacs/conversations/parser/MessageParser.java
index 4090ed39..daf0174c 100644
--- a/src/eu/siacs/conversations/parser/MessageParser.java
+++ b/src/eu/siacs/conversations/parser/MessageParser.java
@@ -469,7 +469,7 @@ public class MessageParser extends AbstractParser implements
}
}
Conversation conversation = message.getConversation();
- conversation.getMessages().add(message);
+ conversation.add(message);
if (packet.getType() != MessagePacket.TYPE_ERROR) {
if (message.getEncryption() == Message.ENCRYPTION_NONE
|| mXmppConnectionService.saveEncryptedMessages()) {
diff --git a/src/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/eu/siacs/conversations/persistance/DatabaseBackend.java
index d90b5c62..d3d6ccf2 100644
--- a/src/eu/siacs/conversations/persistance/DatabaseBackend.java
+++ b/src/eu/siacs/conversations/persistance/DatabaseBackend.java
@@ -152,14 +152,14 @@ public class DatabaseBackend extends SQLiteOpenHelper {
return list;
}
- public CopyOnWriteArrayList<Message> getMessages(
+ public ArrayList<Message> getMessages(
Conversation conversations, int limit) {
return getMessages(conversations, limit, -1);
}
- public CopyOnWriteArrayList<Message> getMessages(Conversation conversation,
+ public ArrayList<Message> getMessages(Conversation conversation,
int limit, long timestamp) {
- CopyOnWriteArrayList<Message> list = new CopyOnWriteArrayList<Message>();
+ ArrayList<Message> list = new ArrayList<Message>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor;
if (timestamp == -1) {
@@ -178,7 +178,9 @@ public class DatabaseBackend extends SQLiteOpenHelper {
if (cursor.getCount() > 0) {
cursor.moveToLast();
do {
- list.add(Message.fromCursor(cursor));
+ Message message = Message.fromCursor(cursor);
+ message.setConversation(conversation);
+ list.add(message);
} while (cursor.moveToPrevious());
}
return list;
diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java
index 36ea350b..f557c3e1 100644
--- a/src/eu/siacs/conversations/services/XmppConnectionService.java
+++ b/src/eu/siacs/conversations/services/XmppConnectionService.java
@@ -529,7 +529,7 @@ public class XmppConnectionService extends Service {
return connection;
}
- synchronized public void sendMessage(Message message) {
+ public void sendMessage(Message message) {
Account account = message.getConversation().getAccount();
account.deactivateGracePeriod();
Conversation conv = message.getConversation();
@@ -615,7 +615,7 @@ public class XmppConnectionService extends Service {
}
}
- conv.getMessages().add(message);
+ conv.add(message);
if (saveInDb) {
if (message.getEncryption() == Message.ENCRYPTION_NONE
|| saveEncryptedMessages()) {
@@ -881,7 +881,7 @@ public class XmppConnectionService extends Service {
for (Message message : messages) {
message.setConversation(conversation);
}
- conversation.getMessages().addAll(0, messages);
+ conversation.addAll(0, messages);
return messages.size();
}
diff --git a/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java b/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java
index bd37f7fc..20c7bee2 100644
--- a/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java
+++ b/src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java
@@ -92,6 +92,8 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
mLastMessage.setText(R.string.receiving_image);
} else if (d.getStatus() == Downloadable.STATUS_OFFER) {
mLastMessage.setText(R.string.image_offered_for_download);
+ } else if (d.getStatus() == Downloadable.STATUS_OFFER_CHECK_FILESIZE) {
+ mLastMessage.setText(R.string.image_offered_for_download);
} else if (d.getStatus() == Downloadable.STATUS_DELETED) {
mLastMessage.setText(R.string.image_file_deleted);
} else {
diff --git a/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java
index 6b2a0094..db783b7f 100644
--- a/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java
+++ b/src/eu/siacs/conversations/ui/adapter/MessageAdapter.java
@@ -264,10 +264,11 @@ public class MessageAdapter extends ArrayAdapter<Message> {
}
private void displayDownloadableMessage(ViewHolder viewHolder,
- final Message message) {
+ final Message message, int resid) {
viewHolder.image.setVisibility(View.GONE);
viewHolder.messageBody.setVisibility(View.GONE);
viewHolder.download_button.setVisibility(View.VISIBLE);
+ viewHolder.download_button.setText(resid);
viewHolder.download_button.setOnClickListener(new OnClickListener() {
@Override
@@ -493,7 +494,9 @@ public class MessageAdapter extends ArrayAdapter<Message> {
&& d.getStatus() == Downloadable.STATUS_DELETED) {
displayInfoMessage(viewHolder, R.string.image_file_deleted);
} else if (d != null && d.getStatus() == Downloadable.STATUS_OFFER) {
- displayDownloadableMessage(viewHolder, item);
+ displayDownloadableMessage(viewHolder, item,R.string.download_image);
+ } else if (d != null && d.getStatus() == Downloadable.STATUS_OFFER_CHECK_FILESIZE) {
+ displayDownloadableMessage(viewHolder, item,R.string.check_image_filesize);
} else if ((item.getEncryption() == Message.ENCRYPTION_DECRYPTED)
|| (item.getEncryption() == Message.ENCRYPTION_NONE)
|| (item.getEncryption() == Message.ENCRYPTION_OTR)) {
diff --git a/src/eu/siacs/conversations/xmpp/XmppConnection.java b/src/eu/siacs/conversations/xmpp/XmppConnection.java
index 43614f50..0252d80e 100644
--- a/src/eu/siacs/conversations/xmpp/XmppConnection.java
+++ b/src/eu/siacs/conversations/xmpp/XmppConnection.java
@@ -10,8 +10,10 @@ import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Hashtable;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
@@ -26,15 +28,19 @@ import org.xmlpull.v1.XmlPullParserException;
import de.duenndns.ssl.MemorizingTrustManager;
+import android.content.Context;
+import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.SystemClock;
+import android.preference.PreferenceManager;
import android.util.Log;
import android.util.SparseArray;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.services.XmppConnectionService;
+import eu.siacs.conversations.ui.StartConversationActivity;
import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.utils.DNSHelper;
import eu.siacs.conversations.utils.zlib.ZLibOutputStream;
@@ -80,6 +86,7 @@ public class XmppConnection implements Runnable {
private SparseArray<String> messageReceipts = new SparseArray<String>();
private boolean usingCompression = false;
+ private boolean usingEncryption = false;
private int stanzasReceived = 0;
private int stanzasSent = 0;
@@ -104,6 +111,7 @@ public class XmppConnection implements Runnable {
private OnBindListener bindListener = null;
private OnMessageAcknowledged acknowledgedListener = null;
private MemorizingTrustManager mMemorizingTrustManager;
+ private final Context applicationContext;
public XmppConnection(Account account, XmppConnectionService service) {
this.mRandom = service.getRNG();
@@ -112,6 +120,7 @@ public class XmppConnection implements Runnable {
this.wakeLock = service.getPowerManager().newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, account.getJid());
tagWriter = new TagWriter();
+ applicationContext = service.getApplicationContext();
}
protected void changeStatus(int nextStatus) {
@@ -135,6 +144,7 @@ public class XmppConnection implements Runnable {
protected void connect() {
Log.d(Config.LOGTAG, account.getJid() + ": connecting");
usingCompression = false;
+ usingEncryption = false;
lastConnect = SystemClock.elapsedRealtime();
lastPingSent = SystemClock.elapsedRealtime();
this.attempt++;
@@ -161,10 +171,23 @@ public class XmppConnection implements Runnable {
+ "[" + srvIpServer + "]:" + srvRecordPort);
socket = new Socket(srvIpServer, srvRecordPort);
} else {
- Log.d(Config.LOGTAG, account.getJid()
- + ": using values from dns " + srvRecordServer
- + ":" + srvRecordPort);
- socket = new Socket(srvRecordServer, srvRecordPort);
+ boolean socketError = true;
+ int srvIndex = 0;
+ while (socketError && namePort.containsKey("name" + srvIndex)){
+ try {
+ srvRecordServer = namePort.getString("name" + srvIndex);
+ srvRecordPort = namePort.getInt("port" + srvIndex);
+ Log.d(Config.LOGTAG, account.getJid()
+ + ": using values from dns " + srvRecordServer
+ + ":" + srvRecordPort);
+ socket = new Socket(srvRecordServer, srvRecordPort);
+ socketError = false;
+ } catch (UnknownHostException e) {
+ srvIndex++;
+ } catch (IOException e) {
+ srvIndex++;
+ }
+ }
}
} else if (namePort.containsKey("error")
&& "nosrv".equals(namePort.getString("error", null))) {
@@ -362,13 +385,13 @@ public class XmppConnection implements Runnable {
iq.addChild("ping", "urn:xmpp:ping");
this.sendIqPacket(iq, new OnIqPacketReceived() {
- @Override
- public void onIqPacketReceived(Account account, IqPacket packet) {
- Log.d(Config.LOGTAG, account.getJid()
- + ": online with resource " + account.getResource());
- changeStatus(Account.STATUS_ONLINE);
- }
- });
+ @Override
+ public void onIqPacketReceived(Account account, IqPacket packet) {
+ Log.d(Config.LOGTAG, account.getJid()
+ + ": online with resource " + account.getResource());
+ changeStatus(Account.STATUS_ONLINE);
+ }
+ });
}
private Element processPacket(Tag currentTag, int packetType)
@@ -504,6 +527,14 @@ public class XmppConnection implements Runnable {
tagWriter.writeTag(startTLS);
}
+ private SharedPreferences getPreferences() {
+ return PreferenceManager.getDefaultSharedPreferences(applicationContext);
+ }
+
+ private boolean enableLegacySSL() {
+ return getPreferences().getBoolean("enable_legacy_ssl", false);
+ }
+
private void switchOverToTls(Tag currentTag) throws XmlPullParserException,
IOException {
tagReader.readTag();
@@ -520,6 +551,21 @@ public class XmppConnection implements Runnable {
socket.getInetAddress().getHostAddress(), socket.getPort(),
true);
+ // Support all protocols except legacy SSL.
+ // The min SDK version prevents us having to worry about SSLv2. In future, this may be
+ // true of SSLv3 as well.
+ final String[] supportProtocols;
+ if (enableLegacySSL()) {
+ supportProtocols = sslSocket.getSupportedProtocols();
+ } else {
+ final List<String> supportedProtocols = new LinkedList<String>(Arrays.asList(
+ sslSocket.getSupportedProtocols()));
+ supportedProtocols.remove("SSLv3");
+ supportProtocols = new String[supportedProtocols.size()];
+ supportedProtocols.toArray(supportProtocols);
+ }
+ sslSocket.setEnabledProtocols(supportProtocols);
+
if (verifier != null
&& !verifier.verify(account.getServer(),
sslSocket.getSession())) {
@@ -533,6 +579,7 @@ public class XmppConnection implements Runnable {
sendStartStream();
Log.d(Config.LOGTAG, account.getJid()
+ ": TLS connection established");
+ usingEncryption = true;
processStream(tagReader.readTag());
sslSocket.close();
} catch (NoSuchAlgorithmException e1) {
@@ -562,20 +609,19 @@ public class XmppConnection implements Runnable {
private void processStreamFeatures(Tag currentTag)
throws XmlPullParserException, IOException {
this.streamFeatures = tagReader.readElement(currentTag);
- if (this.streamFeatures.hasChild("starttls")
- && account.isOptionSet(Account.OPTION_USETLS)) {
+ if (this.streamFeatures.hasChild("starttls") && !usingEncryption) {
sendStartTLS();
} else if (compressionAvailable()) {
sendCompressionZlib();
} else if (this.streamFeatures.hasChild("register")
- && (account.isOptionSet(Account.OPTION_REGISTER))) {
+ && account.isOptionSet(Account.OPTION_REGISTER) && usingEncryption) {
sendRegistryRequest();
} else if (!this.streamFeatures.hasChild("register")
- && (account.isOptionSet(Account.OPTION_REGISTER))) {
+ && account.isOptionSet(Account.OPTION_REGISTER)) {
changeStatus(Account.STATUS_REGISTRATION_NOT_SUPPORTED);
disconnect(true);
} else if (this.streamFeatures.hasChild("mechanisms")
- && shouldAuthenticate) {
+ && shouldAuthenticate && usingEncryption) {
List<String> mechanisms = extractMechanisms(streamFeatures
.findChild("mechanisms"));
if (mechanisms.contains("PLAIN")) {
@@ -591,6 +637,9 @@ public class XmppConnection implements Runnable {
this.tagWriter.writeStanzaAsync(resume);
} else if (this.streamFeatures.hasChild("bind") && shouldBind) {
sendBindRequest();
+ } else {
+ Log.d(Config.LOGTAG,account.getJid()+": incompatible server. disconnecting");
+ disconnect(true);
}
}
diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java
index e7e1a33d..5b3dfbff 100644
--- a/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java
+++ b/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java
@@ -307,7 +307,7 @@ public class JingleConnection implements Downloadable {
if (supportedFile) {
long size = Long.parseLong(fileSize.getContent());
message.setBody(Long.toString(size));
- conversation.getMessages().add(message);
+ conversation.add(message);
mXmppConnectionService.updateConversationUi();
if (size <= this.mJingleConnectionManager
.getAutoAcceptFileSize()) {
@@ -634,6 +634,7 @@ public class JingleConnection implements Downloadable {
}
private void sendFallbackToIbb() {
+ Log.d(Config.LOGTAG,"sending fallback to ibb");
JinglePacket packet = this.bootstrapPacket("transport-replace");
Content content = new Content(this.contentCreator, this.contentName);
this.transportId = this.mJingleConnectionManager.nextRandomId();
@@ -645,6 +646,7 @@ public class JingleConnection implements Downloadable {
}
private boolean receiveFallbackToIbb(JinglePacket packet) {
+ Log.d(Config.LOGTAG,"receiving fallack to ibb");
String receivedBlockSize = packet.getJingleContent().ibbTransport()
.getAttribute("block-size");
if (receivedBlockSize != null) {