diff options
| -rw-r--r-- | .hgignore | 2 | ||||
| -rw-r--r-- | main/build.gradle | 16 | ||||
| -rw-r--r-- | main/jni/Android.mk | 2 | ||||
| -rwxr-xr-x | main/misc/prepareovpn3.sh | 3 | ||||
| -rw-r--r-- | main/ovpn3/Android.mk | 40 | ||||
| -rw-r--r-- | main/ovpn3/boostsrc/error_code.cpp | 430 | ||||
| -rw-r--r-- | main/src/main/java/de/blinkt/openvpn/VpnProfile.java | 12 | ||||
| -rw-r--r-- | main/src/main/java/de/blinkt/openvpn/core/OpenVpnService.java | 29 | ||||
| -rw-r--r-- | main/src/main/java/de/blinkt/openvpn/fragments/GeneralSettings.java | 8 | ||||
| -rw-r--r-- | main/src/main/res/xml/general_settings.xml | 10 | ||||
| -rw-r--r-- | main/src/ovpn3/java/de/blinkt/openvpn/core/OpenVPNThreadv3.java | 277 | 
11 files changed, 817 insertions, 12 deletions
| @@ -74,3 +74,5 @@ cache.properties  .idea  *.iml +main/openvpn3 +main/boost_1_55_0
\ No newline at end of file diff --git a/main/build.gradle b/main/build.gradle index 5e15006e..bb40442a 100644 --- a/main/build.gradle +++ b/main/build.gradle @@ -34,6 +34,10 @@ android {              jniLibs.srcDirs = ['ovpnlibs/jniLibs']              jni.srcDirs = [] //disable automatic ndk-build          } +         +        ovpn3 { +          +        }      }      /* @@ -57,9 +61,14 @@ android {          }      } -    /* +      productFlavors { -        x86 { +      ovpn3 + +      normal +                         +      /*                    +      x86 {              versionCode Integer.parseInt("6" + defaultConfig.versionCode)              ndk {                  abiFilter "x86" @@ -88,8 +97,9 @@ android {          }          fat +        */      } -    */ +  } diff --git a/main/jni/Android.mk b/main/jni/Android.mk index 3ea9f5d4..66f2b737 100644 --- a/main/jni/Android.mk +++ b/main/jni/Android.mk @@ -26,7 +26,7 @@ ifeq ($(USE_POLAR),1)  endif  include openvpn/Android.mk - +include ovpn3/Android.mk  LOCAL_PATH := $(JNI_DIR) diff --git a/main/misc/prepareovpn3.sh b/main/misc/prepareovpn3.sh new file mode 100755 index 00000000..15982727 --- /dev/null +++ b/main/misc/prepareovpn3.sh @@ -0,0 +1,3 @@ +export O3=$PWD/openvpn3 +mkdir -p src/ovpn3/java/net/openvpn/ovpn3 +swig -outdir src/ovpn3/java/net/openvpn/ovpn3/ -c++ -java -package net.openvpn.ovpn3 -I$O3/client -I$O3 $O3/javacli/ovpncli.i
\ No newline at end of file diff --git a/main/ovpn3/Android.mk b/main/ovpn3/Android.mk new file mode 100644 index 00000000..7f037ac0 --- /dev/null +++ b/main/ovpn3/Android.mk @@ -0,0 +1,40 @@ +LOCAL_PATH:= $(call my-dir)/ + +include $(CLEAR_VARS) + +LOCAL_LDLIBS := -lz  +LOCAL_C_INCLUDES := openssl/include lzo/include openssl/crypto openssl openvpn/src/compat openvpn3/client openvpn3 boost_1_55_0 polarssl/include  snappy +LOCAL_CPP_FEATURES += exceptions rtti + +#LOCAL_SHARED_LIBRARIES :=  libssl libcrypto  +LOCAL_SHARED_LIBRARIES := polarssl-dynamic +#LOCAL_STATIC_LIBRARIES :=  libssl_static libcrypto_static  liblzo-static +LOCAL_STATIC_LIBRARIES :=  liblzo-static snappy-static + +#LOCAL_CFLAGS= -DHAVE_CONFIG_H -DTARGET_ABI=\"${TARGET_ABI}\" -DUSE_OPENSSL -DOPENSSL_NO_ENGINE +LOCAL_CFLAGS= -DHAVE_CONFIG_H -DTARGET_ABI=\"${TARGET_ABI}\" -DUSE_POLARSSL -DHAVE_SNAPPY -DHAVE_LZO + +#ifneq ($(TARGET_ARCH),mips) +#LOCAL_STATIC_LIBRARIES += breakpad_client +#LOCAL_CFLAGS += -DGOOGLE_BREAKPAD=1 +#endif + +LOCAL_MODULE = ovpn3 + +LOCAL_SRC_FILES:= \ +	../openvpn3/javacli/ovpncli_wrap.cxx \ +	boostsrc/error_code.cpp \ +	../openvpn3/client/ovpncli.cpp \ + + +#ifneq ($(TARGET_ARCH),mips) +#LOCAL_SRC_FILES+=src/openvpn/breakpad.cpp +#endif + + + +include $(BUILD_SHARED_LIBRARY) +#include $(BUILD_EXECUTABLE) + + + diff --git a/main/ovpn3/boostsrc/error_code.cpp b/main/ovpn3/boostsrc/error_code.cpp new file mode 100644 index 00000000..6772d154 --- /dev/null +++ b/main/ovpn3/boostsrc/error_code.cpp @@ -0,0 +1,430 @@ +//  error_code support implementation file  ----------------------------------// + +//  Copyright Beman Dawes 2002, 2006 + +//  Distributed under the Boost Software License, Version 1.0. (See accompanying +//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +//  See library home page at http://www.boost.org/libs/system + +//----------------------------------------------------------------------------// + +#include <boost/config/warning_disable.hpp> + +// define BOOST_SYSTEM_SOURCE so that <boost/system/config.hpp> knows +// the library is being built (possibly exporting rather than importing code) +#define BOOST_SYSTEM_SOURCE  + +#include <boost/system/config.hpp> +#include <boost/system/error_code.hpp> +#include <boost/cerrno.hpp> +#include <vector> +#include <cstdlib> +#include <cassert> + +using namespace boost::system; +using namespace boost::system::errc; + +#include <cstring> // for strerror/strerror_r + +# if defined( BOOST_WINDOWS_API ) +#   include <windows.h> +#   include "local_free_on_destruction.hpp" +#   ifndef ERROR_INCORRECT_SIZE +#     define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS +#   endif +# endif + +//----------------------------------------------------------------------------// + +namespace +{ +#if defined(__PGI) +  using boost::system::errc::invalid_argument; +#endif +  //  standard error categories  ---------------------------------------------// + +  class generic_error_category : public error_category +  { +  public: +    generic_error_category(){} +    const char *   name() const; +    std::string    message( int ev ) const; +  }; + +  class system_error_category : public error_category +  { +  public: +    system_error_category(){} +    const char *        name() const; +    std::string         message( int ev ) const; +    error_condition     default_error_condition( int ev ) const; +  }; + +  //  generic_error_category implementation  ---------------------------------// + +  const char * generic_error_category::name() const +  { +    return "generic"; +  } + +  std::string generic_error_category::message( int ev ) const +  { +    static std::string unknown_err( "Unknown error" ); +  // strerror_r is preferred because it is always thread safe, +  // however, we fallback to strerror in certain cases because: +  //   -- Windows doesn't provide strerror_r. +  //   -- HP and Sun do provide strerror_r on newer systems, but there is +  //      no way to tell if is available at runtime and in any case their +  //      versions of strerror are thread safe anyhow. +  //   -- Linux only sometimes provides strerror_r. +  //   -- Tru64 provides strerror_r only when compiled -pthread. +  //   -- VMS doesn't provide strerror_r, but on this platform, strerror is +  //      thread safe. +  # if defined(BOOST_WINDOWS_API) || defined(__hpux) || defined(__sun)\ +     || (defined(__linux) && (!defined(__USE_XOPEN2K) || defined(BOOST_SYSTEM_USE_STRERROR)))\ +     || (defined(__osf__) && !defined(_REENTRANT))\ +     || (defined(__INTEGRITY))\ +     || (defined(__vms))\ +     || (defined(__QNXNTO__)) +      const char * c_str = std::strerror( ev ); +      return  c_str +        ? std::string( c_str ) +        : unknown_err; +  # else  // use strerror_r +      char buf[64]; +      char * bp = buf; +      std::size_t sz = sizeof(buf); +  #  if defined(__CYGWIN__) || defined(__USE_GNU) +      // Oddball version of strerror_r +      const char * c_str = strerror_r( ev, bp, sz ); +      return  c_str +        ? std::string( c_str ) +        : unknown_err; +  #  else +      // POSIX version of strerror_r +      int result; +      for (;;) +      { +        // strerror_r returns 0 on success, otherwise ERANGE if buffer too small, +        // invalid_argument if ev not a valid error number +  #  if defined (__sgi) +        const char * c_str = strerror( ev ); +        result = 0; +      return  c_str +        ? std::string( c_str ) +        : unknown_err; +  #  else +        result = strerror_r( ev, bp, sz ); +  #  endif +        if (result == 0 ) +          break; +        else +        { +  #  if defined(__linux) +          // Linux strerror_r returns -1 on error, with error number in errno +          result = errno; +  #  endif +          if ( result !=  ERANGE ) break; +          if ( sz > sizeof(buf) ) std::free( bp ); +          sz *= 2; +          if ( (bp = static_cast<char*>(std::malloc( sz ))) == 0 ) +            return std::string( "ENOMEM" ); +        } +      } +      std::string msg; +      try +      { +        msg = ( ( result == invalid_argument ) ? "Unknown error" : bp ); +      } + +#   ifndef BOOST_NO_EXCEPTIONS +      // See ticket #2098 +      catch(...) +      { +        // just eat the exception +      } +#   endif + +      if ( sz > sizeof(buf) ) std::free( bp ); +      sz = 0; +      return msg; +  #  endif   // else POSIX version of strerror_r +  # endif  // else use strerror_r +  } +  //  system_error_category implementation  --------------------------------//  + +  const char * system_error_category::name() const +  { +    return "system"; +  } + +  error_condition system_error_category::default_error_condition( int ev ) const +  { +    switch ( ev ) +    { +    case 0: return make_error_condition( success ); +# if defined(BOOST_POSIX_API) +    // POSIX-like O/S -> posix_errno decode table  ---------------------------// +    case E2BIG: return make_error_condition( argument_list_too_long ); +    case EACCES: return make_error_condition( permission_denied ); +    case EADDRINUSE: return make_error_condition( address_in_use ); +    case EADDRNOTAVAIL: return make_error_condition( address_not_available ); +    case EAFNOSUPPORT: return make_error_condition( address_family_not_supported ); +    case EAGAIN: return make_error_condition( resource_unavailable_try_again ); +#   if EALREADY != EBUSY  //  EALREADY and EBUSY are the same on QNX Neutrino +    case EALREADY: return make_error_condition( connection_already_in_progress ); +#   endif +    case EBADF: return make_error_condition( bad_file_descriptor ); +    case EBADMSG: return make_error_condition( bad_message ); +    case EBUSY: return make_error_condition( device_or_resource_busy ); +    case ECANCELED: return make_error_condition( operation_canceled ); +    case ECHILD: return make_error_condition( no_child_process ); +    case ECONNABORTED: return make_error_condition( connection_aborted ); +    case ECONNREFUSED: return make_error_condition( connection_refused ); +    case ECONNRESET: return make_error_condition( connection_reset ); +    case EDEADLK: return make_error_condition( resource_deadlock_would_occur ); +    case EDESTADDRREQ: return make_error_condition( destination_address_required ); +    case EDOM: return make_error_condition( argument_out_of_domain ); +    case EEXIST: return make_error_condition( file_exists ); +    case EFAULT: return make_error_condition( bad_address ); +    case EFBIG: return make_error_condition( file_too_large ); +    case EHOSTUNREACH: return make_error_condition( host_unreachable ); +    case EIDRM: return make_error_condition( identifier_removed ); +    case EILSEQ: return make_error_condition( illegal_byte_sequence ); +    case EINPROGRESS: return make_error_condition( operation_in_progress ); +    case EINTR: return make_error_condition( interrupted ); +    case EINVAL: return make_error_condition( invalid_argument ); +    case EIO: return make_error_condition( io_error ); +    case EISCONN: return make_error_condition( already_connected ); +    case EISDIR: return make_error_condition( is_a_directory ); +    case ELOOP: return make_error_condition( too_many_symbolic_link_levels ); +    case EMFILE: return make_error_condition( too_many_files_open ); +    case EMLINK: return make_error_condition( too_many_links ); +    case EMSGSIZE: return make_error_condition( message_size ); +    case ENAMETOOLONG: return make_error_condition( filename_too_long ); +    case ENETDOWN: return make_error_condition( network_down ); +    case ENETRESET: return make_error_condition( network_reset ); +    case ENETUNREACH: return make_error_condition( network_unreachable ); +    case ENFILE: return make_error_condition( too_many_files_open_in_system ); +    case ENOBUFS: return make_error_condition( no_buffer_space ); +    case ENODATA: return make_error_condition( no_message_available ); +    case ENODEV: return make_error_condition( no_such_device ); +    case ENOENT: return make_error_condition( no_such_file_or_directory ); +    case ENOEXEC: return make_error_condition( executable_format_error ); +    case ENOLCK: return make_error_condition( no_lock_available ); +    case ENOLINK: return make_error_condition( no_link ); +    case ENOMEM: return make_error_condition( not_enough_memory ); +    case ENOMSG: return make_error_condition( no_message ); +    case ENOPROTOOPT: return make_error_condition( no_protocol_option ); +    case ENOSPC: return make_error_condition( no_space_on_device ); +    case ENOSR: return make_error_condition( no_stream_resources ); +    case ENOSTR: return make_error_condition( not_a_stream ); +    case ENOSYS: return make_error_condition( function_not_supported ); +    case ENOTCONN: return make_error_condition( not_connected ); +    case ENOTDIR: return make_error_condition( not_a_directory ); +  # if ENOTEMPTY != EEXIST // AIX treats ENOTEMPTY and EEXIST as the same value +    case ENOTEMPTY: return make_error_condition( directory_not_empty ); +  # endif // ENOTEMPTY != EEXIST +  # if ENOTRECOVERABLE != ECONNRESET // the same on some Broadcom chips  +    case ENOTRECOVERABLE: return make_error_condition( state_not_recoverable );  +  # endif // ENOTRECOVERABLE != ECONNRESET  +    case ENOTSOCK: return make_error_condition( not_a_socket ); +    case ENOTSUP: return make_error_condition( not_supported ); +    case ENOTTY: return make_error_condition( inappropriate_io_control_operation ); +    case ENXIO: return make_error_condition( no_such_device_or_address ); +  # if EOPNOTSUPP != ENOTSUP +    case EOPNOTSUPP: return make_error_condition( operation_not_supported ); +  # endif // EOPNOTSUPP != ENOTSUP +    case EOVERFLOW: return make_error_condition( value_too_large ); +  # if EOWNERDEAD != ECONNABORTED // the same on some Broadcom chips  +    case EOWNERDEAD: return make_error_condition( owner_dead );  +  # endif // EOWNERDEAD != ECONNABORTED  +    case EPERM: return make_error_condition( operation_not_permitted ); +    case EPIPE: return make_error_condition( broken_pipe ); +    case EPROTO: return make_error_condition( protocol_error ); +    case EPROTONOSUPPORT: return make_error_condition( protocol_not_supported ); +    case EPROTOTYPE: return make_error_condition( wrong_protocol_type ); +    case ERANGE: return make_error_condition( result_out_of_range ); +    case EROFS: return make_error_condition( read_only_file_system ); +    case ESPIPE: return make_error_condition( invalid_seek ); +    case ESRCH: return make_error_condition( no_such_process ); +    case ETIME: return make_error_condition( stream_timeout ); +    case ETIMEDOUT: return make_error_condition( timed_out ); +    case ETXTBSY: return make_error_condition( text_file_busy ); +  # if EAGAIN != EWOULDBLOCK +    case EWOULDBLOCK: return make_error_condition( operation_would_block ); +  # endif // EAGAIN != EWOULDBLOCK +    case EXDEV: return make_error_condition( cross_device_link ); +  #else +    // Windows system -> posix_errno decode table  ---------------------------// +    // see WinError.h comments for descriptions of errors +    case ERROR_ACCESS_DENIED: return make_error_condition( permission_denied ); +    case ERROR_ALREADY_EXISTS: return make_error_condition( file_exists ); +    case ERROR_BAD_UNIT: return make_error_condition( no_such_device ); +    case ERROR_BUFFER_OVERFLOW: return make_error_condition( filename_too_long ); +    case ERROR_BUSY: return make_error_condition( device_or_resource_busy ); +    case ERROR_BUSY_DRIVE: return make_error_condition( device_or_resource_busy ); +    case ERROR_CANNOT_MAKE: return make_error_condition( permission_denied ); +    case ERROR_CANTOPEN: return make_error_condition( io_error ); +    case ERROR_CANTREAD: return make_error_condition( io_error ); +    case ERROR_CANTWRITE: return make_error_condition( io_error ); +    case ERROR_CURRENT_DIRECTORY: return make_error_condition( permission_denied ); +    case ERROR_DEV_NOT_EXIST: return make_error_condition( no_such_device ); +    case ERROR_DEVICE_IN_USE: return make_error_condition( device_or_resource_busy ); +    case ERROR_DIR_NOT_EMPTY: return make_error_condition( directory_not_empty ); +    case ERROR_DIRECTORY: return make_error_condition( invalid_argument ); // WinError.h: "The directory name is invalid" +    case ERROR_DISK_FULL: return make_error_condition( no_space_on_device ); +    case ERROR_FILE_EXISTS: return make_error_condition( file_exists ); +    case ERROR_FILE_NOT_FOUND: return make_error_condition( no_such_file_or_directory ); +    case ERROR_HANDLE_DISK_FULL: return make_error_condition( no_space_on_device ); +    case ERROR_INVALID_ACCESS: return make_error_condition( permission_denied ); +    case ERROR_INVALID_DRIVE: return make_error_condition( no_such_device ); +    case ERROR_INVALID_FUNCTION: return make_error_condition( function_not_supported ); +    case ERROR_INVALID_HANDLE: return make_error_condition( invalid_argument ); +    case ERROR_INVALID_NAME: return make_error_condition( invalid_argument ); +    case ERROR_LOCK_VIOLATION: return make_error_condition( no_lock_available ); +    case ERROR_LOCKED: return make_error_condition( no_lock_available ); +    case ERROR_NEGATIVE_SEEK: return make_error_condition( invalid_argument ); +    case ERROR_NOACCESS: return make_error_condition( permission_denied ); +    case ERROR_NOT_ENOUGH_MEMORY: return make_error_condition( not_enough_memory ); +    case ERROR_NOT_READY: return make_error_condition( resource_unavailable_try_again ); +    case ERROR_NOT_SAME_DEVICE: return make_error_condition( cross_device_link ); +    case ERROR_OPEN_FAILED: return make_error_condition( io_error ); +    case ERROR_OPEN_FILES: return make_error_condition( device_or_resource_busy ); +    case ERROR_OPERATION_ABORTED: return make_error_condition( operation_canceled ); +    case ERROR_OUTOFMEMORY: return make_error_condition( not_enough_memory ); +    case ERROR_PATH_NOT_FOUND: return make_error_condition( no_such_file_or_directory ); +    case ERROR_READ_FAULT: return make_error_condition( io_error ); +    case ERROR_RETRY: return make_error_condition( resource_unavailable_try_again ); +    case ERROR_SEEK: return make_error_condition( io_error ); +    case ERROR_SHARING_VIOLATION: return make_error_condition( permission_denied ); +    case ERROR_TOO_MANY_OPEN_FILES: return make_error_condition( too_many_files_open ); +    case ERROR_WRITE_FAULT: return make_error_condition( io_error ); +    case ERROR_WRITE_PROTECT: return make_error_condition( permission_denied ); +    case WSAEACCES: return make_error_condition( permission_denied ); +    case WSAEADDRINUSE: return make_error_condition( address_in_use ); +    case WSAEADDRNOTAVAIL: return make_error_condition( address_not_available ); +    case WSAEAFNOSUPPORT: return make_error_condition( address_family_not_supported ); +    case WSAEALREADY: return make_error_condition( connection_already_in_progress ); +    case WSAEBADF: return make_error_condition( bad_file_descriptor ); +    case WSAECONNABORTED: return make_error_condition( connection_aborted ); +    case WSAECONNREFUSED: return make_error_condition( connection_refused ); +    case WSAECONNRESET: return make_error_condition( connection_reset ); +    case WSAEDESTADDRREQ: return make_error_condition( destination_address_required ); +    case WSAEFAULT: return make_error_condition( bad_address ); +    case WSAEHOSTUNREACH: return make_error_condition( host_unreachable ); +    case WSAEINPROGRESS: return make_error_condition( operation_in_progress ); +    case WSAEINTR: return make_error_condition( interrupted ); +    case WSAEINVAL: return make_error_condition( invalid_argument ); +    case WSAEISCONN: return make_error_condition( already_connected ); +    case WSAEMFILE: return make_error_condition( too_many_files_open ); +    case WSAEMSGSIZE: return make_error_condition( message_size ); +    case WSAENAMETOOLONG: return make_error_condition( filename_too_long ); +    case WSAENETDOWN: return make_error_condition( network_down ); +    case WSAENETRESET: return make_error_condition( network_reset ); +    case WSAENETUNREACH: return make_error_condition( network_unreachable ); +    case WSAENOBUFS: return make_error_condition( no_buffer_space ); +    case WSAENOPROTOOPT: return make_error_condition( no_protocol_option ); +    case WSAENOTCONN: return make_error_condition( not_connected ); +    case WSAENOTSOCK: return make_error_condition( not_a_socket ); +    case WSAEOPNOTSUPP: return make_error_condition( operation_not_supported ); +    case WSAEPROTONOSUPPORT: return make_error_condition( protocol_not_supported ); +    case WSAEPROTOTYPE: return make_error_condition( wrong_protocol_type ); +    case WSAETIMEDOUT: return make_error_condition( timed_out ); +    case WSAEWOULDBLOCK: return make_error_condition( operation_would_block ); +  #endif +    default: return error_condition( ev, system_category() ); +    } +  } + +# if !defined( BOOST_WINDOWS_API ) + +  std::string system_error_category::message( int ev ) const +  { +    return generic_category().message( ev ); +  } +# else + +  std::string system_error_category::message( int ev ) const +  { +# ifndef BOOST_NO_ANSI_APIS   +    LPVOID lpMsgBuf = 0; +    DWORD retval = ::FormatMessageA(  +        FORMAT_MESSAGE_ALLOCATE_BUFFER |  +        FORMAT_MESSAGE_FROM_SYSTEM |  +        FORMAT_MESSAGE_IGNORE_INSERTS, +        NULL, +        ev, +        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language +        (LPSTR) &lpMsgBuf, +        0, +        NULL  +    ); +    detail::local_free_on_destruction lfod(lpMsgBuf); +    if (retval == 0) +        return std::string("Unknown error"); +         +    std::string str( static_cast<LPCSTR>(lpMsgBuf) ); +# else  // WinCE workaround +    LPVOID lpMsgBuf = 0; +    DWORD retval = ::FormatMessageW(  +        FORMAT_MESSAGE_ALLOCATE_BUFFER |  +        FORMAT_MESSAGE_FROM_SYSTEM |  +        FORMAT_MESSAGE_IGNORE_INSERTS, +        NULL, +        ev, +        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language +        (LPWSTR) &lpMsgBuf, +        0, +        NULL  +    ); +    detail::local_free_on_destruction lfod(lpMsgBuf); +    if (retval == 0) +        return std::string("Unknown error"); +     +    int num_chars = (wcslen( static_cast<LPCWSTR>(lpMsgBuf) ) + 1) * 2; +    LPSTR narrow_buffer = (LPSTR)_alloca( num_chars ); +    if (::WideCharToMultiByte(CP_ACP, 0, static_cast<LPCWSTR>(lpMsgBuf), -1, narrow_buffer, num_chars, NULL, NULL) == 0) +        return std::string("Unknown error"); + +    std::string str( narrow_buffer ); +# endif +    while ( str.size() +      && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') ) +        str.erase( str.size()-1 ); +    if ( str.size() && str[str.size()-1] == '.' )  +      { str.erase( str.size()-1 ); } +    return str; +  } +# endif + +} // unnamed namespace + +namespace boost +{ +  namespace system +  { + +# ifndef BOOST_SYSTEM_NO_DEPRECATED +    BOOST_SYSTEM_DECL error_code throws; // "throw on error" special error_code; +                                         //  note that it doesn't matter if this +                                         //  isn't initialized before use since +                                         //  the only use is to take its +                                         //  address for comparison purposes +# endif + +    BOOST_SYSTEM_DECL const error_category & system_category() +    { +      static const system_error_category  system_category_const; +      return system_category_const; +    } + +    BOOST_SYSTEM_DECL const error_category & generic_category() +    { +      static const generic_error_category generic_category_const; +      return generic_category_const; +    } + +  } // namespace system +} // namespace boost diff --git a/main/src/main/java/de/blinkt/openvpn/VpnProfile.java b/main/src/main/java/de/blinkt/openvpn/VpnProfile.java index d816d97e..601fb2df 100644 --- a/main/src/main/java/de/blinkt/openvpn/VpnProfile.java +++ b/main/src/main/java/de/blinkt/openvpn/VpnProfile.java @@ -202,7 +202,9 @@ public class VpnProfile implements Serializable {          //cfg += "management-signal\n";          cfg += "management-query-passwords\n";          cfg += "management-hold\n\n"; -        cfg += getVersionEnvString(context); + +        if (!configForOvpn3) +            cfg += String.format("setenv IV_GUI_VER %s \n", openVpnEscape(getVersionEnvString(context)));          cfg += "machine-readable-output\n"; @@ -439,7 +441,7 @@ public class VpnProfile implements Serializable {          return cfg;      } -    private String getVersionEnvString(Context c) { +    public String getVersionEnvString(Context c) {          String version = "unknown";          try {              PackageInfo packageinfo = c.getPackageManager().getPackageInfo(c.getPackageName(), 0); @@ -447,7 +449,7 @@ public class VpnProfile implements Serializable {          } catch (PackageManager.NameNotFoundException e) {              VpnStatus.logException(e);          } -        return String.format(Locale.US, "setenv IV_GUI_VER \"%s %s\"\n", c.getPackageName(), version); +        return String.format(Locale.US, "%s %s", c.getPackageName(), version);      } @@ -573,7 +575,7 @@ public class VpnProfile implements Serializable {          return intent;      } -    String[] getKeyStoreCertificates(Context context) { +    public String[] getKeyStoreCertificates(Context context) {          return getKeyStoreCertificates(context, 5);      } @@ -761,7 +763,7 @@ public class VpnProfile implements Serializable {          }      } -    boolean isUserPWAuth() { +    public boolean isUserPWAuth() {          switch (mAuthenticationType) {              case TYPE_USERPASS:              case TYPE_USERPASS_CERTIFICATES: 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 0de791d6..ff6ccd15 100644 --- a/main/src/main/java/de/blinkt/openvpn/core/OpenVpnService.java +++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVpnService.java @@ -15,6 +15,8 @@ import android.os.*;  import android.os.Handler.Callback;  import android.preference.PreferenceManager;  import android.text.TextUtils; + +import de.blinkt.openvpn.BuildConfig;  import de.blinkt.openvpn.activities.DisconnectVPN;  import de.blinkt.openvpn.activities.LogWindow;  import de.blinkt.openvpn.R; @@ -295,7 +297,8 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac              return START_REDELIVER_INTENT;          } -        assert (intent != null); +        if (intent == null) +            return START_NOT_STICKY;          // Extract information from the intent.          String prefix = getPackageName(); @@ -335,7 +338,8 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac          SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);          mOvpn3 = prefs.getBoolean("ovpn3", false); -        mOvpn3 = false; +        if (!"ovpn3".equals(BuildConfig.FLAVOR)) +            mOvpn3 = false;          // Open the Management Interface @@ -383,6 +387,22 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac      }      private OpenVPNManagement instantiateOpenVPN3Core() { +        try { +            Class cl = Class.forName("de.blinkt.openvpn.core.OpenVPNThreadv3"); +            return (OpenVPNManagement) cl.getConstructor(OpenVpnService.class,VpnProfile.class).newInstance(this,mProfile); +        } catch (IllegalArgumentException e) { +            e.printStackTrace(); +        } catch (InstantiationException e) { +            e.printStackTrace(); +        } catch (IllegalAccessException e) { +            e.printStackTrace(); +        } catch (InvocationTargetException e) { +            e.printStackTrace(); +        } catch (NoSuchMethodException e) { +            e.printStackTrace(); +        } catch (ClassNotFoundException e) { +            e.printStackTrace(); +        }          return null;      } @@ -542,6 +562,11 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac          }      } +    /** Route that is always included, used by the v3 core */ +    public void addRoute (CIDRIP route) { +        mRoutes.addIP(route, true); +    } +      public void addRoute (String dest, String mask, String gateway, String device) {          CIDRIP route = new CIDRIP(dest, mask);          boolean include = isAndroidTunDevice(device); diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/GeneralSettings.java b/main/src/main/java/de/blinkt/openvpn/fragments/GeneralSettings.java index 2e486dfe..0c6bb5b4 100644 --- a/main/src/main/java/de/blinkt/openvpn/fragments/GeneralSettings.java +++ b/main/src/main/java/de/blinkt/openvpn/fragments/GeneralSettings.java @@ -16,6 +16,8 @@ import android.preference.Preference;  import android.preference.Preference.OnPreferenceClickListener;  import android.preference.PreferenceCategory;  import android.preference.PreferenceFragment; + +import de.blinkt.openvpn.BuildConfig;  import de.blinkt.openvpn.R;  import de.blinkt.openvpn.api.ExternalAppDatabase; @@ -54,6 +56,12 @@ public class GeneralSettings extends PreferenceFragment implements OnPreferenceC          if(devHacks.getPreferenceCount()==0)              getPreferenceScreen().removePreference(devHacks); +        if (!"ovpn3".equals(BuildConfig.FLAVOR)) { +            PreferenceCategory appBehaviour = (PreferenceCategory) findPreference("app_behaviour"); +            appBehaviour.removePreference(findPreference("ovpn3")); +        } + +  		setClearApiSummary();  	} diff --git a/main/src/main/res/xml/general_settings.xml b/main/src/main/res/xml/general_settings.xml index d43ab6a3..4eca5243 100644 --- a/main/src/main/res/xml/general_settings.xml +++ b/main/src/main/res/xml/general_settings.xml @@ -1,6 +1,6 @@  <?xml version="1.0" encoding="utf-8"?>  <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> -    <PreferenceCategory android:title="@string/appbehaviour"> +    <PreferenceCategory android:title="@string/appbehaviour" android:key="app_behaviour">          <CheckBoxPreference                  android:defaultValue="true"                  android:key="showlogwindow" @@ -8,6 +8,14 @@                  android:title="@string/show_log_window"/>          <CheckBoxPreference +            android:defaultValue="false" +            android:key="ovpn3" +            android:summaryOn="Use the C++ OpenVPN library" +            android:summaryOff="Use OpenVPN 2.3" +            android:title="OpenVPN 3 Core"/> + + +        <CheckBoxPreference                  android:defaultValue="false"                  android:key="restartvpnonboot"                  android:summary="@string/onbootrestartsummary" diff --git a/main/src/ovpn3/java/de/blinkt/openvpn/core/OpenVPNThreadv3.java b/main/src/ovpn3/java/de/blinkt/openvpn/core/OpenVPNThreadv3.java new file mode 100644 index 00000000..6d3dce69 --- /dev/null +++ b/main/src/ovpn3/java/de/blinkt/openvpn/core/OpenVPNThreadv3.java @@ -0,0 +1,277 @@ +package de.blinkt.openvpn.core; + +import net.openvpn.ovpn3.ClientAPI_Config; +import net.openvpn.ovpn3.ClientAPI_EvalConfig; +import net.openvpn.ovpn3.ClientAPI_Event; +import net.openvpn.ovpn3.ClientAPI_ExternalPKICertRequest; +import net.openvpn.ovpn3.ClientAPI_ExternalPKISignRequest; +import net.openvpn.ovpn3.ClientAPI_LogInfo; +import net.openvpn.ovpn3.ClientAPI_OpenVPNClient; +import net.openvpn.ovpn3.ClientAPI_ProvideCreds; +import net.openvpn.ovpn3.ClientAPI_Status; +import net.openvpn.ovpn3.ClientAPI_TransportStats; + +import java.lang.Override; + +import de.blinkt.openvpn.VpnProfile; +import de.blinkt.openvpn.core.OpenVPNManagement; +import de.blinkt.openvpn.core.OpenVpnService; +import de.blinkt.openvpn.core.VpnStatus; +import android.content.Context; + +public class OpenVPNThreadv3 extends ClientAPI_OpenVPNClient implements Runnable, OpenVPNManagement { + +	static { +		/*System.loadLibrary("crypto"); +		System.loadLibrary("ssl");*/ +        System.loadLibrary("polarssl-dynamic"); +		System.loadLibrary("ovpn3"); +	} + +	private VpnProfile mVp; +	private OpenVpnService mService; + +	class StatusPoller implements  Runnable  +	{ +		private long mSleeptime; + +		boolean mStopped=false; + +		public StatusPoller(long sleeptime) { +			mSleeptime=sleeptime; +		} + +		public void run() { +			while(!mStopped) { +				try { +					Thread.sleep(mSleeptime); +				} catch (InterruptedException e) { +				} +				ClientAPI_TransportStats t = transport_stats(); +				long in = t.getBytesIn(); +				long out = t.getBytesOut(); +				VpnStatus.updateByteCount(in, out); +			} +		} + +		public void stop() { +			mStopped=true; +		} +	} + +	@Override +	public void run() { +		String configstr = mVp.getConfigFile((Context)mService,true); +		if(!setConfig(configstr)) +			return; +		setUserPW(); +        VpnStatus.logInfo(copyright()); + +		StatusPoller statuspoller = new StatusPoller(5000); +		new Thread(statuspoller,"Status Poller").start(); + +		ClientAPI_Status status = connect(); +		if(status.getError()) { +            VpnStatus.logError(String.format("connect() error: %s: %s",status.getStatus(),status.getMessage())); +		} else { +            VpnStatus.logInfo("OpenVPN3 thread finished"); +		} +		statuspoller.stop(); +	} + +	@Override +	public boolean tun_builder_set_remote_address(String address, boolean ipv6) { +		mService.setMtu(1500); +		return true; +	} + +	@Override +	public boolean tun_builder_set_mtu(int mtu) { +		mService.setMtu(mtu); +		return true; +	} +	@Override +	public boolean tun_builder_add_dns_server(String address, boolean ipv6) { +		mService.addDNS(address); +		return true; +	} + +	@Override +	public boolean tun_builder_add_route(String address, int prefix_length, +			boolean ipv6) { +		if (address.equals("remote_host")) +			return false; +		 +		if(ipv6) +			mService.addRoutev6(address + "/" + prefix_length,"tun"); +		else +			mService.addRoute(new CIDRIP(address, prefix_length)); +		return true; +	} + +	@Override +	public boolean tun_builder_add_search_domain(String domain) { +		mService.setDomain(domain); +		return true; +	} + +	@Override +	public int tun_builder_establish() { +		return mService.openTun().detachFd(); +	} + +	@Override +	public boolean tun_builder_set_session_name(String name) { +        VpnStatus.logInfo("We should call this session" + name); +		return true; +	} + + + +	@Override +	public boolean tun_builder_add_address(String address, int prefix_length, +			boolean ipv6) { +		if(!ipv6) +			mService.setLocalIP(new CIDRIP(address, prefix_length)); +		else +			mService.setLocalIPv6(address+ "/" + prefix_length); +		return true; +	} + +	@Override +	public boolean tun_builder_new() { + +		return true; +	} + +	@Override +	public boolean tun_builder_reroute_gw(String server_address, +			boolean server_address_ipv6, boolean ipv4, boolean ipv6, long flags) { +		// ignore +		return true; +	} + +	@Override +	public boolean tun_builder_exclude_route(String address, int prefix_length, +			boolean ipv6) { +		//ignore +		return true; +	} + + +	private boolean setConfig(String vpnconfig) { + +		ClientAPI_Config config = new ClientAPI_Config(); +		if(mVp.getPasswordPrivateKey()!=null) +			config.setPrivateKeyPassword(mVp.getPasswordPrivateKey()); + +		config.setContent(vpnconfig); +		config.setTunPersist(mVp.mPersistTun); +        config.setGuiVersion(mVp.getVersionEnvString(mService)); +		config.setExternalPkiAlias("extpki"); + +		ClientAPI_EvalConfig ec = eval_config(config); +		if(ec.getExternalPki()) { +            VpnStatus.logError("OpenVPN seem to think as external PKI"); +		} +		if (ec.getError()) { +            VpnStatus.logError("OpenVPN config file parse error: " + ec.getMessage()); +			return false; +		} else { +			config.setContent(vpnconfig); +			return true; +		} +	} + +	@Override +	public void external_pki_cert_request(ClientAPI_ExternalPKICertRequest certreq) { +        VpnStatus.logError("EXT PKI CERT"); +		String[] ks = mVp.getKeyStoreCertificates((Context) mService); +		if(ks==null) { +			certreq.setError(true); +			certreq.setErrorText("Error in pki cert request"); +			return; +		} + +        String supcerts = ks[0]; +        /* FIXME: How to differentiate between chain and ca certs in OpenVPN 3? */ +        if (ks[1]!=null) +            supcerts += "\n" + ks[1]; +		certreq.setSupportingChain(supcerts); +		certreq.setCert(ks[2]); +		certreq.setError(false); +	} + +	@Override +	public void external_pki_sign_request(ClientAPI_ExternalPKISignRequest signreq) { +		signreq.setSig(mVp.getSignedData(signreq.getData())); +	} + +	void setUserPW() { +		if(mVp.isUserPWAuth()) { +			ClientAPI_ProvideCreds creds = new ClientAPI_ProvideCreds(); +			creds.setCachePassword(true); +			creds.setPassword(mVp.getPasswordAuth()); +			creds.setUsername(mVp.mUsername); +			provide_creds(creds); +		} +	} + +	@Override +	public boolean socket_protect(int socket) { +		boolean b= mService.protect(socket); +		return b; + +	} + +	public OpenVPNThreadv3(OpenVpnService openVpnService, VpnProfile vp) { +		init_process(); +		mVp =vp; +		mService =openVpnService; +	} + +    @Override +    public void pause(pauseReason pauseReason) +    { +        pause(); +    } + +	@Override +	public void log(ClientAPI_LogInfo arg0) { +		String logmsg =arg0.getText(); +		while (logmsg.endsWith("\n")) +			logmsg = logmsg.substring(0, logmsg.length()-1); + +        VpnStatus.logInfo(logmsg); +	} + +	@Override +	public void event(ClientAPI_Event event) { +		VpnStatus.updateStateString(event.getName(), event.getInfo()); +		if(event.getError()) +            VpnStatus.logError(String.format("EVENT(Error): %s: %s",event.getName(),event.getInfo())); +	} + + +	// When a connection is close to timeout, the core will call this +	// method.  If it returns false, the core will disconnect with a +	// CONNECTION_TIMEOUT event.  If true, the core will enter a PAUSE +	// state. + +	@Override +	public boolean pause_on_connection_timeout() { +        VpnStatus.logInfo("pause on connection timeout?! "); +		return true;  +	} + +	public boolean stopVPN() { +		stop(); +		return true; +	} + +	@Override +	public void reconnect() { +		reconnect(1); +	} + +} | 
