diff --git a/ShhShell.xcodeproj/project.pbxproj b/ShhShell.xcodeproj/project.pbxproj index 5db79c5..843701b 100644 --- a/ShhShell.xcodeproj/project.pbxproj +++ b/ShhShell.xcodeproj/project.pbxproj @@ -70,6 +70,7 @@ A9FD375B2E143D77005319A8 /* GenericPasswordStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9FD375A2E143D77005319A8 /* GenericPasswordStore.swift */; }; A9FD375D2E143D7E005319A8 /* KeyStoreError.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9FD375C2E143D7E005319A8 /* KeyStoreError.swift */; }; A9FD375F2E14648E005319A8 /* KeyImporterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9FD375E2E14648E005319A8 /* KeyImporterView.swift */; }; + A9FD37652E169937005319A8 /* AuthType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9FD37642E169937005319A8 /* AuthType.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -172,6 +173,7 @@ A9FD375A2E143D77005319A8 /* GenericPasswordStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenericPasswordStore.swift; sourceTree = ""; }; A9FD375C2E143D7E005319A8 /* KeyStoreError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyStoreError.swift; sourceTree = ""; }; A9FD375E2E14648E005319A8 /* KeyImporterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyImporterView.swift; sourceTree = ""; }; + A9FD37642E169937005319A8 /* AuthType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthType.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -316,6 +318,7 @@ A93143C12DF61E8500FCD5DB /* SSH */ = { isa = PBXGroup; children = ( + A9FD37642E169937005319A8 /* AuthType.swift */, A9C897EE2DF1A9A400EF9A5F /* SSHHandler.swift */, A9C4140B2E096DB7005E3047 /* SSHError.swift */, A96C6A892E0C0B1100F377FE /* SSHState.swift */, @@ -613,6 +616,7 @@ A96C6B002E0C45FE00F377FE /* KeyDetailView.swift in Sources */, A9DA97712E0D30ED00142DDC /* HostSymbol.swift in Sources */, A96C90A12E12B87A00724253 /* TextBox.swift in Sources */, + A9FD37652E169937005319A8 /* AuthType.swift in Sources */, A96BE6A82E116E2B00C0FEE9 /* SessionsListView.swift in Sources */, A96C90A32E12D53B00724253 /* KeyType.swift in Sources */, A98554612E058433009051BD /* HostsManager.swift in Sources */, diff --git a/ShhShell/SSH/AuthType.swift b/ShhShell/SSH/AuthType.swift new file mode 100644 index 0000000..0cebac0 --- /dev/null +++ b/ShhShell/SSH/AuthType.swift @@ -0,0 +1,27 @@ +// +// AuthType.swift +// ShhShell +// +// Created by neon443 on 03/07/2025. +// + +import Foundation + +enum AuthType: UInt32, CustomStringConvertible, CaseIterable { + case password = 2 + case publickey = 4 + case hostbased = 8 + case interactive = 16 + var description: String { + switch self { + case .password: + return "Password" + case .publickey: + return "Publickey" + case .hostbased: + return "Hostbased" + case .interactive: + return "Keyboard Interactive" + } + } +} diff --git a/ShhShell/SSH/SSHHandler.swift b/ShhShell/SSH/SSHHandler.swift index fd14c78..31e71bd 100644 --- a/ShhShell/SSH/SSHHandler.swift +++ b/ShhShell/SSH/SSHHandler.swift @@ -57,57 +57,48 @@ class SSHHandler: @unchecked Sendable, ObservableObject { } func go() { - guard !connected else { - disconnect() - return - } + guard !connected else { disconnect(); return } - do { - try connect() - } catch { -// print("error in connect \(error.localizedDescription)") + do { try connect() } catch { + print("error when connecting \(error.localizedDescription)") return } do { try authWithNone() - } catch { - - } - getAuthMethods() - - if self.host.key != getHostkey() { - self.host.key = getHostkey() - return - } - + } catch { print("auth with none is not authed") } guard state != .authorized else { return } - if !host.password.isEmpty { - do { try authWithPw() } catch { - state = .authFailed - print("pw auth error") - print(error.localizedDescription) - } - } else { - do { - if host.privateKeyID != nil { - try authWithPubkey() + //TODO: check hostkey + + for method in getAuthMethods() { + switch method { + case .password: + do { try authWithPw() } catch { + state = .authFailed + print("pw auth error") + print(error.localizedDescription) } - } catch { - state = .authFailed - print("error with pubkey auth") - print(error.localizedDescription) + case .publickey: + do { try authWithPubkey() } catch { + state = .authFailed + print("error with pubkey auth") + print(error.localizedDescription) + } + case .hostbased: + disconnect() + case .interactive: + disconnect() } } + guard state == .authorized else { return } + ssh_channel_request_env(channel, "TERM", "xterm-256color") ssh_channel_request_env(channel, "LANG", "en_US.UTF-8") ssh_channel_request_env(channel, "LC_ALL", "en_US.UTF-8") - do { - try openShell() - } catch { + do { try openShell() } catch { print(error.localizedDescription) } @@ -315,29 +306,16 @@ class SSHHandler: @unchecked Sendable, ObservableObject { return } - func getAuthMethods() { - var recievedMethod: CInt - recievedMethod = ssh_userauth_list(session, nil) + func getAuthMethods() -> [AuthType] { + var result: [AuthType] = [] + let recievedMethod = UInt32(ssh_userauth_list(session, nil)) - let allAuthDescriptions: [String] = [ - "password", - "publickey", - "hostbased", - "interactive" - ] - let allAuthRaws: [UInt32] = [ - SSH_AUTH_METHOD_PASSWORD, - SSH_AUTH_METHOD_PUBLICKEY, - SSH_AUTH_METHOD_HOSTBASED, - SSH_AUTH_METHOD_INTERACTIVE - ] - let allAuths = zip(allAuthDescriptions, allAuthRaws) - - for authMethod in allAuths { - if (recievedMethod & Int32(authMethod.1)) != 0 { - print(authMethod.0) + for method in AuthType.allCases { + if (recievedMethod & method.rawValue) != 0 { + result.append(method) } } + return result } //MARK: shell