forked from core/mobile_nebula
Run check config on app boot, fix early error reporting on android
This commit is contained in:
parent
50d50f690b
commit
1a4cbceda0
|
@ -2,11 +2,12 @@ package net.defined.mobile_nebula
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.ServiceConnection
|
import android.content.ServiceConnection
|
||||||
import android.net.VpnService
|
import android.net.VpnService
|
||||||
import android.os.*
|
import android.os.*
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import io.flutter.embedding.android.FlutterActivity
|
import io.flutter.embedding.android.FlutterActivity
|
||||||
import io.flutter.embedding.engine.FlutterEngine
|
import io.flutter.embedding.engine.FlutterEngine
|
||||||
|
@ -28,9 +29,15 @@ class MainActivity: FlutterActivity() {
|
||||||
|
|
||||||
private var activeSiteId: String? = null
|
private var activeSiteId: String? = null
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private var appContext: Context? = null
|
||||||
|
fun getContext(): Context? { return appContext }
|
||||||
|
}
|
||||||
|
|
||||||
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
|
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
|
||||||
|
appContext = context
|
||||||
//TODO: Initializing in the constructor leads to a context lacking info we need, figure out the right way to do this
|
//TODO: Initializing in the constructor leads to a context lacking info we need, figure out the right way to do this
|
||||||
sites = Sites(context, flutterEngine)
|
sites = Sites(flutterEngine)
|
||||||
|
|
||||||
// Bind against our service to detect which site is running on app boot
|
// Bind against our service to detect which site is running on app boot
|
||||||
val intent = Intent(this, NebulaVpnService::class.java)
|
val intent = Intent(this, NebulaVpnService::class.java)
|
||||||
|
@ -153,7 +160,7 @@ class MainActivity: FlutterActivity() {
|
||||||
intent.putExtra("id", siteContainer.site.id)
|
intent.putExtra("id", siteContainer.site.id)
|
||||||
onActivityResult(VPN_START_CODE, Activity.RESULT_OK, intent)
|
onActivityResult(VPN_START_CODE, Activity.RESULT_OK, intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
result.success(null)
|
result.success(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,28 +43,37 @@ class NebulaVpnService : VpnService() {
|
||||||
return Service.START_NOT_STICKY
|
return Service.START_NOT_STICKY
|
||||||
}
|
}
|
||||||
|
|
||||||
startVpn(intent?.getStringExtra("path"), intent?.getStringExtra("id"))
|
val path = intent?.getStringExtra("path")
|
||||||
return super.onStartCommand(intent, flags, startId)
|
val id = intent?.getStringExtra("id")
|
||||||
}
|
|
||||||
|
|
||||||
private fun startVpn(path: String?, id: String?) {
|
|
||||||
if (running) {
|
if (running) {
|
||||||
return announceExit(id, "Trying to run nebula but it is already running")
|
announceExit(id, "Trying to run nebula but it is already running")
|
||||||
|
//TODO: can we signal failure?
|
||||||
|
return super.onStartCommand(intent, flags, startId)
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: if we fail to start, android will attempt a restart lacking all the intent data we need.
|
//TODO: if we fail to start, android will attempt a restart lacking all the intent data we need.
|
||||||
// Link active site config in Main to avoid this
|
// Link active site config in Main to avoid this
|
||||||
site = Site(File(path))
|
site = Site(File(path))
|
||||||
var ipNet: CIDR
|
|
||||||
|
|
||||||
if (site!!.cert == null) {
|
if (site!!.cert == null) {
|
||||||
return announceExit(id, "Site is missing a certificate")
|
announceExit(id, "Site is missing a certificate")
|
||||||
|
//TODO: can we signal failure?
|
||||||
|
return super.onStartCommand(intent, flags, startId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We don't actually start here. In order to properly capture boot errors we wait until an IPC connection is made
|
||||||
|
|
||||||
|
return super.onStartCommand(intent, flags, startId)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startVpn() {
|
||||||
|
var ipNet: CIDR
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ipNet = mobileNebula.MobileNebula.parseCIDR(site!!.cert!!.cert.details.ips[0])
|
ipNet = mobileNebula.MobileNebula.parseCIDR(site!!.cert!!.cert.details.ips[0])
|
||||||
} catch (err: Exception) {
|
} catch (err: Exception) {
|
||||||
return announceExit(id, err.message ?: "$err")
|
return announceExit(site!!.id, err.message ?: "$err")
|
||||||
}
|
}
|
||||||
|
|
||||||
val builder = Builder()
|
val builder = Builder()
|
||||||
|
@ -91,7 +100,7 @@ class NebulaVpnService : VpnService() {
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Got an error $e")
|
Log.e(TAG, "Got an error $e")
|
||||||
vpnInterface?.close()
|
vpnInterface?.close()
|
||||||
announceExit(id, e.message)
|
announceExit(site!!.id, e.message)
|
||||||
return stopSelf()
|
return stopSelf()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +139,7 @@ class NebulaVpnService : VpnService() {
|
||||||
//TODO: how do we limit what can talk to us?
|
//TODO: how do we limit what can talk to us?
|
||||||
//TODO: Make sure replyTo is actually a messenger
|
//TODO: Make sure replyTo is actually a messenger
|
||||||
when (msg.what) {
|
when (msg.what) {
|
||||||
MSG_REGISTER_CLIENT -> mClients.add(msg.replyTo)
|
MSG_REGISTER_CLIENT -> register(msg)
|
||||||
MSG_UNREGISTER_CLIENT -> mClients.remove(msg.replyTo)
|
MSG_UNREGISTER_CLIENT -> mClients.remove(msg.replyTo)
|
||||||
MSG_IS_RUNNING -> isRunning()
|
MSG_IS_RUNNING -> isRunning()
|
||||||
MSG_LIST_HOSTMAP -> listHostmap(msg)
|
MSG_LIST_HOSTMAP -> listHostmap(msg)
|
||||||
|
@ -142,11 +151,29 @@ class NebulaVpnService : VpnService() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun register(msg: Message) {
|
||||||
|
mClients.add(msg.replyTo)
|
||||||
|
if (!running) {
|
||||||
|
startVpn()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun protect(msg: Message): Boolean {
|
||||||
|
if (nebula != null) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.replyTo.send(Message.obtain(null, msg.what))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
private fun isRunning() {
|
private fun isRunning() {
|
||||||
sendSimple(MSG_IS_RUNNING, if (running) 1 else 0)
|
sendSimple(MSG_IS_RUNNING, if (running) 1 else 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun listHostmap(msg: Message) {
|
private fun listHostmap(msg: Message) {
|
||||||
|
if (protect(msg)) { return }
|
||||||
|
|
||||||
val res = nebula!!.listHostmap(msg.what == MSG_LIST_PENDING_HOSTMAP)
|
val res = nebula!!.listHostmap(msg.what == MSG_LIST_PENDING_HOSTMAP)
|
||||||
var m = Message.obtain(null, msg.what)
|
var m = Message.obtain(null, msg.what)
|
||||||
m.data.putString("data", res)
|
m.data.putString("data", res)
|
||||||
|
@ -154,6 +181,8 @@ class NebulaVpnService : VpnService() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getHostInfo(msg: Message) {
|
private fun getHostInfo(msg: Message) {
|
||||||
|
if (protect(msg)) { return }
|
||||||
|
|
||||||
val res = nebula!!.getHostInfoByVpnIp(msg.data.getString("vpnIp"), msg.data.getBoolean("pending"))
|
val res = nebula!!.getHostInfoByVpnIp(msg.data.getString("vpnIp"), msg.data.getBoolean("pending"))
|
||||||
var m = Message.obtain(null, msg.what)
|
var m = Message.obtain(null, msg.what)
|
||||||
m.data.putString("data", res)
|
m.data.putString("data", res)
|
||||||
|
@ -161,6 +190,8 @@ class NebulaVpnService : VpnService() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setRemoteForTunnel(msg: Message) {
|
private fun setRemoteForTunnel(msg: Message) {
|
||||||
|
if (protect(msg)) { return }
|
||||||
|
|
||||||
val res = nebula!!.setRemoteForTunnel(msg.data.getString("vpnIp"), msg.data.getString("addr"))
|
val res = nebula!!.setRemoteForTunnel(msg.data.getString("vpnIp"), msg.data.getString("addr"))
|
||||||
var m = Message.obtain(null, msg.what)
|
var m = Message.obtain(null, msg.what)
|
||||||
m.data.putString("data", res)
|
m.data.putString("data", res)
|
||||||
|
@ -168,6 +199,8 @@ class NebulaVpnService : VpnService() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun closeTunnel(msg: Message) {
|
private fun closeTunnel(msg: Message) {
|
||||||
|
if (protect(msg)) { return }
|
||||||
|
|
||||||
val res = nebula!!.closeTunnel(msg.data.getString("vpnIp"))
|
val res = nebula!!.closeTunnel(msg.data.getString("vpnIp"))
|
||||||
var m = Message.obtain(null, msg.what)
|
var m = Message.obtain(null, msg.what)
|
||||||
m.data.putBoolean("data", res)
|
m.data.putBoolean("data", res)
|
||||||
|
|
|
@ -15,7 +15,7 @@ data class SiteContainer(
|
||||||
val updater: SiteUpdater
|
val updater: SiteUpdater
|
||||||
)
|
)
|
||||||
|
|
||||||
class Sites(private var context: Context, private var engine: FlutterEngine) {
|
class Sites(private var engine: FlutterEngine) {
|
||||||
private var sites: HashMap<String, SiteContainer> = HashMap()
|
private var sites: HashMap<String, SiteContainer> = HashMap()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@ -23,6 +23,7 @@ class Sites(private var context: Context, private var engine: FlutterEngine) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun refreshSites(activeSite: String? = null) {
|
fun refreshSites(activeSite: String? = null) {
|
||||||
|
val context = MainActivity.getContext()!!
|
||||||
val sitesDir = context.filesDir.resolve("sites")
|
val sitesDir = context.filesDir.resolve("sites")
|
||||||
if (!sitesDir.isDirectory) {
|
if (!sitesDir.isDirectory) {
|
||||||
sitesDir.delete()
|
sitesDir.delete()
|
||||||
|
@ -57,7 +58,7 @@ class Sites(private var context: Context, private var engine: FlutterEngine) {
|
||||||
|
|
||||||
fun deleteSite(id: String) {
|
fun deleteSite(id: String) {
|
||||||
sites.remove(id)
|
sites.remove(id)
|
||||||
val siteDir = context.filesDir.resolve("sites").resolve(id)
|
val siteDir = MainActivity.getContext()!!.filesDir.resolve("sites").resolve(id)
|
||||||
siteDir.deleteRecursively()
|
siteDir.deleteRecursively()
|
||||||
//TODO: make sure you stop the vpn
|
//TODO: make sure you stop the vpn
|
||||||
//TODO: make sure you relink the active site if this is the active site
|
//TODO: make sure you relink the active site if this is the active site
|
||||||
|
@ -77,7 +78,6 @@ class SiteUpdater(private var site: Site, engine: FlutterEngine): EventChannel.S
|
||||||
site.connected = connected
|
site.connected = connected
|
||||||
site.status = status
|
site.status = status
|
||||||
val d = mapOf("connected" to site.connected, "status" to site.status)
|
val d = mapOf("connected" to site.connected, "status" to site.status)
|
||||||
|
|
||||||
if (err != null) {
|
if (err != null) {
|
||||||
eventSink?.error("", err, d)
|
eventSink?.error("", err, d)
|
||||||
} else {
|
} else {
|
||||||
|
@ -209,6 +209,14 @@ class Site {
|
||||||
ca = arrayOf()
|
ca = arrayOf()
|
||||||
errors.add("Error while loading certificate authorities: ${err.message}")
|
errors.add("Error while loading certificate authorities: ${err.message}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (errors.isEmpty()) {
|
||||||
|
try {
|
||||||
|
mobileNebula.MobileNebula.testConfig(config, getKey(MainActivity.getContext()!!))
|
||||||
|
} catch (err: Exception) {
|
||||||
|
errors.add("Config test error: ${err.message}")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getKey(context: Context): String? {
|
fun getKey(context: Context): String? {
|
||||||
|
|
|
@ -173,9 +173,9 @@ struct Site: Codable {
|
||||||
|
|
||||||
init(proto: NETunnelProviderProtocol) throws {
|
init(proto: NETunnelProviderProtocol) throws {
|
||||||
let dict = proto.providerConfiguration
|
let dict = proto.providerConfiguration
|
||||||
let rawConfig = dict?["config"] as? Data ?? Data()
|
let config = dict?["config"] as? Data ?? Data()
|
||||||
let decoder = JSONDecoder()
|
let decoder = JSONDecoder()
|
||||||
let incoming = try decoder.decode(IncomingSite.self, from: rawConfig)
|
let incoming = try decoder.decode(IncomingSite.self, from: config)
|
||||||
self.init(incoming: incoming)
|
self.init(incoming: incoming)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,6 +241,22 @@ struct Site: Codable {
|
||||||
logVerbosity = incoming.logVerbosity ?? "info"
|
logVerbosity = incoming.logVerbosity ?? "info"
|
||||||
mtu = incoming.mtu ?? 1300
|
mtu = incoming.mtu ?? 1300
|
||||||
logFile = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.net.defined.mobileNebula")?.appendingPathComponent(id).appendingPathExtension("log").path
|
logFile = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.net.defined.mobileNebula")?.appendingPathComponent(id).appendingPathExtension("log").path
|
||||||
|
|
||||||
|
if (errors.isEmpty) {
|
||||||
|
do {
|
||||||
|
let encoder = JSONEncoder()
|
||||||
|
let rawConfig = try encoder.encode(incoming)
|
||||||
|
let key = try getKey()
|
||||||
|
let strConfig = String(data: rawConfig, encoding: .utf8)
|
||||||
|
var err: NSError?
|
||||||
|
MobileNebulaTestConfig(strConfig, key, &err)
|
||||||
|
if (err != nil) {
|
||||||
|
throw err!
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
errors.append("Config test error: \(error.localizedDescription)")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the private key from the keystore, we don't always need it in memory
|
// Gets the private key from the keystore, we don't always need it in memory
|
||||||
|
|
|
@ -529,7 +529,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 0.0.31;
|
MARKETING_VERSION = 0.0.33;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = net.defined.mobileNebula;
|
PRODUCT_BUNDLE_IDENTIFIER = net.defined.mobileNebula;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
|
@ -559,7 +559,7 @@
|
||||||
INFOPLIST_FILE = NebulaNetworkExtension/Info.plist;
|
INFOPLIST_FILE = NebulaNetworkExtension/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 13.2;
|
IPHONEOS_DEPLOYMENT_TARGET = 13.2;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||||
MARKETING_VERSION = 0.0.31;
|
MARKETING_VERSION = 0.0.33;
|
||||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
OTHER_LDFLAGS = "";
|
OTHER_LDFLAGS = "";
|
||||||
|
@ -594,7 +594,7 @@
|
||||||
INFOPLIST_FILE = NebulaNetworkExtension/Info.plist;
|
INFOPLIST_FILE = NebulaNetworkExtension/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 13.2;
|
IPHONEOS_DEPLOYMENT_TARGET = 13.2;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||||
MARKETING_VERSION = 0.0.31;
|
MARKETING_VERSION = 0.0.33;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
OTHER_LDFLAGS = "";
|
OTHER_LDFLAGS = "";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = net.defined.mobileNebula.NebulaNetworkExtension;
|
PRODUCT_BUNDLE_IDENTIFIER = net.defined.mobileNebula.NebulaNetworkExtension;
|
||||||
|
@ -626,7 +626,7 @@
|
||||||
INFOPLIST_FILE = NebulaNetworkExtension/Info.plist;
|
INFOPLIST_FILE = NebulaNetworkExtension/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 13.2;
|
IPHONEOS_DEPLOYMENT_TARGET = 13.2;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||||
MARKETING_VERSION = 0.0.31;
|
MARKETING_VERSION = 0.0.33;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
OTHER_LDFLAGS = "";
|
OTHER_LDFLAGS = "";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = net.defined.mobileNebula.NebulaNetworkExtension;
|
PRODUCT_BUNDLE_IDENTIFIER = net.defined.mobileNebula.NebulaNetworkExtension;
|
||||||
|
@ -768,7 +768,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 0.0.31;
|
MARKETING_VERSION = 0.0.33;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = net.defined.mobileNebula;
|
PRODUCT_BUNDLE_IDENTIFIER = net.defined.mobileNebula;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
|
@ -801,7 +801,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 0.0.31;
|
MARKETING_VERSION = 0.0.33;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = net.defined.mobileNebula;
|
PRODUCT_BUNDLE_IDENTIFIER = net.defined.mobileNebula;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
|
|
|
@ -27,8 +27,6 @@
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
<Testables>
|
|
||||||
</Testables>
|
|
||||||
<MacroExpansion>
|
<MacroExpansion>
|
||||||
<BuildableReference
|
<BuildableReference
|
||||||
BuildableIdentifier = "primary"
|
BuildableIdentifier = "primary"
|
||||||
|
@ -38,8 +36,8 @@
|
||||||
ReferencedContainer = "container:Runner.xcodeproj">
|
ReferencedContainer = "container:Runner.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</MacroExpansion>
|
</MacroExpansion>
|
||||||
<AdditionalOptions>
|
<Testables>
|
||||||
</AdditionalOptions>
|
</Testables>
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
buildConfiguration = "Debug"
|
buildConfiguration = "Debug"
|
||||||
|
@ -61,8 +59,6 @@
|
||||||
ReferencedContainer = "container:Runner.xcodeproj">
|
ReferencedContainer = "container:Runner.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildableProductRunnable>
|
</BuildableProductRunnable>
|
||||||
<AdditionalOptions>
|
|
||||||
</AdditionalOptions>
|
|
||||||
</LaunchAction>
|
</LaunchAction>
|
||||||
<ProfileAction
|
<ProfileAction
|
||||||
buildConfiguration = "Profile"
|
buildConfiguration = "Profile"
|
||||||
|
|
|
@ -3,17 +3,17 @@ package mobileNebula
|
||||||
type config struct {
|
type config struct {
|
||||||
PKI configPKI `yaml:"pki"`
|
PKI configPKI `yaml:"pki"`
|
||||||
StaticHostmap map[string][]string `yaml:"static_host_map"`
|
StaticHostmap map[string][]string `yaml:"static_host_map"`
|
||||||
Lighthouse configLighthouse `yaml:"lighthouse"`
|
Lighthouse configLighthouse `yaml:"lighthouse"`
|
||||||
Listen configListen `yaml:"listen"`
|
Listen configListen `yaml:"listen"`
|
||||||
Punchy configPunchy `yaml:"punchy"`
|
Punchy configPunchy `yaml:"punchy"`
|
||||||
Cipher string `yaml:"cipher"`
|
Cipher string `yaml:"cipher"`
|
||||||
LocalRange string `yaml:"local_range"`
|
LocalRange string `yaml:"local_range"`
|
||||||
SSHD configSSHD `yaml:"sshd"`
|
SSHD configSSHD `yaml:"sshd"`
|
||||||
Tun configTun `yaml:"tun"`
|
Tun configTun `yaml:"tun"`
|
||||||
Logging configLogging `yaml:"logging"`
|
Logging configLogging `yaml:"logging"`
|
||||||
Stats configStats `yaml:"stats"`
|
Stats configStats `yaml:"stats"`
|
||||||
Handshakes configHandshakes `yaml:"handshakes"`
|
Handshakes configHandshakes `yaml:"handshakes"`
|
||||||
Firewall configFirewall `yaml:"firewall"`
|
Firewall configFirewall `yaml:"firewall"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func newConfig() *config {
|
func newConfig() *config {
|
||||||
|
|
|
@ -45,8 +45,10 @@ func NewNebula(configData string, key string, logFile string, tunFd int) (*Nebul
|
||||||
if err != nil {
|
if err != nil {
|
||||||
switch v := err.(type) {
|
switch v := err.(type) {
|
||||||
case nebula.ContextualError:
|
case nebula.ContextualError:
|
||||||
return nil, v.RealError
|
v.Log(l)
|
||||||
|
return nil, v.Unwrap()
|
||||||
default:
|
default:
|
||||||
|
l.WithError(err).Error("Failed to start")
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,7 +83,7 @@ func (n *Nebula) ListHostmap(pending bool) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Nebula) GetHostInfoByVpnIp(vpnIp string, pending bool) (string, error) {
|
func (n *Nebula) GetHostInfoByVpnIp(vpnIp string, pending bool) (string, error) {
|
||||||
b, err := json.Marshal(n.c.GetHostInfoByVpnIp(stringIpToInt(vpnIp), pending))
|
b, err := json.Marshal(n.c.GetHostInfoByVpnIP(stringIpToInt(vpnIp), pending))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -113,4 +115,4 @@ func stringIpToInt(ip string) uint32 {
|
||||||
return binary.BigEndian.Uint32(n[12:16])
|
return binary.BigEndian.Uint32(n[12:16])
|
||||||
}
|
}
|
||||||
return binary.BigEndian.Uint32(n)
|
return binary.BigEndian.Uint32(n)
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,6 +95,7 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/vishvananda/netlink v1.0.1-0.20190522153524-00009fb8606a h1:Bt1IVPhiCDMqwGrc2nnbIN4QKvJGx6SK2NzWBmW00ao=
|
github.com/vishvananda/netlink v1.0.1-0.20190522153524-00009fb8606a h1:Bt1IVPhiCDMqwGrc2nnbIN4QKvJGx6SK2NzWBmW00ao=
|
||||||
github.com/vishvananda/netlink v1.0.1-0.20190522153524-00009fb8606a/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
github.com/vishvananda/netlink v1.0.1-0.20190522153524-00009fb8606a/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
||||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7ZovXvuNyL3XQl8UFofeikI1NW1Gypu7k=
|
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7ZovXvuNyL3XQl8UFofeikI1NW1Gypu7k=
|
||||||
|
@ -156,3 +157,4 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
|
gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
|
||||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package mobileNebula
|
package mobileNebula
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -9,6 +10,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/slackhq/nebula"
|
"github.com/slackhq/nebula"
|
||||||
"github.com/slackhq/nebula/cert"
|
"github.com/slackhq/nebula/cert"
|
||||||
"golang.org/x/crypto/curve25519"
|
"golang.org/x/crypto/curve25519"
|
||||||
|
@ -108,6 +110,39 @@ func RenderConfig(configData string, key string) (string, error) {
|
||||||
return string(finalConfig), nil
|
return string(finalConfig), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConfig(configData string, key string) error {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
fmt.Println("Recovered in f", r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
yamlConfig, err := RenderConfig(configData, key)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
config := nebula.NewConfig()
|
||||||
|
err = config.LoadString(yamlConfig)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to load config: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't want to leak the config into the system logs
|
||||||
|
l := logrus.New()
|
||||||
|
l.SetOutput(bytes.NewBuffer([]byte{}))
|
||||||
|
_, err = nebula.Main(config, true, "", l, nil)
|
||||||
|
if err != nil {
|
||||||
|
switch v := err.(type) {
|
||||||
|
case nebula.ContextualError:
|
||||||
|
return v.Unwrap()
|
||||||
|
default:
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func GetConfigSetting(configData string, setting string) string {
|
func GetConfigSetting(configData string, setting string) string {
|
||||||
config := nebula.NewConfig()
|
config := nebula.NewConfig()
|
||||||
config.LoadString(configData)
|
config.LoadString(configData)
|
||||||
|
|
Loading…
Reference in New Issue