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';
typedef _OnStdout = void Function(String data, StreamSink<Uint8List> sink);
typedef _OnStdin = void Function(StreamSink<Uint8List> sink);
typedef _OnStdout = void Function(String data, SSHSession session);
typedef _OnStdin = void Function(SSHSession session);
typedef PwdRequestFunc = Future<String?> Function(String? user);
extension SSHClientX on SSHClient {
Future<int?> exec(
Future<SSHSession> 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<void>();
final stderrDone = Completer<void>();
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<int?> execWithPwd(
@@ -61,32 +66,42 @@ 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<Uint8List> runWithSessionAction(
Future<Uint8List> runForOutput(
String command, {
bool runInPty = false,
bool stdout = true,

View File

@@ -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));
})

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/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';