diff options
author | pacien | 2017-09-07 14:27:37 +0200 |
---|---|---|
committer | pacien | 2017-09-07 14:27:37 +0200 |
commit | 4989dad67b68b38e75416916df406dcec908b399 (patch) | |
tree | 1857d313393788234ffa75b9203122d3ae822d3f | |
parent | 9e5aa1a9f95a3b5541aba7e511e13ae51b614416 (diff) | |
download | tincapp-4989dad67b68b38e75416916df406dcec908b399.tar.gz |
Implement encrypted private keys support
17 files changed, 323 insertions, 29 deletions
diff --git a/app/build.gradle b/app/build.gradle index 881bfdf..2605544 100644 --- a/app/build.gradle +++ b/app/build.gradle | |||
@@ -52,6 +52,8 @@ dependencies { | |||
52 | exclude group: 'commons-logging', module: 'commons-logging' | 52 | exclude group: 'commons-logging', module: 'commons-logging' |
53 | } | 53 | } |
54 | 54 | ||
55 | compile 'org.bouncycastle:bcpkix-jdk15on:1.57' | ||
56 | |||
55 | compile 'net.sourceforge.streamsupport:streamsupport-cfuture:1.5.5' | 57 | compile 'net.sourceforge.streamsupport:streamsupport-cfuture:1.5.5' |
56 | 58 | ||
57 | compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" | 59 | compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" |
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 489245d..3ccc9e6 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml | |||
@@ -41,7 +41,7 @@ | |||
41 | 41 | ||
42 | <activity | 42 | <activity |
43 | android:name=".activities.LaunchActivity" | 43 | android:name=".activities.LaunchActivity" |
44 | android:theme="@android:style/Theme.Translucent.NoTitleBar"> | 44 | android:theme="@style/AppTheme.NoActionBar"> |
45 | <intent-filter> | 45 | <intent-filter> |
46 | <action android:name="org.pacien.tincapp.intent.action.CONNECT"/> | 46 | <action android:name="org.pacien.tincapp.intent.action.CONNECT"/> |
47 | <data android:scheme="tinc"/> | 47 | <data android:scheme="tinc"/> |
diff --git a/app/src/main/java/org/pacien/tincapp/activities/ConfigureActivity.kt b/app/src/main/java/org/pacien/tincapp/activities/ConfigureActivity.kt index 9027b14..6c29a53 100644 --- a/app/src/main/java/org/pacien/tincapp/activities/ConfigureActivity.kt +++ b/app/src/main/java/org/pacien/tincapp/activities/ConfigureActivity.kt | |||
@@ -10,6 +10,7 @@ import android.support.v7.app.AlertDialog | |||
10 | import android.view.View | 10 | import android.view.View |
11 | import java8.util.concurrent.CompletableFuture | 11 | import java8.util.concurrent.CompletableFuture |
12 | import kotlinx.android.synthetic.main.base.* | 12 | import kotlinx.android.synthetic.main.base.* |
13 | import kotlinx.android.synthetic.main.dialog_encrypt_decrypt_keys.view.* | ||
13 | import kotlinx.android.synthetic.main.dialog_network_generate.view.* | 14 | import kotlinx.android.synthetic.main.dialog_network_generate.view.* |
14 | import kotlinx.android.synthetic.main.dialog_network_join.view.* | 15 | import kotlinx.android.synthetic.main.dialog_network_join.view.* |
15 | import kotlinx.android.synthetic.main.page_configure.* | 16 | import kotlinx.android.synthetic.main.page_configure.* |
@@ -62,7 +63,10 @@ class ConfigureActivity : BaseActivity() { | |||
62 | val genDialog = layoutInflater.inflate(R.layout.dialog_network_generate, main_content, false) | 63 | val genDialog = layoutInflater.inflate(R.layout.dialog_network_generate, main_content, false) |
63 | AlertDialog.Builder(this).setTitle(R.string.title_new_network).setView(genDialog) | 64 | AlertDialog.Builder(this).setTitle(R.string.title_new_network).setView(genDialog) |
64 | .setPositiveButton(R.string.action_create) { _, _ -> | 65 | .setPositiveButton(R.string.action_create) { _, _ -> |
65 | generateConf(genDialog.new_net_name.text.toString(), genDialog.new_node_name.text.toString()) | 66 | generateConf( |
67 | genDialog.new_net_name.text.toString(), | ||
68 | genDialog.new_node_name.text.toString(), | ||
69 | genDialog.new_passphrase.text.toString()) | ||
66 | }.setNegativeButton(R.string.action_cancel, App.dismissAction).show() | 70 | }.setNegativeButton(R.string.action_cancel, App.dismissAction).show() |
67 | } | 71 | } |
68 | 72 | ||
@@ -70,7 +74,21 @@ class ConfigureActivity : BaseActivity() { | |||
70 | joinDialog = layoutInflater.inflate(R.layout.dialog_network_join, main_content, false) | 74 | joinDialog = layoutInflater.inflate(R.layout.dialog_network_join, main_content, false) |
71 | AlertDialog.Builder(this).setTitle(R.string.title_join_network).setView(joinDialog) | 75 | AlertDialog.Builder(this).setTitle(R.string.title_join_network).setView(joinDialog) |
72 | .setPositiveButton(R.string.action_join) { _, _ -> | 76 | .setPositiveButton(R.string.action_join) { _, _ -> |
73 | joinNetwork(joinDialog!!.net_name.text.toString(), joinDialog!!.invitation_url.text.toString()) | 77 | joinNetwork( |
78 | joinDialog!!.net_name.text.toString(), | ||
79 | joinDialog!!.invitation_url.text.toString(), | ||
80 | joinDialog!!.join_passphrase.text.toString()) | ||
81 | }.setNegativeButton(R.string.action_cancel, App.dismissAction).show() | ||
82 | } | ||
83 | |||
84 | fun openEncryptDecryptPrivateKeyDialog(@Suppress("UNUSED_PARAMETER") v: View) { | ||
85 | val encryptDecryptDialog = layoutInflater.inflate(R.layout.dialog_encrypt_decrypt_keys, main_content, false) | ||
86 | AlertDialog.Builder(this).setTitle(R.string.title_private_keys_encryption).setView(encryptDecryptDialog) | ||
87 | .setPositiveButton(R.string.action_apply) { _, _ -> | ||
88 | encryptDecryptPrivateKeys( | ||
89 | encryptDecryptDialog!!.enc_dec_net_name.text.toString(), | ||
90 | encryptDecryptDialog.enc_dec_current_passphrase.text.toString(), | ||
91 | encryptDecryptDialog.enc_dec_new_passphrase.text.toString()) | ||
74 | }.setNegativeButton(R.string.action_cancel, App.dismissAction).show() | 92 | }.setNegativeButton(R.string.action_cancel, App.dismissAction).show() |
75 | } | 93 | } |
76 | 94 | ||
@@ -80,22 +98,28 @@ class ConfigureActivity : BaseActivity() { | |||
80 | text_tinc_binary.text = AppPaths.tinc().absolutePath | 98 | text_tinc_binary.text = AppPaths.tinc().absolutePath |
81 | } | 99 | } |
82 | 100 | ||
83 | private fun generateConf(netName: String, nodeName: String) = execAction( | 101 | private fun generateConf(netName: String, nodeName: String, passphrase: String? = null) = execAction( |
84 | R.string.message_generating_configuration, | 102 | R.string.message_generating_configuration, |
85 | Tinc.init(netName, nodeName) | 103 | Tinc.init(netName, nodeName) |
86 | .thenCompose { TincApp.removeScripts(netName) }) | 104 | .thenCompose { TincApp.removeScripts(netName) } |
105 | .thenCompose { TincApp.setPassphrase(netName, newPassphrase = passphrase) }) | ||
87 | 106 | ||
88 | private fun joinNetwork(netName: String, url: String) = execAction( | 107 | private fun joinNetwork(netName: String, url: String, passphrase: String? = null) = execAction( |
89 | R.string.message_joining_network, | 108 | R.string.message_joining_network, |
90 | Tinc.join(netName, url) | 109 | Tinc.join(netName, url) |
91 | .thenCompose { TincApp.removeScripts(netName) } | 110 | .thenCompose { TincApp.removeScripts(netName) } |
92 | .thenCompose { TincApp.generateIfaceCfg(netName) }) | 111 | .thenCompose { TincApp.generateIfaceCfg(netName) } |
112 | .thenCompose { TincApp.setPassphrase(netName, newPassphrase = passphrase) }) | ||
113 | |||
114 | private fun encryptDecryptPrivateKeys(netName: String, currentPassphrase: String, newPassphrase: String) = execAction( | ||
115 | R.string.message_encrypting_decrypting_private_keys, | ||
116 | TincApp.setPassphrase(netName, currentPassphrase, newPassphrase)) | ||
93 | 117 | ||
94 | private fun execAction(@StringRes label: Int, action: CompletableFuture<Void>) { | 118 | private fun execAction(@StringRes label: Int, action: CompletableFuture<Void>) { |
95 | showProgressDialog(label).let { progressDialog -> | 119 | showProgressDialog(label).let { progressDialog -> |
96 | action | 120 | action |
97 | .whenComplete { _, _ -> progressDialog.dismiss() } | 121 | .whenComplete { _, _ -> progressDialog.dismiss() } |
98 | .thenAccept { notify(R.string.message_network_configuration_created) } | 122 | .thenAccept { notify(R.string.message_network_configuration_written) } |
99 | .exceptionallyAccept { runOnUiThread { showErrorDialog(it.cause!!.localizedMessage) } } | 123 | .exceptionallyAccept { runOnUiThread { showErrorDialog(it.cause!!.localizedMessage) } } |
100 | } | 124 | } |
101 | } | 125 | } |
diff --git a/app/src/main/java/org/pacien/tincapp/activities/LaunchActivity.kt b/app/src/main/java/org/pacien/tincapp/activities/LaunchActivity.kt index 6eb630d..74a059b 100644 --- a/app/src/main/java/org/pacien/tincapp/activities/LaunchActivity.kt +++ b/app/src/main/java/org/pacien/tincapp/activities/LaunchActivity.kt | |||
@@ -1,20 +1,28 @@ | |||
1 | package org.pacien.tincapp.activities | 1 | package org.pacien.tincapp.activities |
2 | 2 | ||
3 | import android.annotation.SuppressLint | ||
3 | import android.app.Activity | 4 | import android.app.Activity |
4 | import android.content.Intent | 5 | import android.content.Intent |
5 | import android.net.Uri | 6 | import android.net.Uri |
6 | import android.net.VpnService | 7 | import android.net.VpnService |
7 | import android.os.Bundle | 8 | import android.os.Bundle |
9 | import android.support.v7.app.AlertDialog | ||
10 | import android.support.v7.app.AppCompatActivity | ||
11 | import kotlinx.android.synthetic.main.dialog_decrypt_keys.view.* | ||
12 | import org.pacien.tincapp.R | ||
13 | import org.pacien.tincapp.commands.TincApp | ||
8 | import org.pacien.tincapp.context.App | 14 | import org.pacien.tincapp.context.App |
9 | import org.pacien.tincapp.intent.action.ACTION_CONNECT | 15 | import org.pacien.tincapp.intent.action.ACTION_CONNECT |
10 | import org.pacien.tincapp.intent.action.ACTION_DISCONNECT | 16 | import org.pacien.tincapp.intent.action.ACTION_DISCONNECT |
11 | import org.pacien.tincapp.intent.action.TINC_SCHEME | 17 | import org.pacien.tincapp.intent.action.TINC_SCHEME |
12 | import org.pacien.tincapp.service.TincVpnService | 18 | import org.pacien.tincapp.service.TincVpnService |
19 | import org.pacien.tincapp.utils.PemUtils | ||
20 | import java.io.FileNotFoundException | ||
13 | 21 | ||
14 | /** | 22 | /** |
15 | * @author pacien | 23 | * @author pacien |
16 | */ | 24 | */ |
17 | class LaunchActivity : Activity() { | 25 | class LaunchActivity : AppCompatActivity() { |
18 | 26 | ||
19 | override fun onCreate(savedInstanceState: Bundle?) { | 27 | override fun onCreate(savedInstanceState: Bundle?) { |
20 | super.onCreate(savedInstanceState) | 28 | super.onCreate(savedInstanceState) |
@@ -26,15 +34,41 @@ class LaunchActivity : Activity() { | |||
26 | } | 34 | } |
27 | 35 | ||
28 | override fun onActivityResult(request: Int, result: Int, data: Intent?) { | 36 | override fun onActivityResult(request: Int, result: Int, data: Intent?) { |
29 | if (result == Activity.RESULT_OK) TincVpnService.startVpn(intent.data.schemeSpecificPart) | 37 | if (request == PERMISSION_REQUEST_CODE && result == Activity.RESULT_OK) askPassphrase() |
30 | finish() | ||