summaryrefslogtreecommitdiff
path: root/main/src/ui/java/de/blinkt/openvpn/fragments/PasswordDialogFragment.kt
blob: eedb2e59c8afaf847f614a8808b321cd8eb3cf96 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/*
 * Copyright (c) 2012-2019 Arne Schwabe
 * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt
 */
package de.blinkt.openvpn.core

import android.app.AlertDialog
import android.app.Dialog
import android.content.ComponentName
import android.content.DialogInterface
import android.content.Intent
import android.content.ServiceConnection
import android.os.Bundle
import android.os.IBinder
import android.os.RemoteException
import android.text.InputType
import android.widget.EditText
import androidx.fragment.app.DialogFragment
import de.blinkt.openvpn.R
import de.blinkt.openvpn.core.OpenVPNService.EXTRA_CHALLENGE_TXT

class PasswordDialogFragment : DialogFragment() {
    private var mService: IOpenVPNServiceInternal? = null
    private val mConnection: ServiceConnection = object : ServiceConnection {
        override fun onServiceConnected(className: ComponentName,
                                        service: IBinder) {
            mService = IOpenVPNServiceInternal.Stub.asInterface(service)
        }

        override fun onServiceDisconnected(arg0: ComponentName) {
            mService = null
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val intent = Intent(activity, OpenVPNService::class.java)
        intent.action = OpenVPNService.START_SERVICE
        requireActivity().bindService(intent, mConnection, 0)
    }

    override fun onDestroy() {
        super.onDestroy()
        requireActivity().unbindService(mConnection)
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val title = requireArguments().getString("title")
        val echo = requireArguments().getBoolean("echo")
        val finish = requireArguments().getBoolean("finish")
        val input = EditText(activity)
        if (!echo)
            input.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD

        return AlertDialog.Builder(activity)
                .setTitle("Challenge/Response Authentification")
                .setMessage(title)
                .setView(input)
                .setPositiveButton(android.R.string.ok) { _, _ ->
                    try {
                        mService?.challengeResponse(input.text.toString())
                        if (finish) requireActivity().finish()
                    } catch (e: RemoteException) {
                        VpnStatus.logException(e)
                        e.printStackTrace()
                    }
                }
                .setNegativeButton(R.string.cancel
                ) { _, _ -> if (finish) requireActivity().finish() }
                .create()
    }

    companion object {
        fun newInstance(intent: Intent, finish: Boolean): PasswordDialogFragment? {
            val extras = intent.extras ?: return null
            val challenge = extras.getString(EXTRA_CHALLENGE_TXT, "R,E:(empty challenge text)")
            val message = challenge.split(":", limit = 2)[1]
            val flagsStr = challenge.split(":", limit = 2)[0]
            val flags = flagsStr.split(",")
            var echo = false
            var response = false
            for (flag in flags) {
                if (flag == "R") response = true
                else if (flag == "E") echo = true
            }
            if (!response) {
                VpnStatus.logError("Error unrecognised challenge from Server: $challenge")
                return null
            }
            val frag = PasswordDialogFragment()
            val args = Bundle()
            args.putString("title", message)
            args.putBoolean("echo", echo)
            args.putBoolean("finish", finish)
            frag.arguments = args
            return frag
        }
    }
}