UI update: has an x if failed testexec, withanimation cleanup
new hostkey variable
getHostKey returns Data
This commit is contained in:
neon443
2025-06-07 16:06:45 +01:00
parent 5e493c4865
commit 5199158e04
5 changed files with 43 additions and 19 deletions

View File

@@ -1,6 +1,7 @@
{
"images" : [
{
"filename" : "ShhShell.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

BIN
ShhShell.pxd Normal file
View File

Binary file not shown.

View File

@@ -10,7 +10,7 @@ import LibSSH
import OSLog
class SSHHandler: ObservableObject {
var session: ssh_session?
private var session: ssh_session?
@Published var authorized: Bool = false
@Published var username: String
@@ -18,6 +18,8 @@ class SSHHandler: ObservableObject {
@Published var address: String
@Published var port: Int
@Published var hostkey: Data?
private let logger = Logger(subsystem: "xy", category: "sshHandler")
init(
@@ -38,22 +40,23 @@ class SSHHandler: ObservableObject {
#endif
}
func getHostkey() {
func getHostkey() -> Data? {
var hostkey: ssh_key?
ssh_get_server_publickey(session, &hostkey)
var hostkeyB64: UnsafeMutablePointer<CChar>? = nil
if ssh_pki_export_pubkey_base64(hostkey, &hostkeyB64) == SSH_OK {
if let hostkeyB64 = hostkeyB64 {
print(String(cString: hostkeyB64))
}
}
let status = ssh_pki_export_pubkey_base64(hostkey, &hostkeyB64)
guard status == SSH_OK else { return nil }
guard let data = hostkeyB64 else { return nil }
return Data(base64Encoded: String(cString: data))
}
func connect() -> Bool {
defer {
getAuthMethods()
getHostkey()
self.hostkey = getHostkey()
}
var verbosity: Int = 0
@@ -85,6 +88,7 @@ class SSHHandler: ObservableObject {
ssh_free(session)
session = nil
authorized = false
hostkey = nil
}
func testExec() -> Bool {
@@ -262,7 +266,7 @@ class SSHHandler: ObservableObject {
ssh_channel_free(channel)
}
func interactiveShellSession(channel: ssh_channel) {
private func interactiveShellSession(channel: ssh_channel) {
var status: CInt
status = ssh_channel_request_pty(channel)

View File

@@ -10,19 +10,28 @@ import SwiftUI
struct ContentView: View {
@ObservedObject var handler: SSHHandler
@State var connected: Bool = false
@State var testSucceded: Bool = false
@State var testSucceded: Bool?
var body: some View {
VStack {
Text(connected ? "connected" : "not connected")
.foregroundStyle(connected ? .green : .red)
Text(handler.authorized ? "authorized" : "unauthorized")
.foregroundStyle(handler.authorized ? .green : .red)
if testSucceded {
Image(systemName: "checkmark.circle")
if let testSucceded = testSucceded {
Image(systemName: testSucceded ? "checkmark.circle" : "xmark.circle")
.foregroundStyle(testSucceded ? .green : .red)
}
if handler.hostkey != nil {
Text("Hostkey: \(handler.hostkey!.base64EncodedString())")
}
TextField("address", text: $handler.address)
.textFieldStyle(.roundedBorder)
TextField(
"port",
text: Binding(
@@ -31,8 +40,10 @@ struct ContentView: View {
)
.keyboardType(.numberPad)
.textFieldStyle(.roundedBorder)
TextField("username", text: $handler.username)
.textFieldStyle(.roundedBorder)
TextField("password", text: $handler.password)
.textFieldStyle(.roundedBorder)
@@ -42,19 +53,27 @@ struct ContentView: View {
}
handler.authWithPw()
}
.disabled(connected)
Button("disconnect") {
handler.disconnect()
withAnimation { testSucceded = false }
withAnimation { connected = false }
withAnimation { testSucceded = nil }
}
.disabled(!connected)
Button("run a test command") {
withAnimation {
if handler.testExec() {
testSucceded = true
withAnimation { testSucceded = true }
} else {
testSucceded = false
withAnimation { testSucceded = false }
}
}
.disabled(!(connected && handler.authorized))
Button("request a shell") {
handler.openShell()
}
}
}