10000 feat: authentication support fallback by hstyi · Pull Request #431 · TermoraDev/termora · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

feat: authentication support fallback #431

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions src/main/java/app/termora/CombinedKeyIdentityProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package app.termora;

import org.apache.sshd.common.keyprovider.KeyIdentityProvider;
import org.apache.sshd.common.session.SessionContext;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyPair;
import java.util.*;

public class CombinedKeyIdentityProvider implements KeyIdentityProvider {

private final List<KeyIdentityProvider> providers = new ArrayList<>();

@Override
public Iterable<KeyPair> loadKeys(SessionContext context) {
return () -> new Iterator<>() {

private final Iterator<KeyIdentityProvider> factories = providers
.iterator();
private Iterator<KeyPair> current;

private Boolean hasElement;

@Override
public boolean hasNext() {
if (hasElement != null) {
return hasElement;
}
while (current == null || !current.hasNext()) {
if (factories.hasNext()) {
try {
current = factories.next().loadKeys(context)
.iterator();
} catch (IOException | GeneralSecurityException e) {
throw new RuntimeException(e);
}
} else {
current = null;
hasElement = Boolean.FALSE;
return false;
}
}
hasElement = Boolean.TRUE;
return true;
}

@Override
public KeyPair next() {
if ((hasElement == null && !hasNext()) || !hasElement) {
throw new NoSuchElementException();
}
hasElement = null;
KeyPair result;
try {
result = current.next();
} catch (NoSuchElementException e) {
result = null;
}
return result;
}

};
}

public void addKeyKeyIdentityProvider(KeyIdentityProvider provider) {
providers.add(Objects.requireNonNull(provider));
}
}
4 changes: 1 addition & 3 deletions src/main/kotlin/app/termora/HostDialog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package app.termora

import app.termora.actions.AnAction
import app.termora.actions.AnActionEvent
import app.termora.keyboardinteractive.TerminalUserInteraction
import kotlinx.coroutines.*
import kotlinx.coroutines.swing.Swing
import org.apache.commons.lang3.exception.ExceptionUtils
Expand Down Expand Up @@ -103,8 +102,7 @@ class HostDialog(owner: Window, host: Host? = null) : DialogWrapper(owner) {
var client: SshClient? = null
var session: ClientSession? = null
try {
client = SshClients.openClient(host)
client.userInteraction = TerminalUserInteraction(owner)
client = SshClients.openClient(host, this)
session = SshClients.openSession(host, client)
} finally {
session?.close()
Expand Down
8 changes: 6 additions & 2 deletions src/main/kotlin/app/termora/RequestAuthenticationDialog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ class RequestAuthenticationDialog(owner: Window, host: Host) : DialogWrapper(own
pack()

size = Dimension(max(380, size.width), size.height)

setLocationRelativeTo(null)
preferredSize = size
minimumSize = size

publicKeyComboBox.renderer = object : DefaultListCellRenderer() {
override fun getListCellRendererComponent(
Expand Down Expand Up @@ -65,6 +65,10 @@ class RequestAuthenticationDialog(owner: Window, host: Host) : DialogWrapper(own
}
}

if (host.authentication.type != AuthenticationType.No) {
authenticationTypeComboBox.selectedItem = host.authentication.type
}

usernameTextField.text = host.username

}
Expand Down
3 changes: 2 additions & 1 deletion src/main/kotlin/app/termora/SFTPPtyTerminalTab.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class SFTPPtyTerminalTab(windowScope: WindowScope, host: Host) : PtyHostTerminal
private var lastPasswordReporterDataListener: PasswordReporterDataListener? = null
private val sftpCommand get() = Database.getDatabase().sftp.sftpCommand
private val defaultDirectory get() = Database.getDatabase().sftp.defaultDirectory
private val owner get() = SwingUtilities.getWindowAncestor(terminalPanel)

init {
terminalPanel.dropFiles = true
Expand Down Expand Up @@ -67,7 +68,7 @@ class SFTPPtyTerminalTab(windowScope: WindowScope, host: Host) : PtyHostTerminal
)
)

val sshClient = SshClients.openClient(host).apply { sshClient = this }
val sshClient = SshClients.openClient(host, owner).apply { sshClient = this }
val sshSession = SshClients.openSession(host, sshClient).apply { sshSession = this }

// 打开通道
Expand Down
30 changes: 1 addition & 29 deletions src/main/kotlin/app/termora/SSHTerminalTab.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import app.termora.actions.AnActionEvent
import app.termora.actions.DataProviders
import app.termora.actions.TabReconnectAction
import app.termora.addons.zmodem.ZModemPtyConnectorAdaptor
import app.termora.keyboardinteractive.TerminalUserInteraction
import app.termora.keymap.KeyShortcut
import app.termora.keymap.KeymapManager
import app.termora.terminal.ControlCharacters
Expand Down Expand Up @@ -89,35 +88,8 @@ class SSHTerminalTab(windowScope: WindowScope, host: Host) :
terminal.write("SSH client is opening...\r\n")
}

var host =
this.host.copy(authentication = this.host.authentication.copy(), updateDate = System.currentTimeMillis())
val owner = SwingUtilities.getWindowAncestor(terminalPanel)
val client = SshClients.openClient(host).also { sshClient = it }
client.serverKeyVerifier = DialogServerKeyVerifier(owner)
// keyboard interactive
client.userInteraction = TerminalUserInteraction(owner)

if (host.authentication.type == AuthenticationType.No) {
withContext(Dispatchers.Swing) {
val dialog = RequestAuthenticationDialog(owner, host)
val authentication = dialog.getAuthentication()
host = host.copy(
authentication = authentication,
username = dialog.getUsername(),
updateDate = System.currentTimeMillis(),
)
// save
if (dialog.isRemembered()) {
HostManager.getInstance().addHost(
tab.host.copy(
authentication = authentication,
username = dialog.getUsername(), updateDate = System.currentTimeMillis(),
)
)
}
}
}

val client = SshClients.openClient(host, owner).also { sshClient = it }
val sessionListener = MySessionListener()
val channelListener = MyChannelListener()

Expand Down
Loading
0