Bladeren bron

Update models for new Invercargill mapper syntax, move some functions into util file

Billy Barrow 1 maand geleden
bovenliggende
commit
73b4c55c5d
6 gewijzigde bestanden met toevoegingen van 102 en 56 verwijderingen
  1. 0 42
      src/lib/Applicator.vala
  2. 1 1
      src/lib/BlobStorage.vala
  3. 53 12
      src/lib/Manifest.vala
  4. 1 1
      src/lib/ManifestUpdater.vala
  5. 46 0
      src/lib/Util.vala
  6. 1 0
      src/lib/meson.build

+ 0 - 42
src/lib/Applicator.vala

@@ -223,53 +223,11 @@ namespace Binman {
             return status;
         }
 
-        public static BinaryData calculate_file_checksum(string path, FileProgressCallback? progress_callback = null) throws Error {
-            var stream = File.new_for_path(path).read();
-            var checksum = new Checksum(ChecksumType.SHA512);
-
-            const int increment = 1024 * 1024 * 128;
-            uint64 read = 0;
-            var file_size = stream.query_info("*").get_size();
-            var to_read = file_size;
-            while(read < to_read) {
-                var data = new uint8[uint64.min(increment, to_read - read)];
-                data.length = (int)stream.read(data);
-                checksum.update(data, data.length);
-                read += data.length;
-                file_callback(progress_callback, (int64)read, file_size);
-            }
-
-            var checksum_bytes = new uint8[ChecksumType.SHA512.get_length()];
-            size_t size = checksum_bytes.length;
-            checksum.get_digest(checksum_bytes, ref size);
-
-            return new Invercargill.BinaryData.from_byte_array(checksum_bytes);
-        }
-
         private static void file_callback(FileProgressCallback? cb, int64 current, int64 total) {
             if(cb != null) {
                 cb(current, total);
             }
         }
