← Back to team overview

deja-dup-team team mailing list archive

[Merge] lp:~mterry/deja-dup/gio-mount-password into lp:deja-dup

 

Michael Terry has proposed merging lp:~mterry/deja-dup/gio-mount-password into lp:deja-dup.

Requested reviews:
  Ken VanDine (ken-vandine)
Related bugs:
  Bug #588541 in Déjà Dup: "Connection failed, please check your password: Login dialog cancelled"
  https://bugs.launchpad.net/deja-dup/+bug/588541

For more details, see:
https://code.launchpad.net/~mterry/deja-dup/gio-mount-password/+merge/98271

If duplicity is run under sudo (as happens when non-home data is backed up), it can't use the user's remote mount.  So it previously just aborted.  This branch adds the ability to pass along the password to duplicity so it can mount it itself.

To test:
 * Setup Deja Dup like so:
   - Include "/bin"
   - Make your backup location a remote URL that needs a password, like an FTP server or SSH server (though...  if you use SSH, you'll need lp:~mterry/duplicity/gio-questions as a patch to your system duplicity as well)
 * Make a backup
 * Try to restore (./deja-dup/deja-dup --restore)

Before the patch:
 * You should get prompted for your root password and it will fail with "Connection failed, please check your password: Login dialog cancelled"

After the patch:
 * You should get prompted for your root password and it will successfully restore
-- 
https://code.launchpad.net/~mterry/deja-dup/gio-mount-password/+merge/98271
Your team Déjà Dup Developers is subscribed to branch lp:deja-dup.
=== modified file 'common/BackendFile.vala'
--- common/BackendFile.vala	2012-03-19 19:18:14 +0000
+++ common/BackendFile.vala	2012-03-19 19:29:20 +0000
@@ -67,7 +67,20 @@
   public override string? get_location() throws Error
   {
     var file = get_file_from_settings();
-    return file.get_uri();
+    var uri = file.get_uri();
+
+    // Insert username (yes, we've mounted the location, but if we end up
+    // having to run duplicity through sudo, duplicity will have to mount
+    // again, and it will need the username).  The password is passed
+    // separately via envp.
+    if (mount_op.username != null) {
+      var parsed = DejaDupDecodedUri.decode_uri(uri);
+      parsed.userinfo = DejaDup.userinfo_set_user(parsed.scheme, parsed.userinfo, mount_op.username);
+      uri = parsed.encode_uri(true);
+    }
+    // else it should already be in uri
+
+    return uri;
   }
 
   public override string? get_location_pretty() throws Error
@@ -254,8 +267,6 @@
     settings.apply();
   }
 
-  // This doesn't *really* worry about envp, it just is a convenient point to
-  // hook into the operation steps to mount the file.
   public override async void get_envp() throws Error
   {
     this.ref();
@@ -263,7 +274,7 @@
       yield mount_file();
     }
     catch (Error e) {
-      envp_ready(false, new List<string>(), e.message);
+      envp_ready(false, null, e.message);
     }
     this.unref();
   }
@@ -283,6 +294,48 @@
     loop.run();
   }
 
+  // location must already be mounted
+  void find_mount_password()
+  {
+    if (mount_op.password != null) {
+      var envp = new List<string>();
+      envp.append("FTP_PASSWORD=%s".printf(mount_op.password));
+      envp_ready(true, envp);
+      return;
+    }
+
+    // Ugh.  So user didn't have answer any questions.  Either a password isn't
+    // required for this mount, or it's saved.  Unfortunately, there's no
+    // fool-proof way of asking what the password used for a mount was.
+    // So we do the best we can here, leaving off the
+    // difficult-to-know-ahead-of-time object and authtype.
+    var file = get_file_from_settings();
+    var parsed = DejaDupDecodedUri.decode_uri(file.get_uri());
+    var user = DejaDup.userinfo_get_user(parsed.scheme, parsed.userinfo);
+    var domain = DejaDup.userinfo_get_domain(parsed.scheme, parsed.userinfo);
+
+    GnomeKeyring.find_network_password(user,
+                                       domain,
+                                       parsed.host,
+                                       null /* object */,
+                                       parsed.scheme,
+                                       null /* authtype */,
+                                       parsed.port > 0 ? parsed.port : 0,
+                                       found_password);
+  }
+
+  void found_password(GnomeKeyring.Result result,
+                      GLib.List<GnomeKeyring.NetworkPasswordData>? list)
+  {
+    if (result == GnomeKeyring.Result.OK && list != null) {
+      var envp = new List<string>();
+      envp.append("FTP_PASSWORD=%s".printf(list.data.password));
+      envp_ready(true, envp);
+    }
+    else
+      envp_ready(true, null); // just go ahead with backup anyway
+  }
+
   async void mount_file() throws Error
   {
     var success = true;
@@ -324,9 +377,14 @@
       catch (IOError.EXISTS err2) {
         // ignore
       }
+        
+      if (type == "normal" && !gfile.is_native())
+        find_mount_password();
+      else
+        envp_ready(true, null);
     }
-
-    envp_ready(success, new List<string>());
+    else
+      envp_ready(false, null);
   }
 
   async bool mount_remote(File file) throws Error


Follow ups