Skip to content

Commit

Permalink
Fix SSL issue, see #25
Browse files Browse the repository at this point in the history
  • Loading branch information
Blaumeise03 committed Sep 30, 2024
1 parent 8e159a0 commit 342eade
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 14 deletions.
1 change: 1 addition & 0 deletions assets/enableSSLFix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
false
61 changes: 50 additions & 11 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:io';

import 'package:firebase_analytics/firebase_analytics.dart';
Expand All @@ -22,26 +23,64 @@ import 'package:sweet/util/platform_helper.dart';
import 'repository/item_repository.dart';
import 'themed_app.dart';

import 'package:flutter/foundation.dart' show kDebugMode;

import 'util/crash_reporting.dart';
import 'util/http_client.dart';
import 'util/http_client.dart' as http_client;
late File? file;


Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await initializeFirebase();
final shouldEnableLogging = await PlatformHelper.shouldEnableLogging();
if (enableFileLogging || shouldEnableLogging) {
file = await PlatformHelper.logFile();
print("Logging output goes to ${file!.path}");
file!.writeAsStringSync(
"[${DateTime.now()}] Startup\n", mode: FileMode.write);

runApp(
buildRepositories(
child: buildBlocProviders(
child: ThemedApp(),
overridePrint(() async {
WidgetsFlutterBinding.ensureInitialized();
await initializeFirebase();
final shouldEnableSSLFix = await PlatformHelper.shouldEnableSSLFix();
http_client.enableSSLFix = shouldEnableSSLFix;
runApp(
buildRepositories(
child: buildBlocProviders(
child: ThemedApp(),
),
),
);
})();
} else {
WidgetsFlutterBinding.ensureInitialized();
await initializeFirebase();
final shouldEnableSSLFix = await PlatformHelper.shouldEnableSSLFix();
http_client.enableSSLFix = shouldEnableSSLFix;
file = null;
runApp(
buildRepositories(
child: buildBlocProviders(
child: ThemedApp(),
),
),
),
);
);
}
}

void Function() overridePrint(Future<void> Function() mainFn) => () {
var spec = ZoneSpecification(
print: (Zone self, ZoneDelegate parent, Zone zone, String line) {
if (file != null) {
file!.writeAsStringSync(
"[${DateTime.now()}] $line\n", mode: FileMode.append);
}
parent.print(zone, line);
}
);
return Zone.current.fork(specification: spec).run(mainFn);
};

