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
This commit is contained in:
PaperCube
2024-02-17 01:46:02 +00:00
parent 52e94e902b
commit 21860daf41
3 changed files with 34 additions and 20 deletions

View File

@@ -9,26 +9,31 @@ import 'package:toolbox/core/extension/uint8list.dart';
import '../../data/res/misc.dart'; import '../../data/res/misc.dart';
typedef _OnStdout = void Function(String data, StreamSink<Uint8List> sink); typedef _OnStdout = void Function(String data, SSHSession session);
typedef _OnStdin = void Function(StreamSink<Uint8List> sink); typedef _OnStdin = void Function(SSHSession session);
typedef PwdRequestFunc = Future<String?> Function(String? user); typedef PwdRequestFunc = Future<String?> Function(String? user);
extension SSHClientX on SSHClient { extension SSHClientX on SSHClient {
Future<int?> exec( Future<SSHSession> exec(
String cmd, { String cmd, {
_OnStdout? onStderr, _OnStdout? onStderr,
_OnStdout? onStdout, _OnStdout? onStdout,
_OnStdin? stdin, _OnStdin? stdin,
bool redirectToBash = false, // not working yet. do not use
}) async { }) 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<void>(); final stdoutDone = Completer<void>();
final stderrDone = Completer<void>(); final stderrDone = Completer<void>();
if (onStdout != null) { if (onStdout != null) {
session.stdout.listen( session.stdout.listen(
(e) => onStdout(e.string, session.stdin), (e) => onStdout(e.string, session),
onDone: stdoutDone.complete, onDone: stdoutDone.complete,
); );
} else { } else {
@@ -37,7 +42,7 @@ extension SSHClientX on SSHClient {
if (onStderr != null) { if (onStderr != null) {
session.stderr.listen( session.stderr.listen(
(e) => onStderr(e.string, session.stdin), (e) => onStderr(e.string, session),
onDone: stderrDone.complete, onDone: stderrDone.complete,
); );
} else { } else {
@@ -45,14 +50,14 @@ extension SSHClientX on SSHClient {
} }
if (stdin != null) { if (stdin != null) {
stdin(session.stdin); stdin(session);
} }
await stdoutDone.future; await stdoutDone.future;
await stderrDone.future; await stderrDone.future;
session.close(); session.close();
return session.exitCode; return session;
} }
Future<int?> execWithPwd( Future<int?> execWithPwd(
@@ -61,32 +66,42 @@ extension SSHClientX on SSHClient {
_OnStdout? onStdout, _OnStdout? onStdout,
_OnStdout? onStderr, _OnStdout? onStderr,
_OnStdin? stdin, _OnStdin? stdin,
bool redirectToBash = false, // not working yet. do not use
}) async { }) async {
var isRequestingPwd = false; var isRequestingPwd = false;
return await exec( final session = await exec(
cmd, cmd,
onStderr: (data, sink) async { redirectToBash: redirectToBash,
onStderr?.call(data, sink); onStderr: (data, session) async {
debugPrint(
" --- execWithPwd stderr (reqPwd = $isRequestingPwd) --- $data");
onStderr?.call(data, session);
if (isRequestingPwd) return; if (isRequestingPwd) return;
isRequestingPwd = true;
if (data.contains('[sudo] password for ')) { if (data.contains('[sudo] password for ')) {
isRequestingPwd = true;
final user = Miscs.pwdRequestWithUserReg.firstMatch(data)?.group(1); final user = Miscs.pwdRequestWithUserReg.firstMatch(data)?.group(1);
if (context == null) return; if (context == null) return;
final pwd = await context.showPwdDialog(user); final pwd = await context.showPwdDialog(user);
if (pwd == null || pwd.isEmpty) { if (pwd == null || pwd.isEmpty) {
// Add ctrl + c to exit. debugPrint("Empty pwd. Exiting");
sink.add('\x03'.uint8List); session.kill(SSHSignal.INT);
} else { } 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, stdin: stdin,
); );
return session.exitCode;
} }
Future<Uint8List> runWithSessionAction( Future<Uint8List> runForOutput(
String command, { String command, {
bool runInPty = false, bool runInPty = false,
bool stdout = true, bool stdout = true,

View File

@@ -272,7 +272,7 @@ class ServerProvider extends ChangeNotifier {
ensure(await client.run(ShellFunc.installerMkdirs).string); ensure(await client.run(ShellFunc.installerMkdirs).string);
ensure(await client.runWithSessionAction(ShellFunc.installerShellWriter, ensure(await client.runForOutput(ShellFunc.installerShellWriter,
action: (session) async { action: (session) async {
session.stdin.add(utf8.encode(ShellFunc.allScript)); session.stdin.add(utf8.encode(ShellFunc.allScript));
}) })

View File

@@ -15,7 +15,6 @@ import 'package:toolbox/data/res/logger.dart';
import 'package:toolbox/data/res/misc.dart'; import 'package:toolbox/data/res/misc.dart';
import 'package:toolbox/data/res/provider.dart'; import 'package:toolbox/data/res/provider.dart';
import 'package:toolbox/data/res/store.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/omit_start_text.dart';
import 'package:toolbox/view/widget/cardx.dart'; import 'package:toolbox/view/widget/cardx.dart';