Coder Social home page Coder Social logo

frugghi / swiftsh Goto Github PK

View Code? Open in Web Editor NEW
191.0 191.0 70.0 21.67 MB

A Swift SSH framework that wraps libssh2.

License: MIT License

Swift 58.00% Objective-C 2.10% C 37.83% Ruby 0.62% Shell 0.80% Dockerfile 0.65%
ios libssh2 ssh swift swift-framework

swiftsh's People

Contributors

frugghi avatar jesper-bylund avatar jessearmand avatar jpalten avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

swiftsh's Issues

Xcode 12 / Swift 5 - Build Errors

Swift Compiler Error Group
~/SSHCommands.swift:15:5: Value of optional type 'SSHShell?' must be unwrapped to refer to member 'withCallback' of wrapped base type 'SSHShell'
~/SSHCommands.swift:26:5: Value of optional type 'SSHShell?' must be unwrapped to refer to member 'write' of wrapped base type 'SSHShell'
~/SSHCommands.swift:32:5: Value of optional type 'SSHShell?' must be unwrapped to refer to member 'disconnect' of wrapped base type 'SSHShell'
~/SSHCommands.swift:32:22: Missing argument for parameter #1 in call
~//Pods/SwiftSH/SwiftSH/Libssh2.swift:333:119: Value of optional type 'UnsafePointer?' must be unwrapped to a value of type 'UnsafePointer'

This is in a fresh project just to test before implementing in my working project. I changed the swift version from 5 to 4.2 then to 4 and got this error:

~/Pods/SwiftSH/SwiftSH/Libssh2.swift:333:119: Value of optional type 'UnsafePointer?' must be unwrapped to a value of type 'UnsafePointer'

SIGABRT in SSHQueue

Hi Frugghi,
first of all thank you very much (again) for your great work! I've just implemented the library in a productive App, which was a great success all in all.

I'm using Firebase / Crashlytics and there is just a single crash, which is occurring in 10% of the current users (iPhone 6-X, iPad Air / Pro).
I've collected 30 instances of the crash (all identical), unfortunately I've not a lot details on this crash (like executed command or host information) and I'm not able to export a whole crash log, so I'd like to share it simply using copy & paste.

Hope these little information may help.
Again, I think it's great that there is just a single crash in such a complex project so far - great work!
I'll dig deeper using the FB log functions in further releases, maybe I can identify the bug.

The crash (SIGABRT ABORT) takes place in number 6.

Crashed: SSH Queue #1
SIGABRT ABORT 0x000000018368d2ec
keyboard_arrow_up
0
libsystem_kernel.dylib
__pthread_kill + 8
1
libsystem_pthread.dylib
<redacted> + 376
2
libsystem_c.dylib
abort + 140
3
libswiftCore.dylib
swift_vasprintf(char**, char const*, char*) + 54
4
libswiftCore.dylib
swift_getDefaultErrorCode + 50
5
libswiftCore.dylib
swift_unownedRetainStrong + 124
arrow_right 

6
SwiftSH
_T07SwiftSH10SSHCommandC7executeySS_ySS_10Foundation4DataVSgs5Error_pSgtcSg10completiontFyyKcfU0_yycfU0_TA + 40

7
SwiftSH
_T0Ix_IyB_TR + 36
8
libdispatch.dylib
<redacted> + 24
9
libdispatch.dylib
<redacted> + 16
10
libdispatch.dylib
<redacted> + 424
11
libdispatch.dylib
<redacted> + 1020
12
libdispatch.dylib
<redacted> + 280
13
libdispatch.dylib
<redacted> + 336
14
libdispatch.dylib
<redacted> + 340
15
libdispatch.dylib
<redacted> + 668
16
libsystem_pthread.dylib
_pthread_wqthread + 860
17
libsystem_pthread.dylib
start_wqthread + 4

Additional keys:

crash_info_entry_0
Fatal error: Attempted to read an unowned reference but object 0x105948870 was already deallocated

