diff options
| -rw-r--r-- | Cargo.lock | 118 | ||||
| -rw-r--r-- | Cargo.toml | 3 | ||||
| -rw-r--r-- | android/build.gradle | 39 | ||||
| -rw-r--r-- | android/src/main/kotlin/net/mullvad/mullvadvpn/ApiRootCaFile.kt | 29 | ||||
| -rw-r--r-- | android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt | 27 | ||||
| -rw-r--r-- | android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt | 10 | ||||
| -rw-r--r-- | mullvad-daemon/src/main.rs | 11 | ||||
| -rw-r--r-- | mullvad-daemon/src/version.rs | 9 | ||||
| -rw-r--r-- | mullvad-jni/Cargo.toml | 23 | ||||
| -rw-r--r-- | mullvad-jni/src/daemon_interface.rs | 17 | ||||
| -rw-r--r-- | mullvad-jni/src/lib.rs | 102 |
11 files changed, 377 insertions, 11 deletions
diff --git a/Cargo.lock b/Cargo.lock index 4b66ca292e..60bfb33769 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -44,6 +44,11 @@ dependencies = [ ] [[package]] +name = "ascii" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "assert_matches" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -141,6 +146,11 @@ version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "cfg-if" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -195,6 +205,18 @@ dependencies = [ ] [[package]] +name = "combine" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ascii 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "constant_time_eq" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -351,6 +373,11 @@ dependencies = [ ] [[package]] +name = "either" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "env_logger" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -670,6 +697,24 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "jni" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cesu8 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "combine 3.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jni-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "jsonrpc-client-core" version = "0.5.0" source = "git+https://github.com/mullvad/jsonrpc-client-rs?rev=68aac55b#68aac55b6ddff5e1242594b54f7f9149fe215ff7" @@ -891,6 +936,14 @@ dependencies = [ ] [[package]] +name = "lock_api" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "log" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1108,6 +1161,22 @@ dependencies = [ ] [[package]] +name = "mullvad-jni" +version = "0.1.0" +dependencies = [ + "err-derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jni 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log-panics 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "mullvad-daemon 2019.4.0", + "mullvad-paths 0.1.0", + "mullvad-types 0.1.0", + "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "talpid-types 0.1.0", +] + +[[package]] name = "mullvad-paths" version = "0.1.0" dependencies = [ @@ -1435,6 +1504,16 @@ dependencies = [ ] [[package]] +name = "parking_lot" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "parking_lot_core" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1459,6 +1538,21 @@ dependencies = [ ] [[package]] +name = "parking_lot_core" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "percent-encoding" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1800,6 +1894,11 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "scopeguard" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "semver" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2492,6 +2591,14 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "utf8-ranges" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2662,6 +2769,7 @@ dependencies = [ "checksum arc-swap 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "bc4662175ead9cd84451d5c35070517777949a2ed84551764129cedb88384841" "checksum argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3f67b0b6a86dae6e67ff4ca2b6201396074996379fba2b92ff649126f37cb392" "checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71" +"checksum ascii 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a5fc969a8ce2c9c0c4b0429bb8431544f6658283c8326ba5ff8c762b75369335" "checksum assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7deb0a829ca7bcfaf5da70b073a8d128619259a7be8216a355e23f00763059e5" "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" "checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799" @@ -2675,12 +2783,14 @@ dependencies = [ "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" "checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" "checksum cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ad0daef304fa0b4238f5f7ed7178774b43b06f6a9b6509f6642bef4ff1f7b9b2" +"checksum cesu8 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" "checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" "checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" "checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum colored 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e9a455e156a4271e12fd0246238c380b1e223e3736663c7a18ed8b6362028a9" +"checksum combine 3.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680" "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" "checksum core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4e2640d6d0bf22e82bed1b73c6aef8d5dd31e5abe6666c57e6d45e2649f4f887" "checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" @@ -2698,6 +2808,7 @@ dependencies = [ "checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c" "checksum dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" "checksum duct 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3640af123c78bedc20c1d3928e43cc0621e57011899d1ef917900c12fdb7a1ee" +"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b" "checksum env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b61fa891024a945da30a9581546e8cfaf5602c7b3f4c137a2805cf388f92075a" "checksum err-derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3d8ff65eb6c2fc68e76557239d16f5698fd56603925b89856d3f0f7105fd4543" "checksum errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2a071601ed01b988f896ab14b95e67335d1eeb50190932a1320f7fe3cadc84e" @@ -2734,6 +2845,8 @@ dependencies = [ "checksum ipnetwork 0.14.0 (git+https://github.com/mullvad/ipnetwork?branch=fix-deserialization)" = "<none>" "checksum ipnetwork 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3d862c86f7867f19b693ec86765e0252d82e53d4240b9b629815675a0714ad1" "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" +"checksum jni 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "294eca097d1dc0bf59de5ab9f7eafa5f77129e9f6464c957ed3ddeb705fb4292" +"checksum jni-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" "checksum jsonrpc-client-core 0.5.0 (git+https://github.com/mullvad/jsonrpc-client-rs?rev=68aac55b)" = "<none>" "checksum jsonrpc-client-core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f29cb249837420fb0cee7fb0fbf1d22679e121b160e71bb5e0d90b9df241c23e" "checksum jsonrpc-client-http 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e642eb74423b9dfcb4512fda167148746b76f788a823cd712fadf409f31d302" @@ -2756,6 +2869,7 @@ dependencies = [ "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" "checksum linked_hash_set 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7c91c4c7bbeb4f2f7c4e5be11e6a05bd6830bc37249c47ce1ad86ad453ff9c" "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" +"checksum lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" "checksum log-panics 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ae0136257df209261daa18d6c16394757c63e032e27aafd8b07788b051082bef" @@ -2793,8 +2907,10 @@ dependencies = [ "checksum parity-tokio-ipc 0.1.0 (git+https://github.com/nikvolf/parity-tokio-ipc)" = "<none>" "checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" "checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" +"checksum parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa7767817701cce701d5585b9c4db3cdd02086398322c1d7e8bf5094a96a2ce7" "checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" "checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" +"checksum parking_lot_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cb88cb1cb3790baa6776844f968fea3be44956cf184fa1be5a03341f5491278c" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum pfctl 0.2.1 (git+https://github.com/mullvad/pfctl-rs?rev=9f31b5ddcab941862470075eab83bb398195f3d6)" = "<none>" "checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" @@ -2836,6 +2952,7 @@ dependencies = [ "checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" "checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" +"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)" = "92514fb95f900c9b5126e32d020f5c6d40564c27a5ea6d1d7d9f157a96623560" @@ -2899,6 +3016,7 @@ dependencies = [ "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unicode_categories 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" +"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" "checksum uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a" "checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d" diff --git a/Cargo.toml b/Cargo.toml index 20d61b7d1d..04d05658d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ members = [ "mullvad-cli", "mullvad-problem-report", "mullvad-ipc-client", + "mullvad-jni", "mullvad-paths", "mullvad-types", "mullvad-rpc", @@ -12,4 +13,4 @@ members = [ "talpid-core", "talpid-ipc", ] -exclude = ["dist-assets/binaries/shadowsocks-rust"]
\ No newline at end of file +exclude = ["dist-assets/binaries/shadowsocks-rust"] diff --git a/android/build.gradle b/android/build.gradle index 5be82b79d7..d511691624 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -4,6 +4,10 @@ import org.jmailen.gradle.kotlinter.tasks.LintTask apply plugin: 'com.android.application' apply plugin: 'kotlin-android' +def repoRootPath = projectDir.absoluteFile.parentFile.absolutePath +def extraAssetsDirectory = "$project.buildDir/extraAssets" +def extraJniDirectory = "$project.buildDir/extraJni" + android { compileSdkVersion 28 buildToolsVersion '28.0.3' @@ -22,6 +26,28 @@ android { proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" } } + + sourceSets { + main { + assets { + srcDirs = files(extraAssetsDirectory) + } + + jniLibs { + srcDirs = files(extraJniDirectory) + } + } + } + + applicationVariants.all { variant -> + variant.mergeAssetsProvider.configure { + dependsOn copyApiRootCertificate + } + + variant.ndkCompileProvider.configure { + dependsOn copyMullvadJni + } + } } repositories { @@ -33,6 +59,7 @@ dependencies { implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support:recyclerview-v7:28.0.0' implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.3.21' + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1' } buildscript { @@ -65,3 +92,15 @@ task format(type: FormatTask, group: 'formatting') { } lint.dependsOn lintKotlin + +task copyMullvadJni(type: Copy) { + from "$repoRootPath/target/aarch64-linux-android/debug" + include 'libmullvad_jni.so' + into "$extraJniDirectory/arm64-v8a" +} + +task copyApiRootCertificate(type: Copy) { + from "$repoRootPath/dist-assets" + include "api_root_ca.pem" + into extraAssetsDirectory +} diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ApiRootCaFile.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ApiRootCaFile.kt new file mode 100644 index 0000000000..dc8af32ce2 --- /dev/null +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ApiRootCaFile.kt @@ -0,0 +1,29 @@ +package net.mullvad.mullvadvpn + +import java.io.File +import java.io.FileOutputStream +import java.io.InputStream + +import android.content.Context + +private const val API_ROOT_CA_FILE = "api_root_ca.pem" +private const val API_ROOT_CA_PATH = "/data/data/net.mullvad.mullvadvpn/api_root_ca.pem" + +class ApiRootCaFile { + fun extract(context: Context) { + if (!File(API_ROOT_CA_PATH).exists()) { + extractFile(context, API_ROOT_CA_FILE, API_ROOT_CA_PATH) + } + } + + private fun extractFile(context: Context, asset: String, destination: String) { + val destinationStream = FileOutputStream(destination) + + context + .assets + .open(asset) + .copyTo(destinationStream) + + destinationStream.close() + } +} diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt index b7b0e8fa8c..b751bf63d9 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/MainActivity.kt @@ -1,24 +1,51 @@ package net.mullvad.mullvadvpn +import kotlinx.coroutines.async +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.CompletableDeferred +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.Job + import android.os.Bundle import android.support.v4.app.FragmentActivity class MainActivity : FragmentActivity() { + val activityCreated = CompletableDeferred<Unit>() + + val asyncDaemon = startDaemon() + val daemon + get() = runBlocking { asyncDaemon.await() } + var selectedRelayItemCode: String? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main) + activityCreated.complete(Unit) + if (savedInstanceState == null) { addInitialFragment() } } + override fun onDestroy() { + asyncDaemon.cancel() + + super.onDestroy() + } + private fun addInitialFragment() { supportFragmentManager?.beginTransaction()?.apply { add(R.id.main_fragment, LoginFragment()) commit() } } + + private fun startDaemon() = GlobalScope.async(Dispatchers.Default) { + activityCreated.await() + ApiRootCaFile().extract(this@MainActivity) + MullvadDaemon() + } } diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt new file mode 100644 index 0000000000..d5ab845f89 --- /dev/null +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadDaemon.kt @@ -0,0 +1,10 @@ +package net.mullvad.mullvadvpn + +class MullvadDaemon { + init { + System.loadLibrary("mullvad_jni") + initialize() + } + + private external fun initialize() +} diff --git a/mullvad-daemon/src/main.rs b/mullvad-daemon/src/main.rs index 8deae9f489..9d4ca0fb56 100644 --- a/mullvad-daemon/src/main.rs +++ b/mullvad-daemon/src/main.rs @@ -48,7 +48,7 @@ fn init_logging(config: &cli::Config) -> Result<Option<PathBuf>, String> { ) .map_err(|e| e.display_chain_with_msg("Unable to initialize logger"))?; log_panics::init(); - log_version(); + version::log_version(); if let Some(ref log_dir) = log_dir { info!("Logging to {}", log_dir.display()); } @@ -119,15 +119,6 @@ fn create_daemon(log_dir: Option<PathBuf>) -> Result<Daemon, String> { .map_err(|e| e.display_chain_with_msg("Unable to initialize daemon")) } -fn log_version() { - info!( - "Starting {} - {} {}", - env!("CARGO_PKG_NAME"), - version::PRODUCT_VERSION, - version::COMMIT_DATE, - ) -} - #[cfg(unix)] fn running_as_admin() -> bool { let uid = unsafe { libc::getuid() }; diff --git a/mullvad-daemon/src/version.rs b/mullvad-daemon/src/version.rs index f02e2b5fda..72c28144ff 100644 --- a/mullvad-daemon/src/version.rs +++ b/mullvad-daemon/src/version.rs @@ -3,3 +3,12 @@ pub const PRODUCT_VERSION: &str = include_str!(concat!(env!("OUT_DIR"), "/produc /// Contains the date of the git commit this was built from pub const COMMIT_DATE: &str = include_str!(concat!(env!("OUT_DIR"), "/git-commit-date.txt")); + +pub fn log_version() { + log::info!( + "Starting {} - {} {}", + env!("CARGO_PKG_NAME"), + PRODUCT_VERSION, + COMMIT_DATE, + ) +} diff --git a/mullvad-jni/Cargo.toml b/mullvad-jni/Cargo.toml new file mode 100644 index 0000000000..9b87aa07a3 --- /dev/null +++ b/mullvad-jni/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "mullvad-jni" +version = "0.1.0" +authors = ["Mullvad VPN <admin@mullvad.net>"] +description = "JNI interface for the Mullvad daemon" +license = "GPL-3.0" +edition = "2018" + +[lib] +crate_type = ["cdylib"] + +[dependencies] +err-derive = "0.1.5" +jni = "0.11" +lazy_static = "1" +log = "0.4" +log-panics = "2" +parking_lot = "0.8" + +mullvad-daemon = { path = "../mullvad-daemon" } +mullvad-paths = { path = "../mullvad-paths" } +mullvad-types = { path = "../mullvad-types" } +talpid-types = { path = "../talpid-types" } diff --git a/mullvad-jni/src/daemon_interface.rs b/mullvad-jni/src/daemon_interface.rs new file mode 100644 index 0000000000..b682660edf --- /dev/null +++ b/mullvad-jni/src/daemon_interface.rs @@ -0,0 +1,17 @@ +use mullvad_daemon::DaemonCommandSender; + +pub struct DaemonInterface { + command_sender: Option<DaemonCommandSender>, +} + +impl DaemonInterface { + pub fn new() -> Self { + DaemonInterface { + command_sender: None, + } + } + + pub fn set_command_sender(&mut self, sender: DaemonCommandSender) { + self.command_sender = Some(sender); + } +} diff --git a/mullvad-jni/src/lib.rs b/mullvad-jni/src/lib.rs new file mode 100644 index 0000000000..ce6d953fcd --- /dev/null +++ b/mullvad-jni/src/lib.rs @@ -0,0 +1,102 @@ +#![cfg(target_os = "android")] + +mod daemon_interface; + +use crate::daemon_interface::DaemonInterface; +use jni::{objects::JObject, JNIEnv}; +use lazy_static::lazy_static; +use mullvad_daemon::{logging, version, Daemon, DaemonCommandSender, EventListener}; +use mullvad_types::{relay_list::RelayList, settings::Settings}; +use parking_lot::Mutex; +use std::{path::PathBuf, sync::mpsc, thread}; +use talpid_types::{tunnel::TunnelStateTransition, ErrorExt}; + +const LOG_FILENAME: &str = "daemon.log"; + +lazy_static! { + static ref DAEMON_INTERFACE: Mutex<DaemonInterface> = Mutex::new(DaemonInterface::new()); +} + +#[derive(Debug, err_derive::Error)] +pub enum Error { + #[error(display = "Failed to get cache directory path")] + GetCacheDir(#[error(cause)] mullvad_paths::Error), + + #[error(display = "Failed to initialize the mullvad daemon")] + InitializeDaemon(#[error(cause)] mullvad_daemon::Error), +} + +#[no_mangle] +#[allow(non_snake_case)] +pub extern "system" fn Java_net_mullvad_mullvadvpn_MullvadDaemon_initialize(_: JNIEnv, _: JObject) { + let log_dir = start_logging(); + + if let Err(error) = initialize(log_dir) { + log::error!("{}", error.display_chain()); + } +} + +fn start_logging() -> PathBuf { + let log_dir = mullvad_paths::log_dir().unwrap(); + let log_file = log_dir.join(LOG_FILENAME); + + logging::init_logger(log::LevelFilter::Debug, Some(&log_file), true).unwrap(); + log_panics::init(); + version::log_version(); + + log_dir +} + +fn initialize(log_dir: PathBuf) -> Result<(), Error> { + let daemon_command_sender = spawn_daemon(log_dir)?; + + DAEMON_INTERFACE + .lock() + .set_command_sender(daemon_command_sender); + + Ok(()) +} + +fn spawn_daemon(log_dir: PathBuf) -> Result<DaemonCommandSender, Error> { + let (tx, rx) = mpsc::channel(); + + thread::spawn(move || match create_daemon(log_dir) { + Ok(daemon) => { + let _ = tx.send(Ok(daemon.command_sender())); + match daemon.run() { + Ok(()) => log::info!("Mullvad daemon has stopped"), + Err(error) => log::error!("{}", error.display_chain()), + } + } + Err(error) => { + let _ = tx.send(Err(error)); + } + }); + + rx.recv().unwrap() +} + +fn create_daemon(log_dir: PathBuf) -> Result<Daemon<DummyListener>, Error> { + let resource_dir = mullvad_paths::get_resource_dir(); + let cache_dir = mullvad_paths::cache_dir().map_err(Error::GetCacheDir)?; + + let daemon = Daemon::start_with_event_listener( + DummyListener, + Some(log_dir), + resource_dir, + cache_dir, + version::PRODUCT_VERSION.to_owned(), + ) + .map_err(Error::InitializeDaemon)?; + + Ok(daemon) +} + +#[derive(Clone, Copy, Debug)] +struct DummyListener; + +impl EventListener for DummyListener { + fn notify_new_state(&self, _: TunnelStateTransition) {} + fn notify_settings(&self, _: Settings) {} + fn notify_relay_list(&self, _: RelayList) {} +} |
