Bläddra i källkod

backups/restore: implement selecting the backup even in VM

Using new qubes.SelectFile RPC service, qubes manager can show the file
select dialog from within VM.
The user still can enter the path (or command) manually.
Marek Marczykowski-Górecki 10 år sedan
förälder
incheckning
7757e343e1
1 ändrade filer med 21 tillägg och 1 borttagningar
  1. 21 1
      qubesmanager/backup_utils.py

+ 21 - 1
qubesmanager/backup_utils.py

@@ -19,7 +19,7 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 #
 #
 #
 #
-
+import re
 import sys
 import sys
 import os
 import os
 from PyQt4.QtCore import *
 from PyQt4.QtCore import *
@@ -34,6 +34,8 @@ from thread_monitor import *
 from datetime import datetime
 from datetime import datetime
 from string import replace
 from string import replace
 
 
+path_re = re.compile(r"[a-zA-Z0-9/:.,_+=() -]*")
+path_max_len = 512
 mount_for_backup_path = '/usr/libexec/qubes-manager/mount_for_backup.sh'
 mount_for_backup_path = '/usr/libexec/qubes-manager/mount_for_backup.sh'
 
 
 def check_if_mounted(dev_path):
 def check_if_mounted(dev_path):
@@ -198,6 +200,20 @@ def dev_combobox_activated(dialog, idx):
             dialog.dir_line_edit.setText(dialog.dev_mount_path)
             dialog.dir_line_edit.setText(dialog.dev_mount_path)
             dialog.select_dir_page.emit(SIGNAL("completeChanged()"))
             dialog.select_dir_page.emit(SIGNAL("completeChanged()"))
 
 
+
+def get_path_for_vm(vm, service_name):
+    if not vm:
+        return None
+    proc = vm.run("QUBESRPC %s dom0" % service_name, passio_popen=True)
+    proc.stdin.close()
+    untrusted_path = proc.stdout.readline(path_max_len)
+    if len(untrusted_path) == 0:
+        return None
+    if path_re.match(untrusted_path):
+        return untrusted_path
+    else:
+        return None
+
 def select_path_button_clicked(dialog, select_file = False):
 def select_path_button_clicked(dialog, select_file = False):
     backup_location = str(dialog.dir_line_edit.text())
     backup_location = str(dialog.dir_line_edit.text())
     file_dialog = QFileDialog()
     file_dialog = QFileDialog()
@@ -212,6 +228,10 @@ def select_path_button_clicked(dialog, select_file = False):
     new_path = None
     new_path = None
     if dialog.appvm_combobox.currentIndex() != 0:   #An existing appvm chosen
     if dialog.appvm_combobox.currentIndex() != 0:   #An existing appvm chosen
         new_appvm = str(dialog.appvm_combobox.currentText())
         new_appvm = str(dialog.appvm_combobox.currentText())
+        vm = dialog.qvm_collection.get_vm_by_name(new_appvm)
+        if vm:
+            new_path = get_path_for_vm(vm, "qubes.SelectFile" if select_file
+                    else "qubes.SelectDirectory")
     elif dialog.dev_mount_path != None:
     elif dialog.dev_mount_path != None:
         new_path = file_dialog_function(dialog, "Select backup location.", dialog.dev_mount_path)
         new_path = file_dialog_function(dialog, "Select backup location.", dialog.dev_mount_path)
     else:
     else: