add an option to disable ssl certificate verification (#394)

This commit is contained in:
AmirHossein Abdolmotallebi 2025-02-06 06:57:18 +03:30 committed by GitHub
parent 0488fc1df5
commit 62a37606fd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 96 additions and 11 deletions

View File

@ -32,6 +32,7 @@ import ir.amirab.downloader.monitor.DownloadMonitor
import ir.amirab.downloader.utils.IDiskStat import ir.amirab.downloader.utils.IDiskStat
import ir.amirab.util.startup.Startup import ir.amirab.util.startup.Startup
import com.abdownloadmanager.integration.Integration import com.abdownloadmanager.integration.Integration
import com.abdownloadmanager.shared.utils.*
import com.abdownloadmanager.updateapplier.DesktopUpdateApplier import com.abdownloadmanager.updateapplier.DesktopUpdateApplier
import com.abdownloadmanager.updateapplier.UpdateApplier import com.abdownloadmanager.updateapplier.UpdateApplier
import ir.amirab.downloader.DownloadManager import ir.amirab.downloader.DownloadManager
@ -46,10 +47,6 @@ import org.koin.dsl.bind
import org.koin.dsl.module import org.koin.dsl.module
import com.abdownloadmanager.updatechecker.GithubUpdateChecker import com.abdownloadmanager.updatechecker.GithubUpdateChecker
import com.abdownloadmanager.updatechecker.UpdateChecker import com.abdownloadmanager.updatechecker.UpdateChecker
import com.abdownloadmanager.shared.utils.DownloadFoldersRegistry
import com.abdownloadmanager.shared.utils.DownloadSystem
import com.abdownloadmanager.shared.utils.FileIconProvider
import com.abdownloadmanager.shared.utils.FileIconProviderUsingCategoryIcons
import ir.amirab.util.AppVersionTracker import ir.amirab.util.AppVersionTracker
import com.abdownloadmanager.shared.utils.appinfo.PreviousVersion import com.abdownloadmanager.shared.utils.appinfo.PreviousVersion
import com.abdownloadmanager.shared.utils.autoremove.RemovedDownloadsFromDiskTracker import com.abdownloadmanager.shared.utils.autoremove.RemovedDownloadsFromDiskTracker
@ -128,13 +125,7 @@ val downloaderModule = module {
} }
single<DownloaderClient> { single<DownloaderClient> {
OkHttpDownloaderClient( OkHttpDownloaderClient(
OkHttpClient get(),
.Builder()
.dispatcher(Dispatcher().apply {
//bypass limit on concurrent connections!
maxRequests = Int.MAX_VALUE
maxRequestsPerHost = Int.MAX_VALUE
}).build(),
get(), get(),
get(), get(),
get(), get(),
@ -348,6 +339,28 @@ val appModule = module {
) )
} }
single {
val appSettingsStorage: AppSettingsStorage = get()
AppSSLFactoryProvider(
ignoreSSLCertificates = appSettingsStorage.ignoreSSLCertificates
)
}
single<OkHttpClient> {
val appSSLFactoryProvider: AppSSLFactoryProvider = get()
OkHttpClient
.Builder()
.dispatcher(Dispatcher().apply {
//bypass limit on concurrent connections!
maxRequests = Int.MAX_VALUE
maxRequestsPerHost = Int.MAX_VALUE
})
.sslSocketFactory(
appSSLFactoryProvider.createSSLSocketFactory(),
appSSLFactoryProvider.trustManager,
)
.build()
}
} }

View File

@ -139,6 +139,21 @@ fun trackDeletedFilesOnDisk(appRepository: AppRepository): BooleanConfigurable {
) )
} }
fun ignoreSSLCertificates(appSettingsStorage: AppSettingsStorage): BooleanConfigurable {
return BooleanConfigurable(
title = Res.string.settings_ignore_ssl_certificates.asStringSource(),
description = Res.string.settings_ignore_ssl_certificates_description.asStringSource(),
backedBy = appSettingsStorage.ignoreSSLCertificates,
describe = {
if (it) {
Res.string.enabled.asStringSource()
} else {
Res.string.disabled.asStringSource()
}
},
)
}
fun speedUnit(appRepository: AppRepository, scope: CoroutineScope): EnumConfigurable<ConvertSizeConfig> { fun speedUnit(appRepository: AppRepository, scope: CoroutineScope): EnumConfigurable<ConvertSizeConfig> {
return EnumConfigurable( return EnumConfigurable(
title = Res.string.settings_download_speed_unit.asStringSource(), title = Res.string.settings_download_speed_unit.asStringSource(),
@ -478,6 +493,7 @@ class SettingsComponent(
useServerLastModified(appRepository), useServerLastModified(appRepository),
useSparseFileAllocation(appRepository), useSparseFileAllocation(appRepository),
trackDeletedFilesOnDisk(appRepository), trackDeletedFilesOnDisk(appRepository),
ignoreSSLCertificates(appSettings),
) )
} }
} }

View File

