Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Initial Certificate Override Support #546

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application android:name="${applicationName}" android:label="Finamp" android:icon="@mipmap/ic_launcher" android:usesCleartextTraffic="true" android:requestLegacyExternalStorage="true" android:allowBackup="false" android:fullBackupContent="false">
<application android:name="${applicationName}" android:label="Finamp" android:icon="@mipmap/ic_launcher" android:usesCleartextTraffic="true" android:requestLegacyExternalStorage="true" android:allowBackup="false" android:fullBackupContent="false" android:networkSecurityConfig="@xml/network_security_config">
<activity android:name="com.ryanheise.audioservice.AudioServiceActivity" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize" android:exported="true">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
Expand Down
9 changes: 9 additions & 0 deletions android/app/src/main/res/xml/network_security_config.xml
Original file line number Diff line number Diff line change
@@ -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>
18 changes: 17 additions & 1 deletion lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:io';
import 'dart:isolate';
import 'dart:ui';

Expand Down Expand Up @@ -51,7 +52,22 @@ import 'services/music_player_background_task.dart';
import 'services/theme_mode_helper.dart';
import 'setup_logging.dart';

// https://stackoverflow.com/questions/68450768/flutter-chopper-allow-self-signed-certificate-for-use
class MyHttpOverrides extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext? context) {
return super.createHttpClient(context)
..badCertificateCallback = isCertificateOverridden;
}

bool isCertificateOverridden(X509Certificate cert, String host, int port) {
return FinampSettingsHelper.hasCertificateOverride(host, port, cert.sha1);
}
}

void main() async {

HttpOverrides.global = MyHttpOverrides();
// If the app has failed, this is set to true. If true, we don't attempt to run the main app since the error app has started.
bool hasFailed = false;
try {
Expand Down Expand Up @@ -493,4 +509,4 @@ class _DummyCallback {
IsolateNameServer.lookupPortByName('downloader_send_port');
send!.send([id, status, progress]);
}
}
}
9 changes: 8 additions & 1 deletion lib/models/finamp_models.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'dart:collection';
import 'dart:io';

import 'package:flutter/material.dart';
Expand Down Expand Up @@ -88,6 +89,7 @@ class FinampSettings {
this.tabOrder = _tabOrder,
this.hasCompletedBlurhashImageMigration = true,
this.hasCompletedBlurhashImageMigrationIdFix = true,
required this.overriddenCertificates,
});

@HiveField(0)
Expand Down Expand Up @@ -180,6 +182,9 @@ class FinampSettings {
@HiveField(24, defaultValue: false)
bool hasCompletedBlurhashImageMigrationIdFix;

@HiveField(25, defaultValue: {})
Map<String, Set<String>> overriddenCertificates;

static Future<FinampSettings> create() async {
final internalSongDir = await getInternalSongDir();
final downloadLocation = DownloadLocation.create(
Expand All @@ -188,6 +193,7 @@ class FinampSettings {
useHumanReadableNames: false,
deletable: false,
);
final overriddenCertificates = {};
return FinampSettings(
downloadLocations: [],
// Create a map of TabContentType from TabContentType's values.
Expand All @@ -199,6 +205,7 @@ class FinampSettings {
downloadLocationsMap: {downloadLocation.id: downloadLocation},
tabSortBy: {},
tabSortOrder: {},
overriddenCertificates: {},
);
}

Expand Down Expand Up @@ -606,4 +613,4 @@ class OfflineListen {
// The MusicBrainz ID of the track, if available.
@HiveField(6)
String? trackMbid;
}
}
10 changes: 8 additions & 2 deletions lib/models/finamp_models.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 50 additions & 0 deletions lib/services/finamp_settings_helper.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import 'dart:collection';
import 'dart:convert';

import 'package:convert/convert.dart';
import 'package:flutter/foundation.dart';
import 'package:hive_flutter/hive_flutter.dart';

Expand Down Expand Up @@ -224,4 +228,50 @@ class FinampSettingsHelper {
),
);
}

static void addCertificateOverride(
String host, int port, Uint8List thumbprint) {
FinampSettings finampSettingsTemp = finampSettings;
String thumbprintHex = hex.encode(thumbprint);
if (!finampSettingsTemp.overriddenCertificates.containsKey("$host:$port")) {
finampSettingsTemp.overriddenCertificates.addAll({
"$host:$port": {thumbprintHex}
});
} else {
finampSettingsTemp.overriddenCertificates["$host:$port"]
?.add(thumbprintHex);
}
Hive.box<FinampSettings>("FinampSettings")
.put("FinampSettings", finampSettingsTemp);
}

static void deleteCertificateOverride(
String host, int port, Uint8List thumbprint) {
FinampSettings finampSettingsTemp = finampSettings;
String thumbprintHex = hex.encode(thumbprint);
finampSettingsTemp.overriddenCertificates["$host:$port"]
?.remove(thumbprintHex);
Hive.box<FinampSettings>("FinampSettings")
.put("FinampSettings", finampSettingsTemp);
}

static bool hasCertificateOverride(
String host, int port, Uint8List thumbprint) {
FinampSettings finampSettingsTemp = finampSettings;
String thumbprintHex = hex.encode(thumbprint);
if (!finampSettingsTemp.overriddenCertificates.containsKey("$host:port")) {
return false;
} else if (!finampSettingsTemp.overriddenCertificates["$host:port"]!
.contains(thumbprintHex)) {
return false;
}
return true;
}

static void resetCertificateOverrides() {
FinampSettings finampSettingsTemp = finampSettings;
finampSettingsTemp.overriddenCertificates.clear();
Hive.box<FinampSettings>("FinampSettings")
.put("FinampSettings", finampSettingsTemp);
}
}
4 changes: 2 additions & 2 deletions lib/services/jellyfin_api.chopper.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 9 additions & 9 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ packages:
source: hosted
version: "1.18.0"
convert:
dependency: transitive
dependency: "direct main"
description:
name: convert
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
Expand Down Expand Up @@ -530,10 +530,10 @@ packages:
dependency: "direct main"
description:
name: intl
sha256: a3715e3bc90294e971cb7dc063fbf3cd9ee0ebf8604ffeafabd9e6f16abbdbe6
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
url: "https://pub.dev"
source: hosted
version: "0.18.0"
version: "0.18.1"
io:
dependency: transitive
description:
Expand Down Expand Up @@ -619,18 +619,18 @@ packages:
dependency: transitive
description:
name: matcher
sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
url: "https://pub.dev"
source: hosted
version: "0.12.15"
version: "0.12.16"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
url: "https://pub.dev"
source: hosted
version: "0.2.0"
version: "0.5.0"
meta:
dependency: transitive
description:
Expand Down Expand Up @@ -952,10 +952,10 @@ packages:
dependency: transitive
description:
name: source_span
sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.dev"
source: hosted
version: "1.9.1"
version: "1.10.0"
sqflite:
dependency: transitive
description:
Expand Down
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ dependencies:
url: https://github.com/lamarios/locale_names.git
ref: cea057c220f4ee7e09e8f1fc7036110245770948
mini_music_visualizer: ^1.0.2
convert: ^3.1.1

dev_dependencies:
flutter_test:
Expand Down