diff options
-rw-r--r-- | AndroidManifest.xml | 4 | ||||
-rw-r--r-- | openvpn/src/openvpn/error.c | 15 | ||||
-rw-r--r-- | openvpn/src/openvpn/socket.c | 1 | ||||
-rw-r--r-- | openvpn/src/openvpn/testmain.c | 0 | ||||
-rw-r--r-- | res/values/strings.xml | 4 | ||||
-rw-r--r-- | res/xml/vpn_authentification.xml | 12 | ||||
-rw-r--r-- | res/xml/vpn_headers.xml | 3 | ||||
-rw-r--r-- | src/de/blinkt/openvpn/ConfigParser.java | 232 | ||||
-rw-r--r-- | src/de/blinkt/openvpn/Settings_Authentication.java | 13 | ||||
-rw-r--r-- | src/de/blinkt/openvpn/VpnProfile.java | 21 | ||||
-rw-r--r-- | todo.txt | 1 |
11 files changed, 280 insertions, 26 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index bc3f311c..b6cdc32b 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -17,8 +17,8 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="de.blinkt.openvpn" - android:versionCode="21" - android:versionName="0.5.0" > + android:versionCode="22" + android:versionName="0.5.1" > <uses-permission android:name="android.permission.INTERNET" /> diff --git a/openvpn/src/openvpn/error.c b/openvpn/src/openvpn/error.c index 83a9eb4b..e2e24b1e 100644 --- a/openvpn/src/openvpn/error.c +++ b/openvpn/src/openvpn/error.c @@ -199,11 +199,6 @@ msg_fp(const unsigned int flags) int x_msg_line_num; /* GLOBAL */ -#include "android/log.h" - - - - void x_msg (const unsigned int flags, const char *format, ...) { struct gc_arena gc; @@ -219,7 +214,6 @@ void x_msg (const unsigned int flags, const char *format, ...) const char *prefix_sep; void usage_small (void); - #ifndef HAVE_VARARG_MACROS /* the macro has checked this otherwise */ @@ -304,12 +298,10 @@ void x_msg (const unsigned int flags, const char *format, ...) if (!prefix) prefix_sep = prefix = ""; - /* virtual output capability used to copy output to management subsystem */ if (!forked) { const struct virtual_output *vo = msg_get_virtual_output (); - if (vo) { openvpn_snprintf (m2, ERR_BUF_SIZE, "%s%s%s", @@ -331,7 +323,7 @@ void x_msg (const unsigned int flags, const char *format, ...) m1); #endif } - else // No Syslog + else { FILE *fp = msg_fp(flags); const bool show_usec = check_debug_level (DEBUG_LEVEL_USEC_TIME); @@ -356,13 +348,8 @@ void x_msg (const unsigned int flags, const char *format, ...) fflush(fp); ++x_msg_line_num; } -#ifdef TARGET_ANDROID - android_openvpn_log(prefix,prefix_sep,m1);; -#endif } - - if (flags & M_FATAL) msg (M_INFO, "Exiting due to fatal error"); diff --git a/openvpn/src/openvpn/socket.c b/openvpn/src/openvpn/socket.c index 71010979..b92c2828 100644 --- a/openvpn/src/openvpn/socket.c +++ b/openvpn/src/openvpn/socket.c @@ -859,7 +859,6 @@ create_socket_tcp (void) msg (M_SOCKERR, "TCP: Cannot setsockopt SO_LINGER on TCP socket"); } #endif - return sd; } diff --git a/openvpn/src/openvpn/testmain.c b/openvpn/src/openvpn/testmain.c new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/openvpn/src/openvpn/testmain.c diff --git a/res/values/strings.xml b/res/values/strings.xml index 90009e8c..9073c0be 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -185,4 +185,8 @@ <string name="faq_shortcut">Shortcut to start</string> <string name="faq_howto_shortcut">You can place a shortcut to start OpenVPN on your desktop. Depending on your homescreen program you have to add a shortcut or a widget.</string> <string name="no_vpn_support_image">Your image does not support the VPNService API,sorry :(</string> + <string name="encryption">Encryption</string> + <string name="cipher_dialog_title">Enter Encryption method</string> + <string name="chipher_dialog_message">Enter the cipher key for openvpn. Leave empty to use default cipher</string> + <string name="settings_auth">Authentication/Encryption</string> </resources> diff --git a/res/xml/vpn_authentification.xml b/res/xml/vpn_authentification.xml index bd8d8ca5..79d69697 100644 --- a/res/xml/vpn_authentification.xml +++ b/res/xml/vpn_authentification.xml @@ -28,14 +28,20 @@ android:title="@string/tls_auth_file" /> <ListPreference + android:dependency="useTLSAuth" android:entries="@array/tls_directions_entries" - android:dependency="useTLSAuth" - android:entryValues="@array/tls_directions_values" android:key="tls_direction" android:persistent="false" android:title="@string/tls_direction" /> </PreferenceCategory> -/> + <PreferenceCategory android:title="@string/encryption" > + <EditTextPreference + android:dialogMessage="@string/chipher_dialog_message" + android:dialogTitle="@string/cipher_dialog_title" + android:key="cipher" + android:persistent="false" + android:title="Encryption cipher" /> + </PreferenceCategory> </PreferenceScreen>
\ No newline at end of file diff --git a/res/xml/vpn_headers.xml b/res/xml/vpn_headers.xml index f755dc8c..60ddce7c 100644 --- a/res/xml/vpn_headers.xml +++ b/res/xml/vpn_headers.xml @@ -15,8 +15,7 @@ android:title="IP Settings" /> <header android:fragment="de.blinkt.openvpn.Settings_Authentication" - android:summary="Authentication" - android:title="Authentication" /> + android:title="@string/settings_auth" /> <!-- android:icon="@drawable/ic_settings_display" --> <header diff --git a/src/de/blinkt/openvpn/ConfigParser.java b/src/de/blinkt/openvpn/ConfigParser.java new file mode 100644 index 00000000..8497330f --- /dev/null +++ b/src/de/blinkt/openvpn/ConfigParser.java @@ -0,0 +1,232 @@ +package de.blinkt.openvpn; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.Vector; + +//! Openvpn Config FIle Parser, probably not 100% accurate but close enough + +// And rember, this is valid :) +// --<foo> +// bar +// </bar> +public class ConfigParser { + + + private HashMap<String,Vector<String>> options = new HashMap<String, Vector<String>>(); + private void parseConfig(String filename) throws IOException, ConfigParseError { + + + FileReader fr = new FileReader(filename); + BufferedReader br =new BufferedReader(fr); + + int lineno=0; + + while (true){ + String line = br.readLine(); + if(line==null) + break; + lineno++; + System.out.print("LINE:"); + System.out.println(line); + Vector<String> args = parseline(line); + if(args.size() ==0) + continue; + + + + if(args.get(0).startsWith("--")) + args.set(0, args.get(0).substring(2)); + + checkinlinefile(args,br); + + options.put(args.get(0), args); + } + } + + private void checkinlinefile(Vector<String> args, BufferedReader br) throws IOException, ConfigParseError { + String arg0 = args.get(0); + // CHeck for <foo> + if(arg0.startsWith("<") && arg0.endsWith(">")) { + String argname = arg0.substring(1, arg0.length()-1); + String inlinefile = ""; + + String endtag = String.format("</%s>",argname); + do { + String line = br.readLine(); + if(line==null){ + throw new ConfigParseError(String.format("No endtag </%s> for starttag <%s> found",argname,argname)); + } + if(line.equals(endtag)) + break; + else { + inlinefile+=line; + inlinefile+= "\n"; + } + } while(true); + + args.clear(); + args.add(argname); + args.add(inlinefile); + } + + } + + enum linestate { + initial, + readin_single_quote + , reading_quoted, reading_unquoted, done} + + private boolean space(char c) { + // I really hope nobody is using zero bytes inside his/her config file + // to sperate parameter but here we go: + return Character.isSpace(c) || c == '\0'; + + } + + public class ConfigParseError extends Exception { + private static final long serialVersionUID = -60L; + + public ConfigParseError(String msg) { + super(msg); + } + } + + + // adapted openvpn's parse function to java + private Vector<String> parseline(String line) throws ConfigParseError { + Vector<String> parameters = new Vector<String>(); + + if (line.length()==0) + return parameters; + + + linestate state = linestate.initial; + boolean backslash = false; + char out=0; + + int pos=0; + String currentarg=""; + + do { + // Emulate the c parsing ... + char in; + if(pos < line.length()) + in = line.charAt(pos); + else + in = '\0'; + + if (!backslash && in == '\\' && state != linestate.readin_single_quote) + { + backslash = true; + } + else + { + if (state == linestate.initial) + { + if (!space (in)) + { + if (in == ';' || in == '#') /* comment */ + break; + if (!backslash && in == '\"') + state = linestate.reading_quoted; + else if (!backslash && in == '\'') + state = linestate.readin_single_quote; + else + { + out = in; + state = linestate.reading_unquoted; + } + } + } + else if (state == linestate.reading_unquoted) + { + if (!backslash && space (in)) + state = linestate.done; + else + out = in; + } + else if (state == linestate.reading_quoted) + { + if (!backslash && in == '\"') + state = linestate.done; + else + out = in; + } + else if (state == linestate.readin_single_quote) + { + if (in == '\'') + state = linestate.done; + else + out = in; + } + + if (state == linestate.done) + { + /* ASSERT (parm_len > 0); */ + state = linestate.initial; + parameters.add(currentarg); + currentarg = ""; + out =0; + } + + if (backslash && out!=0) + { + if (!(out == '\\' || out == '\"' || space (out))) + { + throw new ConfigParseError("Options warning: Bad backslash ('\\') usage"); + } + } + backslash = false; + } + + /* store parameter character */ + if (out!=0) + { + currentarg+=out; + } + } while (pos++ < line.length()); + + return parameters; + } + + void convertProfile() throws ConfigParseError{ + VpnProfile newprofile = new VpnProfile("converted Profile"); + // Pull, client, tls-client + + if(options.containsKey("client") || options.containsKey("pull")) { + newprofile.mUsePull=true; + options.remove("pull"); + options.remove("client"); + } + + if(options.containsKey("secret")){ + newprofile.mAuthenticationType=VpnProfile.TYPE_STATICKEYS; + options.remove("secret"); + } + + if(options.containsKey("redirect-gateway")) { + options.remove("redirect-gateway"); + newprofile.mUseDefaultRoute=true; + } else { + newprofile.mUseDefaultRoute=true; + } + + Vector<String> mode = options.get("mode"); + if (mode != null){ + options.remove("mode"); + if(mode.size() != 2) + throw new ConfigParseError("--mode has more than one parameter"); + if(!mode.get(1).equals("p2p")) + throw new ConfigParseError("Invalid mode for --mode specified"); + } + + } + +} + + + + diff --git a/src/de/blinkt/openvpn/Settings_Authentication.java b/src/de/blinkt/openvpn/Settings_Authentication.java index 57d99417..6d21ca6a 100644 --- a/src/de/blinkt/openvpn/Settings_Authentication.java +++ b/src/de/blinkt/openvpn/Settings_Authentication.java @@ -24,6 +24,7 @@ public class Settings_Authentication extends PreferenceFragment implements OnPre private ListPreference mTLSAuthDirection; private Preference mTLSAuthFile; private SwitchPreference mUseTLSAuth; + private EditTextPreference mCipher; @Override public void onCreate(Bundle savedInstanceState) { @@ -45,6 +46,8 @@ public class Settings_Authentication extends PreferenceFragment implements OnPre mProfile = ProfileManager.get(profileUUID); mTLSAuthFile.setOnPreferenceClickListener(this); + mCipher =(EditTextPreference) findPreference("cipher"); + loadSettings(); } @@ -59,6 +62,8 @@ public class Settings_Authentication extends PreferenceFragment implements OnPre mUseTLSAuth.setChecked(mProfile.mUseTLSAuth); mTLSAuthFile.setSummary(mProfile.mTLSAuthFilename); mTLSAuthDirection.setValue(mProfile.mTLSAuthDirection); + mCipher.setText(mProfile.mCipher); + onPreferenceChange(mCipher, mProfile.mCipher); } private void saveSettings() { @@ -76,6 +81,12 @@ public class Settings_Authentication extends PreferenceFragment implements OnPre mProfile.mTLSAuthDirection=null; else mProfile.mTLSAuthDirection = mTLSAuthDirection.getValue().toString(); + + if(mCipher.getText()==null) + mProfile.mCipher=null; + else + mProfile.mCipher = mCipher.getText(); + } @Override @@ -91,6 +102,8 @@ public class Settings_Authentication extends PreferenceFragment implements OnPre preference.setSummary(mProfile.mServerName); else preference.setSummary((String)newValue); + } else if (preference == mCipher) { + preference.setSummary((CharSequence) newValue); } return true; } diff --git a/src/de/blinkt/openvpn/VpnProfile.java b/src/de/blinkt/openvpn/VpnProfile.java index 26cf50bd..1b855f5d 100644 --- a/src/de/blinkt/openvpn/VpnProfile.java +++ b/src/de/blinkt/openvpn/VpnProfile.java @@ -90,10 +90,13 @@ public class VpnProfile implements Serializable{ public boolean mUseCustomConfig=false; public String mCustomConfigOptions=""; public String mVerb="1"; + public String mCipher=""; - public static String openVpnEscape(String unescape) { - String escapedString = unescape.replace("\\", "\\\\"); + public static String openVpnEscape(String unescaped) { + if(unescaped==null) + return null; + String escapedString = unescaped.replace("\\", "\\\\"); escapedString = escapedString.replace("\"","\\\""); escapedString = escapedString.replace("\n","\\n"); return '"' + escapedString + '"'; @@ -269,6 +272,9 @@ public class VpnProfile implements Serializable{ cfg += "remote-cert-tls server\n"; + if(nonNull(mCipher)){ + cfg += "cipher " + mCipher + "\n"; + } // Obscure Settings dialog @@ -291,6 +297,13 @@ public class VpnProfile implements Serializable{ return cfg; } + private boolean nonNull(String val) { + if(val == null || val.equals("")) + return false; + else + return true; + } + private Collection<String> getCustomRoutes() { Vector<String> cidrRoutes=new Vector<String>(); if(mCustomRoutes==null) { @@ -343,8 +356,8 @@ public class VpnProfile implements Serializable{ Vector<String> args = new Vector<String>(); // Add fixed paramenters - //args.add(cacheDir.getAbsolutePath() +"/" +"openvpn"); - args.add(cacheDir.getAbsolutePath() +"/" +"minivpn"); + //args.add("/data/data/de.blinkt.openvpn/lib/openvpn"); + args.add(cacheDir.getAbsolutePath() +"/" +"openvpn"); args.add("--config"); args.add(cacheDir.getAbsolutePath() + "/" + OVPNCONFIGFILE); @@ -41,4 +41,5 @@ Requested by users: cipher auth mtu-link +nobind |