rewrite testExec

add authWithPw and authWithPubkey
cleaned up logging
keyboardinteractive auth doesnt work
This commit is contained in:
neon443
2025-06-06 19:43:00 +01:00
parent 9b71bcde57
commit 8d68125b3f
3 changed files with 122 additions and 43 deletions

View File

@@ -7,10 +7,13 @@
import Foundation import Foundation
import LibSSH import LibSSH
import OSLog
class SSHHandler: ObservableObject { class SSHHandler: ObservableObject {
var session: ssh_session? var session: ssh_session?
private let logger = Logger(subsystem: "xy", category: "sshHandler")
init() { init() {
// session = ssh_new() // session = ssh_new()
// guard session != nil else { return } // guard session != nil else { return }
@@ -30,7 +33,11 @@ class SSHHandler: ObservableObject {
ssh_options_set(session, SSH_OPTIONS_PORT, &port) ssh_options_set(session, SSH_OPTIONS_PORT, &port)
let status = ssh_connect(session) let status = ssh_connect(session)
print(status) if status != SSH_OK {
logger.critical("connection not ok: \(status)")
logSshGetError()
fatalError()
}
} }
func disconnect() { func disconnect() {
@@ -41,15 +48,15 @@ class SSHHandler: ObservableObject {
func hardcodedAuth() { func hardcodedAuth() {
var hostkey: ssh_key? var hostkey: ssh_key?
ssh_get_server_publickey(session, &hostkey) ssh_get_server_publickey(session, &hostkey)
print("hostkey \(hostkey)") if let hostkey = hostkey {
print("hostkey \(hostkey)")
}
let password = "root" let password = "root"
let rc = ssh_userauth_password(session, "root", password) let rc = ssh_userauth_password(session, "root", password)
if rc != SSH_AUTH_SUCCESS.rawValue { if rc != SSH_AUTH_SUCCESS.rawValue {
print("auth failure") print("auth failure")
} else {
print("yay success")
} }
} }
@@ -59,51 +66,123 @@ class SSHHandler: ObservableObject {
hardcodedAuth() hardcodedAuth()
var channel: ssh_channel? var status: CInt
var rc: Int32 var buffer: [Int] = Array(repeating: 0, count: 256)
var buffer: [CChar] = Array(repeating: 0, count: 256) var nbytes: CInt
var nbytes: Int32
channel = ssh_channel_new(session) let channel = ssh_channel_new(session)
if channel == nil { guard channel != nil else { fatalError("noChannel") }
fatalError("couldnt create channel \(SSH_ERROR)")
}
rc = ssh_channel_open_session(channel) status = ssh_channel_open_session(channel)
if rc != SSH_OK { guard status == SSH_OK else {
ssh_channel_free(channel) ssh_channel_free(channel)
print("channel opened \(rc)") logger.critical("session opening error")
logSshGetError()
return
} }
rc = ssh_channel_request_exec(channel, "uptime") status = ssh_channel_request_exec(channel, "uptime")
if rc != SSH_OK { guard status == SSH_OK else {
ssh_channel_close(channel) ssh_channel_close(channel)
ssh_channel_free(channel) ssh_channel_free(channel)
print("exec request worked \(rc)") logger.critical("session opening error")
logSshGetError()
return
} }
nbytes = ssh_channel_read(channel, &buffer, UInt32(buffer.count), 0) nbytes = ssh_channel_read(
channel,
&buffer,
UInt32(MemoryLayout.size(ofValue: CChar.self)),
0
)
while nbytes > 0 { while nbytes > 0 {
let written = write(1, buffer, Int(nbytes)) let written = write(1, buffer, Int(nbytes))
if written != Int(nbytes) { guard written == Int(nbytes) else {
ssh_channel_close(channel) ssh_channel_close(channel)
ssh_channel_free(channel) ssh_channel_free(channel)
fatalError("buffer write error \(SSH_ERROR)") logger.critical("write error")
logSshGetError()
return
} }
buffer = [CChar](repeating: 0, count: 256) //clear buffer nbytes = ssh_channel_read(channel, &buffer, UInt32(MemoryLayout.size(ofValue: Character.self)), 0)
nbytes = ssh_channel_read(channel, &buffer, UInt32(buffer.count), 0)
} }
if nbytes < 0 { if nbytes < 0 {
ssh_channel_close(channel) ssh_channel_close(channel)
ssh_channel_free(channel) ssh_channel_free(channel)
fatalError("\(SSH_ERROR)") logger.critical("didnt read?")
logSshGetError()
return
} }
ssh_channel_send_eof(channel) ssh_channel_send_eof(channel)
ssh_channel_close(channel) ssh_channel_close(channel)
ssh_channel_free(channel) ssh_channel_free(channel)
print("testExec succeeded")
}
print("sshNoOk? \(SSH_OK)") func authWithPubkey() {
var status: CInt
status = ssh_userauth_publickey_auto(session, nil, nil)
if status == SSH_AUTH_ERROR.rawValue {
print("pubkey auth failed")
logSshGetError()
fatalError()
}
}
func authWithPw(_ username: String, _ password: String) {
var status: CInt
status = ssh_userauth_password(session, username, password)
guard status != SSH_ERROR else {
print("ssh pw auth error")
logSshGetError()
return
}
}
func authWithKbInt() {
var status: CInt
status = ssh_userauth_kbdint(session, nil, nil)
while status == SSH_AUTH_INFO.rawValue {
let name, instruction: String
var nprompts: CInt
name = UnsafeRawPointer(String(ssh_userauth_kbdint_getname(session)))
instruction = String(ssh_userauth_kbdint_getinstruction(session))
nprompts = ssh_userauth_kbdint_getnprompts(session)
if name.count > 0 {
print(name)
}
if instruction.count > 0 {
print(instruction)
}
for promptI in 0..<nprompts {
let prompt: UnsafePointer<CChar>
var echo: CChar
prompt = ssh_userauth_kbdint_getprompt(session, UInt32(promptI), &echo)
if echo != 0 {
var buffer: [CChar] = Array(repeating: 0, count: 128)
var ptr: UnsafeMutablePointer<CChar> = .init(mutating: buffer)
print(prompt)
if fgets(&buffer, Int32(MemoryLayout.size(ofValue: buffer)), stdin) == nil {
fatalError("autherror")
}
if (ptr = strchr(buffer, 0)) != nil {
ptr.pointee = "\0"
}
if ssh_userauth_kbdint_setanswer(session, promptI, buffer) < 0 {
fatalError("autherr")
}
memset(&buffer, 0, buffer.count)
}
}
}
}
func logSshGetError() {
logger.critical("\(String(describing: ssh_get_error(&self.session)))")
} }
} }

View File

@@ -13,5 +13,6 @@ struct ShhShellApp: App {
WindowGroup { WindowGroup {
ContentView() ContentView()
} }
.windowResizability(.contentMinSize)
} }
} }

View File

@@ -20,7 +20,6 @@ struct ContentView: View {
sshHandler.testExec() sshHandler.testExec()
} }
} }
.padding()
} }
} }