mirror of
https://github.com/neon443/ShhShell.git
synced 2026-03-11 05:19:13 +00:00
YESS
now displays shell on screen!! currently view only :cry but still
This commit is contained in:
@@ -14,6 +14,7 @@
|
|||||||
A92538CD2DEE0744007E0A18 /* ShhShellTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A92538CB2DEE0744007E0A18 /* ShhShellTests.swift */; };
|
A92538CD2DEE0744007E0A18 /* ShhShellTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A92538CB2DEE0744007E0A18 /* ShhShellTests.swift */; };
|
||||||
A92538D12DEE0745007E0A18 /* ShhShellUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A92538CE2DEE0745007E0A18 /* ShhShellUITests.swift */; };
|
A92538D12DEE0745007E0A18 /* ShhShellUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A92538CE2DEE0745007E0A18 /* ShhShellUITests.swift */; };
|
||||||
A92538D22DEE0745007E0A18 /* ShhShellUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A92538CF2DEE0745007E0A18 /* ShhShellUITestsLaunchTests.swift */; };
|
A92538D22DEE0745007E0A18 /* ShhShellUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A92538CF2DEE0745007E0A18 /* ShhShellUITestsLaunchTests.swift */; };
|
||||||
|
A93143BE2DF4D0B300FCD5DB /* libpthread.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = A93143BD2DF4D0A700FCD5DB /* libpthread.tbd */; };
|
||||||
A95FAA472DF3884B00DE2F5A /* Config.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = A95FAA462DF3884B00DE2F5A /* Config.xcconfig */; };
|
A95FAA472DF3884B00DE2F5A /* Config.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = A95FAA462DF3884B00DE2F5A /* Config.xcconfig */; };
|
||||||
A95FAA542DF4B62900DE2F5A /* LibSSH.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = A95FAA502DF4B62100DE2F5A /* LibSSH.xcframework */; };
|
A95FAA542DF4B62900DE2F5A /* LibSSH.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = A95FAA502DF4B62100DE2F5A /* LibSSH.xcframework */; };
|
||||||
A95FAA552DF4B62900DE2F5A /* LibSSH.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = A95FAA502DF4B62100DE2F5A /* LibSSH.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
A95FAA552DF4B62900DE2F5A /* LibSSH.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = A95FAA502DF4B62100DE2F5A /* LibSSH.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||||
@@ -66,6 +67,7 @@
|
|||||||
A92538CB2DEE0744007E0A18 /* ShhShellTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShhShellTests.swift; sourceTree = "<group>"; };
|
A92538CB2DEE0744007E0A18 /* ShhShellTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShhShellTests.swift; sourceTree = "<group>"; };
|
||||||
A92538CE2DEE0745007E0A18 /* ShhShellUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShhShellUITests.swift; sourceTree = "<group>"; };
|
A92538CE2DEE0745007E0A18 /* ShhShellUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShhShellUITests.swift; sourceTree = "<group>"; };
|
||||||
A92538CF2DEE0745007E0A18 /* ShhShellUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShhShellUITestsLaunchTests.swift; sourceTree = "<group>"; };
|
A92538CF2DEE0745007E0A18 /* ShhShellUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShhShellUITestsLaunchTests.swift; sourceTree = "<group>"; };
|
||||||
|
A93143BD2DF4D0A700FCD5DB /* libpthread.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libpthread.tbd; path = usr/lib/libpthread.tbd; sourceTree = SDKROOT; };
|
||||||
A95FAA462DF3884B00DE2F5A /* Config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = SOURCE_ROOT; };
|
A95FAA462DF3884B00DE2F5A /* Config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = SOURCE_ROOT; };
|
||||||
A95FAA502DF4B62100DE2F5A /* LibSSH.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = LibSSH.xcframework; path = Frameworks/LibSSH.xcframework; sourceTree = "<group>"; };
|
A95FAA502DF4B62100DE2F5A /* LibSSH.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = LibSSH.xcframework; path = Frameworks/LibSSH.xcframework; sourceTree = "<group>"; };
|
||||||
A95FAA512DF4B62100DE2F5A /* openssl.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = openssl.xcframework; path = Frameworks/openssl.xcframework; sourceTree = "<group>"; };
|
A95FAA512DF4B62100DE2F5A /* openssl.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = openssl.xcframework; path = Frameworks/openssl.xcframework; sourceTree = "<group>"; };
|
||||||
@@ -82,6 +84,7 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
A95FAA542DF4B62900DE2F5A /* LibSSH.xcframework in Frameworks */,
|
A95FAA542DF4B62900DE2F5A /* LibSSH.xcframework in Frameworks */,
|
||||||
|
A93143BE2DF4D0B300FCD5DB /* libpthread.tbd in Frameworks */,
|
||||||
A9083E402DF2226F0042906E /* libz.tbd in Frameworks */,
|
A9083E402DF2226F0042906E /* libz.tbd in Frameworks */,
|
||||||
A95FAA562DF4B62A00DE2F5A /* openssl.xcframework in Frameworks */,
|
A95FAA562DF4B62A00DE2F5A /* openssl.xcframework in Frameworks */,
|
||||||
);
|
);
|
||||||
@@ -185,6 +188,7 @@
|
|||||||
A9C8976F2DF1980900EF9A5F /* Frameworks */ = {
|
A9C8976F2DF1980900EF9A5F /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
A93143BD2DF4D0A700FCD5DB /* libpthread.tbd */,
|
||||||
A9083E3F2DF2225A0042906E /* libz.tbd */,
|
A9083E3F2DF2225A0042906E /* libz.tbd */,
|
||||||
A95FAA502DF4B62100DE2F5A /* LibSSH.xcframework */,
|
A95FAA502DF4B62100DE2F5A /* LibSSH.xcframework */,
|
||||||
A95FAA512DF4B62100DE2F5A /* openssl.xcframework */,
|
A95FAA512DF4B62100DE2F5A /* openssl.xcframework */,
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import OSLog
|
|||||||
|
|
||||||
class SSHHandler: ObservableObject {
|
class SSHHandler: ObservableObject {
|
||||||
private var session: ssh_session?
|
private var session: ssh_session?
|
||||||
|
private var channel: ssh_channel?
|
||||||
|
|
||||||
@Published var authorized: Bool = false
|
@Published var authorized: Bool = false
|
||||||
@Published var username: String
|
@Published var username: String
|
||||||
@@ -250,7 +251,7 @@ class SSHHandler: ObservableObject {
|
|||||||
func openShell() {
|
func openShell() {
|
||||||
var status: CInt
|
var status: CInt
|
||||||
|
|
||||||
let channel = ssh_channel_new(session)
|
channel = ssh_channel_new(session)
|
||||||
guard let channel = channel else { return }
|
guard let channel = channel else { return }
|
||||||
|
|
||||||
status = ssh_channel_open_session(channel)
|
status = ssh_channel_open_session(channel)
|
||||||
@@ -259,19 +260,15 @@ class SSHHandler: ObservableObject {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
interactiveShellSession(channel: channel)
|
interactiveShellSession()
|
||||||
|
|
||||||
// ssh_channel_close(channel)
|
// ssh_channel_close(channel)
|
||||||
// ssh_channel_send_eof(channel)
|
// ssh_channel_send_eof(channel)
|
||||||
// ssh_channel_free(channel)
|
// ssh_channel_free(channel)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func interactiveShellSession(channel: ssh_channel) {
|
private func interactiveShellSession() {
|
||||||
var status: CInt
|
var status: CInt
|
||||||
var buffer: [CChar] = Array(repeating: 0, count: 256)
|
|
||||||
var nbytes: CInt = 0
|
|
||||||
|
|
||||||
let timer: Timer?
|
|
||||||
|
|
||||||
status = ssh_channel_request_pty(channel)
|
status = ssh_channel_request_pty(channel)
|
||||||
guard status == SSH_OK else { return }
|
guard status == SSH_OK else { return }
|
||||||
@@ -282,29 +279,30 @@ class SSHHandler: ObservableObject {
|
|||||||
status = ssh_channel_request_shell(channel)
|
status = ssh_channel_request_shell(channel)
|
||||||
guard status == SSH_OK else { return }
|
guard status == SSH_OK else { return }
|
||||||
|
|
||||||
timer = Timer(timeInterval: 0.01, repeats: true) { _ in
|
while ssh_channel_is_open(channel) != 0 && ssh_channel_is_eof(channel) == 0 {
|
||||||
// guard let self = self else {
|
var buffer: [CChar] = Array(repeating: 0, count: 256)
|
||||||
// timer?.invalidate()
|
let nbytes = ssh_channel_read_nonblocking(channel, &buffer, UInt32(buffer.count), 0)
|
||||||
// return
|
|
||||||
// }
|
|
||||||
guard ssh_channel_is_open(channel) != 0 else { return }
|
|
||||||
guard ssh_channel_is_eof(channel) == 0 else { return }
|
|
||||||
|
|
||||||
nbytes = ssh_channel_read(channel, &buffer, UInt32(buffer.count), 0)
|
|
||||||
guard nbytes > 0 else { return }
|
guard nbytes > 0 else { return }
|
||||||
|
write(1, buffer, Int(nbytes))
|
||||||
|
|
||||||
if nbytes > 0 {
|
let data = Data(bytes: buffer, count: buffer.count)
|
||||||
write(1, buffer, Int(nbytes))
|
print(String(data: data, encoding: .utf8))
|
||||||
}
|
|
||||||
print(String(cString: buffer))
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func readFromChannel() -> String? {
|
||||||
|
guard ssh_channel_is_open(channel) != 0 else { return nil }
|
||||||
|
guard ssh_channel_is_eof(channel) == 0 else { return nil }
|
||||||
|
|
||||||
DispatchQueue.global().async {
|
var buffer: [CChar] = Array(repeating: 0, count: 256)
|
||||||
RunLoop.current.add(timer!, forMode: .common)
|
let nbytes = ssh_channel_read_nonblocking(channel, &buffer, UInt32(buffer.count), 0)
|
||||||
}
|
|
||||||
|
|
||||||
// ssh_channel_close(channel)
|
guard nbytes > 0 else { return nil }
|
||||||
// ssh_channel_free(channel)
|
write(1, buffer, Int(nbytes))
|
||||||
|
|
||||||
|
let data = Data(bytes: buffer, count: buffer.count)
|
||||||
|
return String(data: data, encoding: .utf8)!
|
||||||
}
|
}
|
||||||
|
|
||||||
private func logSshGetError() {
|
private func logSshGetError() {
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ struct ContentView: View {
|
|||||||
@State var connected: Bool = false
|
@State var connected: Bool = false
|
||||||
@State var testSucceded: Bool?
|
@State var testSucceded: Bool?
|
||||||
|
|
||||||
|
@State var terminal: String = ""
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack {
|
VStack {
|
||||||
Text(connected ? "connected" : "not connected")
|
Text(connected ? "connected" : "not connected")
|
||||||
@@ -74,7 +76,14 @@ struct ContentView: View {
|
|||||||
|
|
||||||
Button("request a shell") {
|
Button("request a shell") {
|
||||||
handler.openShell()
|
handler.openShell()
|
||||||
|
terminal.append(handler.readFromChannel() ?? "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Button("read from server") {
|
||||||
|
terminal.append(handler.readFromChannel() ?? "")
|
||||||
|
}
|
||||||
|
|
||||||
|
Text(terminal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user