安卓签名证书

This commit is contained in:
wanghongenpin
2023-11-22 16:20:25 +08:00
parent 2f2e5b405b
commit 08decff829
12 changed files with 216 additions and 101 deletions

View File

@@ -92,7 +92,6 @@ class Network {
}
String? host = hostAndPort?.host;
host ??= TLS.getDomain(data);
//ssl自签证书
var certificate = await CertificateManager.getCertificateContext(host!);
//服务端等待客户端ssl握手

View File

@@ -1,6 +1,32 @@
/*
* Copyright 2023 WangHongEn
*
* 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 'dart:typed_data';
class TLS {
///判断是否是TLS Client Hello
static bool isTLSClientHello(Uint8List data) {
if (data.length < 43) return false;
if (data[0] != 0x16 /* handshake */) return false;
if (data[1] != 0x03 || data[2] < 0x00 || data[2] > 0x03) return false;
if (data[5] != 0x01 /* client_hello */) return false;
if (data[9] != 0x03 || data[10] < 0x00 || data[10] > 0x03) return false;
return true;
}
///从TLS Client Hello 解析域名
static String? getDomain(Uint8List data) {
try {

View File

@@ -321,7 +321,7 @@ class ScriptList extends StatefulWidget {
}
class _ScriptListState extends State<ScriptList> {
Map<int, bool> selected = {};
int selected = -1;
@override
Widget build(BuildContext context) {
@@ -354,47 +354,9 @@ class _ScriptListState extends State<ScriptList> {
}
});
},
onSecondaryTapDown: (details) {
showContextMenu(context, details.globalPosition, items: [
PopupMenuItem(
height: 35,
child: const Text("编辑"),
onTap: () async {
String script = await (await ScriptManager.instance).getScript(list[index]);
if (!context.mounted) {
return;
}
showDialog(
barrierDismissible: false,
context: context,
builder: (_) => ScriptEdit(scriptItem: list[index], script: script)).then((value) {
if (value != null) {
setState(() {});
}
});
}),
PopupMenuItem(height: 35, child: const Text("导出"), onTap: () => export(list[index])),
PopupMenuItem(
height: 35,
child: list[index].enabled ? const Text("禁用") : const Text("启用"),
onTap: () {
list[index].enabled = !list[index].enabled;
setState(() {});
}),
const PopupMenuDivider(),
PopupMenuItem(
height: 35,
child: const Text("删除"),
onTap: () async {
(await ScriptManager.instance).removeScript(index);
_refreshScript();
setState(() {});
if (context.mounted) FlutterToastr.show('删除成功', context);
}),
]);
},
onSecondaryTapDown: (details) => showMenus(details, index),
child: Container(
color: selected[index] == true
color: selected == index
? primaryColor.withOpacity(0.8)
: index.isEven
? Colors.grey.withOpacity(0.1)
@@ -421,6 +383,52 @@ class _ScriptListState extends State<ScriptList> {
});
}
//点击菜单
showMenus(TapDownDetails details, int index) {
setState(() {
selected = index;
});
showContextMenu(context, details.globalPosition, items: [
PopupMenuItem(
height: 35,
child: const Text("编辑"),
onTap: () async {
String script = await (await ScriptManager.instance).getScript(widget.scripts[index]);
if (!context.mounted) {
return;
}
showDialog(
barrierDismissible: false,
context: context,
builder: (_) => ScriptEdit(scriptItem: widget.scripts[index], script: script)).then((value) {
if (value != null) {
setState(() {});
}
});
}),
PopupMenuItem(height: 35, child: const Text("导出"), onTap: () => export(widget.scripts[index])),
PopupMenuItem(
height: 35,
child: widget.scripts[index].enabled ? const Text("禁用") : const Text("启用"),
onTap: () {
widget.scripts[index].enabled = !widget.scripts[index].enabled;
}),
const PopupMenuDivider(),
PopupMenuItem(
height: 35,
child: const Text("删除"),
onTap: () async {
(await ScriptManager.instance).removeScript(index);
_refreshScript();
if (context.mounted) FlutterToastr.show('删除成功', context);
}),
]).then((value) {
setState(() {
selected = -1;
});
});
}
//导出js
export(ScriptItem item) async {
//

View File

@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:network_proxy/main.dart';
class ThemeSetting extends StatelessWidget {
const ThemeSetting({Key? key}) : super(key: key);
const ThemeSetting({super.key});
@override
Widget build(BuildContext context) {

View File

@@ -12,7 +12,8 @@ class SocketLaunch extends StatefulWidget {
final bool startup;
final Function? onStart;
final Function? onStop;
final bool serverLaunch;
final bool serverLaunch; //是否启动代理服务器
const SocketLaunch(
{super.key,
@@ -30,7 +31,7 @@ class SocketLaunch extends StatefulWidget {
}
class _SocketLaunchState extends State<SocketLaunch> with WindowListener, WidgetsBindingObserver {
bool started = false;
static bool started = false;
@override
void initState() {

View File

@@ -4,6 +4,7 @@ import 'package:easy_permission/easy_permission.dart';
import 'package:flutter/material.dart';
import 'package:flutter_barcode_scanner/flutter_barcode_scanner.dart';
import 'package:flutter_toastr/flutter_toastr.dart';
import 'package:network_proxy/native/vpn.dart';
import 'package:network_proxy/network/bin/server.dart';
import 'package:network_proxy/network/http_client.dart';
import 'package:network_proxy/network/util/host_filter.dart';
@@ -211,7 +212,7 @@ class MoreEnum extends StatelessWidget {
hostname: response.headers.get("hostname"));
if (context.mounted && Navigator.canPop(context)) {
FlutterToastr.show("连接成功${proxyServer.isRunning ? '' : ',手机需要开启抓包才可以抓取请求哦'}", context, duration: 3);
FlutterToastr.show("连接成功${Vpn.isVpnStarted ? '' : ',手机需要开启抓包才可以抓取请求哦'}", context, duration: 3);
Navigator.pop(context);
}
}

View File

@@ -117,7 +117,7 @@ class _MobileScriptState extends State<MobileScript> {
}
try {
var json = jsonDecode(await file.readAsString());
var json = jsonDecode(utf8.decode(await file.readAsBytes()));
var scriptItem = ScriptItem.fromJson(json);
(await ScriptManager.instance).addScript(scriptItem, json['script']);
_refreshScript();
@@ -148,7 +148,7 @@ class ScriptEdit extends StatefulWidget {
final ScriptItem? scriptItem;
final String? script;
const ScriptEdit({Key? key, this.scriptItem, this.script}) : super(key: key);
const ScriptEdit({super.key, this.scriptItem, this.script});
@override
State<StatefulWidget> createState() => _ScriptEditState();
@@ -230,8 +230,7 @@ class _ScriptEditState extends State<ScriptEdit> {
CodeTheme(
data: CodeThemeData(styles: monokaiSublimeTheme),
child: SingleChildScrollView(
child: CodeField(
textStyle: const TextStyle(fontSize: 14), controller: script)))
child: CodeField(textStyle: const TextStyle(fontSize: 14), controller: script)))
],
))));
}
@@ -271,14 +270,19 @@ class ScriptList extends StatefulWidget {
}
class _ScriptListState extends State<ScriptList> {
int selected = -1;
@override
Widget build(BuildContext context) {
return Column(children: rows(widget.scripts));
}
List<Widget> rows(List<ScriptItem> list) {
var primaryColor = Theme.of(context).primaryColor;
return List.generate(list.length, (index) {
return InkWell(
splashColor: primaryColor.withOpacity(0.3),
onDoubleTap: () async {
String script = await (await ScriptManager.instance).getScript(list[index]);
if (!context.mounted) {
@@ -292,47 +296,13 @@ class _ScriptListState extends State<ScriptList> {
}
});
},
onTapDown: (details) {
showContextMenu(context, details.globalPosition, items: [
PopupMenuItem(
height: 35,
child: const Text("编辑"),
onTap: () async {
String script = await (await ScriptManager.instance).getScript(list[index]);
if (!context.mounted) {
return;
}
Navigator.of(context)
.push(MaterialPageRoute(
builder: (context) => ScriptEdit(scriptItem: list[index], script: script)))
.then((value) {
if (value != null) {
setState(() {});
}
});
}),
PopupMenuItem(height: 35, child: const Text("分享"), onTap: () => export(list[index])),
PopupMenuItem(
height: 35,
child: list[index].enabled ? const Text("禁用") : const Text("启用"),
onTap: () {
list[index].enabled = !list[index].enabled;
setState(() {});
}),
const PopupMenuDivider(),
PopupMenuItem(
height: 35,
child: const Text("删除"),
onTap: () async {
(await ScriptManager.instance).removeScript(index);
_refreshScript();
setState(() {});
if (context.mounted) FlutterToastr.show('删除成功', context);
}),
]);
},
onTapDown: (details) => showMenus(details, index),
child: Container(
color: index.isEven ? Colors.grey.withOpacity(0.1) : null,
color: selected == index
? primaryColor.withOpacity(0.8)
: index.isEven
? Colors.grey.withOpacity(0.1)
: null,
height: 45,
padding: const EdgeInsets.all(5),
child: Row(
@@ -358,6 +328,52 @@ class _ScriptListState extends State<ScriptList> {
});
}
//点击菜单
showMenus(TapDownDetails details, int index) {
setState(() {
selected = index;
});
showContextMenu(context, details.globalPosition, items: [
PopupMenuItem(
height: 35,
child: const Text("编辑"),
onTap: () async {
String script = await (await ScriptManager.instance).getScript(widget.scripts[index]);
if (!context.mounted) {
return;
}
Navigator.of(context)
.push(MaterialPageRoute(
builder: (context) => ScriptEdit(scriptItem: widget.scripts[index], script: script)))
.then((value) {
if (value != null) {
setState(() {});
}
});
}),
PopupMenuItem(height: 35, child: const Text("分享"), onTap: () => export(widget.scripts[index])),
PopupMenuItem(
height: 35,
child: widget.scripts[index].enabled ? const Text("禁用") : const Text("启用"),
onTap: () {
widget.scripts[index].enabled = !widget.scripts[index].enabled;
}),
const PopupMenuDivider(),
PopupMenuItem(
height: 35,
child: const Text("删除"),
onTap: () async {
(await ScriptManager.instance).removeScript(index);
_refreshScript();
if (context.mounted) FlutterToastr.show('删除成功', context);
}),
]).then((value) {
setState(() {
selected = -1;
});
});
}
//导出js
export(ScriptItem item) async {
//