mirror of
https://github.com/neon443/ShhShell.git
synced 2026-03-11 13:26:16 +00:00
improved disconnection - will dismiss terminal on exit
-- before you had to type more to exit improved connection logic with a try catch improved disconnection doesnt crash fix [int] to [cchar] reduced mem usage code cleanup try? -> catch print(error.localizedDesc) guard let var = var else ---> guard let var else removed file importers as it didnt eork compbined guards in writetochannel
This commit is contained in:
@@ -58,13 +58,18 @@ class SSHHandler: @unchecked Sendable, ObservableObject {
|
||||
return
|
||||
}
|
||||
|
||||
guard let _ = try? connect() else { return }
|
||||
|
||||
do {
|
||||
try connect()
|
||||
} catch {
|
||||
print("error in connect \(error.localizedDescription)")
|
||||
}
|
||||
guard connected else { return }
|
||||
|
||||
|
||||
if !host.password.isEmpty {
|
||||
do { try authWithPw() } catch {
|
||||
print("pw auth error")
|
||||
print(error.localizedDescription)
|
||||
}
|
||||
} else {
|
||||
do {
|
||||
@@ -74,6 +79,7 @@ class SSHHandler: @unchecked Sendable, ObservableObject {
|
||||
}
|
||||
} catch {
|
||||
print("error with pubkey auth")
|
||||
print(error.localizedDescription)
|
||||
}
|
||||
}
|
||||
openShell()
|
||||
@@ -121,7 +127,10 @@ class SSHHandler: @unchecked Sendable, ObservableObject {
|
||||
withAnimation { testSuceeded = nil }
|
||||
}
|
||||
|
||||
ssh_channel_send_eof(self.channel)
|
||||
//send eof if open
|
||||
if ssh_channel_is_open(channel) == 1 {
|
||||
ssh_channel_send_eof(channel)
|
||||
}
|
||||
ssh_channel_free(self.channel)
|
||||
self.channel = nil
|
||||
|
||||
@@ -157,7 +166,7 @@ class SSHHandler: @unchecked Sendable, ObservableObject {
|
||||
}
|
||||
|
||||
var status: CInt
|
||||
var buffer: [Int] = Array(repeating: 0, count: 256)
|
||||
var buffer: [CChar] = Array(repeating: 0, count: 256)
|
||||
var nbytes: CInt
|
||||
|
||||
let channel = ssh_channel_new(session)
|
||||
@@ -236,8 +245,13 @@ class SSHHandler: @unchecked Sendable, ObservableObject {
|
||||
fileManager.createFile(atPath: tempPubkey.path(), contents: nil)
|
||||
fileManager.createFile(atPath: tempKey.path(), contents: nil)
|
||||
|
||||
try? pubInp.write(to: tempPubkey, options: .completeFileProtection)
|
||||
try? privInp.write(to: tempKey, options: .completeFileProtection)
|
||||
do {
|
||||
try pubInp.write(to: tempPubkey, options: .completeFileProtection)
|
||||
try privInp.write(to: tempKey, options: .completeFileProtection)
|
||||
} catch {
|
||||
print("file writing error")
|
||||
print(error.localizedDescription)
|
||||
}
|
||||
|
||||
let attributes: [FileAttributeKey: Any] = [.posixPermissions: 0o600]
|
||||
do {
|
||||
@@ -271,8 +285,13 @@ class SSHHandler: @unchecked Sendable, ObservableObject {
|
||||
|
||||
ssh_key_free(pubkey)
|
||||
ssh_key_free(privkey)
|
||||
try? FileManager.default.removeItem(at: tempPubkey)
|
||||
try? FileManager.default.removeItem(at: tempKey)
|
||||
do {
|
||||
try FileManager.default.removeItem(at: tempPubkey)
|
||||
try FileManager.default.removeItem(at: tempKey)
|
||||
} catch {
|
||||
print("error removing file")
|
||||
print(error.localizedDescription)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -328,7 +347,7 @@ class SSHHandler: @unchecked Sendable, ObservableObject {
|
||||
var status: CInt
|
||||
|
||||
channel = ssh_channel_new(session)
|
||||
guard let channel = channel else { return }
|
||||
guard let channel else { return }
|
||||
|
||||
status = ssh_channel_open_session(channel)
|
||||
guard status == SSH_OK else {
|
||||
@@ -356,7 +375,7 @@ class SSHHandler: @unchecked Sendable, ObservableObject {
|
||||
|
||||
func readFromChannel() -> String? {
|
||||
guard connected else { return nil }
|
||||
guard ssh_channel_is_open(channel) != 0 || ssh_channel_is_eof(channel) == 0 else {
|
||||
guard ssh_channel_is_open(channel) == 1 && ssh_channel_is_eof(channel) == 0 else {
|
||||
Task { await disconnect() }
|
||||
return nil
|
||||
}
|
||||
@@ -376,19 +395,12 @@ class SSHHandler: @unchecked Sendable, ObservableObject {
|
||||
return nil
|
||||
}
|
||||
|
||||
private func logSshGetError() {
|
||||
logger.critical("\(String(cString: ssh_get_error(&self.session)))")
|
||||
}
|
||||
|
||||
private func logCritical(_ logMessage: String) {
|
||||
logger.critical("\(logMessage)")
|
||||
}
|
||||
|
||||
func writeToChannel(_ string: String?) {
|
||||
guard let string = string else { return }
|
||||
guard channel != nil else { return }
|
||||
guard ssh_channel_is_open(channel) != 0 else { return }
|
||||
guard ssh_channel_is_eof(channel) == 0 else { return }
|
||||
guard let string else { return }
|
||||
guard ssh_channel_is_open(channel) == 1 && ssh_channel_is_eof(channel) == 0 else {
|
||||
Task { await disconnect() }
|
||||
return
|
||||
}
|
||||
|
||||
var buffer: [CChar] = []
|
||||
for byte in string.utf8 {
|
||||
@@ -408,4 +420,13 @@ class SSHHandler: @unchecked Sendable, ObservableObject {
|
||||
ssh_channel_change_pty_size(channel, Int32(toCols), Int32(toRows))
|
||||
// print("resized tty to \(toRows)rows and \(toCols)cols")
|
||||
}
|
||||
|
||||
private func logSshGetError() {
|
||||
guard var session = self.session else { return }
|
||||
logger.critical("\(String(cString: ssh_get_error(&session)))")
|
||||
}
|
||||
|
||||
private func logCritical(_ logMessage: String) {
|
||||
logger.critical("\(logMessage)")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,6 @@ struct ConnectionView: View {
|
||||
@State var privkeyStr: String = ""
|
||||
|
||||
@State var showTerminal: Bool = false
|
||||
@State var privPickerPresented: Bool = false
|
||||
@State var pubPickerPresented: Bool = false
|
||||
|
||||
@State var hostKeyChangedAlert: Bool = false
|
||||
|
||||
@@ -65,26 +63,6 @@ struct ConnectionView: View {
|
||||
let newStr = pubkeyStr.replacingOccurrences(of: "\r\n", with: "")
|
||||
handler.host.publicKey = Data(newStr.utf8)
|
||||
}
|
||||
Button() {
|
||||
pubPickerPresented.toggle()
|
||||
} label: {
|
||||
Image(systemName: "folder")
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.fileImporter(isPresented: $pubPickerPresented, allowedContentTypes: [.item, .content, .data]) { (Result) in
|
||||
do {
|
||||
let fileURL = try Result.get()
|
||||
guard fileURL.startAccessingSecurityScopedResource() else {
|
||||
print("cant acces file")
|
||||
return
|
||||
}
|
||||
defer { fileURL.stopAccessingSecurityScopedResource() }
|
||||
handler.host.publicKey = try? Data(contentsOf: fileURL)
|
||||
print(fileURL)
|
||||
} catch {
|
||||
print(error.localizedDescription)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HStack {
|
||||
@@ -93,27 +71,6 @@ struct ConnectionView: View {
|
||||
let newStr = privkeyStr.replacingOccurrences(of: "\r\n", with: "")
|
||||
handler.host.privateKey = Data(newStr.utf8)
|
||||
}
|
||||
Button() {
|
||||
privPickerPresented.toggle()
|
||||
} label: {
|
||||
Image(systemName: "folder")
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.fileImporter(isPresented: $privPickerPresented, allowedContentTypes: [.item, .content, .data]) { (Result) in
|
||||
do {
|
||||
let fileURL = try Result.get()
|
||||
guard fileURL.startAccessingSecurityScopedResource() else {
|
||||
print("cant access file")
|
||||
return
|
||||
}
|
||||
defer { fileURL.stopAccessingSecurityScopedResource() }
|
||||
handler.host.privateKey = try? Data(contentsOf: fileURL)
|
||||
print(handler.host.privateKey ?? "")
|
||||
print(fileURL)
|
||||
} catch {
|
||||
print(error.localizedDescription)
|
||||
}
|
||||
}
|
||||
}
|
||||
TextField("", text: $passphrase, prompt: Text("Passphrase (Optional)"))
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ final class SSHTerminalView: TerminalView, Sendable, @preconcurrency TerminalVie
|
||||
while handler.connected {
|
||||
if let read = handler.readFromChannel() {
|
||||
Task { [weak self] in
|
||||
guard let self = self else { return }
|
||||
guard let self else { return }
|
||||
await self.feed(text: read)
|
||||
}
|
||||
} else {
|
||||
@@ -50,7 +50,7 @@ final class SSHTerminalView: TerminalView, Sendable, @preconcurrency TerminalVie
|
||||
while handler.connected {
|
||||
if let read = handler.readFromChannel() {
|
||||
Task { [weak self] in
|
||||
guard let self = self else { return }
|
||||
guard let self else { return }
|
||||
await self.feed(text: read)
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user