mirror of
https://github.com/neon443/ShhShell.git
synced 2026-03-11 13:26:16 +00:00
added keypair protocol
added bell support added getkeys added ui to show hostkeys all in one place
This commit is contained in:
@@ -26,6 +26,7 @@
|
|||||||
A95FAA562DF4B62A00DE2F5A /* openssl.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = A95FAA512DF4B62100DE2F5A /* openssl.xcframework */; };
|
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, ); }; };
|
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 */; };
|
A96C6A8A2E0C0B1100F377FE /* SSHState.swift in Sources */ = {isa = PBXBuildFile; fileRef = A96C6A892E0C0B1100F377FE /* SSHState.swift */; };
|
||||||
|
A96C6AFE2E0C43B600F377FE /* Keypair.swift in Sources */ = {isa = PBXBuildFile; fileRef = A96C6AFD2E0C43B600F377FE /* Keypair.swift */; };
|
||||||
A98554552E05535F009051BD /* KeyManagerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98554542E05535F009051BD /* KeyManagerView.swift */; };
|
A98554552E05535F009051BD /* KeyManagerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98554542E05535F009051BD /* KeyManagerView.swift */; };
|
||||||
A98554592E0553AA009051BD /* KeyManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98554582E0553AA009051BD /* KeyManager.swift */; };
|
A98554592E0553AA009051BD /* KeyManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98554582E0553AA009051BD /* KeyManager.swift */; };
|
||||||
A985545D2E055D4D009051BD /* ConnectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A985545C2E055D4D009051BD /* ConnectionView.swift */; };
|
A985545D2E055D4D009051BD /* ConnectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A985545C2E055D4D009051BD /* ConnectionView.swift */; };
|
||||||
@@ -95,6 +96,7 @@
|
|||||||
A95FAA5B2DF4B7A000DE2F5A /* ci_pre_xcodebuild.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = ci_pre_xcodebuild.sh; sourceTree = "<group>"; };
|
A95FAA5B2DF4B7A000DE2F5A /* ci_pre_xcodebuild.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = ci_pre_xcodebuild.sh; sourceTree = "<group>"; };
|
||||||
A95FAA5C2DF4B7A300DE2F5A /* ci_prost_xcodebuild.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = ci_prost_xcodebuild.sh; sourceTree = "<group>"; };
|
A95FAA5C2DF4B7A300DE2F5A /* ci_prost_xcodebuild.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = ci_prost_xcodebuild.sh; sourceTree = "<group>"; };
|
||||||
A96C6A892E0C0B1100F377FE /* SSHState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSHState.swift; sourceTree = "<group>"; };
|
A96C6A892E0C0B1100F377FE /* SSHState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSHState.swift; sourceTree = "<group>"; };
|
||||||
|
A96C6AFD2E0C43B600F377FE /* Keypair.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Keypair.swift; sourceTree = "<group>"; };
|
||||||
A98554542E05535F009051BD /* KeyManagerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyManagerView.swift; sourceTree = "<group>"; };
|
A98554542E05535F009051BD /* KeyManagerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyManagerView.swift; sourceTree = "<group>"; };
|
||||||
A98554582E0553AA009051BD /* KeyManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyManager.swift; sourceTree = "<group>"; };
|
A98554582E0553AA009051BD /* KeyManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyManager.swift; sourceTree = "<group>"; };
|
||||||
A985545C2E055D4D009051BD /* ConnectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionView.swift; sourceTree = "<group>"; };
|
A985545C2E055D4D009051BD /* ConnectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionView.swift; sourceTree = "<group>"; };
|
||||||
@@ -246,6 +248,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
A98554542E05535F009051BD /* KeyManagerView.swift */,
|
A98554542E05535F009051BD /* KeyManagerView.swift */,
|
||||||
|
A96C6AFD2E0C43B600F377FE /* Keypair.swift */,
|
||||||
);
|
);
|
||||||
path = Keys;
|
path = Keys;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -436,6 +439,7 @@
|
|||||||
A9C897EF2DF1A9A400EF9A5F /* SSHHandler.swift in Sources */,
|
A9C897EF2DF1A9A400EF9A5F /* SSHHandler.swift in Sources */,
|
||||||
A98554552E05535F009051BD /* KeyManagerView.swift in Sources */,
|
A98554552E05535F009051BD /* KeyManagerView.swift in Sources */,
|
||||||
A923172D2E07138000ECE1E6 /* SSHTerminalView.swift in Sources */,
|
A923172D2E07138000ECE1E6 /* SSHTerminalView.swift in Sources */,
|
||||||
|
A96C6AFE2E0C43B600F377FE /* Keypair.swift in Sources */,
|
||||||
A9C4140C2E096DB7005E3047 /* SSHError.swift in Sources */,
|
A9C4140C2E096DB7005E3047 /* SSHError.swift in Sources */,
|
||||||
A923172A2E07113100ECE1E6 /* TerminalController.swift in Sources */,
|
A923172A2E07113100ECE1E6 /* TerminalController.swift in Sources */,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -57,4 +57,16 @@ class HostsManager: ObservableObject {
|
|||||||
userDefaults.synchronize()
|
userDefaults.synchronize()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getKeys() -> [Keypair] {
|
||||||
|
var result: [Keypair] = []
|
||||||
|
for host in savedHosts {
|
||||||
|
if !result.contains(where: { $0 == Keypair(publicKey: host.publicKey, privateKey: host.privateKey)}) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
result.append(Keypair(publicKey: host.publicKey, privateKey: host.privateKey))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ struct ContentView: View {
|
|||||||
.tabItem {
|
.tabItem {
|
||||||
Label("Hosts", systemImage: "server.rack")
|
Label("Hosts", systemImage: "server.rack")
|
||||||
}
|
}
|
||||||
KeyManagerView(keyManager: keyManager)
|
KeyManagerView(hostsManager: hostsManger, keyManager: keyManager)
|
||||||
.tabItem {
|
.tabItem {
|
||||||
Label("Keys", systemImage: "key.2.on.ring")
|
Label("Keys", systemImage: "key.2.on.ring")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,18 +8,47 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct KeyManagerView: View {
|
struct KeyManagerView: View {
|
||||||
|
@ObservedObject var hostsManager: HostsManager
|
||||||
@ObservedObject var keyManager: KeyManager
|
@ObservedObject var keyManager: KeyManager
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
List {
|
NavigationStack {
|
||||||
Button("ed25519") {
|
List {
|
||||||
keyManager.generateEd25519()
|
Section {
|
||||||
}
|
ForEach(hostsManager.savedHosts) { host in
|
||||||
Button("rsa") {
|
NavigationLink {
|
||||||
do {
|
|
||||||
try keyManager.generateRSA()
|
} label: {
|
||||||
} catch {
|
|
||||||
print(error.localizedDescription)
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Section {
|
||||||
|
NavigationLink {
|
||||||
|
List {
|
||||||
|
ForEach(hostsManager.savedHosts) { host in
|
||||||
|
Text(host.address)
|
||||||
|
.bold()
|
||||||
|
Text(host.key ?? "nil")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} label: {
|
||||||
|
HStack {
|
||||||
|
Image(systemName: "server.rack")
|
||||||
|
Image(systemName: "key.fill")
|
||||||
|
Text("Hostkey fingerprints")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Button("ed25519") {
|
||||||
|
keyManager.generateEd25519()
|
||||||
|
}
|
||||||
|
Button("rsa") {
|
||||||
|
do {
|
||||||
|
try keyManager.generateRSA()
|
||||||
|
} catch {
|
||||||
|
print(error.localizedDescription)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -27,5 +56,8 @@ struct KeyManagerView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#Preview {
|
#Preview {
|
||||||
KeyManagerView(keyManager: KeyManager())
|
KeyManagerView(
|
||||||
|
hostsManager: HostsManager(),
|
||||||
|
keyManager: KeyManager()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
26
ShhShell/Views/Keys/Keypair.swift
Normal file
26
ShhShell/Views/Keys/Keypair.swift
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
//
|
||||||
|
// Keypair.swift
|
||||||
|
// ShhShell
|
||||||
|
//
|
||||||
|
// Created by neon443 on 25/06/2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
protocol KeypairProtocol: Equatable, Codable, Hashable {
|
||||||
|
var publicKey: Data? { get set }
|
||||||
|
var privateKey: Data? { get set }
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Keypair: KeypairProtocol {
|
||||||
|
var publicKey: Data?
|
||||||
|
var privateKey: Data?
|
||||||
|
|
||||||
|
init(
|
||||||
|
publicKey: Data?,
|
||||||
|
privateKey: Data?
|
||||||
|
) {
|
||||||
|
self.publicKey = publicKey
|
||||||
|
self.privateKey = privateKey
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -65,7 +65,7 @@ final class SSHTerminalView: TerminalView, Sendable, @preconcurrency TerminalVie
|
|||||||
}
|
}
|
||||||
|
|
||||||
nonisolated public func scrolled(source: TerminalView, position: Double) {
|
nonisolated public func scrolled(source: TerminalView, position: Double) {
|
||||||
print("scrolled to \(position)")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nonisolated public func setTerminalTitle(source: TerminalView, title: String) {
|
nonisolated public func setTerminalTitle(source: TerminalView, title: String) {
|
||||||
@@ -100,4 +100,9 @@ final class SSHTerminalView: TerminalView, Sendable, @preconcurrency TerminalVie
|
|||||||
nonisolated public func rangeChanged(source: TerminalView, startY: Int, endY: Int) {
|
nonisolated public func rangeChanged(source: TerminalView, startY: Int, endY: Int) {
|
||||||
print(startY, endY)
|
print(startY, endY)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func bell(source: TerminalView) {
|
||||||
|
print("bell rung")
|
||||||
|
handler?.ring()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user