Create OpenVPN module without a configuration (#729)

Update library to allow optional VPN configurations. This in turn allows
a module to be used with a provider, where the configuration is
generated on the fly.
This commit is contained in:
Davide 2024-10-11 19:11:42 +02:00 committed by GitHub
parent c96e7e9d6e
commit 208198c3f8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 28 additions and 21 deletions

View File

@ -41,7 +41,8 @@
"kind" : "remoteSourceControl", "kind" : "remoteSourceControl",
"location" : "git@github.com:passepartoutvpn/passepartoutkit-source", "location" : "git@github.com:passepartoutvpn/passepartoutkit-source",
"state" : { "state" : {
"revision" : "bec0635fe047e09c8b6c894d103ab8dd741b8340" "revision" : "126392d2614c9d0ffe2aa2d96f6c5509221b8481",
"version" : "0.9.0"
} }
}, },
{ {
@ -58,8 +59,8 @@
"kind" : "remoteSourceControl", "kind" : "remoteSourceControl",
"location" : "git@github.com:passepartoutvpn/passepartoutkit-source-wireguard-go", "location" : "git@github.com:passepartoutvpn/passepartoutkit-source-wireguard-go",
"state" : { "state" : {
"revision" : "ea39fa396e98cfd2b9a235f0a801aaf03a37e30a", "revision" : "4f766400057b3c8a3ceb7cfce4950393e292858e",
"version" : "0.8.0" "version" : "0.9.0"
} }
}, },
{ {

View File

@ -27,14 +27,14 @@ let package = Package(
) )
], ],
dependencies: [ dependencies: [
// .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source", from: "0.8.0"), .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source", from: "0.9.0"),
.package(url: "git@github.com:passepartoutvpn/passepartoutkit-source", revision: "bec0635fe047e09c8b6c894d103ab8dd741b8340"), // .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source", revision: "bec0635fe047e09c8b6c894d103ab8dd741b8340"),
// .package(path: "../../../passepartoutkit-source"), // .package(path: "../../../passepartoutkit-source"),
.package(url: "git@github.com:passepartoutvpn/passepartoutkit-source-openvpn-openssl", from: "0.8.0"), .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source-openvpn-openssl", from: "0.8.0"),
// .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source-openvpn-openssl", revision: "031863a1cd683962a7dfe68e20b91fa820a1ecce"), // .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source-openvpn-openssl", revision: "031863a1cd683962a7dfe68e20b91fa820a1ecce"),
// .package(path: "../../../passepartoutkit-source-openvpn-openssl"), // .package(path: "../../../passepartoutkit-source-openvpn-openssl"),
.package(url: "git@github.com:passepartoutvpn/passepartoutkit-source-wireguard-go", from: "0.8.0"), .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source-wireguard-go", from: "0.9.0"),
// .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source-wireguard-go", revision: "ea39fa396e98cfd2b9a235f0a801aaf03a37e30a"), // .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source-wireguard-go", revision: "ea39fa396e98cfd2b9a235f0a801aaf03a37e30a"),
// .package(path: "../../../passepartoutkit-source-wireguard-go"), // .package(path: "../../../passepartoutkit-source-wireguard-go"),
.package(url: "https://github.com/Cocoanetics/Kvitto", from: "1.0.0") .package(url: "https://github.com/Cocoanetics/Kvitto", from: "1.0.0")
], ],

View File

