Validate Telecom request identity and contain extras decoding errors

This commit is contained in:
evgeny committed 2026-10-29 13:34:25 +01:00
1 parent 482e1658b0
commit 90e33f568b
2 files changed
+35 -14

No files matched your search

@@ -61,6 +61,7 @@ object TelecomCallManager {
/** Инициализация из ChatApplication.onCreate: регистрирует PhoneAccount. Идемпотентно. */
fun init() {
checkMain()
if (ready) return
try {
val ctx = ChatApplication.instance
@@ -129,6 +130,7 @@ object TelecomCallManager {
/* ── реестр Connection (вызывается из UtunConnectionService) ── */
fun registerConnection(callId: Long, conn: UtunConnection): Boolean {
checkMain()
val st = CallController.state.value
if (st == null || st.callId != callId || !st.ongoing) {
LogManager.addLog("WARN", TAG, "late connection for ended/stale call id=$callId current=${st?.callId}")
@@ -173,14 +175,17 @@ object TelecomCallManager {
/* ── управление состоянием из контроллера ── */
fun setRinging(callId: Long) {
checkMain()
try { connections[callId]?.markRinging() } catch (e: Exception) { LogManager.addLog("ERROR", TAG, "ringing state failed id=$callId: $e") }
}
fun setActive(callId: Long) {
checkMain()
try { connections[callId]?.markActive() } catch (e: Exception) { LogManager.addLog("ERROR", TAG, "active state failed id=$callId: $e") }
}
fun setDisconnected(callId: Long, reason: Int) {
checkMain()
val conn = connections[callId] ?: return
reasons[conn] = reason
try { conn.markDisconnected(reason); disconnected.add(conn) } catch (e: Exception) {
@@ -189,6 +194,7 @@ object TelecomCallManager {
}
fun removeConnection(callId: Long) {
checkMain()
val conn = connections.remove(callId)
if (conn != null) retire(callId, conn, reasons[conn] ?: 0) else cleanupConnections()
LogManager.addLog("DEBUG", TAG, "connection removed id=0x%016x".format(callId))
@@ -218,6 +224,11 @@ object TelecomCallManager {
/* ── helpers ── */
private fun checkMain() = check(Looper.myLooper() == Looper.getMainLooper()) {
LogManager.addLog("ERROR", TAG, "Telecom owner mutation outside main")
"Telecom owner mutation requires main"
}
private fun telecomManager(): TelecomManager? {
if (!ready) { LogManager.addLog("WARN", TAG, "Telecom request before account registration"); return null }
return try {
@@ -16,13 +16,13 @@ import android.telecom.DisconnectCause
class UtunConnectionService : ConnectionService() {
override fun onCreateIncomingConnectionFailed(account: PhoneAccountHandle?, request: ConnectionRequest?) {
val id = request?.extras?.getLong(TelecomCallManager.EXTRA_CALL_ID, 0) ?: 0
val id = requestId(request)
LogManager.addLog("WARN", "UtunConnSvc", "Telecom rejected incoming call id=$id")
TelecomCallManager.notifyConnectionFailed(id)
}
override fun onCreateOutgoingConnectionFailed(account: PhoneAccountHandle?, request: ConnectionRequest?) {
val id = request?.extras?.getLong(TelecomCallManager.EXTRA_CALL_ID, 0) ?: 0
val id = requestId(request)
LogManager.addLog("WARN", "UtunConnSvc", "Telecom rejected outgoing call id=$id")
TelecomCallManager.notifyConnectionFailed(id)
}
@@ -33,6 +33,7 @@ class UtunConnectionService : ConnectionService() {
): Connection? {
val (callId, peerNodeId, name) = parseRequest(request) ?: run {
LogManager.addLog("WARN", "UtunConnSvc", "onCreateIncomingConnection: bad request extras")
TelecomCallManager.notifyConnectionFailed(requestId(request))
return Connection.createCanceledConnection()
}
LogManager.addLog("INFO", "UtunConnSvc",
@@ -46,6 +47,7 @@ class UtunConnectionService : ConnectionService() {
): Connection? {
val (callId, peerNodeId, name) = parseRequest(request) ?: run {
LogManager.addLog("WARN", "UtunConnSvc", "onCreateOutgoingConnection: bad request extras")
TelecomCallManager.notifyConnectionFailed(requestId(request))
return Connection.createCanceledConnection()
}
LogManager.addLog("INFO", "UtunConnSvc",
@@ -64,18 +66,26 @@ class UtunConnectionService : ConnectionService() {
}
}
private fun parseRequest(request: ConnectionRequest?): Triple<Long, Long, String>? {
val extras = request?.extras ?: run {
LogManager.addLog("WARN", "UtunConnSvc", "connection request has no extras")
return null
private fun requestId(request: ConnectionRequest?): Long = try {
request?.extras?.getLong(TelecomCallManager.EXTRA_CALL_ID, 0) ?: 0
} catch (e: Exception) {
LogManager.addLog("ERROR", "UtunConnSvc", "connection request ID decode failed: $e"); 0
}
private fun parseRequest(request: ConnectionRequest?): Triple<Long, Long, String>? = try {
val extras = request?.extras
if (extras == null) {
LogManager.addLog("WARN", "UtunConnSvc", "connection request has no extras"); null
} else {
val callId = extras.getLong(TelecomCallManager.EXTRA_CALL_ID, 0L)
val peer = extras.getLong(TelecomCallManager.EXTRA_PEER_NODE_ID, 0L)
val name = extras.getString(TelecomCallManager.EXTRA_DISPLAY_NAME) ?: ""
if (callId == 0L || peer == 0L) {
LogManager.addLog("WARN", "UtunConnSvc", "connection request missing identity id=$callId peer=$peer; keys=${extras.keySet()}")
null
} else Triple(callId, peer, name)
}
val callId = extras.getLong(TelecomCallManager.EXTRA_CALL_ID, 0L)
val peer = extras.getLong(TelecomCallManager.EXTRA_PEER_NODE_ID, 0L)
val name = extras.getString(TelecomCallManager.EXTRA_DISPLAY_NAME) ?: ""
if (callId == 0L) {
LogManager.addLog("WARN", "UtunConnSvc", "connection request missing call ID; keys=${extras.keySet()}")
return null
}
return Triple(callId, peer, name)
} catch (e: Exception) {
LogManager.addLog("ERROR", "UtunConnSvc", "connection request extras decode failed: $e"); null
}
}