OpenVPN OTP is persisted with the password (#785)

Encode OpenVPN password + OTP in tunnel rather than in the app.

Encoding them upfront in the app ends up persisting the profile with the
combined password. Update the library with a new OTP field in
OpenVPN.Credentials, so that the password encoding is performed [on the
fly in the
tunnel](https://github.com/passepartoutvpn/passepartoutkit-source/pull/398).
Similar to how provider modules are generated.

This is likely a regression caused by migrating to NEProfileRepository,
because starting a connection causes the profile to be saved to NE with
the encoded password. Later, the profile is restored from NE and
therefore contains the encoded password.
This commit is contained in:
Davide 2024-10-30 17:07:59 +01:00 committed by GitHub
parent 9a365703c5
commit bb8c760278
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 18 additions and 14 deletions

View File

@ -41,7 +41,7 @@
"kind" : "remoteSourceControl", "kind" : "remoteSourceControl",
"location" : "git@github.com:passepartoutvpn/passepartoutkit-source", "location" : "git@github.com:passepartoutvpn/passepartoutkit-source",
"state" : { "state" : {
"revision" : "7426954e8ec84e6ddf6c8cd415bfa2c5c7064534" "revision" : "8b4c47f716120fab3f219593cf4ae0e6e2c86677"
} }
}, },
{ {

View File

@ -36,7 +36,7 @@ let package = Package(
], ],
dependencies: [ dependencies: [
// .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source", from: "0.9.0"), // .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source", from: "0.9.0"),
.package(url: "git@github.com:passepartoutvpn/passepartoutkit-source", revision: "7426954e8ec84e6ddf6c8cd415bfa2c5c7064534"), .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source", revision: "8b4c47f716120fab3f219593cf4ae0e6e2c86677"),
// .package(path: "../../../passepartoutkit-source"), // .package(path: "../../../passepartoutkit-source"),
.package(url: "git@github.com:passepartoutvpn/passepartoutkit-source-openvpn-openssl", from: "0.9.1"), .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source-openvpn-openssl", from: "0.9.1"),
// .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source-openvpn-openssl", revision: "031863a1cd683962a7dfe68e20b91fa820a1ecce"), // .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source-openvpn-openssl", revision: "031863a1cd683962a7dfe68e20b91fa820a1ecce"),

View File

@ -25,6 +25,7 @@
import PassepartoutKit import PassepartoutKit
import SwiftUI import SwiftUI
import UtilsLibrary
extension OpenVPNView { extension OpenVPNView {
struct CredentialsView: View { struct CredentialsView: View {
@ -43,9 +44,6 @@ extension OpenVPNView {
@State @State
private var builder = OpenVPN.Credentials.Builder() private var builder = OpenVPN.Credentials.Builder()
@State
private var otp = ""
@State @State
private var paywallReason: PaywallReason? private var paywallReason: PaywallReason?
@ -60,16 +58,17 @@ extension OpenVPNView {
.navigationTitle(Strings.Modules.Openvpn.credentials) .navigationTitle(Strings.Modules.Openvpn.credentials)
.onLoad { .onLoad {
builder = credentials?.builder() ?? OpenVPN.Credentials.Builder() builder = credentials?.builder() ?? OpenVPN.Credentials.Builder()
builder.otp = nil
} }
.onChange(of: builder) { .onChange(of: builder) {
if isEligibleForInteractiveLogin, isAuthenticating { var copy = $0
credentials = $0.buildForAuthentication(otp: otp) if isEligibleForInteractiveLogin {
copy.otp = copy.otp?.nilIfEmpty
} else { } else {
credentials = $0.build() copy.otpMethod = .none
copy.otp = nil
} }
} credentials = copy.build()
.onChange(of: otp) {
credentials = builder.buildForAuthentication(otp: $0)
} }
.modifier(PaywallModifier(reason: $paywallReason)) .modifier(PaywallModifier(reason: $paywallReason))
} }
@ -135,9 +134,13 @@ private extension OpenVPNView.CredentialsView {
ThemeSecureField(title: Strings.Global.password, text: $builder.password, placeholder: Strings.Placeholders.secret) ThemeSecureField(title: Strings.Global.password, text: $builder.password, placeholder: Strings.Placeholders.secret)
.textContentType(.password) .textContentType(.password)
if isEligibleForInteractiveLogin, isAuthenticating && builder.otpMethod != .none { if isEligibleForInteractiveLogin, isAuthenticating, builder.otpMethod != .none {
ThemeSecureField(title: Strings.Unlocalized.otp, text: $otp, placeholder: Strings.Placeholders.secret) ThemeSecureField(
.textContentType(.oneTimeCode) title: Strings.Unlocalized.otp,
text: $builder.otp ?? "",
placeholder: Strings.Placeholders.secret
)
.textContentType(.oneTimeCode)
} }
} }
.themeSection(footer: inputFooter) .themeSection(footer: inputFooter)
@ -146,6 +149,7 @@ private extension OpenVPNView.CredentialsView {
var inputFooter: String? { var inputFooter: String? {
if isAuthenticating { if isAuthenticating {
return builder.otpMethod.localizedDescription(style: .approachDescription) return builder.otpMethod.localizedDescription(style: .approachDescription)
.nilIfEmpty
} }
return nil return nil
} }