SSH and SFTP client for Flutter

Overview

ssh

SSH and SFTP client for Flutter. Wraps iOS library NMSSH and Android library JSch.

Installation

Add ssh as a dependency in your pubspec.yaml file.

Known issue

  • Platform exception in release mode for Android:

    PlatformException(connection_failure, java.lang.ClassNotFoundException: com.jcraft.jsch.jce.Random, null)
    

    There are 2 workarounds:

    • Disable shrink:

      flutter build apk --no-shrink

    • Configure proguard-rules. Refer to this comment for details.

Usage

Create a client using password authentication

import 'package:ssh/ssh.dart';

var client = new SSHClient(
  host: "my.sshtest",
  port: 22,
  username: "sha",
  passwordOrKey: "Password01.",
);

Create a client using public key authentication

import 'package:ssh/ssh.dart';

var client = new SSHClient(
  host: "my.sshtest",
  port: 22,
  username: "sha",
  passwordOrKey: {
    "privateKey": """-----BEGIN RSA PRIVATE KEY-----
    ......
-----END RSA PRIVATE KEY-----""",
    "passphrase": "passphrase-for-key",
  },
);

OpenSSH keys

Recent versions of OpenSSH introduce a proprietary key format that is not supported by most other software, including this one, you must convert it to a PEM-format RSA key using the puttygen tool. On Windows this is a graphical tool. On the Mac, install it per these instructions. On Linux install your distribution's putty or puttygen packages.

  • Temporarily remove the passphrase from the original key (enter blank password as the new password)
    ssh-keygen -p -f id_rsa
  • convert to RSA PEM format
    puttygen id_rsa -O private-openssh -o id_rsa_unencrypted
  • re-apply the passphrase to the original key
    ssh-keygen -p -f id_rsa
  • apply a passphrase to the converted key:
    puttygen id_rsa_unencrypted -P -O private-openssh -o id_rsa_flutter
  • remove the unencrypted version:
    rm id_rsa_unencrypted

Connect client

await client.connect();

Close client

await client.disconnect();

Execute SSH command

var result = await client.execute("ps");

Shell

Start shell:

  • Supported ptyType: vanilla, vt100, vt102, vt220, ansi, xterm
var result = await client.startShell(
  ptyType: "xterm", // defaults to vanilla
  callback: (dynamic res) {
    print(res);     // read from shell
  }
);

Write to shell:

await client.writeToShell("ls\n");

Close shell:

await client.closeShell();

SFTP

Connect SFTP:

await client.connectSFTP();

List directory:

var array = await client.sftpLs("/home"); // defaults to .

Create directory:

await client.sftpMkdir("testdir");

Rename file or directory:

await client.sftpRename(
  oldPath: "testfile",
  newPath: "newtestfile",
);

Remove directory:

await client.sftpRmdir("testdir");

Remove file:

await client.sftpRm("testfile");

Download file:

var filePath = await client.sftpDownload(
  path: "testfile",
  toPath: tempPath,
  callback: (progress) {
    print(progress); // read download progress
  },
);

// Cancel download:
await client.sftpCancelDownload();

Upload file:

await client.sftpUpload(
  path: filePath,
  toPath: ".",
  callback: (progress) {
    print(progress); // read upload progress
  },
);

// Cancel upload:
await client.sftpCancelUpload();

Close SFTP:

await client.disconnectSFTP();

Demo

Refer to the example.

