SSH and SFTP client for Flutter

Last update: Mar 4, 2022

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.

GitHub

https://github.com/shaqian/flutter_ssh
Comments
  • 1. 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

    Reviewed by nn1ks at 2019-07-10 21:57
  • 2. "@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)

    Reviewed by Akoszewski at 2019-09-10 16:15
  • 3. 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.

    Reviewed by pbaker5 at 2019-02-27 21:35
  • 4. 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

    Reviewed by MrHazee at 2020-05-07 08:43
  • 5. 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.

    Reviewed by newnishad at 2020-04-25 14:40
  • 6. 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)

    Reviewed by mevans at 2018-10-10 18:54
  • 7. 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") {`
            ...
    
    
    Reviewed by track02 at 2019-05-21 16:02
  • 8. 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?

    Reviewed by writingdeveloper at 2021-05-19 10:44
  • 9. 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

    Reviewed by prinzpiuz at 2020-04-04 10:52
  • 10. 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.

    Reviewed by benjaminji at 2019-12-16 12:40
  • 11. 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

    Reviewed by ralph-fuechtenkort at 2019-11-15 02:54
  • 12. 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.

    Reviewed by sitakanta136 at 2022-01-20 10:27
  • 13. 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.

    Reviewed by s681562 at 2021-10-07 00:58
  • 14. 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('[email protected]: ${utf8.decode(data)}');
              outStream.add(utf8.decode(data));
            },
            success: () {
              isConnected = true;
              Future.delayed(Duration(seconds: 1)).then((value) => completer.complete());
              print('[email protected]');
            },
            disconnected: () {
              print('[email protected]');
              isConnected = false;
            },
          );
        } catch (e, s) {
          print('[email protected] $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) {
            //[email protected]:/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('[email protected] $e $s');
          completer.completeError(e, s);
        }
        return completer.future;
      }
    
      void close() {
        client?.disconnect('terminate');
        outStream?.close();
      }
    }
    
    

    but it doesn't seem quite right

    Reviewed by insinfo at 2021-08-27 21:21
  • 15. 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.

    Reviewed by ahoelzemann at 2021-08-24 08:25

Related

SFTP upload App for mobile
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

Sep 24, 2021
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

Dec 20, 2021
MPV Remote: Remote control for MPV over SSH
MPV Remote: Remote control for MPV over SSH

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

Feb 12, 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]

Jul 22, 2021
A GraphQL client for Flutter, bringing all the features from a modern GraphQL client to one easy to use package.
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

May 26, 2022
Vrchat mobile client - VRChat Unofficial Mobile Client For Flutter
Vrchat mobile client - VRChat Unofficial Mobile Client For Flutter

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

Feb 15, 2022
A wrapper around our Cocoa and Java client library SDKs, providing iOS and Android support for those using Flutter and Dart.
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

May 5, 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

May 15, 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

May 23, 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,

May 13, 2022
Unsplash Client App written using dart and flutter. (Work in progress)
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

May 4, 2021
An efficient and easy CA-Client interaction flutter project
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

Dec 2, 2021
A client for Pleroma and Mastodon instances written using Flutter
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

May 7, 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(

Jan 26, 2022
Yaz State and Content Manager For Flutter Client
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

Oct 4, 2021
Zone is yet another Hacker News client, built with Flutter, Slidy, and Hacker News API.
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

Feb 27, 2022
This is a simple client of Reddit built with MVVM and Provider powered by a custom OAuth2.0 login

?? ?? ?? Flutter Starter Architecture (MVVM + Hive) My custom starter project for Flutter apps. I was looking for a simple way to build Flutter app in

Apr 1, 2022
Weather app using Bloc architecture pattern & generic HTTP client with interface implementation and much more for more detail read Readme
Weather app using Bloc architecture pattern & generic HTTP client with interface implementation and much more for more detail read Readme

weather Weather application for current weather, hourly forecast for 48 hours, Daily forecast for 7 days and national weather alerts. How to Run Insta

Jan 28, 2022
Powerful, helpfull, extensible and highly customizable API's that wrap http client to make communication easier with Axelor server with boilerplate code free.
Powerful, helpfull, extensible and highly customizable API's that wrap http client to make communication easier with Axelor server with boilerplate code free.

flutter_axelor_sdk Powerful, helpful, extensible and highly customizable API's that wrap http client to make communication easier with Axelor server w

Nov 12, 2021