(#23343) Use `replace_file` to update a file's contents

The previous code had an unsafe use of temp files by looking for a name
it can use in a directory and then later opening the file and writing to
it. An attacker could, through some lucky timing and good access, make
the selected name a symlink to another file and thereby cause puppet to
overwrite something that it did not intend to.

The temporary file is used to make the file update atomic and also to
check that the contents have been written correctly. This updates the
file type to use the Puppet::Util#replace_file method to do a safe,
atomic, content swap. Since replace_file requires a mode to be provided,
the code was also updated to use the assumed default of 0644, which is
used when figuring out the absolute mode integer from symbolic modes.

In order to get this change to work on windows, there were a few
modifications that needed to be made as well:

 - New file must have binmode set to generate checksums
   appropriately across operating sytems that results from newline
   differences
 - replace_file has been adjusted so that passing a mode is now
   optional, and mode is only applied when the passed value is not nil
 - Windows code has been cleaned up / refactored to reduce unnecessary
   confusing code paths.  The simple mechanism for ensuring Windows
   ReplaceFile will always succeed is to first create a file by
   touching it (yielding default permissions) if it does not yet exist.
 - New integration tests assert that replace_file behaves properly on
   Windows, and the == operator was implemented on access_control_list
   for the sake of test clarity
 - replace_file is now allowed to take a nil `default_mode` so that when
   the file type is not attempting to manage the mode of the file we
   will end up with the system default.
(packaging) Update PUPPETVERSION to 3.4.1
Merge tag '3.4.1' into stable

3.4.1

* tag '3.4.1':
  (packaging) Update PUPPETVERSION to 3.4.1
  (#23343) Use `replace_file` to update a file's contents