Comments
  • App crashes when connecting

    App crashes when connecting

    When using the .connect() method the app crashes and throws the following error:

    FATAL EXCEPTION: Thread-5
    E/AndroidRuntime( 1722): Process: com.niklas8.remotefiles, PID: 1722
    E/AndroidRuntime( 1722): java.lang.RuntimeException: Methods marked with @UiThread must be executed on the main thread. Current thread: Thread-5
    E/AndroidRuntime( 1722):        at io.flutter.embedding.engine.FlutterJNI.ensureRunningOnMainThread(FlutterJNI.java:794)
    E/AndroidRuntime( 1722):        at io.flutter.embedding.engine.FlutterJNI.invokePlatformMessageResponseCallback(FlutterJNI.java:727)
    E/AndroidRuntime( 1722):        at io.flutter.embedding.engine.dart.DartMessenger$Reply.reply(DartMessenger.java:140)
    E/AndroidRuntime( 1722):        at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler$1.error(MethodChannel.java:230)
    E/AndroidRuntime( 1722):        at sq.flutter.ssh.SshPlugin$1.run(SshPlugin.java:169)
    E/AndroidRuntime( 1722):        at java.lang.Thread.run(Thread.java:762)
    

    This occurred since I updated to Flutter 1.7 On iOS everything is working

    bug 
    opened by nn1ks 11
  • "@UiThread must be executed on the main thread" exception while uploading to SFTP server

    I tried to upload a file but after successfull connect and connectSFTP I got a strange exception while trying to sftpUpload. I found info that many plugins had such issue and needed a fix.

    E/SshPlugin(26101): Failed to upload /data/user/0/com.example.picker/app_flutter/file0.jpg E/flutter (26101): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: PlatformException(upload_failure, java.lang.RuntimeException: Methods marked with @UiThread must be executed on the main thread. Current thread: Thread-8, null) E/flutter (26101): #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:564:7) E/flutter (26101): #1 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:316:33) E/flutter (26101): E/flutter (26101): #2 SSHClient.sftpUpload (package:ssh/ssh.dart:185:33) E/flutter (26101): E/flutter (26101): #3 MyApp.sendPhotos (package:picker/main.dart:126:24) E/flutter (26101): E/flutter (26101): #4 MyApp.build. (package:picker/main.dart:74:22) E/flutter (26101): #5 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:635:14) E/flutter (26101): #6 _InkResponseState.build. (package:flutter/src/material/ink_well.dart:711:32) E/flutter (26101): #7 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24) E/flutter (26101): #8 TapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:365:11) E/flutter (26101): #9 TapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:275:7) E/flutter (26101): #10 PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:455:9) E/flutter (26101): #11 PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:75:13) E/flutter (26101): #12 PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:102:11) E/flutter (26101): #13 _WidgetsFlutterBinding&BindingBase&GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:218:19) E/flutter (26101): #14 _WidgetsFlutterBinding&BindingBase&GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:198:22) E/flutter (26101): #15 _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:156:7) binding.dart:102:7) E/flutter (26101): #17 _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerDataPacket (package:flutter/src/gesturesE/flutter (26101): #18 _rootRunUnary (dart:async/zone.dart:1136:13) E/flutter (26101): #19 _CustomZone.runUnary (dart:async/zone.dart:1029:19) E/flutter (26101): #21 _invoke1 (dart:ui/hooks.dart:250:10)

    bug 
    opened by Akoszewski 9
  • SSHClient disconnect never completes

    SSHClient disconnect never completes

    On both iOS and Android, disconnect never completes.

    This happens even for a simple use case of:

    SSHClient _client; await _client.connect(); await _client.disconnect();

    I'm on Flutter Channel dev, v1.1.8, on Mac OS X 10.14.3.

    bug 
    opened by pbaker5 7
  • Not able to create SSHClient when building release

    Not able to create SSHClient when building release

    Hi,

    First I had the problem with no internet connection as mentioned here #32 but adding the flag --no-shrink solved that problem. But I still cant connect nor create a SSHClient. Everything works as expected on iOS and in Android debug mode. I am having a hard time to debug this as well. But I´ve narrowed it down to where it fails: "var client = new SSHClient(....)" Can I catch any exception when new SSHClient fails? Do I need to add (except from INTERNET) any android permissions to use SSH? Ive tried searching but no success.

    EDIT: It fails when I run result = await client.connect();

    Im also getting this warning (as well in debug mode): "Note: /Users/razbook3.0/development/flutter/.pub-cache/hosted/pub.dartlang.org/ssh-0.0.6/android/src/main/java/sq/flutter/ssh/SshPlugin.java uses unchecked or unsafe operations." Thanks /Rasmus

    opened by MrHazee 4
  • PlatformException(connection_failure, java.lang.ClassNotFoundException: com.jcraft.jsch.jce.Random, null)

    PlatformException(connection_failure, java.lang.ClassNotFoundException: com.jcraft.jsch.jce.Random, null)

    PlatformException(connection_failure, java.lang.ClassNotFoundException: com.jcraft.jsch.jce.Random, null)

    An exception occurs when trying to connect on release APK, works fine on debug.

    opened by newnishad 4
  • App crashes on startup

    App crashes on startup

    App crashes on startup with the error:

    E/AndroidRuntime(19915): FATAL EXCEPTION: Thread-2 E/AndroidRuntime(19915): Process: xyz.mevans.ftpclient, PID: 19915 E/AndroidRuntime(19915): java.lang.NullPointerException: Attempt to read from field 'com.jcraft.jsch.Session sq.flutter.ssh.SshPlugin$SSHClient._session' on a null object reference E/AndroidRuntime(19915): at sq.flutter.ssh.SshPlugin$6.run(SshPlugin.java:278) E/AndroidRuntime(19915): at java.lang.Thread.run(Thread.java:764)

    opened by mevans 4
  • SFTP - Connect Hangs

    SFTP - Connect Hangs

    I'm interested in your library and trying to run the example to test SFTP access - however after calling connect() the system just seems to hang and nothing resolves

    Is this due to my host being an IP Address? And If so is there a correct way to do this?

        var client = new SSHClient(
          host: "192.168.10.5",
          port: 21,
          username: "user",
          passwordOrKey: "pass",
        );
    
        try {
          print("Attempting connection");
          String result = await client.connect(); //Never get past here!
          if (result == "session_connected") {
            result = await client.connectSFTP();
            if (result == "sftp_connected") {`
            ...
    
    
    opened by track02 3
  • Is there any issue with releasing in Google PlayStore?

    Is there any issue with releasing in Google PlayStore?

    I have an issue that when I build release mode to create app bundle. It works.

    And I upload the APK file to directly my phone and install it and it works.

    And also When I upload APK file to 3rd party App store Galaxy Store or Onestore it also works fine.

    But When I upload to Google Play store, it uploads well but When I download app from Google playstore it only shows start screen and it closed without any error message.

    Is there any problem with Google play store with flutter_ssh package?

    opened by writingdeveloper 2
  • Functionalities not working in release mode

    Functionalities not working in release mode

    all ssh functionalites working in debug mode and release mode but nothing working in built apk i am trying to connect to my local network..

    [✓] Flutter (Channel stable, v1.12.13+hotfix.9, on Linux, locale en_US.UTF-8) [✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2) [!] Android Studio (not installed) [✓] Connected device (1 available)

    this is the output of flutter build apk --verbose https://pastebin.com/LW9zUJ3y this is my app repo https://github.com/prinzpiuz/MSM_mobile

    opened by prinzpiuz 2
  • version of ssh and uuid conflict

    version of ssh and uuid conflict

    Here are my dependencies: ssh: ^0.0.5 flutter_cache_manager: ^1.1.3 uuid: ^2.0.4 path_provider: ^1.4.4 cached_network_image: ^1.1.3 image_picker: ^0.6.2+2

    got below issue----------------------------------

    Because ssh 0.0.5 depends on uuid ^1.0.3 and no versions of ssh match >0.0.5 <0.1.0, ssh ^0.0.5 requires uuid ^1.0.3.

    So, because project1 depends on both ssh ^0.0.5 and uuid ^2.0.4, version solving failed. pub get failed (1)

    changed uuid to ^1.0.3 got another issue -----------------------------

    Because flutter_cache_manager >=0.3.0 depends on uuid ^2.0.0 and yszltech depends on uuid ^1.0.3, flutter_cache_manager >=0.3.0 is forbidden.

    So, because yszltech depends on flutter_cache_manager ^1.1.3, version solving failed. pub get failed (1)

    please someone help me on this issue, thanks.

    opened by benjaminji 2
  • Error instantiating client

    Error instantiating client

    Good Morning, just try to integrate flutter_ssh. pubspec and import works fine but actually trying to connect i always receive the error "unknown_client". I am using it on a machine with android 7.1 and i also have included the libraries dependency in the build grade file.

    Any help solving my "stupid" error" highly appreciated :)

    Greets from Manila

    Ralph

    opened by ralph-fuechtenkort 2
  •  Error starting shell: Stream closed

    Error starting shell: Stream closed

    App Terminated :

    E/SshPlugin(20833): Error starting shell: Stream closed D/AndroidRuntime(20833): Shutting down VM E/AndroidRuntime(20833): FATAL EXCEPTION: main E/AndroidRuntime(20833): Process: com.parker.servicetool, PID: 20833 E/AndroidRuntime(20833): java.lang.IllegalStateException: Reply already submitted E/AndroidRuntime(20833): at io.flutter.embedding.engine.dart.DartMessenger$Reply.reply(DartMessenger.java:431) E/AndroidRuntime(20833): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler$1.error(MethodChannel.java:272) E/AndroidRuntime(20833): at sq.flutter.ssh.SshPlugin$MethodResultWrapper$2.run(SshPlugin.java:81) E/AndroidRuntime(20833): at android.os.Handler.handleCallback(Handler.java:938) E/AndroidRuntime(20833): at android.os.Handler.dispatchMessage(Handler.java:99) E/AndroidRuntime(20833): at android.os.Looper.loop(Looper.java:236) E/AndroidRuntime(20833): at android.app.ActivityThread.main(ActivityThread.java:7889) E/AndroidRuntime(20833): at java.lang.reflect.Method.invoke(Native Method) E/AndroidRuntime(20833): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:600) E/AndroidRuntime(20833): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967) I/Process (20833): Sending signal. PID: 20833 SIG: 9 Lost connection to device.

    How to handle this error.

    opened by sitakanta136 0
  • ssh 0.0.7 incompatible with web_socket_channel 2.1.0

    ssh 0.0.7 incompatible with web_socket_channel 2.1.0

    PLEASE UPDATE TO crypt 3.0.X ASAP IN 2021!

    Package web_socket_channel 2.1.0 used crypt 3.0.0. Package ssh 0.0.7 still used only crypt 2.0.0

    **Therefore it is not possible to use websockets 2.1.0 and ssh 0.0.7 for sftp fileupload in same project.

    Would you please so kind and update ssh 0.0.7 to 0.0.8 with current modern crypt 3.0.0?**

    Thank you in advance.

    opened by s681562 0
  • have plans to make this lib work on Flutter Windows

    have plans to make this lib work on Flutter Windows

    I'm currently developing an App Flutter for windows, where I need to send commands to a linux server via SSH, this commands will make the server mount a network share and copy backup files to this share, I'm trying to do this with this SSH lib https://github.com/TerminalStudio/dartssh

    I currently have this code:

    class SshService {
      final Uri uri;
      final String user;
      final String pass;
      SSHClient client;
      bool isConnected = false;
      StreamController<String> outStream;
    
      SshService({
        this.uri,//ssh://192.168.133.13:22
        this.user,
        this.pass,
      });
    
      Future<dynamic> connnect() {
        var completer = Completer<bool>();
        outStream = StreamController<String>.broadcast();
        try {
          client = SSHClient(
            hostport: uri,//ssh://192.168.133.13:22
            login: user,
            print: print,
            termWidth: 80,
            termHeight: 25,
            termvar: 'xterm-256color',
            getPassword: () => utf8.encode(pass),
            response: (transport, data) async {
              //print('SshService@response: ${utf8.decode(data)}');
              outStream.add(utf8.decode(data));
            },
            success: () {
              isConnected = true;
              Future.delayed(Duration(seconds: 1)).then((value) => completer.complete());
              print('SshService@success');
            },
            disconnected: () {
              print('SshService@disconnected');
              isConnected = false;
            },
          );
        } catch (e, s) {
          print('SshService@connnect $e $s');
          //completer.complete();
          completer.completeError(e, s);
        }
        return completer.future;
      }
    
      Future<String> sendCommand(String cmd) async {
        var completer = Completer<String>();
        try {
          client.sendChannelData(utf8.encode(cmd));
          var isEnd = false;
          var result = '';
          outStream.stream.listen((data) {
            //isaque.neves@laravel:/var/www/dart$
            result += data;
            if (data.trim().endsWith('\$')) {
              //print('stream.listen $data');
              if (isEnd == false) {
                isEnd = true;
                completer.complete(result);
              }
            }
          });
        } catch (e, s) {
          print('SshService@sendCommand $e $s');
          completer.completeError(e, s);
        }
        return completer.future;
      }
    
      void close() {
        client?.disconnect('terminate');
        outStream?.close();
      }
    }
    
    

    but it doesn't seem quite right

    opened by insinfo 0
  • ssh2 package

    ssh2 package

    Hi everyone, since this package seems to be abandoned I just wanted to leave a comment for everyone who faces the same problems as I did regarding the compatibility with other packages.

    Someone else forked this package and further developed it, please check out https://github.com/jda258/flutter_ssh2

    best regards.

    opened by ahoelzemann 1
An open source SFTP client for Android and iOS

RemoteFiles An open source SFTP client for Android and iOS. Website · Releases Downloads Google PlayStore APK file About RemoteFiles is an open source

Niklas Sauter 133 Jan 1, 2023
SFTP upload App for mobile

Tuma Upload files to SFTP servers. Help The data required to upload files to a specific path on an SFTP server is called a Target. Saved Targets are l

Imran Remtulla 6 Nov 6, 2022
Binding and high-level wrapper on top of libssh - The SSH library!

Dart Binding to libssh version 0.9.6 binding and high-level wrapper on top of libssh - The SSH library! libssh is a multiplatform C library implementi

Isaque Neves 2 Dec 20, 2021
MPV Remote: Remote control for MPV over SSH

MPV Remote Remote control for MPV over SSH. Big work-in-progress. Screenshots

Sam Lakerveld 1 Jun 2, 2022
A GraphQL client for Flutter, bringing all the features from a modern GraphQL client to one easy to use package. Built after react apollo

Flutter GraphQL Table of Contents Flutter GraphQL Table of Contents About this project Installation Usage GraphQL Provider [Graphql Link and Headers]

Snowball Digital 45 Nov 9, 2022
A GraphQL client for Flutter, bringing all the features from a modern GraphQL client to one easy to use package.

GraphQL Flutter ?? Bulletin See the v3 -> v4 Migration Guide if you're still on v3. Maintenance status: Low. Follow #762 for updates on the planned ar

Zino & Co. 3.1k Jan 5, 2023
Vrchat mobile client - VRChat Unofficial Mobile Client For Flutter

VRChatMC VRChatの非公式なAPIを利用したVRChatのモバイルクライアント Flutterで作成されたシンプルなUIが特徴的です iosビルドは

ふぁ 8 Sep 28, 2022
A wrapper around our Cocoa and Java client library SDKs, providing iOS and Android support for those using Flutter and Dart.

Ably Flutter Plugin A Flutter plugin wrapping the ably-cocoa (iOS) and ably-java (Android) client library SDKs for Ably, the platform that powers sync

Ably Realtime - our client library SDKs and libraries 46 Dec 13, 2022
App HTTP Client is a wrapper around the HTTP library Dio to make network requests and error handling simpler, more predictable, and less verbose.

App HTTP Client App HTTP Client is a wrapper around the HTTP library Dio to make network requests and error handling simpler, more predictable, and le

Joanna May 44 Nov 1, 2022
A simple and robust dart FTP Client Library to interact with FTP Servers with possibility of zip and unzip files.

Flutter FTP Connect Flutter simple and robust dart FTP Connect Library to interact with FTP Servers with possibility of zip and unzip files. Key Featu

Salim Lachdhaf 49 Dec 13, 2022
A fully-featured Last.fm client and scrobbler with Shazam-like scrobbling, a collage generator, home screen widgets, and more!

Finale A fully-featured Last.fm client and scrobbler with Shazam-like scrobbling, a collage generator, and more! The app is available on iOS, Android,

Noah Rubin 66 Jan 5, 2023
Unsplash Client App written using dart and flutter. (Work in progress)

Upsplash Unofficial Unsplash client written using dart and flutter Sreenshots Architecture The goal of this pattern is to make it easy to separate pre

Arslan 25 Sep 1, 2022
An efficient and easy CA-Client interaction flutter project

Cloud Accounting An efficient and easy CA-Client interaction flutter project This is an application for a CA to interact with its clients. Clients can

null 1 Dec 18, 2022
A client for Pleroma and Mastodon instances written using Flutter

Fedi for Pleroma and Mastodon Fedi is open-source client for Pleroma and Mastodon social networks written using Flutter. Pleroma and Mastodon are part

null 99 Dec 24, 2022
A Dart client for the NATS messaging system. Design to use with Dart and Flutter.

Dart-NATS A Dart client for the NATS messaging system. Design to use with Dart and flutter. Flutter Web Support by WebSocket client.connect(Uri.parse(

Chart Chongcharoen 32 Nov 18, 2022
Yaz State and Content Manager For Flutter Client

yaz Yaz Package for State, Content and User's Options Managements Introduction This package is supported for Web, Mobile and Desktop applications. Yaz

Mehmet Yaz 3 Nov 15, 2022
Zone is yet another Hacker News client, built with Flutter, Slidy, and Hacker News API.

Zone for Hacker News Zone is yet another Hacker News client, built with Flutter, Slidy, and Hacker News API. Setup Clone this repo to your machine Req

null 11 Feb 27, 2022
Generates a new Flutter app with http client, theme, routing and localization features.

Starter Template Generates a new Flutter app with http client, theme, routing and localization features. Brick Uses: dio as http client pretty_dio_log

Cem Avcı 12 Nov 3, 2022
Flutter Client for the stability.ai GRPC protocol, should be compatible with grpc.stability.ai and hafriedlander/stable-diffusion-grpcserver

idea2art This is idea2.art, a Flutter client for the stability.ai GRPC API for Stable Diffusion. It's usable both with the cloud-based grpc.stability.

Hamish Friedlander 9 Dec 5, 2022