-
-        internal static void posix_to_error(int result) throws Error {
-            if(result == 0) {
-                return;
-            }
-            throw new Error(GLib.Quark.from_string("posix"), errno, Posix.strerror(errno));
-        }
-
-        internal static void reflink_copy(string src, string dest) throws Error {
-            int pid = Posix.fork();
-            if (pid == 0) {
-                posix_to_error(Posix.execv("/bin/cp", new string[] {"--reflink=always", src, dest}));
-                Posix.exit(Posix.ENOENT);
-            }
-            int status;
-            Posix.waitpid(pid, out status, 0);
-            posix_to_error(status);
-        }
-
     }
 
     public class FileDetails {

+ 1 - 1
src/lib/BlobStorage.vala

@@ -32,7 +32,7 @@ namespace Binman {
             }
 
             try {
-                return Applicator.calculate_file_checksum(file.get_path()).equals(descriptor.checksum);
+                return calculate_file_checksum(file.get_path()).equals(descriptor.checksum);
             }
             catch (Error e) {
                 warning("Failed to verify file in blob storage: " + e.message);

+ 53 - 12
src/lib/Manifest.vala

@@ -60,7 +60,7 @@ namespace Binman {
             return new BinaryData.from_byte_array(signed_checksum).equals(new BinaryData.from_byte_array(checksum_bytes));
         }
 
-        private InputStream get_stream() throws Error {
+        internal InputStream get_stream() throws Error {
             var decompressor = new ZlibDecompressor(ZlibCompressorFormat.GZIP);
             return new ConverterInputStream(file.read(), decompressor);
         }
@@ -86,7 +86,7 @@ namespace Binman {
         public string name { get; set; }
         public string description { get; set; }
         public int serial { get; set; }
-        public string post_exec { get; set; }
+        public string? post_exec { get; set; }
         public BinaryData key { get; set; }
         public Vector<string> remotes { get; set; }
 
@@ -95,7 +95,9 @@ namespace Binman {
                 cfg.map<string>("name", o => o.name, (o, v) => o.name = v);
                 cfg.map<string>("desc", o => o.description, (o, v) => o.description = v);
                 cfg.map<int>("serial", o => o.serial, (o, v) => o.serial = v);
-                cfg.map<string>("post-exec", o => o.post_exec, (o, v) => o.post_exec = v);
+                cfg.map<string>("post-exec", o => o.post_exec, (o, v) => o.post_exec = v)
+                    .undefined_when(o => o.post_exec == null)
+                    .when_undefined(o => o.post_exec = null);
                 cfg.map<string>("key", o => o.key.to_base64(), (o, v) => o.key = new BinaryData.from_base64(v));
                 cfg.map_many<string>("remotes", o => o.remotes, (o, v) => o.remotes = v.to_vector());
                 cfg.set_constructor(() => new ManifestHeader());
@@ -105,8 +107,8 @@ namespace Binman {
 
     public class ManifestEntry {
         public string path { get; set; }
-        public int user { get; set; }
-        public int group { get; set; }
+        public Posix.uid_t user { get; set; }
+        public Posix.gid_t group { get; set; }
         public Posix.mode_t mode { get; set; }
         public string? target { get; set; }
         public string? licence { get; set; }
@@ -116,13 +118,21 @@ namespace Binman {
         public static PropertyMapper<ManifestEntry> get_mapper() {
             return PropertyMapper.build_for<ManifestEntry>(cfg => cfg
                 .map<string>("path", o => o.path, (o, v) => o.path = v)
-                .map<int>("uid", o => o.user, (o, v) => o.user = v)
-                .map<int>("gid", o => o.group, (o, v) => o.group = v)
-                .map<int>("mod", o => (int)o.mode, (o, v) => o.mode = v)
-                .map<string?>("target", o => o.target, (o, v) => o.target = v, false)
-                .map<string?>("licence", o => o.licence, (o, v) => o.licence = v, false)
-                .map_properties_with<ManifestFileDescriptor?>("bin", o => o.binary, (o, v) => o.binary = v, ManifestFileDescriptor.get_mapper(), false)
-                .map_properties_with<ManifestFileDescriptor?>("ccs", o => o.source, (o, v) => o.source = v, ManifestFileDescriptor.get_mapper(), false)
+                .map<uint>("uid", o => (uint)o.user, (o, v) => o.user = v)
+                .map<uint>("gid", o => (uint)o.group, (o, v) => o.group = v)
+                .map<uint>("mod", o => (uint)o.mode, (o, v) => o.mode = v)
+                .map<string?>("target", o => o.target, (o, v) => o.target = v)
+                    .undefined_when(o => o.target == null)
+                    .when_undefined(o => o.target = null)
+                .map<string?>("licence", o => o.licence, (o, v) => o.licence = v)
+                    .undefined_when(o => o.licence == null)
+                    .when_undefined(o => o.licence = null)
+                .map_properties_with<ManifestFileDescriptor?>("bin", o => o.binary, (o, v) => o.binary = v, ManifestFileDescriptor.get_mapper())
+                    .undefined_when(o => o.binary == null)
+                    .when_undefined(o => o.binary = null)
+                .map_properties_with<ManifestFileDescriptor?>("ccs", o => o.source, (o, v) => o.source = v, ManifestFileDescriptor.get_mapper())
+                    .undefined_when(o => o.source == null)
+                    .when_undefined(o => o.source = null)
                 .set_constructor(() => new ManifestEntry())
             );
         }
@@ -152,5 +162,36 @@ namespace Binman {
                 .set_constructor(() => new ManifestSignature())
             );
         }
+
+        public ManifestSignature.generate(File file, uint8[] signing_key) throws Error {
+            var manifest_file = new ManifestFile(file);
+            var stream = new DataInputStream(manifest_file.get_stream());
+            var checksum = new Checksum(ChecksumType.SHA512);
+
+            string? line;
+            try {
+                while ((line = stream.read_line()) != null && line.chomp().length > 0) {
+                    var obj = new JsonElement.from_string(line).as<JsonObject>();
+    
+                    // Don't include signature object in checksum
+                    if(obj.has("signature")) {
+                        break;
+                    }
+    
+                    checksum.update(line.data, line.data.length);
+                }
+            }
+            catch(Error e) {
+                // Ignore
+            }
+
+            // Calculate checksum
+            var checksum_bytes = new uint8[ChecksumType.SHA512.get_length()];
+            size_t size = checksum_bytes.length;
+            checksum.get_digest(checksum_bytes, ref size);
+
+            // Sign checksum
+            this.signature = new BinaryData.from_byte_array(Sodium.Asymmetric.Signing.sign(checksum_bytes, signing_key));
+        }
     }
 }

+ 1 - 1
src/lib/ManifestUpdater.vala

@@ -63,7 +63,7 @@ namespace Binman {
                     manifest_tmp.move(dest, FileCopyFlags.TARGET_DEFAULT_MODIFIED_TIME | FileCopyFlags.TARGET_DEFAULT_PERMS);
 
                     // Update "latest" symlink
-                    Applicator.posix_to_error(Posix.symlink(dest.get_path(), Path.build_filename("/var/binman/", component.name, "latest")));
+                    posix_to_error(Posix.symlink(dest.get_path(), Path.build_filename("/var/binman/", component.name, "latest")));
                     result = dest;
 
                 }

+ 46 - 0
src/lib/Util.vala

@@ -0,0 +1,46 @@
+using Invercargill;
+namespace Binman {
+
+    public static void posix_to_error(int result) throws Error {
+        if(result == 0) {
+            return;
+        }
+        throw new Error(GLib.Quark.from_string("posix"), errno, Posix.strerror(errno));
+    }
+    
+    public static void reflink_copy(string src, string dest) throws Error {
+        int pid = Posix.fork();
+        if (pid == 0) {
+            posix_to_error(Posix.execv("/bin/cp", new string[] {"--reflink=always", src, dest}));
+            Posix.exit(Posix.ENOENT);
+        }
+        int status;
+        Posix.waitpid(pid, out status, 0);
+        posix_to_error(status);
+    }
+
+    public static BinaryData calculate_file_checksum(string path, FileProgressCallback? progress_callback = null) throws Error {
+        var stream = File.new_for_path(path).read();
+        var checksum = new Checksum(ChecksumType.SHA512);
+
+        const int increment = 1024 * 1024 * 128;
+        uint64 read = 0;
+        var file_size = stream.query_info("*").get_size();
+        var to_read = file_size;
+        while(read < to_read) {
+            var data = new uint8[uint64.min(increment, to_read - read)];
+            data.length = (int)stream.read(data);
+            checksum.update(data, data.length);
+            read += data.length;
+            if(progress_callback != null) {
+                progress_callback((int64)read, file_size);
+            }
+        }
+
+        var checksum_bytes = new uint8[ChecksumType.SHA512.get_length()];
+        size_t size = checksum_bytes.length;
+        checksum.get_digest(checksum_bytes, ref size);
+
+        return new Invercargill.BinaryData.from_byte_array(checksum_bytes);
+    }
+}

+ 1 - 0
src/lib/meson.build

@@ -6,6 +6,7 @@ sources += files('Composition.vala')
 sources += files('Applicator.vala')
 sources += files('ManifestUpdater.vala')
 sources += files('BlobStorage.vala')
+sources += files('Util.vala')
 
 
 dependencies = [