]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
android: Add interface for VPN data source
authorMarkus Pfeiffer <markus.pfeiffer@relution.io>
Tue, 21 Nov 2023 14:37:21 +0000 (15:37 +0100)
committerTobias Brunner <tobias@strongswan.org>
Wed, 21 Feb 2024 11:24:52 +0000 (12:24 +0100)
Change VPN profile source to an interface. Preparation to allow managed
configurations as a second source.

src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfileDataSource.java
src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfileSource.java [new file with mode: 0644]
src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfileSqlDataSource.java [new file with mode: 0644]
src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java
src/frontends/android/app/src/main/java/org/strongswan/android/ui/SettingsFragment.java
src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileControlActivity.java
src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileDetailActivity.java
src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileImportActivity.java
src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileListFragment.java
src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnTileService.java

index 5604f67a1a29d71b951a698d85d4c8a05d0d25ec..07308956c7c22a0d5f7d32a3fa9a46689cc202c5 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2023 Relution GmbH
  * Copyright (C) 2012-2019 Tobias Brunner
  * Copyright (C) 2012 Giuliano Grassi
  * Copyright (C) 2012 Ralf Sager
 
 package org.strongswan.android.data;
 
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
 import android.database.SQLException;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.database.sqlite.SQLiteQueryBuilder;
-import android.util.Log;
 
-import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
 
-public class VpnProfileDataSource
+public interface VpnProfileDataSource
 {
-       private static final String TAG = VpnProfileDataSource.class.getSimpleName();
-       public static final String KEY_ID = "_id";
-       public static final String KEY_UUID = "_uuid";
-       public static final String KEY_NAME = "name";
-       public static final String KEY_GATEWAY = "gateway";
-       public static final String KEY_VPN_TYPE = "vpn_type";
-       public static final String KEY_USERNAME = "username";
-       public static final String KEY_PASSWORD = "password";
-       public static final String KEY_CERTIFICATE = "certificate";
-       public static final String KEY_USER_CERTIFICATE = "user_certificate";
-       public static final String KEY_MTU = "mtu";
-       public static final String KEY_PORT = "port";
-       public static final String KEY_SPLIT_TUNNELING = "split_tunneling";
-       public static final String KEY_LOCAL_ID = "local_id";
-       public static final String KEY_REMOTE_ID = "remote_id";
-       public static final String KEY_EXCLUDED_SUBNETS = "excluded_subnets";
-       public static final String KEY_INCLUDED_SUBNETS = "included_subnets";
-       public static final String KEY_SELECTED_APPS = "selected_apps";
-       public static final String KEY_SELECTED_APPS_LIST = "selected_apps_list";
-       public static final String KEY_NAT_KEEPALIVE = "nat_keepalive";
-       public static final String KEY_FLAGS = "flags";
-       public static final String KEY_IKE_PROPOSAL = "ike_proposal";
-       public static final String KEY_ESP_PROPOSAL = "esp_proposal";
-       public static final String KEY_DNS_SERVERS = "dns_servers";
-
-       private DatabaseHelper mDbHelper;
-       private SQLiteDatabase mDatabase;
-       private final Context mContext;
-
-       private static final String DATABASE_NAME = "strongswan.db";
-       private static final String TABLE_VPNPROFILE = "vpnprofile";
-
-       private static final int DATABASE_VERSION = 17;
-
-       public static final DbColumn[] COLUMNS = new DbColumn[] {
-                                                               new DbColumn(KEY_ID, "INTEGER PRIMARY KEY AUTOINCREMENT", 1),
-                                                               new DbColumn(KEY_UUID, "TEXT UNIQUE", 9),
-                                                               new DbColumn(KEY_NAME, "TEXT NOT NULL", 1),
-                                                               new DbColumn(KEY_GATEWAY, "TEXT NOT NULL", 1),
-                                                               new DbColumn(KEY_VPN_TYPE, "TEXT NOT NULL", 3),
-                                                               new DbColumn(KEY_USERNAME, "TEXT", 1),
-                                                               new DbColumn(KEY_PASSWORD, "TEXT", 1),
-                                                               new DbColumn(KEY_CERTIFICATE, "TEXT", 1),
-                                                               new DbColumn(KEY_USER_CERTIFICATE, "TEXT", 2),
-                                                               new DbColumn(KEY_MTU, "INTEGER", 5),
-                                                               new DbColumn(KEY_PORT, "INTEGER", 5),
-                                                               new DbColumn(KEY_SPLIT_TUNNELING, "INTEGER", 7),
-                                                               new DbColumn(KEY_LOCAL_ID, "TEXT", 8),
-                                                               new DbColumn(KEY_REMOTE_ID, "TEXT", 8),
-                                                               new DbColumn(KEY_EXCLUDED_SUBNETS, "TEXT", 10),
-                                                               new DbColumn(KEY_INCLUDED_SUBNETS, "TEXT", 11),
-                                                               new DbColumn(KEY_SELECTED_APPS, "INTEGER", 12),
-                                                               new DbColumn(KEY_SELECTED_APPS_LIST, "TEXT", 12),
-                                                               new DbColumn(KEY_NAT_KEEPALIVE, "INTEGER", 13),
-                                                               new DbColumn(KEY_FLAGS, "INTEGER", 14),
-                                                               new DbColumn(KEY_IKE_PROPOSAL, "TEXT", 15),
-                                                               new DbColumn(KEY_ESP_PROPOSAL, "TEXT", 15),
-                                                               new DbColumn(KEY_DNS_SERVERS, "TEXT", 17),
-                                                       };
-
-       private static final String[] ALL_COLUMNS = getColumns(DATABASE_VERSION);
-
-       private static String getDatabaseCreate(int version)
-       {
-               boolean first = true;
-               StringBuilder create = new StringBuilder("CREATE TABLE ");
-               create.append(TABLE_VPNPROFILE);
-               create.append(" (");
-               for (DbColumn column : COLUMNS)
-               {
-                       if (column.Since <= version)
-                       {
-                               if (!first)
-                               {
-                                       create.append(",");
-                               }
-                               first = false;
-                               create.append(column.Name);
-                               create.append(" ");
-                               create.append(column.Type);
-                       }
-               }
-               create.append(");");
-               return create.toString();
-       }
-
-       private static String[] getColumns(int version)
-       {
-               ArrayList<String> columns = new ArrayList<>();
-               for (DbColumn column : COLUMNS)
-               {
-                       if (column.Since <= version)
-                       {
-                               columns.add(column.Name);
-                       }
-               }
-               return columns.toArray(new String[0]);
-       }
-
-       private static class DatabaseHelper extends SQLiteOpenHelper
-       {
-               public DatabaseHelper(Context context)
-               {
-                       super(context, DATABASE_NAME, null, DATABASE_VERSION);
-               }
-
-               @Override
-               public void onCreate(SQLiteDatabase database)
-               {
-                       database.execSQL(getDatabaseCreate(DATABASE_VERSION));
-               }
-
-               @Override
-               public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
-               {
-                       Log.w(TAG, "Upgrading database from version " + oldVersion +
-                                 " to " + newVersion);
-                       if (oldVersion < 2)
-                       {
-                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_USER_CERTIFICATE +
-                                                  " TEXT;");
-                       }
-                       if (oldVersion < 3)
-                       {
-                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_VPN_TYPE +
-                                                  " TEXT DEFAULT '';");
-                       }
-                       if (oldVersion < 4)
-                       {       /* remove NOT NULL constraint from username column */
-                               updateColumns(db, 4);
-                       }
-                       if (oldVersion < 5)
-                       {
-                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_MTU +
-                                                  " INTEGER;");
-                       }
-                       if (oldVersion < 6)
-                       {
-                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_PORT +
-                                                  " INTEGER;");
-                       }
-                       if (oldVersion < 7)
-                       {
-                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_SPLIT_TUNNELING +
-                                                  " INTEGER;");
-                       }
-                       if (oldVersion < 8)
-                       {
-                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_LOCAL_ID +
-                                                  " TEXT;");
-                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_REMOTE_ID +
-                                                  " TEXT;");
-                       }
-                       if (oldVersion < 9)
-                       {
-                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_UUID +
-                                                  " TEXT;");
-                               updateColumns(db, 9);
-                       }
-                       if (oldVersion < 10)
-                       {
-                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_EXCLUDED_SUBNETS +
-                                                  " TEXT;");
-                       }
-                       if (oldVersion < 11)
-                       {
-                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_INCLUDED_SUBNETS +
-                                                  " TEXT;");
-                       }
-                       if (oldVersion < 12)
-                       {
-                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_SELECTED_APPS +
-                                                  " INTEGER;");
-                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_SELECTED_APPS_LIST +
-                                                  " TEXT;");
-                       }
-                       if (oldVersion < 13)
-                       {
-                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_NAT_KEEPALIVE +
-                                                  " INTEGER;");
-                       }
-                       if (oldVersion < 14)
-                       {
-                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_FLAGS +
-                                                  " INTEGER;");
-                       }
-                       if (oldVersion < 15)
-                       {
-                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_IKE_PROPOSAL +
-                                                  " TEXT;");
-                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_ESP_PROPOSAL +
-                                                  " TEXT;");
-                       }
-                       if (oldVersion < 16)
-                       {       /* add a UUID to all entries that haven't one yet */
-                               db.beginTransaction();
-                               try
-                               {
-                                       Cursor cursor = db.query(TABLE_VPNPROFILE, getColumns(16), KEY_UUID + " is NULL", null, null, null, null);
-                                       for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext())
-                                       {
-                                               ContentValues values = new ContentValues();
-                                               values.put(KEY_UUID, UUID.randomUUID().toString());
-                                               db.update(TABLE_VPNPROFILE, values, KEY_ID + " = " + cursor.getLong(cursor.getColumnIndexOrThrow(KEY_ID)), null);
-                                       }
-                                       cursor.close();
-                                       db.setTransactionSuccessful();
-                               }
-                               finally
-                               {
-                                       db.endTransaction();
-                               }
-                       }
-                       if (oldVersion < 17)
-                       {
-                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_DNS_SERVERS +
-                                                  " TEXT;");
-                       }
-               }
-
-               private void updateColumns(SQLiteDatabase db, int version)
-               {
-                       db.beginTransaction();
-                       try
-                       {
-                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " RENAME TO tmp_" + TABLE_VPNPROFILE + ";");
-                               db.execSQL(getDatabaseCreate(version));
-                               StringBuilder insert = new StringBuilder("INSERT INTO " + TABLE_VPNPROFILE + " SELECT ");
-                               SQLiteQueryBuilder.appendColumns(insert, getColumns(version));
-                               db.execSQL(insert.append(" FROM tmp_" + TABLE_VPNPROFILE + ";").toString());
-                               db.execSQL("DROP TABLE tmp_" + TABLE_VPNPROFILE + ";");
-                               db.setTransactionSuccessful();
-                       }
-                       finally
-                       {
-                               db.endTransaction();
-                       }
-               }
-       }
-
-       /**
-        * Construct a new VPN profile data source. The context is used to
-        * open/create the database.
-        * @param context context used to access the database
-        */
-       public VpnProfileDataSource(Context context)
-       {
-               this.mContext = context;
-       }
+       String KEY_ID = "_id";
+       String KEY_UUID = "_uuid";
+       String KEY_NAME = "name";
+       String KEY_GATEWAY = "gateway";
+       String KEY_VPN_TYPE = "vpn_type";
+       String KEY_USERNAME = "username";
+       String KEY_PASSWORD = "password";
+       String KEY_CERTIFICATE = "certificate";
+       String KEY_USER_CERTIFICATE = "user_certificate";
+       String KEY_MTU = "mtu";
+       String KEY_PORT = "port";
+       String KEY_SPLIT_TUNNELING = "split_tunneling";
+       String KEY_LOCAL_ID = "local_id";
+       String KEY_REMOTE_ID = "remote_id";
+       String KEY_EXCLUDED_SUBNETS = "excluded_subnets";
+       String KEY_INCLUDED_SUBNETS = "included_subnets";
+       String KEY_SELECTED_APPS = "selected_apps";
+       String KEY_SELECTED_APPS_LIST = "selected_apps_list";
+       String KEY_NAT_KEEPALIVE = "nat_keepalive";
+       String KEY_FLAGS = "flags";
+       String KEY_IKE_PROPOSAL = "ike_proposal";
+       String KEY_ESP_PROPOSAL = "esp_proposal";
+       String KEY_DNS_SERVERS = "dns_servers";
 
        /**
         * Open the VPN profile data source. The database is automatically created
         * if it does not yet exist. If that fails an exception is thrown.
+        *
         * @return itself (allows to chain initialization calls)
         * @throws SQLException if the database could not be opened or created
         */
