This commit is contained in:
arm64v8a 2023-04-04 14:28:53 +09:00
parent e008a8ac68
commit 93bcdc830b
14 changed files with 111 additions and 96 deletions

View File

@ -94,6 +94,7 @@ object Key {
const val SERVER_CONFIG = "serverConfig"
const val SERVER_SECURITY_CATEGORY = "serverSecurityCategory"
const val SERVER_TLS_MODIFY_CATEGORY = "serverTlsModifyCategory"
const val SERVER_WS_CATEGORY = "serverWsCategory"
const val SERVER_SS_CATEGORY = "serverSsCategory"
const val SERVER_HEADERS = "serverHeaders"
@ -180,6 +181,7 @@ object Action {
const val SERVICE = "io.nekohasekai.sagernet.SERVICE"
const val CLOSE = "io.nekohasekai.sagernet.CLOSE"
const val RELOAD = "io.nekohasekai.sagernet.RELOAD"
// const val SWITCH_WAKE_LOCK = "io.nekohasekai.sagernet.SWITCH_WAKELOCK"
const val RESET_UPSTREAM_CONNECTIONS = "moe.nb4a.RESET_UPSTREAM_CONNECTIONS"
}

View File

@ -98,7 +98,7 @@ fun buildConfig(
val trafficMap = HashMap<String, List<ProxyEntity>>()
val tagMap = HashMap<Long, String>()
val globalOutbounds = ArrayList<Long>()
val globalOutbounds = HashMap<Long, String>()
val selectorNames = ArrayList<String>()
val group = SagerDatabase.groupDao.getById(proxy.groupId)
var optionsToMerge = ""
@ -336,6 +336,13 @@ fun buildConfig(
bypassDNSBeans += proxyEntity.requireBean()
}
if (needGlobal) {
globalOutbounds[proxyEntity.id]?.let {
if (index == 0) chainTagOut = it // single, duplicate chain
return@forEachIndexed
}
}
// last profile set as "proxy"
if (chainId == 0L && index == 0) {
tagOut = TAG_PROXY
@ -346,6 +353,11 @@ fun buildConfig(
tagOut = selectorName(bean.displayName())
}
// now tagOut is determined
if (needGlobal) {
globalOutbounds[proxyEntity.id] = tagOut
}
// chain rules
if (index > 0) {
// chain route/proxy rules
@ -362,13 +374,6 @@ fun buildConfig(
chainTagOut = tagOut
}
if (needGlobal) {
if (globalOutbounds.contains(proxyEntity.id)) {
return@forEachIndexed
}
globalOutbounds.add(proxyEntity.id)
}
// Chain outbound
if (proxyEntity.needExternal()) {
val localPort = mkPort()
@ -706,18 +711,32 @@ fun buildConfig(
if (enableDnsRouting) {
val dnsRuleObj = mutableListOf<DNSRule_DefaultOptions>()
if (uidListDNSRemote.isNotEmpty()) {
if (useFakeDns) dnsRuleObj.add(
DNSRule_DefaultOptions().apply {
user_id = uidListDNSRemote.toHashSet().toList()
server = "dns-fake"
inbound = listOf("tun-in")
}
)
dnsRuleObj.add(
DNSRule_DefaultOptions().apply {
user_id = uidListDNSRemote.toHashSet().toList()
server = if (useFakeDns) "dns-fake" else "dns-remote"
server = "dns-remote"
}
)
}
if (domainListDNSRemote.isNotEmpty()) {
if (useFakeDns) dnsRuleObj.add(
DNSRule_DefaultOptions().apply {
makeSingBoxRule(domainListDNSRemote.toHashSet().toList())
server = "dns-fake"
inbound = listOf("tun-in")
}
)
dnsRuleObj.add(
DNSRule_DefaultOptions().apply {
makeSingBoxRule(domainListDNSRemote.toHashSet().toList())
server = if (useFakeDns) "dns-fake" else "dns-remote"
server = "dns-remote"
}
)
}

View File

@ -114,7 +114,11 @@ fun buildSingBoxOutboundShadowsocksBean(bean: ShadowsocksBean): SingBoxOptions.O
server_port = bean.serverPort
password = bean.password
method = bean.method
udp_over_tcp = bean.sUoT
if (bean.sUoT) {
udp_over_tcp = SingBoxOptions.UDPOverTCPOptions().apply {
enabled = true
}
}
if (bean.plugin.isNotBlank()) {
plugin = bean.plugin.substringBefore(";")
plugin_opts = bean.plugin.substringAfter(";")

View File

@ -563,7 +563,7 @@ fun buildSingBoxOutboundTLS(bean: StandardV2RayBean): OutboundTLSOptions? {
fingerprint = bean.utlsFingerprint
}
}
if (bean.realityPubKey.isNotBlank() && bean.realityShortId.isNotBlank()) {
if (bean.realityPubKey.isNotBlank()) {
reality = OutboundRealityOptions().apply {
enabled = true
public_key = bean.realityPubKey

View File

@ -63,6 +63,7 @@ abstract class StandardV2RaySettingsActivity : ProfileSettingsActivity<StandardV
}
lateinit var securityCategory: PreferenceCategory
lateinit var tlsModifyCategory: PreferenceCategory
lateinit var wsCategory: PreferenceCategory
override fun PreferenceFragmentCompat.createPreferences(
@ -72,6 +73,7 @@ abstract class StandardV2RaySettingsActivity : ProfileSettingsActivity<StandardV
addPreferencesFromResource(R.xml.standard_v2ray_preferences)
pbm.setPreferenceFragment(this)
securityCategory = findPreference(Key.SERVER_SECURITY_CATEGORY)!!
tlsModifyCategory = findPreference(Key.SERVER_TLS_MODIFY_CATEGORY)!!
wsCategory = findPreference(Key.SERVER_WS_CATEGORY)!!
@ -171,6 +173,7 @@ abstract class StandardV2RaySettingsActivity : ProfileSettingsActivity<StandardV
fun updateTle(tle: String) {
val isTLS = tle == "tls"
securityCategory.isVisible = isTLS
tlsModifyCategory.isVisible = isTLS
}
}

View File

@ -82,6 +82,8 @@ public class SingBoxOptions {
public static class Options extends SingBoxOption {
public String $schema;
public LogOptions log;
public DNSOptions dns;
@ -112,6 +114,25 @@ public class SingBoxOptions {
}
public static class DebugOptions extends SingBoxOption {
public Integer gc_percent;
public Integer max_stack;
public Integer max_threads;
public Boolean panic_on_fault;
public String trace_back;
public Long memory_limit;
public Boolean oom_killer;
}
public static class DirectInboundOptions extends SingBoxOption {
// Generate note: nested type ListenOptions
@ -351,6 +372,8 @@ public class SingBoxOptions {
public V2RayAPIOptions v2ray_api;
public DebugOptions debug;
}
public static class HysteriaInboundOptions extends SingBoxOption {
@ -617,6 +640,8 @@ public class SingBoxOptions {
public Long interval;
public Boolean write_to_system;
// Generate note: nested type ServerOptions
public String server;
@ -1108,7 +1133,7 @@ public class SingBoxOptions {
public String network;
public Boolean udp_over_tcp;
public UDPOverTCPOptions udp_over_tcp;
public MultiplexOptions multiplex;
@ -1436,7 +1461,7 @@ public class SingBoxOptions {
public String network;
public Boolean udp_over_tcp;
public UDPOverTCPOptions udp_over_tcp;
}
@ -1955,6 +1980,14 @@ public class SingBoxOptions {
}
public static class UDPOverTCPOptions extends SingBoxOption {
public Boolean enabled;
public Integer version;
}
public static class V2RayAPIOptions extends SingBoxOption {
public String listen;
@ -2001,6 +2034,10 @@ public class SingBoxOptions {
public Map<String, String> headers;
public Long idle_timeout;
public Long ping_timeout;
}
public static class V2RayWebsocketOptions extends SingBoxOption {
@ -2020,6 +2057,12 @@ public class SingBoxOptions {
public String service_name;
public Long idle_timeout;
public Long ping_timeout;
public Boolean permit_without_stream;
// Generate note: option type: public Boolean ForceLite;
}
@ -3091,7 +3134,7 @@ public class SingBoxOptions {
public String network;
public Boolean udp_over_tcp;
public UDPOverTCPOptions udp_over_tcp;
}
@ -3187,7 +3230,7 @@ public class SingBoxOptions {
public String network;
public Boolean udp_over_tcp;
public UDPOverTCPOptions udp_over_tcp;
public MultiplexOptions multiplex;
@ -3793,6 +3836,10 @@ public class SingBoxOptions {
public Map<String, String> headers;
public Long idle_timeout;
public Long ping_timeout;
}
public static class V2RayTransportOptions_WebsocketOptions extends V2RayTransportOptions {
@ -3812,6 +3859,12 @@ public class SingBoxOptions {
public String service_name;
public Long idle_timeout;
public Long ping_timeout;
public Boolean permit_without_stream;
}

View File

@ -104,5 +104,9 @@ fun SingBoxOptions.Rule_DefaultOptions.checkEmpty(): Boolean {
if (domain_regex?.isNotEmpty() == true) return false
if (domain_keyword?.isNotEmpty() == true) return false
if (user_id?.isNotEmpty() == true) return false
//
if (port?.isNotEmpty() == true) return false
if (port_range?.isNotEmpty() == true) return false
if (source_ip_cidr?.isNotEmpty() == true) return false
return true
}

View File

@ -68,6 +68,6 @@ object SendLog {
if (max in 1 until len) {
stream.skip(len - max) // TODO string?
}
return stream.readBytes()
return stream.use { it.readBytes() }
}
}

View File

@ -246,7 +246,7 @@
<string name="enable">启用</string>
<string name="auto">自动</string>
<string name="follow_system">跟随系统</string>
<string name="security_settings">安全设置</string>
<string name="security_settings">TLS 安全设置</string>
<string name="allow_insecure">允许不安全的连接</string>
<string name="allow_insecure_sum">禁用证书检查. 启用后该配置安全性相当于明文</string>
<string name="config_type">配置类型</string>
@ -470,4 +470,5 @@
<string name="show_group_in_notification">在通知中显示组名</string>
<string name="reset_connections">重置连接</string>
<string name="remove_duplicate">删除重复的服务器</string>
<string name="tls_modify_settings">TLS 伪装设置</string>
</resources>

View File

@ -69,7 +69,7 @@
<string name="show_stop_sum">If you dont want to use Quick Tile as the switch</string>
<string name="show_direct_speed">Show Direct Speed</string>
<string name="show_direct_speed_sum">Show the traffic speed without proxy in the notification as well</string>
<string name="security_settings">Security Settings</string>
<string name="security_settings">TLS Security Settings</string>
<string name="allow_insecure">Allow Insecure</string>
<string name="allow_insecure_sum">Disable certificate checking. When enabled, this configuration is as secure as plaintext</string>
<string name="traffic" translatable="false">%1$s↑ %2$s↓</string>
@ -513,5 +513,6 @@ Anyone can write advanced plugins, which can control NekoBox. please download an
<string name="remove_duplicate">Remove duplicate servers</string>
<string name="mtu_help">Long press the preference to set custom MTU.</string>
<string name="log_level_help">Long press the preference to set the buffer size.</string>
<string name="tls_modify_settings">TLS Modify Settings</string>
</resources>

View File

@ -118,6 +118,11 @@
app:key="allowInsecure"
app:summary="@string/allow_insecure_sum"
app:title="@string/allow_insecure" />
</PreferenceCategory>
<PreferenceCategory
app:key="serverTlsModifyCategory"
app:title="@string/tls_modify_settings">
<moe.matsuri.nb4a.ui.SimpleMenuPreference
app:defaultValue=""
app:entries="@array/utls_fingerprint_entry"

View File

@ -3,7 +3,6 @@ module libcore
go 1.18
require (
github.com/avast/apkverifier v0.0.0-20221110131049-7720fc1ebef0
github.com/codeclysm/extract v2.2.0+incompatible
github.com/matsuridayo/libneko v0.0.0-20230315005352-9d7e3f3a79d1
github.com/matsuridayo/sing-box-extra v0.0.0-20230403023034-c868033055eb
@ -21,7 +20,6 @@ require (
github.com/Dreamacro/clash v1.14.0 // indirect
github.com/ajg/form v1.5.1 // indirect
github.com/andybalholm/brotli v1.0.5 // indirect
github.com/avast/apkparser v0.0.0-20221012080151-bfc57d4d0502 // indirect
github.com/caddyserver/certmagic v0.17.2 // indirect
github.com/cloudflare/circl v1.2.1-0.20221019164342-6ab4dfed8f3c // indirect
github.com/cretz/bine v0.2.0 // indirect

View File

@ -7,20 +7,6 @@ github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/avast/apkparser v0.0.0-20190516101250-3b8c5efcb6a9/go.mod h1:c0733VBXm1we9M1zCtoOspplSwOYebS3hpDkJyMORRU=
github.com/avast/apkparser v0.0.0-20200102113521-69bcdd9c2403/go.mod h1:eZzHNfZWA1eeKPQE3LVmfRw32lhrH351jDCsma9qxOc=
github.com/avast/apkparser v0.0.0-20200402131724-9fd46d5c4749/go.mod h1:CSBdDZNEsGRYPiDt9QcGrIy8iWQ9YzB1rcuxn44+0jc=
github.com/avast/apkparser v0.0.0-20200924103028-30471fa5618f/go.mod h1:SKNzWGFyNJji/Z+iXjPCpmpFPvenFuhLjrSLCwCM/cM=
github.com/avast/apkparser v0.0.0-20210223100516-186f320f9bfc/go.mod h1:98WPhH/r8MbKpffuuDCAGtPyzSI2IVwXBcWAlXhMVC4=
github.com/avast/apkparser v0.0.0-20221012080151-bfc57d4d0502 h1:Ka3itfe3khrY1wBEgwaBXMCEhWRd9SG6rnAT8eOFXZQ=
github.com/avast/apkparser v0.0.0-20221012080151-bfc57d4d0502/go.mod h1:+p/TgE5RkPjTZkzIeZ1Ut/xlKcxsdJtNOuT33v8DKQU=
github.com/avast/apkverifier v0.0.0-20190808142831-dbbe53a24744/go.mod h1:mhWRoMg0KhvWt8SX7B2v2E3VfWt5jWfHfD9PtWAN+qM=
github.com/avast/apkverifier v0.0.0-20200217135742-aa28c80b82ae/go.mod h1:SV58cyAAN+SzX8GIBhizatMJNGcDyfQUj/xZUlKRW+I=
github.com/avast/apkverifier v0.0.0-20200416105355-97c5338f32f0/go.mod h1:HskRSJJJbP3poUkDRAyRAdDVSsh5J1mz8cRc2/B4kbc=
github.com/avast/apkverifier v0.0.0-20210219091843-33631264c352/go.mod h1:uhY/I/3Vh3V6ZFgLm/EFX/j5//MdoXpvcULTtzRW3YA=
github.com/avast/apkverifier v0.0.0-20210916093748-2146ff7c4b7f/go.mod h1:APQFx11UQTdbLKlZVJQFddZcJZxoHl6NnJfHN7foLD8=
github.com/avast/apkverifier v0.0.0-20221110131049-7720fc1ebef0 h1:x9HVJYrutJsTbfgN+Fg1mIn9moi8t1oSxvNIY3qhjks=
github.com/avast/apkverifier v0.0.0-20221110131049-7720fc1ebef0/go.mod h1:fnZDjIhf6G9k2Qr2f9IZcXctjGmzOK3y2II9gdG1GP8=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/caddyserver/certmagic v0.17.2 h1:o30seC1T/dBqBCNNGNHWwj2i5/I/FMjBbTAhjADP3nE=
github.com/caddyserver/certmagic v0.17.2/go.mod h1:ouWUuC490GOLJzkyN35eXfV8bSbwMwSf4bdhkIxtdQE=
@ -74,9 +60,6 @@ github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtL
github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
github.com/juju/errors v1.0.0 h1:yiq7kjCLll1BiaRuNY53MGI0+EQ3rF6GB+wvboZDefM=
github.com/juju/errors v1.0.0/go.mod h1:B5x9thDqx0wIMH3+aLIMP9HjItInYWObRovoCFM5Qe8=
github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.11.8/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw=
github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=

View File

@ -1,10 +1,6 @@
package libcore
import (
"bufio"
"bytes"
"crypto/sha256"
"fmt"
"libcore/device"
"os"
"path/filepath"
@ -15,7 +11,6 @@ import (
"log"
"github.com/avast/apkverifier"
"github.com/matsuridayo/libneko/neko_common"
"github.com/matsuridayo/libneko/neko_log"
)
@ -83,60 +78,7 @@ func InitCore(process, cachePath, internalAssets, externalAssets string,
// bg
if isBgProcess {
go verifyAPK()
extractAssets()
}
}()
}
var apkSignerSHA256 = [][]byte{
{0x35, 0x76, 0x27, 0x58, 0xce, 0x86, 0xa6, 0xec, 0x29, 0x7d, 0x9c, 0xca, 0xc6, 0x89, 0x46, 0x9b, 0xc4, 0x3b, 0x9f, 0xed, 0x8a, 0xe1, 0xb2, 0x7f, 0x10, 0x0a, 0x86, 0xbb, 0xac, 0x00, 0xa0, 0x55},
}
func verifyAPK() {
var apkPath string
f, err := os.Open("/proc/self/maps")
if err != nil {
outdated = fmt.Sprintf("verifyAPK: open maps: %v", err)
return
}
defer f.Close()
sc := bufio.NewScanner(f)
for sc.Scan() {
line := sc.Text()
if strings.HasSuffix(line, "/base.apk") {
apkPath = line[strings.Index(line, "/"):]
break
}
}
certs, err := apkverifier.ExtractCerts(apkPath, nil)
if certs == nil || err != nil {
outdated = fmt.Sprintf("verifyAPK: no certificate: %v", err)
return
}
var ok = false
for _, cert := range certs {
for _, c := range cert {
var s = sha256.Sum256(c.Raw)
if isGoodSigner(s[:]) {
ok = true
break
}
}
}
if !ok {
outdated = "verifyAPK: unknown signer"
}
}
func isGoodSigner(sha256 []byte) bool {
for _, hash := range apkSignerSHA256 {
if bytes.Equal(sha256, hash) {
return true
}
}
return false
}