Skip to content

Commit 539ede6

Browse files
author
Andrey
committed
Fix: Correct SMB1 connection validation; now caches contexts/sessions only if connection succeeds, preventing invalid credentials from being stored
1 parent 79ed7e6 commit 539ede6

File tree

4 files changed

+52
-32
lines changed

4 files changed

+52
-32
lines changed

app/src/main/java/com/raival/compose/file/explorer/screen/main/tab/files/holder/SMB1FileHolder.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,10 @@ class SMB1FileHolder(
8484

8585
override suspend fun isValid(): Boolean = withContext(Dispatchers.IO) {
8686
try {
87-
getSmbFile().exists()
87+
val file = getSmbFile()
88+
file.connect() // fuerza la conexión al servidor
89+
file.list() // opcional: lista el directorio para asegurarte que existe
90+
true
8891
} catch (e: Exception) {
8992
false
9093
}

app/src/main/java/com/raival/compose/file/explorer/screen/main/tab/files/smb/SMB1ConnectionManager.kt

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,27 @@ object SMB1ConnectionManager {
2828
anonymous: Boolean
2929
): CIFSContext {
3030
val key = "$host|$port|$share|${username ?: "anon"}|$anonymous"
31-
return contexts[key] ?: run {
32-
val baseContext = SingletonContext.getInstance() as BaseContext
33-
val context = if (anonymous || username.isNullOrBlank()) {
34-
baseContext.withAnonymousCredentials()
35-
} else {
36-
val auth = NtlmPasswordAuthenticator(domain ?: "", username, password)
37-
baseContext.withCredentials(auth)
38-
}
39-
contexts[key] = context
40-
context
31+
32+
contexts[key]?.let { return it }
33+
34+
val baseContext = SingletonContext.getInstance() as BaseContext
35+
val context = if (anonymous || username.isNullOrBlank()) {
36+
baseContext.withAnonymousCredentials()
37+
} else {
38+
val auth = NtlmPasswordAuthenticator(domain ?: "", username, password)
39+
baseContext.withCredentials(auth)
4140
}
41+
42+
val testUrl = "smb://$host:$port/$share/"
43+
try {
44+
val file = SmbFile(testUrl, context)
45+
file.connect()
46+
} catch (e: Exception) {
47+
throw RuntimeException("Unable to connect to SMB1 share: $testUrl", e)
48+
}
49+
50+
contexts[key] = context
51+
return context
4252
}
4353

4454
fun getFile(

app/src/main/java/com/raival/compose/file/explorer/screen/main/tab/files/smb/SMBConnectionManager.kt

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,40 @@ object SMBConnectionManager {
99

1010
fun getSession(
1111
host: String,
12-
port: Int = 445, // default smb port 445
12+
port: Int = 445,
1313
username: String?,
1414
password: String?,
1515
domain: String?,
1616
anonymous: Boolean
1717
): Session {
1818
val key = "$domain|$host|$port|${username ?: "anon"}"
19-
return clients[key] ?: run {
20-
val client = SMBClient()
21-
val connection = client.connect(host, port)
22-
val session = if (anonymous || username.isNullOrBlank()) {
19+
clients[key]?.let { return it }
20+
21+
val client = SMBClient()
22+
val connection = client.connect(host, port)
23+
val session = try {
24+
if (anonymous || username.isNullOrBlank()) {
2325
connection.authenticate(null)
2426
} else {
2527
connection.authenticate(
2628
AuthenticationContext(username, password?.toCharArray(), domain)
2729
)
2830
}
29-
clients[key] = session
30-
session
31+
} catch (e: Exception) {
32+
connection.close()
33+
throw RuntimeException("Authentication failed for $username@$host:$port", e)
34+
}
35+
36+
try {
37+
val share = session.connectShare("IPC$") // share estándar que siempre existe
38+
share.close()
39+
} catch (e: Exception) {
40+
session.logoff()
41+
throw RuntimeException("Session could not access share. Bad credentials?", e)
3142
}
43+
44+
clients[key] = session
45+
return session
3246
}
47+
3348
}

app/src/main/java/com/raival/compose/file/explorer/screen/main/ui/AddSMBDriveDialog.kt

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -267,22 +267,14 @@ fun AddSMBDriveDialog(
267267
modifier = Modifier.weight(1f),
268268
onClick = {
269269
CoroutineScope(Dispatchers.IO).launch {
270-
val port = portText.toIntOrNull() ?: 445
270+
val smb1Port = portText.toIntOrNull() ?: 139
271+
val smb2Port = portText.toIntOrNull() ?: 445
271272

272273
val success = when (smbVersion) {
273-
smb1Text -> mainActivityManager.addSmb1Drive(
274-
host, port, username, password, anonymous, domain, context
275-
)
276-
smb2Text -> mainActivityManager.addSmbDrive(
277-
host, port, username, password, anonymous, domain, context
278-
)
279-
else -> {
280-
mainActivityManager.addSmbDrive(
281-
host, port, username, password, anonymous, domain, context
282-
) || mainActivityManager.addSmb1Drive(
283-
host, port, username, password, anonymous, domain, context
284-
)
285-
}
274+
smb1Text -> mainActivityManager.addSmb1Drive(host, smb1Port, username, password, anonymous, domain, context)
275+
smb2Text -> mainActivityManager.addSmbDrive(host, smb2Port, username, password, anonymous, domain, context)
276+
else -> mainActivityManager.addSmbDrive(host, smb2Port, username, password, anonymous, domain, context)
277+
|| mainActivityManager.addSmb1Drive(host, smb1Port, username, password, anonymous, domain, context)
286278
}
287279

288280
withContext(Dispatchers.Main) {

0 commit comments

Comments
 (0)