A pure dart SSH implementation based on dartssh, with bug fixes, up-to-date dependencies and sound null safety.

Last update: Aug 5, 2022

DartSSH 2

pub package Build status Coverage Status documentation

dartssh2 is a pure dart SSH implementation based on dartssh, with bug fixes, up-to-date dependencies and sound null safety.

dartssh2 providing first-class tunnelling primitives.

Feature support

Keys Ed25519, ECDSA, RSA
KEX X25519DH, ECDH, DHGEX, DH
Cipher AES-CTR, AES-CBC
MAC MD5, SHA
Compression not yet supported
Forwarding TCP/IP, Agent
Tunneling drop-ins for Socket, WebSocket, package:http

Try

# Install the `dartssh` command.
dart pub global activate dartssh2

# Then use `dartssh` as regular `ssh` command.
dartssh [email protected]

If the dartssh command can not be found after installation, you might need to set up your path.

Quick start - SSH client

Click to see more:
import 'package:dartssh2/dartssh2.dart';
TODO
TODO

Quick start - SSH server

Click to see more:
import 'package:dartssh2/dartssh2.dart';
TODO
TODO

Example

SSH client: example/dartssh.dart

SSH server: example/dartsshs.dart

Roadmap

  • Fix broken tests
  • Sound null safety
  • Redesign API to allow starting multiple sessions. In progress...
  • SFTP

References

  • RFC 4251 The Secure Shell (SSH) Protocol Architecture
  • RFC 4252 The Secure Shell (SSH) Authentication Protocol
  • RFC 4253 The Secure Shell (SSH) Transport Layer Protocol
  • RFC 4254 The Secure Shell (SSH) Connection Protocol
  • RFC 4255 Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints
  • RFC 4256 Generic Message Exchange Authentication for the Secure Shell Protocol (SSH)

Credits

https://github.com/GreenAppers/dartssh by GreenAppers

License

dartssh is released under the terms of the MIT license. See LICENSE.

GitHub

