From 6f74ca80d395542ae92e7e9eb97af11aa4c706bd Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Fri, 27 Apr 2012 23:24:49 +0200 Subject: it is not getIntent() nor savedState nor other fancy stuff, getArgument() is what I want --- src/de/blinkt/openvpn/VpnProfile.java | 236 +++++++++++++++++++++++++++++++++- 1 file changed, 234 insertions(+), 2 deletions(-) (limited to 'src/de/blinkt/openvpn/VpnProfile.java') diff --git a/src/de/blinkt/openvpn/VpnProfile.java b/src/de/blinkt/openvpn/VpnProfile.java index 0eddabaa..c199cf8b 100644 --- a/src/de/blinkt/openvpn/VpnProfile.java +++ b/src/de/blinkt/openvpn/VpnProfile.java @@ -1,12 +1,31 @@ package de.blinkt.openvpn; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; import java.io.Serializable; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Random; import java.util.UUID; +import java.util.Vector; +import android.app.Activity; +import android.content.Context; +import android.content.Intent; import android.os.Parcel; import android.os.Parcelable; +import android.security.KeyChain; +import android.security.KeyChainException; -public class VpnProfile implements Parcelable, Serializable{ +public class VpnProfile implements Serializable{ + // Parcable /** * */ @@ -16,7 +35,8 @@ public class VpnProfile implements Parcelable, Serializable{ static final int TYPE_KEYSTORE=2; public static final int TYPE_USERPASS = 3; public static final int TYPE_STATICKEYS = 4; - + + private static final String OVPNCONFIGFILE = "android.conf"; // Keep in order of parceling // Public attributes, since I got mad with getter/setter @@ -37,6 +57,20 @@ public class VpnProfile implements Parcelable, Serializable{ public String mPKCS12Password; public boolean mUseTLSAuth = false; public String mServerName = "openvpn.blinkt.de" ; + public String mDNS1="131.234.137.23"; + public String mDNS2="131.234.137.24"; + public String mIPv4Address; + public String mIPv6Address; + public boolean mOverrideDNS=false; + public String mSearchDomain="blinkt.de"; + public boolean mUseDefaultRoute=true; + public boolean mUsePull=true; + public String mCustomRoutes; + public boolean mCheckRemoteCN=false; + public boolean mExpectTLSCert=true; + public String mRemoteCN=""; + private String mPassword; + private String mUsername; public int describeContents() { @@ -93,6 +127,9 @@ public class VpnProfile implements Parcelable, Serializable{ } }; + + static final String OVPNCONFIGPKCS12 = "android.pkcs12"; + public VpnProfile(String name) { mUuid = UUID.randomUUID(); mName = name; @@ -108,7 +145,202 @@ public class VpnProfile implements Parcelable, Serializable{ return mName; } + + public String getConfigFile(File cacheDir) + { + + String cfg=""; + + + // TODO "--remote-cert-eku", "TLS Web Server Authentication" + + + + cfg+="client\n"; + cfg+="verb 2\n"; + + + // /tmp does not exist on Android + cfg+="tmp-dir "; + cfg+=cacheDir.getAbsolutePath(); + cfg+="\n"; + + // quit after 5 tries + cfg+="connect-retry-max 5\n"; + cfg+="resolv-retry 5\n"; + + + + // We cannot use anything else than tun + cfg+="dev tun\n"; + + // Server Address + cfg+="remote "; + cfg+=mServerName; + cfg+=" "; + cfg+=mServerPort; + if(mUseUdp) + cfg+=" udp\n"; + else + cfg+=" tcp\n"; + + + switch(mAuthenticationType) { + case VpnProfile.TYPE_CERTIFICATES: + // Ca + cfg+="ca "; + cfg+=mCaFilename; + cfg+="\n"; + + // Client Cert + Key + cfg+="key "; + cfg+=mClientKeyFilename; + cfg+="\n"; + cfg+="cert "; + cfg+=mClientCertFilename; + cfg+="\n"; + break; + case VpnProfile.TYPE_PKCS12: + cfg+="pkcs12 "; + cfg+=mPKCS12Filename; + cfg+="\n"; + cfg+="management-query-passwords\n"; + break; + + case VpnProfile.TYPE_KEYSTORE: + cfg+="pkcs12 "; + cfg+=cacheDir.getAbsolutePath() + "/" + OVPNCONFIGPKCS12; + cfg+="\n"; + cfg+="management-query-passwords\n"; + break; + + } + + if(mUseLzo) { + cfg+="comp-lzo\n"; + } + + if(mUseTLSAuth) { + cfg+="tls-auth "; + cfg+=mTLSAuthFilename; + int tlsdir= mTLSAuthDirection; + // 2 is unspecified + if(tlsdir == 0 || tlsdir==1) { + cfg+=" "; + cfg+=new Integer(tlsdir).toString(); + } + cfg+="\n"; + } + + return cfg; + } + private String[] buildOpenvpnArgv(File cacheDir) + { + Vector args = new Vector(); + + // Add fixed paramenters + args.add("openvpn"); + + // Enable managment interface to + // stop openvpn + args.add("--management"); + + args.add(cacheDir.getAbsolutePath() + "/" + "mgmtsocket"); + args.add("unix"); + //args.add("--management-hold"); + + args.add("--config"); + args.add(cacheDir.getAbsolutePath() + "/" + OVPNCONFIGFILE); + + + return (String[]) args.toArray(new String[args.size()]); + } + + public Intent prepareIntent(Activity activity) { + String prefix = activity.getPackageName(); + + Intent intent = new Intent(activity,OpenVpnService.class); + + intent.putExtra(prefix + ".ARGV" , buildOpenvpnArgv(activity.getCacheDir())); + + if(mAuthenticationType == TYPE_PKCS12){ + intent.putExtra(prefix + ".PKCS12PASS", + mPKCS12Password); + } + + if(mAuthenticationType == VpnProfile.TYPE_KEYSTORE) { + String pkcs12pw = savePKCS12(activity); + intent.putExtra(prefix + ".PKCS12PASS", pkcs12pw); + } + + if(mAuthenticationType == VpnProfile.TYPE_USERPASS) { + intent.putExtra(prefix + ".USERNAME", mUsername); + intent.putExtra(prefix + ".PASSWORD", mPassword); + } + + try { + FileWriter cfg = new FileWriter(activity.getCacheDir().getAbsolutePath() + "/" + OVPNCONFIGFILE); + cfg.write(getConfigFile(activity.getCacheDir())); + cfg.flush(); + cfg.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + return intent; + } + + private String getRandomPW() { + String pw= ""; + // Put enough digits togher to make a password :) + Random r = new Random(); + for(int i=0;i < 4;i++) { + pw += new Integer(r.nextInt(1000)).toString(); + } + + return pw; + + } + + private String savePKCS12(Context context) { + PrivateKey privateKey = null; + X509Certificate[] cachain=null; + try { + privateKey = KeyChain.getPrivateKey(context,mAlias); + cachain = KeyChain.getCertificateChain(context, mAlias); + + KeyStore ks = KeyStore.getInstance("PKCS12"); + ks.load(null, null); + ks.setKeyEntry("usercert", privateKey, null, cachain); + String mypw = getRandomPW(); + FileOutputStream fout = new FileOutputStream(context.getCacheDir().getAbsolutePath() + "/" + VpnProfile.OVPNCONFIGPKCS12); + ks.store(fout,mypw.toCharArray()); + fout.flush(); fout.close(); + return mypw; + } catch (KeyChainException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (KeyStoreException e) { + e.printStackTrace(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (CertificateException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return "ERROR"; + + } + } + + + + -- cgit v1.2.3