-       public VpnProfileDataSource open() throws SQLException
-       {
-               if (mDbHelper == null)
-               {
-                       mDbHelper = new DatabaseHelper(mContext);
-                       mDatabase = mDbHelper.getWritableDatabase();
-               }
-               return this;
-       }
+       VpnProfileDataSource open() throws SQLException;
 
        /**
         * Close the data source.
         */
-       public void close()
-       {
-               if (mDbHelper != null)
-               {
-                       mDbHelper.close();
-                       mDbHelper = null;
-               }
-       }
+       void close();
 
        /**
         * Insert the given VPN profile into the database.  On success the Id of
@@ -318,83 +71,47 @@ public class VpnProfileDataSource
         * @param profile the profile to add
         * @return the added VPN profile or null, if failed
         */
-       public VpnProfile insertProfile(VpnProfile profile)
-       {
-               ContentValues values = ContentValuesFromVpnProfile(profile);
-               long insertId = mDatabase.insert(TABLE_VPNPROFILE, null, values);
-               if (insertId == -1)
-               {
-                       return null;
-               }
-               profile.setId(insertId);
-               return profile;
-       }
+       VpnProfile insertProfile(VpnProfile profile);
 
        /**
         * Updates the given VPN profile in the database.
+        *
         * @param profile the profile to update
         * @return true if update succeeded, false otherwise
         */
