From cd6a124c8464dce75ec83e32592a5559013f15db Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Wed, 8 Nov 2017 00:49:44 -0600 Subject: [PATCH] VpnService: Add helper for importing configs Signed-off-by: Jason A. Donenfeld --- .../com/wireguard/android/VpnService.java | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/app/src/main/java/com/wireguard/android/VpnService.java b/app/src/main/java/com/wireguard/android/VpnService.java index 265c6e57..0a828bc0 100644 --- a/app/src/main/java/com/wireguard/android/VpnService.java +++ b/app/src/main/java/com/wireguard/android/VpnService.java @@ -2,8 +2,10 @@ package com.wireguard.android; import android.app.Service; import android.content.ComponentName; +import android.content.ContentResolver; import android.content.Intent; import android.content.SharedPreferences; +import android.net.Uri; import android.os.AsyncTask; import android.os.Binder; import android.os.Build; @@ -21,7 +23,10 @@ import java.io.File; import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.LinkedList; @@ -112,6 +117,10 @@ public class VpnService extends Service return configurations; } + public void importFrom(final Uri... uris) { + new ConfigImporter().execute(uris); + } + @Override public IBinder onBind(final Intent intent) { instance = this; @@ -268,6 +277,47 @@ public class VpnService extends Service } } + private class ConfigImporter extends AsyncTask> { + @Override + protected List doInBackground(final Uri... uris) { + final ContentResolver contentResolver = getContentResolver(); + final List files = new ArrayList<>(uris.length); + for (final Uri uri : uris) { + if (isCancelled()) + return null; + String name = Uri.decode(uri.getLastPathSegment()); + if (name.indexOf('/') >= 0) + name = name.substring(name.lastIndexOf('/')); + if (!name.endsWith(".conf")) + name = name + ".conf"; + final File output = new File(getFilesDir(), name); + if (output.exists()) { + Log.w(getClass().getSimpleName(), "Config file for " + uri + " already exists"); + continue; + } + try (final InputStream in = contentResolver.openInputStream(uri); + final OutputStream out = new FileOutputStream(output, false)) { + if (in == null) + throw new IOException("Failed to open input"); + // FIXME: This is a rather arbitrary size. + final byte[] buffer = new byte[4096]; + int bytes; + while ((bytes = in.read(buffer)) != -1) + out.write(buffer, 0, bytes); + files.add(output); + } catch (final IOException e) { + Log.w(getClass().getSimpleName(), "Failed to import config from " + uri, e); + } + } + return files; + } + + @Override + protected void onPostExecute(final List files) { + new ConfigLoader().execute(files.toArray(new File[files.size()])); + } + } + private class ConfigLoader extends AsyncTask> { @Override protected List doInBackground(final File... files) {