refactor: run as root via pkexec, remove sudo handling
- Add privilege escalation at startup (pkexec if not root) - Remove all sudo password handling (echo password | sudo -S) - Remove show_sudo_dialog and current_sudo_password_ - Remove --sudo-password CLI option - All rsync/restore operations run directly as root - format_size: use GB as default unit for large files - Remove [cmd] log leaking sudo password - Simplify snapshot_manager: no sudo_password parameter - Simplify rsync_manager: no sudo_password parameter
This commit is contained in:
+29
-80
@@ -4,16 +4,17 @@
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <sys/stat.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
static std::string format_size(int64_t bytes) {
|
||||
const char* units[] = {"B", "KB", "MB", "GB", "TB"};
|
||||
int u = 0;
|
||||
double size = bytes;
|
||||
while (size >= 1024 && u < 4) { size /= 1024; u++; }
|
||||
char buf[64];
|
||||
snprintf(buf, sizeof(buf), "%.1f %s", size, units[u]);
|
||||
if (bytes < 1024)
|
||||
snprintf(buf, sizeof(buf), "%ld B", (long)bytes);
|
||||
else if (bytes < 1024LL * 1024)
|
||||
snprintf(buf, sizeof(buf), "%.1f KB", (double)bytes / 1024);
|
||||
else if (bytes < 1024LL * 1024 * 1024)
|
||||
snprintf(buf, sizeof(buf), "%.1f MB", (double)bytes / (1024 * 1024));
|
||||
else
|
||||
snprintf(buf, sizeof(buf), "%.2f GB", (double)bytes / (1024LL * 1024 * 1024));
|
||||
return buf;
|
||||
}
|
||||
|
||||
@@ -612,11 +613,9 @@ gboolean MainWindow::on_file_button_press(GtkWidget*, GdkEventButton* event, gpo
|
||||
auto* ctx = new RestoreCtx{self, file_path};
|
||||
g_signal_connect_data(restore_item, "activate", G_CALLBACK(+[](GtkWidget*, gpointer d) {
|
||||
auto* c = static_cast<RestoreCtx*>(d);
|
||||
c->self->show_sudo_dialog([c](const std::string& pw) {
|
||||
std::vector<std::string> files = {c->path};
|
||||
c->self->snapshots_.restore_selected(c->self->current_snapshot_, files, pw);
|
||||
c->self->tray_.show_notification("x3-Backup", "File restored: " + c->path);
|
||||
});
|
||||
std::vector<std::string> files = {c->path};
|
||||
c->self->snapshots_.restore_selected(c->self->current_snapshot_, files);
|
||||
c->self->tray_.show_notification("x3-Backup", "File restored: " + c->path);
|
||||
delete c;
|
||||
}), ctx, nullptr, (GConnectFlags)0);
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(menu), restore_item);
|
||||
@@ -641,11 +640,9 @@ gboolean MainWindow::on_file_button_press(GtkWidget*, GdkEventButton* event, gpo
|
||||
ctx = new RestoreCtx{self, file_path};
|
||||
g_signal_connect_data(restore_item, "activate", G_CALLBACK(+[](GtkWidget*, gpointer d) {
|
||||
auto* c = static_cast<RestoreCtx*>(d);
|
||||
c->self->show_sudo_dialog([c](const std::string& pw) {
|
||||
std::vector<std::string> files = {c->path};
|
||||
c->self->snapshots_.restore_selected(c->self->current_snapshot_, files, pw);
|
||||
c->self->tray_.show_notification("x3-Backup", "Directory restored: " + c->path);
|
||||
});
|
||||
std::vector<std::string> files = {c->path};
|
||||
c->self->snapshots_.restore_selected(c->self->current_snapshot_, files);
|
||||
c->self->tray_.show_notification("x3-Backup", "Directory restored: " + c->path);
|
||||
delete c;
|
||||
}), ctx, nullptr, (GConnectFlags)0);
|
||||
}
|
||||
@@ -658,48 +655,6 @@ gboolean MainWindow::on_file_button_press(GtkWidget*, GdkEventButton* event, gpo
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void MainWindow::show_sudo_dialog(std::function<void(const std::string&)> callback) {
|
||||
GtkWidget* dialog = gtk_dialog_new_with_buttons(
|
||||
"Authentication Required", GTK_WINDOW(window_),
|
||||
(GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
|
||||
"_Cancel", GTK_RESPONSE_CANCEL,
|
||||
"_OK", GTK_RESPONSE_ACCEPT,
|
||||
nullptr);
|
||||
|
||||
GtkWidget* content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
|
||||
GtkWidget* box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8);
|
||||
gtk_widget_set_margin_start(box, 16);
|
||||
gtk_widget_set_margin_end(box, 16);
|
||||
gtk_widget_set_margin_top(box, 16);
|
||||
|
||||
GtkWidget* icon = gtk_image_new_from_icon_name("dialog-password", GTK_ICON_SIZE_DIALOG);
|
||||
gtk_box_pack_start(GTK_BOX(box), icon, FALSE, FALSE, 0);
|
||||
|
||||
GtkWidget* label = gtk_label_new("Root access is required to preserve file permissions.\n"
|
||||
"Backups will be created with sudo to ensure correct ownership and permissions.\n\n"
|
||||
"Enter your sudo password:");
|
||||
gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
|
||||
gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
|
||||
|
||||
GtkWidget* pass_entry = gtk_entry_new();
|
||||
gtk_entry_set_visibility(GTK_ENTRY(pass_entry), FALSE);
|
||||
gtk_entry_set_placeholder_text(GTK_ENTRY(pass_entry), "Password");
|
||||
gtk_box_pack_start(GTK_BOX(box), pass_entry, FALSE, FALSE, 0);
|
||||
|
||||
gtk_container_add(GTK_CONTAINER(content), box);
|
||||
gtk_widget_show_all(dialog);
|
||||
gtk_widget_grab_focus(pass_entry);
|
||||
|
||||
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||
const char* pw = gtk_entry_get_text(GTK_ENTRY(pass_entry));
|
||||
if (pw && *pw) {
|
||||
current_sudo_password_ = std::string(pw);
|
||||
callback(std::string(pw));
|
||||
}
|
||||
}
|
||||
gtk_widget_destroy(dialog);
|
||||
}
|
||||
|
||||
void MainWindow::open_backup_window(const std::string& description) {
|
||||
if (backup_win_) {
|
||||
/* Clear previous output */
|
||||
@@ -879,17 +834,15 @@ void MainWindow::append_backup_line(const std::string& line, const char* tag) {
|
||||
|
||||
void MainWindow::on_backup(GtkWidget*, gpointer d) {
|
||||
auto* self = static_cast<MainWindow*>(d);
|
||||
self->show_sudo_dialog([self](const std::string& pw) {
|
||||
self->tray_.set_status("x3-Backup - Creating backup...", true);
|
||||
self->open_backup_window("Creating Snapshot...");
|
||||
gtk_label_set_text(GTK_LABEL(self->live_log_label_), "Backup running...");
|
||||
self->tray_.set_status("x3-Backup - Creating backup...", true);
|
||||
self->open_backup_window("Creating Snapshot...");
|
||||
gtk_label_set_text(GTK_LABEL(self->live_log_label_), "Backup running...");
|
||||
|
||||
g_thread_new("backup", [](gpointer data) -> gpointer {
|
||||
auto* s = static_cast<MainWindow*>(data);
|
||||
s->snapshots_.create_snapshot("", s->current_sudo_password_);
|
||||
return nullptr;
|
||||
}, self);
|
||||
});
|
||||
g_thread_new("backup", [](gpointer data) -> gpointer {
|
||||
auto* s = static_cast<MainWindow*>(data);
|
||||
s->snapshots_.create_snapshot("");
|
||||
return nullptr;
|
||||
}, self);
|
||||
}
|
||||
|
||||
void MainWindow::start_quick_backup() {
|
||||
@@ -925,13 +878,11 @@ void MainWindow::on_restore(GtkWidget*, gpointer d) {
|
||||
? std::string(name) : self->current_path_ + "/" + name;
|
||||
g_free(name);
|
||||
|
||||
self->show_sudo_dialog([self, file_path](const std::string& pw) {
|
||||
std::vector<std::string> files = {file_path};
|
||||
self->tray_.set_status("x3-Backup - Restoring...", true);
|
||||
self->snapshots_.restore_selected(self->current_snapshot_, files, pw);
|
||||
self->tray_.set_status("x3-Backup - Idle");
|
||||
self->tray_.show_notification("x3-Backup", "Restored: " + file_path);
|
||||
});
|
||||
std::vector<std::string> files = {file_path};
|
||||
self->tray_.set_status("x3-Backup - Restoring...", true);
|
||||
self->snapshots_.restore_selected(self->current_snapshot_, files);
|
||||
self->tray_.set_status("x3-Backup - Idle");
|
||||
self->tray_.show_notification("x3-Backup", "Restored: " + file_path);
|
||||
}
|
||||
|
||||
void MainWindow::on_delete_snapshot(GtkWidget*, gpointer d) {
|
||||
@@ -1053,10 +1004,8 @@ void MainWindow::on_system_restore(GtkWidget*, gpointer d) {
|
||||
return;
|
||||
}
|
||||
|
||||
self->show_sudo_dialog([self](const std::string& pw) {
|
||||
self->snapshots_.restore_full(self->current_snapshot_, pw);
|
||||
self->tray_.show_notification("x3-Backup", "Full system restore completed");
|
||||
});
|
||||
self->snapshots_.restore_full(self->current_snapshot_);
|
||||
self->tray_.show_notification("x3-Backup", "Full system restore completed");
|
||||
}
|
||||
gtk_widget_destroy(dialog);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user