crash_info_entry_1
abort() called

SSH DynamicForward

Does SwiftSH support DynamicForward or the -D flag to bind a dynamic tunnel to a local port. For example:

SSH -D 10000 user@host

Get a response

Is there any way to get the response (if any) that a command might generate? The documentation link isn't working.

Connection closed without notification?

When the other side of the ssh shell disconnects for some reason, I get no error callback. Any idea how to catch this hangup?

The console gives me this:

 [] nw_socket_handle_socket_event Event mask: 0x4
 [] tcp_connection_cancel 28
 [] nw_socket_handle_socket_event Socket received WRITE_CLOSE event
 [] nw_endpoint_handler_cancel [26 api.dropbox.com:443 ready resolver (satisfied)]
 [] nw_endpoint_handler_cancel [26.1 162.125.1.7:443 ready socket-flow (satisfied)]
 [] __nw_socket_service_writes_block_invoke sendmsg(fd 263, 31 bytes): socket has been closed
 [] nw_endpoint_flow_protocol_error [26.1 162.125.1.7:443 cancelled socket-flow (null)] Socket protocol sent error: [32] Broken pipe
 [] nw_endpoint_flow_protocol_disconnected [26.1 162.125.1.7:443 cancelled socket-flow (null)] Output protocol disconnected
 [] nw_resolver_cancel_on_queue 0x60800010efa0
 [] nw_endpoint_handler_cancel [28 api-content.dropbox.com:443 ready resolver (satisfied)]
 [] nw_endpoint_handler_cancel [28.1 162.125.1.8:443 ready socket-flow (satisfied)]
 [] __nw_socket_service_writes_block_invoke sendmsg(fd 318, 31 bytes): socket has been closed
 [] nw_endpoint_flow_protocol_error [28.1 162.125.1.8:443 cancelled socket-flow (null)] Socket protocol sent error: [32] Broken pipe
 [] nw_endpoint_flow_protocol_disconnected [28.1 162.125.1.8:443 cancelled socket-flow (null)] Output protocol disconnected
 [] nw_resolver_cancel_on_queue 0x60800010eb20
 [] -[NWConcrete_tcp_connection dealloc] 26
 [] nw_socket_handle_socket_event Event mask: 0x4
 [] nw_socket_handle_socket_event Socket received WRITE_CLOSE event
 [] -[NWConcrete_tcp_connection dealloc] 28
 [] tcp_connection_cancel 27
 [] nw_socket_handle_socket_event Event mask: 0x4
 [] nw_socket_handle_socket_event Socket received WRITE_CLOSE event
 [] nw_endpoint_handler_cancel [27 api-content.dropbox.com:443 ready resolver (satisfied)]
 [] nw_endpoint_handler_cancel [27.1 162.125.1.8:443 ready socket-flow (satisfied)]
 [] __nw_socket_service_writes_block_invoke sendmsg(fd 316, 31 bytes): socket has been closed
 [] nw_endpoint_flow_protocol_error [27.1 162.125.1.8:443 cancelled socket-flow (null)] Socket protocol sent error: [32] Broken pipe
 [] nw_endpoint_flow_protocol_disconnected [27.1 162.125.1.8:443 cancelled socket-flow (null)] Output protocol disconnected
 [] nw_resolver_cancel_on_queue 0x60800010add0
 [] -[NWConcrete_tcp_connection dealloc] 27

Active use?

I know this is a wrong use of issues. But it's the best way to reach fellow devs in this situation I think:

Is anyone using this lib for active development? If not, what are you using instead?

Q: How to read bash error message

Hi there!
Just a quick question. When you execute something like "foo bar" there occurs of course a bash error which is returned via a SSHError.Command.execError:

// Command
public enum Command: Error {
    case execError(String?, Data)
}

The printed error looks like:

execError : 2 elements
      ▿ .0 : Optional<String>
        - some : "bash: foo: command not found\n"
      ▿ .1 : 29 bytes
          ...

