- Prompt for authentication password at baresip start if not given in
account config.
This commit is contained in:
@ -122,9 +122,34 @@ static const char *translate_errorcode(uint16_t scode)
|
||||
}
|
||||
}
|
||||
|
||||
static void get_password(char *aor, char *password)
|
||||
{
|
||||
LOGD("getting password of AoR %s\n", aor);
|
||||
|
||||
JavaVM *javaVM = g_ctx.javaVM;
|
||||
JNIEnv *env;
|
||||
jint res = (*javaVM)->GetEnv(javaVM, (void**)&env, JNI_VERSION_1_6);
|
||||
if (res != JNI_OK) {
|
||||
res = (*javaVM)->AttachCurrentThread(javaVM, &env, NULL);
|
||||
if (JNI_OK != res) {
|
||||
LOGE("failed to AttachCurrentThread, ErrorCode = %d\n", res);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
jmethodID methodId = (*env)->GetMethodID(env, g_ctx.mainActivityClz, "getPassword",
|
||||
"(Ljava/lang/String;)Ljava/lang/String;");
|
||||
jstring javaAoR = (*env)->NewStringUTF(env, aor);
|
||||
jstring javaPassword = (*env)->CallObjectMethod(env, g_ctx.mainActivityObj, methodId, javaAoR);
|
||||
const char *pwd = (*env)->GetStringUTFChars(env, javaPassword, 0);
|
||||
strcpy(password, pwd);
|
||||
(*env)->ReleaseStringUTFChars(env, javaPassword, pwd);
|
||||
}
|
||||
|
||||
static void ua_event_handler(struct ua *ua, enum ua_event ev,
|
||||
struct call *call, const char *prm, void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
const char *event;
|
||||
char event_buf[256];
|
||||
char ua_buf[32];
|
||||
@ -196,6 +221,9 @@ static void ua_event_handler(struct ua *ua, enum ua_event ev,
|
||||
case UA_EVENT_AUDIO_ERROR:
|
||||
mem_deref(call);
|
||||
return;
|
||||
case UA_EVENT_GET_PASSWORD:
|
||||
get_password((char *)ua, (char *)call);
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
@ -218,6 +246,18 @@ static void ua_event_handler(struct ua *ua, enum ua_event ev,
|
||||
}
|
||||
}
|
||||
|
||||
if (ev == UA_EVENT_GET_PASSWORD) {
|
||||
jmethodID methodId = (*env)->GetMethodID(env, g_ctx.mainActivityClz, "getPassword",
|
||||
"(Ljava/lang/String;)Ljava/lang/String;");
|
||||
sprintf(ua_buf, "%lu", (unsigned long)ua);
|
||||
jstring javaUA = (*env)->NewStringUTF(env, ua_buf);
|
||||
jstring javaPassword = (*env)->CallObjectMethod(env, g_ctx.mainActivityObj, methodId, javaUA);
|
||||
const char *password = (*env)->GetStringUTFChars(env, javaPassword, 0);
|
||||
strcpy((char *)call, password);
|
||||
(*env)->ReleaseStringUTFChars(env, javaPassword, password);
|
||||
return;
|
||||
}
|
||||
|
||||
jmethodID methodId = (*env)->GetMethodID(env, g_ctx.mainActivityClz,
|
||||
"uaEvent",
|
||||
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
|
||||
|
||||
@ -80,7 +80,8 @@ class Account(val accp: String) {
|
||||
|
||||
if (authUser != "") res = res + ";auth_user=\"${authUser}\""
|
||||
|
||||
if (authPass != "") res = res + ";auth_pass=\"${authPass}\""
|
||||
if ((authPass != "") && !MainActivity.aorPasswords.containsKey(aor))
|
||||
res = res + ";auth_pass=\"${authPass}\""
|
||||
|
||||
if (outbound.size > 0) {
|
||||
res = res + ";outbound=\"${outbound[0]}\""
|
||||
|
||||
@ -61,7 +61,10 @@ class AccountActivity : AppCompatActivity() {
|
||||
authUser.setText(acc.authUser)
|
||||
|
||||
authPass = findViewById(R.id.AuthPass) as EditText
|
||||
authPass.setText(acc.authPass)
|
||||
if (MainActivity.aorPasswords.containsKey(aor))
|
||||
authPass.setText("")
|
||||
else
|
||||
authPass.setText(acc.authPass)
|
||||
|
||||
outbound1 = findViewById(R.id.Outbound1) as EditText
|
||||
outbound2 = findViewById(R.id.Outbound2) as EditText
|
||||
@ -223,7 +226,8 @@ class AccountActivity : AppCompatActivity() {
|
||||
|
||||
val au = authUser.text.toString().trim()
|
||||
val ap = authPass.text.toString().trim()
|
||||
if (((au != "") && (ap == "")) || ((au == "") && (ap != ""))) {
|
||||
|
||||
if ((au == "") && (ap != "")) {
|
||||
Utils.alertView(this, getString(R.string.notice),
|
||||
getString(R.string.authentication_username_password_mismatch))
|
||||
return false
|
||||
@ -245,10 +249,11 @@ class AccountActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
if (ap != acc.authPass) {
|
||||
if (Utils.checkPrintAscii(ap)) {
|
||||
if ((ap != acc.authPass) && (ap != "")) {
|
||||
if (Utils.checkPrintAscii(ap) && (ap.length <= 64)) {
|
||||
if (account_set_auth_pass(acc.accp, ap) == 0) {
|
||||
acc.authPass = account_auth_pass(acc.accp)
|
||||
MainActivity.aorPasswords.remove(aor)
|
||||
// Log.d("Baresip", "New auth password is ${acc.authPass}")
|
||||
save = true
|
||||
} else {
|
||||
@ -259,6 +264,11 @@ class AccountActivity : AppCompatActivity() {
|
||||
String.format(getString(R.string.invalid_authentication_password), ap))
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
if ((ap == "") && !MainActivity.aorPasswords.containsKey(aor)) {
|
||||
MainActivity.aorPasswords.put(aor, acc.authPass)
|
||||
save = true
|
||||
}
|
||||
}
|
||||
|
||||
val ob = ArrayList<String>()
|
||||
|
||||
@ -843,6 +843,16 @@ class BaresipService: Service() {
|
||||
LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
|
||||
}
|
||||
|
||||
@Keep
|
||||
fun getPassword(aor: String): String {
|
||||
if (!isServiceRunning) return ""
|
||||
Log.d(LOG_TAG, "getPassword of $aor")
|
||||
if (MainActivity.aorPasswords[aor] != null)
|
||||
return MainActivity.aorPasswords[aor]!!
|
||||
else
|
||||
return ""
|
||||
}
|
||||
|
||||
@Keep
|
||||
fun stopped(error: String) {
|
||||
Log.d(LOG_TAG, "Received 'stopped' from baresip with param '$error'")
|
||||
|
||||
@ -424,11 +424,13 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
baresipService = Intent(this@MainActivity, BaresipService::class.java)
|
||||
|
||||
if (!BaresipService.isServiceRunning) {
|
||||
baresipService.setAction("Start")
|
||||
startService(baresipService)
|
||||
Utils.requestPermission(this, Manifest.permission.RECORD_AUDIO,
|
||||
RECORD_PERMISSION_REQUEST_CODE)
|
||||
if (File(filesDir.absolutePath + "/accounts").exists()) {
|
||||
var accounts = String(Utils.getFileContents(filesDir.absolutePath + "/accounts")!!,
|
||||
Charsets.UTF_8).lines().toMutableList()
|
||||
askAorPasswords(accounts)
|
||||
}
|
||||
}
|
||||
|
||||
if (intent.hasExtra("onStartup"))
|
||||
@ -966,6 +968,53 @@ class MainActivity : AppCompatActivity() {
|
||||
builder.show()
|
||||
}
|
||||
|
||||
private fun askAorPasswords(accounts: MutableList<String>) {
|
||||
if (accounts.isNotEmpty()) {
|
||||
val account = accounts.removeAt(0)
|
||||
val params = account.substringAfter(">")
|
||||
if ((Utils.paramValue(params, "auth_user") != "") &&
|
||||
(Utils.paramValue(params, "auth_pass") == "")) {
|
||||
val aor = account.substringAfter("<").substringBefore(">")
|
||||
val builder = AlertDialog.Builder(this)
|
||||
builder.setTitle(String.format(getString(R.string.account_password), Utils.plainAor(aor)))
|
||||
val viewInflated = LayoutInflater.from(this)
|
||||
.inflate(R.layout.password_dialog, findViewById(android.R.id.content) as ViewGroup,
|
||||
false)
|
||||
val input = viewInflated.findViewById(R.id.password) as EditText
|
||||
builder.setView(viewInflated)
|
||||
builder.setPositiveButton(android.R.string.ok) { dialog, _ ->
|
||||
dialog.dismiss()
|
||||
val password = input.text.toString()
|
||||
if ((password.length < 1) || (password.length > 64) || !Utils.checkPrintAscii(password)) {
|
||||
Utils.alertView(this, getString(R.string.notice),
|
||||
String.format(getString(R.string.invalid_authentication_password), password))
|
||||
accounts.add(0, account)
|
||||
} else {
|
||||
aorPasswords.put(aor, password)
|
||||
}
|
||||
askAorPasswords(accounts)
|
||||
}
|
||||
builder.setNegativeButton(android.R.string.cancel) { dialog, _ ->
|
||||
dialog.cancel()
|
||||
aorPasswords.put(aor, "")
|
||||
askAorPasswords(accounts)
|
||||
}
|
||||
builder.show()
|
||||
} else {
|
||||
askAorPasswords(accounts)
|
||||
}
|
||||
} else {
|
||||
startBaresip()
|
||||
}
|
||||
}
|
||||
|
||||
private fun startBaresip() {
|
||||
baresipService.setAction("Start")
|
||||
startService(baresipService)
|
||||
Utils.requestPermission(this, Manifest.permission.RECORD_AUDIO,
|
||||
RECORD_PERMISSION_REQUEST_CODE)
|
||||
}
|
||||
|
||||
private fun backup(password: String) {
|
||||
val files = arrayListOf("accounts", "calls", "config", "contacts", "messages", "uuid",
|
||||
"zrtp_cache.dat", "zrtp_zid", "cert.pem", "ca_cert", "ca_certs.crt")
|
||||
@ -1365,6 +1414,7 @@ class MainActivity : AppCompatActivity() {
|
||||
var resumeUap = ""
|
||||
var resumeCall: Call? = null
|
||||
var resumeUri = ""
|
||||
val aorPasswords = mutableMapOf<String, String>()
|
||||
|
||||
const val ACCOUNTS_CODE = 1
|
||||
const val CONTACTS_CODE = 2
|
||||
|
||||
@ -97,6 +97,12 @@ object Utils {
|
||||
return if (domain == aor) "" else domain
|
||||
}
|
||||
|
||||
fun plainAor(aor: String): String {
|
||||
return aor.substringAfter(":").substringBefore("@") + "@" +
|
||||
aor.substringAfter("@").substringBefore(";")
|
||||
.substringBefore(":")
|
||||
}
|
||||
|
||||
fun checkAor(aor: String): Boolean {
|
||||
val p = aor.split(":")
|
||||
if (p.size == 2)
|
||||
|
||||
@ -38,16 +38,19 @@
|
||||
<string name="display_name_help">Tilin käyttäjän nimi, joka esiintyy
|
||||
SIP-sanomien From URI:ssa (vapaaehtoinen).</string>
|
||||
<string name="invalid_display_name">Virheellinen tilin käyttäjän nimi \'%1$s\'</string>
|
||||
<string name="authentication_username_password_mismatch">Käyttäjätunnus ja salasana ovat molemmat
|
||||
annettava ellei kumpikin ole tyhjä.
|
||||
<string name="authentication_username_password_mismatch">Salasanaa ei
|
||||
voi antaa ilman käyttäjätunnusta.
|
||||
</string>
|
||||
<string name="authentication_username">Käyttäjätunnus</string>
|
||||
<string name="authentication_username_help">Todentamiseen käytettävä
|
||||
käyttäjätunnus, jos välityspalvelin vaatii sellaisen.</string>
|
||||
käyttäjätunnus, jos välityspalvelin vaatii sellaisen.</string>
|
||||
<string name="invalid_authentication_username">Virheellinen käyttäjätunnus \'%1$s\'</string>
|
||||
<string name="authentication_password">Salasana</string>
|
||||
<string name="authentication_password_help">Todentamiseen käytettävä
|
||||
salasana, jos välityspalvelin vaatii sellaisen.</string>
|
||||
salasana, jonka pituus on enintään 64 ASCII merkkiä. Jos
|
||||
käyttäjätunnus on annettu, mutta salasanaa ei ole annettu, se
|
||||
kysytään, kun baresip käynnistetään.
|
||||
</string>
|
||||
<string name="invalid_authentication_password">Virheellinen salasana \'%1$s\'</string>
|
||||
<string name="outbound_proxies">Välityspalvelimet</string>
|
||||
<string name="outbound_proxies_help">Yhden tai kahden
|
||||
@ -356,4 +359,5 @@
|
||||
<string name="no_calls">Et voi soittaa puheluita tai vastata niihin
|
||||
ilman Mikrofoni-käyttöoikeutta.
|
||||
</string>
|
||||
<string name="account_password">Tilin %1$s salasana</string>
|
||||
</resources>
|
||||
|
||||
@ -41,8 +41,7 @@
|
||||
<string name="your_name">Your Name</string>
|
||||
<string name="display_name_help">Name (if any) used in From URI of outbound requests.</string>
|
||||
<string name="invalid_display_name">Invalid Display Name \'%1$s\'</string>
|
||||
<string name="authentication_username_password_mismatch">Autentication Username and Authentication
|
||||
Password must both be given or both must be empty.
|
||||
<string name="authentication_username_password_mismatch">Authentication Password cannot be given without Authentication Username.
|
||||
</string>
|
||||
<string name="authentication_username">Authentication Username</string>
|
||||
<string name="authentication_username_help">Authentication username if authentication of SIP
|
||||
@ -50,8 +49,9 @@
|
||||
</string>
|
||||
<string name="invalid_authentication_username">Invalid Authentication Username \'%1$s\'</string>
|
||||
<string name="authentication_password">Authentication Password</string>
|
||||
<string name="authentication_password_help">Authentication password if authentication of SIP
|
||||
requests is required.
|
||||
<string name="authentication_password_help">Authentication
|
||||
Password up to 64 characters. If Authentication Username is given, but Password is not
|
||||
given, it will be asked when baresip is started.
|
||||
</string>
|
||||
<string name="invalid_authentication_password">Invalid Authentication Password \'%1$s\'</string>
|
||||
<string name="outbound_proxies">Outbound Proxies</string>
|
||||
@ -318,4 +318,5 @@
|
||||
and, if so, you gave correct Decrypt Password.
|
||||
</string>
|
||||
<string name="no_calls">You are not able to place or answer calls without Microphone permission.</string>
|
||||
</resources>
|
||||
<string name="account_password">Account %1$s Authentication Password</string>
|
||||
</resources>
|
||||
|
||||
@ -7,7 +7,7 @@ buildscript {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.5.3'
|
||||
classpath 'com.android.tools.build:gradle:3.6.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
||||
3
gradle/wrapper/gradle-wrapper.properties
vendored
3
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,6 @@
|
||||
#Tue Mar 17 05:24:25 EET 2020
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
|
||||
|
||||
Reference in New Issue
Block a user