@ -117,8 +117,8 @@ extension Profile {
do { do {
var ovpn = OpenVPNModule.Builder() var ovpn = OpenVPNModule.Builder()
ovpn.configurationBuilder = OpenVPN.Configuration.Builder(withFallbacks: true) ovpn.configurationBuilder = OpenVPN.Configuration.Builder(withFallbacks: true)
ovpn.configurationBuilder.ca = .init(pem: "some CA") ovpn.configurationBuilder?.ca = .init(pem: "some CA")
ovpn.configurationBuilder.remotes = [ ovpn.configurationBuilder?.remotes = [
try .init("1.2.3.4", .init(.udp, 80)) try .init("1.2.3.4", .init(.udp, 80))
] ]
profile.modules.append(try ovpn.tryBuild()) profile.modules.append(try ovpn.tryBuild())

View File

@ -93,11 +93,12 @@ struct OpenVPNView: View {
private extension OpenVPNView { private extension OpenVPNView {
var configuration: OpenVPN.Configuration.Builder { var configuration: OpenVPN.Configuration.Builder {
draft.configurationBuilder draft.configurationBuilder ?? .init(withFallbacks: true)
} }
var providerModifier: some ViewModifier { var providerModifier: some ViewModifier {
ProviderPanelModifier( ProviderPanelModifier(
isRequired: draft.configurationBuilder == nil,
providerId: $providerId, providerId: $providerId,
selectedEntity: $providerEntity, selectedEntity: $providerEntity,
providerContent: providerContentView providerContent: providerContentView

View File

@ -23,6 +23,7 @@
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>. // along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
// //
import CommonLibrary
import PassepartoutKit import PassepartoutKit
import PassepartoutWireGuardGo import PassepartoutWireGuardGo
import SwiftUI import SwiftUI
@ -75,7 +76,7 @@ private struct WireGuardView: View {
private extension WireGuardView { private extension WireGuardView {
var configuration: WireGuard.Configuration.Builder { var configuration: WireGuard.Configuration.Builder {
draft.configurationBuilder draft.configurationBuilder ?? .default
} }
@ViewBuilder @ViewBuilder

View File

@ -34,6 +34,8 @@ struct ProviderPanelModifier<Entity, ProviderContent>: ViewModifier where Entity
var apis: [APIMapper] = API.shared var apis: [APIMapper] = API.shared
let isRequired: Bool
@Binding @Binding
var providerId: ProviderID? var providerId: ProviderID?
@ -51,7 +53,7 @@ struct ProviderPanelModifier<Entity, ProviderContent>: ViewModifier where Entity
if let providerId { if let providerId {
providerContent(providerId, selectedEntity) providerContent(providerId, selectedEntity)
} else { } else if !isRequired {
content content
} }
} }
@ -64,17 +66,15 @@ private extension ProviderPanelModifier {
} }
} }
var providersPlusEmpty: [ProviderMetadata] {
[ProviderMetadata("", description: Strings.Global.none)] + supportedProviders
}
var providerPicker: some View { var providerPicker: some View {
let hasProviders = !supportedProviders.isEmpty let hasProviders = !supportedProviders.isEmpty
return Picker(Strings.Global.provider, selection: $providerId) { return Picker(Strings.Global.provider, selection: $providerId) {
if hasProviders { if hasProviders {
ForEach(providersPlusEmpty, id: \.id) { Text(Strings.Global.none)
.tag(nil as ProviderID?)
ForEach(supportedProviders, id: \.id) {
Text($0.description) Text($0.description)
.tag($0.id.nilIfEmpty) .tag($0.id as ProviderID?)
} }
} else { } else {
Text(" ") // enforce constant picker height on iOS Text(" ") // enforce constant picker height on iOS
@ -120,9 +120,10 @@ private extension ProviderID {
EmptyView() EmptyView()
.modifier(ProviderPanelModifier( .modifier(ProviderPanelModifier(
apis: [API.bundled], apis: [API.bundled],
isRequired: false,
providerId: $providerId, providerId: $providerId,
selectedEntity: $vpnEntity, selectedEntity: $vpnEntity,
providerContent: { id, entity in providerContent: { _, entity in
HStack { HStack {
Text("Server") Text("Server")
Spacer() Spacer()

View File

@ -37,8 +37,11 @@ extension Registry {
dns: CFDNSResolver(), dns: CFDNSResolver(),
importer: StandardOpenVPNParser(decrypter: OSSLTLSBox()), importer: StandardOpenVPNParser(decrypter: OSSLTLSBox()),
sessionBlock: { _, module in sessionBlock: { _, module in
try OpenVPNSession( guard let configuration = module.configuration else {
configuration: module.configuration, fatalError("Creating session without OpenVPN configuration?")
}
return try OpenVPNSession(
configuration: configuration,
credentials: module.credentials, credentials: module.credentials,
prng: SecureRandom(), prng: SecureRandom(),
tlsFactory: { tlsFactory: {