From 6782227037711f1a5d79e94cf30d611d49a1610a Mon Sep 17 00:00:00 2001 From: ssrlive <30760636+ssrlive@users.noreply.github.com> Date: Thu, 30 May 2024 21:21:57 +0800 Subject: [PATCH] self-signed certificate --- .../3.json | 8 +++++++- .../github/shadowsocks/database/Profile.kt | 20 +++++++++++++++++-- .../com/github/shadowsocks/utils/Constants.kt | 1 + core/src/main/res/values-zh-rCN/strings.xml | 2 ++ core/src/main/res/values/strings.xml | 2 ++ .../shadowsocks/ProfileConfigFragment.kt | 4 ++++ .../github/shadowsocks/ProfilesFragment.kt | 6 +++++- mobile/src/main/res/xml/pref_profile.xml | 6 ++++++ 8 files changed, 45 insertions(+), 4 deletions(-) diff --git a/core/schemas/com.github.shadowsocks.database.PrivateDatabase/3.json b/core/schemas/com.github.shadowsocks.database.PrivateDatabase/3.json index 38d3abf40..13c9af883 100644 --- a/core/schemas/com.github.shadowsocks.database.PrivateDatabase/3.json +++ b/core/schemas/com.github.shadowsocks.database.PrivateDatabase/3.json @@ -6,7 +6,7 @@ "entities": [ { "tableName": "Profile", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `host` TEXT NOT NULL, `remotePort` INTEGER NOT NULL, `password` TEXT NOT NULL, `protocol` TEXT NOT NULL, `protocol_param` TEXT NOT NULL, `obfs` TEXT NOT NULL, `obfs_param` TEXT NOT NULL, `method` TEXT NOT NULL, `over_tls_enable` INTEGER NOT NULL, `over_tls_server_domain` TEXT NOT NULL, `over_tls_path` TEXT NOT NULL, `route` TEXT NOT NULL, `remoteDns` TEXT NOT NULL, `proxyApps` INTEGER NOT NULL, `bypass` INTEGER NOT NULL, `udpdns` INTEGER NOT NULL, `url_group` TEXT NOT NULL, `ipv6` INTEGER NOT NULL, `metered` INTEGER NOT NULL, `individual` TEXT NOT NULL, `plugin` TEXT, `udpFallback` INTEGER, `subscription` INTEGER NOT NULL, `tx` INTEGER NOT NULL, `rx` INTEGER NOT NULL, `elapsed` INTEGER NOT NULL, `userOrder` INTEGER NOT NULL)", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `host` TEXT NOT NULL, `remotePort` INTEGER NOT NULL, `password` TEXT NOT NULL, `protocol` TEXT NOT NULL, `protocol_param` TEXT NOT NULL, `obfs` TEXT NOT NULL, `obfs_param` TEXT NOT NULL, `method` TEXT NOT NULL, `over_tls_enable` INTEGER NOT NULL, `over_tls_server_domain` TEXT NOT NULL, `over_tls_path` TEXT NOT NULL, `over_tls_cafile` TEXT NOT NULL, `route` TEXT NOT NULL, `remoteDns` TEXT NOT NULL, `proxyApps` INTEGER NOT NULL, `bypass` INTEGER NOT NULL, `udpdns` INTEGER NOT NULL, `url_group` TEXT NOT NULL, `ipv6` INTEGER NOT NULL, `metered` INTEGER NOT NULL, `individual` TEXT NOT NULL, `plugin` TEXT, `udpFallback` INTEGER, `subscription` INTEGER NOT NULL, `tx` INTEGER NOT NULL, `rx` INTEGER NOT NULL, `elapsed` INTEGER NOT NULL, `userOrder` INTEGER NOT NULL)", "fields": [ { "fieldPath": "id", @@ -86,6 +86,12 @@ "affinity": "TEXT", "notNull": true }, + { + "fieldPath": "over_tls_cafile", + "columnName": "over_tls_cafile", + "affinity": "TEXT", + "notNull": true + }, { "fieldPath": "route", "columnName": "route", diff --git a/core/src/main/java/com/github/shadowsocks/database/Profile.kt b/core/src/main/java/com/github/shadowsocks/database/Profile.kt index a9ca50c20..348f539fc 100644 --- a/core/src/main/java/com/github/shadowsocks/database/Profile.kt +++ b/core/src/main/java/com/github/shadowsocks/database/Profile.kt @@ -60,6 +60,7 @@ data class Profile( var over_tls_enable: Boolean = false, var over_tls_server_domain: String = "", var over_tls_path: String = "", + var over_tls_cafile: String = "", var route: String = "all", var remoteDns: String = "8.8.8.8:53", @@ -120,6 +121,7 @@ data class Profile( private val decodedPattern_ssr_over_tls_enable = "(?i)(.*)[?&]ot_enable=([0-9_=-]*)(.*)".toRegex() private val decodedPattern_ssr_over_tls_server_domain = "(?i)(.*)[?&]ot_domain=([A-Za-z0-9_=-]*)(.*)".toRegex() private val decodedPattern_ssr_over_tls_path = "(?i)(.*)[?&]ot_path=([A-Za-z0-9_=-]*)(.*)".toRegex() + private val decodedPattern_ssr_over_tls_cafile = "(?i)(.*)[?&]ot_cert=([A-Za-z0-9_=-]*)(.*)".toRegex() private fun base64Decode(data: String) = String(Base64.decode(data.replace("=", ""), Base64.URL_SAFE), Charsets.UTF_8) @@ -159,6 +161,9 @@ data class Profile( val match7 = decodedPattern_ssr_over_tls_path.matchEntire(match.groupValues[8]) if (match7 != null) profile.over_tls_path = base64Decode(match7.groupValues[2]) + val match8 = decodedPattern_ssr_over_tls_cafile.matchEntire(match.groupValues[8]) + if (match8 != null) profile.over_tls_cafile = base64Decode(match8.groupValues[2]) + profile } else { null @@ -257,6 +262,7 @@ data class Profile( val over_tls_enable = json["over_tls_enable"]?.optBoolean val over_tls_server_domain = json["over_tls_server_domain"].optString ?: return null val over_tls_path = json["over_tls_path"].optString ?: return null + val over_tls_cafile = json["over_tls_cafile"].optString ?: return null val method = json["method"].optString if (method.isNullOrEmpty()) return null @@ -272,6 +278,7 @@ data class Profile( it.over_tls_enable = if (over_tls_enable != null && over_tls_enable == true) true else false it.over_tls_server_domain = over_tls_server_domain it.over_tls_path = over_tls_path + it.over_tls_cafile = over_tls_cafile }.apply { feature?.copyFeatureSettingsTo(this) name = json["remarks"].optString.toString() @@ -314,6 +321,7 @@ data class Profile( fallback.over_tls_enable == it.over_tls_enable && fallback.over_tls_server_domain == it.over_tls_server_domain && fallback.over_tls_path == it.over_tls_path && + fallback.over_tls_cafile == it.over_tls_cafile && it.plugin.isNullOrEmpty() } @@ -396,6 +404,7 @@ data class Profile( profile.over_tls_enable = over_tls_enable profile.over_tls_server_domain = over_tls_server_domain profile.over_tls_path = over_tls_path + profile.over_tls_cafile = over_tls_cafile profile.method = method } } @@ -407,6 +416,7 @@ data class Profile( other.over_tls_enable == over_tls_enable && other.over_tls_server_domain == over_tls_server_domain && other.over_tls_path == over_tls_path && + other.over_tls_cafile == over_tls_cafile && other.name == name && other.url_group == url_group override fun toString(): String { @@ -421,6 +431,7 @@ data class Profile( val b64url_group = Base64.encodeToString("%s".format(Locale.ENGLISH, url_group).toByteArray(), flags) val b64over_tls_server_domain = Base64.encodeToString("%s".format(Locale.ENGLISH, over_tls_server_domain).toByteArray(), flags) val b64over_tls_path = Base64.encodeToString("%s".format(Locale.ENGLISH, over_tls_path).toByteArray(), flags) + val b64over_tls_cafile = Base64.encodeToString("%s".format(Locale.ENGLISH, over_tls_cafile).toByteArray(), flags) if (!over_tls_enable && obfs == "plain" && protocol == "origin") { return "ss://" + b64userinfo + "@" + host + ":" + remotePort + "#" + URLEncoder.encode(name, "utf-8") @@ -428,11 +439,12 @@ data class Profile( if (over_tls_enable) { return "ssr://" + Base64.encodeToString( - "%s:%d:%s:%s:%s:%s/?obfsparam=%s&protoparam=%s&remarks=%s&group=%s&ot_enable=%d&ot_domain=%s&ot_path=%s" + "%s:%d:%s:%s:%s:%s/?obfsparam=%s&protoparam=%s&remarks=%s&group=%s&ot_enable=%d&ot_domain=%s&ot_path=%s%s" .format( Locale.ENGLISH, host, remotePort, protocol, method, obfs, b64password, b64obfs_param, b64protocol_param, b64name, b64url_group, - 1, b64over_tls_server_domain, b64over_tls_path + 1, b64over_tls_server_domain, b64over_tls_path, + if (b64over_tls_cafile.isEmpty()) "" else "&ot_cert=${b64over_tls_cafile}" ).toByteArray(), flags ) } else { @@ -460,6 +472,7 @@ data class Profile( put("server_domain", over_tls_server_domain) put("listen_host", DataStore.listenAddress) put("listen_port", DataStore.portProxy) + put("cafile", over_tls_cafile) }) } @@ -481,6 +494,7 @@ data class Profile( put("enable", over_tls_enable) put("server_domain", over_tls_server_domain) put("path", over_tls_path) + put("root_cert_file", over_tls_cafile) }) } @@ -521,6 +535,7 @@ data class Profile( DataStore.privateStore.putBoolean(Key.over_tls_enable, over_tls_enable) DataStore.privateStore.putString(Key.over_tls_server_domain, over_tls_server_domain) DataStore.privateStore.putString(Key.over_tls_path, over_tls_path) + DataStore.privateStore.putString(Key.over_tls_cafile, over_tls_cafile) DataStore.proxyApps = proxyApps DataStore.bypass = bypass @@ -551,6 +566,7 @@ data class Profile( over_tls_enable = (DataStore.privateStore.getBoolean(Key.over_tls_enable) == true) over_tls_server_domain = DataStore.privateStore.getString(Key.over_tls_server_domain) ?: "" over_tls_path = DataStore.privateStore.getString(Key.over_tls_path) ?: "" + over_tls_cafile = DataStore.privateStore.getString(Key.over_tls_cafile) ?: "" method = DataStore.privateStore.getString(Key.method) ?: "" route = DataStore.privateStore.getString(Key.route) ?: "" diff --git a/core/src/main/java/com/github/shadowsocks/utils/Constants.kt b/core/src/main/java/com/github/shadowsocks/utils/Constants.kt index 984e39569..04e5d42d3 100644 --- a/core/src/main/java/com/github/shadowsocks/utils/Constants.kt +++ b/core/src/main/java/com/github/shadowsocks/utils/Constants.kt @@ -64,6 +64,7 @@ object Key { const val over_tls_enable = "over_tls_enable" const val over_tls_server_domain = "over_tls_server_domain" const val over_tls_path = "over_tls_path" + const val over_tls_cafile = "over_tls_cafile" const val remotePort = "remotePortNum" const val remoteDns = "remoteDns" diff --git a/core/src/main/res/values-zh-rCN/strings.xml b/core/src/main/res/values-zh-rCN/strings.xml index 1029cee26..956966560 100644 --- a/core/src/main/res/values-zh-rCN/strings.xml +++ b/core/src/main/res/values-zh-rCN/strings.xml @@ -40,6 +40,8 @@ "SSRoT 啓用" "SSRoT 服務器域名" "SSRoT 祕密入口路徑" + "over_tls CA 憑證文件" + 這個節點不支持二維碼因爲它含有自簽名證書 "IPv6 路由" diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index 5db355b3b..c37a5ca47 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -40,6 +40,8 @@ SSRoT enable SSRoT domain name SSRoT secret path + over_tls CA file + QR code not supported because of this node contains self-signed certificate IPv6 Route diff --git a/mobile/src/main/java/com/github/shadowsocks/ProfileConfigFragment.kt b/mobile/src/main/java/com/github/shadowsocks/ProfileConfigFragment.kt index c45384428..3e77f6615 100644 --- a/mobile/src/main/java/com/github/shadowsocks/ProfileConfigFragment.kt +++ b/mobile/src/main/java/com/github/shadowsocks/ProfileConfigFragment.kt @@ -73,6 +73,7 @@ class ProfileConfigFragment : PreferenceFragmentCompat(), OnPreferenceDataStoreC private lateinit var over_tls_enable: SwitchPreference private lateinit var over_tls_server_domain: EditTextPreference private lateinit var over_tls_path: EditTextPreference + private lateinit var over_tls_cafile: EditTextPreference override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { preferenceManager.preferenceDataStore = DataStore.privateStore @@ -104,6 +105,7 @@ class ProfileConfigFragment : PreferenceFragmentCompat(), OnPreferenceDataStoreC over_tls_server_domain = findPreference(Key.over_tls_server_domain)!! over_tls_path = findPreference(Key.over_tls_path)!! + over_tls_cafile = findPreference(Key.over_tls_cafile)!! over_tls_enable = findPreference(Key.over_tls_enable)!! over_tls_enable.setOnPreferenceChangeListener { _, newValue -> @@ -130,6 +132,7 @@ class ProfileConfigFragment : PreferenceFragmentCompat(), OnPreferenceDataStoreC findPreference(Key.over_tls_enable)!!.isEnabled = false findPreference(Key.over_tls_server_domain)!!.isEnabled = false findPreference(Key.over_tls_path)!!.isEnabled = false + findPreference(Key.over_tls_cafile)!!.isEnabled = false } else findPreference(Key.group)!!.isEnabled = false } @@ -142,6 +145,7 @@ class ProfileConfigFragment : PreferenceFragmentCompat(), OnPreferenceDataStoreC over_tls_enable.isChecked = enable over_tls_server_domain.isEnabled = enable over_tls_path.isEnabled = enable + over_tls_cafile.isEnabled = enable } private fun saveAndExit() { diff --git a/mobile/src/main/java/com/github/shadowsocks/ProfilesFragment.kt b/mobile/src/main/java/com/github/shadowsocks/ProfilesFragment.kt index bffb14935..e3a88eb26 100644 --- a/mobile/src/main/java/com/github/shadowsocks/ProfilesFragment.kt +++ b/mobile/src/main/java/com/github/shadowsocks/ProfilesFragment.kt @@ -203,7 +203,11 @@ class ProfilesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener, Sea override fun onMenuItemClick(item: MenuItem): Boolean = when (item.itemId) { R.id.action_qr_code -> { - QRCodeDialog(this.item.toString()).showAllowingStateLoss(parentFragmentManager) + if (this.item.over_tls_cafile.length > 0) { + (activity as MainActivity).snackbar().setText(R.string.qr_code_not_support).setDuration(4000).show() + } else { + QRCodeDialog(this.item.toString()).showAllowingStateLoss(parentFragmentManager) + } true } R.id.action_export_clipboard -> { diff --git a/mobile/src/main/res/xml/pref_profile.xml b/mobile/src/main/res/xml/pref_profile.xml index eb33a41f5..5699ac5f4 100644 --- a/mobile/src/main/res/xml/pref_profile.xml +++ b/mobile/src/main/res/xml/pref_profile.xml @@ -85,6 +85,12 @@ app:title="@string/over_tls_path" app:useSimpleSummaryProvider="true" /> + +