(#13009) Compare scheduled task commands using backslashes

Previously, if the command for a scheduled task was specified using
forward slashes, puppet would always think the resource was out-of-sync.
This issue is that Windows does not preserve forward slashes, so the
*current* value always contains backslashes.

This commit munges forward slashes in the command to backslashes. It also
uses `File.expand_path`, because otherwise commands like the following in
the puppet language would be considered different:

    command => 'c:\\windows\\system32\\cmd.exe'
    command => 'c:\windows\system32\cmd.exe'
 (#13008) Allow scheduled task arguments to be specified

Previously, the `arguments` property of a `scheduled_task` resource
could not be specified as it would lead to a TypeError when we passed
the `should` array value to the task scheduler method that expected a
string.

Previously, scheduled tasks arguments could be specified as either a
string or an array. But if an array was specified it could only contain
a single element.

This commit requires that the arguments be specified as a
space-delimited string, e.g.  'arg1 arg2'.  It is not a breaking change,
because the ability to specify arguments never worked.
(#14749) Clear reference to invalid task after saving

Previously, running `puppet resource scheduled_task <name> ...` to
create a scheduled task would raise an exception. This would occur
because the provider's flush method calls `task.save`, which releases
the reference to the COM interface and sets it to nil. Then later the
`resource` application attempts to retrieve the state of the resource it
just flushed. This causes the win32-taskscheduler gem to raise an
exception because the underlying interface is nil.

This is not an issue when applying a manifest, because puppet doesn't
retrieve the state of the resource after it's been flushed. However,
when writing acceptance tests for the scheduled_task type using `puppet
resource scheduled_task` this bug occurred.

The `Win32::TaskScheduler#save` method should have probably been called
`close` since you can't perform additional operations on it, once it's
been closed. However, this is the gem, not puppet code, and the method
does say:

    Note that calling TaskScheduler#save also resets the
    TaskScheduler object so that there is no currently active task.

So whatever.

This commit simply changes the provider's flush method to clear the
`Win32::TaskScheduler` object after saving it, so that subsequent calls
to the `task` getter method will create a new `Win32::TaskScheduler`
instance.

This commit also adds acceptance tests that exercise things that were
previously broken in #13749, #13008, and #13009. The tests rely on the
ability to create scheduled_tasks using the `puppet resource
scheduled_task` style invocation, which this commit fixes.

The acceptance tests are more verbose than one would like because the
options to the `schtasks.exe` are different for before Vista, and
Vista and later.
(#14964) Don't fail if we can't unlink the Tempfile on Windows

Previously, if the exec resource created a process, e.g. start.exe, that
executed another process asynchronously, then the grandchild would inherit
the tempfile handle, preventing puppet from being able to unlink it. This
is not an issue on POSIX systems.

This commit changes the `wait_for_output` method to ignore Errno::EACCES
exceptions caused when closing and unlinking the stdout tempfile. The
behavior on POSIX systems is unchanged.
(#13489) Synchronously start and stop services

Previously, we were using the `win32-service` gem to start and stop
services.  It uses Win32 APIs to programmatically send start and stop
requests.  The actual service starts/stops asynchronously with respect
to the request.  As a result, when refreshing a service, puppet would
issue a stop request, immediately followed by a start request, and that
would race as the service would often still be running when the start
request occurred, leading to 'An instance of the service is already
running'.

This commit changes the windows service provider to use `net.exe` to
start and stop services.  This command will block until the service
start/stops, and returns 0 on success, making it easy to adapt to the
provider command pattern.  The one downside is that the exit codes don't
have the same resolution that we can get via the `sc.exe` or by calling
the Service Control Manager programmatically.  But that is not too
critical because we do capture the output of the `net.exe` command, e.g.
'The service name is invalid.' and include it in the exception message.
(#13489) Use let to memoize instance variables

Converted instance variables, e.g. @resource, to let helper methods to
reduce verbosity.
Deprecate IP-based authentication

This will need to be made explicit in a future version, so it's good to
get people to stop using it if possible.
Add Selector terminus for file_content/file_metadata

This terminus is now the default, and encapsulates the behavior that was
previously in the IndirectionHooks. That is, we dynamically select the
terminus to use for a file request based on the key. However, for the
puppet master, we instead explicitly always use the FileServer terminus,
so that *all* requests for files from the master will go through
the file server. This ensures that we will never accidentally
serve local files on the puppet master.
Reject file requests containing ..
Fail more gracefully when finding module files if no file is specified

Previously this would just complain about trying to call `nil.split`.
Always use the local file_bucket on master

This fixes an issue where the master could be made to issue arbitrary
HTTPS requests through carefully constructed URLs. Now the master will
always use the file_bucket, whereas other applications retain their
behavior of dynamically selecting the source (rest or file) based on the
particular request.
Use head method to determine if file is in file bucket

This call was using find, but wasn't doing anything with the result,
only checking whether the file existed. Using head here is more
semantic and saves the trouble of reading the file if it does
exist.
Fix whitespace inside parentheses
Add specs for selector terminuses of file_{content,metadata}
Validate CSR CN and provided certname before signing

This adds a few new checks when signing CSRs, to validate the CN. First,
it must conform to a small set of characters, which are the printable
ASCII characters, except for '/' (because we store these in files). This
prevents attacks such as a CN "foo^H^H^Hbar", which appears as "bar" to
"puppet cert list".

The other check is that the certname for the SSL::Host that we think
we're signing must match the CN. This prevents a CSR with the CN "foo"
from being submitted as a CSR for "bar", which would cause it to appear
as "bar" to "puppet cert list", but to issue a certificate for "foo".
Don't allow the creation of SSL objects with invalid certnames

This ensures we catch invalid certnames earlier in the process, such as
when an agent is starting or making a certificate request, rather than
at the very last step of signing the request. This should make for
better error messages to the user.
Use "inspect" when listing certificates

This fixes an issue of `puppet cert list` potentially not accurately
depicting the actual certname of the certificate/request. For instance,
"foo^H^H^Hbar" would simply appear as "bar".
Tighten permissions on classfile, resourcefile, lastrunfile, and lastrunreport.
Merge branch 'file-server-2.7.17' into security_fixes_2.7.18
Merge branch 'deprecate-ip-authentication-2.7.17' into security_fixes_2.7.18