[gparted] Make encrypted Partition objects look like whole disk device ones (#775932)



commit 9f08875997651cf19e8ed6cb531afa7412bcfd28
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Tue Nov 8 07:03:09 2016 +0000

    Make encrypted Partition objects look like whole disk device ones (#775932)
    
    Until now an encryption mapping has been modelled as a Partition object
    similar to a partition like this:
        .encrypted.device_path  = "/dev/sdb1"
        .encrypted.path         = "/dev/mapper/sdb1_crypt"
        .encrypted.whole_device = false
        .encrypted.sector_start = // start of the mapping in the partition
        .encrypted.sector_end   = // end of the mapping in the partition
    However accessing device_path in the start to end sector range is not
    equivalent to accessing the partition path as it doesn't provide access
    to the encrypted data.  Therefore existing functions which read and
    write partition data (GParted file system copying and signature erasure)
    via libparted using the device_path won't work and will in fact destroy
    the encrypted data.  This could be coded around with an extra case in
    the device opening code, however it is not necessary.
    
    An encrypted block special device /dev/mapper/CRYPTNAME looks just like
    a whole disk device because it doesn't contain a partition and the file
    system it contains starts at sector 0 and goes to the end.  Therefore
    model an encryption mapping in the same way a whole disk device is
    modelled as a Partition object like this:
        .encrypted.device_path  = "/dev/mapper/sdb1_crypt"
        .encrypted.path         = "/dev/mapper/sdb1_crypt"
        .encrypted.whole_device = true
        .encrypted.sector_start = 0
        .encrypted.sector_end   = // size of the encryption mapping - 1
    Now GParted file system copy and erasure will just work without any
    change.  Just need to additionally store the LUKS header size, which was
    previous stored in the sector_start, for use in the
    get_sectors_{used,unused,unallocated}() calculations.
    
    Bug 775932 - Refactor mostly applying of operations

 include/PartitionLUKS.h |   10 ++++++++++
 src/GParted_Core.cc     |   20 +++++++-------------
 src/PartitionLUKS.cc    |   43 +++++++++++++++++++++++++++++++++++--------
 3 files changed, 52 insertions(+), 21 deletions(-)
---
diff --git a/include/PartitionLUKS.h b/include/PartitionLUKS.h
index f12f38a..11107ea 100644
--- a/include/PartitionLUKS.h
+++ b/include/PartitionLUKS.h
@@ -21,6 +21,8 @@
 #include "../include/Partition.h"
 #include "../include/Utils.h"
 
+#include <glibmm/ustring.h>
+
 namespace GParted
 {
 
@@ -31,6 +33,13 @@ public:
        virtual ~PartitionLUKS();
        virtual PartitionLUKS * clone() const;
 
+       void set_luks( const Glib::ustring & path,
+                      FILESYSTEM fstype,
+                      Sector header_size,
+                      Sector mapping_size,
+                      Byte_Value sector_size,
+                      bool busy );
+
        Partition & get_encrypted()              { return encrypted; };
        const Partition & get_encrypted() const  { return encrypted; };
 
@@ -46,6 +55,7 @@ public:
 
 private:
        Partition encrypted;
+       Sector header_size;  // Size of the LUKS header (everything up to the start of the mapping)
 };
 
 }//GParted
diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc
index 360898c..dadc18a 100644
--- a/src/GParted_Core.cc
+++ b/src/GParted_Core.cc
@@ -1243,20 +1243,14 @@ void GParted_Core::set_luks_partition( PartitionLUKS & partition )
        }
        bool fs_busy = is_busy( fstype, mapping_path );
 
+       partition.set_luks( mapping_path,
+                           fstype,
+                           mapping.offset / partition.sector_size,
+                           mapping.length / partition.sector_size,
+                           partition.sector_size,
+                           fs_busy );
+
        Partition & encrypted = partition.get_encrypted();
-       encrypted.Set( partition.get_path(),
-                      mapping_path,
-                      1,
-                      TYPE_PRIMARY,
-                      false,
-                      fstype,
-                      // Start and end sectors locate the encrypted file system within
-                      // the LUKS partition.  LUKS header is everything before.
-                      mapping.offset / partition.sector_size,
-                      ( mapping.offset + mapping.length ) / partition.sector_size - 1LL,
-                      partition.sector_size,
-                      false,
-                      fs_busy );
        encrypted.append_messages( detect_messages );
 
        set_partition_label_and_uuid( encrypted );