MultiRepositoryProvider buildRepositories({required Widget child}) {
final client = createHttpClient();
final client = http_client.createHttpClient();

return MultiRepositoryProvider(
providers: [
Expand Down
5 changes: 3 additions & 2 deletions lib/repository/item_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import 'package:sweet/model/implant/implant_loadout_definition.dart';
import 'package:sweet/model/implant/slot_type.dart';
import 'package:sweet/model/nihilus_space_modifier.dart';
import 'package:sweet/model/ship/ship_fitting_slot_module.dart';
import 'package:sweet/util/http_client.dart';

import '../extensions/item_meta_extension.dart';

Expand Down Expand Up @@ -110,7 +111,7 @@ class ItemRepository {

if (checkEtag) {
final dbUrl = Uri.parse(kDBUrl);
final response = await http.Client().send(http.Request('HEAD', dbUrl));
final response = await createHttpClient().send(http.Request('HEAD', dbUrl));
final dbEtag = response.headers['etag'];

if (response.statusCode >= 400) {
Expand Down Expand Up @@ -166,7 +167,7 @@ class ItemRepository {
final dbTestUrl = Uri.parse(kDBUrl);
print('Downloading DB from $dbTestUrl');

var response = await http.Client().send(http.Request('GET', dbTestUrl));
var response = await createHttpClient().send(http.Request('GET', dbTestUrl));
var totalBytes = response.contentLength;
var downloadedBytes = 0;
var bytes = <int>[];
Expand Down
3 changes: 3 additions & 0 deletions lib/util/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,6 @@ const kManUpUrl = 'https://sweet.silkypants.dev/manup.json';
const kDBUrl = 'https://sweet.silkypants.dev/game_data/echoes_db.tbz';

const kNihilusCapAdjustmentModifierTypeCode = '/Nihilus/ChargeDe/';

// Override to enable logging no matter if the enableLog file exists
const bool enableFileLogging = false;
52 changes: 51 additions & 1 deletion lib/util/http_client.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import 'dart:convert';
import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:http/http.dart';
import 'package:http/io_client.dart';

bool enableSSLFix = false;

Client createHttpClient({bool enableProxy = false}) {
if (kDebugMode && enableProxy) {
// Make sure to replace <YOUR_LOCAL_IP> with
Expand All @@ -25,8 +28,55 @@ Client createHttpClient({bool enableProxy = false}) {
httpClient.badCertificateCallback =
((X509Certificate cert, String host, int port) => Platform.isAndroid);

return IOClient(httpClient);
} else if (enableSSLFix) {
print("[HTTP] Using SSL fix");
final SecurityContext context = SecurityContext(withTrustedRoots: true);
var httpClient = HttpClient(context: context);
httpClient.badCertificateCallback = checkBadCertificate;
return IOClient(httpClient);
}

return Client();
}
}

bool checkBadCertificate(X509Certificate cert, String host, int port) {
print("[HTTP] Checking certificate for $host");
print(" Subject: ${cert.subject}");
print(" Issuer: ${cert.issuer}");
print(" SHA1: ${cert.sha1}");
// print(" Valid from: ${cert.startValidity}");
// print(" Valid to: ${cert.endValidity}");

if (host != 'sweet.silkypants.dev') {
print("[HTTP] Rejecting certificate for $host");
return false;
}
if (cert.sha1.length != certSha1.length) {
print("[HTTP] Rejecting certificate for $host: SHA1 length mismatch");
return false;
}
for (var i = 0; i < cert.sha1.length; i++) {
if (cert.sha1[i] != certSha1[i]) {
print("[HTTP] Rejecting certificate for $host: SHA1 mismatch at $i");
return false;
}
}
print("[HTTP] Warning: Allowing untrusted certificate ${cert.subject} from ${cert.issuer} for $host");
return true;
}
// The certificate for sweet.silkypants.dev seems to be signed by different
// versions of the Amazon Root CA 1. The normal version works, but on some
// clients the cross-signed version is used. This is the SHA1 of the Amazon
// root certificate that is signed by the Starfield root certificate. This
// certificate is being rejected by the default client.
// https://crt.sh/?id=11265962
// ToDo: Figure out why this is happening and fix it, see https://github.com/sweet-org/sweet/issues/25

final certSha1 = Uint8List.fromList([
6, 178, 89, 39,
196, 42, 114, 22,
49, 193, 239, 217,
67, 30, 100, 143,
166, 46, 30, 57
]);
38 changes: 38 additions & 0 deletions lib/util/platform_helper.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:io';
import 'dart:ui';

import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';

import 'package:path/path.dart';
Expand Down Expand Up @@ -39,4 +40,41 @@ class PlatformHelper {
final dir = await _dbDirectory();
return File(join(dir.path, 'echoes.db'));
}

static Future<File> logFile() async {
final dir = await _dbDirectory();
return File(join(dir.path, 'log.txt'));
}

static Future<bool> shouldEnableLogging() async {
final dir = await _dbDirectory();
final file = File(join(dir.path, 'enableLog'));
if (await file.exists()) {
return true;
}
return false;
}

static Future<bool> shouldEnableSSLFix() async {
final dir = await _dbDirectory();
final file = File(join(dir.path, 'enableSSLFix'));
if (await file.exists()) {
print("SSL fix should be enabled, file in support dir found");
return true;
} else {
print("SSL fix: file not found in support dir");
}
try {
final data = await rootBundle.loadString('assets/enableSSLFix');
if (data.toLowerCase().startsWith("true")) {
print("SSL fix should be enabled because of assets/enableSSLFix");
return true;
}
print("SSL fix: assets/enableSSLFix found but not set to true");
} catch (e) {
print("SSL fix: assets/enableSSLFix not found: $e");
}
print("SSL fix should not be enabled");
return false;
}
}
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ flutter:
# To add assets to your application, add an assets section, like this:
assets:
- assets/fitting-patterns.json
- assets/enableSSLFix
- assets/svg/logo-transparent.svg
- assets/icons/
- assets/branding/
Expand Down

0 comments on commit 342eade

Please sign in to comment.