diff options
-rw-r--r-- | README.txt | 20 | ||||
-rw-r--r-- | proguard.cfg | 40 | ||||
-rw-r--r-- | res/values/strings.xml | 68 | ||||
-rw-r--r-- | res/xml/general_settings.xml | 10 | ||||
-rw-r--r-- | src/de/blinkt/openvpn/LaunchVPN.java | 60 | ||||
-rw-r--r-- | src/de/blinkt/openvpn/LogWindow.java | 7 | ||||
-rw-r--r-- | src/de/blinkt/openvpn/NetworkSateReceiver.java | 1 | ||||
-rw-r--r-- | src/de/blinkt/openvpn/OpenVPN.java | 16 | ||||
-rw-r--r-- | src/de/blinkt/openvpn/OpenVPNThread.java | 2 | ||||
-rw-r--r-- | src/de/blinkt/openvpn/OpenVpnManagementThread.java | 40 | ||||
-rw-r--r-- | src/de/blinkt/openvpn/OpenVpnService.java | 72 | ||||
-rw-r--r-- | todo.txt | 10 |
12 files changed, 202 insertions, 144 deletions
@@ -12,3 +12,23 @@ Do ndk-build in the root directory of the project. Use eclipse with android plugins to build the project. Optional: Copy minivpn from lib/ to assets (if you want your own compiled version) + + + + +Starting a VPN by name from an external app: + +public class StartOpenVPNActivity extends Activity { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + + final String EXTRA_NAME = "de.blinkt.openvpn.shortcutProfileName"; + + Intent shortcutIntent = new Intent(Intent.ACTION_MAIN); + shortcutIntent.setClassName("de.blinkt.openvpn", "de.blinkt.openvpn.LaunchVPN"); + shortcutIntent.putExtra(EXTRA_NAME,"upb ssl"); + startActivity(shortcutIntent); + } +}
\ No newline at end of file diff --git a/proguard.cfg b/proguard.cfg deleted file mode 100644 index b1cdf17..0000000 --- a/proguard.cfg +++ /dev/null @@ -1,40 +0,0 @@ --optimizationpasses 5 --dontusemixedcaseclassnames --dontskipnonpubliclibraryclasses --dontpreverify --verbose --optimizations !code/simplification/arithmetic,!field/*,!class/merging/* - --keep public class * extends android.app.Activity --keep public class * extends android.app.Application --keep public class * extends android.app.Service --keep public class * extends android.content.BroadcastReceiver --keep public class * extends android.content.ContentProvider --keep public class * extends android.app.backup.BackupAgentHelper --keep public class * extends android.preference.Preference --keep public class com.android.vending.licensing.ILicensingService - --keepclasseswithmembernames class * { - native <methods>; -} - --keepclasseswithmembers class * { - public <init>(android.content.Context, android.util.AttributeSet); -} - --keepclasseswithmembers class * { - public <init>(android.content.Context, android.util.AttributeSet, int); -} - --keepclassmembers class * extends android.app.Activity { - public void *(android.view.View); -} - --keepclassmembers enum * { - public static **[] values(); - public static ** valueOf(java.lang.String); -} - --keep class * implements android.os.Parcelable { - public static final android.os.Parcelable$Creator *; -} diff --git a/res/values/strings.xml b/res/values/strings.xml index f7c9817..2f827fe 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -24,6 +24,7 @@ <string name="defaultport" translatable="false">1194</string> <string name="location">Location</string> <string name="cant_read_folder">folder can\'t be read!</string> + <string name="select">Select</string> <string name="cancel">Cancel</string> <string name="no_data">No Data</string> <string name="useLZO">LZO Compression</string> @@ -32,6 +33,7 @@ <string name="client_key_title">Client Certificate Key</string> <string name="client_pkcs12_title">PKCS12 File</string> <string name="ca_title">CA Certificate</string> + <string name="select_certificate">Select</string> <string name="no_certificate">Nothing selected</string> <string name="opevpn_copyright" translatable="false">Copyright © 2002–2010 OpenVPN Technologies, Inc. <sales@openvpn.net>\n @@ -50,12 +52,11 @@ <string name="lzo" translatable="false">LZO</string> <string name="openssl" translatable="false">OpenSSL</string> <string name="about">About</string> - <string name="about_summary">About Openvpn for Android</string> + <string name="about_summary">About OpenVPN for Android</string> <string name="vpn_list_summary">List of all configured VPNs</string> <string name="vpn_list_title">All your precious VPNs</string> <string name="vpn_type">Type</string> <string name="pkcs12pwquery">PKCS12 Password</string> - <string name="select">Select…</string> <string name="file_select">Select…</string> <string name="file_nothing_selected">Nothing Selected</string> <string name="useTLSAuth">Use TLS Authentication</string> @@ -64,7 +65,7 @@ <string name="ipv4_dialog_title">Enter IPv4 Address/Netmask in CIDR Format (e.g. 1.2.3.4/24)</string> <string name="ipv4_address">IPv4 Address</string> <string name="ipv6_address">IPv6 Address</string> - <string name="custom_option_warning">Enter custom OpenVPN options. Use with great care. Also note that many of the tun related Openvpn settings cannot be supported by design of the VPNSettings. If you think an important option is missing contact the author</string> + <string name="custom_option_warning">Enter custom OpenVPN options. Use with great care. Also note that many of the tun related OpenVPN settings cannot be supported by design of the VPNSettings. If you think an important option is missing contact the author</string> <string name="auth_username">Username</string> <string name="auth_pwquery">Password</string> <string name="static_keys_info">For the static configuration the TLS Auth Keys will be used as static keys.</string> @@ -83,7 +84,7 @@ <string name="vpn_launch_title">Connect 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> + <string name="random_host_summary">Adds 6 random chars in front of hostname</string> <string name="custom_config_title">Enable Custom Options</string> <string name="custom_config_summary">Specify custom options. Use with care!</string> <string name="route_rejected">Route rejected by Android</string> @@ -94,9 +95,9 @@ <string name="remove_vpn">Remove VPN</string> <string name="check_remote_tlscert">Checks whether the server uses a TLS Server Certificate</string> <string name="check_remote_tlscert_title">Except TLS Server</string> - <string name="remote_tlscn_check_summary">Checks the Remote Server Certificate CN against a String</string> + <string name="remote_tlscn_check_summary">Checks the Remote Server Certificate CN against a string</string> <string name="remote_tlscn_check_title">Certificate Hostname Check</string> - <string name="enter_tlscn_dialog">Enter the string against which the remote Server is checked. Openvpn will use prefix matching. "Server" matches "Server-1" and "Server-2"\nLeave empty to check the CN against the server hostname.</string> + <string name="enter_tlscn_dialog">Enter the string against which the remote Server is checked. OpenVPN will use prefix matching. "Server" matches "Server-1" and "Server-2"\nLeave empty to check the CN against the server hostname.</string> <string name="enter_tlscn_title">Remote Hostname(CN)</string> <string name="tls_key_auth">Enables the TLS Key Authentication</string> <string name="tls_auth_file">TLS Auth File</string> @@ -123,56 +124,56 @@ <string name="custom_options_title">Custom Options</string> <string name="edit_vpn">Edit VPN Settings</string> <string name="remove_vpn_query">Remove the VPN Profile %s?</string> - <string name="tun_error_helpful">On some custom ICS images the permission on /dev/tun might be wrong, or the tun module might be missing completly. For CM9 images try the fix ownership option under general settings"</string> + <string name="tun_error_helpful">On some custom ICS images the permission on /dev/tun might be wrong, or the tun module might be missing completely. For CM9 images try the fix ownership option under general settings</string> <string name="tun_open_error">Opening tun interface failed badly.</string> <string name="error">"Error: "</string> <string name="clear">Clear</string> <string name="info">info</string> <string name="show_connection_details">Show connection details</string> - <string name="last_openvpn_tun_config">Last interface configuration from Openvpn:</string> + <string name="last_openvpn_tun_config">Last interface configuration from OpenVPN:</string> <string name="local_ip_info">Local IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d</string> <string name="dns_server_info">DNS Server: %s</string> <string name="dns_domain_info">DNS Domain: %s</string> <string name="routes_info">Routes: %s</string> - <string name="routes_info6">Routes Ipv6: %s</string> - <string name="ip_not_cidr">Got interface information %1$s and %2$s, assuming second address is peer address of remote. Using /32 netmask for local IP. Mode given by openvpn is \"%3$s\".</string> + <string name="routes_info6">Routes IPv6: %s</string> + <string name="ip_not_cidr">Got interface information %1$s and %2$s, assuming second address is peer address of remote. Using /32 netmask for local IP. Mode given by OpenVPN is \"%3$s\".</string> <string name="route_not_cidr">Cannot make sense of %1$s and %2$s as IP route with CIDR netmask, using /32 as netmask.</string> <string name="route_not_netip">Corrected route %1$s/%2$s to %3$s/%2$s</string> - <string name="keychain_access">Cannot accces the Android Keychain Certificates. If you restored a backup of the app/app settings reselect the certificate to recreate the permission to access the certificate.</string> + <string name="keychain_access">Cannot access the Android Keychain Certificates. If you restored a backup of the app/app settings re-select the certificate to recreate the permission to access the certificate.</string> <string name="version_info">%1$s %2$s</string> - <string name="send_logfile">Send Logfile</string> + <string name="send_logfile">Send log file</string> <string name="send">Send</string> - <string name="ics_openvpn_log_file">ICS Openvpn log file</string> + <string name="ics_openvpn_log_file">ICS OpenVPN log file</string> <string name="copied_entry">Copied log entry to clip board</string> <string name="tap_mode">Tap Mode</string> <string name="faq_tap_mode">Tap Mode is not possible with the non root VPN API. Therefore this application cannot provide tap support</string> - <string name="tap_faq2">Again? Are you kidding? No tap mode is really not supported and sending more mail aksing if it will be supported will not help.</string> + <string name="tap_faq2">Again? Are you kidding? No tap mode is really not supported and sending more mail asking if it will be supported will not help.</string> <string name="tap_faq3">A third time? Actually one could write a a tap emulator based on tun that would add layer2 information on send and strip layer2 information on receive. But this tap emulator would have to implement also ARP and possible a DHCP client. I am not aware of anybody doing any work in this direction. Contact me if you want to start coding on this.</string> <string name="faq">FAQ</string> - <string name="faq_summary">frequently asked questions and some adivce</string> + <string name="faq_summary">Frequently asked questions and some advice</string> <string name="copying_log_entries">Copying log entries</string> - <string name="faq_copying">To copy a single log entry press and and hold on the log entry. To copy/send the whole log use the Send Log option. Use the hardware menu button if not visible in the gui.</string> + <string name="faq_copying">To copy a single log entry press and and hold on the log entry. To copy/send the whole log use the Send Log option. Use the hardware menu button if not visible in the GUI.</string> <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="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> <string name="file_explorer_tab">File Explorer</string> <string name="inline_file_tab">Inline File</string> <string name="import_file">Import</string> <string name="error_importing_file">Error importing File</string> - <string name="import_error_message">Could not import File from Filesystem</string> + <string name="import_error_message">Could not import File from filesystem</string> <string name="inline_file_data">[[Inline file data]]</string> <string name="opentun_no_ipaddr">Refusing to open tun device without IP information</string> <string name="menu_import">Import Profile from ovpn file</string> <string name="menu_import_short">Import</string> <string name="import_content_resolve_error">Could not read Profile to import</string> - <string name="error_reading_config_file">Error reading Config file</string> + <string name="error_reading_config_file">Error reading config file</string> <string name="add_profile">add Profile</string> <string name="trying_to_read">Trying to read file: %1$s</string> - <string name="import_could_not_open">Could not find file %1$s mentioned in the imported Config file</string> + <string name="import_could_not_open">Could not find file %1$s mentioned in the imported config file</string> <string name="importing_config">Importing config file from source %1$s</string> <string name="import_pkcs12_to_keystore">Your config file specified a pkcs12 file. Please import the file by selecting select in the Basic Settings configuration of the converted VPN</string> <string name="import_warning_custom_options">Your configuration had a few configuration options that could be parsed. These options were added as custom configuration options. The custom configuration is displayed below:</string> @@ -182,17 +183,17 @@ <string name="import_experimental">Please not that the config importer is an experimental feature. If it does not work for you or you think that things could be done better please drop me a email.</string> <string name="import_configuration_file">Import configuration file</string> <string name="faq_security_title">Security considerations</string> - <string name="faq_security">"As openvpn is security sensitive a few notes about security are sensible. All data on the sdcard is inherently unsecure. Every app can read it (for example this program requires no special sd card rights). The data of this application can only be read by the application itself. By using the import option for cacert/cert/key in the file dialog the data is stored in the vpn profile. The vpn profiles are only accessable by this application. (Do not forget to delete the copies on the sd card afterwards). Even though accessible only by this application the data is stil unecrypted. By rooting the telephone or other exploits it may be possible to retrieve the data. Saved passwords are stored in plain text as well. For pkcs12 files it is highly recommended that you import them into the android keystore."</string> + <string name="faq_security">"As OpenVPN is security sensitive a few notes about security are sensible. All data on the sdcard is inherently insecure. Every app can read it (for example this program requires no special sd card rights). The data of this application can only be read by the application itself. By using the import option for cacert/cert/key in the file dialog the data is stored in the VPN profile. The VPN profiles are only accessible by this application. (Do not forget to delete the copies on the sd card afterwards). Even though accessible only by this application the data is still unencrypted. By rooting the telephone or other exploits it may be possible to retrieve the data. Saved passwords are stored in plain text as well. For pkcs12 files it is highly recommended that you import them into the android keystore."</string> <string name="import_vpn">Import</string> <string name="broken_image_cert_title">Error showing certificate selection</string> - <string name="broken_image_cert">Got an excption trying to show the Android 4.0+ certificate selction dialog. This should never happens as this a standard feature of Android 4.0+. Maybe your Android ROM support for certificate storage is broken</string> + <string name="broken_image_cert">Got an exception trying to show the Android 4.0+ certificate selection dialog. This should never happen as this a standard feature of Android 4.0+. Maybe your Android ROM support for certificate storage is broken</string> <string name="ipv4">IPv4</string> <string name="ipv6">IPv6</string> <string name="speed_waiting">Waiting for state message…</string> <string name="converted_profile">imported profile</string> <string name="converted_profile_i">imported profile %d</string> <string name="broken_images">Broken Images</string> - <string name="broken_images_faq"><p>Offical HTC images are known to have a strange routing problem causing traffic not to flow through the tunnel (See also <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=18\">Issue 18</a> in the bug tracker.)</p><p>The offical SONY images from Xperia arc S and Xperia Ray have been reported to be missing the VPNService completly from the image. Other Sony images may be affected as well. (See also <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=29\">Issue 29</a> in the bug tracker.)</p><p>On custom build images the tun module might be missing or the rights of /dev/tun might be wrong. Some CM9 images need the fix ownership option under general settings.</p><p>Most important: If you have a broken image, report it to your vendor. The more people report the issue to the vendor the more likely you will get a fix.</p></string> + <string name="broken_images_faq"><p>Official HTC images are known to have a strange routing problem causing traffic not to flow through the tunnel (See also <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=18\">Issue 18</a> in the bug tracker.)</p><p>The official SONY images from Xperia arc S and Xperia Ray have been reported to be missing the VPNService completely from the image. Other Sony images may be affected as well. (See also <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=29\">Issue 29</a> in the bug tracker.)</p><p>On custom build images the tun module might be missing or the rights of /dev/tun might be wrong. Some CM9 images need the fix ownership option under general settings.</p><p>Most important: If you have a broken image, report it to your vendor. The more people report the issue to the vendor the more likely you will get a fix.</p></string> <string name="error_empty_username">The username must not be empty.</string> <string name="pkcs12_file_encryption_key">PKCS12 File Encryption Key</string> <string name="private_key_password">Private Key Password</string> @@ -203,15 +204,20 @@ <string name="generalsettings">General Settings</string> <string name="owner_fix_summary">Tries to set the owner of /dev/tun to system. Some CM9 images need this to make the VPNService API work. Requires root.</string> <string name="owner_fix">Fix ownership of /dev/tun</string> - <string name="generated_config_summary">Shows the generated openvpn Configuration File</string> + <string name="generated_config_summary">Shows the generated OpenVPN Configuration File</string> <string name="edit_profile_title">Editing \"%s\"</string> - <string name="building_configration">Building configration…</string> - <string name="netchange_summary">Turning this option on will force a reconnet if the network state is change (WIFI to/from mobile)</string> - <string name="netchange">Reconnect on Network change</string> + <string name="building_configration">Building configuration…</string> + <string name="netchange_summary">Turning this option on will force a reconnect if the network state is change (WIFI to/from mobile)</string> + <string name="netchange">Reconnect on network change</string> <string name="cert_from_keystore">Got certificate \'%s\' from Keystore</string> <string name="netstatus">Network Status: %s</string> - <string name="extracahint">The CA cert is usually returned from the Android Keystore. Specify a seperate certificate if you get certificate verification errors.</string> + <string name="extracahint">The CA cert is usually returned from the Android Keystore. Specify a separate certificate if you get certificate verification errors.</string> <string name="select_file">Select</string> - <string name="keychain_nocacert">No CA Certificate returned while reading from Android keystore. Auhtentication will probably fail.</string> - + + <string name="keychain_nocacert">No CA Certificate returned while reading from Android keystore. Auhtentication will probably fail.</string> + <string name="show_log_summary">Shows the log window on connect. The log window can always be accessed from the notification status.</string> + <string name="show_log_window">Show log window</string> + <string name="keppstatus_summary">Keep the notification displayed after the connection is established to show traffic statistics.</string> + <string name="keepstatus">Show Traffic Statistics</string> </resources> + diff --git a/res/xml/general_settings.xml b/res/xml/general_settings.xml index 74c8965..2da80cc 100644 --- a/res/xml/general_settings.xml +++ b/res/xml/general_settings.xml @@ -11,5 +11,15 @@ android:key="useCM9Fix" android:summary="@string/owner_fix_summary" android:title="@string/owner_fix" /> + <CheckBoxPreference + android:defaultValue="false" + android:key="showlogwindow" + android:summary="@string/show_log_summary" + android:title="@string/show_log_window" /> + <CheckBoxPreference + android:defaultValue="false" + android:key="statusafterconnect" + android:summary="@string/keppstatus_summary" + android:title="@string/keepstatus" /> </PreferenceScreen>
\ No newline at end of file diff --git a/src/de/blinkt/openvpn/LaunchVPN.java b/src/de/blinkt/openvpn/LaunchVPN.java index e76057d..1c873f2 100644 --- a/src/de/blinkt/openvpn/LaunchVPN.java +++ b/src/de/blinkt/openvpn/LaunchVPN.java @@ -44,7 +44,6 @@ import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.ListView; import android.widget.TextView; -import android.widget.Toast; /** * This Activity actually handles two stages of a launcher shortcut's life cycle. @@ -80,11 +79,11 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener { private ProfileManager mPM; private VpnProfile mSelectedProfile; - - + + private boolean mCmfixed=false; static boolean minivpnwritten=false; - + @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); @@ -92,7 +91,7 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener { mPM =ProfileManager.getInstance(this); } - + @Override protected void onStart() { super.onStart(); @@ -100,6 +99,7 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener { final Intent intent = getIntent(); final String action = intent.getAction(); + // If the intent is a request to create a shortcut, we'll do that and exit if(Intent.ACTION_MAIN.equals(action)) { @@ -110,10 +110,11 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener { VpnProfile profileToConnect = ProfileManager.get(shortcutUUID); if(shortcutName != null && profileToConnect ==null) profileToConnect = ProfileManager.getInstance(this).getProfileByName(shortcutName); - + if(profileToConnect ==null) { - Toast notfound = Toast.makeText(this, R.string.shortcut_profile_notfound, Toast.LENGTH_SHORT); - notfound.show(); + OpenVPN.logError(R.string.shortcut_profile_notfound); + // show Log window to display error + showLogWindow(); finish(); return; } @@ -221,31 +222,31 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener { // } } - + private boolean writeMiniVPN() { File mvpnout = new File(getCacheDir(),"minivpn"); if (mvpnout.exists() && mvpnout.canExecute()) return true; - + if(minivpnwritten) return true; try { InputStream mvpn = getAssets().open("minivpn"); - + FileOutputStream fout = new FileOutputStream(mvpnout); - + byte buf[]= new byte[4096]; - + int lenread = mvpn.read(buf); while(lenread> 0) { fout.write(buf, 0, lenread); lenread = mvpn.read(buf); } fout.close(); - + if(!mvpnout.setExecutable(true)) return false; - + minivpnwritten=true; return true; } catch (IOException e) { @@ -303,26 +304,36 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener { if(needpw !=0) { askForPW(needpw); } else { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + boolean showlogwindow = prefs.getBoolean("showlogwindow", false); + if(showlogwindow) + showLogWindow(); new startOpenVpnThread().start(); } - } else if (resultCode == Activity.RESULT_CANCELED) { // User does not want us to start, so we just vanish finish(); } } } + void showLogWindow() { + + Intent startLW = new Intent(getBaseContext(),LogWindow.class); + startLW.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); + startActivity(startLW); + + } void showConfigErrorDialog(int vpnok) { AlertDialog.Builder d = new AlertDialog.Builder(this); d.setTitle(R.string.config_error_found); d.setMessage(vpnok); d.setPositiveButton(android.R.string.ok, new OnClickListener() { - + @Override public void onClick(DialogInterface dialog, int which) { finish(); - + } }); d.show(); @@ -339,7 +350,7 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener { // Check if we want to fix /dev/tun SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); boolean usecm9fix = prefs.getBoolean("useCM9Fix", false); - + if(usecm9fix && !mCmfixed ) { ProcessBuilder pb = new ProcessBuilder(new String[] {"su","-c","chown system /dev/tun"}); try { @@ -353,8 +364,8 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener { e.printStackTrace(); } } - - + + if (intent != null) { // Start the query @@ -363,7 +374,8 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener { } catch (ActivityNotFoundException ane) { // Shame on you Sony! At least one user reported that // an official Sony Xperia Arc S image triggers this exception - Toast.makeText(this, R.string.no_vpn_support_image, Toast.LENGTH_LONG).show(); + OpenVPN.logError(R.string.no_vpn_support_image); + showLogWindow(); } } else { onActivityResult(START_VPN_PROFILE, Activity.RESULT_OK, null); @@ -379,10 +391,6 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener { } void startOpenVpn() { - Intent startLW = new Intent(getBaseContext(),LogWindow.class); - startLW.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); - startActivity(startLW); - if(!writeMiniVPN()) { OpenVPN.logMessage(0, "", "Error writing minivpn binary"); return; diff --git a/src/de/blinkt/openvpn/LogWindow.java b/src/de/blinkt/openvpn/LogWindow.java index 6060e7a..ae5277c 100644 --- a/src/de/blinkt/openvpn/LogWindow.java +++ b/src/de/blinkt/openvpn/LogWindow.java @@ -271,12 +271,15 @@ public class LogWindow extends ListActivity implements StateListener { } @Override - public void updateState(final String logmessage) { + public void updateState(final String status,final String logmessage) { runOnUiThread(new Runnable() { @Override public void run() { - mSpeedView.setText(logmessage); + String prefix=status+ ":"; + if (status.equals("BYTECOUNT") || status.equals("NOPROCESS") ) + prefix=""; + mSpeedView.setText(prefix + logmessage); } }); diff --git a/src/de/blinkt/openvpn/NetworkSateReceiver.java b/src/de/blinkt/openvpn/NetworkSateReceiver.java index a8d6989..0758cf3 100644 --- a/src/de/blinkt/openvpn/NetworkSateReceiver.java +++ b/src/de/blinkt/openvpn/NetworkSateReceiver.java @@ -26,7 +26,6 @@ public class NetworkSateReceiver extends BroadcastReceiver { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean sendusr1 = prefs.getBoolean("netchangereconnect", true);
-
String netstatestring;
if(networkInfo==null)
netstatestring = "not connected";
diff --git a/src/de/blinkt/openvpn/OpenVPN.java b/src/de/blinkt/openvpn/OpenVPN.java index b09eb60..c23ee56 100644 --- a/src/de/blinkt/openvpn/OpenVPN.java +++ b/src/de/blinkt/openvpn/OpenVPN.java @@ -41,6 +41,12 @@ public class OpenVPN { } + public LogItem(int loglevel, int ressourceId) { + mRessourceId =ressourceId; + mLevel = loglevel; + } + + String getString(Context c) { if(mMessage !=null) { return mMessage; @@ -73,7 +79,7 @@ public class OpenVPN { } public interface StateListener { - void updateState(String logmessage); + void updateState(String state, String logmessage); } synchronized static void logMessage(int level,String prefix, String message) @@ -126,9 +132,9 @@ public class OpenVPN { } - public static void updateStateString(String msg) { + public static void updateStateString(String state, String msg) { for (StateListener sl : stateListener) { - sl.updateState(msg); + sl.updateState(state,msg); } } @@ -155,6 +161,10 @@ public class OpenVPN { } + public static void logError(int ressourceId) { + newlogItem(new LogItem(LogItem.ERROR, ressourceId)); + } + } diff --git a/src/de/blinkt/openvpn/OpenVPNThread.java b/src/de/blinkt/openvpn/OpenVPNThread.java index fdb0ac0..22a0876 100644 --- a/src/de/blinkt/openvpn/OpenVPNThread.java +++ b/src/de/blinkt/openvpn/OpenVPNThread.java @@ -41,7 +41,7 @@ public class OpenVPNThread implements Runnable { //mInterface = null;
- OpenVPN.updateStateString("No process running");
+ OpenVPN.updateStateString("NOPROCESS","No process running");
// Not a good place to do it, but will do
OpenVPN.logBuilderConfig(null);
Log.i(TAG, "Exiting");
diff --git a/src/de/blinkt/openvpn/OpenVpnManagementThread.java b/src/de/blinkt/openvpn/OpenVpnManagementThread.java index 012e092..f23d9d9 100644 --- a/src/de/blinkt/openvpn/OpenVpnManagementThread.java +++ b/src/de/blinkt/openvpn/OpenVpnManagementThread.java @@ -21,7 +21,8 @@ public class OpenVpnManagementThread implements Runnable { private LinkedList<FileDescriptor> mFDList=new LinkedList<FileDescriptor>();
private int mBytecountinterval=2;
private long mLastIn=0;
- private long mLastOut=0;
+ private long mLastOut=0;
+ private String mCurrentstate;
private static Vector<OpenVpnManagementThread> active=new Vector<OpenVpnManagementThread>();
@@ -185,8 +186,9 @@ public class OpenVpnManagementThread implements Runnable { }
private void processState(String argument) {
- String[] args = argument.split(",",2);
- OpenVPN.updateStateString(args[1]);
+ String[] args = argument.split(",",3);
+ mCurrentstate = args[1];
+ OpenVPN.updateStateString(mCurrentstate,args[2]);
}
@@ -195,32 +197,32 @@ public class OpenVpnManagementThread implements Runnable { int comma = argument.indexOf(',');
long in = Long.parseLong(argument.substring(0, comma));
long out = Long.parseLong(argument.substring(comma+1));
-
+
long diffin = in - mLastIn;
long diffout = out - mLastOut;
-
+
mLastIn=in;
mLastOut=out;
-
- String netstat = String.format("In: %8s, %8s/s Out %8s, %8s/s ",
+
+ String netstat = String.format("In: %8s, %8s/s Out %8s, %8s/s",
humanReadableByteCount(in, false),
humanReadableByteCount(diffin, false),
humanReadableByteCount(out, false),
humanReadableByteCount(diffout, false));
- OpenVPN.updateStateString(netstat);
-
-
+ OpenVPN.updateStateString("BYTECOUNT",netstat);
+
+
}
// From: http://stackoverflow.com/questions/3758606/how-to-convert-byte-size-into-human-readable-format-in-java
public static String humanReadableByteCount(long bytes, boolean si) {
- int unit = si ? 1000 : 1024;
- if (bytes < unit) return bytes + " B";
- int exp = (int) (Math.log(bytes) / Math.log(unit));
- String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp-1) + (si ? "" : "i");
- return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
+ int unit = si ? 1000 : 1024;
+ if (bytes < unit) return bytes + " B";
+ int exp = (int) (Math.log(bytes) / Math.log(unit));
+ String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp-1) + (si ? "" : "i");
+ return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
}
-
+
private void processNeedCommand(String argument) {
int p1 =argument.indexOf('\'');
int p2 = argument.indexOf('\'',p1+1);
@@ -328,10 +330,10 @@ public class OpenVpnManagementThread implements Runnable { private void processPWCommand(String argument) {
//argument has the form Need 'Private Key' password
-
+
String needed;
try{
-
+
int p1 = argument.indexOf('\'');
int p2 = argument.indexOf('\'',p1+1);
needed = argument.substring(p1+1, p2);
@@ -384,7 +386,7 @@ public class OpenVpnManagementThread implements Runnable { public void reconnect() {
managmentCommand("signal SIGUSR1\n");
-
+
}
}
diff --git a/src/de/blinkt/openvpn/OpenVpnService.java b/src/de/blinkt/openvpn/OpenVpnService.java index 8c17211..fd0b4f2 100644 --- a/src/de/blinkt/openvpn/OpenVpnService.java +++ b/src/de/blinkt/openvpn/OpenVpnService.java @@ -19,19 +19,24 @@ package de.blinkt.openvpn; import java.io.IOException; import java.util.Vector; +import de.blinkt.openvpn.OpenVPN.StateListener; + import android.app.Notification; +import android.app.Notification.Builder; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.SharedPreferences; import android.net.ConnectivityManager; import android.net.LocalSocket; import android.net.LocalSocketAddress; import android.net.VpnService; import android.os.ParcelFileDescriptor; +import android.preference.PreferenceManager; -public class OpenVpnService extends VpnService { +public class OpenVpnService extends VpnService implements StateListener { private Thread mServiceThread; private Vector<String> mDnslist=new Vector<String>(); @@ -54,7 +59,9 @@ public class OpenVpnService extends VpnService { private NetworkSateReceiver mNetworkStateReceiver; - private static final int HELLO_ID = 1; + private boolean mDisplayBytecount=false; + + private static final int OPENVPN_STATUS = 1; @Override public void onRevoke() { @@ -63,24 +70,39 @@ public class OpenVpnService extends VpnService { stopSelf(); }; - private void showNotification() { + private void hideNotification() { + String ns = Context.NOTIFICATION_SERVICE; + NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns); + mNotificationManager.cancel(OPENVPN_STATUS); + + } + private void showNotification(String msg, String tickerText) { String ns = Context.NOTIFICATION_SERVICE; NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns); int icon = R.drawable.icon; - CharSequence tickerText = "Hello"; long when = System.currentTimeMillis(); + + android.app.Notification.Builder nbuilder = new Notification.Builder(this); + + nbuilder.setContentTitle("OpenVPN - " + mProfile.mName); + nbuilder.setContentText(msg); + nbuilder.setOnlyAlertOnce(true); + nbuilder.setOngoing(true); + nbuilder.setContentIntent(getLogPendingIntent()); + nbuilder.setSmallIcon(icon); + nbuilder.setWhen(when); + + if(tickerText!=null) + nbuilder.setTicker(tickerText); - mNotification = new Notification(icon, tickerText, when); + mNotification = nbuilder.getNotification(); - Context context = getApplicationContext(); - CharSequence contentTitle = "My notification"; - CharSequence contentText = "Hello World!"; - mNotification.setLatestEventInfo(context, contentTitle, contentText, getLogPendingIntent()); + - mNotificationManager.notify(HELLO_ID, mNotification); + mNotificationManager.notify(OPENVPN_STATUS, mNotification); } @@ -135,7 +157,7 @@ public class OpenVpnService extends VpnService { String profileUUID = intent.getStringExtra(prefix + ".profileUUID"); mProfile = ProfileManager.get(profileUUID); - //showNotification(); + OpenVPN.addSpeedListener(this); // Stop the previous session by interrupting the thread. if(OpenVpnManagementThread.stopOpenVPN()){ @@ -357,4 +379,32 @@ public class OpenVpnService extends VpnService { mLocalIPv6 = ipv6addr; } + @Override + public void updateState(String state,String logmessage) { + if("NOPROCESS".equals(state)) { + hideNotification(); + mDisplayBytecount=false; + return; + } + + if("CONNECTED".equals(state)) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + mDisplayBytecount = prefs.getBoolean("statusafterconnect", false); + if(!mDisplayBytecount) { + hideNotification(); + return; + } + } + + if("BYTECOUNT".equals(state)) { + if(mDisplayBytecount) { + showNotification(logmessage,null); + } + } else { + // Other notifications are shown + String ticker = state.toLowerCase(); + showNotification(state +" " + logmessage,ticker); + } + } + } @@ -9,16 +9,10 @@ Ideas: - implement general settings dialog - encryption of profiles - Speed/Transfered in notification bar (byte counter of management) - - Kick openvpn on network state change (Wifi <-> GPRS/EDGE/UMTS) - - rework logging system (first step: rename OpenVPN class to samething sensible) - - map SIGUSR1 to SIGINT - add a put this certificate into file obscure option -- adding a profile should bring up editing the profile instantly - - Bugfixes: - startpath file explorer @@ -38,7 +32,3 @@ Tap support: - implement arp, possible the most difficult task ... - need to chose right mac of receiver -Requested by users: -auth -mtu-link - |