diff options
| author | Arne Schwabe <arne@rfc2549.org> | 2015-03-16 12:55:41 +0100 | 
|---|---|---|
| committer | Arne Schwabe <arne@rfc2549.org> | 2015-03-16 12:55:41 +0100 | 
| commit | d98f6c6ba51ae8810bd2d035fa89f6ca24eba8fd (patch) | |
| tree | e2a263c9d409cead340a163230eb01f3bc62124c | |
| parent | d8a10a7d9f9de6dd86ed382c3eb7a22bbd8cd21e (diff) | |
Update/cleanup of external API, allow adding of non user editable profiles
--HG--
rename : remoteExample/src/main/assets/hd.conf => remoteExample/src/main/assets/test.conf
20 files changed, 309 insertions, 161 deletions
diff --git a/.idea/copyright/ics_openvpn_gpl.xml b/.idea/copyright/ics_openvpn_gpl.xml index fb4d0809..2980b0c4 100644 --- a/.idea/copyright/ics_openvpn_gpl.xml +++ b/.idea/copyright/ics_openvpn_gpl.xml @@ -1,6 +1,6 @@  <component name="CopyrightManager">    <copyright> -    <option name="notice" value="Copyright (c) 2012-2014 Arne Schwabe
Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt" /> +    <option name="notice" value="Copyright (c) 2012-2015 Arne Schwabe
Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt" />      <option name="keyword" value="Copyright" />      <option name="allowReplaceKeyword" value="Copyright (c) 2012-2014 Arne Schwabe" />      <option name="myName" value="ics-openvpn-gpl" /> diff --git a/main/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl b/main/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl index d0791a4a..273a0046 100644 --- a/main/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl +++ b/main/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl @@ -12,10 +12,14 @@ interface IOpenVPNAPIService {  	void startProfile (String profileUUID);
 -	/** Use a profile with all certificates etc. embedded */
 +	/** Use a profile with all certificates etc. embedded,
 +	 * old version which does not return the UUID of the addded profile, see
 +	 * below for a version that return the UUID on add */
  	boolean addVPNProfile (String name, String config);
 -	/** start a profile using an config */
 +	/** start a profile using a config as inline string. Make sure that all needed data is inlined,
 +	 * e.g., using <ca>...</ca> or <auth-user-data>...</auth-user-data>
 +	 * See the OpenVPN manual page for more on inlining files */
  	void startVPN (String inlineconfig);
  	/** This permission framework is used  to avoid confused deputy style attack to the VPN
 @@ -55,5 +59,8 @@ interface IOpenVPNAPIService {  	  * Before calling this function you should make sure OpenVPN for Android may actually
  	  * this function by checking if prepareVPNService returns null; */
  	boolean protectSocket(in ParcelFileDescriptor fd);
 -		
 +
 +
 +    /** Use a profile with all certificates etc. embedded */
 +    APIVpnProfile addNewVPNProfile (String name, boolean userEditable, String config);
  }