-       public boolean updateVpnProfile(VpnProfile profile)
-       {
-               long id = profile.getId();
-               ContentValues values = ContentValuesFromVpnProfile(profile);
-               return mDatabase.update(TABLE_VPNPROFILE, values, KEY_ID + " = " + id, null) > 0;
-       }
+       boolean updateVpnProfile(VpnProfile profile);
 
        /**
         * Delete the given VPN profile from the database.
+        *
         * @param profile the profile to delete
         * @return true if deleted, false otherwise
         */
-       public boolean deleteVpnProfile(VpnProfile profile)
-       {
-               long id = profile.getId();
-               return mDatabase.delete(TABLE_VPNPROFILE, KEY_ID + " = " + id, null) > 0;
-       }
+       boolean deleteVpnProfile(VpnProfile profile);
 
        /**
         * Get a single VPN profile from the database.
+        *
         * @param id the ID of the VPN profile
         * @return the profile or null, if not found
         */
-       public VpnProfile getVpnProfile(long id)
-       {
-               VpnProfile profile = null;
-               Cursor cursor = mDatabase.query(TABLE_VPNPROFILE, ALL_COLUMNS,
-                                                                               KEY_ID + "=" + id, null, null, null, null);
-               if (cursor.moveToFirst())
-               {
-                       profile = VpnProfileFromCursor(cursor);
-               }
-               cursor.close();
-               return profile;
-       }
+       VpnProfile getVpnProfile(long id);
 
        /**
         * Get a single VPN profile from the database by its UUID.
+        *
         * @param uuid the UUID of the VPN profile
         * @return the profile or null, if not found
         */
-       public VpnProfile getVpnProfile(UUID uuid)
-       {
-               VpnProfile profile = null;
-               Cursor cursor = mDatabase.query(TABLE_VPNPROFILE, ALL_COLUMNS,
-                                                                               KEY_UUID + "='" + uuid.toString() + "'", null, null, null, null);
-               if (cursor.moveToFirst())
-               {
-                       profile = VpnProfileFromCursor(cursor);
-               }
-               cursor.close();
-               return profile;
-       }
+       VpnProfile getVpnProfile(UUID uuid);
 
        /**
         * Get a single VPN profile from the database by its UUID as String.
+        *
         * @param uuid the UUID of the VPN profile as String
         * @return the profile or null, if not found
         */