https://github.com/TerminalStudio/dartssh2
Comments
  • 1. Create and Write to file

    Hi, I was trying to create a text file and write to it. However, every time I run the test, I was able to create the file or write to the file but got an error when I wanted to create and write to it. Below is my example.

    void main() { test('', () async { final socket = await SSHSocket.connect('localhost', 22);

    final client = SSHClient(
      socket,
      username: 'yh',
      onPasswordRequest: () => 'secret',
    );
    
    final sftp = await client.sftp();
    await sftp.open(
      'asdf.txt',
      mode: SftpFileOpenMode.create,
    );
    
    final file1 = await sftp.open('asdf.txt', mode: SftpFileOpenMode.write);
    final lists = 'asdfasdf'.codeUnits;
    await file1.writeBytes(Uint8List.fromList(lists));
    
    client.close();
    await client.done;
    

    }); }

    Reviewed by yinhang1107 at 2022-01-14 03:20
  • 2. Question: Server auth requires keyboard interaction.

    I know this is kind of an edge case, however I am trying to log into the sftp server of a piece of equipment I work with, and it requires some sort of keyboard interaction with the cl as part of the password. I have been poking around several different packages, and have not been able to figure out how this works. I was able to sign in using the node library 'ssh2-sftp-client' with the parameter of 'tryKeyboard' set to true. I would really prefer to build this as a flutter app, instead of js. Is there a way in the 'onPasswordRequest' function that I can add this keyboard interaction?

    Reviewed by ShadowOfThePenguin at 2022-04-16 00:07
  • 3. How do I know a SftpName of type SymbolicLink is linked to a directory or a file?

    final sftp = await client.sftp();
    final items = await sftp.listdir('/');
    for (final item in items) {
      if ((file.attr.isSymbolicLink)){
         print(item.longname);
      }
    }
    
    Reviewed by jonahzheng at 2022-06-01 09:50
  • 4. [SFTP] cannot remove characters from file

    Perhaps I missed it when going though the code but I couldn't find a way to remove characters from a file using the SFTP client, other than by truncating the entire file.

    Is there a way to do that with this library?

    Reviewed by LucasAschenbach at 2022-06-05 19:24
  • 5. Killing the session results in an internal unhandled exception

    Example:

    import 'dart:io';
    import 'package:dartssh2/dartssh2.dart';
    
    void main() async {
      var client = SSHClient(
        await SSHSocket.connect("192.168.0.1", 22),
        username: "root",
        onPasswordRequest: () => "mypass",
      );
    
      final session = await client.execute('sleep 10');
      stdout.addStream(session.stdout);
      stderr.addStream(session.stderr); 
      
      session.done.then((_) {
        print("session done");
        client.close();
      }).catchError((err) {
        print("session errored");
        client.close();
      });
    
      await Future.delayed(Duration(seconds: 2));
      session.kill(SSHSignal.INT);
    }
    

    Alternatively:

    import 'dart:io';
    import 'package:dartssh2/dartssh2.dart';
    
    void main() async {
      var client = SSHClient(
        await SSHSocket.connect("192.168.0.1", 22),
        username: "root",
        onPasswordRequest: () => "mypass",
      );
    
      final session = await client.execute('sleep 10');
      stdout.addStream(session.stdout);
      stderr.addStream(session.stderr); 
      
      await Future.delayed(Duration(seconds: 2));
      session.kill(SSHSignal.INT);
    
      await session.done;
      client.close();
    }
    

    Will both result in this exception being thown:

    Unhandled exception:
    Null check operator used on a null value
    #0      SSHSession._handleRequest (package:dartssh2/src/ssh_session.dart:119:41)
    #1      SSHChannelController._handleRequestMessage (package:dartssh2/src/ssh_channel.dart:234:36)
    #2      SSHChannelController.handleMessage (package:dartssh2/src/ssh_channel.dart:185:7)
    #3      SSHClient._handleChannelRequest (package:dartssh2/src/ssh_client.dart:705:42)
    #4      SSHClient._dispatchMessage (package:dartssh2/src/ssh_client.dart:489:16)
    #5      SSHClient._onPacket (package:dartssh2/src/ssh_client.dart:432:7)
    #6      SSHTransport._handleMessage (package:dartssh2/src/ssh_transport.dart:639:19)
    #7      SSHTransport._processPackets (package:dartssh2/src/ssh_transport.dart:312:7)
    #8      SSHTransport._processData (package:dartssh2/src/ssh_transport.dart:257:7)
    #9      SSHTransport._onSocketData (package:dartssh2/src/ssh_transport.dart:235:7)
    #10     _RootZone.runUnaryGuarded (dart:async/zone.dart:1620:10)
    #11     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
    #12     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
    #13     _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:733:19)
    #14     _StreamController._add (dart:async/stream_controller.dart:607:7)
    #15     _StreamController.add (dart:async/stream_controller.dart:554:5)
    #16     _Socket._onData (dart:io-patch/socket_patch.dart:2166:41)
    #17     _RootZone.runUnaryGuarded (dart:async/zone.dart:1620:10)
    #18     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
    #19     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
    #20     _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:733:19)
    #21     _StreamController._add (dart:async/stream_controller.dart:607:7)
    #22     _StreamController.add (dart:async/stream_controller.dart:554:5)
    #23     new _RawSocket.<anonymous closure> (dart:io-patch/socket_patch.dart:1702:33)
    #24     _NativeSocket.issueReadEvent.issue (dart:io-patch/socket_patch.dart:1213:14)
    #25     _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
    #26     _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)
    #27     _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:120:13)
    #28     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:185:5)
    

    The problem also happens with shell.kill(), and won't happen if you dont use the .done promise

    Reviewed by lmmfranco at 2022-01-18 16:57
  • 6. Copy file?

    Hi!

    I want to copy a file (.tgz) from my host to the server (scp isn't available).

    I tried

    final session = await client.execute("tar -zxf -");
    session.write(filebytes);
    

    but without success. I think the problem is that tar don't know when he should stop listening on stdin.

    I got the same result with cat > file.tgz.

    Is there a way to copy a file from host to remote without scp?

    Thanks for your help!

    Reviewed by Migarl at 2022-01-12 13:17
  • 7. Support ssh v2 when version string does not contain CR

    It was observed that there are ssh-2 servers that are not compliant with RFC4253 and terminate the version string only with (not preceded by ).

    This PR aims to support this kind of non-compliant server.

    The observation was made on a Synology NAS DS120j (kernel date March 2021):

    $ uname -a
    Linux NAS11 4.4.59+ #25556 SMP Thu Mar 4 18:01:32 CST 2021 aarch64 GNU/Linux synology_armada37xx_ds120j
    
    Reviewed by Migarl at 2022-01-11 17:43
  • 8. Can I programmatically perform remote forwarding?

    Inside my main.dart I want to make a remote forwarding call like this:

    ssh -R 80:127.0.0.1:3000 [email protected]<remote_server_ip>

    Is that currently possible and if so how would I go about doing it?

    Reviewed by rohanpanuganti at 2021-12-30 09:56
  • 9. DiffieHellman is not show

    SSHDiffieHellman is comment out, could remove this comment, and show EllipticCurveDiffieHellman, DiffieHellman & ScalarMult? thanks :) https://github.com/TerminalStudio/dartssh2/blob/3316b252ace4948f64812b7e5eca11f466d3f62d/lib/dartssh2.dart#L19

    Reviewed by dan12411 at 2021-12-15 01:01
  • 10. Local port forwarding

    I tested the local port forwarding feature, but cannot get it running.

    SSH Command I want to run: ssh 172.17.0.2 -l root -L 1234:localhost:80 With the dart client: dart run dartssh.dart -l root 172.17.0.2 --debug --password test --tunnel localhost:80

    Is my command right at this point?

    It says tunnel is up, but curl 127.0.0.1:1234 responds connection refused.

    Reviewed by FaFre at 2021-12-08 19:38
  • 11. fixed bug in exporting openssh private key to pem

    openssh private key padding must start with 1 and not 0 as it was before (altho comments in code say to start with 1). If padding is needed, it must be a right-trimmed substring of '0x01020304050607', as noted in https://coolaj86.com/articles/the-openssh-private-key-format/

    It used to produce keys with ssh-keygen would consider as 'invalid format' key, now it works as intended

    Reviewed by PIDAMI at 2022-07-13 13:36
  • 12. file size is not correct

    I am using dartssh2 and I am trying to get the file size with sftp but it displaying 4096 almost all the time sometimes i get another number but still not correct if run the command du -h --max-depth=1 | sort -hr it prints out:

    [email protected]:~# du -h --max-depth=1 | sort -hr
    44K     .
    16K     ./snap
    4.0K    ./.ssh
    4.0K    ./.cache
    

    but in my program:

    image

    I am using dartssh2: ^2.7.2+3 and flutter sdk: ">=2.17.6 <3.0.0"

    Reviewed by seifalmotaz at 2022-08-07 20:27
  • 13. sftp: FormatException: Unexpected extension byte (at offset 0)

    The following code fails on stat or open. The sftp site is a site with public access. I am able to test the site access with FileZilla without any issues. The same behavior on both Linux and Windows.

    import 'package:dartssh2/dartssh2.dart';
    
    void main(List<String> args) async {
      final socket = await SSHSocket.connect('sftp.floridados.gov', 22);
    
      final client = SSHClient(
        socket,
        username: 'Public',
        onPasswordRequest: () => 'PubAccess1845!',
        onAuthenticated: () => print('*** Signed in'),
        printTrace: (msg) => print('TRACE: $msg'),
        printDebug: (msg) => print('DEBUG: $msg'),
      );
    
      final sftp = await client.sftp();
      print('*** Before calling stat');
      final stat = await sftp.stat('/');
    
      print(stat.size);
      print(stat.mode);
    
      client.close();
      await client.done;
    }
    

    StackTrace:

    Unhandled exception:
    FormatException: Unexpected extension byte (at offset 0)
    #0      _Utf8Decoder.convertSingle (dart:convert-patch/convert_patch.dart:1755:7)
    #1      Utf8Decoder.convert (dart:convert/utf.dart:351:42)
    #2      Utf8Codec.decode (dart:convert/utf.dart:63:20)
    #3      SSHMessageReader.readUtf8 (package:dartssh2/src/ssh_message.dart:75:17)
    #4      new SftpVersionPacket.decode (package:dartssh2/src/sftp/sftp_packet.dart:105:28)
    #5      SftpClient._handleVersionPacket (package:dartssh2/src/sftp/sftp_client.dart:410:38)
    #6      SftpClient._handlePacket (package:dartssh2/src/sftp/sftp_client.dart:392:16)
    #7      SftpClient._handlePackets (package:dartssh2/src/sftp/sftp_client.dart:384:7)
    #8      SftpClient._handleData (package:dartssh2/src/sftp/sftp_client.dart:374:5)
    #9      _RootZone.runUnaryGuarded (dart:async/zone.dart:1618:10)
    #10     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
    #11     _DelayedData.perform (dart:async/stream_impl.dart:591:14)
    #12     _StreamImplEvents.handleNext (dart:async/stream_impl.dart:706:11)
    #13     _PendingEvents.schedule.<anonymous closure> (dart:async/stream_impl.dart:663:7)
    #14     _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
    #15     _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)
    #16     _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:122:13)
    #17     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:193:5)
    
    Reviewed by holobeat at 2022-07-08 04:13
  • 14. SSHAuthAbortError(Connection closed before authentication)

    I've vsftp hosted on my vps but whenever I try to connect via sftp it shows this err.

    Tue Apr 26 03:08:58 2022 [pid 8454] CONNECT: Client "::ffff:ip>"

    this is all it shows in the log, I tried to connect with filezilla by copy pasting ip, port, username and pw and it worked perfectly so there isn't any mistake in credentials.

    The dart code is same as documented

    final sftp = await client.sftp(); final items = await sftp.listdir('/'); for (final item in items) { print(item.longname); }

    Reviewed by ssddOnTop at 2022-04-26 03:12
  • 15. Forward Remote connection does not disconnect when client app disconnect

    Following is my connection scenario: PC 1: listen local:8000. RemoteForwarding:remoteServer 8000 -> local 8000 , and do //here I launch with another thread Future.delay(Duration.zero, () async { await for (final connection in forward.connections) { final socket = await Socket.connect('localhost', 8000); connection.stream.cast<List>().pipe(socket); socket.pipe(connection.sink); } }

    remoteServer : nginx /connection -> localhost:8000

    PC2: ws://remoteServer/connection

    When connected , everything works very well. But when PC2 disconnect, the sshd instance on remoteServer does not stop which was still running with 8000 port . This make the forwarding fail for the next time.

    I wonder what I should do to enforce the disconnection when client disconnect from the remote server port.

    Reviewed by delphi007 at 2022-04-21 14:45

