diff --git a/lib/pages/remotes/add_remote.dart b/lib/pages/remotes/add_remote.dart index 483dbc0..bbe9d6b 100644 --- a/lib/pages/remotes/add_remote.dart +++ b/lib/pages/remotes/add_remote.dart @@ -27,10 +27,12 @@ class _AddRemotePageState extends State { final _portController = TextEditingController(); final _usernameController = TextEditingController(); final _passwordController = TextEditingController(); + final _privateKeyController = TextEditingController(); final _socketPathController = TextEditingController(); late final String _id; bool _keepPassword = false; + bool _keepPrivateKey = false; static const _defaultPort = "22"; static const _defaultSocketPath = "/tmp/mpvsocket"; @@ -51,12 +53,17 @@ class _AddRemotePageState extends State { _portController.dispose(); _usernameController.dispose(); _passwordController.dispose(); + _privateKeyController.dispose(); _socketPathController.dispose(); if (!_keepPassword) { _deletePassword(); } + if (!_keepPrivateKey) { + _deletePrivateKey(); + } + super.dispose(); } @@ -124,6 +131,11 @@ class _AddRemotePageState extends State { ), ), _Field(_passwordController, "Password", password: true), + _Field( + _privateKeyController, + "Private Key", + privateKey: true, + ), _Field( _socketPathController, "Socket path", @@ -191,10 +203,19 @@ class _AddRemotePageState extends State { SecureStorage.savePassword(_id, password); } + Future _savePrivateKey() async { + final privateKey = _privateKeyController.text; + SecureStorage.savePrivateKey(_id, privateKey); + } + Future _deletePassword() async { SecureStorage.deletePassword(_id); } + Future _deletePrivateKey() async { + SecureStorage.deletePrivateKey(_id); + } + Future _testConnection() async { final conn = _readForm(); if (conn == null) { @@ -208,6 +229,7 @@ class _AddRemotePageState extends State { }); await _savePassword(); + await _savePrivateKey(); final sc = StreamController(); sc.stream.listen((line) { @@ -268,8 +290,10 @@ class _AddRemotePageState extends State { Preferences.remoteConnections.setValue(remotes); await _savePassword(); + await _savePrivateKey(); _keepPassword = true; + _keepPrivateKey = true; Navigator.pop(context); } } @@ -284,6 +308,7 @@ class _Field extends StatefulWidget { this.urlKeyboard = false, this.portNumber = false, this.password = false, + this.privateKey = false, Key? key, }) : super(key: key); @@ -294,6 +319,7 @@ class _Field extends StatefulWidget { final bool urlKeyboard; final bool portNumber; final bool password; + final bool privateKey; @override State<_Field> createState() => _FieldState(); @@ -305,6 +331,7 @@ class _FieldState extends State<_Field> { @override Widget build(BuildContext context) { final field = TextFormField( + maxLines: widget.privateKey ? null : 1, controller: widget.controller, textInputAction: TextInputAction.next, obscureText: widget.password && !showPassword, @@ -314,7 +341,9 @@ class _FieldState extends State<_Field> { ? TextInputType.url : (widget.password && showPassword) ? TextInputType.visiblePassword - : TextInputType.text, + : widget.privateKey + ? TextInputType.multiline + : TextInputType.text, decoration: InputDecoration( alignLabelWithHint: true, floatingLabelBehavior: (widget.defaultValue != null) diff --git a/lib/remote_connection.dart b/lib/remote_connection.dart index 134619c..b37c0a8 100644 --- a/lib/remote_connection.dart +++ b/lib/remote_connection.dart @@ -58,10 +58,12 @@ class RemoteConnection { Future testConnection(Sink printOut) async { final socket = await SSHSocket.connect(host, port); + final privateKey = await SecureStorage.getPrivateKeyById(id); final client = SSHClient( socket, username: username, onPasswordRequest: _getPassword, + identities: privateKey == null ? null : SSHKeyPair.fromPem(privateKey), printDebug: (s) => printOut.add(s ?? ""), ); @@ -93,10 +95,12 @@ class RemoteConnection { Future connect() async { final socket = await SSHSocket.connect(host, port); + final privateKey = await SecureStorage.getPrivateKeyById(id); final client = SSHClient( socket, username: username, onPasswordRequest: _getPassword, + identities: privateKey == null ? null : SSHKeyPair.fromPem(privateKey), ); await client.authenticated; diff --git a/lib/secure_storage.dart b/lib/secure_storage.dart index 66086bd..773ad24 100644 --- a/lib/secure_storage.dart +++ b/lib/secure_storage.dart @@ -14,4 +14,16 @@ class SecureStorage { static Future deletePassword(String id) async { await _storage.delete(key: "password_$id"); } + + static Future getPrivateKeyById(String id) async { + return _storage.read(key: "privateKey_$id"); + } + + static Future savePrivateKey(String id, String privateKey) async { + await _storage.write(key: "privateKey_$id", value: privateKey); + } + + static Future deletePrivateKey(String id) async { + await _storage.delete(key: "privateKey_$id"); + } }