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

View File

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