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

Fixed Repository #106

Merged
merged 22 commits into from
Aug 29, 2024
Merged
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
13 changes: 13 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file

version: 2
updates:
- package-ecosystem: "pub"
directory: "/"
schedule:
interval: "weekly"
time: "09:00"
timezone: Europe/Madrid
20 changes: 11 additions & 9 deletions .github/workflows/dart.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
name: Dart

on:
push:
branches: [master]
pull_request:
branches: [master]
on: push

jobs:
test:
Expand All @@ -13,11 +9,10 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
# sdk: [stable, beta, dev, 2.10.3, 2.12.0-29.10.beta]
sdk: [stable, dev]
sdk: [stable]

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- uses: dart-lang/setup-dart@v1
with:
sdk: ${{ matrix.sdk }}
Expand All @@ -43,4 +38,11 @@ jobs:
run: dart pub global run coverage:test_with_coverage

- name: Upload coverage
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v4
with:
fail_ci_if_error: true # optional (default = false)
files: ./coverage1.xml,./coverage2.xml # optional
flags: unittests # optional
name: codecov-umbrella # optional
token: ${{ secrets.CODECOV_TOKEN }} # required
verbose: true # optional (default = false)
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## [2.10.0] - 2024-08-29
- Improved Readme.
- Bug fix in SftpFileWriter for [#50], [#71], [#100].
- Added DartShell product [#101].
- Fixed dynamic return on SftpFileOpenMode in | operator [#80].
- DCM updated.
- Fixed warnings related with new DCM version.
- Dependencies updated.
- Fixed Flutter 3.24 issue.

## [2.9.1-pre] - 2023-04-02
- Make the type of `SSHForwardChannel.sink` to `StreamSink<List<int>>` to match
its super class.
Expand Down Expand Up @@ -146,6 +156,11 @@

- Initial release.

[#101]: https://github.com/TerminalStudio/dartssh2/pull/101
[#100]: https://github.com/TerminalStudio/dartssh2/issues/100
[#80]: https://github.com/TerminalStudio/dartssh2/issues/80
[#71]: https://github.com/TerminalStudio/dartssh2/issues/71
[#50]: https://github.com/TerminalStudio/dartssh2/issues/50
[#24]: https://github.com/TerminalStudio/dartssh2/issues/24
[#21]: https://github.com/TerminalStudio/dartssh2/issues/21
[#18]: https://github.com/TerminalStudio/dartssh2/issues/18
Expand Down
91 changes: 50 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
<!-- Title-->
<p align="center">
<h1 align="center">DartSSH 2</h1>
</p>
<h1 style="text-align: center;">DartSSH 2</h1>

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

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

Expand All @@ -41,29 +40,39 @@ SSH and SFTP client written in pure Dart, aiming to be feature-rich as well as e
<table>
<tr>
<!-- ServerBox -->
<td align="center">
<td style="text-align: center;">
<b><a href="https://github.com/LollipopKit/flutter_server_box">ServerBox</a></b>
</td>
<!-- Ssh! No Ports -->
<td align="center">
<td style="text-align: center;">
<b><a href="https://github.com/atsign-foundation/sshnoports">Ssh! No Ports</a></b>
</td>
<!-- dartShell -->
<td style="text-align: center;">
<b><a href="https://github.com/hsduren/dartshell">DartShell</a></b>
</td>
</tr>

<tr>
<!-- ServerBox -->
<td>
<img src="https://raw.githubusercontent.com/TerminalStudio/dartssh2/master/media/showcase-1-serverbox.1.jpg" width="150px">
<img src="https://raw.githubusercontent.com/TerminalStudio/dartssh2/master/media/showcase-1-serverbox.2.png" width="150px">
<img src="https://raw.githubusercontent.com/TerminalStudio/dartssh2/master/media/showcase-1-serverbox.1.jpg" width="150px" alt="ServerBox interface displaying connection management options">
<img src="https://raw.githubusercontent.com/TerminalStudio/dartssh2/master/media/showcase-1-serverbox.2.png" width="150px" alt="ServerBox user interface for server control and monitoring">
</td>
<!-- Ssh! No Ports -->
<td>
<a href="https://asciinema.org/a/496148">
<img src="https://user-images.githubusercontent.com/6131216/185263634-07e8dba7-b5a8-44fc-ac44-8703e247143f.png" width="300px">
<img src="https://user-images.githubusercontent.com/6131216/185263634-07e8dba7-b5a8-44fc-ac44-8703e247143f.png" width="300px" alt="Ssh! No Ports demo showcasing SSH connectivity without open ports">
</a>
</td>
<!-- dartShell -->
<td>
<img src="https://github.com/hsduren/dartshell/blob/main/info1.png" width="300px" alt="dartShell displaying terminal and session information for SSH operations">
</td>
</tr>
</table>


> Feel free to add your own app here by opening a pull request.


Expand Down Expand Up @@ -388,46 +397,46 @@ print('free: ${statvfs.blockSize * statvfs.freeBlocks}');
**Private key**:

| **Type** | **Decode** | **Decrypt** | **Encode** | **Encrypt** |
| ------------------- | ---------- | ----------- | ---------- | ----------- |
| **RSA** | ✔️ | ✔️ | ✔️ | WIP |
| **OpenSSH RSA** | ✔️ | ✔️ | ✔️ | WIP |
| **OpenSSH ECDSA** | ✔️ | ✔️ | ✔️ | WIP |
| **OpenSSH Ed25519** | ✔️ | ✔️ | ✔️ | WIP |
|---------------------|------------|-------------|------------|-------------|
| **RSA** | ✔️ | ✔️ | ✔️ | WIP |
| **OpenSSH RSA** | ✔️ | ✔️ | ✔️ | WIP |
| **OpenSSH ECDSA** | ✔️ | ✔️ | ✔️ | WIP |
| **OpenSSH Ed25519** | ✔️ | ✔️ | ✔️ | WIP |



## ⏳ Roadmap

- [x] Fix broken tests
- [x] Sound null safety
- [x] Fix broken tests.
- [x] Sound null safety.
- [x] Redesign API to allow starting multiple sessions.
- [x] Full SFTP
- [ ] Server
- [x] Full SFTP.
- [ ] Server.

## References

- [`RFC 4250`](https://datatracker.ietf.org/doc/html/rfc4250) The Secure Shell (SSH) Protocol Assigned Numbers
- [`RFC 4251`](https://datatracker.ietf.org/doc/html/rfc4251) The Secure Shell (SSH) Protocol Architecture
- [`RFC 4252`](https://datatracker.ietf.org/doc/html/rfc4252) The Secure Shell (SSH) Authentication Protocol
- [`RFC 4253`](https://datatracker.ietf.org/doc/html/rfc4253) The Secure Shell (SSH) Transport Layer Protocol
- [`RFC 4254`](https://datatracker.ietf.org/doc/html/rfc4254) The Secure Shell (SSH) Connection Protocol
- [`RFC 4255`](https://datatracker.ietf.org/doc/html/rfc4255) Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints
- [`RFC 4256`](https://datatracker.ietf.org/doc/html/rfc4256) Generic Message Exchange Authentication for the Secure Shell Protocol (SSH)
- [`RFC 4419`](https://datatracker.ietf.org/doc/html/rfc4419) Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer Protocol
- [`RFC 4716`](https://datatracker.ietf.org/doc/html/rfc4716) The Secure Shell (SSH) Public Key File Format
- [`RFC 5656`](https://datatracker.ietf.org/doc/html/rfc5656) Elliptic Curve Algorithm Integration in the Secure Shell Transport Layer
- [`RFC 8332`](https://datatracker.ietf.org/doc/html/rfc8332) Use of RSA Keys with SHA-256 and SHA-512 in the Secure Shell (SSH) Protocol
- [`RFC 8731`](https://datatracker.ietf.org/doc/html/rfc8731) Secure Shell (SSH) Key Exchange Method Using Curve25519 and Curve448
- [`draft-miller-ssh-agent-03`](https://datatracker.ietf.org/doc/html/draft-miller-ssh-agent-03) SSH Agent Protocol
- [`draft-ietf-secsh-filexfer-02`](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02) SSH File Transfer Protocol
- [`draft-dbider-sha2-mac-for-ssh-06`](https://datatracker.ietf.org/doc/html/draft-dbider-sha2-mac-for-ssh-06) SHA-2 Data Integrity Verification for the Secure Shell (SSH) Transport Layer Protocol
- [`RFC 4250`](https://datatracker.ietf.org/doc/html/rfc4250) The Secure Shell (SSH) Protocol Assigned Numbers.
- [`RFC 4251`](https://datatracker.ietf.org/doc/html/rfc4251) The Secure Shell (SSH) Protocol Architecture.
- [`RFC 4252`](https://datatracker.ietf.org/doc/html/rfc4252) The Secure Shell (SSH) Authentication Protocol.
- [`RFC 4253`](https://datatracker.ietf.org/doc/html/rfc4253) The Secure Shell (SSH) Transport Layer Protocol.
- [`RFC 4254`](https://datatracker.ietf.org/doc/html/rfc4254) The Secure Shell (SSH) Connection Protocol.
- [`RFC 4255`](https://datatracker.ietf.org/doc/html/rfc4255) Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints.
- [`RFC 4256`](https://datatracker.ietf.org/doc/html/rfc4256) Generic Message Exchange Authentication for the Secure Shell Protocol (SSH).
- [`RFC 4419`](https://datatracker.ietf.org/doc/html/rfc4419) Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer Protocol.
- [`RFC 4716`](https://datatracker.ietf.org/doc/html/rfc4716) The Secure Shell (SSH) Public Key File Format.
- [`RFC 5656`](https://datatracker.ietf.org/doc/html/rfc5656) Elliptic Curve Algorithm Integration in the Secure Shell Transport Layer.
- [`RFC 8332`](https://datatracker.ietf.org/doc/html/rfc8332) Use of RSA Keys with SHA-256 and SHA-512 in the Secure Shell (SSH) Protocol.
- [`RFC 8731`](https://datatracker.ietf.org/doc/html/rfc8731) Secure Shell (SSH) Key Exchange Method Using Curve25519 and Curve448.
- [`draft-miller-ssh-agent-03`](https://datatracker.ietf.org/doc/html/draft-miller-ssh-agent-03) SSH Agent Protocol.
- [`draft-ietf-secsh-filexfer-02`](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02) SSH File Transfer Protocol.
- [`draft-dbider-sha2-mac-for-ssh-06`](https://datatracker.ietf.org/doc/html/draft-dbider-sha2-mac-for-ssh-06) SHA-2 Data Integrity Verification for the Secure Shell (SSH) Transport Layer Protocol.

## Credits

https://github.com/GreenAppers/dartssh by GreenAppers
- [https://github.com/GreenAppers/dartssh](https://github.com/GreenAppers/dartssh) by GreenAppers.

## License

dartssh is released under the terms of the MIT license. See [LICENSE](LICENSE).

[dartssh]: https://github.com/GreenAppers/dartssh
[dartssh]: https://github.com/GreenAppers/dartssh
20 changes: 1 addition & 19 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,4 @@ linter:

analyzer:
plugins:
- dart_code_metrics

dart_code_metrics:
anti-patterns:
# - long-method
# - long-parameter-list
metrics:
cyclomatic-complexity: 20
maximum-nesting-level: 5
number-of-parameters: 4
source-lines-of-code: 50
metrics-exclude:
- test/**
rules:
# - no-boolean-literal-compare
# - no-empty-block
- prefer-trailing-comma
- prefer-conditional-expressions
- no-equal-then-else
- dart_code_metrics_presets
27 changes: 26 additions & 1 deletion lib/src/sftp/sftp_file_open_mode.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,34 @@ class SftpFileOpenMode {
/// [create] MUST also be specified if this flag is used.
static const exclusive = SftpFileOpenMode._(1 << 5);

/// Internal integer flag representing the file open mode.
final int flag;

/// Private constructor used to create instances of [SftpFileOpenMode] with specific flags.
///
/// This constructor is marked as private (`._`) to restrict direct instantiation and ensure
/// that only predefined modes like [read], [write], etc., can be used.
const SftpFileOpenMode._(this.flag);

operator |(SftpFileOpenMode other) => SftpFileOpenMode._(flag | other.flag);
/// Overloads the bitwise OR operator `|` for the `SftpFileOpenMode` class.
///
/// This operator allows combining two `SftpFileOpenMode` instances by performing
/// a bitwise OR operation on their respective flags. The result is a new
/// `SftpFileOpenMode` instance that represents the combined flags of both modes.
///
/// Example:
/// ```dart
/// SftpFileOpenMode readMode = SftpFileOpenMode.read;
/// SftpFileOpenMode writeMode = SftpFileOpenMode.write;
///
/// SftpFileOpenMode combinedMode = readMode | writeMode;
/// ```
///
/// In the example above, the `combinedMode` will contain the flags of both
/// `readMode` and `writeMode`.
///
/// - Parameter [other]: Another instance of `SftpFileOpenMode` to combine with.
/// - Returns: A new `SftpFileOpenMode` instance containing the combined flags.
SftpFileOpenMode operator |(SftpFileOpenMode other) =>
SftpFileOpenMode._(flag | other.flag);
}
23 changes: 21 additions & 2 deletions lib/src/sftp/sftp_stream_io.dart
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,14 @@ class SftpFileWriter with DoneFuture {
_subscription.resume();
}

/// Handles the incoming data chunks from the stream.
///
/// This function manages the flow control by pausing the stream if the
/// amount of unacknowledged data (`_bytesOnTheWire`) exceeds the
/// `maxBytesOnTheWire` limit. It then writes the data chunk to the remote file
/// at the appropriate offset, updates the counters, and triggers the
/// progress callback. Finally, it checks if all data has been acknowledged
/// and completes the operation if done.
Future<void> _handleLocalData(Uint8List chunk) async {
if (_bytesOnTheWire >= maxBytesOnTheWire) {
_subscription.pause();
Expand All @@ -108,19 +116,30 @@ class SftpFileWriter with DoneFuture {
_subscription.resume();
}

if (_streamDone && _bytesSent == _bytesAcked) {
if (_streamDone &&
_bytesSent == _bytesAcked &&
!_doneCompleter.isCompleted) {
_doneCompleter.complete();
}
}

/// Handles the completion of the data stream.
///
/// This function is triggered when the stream has finished emitting all its
/// data. It checks if all data has been successfully acknowledged and
/// marks the operation as complete by calling `_doneCompleter.complete()`
/// if no more data remains to be processed.
void _handleLocalDone() {
_streamDone = true;
if (_bytesSent == _bytesAcked) {
_doneCompleter.complete();
}
}
}

/// Implements [Future] interface for [SftpFileWriter].
///
/// This is for compatibility with earlier versions of dartssh2.
/// This is for compatibility with earlier versions of dartssh2 and dartssh2.
mixin DoneFuture implements Future {
Future<void> get done;

Expand Down
2 changes: 1 addition & 1 deletion lib/src/ssh_channel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ class SSHChannelDataSplitter
}

class SSHChannelDataConsumer extends StreamConsumerBase<SSHChannelData> {
SSHChannelDataConsumer(Stream<SSHChannelData> stream) : super(stream);
SSHChannelDataConsumer(super.stream);

@override
int getLength(SSHChannelData chunk) {
Expand Down
2 changes: 1 addition & 1 deletion lib/src/ssh_errors.dart
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class SSHKeyDecodeError with SSHMessageError implements SSHError {

/// Errors that happen when the library fails to decrypt the host key.
class SSHKeyDecryptError extends SSHKeyDecodeError {
SSHKeyDecryptError(String message, [Object? error]) : super(message, error);
SSHKeyDecryptError(super.message, [super.error]);
}

/// Errors that happen when the library fails to open a channel.
Expand Down
18 changes: 9 additions & 9 deletions lib/src/ssh_key_pair.dart
Original file line number Diff line number Diff line change
Expand Up @@ -663,15 +663,15 @@ class RsaPrivateKey implements SSHKeyPair {
final coefficient = (sequence.elements[8] as ASN1Integer).valueAsBigInteger;

return RsaPrivateKey(
version!,
n!,
e!,
d!,
p!,
q!,
exponent1!,
exponent2!,
coefficient!,
version,
n,
e,
d,
p,
q,
exponent1,
exponent2,
coefficient,
);
}

Expand Down
2 changes: 2 additions & 0 deletions lib/src/ssh_transport.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import 'package:dartssh2/src/message/msg_kex_ecdh.dart';
import 'package:dartssh2/src/ssh_message.dart';
import 'package:pointycastle/export.dart';

import '../dartssh2.dart';

typedef SSHPrintHandler = void Function(String?);

/// Function called when host key is received.
Expand Down
Loading