-       public VpnProfile getVpnProfile(String uuid)
+       default VpnProfile getVpnProfile(String uuid)
        {
                try
                {
@@ -413,97 +130,8 @@ public class VpnProfileDataSource
 
        /**
         * Get a list of all VPN profiles stored in the database.
+        *
         * @return list of VPN profiles
         */
-       public List<VpnProfile> getAllVpnProfiles()
-       {
-               List<VpnProfile> vpnProfiles = new ArrayList<VpnProfile>();
-
-               Cursor cursor = mDatabase.query(TABLE_VPNPROFILE, ALL_COLUMNS, null, null, null, null, null);
-               cursor.moveToFirst();
-               while (!cursor.isAfterLast())
-               {
-                       VpnProfile vpnProfile = VpnProfileFromCursor(cursor);
-                       vpnProfiles.add(vpnProfile);
-                       cursor.moveToNext();
-               }
-               cursor.close();
-               return vpnProfiles;
-       }
-
-       private VpnProfile VpnProfileFromCursor(Cursor cursor)
-       {
-               VpnProfile profile = new VpnProfile();
-               profile.setId(cursor.getLong(cursor.getColumnIndexOrThrow(KEY_ID)));
-               profile.setUUID(UUID.fromString(cursor.getString(cursor.getColumnIndexOrThrow(KEY_UUID))));
-               profile.setName(cursor.getString(cursor.getColumnIndexOrThrow(KEY_NAME)));
-               profile.setGateway(cursor.getString(cursor.getColumnIndexOrThrow(KEY_GATEWAY)));
-               profile.setVpnType(VpnType.fromIdentifier(cursor.getString(cursor.getColumnIndexOrThrow(KEY_VPN_TYPE))));
-               profile.setUsername(cursor.getString(cursor.getColumnIndexOrThrow(KEY_USERNAME)));
-               profile.setPassword(cursor.getString(cursor.getColumnIndexOrThrow(KEY_PASSWORD)));
-               profile.setCertificateAlias(cursor.getString(cursor.getColumnIndexOrThrow(KEY_CERTIFICATE)));
-               profile.setUserCertificateAlias(cursor.getString(cursor.getColumnIndexOrThrow(KEY_USER_CERTIFICATE)));
-               profile.setMTU(getInt(cursor, cursor.getColumnIndexOrThrow(KEY_MTU)));
-               profile.setPort(getInt(cursor, cursor.getColumnIndexOrThrow(KEY_PORT)));
-               profile.setSplitTunneling(getInt(cursor, cursor.getColumnIndexOrThrow(KEY_SPLIT_TUNNELING)));
-               profile.setLocalId(cursor.getString(cursor.getColumnIndexOrThrow(KEY_LOCAL_ID)));
-               profile.setRemoteId(cursor.getString(cursor.getColumnIndexOrThrow(KEY_REMOTE_ID)));
-               profile.setExcludedSubnets(cursor.getString(cursor.getColumnIndexOrThrow(KEY_EXCLUDED_SUBNETS)));
-               profile.setIncludedSubnets(cursor.getString(cursor.getColumnIndexOrThrow(KEY_INCLUDED_SUBNETS)));
-               profile.setSelectedAppsHandling(getInt(cursor, cursor.getColumnIndexOrThrow(KEY_SELECTED_APPS)));
-               profile.setSelectedApps(cursor.getString(cursor.getColumnIndexOrThrow(KEY_SELECTED_APPS_LIST)));
-               profile.setNATKeepAlive(getInt(cursor, cursor.getColumnIndexOrThrow(KEY_NAT_KEEPALIVE)));
-               profile.setFlags(getInt(cursor, cursor.getColumnIndexOrThrow(KEY_FLAGS)));
-               profile.setIkeProposal(cursor.getString(cursor.getColumnIndexOrThrow(KEY_IKE_PROPOSAL)));
-               profile.setEspProposal(cursor.getString(cursor.getColumnIndexOrThrow(KEY_ESP_PROPOSAL)));
-               profile.setDnsServers(cursor.getString(cursor.getColumnIndexOrThrow(KEY_DNS_SERVERS)));
-               return profile;
-       }
-
-       private ContentValues ContentValuesFromVpnProfile(VpnProfile profile)
-       {
-               ContentValues values = new ContentValues();
-               values.put(KEY_UUID, profile.getUUID().toString());
-               values.put(KEY_NAME, profile.getName());
-               values.put(KEY_GATEWAY, profile.getGateway());
-               values.put(KEY_VPN_TYPE, profile.getVpnType().getIdentifier());
-               values.put(KEY_USERNAME, profile.getUsername());
-               values.put(KEY_PASSWORD, profile.getPassword());
-               values.put(KEY_CERTIFICATE, profile.getCertificateAlias());
-               values.put(KEY_USER_CERTIFICATE, profile.getUserCertificateAlias());
-               values.put(KEY_MTU, profile.getMTU());
-               values.put(KEY_PORT, profile.getPort());
-               values.put(KEY_SPLIT_TUNNELING, profile.getSplitTunneling());
-               values.put(KEY_LOCAL_ID, profile.getLocalId());
-               values.put(KEY_REMOTE_ID, profile.getRemoteId());
-               values.put(KEY_EXCLUDED_SUBNETS, profile.getExcludedSubnets());
-               values.put(KEY_INCLUDED_SUBNETS, profile.getIncludedSubnets());
-               values.put(KEY_SELECTED_APPS, profile.getSelectedAppsHandling().getValue());
-               values.put(KEY_SELECTED_APPS_LIST, profile.getSelectedApps());
-               values.put(KEY_NAT_KEEPALIVE, profile.getNATKeepAlive());
-               values.put(KEY_FLAGS, profile.getFlags());
-               values.put(KEY_IKE_PROPOSAL, profile.getIkeProposal());
-               values.put(KEY_ESP_PROPOSAL, profile.getEspProposal());
-               values.put(KEY_DNS_SERVERS, profile.getDnsServers());
-               return values;
-       }
-
-       private Integer getInt(Cursor cursor, int columnIndex)
-       {
-               return cursor.isNull(columnIndex) ? null : cursor.getInt(columnIndex);
-       }
-
-       private static class DbColumn
-       {
-               public final String Name;
-               public final String Type;
-               public final Integer Since;
-
-               public DbColumn(String name, String type, Integer since)
-               {
-                       Name = name;
-                       Type = type;
-                       Since = since;
-               }
-       }
+       List<VpnProfile> getAllVpnProfiles();
 }
diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfileSource.java b/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfileSource.java
new file mode 100644 (file)
index 0000000..98e8794
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2023 Relution GmbH
+ *
+ * Copyright (C) secunet Security Networks AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+package org.strongswan.android.data;
+
+import android.content.Context;
+import android.database.SQLException;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+public class VpnProfileSource implements VpnProfileDataSource
+{
+       private final List<VpnProfileDataSource> dataSources = new ArrayList<>();
+       private final VpnProfileSqlDataSource vpnProfileSqlDataSource;
+
+       public VpnProfileSource(Context context)
+       {
+               vpnProfileSqlDataSource = new VpnProfileSqlDataSource(context);
+               dataSources.add(vpnProfileSqlDataSource);
+       }
+
+       @Override
+       public VpnProfileDataSource open() throws SQLException
+       {
+               for (final VpnProfileDataSource source : dataSources)
+               {
+                       source.open();
+               }
+               return this;
+       }
+
+       @Override
+       public void close()
+       {
+               for (final VpnProfileDataSource source : dataSources)
+               {
+                       source.close();
+               }
+       }
+
+       @Override
+       public VpnProfile insertProfile(VpnProfile profile)
+       {
+               return vpnProfileSqlDataSource.insertProfile(profile);
+       }
+
+       @Override
+       public boolean updateVpnProfile(VpnProfile profile)
+       {
+               return vpnProfileSqlDataSource.updateVpnProfile(profile);
+       }
+
+       @Override
+       public boolean deleteVpnProfile(VpnProfile profile)
+       {
+               return vpnProfileSqlDataSource.deleteVpnProfile(profile);
+       }
+
+       @Override
+       public VpnProfile getVpnProfile(long id)
+       {
+               for (final VpnProfileDataSource source : dataSources)
+               {
+                       final VpnProfile profile = source.getVpnProfile(id);
+                       if (profile != null)
+                       {
+                               return profile;
+                       }
+               }
+               return null;
+       }
+
+       @Override
+       public VpnProfile getVpnProfile(UUID uuid)
+       {
+               for (final VpnProfileDataSource source : dataSources)
+               {
+                       final VpnProfile profile = source.getVpnProfile(uuid);
+                       if (profile != null)
+                       {
+                               return profile;
+                       }
+               }
+               return null;
+       }
+
+       @Override
+       public List<VpnProfile> getAllVpnProfiles()
+       {
+               final List<VpnProfile> profiles = new ArrayList<>();
+
+               for (final VpnProfileDataSource source : dataSources)
+               {
+                       profiles.addAll(source.getAllVpnProfiles());
+               }
+
+               return profiles;
+       }
+}
diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfileSqlDataSource.java b/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfileSqlDataSource.java
new file mode 100644 (file)
index 0000000..3b5339e
--- /dev/null
@@ -0,0 +1,433 @@
+/*
+ * Copyright (C) 2012-2019 Tobias Brunner
+ * Copyright (C) 2012 Giuliano Grassi
+ * Copyright (C) 2012 Ralf Sager
+ *
+ * Copyright (C) secunet Security Networks AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+package org.strongswan.android.data;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.SQLException;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+public class VpnProfileSqlDataSource implements VpnProfileDataSource
+{
+       private static final String TAG = VpnProfileSqlDataSource.class.getSimpleName();
+
+       private static final DbColumn[] COLUMNS = new VpnProfileSqlDataSource.DbColumn[]{
+               new VpnProfileSqlDataSource.DbColumn(KEY_ID, "INTEGER PRIMARY KEY AUTOINCREMENT", 1),
+               new VpnProfileSqlDataSource.DbColumn(KEY_UUID, "TEXT UNIQUE", 9),
+               new VpnProfileSqlDataSource.DbColumn(KEY_NAME, "TEXT NOT NULL", 1),
+               new VpnProfileSqlDataSource.DbColumn(KEY_GATEWAY, "TEXT NOT NULL", 1),
+               new VpnProfileSqlDataSource.DbColumn(KEY_VPN_TYPE, "TEXT NOT NULL", 3),
+               new VpnProfileSqlDataSource.DbColumn(KEY_USERNAME, "TEXT", 1),
+               new VpnProfileSqlDataSource.DbColumn(KEY_PASSWORD, "TEXT", 1),
+               new VpnProfileSqlDataSource.DbColumn(KEY_CERTIFICATE, "TEXT", 1),
+               new VpnProfileSqlDataSource.DbColumn(KEY_USER_CERTIFICATE, "TEXT", 2),
+               new VpnProfileSqlDataSource.DbColumn(KEY_MTU, "INTEGER", 5),
+               new VpnProfileSqlDataSource.DbColumn(KEY_PORT, "INTEGER", 5),
+               new VpnProfileSqlDataSource.DbColumn(KEY_SPLIT_TUNNELING, "INTEGER", 7),
+               new VpnProfileSqlDataSource.DbColumn(KEY_LOCAL_ID, "TEXT", 8),
+               new VpnProfileSqlDataSource.DbColumn(KEY_REMOTE_ID, "TEXT", 8),
+               new VpnProfileSqlDataSource.DbColumn(KEY_EXCLUDED_SUBNETS, "TEXT", 10),
+               new VpnProfileSqlDataSource.DbColumn(KEY_INCLUDED_SUBNETS, "TEXT", 11),
+               new VpnProfileSqlDataSource.DbColumn(KEY_SELECTED_APPS, "INTEGER", 12),
+               new VpnProfileSqlDataSource.DbColumn(KEY_SELECTED_APPS_LIST, "TEXT", 12),
+               new VpnProfileSqlDataSource.DbColumn(KEY_NAT_KEEPALIVE, "INTEGER", 13),
+               new VpnProfileSqlDataSource.DbColumn(KEY_FLAGS, "INTEGER", 14),
+               new VpnProfileSqlDataSource.DbColumn(KEY_IKE_PROPOSAL, "TEXT", 15),
+               new VpnProfileSqlDataSource.DbColumn(KEY_ESP_PROPOSAL, "TEXT", 15),
+               new VpnProfileSqlDataSource.DbColumn(KEY_DNS_SERVERS, "TEXT", 17),
+       };
+
+       private DatabaseHelper mDbHelper;
+       private SQLiteDatabase mDatabase;
+       private final Context mContext;
+
+       private static final String DATABASE_NAME = "strongswan.db";
+       private static final String TABLE_VPNPROFILE = "vpnprofile";
+
+       private static final int DATABASE_VERSION = 17;
+
+       private static final String[] ALL_COLUMNS = getColumns(DATABASE_VERSION);
+
+       private static String getDatabaseCreate(int version)
+       {
+               boolean first = true;
+               StringBuilder create = new StringBuilder("CREATE TABLE ");
+               create.append(TABLE_VPNPROFILE);
+               create.append(" (");
+               for (DbColumn column : COLUMNS)
+               {
+                       if (column.Since <= version)
+                       {
+                               if (!first)
+                               {
+                                       create.append(",");
+                               }
+                               first = false;
+                               create.append(column.Name);
+                               create.append(" ");
+                               create.append(column.Type);
+                       }
+               }
+               create.append(");");
+               return create.toString();
+       }
+
+       private static String[] getColumns(int version)
+       {
+               ArrayList<String> columns = new ArrayList<>();
+               for (DbColumn column : COLUMNS)
+               {
+                       if (column.Since <= version)
+                       {
+                               columns.add(column.Name);
+                       }
+               }
+               return columns.toArray(new String[0]);
+       }
+
+       private static class DatabaseHelper extends SQLiteOpenHelper
+       {
+               public DatabaseHelper(Context context)
+               {
+                       super(context, DATABASE_NAME, null, DATABASE_VERSION);
+               }
+
+               @Override
+               public void onCreate(SQLiteDatabase database)
+               {
+                       database.execSQL(getDatabaseCreate(DATABASE_VERSION));
+               }
+
+               @Override
+               public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
+               {
+                       Log.w(TAG, "Upgrading database from version " + oldVersion +
+                                 " to " + newVersion);
+                       if (oldVersion < 2)
+                       {
+                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_USER_CERTIFICATE +
+                                                  " TEXT;");
+                       }
+                       if (oldVersion < 3)
+                       {
+                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_VPN_TYPE +
+                                                  " TEXT DEFAULT '';");
+                       }
+                       if (oldVersion < 4)
+                       {       /* remove NOT NULL constraint from username column */
+                               updateColumns(db, 4);
+                       }
+                       if (oldVersion < 5)
+                       {
+                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_MTU +
+                                                  " INTEGER;");
+                       }
+                       if (oldVersion < 6)
+                       {
+                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_PORT +
+                                                  " INTEGER;");
+                       }
+                       if (oldVersion < 7)
+                       {
+                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_SPLIT_TUNNELING +
+                                                  " INTEGER;");
+                       }
+                       if (oldVersion < 8)
+                       {
+                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_LOCAL_ID +
+                                                  " TEXT;");
+                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_REMOTE_ID +
+                                                  " TEXT;");
+                       }
+                       if (oldVersion < 9)
+                       {
+                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_UUID +
+                                                  " TEXT;");
+                               updateColumns(db, 9);
+                       }
+                       if (oldVersion < 10)
+                       {
+                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_EXCLUDED_SUBNETS +
+                                                  " TEXT;");
+                       }
+                       if (oldVersion < 11)
+                       {
+                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_INCLUDED_SUBNETS +
+                                                  " TEXT;");
+                       }
+                       if (oldVersion < 12)
+                       {
+                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_SELECTED_APPS +
+                                                  " INTEGER;");
+                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_SELECTED_APPS_LIST +
+                                                  " TEXT;");
+                       }
+                       if (oldVersion < 13)
+                       {
+                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_NAT_KEEPALIVE +
+                                                  " INTEGER;");
+                       }
+                       if (oldVersion < 14)
+                       {
+                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_FLAGS +
+                                                  " INTEGER;");
+                       }
+                       if (oldVersion < 15)
+                       {
+                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_IKE_PROPOSAL +
+                                                  " TEXT;");
+                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_ESP_PROPOSAL +
+                                                  " TEXT;");
+                       }
+                       if (oldVersion < 16)
+                       {       /* add a UUID to all entries that haven't one yet */
+                               db.beginTransaction();
+                               try
+                               {
+                                       Cursor cursor = db.query(TABLE_VPNPROFILE, getColumns(16), KEY_UUID + " is NULL", null, null, null, null);
+                                       for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext())
+                                       {
+                                               ContentValues values = new ContentValues();
+                                               values.put(KEY_UUID, UUID.randomUUID().toString());
+                                               db.update(TABLE_VPNPROFILE, values, KEY_ID + " = " + cursor.getLong(cursor.getColumnIndexOrThrow(KEY_ID)), null);
+                                       }
+                                       cursor.close();
+                                       db.setTransactionSuccessful();
+                               }
+                               finally
+                               {
+                                       db.endTransaction();
+                               }
+                       }
+                       if (oldVersion < 17)
+                       {
+                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_DNS_SERVERS +
+                                                  " TEXT;");
+                       }
+               }
+
+               private void updateColumns(SQLiteDatabase db, int version)
+               {
+                       db.beginTransaction();
+                       try
+                       {
+                               db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " RENAME TO tmp_" + TABLE_VPNPROFILE + ";");
+                               db.execSQL(getDatabaseCreate(version));
+                               StringBuilder insert = new StringBuilder("INSERT INTO " + TABLE_VPNPROFILE + " SELECT ");
+                               SQLiteQueryBuilder.appendColumns(insert, getColumns(version));
+                               db.execSQL(insert.append(" FROM tmp_" + TABLE_VPNPROFILE + ";").toString());
+                               db.execSQL("DROP TABLE tmp_" + TABLE_VPNPROFILE + ";");
+                               db.setTransactionSuccessful();
+                       }
+                       finally
+                       {
+                               db.endTransaction();
+                       }
+               }
+       }
+
+       /**
+        * Construct a new VPN profile data source. The context is used to
+        * open/create the database.
+        *
+        * @param context context used to access the database
+        */
+       public VpnProfileSqlDataSource(Context context)
+       {
+               this.mContext = context;
+       }
+
+       @Override
+       public VpnProfileDataSource open() throws SQLException
+       {
+               if (mDbHelper == null)
+               {
+                       mDbHelper = new DatabaseHelper(mContext);
+                       mDatabase = mDbHelper.getWritableDatabase();
+               }
+               return this;
+       }
+
+       @Override
+       public void close()
+       {
+               if (mDbHelper != null)
+               {
+                       mDbHelper.close();
+                       mDbHelper = null;
+               }
+       }
+
+       @Override
+       public VpnProfile insertProfile(VpnProfile profile)
+       {
+               ContentValues values = ContentValuesFromVpnProfile(profile);
+               long insertId = mDatabase.insert(TABLE_VPNPROFILE, null, values);
+               if (insertId == -1)
+               {
+                       return null;
+               }
+               profile.setId(insertId);
+               return profile;
+       }
+
+       @Override
+       public boolean updateVpnProfile(VpnProfile profile)
+       {
+               long id = profile.getId();
+               ContentValues values = ContentValuesFromVpnProfile(profile);
+               return mDatabase.update(TABLE_VPNPROFILE, values, KEY_ID + " = " + id, null) > 0;
+       }
+
+       @Override
+       public boolean deleteVpnProfile(VpnProfile profile)
+       {
+               long id = profile.getId();
+               return mDatabase.delete(TABLE_VPNPROFILE, KEY_ID + " = " + id, null) > 0;
+       }
+
+       @Override
+       public VpnProfile getVpnProfile(long id)
+       {
+               VpnProfile profile = null;
+               Cursor cursor = mDatabase.query(TABLE_VPNPROFILE, ALL_COLUMNS,
+                                                                               KEY_ID + "=" + id, null, null, null, null);
+               if (cursor.moveToFirst())
+               {
+                       profile = VpnProfileFromCursor(cursor);
+               }
+               cursor.close();
+               return profile;
+       }
+
+       @Override
+       public VpnProfile getVpnProfile(UUID uuid)
+       {
+               VpnProfile profile = null;
+               Cursor cursor = mDatabase.query(TABLE_VPNPROFILE, ALL_COLUMNS,
+                                                                               KEY_UUID + "='" + uuid.toString() + "'", null, null, null, null);
+               if (cursor.moveToFirst())
+               {
+                       profile = VpnProfileFromCursor(cursor);
+               }
+               cursor.close();
+               return profile;
+       }
+
+       @Override
+       public List<VpnProfile> getAllVpnProfiles()
+       {
+               List<VpnProfile> vpnProfiles = new ArrayList<VpnProfile>();
+
+               Cursor cursor = mDatabase.query(TABLE_VPNPROFILE, ALL_COLUMNS, null, null, null, null, null);
+               cursor.moveToFirst();
+               while (!cursor.isAfterLast())
+               {
+                       VpnProfile vpnProfile = VpnProfileFromCursor(cursor);
+                       vpnProfiles.add(vpnProfile);
+                       cursor.moveToNext();
+               }
+               cursor.close();
+               return vpnProfiles;
+       }
+
+       private VpnProfile VpnProfileFromCursor(Cursor cursor)
+       {
+               VpnProfile profile = new VpnProfile();
+               profile.setId(cursor.getLong(cursor.getColumnIndexOrThrow(KEY_ID)));
+               profile.setUUID(UUID.fromString(cursor.getString(cursor.getColumnIndexOrThrow(KEY_UUID))));
+               profile.setName(cursor.getString(cursor.getColumnIndexOrThrow(KEY_NAME)));
+               profile.setGateway(cursor.getString(cursor.getColumnIndexOrThrow(KEY_GATEWAY)));
+               profile.setVpnType(VpnType.fromIdentifier(cursor.getString(cursor.getColumnIndexOrThrow(KEY_VPN_TYPE))));
+               profile.setUsername(cursor.getString(cursor.getColumnIndexOrThrow(KEY_USERNAME)));
+               profile.setPassword(cursor.getString(cursor.getColumnIndexOrThrow(KEY_PASSWORD)));
+               profile.setCertificateAlias(cursor.getString(cursor.getColumnIndexOrThrow(KEY_CERTIFICATE)));
+               profile.setUserCertificateAlias(cursor.getString(cursor.getColumnIndexOrThrow(KEY_USER_CERTIFICATE)));
+               profile.setMTU(getInt(cursor, cursor.getColumnIndexOrThrow(KEY_MTU)));
+               profile.setPort(getInt(cursor, cursor.getColumnIndexOrThrow(KEY_PORT)));
+               profile.setSplitTunneling(getInt(cursor, cursor.getColumnIndexOrThrow(KEY_SPLIT_TUNNELING)));
+               profile.setLocalId(cursor.getString(cursor.getColumnIndexOrThrow(KEY_LOCAL_ID)));
+               profile.setRemoteId(cursor.getString(cursor.getColumnIndexOrThrow(KEY_REMOTE_ID)));
+               profile.setExcludedSubnets(cursor.getString(cursor.getColumnIndexOrThrow(KEY_EXCLUDED_SUBNETS)));
+               profile.setIncludedSubnets(cursor.getString(cursor.getColumnIndexOrThrow(KEY_INCLUDED_SUBNETS)));
+               profile.setSelectedAppsHandling(getInt(cursor, cursor.getColumnIndexOrThrow(KEY_SELECTED_APPS)));
+               profile.setSelectedApps(cursor.getString(cursor.getColumnIndexOrThrow(KEY_SELECTED_APPS_LIST)));
+               profile.setNATKeepAlive(getInt(cursor, cursor.getColumnIndexOrThrow(KEY_NAT_KEEPALIVE)));
+               profile.setFlags(getInt(cursor, cursor.getColumnIndexOrThrow(KEY_FLAGS)));
+               profile.setIkeProposal(cursor.getString(cursor.getColumnIndexOrThrow(KEY_IKE_PROPOSAL)));
+               profile.setEspProposal(cursor.getString(cursor.getColumnIndexOrThrow(KEY_ESP_PROPOSAL)));
+               profile.setDnsServers(cursor.getString(cursor.getColumnIndexOrThrow(KEY_DNS_SERVERS)));
+               return profile;
+       }
+
+       private ContentValues ContentValuesFromVpnProfile(VpnProfile profile)
+       {
+               ContentValues values = new ContentValues();
+               values.put(KEY_UUID, profile.getUUID().toString());
+               values.put(KEY_NAME, profile.getName());
+               values.put(KEY_GATEWAY, profile.getGateway());
+               values.put(KEY_VPN_TYPE, profile.getVpnType().getIdentifier());
+               values.put(KEY_USERNAME, profile.getUsername());
+               values.put(KEY_PASSWORD, profile.getPassword());
+               values.put(KEY_CERTIFICATE, profile.getCertificateAlias());
+               values.put(KEY_USER_CERTIFICATE, profile.getUserCertificateAlias());
+               values.put(KEY_MTU, profile.getMTU());
+               values.put(KEY_PORT, profile.getPort());
+               values.put(KEY_SPLIT_TUNNELING, profile.getSplitTunneling());
+               values.put(KEY_LOCAL_ID, profile.getLocalId());
+               values.put(KEY_REMOTE_ID, profile.getRemoteId());
+               values.put(KEY_EXCLUDED_SUBNETS, profile.getExcludedSubnets());
+               values.put(KEY_INCLUDED_SUBNETS, profile.getIncludedSubnets());
+               values.put(KEY_SELECTED_APPS, profile.getSelectedAppsHandling().getValue());
+               values.put(KEY_SELECTED_APPS_LIST, profile.getSelectedApps());
+               values.put(KEY_NAT_KEEPALIVE, profile.getNATKeepAlive());
+               values.put(KEY_FLAGS, profile.getFlags());
+               values.put(KEY_IKE_PROPOSAL, profile.getIkeProposal());
+               values.put(KEY_ESP_PROPOSAL, profile.getEspProposal());
+               values.put(KEY_DNS_SERVERS, profile.getDnsServers());
+               return values;
+       }
+
+       private Integer getInt(Cursor cursor, int columnIndex)
+       {
+               return cursor.isNull(columnIndex) ? null : cursor.getInt(columnIndex);
+       }
+
+       private static class DbColumn
+       {
+               public final String Name;
+               public final String Type;
+               public final Integer Since;
+
+               public DbColumn(String name, String type, Integer since)
+               {
+                       Name = name;
+                       Type = type;
+                       Since = since;
+               }
+       }
+}
index 5f5b2a1879e75731506abc97794a6f6313aa733f..115ff7cec428e9392b160fa87b6bd9a94c78c945 100644 (file)
@@ -45,6 +45,7 @@ import org.strongswan.android.R;
 import org.strongswan.android.data.VpnProfile;
 import org.strongswan.android.data.VpnProfile.SelectedAppsHandling;
 import org.strongswan.android.data.VpnProfileDataSource;