I'd like to access the error message "bash: foo: command not found\n", but I wasn't able to get it working.

Any hint is highly appreciated :-)
Thanks in advance!

Authenticating with Public/Private key

Not really an issue I guess, more an open question:

I'm trying to open a shell with an RSA key, but I can't quite follow the code to see how that's done. Am I right in believing I should be using the authorise() method? The challenge seems to accept public/private keys, but I can't figure out how.

AuthenticationFailed

Thanks for the demo.

i have SFTP server and able to connect with SFTP client(FlieZilla, CyberDuck)

When I tried this demo and added all information, then it always given authenticationfailed error.

Can you please help me If anything extra I have to do?

SwiftSH in iOS Simulator

For some reason SwiftSH won't run in the simulator on my machine. Any idea why not? Does that work on your machine? Any ideas how to fix that?

Error with file: Libssh2.swift

I have updated Xcode to 10.2 yesterday.
But when I build my program today, an error at Libssh2.swift: 333

let response = LIBSSH2_USERAUTH_KBDINT_RESPONSE(text: strdup(password), length: UInt32(strlen(password)))

reason is:
Value of optional type 'UnsafePointer?' must be unwrapped to a value of type 'UnsafePointer'

I change the code to:
let response = LIBSSH2_USERAUTH_KBDINT_RESPONSE(text: strdup(password), length: UInt32(strlen(password!)))
and solve this problem, but I don't think that is good way.

How to integrate SwiftSH in a custom react native library

This is more of a generic pod question. I'm trying to install SwiftSH in my custom react native library which is added as a dependency to my react native ios project. Currently my custom library is linked to ios project as a .xcodeProj. When I install the pod and use my xcworkspace, it's all happy with referencing the pod but, when I add the custom library as a xcodeproj, it doesn't recognise the pod headers.

Is there a way to use the xcodeproj and still use the pods?

diffie_hellman crash

Every once in a while I get a crash in the diffie_hellman call, which was triggered by session.handshake(socket). Not sure what causes this, and where the problem could be.

Is there a newer version of the libssh2 library available to include in the SwiftSH framework perhaps?

Make compatible with macOS

I'd love to use this in my macOS swift app, but I get the following error:

[!] The platform of the target `ProjectName` (macOS 10.12) is not compatible with `SwiftSH (0.1.0)`, which does not support `osx`.

Invalid example of ssh command

Hi, I am very new to iPhone programming, the first and most useful thing I may need to do with my phone is exactly to check server statues. So, I would really like to be able to send a command to a remote server and get the STDOUT,STDERR and exitcode.

In the example provided for 'Execute ssh command' I don't understand where the command for the server really is. Suppose I want to run a simple ls -la, it is not clear at all to me where to write ls -la. I tried to guess it without luck. Any help would be very much appreciated.

let command = Command(host: "localhost", port: 22)
// ...
command.connect()
       .authenticate(.byPassword(username: "username", password: "password"))
       .execute(command) { (command, result: String?, error) in
           if let result = result {
               print("\(result)")
           } else {
               print("ERROR: \(error)")
           }
       }

Build Error

After installing the pod, I tried importing it in my Swift ViewController, I got the error "Could not build Objective-C Module 'SwiftSH' "Is this library used with Objective-C or Swift? Would highly appreciate if someone could share any sample implementation.

Package.swift?

I am new to xcode and ios programming, but wouldn't this repository be much more convenient and useful if it had a Package.swift file?

Q: How to send multiple commands in a row?

Hi,

I want to implement a "today extension" and send ssh commands with a button from there.

Sometimes this button is pressed multiple times and there is a chance that the previous connection is not closed yet.

Is there any way to "intercept" the previous command and send it there? I have already tried following code but this did not work either:

