Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug fix in SftpFileWriter and increased version constraints #104

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
## [3.0.0] - 2024-08-13

- Changed version constraints for package `pinenacl` from `^0.5.0` to `">=0.5.0 <1.0.0"` to support Dart SDK `>= 3.5.0`. See Dart SDK [Changelog](https://github.com/dart-lang/sdk/blob/3ccadc5c277a6c70f207d14600524578f4c527ad/CHANGELOG.md?plain=1#L106).

- Bumped SDK constraints from `">=2.17.0 <3.0.0"` up to `">=2.17.0 <4.0.0"`

- Bug fix in `SftpFileWriter` for [#50](https://github.com/TerminalStudio/dartssh2/issues/50), [#71](https://github.com/TerminalStudio/dartssh2/issues/71), [#100](https://github.com/TerminalStudio/dartssh2/issues/100):

When the input stream contains only one event and that event has fewer bytes than `maxBytesOnTheWire`, then the `SftpFileWriter._doneCompleter` never got completed. This happened because the completer got only completed in the `_handleLocalData` event handler if the `_streamDone` flag was already true, the problem is that if the stream only has one small event, then `_handleLocalData` will only be called once with the event and afterward `_handleLocalDone` will be called once, which sets `_streamDone` to true. At this point the `_doneCompleter` cannot be completed anymore because the `_handleLocalData` will not get called anymore. This problem causes never ending `await` statements when opening and writing a file.

This issue has been fixed by checking if all sent bytes have already been acknowledged in the `_handleLocalDone` event handler and subsequently completing the `_doneCompleter`.
```dart
void _handleLocalDone() {
_streamDone = true;
if (_bytesSent == _bytesAcked) {
_doneCompleter.complete();
}
}
```

- Added return type `SftpFileOpenMode` to operator `|` in class `SftpFileOpenMode`. Fix for [#80](https://github.com/TerminalStudio/dartssh2/issues/80).

## [2.9.1-pre] - 2023-04-02
- Make the type of `SSHForwardChannel.sink` to `StreamSink<List<int>>` to match
its super class.
Expand Down
1 change: 1 addition & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
MIT License

Copyright (c) 2022 xuty
Copyright (c) 2024 Emanuel Oberholzer

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
29 changes: 14 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,29 @@
<!-- Title-->
<p align="center">
<h1 align="center">DartSSH 2</h1>
<h1 align="center">DartSSH 3</h1>
</p>

<!-- Badges-->
<p align="center">
<a href="https://pub.dartlang.org/packages/dartssh2">
<img src="https://img.shields.io/pub/v/dartssh2.svg">
<a href="https://pub.dartlang.org/packages/dartssh3">
<img src="https://img.shields.io/pub/v/dartssh3.svg">
</a>
<a href="https://pub.dev/packages/dartssh2">
<img src="https://img.shields.io/pub/popularity/dartssh2?logo=dart">
<a href="https://pub.dev/packages/dartssh3">
<img src="https://img.shields.io/pub/popularity/dartssh3?logo=dart">
</a>
<a href="https://www.dartdocs.org/documentation/dartssh2/latest/">
<img src="https://img.shields.io/badge/Docs-dartssh2-blue.svg">
<a href="https://pub.dev/documentation/dartssh3/latest/">
<img src="https://img.shields.io/badge/Docs-dartssh3-blue.svg">
</a>
<a href="https://github.com/TerminalStudio/dartssh2/actions/workflows/dart.yml">
<!-- <a href="https://github.com/TerminalStudio/dartssh2/actions/workflows/dart.yml">
<img src="https://github.com/TerminalStudio/dartssh2/actions/workflows/dart.yml/badge.svg">
</a>
<a href="https://ko-fi.com/F1F61K6BL">
<img src="https://img.shields.io/badge/Buy%20Me%20a%20Coffee-F16061?style=flat&logo=buy-me-a-coffee&logoColor=white&labelColor=555555">
</a>
</a> -->
</p>

<p align="center">
SSH and SFTP client written in pure Dart, aiming to be feature-rich as well as easy to use.
</p>

> **dartssh2** is now a complete rewrite of [dartssh].
> **dartssh3** is a fork of [dartssh2](https://pub.dev/packages/dartssh2), because the original author stopped development.

## ✨ Features

Expand Down Expand Up @@ -426,8 +423,10 @@ print('free: ${statvfs.blockSize * statvfs.freeBlocks}');

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

https://github.com/TerminalStudio/dartssh2 by TerminalStudio

## License

dartssh is released under the terms of the MIT license. See [LICENSE](LICENSE).
[dartssh](https://github.com/GreenAppers/dartssh) is released under the terms of the MIT license. See [LICENSE](https://github.com/GreenAppers/dartssh/blob/d209ba2015937f0605d5eb254dc16baebbdab30f/LICENSE).

[dartssh]: https://github.com/GreenAppers/dartssh
[dartssh2](https://github.com/TerminalStudio/dartssh2) is released under the terms of the MIT license. See [LICENSE](https://github.com/TerminalStudio/dartssh2/blob/9e7d3eafb02de28e080be92a5db1761d8251aa66/LICENSE).
3 changes: 3 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- [ ] Fix test cases from old dev TerminalStudio

- [ ] Reimplement GitHub workflows
2 changes: 1 addition & 1 deletion example/example.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'dart:convert';
import 'dart:io';

import 'package:dartssh2/dartssh2.dart';
import 'package:dartssh3/dartssh3.dart';

void main(List<String> args) async {
final socket = await SSHSocket.connect('localhost', 22);
Expand Down
2 changes: 1 addition & 1 deletion example/execute.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'dart:io';
import 'dart:typed_data';

import 'package:dartssh2/dartssh2.dart';
import 'package:dartssh3/dartssh3.dart';

void main(List<String> args) async {
final client = SSHClient(
Expand Down
2 changes: 1 addition & 1 deletion example/forward_local.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'dart:io';

import 'package:dartssh2/dartssh2.dart';
import 'package:dartssh3/dartssh3.dart';

void main(List<String> args) async {
final socket = await SSHSocket.connect('localhost', 22);
Expand Down
2 changes: 1 addition & 1 deletion example/forward_remote.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'dart:io';

import 'package:dartssh2/dartssh2.dart';
import 'package:dartssh3/dartssh3.dart';

void main(List<String> args) async {
final socket = await SSHSocket.connect('localhost', 22);
Expand Down
2 changes: 1 addition & 1 deletion example/pubkey.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'dart:convert';
import 'dart:io';

import 'package:dartssh2/dartssh2.dart';
import 'package:dartssh3/dartssh3.dart';

void main(List<String> args) async {
final socket = await SSHSocket.connect('localhost', 22);
Expand Down
2 changes: 1 addition & 1 deletion example/sftp_filetype.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'dart:io';

import 'package:dartssh2/dartssh2.dart';
import 'package:dartssh3/dartssh3.dart';

void main(List<String> args) async {
final socket = await SSHSocket.connect('localhost', 22);
Expand Down
2 changes: 1 addition & 1 deletion example/sftp_list.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'dart:io';

import 'package:dartssh2/dartssh2.dart';
import 'package:dartssh3/dartssh3.dart';

void main(List<String> args) async {
final socket = await SSHSocket.connect('localhost', 22);
Expand Down
2 changes: 1 addition & 1 deletion example/sftp_read.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'dart:convert';
import 'dart:io';

import 'package:dartssh2/dartssh2.dart';
import 'package:dartssh3/dartssh3.dart';

void main(List<String> args) async {
final socket = await SSHSocket.connect('localhost', 22);
Expand Down
2 changes: 1 addition & 1 deletion example/sftp_stat.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'dart:io';

import 'package:dartssh2/dartssh2.dart';
import 'package:dartssh3/dartssh3.dart';

void main(List<String> args) async {
final socket = await SSHSocket.connect('localhost', 22);
Expand Down
2 changes: 1 addition & 1 deletion example/sftp_upload.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'dart:io';

import 'package:dartssh2/dartssh2.dart';
import 'package:dartssh3/dartssh3.dart';

void main(List<String> args) async {
final client = SSHClient(
Expand Down
2 changes: 1 addition & 1 deletion example/sftp_write.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'dart:convert';
import 'dart:io';

import 'package:dartssh2/dartssh2.dart';
import 'package:dartssh3/dartssh3.dart';

void main(List<String> args) async {
final socket = await SSHSocket.connect('localhost', 22);
Expand Down
2 changes: 1 addition & 1 deletion example/shell.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'dart:io';
import 'dart:typed_data';

import 'package:dartssh2/dartssh2.dart';
import 'package:dartssh3/dartssh3.dart';

void main(List<String> args) async {
final socket = await SSHSocket.connect('localhost', 22);
Expand Down
2 changes: 1 addition & 1 deletion example/ssh_http.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import 'package:dartssh2/dartssh2.dart';
import 'package:dartssh3/dartssh3.dart';

void main(List<String> args) async {
final client = SSHClient(
Expand Down
2 changes: 1 addition & 1 deletion example/ssh_jump.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'dart:convert';

import 'package:dartssh2/dartssh2.dart';
import 'package:dartssh3/dartssh3.dart';

void main() async {
final jumpServer = SSHClient(
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion lib/src/algorithm/ssh_cipher_type.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'dart:typed_data';

import 'package:dartssh2/src/ssh_algorithm.dart';
import 'package:dartssh3/src/ssh_algorithm.dart';
import 'package:pointycastle/export.dart';

class SSHCipherType with SSHAlgorithm {
Expand Down
2 changes: 1 addition & 1 deletion lib/src/algorithm/ssh_hostkey_type.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import 'package:dartssh2/src/ssh_algorithm.dart';
import 'package:dartssh3/src/ssh_algorithm.dart';

class SSHHostkeyType with SSHAlgorithm {
static const rsaSha1 = SSHHostkeyType._('ssh-rsa');
Expand Down
2 changes: 1 addition & 1 deletion lib/src/algorithm/ssh_kex_type.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import 'package:dartssh2/src/ssh_algorithm.dart';
import 'package:dartssh3/src/ssh_algorithm.dart';
import 'package:pointycastle/export.dart';

class SSHKexType with SSHAlgorithm {
Expand Down
2 changes: 1 addition & 1 deletion lib/src/algorithm/ssh_mac_type.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'dart:typed_data';

import 'package:dartssh2/src/ssh_algorithm.dart';
import 'package:dartssh3/src/ssh_algorithm.dart';
import 'package:pointycastle/export.dart';

class SSHMacType with SSHAlgorithm {
Expand Down
4 changes: 2 additions & 2 deletions lib/src/hostkey/hostkey_ecdsa.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import 'dart:typed_data';

import 'package:convert/convert.dart';
import 'package:dartssh2/src/ssh_hostkey.dart';
import 'package:dartssh2/src/ssh_message.dart';
import 'package:dartssh3/src/ssh_hostkey.dart';
import 'package:dartssh3/src/ssh_message.dart';
import 'package:pointycastle/export.dart';

class SSHEcdsaPublicKey implements SSHHostKey {
Expand Down
4 changes: 2 additions & 2 deletions lib/src/hostkey/hostkey_ed25519.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'package:convert/convert.dart';
import 'package:dartssh2/src/ssh_hostkey.dart';
import 'package:dartssh2/src/ssh_message.dart';
import 'package:dartssh3/src/ssh_hostkey.dart';
import 'package:dartssh3/src/ssh_message.dart';
import 'package:pinenacl/ed25519.dart';

class SSHEd25519PublicKey implements SSHHostKey {
Expand Down
4 changes: 2 additions & 2 deletions lib/src/hostkey/hostkey_rsa.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import 'dart:typed_data';

import 'package:convert/convert.dart';
import 'package:dartssh2/src/ssh_hostkey.dart';
import 'package:dartssh2/src/ssh_message.dart';
import 'package:dartssh3/src/ssh_hostkey.dart';
import 'package:dartssh3/src/ssh_message.dart';

import 'package:pinenacl/ed25519.dart';
import 'package:pointycastle/api.dart' hide Signature;
Expand Down
12 changes: 6 additions & 6 deletions lib/src/http/http_client.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import 'dart:convert';
import 'dart:typed_data';

import 'package:dartssh2/src/http/http_exception.dart';
import 'package:dartssh2/src/http/line_decoder.dart';
import 'package:dartssh2/src/http/http_content_type.dart';
import 'package:dartssh2/src/http/http_headers.dart';
import 'package:dartssh2/src/socket/ssh_socket.dart';
import 'package:dartssh2/src/ssh_client.dart';
import 'package:dartssh3/src/http/http_exception.dart';
import 'package:dartssh3/src/http/line_decoder.dart';
import 'package:dartssh3/src/http/http_content_type.dart';
import 'package:dartssh3/src/http/http_headers.dart';
import 'package:dartssh3/src/socket/ssh_socket.dart';
import 'package:dartssh3/src/ssh_client.dart';

/// A HTTP client that works over SSH port forwarding.
///
Expand Down
4 changes: 2 additions & 2 deletions lib/src/http/http_content_type.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'dart:collection';

import 'package:dartssh2/src/http/http_exception.dart';
import 'package:dartssh2/src/http/http_headers.dart';
import 'package:dartssh3/src/http/http_exception.dart';
import 'package:dartssh3/src/http/http_headers.dart';

/// A MIME/IANA media type used as the value of the
/// [SSHHttpHeaders.contentTypeHeader] header.
Expand Down
2 changes: 1 addition & 1 deletion lib/src/http/http_headers.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import 'package:dartssh2/src/http/http_content_type.dart';
import 'package:dartssh3/src/http/http_content_type.dart';

/// Headers for HTTP requests and responses.
///
Expand Down
6 changes: 3 additions & 3 deletions lib/src/kex/kex_dh.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import 'dart:typed_data';

import 'package:dartssh2/src/ssh_kex.dart';
import 'package:dartssh2/src/utils/bigint.dart';
import 'package:dartssh2/src/utils/list.dart';
import 'package:dartssh3/src/ssh_kex.dart';
import 'package:dartssh3/src/utils/bigint.dart';
import 'package:dartssh3/src/utils/list.dart';

/// The Diffie-Hellman (DH) key exchange provides a shared secret that
/// cannot be determined by either party alone.
Expand Down
6 changes: 3 additions & 3 deletions lib/src/kex/kex_nist.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import 'dart:typed_data';

import 'package:dartssh2/src/ssh_kex.dart';
import 'package:dartssh2/src/utils/bigint.dart';
import 'package:dartssh2/src/utils/list.dart';
import 'package:dartssh3/src/ssh_kex.dart';
import 'package:dartssh3/src/utils/bigint.dart';
import 'package:dartssh3/src/utils/list.dart';
import 'package:pointycastle/ecc/curves/secp256r1.dart';
import 'package:pointycastle/ecc/curves/secp384r1.dart';
import 'package:pointycastle/ecc/curves/secp521r1.dart';
Expand Down
6 changes: 3 additions & 3 deletions lib/src/kex/kex_x25519.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import 'dart:typed_data';

import 'package:dartssh2/src/ssh_kex.dart';
import 'package:dartssh2/src/utils/bigint.dart';
import 'package:dartssh2/src/utils/list.dart';
import 'package:dartssh3/src/ssh_kex.dart';
import 'package:dartssh3/src/utils/bigint.dart';
import 'package:dartssh3/src/utils/list.dart';
import 'package:pinenacl/tweetnacl.dart';

class SSHKexX25519 implements SSHKexECDH {
Expand Down
2 changes: 1 addition & 1 deletion lib/src/message/msg_channel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import 'dart:typed_data';

import 'package:dartssh2/src/ssh_message.dart';
import 'package:dartssh3/src/ssh_message.dart';

/// Message to request opening a channel to remote host.
class SSH_Message_Channel_Open implements SSHMessage {
Expand Down
2 changes: 1 addition & 1 deletion lib/src/message/msg_debug.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import 'dart:typed_data';

import 'package:dartssh2/src/ssh_message.dart';
import 'package:dartssh3/src/ssh_message.dart';

class SSH_Message_Debug implements SSHMessage {
static const messageId = 4;
Expand Down
2 changes: 1 addition & 1 deletion lib/src/message/msg_disconnect.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import 'dart:typed_data';

import 'package:dartssh2/src/ssh_message.dart';
import 'package:dartssh3/src/ssh_message.dart';

class SSH_Message_Disconnect extends SSHMessage {
static const messageId = 1;
Expand Down
2 changes: 1 addition & 1 deletion lib/src/message/msg_ignore.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import 'dart:typed_data';

import 'package:dartssh2/src/ssh_message.dart';
import 'package:dartssh3/src/ssh_message.dart';

class SSH_Message_Ignore extends SSHMessage {
static const messageId = 2;
Expand Down
4 changes: 2 additions & 2 deletions lib/src/message/msg_kex.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import 'dart:typed_data';

import 'package:dartssh2/src/ssh_message.dart';
import 'package:dartssh2/src/utils/list.dart';
import 'package:dartssh3/src/ssh_message.dart';
import 'package:dartssh3/src/utils/list.dart';

class SSH_Message_KexInit implements SSHMessage {
static const messageId = 20;
Expand Down
2 changes: 1 addition & 1 deletion lib/src/message/msg_kex_dh.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import 'dart:typed_data';

import 'package:dartssh2/src/ssh_message.dart';
import 'package:dartssh3/src/ssh_message.dart';

class SSH_Message_KexDH_Init implements SSHMessage {
static const messageId = 30;
Expand Down
Loading