Related

Flutter Sound Editing App - Midia App
 Flutter Sound Editing App - Midia App

Flutter Sound Editing App - Midia App I uploaded on youtube!! Thanks to Watch And Thanks to Subscribe!!! Introduction I'm working on a project to laun

Nov 1, 2021
Amaan Women Safety App Built Using Flutter
Amaan Women Safety App Built Using Flutter

Amaan - You Deserve to be Safe! This is Hackfair 2.0 Submission where team from Google DSC COMSATS University Islamabad developed a women safety app a

Aug 13, 2022
Flutter-based mobile app displaying a list of daily curated content from top engineering blogs and articles. Backed by a GraphQL-based API written in Kotlin..
Flutter-based mobile app displaying a list of daily curated content from top engineering blogs and articles. Backed by a GraphQL-based API written in Kotlin..

Flutter-based mobile app displaying a list of daily curated content from top engineering blogs and articles. Backed by a GraphQL-based API written in Kotlin..

May 31, 2022
An Login Page App in Flutter with MVP and SQFLITE ( SQLITE) Implementation.
An Login Page App in Flutter with MVP and SQFLITE ( SQLITE) Implementation.

Flutter SQFLITE MVP LOGIN APP A Login Page Flutter App with SQFLITE (SQLITE) and MVP implementation. Written in dart using Flutter SDK. Please don't f