if (command.connected && command.authenticated){
    command.execute(command) { (command, result: String?, error) in
        if let result = result {
        // ...
} else {
    // connect normally
}

Here is my file:

import UIKit
import NotificationCenter
import SwiftSH

class TodayViewController: UIViewController, NCWidgetProviding {

    var command: Command!
    @IBOutlet var button1: UIButton!

// ...

    override func viewDidLoad() {
        super.viewDidLoad()
        self.command = Command(host: "111.222.3.444", port: 22)
        // ...
    }

    @IBAction func button1Pressed(sender: UIButton){
        performCommand("pwd")
    }

    func performCommand(_ cmd: String) {
        print("send Command " + cmd)
        
        self.command
            .connect()
            .authenticate(.byPassword(username: "user", password: "pass"))
            .execute(cmd) { (cmd, result: String?, error) in
                if let result = result {
                    //...
                } else {
                    //...
                }
            }
    }
}

Authentication Failed using Private Key,Public Key

Hello
We are trying to connect our Mac and aws servers using the private key. but every time we got authentication failed.
Also, we have checked both keys on another application and it's working fine.so I think the problem is in the library. can you please help?

self.authenticationChallenge = .byPublicKeyFromFile(username: self.username, password: "", publicKey: "", privateKey: pvtfilePath?.relativePath ?? "")
self.shell = try? SSHShell(host: self.hostname, port: self.port ?? 22, terminal: "vanilla")
self.shell.withCallback { [unowned self] (string: String?, error: String?) in
                DispatchQueue.main.async {
                    if let string = string {
                        self.appendToTextView(string)
                    }
                    if let error = error {
                        self.appendToTextView("[ERROR] \(error)")
                    }
                }
            }
            .connect()
            .authenticate(self.authenticationChallenge)
            .open { [unowned self] (error) in
                if let error = error {
                    self.appendToTextView("[ERROR] \(error)")
                    self.textView.isEditable = false
                } else {
                    self.textView.isEditable = true
                }                
            }

SCP protocol

Hi, there is some news regarding the implementation of SCP ?

execute output

How can we get the output result of a command ?

I created a swift file with the following content:

import Foundation
import SwiftSH

class sshShell {
    func executeCMD(cmd:String) -> String {
        let command = Command(host: "192.168.1.50", port: 22)
        var output:String = ""
    
        command!.connect()
               .authenticate(.byPassword(username: "user1", password: "password1"))
               .execute(cmd) { (cmd, result: String?, error) in
                   if let result = result {
                       print("here")
                       print(result)
                       output = result
                   } else {
                       print("there")
                       output =  "ERROR"
                   }
               }
        return output
    }
}

And in the ContentView, I have:

        var output: String = ""
        Button(action: {
            let atest = sshShell()
            output = atest.executeCMD(cmd: "/bin/ls -la")
        }, label: {
            Text("Click me")
        })

        Text(output)
            .padding()

Here is the debugger output:

DEBUG: Timeout set to 10.0 seconds
INFO: Libssh2 v1.9.0
DEBUG: 192.168.1.50 resolved. 1 addresses
INFO: Connection to 192.168.1.50 on port 22 successful
DEBUG: Remote banner is SSH-2.0-OpenSSH_8.6
DEBUG: Fingerprint is BF:...
DEBUG: Supported authentication methods: [Public Key, Password, Keyboard Interactive]
DEBUG: Authenticating by Password
DEBUG: Opening the channel...
DEBUG: Environment: []
INFO: Bye bye
DEBUG: Disconnected

The connection seems OK but no result.

unowned vs weak

I see a lot of unowned where weak should be used. Would you like me to look into that and create a merge request for that?

Running SSH command into *BSD servers

Beside the timeout issue that is already detailed in a pull request, the connection fails systematically to OpenBSD and FreeBSD servers. Ths is because by default in /etc/ssh/sshd_config they do not state PasswordAuthentication yes. Adding this line it all works.

Using SwiftSH in Objective C

Hi Frugghi!
First of all thank you all so much for sharing your awesome library! I switched from NMSSH and already tested your project in a tiny Swift Hello-World, which worked great.

Due to the fact that my existing App is written in ObjC, I'd like to get everything running within a ObjC class but the compiler can't find any classes, like for example the Command class or the SSHConnection class beyond.
I tried multiple lines of code, in order to import the framework into my ObjC wrapper class:

#import "<MyProjectName>-Swift.h"

#import <SwiftSH/SwiftSH-Swift.h>
#import <SwiftSH/SwiftSH-umbrella.h>

@import SwiftSH;

Of course I followed your handy description to install the framework via CocoaPods.
Do you have any idea, recommendation or workaround?

Thank you very much!

How to use .byPublicKey,i always fail.

Thanks for the ssh tool provided, it has helped me a lot.

I want to connect to ssh using .byPublicKey, so I generated a key pair of type ed25519 and tested it successfully on mac, but on iOS it always fails.

Hope to give us an example of a connection using .byPublicKey?

Thank you!

High CPU usage

Hi there!
I'm trying to build an App which pulls a lot of information from a SSH server.

On startup the puller executes a lot of single commands (like 20) almost at once, in order to fetch all relevant information asap from the system. After the start the App pulls further information on a regular basis every 30 seconds 5 commands.
The CPU load rushes up and the App needs almost 2-3 CPU units at the beginning (which is fine for me, regarding the amount of work to do) but the problem is, that the CPU load almost remains this high and goes also up after a little amount of time, when the puller starts pulling every 30 sec.
Without the high amount of commands after startup, the CPU starts with a load of 30% and goes slowly up to 100%, due to the regular pulling. I was expecting a normal CPU load after all commands have finished executing.

Also a maybe related phenomenon is, that sometimes the callback function of the Command object never gets called, also after the timeout is passed a long time ago. This is why I've set a custom timeout in a more abstract method, to be able to get a feedback. This is weird because I can verify that the command is executed on the target system, I'm just not getting the response. This is happening a lot (80%) during the burst of commands during the startup but also sometimes while pulling. Unfortunately I couldn't find a reason or a step-by-step description on how to reproduce the issue, so just FYI.

I know this is an extreme usage of the framework, so this behavior could be normal but my question is, is there a way I can improve my code, so the CPU load decreases after the execution of a command?

All in all I just want to thank you one more time for your awesome work you did here! Great job and it helped me a lot, just wanted to share the issues to improve this great project! :-)

Command examples:

echo "foo bar" > /path/of/file ; cat /path/of/file
ip a
ls 

The use of SwiftSH is wrapped in a function, which is wrapped in a custom "SSH" NSObject. For each command I wanna execute, I'm creating a new SSH object, to separate all commands and connections.
I already tried to disconnect() and close() the Command objects or also storing them in arrays of long living objects but unfortunately I had no luck.
All commands are pretty simple (see the examples below) and every command has a timeout of 10 sec and is usually executed after 3 sec.

SSH().executeShortrunningSSHCommand(command, host: hostname, port: port, user: username, pwd: password) { (result, error) in
            completion(result, error)
}
var myCommand = Command(host:"hostname", port: 22)
        myCommand?.timeout = TimeInterval(10)
        
        // Connect
        myCommand!.connect { (connError) in
            if nil != connError {
                completion(nil, connError)
                myCommand?.disconnect(nil)
                return
            }
            
            // Authentication
            myCommand!.authenticate(AuthenticationChallenge.byPassword(username: "username", password: "password"), completion: { (authError) in
                if nil != authError {
                    completion(nil, authError)
                    myCommand?.disconnect(nil)
                    return
                }
                
                // Execute
                myCommand!.execute(fullCommand) { (command: String, result: String?, execError: Error?) -> Void in
                    completion(result, execError)
                    
                    myCommand?.disconnect({
                        myCommand = nil
                    })
                }
         }
}

screen shot 2018-08-24 at 00 21 59

screen shot 2018-08-24 at 00 04 50

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.