Migrate profiles routing policies

- Providers: enforce all (IPv4 + IPv6)
- Hosts: re-read .ovpn on app update, fall back to all (safer)

Reload hosts in order to re-interpret "redirect-gateway".
This commit is contained in:
Davide De Rosa 2019-04-25 14:54:09 +02:00
parent b3a509fbea
commit 04c2191e83
3 changed files with 62 additions and 5 deletions

View File

@ -265,22 +265,22 @@ public class ConnectionService: Codable {
case .provider: case .provider:
let providerProfile = try decoder.decode(ProviderConnectionProfile.self, from: data) let providerProfile = try decoder.decode(ProviderConnectionProfile.self, from: data)
// fix renamed presets, fall back to default // XXX: fix renamed presets, fall back to default
if providerProfile.preset == nil { if providerProfile.preset == nil {
providerProfile.presetId = providerProfile.infrastructure.defaults.preset providerProfile.presetId = providerProfile.infrastructure.defaults.preset
} }
// fix renamed pool, fall back to default // XXX: fix renamed pool, fall back to default
if providerProfile.pool == nil, let fallbackPool = providerProfile.infrastructure.defaultPool() { if providerProfile.pool == nil, let fallbackPool = providerProfile.infrastructure.defaultPool() {
providerProfile.poolId = fallbackPool.id providerProfile.poolId = fallbackPool.id
} }
profile = providerProfile profile = providerProfile
case .host: case .host:
let hostProfile = try decoder.decode(HostConnectionProfile.self, from: data) let hostProfile = try decoder.decode(HostConnectionProfile.self, from: data)
// migrate old endpointProtocols // XXX: migrate old endpointProtocols
if hostProfile.parameters.sessionConfiguration.endpointProtocols == nil { if hostProfile.parameters.sessionConfiguration.endpointProtocols == nil {
var sessionBuilder = hostProfile.parameters.sessionConfiguration.builder() var sessionBuilder = hostProfile.parameters.sessionConfiguration.builder()
sessionBuilder.endpointProtocols = hostProfile.parameters.endpointProtocols sessionBuilder.endpointProtocols = hostProfile.parameters.endpointProtocols
@ -288,6 +288,8 @@ public class ConnectionService: Codable {
parametersBuilder.sessionConfiguration = sessionBuilder.build() parametersBuilder.sessionConfiguration = sessionBuilder.build()
hostProfile.parameters = parametersBuilder.build() hostProfile.parameters = parametersBuilder.build()
} }
// XXX: re-read routing policies for
profile = hostProfile profile = hostProfile
} }
@ -329,6 +331,37 @@ public class ConnectionService: Codable {
return url.deletingPathExtension().lastPathComponent return url.deletingPathExtension().lastPathComponent
} }
func reloadHostProfilesFromConfigurationFiles() -> Bool {
var anyReloaded = false
for entry in cache {
guard entry.value.context == .host else {
continue
}
guard let host = profile(withKey: entry.key) as? HostConnectionProfile else {
log.warning("Host context but not a HostConnectionProfile?")
continue
}
guard let url = configurationURL(for: entry.key) else {
continue
}
// can fail due to passphrase (migration is non-interactive)
if let result = try? ConfigurationParser.parsed(fromURL: url) {
host.parameters = TunnelKitProvider.ConfigurationBuilder(sessionConfiguration: result.configuration).build()
} else {
// fall back to the safer option
var builder = host.parameters.builder()
builder.sessionConfiguration.routingPolicies = [.IPv4, .IPv6]
host.parameters = builder.build()
}
cache[entry.key] = host
anyReloaded = true
}
return anyReloaded
}
// MARK: Profiles // MARK: Profiles
public func hasProfiles() -> Bool { public func hasProfiles() -> Bool {

View File

@ -34,6 +34,10 @@ public class TransientStore {
static let didHandleSubreddit = "DidHandleSubreddit" static let didHandleSubreddit = "DidHandleSubreddit"
static let masksPrivateData = "MasksPrivateData" static let masksPrivateData = "MasksPrivateData"
// migrations
static let didMigrateHostsRoutingPolicies = "DidMigrateHostsRoutingPolicies"
} }
public static let shared = TransientStore() public static let shared = TransientStore()
@ -62,6 +66,15 @@ public class TransientStore {
} }
} }
public static var didMigrateHostsRoutingPolicies: Bool {
get {
return UserDefaults.standard.bool(forKey: Keys.didMigrateHostsRoutingPolicies)
}
set {
UserDefaults.standard.set(newValue, forKey: Keys.didMigrateHostsRoutingPolicies)
}
}
public static var baseVPNConfiguration: TunnelKitProvider.ConfigurationBuilder { public static var baseVPNConfiguration: TunnelKitProvider.ConfigurationBuilder {
let sessionBuilder = SessionProxy.ConfigurationBuilder() let sessionBuilder = SessionProxy.ConfigurationBuilder()
var builder = TunnelKitProvider.ConfigurationBuilder(sessionConfiguration: sessionBuilder.build()) var builder = TunnelKitProvider.ConfigurationBuilder(sessionConfiguration: sessionBuilder.build())
@ -84,7 +97,7 @@ public class TransientStore {
// this must be graceful // this must be graceful
ConnectionService.migrateJSON(from: TransientStore.serviceURL, to: TransientStore.serviceURL) ConnectionService.migrateJSON(from: TransientStore.serviceURL, to: TransientStore.serviceURL)
let cfg = TransientStore.baseVPNConfiguration.build() let cfg = TransientStore.baseVPNConfiguration.build()
do { do {
let data = try Data(contentsOf: TransientStore.serviceURL) let data = try Data(contentsOf: TransientStore.serviceURL)
@ -95,6 +108,14 @@ public class TransientStore {
service = try JSONDecoder().decode(ConnectionService.self, from: data) service = try JSONDecoder().decode(ConnectionService.self, from: data)
service.baseConfiguration = cfg service.baseConfiguration = cfg
service.loadProfiles() service.loadProfiles()
// do migrations
if !TransientStore.didMigrateHostsRoutingPolicies {
if service.reloadHostProfilesFromConfigurationFiles() {
service.saveProfiles()
}
TransientStore.didMigrateHostsRoutingPolicies = true
}
} catch let e { } catch let e {
log.error("Could not decode service: \(e)") log.error("Could not decode service: \(e)")
service = ConnectionService( service = ConnectionService(

View File

@ -162,6 +162,9 @@ public struct InfrastructurePreset: Codable {
sessionBuilder.randomizeEndpoint = try cfgContainer.decodeIfPresent(Bool.self, forKey: .randomizeEndpoint) ?? false sessionBuilder.randomizeEndpoint = try cfgContainer.decodeIfPresent(Bool.self, forKey: .randomizeEndpoint) ?? false
sessionBuilder.usesPIAPatches = try cfgContainer.decodeIfPresent(Bool.self, forKey: .usesPIAPatches) ?? false sessionBuilder.usesPIAPatches = try cfgContainer.decodeIfPresent(Bool.self, forKey: .usesPIAPatches) ?? false
// XXX: redirect everything through the VPN for providers
sessionBuilder.routingPolicies = [.IPv4, .IPv6]
let builder = TunnelKitProvider.ConfigurationBuilder(sessionConfiguration: sessionBuilder.build()) let builder = TunnelKitProvider.ConfigurationBuilder(sessionConfiguration: sessionBuilder.build())
configuration = builder.build() configuration = builder.build()
} }