@ -34,6 +34,7 @@ data class AppSettingsModel(
val browserIntegrationPort: Int = 15151, val browserIntegrationPort: Int = 15151,
val trackDeletedFilesOnDisk: Boolean = false, val trackDeletedFilesOnDisk: Boolean = false,
val useBitsForSpeed: Boolean = false, val useBitsForSpeed: Boolean = false,
val ignoreSSLCertificates: Boolean = false,
) { ) {
companion object { companion object {
val default: AppSettingsModel get() = AppSettingsModel() val default: AppSettingsModel get() = AppSettingsModel()
@ -60,6 +61,7 @@ data class AppSettingsModel(
val browserIntegrationPort = intKeyOf("browserIntegrationPort") val browserIntegrationPort = intKeyOf("browserIntegrationPort")
val trackDeletedFilesOnDisk = booleanKeyOf("trackDeletedFilesOnDisk") val trackDeletedFilesOnDisk = booleanKeyOf("trackDeletedFilesOnDisk")
val useBitsForSpeed = booleanKeyOf("useBitsForSpeed") val useBitsForSpeed = booleanKeyOf("useBitsForSpeed")
val ignoreSSLCertificates = booleanKeyOf("ignoreSSLCertificates")
} }
@ -89,6 +91,7 @@ data class AppSettingsModel(
browserIntegrationPort = source.get(Keys.browserIntegrationPort) ?: default.browserIntegrationPort, browserIntegrationPort = source.get(Keys.browserIntegrationPort) ?: default.browserIntegrationPort,
trackDeletedFilesOnDisk = source.get(Keys.trackDeletedFilesOnDisk) ?: default.trackDeletedFilesOnDisk, trackDeletedFilesOnDisk = source.get(Keys.trackDeletedFilesOnDisk) ?: default.trackDeletedFilesOnDisk,
useBitsForSpeed = source.get(Keys.useBitsForSpeed) ?: default.useBitsForSpeed, useBitsForSpeed = source.get(Keys.useBitsForSpeed) ?: default.useBitsForSpeed,
ignoreSSLCertificates = source.get(Keys.ignoreSSLCertificates) ?: default.ignoreSSLCertificates,
) )
} }
@ -113,6 +116,7 @@ data class AppSettingsModel(
put(Keys.browserIntegrationPort, focus.browserIntegrationPort) put(Keys.browserIntegrationPort, focus.browserIntegrationPort)
put(Keys.trackDeletedFilesOnDisk, focus.trackDeletedFilesOnDisk) put(Keys.trackDeletedFilesOnDisk, focus.trackDeletedFilesOnDisk)
put(Keys.useBitsForSpeed, focus.useBitsForSpeed) put(Keys.useBitsForSpeed, focus.useBitsForSpeed)
put(Keys.ignoreSSLCertificates, focus.ignoreSSLCertificates)
} }
} }
} }
@ -161,4 +165,5 @@ class AppSettingsStorage(
val browserIntegrationPort = from(AppSettingsModel.browserIntegrationPort) val browserIntegrationPort = from(AppSettingsModel.browserIntegrationPort)
val trackDeletedFilesOnDisk = from(AppSettingsModel.trackDeletedFilesOnDisk) val trackDeletedFilesOnDisk = from(AppSettingsModel.trackDeletedFilesOnDisk)
val useBitsForSpeed = from(AppSettingsModel.useBitsForSpeed) val useBitsForSpeed = from(AppSettingsModel.useBitsForSpeed)
val ignoreSSLCertificates = from(AppSettingsModel.ignoreSSLCertificates)
} }

View File

@ -0,0 +1,49 @@
package com.abdownloadmanager.shared.utils
import kotlinx.coroutines.flow.StateFlow
import okhttp3.internal.platform.Platform
import java.security.cert.X509Certificate
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.X509TrustManager
/**
* at the moment we simply use okhttp ssl factory provider with a toggleable trust manager to ignore ssl certificates
*/
class AppSSLFactoryProvider(
private val ignoreSSLCertificates: StateFlow<Boolean>,
) {
val trustManager: X509TrustManager by lazy {
ToggleableTrustManager(
trustManager = Platform.get().platformTrustManager(),
shouldCheck = { !ignoreSSLCertificates.value }
)
}
fun createSSLSocketFactory(): SSLSocketFactory {
return Platform.get().newSslSocketFactory(
trustManager = trustManager,
)
}
}
private class ToggleableTrustManager(
private val trustManager: X509TrustManager,
private val shouldCheck: () -> Boolean,
) : X509TrustManager {
override fun checkClientTrusted(chain: Array<out X509Certificate>?, authType: String?) {
if (shouldCheck()) {
trustManager.checkClientTrusted(chain, authType)
}
}
override fun checkServerTrusted(chain: Array<out X509Certificate>?, authType: String?) {
if (shouldCheck()) {
trustManager.checkServerTrusted(chain, authType)
}
}
override fun getAcceptedIssuers(): Array<X509Certificate> {
return trustManager.acceptedIssuers
}
}

View File

@ -184,6 +184,8 @@ settings_use_server_last_modified_time=Use Server's Last-Modified Time
settings_use_server_last_modified_time_description=When downloading a file, use server's last modified time for the local file settings_use_server_last_modified_time_description=When downloading a file, use server's last modified time for the local file
settings_use_sparse_file_allocation=Sparse File Allocation settings_use_sparse_file_allocation=Sparse File Allocation
settings_use_sparse_file_allocation_description=Create files more efficiently, especially on SSDs, by reducing unnecessary data writing. This can speed up download starts and reduce disk usage. If downloads start slowly or you experience unusual download speeds, consider disabling this option, as it may not be fully supported on some devices. settings_use_sparse_file_allocation_description=Create files more efficiently, especially on SSDs, by reducing unnecessary data writing. This can speed up download starts and reduce disk usage. If downloads start slowly or you experience unusual download speeds, consider disabling this option, as it may not be fully supported on some devices.
settings_ignore_ssl_certificates=Ignore SSL Certificates
settings_ignore_ssl_certificates_description=Disables SSL certificate verification. Use only if necessary, as it may expose your connection to security risks.
settings_global_speed_limiter=Global Speed Limiter settings_global_speed_limiter=Global Speed Limiter
settings_global_speed_limiter_description=Global download speed limit (0 means unlimited) settings_global_speed_limiter_description=Global download speed limit (0 means unlimited)
settings_show_average_speed=Show Average Speed settings_show_average_speed=Show Average Speed