Changes for updating to Yggdrasil 0.5. (#49)

This commit is contained in:
Revertron 2023-10-28 23:31:32 +02:00 committed by GitHub
parent 9df80c0612
commit f4e1a75cfc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 189 additions and 78 deletions

View file

@ -32,14 +32,12 @@ object ConfigurationProxy {
val newJson = JSONObject(String(Mobile.generateConfigJSON()))
updateJSON { json ->
json.put("PrivateKey", newJson.getString("PrivateKey"))
json.put("PublicKey", newJson.getString("PublicKey"))
}
}
fun setKeys(privateKey: String, publicKey: String) {
fun setKeys(privateKey: String) {
updateJSON { json ->
json.put("PrivateKey", privateKey)
json.put("PublicKey", publicKey)
}
}
@ -62,7 +60,8 @@ object ConfigurationProxy {
{
"Regex": ".*",
"Beacon": true,
"Listen": true
"Listen": true,
"Password": ""
}
""".trimIndent()))
json.put("MulticastInterfaces", ar)
@ -94,4 +93,12 @@ object ConfigurationProxy {
(json.getJSONArray("MulticastInterfaces").get(0) as JSONObject).put("Beacon", value)
}
}
var multicastPassword: String
get() = (json.getJSONArray("MulticastInterfaces").get(0) as JSONObject).getString("Password")
set(value) {
updateJSON { json ->
(json.getJSONArray("MulticastInterfaces").get(0) as JSONObject).put("Password", value)
}
}
}

View file

@ -47,8 +47,10 @@ class GlobalApplication: Application(), YggStateReceiver.StateReceiver {
@RequiresApi(Build.VERSION_CODES.N)
override fun onStateChange(state: State) {
if (state != currentState) {
val componentName = ComponentName(this, YggTileService::class.java)
TileService.requestListeningState(this, componentName)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val componentName = ComponentName(this, YggTileService::class.java)
TileService.requestListeningState(this, componentName)
}
if (state != State.Disabled) {
val notification = createServiceNotification(this, state)
@ -68,7 +70,11 @@ fun createServiceNotification(context: Context, state: State): Notification {
val intent = Intent(context, MainActivity::class.java).apply {
this.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val pendingIntent: PendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
var flags = PendingIntent.FLAG_UPDATE_CURRENT
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
flags = PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
}
val pendingIntent: PendingIntent = PendingIntent.getActivity(context, 0, intent, flags)
val text = when (state) {
State.Disabled -> context.getText(R.string.tile_disabled)
@ -91,7 +97,11 @@ fun createPermissionMissingNotification(context: Context): Notification {
val intent = Intent(context, MainActivity::class.java).apply {
this.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val pendingIntent: PendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
var flags = PendingIntent.FLAG_UPDATE_CURRENT
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
flags = PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
}
val pendingIntent: PendingIntent = PendingIntent.getActivity(context, 0, intent, flags)
return NotificationCompat.Builder(context, MAIN_CHANNEL_ID)
.setShowWhen(false)

View file

@ -24,7 +24,7 @@ class MainActivity : AppCompatActivity() {
private lateinit var enabledLabel: TextView
private lateinit var ipAddressLabel: TextView
private lateinit var subnetLabel: TextView
private lateinit var coordinatesLabel: TextView
private lateinit var treeLengthLabel: TextView
private lateinit var peersLabel: TextView
private lateinit var peersRow: LinearLayoutCompat
private lateinit var dnsLabel: TextView
@ -53,7 +53,7 @@ class MainActivity : AppCompatActivity() {
enabledLabel = findViewById(R.id.yggdrasilStatusLabel)
ipAddressLabel = findViewById(R.id.ipAddressValue)
subnetLabel = findViewById(R.id.subnetValue)
coordinatesLabel = findViewById(R.id.coordinatesValue)
treeLengthLabel = findViewById(R.id.treeLengthValue)
peersLabel = findViewById(R.id.peersValue)
peersRow = findViewById(R.id.peersTableRow)
dnsLabel = findViewById(R.id.dnsValue)
@ -155,11 +155,11 @@ class MainActivity : AppCompatActivity() {
"state" -> {
enabledLabel.text = if (intent.getBooleanExtra("started", false)) {
var count = 0
if (intent.hasExtra("dht")) {
val dht = intent.getStringExtra("dht")
if (dht != null && dht != "null") {
val dhtState = JSONArray(dht)
count = dhtState.length()
if (intent.hasExtra("tree")) {
val tree = intent.getStringExtra("tree")
if (tree != null && tree != "null") {
val treeState = JSONArray(tree)
count = treeState.length()
}
}
if (count == 0) {
@ -175,7 +175,7 @@ class MainActivity : AppCompatActivity() {
}
ipAddressLabel.text = intent.getStringExtra("ip") ?: "N/A"
subnetLabel.text = intent.getStringExtra("subnet") ?: "N/A"
coordinatesLabel.text = intent.getStringExtra("coords") ?: "[]"
treeLengthLabel.text = intent.getStringExtra("coords") ?: "0"
if (intent.hasExtra("peers")) {
val peerState = JSONArray(intent.getStringExtra("peers") ?: "[]")
peersLabel.text = when (val count = peerState.length()) {

View file

@ -1,7 +1,8 @@
package eu.neilalexander.yggdrasil
import android.content.*
import android.content.Intent
import android.net.VpnService
import android.net.wifi.WifiManager
import android.os.Build
import android.os.ParcelFileDescriptor
import android.system.OsConstants
@ -42,6 +43,7 @@ open class PacketTunnelProvider: VpnService() {
private var parcel: ParcelFileDescriptor? = null
private var readerStream: FileInputStream? = null
private var writerStream: FileOutputStream? = null
private var multicastLock: WifiManager.MulticastLock? = null
override fun onCreate() {
super.onCreate()
@ -101,6 +103,13 @@ open class PacketTunnelProvider: VpnService() {
val notification = createServiceNotification(this, State.Enabled)
startForeground(SERVICE_NOTIFICATION_ID, notification)
// Acquire multicast lock
val wifi = applicationContext.getSystemService(WIFI_SERVICE) as WifiManager
multicastLock = wifi.createMulticastLock("Yggdrasil").apply {
setReferenceCounted(false)
acquire()
}
Log.d(TAG, config.getJSON().toString())
yggdrasil.startJSON(config.getJSONByteArray())
@ -163,16 +172,7 @@ open class PacketTunnelProvider: VpnService() {
updater()
}
var intent = Intent(STATE_INTENT)
intent.putExtra("type", "state")
intent.putExtra("started", true)
intent.putExtra("ip", yggdrasil.addressString)
intent.putExtra("subnet", yggdrasil.subnetString)
intent.putExtra("coords", yggdrasil.coordsString)
intent.putExtra("peers", yggdrasil.peersJSON)
LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
intent = Intent(YGG_STATE_INTENT)
var intent = Intent(YGG_STATE_INTENT)
intent.putExtra("state", STATE_ENABLED)
LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
}
@ -221,6 +221,7 @@ open class PacketTunnelProvider: VpnService() {
stopForeground(true)
stopSelf()
multicastLock?.release()
}
private fun connect() {
@ -231,27 +232,37 @@ open class PacketTunnelProvider: VpnService() {
}
private fun updater() {
Thread.sleep(500)
var lastStateUpdate = System.currentTimeMillis()
updates@ while (started.get()) {
val treeJSON = yggdrasil.treeJSON
var treeLength = 0
if (treeJSON != null && treeJSON != "null") {
val treeState = JSONArray(treeJSON)
treeLength = treeState.length()
}
if ((application as GlobalApplication).needUiUpdates()) {
val intent = Intent(STATE_INTENT)
intent.putExtra("type", "state")
intent.putExtra("started", true)
intent.putExtra("ip", yggdrasil.addressString)
intent.putExtra("subnet", yggdrasil.subnetString)
intent.putExtra("coords", yggdrasil.coordsString)
intent.putExtra("pubkey", yggdrasil.publicKeyString)
intent.putExtra("coords", "$treeLength")
intent.putExtra("peers", yggdrasil.peersJSON)
intent.putExtra("dht", yggdrasil.dhtjson)
intent.putExtra("tree", treeJSON)
LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
}
val curTime = System.currentTimeMillis()
if (lastStateUpdate + 10000 < curTime) {
val intent = Intent(YGG_STATE_INTENT)
var state = STATE_ENABLED
val dht = yggdrasil.dhtjson
if (dht != null && dht != "null") {
val dhtState = JSONArray(dht)
val count = dhtState.length()
if (yggdrasil.routingEntries > 0) {
state = STATE_CONNECTED
}
if (treeJSON != null && treeJSON != "null") {
val treeState = JSONArray(treeJSON)
val count = treeState.length()
if (count > 1)
state = STATE_CONNECTED
}

View file

@ -7,10 +7,13 @@ import android.content.Intent
import android.content.IntentFilter
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.ContextThemeWrapper
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View
import android.widget.*
import androidx.core.widget.doOnTextChanged
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.google.android.material.textfield.TextInputEditText
import org.json.JSONArray
@ -27,6 +30,7 @@ class PeersActivity : AppCompatActivity() {
private lateinit var configuredTableLabel: TextView
private lateinit var multicastListenSwitch: Switch
private lateinit var multicastBeaconSwitch: Switch
private lateinit var passwordEdit: EditText
private lateinit var addPeerButton: ImageButton
override fun onCreate(savedInstanceState: Bundle?) {
@ -62,6 +66,30 @@ class PeersActivity : AppCompatActivity() {
multicastListenPanel.setOnClickListener {
multicastListenSwitch.toggle()
}
passwordEdit = findViewById(R.id.passwordEdit)
passwordEdit.setText(config.multicastPassword)
passwordEdit.doOnTextChanged { text, _, _, _ ->
config.multicastPassword = text.toString()
}
passwordEdit.setOnKeyListener { _, keyCode, _ ->
(keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_ENTER)
}
findViewById<View>(R.id.passwordTableRow).setOnKeyListener { _, keyCode, event ->
Log.i("Key", keyCode.toString())
if (event.action == KeyEvent.ACTION_DOWN) {
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_ENTER) {
passwordEdit.requestFocus()
true
} else {
false
}
} else {
false
}
}
addPeerButton = findViewById(R.id.addPeerButton)
addPeerButton.setOnClickListener {
@ -156,7 +184,7 @@ class PeersActivity : AppCompatActivity() {
val view = inflater.inflate(R.layout.peers_connected, null)
val ip = peer.getString("IP")
view.findViewById<TextView>(R.id.addressLabel).text = ip
view.findViewById<TextView>(R.id.detailsLabel).text = peer.getString("Remote")
view.findViewById<TextView>(R.id.detailsLabel).text = peer.getString("URI")
connectedTableLayout.addView(view)
}
}
@ -168,7 +196,9 @@ class PeersActivity : AppCompatActivity() {
when (intent.getStringExtra("type")) {
"state" -> {
if (intent.hasExtra("peers")) {
val peersArray = JSONArray(intent.getStringExtra("peers") ?: "[]")
val peers1 = intent.getStringExtra("peers")
//Log.i("PeersActivity", "Peers json: $peers1")
val peersArray = JSONArray(peers1 ?: "[]")
val array = Array(peersArray.length()) { i ->
peersArray.getJSONObject(i)
}

View file

@ -1,8 +1,12 @@
package eu.neilalexander.yggdrasil
import android.app.AlertDialog
import android.content.BroadcastReceiver
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
@ -13,6 +17,7 @@ import android.view.View
import android.widget.*
import androidx.appcompat.widget.LinearLayoutCompat
import androidx.core.widget.doOnTextChanged
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import org.json.JSONObject
class SettingsActivity : AppCompatActivity() {
@ -87,11 +92,10 @@ class SettingsActivity : AppCompatActivity() {
val view = inflater.inflate(R.layout.dialog_set_keys, null)
val builder: AlertDialog.Builder = AlertDialog.Builder(ContextThemeWrapper(this, R.style.Theme_MaterialComponents_DayNight_Dialog))
val privateKey = view.findViewById<EditText>(R.id.private_key)
val publicKey = view.findViewById<EditText>(R.id.public_key)
builder.setTitle(getString(R.string.set_keys))
builder.setView(view)
builder.setPositiveButton(getString(R.string.save)) { dialog, _ ->
config.setKeys(privateKey.text.toString(), publicKey.text.toString())
config.setKeys(privateKey.text.toString())
updateView()
dialog.dismiss()
}
@ -113,13 +117,40 @@ class SettingsActivity : AppCompatActivity() {
}
private fun updateView() {
val nodeinfo = config.getJSON().optJSONObject("NodeInfo")
val json = config.getJSON()
val nodeinfo = json.optJSONObject("NodeInfo")
if (nodeinfo != null) {
deviceNameEntry.setText(nodeinfo.getString("name"), TextView.BufferType.EDITABLE)
} else {
deviceNameEntry.setText("", TextView.BufferType.EDITABLE)
}
publicKeyLabel.text = config.getJSON().getString("PublicKey")
publicKeyLabel.text = json.optString("PublicKey")
}
override fun onResume() {
super.onResume()
LocalBroadcastManager.getInstance(this).registerReceiver(
receiver, IntentFilter(PacketTunnelProvider.STATE_INTENT)
)
(application as GlobalApplication).subscribe()
}
override fun onPause() {
super.onPause()
(application as GlobalApplication).unsubscribe()
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver)
}
// To be able to get public key from running Yggdrasil we use this receiver, as we don't have this field in config
private val receiver: BroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent) {
if (intent.hasExtra("pubkey")) {
val tree = intent.getStringExtra("pubkey")
if (tree != null && tree != "null") {
publicKeyLabel.text = intent.getStringExtra("pubkey")
}
}
}
}
}