dartssh2 2.4.0 copy "dartssh2: ^2.4.0" to clipboard
dartssh2: ^2.4.0 copied to clipboard

outdated

SSH and SFTP client written in pure Dart, aiming to be feature-rich as well as easy to use.

DartSSH 2

SSH and SFTP client written in pure Dart, aiming to be feature-rich as well as easy to use.

dartssh2 is now a complete rewrite of dartssh.

โœจ Features #

  • Pure Dart: Working with both Dart VM and Flutter.
  • SSH Session: Executing commands, spawning shells, setting environment variables, pseudo terminals, etc.
  • Authentication: Supports password, private key and interactive authentication method.
  • Forwarding: Supports local forwarding and remote forwarding.
  • SFTP: Supports all operations defined in SFTPv3 protocol including upload, download, list, link, remove, rename, etc.

๐Ÿงช Try #

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

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

# Example: execute a command on remote host.
dartssh [email protected] ls -al

# Example: connect to a non-standard port.
dartssh [email protected]:<port>

# Transfer files via SFTP.
dartsftp [email protected]

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

๐Ÿš€ Quick start #

Connect to a remote host #

final client = SSHClient(
  await SSHSocket.connect('localhost', 22),
  username: '<username>',
  onPasswordRequest: () => '<password>',
);

SSHSocket is an interface and it's possible to implement your own SSHSocket if you want to use a different underlying transport rather than standard TCP socket. For example WebSocket or Unix domain socket.

Spawn a shell on remote host #

final shell = await client.shell();
stdout.addStream(shell.stdout); // listening for stdout
stderr.addStream(shell.stderr); // listening for stderr
stdin.cast<Uint8List>().listen(shell.write); // writing to stdin

await shell.done; // wait for shell to exit
client.close();

Execute a command on remote host #

final uptime = await client.run('uptime');
print(utf8.decode(uptime));

client.run() is a convenience method that wraps client.execute() for running non-interactive commands.

Start a process on remote host #

final session = await client.execute('cat > file.txt');
await session.stdin.addStream(File('local_file.txt').openRead().cast());
await session.stdin.close(); // Close the stream to send EOF to the remote process.

await session.done;
print(session.exitCode);

session.write() is a shorthand for session.stdin.add(). It's recommended to use session.stdin.addStream() instead of session.write() when you want to stream large amount of data to the remote process.

Forward connections on local port 8080 to the server #

final serverSocket = await ServerSocket.bind('localhost', 8080);
await for (final socket in serverSocket) {
  final forward = await client.forwardLocal('httpbin.org', 80);
  forward.stream.cast<List<int>>().pipe(socket);
  socket.pipe(forward.sink);
}

Forward connections to port 2222 on the server to local port 22 #

final forward = await client.forwardRemote(port: 2222);

if (forward == null) {
  print('Failed to forward remote port');
  return;
}

await for (final connection in forward.connections) {
  final socket = await Socket.connect('localhost', 22);
  connection.stream.cast<List<int>>().pipe(socket);
  socket.pipe(connection.sink);
}

Authenticate with public keys #

final client = SSHClient(
  socket,
  username: '<username>',
  identities: [
    // A single private key file may contain multiple keys.
    ...SSHKeyPair.fromPem(await File('path/to/id_rsa').readAsString())
  ],
);

Use encrypted PEM files #

// Test whether the private key is encrypted.
final encrypted = SSHKeyPair.isEncrypted(await File('path/to/id_rsa').readAsString());
print(encrypted);

// If the private key is encrypted, you need to provide the passphrase.
final keys = SSHKeyPair.fromPem('<pem text>', '<passphrase>');
print(keys);

Decrypt PEM file with compute in Flutter

List<SSHKeyPair> decryptKeyPairs(List<String> args) {
  return SSHKeyPair.fromPem(args[0], args[1]);
}

final keypairs = await compute(decryptKeyPairs, ['<pem text>', '<passphrase>']);

Get the version of SSH server #

await client.authenticated;
print(client.remoteVersion); // SSH-2.0-OpenSSH_7.4p1

SFTP #

List remote directory #

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

Read remote file #

final sftp = await client.sftp();
final file = await sftp.open('/etc/passwd');
final content = await file.readBytes();
print(latin1.decode(content));

Directory operations #

final sftp = await client.sftp();
await sftp.mkdir('/path/to/dir');
await sftp.rmdir('/path/to/dir');

Get/Set attributes from/to remote file/directory #

await sftp.stat('/path/to/file');
await sftp.setStat(
  '/path/to/file',
  SftpFileAttrs(mode: SftpFileMode(userRead: true)),
);
final sftp = await client.sftp();
sftp.link('/from', '/to');

๐Ÿชœ Example #

SSH client: #

SFTP: #

๐Ÿ” Supported algorithms #

Host key:

  • ssh-rsa
  • rsa-sha2-[256|512]
  • ecdsa-sha2-nistp[256|384|521]
  • ssh-ed25519

Key exchange:

  • curve25519-sha256
  • ecdh-sha2-nistp[256|384|521]
  • diffie-hellman-group-exchange-sha[1|256]
  • diffie-hellman-group14-sha[1|256]
  • diffie-hellman-group1-sha1

Cipher:

  • aes[128|192|256]-ctr
  • aes[128|192|256]-cbc

Integrity:

  • hmac-md5
  • hmac-sha1
  • hmac-sha2-[256|512]

โณ Roadmap #

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

References #

  • RFC 4250 The Secure Shell (SSH) Protocol Assigned Numbers
  • 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)
  • RFC 4419 Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer Protocol
  • RFC 4716 The Secure Shell (SSH) Public Key File Format
  • RFC 5656 Elliptic Curve Algorithm Integration in the Secure Shell Transport Layer
  • RFC 8332 Use of RSA Keys with SHA-256 and SHA-512 in the Secure Shell (SSH) Protocol
  • RFC 8731 Secure Shell (SSH) Key Exchange Method Using Curve25519 and Curve448
  • draft-miller-ssh-agent-03 SSH Agent Protocol
  • draft-ietf-secsh-filexfer-02 SSH File Transfer Protocol
  • 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

License #

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

108
likes
0
pub points
93%
popularity

Publisher

verified publisherterminal.studio

SSH and SFTP client written in pure Dart, aiming to be feature-rich as well as easy to use.

Repository (GitHub)
View/report issues

License

unknown (LICENSE)

Dependencies

args, asn1lib, convert, dart_console, http, meta, pinenacl, pointycastle, validators

More

Packages that depend on dartssh2