diff --git a/app/build.gradle b/app/build.gradle index 173378b..22d1114 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,6 +1,5 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' -apply plugin: 'kotlin-android-extensions' android { compileSdkVersion 29 @@ -8,8 +7,8 @@ android { applicationId "io.github.chronosx88.yggdrasil" minSdkVersion 15 targetSdkVersion 29 - versionCode 18 - versionName "1.7" + versionCode 23 + versionName "2.0.3" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" setProperty("archivesBaseName", project.getParent().name+"-"+versionName) } @@ -46,6 +45,10 @@ android { exclude 'META-INF/LICENSE' exclude 'META-INF/NOTICE' } + buildFeatures { + viewBinding true + } + } task ndkBuild(type: Exec) { @@ -59,16 +62,19 @@ gradle.projectsEvaluated { } dependencies { + + implementation 'ch.acra:acra-http:5.8.3' + implementation 'ch.acra:acra-dialog:5.8.3' implementation fileTree(dir: 'libs', include: ['*.jar']) implementation project(path: ':yggdrasil') - implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'androidx.appcompat:appcompat:1.3.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.4' - implementation "androidx.preference:preference-ktx:1.1.1" + implementation 'androidx.preference:preference-ktx:1.1.1' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7' - implementation 'com.google.android.material:material:1.3.0-alpha04' + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.8' + implementation 'com.google.android.material:material:1.4.0-rc01' implementation 'com.google.code.gson:gson:2.8.6' implementation 'com.hbb20:ccp:2.4.0' implementation 'com.vincentbrison.openlibraries.android:dualcache:3.1.1' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9f24941..08a84d9 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,7 @@ (R.id.node_info_list) - val nodeInfoList = listOf>(Pair("IP address", ipv6Address!!), Pair("Encryption Public Key", encryptionPublicKey!!), Pair("Signing Public Key", signingPublicKey!!)); + val publicKey = preferences.getString(MainActivity.publicKey, "") + var nodeInfoListView = findViewById(R.id.nodeInfoList) + val nodeInfoList = listOf(NodeInfo("IP address", ipv6Address!!), NodeInfo("Public Key", publicKey!!)); val adapter = NodeInfoListAdapter( this, nodeInfoList.toTypedArray() ) + nodeInfoListView.adapter = adapter nodeInfoListView.layoutManager = LinearLayoutManager(this) diff --git a/app/src/main/java/io/github/chronosx88/yggdrasil/MainActivity.kt b/app/src/main/java/io/github/chronosx88/yggdrasil/MainActivity.kt index ef59fe1..9bf848e 100644 --- a/app/src/main/java/io/github/chronosx88/yggdrasil/MainActivity.kt +++ b/app/src/main/java/io/github/chronosx88/yggdrasil/MainActivity.kt @@ -34,10 +34,8 @@ class MainActivity : AppCompatActivity() { const val STATUS_PEERS_UPDATE = 12 const val MESH_PEERS = "MESH_PEERS" const val STATIC_IP = "STATIC_IP_FLAG" - const val signingPrivateKey = "signingPrivateKey" - const val signingPublicKey = "signingPublicKey" - const val encryptionPrivateKey = "encryptionPrivateKey" - const val encryptionPublicKey = "encryptionPublicKey" + const val privateKey = "privateKey" + const val publicKey = "publicKey" const val COMMAND = "COMMAND" const val STOP = "STOP" const val START = "START" diff --git a/app/src/main/java/io/github/chronosx88/yggdrasil/Utils.kt b/app/src/main/java/io/github/chronosx88/yggdrasil/Utils.kt index 8603749..25b62ea 100644 --- a/app/src/main/java/io/github/chronosx88/yggdrasil/Utils.kt +++ b/app/src/main/java/io/github/chronosx88/yggdrasil/Utils.kt @@ -11,14 +11,12 @@ val gson = Gson() fun createNativeYggConfig(config: Config): NodeConfig { val nativeConfig = NodeConfig() nativeConfig.adminListen = config.adminListen - nativeConfig.encryptionPrivateKey = config.encryptionPrivateKey - nativeConfig.encryptionPublicKey = config.encryptionPublicKey + nativeConfig.privateKey = config.privateKey + nativeConfig.publicKey = config.publicKey //nativeConfig.ifMTU = config.ifMTU nativeConfig.ifName = config.ifName //nativeConfig.ifTAPMode = config.ifTAPMode nativeConfig.nodeInfoPrivacy = config.nodeInfoPrivacy - nativeConfig.signingPrivateKey = config.signingPrivateKey - nativeConfig.signingPublicKey = config.signingPublicKey return nativeConfig } diff --git a/app/src/main/java/io/github/chronosx88/yggdrasil/YggApplication.kt b/app/src/main/java/io/github/chronosx88/yggdrasil/YggApplication.kt new file mode 100644 index 0000000..67ab86b --- /dev/null +++ b/app/src/main/java/io/github/chronosx88/yggdrasil/YggApplication.kt @@ -0,0 +1,46 @@ +package io.github.chronosx88.yggdrasil + +import android.app.Application +import android.content.Context +import org.acra.config.dialog +import org.acra.config.httpSender +import org.acra.data.StringFormat +import org.acra.ktx.initAcra +import org.acra.sender.HttpSender + +class YggApplication : Application() { + override fun attachBaseContext(base: Context) { + super.attachBaseContext(base) + + initAcra { + //core configuration: + buildConfigClass = BuildConfig::class.java + reportFormat = StringFormat.JSON + //each plugin you chose above can be configured in a block like this: + httpSender { + uri = "http:///report" + basicAuthLogin="***" + basicAuthPassword = "***" + httpMethod = HttpSender.Method.POST + } + dialog { + //required + text = getString(R.string.report_dialog_text) + //optional, enables the dialog title + title = getString(R.string.app_name) + //defaults to android.R.string.ok + positiveButtonText = getString(android.R.string.ok) + //defaults to android.R.string.cancel + negativeButtonText = getString(android.R.string.cancel) + //optional, enables the comment input + commentPrompt = getString(R.string.report_dialog_comment) + //optional, enables the email input + //emailPrompt = getString(R.string.report_dialog_email) + //defaults to android.R.drawable.ic_dialog_alert + resIcon = android.R.drawable.ic_dialog_alert + //optional, defaults to @android:style/Theme.Dialog + resTheme = R.style.Theme_AppCompat_Dialog + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/io/github/chronosx88/yggdrasil/YggdrasilTunService.kt b/app/src/main/java/io/github/chronosx88/yggdrasil/YggdrasilTunService.kt index 99072c5..b361eb0 100644 --- a/app/src/main/java/io/github/chronosx88/yggdrasil/YggdrasilTunService.kt +++ b/app/src/main/java/io/github/chronosx88/yggdrasil/YggdrasilTunService.kt @@ -14,7 +14,6 @@ import androidx.core.app.NotificationCompat import androidx.preference.PreferenceManager import com.google.gson.Gson import com.google.gson.reflect.TypeToken -import dummy.ConduitEndpoint import io.github.chronosx88.yggdrasil.models.DNSInfo import io.github.chronosx88.yggdrasil.models.PeerInfo import io.github.chronosx88.yggdrasil.models.config.Peer @@ -22,7 +21,6 @@ import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.convertPeer2 import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.convertPeerInfoSet2PeerIdSet import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.deserializeStringList2DNSInfoSet import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.deserializeStringList2PeerInfoSet -import kotlinx.coroutines.* import mobile.Mobile import mobile.Yggdrasil import java.io.* @@ -119,19 +117,19 @@ class YggdrasilTunService : VpnService() { configJson = gson.toJson(config).toByteArray() - var yggConduitEndpoint = ygg.startJSON(configJson) + ygg.startJSON(configJson) setupIOStreams(dns) thread(start = true) { val buffer = ByteArray(MAX_PACKET_SIZE) while (!isClosed) { - readPacketsFromTun(yggConduitEndpoint, buffer) + readPacketsFromTun(buffer) } } thread(start = true) { while (!isClosed) { - writePacketsToTun(yggConduitEndpoint) + writePacketsToTun() } } val intent: Intent = Intent().putExtra(MainActivity.IPv6, address) @@ -147,7 +145,6 @@ class YggdrasilTunService : VpnService() { convertPeer2PeerStringList(meshPeers) ); pi?.send(this, MainActivity.STATUS_PEERS_UPDATE, intent) - } private fun fixConfig( @@ -168,37 +165,27 @@ class YggdrasilTunService : VpnService() { val preferences = PreferenceManager.getDefaultSharedPreferences(this.baseContext) if(preferences.getString(MainActivity.STATIC_IP, null)==null) { - val encryptionPublicKey = config["EncryptionPublicKey"].toString() - val encryptionPrivateKey = config["EncryptionPrivateKey"].toString() - val signingPublicKey = config["SigningPublicKey"].toString() - val signingPrivateKey = config["SigningPrivateKey"].toString() + val publicKey = config["PublicKey"].toString() + val privateKey = config["PrivateKey"].toString() preferences.edit() - .putString(MainActivity.signingPrivateKey, signingPrivateKey) - .putString(MainActivity.signingPublicKey, signingPublicKey) - .putString(MainActivity.encryptionPrivateKey, encryptionPrivateKey) - .putString(MainActivity.encryptionPublicKey, encryptionPublicKey) + .putString(MainActivity.privateKey, privateKey) + .putString(MainActivity.publicKey, publicKey) .putString(MainActivity.STATIC_IP, MainActivity.STATIC_IP).apply() } else { - val signingPrivateKey = preferences.getString(MainActivity.signingPrivateKey, null) - val signingPublicKey = preferences.getString(MainActivity.signingPublicKey, null) - val encryptionPrivateKey = preferences.getString(MainActivity.encryptionPrivateKey, null) - val encryptionPublicKey = preferences.getString(MainActivity.encryptionPublicKey, null) + val privateKey = preferences.getString(MainActivity.privateKey, null) + val publicKey = preferences.getString(MainActivity.publicKey, null) - config["SigningPrivateKey"] = signingPrivateKey - config["SigningPublicKey"] = signingPublicKey - config["EncryptionPrivateKey"] = encryptionPrivateKey - config["EncryptionPublicKey"] = encryptionPublicKey + config["PrivateKey"] = privateKey + config["PublicKey"] = publicKey } } - - (config["SessionFirewall"] as MutableMap)["Enable"] = false //(config["SessionFirewall"] as MutableMap)["AllowFromDirect"] = true //(config["SessionFirewall"] as MutableMap)["AllowFromRemote"] = true //(config["SessionFirewall"] as MutableMap)["AlwaysAllowOutbound"] = true //(config["SessionFirewall"] as MutableMap)["WhitelistEncryptionPublicKeys"] = whiteList //(config["SessionFirewall"] as MutableMap)["BlacklistEncryptionPublicKeys"] = blackList - (config["SwitchOptions"] as MutableMap)["MaxTotalQueueSize"] = 4194304 + //(config["SwitchOptions"] as MutableMap)["MaxTotalQueueSize"] = 4194304 if (config["AutoStart"] == null) { val tmpMap = emptyMap().toMutableMap() tmpMap["WiFi"] = false @@ -208,18 +195,18 @@ class YggdrasilTunService : VpnService() { return config } - private fun readPacketsFromTun(yggConduitEndpoint: ConduitEndpoint, buffer: ByteArray) { + private fun readPacketsFromTun(buffer: ByteArray) { try { // Read the outgoing packet from the input stream. val length = tunInputStream.read(buffer) - yggConduitEndpoint.send(buffer.sliceArray(IntRange(0, length - 1))) + ygg.send(buffer.sliceArray(IntRange(0, length - 1))) } catch (e: IOException) { e.printStackTrace() } } - private fun writePacketsToTun(yggConduitEndpoint: ConduitEndpoint) { - val buffer = yggConduitEndpoint.recv() + private fun writePacketsToTun() { + val buffer = ygg.recv() if(buffer!=null) { try { tunOutputStream.write(buffer) diff --git a/app/src/main/java/io/github/chronosx88/yggdrasil/models/config/Config.kt b/app/src/main/java/io/github/chronosx88/yggdrasil/models/config/Config.kt index 085f1a9..6107b99 100644 --- a/app/src/main/java/io/github/chronosx88/yggdrasil/models/config/Config.kt +++ b/app/src/main/java/io/github/chronosx88/yggdrasil/models/config/Config.kt @@ -4,23 +4,21 @@ import com.google.gson.annotations.SerializedName // FIXME This is old config scheme data class Config ( - @SerializedName("peers") var peers : List, - @SerializedName("interfacePeers") var interfacePeers : Map>, - @SerializedName("listen") var listen : List, - @SerializedName("adminListen") var adminListen : String, - @SerializedName("multicastInterfaces") var multicastInterfaces : List, - @SerializedName("allowedEncryptionPublicKeys") var allowedEncryptionPublicKeys : List, - @SerializedName("encryptionPublicKey") var encryptionPublicKey : String, - @SerializedName("encryptionPrivateKey") var encryptionPrivateKey : String, - @SerializedName("signingPublicKey") var signingPublicKey : String, - @SerializedName("signingPrivateKey") var signingPrivateKey : String, - @SerializedName("linkLocalTCPPort") var linkLocalTCPPort : Int, - @SerializedName("ifName") var ifName : String, - @SerializedName("ifTAPMode") var ifTAPMode : Boolean, - @SerializedName("ifMTU") var ifMTU : Long, - @SerializedName("sessionFirewall") var sessionFirewall : SessionFirewall, - @SerializedName("tunnelRouting") var tunnelRouting : TunnelRouting, - @SerializedName("switchOptions") var switchOptions : SwitchOptions, - @SerializedName("nodeInfoPrivacy") var nodeInfoPrivacy : Boolean, - @SerializedName("nodeInfo") var nodeInfo : Map + @SerializedName("peers") var peers : List, + @SerializedName("interfacePeers") var interfacePeers : Map>, + @SerializedName("listen") var listen : List, + @SerializedName("adminListen") var adminListen : String, + @SerializedName("multicastInterfaces") var multicastInterfaces : List, + @SerializedName("allowedEncryptionPublicKeys") var allowedEncryptionPublicKeys : List, + @SerializedName("publicKey") var publicKey : String, + @SerializedName("privateKey") var privateKey : String, + @SerializedName("linkLocalTCPPort") var linkLocalTCPPort : Int, + @SerializedName("ifName") var ifName : String, + @SerializedName("ifTAPMode") var ifTAPMode : Boolean, + @SerializedName("ifMTU") var ifMTU : Long, + @SerializedName("sessionFirewall") var sessionFirewall : SessionFirewall, + @SerializedName("tunnelRouting") var tunnelRouting : TunnelRouting, + @SerializedName("switchOptions") var switchOptions : SwitchOptions, + @SerializedName("nodeInfoPrivacy") var nodeInfoPrivacy : Boolean, + @SerializedName("nodeInfo") var nodeInfo : Map ) \ No newline at end of file diff --git a/app/src/main/java/io/github/chronosx88/yggdrasil/models/config/Utils.kt b/app/src/main/java/io/github/chronosx88/yggdrasil/models/config/Utils.kt index d6078f2..1c737ad 100644 --- a/app/src/main/java/io/github/chronosx88/yggdrasil/models/config/Utils.kt +++ b/app/src/main/java/io/github/chronosx88/yggdrasil/models/config/Utils.kt @@ -3,6 +3,7 @@ package io.github.chronosx88.yggdrasil.models.config import com.google.gson.Gson import io.github.chronosx88.yggdrasil.models.DNSInfo import io.github.chronosx88.yggdrasil.models.PeerInfo +import org.acra.ACRA import java.net.InetAddress import java.net.InetSocketAddress import java.net.Socket @@ -113,6 +114,7 @@ class Utils { @JvmStatic fun deserializePeerStringList2PeerInfoSet(list: List?): MutableSet { var gson = Gson() + ACRA.errorReporter.putCustomData("Peer list", gson.toJson(list)) var out = mutableSetOf() if (list != null) { for(s in list) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5efec01..00fcd5e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -9,4 +9,6 @@ Schema Yggdrasil Node info + Sorry, the application crashed. + Please describe what were you doing when the app crashed: diff --git a/build.gradle b/build.gradle index 7c95eb1..2f3d35b 100644 --- a/build.gradle +++ b/build.gradle @@ -1,15 +1,14 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. - buildscript { - ext.kotlin_version = '1.4.10' + ext.kotlin_version = "1.5.10" repositories { google() mavenCentral() - jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:4.1.3' + classpath "com.android.tools.build:gradle:4.2.1" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } @@ -18,10 +17,11 @@ buildscript { allprojects { repositories { google() - jcenter() + mavenCentral() + jcenter() // Warning: this repository is going to shut down soon } } task clean(type: Delete) { delete rootProject.buildDir -} +} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 39eebd9..1f7c3f7 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip +distributionUrl=https://services.gradle.org/distributions/gradle-6.7.1-all.zip diff --git a/yggdrasil/Makefile b/yggdrasil/Makefile index 46870d0..8745071 100644 --- a/yggdrasil/Makefile +++ b/yggdrasil/Makefile @@ -1,10 +1,10 @@ GOPATH=$(shell go env GOPATH) - +export GO111MODULE=off all: -go get -u github.com/yggdrasil-network/yggdrasil-go; -cd $(GOPATH)/src/github.com/yggdrasil-network/yggdrasil-go; \ go get -v -d ./...; \ - go get -u github.com/yggdrasil-network/yggdrasil-extras@005d79c; \ + go get -u github.com/yggdrasil-network/yggdrasil-extras; \ ANDROID=true ./build; mv -f $(GOPATH)/src/github.com/yggdrasil-network/yggdrasil-go/yggdrasil.aar yggdrasil.aar; mv -f $(GOPATH)/src/github.com/yggdrasil-network/yggdrasil-go/yggdrasil-sources.jar yggdrasil-sources.jar;