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

Overview

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.

Comments
  • Create and Write to file

    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;
    

    }); }

    opened by yinhang1107 4
  • Question: Server auth requires keyboard interaction.

    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?

    opened by ShadowOfThePenguin 3
  • sftp: FormatException: Unexpected extension byte (at offset 0)

    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)
    
    opened by holobeat 2
  • How do I know a SftpName of type SymbolicLink is linked to a directory or a file?

    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);
      }
    }
    
    opened by jonahzheng 2
  • [SFTP] cannot remove characters from file

    [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?

    opened by LucasAschenbach 1
  • Killing the session results in an internal unhandled exception

    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

    opened by lmmfranco 1
  • Copy file?

    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!

    opened by Migarl 1
  • Support ssh v2 when version string does not contain CR

    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
    
    opened by Migarl 1
  • Can I programmatically perform remote forwarding?

    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 user@<remote_server_ip>

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

    opened by rohanpanuganti 1
  • DiffieHellman is not show

    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

    opened by dan12411 1
  • Local port forwarding

    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.

    opened by FaFre 1
  • Feature Request: Host Key Verification

    Feature Request: Host Key Verification

    Hello. I wonder if there are any plans to implement Host Key Verification function. (Server host key can be returned, whether to connect through server host key acceptance)

    As in the following ssh2.js (SSH client implemented in JavaScript) hostVerifier example, I would like to be given a server hash to compare against, and handle the process of accepting or rejecting connections via a callback.

    https://github.com/mscdex/ssh2#:~:text=Default%3A%20(none)-,hostVerifier,-%2D%20function%20%2D%20Function

    If this is not currently possible, it would be nice if implemented in the future.

    Regards,

    opened by jooy2 0
  • Halting when uploading 0 bytes files.

    Halting when uploading 0 bytes files.

    When attempting to SFTP upload an empty file (with 0 bytes in size) the upload halts (neither raises an error, no exits the program).

    The client machine where the program is executes is Windows the remote one is Amazon Linux 2.

    One might wonder what is the use case for such files. Sometime programs create programx.lock files which are used as a persisted on file system boolean switch.

    opened by gaddlord 0
  • auth with rsa privacy key. but have error: SSHAuthFailError(All authentication methods failed)

    auth with rsa privacy key. but have error: SSHAuthFailError(All authentication methods failed)

    this is log:

    flutter: SSHTransport._sendKexInit flutter: SSHTransport._processVersionExchange flutter: SSHTransport._remoteVersion = "SSH-2.0-OpenSSH_6.4" 2 flutter: SSHTransport._processPackets flutter: SSHTransport._consumeClearTextPacket flutter: SSHTransport._handleMessageKexInit flutter: SSHTransport._kexType: SSHKexType(ecdh-sha2-nistp521) flutter: SSHTransport._hostkeyType: SSHHostkeyType(ssh-rsa) flutter: SSHTransport._clientCipherType: SSHCipherType(aes128-ctr) flutter: SSHTransport._serverCipherType: SSHCipherType(aes128-ctr) flutter: SSHTransport._clientMacType: SSHMacType(hmac-sha1) flutter: SSHTransport._serverMacType: SSHMacType(hmac-sha1) flutter: SSHTransport._sendKexDHInit flutter: SSHTransport._processPackets flutter: SSHTransport._consumeClearTextPacket flutter: SSHTransport._handleMessageKexReply flutter: SSHTransport._consumeClearTextPacket flutter: SSHTransport._handleMessageNewKeys flutter: SSHTransport._sendNewKeys flutter: SSHClient._onTransportReady flutter: SSHClient._requestAuthentication flutter: SSHTransport._processPackets flutter: SSHTransport._consumeEncryptedPacket flutter: SSHClient._startAuthentication flutter: SSHClient._tryNextAuthenticationMethod flutter: _currentAuthMethod = SSHAuthMethod.publicKey flutter: SSHClient._authWithPublicKey flutter: SSHTransport._processPackets flutter: SSHTransport._consumeEncryptedPacket flutter: SSHClient._handleUserauthFailure flutter: SSHClient._tryNextAuthenticationMethod flutter: _currentAuthMethod = SSHAuthMethod.none flutter: SSHClient._authWithNone flutter: SSHTransport._processPackets flutter: SSHTransport._consumeEncryptedPacket flutter: SSHClient._handleUserauthFailure flutter: SSHClient._tryNextAuthenticationMethod flutter: SSHTransport.closeWithError SSHAuthFailError(All authentication methods failed)

    I try to use FileZilla to connect, it's fine. So I don't know where I'm going wrong

    opened by openUmbrella 1
  • Feature Request: Support KeepAlive Option

    Feature Request: Support KeepAlive Option

    Hello. Thanks for creating & developing the dartssh2 project.

    I am developing a terminal app with shell interaction using dartssh2.

    Are the KeepAliveInterval and KeepAliveCountMax values configurable via dartssh2 options on the client?

    I looked for a similar issue below but couldn't find the answer I was looking for. https://github.com/TerminalStudio/dartssh2/issues/27

    If not, hopefully a feature will be added in the future.

    Regards,


    (Please ignore the problem I had below. It was a hardware issue with my development rig.)

    When the SSH connection is completed, the connection is forcibly closed after a certain amount of time with the error below.

    (An error is displayed when a key input is attempted after a certain amount of time has elapsed.)

    E/flutter (21226): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: SSHStateError(Transport is closed)
    E/flutter (21226): #0      SSHTransport.sendPacket (package:dartssh2/src/ssh_transport.dart:183:7)
    E/flutter (21226): #1      SSHClient._sendMessage (package:dartssh2/src/ssh_client.dart:460:16)
    E/flutter (21226): #2      SSHChannelController._sendEOFIfNeeded (package:dartssh2/src/ssh_channel.dart:269:16)
    E/flutter (21226): #3      SSHChannelController.close (package:dartssh2/src/ssh_channel.dart:200:5)
    E/flutter (21226): #4      SSHClient._closeChannels (package:dartssh2/src/ssh_client.dart:428:15)
    E/flutter (21226): #5      SSHClient._onTransportClosed (package:dartssh2/src/ssh_client.dart:447:5)
    E/flutter (21226): #6      new SSHClient.<anonymous closure> (package:dartssh2/src/ssh_client.dart:161:23)
    E/flutter (21226): #7      _RootZone.runUnary (dart:async/zone.dart:1653:54)
    E/flutter (21226): #8      _FutureListener.handleError (dart:async/future_impl.dart:165:22)
    E/flutter (21226): #9      Future._propagateToListeners.handleError (dart:async/future_impl.dart:778:47)
    E/flutter (21226): #10     Future._propagateToListeners (dart:async/future_impl.dart:799:13)
    E/flutter (21226): #11     Future._completeError (dart:async/future_impl.dart:574:5)
    E/flutter (21226): #12     Future._asyncCompleteError.<anonymous closure> (dart:async/future_impl.dart:665:7)
    E/flutter (21226): #13     _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
    E/flutter (21226): #14     _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)
    

    Connection code

    connect() async {
        final socket = await SSHSocket.connect('host', 'port');
    
        _client = SSHClient(
          socket,
          username: 'username',
          onPasswordRequest: () {
            return 'password';
          },
        );
    
        _shell = await _client.shell();
    }
    

    pubspec.yarn

    dependencies:
      flutter:
        sdk: flutter
    
      dartssh2: 2.7.3
    
    opened by jooy2 1
  • Write on shell

    Write on shell

    Hi !

    Is there a way to write from the code to the shell and not the IDE terminal

    I'm implementing the code form the shell example and it works fine:

    final shell = await client.shell();
    stdout.addStream(shell.stdout);
    stderr.addStream(shell.stderr);
    stdin.cast<Uint8List>().listen(shell.write);
    

    But I would like to be able to write multiple entry lines from the code to the open shell

    opened by laura-rodriguez8 3
Flutter: Overriding Dependencies | Solving Version Conflicts | Solving Version Conflicts

flutterutils A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if

Pawan Kumar 51 Mar 2, 2022
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

Muhammad Hamza 28 Nov 10, 2022
Astronomy Picture of The Day gives you the best picture or a video nasa took on that particular date, or today.

NASA Astronomical Picture of the Day (APOD) A simple Flutter Application that shows a list of Astronomical Pictures in chronological order fetched fro

Aman Jain 2 Nov 4, 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..

Armel Soro 20 Dec 14, 2022
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

Pawan Kumar 179 Jan 4, 2023
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

Pawan Kumar 644 Dec 20, 2022
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

Pawan Kumar 46 Jun 16, 2022
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

Souvik Biswas 186 Dec 24, 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

Bdaya Development 0 Nov 2, 2021
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.

null 4 Nov 14, 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'

Dutch Coding Company 1 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

gskinner team 22 Nov 28, 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

gskinner team 22 Nov 28, 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. It's a simple app that uses a simple logo, two text fields and a button that calculate and show the best option.

Cácio Lucas 0 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

null 6 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.

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

Gabriel García 23 Jan 3, 2023
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.

Ayush Shekhar 19 Nov 11, 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 Beautiful Material Design Music Player(Online Radio will be added soon.) Demo App Play Store BETA

Pawan Kumar 1.5k Jan 2, 2023
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

Pawan Kumar 316 Nov 23, 2022