add disable openvpnconnection, refactoring

This commit is contained in:
Розов Никита Валерьевич 2021-10-13 18:33:43 +03:00
parent 6c2e6ead2b
commit 28ae7eeaee
8 changed files with 500 additions and 482 deletions

View file

@ -29,33 +29,26 @@ import net.openvpn.ovpn3.ClientAPI_TransportStats
class OpenVPNThreadv3(var service: VPNService): ClientAPI_OpenVPNClient(), Runnable { class OpenVPNThreadv3(var service: VPNService): ClientAPI_OpenVPNClient(), Runnable {
private val tag = "OpenVPNThreadv3" private val tag = "OpenVPNThreadv3"
private var mConfig: JSONObject? = null private var mConfig: JSONObject? = null
private var mConnectionTime: Long = 0
private var mAlreadyInitialised = false private var mAlreadyInitialised = false
private var mService: VPNService = service private var mService: VPNService = service
private var currentTunnelHandle = -1
override fun run() { override fun run() {
//TEMP //TEMP
val lConfigData: String = readFileDirectlyAsText("/data/local/tmp/android_conf.ovpn")
val config: ClientAPI_Config = ClientAPI_Config() val config: ClientAPI_Config = ClientAPI_Config()
config.content = lConfigData config.content = mService.getVpnConfig().getString("openvpn_config_data")
val lCreds: ClientAPI_ProvideCreds = ClientAPI_ProvideCreds()
//username from config or GUI
lCreds.username = ""
//password from config or GUI
lCreds.password = ""
provide_creds(lCreds)
eval_config(config) eval_config(config)
connect() val status = connect()
Log.i(tag, "Connect succesfully") Log.i(tag, "ERROR " + status)
if (status.getError() != false) {
Log.i(tag, "connect() error: " + status.getError() + ": " + status.getMessage())
mService.openvpnConnected()
} else {
Log.i(tag, "Connect succesfully, OpenVPN3 thread finished")
mService.openvpnConnected()
}
} }
fun readFileDirectlyAsText(fileName: String): String = File(fileName).readText(Charsets.UTF_8)
override fun log(arg0: ClientAPI_LogInfo){ override fun log(arg0: ClientAPI_LogInfo){
Log.i(tag, arg0.getText()) Log.i(tag, arg0.getText())
@ -65,7 +58,6 @@ class OpenVPNThreadv3(var service: VPNService): ClientAPI_OpenVPNClient(), Runna
Log.i(tag, event.getName()) Log.i(tag, event.getName())
} }
override fun tun_builder_new(): Boolean { override fun tun_builder_new(): Boolean {
return true return true
} }
@ -119,4 +111,13 @@ class OpenVPNThreadv3(var service: VPNService): ClientAPI_OpenVPNClient(), Runna
return true return true
} }
fun stopVPN(): Boolean {
stop()
return false
}
override fun stop() {
super.stop()
}
} }

View file

