Skip to content

Commit 876759c

Browse files
Fixed broken iOS build and bump version
1 parent c81f912 commit 876759c

7 files changed

Lines changed: 123 additions & 118 deletions

File tree

regions/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ android {
3838
@OptIn(org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi::class)
3939
kotlin {
4040
group = "com.kape.android"
41-
version = "1.7.1"
41+
version = "1.7.2"
4242

4343
jvmToolchain(17)
4444

regions/src/androidMain/kotlin/com/privateinternetaccess/regions/internals/RegionsDataSourceFactoryImpl.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ internal actual class RegionsDataSourceFactoryImpl actual constructor(
88
): RegionsDataSourceFactory {
99
private val platformProvider: PlatformInstancesProvider = platformProvider ?: throw NullPointerException("platform provider may not be null")
1010

11-
override fun newInMemoryDataSource(): RegionsCacheDataSource = InMemoryRegionsCacheDataSource()
11+
actual override fun newInMemoryDataSource(): RegionsCacheDataSource = InMemoryRegionsCacheDataSource()
1212

13-
override fun newPersistenceRegionsDataSource(
13+
actual override fun newPersistenceRegionsDataSource(
1414
preferenceName: String?
1515
): RegionsCacheDataSource = PersistenceRegionsDataSource(
1616
provider = platformProvider,

regions/src/commonMain/kotlin/com/privateinternetaccess/regions/internals/RegionsCacheDataSource.kt

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,22 @@ internal data class CacheEntry(
2929
internal expect class RegionsDataSourceFactoryImpl(
3030
platformProvider: PlatformInstancesProvider?,
3131
logErrors: Boolean
32-
): RegionsDataSourceFactory
32+
): RegionsDataSourceFactory {
33+
override fun newInMemoryDataSource(): RegionsCacheDataSource
34+
override fun newPersistenceRegionsDataSource(preferenceName: String?): RegionsCacheDataSource
35+
}
36+
37+
internal expect class PersistenceRegionsDataSource : RegionsCacheDataSource {
38+
override fun saveVpnRegions(
39+
locale: String,
40+
response: VpnRegionsResponse
41+
)
3342

34-
internal expect class PersistenceRegionsDataSource : RegionsCacheDataSource
43+
override fun getVpnRegions(locale: String?): Result<VpnRegionsResponse>
44+
override fun saveShadowsocksRegions(
45+
locale: String,
46+
response: List<ShadowsocksRegionsResponse>
47+
)
48+
49+
override fun getShadowsocksRegions(locale: String?): Result<List<ShadowsocksRegionsResponse>>
50+
}
Lines changed: 49 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@file:Suppress("ARGUMENT_TYPE_MISMATCH")
2+
13
package com.privateinternetaccess.regions.internals
24

35
/*
@@ -21,7 +23,6 @@ package com.privateinternetaccess.regions.internals
2123
import com.privateinternetaccess.regions.internals.Regions.Companion.REQUEST_TIMEOUT_MS
2224
import io.ktor.client.HttpClient
2325
import io.ktor.client.engine.darwin.*
24-
import io.ktor.client.engine.ios.*
2526
import io.ktor.client.plugins.*
2627
import kotlinx.cinterop.*
2728
import platform.CoreFoundation.*
@@ -44,7 +45,7 @@ internal actual object RegionHttpClient {
4445
if (certificate != null && pinnedEndpoint != null) {
4546
engine {
4647
handleChallenge(
47-
RegionCertificatePinner(
48+
buildCertificatePinnerHandler(
4849
certificate,
4950
pinnedEndpoint.first,
5051
pinnedEndpoint.second
@@ -56,14 +57,13 @@ internal actual object RegionHttpClient {
5657
}
5758
}
5859

59-
@OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
60-
private class RegionCertificatePinner(
60+
@OptIn(kotlinx.cinterop.ExperimentalForeignApi::class, kotlinx.cinterop.BetaInteropApi::class)
61+
private fun buildCertificatePinnerHandler(
6162
certificate: String,
62-
private val hostname: String,
63-
private val commonName: String
64-
) : ChallengeHandler {
65-
66-
private val certificateData = NSData.create(
63+
hostname: String,
64+
commonName: String
65+
): ChallengeHandler {
66+
val certificateData = NSData.create(
6767
base64EncodedString =
6868
certificate
6969
.replace("-----BEGIN CERTIFICATE-----", "")
@@ -72,59 +72,53 @@ private class RegionCertificatePinner(
7272
options = NSDataBase64Encoding64CharacterLineLength
7373
)
7474

75-
override fun invoke(
76-
session: NSURLSession,
77-
task: NSURLSessionTask,
78-
challenge: NSURLAuthenticationChallenge,
79-
completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Unit
80-
) {
75+
return { _, _, challenge, completionHandler ->
8176
if (challenge.protectionSpace.authenticationMethod != NSURLAuthenticationMethodServerTrust) {
8277
challenge.sender?.cancelAuthenticationChallenge(challenge)
8378
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, null)
84-
return
85-
}
86-
87-
val serverTrust = challenge.protectionSpace.serverTrust
88-
val serverCertificateRef = SecTrustGetCertificateAtIndex(serverTrust, 0)
89-
val certificateDataRef = CFBridgingRetain(certificateData) as CFDataRef
90-
val certificateRef = SecCertificateCreateWithData(null, certificateDataRef)
91-
val policyRef = SecPolicyCreateSSL(true, null)
92-
93-
memScoped {
94-
var preparationSucceeded = true
95-
val serverCommonNameRef = alloc<CFStringRefVar>()
96-
SecCertificateCopyCommonName(serverCertificateRef, serverCommonNameRef.ptr)
97-
val commonNameEvaluationSucceeded = (commonName == CFBridgingRelease(serverCommonNameRef.value))
98-
val hostNameEvaluationSucceeded = (hostname == challenge.protectionSpace.host)
79+
} else {
80+
val serverTrust = challenge.protectionSpace.serverTrust
81+
val serverCertificateRef = SecTrustGetCertificateAtIndex(serverTrust, 0)
82+
val certificateDataRef = CFBridgingRetain(certificateData) as CFDataRef
83+
val certificateRef = SecCertificateCreateWithData(null, certificateDataRef)
84+
val policyRef = SecPolicyCreateSSL(true, null)
85+
86+
memScoped {
87+
var preparationSucceeded = true
88+
val serverCommonNameRef = alloc<CFStringRefVar>()
89+
SecCertificateCopyCommonName(serverCertificateRef, serverCommonNameRef.ptr)
90+
val commonNameEvaluationSucceeded = (commonName == CFBridgingRelease(serverCommonNameRef.value))
91+
val hostNameEvaluationSucceeded = (hostname == challenge.protectionSpace.host)
92+
93+
val trust = alloc<SecTrustRefVar>()
94+
val trustCreation = SecTrustCreateWithCertificates(serverCertificateRef, policyRef, trust.ptr)
95+
if (trustCreation != errSecSuccess) {
96+
preparationSucceeded = false
97+
}
9998

100-
val trust = alloc<SecTrustRefVar>()
101-
val trustCreation = SecTrustCreateWithCertificates(serverCertificateRef, policyRef, trust.ptr)
102-
if (trustCreation != errSecSuccess) {
103-
preparationSucceeded = false
104-
}
99+
val mutableArrayRef = CFArrayCreateMutable(kCFAllocatorDefault, 1, null)
100+
CFArrayAppendValue(mutableArrayRef, certificateRef)
105101

106-
val mutableArrayRef = CFArrayCreateMutable(kCFAllocatorDefault, 1, null)
107-
CFArrayAppendValue(mutableArrayRef, certificateRef)
102+
val trustAnchor = SecTrustSetAnchorCertificates(trust.value, mutableArrayRef)
103+
if (trustAnchor != errSecSuccess) {
104+
preparationSucceeded = false
105+
}
108106

109-
val trustAnchor = SecTrustSetAnchorCertificates(trust.value, mutableArrayRef)
110-
if (trustAnchor != errSecSuccess) {
111-
preparationSucceeded = false
112-
}
107+
val error = alloc<CFErrorRefVar>()
108+
val certificateEvaluationSucceeded = SecTrustEvaluateWithError(trust.value, error.ptr)
109+
challenge.sender?.useCredential(NSURLCredential.create(serverTrust), challenge)
110+
if (preparationSucceeded && hostNameEvaluationSucceeded && commonNameEvaluationSucceeded && certificateEvaluationSucceeded) {
111+
completionHandler(NSURLSessionAuthChallengeUseCredential, NSURLCredential.create(serverTrust))
112+
} else {
113+
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, null)
114+
}
113115

114-
val error = alloc<CFErrorRefVar>()
115-
val certificateEvaluationSucceeded = SecTrustEvaluateWithError(trust.value, error.ptr)
116-
challenge.sender?.useCredential(NSURLCredential.create(serverTrust), challenge)
117-
if (preparationSucceeded && hostNameEvaluationSucceeded && commonNameEvaluationSucceeded && certificateEvaluationSucceeded) {
118-
completionHandler(NSURLSessionAuthChallengeUseCredential, NSURLCredential.create(serverTrust))
119-
} else {
120-
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, null)
116+
CFRelease(serverCertificateRef)
117+
CFRelease(certificateDataRef)
118+
CFRelease(certificateRef)
119+
CFRelease(policyRef)
120+
CFRelease(mutableArrayRef)
121121
}
122-
123-
CFRelease(serverCertificateRef)
124-
CFRelease(certificateDataRef)
125-
CFRelease(certificateRef)
126-
CFRelease(policyRef)
127-
CFRelease(mutableArrayRef)
128122
}
129123
}
130-
}
124+
}

regions/src/iosMain/kotlin/com/privateinternetaccess/regions/internals/RegionsDataSourceFactoryImpl.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ internal actual class RegionsDataSourceFactoryImpl actual constructor(
77
private val logErrors: Boolean
88
): RegionsDataSourceFactory {
99

10-
override fun newInMemoryDataSource(): RegionsCacheDataSource =
10+
actual override fun newInMemoryDataSource(): RegionsCacheDataSource =
1111
InMemoryRegionsCacheDataSource()
1212

13-
override fun newPersistenceRegionsDataSource(
13+
actual override fun newPersistenceRegionsDataSource(
1414
preferenceName: String?
1515
): RegionsCacheDataSource = PersistenceRegionsDataSource(
1616
preferenceName = preferenceName,
Lines changed: 49 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@file:Suppress("ARGUMENT_TYPE_MISMATCH")
2+
13
package com.privateinternetaccess.regions.internals
24

35
/*
@@ -43,7 +45,7 @@ internal actual object RegionHttpClient {
4345
if (certificate != null && pinnedEndpoint != null) {
4446
engine {
4547
handleChallenge(
46-
RegionCertificatePinner(
48+
buildCertificatePinnerHandler(
4749
certificate,
4850
pinnedEndpoint.first,
4951
pinnedEndpoint.second
@@ -55,14 +57,13 @@ internal actual object RegionHttpClient {
5557
}
5658
}
5759

58-
@OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
59-
private class RegionCertificatePinner(
60+
@OptIn(kotlinx.cinterop.ExperimentalForeignApi::class, kotlinx.cinterop.BetaInteropApi::class)
61+
private fun buildCertificatePinnerHandler(
6062
certificate: String,
61-
private val hostname: String,
62-
private val commonName: String
63-
) : ChallengeHandler {
64-
65-
private val certificateData = NSData.create(
63+
hostname: String,
64+
commonName: String
65+
): ChallengeHandler {
66+
val certificateData = NSData.create(
6667
base64EncodedString =
6768
certificate
6869
.replace("-----BEGIN CERTIFICATE-----", "")
@@ -71,59 +72,53 @@ private class RegionCertificatePinner(
7172
options = NSDataBase64Encoding64CharacterLineLength
7273
)
7374

74-
override fun invoke(
75-
session: NSURLSession,
76-
task: NSURLSessionTask,
77-
challenge: NSURLAuthenticationChallenge,
78-
completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Unit
79-
) {
75+
return { _, _, challenge, completionHandler ->
8076
if (challenge.protectionSpace.authenticationMethod != NSURLAuthenticationMethodServerTrust) {
8177
challenge.sender?.cancelAuthenticationChallenge(challenge)
8278
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, null)
83-
return
84-
}
85-
86-
val serverTrust = challenge.protectionSpace.serverTrust
87-
val serverCertificateRef = SecTrustGetCertificateAtIndex(serverTrust, 0)
88-
val certificateDataRef = CFBridgingRetain(certificateData) as CFDataRef
89-
val certificateRef = SecCertificateCreateWithData(null, certificateDataRef)
90-
val policyRef = SecPolicyCreateSSL(true, null)
91-
92-
memScoped {
93-
var preparationSucceeded = true
94-
val serverCommonNameRef = alloc<CFStringRefVar>()
95-
SecCertificateCopyCommonName(serverCertificateRef, serverCommonNameRef.ptr)
96-
val commonNameEvaluationSucceeded = (commonName == CFBridgingRelease(serverCommonNameRef.value))
97-
val hostNameEvaluationSucceeded = (hostname == challenge.protectionSpace.host)
79+
} else {
80+
val serverTrust = challenge.protectionSpace.serverTrust
81+
val serverCertificateRef = SecTrustGetCertificateAtIndex(serverTrust, 0)
82+
val certificateDataRef = CFBridgingRetain(certificateData) as CFDataRef
83+
val certificateRef = SecCertificateCreateWithData(null, certificateDataRef)
84+
val policyRef = SecPolicyCreateSSL(true, null)
85+
86+
memScoped {
87+
var preparationSucceeded = true
88+
val serverCommonNameRef = alloc<CFStringRefVar>()
89+
SecCertificateCopyCommonName(serverCertificateRef, serverCommonNameRef.ptr)
90+
val commonNameEvaluationSucceeded = (commonName == CFBridgingRelease(serverCommonNameRef.value))
91+
val hostNameEvaluationSucceeded = (hostname == challenge.protectionSpace.host)
92+
93+
val trust = alloc<SecTrustRefVar>()
94+
val trustCreation = SecTrustCreateWithCertificates(serverCertificateRef, policyRef, trust.ptr)
95+
if (trustCreation != errSecSuccess) {
96+
preparationSucceeded = false
97+
}
9898

99-
val trust = alloc<SecTrustRefVar>()
100-
val trustCreation = SecTrustCreateWithCertificates(serverCertificateRef, policyRef, trust.ptr)
101-
if (trustCreation != errSecSuccess) {
102-
preparationSucceeded = false
103-
}
99+
val mutableArrayRef = CFArrayCreateMutable(kCFAllocatorDefault, 1, null)
100+
CFArrayAppendValue(mutableArrayRef, certificateRef)
104101

105-
val mutableArrayRef = CFArrayCreateMutable(kCFAllocatorDefault, 1, null)
106-
CFArrayAppendValue(mutableArrayRef, certificateRef)
102+
val trustAnchor = SecTrustSetAnchorCertificates(trust.value, mutableArrayRef)
103+
if (trustAnchor != errSecSuccess) {
104+
preparationSucceeded = false
105+
}
107106

108-
val trustAnchor = SecTrustSetAnchorCertificates(trust.value, mutableArrayRef)
109-
if (trustAnchor != errSecSuccess) {
110-
preparationSucceeded = false
111-
}
107+
val error = alloc<CFErrorRefVar>()
108+
val certificateEvaluationSucceeded = SecTrustEvaluateWithError(trust.value, error.ptr)
109+
challenge.sender?.useCredential(NSURLCredential.create(serverTrust), challenge)
110+
if (preparationSucceeded && hostNameEvaluationSucceeded && commonNameEvaluationSucceeded && certificateEvaluationSucceeded) {
111+
completionHandler(NSURLSessionAuthChallengeUseCredential, NSURLCredential.create(serverTrust))
112+
} else {
113+
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, null)
114+
}
112115

113-
val error = alloc<CFErrorRefVar>()
114-
val certificateEvaluationSucceeded = SecTrustEvaluateWithError(trust.value, error.ptr)
115-
challenge.sender?.useCredential(NSURLCredential.create(serverTrust), challenge)
116-
if (preparationSucceeded && hostNameEvaluationSucceeded && commonNameEvaluationSucceeded && certificateEvaluationSucceeded) {
117-
completionHandler(NSURLSessionAuthChallengeUseCredential, NSURLCredential.create(serverTrust))
118-
} else {
119-
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, null)
116+
CFRelease(serverCertificateRef)
117+
CFRelease(certificateDataRef)
118+
CFRelease(certificateRef)
119+
CFRelease(policyRef)
120+
CFRelease(mutableArrayRef)
120121
}
121-
122-
CFRelease(serverCertificateRef)
123-
CFRelease(certificateDataRef)
124-
CFRelease(certificateRef)
125-
CFRelease(policyRef)
126-
CFRelease(mutableArrayRef)
127122
}
128123
}
129-
}
124+
}

regions/src/tvosMain/kotlin/com/privateinternetaccess/regions/internals/RegionsDataSourceFactoryImpl.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ internal actual class RegionsDataSourceFactoryImpl actual constructor(
77
private val logErrors: Boolean
88
): RegionsDataSourceFactory {
99

10-
override fun newInMemoryDataSource(): RegionsCacheDataSource =
10+
actual override fun newInMemoryDataSource(): RegionsCacheDataSource =
1111
InMemoryRegionsCacheDataSource()
1212

13-
override fun newPersistenceRegionsDataSource(
13+
actual override fun newPersistenceRegionsDataSource(
1414
preferenceName: String?
1515
): RegionsCacheDataSource = PersistenceRegionsDataSource(
1616
preferenceName = preferenceName,

0 commit comments

Comments
 (0)