diff --git a/src/PartitionLUKS.cc b/src/PartitionLUKS.cc
index fc4c35c..66b4388 100644
--- a/src/PartitionLUKS.cc
+++ b/src/PartitionLUKS.cc
@@ -20,7 +20,7 @@
 namespace GParted
 {
 
-PartitionLUKS::PartitionLUKS()
+PartitionLUKS::PartitionLUKS() : header_size( 0 )
 {
        // Nothing further to do here as the base class Partition default constructor,
        // which calls Partition::Reset(), is called for this object and also to
@@ -37,6 +37,31 @@ PartitionLUKS * PartitionLUKS::clone() const
        return new PartitionLUKS( *this );
 }
 
+// Mostly a convenience method calling Partition::Set() on the encrypted Partition but
+// also sets private header_size.  Makes encrypted Partition object look like a whole disk
+// device as /dev/mapper/CRYPTNAME contains no partition table and the file system starts
+// from sector 0 going to the very end.
+void PartitionLUKS::set_luks( const Glib::ustring & path,
+                              FILESYSTEM fstype,
+                              Sector header_size,
+                              Sector mapping_size,
+                              Byte_Value sector_size,
+                              bool busy )
+{
+       encrypted.Set( path,
+                      path,
+                      1,
+                      TYPE_PRIMARY,
+                      true,
+                      fstype,
+                      0LL,
+                      mapping_size - 1LL,
+                      sector_size,
+                      false,
+                      busy );
+       this->header_size = header_size;
+}
+
 bool PartitionLUKS::sector_usage_known() const
 {
        if ( busy )
@@ -53,25 +78,27 @@ bool PartitionLUKS::sector_usage_known() const
 //     LUKS   LUKS
 //     Header Mapping
 //     |<--->||<----------------------->|           <- encrypted Partition object member
+//     hhhhhhh                                      <- this->header_size
 //     1111111111111111111111111111111111uuuuuuuuuu <- this->sectors_{used,unused,unallocated}
 //            Encrypted file system
 //            |<----------------->|
 //            111111111111110000000uuuuuu           <- encrypted.sectors_{used,unused,unallocated}
-//            ^                         ^
-//            |                         `------------- encrypted.sector_end
-//            `--------------------------------------- encrypted.sector_start (== size of LUKS header)
+//                                                     encrypted.sector_start = 0
+//                                                     encrypted.sector_end = (last sector in LUKS mapping)
+//
 //     1111111111111111111110000000uuuuuuuuuuuuuuuu <- Overall usage figures as used in the following
 //                                                     usage related methods.
 // Legend:
 // 1 - used sectors
 // 0 - unused sectors
 // u - unallocated sectors
+// h - LUKS header sectors
 //
 // Calculations:
 //     total_used        = LUKS Header size + Encrypted file system used
-//                       = encrypted.sector_start + encrypted.sectors_used
+//                       = this->header_size + encrypted.sectors_used
 //     total_unallocated = LUKS unallocated + Encrypted file system unallocated
-//                       = this->sectors_unallocated + encrypted_unallocated
+//                       = this->sectors_unallocated + encrypted.sectors_unallocated
 //     total_unused      = LUKS unused + Encrypted file system unused
 //                       = 0 + encrypted.sectors_unused
 //
@@ -86,7 +113,7 @@ Sector PartitionLUKS::estimated_min_size() const
                // For an open dm-crypt mapping work with above described totals.
                if ( sectors_used >= 0 && encrypted.sectors_used >= 0 )
                {
-                       Sector total_used        = encrypted.sector_start + encrypted.sectors_used;
+                       Sector total_used        = header_size + encrypted.sectors_used;
                        Sector total_unallocated = sectors_unallocated + encrypted.sectors_unallocated;
                        return total_used + std::min( total_unallocated, significant_threshold );
                }
@@ -104,7 +131,7 @@ Sector PartitionLUKS::get_sectors_used() const
                // For an open dm-crypt mapping work with above described totals.
                if ( sectors_used >= 0 && encrypted.sectors_used >= 0 )
                {
-                       Sector total_used        = encrypted.sector_start + encrypted.sectors_used;
+                       Sector total_used        = header_size + encrypted.sectors_used;
                        Sector total_unallocated = sectors_unallocated + encrypted.sectors_unallocated;
                        if ( total_unallocated < significant_threshold )
                                return total_used + total_unallocated;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]