diff options
| author | Arne Schwabe <arne@rfc2549.org> | 2016-12-16 12:26:20 +0100 | 
|---|---|---|
| committer | Arne Schwabe <arne@rfc2549.org> | 2016-12-16 12:26:20 +0100 | 
| commit | 1eac1f1a6e4dbc70db1cd7ec0555a7fd1996374d (patch) | |
| tree | 2949d3d86a3d1197ed10e651e3c4b12d3b6625be | |
| parent | 73b79c6874341584d468d58e7a474ca283b062fb (diff) | |
Implement password handover between ui and service
13 files changed, 217 insertions, 78 deletions
| diff --git a/build.gradle b/build.gradle index 1645c2a8..65620b6e 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ buildscript {          jcenter()      }      dependencies { -        classpath 'com.android.tools.build:gradle:2.3.0-alpha1' +        classpath 'com.android.tools.build:gradle:2.3.0-alpha3'      }  } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 90a1a2cd..4d7436fe 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu Aug 04 16:24:55 CEST 2016 +#Wed Dec 14 15:14:57 CET 2016  distributionBase=GRADLE_USER_HOME  distributionPath=wrapper/dists  zipStoreBase=GRADLE_USER_HOME  zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-3.2-all.zip diff --git a/main/src/main/AndroidManifest.xml b/main/src/main/AndroidManifest.xml index d80ae581..548e0ef8 100644 --- a/main/src/main/AndroidManifest.xml +++ b/main/src/main/AndroidManifest.xml @@ -198,6 +198,7 @@              android:grantUriPermissions="true"              tools:ignore="ExportedContentProvider" /> +          <!--          <receiver android:name="core.GetRestrictionReceiver">              <intent-filter> diff --git a/main/src/main/aidl/de/blinkt/openvpn/core/IServiceStatus.aidl b/main/src/main/aidl/de/blinkt/openvpn/core/IServiceStatus.aidl index cbcb0181..6254566a 100644 --- a/main/src/main/aidl/de/blinkt/openvpn/core/IServiceStatus.aidl +++ b/main/src/main/aidl/de/blinkt/openvpn/core/IServiceStatus.aidl @@ -18,7 +18,12 @@ interface IServiceStatus {          void unregisterStatusCallback(in IStatusCallbacks cb);          /** -         * +         * Returns the last connedcted VPN           */          String getLastConnectedVPN(); + +        /** +          * Sets a cached password +          */ +       void setCachedPassword(in String uuid, int type, String password);  } diff --git a/main/src/main/java/de/blinkt/openvpn/LaunchVPN.java b/main/src/main/java/de/blinkt/openvpn/LaunchVPN.java index 9490c269..5eb44953 100644 --- a/main/src/main/java/de/blinkt/openvpn/LaunchVPN.java +++ b/main/src/main/java/de/blinkt/openvpn/LaunchVPN.java @@ -9,13 +9,18 @@ import android.annotation.TargetApi;  import android.app.Activity;  import android.app.AlertDialog;  import android.content.ActivityNotFoundException; +import android.content.ComponentName; +import android.content.Context;  import android.content.DialogInterface;  import android.content.DialogInterface.OnClickListener;  import android.content.Intent; +import android.content.ServiceConnection;  import android.content.SharedPreferences;  import android.net.VpnService;  import android.os.Build;  import android.os.Bundle; +import android.os.IBinder; +import android.os.RemoteException;  import android.preference.PreferenceManager;  import android.text.InputType;  import android.text.TextUtils; @@ -29,6 +34,9 @@ import java.io.IOException;  import de.blinkt.openvpn.activities.LogWindow;  import de.blinkt.openvpn.core.ConnectionStatus; +import de.blinkt.openvpn.core.IServiceStatus; +import de.blinkt.openvpn.core.OpenVPNStatusService; +import de.blinkt.openvpn.core.PasswordCache;  import de.blinkt.openvpn.core.ProfileManager;  import de.blinkt.openvpn.core.VPNLaunchHelper;  import de.blinkt.openvpn.core.VpnStatus; @@ -73,14 +81,42 @@ public class LaunchVPN extends Activity {      private boolean mhideLog = false;      private boolean mCmfixed = false; +    private String mTransientAuthPW; +    private String mTransientCertOrPCKS12PW;      @Override      public void onCreate(Bundle icicle) {          super.onCreate(icicle); - +        setContentView(R.layout.launchvpn);          startVpnFromIntent();      } +    private ServiceConnection mConnection = new ServiceConnection() { +        @Override +        public void onServiceConnected(ComponentName componentName, IBinder binder) { +            IServiceStatus service = IServiceStatus.Stub.asInterface(binder); +            try { +                if (mTransientAuthPW != null) + +                    service.setCachedPassword(mSelectedProfile.getUUIDString(), PasswordCache.AUTHPASSWORD, mTransientAuthPW); +                if (mTransientCertOrPCKS12PW != null) +                    service.setCachedPassword(mSelectedProfile.getUUIDString(), PasswordCache.PCKS12ORCERTPASSWORD, mTransientCertOrPCKS12PW); + +                onActivityResult(START_VPN_PROFILE, Activity.RESULT_OK, null); + +            } catch (RemoteException e) { +                e.printStackTrace(); +            } + +            unbindService(this); +        } + +        @Override +        public void onServiceDisconnected(ComponentName componentName) { + +        } +    }; +      protected void startVpnFromIntent() {          // Resolve the intent @@ -161,13 +197,13 @@ public class LaunchVPN extends Activity {                                  mSelectedProfile.mPassword = pw;                              } else {                                  mSelectedProfile.mPassword = null; -                                mSelectedProfile.mTransientPW = pw; +                                mTransientAuthPW = pw;                              }                          } else { -                            mSelectedProfile.mTransientPCKS12PW = entry.getText().toString(); +                            mTransientCertOrPCKS12PW = entry.getText().toString();                          } -                        onActivityResult(START_VPN_PROFILE, Activity.RESULT_OK, null); - +                        Intent intent = new Intent(LaunchVPN.this, OpenVPNStatusService.class); +                        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);                      }                  }); @@ -191,7 +227,7 @@ public class LaunchVPN extends Activity {          if (requestCode == START_VPN_PROFILE) {              if (resultCode == Activity.RESULT_OK) { -                int needpw = mSelectedProfile.needUserPWInput(false); +                int needpw = mSelectedProfile.needUserPWInput(mTransientCertOrPCKS12PW, mTransientAuthPW);                  if (needpw != 0) {                      VpnStatus.updateStateString("USER_VPN_PASSWORD", "", R.string.state_user_vpn_password,                              ConnectionStatus.LEVEL_WAITING_FOR_USER_INPUT); diff --git a/main/src/main/java/de/blinkt/openvpn/VpnProfile.java b/main/src/main/java/de/blinkt/openvpn/VpnProfile.java index dbec98e4..4c03f686 100644 --- a/main/src/main/java/de/blinkt/openvpn/VpnProfile.java +++ b/main/src/main/java/de/blinkt/openvpn/VpnProfile.java @@ -9,7 +9,6 @@ import android.annotation.SuppressLint;  import android.content.Context;  import android.content.Intent;  import android.content.SharedPreferences; -import android.content.pm.ApplicationInfo;  import android.content.pm.PackageInfo;  import android.content.pm.PackageManager;  import android.os.Build; @@ -52,6 +51,7 @@ import javax.crypto.NoSuchPaddingException;  import de.blinkt.openvpn.core.Connection;  import de.blinkt.openvpn.core.NativeUtils;  import de.blinkt.openvpn.core.OpenVPNService; +import de.blinkt.openvpn.core.PasswordCache;  import de.blinkt.openvpn.core.VPNLaunchHelper;  import de.blinkt.openvpn.core.VpnStatus;  import de.blinkt.openvpn.core.X509Utils; @@ -75,10 +75,6 @@ public class VpnProfile implements Serializable, Cloneable {      public static String DEFAULT_DNS1 = "8.8.8.8";      public static String DEFAULT_DNS2 = "8.8.4.4"; -    public transient String mTransientPW = null; -    public transient String mTransientPCKS12PW = null; - -      public static final int TYPE_CERTIFICATES = 0;      public static final int TYPE_PKCS12 = 1;      public static final int TYPE_KEYSTORE = 2; @@ -164,7 +160,7 @@ public class VpnProfile implements Serializable, Cloneable {      public boolean mPushPeerInfo = false;      public static final boolean mIsOpenVPN22 = false; -    public int mVersion=0; +    public int mVersion = 0;      /* Options no longer used in new profiles */      public String mServerName = "openvpn.example.com"; @@ -313,7 +309,7 @@ public class VpnProfile implements Serializable, Cloneable {              mConnectRetry = "2";          if (TextUtils.isEmpty(mConnectRetryMaxTime)) -            mConnectRetryMaxTime="300"; +            mConnectRetryMaxTime = "300";          if (!mIsOpenVPN22) @@ -406,7 +402,7 @@ public class VpnProfile implements Serializable, Cloneable {              if (mAuthenticationType == TYPE_STATICKEYS)                  cfg += insertFileData("secret", mTLSAuthFilename); -            else if(useTlsCrypt) +            else if (useTlsCrypt)                  cfg += insertFileData("tls-crypt", mTLSAuthFilename);              else                  cfg += insertFileData("tls-auth", mTLSAuthFilename); @@ -503,7 +499,7 @@ public class VpnProfile implements Serializable, Cloneable {                              break;                      }                  if (!TextUtils.isEmpty(mx509UsernameField)) -                    cfg+= "x509-username-field " + openVpnEscape(mx509UsernameField) +"\n"; +                    cfg += "x509-username-field " + openVpnEscape(mx509UsernameField) + "\n";              }              if (mExpectTLSCert)                  cfg += "remote-cert-tls server\n"; @@ -858,8 +854,12 @@ public class VpnProfile implements Serializable, Cloneable {          if (mAuthenticationType == TYPE_KEYSTORE || mAuthenticationType == TYPE_USERPASS_KEYSTORE) {              if (mAlias == null)                  return R.string.no_keystore_cert_selected; +        } else { +            if (TextUtils.isEmpty(mCaFilename)) +                return R.string.no_ca_cert_selected;          } +          if (!mUsePull || mAuthenticationType == TYPE_STATICKEYS) {              if (mIPv4Address == null || cidrToIPAndNetmask(mIPv4Address) == null)                  return R.string.ipv4_format_error; @@ -901,10 +901,9 @@ public class VpnProfile implements Serializable, Cloneable {      //! Openvpn asks for a "Private Key", this should be pkcs12 key      //      public String getPasswordPrivateKey() { -        if (mTransientPCKS12PW != null) { -            String pwcopy = mTransientPCKS12PW; -            mTransientPCKS12PW = null; -            return pwcopy; +        String cachedPw = PasswordCache.getPKCS12orCertificatePassword(mUuid, true); +        if (cachedPw != null) { +            return cachedPw;          }          switch (mAuthenticationType) {              case TYPE_PKCS12: @@ -969,33 +968,32 @@ public class VpnProfile implements Serializable, Cloneable {              return false;      } -    public int needUserPWInput(boolean ignoreTransient) { +    public int needUserPWInput(String transientCertOrPkcs12PW, String mTransientAuthPW) {          if ((mAuthenticationType == TYPE_PKCS12 || mAuthenticationType == TYPE_USERPASS_PKCS12) &&                  (mPKCS12Password == null || mPKCS12Password.equals(""))) { -            if (ignoreTransient || mTransientPCKS12PW == null) +            if (transientCertOrPkcs12PW == null)                  return R.string.pkcs12_file_encryption_key;          }          if (mAuthenticationType == TYPE_CERTIFICATES || mAuthenticationType == TYPE_USERPASS_CERTIFICATES) {              if (requireTLSKeyPassword() && TextUtils.isEmpty(mKeyPassword)) -                if (ignoreTransient || mTransientPCKS12PW == null) { +                if (transientCertOrPkcs12PW == null) {                      return R.string.private_key_password;                  }          }          if (isUserPWAuth() &&                  (TextUtils.isEmpty(mUsername) || -                        (TextUtils.isEmpty(mPassword) && (mTransientPW == null || ignoreTransient)))) { +                        (TextUtils.isEmpty(mPassword) && mTransientAuthPW == null))) {              return R.string.password;          }          return 0;      }      public String getPasswordAuth() { -        if (mTransientPW != null) { -            String pwcopy = mTransientPW; -            mTransientPW = null; -            return pwcopy; +        String cachedPw = PasswordCache.getAuthPassword(mUuid, true); +        if (cachedPw != null) { +            return cachedPw;          } else {              return mPassword;          } 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 6d7e9a4b..85d0ae2c 100644 --- a/main/src/main/java/de/blinkt/openvpn/api/ExternalOpenVPNService.java +++ b/main/src/main/java/de/blinkt/openvpn/api/ExternalOpenVPNService.java @@ -153,7 +153,7 @@ public class ExternalOpenVPNService extends Service implements StateListener {              /* Check if we need to show the confirmation dialog,
               * Check if we need to ask for username/password */
 -            int neddPassword = vp.needUserPWInput(false);
 +            int neddPassword = vp.needUserPWInput(null, null);
              if(vpnPermissionIntent != null || neddPassword != 0){
                  Intent shortVPNIntent = new Intent(Intent.ACTION_MAIN);
 diff --git a/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java index 4e8deac0..f0d739c3 100644 --- a/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java +++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java @@ -22,6 +22,7 @@ import android.net.ConnectivityManager;  import android.net.VpnService;  import android.os.Binder;  import android.os.Build; +import android.os.Bundle;  import android.os.Handler;  import android.os.Handler.Callback;  import android.os.IBinder; @@ -46,6 +47,7 @@ import java.util.Locale;  import java.util.Vector;  import de.blinkt.openvpn.BuildConfig; +import de.blinkt.openvpn.LaunchVPN;  import de.blinkt.openvpn.R;  import de.blinkt.openvpn.VpnProfile;  import de.blinkt.openvpn.activities.DisconnectVPN; @@ -89,6 +91,11 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac      private Runnable mOpenVPNThread;      private static Class mNotificationActivityClass; +    private static final int PRIORITY_MIN = -2; +    private static final int PRIORITY_DEFAULT = 0; +    private static final int PRIORITY_MAX = 2; + +      private final IBinder mBinder = new IOpenVPNServiceInternal.Stub() {          @Override @@ -162,11 +169,10 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac          }      } -    private void showNotification(final String msg, String tickerText, boolean lowpriority, long when, ConnectionStatus status) { + +    private void showNotification(final String msg, String tickerText, int priority, long when, ConnectionStatus status) {          String ns = Context.NOTIFICATION_SERVICE;          NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns); - -          int icon = getIconByConnectionStatus(status);          android.app.Notification.Builder nbuilder = new Notification.Builder(this); @@ -179,9 +185,12 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac          nbuilder.setContentText(msg);          nbuilder.setOnlyAlertOnce(true);          nbuilder.setOngoing(true); -        nbuilder.setContentIntent(getLogPendingIntent()); -        nbuilder.setSmallIcon(icon); +        nbuilder.setSmallIcon(icon); +        if (status == LEVEL_WAITING_FOR_USER_INPUT) +            nbuilder.setContentIntent(getUserInputIntent(msg)); +        else +            nbuilder.setContentIntent(getLogPendingIntent());          if (when != 0)              nbuilder.setWhen(when); @@ -189,7 +198,8 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac          // Try to set the priority available since API 16 (Jellybean)          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) -            jbNotificationExtras(lowpriority, nbuilder); + +            jbNotificationExtras(priority, nbuilder);          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)              lpNotificationExtras(nbuilder); @@ -205,7 +215,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac          startForeground(OPENVPN_STATUS, notification);          // Check if running on a TV -        if (runningOnAndroidTV() && !lowpriority) +        if (runningOnAndroidTV() && !(priority < 0))              guiHandler.post(new Runnable() {                  @Override @@ -255,13 +265,12 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac      }      @TargetApi(Build.VERSION_CODES.JELLY_BEAN) -    private void jbNotificationExtras(boolean lowpriority, +    private void jbNotificationExtras(int priority,                                        android.app.Notification.Builder nbuilder) {          try { -            if (lowpriority) { +            if (priority != 0) {                  Method setpriority = nbuilder.getClass().getMethod("setPriority", int.class); -                // PRIORITY_MIN == -2 -                setpriority.invoke(nbuilder, -2); +                setpriority.invoke(nbuilder, priority);                  Method setUsesChronometer = nbuilder.getClass().getMethod("setUsesChronometer", boolean.class);                  setUsesChronometer.invoke(nbuilder, true); @@ -307,6 +316,16 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac          mNotificationActivityClass = activityClass;      } +    PendingIntent getUserInputIntent(String needed) { +        Intent intent = new Intent(getApplicationContext(), LaunchVPN.class); +        intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); +        intent.putExtra("need", needed); +        Bundle b = new Bundle(); +        b.putString("need", needed); +        PendingIntent pIntent = PendingIntent.getActivity(this, 12, intent, 0); +        return pIntent; +    } +      PendingIntent getLogPendingIntent() {          // Let the configure Button show the Log          Class activityClass = LogWindow.class; @@ -360,8 +379,8 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac      @Override      public boolean stopVPN(boolean replaceConnection) throws RemoteException { -        if(getManagement() !=null) -            return  getManagement().stopVPN(replaceConnection); +        if (getManagement() != null) +            return getManagement().stopVPN(replaceConnection);          else              return false;      } @@ -412,16 +431,13 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac                  Log.d("OpenVPN", "Got no last connected profile on null intent. Assuming always on.");                  mProfile = ProfileManager.getAlwaysOnVPN(this); -                if (mProfile==null) { +                if (mProfile == null) {                      stopSelf(startId);                      return START_NOT_STICKY;                  }              }              /* Do the asynchronous keychain certificate stuff */              mProfile.checkForRestart(this); - -            /* Recreate the intent */ -            intent = mProfile.getStartServiceIntent(this);          }          /* start the OpenVPN process itself in a background thread */ @@ -435,10 +451,6 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac          ProfileManager.setConnectedVpnProfile(this, mProfile);          VpnStatus.setConnectedVPNProfile(mProfile.getUUIDString()); -        /* TODO: At the moment we have no way to handle asynchronous PW input -         * Fixing will also allow to handle challenge/response authentication */ -        if (mProfile.needUserPWInput(true) != 0) -            return START_NOT_STICKY;          return START_STICKY;      } @@ -455,12 +467,9 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac              endVpnService();              return;          } - -        // Extract information from the intent. -        String prefix = getPackageName();          String nativeLibraryDirectory = getApplicationInfo().nativeLibraryDir; -        // Also writes OpenVPN binary +        // Write OpenVPN binary          String[] argv = VPNLaunchHelper.buildOpenvpnArgv(this); @@ -518,21 +527,21 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac          }          new Handler(getMainLooper()).post(new Runnable() { -                         @Override -                         public void run() { -                             if (mDeviceStateReceiver != null) -                                 unregisterDeviceStateReceiver(); +                                              @Override +                                              public void run() { +                                                  if (mDeviceStateReceiver != null) +                                                      unregisterDeviceStateReceiver(); -                             registerDeviceStateReceiver(mManagement); -                         } -                     } +                                                  registerDeviceStateReceiver(mManagement); +                                              } +                                          } -                ); +        );      }      private void stopOldOpenVPNProcess() {          if (mManagement != null) { -            if (mOpenVPNThread!=null) +            if (mOpenVPNThread != null)                  ((OpenVPNThread) mOpenVPNThread).setReplaceConnection();              if (mManagement.stopVPN(true)) {                  // an old was asked to exit, wait 1s @@ -980,7 +989,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac          if (mProcessThread == null && !mNotificationAlwaysVisible)              return; -        boolean lowpriority = false; +        int priority = PRIORITY_DEFAULT;          // Display byte count only after being connected          { @@ -992,7 +1001,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac                  mDisplayBytecount = true;                  mConnecttime = System.currentTimeMillis();                  if (!runningOnAndroidTV()) -                    lowpriority = true; +                    priority = PRIORITY_MIN;              } else {                  mDisplayBytecount = false;              } @@ -1003,7 +1012,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac              // Does not work :(              String msg = getString(resid);              showNotification(VpnStatus.getLastCleanLogMessage(this), -                    msg, lowpriority, 0, level); +                    msg, priority, 0, level);          }      } @@ -1029,8 +1038,8 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac                      humanReadableByteCount(out, false),                      humanReadableByteCount(diffOut / OpenVPNManagement.mBytecountInterval, true)); -            boolean lowpriority = !mNotificationAlwaysVisible; -            showNotification(netstat, null, lowpriority, mConnecttime, LEVEL_CONNECTED); +            int priority = mNotificationAlwaysVisible ? PRIORITY_DEFAULT : PRIORITY_MIN; +            showNotification(netstat, null, priority, mConnecttime, LEVEL_CONNECTED);          }      } @@ -1064,4 +1073,9 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac                  return "OPEN_BEFORE_CLOSE";          }      } + +    public void requestInputFromUser(int resid, String needed) { +        VpnStatus.updateStateString("NEED", "need " + needed, resid, LEVEL_WAITING_FOR_USER_INPUT); +        showNotification(getString(resid), getString(resid), PRIORITY_MAX, 0, LEVEL_WAITING_FOR_USER_INPUT); +    }  } diff --git a/main/src/main/java/de/blinkt/openvpn/core/OpenVPNStatusService.java b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNStatusService.java index afac749c..c2a943e9 100644 --- a/main/src/main/java/de/blinkt/openvpn/core/OpenVPNStatusService.java +++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNStatusService.java @@ -113,6 +113,12 @@ public class OpenVPNStatusService extends Service implements VpnStatus.LogListen          public String getLastConnectedVPN() throws RemoteException {              return VpnStatus.getLastConnectedVPNProfile();          } + +        @Override +        public void setCachedPassword(String uuid, int type, String password) { +            PasswordCache.setCachedPassword(uuid, type, password); +        } +      };      @Override @@ -162,7 +168,7 @@ public class OpenVPNStatusService extends Service implements VpnStatus.LogListen      private static final int SEND_NEW_BYTECOUNT = 102;      private static final int SEND_NEW_CONNECTED_VPN = 103; -    static class OpenVPNStatusHandler extends Handler { +    private static class OpenVPNStatusHandler extends Handler {          WeakReference<OpenVPNStatusService> service = null;          private void setService(OpenVPNStatusService statusService) { @@ -188,7 +194,7 @@ public class OpenVPNStatusService extends Service implements VpnStatus.LogListen                              broadcastItem.newLogItem((LogItem) msg.obj);                              break;                          case SEND_NEW_BYTECOUNT: -                            Pair<Long, Long> inout = (Pair<Long, Long>) msg.obj; +                        Pair<Long, Long> inout = (Pair<Long, Long>) msg.obj;                              broadcastItem.updateByteCount(inout.first, inout.second);                              break;                          case SEND_NEW_STATE: diff --git a/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java b/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java index 75b0120a..92a9ecb7 100644 --- a/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java +++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java @@ -12,6 +12,7 @@ import android.net.LocalSocketAddress;  import android.os.Handler;
  import android.os.ParcelFileDescriptor;
  import android.support.annotation.NonNull;
 +import android.text.TextUtils;
  import android.util.Log;
  import junit.framework.Assert;
 @@ -141,7 +142,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {              // Close the management socket after client connected
              try {
                  mServerSocket.close();
 -            } catch (IOException e){
 +            } catch (IOException e) {
                  VpnStatus.logException(e);
              }
 @@ -564,15 +565,16 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {          if (needed.equals("Private Key")) {
              pw = mProfile.getPasswordPrivateKey();
          } else if (needed.equals("Auth")) {
 -            String usercmd = String.format("username '%s' %s\n",
 -                    needed, VpnProfile.openVpnEscape(mProfile.mUsername));
 -            managmentCommand(usercmd);
              pw = mProfile.getPasswordAuth();
          }
          if (pw != null) {
 +            String usercmd = String.format("username '%s' %s\n",
 +                    needed, VpnProfile.openVpnEscape(mProfile.mUsername));
 +            managmentCommand(usercmd);
              String cmd = String.format("password '%s' %s\n", needed, VpnProfile.openVpnEscape(pw));
              managmentCommand(cmd);
          } else {
 +            mOpenVPNService.requestInputFromUser(R.string.password, needed);
              VpnStatus.logError(String.format("Openvpn requires Authentication type '%s' but no password/key information available", needed));
          }
 diff --git a/main/src/main/java/de/blinkt/openvpn/core/PasswordCache.java b/main/src/main/java/de/blinkt/openvpn/core/PasswordCache.java new file mode 100644 index 00000000..179a8a7b --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/core/PasswordCache.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2012-2016 Arne Schwabe + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt + */ + +package de.blinkt.openvpn.core; + +import java.util.UUID; + +/** + * Created by arne on 15.12.16. + */ + +public class PasswordCache { +    public static final int PCKS12ORCERTPASSWORD = 2; +    public static final int AUTHPASSWORD = 3; +    private static PasswordCache mInstance; +    final private UUID mUuid; +    private String mKeyOrPkcs12Password; +    private String mAuthPassword; + +    private PasswordCache(UUID uuid) { +        mUuid = uuid; +    } + +    public static PasswordCache getInstance(UUID uuid) { +        if (mInstance == null || !mInstance.mUuid.equals(uuid)) { +            mInstance = new PasswordCache(uuid); +        } +        return mInstance; +    } + +    public static String getPKCS12orCertificatePassword(UUID uuid, boolean resetPw) { +        String pwcopy = getInstance(uuid).mKeyOrPkcs12Password; +        if (resetPw) +            getInstance(uuid).mKeyOrPkcs12Password = null; +        return pwcopy; +    } + + +    public static String getAuthPassword(UUID uuid, boolean resetPW) { +        String pwcopy = getInstance(uuid).mAuthPassword; +        if (resetPW) +            getInstance(uuid).mAuthPassword = null; +        return pwcopy; +    } + +    public static void setCachedPassword(String uuid, int type, String password) { +        PasswordCache instance = getInstance(UUID.fromString(uuid)); +        switch (type) { +            case PCKS12ORCERTPASSWORD: +                instance.mKeyOrPkcs12Password = password; +                break; +            case AUTHPASSWORD: +                instance.mAuthPassword = password; +                break; +        } +    } + + +} diff --git a/main/src/main/res/layout/launchvpn.xml b/main/src/main/res/layout/launchvpn.xml new file mode 100644 index 00000000..245d2f01 --- /dev/null +++ b/main/src/main/res/layout/launchvpn.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +  ~ Copyright (c) 2012-2016 Arne Schwabe +  ~ Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt +  --> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" +    android:orientation="vertical" android:layout_width="match_parent" +    android:layout_height="match_parent"> +    <ProgressBar +        android:layout_gravity="center" +        style="?android:attr/progressBarStyleLarge" +        android:layout_width="wrap_content" +        android:layout_height="wrap_content" /> +</FrameLayout>
\ 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 faab789c..9ce804b5 100755 --- a/main/src/main/res/values/strings.xml +++ b/main/src/main/res/values/strings.xml @@ -42,13 +42,14 @@      <string name="duplicate_profile_name">Please enter a unique Profile Name</string>      <string name="profilename">Profile Name</string>      <string name="no_keystore_cert_selected">You must select a User certificate</string> +    <string name="no_ca_cert_selected">You must select a CA certificate</string>      <string name="no_error_found">No error found</string>      <string name="config_error_found">Error in Configuration</string>      <string name="ipv4_format_error">Error parsing the IPv4 address</string>      <string name="custom_route_format_error">Error parsing the custom routes</string>      <string name="pw_query_hint">(leave empty to query on demand)</string>      <string name="vpn_shortcut">OpenVPN Shortcut</string> -    <string name="vpn_launch_title">Connect to VPN</string> +    <string name="vpn_launch_title">Connecting to VPNā¦</string>      <string name="shortcut_profile_notfound">Profile specified in shortcut not found</string>      <string name="random_host_prefix">Random Host Prefix</string>      <string name="random_host_summary">Adds 6 random chars in front of hostname</string> | 
