Support banner during authentication#151
Merged
Merged
Conversation
Some authentication methods use out-of-band authentication where the user is prompted to take action using the SSH_MSG_USERAUTH_BANNER message from the server. Support this by adding a new onBanner callback to the AuthHandler.
Contributor
There was a problem hiding this comment.
Pull request overview
Adds support for SSH SSH_MSG_USERAUTH_BANNER during the strategy-based AuthHandler authentication flow, including a new callback so consumers can surface out-of-band instructions (e.g., MFA URLs) to users.
Changes:
- Add
AuthHandler.onBanner(message: String)callback and plumb banner delivery throughSshConnection’s auth result channel. - Extend
FakeSshServerand add a new unit test to validate banner delivery during auth. - Move Spotless configuration to the root project and introduce a shared license header template.
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| sshlib/src/test/kotlin/org/connectbot/sshlib/client/SshAuthBannerTest.kt | New test validating that auth banners are delivered to AuthHandler.onBanner. |
| sshlib/src/test/kotlin/org/connectbot/sshlib/client/FakeSshServer.kt | Adds helper methods to emit USERAUTH_BANNER and USERAUTH_FAILURE in tests. |
| sshlib/src/main/kotlin/org/connectbot/sshlib/client/SshConnection.kt | Routes SSH_MSG_USERAUTH_BANNER into the auth flow and forwards it to the handler. |
| sshlib/src/main/kotlin/org/connectbot/sshlib/client/AuthResult.kt | Adds an internal Banner auth result type. |
| sshlib/src/main/kotlin/org/connectbot/sshlib/AuthHandler.kt | Adds the onBanner callback with a default implementation. |
| sshlib/build.gradle.kts | Removes per-module Spotless configuration (now centralized). |
| spotless/license-header.txt | Adds a shared license header template for Spotless. |
| build.gradle.kts | Centralizes Spotless configuration at the root and applies the license header step. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+552
to
+573
| fun sendUserauthBanner(message: String) { | ||
| scope.launch(coroutineContext) { | ||
| val banner = SshMsgUserauthBanner() | ||
| val utf8 = createUtf8String(message) | ||
| banner.setMessage(utf8) | ||
| banner.setLanguageTag(createByteString(ByteArray(0))) | ||
| banner._check() | ||
| writeMutex.withLock { | ||
| serverIo.writePacket(SshEnums.MessageType.SSH_MSG_USERAUTH_BANNER.id().toInt(), banner.toByteArray()) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| fun sendUserauthFailure(allowedMethods: Set<String>, partialSuccess: Boolean) { | ||
| scope.launch(coroutineContext) { | ||
| val failure = SshMsgUserauthFailure() | ||
| failure.setValidAuthentications(createNameList(allowedMethods.joinToString(","))) | ||
| failure.setPartialSuccess(if (partialSuccess) 1 else 0) | ||
| failure._check() | ||
| writeMutex.withLock { | ||
| serverIo.writePacket(SshEnums.MessageType.SSH_MSG_USERAUTH_FAILURE.id().toInt(), failure.toByteArray()) | ||
| } |
Comment on lines
+107
to
+109
| authJob.join() | ||
|
|
||
| assertEquals(bannerText, bannerReceived.await()) |
Comment on lines
+1653
to
+1658
| val ch = authResultChannel | ||
| if (ch != null) { | ||
| val message = msg.message().value() | ||
| if (ch.trySend(InternalAuthResult.Banner(message)).isFailure) { | ||
| logger.warn("Failed to deliver banner to auth channel") | ||
| } |
Comment on lines
+747
to
+751
| var noneResult = channel.receive() | ||
| while (noneResult is InternalAuthResult.Banner) { | ||
| handler.onBanner(noneResult.message) | ||
| noneResult = channel.receive() | ||
| } |
Comment on lines
+97
to
+100
| // Wait for server to receive the "none" auth request | ||
| // FakeSshServer doesn't have a way to await auth request easily, but we can just wait a bit or use yield | ||
| yield() | ||
|
|
| import kotlinx.coroutines.yield | ||
| import org.connectbot.sshlib.AuthHandler | ||
| import org.connectbot.sshlib.AuthPublicKey | ||
| import org.connectbot.sshlib.AuthResult |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Some authentication methods use out-of-band authentication where the user
is prompted to take action using the SSH_MSG_USERAUTH_BANNER message from
the server. Support this by adding a new onBanner callback to the
AuthHandler.