@ -19,11 +19,11 @@ class VPNService : android.net.VpnService() {
private val tag = "VPNService" private val tag = "VPNService"
private var mBinder: VPNServiceBinder = VPNServiceBinder(this) private var mBinder: VPNServiceBinder = VPNServiceBinder(this)
private var mConfig: JSONObject? = null private var mConfig: JSONObject? = null
private var mProtocol: String? = null
private var mConnectionTime: Long = 0 private var mConnectionTime: Long = 0
private var mAlreadyInitialised = false private var mAlreadyInitialised = false
private var mbuilder: Builder = Builder() private var mbuilder: Builder = Builder()
private var mOpenVPNThreadv3: OpenVPNThreadv3? = null private var mOpenVPNThreadv3: OpenVPNThreadv3? = null
private var currentTunnelHandle = -1 private var currentTunnelHandle = -1
@ -67,31 +67,27 @@ class VPNService : android.net.VpnService() {
*/ */
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
init() init()
// intent?.let { intent?.let {
// if (intent.getBooleanExtra("startOnly", false)) { if (intent.getBooleanExtra("startOnly", false)) {
// Log.i(tag, "Start only!") Log.i(tag, "Start only!")
// return super.onStartCommand(intent, flags, startId) return super.onStartCommand(intent, flags, startId)
// } }
// } }
// // This start is from always-on // This start is from always-on
// if (this.mConfig == null) { if (this.mConfig == null) {
// // We don't have tunnel to turn on - Try to create one with last config the service got // We don't have tunnel to turn on - Try to create one with last config the service got
// val prefs = Prefs.get(this) val prefs = Prefs.get(this)
// val lastConfString = prefs.getString("lastConf", "") val lastConfString = prefs.getString("lastConf", "")
// if (lastConfString.isNullOrEmpty()) { if (lastConfString.isNullOrEmpty()) {
// // We have nothing to connect to -> Exit // We have nothing to connect to -> Exit
// Log.e( Log.e(
// tag, tag,
// "VPN service was triggered without defining a Server or having a tunnel" "VPN service was triggered without defining a Server or having a tunnel"
// ) )
// return super.onStartCommand(intent, flags, startId) return super.onStartCommand(intent, flags, startId)
// } }
// this.mConfig = JSONObject(lastConfString) this.mConfig = JSONObject(lastConfString)
// } }
// Log.v(tag, "onStartCommand:" + this.mConfig)
// turnOn(this.mConfig)
return super.onStartCommand(intent, flags, startId) return super.onStartCommand(intent, flags, startId)
} }
@ -149,54 +145,24 @@ class VPNService : android.net.VpnService() {
return false return false
} }
fun turnOn(json: JSONObject?): ParcelFileDescriptor? { fun turnOn(json: JSONObject?): Int {
Log.sensitive(tag, "" + json.toString())
// val wireguard_conf = buildWireugardConfig(json)
if (!checkPermissions()) { if (!checkPermissions()) {
Log.e(tag, "turn on was called without no permissions present!") Log.e(tag, "turn on was called without no permissions present!")
isUp = false isUp = false
return null return 0
} }
// Log.i(tag, "Permission okay") Log.i(tag, "Permission okay")
// if (currentTunnelHandle != -1) { mConfig = json
// Log.e(tag, "Tunnel already up") mProtocol = mConfig!!.getString("protocol")
// // Turn the tunnel down because this might be a switch when (mProtocol) {
// wgTurnOff(currentTunnelHandle) "openvpn" -> startOpenVpn()
// } "wireguard" -> startWireGuard()
// val wgConfig: String = wireguard_conf!!.toWgUserspaceString() else -> {
// val builder = Builder() Log.e(tag, "No protocol")
// setupBuilder(wireguard_conf, builder) return 0
// builder.setSession("mvpn0") }
// builder.establish().use { tun -> }
// if (tun == null)return return 1
// Log.i(tag, "Go backend " + wgVersion())
// currentTunnelHandle = wgTurnOn("mvpn0", tun.detachFd(), wgConfig)
// }
// if (currentTunnelHandle < 0) {
// Log.e(tag, "Activation Error Code -> $currentTunnelHandle")
// isUp = false
// return
// }
// protect(wgGetSocketV4(currentTunnelHandle))
// protect(wgGetSocketV6(currentTunnelHandle))
// mConfig = json
// isUp = true
// // Store the config in case the service gets
// // asked boot vpn from the OS
// val prefs = Prefs.get(this)
// prefs.edit()
// .putString("lastConf", json.toString())
// .apply()
// NotificationUtil.show(this) // Go foreground
startOpenVpn()
return 1//localTunnel
} }
fun establish(): ParcelFileDescriptor? { fun establish(): ParcelFileDescriptor? {
@ -204,17 +170,14 @@ class VPNService : android.net.VpnService() {
} }
fun setMtu(mtu: Int) { fun setMtu(mtu: Int) {
Log.v(tag, "setMtu()" + mtu)
mbuilder.setMtu(mtu) mbuilder.setMtu(mtu)
} }
fun addAddress(ip: String, len: Int){ fun addAddress(ip: String, len: Int){
Log.v(tag, "addAddress()" + ip + " " + len)
mbuilder.addAddress(ip, len) mbuilder.addAddress(ip, len)
} }
fun addRoute(ip: String, len: Int){ fun addRoute(ip: String, len: Int){
Log.v(tag, "addRoute()" + ip + " " + len)
mbuilder.addRoute(ip, len) mbuilder.addRoute(ip, len)
} }
@ -222,13 +185,20 @@ class VPNService : android.net.VpnService() {
mbuilder.addDnsServer(ip) mbuilder.addDnsServer(ip)
} }
fun turnOff() { fun turnOff() {
Log.v(tag, "Try to disable tunnel") Log.v(tag, "Try to disable tunnel")
wgTurnOff(currentTunnelHandle) when(mProtocol){
"wireguard" -> wgTurnOff(currentTunnelHandle)
"openvpn" -> mOpenVPNThreadv3?.stopVPN()
else -> {
Log.e(tag, "No protocol")
}
}
currentTunnelHandle = -1 currentTunnelHandle = -1
stopForeground(false) stopForeground(true)
isUp = false isUp = false
stopSelf();
} }
/** /**
@ -324,23 +294,62 @@ class VPNService : android.net.VpnService() {
return confBuilder.build() return confBuilder.build()
} }
fun getVpnConfig(): JSONObject {
return mConfig!!
}
private fun startOpenVpn() { private fun startOpenVpn() {
Thread ({ Thread ({
mOpenVPNThreadv3?.run() mOpenVPNThreadv3?.run()
}).start() }).start()
Log.i(tag, "OpenVPNThreadv3 start")
isUp = true
} }
fun openvpnConnected(){
isUp = true;
}
private fun startWireGuard(){
val wireguard_conf = buildWireugardConfig(mConfig!!)
if (currentTunnelHandle != -1) {
Log.e(tag, "Tunnel already up")
// Turn the tunnel down because this might be a switch
wgTurnOff(currentTunnelHandle)
}
val wgConfig: String = wireguard_conf!!.toWgUserspaceString()
val builder = Builder()
setupBuilder(wireguard_conf, builder)
builder.setSession("mvpn0")
builder.establish().use { tun ->
if (tun == null)return
Log.i(tag, "Go backend " + wgVersion())
currentTunnelHandle = wgTurnOn("mvpn0", tun.detachFd(), wgConfig)
}
if (currentTunnelHandle < 0) {
Log.e(tag, "Activation Error Code -> $currentTunnelHandle")
isUp = false
return
}
protect(wgGetSocketV4(currentTunnelHandle))
protect(wgGetSocketV6(currentTunnelHandle))
isUp = true
// Store the config in case the service gets
// asked boot vpn from the OS
val prefs = Prefs.get(this)
prefs.edit()
.putString("lastConf", mConfig.toString())
.apply()
NotificationUtil.show(this) // Go foreground
}
companion object { companion object {
@JvmStatic @JvmStatic
fun startService(c: Context) { fun startService(c: Context) {
c.applicationContext.startService( c.applicationContext.startService(
Intent(c.applicationContext, VPNService::class.java).apply { Intent(c.applicationContext, VPNService::class.java).apply {
putExtra("startOnly", true) putExtra("startOnly", true)
} })
)
} }
@JvmStatic @JvmStatic

View file

@ -31,7 +31,6 @@ class VPNServiceBinder(service: VPNService) : Binder() {
const val resumeActivate = 7 const val resumeActivate = 7
const val setNotificationText = 8 const val setNotificationText = 8
const val setFallBackNotification = 9 const val setFallBackNotification = 9
const val myLog = 10
} }
/** /**
@ -54,7 +53,6 @@ class VPNServiceBinder(service: VPNService) : Binder() {
val buffer = data.createByteArray() val buffer = data.createByteArray()
val json = buffer?.let { String(it) } val json = buffer?.let { String(it) }
val config = JSONObject(json) val config = JSONObject(json)
Log.v(tag, "config: " + config.toString())
Log.v(tag, "Stored new Tunnel config in Service") Log.v(tag, "Stored new Tunnel config in Service")
if (!mService.checkPermissions()) { if (!mService.checkPermissions()) {
@ -97,7 +95,6 @@ class VPNServiceBinder(service: VPNService) : Binder() {
obj.put("connected", mService.isUp) obj.put("connected", mService.isUp)
obj.put("time", mService.connectionTime) obj.put("time", mService.connectionTime)
dispatchEvent(EVENTS.init, obj.toString()) dispatchEvent(EVENTS.init, obj.toString())
Log.i(tag, "ACTIONS.registerEventListener")
return true return true
} }
@ -120,7 +117,7 @@ class VPNServiceBinder(service: VPNService) : Binder() {
return true return true
} }
ACTIONS.setFallBackNotification -> { ACTIONS.setFallBackNotification -> {
// NotificationUtil.saveFallBackMessage(data, mService) NotificationUtil.saveFallBackMessage(data, mService)
return true return true
} }
IBinder.LAST_CALL_TRANSACTION -> { IBinder.LAST_CALL_TRANSACTION -> {

View file

@ -16,8 +16,8 @@ class VPNPermissionHelper : android.net.VpnService() {
* is present and prompting if not. * is present and prompting if not.
*/ */
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.i(tag, "onStartCommand")
val intent = prepare(this.applicationContext) val intent = prepare(this.applicationContext)
Log.i(tag, "VPNPermissionHelper onStartCommand")
if (intent != null) { if (intent != null) {
startActivityForResult(intent) startActivityForResult(intent)
} }

