aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Schneppe <christian.schneppe@pix-art.de>2020-04-07 21:26:49 +0200
committerChristian Schneppe <christian.schneppe@pix-art.de>2020-04-07 21:26:49 +0200
commitdddff7965f30cbe944b1cb655a12e08b09b91484 (patch)
treedb02b86bd4fef18b1183802e8e31f43abfbe99d0
parenta7fd6b31e20e722a524467cd93bf65900ee7af92 (diff)
fix updater
-rw-r--r--src/main/java/de/pixart/messenger/http/NoSSLv3SocketFactory.java419
-rw-r--r--src/main/java/de/pixart/messenger/services/UpdateService.java24
-rw-r--r--src/main/java/de/pixart/messenger/ui/UpdaterActivity.java35
3 files changed, 467 insertions, 11 deletions
diff --git a/src/main/java/de/pixart/messenger/http/NoSSLv3SocketFactory.java b/src/main/java/de/pixart/messenger/http/NoSSLv3SocketFactory.java
new file mode 100644
index 000000000..2a7794c92
--- /dev/null
+++ b/src/main/java/de/pixart/messenger/http/NoSSLv3SocketFactory.java
@@ -0,0 +1,419 @@
+package de.pixart.messenger.http;
+
+/*Copyright 2015 Bhavit Singh Sengar
+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.*/
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.nio.channels.SocketChannel;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.net.ssl.HandshakeCompletedListener;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+
+
+public class NoSSLv3SocketFactory extends SSLSocketFactory {
+ private final SSLSocketFactory delegate;
+
+ public NoSSLv3SocketFactory() {
+ this.delegate = HttpsURLConnection.getDefaultSSLSocketFactory();
+ }
+
+ public NoSSLv3SocketFactory(SSLSocketFactory delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public String[] getDefaultCipherSuites() {
+ return delegate.getDefaultCipherSuites();
+ }
+
+ @Override
+ public String[] getSupportedCipherSuites() {
+ return delegate.getSupportedCipherSuites();
+ }
+
+ private Socket makeSocketSafe(Socket socket) {
+ if (socket instanceof SSLSocket) {
+ socket = new NoSSLv3SSLSocket((SSLSocket) socket);
+ }
+ return socket;
+ }
+
+ @Override
+ public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
+ return makeSocketSafe(delegate.createSocket(s, host, port, autoClose));
+ }
+
+ @Override
+ public Socket createSocket(String host, int port) throws IOException {
+ return makeSocketSafe(delegate.createSocket(host, port));
+ }
+
+ @Override
+ public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
+ return makeSocketSafe(delegate.createSocket(host, port, localHost, localPort));
+ }
+
+ @Override
+ public Socket createSocket(InetAddress host, int port) throws IOException {
+ return makeSocketSafe(delegate.createSocket(host, port));
+ }
+
+ @Override
+ public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
+ return makeSocketSafe(delegate.createSocket(address, port, localAddress, localPort));
+ }
+
+ private class NoSSLv3SSLSocket extends DelegateSSLSocket {
+
+ private NoSSLv3SSLSocket(SSLSocket delegate) {
+ super(delegate);
+
+ }
+
+ @Override
+ public void setEnabledProtocols(String[] protocols) {
+ if (protocols != null && protocols.length == 1 && "SSLv3".equals(protocols[0])) {
+
+ List<String> enabledProtocols = new ArrayList<String>(Arrays.asList(delegate.getEnabledProtocols()));
+ if (enabledProtocols.size() > 1) {
+ enabledProtocols.remove("SSLv3");
+ System.out.println("Removed SSLv3 from enabled protocols");
+ } else {
+ System.out.println("SSL stuck with protocol available for " + String.valueOf(enabledProtocols));
+ }
+ protocols = enabledProtocols.toArray(new String[enabledProtocols.size()]);
+ }
+
+ super.setEnabledProtocols(protocols);
+ }
+ }
+
+ public class DelegateSSLSocket extends SSLSocket {
+
+ protected final SSLSocket delegate;
+
+ DelegateSSLSocket(SSLSocket delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public String[] getSupportedCipherSuites() {
+ return delegate.getSupportedCipherSuites();
+ }
+
+ @Override
+ public String[] getEnabledCipherSuites() {
+ return delegate.getEnabledCipherSuites();
+ }
+
+ @Override
+ public void setEnabledCipherSuites(String[] suites) {
+ delegate.setEnabledCipherSuites(suites);
+ }
+
+ @Override
+ public String[] getSupportedProtocols() {
+ return delegate.getSupportedProtocols();
+ }
+
+ @Override
+ public String[] getEnabledProtocols() {
+ return delegate.getEnabledProtocols();
+ }
+
+ @Override
+ public void setEnabledProtocols(String[] protocols) {
+ delegate.setEnabledProtocols(protocols);
+ }
+
+ @Override
+ public SSLSession getSession() {
+ return delegate.getSession();
+ }
+
+ @Override
+ public void addHandshakeCompletedListener(HandshakeCompletedListener listener) {
+ delegate.addHandshakeCompletedListener(listener);
+ }
+
+ @Override
+ public void removeHandshakeCompletedListener(HandshakeCompletedListener listener) {
+ delegate.removeHandshakeCompletedListener(listener);
+ }
+
+ @Override
+ public void startHandshake() throws IOException {
+ delegate.startHandshake();
+ }
+
+ @Override
+ public void setUseClientMode(boolean mode) {
+ delegate.setUseClientMode(mode);
+ }
+
+ @Override
+ public boolean getUseClientMode() {
+ return delegate.getUseClientMode();
+ }
+
+ @Override
+ public void setNeedClientAuth(boolean need) {
+ delegate.setNeedClientAuth(need);
+ }
+
+ @Override
+ public void setWantClientAuth(boolean want) {
+ delegate.setWantClientAuth(want);
+ }
+
+ @Override
+ public boolean getNeedClientAuth() {
+ return delegate.getNeedClientAuth();
+ }
+
+ @Override
+ public boolean getWantClientAuth() {
+ return delegate.getWantClientAuth();
+ }
+
+ @Override
+ public void setEnableSessionCreation(boolean flag) {
+ delegate.setEnableSessionCreation(flag);
+ }
+
+ @Override
+ public boolean getEnableSessionCreation() {
+ return delegate.getEnableSessionCreation();
+ }
+
+ @Override
+ public void bind(SocketAddress localAddr) throws IOException {
+ delegate.bind(localAddr);
+ }
+
+ @Override
+ public synchronized void close() throws IOException {
+ delegate.close();
+ }
+
+ @Override
+ public void connect(SocketAddress remoteAddr) throws IOException {
+ delegate.connect(remoteAddr);
+ }
+
+ @Override
+ public void connect(SocketAddress remoteAddr, int timeout) throws IOException {
+ delegate.connect(remoteAddr, timeout);
+ }
+
+ @Override
+ public SocketChannel getChannel() {
+ return delegate.getChannel();
+ }
+
+ @Override
+ public InetAddress getInetAddress() {
+ return delegate.getInetAddress();
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return delegate.getInputStream();
+ }
+
+ @Override
+ public boolean getKeepAlive() throws SocketException {
+ return delegate.getKeepAlive();
+ }
+
+ @Override
+ public InetAddress getLocalAddress() {
+ return delegate.getLocalAddress();
+ }
+
+ @Override
+ public int getLocalPort() {
+ return delegate.getLocalPort();
+ }
+
+ @Override
+ public SocketAddress getLocalSocketAddress() {
+ return delegate.getLocalSocketAddress();
+ }
+
+ @Override
+ public boolean getOOBInline() throws SocketException {
+ return delegate.getOOBInline();
+ }
+
+ @Override
+ public OutputStream getOutputStream() throws IOException {
+ return delegate.getOutputStream();
+ }
+
+ @Override
+ public int getPort() {
+ return delegate.getPort();
+ }
+
+ @Override
+ public synchronized int getReceiveBufferSize() throws SocketException {
+ return delegate.getReceiveBufferSize();
+ }
+
+ @Override
+ public SocketAddress getRemoteSocketAddress() {
+ return delegate.getRemoteSocketAddress();
+ }
+
+ @Override
+ public boolean getReuseAddress() throws SocketException {
+ return delegate.getReuseAddress();
+ }
+
+ @Override
+ public synchronized int getSendBufferSize() throws SocketException {
+ return delegate.getSendBufferSize();
+ }
+
+ @Override
+ public int getSoLinger() throws SocketException {
+ return delegate.getSoLinger();
+ }
+
+ @Override
+ public synchronized int getSoTimeout() throws SocketException {
+ return delegate.getSoTimeout();
+ }
+
+ @Override
+ public boolean getTcpNoDelay() throws SocketException {
+ return delegate.getTcpNoDelay();
+ }
+
+ @Override
+ public int getTrafficClass() throws SocketException {
+ return delegate.getTrafficClass();
+ }
+
+ @Override
+ public boolean isBound() {
+ return delegate.isBound();
+ }
+
+ @Override
+ public boolean isClosed() {
+ return delegate.isClosed();
+ }
+
+ @Override
+ public boolean isConnected() {
+ return delegate.isConnected();
+ }
+
+ @Override
+ public boolean isInputShutdown() {
+ return delegate.isInputShutdown();
+ }
+
+ @Override
+ public boolean isOutputShutdown() {
+ return delegate.isOutputShutdown();
+ }
+
+ @Override
+ public void sendUrgentData(int value) throws IOException {
+ delegate.sendUrgentData(value);
+ }
+
+ @Override
+ public void setKeepAlive(boolean keepAlive) throws SocketException {
+ delegate.setKeepAlive(keepAlive);
+ }
+
+ @Override
+ public void setOOBInline(boolean oobinline) throws SocketException {
+ delegate.setOOBInline(oobinline);
+ }
+
+ @Override
+ public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {
+ delegate.setPerformancePreferences(connectionTime, latency, bandwidth);
+ }
+
+ @Override
+ public synchronized void setReceiveBufferSize(int size) throws SocketException {
+ delegate.setReceiveBufferSize(size);
+ }
+
+ @Override
+ public void setReuseAddress(boolean reuse) throws SocketException {
+ delegate.setReuseAddress(reuse);
+ }
+
+ @Override
+ public synchronized void setSendBufferSize(int size) throws SocketException {
+ delegate.setSendBufferSize(size);
+ }
+
+ @Override
+ public void setSoLinger(boolean on, int timeout) throws SocketException {
+ delegate.setSoLinger(on, timeout);
+ }
+
+ @Override
+ public synchronized void setSoTimeout(int timeout) throws SocketException {
+ delegate.setSoTimeout(timeout);
+ }
+
+ @Override
+ public void setTcpNoDelay(boolean on) throws SocketException {
+ delegate.setTcpNoDelay(on);
+ }
+
+ @Override
+ public void setTrafficClass(int value) throws SocketException {
+ delegate.setTrafficClass(value);
+ }
+
+ @Override
+ public void shutdownInput() throws IOException {
+ delegate.shutdownInput();
+ }
+
+ @Override
+ public void shutdownOutput() throws IOException {
+ delegate.shutdownOutput();
+ }
+
+ @Override
+ public String toString() {
+ return delegate.toString();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return delegate.equals(o);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/main/java/de/pixart/messenger/services/UpdateService.java b/src/main/java/de/pixart/messenger/services/UpdateService.java
index 64347bd5a..27b40e986 100644
--- a/src/main/java/de/pixart/messenger/services/UpdateService.java
+++ b/src/main/java/de/pixart/messenger/services/UpdateService.java
@@ -15,13 +15,18 @@ import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
import de.pixart.messenger.BuildConfig;
import de.pixart.messenger.Config;
import de.pixart.messenger.R;
+import de.pixart.messenger.http.NoSSLv3SocketFactory;
import de.pixart.messenger.ui.UpdaterActivity;
import me.drakeet.support.toast.ToastCompat;
@@ -32,6 +37,7 @@ public class UpdateService extends AsyncTask<String, Object, UpdateService.Wrapp
private Context context;
private String store;
private NotificationService getNotificationService;
+
public UpdateService() {
}
@@ -52,9 +58,19 @@ public class UpdateService extends AsyncTask<String, Object, UpdateService.Wrapp
if (params[0].equals("true")) {
showNoUpdateToast = true;
}
-
+ SSLContext sslcontext = null;
+ SSLSocketFactory NoSSLv3Factory = null;
+ try {
+ sslcontext = SSLContext.getInstance("TLSv1");
+ if (sslcontext != null) {
+ sslcontext.init(null, null, null);
+ NoSSLv3Factory = new NoSSLv3SocketFactory(sslcontext.getSocketFactory());
+ }
+ } catch (NoSuchAlgorithmException | KeyManagementException e) {
+ e.printStackTrace();
+ }
+ HttpsURLConnection.setDefaultSSLSocketFactory(NoSSLv3Factory);
HttpsURLConnection connection = null;
-
try {
URL url = new URL(Config.UPDATE_URL);
if (mUseTor) {
@@ -163,7 +179,7 @@ public class UpdateService extends AsyncTask<String, Object, UpdateService.Wrapp
String[] remoteV = null;
String[] installedV = null;
try {
- installedV = installedVersion.split(" ");
+ installedV = installedVersion.split("-");
Log.d(Config.LOGTAG, "AppUpdater: Version installed: " + installedV[0]);
installed = installedV[0].split("\\.");
} catch (Exception e) {
@@ -172,7 +188,7 @@ public class UpdateService extends AsyncTask<String, Object, UpdateService.Wrapp
try {
remoteV = remoteVersion.split(" ");
if (installedV != null && installedV.length > 1) {
- if (installedV[1] != null) {
+ if (installedV[1] != null && installedV[1].toLowerCase().contains("beta")) {
remoteV[0] = remoteV[0] + ".1";
}
}
diff --git a/src/main/java/de/pixart/messenger/ui/UpdaterActivity.java b/src/main/java/de/pixart/messenger/ui/UpdaterActivity.java
index 6cc3571b5..f3b233f20 100644
--- a/src/main/java/de/pixart/messenger/ui/UpdaterActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/UpdaterActivity.java
@@ -25,12 +25,18 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.net.HttpURLConnection;
import java.net.URL;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
import java.util.List;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+
import de.pixart.messenger.Config;
import de.pixart.messenger.R;
+import de.pixart.messenger.http.NoSSLv3SocketFactory;
import de.pixart.messenger.persistance.FileBackend;
import de.pixart.messenger.services.XmppConnectionService;
import de.pixart.messenger.utils.WakeLockHelper;
@@ -284,7 +290,7 @@ public class UpdaterActivity extends XmppActivity {
}
private class DownloadTask extends AsyncTask<String, Integer, String> {
-
+ XmppActivity activity;
File dir = new File(FileBackend.getAppUpdateDirectory());
File file = new File(dir, FileName);
XmppConnectionService xmppConnectionService;
@@ -325,7 +331,19 @@ public class UpdaterActivity extends XmppActivity {
protected String doInBackground(String... sUrl) {
InputStream is = null;
OutputStream os = null;
- HttpURLConnection connection = null;
+ SSLContext sslcontext = null;
+ SSLSocketFactory NoSSLv3Factory = null;
+ try {
+ sslcontext = SSLContext.getInstance("TLSv1");
+ if (sslcontext != null) {
+ sslcontext.init(null, null, null);
+ NoSSLv3Factory = new NoSSLv3SocketFactory(sslcontext.getSocketFactory());
+ }
+ } catch (NoSuchAlgorithmException | KeyManagementException e) {
+ e.printStackTrace();
+ }
+ HttpsURLConnection.setDefaultSSLSocketFactory(NoSSLv3Factory);
+ HttpsURLConnection connection = null;
try {
Log.d(Config.LOGTAG, "AppUpdater: save file to " + file.toString());
Log.d(Config.LOGTAG, "AppUpdater: download update from url: " + sUrl[0] + " to file name: " + file.toString());
@@ -333,15 +351,18 @@ public class UpdaterActivity extends XmppActivity {
URL url = new URL(sUrl[0]);
if (mUseTor) {
- connection = (HttpURLConnection) url.openConnection(getProxy());
+ connection = (HttpsURLConnection) url.openConnection(getProxy());
} else {
- connection = (HttpURLConnection) url.openConnection();
+ connection = (HttpsURLConnection) url.openConnection();
}
+ connection.setConnectTimeout(Config.SOCKET_TIMEOUT * 1000);
+ connection.setReadTimeout(Config.SOCKET_TIMEOUT * 1000);
+ connection.setRequestProperty("User-Agent", context.getString(R.string.app_name));
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
- if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
+ if (connection.getResponseCode() != HttpsURLConnection.HTTP_OK) {
ToastCompat.makeText(getApplicationContext(), getText(R.string.failed), Toast.LENGTH_LONG).show();
return connection.getResponseCode() + ": " + connection.getResponseMessage();
}
@@ -355,7 +376,7 @@ public class UpdaterActivity extends XmppActivity {
if (parentDirectory.mkdirs()) {
Log.d(Config.LOGTAG, "created " + parentDirectory.getAbsolutePath());
}
-
+
// download the file
is = connection.getInputStream();
os = new FileOutputStream(file);