diff --git a/ShhShell.xcodeproj/project.pbxproj b/ShhShell.xcodeproj/project.pbxproj index 6465c15..aecfec4 100644 --- a/ShhShell.xcodeproj/project.pbxproj +++ b/ShhShell.xcodeproj/project.pbxproj @@ -25,6 +25,7 @@ A95FAA552DF4B62900DE2F5A /* LibSSH.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = A95FAA502DF4B62100DE2F5A /* LibSSH.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; A95FAA562DF4B62A00DE2F5A /* openssl.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = A95FAA512DF4B62100DE2F5A /* openssl.xcframework */; }; A95FAA572DF4B62A00DE2F5A /* openssl.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = A95FAA512DF4B62100DE2F5A /* openssl.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + A96C6A8A2E0C0B1100F377FE /* SSHState.swift in Sources */ = {isa = PBXBuildFile; fileRef = A96C6A892E0C0B1100F377FE /* SSHState.swift */; }; A98554552E05535F009051BD /* KeyManagerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98554542E05535F009051BD /* KeyManagerView.swift */; }; A98554592E0553AA009051BD /* KeyManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98554582E0553AA009051BD /* KeyManager.swift */; }; A985545D2E055D4D009051BD /* ConnectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A985545C2E055D4D009051BD /* ConnectionView.swift */; }; @@ -93,6 +94,7 @@ A95FAA5A2DF4B79900DE2F5A /* ci_post_clone.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = ci_post_clone.sh; sourceTree = ""; }; A95FAA5B2DF4B7A000DE2F5A /* ci_pre_xcodebuild.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = ci_pre_xcodebuild.sh; sourceTree = ""; }; A95FAA5C2DF4B7A300DE2F5A /* ci_prost_xcodebuild.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = ci_prost_xcodebuild.sh; sourceTree = ""; }; + A96C6A892E0C0B1100F377FE /* SSHState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSHState.swift; sourceTree = ""; }; A98554542E05535F009051BD /* KeyManagerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyManagerView.swift; sourceTree = ""; }; A98554582E0553AA009051BD /* KeyManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyManager.swift; sourceTree = ""; }; A985545C2E055D4D009051BD /* ConnectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionView.swift; sourceTree = ""; }; @@ -225,6 +227,7 @@ children = ( A9C897EE2DF1A9A400EF9A5F /* SSHHandler.swift */, A9C4140B2E096DB7005E3047 /* SSHError.swift */, + A96C6A892E0C0B1100F377FE /* SSHState.swift */, ); path = SSH; sourceTree = ""; @@ -422,6 +425,7 @@ A985545F2E056EDD009051BD /* KeychainLayer.swift in Sources */, A93143C62DF61FE300FCD5DB /* ViewModifiers.swift in Sources */, A98554632E0587DF009051BD /* HostsView.swift in Sources */, + A96C6A8A2E0C0B1100F377FE /* SSHState.swift in Sources */, A92538C82DEE0742007E0A18 /* ContentView.swift in Sources */, A93143C02DF61B3200FCD5DB /* Host.swift in Sources */, A9B15A9A2E0ABA0400F66E02 /* DialogView.swift in Sources */, diff --git a/ShhShell/SSH/SSHHandler.swift b/ShhShell/SSH/SSHHandler.swift index 1b5b3a5..6b22758 100644 --- a/ShhShell/SSH/SSHHandler.swift +++ b/ShhShell/SSH/SSHHandler.swift @@ -91,6 +91,7 @@ class SSHHandler: @unchecked Sendable, ObservableObject { func connect() throws(SSHError) { defer { + try? authWithNone() getAuthMethods() self.host.key = getHostkey() } @@ -169,25 +170,25 @@ class SSHHandler: @unchecked Sendable, ObservableObject { var buffer: [CChar] = Array(repeating: 0, count: 256) var nbytes: CInt - let channel = ssh_channel_new(session) - guard channel != nil else { + let testChannel = ssh_channel_new(session) + guard testChannel != nil else { withAnimation { testSuceeded = false } return } - status = ssh_channel_open_session(channel) + status = ssh_channel_open_session(testChannel) guard status == SSH_OK else { - ssh_channel_free(channel) + ssh_channel_free(testChannel) logger.critical("session opening error") logSshGetError() withAnimation { testSuceeded = false } return } - status = ssh_channel_request_exec(channel, "uptime") + status = ssh_channel_request_exec(testChannel, "uptime") guard status == SSH_OK else { - ssh_channel_close(channel) - ssh_channel_free(channel) + ssh_channel_close(testChannel) + ssh_channel_free(testChannel) logger.critical("session opening error") logSshGetError() withAnimation { testSuceeded = false } @@ -195,36 +196,27 @@ class SSHHandler: @unchecked Sendable, ObservableObject { } nbytes = ssh_channel_read( - channel, + testChannel, &buffer, UInt32(buffer.count), 0 ) while nbytes > 0 { - let written = write(1, buffer, Int(nbytes)) - guard written == Int(nbytes) else { - ssh_channel_close(channel) - ssh_channel_free(channel) - logger.critical("write error") - logSshGetError() - withAnimation { testSuceeded = false } - return - } - nbytes = ssh_channel_read(channel, &buffer, UInt32(buffer.count), 0) + nbytes = ssh_channel_read_nonblocking(testChannel, &buffer, UInt32(buffer.count), 0) } if nbytes < 0 { - ssh_channel_close(channel) - ssh_channel_free(channel) + ssh_channel_close(testChannel) + ssh_channel_free(testChannel) logger.critical("didnt read?") logSshGetError() withAnimation { testSuceeded = false } return } - ssh_channel_send_eof(channel) - ssh_channel_close(channel) - ssh_channel_free(channel) + ssh_channel_send_eof(testChannel) + ssh_channel_close(testChannel) + ssh_channel_free(testChannel) print("testExec succeeded") withAnimation { testSuceeded = true } return @@ -339,7 +331,6 @@ class SSHHandler: @unchecked Sendable, ObservableObject { print(authMethod.0) } } - print(recievedMethod) } //MARK: shell diff --git a/ShhShell/SSH/SSHState.swift b/ShhShell/SSH/SSHState.swift new file mode 100644 index 0000000..120440e --- /dev/null +++ b/ShhShell/SSH/SSHState.swift @@ -0,0 +1,17 @@ +// +// SSHState.swift +// ShhShell +// +// Created by neon443 on 25/06/2025. +// + +import Foundation + +enum SSHState { + case idle + case connecting + case authorizing + case authorized + case shellOpen +// case unauthorized +} diff --git a/ShhShell/Views/ConnectionView.swift b/ShhShell/Views/ConnectionView.swift index 5abe7f2..559e668 100644 --- a/ShhShell/Views/ConnectionView.swift +++ b/ShhShell/Views/ConnectionView.swift @@ -98,7 +98,14 @@ struct ConnectionView: View { } else { handler.go() } - withAnimation { handler.testExec() } + handler.testExec() + DispatchQueue.main.asyncAfter(deadline: .now()+3) { + Task { + let result = handler.testSuceeded + await handler.disconnect() + handler.testSuceeded = result + } + } } label: { if let testResult = handler.testSuceeded { Image(systemName: testResult ? "checkmark.circle" : "xmark.circle")