View file

@ -121,6 +121,7 @@ int main(int argc, char *argv[])
qRegisterMetaType<Protocol>("Protocol"); qRegisterMetaType<Protocol>("Protocol");
qRegisterMetaType<ServiceType>("ServiceType"); qRegisterMetaType<ServiceType>("ServiceType");
qRegisterMetaType<Page>("Page"); qRegisterMetaType<Page>("Page");
qRegisterMetaType<VpnProtocol::ConnectionState>("ConnectionState");
qRegisterMetaType<PageProtocolLogicBase *>("PageProtocolLogicBase *"); qRegisterMetaType<PageProtocolLogicBase *>("PageProtocolLogicBase *");

View file

@ -58,7 +58,7 @@ AndroidVpnProtocol* AndroidVpnProtocol::instance() {
return s_instance; return s_instance;
} }
void AndroidVpnProtocol::initialize() bool AndroidVpnProtocol::initialize()
{ {
qDebug() << "Initializing"; qDebug() << "Initializing";
@ -81,9 +81,12 @@ void AndroidVpnProtocol::initialize()
"(Landroid/content/Context;)V", appContext.object()); "(Landroid/content/Context;)V", appContext.object());
// Start the VPN Service (if not yet) and Bind to it // Start the VPN Service (if not yet) and Bind to it
QtAndroid::bindService( const bool bindResult = QtAndroid::bindService(
QAndroidIntent(appContext.object(), "org.amnezia.vpn.VPNService"), QAndroidIntent(appContext.object(), "org.amnezia.vpn.VPNService"),
*this, QtAndroid::BindFlag::AutoCreate); *this, QtAndroid::BindFlag::AutoCreate);
qDebug() << "Binding to the service..." << bindResult;
return bindResult;
} }
ErrorCode AndroidVpnProtocol::start() ErrorCode AndroidVpnProtocol::start()
@ -128,8 +131,12 @@ ErrorCode AndroidVpnProtocol::start()
QAndroidParcel sendData; QAndroidParcel sendData;
sendData.writeData(QJsonDocument(m_rawConfig).toJson()); sendData.writeData(QJsonDocument(m_rawConfig).toJson());
m_serviceBinder.transact(ACTION_ACTIVATE, sendData, nullptr); bool activateResult = false;
return NoError; while (!activateResult){
activateResult = m_serviceBinder.transact(ACTION_ACTIVATE, sendData, nullptr);
}
return activateResult ? NoError : UnknownError;
} }
// Activates the tunnel that is currently set // Activates the tunnel that is currently set
@ -212,7 +219,7 @@ void AndroidVpnProtocol::cleanupBackendLogs() {
void AndroidVpnProtocol::onServiceConnected( void AndroidVpnProtocol::onServiceConnected(
const QString& name, const QAndroidBinder& serviceBinder) { const QString& name, const QAndroidBinder& serviceBinder) {
qDebug() << "Server connected"; qDebug() << "Server " + name + " connected";
Q_UNUSED(name); Q_UNUSED(name);

View file

@ -22,7 +22,7 @@ public:
virtual ~AndroidVpnProtocol() override = default; virtual ~AndroidVpnProtocol() override = default;
void initialize(); bool initialize();
virtual ErrorCode start() override; virtual ErrorCode start() override;
virtual void stop() override; virtual void stop() override;

View file

@ -232,7 +232,6 @@ ErrorCode VpnConnection::connectToVpn(int serverIndex,
m_vpnProtocol.reset(); m_vpnProtocol.reset();
} }
ErrorCode e = ErrorCode::NoError; ErrorCode e = ErrorCode::NoError;
m_vpnConfiguration = createVpnConfiguration(serverIndex, credentials, container, containerConfig); m_vpnConfiguration = createVpnConfiguration(serverIndex, credentials, container, containerConfig);
if (e) { if (e) {
@ -252,8 +251,12 @@ ErrorCode VpnConnection::connectToVpn(int serverIndex,
#else #else
AndroidVpnProtocol *androidVpnProtocol = new AndroidVpnProtocol(Protocol::OpenVpn, m_vpnConfiguration); Protocol proto = ContainerProps::defaultProtocol(container);
androidVpnProtocol->initialize(); AndroidVpnProtocol *androidVpnProtocol = new AndroidVpnProtocol(proto, m_vpnConfiguration);
if (!androidVpnProtocol->initialize()) {
qDebug() << QString("Init failed") ;
return UnknownError;
}
m_vpnProtocol.reset(androidVpnProtocol); m_vpnProtocol.reset(androidVpnProtocol);
#endif #endif