ui to show if conneced, auth and if test succeeded

working on requesting and displaying a shell
This commit is contained in:
neon443
2025-06-07 14:55:29 +01:00
parent f979ea4e9c
commit 5e493c4865
2 changed files with 108 additions and 59 deletions

View File

@@ -52,8 +52,8 @@ class SSHHandler: ObservableObject {
func connect() -> Bool { func connect() -> Bool {
defer { defer {
getHostkey()
getAuthMethods() getAuthMethods()
getHostkey()
} }
var verbosity: Int = 0 var verbosity: Int = 0
@@ -89,10 +89,8 @@ class SSHHandler: ObservableObject {
func testExec() -> Bool { func testExec() -> Bool {
if ssh_is_connected(session) == 0 { if ssh_is_connected(session) == 0 {
if !connect() {
return false return false
} }
}
guard authorized else { return false } guard authorized else { return false }
@@ -178,58 +176,58 @@ class SSHHandler: ObservableObject {
return true return true
} }
func authWithKbInt() -> Bool { // func authWithKbInt() -> Bool {
var status: CInt // var status: CInt
status = ssh_userauth_kbdint(session, nil, nil) // status = ssh_userauth_kbdint(session, nil, nil)
while status == SSH_AUTH_INFO.rawValue { // while status == SSH_AUTH_INFO.rawValue {
let name, instruction: String // let name, instruction: String
var nprompts: CInt // var nprompts: CInt
//
if let namePtr = ssh_userauth_kbdint_getname(session) { // if let namePtr = ssh_userauth_kbdint_getname(session) {
name = String(cString: namePtr) // name = String(cString: namePtr)
} else { // } else {
return false // return false
} // }
if let instrPtr = ssh_userauth_kbdint_getinstruction(session) { // if let instrPtr = ssh_userauth_kbdint_getinstruction(session) {
instruction = String(cString: instrPtr) // instruction = String(cString: instrPtr)
} else { // } else {
return false // return false
} // }
nprompts = ssh_userauth_kbdint_getnprompts(session) // nprompts = ssh_userauth_kbdint_getnprompts(session)
//
if name.count > 0 { // if name.count > 0 {
print(name) // print(name)
} // }
if instruction.count > 0 { // if instruction.count > 0 {
print(instruction) // print(instruction)
} // }
for promptI in 0..<nprompts { // for promptI in 0..<nprompts {
let prompt: UnsafePointer<CChar> // let prompt: UnsafePointer<CChar>
var echo: CChar = 0 // var echo: CChar = 0
prompt = ssh_userauth_kbdint_getprompt(session, UInt32(promptI), &echo) // prompt = ssh_userauth_kbdint_getprompt(session, UInt32(promptI), &echo)
if echo != 0 { // if echo != 0 {
var buffer: [CChar] = Array(repeating: 0, count: 128) // var buffer: [CChar] = Array(repeating: 0, count: 128)
let ptr: UnsafeMutablePointer<CChar> = .init(mutating: buffer) // let ptr: UnsafeMutablePointer<CChar> = .init(mutating: buffer)
print(prompt) // print(prompt)
if fgets(&buffer, Int32(MemoryLayout.size(ofValue: buffer)), stdin) == nil { // if fgets(&buffer, Int32(MemoryLayout.size(ofValue: buffer)), stdin) == nil {
return false // return false
} // }
ptr.pointee = 0//prob fucked // ptr.pointee = 0//prob fucked
if ssh_userauth_kbdint_setanswer(session, UInt32(promptI), buffer) < 0 { // if ssh_userauth_kbdint_setanswer(session, UInt32(promptI), buffer) < 0 {
return false // return false
} // }
memset(&buffer, 0, buffer.count) // memset(&buffer, 0, buffer.count)
} else { // } else {
if (ssh_userauth_kbdint_setanswer(session, UInt32(promptI), &password) != 0) { // if (ssh_userauth_kbdint_setanswer(session, UInt32(promptI), &password) != 0) {
return false // return false
} // }
} // }
} // }
status = ssh_userauth_kbdint(session, nil, nil) // status = ssh_userauth_kbdint(session, nil, nil)
} // }
authorized = true // authorized = true
return true // return true
} // }
func authWithNone() -> Bool { func authWithNone() -> Bool {
let status = ssh_userauth_none(session, nil) let status = ssh_userauth_none(session, nil)
@@ -245,6 +243,38 @@ class SSHHandler: ObservableObject {
method = ssh_userauth_list(session, username) method = ssh_userauth_list(session, username)
} }
func openShell() {
var status: CInt
let channel = ssh_channel_new(session)
guard let channel = channel else { return }
status = ssh_channel_open_session(channel)
guard status == SSH_OK else {
ssh_channel_free(channel)
return
}
interactiveShellSession(channel: channel)
ssh_channel_close(channel)
ssh_channel_send_eof(channel)
ssh_channel_free(channel)
}
func interactiveShellSession(channel: ssh_channel) {
var status: CInt
status = ssh_channel_request_pty(channel)
guard status == SSH_OK else { return }
status = ssh_channel_change_pty_size(channel, 80, 24)
guard status == SSH_OK else { return }
status = ssh_channel_request_shell(channel)
guard status == SSH_OK else { return }
}
func logSshGetError() { func logSshGetError() {
logger.critical("\(String(cString: ssh_get_error(&self.session)))") logger.critical("\(String(cString: ssh_get_error(&self.session)))")
} }

View File

@@ -9,9 +9,18 @@ import SwiftUI
struct ContentView: View { struct ContentView: View {
@ObservedObject var handler: SSHHandler @ObservedObject var handler: SSHHandler
@State var connected: Bool = false
@State var testSucceded: Bool = false
var body: some View { var body: some View {
VStack { 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")
}
TextField("address", text: $handler.address) TextField("address", text: $handler.address)
.textFieldStyle(.roundedBorder) .textFieldStyle(.roundedBorder)
TextField( TextField(
@@ -27,15 +36,25 @@ struct ContentView: View {
TextField("password", text: $handler.password) TextField("password", text: $handler.password)
.textFieldStyle(.roundedBorder) .textFieldStyle(.roundedBorder)
Button("connect & auth") { Button("connect") {
handler.connect() if handler.connect() {
withAnimation { connected = true }
}
handler.authWithPw() handler.authWithPw()
} }
Button("disconnect") { Button("disconnect") {
handler.disconnect() handler.disconnect()
withAnimation { testSucceded = false }
withAnimation { connected = false}
}
Button("run a test command") {
withAnimation {
if handler.testExec() {
testSucceded = true
} else {
testSucceded = false
}
} }
Button("testExec") {
handler.testExec()
} }
} }
} }