Aug 7, 2022
A Flutter app with firebase libraries implementation
A Flutter app with firebase libraries implementation

FlutFire A Flutter project with implementation of all firebase libraries for Android and iOS both. Show some ❤️ and star the repo to support the proje

Jul 24, 2022
A simple flutter app with demo implementation of redux.
A simple flutter app with demo implementation of redux.

Flutter Redux Tutorial Redux Project is just a quick guide for implementation of redux.dart and flutter_redux . Written in dart using Flutter SDK. Ple

Jun 16, 2022
Firebase + Flutter sample apps with code snippets, supported by comprehensive articles for each implementation.
Firebase + Flutter sample apps with code snippets, supported by comprehensive articles for each implementation.

FlutterFire Samples This repo is created to contain various sample apps demonstrating the integration of Firebase with Flutter. The final goal is to c

Aug 11, 2022
a better implementation of myfatoorah_flutter

myfatoorah_flutter In order to simplify the integration of your application with MyFatoorah payment platforms, we have developed a cutting-edge plugin

Nov 2, 2021
A simple POC implementation of the project Real World Project
A simple POC implementation of the project Real World Project

Real World Project in Dart/Flutter This is a simple POC implementation of the project Real World Project.

Apr 12, 2022
Wraps flutter_svg and the Flutter SDK image providers and picks the right widget based on the file extension

