From 21860daf419a1f0edefce4dc0fac26f362a6ab5a Mon Sep 17 00:00:00 2001 From: PaperCube Date: Sat, 17 Feb 2024 01:46:02 +0000 Subject: [PATCH] Fix sudo pswd dialog neither re-appearing nor closing session - Fixed that when empty password was provided the dialog should have stopped the session - Fixed that when wrong password was provided the dialog should have appeared again but it didn't --- lib/core/extension/ssh_client.dart | 51 +++++++++++++++++++----------- lib/data/provider/server.dart | 2 +- lib/view/page/storage/sftp.dart | 1 - 3 files changed, 34 insertions(+), 20 deletions(-) diff --git a/lib/core/extension/ssh_client.dart b/lib/core/extension/ssh_client.dart index d963096d..42d66c33 100644 --- a/lib/core/extension/ssh_client.dart +++ b/lib/core/extension/ssh_client.dart @@ -9,26 +9,31 @@ import 'package:toolbox/core/extension/uint8list.dart'; import '../../data/res/misc.dart'; -typedef _OnStdout = void Function(String data, StreamSink sink); -typedef _OnStdin = void Function(StreamSink sink); +typedef _OnStdout = void Function(String data, SSHSession session); +typedef _OnStdin = void Function(SSHSession session); typedef PwdRequestFunc = Future Function(String? user); extension SSHClientX on SSHClient { - Future exec( + Future exec( String cmd, { _OnStdout? onStderr, _OnStdout? onStdout, _OnStdin? stdin, + bool redirectToBash = false, // not working yet. do not use }) async { - final session = await execute(cmd); + final session = await execute(redirectToBash ? "head -1 | bash" : cmd); + + if (redirectToBash) { + session.stdin.add("$cmd\n".uint8List); + } final stdoutDone = Completer(); final stderrDone = Completer(); if (onStdout != null) { session.stdout.listen( - (e) => onStdout(e.string, session.stdin), + (e) => onStdout(e.string, session), onDone: stdoutDone.complete, ); } else { @@ -37,7 +42,7 @@ extension SSHClientX on SSHClient { if (onStderr != null) { session.stderr.listen( - (e) => onStderr(e.string, session.stdin), + (e) => onStderr(e.string, session), onDone: stderrDone.complete, ); } else { @@ -45,14 +50,14 @@ extension SSHClientX on SSHClient { } if (stdin != null) { - stdin(session.stdin); + stdin(session); } await stdoutDone.future; await stderrDone.future; session.close(); - return session.exitCode; + return session; } Future execWithPwd( @@ -61,38 +66,48 @@ extension SSHClientX on SSHClient { _OnStdout? onStdout, _OnStdout? onStderr, _OnStdin? stdin, + bool redirectToBash = false, // not working yet. do not use }) async { var isRequestingPwd = false; - return await exec( + final session = await exec( cmd, - onStderr: (data, sink) async { - onStderr?.call(data, sink); + redirectToBash: redirectToBash, + onStderr: (data, session) async { + debugPrint( + " --- execWithPwd stderr (reqPwd = $isRequestingPwd) --- $data"); + onStderr?.call(data, session); if (isRequestingPwd) return; - isRequestingPwd = true; + if (data.contains('[sudo] password for ')) { + isRequestingPwd = true; final user = Miscs.pwdRequestWithUserReg.firstMatch(data)?.group(1); if (context == null) return; final pwd = await context.showPwdDialog(user); if (pwd == null || pwd.isEmpty) { - // Add ctrl + c to exit. - sink.add('\x03'.uint8List); + debugPrint("Empty pwd. Exiting"); + session.kill(SSHSignal.INT); } else { - sink.add('$pwd\n'.uint8List); + session.stdin.add('$pwd\n'.uint8List); } + isRequestingPwd = false; } }, - onStdout: onStdout, + onStdout: (data, sink) async { + onStdout?.call(data, sink); + debugPrint(" --- execWithPwd stdout --- $data"); + }, stdin: stdin, ); + return session.exitCode; } - Future runWithSessionAction( + Future runForOutput( String command, { bool runInPty = false, bool stdout = true, bool stderr = true, Map? environment, - Future Function(SSHSession)? action, + Future Function(SSHSession)? action, }) async { final session = await execute( command, diff --git a/lib/data/provider/server.dart b/lib/data/provider/server.dart index ff5c55f4..e3ca23dd 100644 --- a/lib/data/provider/server.dart +++ b/lib/data/provider/server.dart @@ -272,7 +272,7 @@ class ServerProvider extends ChangeNotifier { ensure(await client.run(ShellFunc.installerMkdirs).string); - ensure(await client.runWithSessionAction(ShellFunc.installerShellWriter, + ensure(await client.runForOutput(ShellFunc.installerShellWriter, action: (session) async { session.stdin.add(utf8.encode(ShellFunc.allScript)); }) diff --git a/lib/view/page/storage/sftp.dart b/lib/view/page/storage/sftp.dart index 4f973812..94da5db4 100644 --- a/lib/view/page/storage/sftp.dart +++ b/lib/view/page/storage/sftp.dart @@ -15,7 +15,6 @@ import 'package:toolbox/data/res/logger.dart'; import 'package:toolbox/data/res/misc.dart'; import 'package:toolbox/data/res/provider.dart'; import 'package:toolbox/data/res/store.dart'; -import 'package:toolbox/data/store/setting.dart'; import 'package:toolbox/view/widget/omit_start_text.dart'; import 'package:toolbox/view/widget/cardx.dart';