vandmo / dependency-lock-maven-plugin

Maven plugin that makes sure that Maven dependency are not accidentaly changed.
https://github.com/vandmo/dependency-lock-maven-plugin
Apache License 2.0
64 stars 10 forks source link

Add checksum support #62

Closed danielhodder closed 1 year ago

danielhodder commented 1 year ago

This adds dependency integrity checking to the plugin. It's off by default (for compatibility), and only works with the JSON format option. As far as I can tell with the existing way of parsing maven artifacts there's no place to put the checksum without breaking maven's ability to parse the POM.

This uses Maven's view of the resolved artifact and does a SHA-256 sum on it and then adds that to the artifact metadata. Since I didn't wan to tunnel the configuration option all the way down to the toString method of LockedDependency it will always have a checsum component on the end of it now. This is identified by @<checksum>, a format taken from the container systems which use image@ref for this kind of thing.

The tests gave me a lot of trouble here since the MRN plugin does not seem to transfer the JAR files exactly as they are. There's a noticeable difference between the JAR files checked into the project and what appears in target/local-repository. The contents are the same but directory entries are removed, and it seems that the header meta-data is also changed. To work around this the new integration tests only test the integrity check matches that in the local registry, rather than the source file.

Issue: #49

vandmo commented 1 year ago

Thanks a lot! I will have a closer look a this during the weekend. Some quick notes now though.

It is possible to add additional information in pom.xml in a different XML namespace.

I think "integrity": "sha256-7r...Bg==", might be better. It will never make sense to add multiple checksums, only the one that is secure enough. It would be good if older versions of the plugin fails if it encounters a checksum that it doesn't understand. Saying something like "Encountered unsupported checksum format, consider using a later version of this plugin".

The master branch is intended for a 1.0 version of the plugin where configuration will be more flexible and integrity checking enabled by default.

<dependencySets>
  <dependencySet>
    <ignoreVersion>true</ignoreVersion>
    <ignoreIntegrity>true</ignoreIntegrity>
    <includes>
      <include>com.mycompany.something</include>
      ...
    </includes>
    <excludes>...</excludes>
  </dependencySet>
  <dependencySet>
     ....
  </dependencySet>
</dependencySets

You could target the 0.x branch if you want to as well, but there it will have to be 100% opt-in.

danielhodder commented 1 year ago

I would ideally like to use this functionality soon-ish so if the 1.0 release doesn't have a soon-ish timescale then targeting the 0.x branch probably makes sense.

I will work on the rest of these changes this week and try and get them through as soon as I can.

danielhodder commented 1 year ago

I've added a sha256 header to the integrity strings, and added the verification of that. I have also made it write out that as part of a POM but I have no idea how to read that back in, without parsing the POM using a different XML mechanism. The existing maven parser, correctly, ignores the integrity elements but that means that data isn't available to be read back in at this point. which means while it records the checksum, it can't actually check it right now.

vandmo commented 1 year ago

I realized this was for the master branch which is for 1.0 just before merging. I have pushed some changes and I am working on parsing the pom file to get the integrity field. After that I can create a 0.0.commit-id release so you can try it out if you want to. Integrity checking should be enabled by default for the 1.0 release so there will be incompatible changes.

vandmo commented 1 year ago

POM is now parsed "manually". I still have some work to do, but I am working actively on it so I am hoping to have a 1.0 or at least a 0.0.commit which will be close to the final 1.0 release. I also encountered the strange behavior where mrm changes the jar file and the hash no longer matches. Did you ever find a solution to that @danielhodder ?

danielhodder commented 1 year ago

If you mean checksums of the jars that are exposed via MRN then yes. I ran into this in the JSON format as well https://github.com/vandmo/dependency-lock-maven-plugin/pull/62/files#diff-07cefa6399119458dd8677039ac63194cee36f4342ebd161550870ba2ff1fca7R16-R20. Somehow the process which copies the jars from src/it/mrn to target/local-repo seems to re-write the entities in the jar. I suspect something it iterating a ZipFileStream, and re-writeing it.

This is what the entries in the src/it/mrn/repository/leaf-1.0.jar looks like

unzip -l src/it/mrm/repository/leaf-1.0.jar
Archive:  src/it/mrm/repository/leaf-1.0.jar
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  12-31-2008 22:16   META-INF/
       71  12-31-2008 22:16   META-INF/MANIFEST.MF
---------                     -------
       71                     2 files

While this is what it looks like in the target/local-repository

unzip -l target/local-repo/se/vandmo/testing/leaf/1.0/leaf-1.0.jar
Archive:  target/local-repo/se/vandmo/testing/leaf/1.0/leaf-1.0.jar
  Length      Date    Time    Name
---------  ---------- -----   ----
       90  10-06-2022 09:15   META-INF/MANIFEST.MF
---------                     -------
       90                     1 file

In the JSON case I had to basically go and find the checksum and of the final jar that got copied across and use that to verify the contents of the lock file.

vandmo commented 1 year ago

Apparently MRM creates a new JAR for the manifest even when a jar is supplied. Anyhow, turns out MRM isn't needed. I created a setup-dependencies module which will run first and run install-file for the jar files.