Hybrid Image Wraps flutter_svg and the Flutter SDK image providers and picks the right widget based on the file extension Features As of right now it'

Jun 18, 2022
A simple but powerful path-based navigation router with full web-browser and deeplink support.

nav_stack A simple but powerful path-based routing system, based on MaterialApp.router (Nav 2.0). It has browser / deeplink support and maintains a hi

Jun 9, 2022
A simple but powerful path-based navigation router with full web-browser and deeplink support.

nav_stack A simple but powerful path-based routing system, based on MaterialApp.router (Nav 2.0). It has browser / deeplink support and maintains a hi

Jun 9, 2022
This app it's a simple app to help you choose between alcool or gasoline based on the price of the gasoline and the price of the alcool.
This app it's a simple app to help you choose between alcool or gasoline based on the price of the gasoline and the price of the alcool.

This app it's a simple app to help you choose between alcool or gasoline based on the price of the gasoline and the price of the alcool. It's a simple app that uses a simple logo, two text fields and a button that calculate and show the best option.

Oct 3, 2021
A cross-platform BlockChain Based Application that performs Data and Sentimental Analysis using Machine Learning Algorithms.

DynaMedico Mobile App A new Flutter application. Getting Started This project is a starting point for a Flutter application. A few resources to get yo

May 10, 2022
A simple app for studying the japanese vocabulary you will learn in your japanese learning journey based on cards with meaning, pronunciation and kanji.
A simple app for studying the japanese vocabulary you will learn in your japanese learning journey based on cards with meaning, pronunciation and kanji.

KanPractice A simple app for studying the japanese vocabulary you will learn in your japanese learning journey based on cards with meaning, pronunciat

Jul 10, 2022
An app to get you the latest and the trending news based on your location.

An app to get you the latest and the trending news based on your location.

Feb 10, 2022
Flutter Music Player - First Open Source Flutter based material design music player with audio plugin to play local music files.
Flutter Music Player - First Open Source Flutter based material design music player with audio plugin to play local music files.

Flutter Music Player First Open Source Flutter based Beautiful Material Design Music Player(Online Radio will be added soon.) Demo App Play Store BETA

Aug 14, 2022
Flute Music Player - First Open Source Flutter based material design music player with audio plugin to play local music files.
Flute Music Player - First Open Source Flutter based material design music player with audio plugin to play local music files.

Flute Music Player Plugin Only Updated to androidx First Open Source Flutter based material design music player with audio plugin to play local music

Aug 6, 2022
Flutter based Open Source Hentai Viewer App
Flutter based  Open Source Hentai Viewer App

Flutter based Open Source Hentai Viewer App

Aug 3, 2022