VpnService: Fix some edge cases in ConfigUpdater

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
Samuel Holland 2017-08-23 18:04:45 -05:00
parent 0e46f95668
commit d1a5c1a72e

View File

@ -353,27 +353,27 @@ public class VpnService extends Service
} }
private class ConfigUpdater extends AsyncTask<Void, Void, Boolean> { private class ConfigUpdater extends AsyncTask<Void, Void, Boolean> {
private Config newConfig; private Config knownConfig;
private final Config newConfig;
private final String newName; private final String newName;
private final Config oldConfig;
private final String oldName; private final String oldName;
private final Boolean shouldConnect; private final Boolean shouldConnect;
private ConfigUpdater(final Config oldConfig, final Config newConfig, private ConfigUpdater(final Config knownConfig, final Config newConfig,
final Boolean shouldConnect) { final Boolean shouldConnect) {
this.newConfig = newConfig; this.knownConfig = knownConfig;
this.oldConfig = oldConfig; this.newConfig = newConfig.copy();
this.shouldConnect = shouldConnect;
newName = newConfig.getName(); newName = newConfig.getName();
// When adding a config, "old file" and "new file" are the same thing. // When adding a config, "old file" and "new file" are the same thing.
oldName = oldConfig != null ? oldConfig.getName() : newName; oldName = knownConfig != null ? knownConfig.getName() : newName;
this.shouldConnect = shouldConnect;
if (isAddOrRename() && configurations.containsKey(newName)) if (isAddOrRename() && configurations.containsKey(newName))
throw new IllegalStateException("Config " + newName + " already exists"); throw new IllegalStateException("Config " + newName + " already exists");
} }
@Override @Override
protected Boolean doInBackground(final Void... voids) { protected Boolean doInBackground(final Void... voids) {
Log.i(TAG, (oldConfig == null ? "Adding" : "Updating") + " config " + newName); Log.i(TAG, (knownConfig == null ? "Adding" : "Updating") + " config " + newName);
final File newFile = new File(getFilesDir(), newName + ".conf"); final File newFile = new File(getFilesDir(), newName + ".conf");
final File oldFile = new File(getFilesDir(), oldName + ".conf"); final File oldFile = new File(getFilesDir(), oldName + ".conf");
if (isAddOrRename() && newFile.exists()) { if (isAddOrRename() && newFile.exists()) {
@ -396,28 +396,29 @@ public class VpnService extends Service
} }
private boolean isAddOrRename() { private boolean isAddOrRename() {
return oldConfig == null || !newName.equals(oldName); return knownConfig == null || !newName.equals(oldName);
} }
private boolean isRename() { private boolean isRename() {
return oldConfig != null && !newName.equals(oldName); return knownConfig != null && !newName.equals(oldName);
} }
@Override @Override
protected void onPostExecute(final Boolean result) { protected void onPostExecute(final Boolean result) {
if (!result) if (!result)
return; return;
if (oldConfig != null) { if (knownConfig != null)
configurations.remove(oldName); configurations.remove(oldName);
oldConfig.copyFrom(newConfig); if (knownConfig == null)
newConfig = oldConfig; knownConfig = new Config();
} knownConfig.copyFrom(newConfig);
newConfig.setIsEnabled(false); knownConfig.setIsEnabled(false);
configurations.put(newName, newConfig); knownConfig.setIsPrimary(oldName != null && oldName.equals(primaryName));
if (isRename() && oldName.equals(primaryName)) configurations.put(newName, knownConfig);
if (isRename() && oldName != null && oldName.equals(primaryName))
preferences.edit().putString(KEY_PRIMARY_CONFIG, newName).apply(); preferences.edit().putString(KEY_PRIMARY_CONFIG, newName).apply();
if (shouldConnect) if (shouldConnect)
new ConfigEnabler(newConfig).execute(); new ConfigEnabler(knownConfig).execute();
} }
} }
} }