\ No newline at end of file diff --git a/main/src/main/java/de/blinkt/openvpn/VpnProfile.java b/main/src/main/java/de/blinkt/openvpn/VpnProfile.java index 73e095ad..058e8097 100644 --- a/main/src/main/java/de/blinkt/openvpn/VpnProfile.java +++ b/main/src/main/java/de/blinkt/openvpn/VpnProfile.java @@ -152,7 +152,7 @@ public class VpnProfile implements Serializable, Cloneable {      public boolean mRemoteRandom=false;      public HashSet<String> mAllowedAppsVpn = new HashSet<String>();      public boolean mAllowedAppsVpnAreDisallowed = true; - +    public String mProfileCreator;      /* Options no long used in new profiles */      public String mServerName = "openvpn.blinkt.de"; diff --git a/main/src/main/java/de/blinkt/openvpn/activities/VPNPreferences.java b/main/src/main/java/de/blinkt/openvpn/activities/VPNPreferences.java index f56a2d48..d81968a2 100644 --- a/main/src/main/java/de/blinkt/openvpn/activities/VPNPreferences.java +++ b/main/src/main/java/de/blinkt/openvpn/activities/VPNPreferences.java @@ -28,6 +28,7 @@ import de.blinkt.openvpn.fragments.Settings_Connections;  import de.blinkt.openvpn.fragments.Settings_IP;  import de.blinkt.openvpn.fragments.Settings_Obscure;  import de.blinkt.openvpn.fragments.Settings_Routing; +import de.blinkt.openvpn.fragments.Settings_UserEditable;  import de.blinkt.openvpn.fragments.ShowConfigFragment;  import de.blinkt.openvpn.fragments.VPNProfileList;  import de.blinkt.openvpn.views.ScreenSlidePagerAdapter; @@ -134,21 +135,23 @@ public class VPNPreferences extends Activity {          fragmentArguments.putString(getPackageName() + ".profileUUID",mProfileUUID);          mPagerAdapter.setFragmentArgs(fragmentArguments); -        mPagerAdapter.addTab(R.string.basic, Settings_Basic.class); -        mPagerAdapter.addTab(R.string.server_list, Settings_Connections.class); -        mPagerAdapter.addTab(R.string.ipdns, Settings_IP.class); -        mPagerAdapter.addTab(R.string.routing, Settings_Routing.class); -        mPagerAdapter.addTab(R.string.settings_auth, Settings_Authentication.class); +        if (mProfile.mUserEditable) { +            mPagerAdapter.addTab(R.string.basic, Settings_Basic.class); +            mPagerAdapter.addTab(R.string.server_list, Settings_Connections.class); +            mPagerAdapter.addTab(R.string.ipdns, Settings_IP.class); +            mPagerAdapter.addTab(R.string.routing, Settings_Routing.class); +            mPagerAdapter.addTab(R.string.settings_auth, Settings_Authentication.class); -        mPagerAdapter.addTab(R.string.advanced, Settings_Obscure.class); +            mPagerAdapter.addTab(R.string.advanced, Settings_Obscure.class); +        } else { +            mPagerAdapter.addTab(R.string.basic, Settings_UserEditable.class); +        }          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)              mPagerAdapter.addTab(R.string.vpn_allowed_apps, Settings_Allowed_Apps.class);          mPagerAdapter.addTab(R.string.generated_config, ShowConfigFragment.class); - -          mPager.setAdapter(mPagerAdapter);          TabBarView tabs = (TabBarView) findViewById(R.id.sliding_tabs); diff --git a/main/src/main/java/de/blinkt/openvpn/api/APIVpnProfile.java b/main/src/main/java/de/blinkt/openvpn/api/APIVpnProfile.java index 7637f57f..fe96c668 100644 --- a/main/src/main/java/de/blinkt/openvpn/api/APIVpnProfile.java +++ b/main/src/main/java/de/blinkt/openvpn/api/APIVpnProfile.java @@ -10,47 +10,51 @@ import android.os.Parcelable;  public class APIVpnProfile implements Parcelable {
 -	public final String mUUID;
 -	public final String mName;
 -	public final boolean mUserEditable;
 -
 -	public APIVpnProfile(Parcel in) {
 -		mUUID = in.readString();
 -		mName = in.readString();
 +    public final String mUUID;
 +    public final String mName;
 +    public final boolean mUserEditable;
 +    public final String mProfileCreator;
 +
 +    public APIVpnProfile(Parcel in) {
 +        mUUID = in.readString();
 +        mName = in.readString();
          mUserEditable = in.readInt() != 0;
 -	}
 -
 -	public APIVpnProfile(String uuidString, String name, boolean userEditable) {
 -		mUUID=uuidString;
 -		mName = name;
 -		mUserEditable=userEditable;
 -	}
 -
 -	@Override
 -	public int describeContents() {
 -		return 0;
 -	}
 -
 -	@Override
 -	public void writeToParcel(Parcel dest, int flags) {
 -		dest.writeString(mUUID);
 -		dest.writeString(mName);
 -		if(mUserEditable)
 -			dest.writeInt(0);
 -		else
 -			dest.writeInt(1);
 -	}
 -
 -	public static final Parcelable.Creator<APIVpnProfile> CREATOR
 -	= new Parcelable.Creator<APIVpnProfile>() {
 -		public APIVpnProfile createFromParcel(Parcel in) {
 -			return new APIVpnProfile(in);
 -		}
 -
 -		public APIVpnProfile[] newArray(int size) {
 -			return new APIVpnProfile[size];
 -		}
 -	};
 +        mProfileCreator = in.readString();
 +    }
 +
 +    public APIVpnProfile(String uuidString, String name, boolean userEditable, String profileCreator) {
 +        mUUID = uuidString;
 +        mName = name;
 +        mUserEditable = userEditable;
 +        mProfileCreator = profileCreator;
 +    }
 +
 +    @Override
 +    public int describeContents() {
 +        return 0;
 +    }
 +
 +    @Override
 +    public void writeToParcel(Parcel dest, int flags) {
 +        dest.writeString(mUUID);
 +        dest.writeString(mName);
 +        if (mUserEditable)
 +            dest.writeInt(0);
 +        else
 +            dest.writeInt(1);
 +        dest.writeString(mProfileCreator);
 +    }
 +
 +    public static final Parcelable.Creator<APIVpnProfile> CREATOR
 +            = new Parcelable.Creator<APIVpnProfile>() {
 +        public APIVpnProfile createFromParcel(Parcel in) {
 +            return new APIVpnProfile(in);
 +        }
 +
 +        public APIVpnProfile[] newArray(int size) {
 +            return new APIVpnProfile[size];
 +        }
 +    };
  }
 diff --git a/main/src/main/java/de/blinkt/openvpn/api/ExternalOpenVPNService.java b/main/src/main/java/de/blinkt/openvpn/api/ExternalOpenVPNService.java index 27143781..eae31b17 100644 --- a/main/src/main/java/de/blinkt/openvpn/api/ExternalOpenVPNService.java +++ b/main/src/main/java/de/blinkt/openvpn/api/ExternalOpenVPNService.java @@ -48,7 +48,7 @@ public class ExternalOpenVPNService extends Service implements StateListener {      private static final int SEND_TOALL = 0;
      final RemoteCallbackList<IOpenVPNStatusCallback> mCallbacks =
 -            new RemoteCallbackList<IOpenVPNStatusCallback>();
 +            new RemoteCallbackList<>();
      private OpenVPNService mService;
      private ExternalAppDatabase mExtAppDb;
 @@ -87,19 +87,19 @@ public class ExternalOpenVPNService extends Service implements StateListener {      private final IOpenVPNAPIService.Stub mBinder = new IOpenVPNAPIService.Stub() {
 -        private void checkOpenVPNPermission() throws SecurityRemoteException {
 +        private String checkOpenVPNPermission() throws SecurityRemoteException {
              PackageManager pm = getPackageManager();
 -            for (String apppackage : mExtAppDb.getExtAppList()) {
 +            for (String appPackage : mExtAppDb.getExtAppList()) {
                  ApplicationInfo app;
                  try {
 -                    app = pm.getApplicationInfo(apppackage, 0);
 +                    app = pm.getApplicationInfo(appPackage, 0);
                      if (Binder.getCallingUid() == app.uid) {
 -                        return;
 +                        return appPackage;
                      }
                  } catch (NameNotFoundException e) {
                      // App not found. Remove it from the list
 -                    mExtAppDb.removeApp(apppackage);
 +                    mExtAppDb.removeApp(appPackage);
                  }
              }
 @@ -112,11 +112,11 @@ public class ExternalOpenVPNService extends Service implements StateListener {              ProfileManager pm = ProfileManager.getInstance(getBaseContext());
 -            List<APIVpnProfile> profiles = new LinkedList<APIVpnProfile>();
 +            List<APIVpnProfile> profiles = new LinkedList<>();
              for (VpnProfile vp : pm.getProfiles()) {
                  if (!vp.profileDeleted)
 -                    profiles.add(new APIVpnProfile(vp.getUUIDString(), vp.mName, vp.mUserEditable));
 +                    profiles.add(new APIVpnProfile(vp.getUUIDString(), vp.mName, vp.mUserEditable, vp.mProfileCreator));
              }
              return profiles;
 @@ -155,12 +155,12 @@ public class ExternalOpenVPNService extends Service implements StateListener {              startProfile(vp);
          }
 -        public void startVPN(String inlineconfig) throws RemoteException {
 +        public void startVPN(String inlineConfig) throws RemoteException {
              checkOpenVPNPermission();
              ConfigParser cp = new ConfigParser();
              try {
 -                cp.parseConfig(new StringReader(inlineconfig));
 +                cp.parseConfig(new StringReader(inlineConfig));
                  VpnProfile vp = cp.convertProfile();
                  if (vp.checkProfile(getApplicationContext()) != R.string.no_error_found)
                      throw new RemoteException(getString(vp.checkProfile(getApplicationContext())));
 @@ -173,35 +173,41 @@ public class ExternalOpenVPNService extends Service implements StateListener {                  ProfileManager.setTemporaryProfile(vp);
                  startProfile(vp);
 -            } catch (IOException e) {
 -                throw new RemoteException(e.getMessage());
 -            } catch (ConfigParseError e) {
 +            } catch (IOException | ConfigParseError e) {
                  throw new RemoteException(e.getMessage());
              }
          }
 -
          @Override
          public boolean addVPNProfile(String name, String config) throws RemoteException {
 -            checkOpenVPNPermission();
 +            return addNewVPNProfile(name, true, config) != null;
 +        }
 +
 +
 +        @Override
 +        public APIVpnProfile addNewVPNProfile(String name, boolean userEditable, String config) throws RemoteException {
 +            String callingPackage = checkOpenVPNPermission();
              ConfigParser cp = new ConfigParser();
              try {
                  cp.parseConfig(new StringReader(config));
                  VpnProfile vp = cp.convertProfile();
                  vp.mName = name;
 +                vp.mProfileCreator = callingPackage;
 +                vp.mUserEditable = userEditable;
                  ProfileManager pm = ProfileManager.getInstance(getBaseContext());
                  pm.addProfile(vp);
 +                pm.saveProfile(ExternalOpenVPNService.this, vp);
 +                pm.saveProfileList(ExternalOpenVPNService.this);
 +                return new APIVpnProfile(vp.getUUIDString(), vp.mName, vp.mUserEditable, vp.mProfileCreator);
              } catch (IOException e) {
                  VpnStatus.logException(e);
 -                return false;
 +                return null;
              } catch (ConfigParseError e) {
                  VpnStatus.logException(e);
 -                return false;
 +                return null;
              }
 -
 -            return true;
          }
          @Override
 @@ -226,8 +232,8 @@ public class ExternalOpenVPNService extends Service implements StateListener {          @Override
 -        public Intent prepare(String packagename) {
 -            if (new ExternalAppDatabase(ExternalOpenVPNService.this).isAllowed(packagename))
 +        public Intent prepare(String packageName) {
 +            if (new ExternalAppDatabase(ExternalOpenVPNService.this).isAllowed(packageName))
                  return null;
              Intent intent = new Intent();
 @@ -339,7 +345,7 @@ public class ExternalOpenVPNService extends Service implements StateListener {          WeakReference<ExternalOpenVPNService> service = null;
          private void setService(ExternalOpenVPNService eos) {
 -            service = new WeakReference<ExternalOpenVPNService>(eos);
 +            service = new WeakReference<>(eos);
          }
          @Override
 diff --git a/main/src/main/java/de/blinkt/openvpn/core/ProfileManager.java b/main/src/main/java/de/blinkt/openvpn/core/ProfileManager.java index 1ebc0a57..e4687c3c 100644 --- a/main/src/main/java/de/blinkt/openvpn/core/ProfileManager.java +++ b/main/src/main/java/de/blinkt/openvpn/core/ProfileManager.java @@ -140,9 +140,7 @@ public class ProfileManager {  	} -	public void saveProfile(Context context,VpnProfile profile) { -		// First let basic settings save its state -		 +	public void saveProfile(Context context, VpnProfile profile) {  		ObjectOutputStream vpnfile;  		try {  			vpnfile = new ObjectOutputStream(context.openFileOutput((profile.getUUID().toString() + ".vp"),Activity.MODE_PRIVATE)); @@ -150,10 +148,6 @@ public class ProfileManager {  			vpnfile.writeObject(profile);  			vpnfile.flush();  			vpnfile.close(); -		} catch (FileNotFoundException e) { - -            VpnStatus.logException("saving VPN profile", e); -			throw new RuntimeException(e);  		} catch (IOException e) {              VpnStatus.logException("saving VPN profile", e);  			throw new RuntimeException(e); diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/FaqFragment.java b/main/src/main/java/de/blinkt/openvpn/fragments/FaqFragment.java index 4bc93cef..91a683b8 100644 --- a/main/src/main/java/de/blinkt/openvpn/fragments/FaqFragment.java +++ b/main/src/main/java/de/blinkt/openvpn/fragments/FaqFragment.java @@ -8,16 +8,21 @@ package de.blinkt.openvpn.fragments;  import android.app.Fragment;  import android.content.Context;  import android.os.Build; +import android.os.Bundle; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.StaggeredGridLayoutManager; +import android.util.DisplayMetrics; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import java.util.Vector;  import de.blinkt.openvpn.R;  public class FaqFragment extends Fragment {      static class FAQEntry { -        public FAQEntry(int startVersion, int endVersion, int description) { -            this(startVersion, endVersion, -1, description); -        } -          public FAQEntry(int startVersion, int endVersion, int title, int description) {              this.startVersion = startVersion;              this.endVersion = endVersion; diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Basic.java b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Basic.java index 1fda0a9c..5f25b38b 100644 --- a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Basic.java +++ b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Basic.java @@ -9,7 +9,6 @@ import android.annotation.TargetApi;  import android.app.Activity;  import android.app.AlertDialog;  import android.app.AlertDialog.Builder; -import android.app.Fragment;  import android.content.ActivityNotFoundException;  import android.content.Intent;  import android.os.Build; @@ -40,7 +39,7 @@ import de.blinkt.openvpn.core.ProfileManager;  import de.blinkt.openvpn.core.X509Utils;  import de.blinkt.openvpn.views.FileSelectLayout; -public class Settings_Basic extends Fragment implements View.OnClickListener, OnItemSelectedListener, Callback, FileSelectLayout.FileSelectCallback { +public class Settings_Basic extends Settings_Fragment implements View.OnClickListener, OnItemSelectedListener, Callback, FileSelectLayout.FileSelectCallback {  	private static final int CHOOSE_FILE_OFFSET = 1000;  	private static final int UPDATE_ALIAS = 20; @@ -57,11 +56,10 @@ public class Settings_Basic extends Fragment implements View.OnClickListener, On  	private EditText mUserName;  	private EditText mPassword;  	private View mView; -	private VpnProfile mProfile;  	private EditText mProfileName;  	private EditText mKeyPassword; -	private SparseArray<FileSelectLayout> fileselects = new SparseArray<FileSelectLayout>(); +	private SparseArray<FileSelectLayout> fileselects = new SparseArray<>(); @@ -73,9 +71,7 @@ public class Settings_Basic extends Fragment implements View.OnClickListener, On  	public void onCreate(Bundle savedInstanceState) {  		super.onCreate(savedInstanceState); -		String profileUuid = getArguments().getString(getActivity().getPackageName() + ".profileUUID"); -		mProfile=ProfileManager.get(getActivity(),profileUuid); -		getActivity().setTitle(getString(R.string.edit_profile_title, mProfile.getName())); +  	} @@ -191,15 +187,9 @@ public class Settings_Basic extends Fragment implements View.OnClickListener, On  			changeType(position);  		}  	} -	@Override -	public void onPause() { -		super.onPause(); -		savePreferences(); -	} - -	private void changeType(int type){ +    private void changeType(int type){  		// hide everything  		mView.findViewById(R.id.pkcs12).setVisibility(View.GONE);  		mView.findViewById(R.id.certs).setVisibility(View.GONE); @@ -266,7 +256,7 @@ public class Settings_Basic extends Fragment implements View.OnClickListener, On  	} -	void savePreferences() { +	protected void savePreferences() {  		mProfile.mName = mProfileName.getText().toString();  		mProfile.mCaFilename = mCaCert.getData(); diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Connections.java b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Connections.java index 55cce60b..530d1df8 100644 --- a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Connections.java +++ b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Connections.java @@ -25,8 +25,7 @@ import de.blinkt.openvpn.R;  import de.blinkt.openvpn.VpnProfile;  import de.blinkt.openvpn.core.ProfileManager; -public class Settings_Connections extends Fragment implements View.OnClickListener { -    private VpnProfile mProfile; +public class Settings_Connections extends Settings_Fragment implements View.OnClickListener {      private ConnectionsAdapter mConnectionsAdapter;      private TextView mWarning;      private Checkable mUseRandomRemote; @@ -35,9 +34,7 @@ public class Settings_Connections extends Fragment implements View.OnClickListen      @Override      public void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState); -        String profileUuid = getArguments().getString(getActivity().getPackageName() + ".profileUUID"); -        mProfile= ProfileManager.get(getActivity(), profileUuid); -        getActivity().setTitle(getString(R.string.edit_profile_title, mProfile.getName())); +          setHasOptionsMenu(true);      } @@ -82,8 +79,6 @@ public class Settings_Connections extends Fragment implements View.OnClickListen          return v;      } - -      @Override      public void onClick(View v) {          if (v.getId() == R.id.add_new_remote) { @@ -99,8 +94,7 @@ public class Settings_Connections extends Fragment implements View.OnClickListen      }      @Override -    public void onPause() { -        super.onPause(); +    protected void savePreferences() {          mConnectionsAdapter.saveProfile();          mProfile.mRemoteRandom = mUseRandomRemote.isChecked();      } diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Fragment.java b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Fragment.java new file mode 100644 index 00000000..738bd0e9 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Fragment.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2012-2015 Arne Schwabe + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt + */ + +package de.blinkt.openvpn.fragments; + +import android.app.Fragment; +import android.os.Bundle; + +import de.blinkt.openvpn.R; +import de.blinkt.openvpn.VpnProfile; +import de.blinkt.openvpn.core.ProfileManager; + +public abstract class Settings_Fragment extends Fragment { + +    protected VpnProfile mProfile; + +    @Override +    public void onCreate(Bundle savedInstanceState) { +        super.onCreate(savedInstanceState); +        String profileUuid = getArguments().getString(getActivity().getPackageName() + ".profileUUID"); +        mProfile= ProfileManager.get(getActivity(), profileUuid); +        getActivity().setTitle(getString(R.string.edit_profile_title, mProfile.getName())); +    } + + +    @Override +    public void onPause() { +        super.onPause(); +        savePreferences(); +    } + +    protected abstract void savePreferences(); +} diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_UserEditable.java b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_UserEditable.java new file mode 100644 index 00000000..f9477a85 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_UserEditable.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2012-2015 Arne Schwabe + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt + */ + +package de.blinkt.openvpn.fragments; + +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import de.blinkt.openvpn.R; + +public class Settings_UserEditable extends OpenVpnPreferencesFragment { +    @Override +    protected void loadSettings() { + +    } + +    @Override +    protected void saveSettings() { + +    } + +    @Override +    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { +        View v = inflater.inflate(R.layout.settings_usereditable, container, false); +        TextView messageView = (TextView) v.findViewById(R.id.messageUserEdit); +        messageView.setText(getString(R.string.message_no_user_edit, getPackageString(mProfile.mProfileCreator))); +        return v; +    } + + +    private String getPackageString(String packageName) { +        final PackageManager pm = getActivity().getPackageManager(); +        ApplicationInfo ai; +        try { +            ai = pm.getApplicationInfo( packageName, 0); +        } catch (final PackageManager.NameNotFoundException e) { +            ai = null; +        } +        final String applicationName = (String) (ai != null ? pm.getApplicationLabel(ai) : "(unknown)"); +        return String.format("%s (%s)", applicationName, packageName); +    } +} diff --git a/main/src/main/res/layout/settings_usereditable.xml b/main/src/main/res/layout/settings_usereditable.xml new file mode 100644 index 00000000..5a330df2 --- /dev/null +++ b/main/src/main/res/layout/settings_usereditable.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +  ~ Copyright (c) 2012-2014 Arne Schwabe +  ~ Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt +  --> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +    xmlns:tools="http://schemas.android.com/tools" +    android:orientation="vertical" +    android:padding="@dimen/stdpadding" +    android:layout_width="match_parent" +    android:gravity="center" +    android:layout_height="match_parent"> + +    <TextView +        android:layout_width="wrap_content" +        android:layout_height="wrap_content" +        tools:text="@string/message_no_user_edit" +        android:id="@+id/messageUserEdit" +        android:layout_gravity="center_horizontal" /> +</LinearLayout>
\ No newline at end of file diff --git a/main/src/main/res/values/strings.xml b/main/src/main/res/values/strings.xml index 61cf4700..f552cb3d 100755 --- a/main/src/main/res/values/strings.xml +++ b/main/src/main/res/values/strings.xml @@ -378,5 +378,6 @@      <string name="version_and_later">%s and later</string>      <string name="tls_cipher_alert_title">Connections fails with SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure</string>      <string name="tls_cipher_alert">Newer OpenVPN for Android versions (0.6.29/March 2015) use a more secure default for the allowed cipher suites (tls-cipher \"DEFAULT:!EXP:!PSK:!SRP:!kRSA\"). Unfortunately, omitting the less secure cipher suites and export cipher suites, especially the omission of cipher suites that do not support Perfect Forward Secrecy (Diffie-Hellman) causes some problems. This usually caused by an well-intentioned but poorly executed attempts to strengthen TLS security by setting tls-cipher on the server.\nTo solve this problem the problem, set the tls-cipher settings on the server to reasonable default like tls-cipher \"DEFAULT:!EXP:!PSK:!SRP:!kRSA\". To work around the problem on the client add the custom option tls-cipher DEFAULT on the Android client.</string> +    <string name="message_no_user_edit">This profile has been added from an external app (%s) and has been marked as not user editable.</string>  </resources> diff --git a/remoteExample/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl b/remoteExample/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl index d0791a4a..273a0046 100644 --- a/remoteExample/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl +++ b/remoteExample/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl @@ -12,10 +12,14 @@ interface IOpenVPNAPIService {  	void startProfile (String profileUUID);
 -	/** Use a profile with all certificates etc. embedded */
 +	/** Use a profile with all certificates etc. embedded,
 +	 * old version which does not return the UUID of the addded profile, see
 +	 * below for a version that return the UUID on add */
  	boolean addVPNProfile (String name, String config);
 -	/** start a profile using an config */
 +	/** start a profile using a config as inline string. Make sure that all needed data is inlined,
 +	 * e.g., using <ca>...</ca> or <auth-user-data>...</auth-user-data>
 +	 * See the OpenVPN manual page for more on inlining files */
  	void startVPN (String inlineconfig);
  	/** This permission framework is used  to avoid confused deputy style attack to the VPN
 @@ -55,5 +59,8 @@ interface IOpenVPNAPIService {  	  * Before calling this function you should make sure OpenVPN for Android may actually
  	  * this function by checking if prepareVPNService returns null; */
  	boolean protectSocket(in ParcelFileDescriptor fd);
 -		
 +
 +
 +    /** Use a profile with all certificates etc. embedded */
 +    APIVpnProfile addNewVPNProfile (String name, boolean userEditable, String config);
  }
\ No newline at end of file diff --git a/remoteExample/src/main/assets/hd.conf b/remoteExample/src/main/assets/test.conf index 3dc917aa..3dc917aa 100644 --- a/remoteExample/src/main/assets/hd.conf +++ b/remoteExample/src/main/assets/test.conf diff --git a/remoteExample/src/main/java/de/blinkt/openvpn/api/APIVpnProfile.java b/remoteExample/src/main/java/de/blinkt/openvpn/api/APIVpnProfile.java index f5591764..9d7e3b8e 100644 --- a/remoteExample/src/main/java/de/blinkt/openvpn/api/APIVpnProfile.java +++ b/remoteExample/src/main/java/de/blinkt/openvpn/api/APIVpnProfile.java @@ -1,3 +1,8 @@ +/*
 + * Copyright (c) 2012-2015 Arne Schwabe
 + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt
 + */
 +
  package de.blinkt.openvpn.api;
  import android.os.Parcel;
 @@ -5,47 +10,51 @@ import android.os.Parcelable;  public class APIVpnProfile implements Parcelable {
 -	public final String mUUID;
 -	public final String mName;
 -	public final boolean mUserEditable;
 +    public final String mUUID;
 +    public final String mName;
 +    public final boolean mUserEditable;
 +    public final String mProfileCreator;
 -	public APIVpnProfile(Parcel in) {
 -		mUUID = in.readString();
 -		mName = in.readString();
 +    public APIVpnProfile(Parcel in) {
 +        mUUID = in.readString();
 +        mName = in.readString();
          mUserEditable = in.readInt() != 0;
 -	}
 -
 -	public APIVpnProfile(String uuidString, String name, boolean userEditable) {
 -		mUUID=uuidString;
 -		mName = name;
 -		mUserEditable=userEditable;
 -	}
 -
 -	@Override
 -	public int describeContents() {
 -		return 0;
 -	}
 -
 -	@Override
 -	public void writeToParcel(Parcel dest, int flags) {
 -		dest.writeString(mUUID);
 -		dest.writeString(mName);
 -		if(mUserEditable)
 -			dest.writeInt(0);
 -		else
 -			dest.writeInt(1);
 -	}
 -
 -	public static final Parcelable.Creator<APIVpnProfile> CREATOR
 -	= new Parcelable.Creator<APIVpnProfile>() {
 -		public APIVpnProfile createFromParcel(Parcel in) {
 -			return new APIVpnProfile(in);
 -		}
 -
 -		public APIVpnProfile[] newArray(int size) {
 -			return new APIVpnProfile[size];
 -		}
 -	};
 +        mProfileCreator = in.readString();
 +    }
 +
 +    public APIVpnProfile(String uuidString, String name, boolean userEditable, String profileCreator) {
 +        mUUID = uuidString;
 +        mName = name;
 +        mUserEditable = userEditable;
 +        mProfileCreator = profileCreator;
 +    }
 +
 +    @Override
 +    public int describeContents() {
 +        return 0;
 +    }
 +
 +    @Override
 +    public void writeToParcel(Parcel dest, int flags) {
 +        dest.writeString(mUUID);
 +        dest.writeString(mName);
 +        if (mUserEditable)
 +            dest.writeInt(0);
 +        else
 +            dest.writeInt(1);
 +        dest.writeString(mProfileCreator);
 +    }
 +
 +    public static final Creator<APIVpnProfile> CREATOR
 +            = new Creator<APIVpnProfile>() {
 +        public APIVpnProfile createFromParcel(Parcel in) {
 +            return new APIVpnProfile(in);
 +        }
 +
 +        public APIVpnProfile[] newArray(int size) {
 +            return new APIVpnProfile[size];
 +        }
 +    };
  }
 diff --git a/remoteExample/src/main/java/de/blinkt/openvpn/remote/MainFragment.java b/remoteExample/src/main/java/de/blinkt/openvpn/remote/MainFragment.java index 4f6481b0..a6d2baf5 100644 --- a/remoteExample/src/main/java/de/blinkt/openvpn/remote/MainFragment.java +++ b/remoteExample/src/main/java/de/blinkt/openvpn/remote/MainFragment.java @@ -44,6 +44,7 @@ public class MainFragment extends Fragment implements View.OnClickListener, Hand          v.findViewById(R.id.disconnect).setOnClickListener(this);          v.findViewById(R.id.getMyIP).setOnClickListener(this);          v.findViewById(R.id.startembedded).setOnClickListener(this); +        v.findViewById(R.id.addNewProfile).setOnClickListener(this);          mHelloWorld = (TextView) v.findViewById(R.id.helloworld);          mStartVpn = (Button) v.findViewById(R.id.startVPN);          mStatus = (TextView) v.findViewById(R.id.status); @@ -59,6 +60,8 @@ public class MainFragment extends Fragment implements View.OnClickListener, Hand      private static final int START_PROFILE_EMBEDDED = 2;      private static final int START_PROFILE_BYUUID = 3;      private static final int ICS_OPENVPN_PERMISSION = 7; +    private static final int PROFILE_ADD_NEW = 8; +      protected IOpenVPNAPIService mService=null;      private Handler mHandler; @@ -66,7 +69,7 @@ public class MainFragment extends Fragment implements View.OnClickListener, Hand -    private void startEmbeddedProfile() +    private void startEmbeddedProfile(boolean addNew)      {          try {              InputStream conf = getActivity().getAssets().open("test.conf"); @@ -82,12 +85,11 @@ public class MainFragment extends Fragment implements View.OnClickListener, Hand              }              br.readLine(); -            //			mService.addVPNProfile("test", config); -            mService.startVPN(config); -        } catch (IOException e) { -            e.printStackTrace(); -        } catch (RemoteException e) { -            // TODO Auto-generated catch block +            if (addNew) +                mService.addNewVPNProfile("nonEditable", false, config); +            else +                mService.startVPN(config); +        } catch (IOException | RemoteException e) {              e.printStackTrace();          }      } @@ -252,6 +254,14 @@ public class MainFragment extends Fragment implements View.OnClickListener, Hand                      e.printStackTrace();                  }                  break; + +            case R.id.addNewProfile: +                try { +                    prepareStartProfile(PROFILE_ADD_NEW); +                } catch (RemoteException e) { +                    // TODO Auto-generated catch block +                    e.printStackTrace(); +                }              default:                  break;          } @@ -271,12 +281,11 @@ public class MainFragment extends Fragment implements View.OnClickListener, Hand      public void onActivityResult(int requestCode, int resultCode, Intent data) {          if (resultCode == Activity.RESULT_OK) {              if(requestCode==START_PROFILE_EMBEDDED) -                startEmbeddedProfile(); +                startEmbeddedProfile(false);              if(requestCode==START_PROFILE_BYUUID)                  try {                      mService.startProfile(mStartUUID);                  } catch (RemoteException e) { -                    // TODO Auto-generated catch block                      e.printStackTrace();                  }              if (requestCode == ICS_OPENVPN_PERMISSION) { @@ -288,6 +297,9 @@ public class MainFragment extends Fragment implements View.OnClickListener, Hand                  }              } +            if (requestCode == PROFILE_ADD_NEW) { +                startEmbeddedProfile(true); +            }          }      }; diff --git a/remoteExample/src/main/res/layout/fragment_main.xml b/remoteExample/src/main/res/layout/fragment_main.xml index e4fa019d..9279bd69 100644 --- a/remoteExample/src/main/res/layout/fragment_main.xml +++ b/remoteExample/src/main/res/layout/fragment_main.xml @@ -67,4 +67,14 @@              android:layout_below="@+id/getMyIP"              android:text="@string/start_embedded" /> +    <Button +        android:id="@+id/addNewProfile" +        style="?android:attr/buttonStyleSmall" +        android:layout_width="wrap_content" +        android:layout_height="wrap_content" +        android:text="@string/addNew" +        android:layout_alignTop="@+id/startembedded" +        android:layout_toRightOf="@+id/startembedded" +        android:layout_toEndOf="@+id/startembedded" /> +  </RelativeLayout> diff --git a/remoteExample/src/main/res/values/strings.xml b/remoteExample/src/main/res/values/strings.xml index bbaee226..49d4978d 100644 --- a/remoteExample/src/main/res/values/strings.xml +++ b/remoteExample/src/main/res/values/strings.xml @@ -10,6 +10,7 @@      <string name="show_my_ip">Show my IP</string>      <string name="disconnect">Disconnect</string>      <string name="start_embedded">Start embedded profile</string> +    <string name="addNew">Add new Profile</string>  </resources>  | 