+import org.strongswan.android.data.VpnProfileSource;
 import org.strongswan.android.data.VpnType.VpnTypeFeature;
 import org.strongswan.android.logic.VpnStateService.ErrorState;
 import org.strongswan.android.logic.VpnStateService.State;
@@ -196,7 +197,7 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe
                /* handler used to do changes in the main UI thread */
                mHandler = new Handler(getMainLooper());
 
-               mDataSource = new VpnProfileDataSource(this);
+               mDataSource = new VpnProfileSource(this);
                mDataSource.open();
                /* use a separate thread as main thread for charon */
                mConnectionHandler = new Thread(this);
index 98e39925655cc1916d07df7aa9f50c4a13fece17..7f047ce6b4bc1e2aa0a4d4e681ba117aaaccf2dc 100644 (file)
@@ -16,6 +16,9 @@
 
 package org.strongswan.android.ui;
 
+import static org.strongswan.android.utils.Constants.PREF_DEFAULT_VPN_PROFILE;
+import static org.strongswan.android.utils.Constants.PREF_DEFAULT_VPN_PROFILE_MRU;
+
 import android.content.SharedPreferences;
 import android.os.Build;
 import android.os.Bundle;
@@ -23,6 +26,7 @@ import android.os.Bundle;
 import org.strongswan.android.R;
 import org.strongswan.android.data.VpnProfile;
 import org.strongswan.android.data.VpnProfileDataSource;
