mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-31 07:44:24 +02:00
Bangle.js: Add support for insecure TLS and HTTP requests
This commit is contained in:
@@ -121,6 +121,7 @@
|
||||
android:fullBackupContent="false"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:requestLegacyExternalStorage="true"
|
||||
android:theme="@style/GadgetbridgeTheme"
|
||||
|
||||
+42
-7
@@ -157,6 +157,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.LimitedQueue;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.VolleyUtils;
|
||||
|
||||
public class BangleJSDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(BangleJSDeviceSupport.class);
|
||||
@@ -190,6 +191,7 @@ public class BangleJSDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
|
||||
// used to make HTTP requests and handle responses
|
||||
private RequestQueue requestQueue = null;
|
||||
private RequestQueue insecureRequestQueue = null;
|
||||
|
||||
/// Maximum amount of characters to store in receiveHistory
|
||||
public static final int MAX_RECEIVE_HISTORY_CHARS = 100000;
|
||||
@@ -240,13 +242,32 @@ public class BangleJSDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
if (requestQueue != null) {
|
||||
requestQueue.stop();
|
||||
}
|
||||
if (insecureRequestQueue != null) {
|
||||
insecureRequestQueue.stop();
|
||||
}
|
||||
}
|
||||
|
||||
private RequestQueue getRequestQueue() {
|
||||
if (requestQueue == null) {
|
||||
requestQueue = Volley.newRequestQueue(getContext());
|
||||
private RequestQueue getRequestQueue(final boolean insecure) {
|
||||
if (insecure) {
|
||||
if (insecureRequestQueue == null) {
|
||||
try {
|
||||
insecureRequestQueue = Volley.newRequestQueue(
|
||||
getContext(),
|
||||
VolleyUtils.createInsecureHurlStack()
|
||||
);
|
||||
} catch (final Exception e) {
|
||||
LOG.error("Failed to initialized insecure request queue", e);
|
||||
// fallback to secure one
|
||||
return getRequestQueue(false);
|
||||
}
|
||||
}
|
||||
return insecureRequestQueue;
|
||||
} else {
|
||||
if (requestQueue == null) {
|
||||
requestQueue = Volley.newRequestQueue(getContext());
|
||||
}
|
||||
return requestQueue;
|
||||
}
|
||||
return requestQueue;
|
||||
}
|
||||
|
||||
private void addReceiveHistory(String s) {
|
||||
@@ -886,7 +907,7 @@ public class BangleJSDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
}
|
||||
final String id = _id;
|
||||
|
||||
if (! BuildConfig.INTERNET_ACCESS) {
|
||||
if (!BuildConfig.INTERNET_ACCESS) {
|
||||
uartTxJSONError("http", "Internet access not enabled, check Gadgetbridge Device Settings", id);
|
||||
return;
|
||||
}
|
||||
@@ -898,7 +919,7 @@ public class BangleJSDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
}
|
||||
|
||||
String url = json.getString("url");
|
||||
|
||||
final boolean insecure = json.optBoolean("insecure", false);
|
||||
int method = Request.Method.GET;
|
||||
if (json.has("method")) {
|
||||
String m = json.getString("method").toLowerCase(Locale.US);
|
||||
@@ -1008,7 +1029,7 @@ public class BangleJSDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
int timeout = json.getInt("timeout");
|
||||
stringRequest.setRetryPolicy(new DefaultRetryPolicy(timeout, 0, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
|
||||
}
|
||||
RequestQueue queue = getRequestQueue();
|
||||
RequestQueue queue = getRequestQueue(insecure);
|
||||
queue.add(stringRequest);
|
||||
}
|
||||
|
||||
@@ -2403,4 +2424,18 @@ public class BangleJSDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
LOG.info("JSONException: " + e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTestNewFunction() {
|
||||
try {
|
||||
final JSONObject json = new JSONObject();
|
||||
//json.put("t", "http");
|
||||
//json.put("url", "https://example.com/");
|
||||
//json.put("url", "https://192.168.1.2:4443");
|
||||
//json.put("insecure", true);
|
||||
//handleHttp(json);
|
||||
} catch (final Exception e) {
|
||||
LOG.error("Failed to test new function", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/* Copyright (C) 2025 José Rebelo
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
Gadgetbridge is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Gadgetbridge is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.util;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
|
||||
import com.android.volley.toolbox.HurlStack;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
public class VolleyUtils {
|
||||
public static HurlStack createInsecureHurlStack() throws Exception {
|
||||
// Trust all certificates
|
||||
final TrustManager[] trustAllCerts = new TrustManager[]{new InsecureTrustManager()};
|
||||
final SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
sslContext.init(null, trustAllCerts, new SecureRandom());
|
||||
|
||||
return new HurlStack(null, sslContext.getSocketFactory()) {
|
||||
@Override
|
||||
protected HttpURLConnection createConnection(final URL url) throws IOException {
|
||||
final HttpURLConnection httpURLConnection = super.createConnection(url);
|
||||
if (httpURLConnection instanceof HttpsURLConnection httpsURLConnection) {
|
||||
// Trust all hostnames
|
||||
httpsURLConnection.setHostnameVerifier((hostname, session) -> true);
|
||||
}
|
||||
return httpURLConnection;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@SuppressLint("CustomX509TrustManager")
|
||||
public static class InsecureTrustManager implements X509TrustManager {
|
||||
@SuppressLint("TrustAllX509TrustManager")
|
||||
@Override
|
||||
public void checkClientTrusted(final X509Certificate[] chain, final String authType) {
|
||||
}
|
||||
|
||||
@SuppressLint("TrustAllX509TrustManager")
|
||||
@Override
|
||||
public void checkServerTrusted(final X509Certificate[] chain, final String authType) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return new X509Certificate[]{};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config>
|
||||
<base-config cleartextTrafficPermitted="true">
|
||||
<trust-anchors>
|
||||
<certificates src="system" />
|
||||
<certificates src="user" />
|
||||
</trust-anchors>
|
||||
</base-config>
|
||||
</network-security-config>
|
||||
Reference in New Issue
Block a user