+import org.strongswan.android.data.VpnProfileSource;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -34,9 +38,6 @@ import androidx.preference.Preference;
 import androidx.preference.PreferenceFragmentCompat;
 import androidx.preference.PreferenceManager;
 
-import static org.strongswan.android.utils.Constants.PREF_DEFAULT_VPN_PROFILE;
-import static org.strongswan.android.utils.Constants.PREF_DEFAULT_VPN_PROFILE_MRU;
-
 public class SettingsFragment extends PreferenceFragmentCompat implements Preference.OnPreferenceChangeListener
 {
        private ListPreference mDefaultVPNProfile;
@@ -46,7 +47,7 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Prefer
        {
                setPreferencesFromResource(R.xml.settings, s);
 
-               mDefaultVPNProfile = (ListPreference)findPreference(PREF_DEFAULT_VPN_PROFILE);
+               mDefaultVPNProfile = findPreference(PREF_DEFAULT_VPN_PROFILE);
                mDefaultVPNProfile.setOnPreferenceChangeListener(this);
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N)
                {
@@ -59,11 +60,12 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Prefer
        {
                super.onResume();
 
-               VpnProfileDataSource profiles = new VpnProfileDataSource(getActivity());
+               VpnProfileDataSource profiles = new VpnProfileSource(getActivity());
                profiles.open();
 
                List<VpnProfile> all = profiles.getAllVpnProfiles();
-               Collections.sort(all, new Comparator<VpnProfile>() {
+               Collections.sort(all, new Comparator<VpnProfile>()
+               {
                        @Override
                        public int compare(VpnProfile lhs, VpnProfile rhs)
                        {
@@ -111,7 +113,7 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Prefer
 
        private void setCurrentProfileName(String uuid)
        {
-               VpnProfileDataSource profiles = new VpnProfileDataSource(getActivity());
+               VpnProfileDataSource profiles = new VpnProfileSource(getActivity());
                profiles.open();
 
                if (!uuid.equals(PREF_DEFAULT_VPN_PROFILE_MRU))
index 1913bbb5f3070c01a9806dce433297a6f82c31c5..fb83c4e10c3f8304471af08980374a522f2e9f8d 100644 (file)
@@ -42,12 +42,12 @@ import android.widget.Toast;
 import org.strongswan.android.R;
 import org.strongswan.android.data.VpnProfile;
 import org.strongswan.android.data.VpnProfileDataSource;
+import org.strongswan.android.data.VpnProfileSource;
 import org.strongswan.android.data.VpnType.VpnTypeFeature;
 import org.strongswan.android.logic.VpnStateService;
 import org.strongswan.android.logic.VpnStateService.State;
 import org.strongswan.android.utils.Constants;
 
-import androidx.activity.result.ActivityResultCallback;
 import androidx.activity.result.ActivityResultLauncher;
 import androidx.activity.result.contract.ActivityResultContracts;
 import androidx.annotation.NonNull;
@@ -257,6 +257,7 @@ public class VpnProfileControlActivity extends AppCompatActivity
        /**
         * Check if we have permission to display notifications to the user, if necessary,
         * ask the user to allow this.
+        *
         * @return true if profile can be initiated immediately
         */
        private boolean checkNotificationPermission()
@@ -274,6 +275,7 @@ public class VpnProfileControlActivity extends AppCompatActivity
        /**
         * Check if we are on the system's power whitelist, if necessary, or ask the user
         * to add us.
+        *
         * @return true if profile can be initiated immediately
         */
        private boolean checkPowerWhitelist()
@@ -373,7 +375,7 @@ public class VpnProfileControlActivity extends AppCompatActivity
        {
                VpnProfile profile = null;
 
-               VpnProfileDataSource dataSource = new VpnProfileDataSource(this);
+               VpnProfileDataSource dataSource = new VpnProfileSource(this);
                dataSource.open();
                String profileUUID = intent.getStringExtra(EXTRA_VPN_PROFILE_ID);
                if (profileUUID != null)
@@ -415,7 +417,7 @@ public class VpnProfileControlActivity extends AppCompatActivity
                String profileUUID = intent.getStringExtra(EXTRA_VPN_PROFILE_ID);
                if (profileUUID != null)
                {
-                       VpnProfileDataSource dataSource = new VpnProfileDataSource(this);
+                       VpnProfileDataSource dataSource = new VpnProfileSource(this);
                        dataSource.open();
                        profile = dataSource.getVpnProfile(profileUUID);
                        dataSource.close();
@@ -583,9 +585,9 @@ public class VpnProfileControlActivity extends AppCompatActivity
                        final Bundle profileInfo = getArguments();
                        LayoutInflater inflater = getActivity().getLayoutInflater();
                        View view = inflater.inflate(R.layout.login_dialog, null);
-                       EditText username = (EditText)view.findViewById(R.id.username);
+                       EditText username = view.findViewById(R.id.username);
                        username.setText(profileInfo.getString(VpnProfileDataSource.KEY_USERNAME));
-                       final EditText password = (EditText)view.findViewById(R.id.password);
+                       final EditText password = view.findViewById(R.id.password);
 
                        AlertDialog.Builder adb = new AlertDialog.Builder(getActivity());
                        adb.setView(view);
index 85d178e52f28bdec4d68fb03af08ef25abb1dcd1..8fd12338f7f41c0364c678f31a050dda103a89b8 100644 (file)
@@ -56,6 +56,7 @@ import org.strongswan.android.R;
 import org.strongswan.android.data.VpnProfile;
 import org.strongswan.android.data.VpnProfile.SelectedAppsHandling;
 import org.strongswan.android.data.VpnProfileDataSource;
+import org.strongswan.android.data.VpnProfileSource;
 import org.strongswan.android.data.VpnType;
 import org.strongswan.android.data.VpnType.VpnTypeFeature;
 import org.strongswan.android.logic.StrongSwanApplication;
@@ -188,7 +189,7 @@ public class VpnProfileDetailActivity extends AppCompatActivity
                /* the title is set when we load the profile, if any */
                getSupportActionBar().setDisplayHomeAsUpEnabled(true);
 
-               mDataSource = new VpnProfileDataSource(this);
+               mDataSource = new VpnProfileSource(this);
                mDataSource.open();
 
                setContentView(R.layout.profile_detail_view);
index c58365d9cdfce953f6a72284195a5238735e14a9..3f7c51c19c4b911cd357bc5902a53de437aeabfa 100644 (file)
@@ -45,6 +45,7 @@ import org.strongswan.android.R;
 import org.strongswan.android.data.VpnProfile;
 import org.strongswan.android.data.VpnProfile.SelectedAppsHandling;
 import org.strongswan.android.data.VpnProfileDataSource;
+import org.strongswan.android.data.VpnProfileSource;
 import org.strongswan.android.data.VpnType;
 import org.strongswan.android.data.VpnType.VpnTypeFeature;
 import org.strongswan.android.logic.TrustedCertificateManager;
@@ -184,7 +185,7 @@ public class VpnProfileImportActivity extends AppCompatActivity
                getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_close_white_24dp);
                getSupportActionBar().setDisplayHomeAsUpEnabled(true);
 
-               mDataSource = new VpnProfileDataSource(this);
+               mDataSource = new VpnProfileSource(this);
                mDataSource.open();
 
                setContentView(R.layout.profile_import_view);
index 291a4fceac08673da0a23056d988c098a4c94a52..a4ed1930838c7b7ae6b734f33292562422421d49 100644 (file)
@@ -41,6 +41,7 @@ import android.widget.Toast;
 import org.strongswan.android.R;
 import org.strongswan.android.data.VpnProfile;
 import org.strongswan.android.data.VpnProfileDataSource;
+import org.strongswan.android.data.VpnProfileSource;
 import org.strongswan.android.ui.adapter.VpnProfileAdapter;
 import org.strongswan.android.utils.Constants;
 
@@ -65,12 +66,14 @@ public class VpnProfileListFragment extends Fragment
        private HashSet<Integer> mSelected;
        private boolean mReadOnly;
 
-       private BroadcastReceiver mProfilesChanged = new BroadcastReceiver()
+       private final BroadcastReceiver mProfilesChanged = new BroadcastReceiver()
        {
                @Override
                public void onReceive(Context context, Intent intent)
                {
-                       long id, ids[];
+                       long id;
+                       long[] ids;
+
                        if ((id = intent.getLongExtra(Constants.VPN_PROFILES_SINGLE, 0)) > 0)
                        {
                                VpnProfile profile = mDataSource.getVpnProfile(id);
@@ -104,7 +107,8 @@ public class VpnProfileListFragment extends Fragment
        /**
         * The activity containing this fragment should implement this interface
         */
-       public interface OnVpnProfileSelectedListener {
+       public interface OnVpnProfileSelectedListener
+       {
                void onVpnProfileSelected(VpnProfile profile);
        }
 
@@ -159,7 +163,7 @@ public class VpnProfileListFragment extends Fragment
                        mSelected = selected != null ? new HashSet<>(selected) : new HashSet<>();
                }
 
-               mDataSource = new VpnProfileDataSource(this.getActivity());
+               mDataSource = new VpnProfileSource(this.getActivity());
                mDataSource.open();
 
                /* cached list of profiles used as backend for the ListView */
@@ -206,19 +210,18 @@ public class VpnProfileListFragment extends Fragment
        @Override
        public boolean onOptionsItemSelected(MenuItem item)
        {
-               switch (item.getItemId())
+               if (item.getItemId() == R.id.add_profile)
                {
-                       case R.id.add_profile:
-                               Intent connectionIntent = new Intent(getActivity(),
-                                                                                                        VpnProfileDetailActivity.class);
-                               startActivity(connectionIntent);
-                               return true;
-                       default:
-                               return super.onOptionsItemSelected(item);
+                       Intent connectionIntent = new Intent(getActivity(),
+                                                                                                VpnProfileDetailActivity.class);
+                       startActivity(connectionIntent);
+                       return true;
                }
+               return super.onOptionsItemSelected(item);
        }
 
-       private final OnItemClickListener mVpnProfileClicked = new OnItemClickListener() {
+       private final OnItemClickListener mVpnProfileClicked = new OnItemClickListener()
+       {
                @Override
                public void onItemClick(AdapterView<?> a, View v, int position, long id)
                {
@@ -229,7 +232,8 @@ public class VpnProfileListFragment extends Fragment
                }
        };
 
-       private final MultiChoiceModeListener mVpnProfileSelected = new MultiChoiceModeListener() {
+       private final MultiChoiceModeListener mVpnProfileSelected = new MultiChoiceModeListener()
+       {
                private MenuItem mEditProfile;
                private MenuItem mCopyProfile;
 
@@ -297,7 +301,7 @@ public class VpnProfileListFragment extends Fragment
                                        {
                                                profiles.add((VpnProfile)mListView.getItemAtPosition(position));
                                        }
-                                       long ids[] = new long[profiles.size()];
+                                       long[] ids = new long[profiles.size()];
                                        for (int i = 0; i < profiles.size(); i++)
                                        {
                                                VpnProfile profile = profiles.get(i);
index 2e128962d219b126d0d65eab26e28a225d096627..6178c59ba671f0de400aee645a7ae1bfe92b2dba 100644 (file)
@@ -32,6 +32,7 @@ import android.service.quicksettings.TileService;
 import org.strongswan.android.R;
 import org.strongswan.android.data.VpnProfile;
 import org.strongswan.android.data.VpnProfileDataSource;
+import org.strongswan.android.data.VpnProfileSource;
 import org.strongswan.android.data.VpnType;
 import org.strongswan.android.logic.VpnStateService;
 import org.strongswan.android.utils.Constants;
@@ -73,7 +74,7 @@ public class VpnTileService extends TileService implements VpnStateService.VpnSt
                context.bindService(new Intent(context, VpnStateService.class),
                                                        mServiceConnection, Service.BIND_AUTO_CREATE);
 
-               mDataSource = new VpnProfileDataSource(this);
+               mDataSource = new VpnProfileSource(this);
                mDataSource.open();
        }