diff --git a/.gitignore b/.gitignore index 988dcbb..3f15512 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,7 @@ /log/ /pkg/ /spec/fixtures/manifests/ -/spec/fixtures/modules/ +/spec/fixtures/modules/* /tmp/ /vendor/ /convert_report.txt diff --git a/.pdkignore b/.pdkignore index c538bea..584438f 100644 --- a/.pdkignore +++ b/.pdkignore @@ -16,7 +16,7 @@ /log/ /pkg/ /spec/fixtures/manifests/ -/spec/fixtures/modules/ +/spec/fixtures/modules/* /tmp/ /vendor/ /convert_report.txt @@ -26,20 +26,16 @@ .envrc /inventory.yaml /spec/fixtures/litmus_inventory.yaml -/appveyor.yml -/.editorconfig /.fixtures.yml /Gemfile /.gitattributes /.gitignore -/.gitlab-ci.yml /.pdkignore /.puppet-lint.rc /Rakefile /rakelib/ /.rspec -/.rubocop.yml -/.travis.yml +/..yml /.yardopts /spec/ /.vscode/ diff --git a/.rubocop.yml b/.rubocop.yml index 8f782e7..23b9a2e 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -4,7 +4,7 @@ require: - rubocop-rspec AllCops: DisplayCopNames: true - TargetRubyVersion: '2.4' + TargetRubyVersion: '2.6' Include: - "**/*.rb" Exclude: @@ -18,9 +18,10 @@ AllCops: - "**/Puppetfile" - "**/Vagrantfile" - "**/Guardfile" + - spec/functions/* Layout/LineLength: Description: People have wide screens, use them. - Max: 200 + Max: 20000 RSpec/BeforeAfterAll: Description: Beware of using after(:all) as it may cause state to leak between tests. A necessary evil in acceptance testing. @@ -111,8 +112,14 @@ Style/MethodCalledOnDoEndBlock: Enabled: true Style/StringMethods: Enabled: true +Bundler/GemFilename: + Enabled: false Bundler/InsecureProtocolSource: Enabled: false +Capybara/CurrentPathExpectation: + Enabled: false +Capybara/VisibilityMatcher: + Enabled: false Gemspec/DuplicatedAssignment: Enabled: false Gemspec/OrderedDependencies: @@ -187,6 +194,8 @@ Lint/MixedRegexpCaptureTypes: Enabled: false Lint/NestedPercentLiteral: Enabled: false +Lint/Next: + Enabled: false Lint/NonDeterministicRequireOrder: Enabled: false Lint/OrderedMagicComments: @@ -213,6 +222,8 @@ Lint/SafeNavigationConsistency: Enabled: false Lint/SafeNavigationWithEmpty: Enabled: false +Lint/SafeNavigation: + Enabled: false Lint/SelfAssignment: Enabled: false Lint/SendWithMixinArgument: @@ -287,11 +298,9 @@ Performance/UriDefaultParser: Enabled: false RSpec/Be: Enabled: false -RSpec/Capybara/CurrentPathExpectation: - Enabled: false RSpec/Capybara/FeatureMethods: Enabled: false -RSpec/Capybara/VisibilityMatcher: +RSpec/ContainExactly: Enabled: false RSpec/ContextMethod: Enabled: false @@ -331,6 +340,8 @@ RSpec/LeakyConstantDeclaration: Enabled: false RSpec/LetBeforeExamples: Enabled: false +RSpec/MatchArray: + Enabled: false RSpec/MissingExampleGroupArgument: Enabled: false RSpec/MultipleExpectations: @@ -373,8 +384,6 @@ Style/AccessModifierDeclarations: Enabled: false Style/AccessorGrouping: Enabled: false -Style/AsciiComments: - Enabled: false Style/BisectedAttrAccessor: Enabled: false Style/CaseLikeIf: @@ -485,35 +494,235 @@ Style/TrailingMethodEndStatement: Enabled: false Style/UnpackFirst: Enabled: false +Capybara/MatchStyle: + Enabled: false +Capybara/NegationMatcher: + Enabled: false +Capybara/SpecificActions: + Enabled: false +Capybara/SpecificFinders: + Enabled: false +Capybara/SpecificMatcher: + Enabled: false +Gemspec/DeprecatedAttributeAssignment: + Enabled: false +Gemspec/DevelopmentDependencies: + Enabled: false +Gemspec/RequireMFA: + Enabled: false +Layout/LineContinuationLeadingSpace: + Enabled: false +Layout/LineContinuationSpacing: + Enabled: false +Layout/LineEndStringConcatenationIndentation: + Enabled: false +Layout/SpaceBeforeBrackets: + Enabled: false +Lint/AmbiguousAssignment: + Enabled: false +Lint/AmbiguousOperatorPrecedence: + Enabled: false +Lint/AmbiguousRange: + Enabled: false +Lint/ConstantOverwrittenInRescue: + Enabled: false +Lint/DeprecatedConstants: + Enabled: false Lint/DuplicateBranch: Enabled: false +Lint/DuplicateMagicComment: + Enabled: false Lint/DuplicateRegexpCharacterClassElement: Enabled: false Lint/EmptyBlock: Enabled: false Lint/EmptyClass: Enabled: false +Lint/EmptyInPattern: + Enabled: false +Lint/IncompatibleIoSelectWithFiberScheduler: + Enabled: false +Lint/LambdaWithoutLiteralBlock: + Enabled: false Lint/NoReturnInBeginEndBlocks: Enabled: false +Lint/NonAtomicFileOperation: + Enabled: false +Lint/NumberedParameterAssignment: + Enabled: false +Lint/OrAssignmentToConstant: + Enabled: false +Lint/RedundantDirGlobSort: + Enabled: false +Lint/RefinementImportMethods: + Enabled: false +Lint/RequireRangeParentheses: + Enabled: false +Lint/RequireRelativeSelfPath: + Enabled: false +Lint/SymbolConversion: + Enabled: false Lint/ToEnumArguments: Enabled: false +Lint/TripleQuotes: + Enabled: false Lint/UnexpectedBlockArity: Enabled: false Lint/UnmodifiedReduceAccumulator: Enabled: false +Lint/UselessRescue: + Enabled: false +Lint/UselessRuby2Keywords: + Enabled: false +Metrics/CollectionLiteralLength: + Enabled: false +Naming/BlockForwarding: + Enabled: false Performance/CollectionLiteralInLoop: Enabled: false +Performance/ConcurrentMonotonicTime: + Enabled: false +Performance/MapCompact: + Enabled: false +Performance/RedundantEqualityComparisonBlock: + Enabled: false +Performance/RedundantSplitRegexpArgument: + Enabled: false +Performance/StringIdentifierArgument: + Enabled: false +RSpec/BeEq: + Enabled: false +RSpec/BeNil: + Enabled: false +RSpec/ChangeByZero: + Enabled: false +RSpec/ClassCheck: + Enabled: false +RSpec/DuplicatedMetadata: + Enabled: false +RSpec/ExcessiveDocstringSpacing: + Enabled: false +RSpec/FactoryBot/ConsistentParenthesesStyle: + Enabled: false +RSpec/FactoryBot/FactoryNameStyle: + Enabled: false +RSpec/FactoryBot/SyntaxMethods: + Enabled: false +RSpec/IdenticalEqualityAssertion: + Enabled: false +RSpec/NoExpectationExample: + Enabled: false +RSpec/PendingWithoutReason: + Enabled: false +RSpec/Rails/AvoidSetupHook: + Enabled: false +RSpec/Rails/HaveHttpStatus: + Enabled: false +RSpec/Rails/InferredSpecType: + Enabled: false +RSpec/Rails/MinitestAssertions: + Enabled: false +RSpec/Rails/TravelAround: + Enabled: false +RSpec/RedundantAround: + Enabled: false +RSpec/SkipBlockInsideExample: + Enabled: false +RSpec/SortMetadata: + Enabled: false +RSpec/SubjectDeclaration: + Enabled: false +RSpec/VerifiedDoubleReference: + Enabled: false +Security/CompoundHash: + Enabled: false +Security/IoMethods: + Enabled: false Style/ArgumentsForwarding: Enabled: false +Style/ArrayIntersect: + Enabled: false Style/CollectionCompact: Enabled: false +Style/ComparableClamp: + Enabled: false +Style/ConcatArrayLiterals: + Enabled: false +Style/DirEmpty: + Enabled: false Style/DocumentDynamicEvalDefinition: Enabled: false +Style/EmptyHeredoc: + Enabled: false +Style/EndlessMethod: + Enabled: false +Style/EnvHome: + Enabled: false +Style/FetchEnvVar: + Enabled: false +Style/FileEmpty: + Enabled: false +Style/FileRead: + Enabled: false +Style/FileWrite: + Enabled: false +Style/HashConversion: + Enabled: false +Style/HashExcept: + Enabled: false +Style/IfWithBooleanLiteralBranches: + Enabled: false +Style/InPatternThen: + Enabled: false +Style/MagicCommentFormat: + Enabled: false +Style/MapCompactWithConditionalBlock: + Enabled: false +Style/MapToHash: + Enabled: false +Style/MapToSet: + Enabled: false +Style/MinMaxComparison: + Enabled: false +Style/MultilineInPatternThen: + Enabled: false Style/NegatedIfElseCondition: Enabled: false +Style/NestedFileDirname: + Enabled: false Style/NilLambda: Enabled: false +Style/NumberedParameters: + Enabled: false +Style/NumberedParametersLimit: + Enabled: false +Style/ObjectThen: + Enabled: false +Style/OpenStructUse: + Enabled: false +Style/OperatorMethodCall: + Enabled: false +Style/QuotedSymbols: + Enabled: false Style/RedundantArgument: Enabled: false +Style/RedundantConstantBase: + Enabled: false +Style/RedundantDoubleSplatHashBraces: + Enabled: false +Style/RedundantEach: + Enabled: false +Style/RedundantHeredocDelimiterQuotes: + Enabled: false +Style/RedundantInitialize: + Enabled: false +Style/RedundantSelfAssignmentBranch: + Enabled: false +Style/RedundantStringEscape: + Enabled: false +Style/SelectByRegexp: + Enabled: false +Style/StringChars: + Enabled: false Style/SwapValues: Enabled: false diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c954cd..b955f0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ All notable changes to this project will be documented in this file. **Features** +- First release to forge. + **Bugfixes** **Known Issues** diff --git a/Gemfile b/Gemfile index a167b88..169c429 100644 --- a/Gemfile +++ b/Gemfile @@ -1,5 +1,7 @@ source ENV['GEM_SOURCE'] || 'https://rubygems.org' +gem 'xml-simple' + def location_for(place_or_version, fake_version = nil) git_url_regex = %r{\A(?(https?|git)[:@][^#]*)(#(?.*))?} file_url_regex = %r{\Afile:\/\/(?.*)} @@ -13,21 +15,32 @@ def location_for(place_or_version, fake_version = nil) end end -ruby_version_segments = Gem::Version.new(RUBY_VERSION.dup).segments -minor_version = ruby_version_segments[0..1].join('.') - group :development do - gem "json", '= 2.0.4', require: false if Gem::Requirement.create('~> 2.4.2').satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) - gem "json", '= 2.1.0', require: false if Gem::Requirement.create(['>= 2.5.0', '< 2.7.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) - gem "json", '= 2.3.0', require: false if Gem::Requirement.create(['>= 2.7.0', '< 2.8.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) - gem "puppet-module-posix-default-r#{minor_version}", '~> 1.0', require: false, platforms: [:ruby] - gem "puppet-module-posix-dev-r#{minor_version}", '~> 1.0', require: false, platforms: [:ruby] - gem "puppet-module-win-default-r#{minor_version}", '~> 1.0', require: false, platforms: [:mswin, :mingw, :x64_mingw] - gem "puppet-module-win-dev-r#{minor_version}", '~> 1.0', require: false, platforms: [:mswin, :mingw, :x64_mingw] + gem "json", '= 2.1.0', require: false if Gem::Requirement.create(['>= 2.5.0', '< 2.7.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) + gem "json", '= 2.3.0', require: false if Gem::Requirement.create(['>= 2.7.0', '< 3.0.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) + gem "json", '= 2.5.1', require: false if Gem::Requirement.create(['>= 3.0.0', '< 3.0.5']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) + gem "json", '= 2.6.1', require: false if Gem::Requirement.create(['>= 3.1.0', '< 3.1.3']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) + gem "json", '= 2.6.3', require: false if Gem::Requirement.create(['>= 3.2.0', '< 4.0.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) + gem "racc", '~> 1.4.0', require: false if Gem::Requirement.create(['>= 2.7.0', '< 3.0.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) + gem "voxpupuli-puppet-lint-plugins", '~> 5.0', require: false + gem "facterdb", '~> 1.18', require: false + gem "metadata-json-lint", '~> 3.0', require: false + gem "puppetlabs_spec_helper", '~> 6.0', require: false + gem "rspec-puppet-facts", '~> 2.0', require: false + gem "codecov", '~> 0.2', require: false + gem "dependency_checker", '~> 1.0.0', require: false + gem "parallel_tests", '= 3.12.1', require: false + gem "pry", '~> 0.10', require: false + gem "simplecov-console", '~> 0.5', require: false + gem "puppet-debugger", '~> 1.0', require: false + gem "rubocop", '= 1.48.1', require: false + gem "rubocop-performance", '= 1.16.0', require: false + gem "rubocop-rspec", '= 2.19.0', require: false + gem "rb-readline", '= 0.5.5', require: false, platforms: [:mswin, :mingw, :x64_mingw] end group :system_tests do - gem "puppet-module-posix-system-r#{minor_version}", '~> 1.0', require: false, platforms: [:ruby] - gem "puppet-module-win-system-r#{minor_version}", '~> 1.0', require: false, platforms: [:mswin, :mingw, :x64_mingw] + gem "puppet_litmus", '~> 1.0', require: false, platforms: [:ruby, :x64_mingw] + gem "serverspec", '~> 2.41', require: false end puppet_version = ENV['PUPPET_GEM_VERSION'] diff --git a/README.md b/README.md index 1f10228..20a4a13 100644 --- a/README.md +++ b/README.md @@ -1,117 +1,272 @@ # applocker -Welcome to your new module. A short overview of the generated parts can be found -in the [PDK documentation][1]. +A Puppet module which configures applocker on Windows (Application whitelisting). For information about applocker see [here][2] -The README template below provides a starting point with details about what -information to include in your README. +## Setup requirements + +benjaminrobertson-applocker requires the xml-simple ruby gem installed on the Puppet Primary server. Install by running `puppetserver gem install xml-simple` as root on the Puppet Primary server. If the gem is not installed the module will not work. + +**Note:** When Puppet attempts to enable applocker service for the first time, this error will be seen in the Puppet logs. `Error: Cannot enable AppIDSvc, error was: undefined method 'windows' for Puppet::Util:Module` Applocker is running regardless of this error. ## Table of Contents 1. [Description](#description) 1. [Setup - The basics of getting started with applocker](#setup) * [What applocker affects](#what-applocker-affects) - * [Setup requirements](#setup-requirements) - * [Beginning with applocker](#beginning-with-applocker) 1. [Usage - Configuration options and additional functionality](#usage) 1. [Limitations - OS compatibility, etc.](#limitations) 1. [Development - Guide for contributing to the module](#development) ## Description -Briefly tell users why they might want to use your module. Explain what your -module does and what kind of problems users can solve with it. - -This should be a fairly short description helps the user decide if your module -is what they want. - ## Setup -### What applocker affects **OPTIONAL** - -If it's obvious what your module touches, you can skip this section. For -example, folks can probably figure out that your mysql_instance module affects -their MySQL instances. - -If there's more that they should know about, though, this is the place to -mention: +### What applocker affects -* Files, packages, services, or operations that the module will alter, impact, - or execute. -* Dependencies that your module automatically installs. -* Warnings or other important notices. +benjaminrobertson-applocker configures Windows applocker service. Applocker enforces applications whitelisting. -### Setup Requirements **OPTIONAL** +**Warning:** Ensure applocker policies are first tested on a non-production host. You can very easily break systems by enforcing strict applocker policies. -If your module requires anything extra before setting up (pluginsync enabled, -another module, etc.), mention it here. - -If your most recent release breaks compatibility or requires particular steps -for upgrading, you might want to include an additional "Upgrading" section here. - -### Beginning with applocker - -The very basic steps needed for a user to get the module up and running. This -can include setup steps, if necessary, or it can be an example of the most basic -use of the module. +I suggest applying applocker policies in 'AuditOnly' mode (modules default). Use Windows event viewer to check for unexpected applocker denies. [EventId's][3] ## Usage -Include usage examples for common use cases in the **Usage** section. Show your -users how to use your module to solve problems, and be sure to include code -examples. Include three to five examples of the most important or common tasks a -user can accomplish with your module. Show users how to accomplish more complex -tasks that involve different types, classes, and functions working in tandem. +Include applocker module in Puppet manifest. +``` +include applocker +``` -## Reference +**Note:** If generating a hash for an executable, you cannot use a standard SHA256 filehash. Microsoft uses [Authenticode][4] hash. Generate one by running in powershell. +``` +Get-AppLockerFileInformation .\putty.exe | Format-wide -Property hash -AutoSize +``` +This will print the hash which should look as follows. `0x7537EBDECCA5F65EA98216C23E9441B72269A546B3234F6CF4069C60269FE18F` -This section is deprecated. Instead, add reference information to your code as -Puppet Strings comments, and then use Strings to generate a REFERENCE.md in your -module. For details on how to add code comments and generate documentation with -Strings, see the [Puppet Strings documentation][2] and [style guide][3]. +Set applocker rules using hiera data as follows. Customise as required for your environment. -If you aren't ready to use Strings yet, manually create a REFERENCE.md in the -root of your module directory and list out each of your module's classes, -defined types, facts, functions, Puppet tasks, task plans, and resource types -and providers, along with the parameters for each. +### Exec applocker rules - Example +``` +applocker::exec_applocker_rules: + Exec %windir/%: + ensure: "present" # No longer required. Can leave option in for backwards support + action: "Allow" + conditions: + path: "%WINDIR%\\*" + exceptions: + - '%System32%\Microsoft\Crypto\RSA\MachineKeys\*' + - '%SYSTEM32%\spool\drivers\color\*' + - '%SYSTEM32%\Tasks\*' + - '%WINDIR%\Tasks\*' + - '%WINDIR%\Temp\*' + description: "Allow all users to run apps in windir" + rule_type: "path" + type: "Exe" # Not required, we know its a exe rule. Can leave option in for backwards support + user_or_group_sid: "S-1-1-0" + Exec %%PROGRAMFILES/%: + action: "Allow" + conditions: + path: "%PROGRAMFILES%\\*" + description: "Allow all users to run apps in programfiles" + rule_type: "path" + type: "Exe" + user_or_group_sid: "S-1-1-0" + Exec %OSDRIVE/CHOCO/%: + action: "Allow" + conditions: + path: "%OSDRIVE%\\CHOCO\\*" + description: "Allow all users to run apps in osdrive choco" + rule_type: "path" + type: "Exe" + user_or_group_sid: "S-1-1-0" + Exec %OSDRIVE/temp/%: + action: "Allow" + conditions: + path: "%OSDRIVE%\\temp\\doge\\*" + description: "Allow all users to run apps in osdrive temp" + rule_type: "path" + type: "Exe" + user_or_group_sid: "S-1-1-0" + Exec putty hash: + # ensure: "present" + action: "Allow" + conditions: + - type: "SHA256" + length: "1647912" + file_name: "putty.exe" + hash: "0x6E7F0B23165CDD134DA7E893DEE9422640287B02EAE3CE64AA1EE76AE9ED6512" + rule_type: "hash" + type: "Exe" + user_or_group_sid: "S-1-1-0" +``` -For each element (class, defined type, function, and so on), list: +### MSI applocker rules - Example +``` +applocker::msi_applocker_rules: + MSI rule MS corp: + ensure: "present" + action: "Allow" + conditions: + publisher: "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" + product: "*" + binaryname: "*" + hi_version: "*" + lo_version: "*" + description: "Allow Package app rule Microsoft corporation" + rule_type: "publisher" + type: "Msi" + user_or_group_sid: "S-1-1-0" + MSI rule MS corp windows: + ensure: "present" + action: "Allow" + conditions: + publisher: "CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" + product: "*" + binaryname: "*" + hi_version: "*" + lo_version: "*" + description: "Allow Package app rule Microsoft corporation (Windows)" + rule_type: "publisher" + type: "Msi" + user_or_group_sid: "S-1-1-0" +``` -* The data type, if applicable. -* A description of what the element does. -* Valid values, if the data type doesn't make it obvious. -* Default value, if any. +### Packaged applocker rules - Example +``` +applocker::appx_applocker_rules: + Packaged app MS corp: + ensure: "present" + action: "Allow" + conditions: + publisher: "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" + product: "*" + binaryname: "*" + hi_version: "*" + lo_version: "*" + description: "Allow Package app rule Microsoft corporation" + exceptions: + - publisher: "CN=Louis, O=Robertson, C=AU" + product: "*" + binaryname: "*" + lo_version: "*" + hi_version: "3.0.0.0" # Note this needs to be in format x.x.x.x + - publisher: "CN=doge, O=coin, C=AU" + product: "*" + binaryname: "*" + lo_version: "*" + hi_version: "*" + rule_type: "publisher" + type: "Appx" + user_or_group_sid: "S-1-1-0" + Packaged app MS corp windows: + ensure: "present" + action: "Allow" + conditions: + publisher: "CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" + product: "*" + binaryname: "*" + hi_version: "*" + lo_version: "*" + description: "Allow Package app rule Microsoft corporation (Windows)" + rule_type: "publisher" + type: "Appx" + user_or_group_sid: "S-1-1-0" +``` -For example: +### Script applocker rules - Example +``` +applocker::script_applocker_rules: + Script %WINDIR/%: + action: "Allow" + conditions: + path: "%WINDIR%\\*" + exceptions: + - '%SYSTEM32%\Com\dmp\*' + - '%SYSTEM32%\FxsTmp\*' + - '%System32%\Microsoft\Crypto\RSA\MachineKeys\*' + - '%SYSTEM32%\spool\drivers\color\*' + - '%SYSTEM32%\spool\PRINTERS\*' + - '%SYSTEM32%\spool\SERVERS\*' + - '%SYSTEM32%\Tasks\*' + - '%WINDIR%\Registration\CRMLog\*' + - '%WINDIR%\Tasks\*' + - '%WINDIR%\Temp\*' + - '%WINDIR%\tracing\*' + description: "Allow scripts in the windir directory" + rule_type: "path" + type: "Script" + user_or_group_sid: "S-1-1-0" + Script %PROGRAMFILES/%: + action: "Allow" + conditions: + path: "%PROGRAMFILES%\\*" + description: "Allow scripts in the programfiles directory" + rule_type: "path" + type: "Script" + user_or_group_sid: "S-1-1-0" + Script powershell hash: + action: "Allow" + description: "random test powershell script" + conditions: + - type: "SHA256" + length: "20" + file_name: "powerfulshell.ps1" + hash: "0x2057696D8662313670D36C3A3C8009FB038C8732C40C65275F158F63AAAD1629" + rule_type: "hash" + user_or_group_sid: "S-1-1-0" +``` +### DLL applocker rules - Example +``` +applocker::dll_applocker_rules: + DLL %PROGRAMFILES/%: + action: "Allow" + conditions: + path: "%PROGRAMFILES%\\*" + description: "Allow dll in the programfiles directory" + rule_type: "path" + type: "Dll" + user_or_group_sid: "S-1-1-0" + DLL %WINDIR/%: + action: "Allow" + conditions: + path: "%WINDIR%\\*" + exceptions: + - '%SYSTEM32%\spool\drivers\color\*' + - '%SYSTEM32%\Tasks\*' + - '%WINDIR%\Tasks\*' + - '%WINDIR%\Temp\' + - '%System32%\Microsoft\Crypto\RSA\MachineKeys\*' + description: "Allow dll in the programfiles directory" + rule_type: "path" + type: "Dll" + user_or_group_sid: "S-1-1-0" ``` -### `pet::cat` -#### Parameters +### Enabling applocker rules -##### `meow` +Applocker rules can be enabled or disabled by setting Enum['Enabled','AuditOnly'] for the following parameters. -Enables vocalization in your cat. Valid options: 'string'. +* executable_rules +* msi_rules +* dll_rules +* script_rules +* packaged_app_rules -Default: 'medium-loud'. -``` ## Limitations -In the Limitations section, list any incompatibilities, known issues, or other -warnings. +* Developed on Puppet Enterprise 2021.7.6 and Windows 2019 +* Expected to work with all modern versions of Puppet and Windows. ## Development -In the Development section, tell other users the ground rules for contributing -to your project and how they should submit their work. +If you find any issues with this module, please log them in the issues register of the GitHub project. [Issues][1] -## Release Notes/Contributors/Etc. **Optional** +Module was developed with PDK. Unit tests only pass on Windows system. eg `pdk test unit`. -If you aren't using changelog, put your release notes here (though you should -consider using changelog). You can also add any additional sections you feel are -necessary or important to include here. Please use the `##` header. +PR glady accepted :) -[1]: https://puppet.com/docs/pdk/latest/pdk_generating_modules.html -[2]: https://puppet.com/docs/puppet/latest/puppet_strings.html -[3]: https://puppet.com/docs/puppet/latest/puppet_strings_style.html +[1]: https://github.com/benjamin-robertson/applocker/issues +[2]: https://learn.microsoft.com/en-us/windows/security/application-security/application-control/windows-defender-application-control/applocker/what-is-applocker +[3]: https://learn.microsoft.com/en-us/windows/security/application-security/application-control/windows-defender-application-control/applocker/using-event-viewer-with-applocker#review-the-applocker-logs-in-windows-event-viewer +[4]: https://learn.microsoft.com/en-us/windows-hardware/drivers/install/authenticode \ No newline at end of file diff --git a/REFERENCE.md b/REFERENCE.md new file mode 100644 index 0000000..270ffe2 --- /dev/null +++ b/REFERENCE.md @@ -0,0 +1,255 @@ +# Reference + + + +## Table of Contents + +### Classes + +* [`applocker`](#applocker): Set applocker rules for windows +* [`applocker::service`](#applockerservice): Starts applocker service + +### Functions + +* [`applocker::compare_rules`](#applockercompare_rules): Compares Windows applocker rules. +* [`applocker::extract_rules`](#applockerextract_rules): Extract applocker rules +* [`applocker::get_id`](#applockerget_id): Get ID of existing applocker rules. If no existing rule by that name, a new hash is generated. +* [`applocker::hash_toxml`](#applockerhash_toxml): Convert hash to xml +* [`applocker::xml_tohash`](#applockerxml_tohash): XML to hash + +## Classes + +### `applocker` + +Configures applocker rules for windows. See readme on how to structure applocker rules. + +lint:ignore:140chars + +#### Examples + +##### + +```puppet +include applocker +``` + +#### Parameters + +The following parameters are available in the `applocker` class: + +* [`exec_applocker_rules`](#exec_applocker_rules) +* [`msi_applocker_rules`](#msi_applocker_rules) +* [`appx_applocker_rules`](#appx_applocker_rules) +* [`script_applocker_rules`](#script_applocker_rules) +* [`dll_applocker_rules`](#dll_applocker_rules) +* [`executable_rules`](#executable_rules) +* [`msi_rules`](#msi_rules) +* [`dll_rules`](#dll_rules) +* [`script_rules`](#script_rules) +* [`packaged_app_rules`](#packaged_app_rules) +* [`start_service`](#start_service) + +##### `exec_applocker_rules` + +Data type: `Hash` + +Exec applocker rules to configure. + +Default value: `{}` + +##### `msi_applocker_rules` + +Data type: `Hash` + +msi applocker rules to configure. + +Default value: `{}` + +##### `appx_applocker_rules` + +Data type: `Hash` + +Packaged app rules to configure. + +Default value: `{}` + +##### `script_applocker_rules` + +Data type: `Hash` + +scipt applocker rules to configure. + +Default value: `{}` + +##### `dll_applocker_rules` + +Data type: `Hash` + +dll applocker rules to configure. + +Default value: `{}` + +##### `executable_rules` + +Data type: `Enum['Enabled','AuditOnly']` + +Mode for executable rules, Enum['Enabled','AuditOnly'] Default: AuditOnly. + +Default value: `'AuditOnly'` + +##### `msi_rules` + +Data type: `Enum['Enabled','AuditOnly']` + +Mode for msi rules, Enum['Enabled','AuditOnly'] Default: AuditOnly. + +Default value: `'AuditOnly'` + +##### `dll_rules` + +Data type: `Enum['Enabled','AuditOnly']` + +Mode for dll rules, Enum['Enabled','AuditOnly'] Default: AuditOnly. + +Default value: `'AuditOnly'` + +##### `script_rules` + +Data type: `Enum['Enabled','AuditOnly']` + +Mode for script rules, Enum['Enabled','AuditOnly'] Default: AuditOnly. + +Default value: `'AuditOnly'` + +##### `packaged_app_rules` + +Data type: `Enum['Enabled','AuditOnly']` + +Mode for packaged app rules, Enum['Enabled','AuditOnly'] Default: AuditOnly. + +Default value: `'AuditOnly'` + +##### `start_service` + +Data type: `Boolean` + +Whether to start the applocker service. Default: true + +Default value: ``true`` + +### `applocker::service` + +Starts applocker service + +#### Examples + +##### + +```puppet +private class +``` + +## Functions + +### `applocker::compare_rules` + +Type: Ruby 4.x API + +Compares Windows applocker rules. + +#### `applocker::compare_rules(Hash $rules, Hash $desired_rules)` + +Compares Windows applocker rules. + +Returns: `Hash` Returns true if match, if no match, false along with which rule failed to match. + +##### `rules` + +Data type: `Hash` + +Existing rules from a host + +##### `desired_rules` + +Data type: `Hash` + +Desired applocker rules from Puppet manifest. + +### `applocker::extract_rules` + +Type: Ruby 4.x API + +Extract applocker rules + +#### `applocker::extract_rules(Hash $rules)` + +Extract applocker rules + +Returns: `Hash` Hash of all applocker rules in policy along with the rule hash. + +##### `rules` + +Data type: `Hash` + +Applocker rules to extract + +### `applocker::get_id` + +Type: Ruby 4.x API + +Get ID of existing applocker rules. If no existing rule by that name, a new hash is generated. + +#### `applocker::get_id(Hash $applocker_rules, Hash $name_to_id)` + +Get ID of existing applocker rules. If no existing rule by that name, a new hash is generated. + +Returns: `Hash` Hash with rulename to rule mapping. + +##### `applocker_rules` + +Data type: `Hash` + +Applocker rules to check from Puppet catalog + +##### `name_to_id` + +Data type: `Hash` + +Name to ID mapping to check. + +### `applocker::hash_toxml` + +Type: Ruby 4.x API + +Convert hash to xml + +#### `applocker::hash_toxml(Hash $hash_val)` + +Convert hash to xml + +Returns: `String` XML string + +##### `hash_val` + +Data type: `Hash` + +Hash to convert to XML + +### `applocker::xml_tohash` + +Type: Ruby 4.x API + +XML to hash + +#### `applocker::xml_tohash(String $xml_content)` + +XML to hash + +Returns: `Hash` Hash converted from XML + +##### `xml_content` + +Data type: `String` + +XML to convert to hash + diff --git a/Rakefile b/Rakefile index 0f8754e..74415a9 100644 --- a/Rakefile +++ b/Rakefile @@ -1,12 +1,11 @@ # frozen_string_literal: true require 'bundler' -require 'puppet_litmus/rake_tasks' if Bundler.rubygems.find_name('puppet_litmus').any? +require 'puppet_litmus/rake_tasks' if Gem.loaded_specs.key? 'puppet_litmus' require 'puppetlabs_spec_helper/rake_tasks' require 'puppet-syntax/tasks/puppet-syntax' -require 'puppet_blacksmith/rake_tasks' if Bundler.rubygems.find_name('puppet-blacksmith').any? -require 'github_changelog_generator/task' if Bundler.rubygems.find_name('github_changelog_generator').any? -require 'puppet-strings/tasks' if Bundler.rubygems.find_name('puppet-strings').any? +require 'github_changelog_generator/task' if Gem.loaded_specs.key? 'github_changelog_generator' +require 'puppet-strings/tasks' if Gem.loaded_specs.key? 'puppet-strings' def changelog_user return unless Rake.application.top_level_tasks.include? "changelog" @@ -44,7 +43,7 @@ end PuppetLint.configuration.send('disable_relative') -if Bundler.rubygems.find_name('github_changelog_generator').any? +if Gem.loaded_specs.key? 'github_changelog_generator' GitHubChangelogGenerator::RakeTask.new :changelog do |config| raise "Set CHANGELOG_GITHUB_TOKEN environment variable eg 'export CHANGELOG_GITHUB_TOKEN=valid_token_here'" if Rake.application.top_level_tasks.include? "changelog" and ENV['CHANGELOG_GITHUB_TOKEN'].nil? config.user = "#{changelog_user}" diff --git a/data/common.yaml b/data/common.yaml index f7e8dc0..ed97d53 100644 --- a/data/common.yaml +++ b/data/common.yaml @@ -1,153 +1 @@ --- -applocker::exec_applocker_rules: - Exec %windir/%: - ensure: "present" # No longer required. We can leave option in for backwards support - action: "Allow" - conditions: - path: "%WINDIR%\\*" - exceptions: - - '%System32%\Microsoft\Crypto\RSA\MachineKeys\*' - - '%SYSTEM32%\spool\drivers\color\*' - - '%SYSTEM32%\Tasks\*' - - '%WINDIR%\Tasks\*' - - '%WINDIR%\Temp\*' - description: "Allow all users to run apps in windir" - rule_type: "path" - type: "Exe" # Not required, we know its a exe rule. We can leave option in for backwards support - user_or_group_sid: "S-1-1-0" - Exec %%PROGRAMFILES/%: - ensure: "present" - action: "Allow" - conditions: - path: "%PROGRAMFILES%\\*" - description: "Allow all users to run apps in programfiles" - rule_type: "path" - type: "Exe" - user_or_group_sid: "S-1-1-0" - Exec %OSDRIVE/CHOCO/%: - ensure: "present" - action: "Allow" - conditions: - path: "%OSDRIVE%\\CHOCO\\*" - description: "Allow all users to run apps in osdrive choco" - rule_type: "path" - type: "Exe" - user_or_group_sid: "S-1-1-0" - - -applocker::script_applocker_rules: - Script %WINDIR/%: - ensure: "present" - action: "Allow" - conditions: - path: "%WINDIR%\\*" - exceptions: - - '%SYSTEM32%\Com\dmp\*' - - '%SYSTEM32%\FxsTmp\*' - - '%System32%\Microsoft\Crypto\RSA\MachineKeys\*' - - '%SYSTEM32%\spool\drivers\color\*' - - '%SYSTEM32%\spool\PRINTERS\*' - - '%SYSTEM32%\spool\SERVERS\*' - - '%SYSTEM32%\Tasks\*' - - '%WINDIR%\Registration\CRMLog\*' - - '%WINDIR%\Tasks\*' - - '%WINDIR%\Temp\*' - - '%WINDIR%\tracing\*' - description: "Allow scripts in the windir directory" - rule_type: "path" - type: "Script" - user_or_group_sid: "S-1-1-0" - Script %PROGRAMFILES/%: - ensure: "present" - action: "Allow" - conditions: - path: "%PROGRAMFILES%\\*" - description: "Allow scripts in the programfiles directory" - rule_type: "path" - type: "Script" - user_or_group_sid: "S-1-1-0" - - -applocker::dll_applocker_rules: - DLL %PROGRAMFILES/%: - ensure: "present" - action: "Allow" - conditions: - path: "%PROGRAMFILES%\\*" - description: "Allow dll in the programfiles directory" - rule_type: "path" - type: "Dll" - user_or_group_sid: "S-1-1-0" - DLL %WINDIR/%: - ensure: "present" - action: "Allow" - conditions: - path: "%WINDIR%\\*" - exceptions: - - '%SYSTEM32%\spool\drivers\color\*' - - '%SYSTEM32%\Tasks\*' - - '%WINDIR%\Tasks\*' - - '%WINDIR%\Temp\' - - '%System32%\Microsoft\Crypto\RSA\MachineKeys\*' - description: "Allow dll in the programfiles directory" - rule_type: "path" - type: "Dll" - user_or_group_sid: "S-1-1-0" - - -applocker::appx_applocker_rules: - Packaged app MS corp: - ensure: "present" - action: "Allow" - conditions: - publisher: "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" - product: "*" - binaryname: "*" - hi_version: "*" - lo_version: "*" - description: "Allow Package app rule Microsoft corporation" - rule_type: "publisher" - type: "Appx" - user_or_group_sid: "S-1-1-0" - Packaged app MS corp windows: - ensure: "present" - action: "Allow" - conditions: - publisher: "CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" - product: "*" - binaryname: "*" - hi_version: "*" - lo_version: "*" - description: "Allow Package app rule Microsoft corporation (Windows)" - rule_type: "publisher" - type: "Appx" - user_or_group_sid: "S-1-1-0" - - -applocker::msi_applocker_rules: - MSI rule MS corp: - ensure: "present" - action: "Allow" - conditions: - publisher: "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" - product: "*" - binaryname: "*" - hi_version: "*" - lo_version: "*" - description: "Allow Package app rule Microsoft corporation" - rule_type: "publisher" - type: "Msi" - user_or_group_sid: "S-1-1-0" - MSI rule MS corp windows: - ensure: "present" - action: "Allow" - conditions: - publisher: "CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" - product: "*" - binaryname: "*" - hi_version: "*" - lo_version: "*" - description: "Allow Package app rule Microsoft corporation (Windows)" - rule_type: "publisher" - type: "Msi" - user_or_group_sid: "S-1-1-0" \ No newline at end of file diff --git a/lib/facter/applocker_rules.rb b/lib/facter/applocker_rules.rb index 1119e92..26088f4 100644 --- a/lib/facter/applocker_rules.rb +++ b/lib/facter/applocker_rules.rb @@ -1,10 +1,12 @@ # frozen_string_literal: true +require 'open3' + Facter.add(:applocker_rules) do confine kernel: 'windows' setcode do powershell = 'C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe' command = 'Get-ApplockerPolicy -Effective -xml' - Facter::Util::Resolution.exec(%(#{powershell} -command "#{command})) + Facter::Core::Execution.execute(%(#{powershell} -command "#{command}")) end end diff --git a/lib/puppet/functions/applocker/compare_rules.rb b/lib/puppet/functions/applocker/compare_rules.rb new file mode 100644 index 0000000..3f9b73e --- /dev/null +++ b/lib/puppet/functions/applocker/compare_rules.rb @@ -0,0 +1,185 @@ +# frozen_string_literal: true + +# Compares Windows applocker rules. +Puppet::Functions.create_function(:"applocker::compare_rules") do + # @param rules Existing rules from a host + # @param desired_rules Desired applocker rules from Puppet manifest. + # @return [Hash] Returns true if match, if no match, false along with which rule failed to match. + dispatch :compare_rules do + param 'Hash', :rules + param 'Hash', :desired_rules + return_type 'Hash' + end + # the function below is called by puppet and and must match + # the name of the puppet function above. You can set your + # required parameters below and puppet will enforce these + # so change x to suit your needs although only one parameter is required + # as defined in the dispatch method. + def compare_rules(rules, desired_rules) + rule_collection = rules['RuleCollection'] + desired_collection = desired_rules['RuleCollection'] + + unless rules['RuleCollection'] && desired_rules['RuleCollection'] + # confirm both rules are not empty + if rule_collection == desired_collection + return { 'Result' => true } + end + # no rules found in one of the hashes + return { 'Result' => false } + end + + # Check appx rules + appx_a = get_rule_section('Appx', rule_collection) + appx_b = get_rule_section('Appx', desired_collection) + appx_result = rule_comparison(appx_a, appx_b) + + if appx_result == false + return { 'Result' => false, + 'failing_rule' => 'Appx' } + end + + # Check Dll rules + dll_a = get_rule_section('Dll', rule_collection) + dll_b = get_rule_section('Dll', desired_collection) + dll_result = rule_comparison(dll_a, dll_b) + + if dll_result == false + return { 'Result' => false, + 'failing_rule' => 'Dll' } + end + + # Check Exe rules + exe_a = get_rule_section('Exe', rule_collection) + exe_b = get_rule_section('Exe', desired_collection) + exe_result = rule_comparison(exe_a, exe_b) + + if exe_result == false + return { 'Result' => false, + 'failing_rule' => 'Exe' } + end + + # Check Msi rules + msi_a = get_rule_section('Msi', rule_collection) + msi_b = get_rule_section('Msi', desired_collection) + msi_result = rule_comparison(msi_a, msi_b) + + if msi_result == false + return { 'Result' => false, + 'failing_rule' => 'Msi' } + end + + # Check Script rules + script_a = get_rule_section('Script', rule_collection) + script_b = get_rule_section('Script', desired_collection) + script_result = rule_comparison(script_a, script_b) + + if script_result == false + return { 'Result' => false, + 'failing_rule' => 'Script' } + end + + { 'Result' => true } + end + + def get_rule_section(type, rules) + rules.each do |element| + if element['Type'] == type + return element + end + end + {} # we did not match anything return empty string + rescue + { 'EnforcementMode' => 'no_match' } + end + + def rule_comparison(rule1, rule2) + matched = false + + # confirm we are not checking the same hash + if rule1.hash == rule2.hash + return true + end + + # check enforcement mode + begin + if rule1['EnforcementMode'] != rule2['EnforcementMode'] + return false + end + rescue + return false + end + + # check FilePublisherRule + if rule1.key?('FilePublisherRule') || rule2.key?('FilePublisherRule') + begin + if rule1['FilePublisherRule'].length != rule2['FilePublisherRule'].length + return false + end + rule1['FilePublisherRule'].each do |element| + rule2['FilePublisherRule'].each do |element2| + if element == element2 + matched = true + end + end + # confirm each rule matched + if matched == false + return false + end + matched = false + end + rescue + return false + end + end + + # check FilePathRule + if rule1.key?('FilePathRule') || rule2.key?('FilePathRule') + begin + if rule1['FilePathRule'].length != rule2['FilePathRule'].length + return false + end + rule1['FilePathRule'].each do |element| + rule2['FilePathRule'].each do |element2| + if element == element2 + matched = true + end + end + # confirm each rule matched + if matched == false + return false + end + matched = false + end + rescue + return false + end + end + + # check FileHashRule. + if rule1.key?('FileHashRule') || rule2.key?('FileHashRule') + begin + if rule1['FileHashRule'].length != rule2['FileHashRule'].length + return false + end + rule1['FileHashRule'].each do |element| + rule2['FileHashRule'].each do |element2| + if element == element2 + matched = true + end + end + # confirm each rule matched + if matched == false + return false + end + matched = false + end + rescue + return false + end + end + # Check if there was a match + true + end + + # you can define other helper methods in this code block as well +end diff --git a/lib/puppet/functions/applocker/extract_rules.rb b/lib/puppet/functions/applocker/extract_rules.rb index f559cfe..2902d52 100644 --- a/lib/puppet/functions/applocker/extract_rules.rb +++ b/lib/puppet/functions/applocker/extract_rules.rb @@ -1,7 +1,9 @@ # frozen_string_literal: true -# https://github.com/puppetlabs/puppet-specifications/blob/master/language/func-api.md#the-4x-api +# Extract applocker rules Puppet::Functions.create_function(:"applocker::extract_rules") do + # @param rules Applocker rules to extract + # @return [Hash] Hash of all applocker rules in policy along with the rule hash. dispatch :extract_rules do param 'Hash', :rules return_type 'Hash' @@ -29,6 +31,11 @@ def extract_rules(rules) } name_to_id = {} + # check rules exist + unless rules['RuleCollection'] + return {} + end + # Loop through Rules and populate hash values rules['RuleCollection'].each do |array| rule_status[array['Type']] = array['EnforcementMode'] @@ -46,7 +53,13 @@ def extract_rules(rules) name_to_id[value['Name']] = value['Id'] end end - # need to code in filehash rule. But need to get this working first. + if array['FileHashRule'] + array['FileHashRule'].each do |value| + hash_tmp = { 'name' => value['Name'], 'id' => value['Id'] } + rule_hash[array['Type']].push(hash_tmp) + name_to_id[value['Name']] = value['Id'] + end + end end return_hash = { 'rule_status' => rule_status, 'rule_hash' => rule_hash, 'name_to_id' => name_to_id } return_hash diff --git a/lib/puppet/functions/applocker/get_id.rb b/lib/puppet/functions/applocker/get_id.rb index c968d7a..cb2a466 100644 --- a/lib/puppet/functions/applocker/get_id.rb +++ b/lib/puppet/functions/applocker/get_id.rb @@ -2,8 +2,11 @@ require 'securerandom' -# https://github.com/puppetlabs/puppet-specifications/blob/master/language/func-api.md#the-4x-api +# Get ID of existing applocker rules. If no existing rule by that name, a new hash is generated. Puppet::Functions.create_function(:"applocker::get_id") do + # @param applocker_rules Applocker rules to check from Puppet catalog + # @param name_to_id Name to ID mapping to check. + # @return [Hash] Hash with rulename to rule mapping. dispatch :get_id do param 'Hash', :applocker_rules param 'Hash', :name_to_id @@ -15,7 +18,7 @@ # so change x to suit your needs although only one parameter is required # as defined in the dispatch method. def get_id(applocker_rules, name_to_id) - applocker_with_id = applocker_rules.dup() + applocker_with_id = applocker_rules.dup applocker_rules.each do |key, _value| # Check if the id is already defined. if name_to_id.key?(key) diff --git a/lib/puppet/functions/applocker/hash_toxml.rb b/lib/puppet/functions/applocker/hash_toxml.rb index ebffced..1fd0e8a 100644 --- a/lib/puppet/functions/applocker/hash_toxml.rb +++ b/lib/puppet/functions/applocker/hash_toxml.rb @@ -2,8 +2,10 @@ require 'xmlsimple' -# https://github.com/puppetlabs/puppet-specifications/blob/master/language/func-api.md#the-4x-api +# Convert hash to xml Puppet::Functions.create_function(:"applocker::hash_toxml") do + # @param hash_val Hash to convert to XML + # @return [String] XML string dispatch :hash_toxml do param 'Hash', :hash_val return_type 'String' diff --git a/lib/puppet/functions/applocker/xml_tohash.rb b/lib/puppet/functions/applocker/xml_tohash.rb index 9631187..6e076d1 100644 --- a/lib/puppet/functions/applocker/xml_tohash.rb +++ b/lib/puppet/functions/applocker/xml_tohash.rb @@ -2,8 +2,10 @@ require 'xmlsimple' -# https://github.com/puppetlabs/puppet-specifications/blob/master/language/func-api.md#the-4x-api +# XML to hash Puppet::Functions.create_function(:"applocker::xml_tohash") do + # @param xml_content XML to convert to hash + # @return [Hash] Hash converted from XML dispatch :xml_tohash do param 'String', :xml_content return_type 'Hash' diff --git a/manifests/init.pp b/manifests/init.pp index aa98e01..061349b 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -1,10 +1,21 @@ -# @summary A short summary of the purpose of this class +# @summary Set applocker rules for windows # -# A description of what this class does +# Configures applocker rules for windows. See readme on how to structure applocker rules. # # lint:ignore:140chars +# @param exec_applocker_rules Exec applocker rules to configure. +# @param msi_applocker_rules msi applocker rules to configure. +# @param appx_applocker_rules Packaged app rules to configure. +# @param script_applocker_rules scipt applocker rules to configure. +# @param dll_applocker_rules dll applocker rules to configure. +# @param executable_rules Mode for executable rules, Enum['Enabled','AuditOnly'] Default: AuditOnly. +# @param msi_rules Mode for msi rules, Enum['Enabled','AuditOnly'] Default: AuditOnly. +# @param dll_rules Mode for dll rules, Enum['Enabled','AuditOnly'] Default: AuditOnly. +# @param script_rules Mode for script rules, Enum['Enabled','AuditOnly'] Default: AuditOnly. +# @param packaged_app_rules Mode for packaged app rules, Enum['Enabled','AuditOnly'] Default: AuditOnly. +# @param start_service Whether to start the applocker service. Default: true # @example -# include applocker +# include applocker class applocker ( Hash $exec_applocker_rules = {}, Hash $msi_applocker_rules = {}, @@ -16,50 +27,88 @@ Enum['Enabled','AuditOnly'] $dll_rules = 'AuditOnly', Enum['Enabled','AuditOnly'] $script_rules = 'AuditOnly', Enum['Enabled','AuditOnly'] $packaged_app_rules = 'AuditOnly', - Boolean $purge_existing_rules = true, Boolean $start_service = true, ) { - #notify{"exec_applocker_rules lenght is ${exec_applocker_rules.length}":} - #notify{"Applocker rules are ${applocker::xml_tohash($facts['applocker_rules'])}":} $hash_policy = applocker::xml_tohash($facts['applocker_rules']) - #notify{"applocker hash type ${type($hash_policy)}":} - # file { 'policy from fact': - # ensure => present, - # path => 'c:\temp\applocker_from_fact.xml', - # content => applocker::hash_toxml($hash_policy), - # } # Break down structure using function, We want to retrieve all the names of each rules type and return $rule_results = applocker::extract_rules($hash_policy) - #notify{"rule results ${rule_results}":} + + # Check if we have any rules set + $rule_results_final = $rule_results.dig('name_to_id') ? { + undef => {}, + default => $rule_results['name_to_id'], + } # Generate id for each rule, or get from existing rule. - $exec_applocker_rules_with_id = applocker::get_id($exec_applocker_rules, $rule_results['name_to_id']) - $msi_applocker_rules_with_id = applocker::get_id($msi_applocker_rules, $rule_results['name_to_id']) - $appx_applocker_rules_with_id = applocker::get_id($appx_applocker_rules, $rule_results['name_to_id']) - $script_applocker_rules_with_id = applocker::get_id($script_applocker_rules, $rule_results['name_to_id']) - $dll_applocker_rules_with_id = applocker::get_id($dll_applocker_rules, $rule_results['name_to_id']) - notify{"exec with id ${$exec_applocker_rules_with_id}":} - notify{"msi with id ${$msi_applocker_rules_with_id}":} - notify{"appx with id ${$appx_applocker_rules_with_id}":} - notify{"script with id ${$script_applocker_rules_with_id}":} - notify{"dll with id ${$dll_applocker_rules_with_id}":} + $exec_applocker_rules_with_id = applocker::get_id($exec_applocker_rules, $rule_results_final) + $msi_applocker_rules_with_id = applocker::get_id($msi_applocker_rules, $rule_results_final) + $appx_applocker_rules_with_id = applocker::get_id($appx_applocker_rules, $rule_results_final) + $script_applocker_rules_with_id = applocker::get_id($script_applocker_rules, $rule_results_final) + $dll_applocker_rules_with_id = applocker::get_id($dll_applocker_rules, $rule_results_final) # create xml file file { 'policy file': - ensure => present, - path => 'c:\temp\applocker_puppet.xml', + ensure => file, + path => 'c:\\windows\\\applocker_puppet_policy.xml', content => epp('applocker/xmlrule.epp', { - 'exec_applocker_rules' => $exec_applocker_rules_with_id, - 'msi_applocker_rules' => $msi_applocker_rules_with_id, - 'appx_applocker_rules' => $appx_applocker_rules_with_id, - 'script_applocker_rules' => $script_applocker_rules_with_id, - 'dll_applocker_rules' => $dll_applocker_rules_with_id, - 'executable_rules' => $executable_rules, - 'msi_rules' => $msi_rules, - 'dll_rules' => $dll_rules, - 'script_rules' => $script_rules, - 'packaged_app_rules' => $packaged_app_rules,}), + 'exec_applocker_rules' => $exec_applocker_rules_with_id, + 'msi_applocker_rules' => $msi_applocker_rules_with_id, + 'appx_applocker_rules' => $appx_applocker_rules_with_id, + 'script_applocker_rules' => $script_applocker_rules_with_id, + 'dll_applocker_rules' => $dll_applocker_rules_with_id, + 'executable_rules' => $executable_rules, + 'msi_rules' => $msi_rules, + 'dll_rules' => $dll_rules, + 'script_rules' => $script_rules, + 'packaged_app_rules' => $packaged_app_rules, }), + } + # check length of rules. If all rules are empty use default empty rule string + if $exec_applocker_rules.length == 0 and $msi_applocker_rules.length == 0 and $appx_applocker_rules.length == 0 and $script_applocker_rules.length == 0 and $dll_applocker_rules.length == 0 { + $proposed_rules = applocker::xml_tohash('') + } else { + $proposed_rules = applocker::xml_tohash(epp('applocker/xmlrule.epp', { + 'exec_applocker_rules' => $exec_applocker_rules_with_id, + 'msi_applocker_rules' => $msi_applocker_rules_with_id, + 'appx_applocker_rules' => $appx_applocker_rules_with_id, + 'script_applocker_rules' => $script_applocker_rules_with_id, + 'dll_applocker_rules' => $dll_applocker_rules_with_id, + 'executable_rules' => $executable_rules, + 'msi_rules' => $msi_rules, + 'dll_rules' => $dll_rules, + 'script_rules' => $script_rules, + 'packaged_app_rules' => $packaged_app_rules, })) + } + + # Verify applocker policy defined by user is valid. + exec { 'Verify applocker policy failed': + path => 'C:/Windows/System32/WindowsPowerShell/v1.0', + command => 'powershell Test-AppLockerPolicy -XmlPolicy c:\\windows\\applocker_puppet_policy.xml -path C:\\windows\\notepad.exe', + unless => 'powershell Test-AppLockerPolicy -XmlPolicy c:\\windows\\applocker_puppet_policy.xml -path C:\\windows\\notepad.exe', + require => File['policy file'], + } + + $rule_check_results = applocker::compare_rules($hash_policy, $proposed_rules) + if $rule_check_results['Result'] == false { + notify { "Rules don\'t match. Results ${rule_check_results}": } + exec { 'Update applocker rules': + path => 'C:/Windows/System32/WindowsPowerShell/v1.0', + command => 'powershell Set-AppLockerPolicy -XMLPolicy c:\\windows\\applocker_puppet_policy.xml', + onlyif => 'powershell Test-AppLockerPolicy -XmlPolicy c:\\windows\\applocker_puppet_policy.xml -path C:\\windows\\notepad.exe', + require => File['policy file'], + } + } + + if $start_service { + include applocker::service + } + + file { 'c:\temp': + ensure => directory, + } + + file { 'c:\temp\policies': + ensure => directory, } } # lint:endignore diff --git a/manifests/service.pp b/manifests/service.pp new file mode 100644 index 0000000..821de75 --- /dev/null +++ b/manifests/service.pp @@ -0,0 +1,13 @@ +# @summary +# +# Starts applocker service +# +# @example +# private class +class applocker::service { + service { 'application identity service': + ensure => running, + name => 'AppIDSvc', + enable => true, + } +} diff --git a/metadata.json b/metadata.json index 8f2666d..932fee2 100644 --- a/metadata.json +++ b/metadata.json @@ -2,17 +2,24 @@ "name": "benjaminrobertson-applocker", "version": "0.1.0", "author": "benjaminrobertson", - "summary": "", + "summary": "Configured applocker (Applications whitelisting) for Windows", "license": "Apache-2.0", - "source": "", + "source": "https://github.com/benjamin-robertson/applocker", + "project_page": "https://github.com/benjamin-robertson/applocker", + "issues_url": "https://github.com/benjamin-robertson/applocker/issues", "dependencies": [ - + { + "name": "puppetlabs/stdlib", + "version_requirement": ">= 6.0.0 < 10.0.0" + } ], "operatingsystem_support": [ { "operatingsystem": "windows", "operatingsystemrelease": [ + "2016", "2019", + "2022", "10" ] } @@ -20,10 +27,10 @@ "requirements": [ { "name": "puppet", - "version_requirement": ">= 6.21.0 < 8.0.0" + "version_requirement": ">= 6.21.0 < 9.0.0" } ], - "pdk-version": "2.4.0", - "template-url": "pdk-default#2.4.0", - "template-ref": "tags/2.4.0-0-gfa6b6d2" + "pdk-version": "3.0.0", + "template-url": "pdk-default#3.0.0", + "template-ref": "tags/3.0.0-0-g056e50d" } diff --git a/spec/classes/applocker_spec.rb b/spec/classes/applocker_spec.rb index f7d3152..7fa6264 100644 --- a/spec/classes/applocker_spec.rb +++ b/spec/classes/applocker_spec.rb @@ -7,7 +7,13 @@ context "on #{os}" do let(:facts) { os_facts } - it { is_expected.to compile } + context 'with applocker fact' do + let(:facts) do + super().merge({ 'applocker_rules' => '' }) + end + + it { is_expected.to compile } + end end end end diff --git a/spec/functions/compare_rules_spec.rb b/spec/functions/compare_rules_spec.rb new file mode 100644 index 0000000..e52cc34 --- /dev/null +++ b/spec/functions/compare_rules_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'applocker::compare_rules' do + # please note that these tests are examples only + # you will need to replace the params and return value + # with your expectations + it { is_expected.to run.with_params({'Version' => '1', 'RuleCollection' => [{'Type' => 'Appx', 'EnforcementMode' => 'AuditOnly', 'FilePublisherRule' => [{'Id' => '3ae31537-34e8-c52c-0363-df50388fea30', 'Name' => 'Packaged app MS corp windows', 'Description' => 'Allow Package app rule Microsoft corporation (Windows)', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington', 'C=US, ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}, {'Id' => 'cc1cc505-ce9a-6dd7-4d73-9d0204f9735d', 'Name' => 'Packaged app MS corp', 'Description' => 'Allow Package app rule Microsoft corporation', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}], 'Exceptions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Louis, O=Poodle, C=AU', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '3.0.0.0'}]}, {'PublisherName' => 'CN=doge, O=coin, C=AU', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}]}, {'Type' => 'Dll', 'EnforcementMode' => 'AuditOnly', 'FilePathRule' => [{'Id' => '81baaabe-4266-ffd4-ca79-6c66a2ea3e98', 'Name' => 'DLL %WINDIR/%', 'Description' => 'Allow dll in the programfiles directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%WINDIR%\*}]}]', 'Exceptions' => [{'FilePathCondition' => [{'Path' => '%SYSTEM32%\spool\drivers\color\*'}, {'Path' => '%SYSTEM32%\Tasks\*'}, {'Path' => '%WINDIR%\Tasks\*'}, {'Path' => '%WINDIR%\Temp\\'}, {'Path' => '%System32%\Microsoft\Crypto\RSA\MachineKeys\*'}]}]}, {'Id' => 'f9efadbf-0255-9e65-dbcf-11fcd8cb27d4', 'Name' => 'DLL %PROGRAMFILES/%', 'Description' => 'Allow dll in the programfiles directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%PROGRAMFILES%\*'}]}]}]}]}]}, {'Type' => 'Exe', 'EnforcementMode' => 'AuditOnly', 'FilePathRule' => [{'Id' => '93246af9-225e-01ab-a22b-2ea6defbac20', 'Name' => 'Exec %%PROGRAMFILES/%', 'Description' => 'Allow all users to run apps in programfiles', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%PROGRAMFILES%\*'}]}]}, {'Id' => 'a8cdb667-143d-127e-32a9-b9e641c19f39', 'Name' => 'Exec %OSDRIVE/temp/%', 'Description' => 'Allow all users to run apps in osdrive temp', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%OSDRIVE%\temp\doge\*'}]}]}, {'Id' => 'd2b6b159-3d42-470c-4108-2a1d43be39cc', 'Name' => 'Exec %OSDRIVE/CHOCO/%', 'Description' => 'Allow all users to run apps in osdrive choco', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%OSDRIVE%\CHOCO\*'}]}]}, {'Id' => 'fd042c8a-c663-028d-8e61-7adf35f86da0', 'Name' => 'Exec %windir/%', 'Description' => 'Allow all users to run apps in windir', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%WINDIR%\*'}]}], 'Exceptions' => [{'FilePathCondition' => [{'Path' => '%System32%\Microsoft\Crypto\RSA\MachineKeys\*'}, {'Path' => '%SYSTEM32%\spool\drivers\color\*'}, {'Path' => '%SYSTEM32%\Tasks\*'}, {'Path' => '%WINDIR%\Tasks\*'}, {'Path' => '%WINDIR%\Temp\*'}]}]}]}, {'Type' => 'Msi', 'EnforcementMode' => 'AuditOnly', 'FilePublisherRule' => [{'Id' => '3088d67f-075c-4c08-c773-6bc75fd74381', 'Name' => 'MSI rule MS corp windows', 'Description' => 'Allow Package app rule Microsoft corporation (Windows)', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington, C=US', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}, {'Id' => 'd70f545d-8d7b-a801-6e4b-ce152ba570f2', 'Name' => 'MSI rule MS corp', 'Description' => 'Allow Package app rule Microsoft corporation', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}]}, {'Type' => 'Script', 'EnforcementMode' => 'Enabled', 'FilePathRule' => [{'Id' => '03dfa177-8b1a-6ef2-a6b2-07cbedc9a990', 'Name' => 'Script %PROGRAMFILES/%', 'Description' => 'Allow scripts in the programfiles directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%PROGRAMFILES%\*'}]}]}, {'Id' => '35ff3c00-3ede-6cba-13f4-c9de04a72a79', 'Name' => 'Script %WINDIR/%', 'Description' => 'Allow scripts in the windir directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%WINDIR%\*'}]}], 'Exceptions' => [{'FilePathCondition' => [{'Path' => '%SYSTEM32%\Com\dmp\*'}, {'Path' => '%SYSTEM32%\FxsTmp\*'}, {'Path' => '%System32%\Microsoft\Crypto\RSA\MachineKeys\*'}, {'Path' => '%SYSTEM32%\spool\drivers\color\*'}, {'Path' => '%SYSTEM32%\spool\PRINTERS\*'}, {'Path' => '%SYSTEM32%\spool\SERVERS\*'}, {'Path' => '%SYSTEM32%\Tasks\*'}, {'Path' => '%WINDIR%\Registration\CRMLog\*'}, {'Path' => '%WINDIR%\Tasks\*'}, {'Path' => '%WINDIR%\Temp\*'}, {'Path' => '%WINDIR%\tracing\*'}]}]}], 'FileHashRule' => [{'Id' => '778e4183-dec5-42df-e395-87173ace089d', 'Name' => 'Script powershell hash', 'Description' => 'random test powershell script', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FileHashCondition' => [{'FileHash' => [{'Type' => 'SHA256', 'Data' => '0x2057696D8662313670D36C3A3C8009FB038C8732C40C65275F158F63AAAD1629', 'SourceFileName' => 'powerfulshell.ps1', 'SourceFileLength' => '20'}]}]}]}]}]}, {'Version' => '1', 'RuleCollection' => [{'Type' => 'Appx', 'EnforcementMode' => 'AuditOnly', 'FilePublisherRule' => [{'Id' => '3ae31537-34e8-c52c-0363-df50388fea30', 'Name' => 'Packaged app MS corp windows', 'Description' => 'Allow Package app rule Microsoft corporation (Windows)', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington', 'C=US, ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}, {'Id' => 'cc1cc505-ce9a-6dd7-4d73-9d0204f9735d', 'Name' => 'Packaged app MS corp', 'Description' => 'Allow Package app rule Microsoft corporation', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}], 'Exceptions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Louis, O=Poodle, C=AU', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '3.0.0.0'}]}, {'PublisherName' => 'CN=doge, O=coin, C=AU', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}]}, {'Type' => 'Dll', 'EnforcementMode' => 'AuditOnly', 'FilePathRule' => [{'Id' => '81baaabe-4266-ffd4-ca79-6c66a2ea3e98', 'Name' => 'DLL %WINDIR/%', 'Description' => 'Allow dll in the programfiles directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%WINDIR%\*}]}]', 'Exceptions' => [{'FilePathCondition' => [{'Path' => '%SYSTEM32%\spool\drivers\color\*'}, {'Path' => '%SYSTEM32%\Tasks\*'}, {'Path' => '%WINDIR%\Tasks\*'}, {'Path' => '%WINDIR%\Temp\\'}, {'Path' => '%System32%\Microsoft\Crypto\RSA\MachineKeys\*'}]}]}, {'Id' => 'f9efadbf-0255-9e65-dbcf-11fcd8cb27d4', 'Name' => 'DLL %PROGRAMFILES/%', 'Description' => 'Allow dll in the programfiles directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%PROGRAMFILES%\*'}]}]}]}]}]}, {'Type' => 'Exe', 'EnforcementMode' => 'AuditOnly', 'FilePathRule' => [{'Id' => '93246af9-225e-01ab-a22b-2ea6defbac20', 'Name' => 'Exec %%PROGRAMFILES/%', 'Description' => 'Allow all users to run apps in programfiles', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%PROGRAMFILES%\*'}]}]}, {'Id' => 'a8cdb667-143d-127e-32a9-b9e641c19f39', 'Name' => 'Exec %OSDRIVE/temp/%', 'Description' => 'Allow all users to run apps in osdrive temp', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%OSDRIVE%\temp\doge\*'}]}]}, {'Id' => 'd2b6b159-3d42-470c-4108-2a1d43be39cc', 'Name' => 'Exec %OSDRIVE/CHOCO/%', 'Description' => 'Allow all users to run apps in osdrive choco', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%OSDRIVE%\CHOCO\*'}]}]}, {'Id' => 'fd042c8a-c663-028d-8e61-7adf35f86da0', 'Name' => 'Exec %windir/%', 'Description' => 'Allow all users to run apps in windir', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%WINDIR%\*'}]}], 'Exceptions' => [{'FilePathCondition' => [{'Path' => '%System32%\Microsoft\Crypto\RSA\MachineKeys\*'}, {'Path' => '%SYSTEM32%\spool\drivers\color\*'}, {'Path' => '%SYSTEM32%\Tasks\*'}, {'Path' => '%WINDIR%\Tasks\*'}, {'Path' => '%WINDIR%\Temp\*'}]}]}]}, {'Type' => 'Msi', 'EnforcementMode' => 'AuditOnly', 'FilePublisherRule' => [{'Id' => '3088d67f-075c-4c08-c773-6bc75fd74381', 'Name' => 'MSI rule MS corp windows', 'Description' => 'Allow Package app rule Microsoft corporation (Windows)', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington, C=US', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}, {'Id' => 'd70f545d-8d7b-a801-6e4b-ce152ba570f2', 'Name' => 'MSI rule MS corp', 'Description' => 'Allow Package app rule Microsoft corporation', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}]}, {'Type' => 'Script', 'EnforcementMode' => 'Enabled', 'FilePathRule' => [{'Id' => '03dfa177-8b1a-6ef2-a6b2-07cbedc9a990', 'Name' => 'Script %PROGRAMFILES/%', 'Description' => 'Allow scripts in the programfiles directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%PROGRAMFILES%\*'}]}]}, {'Id' => '35ff3c00-3ede-6cba-13f4-c9de04a72a79', 'Name' => 'Script %WINDIR/%', 'Description' => 'Allow scripts in the windir directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%WINDIR%\*'}]}], 'Exceptions' => [{'FilePathCondition' => [{'Path' => '%SYSTEM32%\Com\dmp\*'}, {'Path' => '%SYSTEM32%\FxsTmp\*'}, {'Path' => '%System32%\Microsoft\Crypto\RSA\MachineKeys\*'}, {'Path' => '%SYSTEM32%\spool\drivers\color\*'}, {'Path' => '%SYSTEM32%\spool\PRINTERS\*'}, {'Path' => '%SYSTEM32%\spool\SERVERS\*'}, {'Path' => '%SYSTEM32%\Tasks\*'}, {'Path' => '%WINDIR%\Registration\CRMLog\*'}, {'Path' => '%WINDIR%\Tasks\*'}, {'Path' => '%WINDIR%\Temp\*'}, {'Path' => '%WINDIR%\tracing\*'}]}]}], 'FileHashRule' => [{'Id' => '778e4183-dec5-42df-e395-87173ace089d', 'Name' => 'Script powershell hash', 'Description' => 'random test powershell script', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FileHashCondition' => [{'FileHash' => [{'Type' => 'SHA256', 'Data' => '0x2057696D8662313670D36C3A3C8009FB038C8732C40C65275F158F63AAAD1629', 'SourceFileName' => 'powerfulshell.ps1', 'SourceFileLength' => '20'}]}]}]}]}]}).and_return({ 'Result' => true }) } + it { is_expected.to run.with_params({'Version' => '1'}, {'Version' => '1', 'RuleCollection' => [{'Type' => 'Appx', 'EnforcementMode' => 'AuditOnly', 'FilePublisherRule' => [{'Id' => '3ae31537-34e8-c52c-0363-df50388fea30', 'Name' => 'Packaged app MS corp windows', 'Description' => 'Allow Package app rule Microsoft corporation (Windows)', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington', 'C=US, ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}, {'Id' => 'cc1cc505-ce9a-6dd7-4d73-9d0204f9735d', 'Name' => 'Packaged app MS corp', 'Description' => 'Allow Package app rule Microsoft corporation', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}], 'Exceptions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Louis, O=Poodle, C=AU', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '3.0.0.0'}]}, {'PublisherName' => 'CN=doge, O=coin, C=AU', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}]}, {'Type' => 'Dll', 'EnforcementMode' => 'AuditOnly', 'FilePathRule' => [{'Id' => '81baaabe-4266-ffd4-ca79-6c66a2ea3e98', 'Name' => 'DLL %WINDIR/%', 'Description' => 'Allow dll in the programfiles directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%WINDIR%\*}]}]', 'Exceptions' => [{'FilePathCondition' => [{'Path' => '%SYSTEM32%\spool\drivers\color\*'}, {'Path' => '%SYSTEM32%\Tasks\*'}, {'Path' => '%WINDIR%\Tasks\*'}, {'Path' => '%WINDIR%\Temp\\'}, {'Path' => '%System32%\Microsoft\Crypto\RSA\MachineKeys\*'}]}]}, {'Id' => 'f9efadbf-0255-9e65-dbcf-11fcd8cb27d4', 'Name' => 'DLL %PROGRAMFILES/%', 'Description' => 'Allow dll in the programfiles directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%PROGRAMFILES%\*'}]}]}]}]}]}, {'Type' => 'Exe', 'EnforcementMode' => 'AuditOnly', 'FilePathRule' => [{'Id' => '93246af9-225e-01ab-a22b-2ea6defbac20', 'Name' => 'Exec %%PROGRAMFILES/%', 'Description' => 'Allow all users to run apps in programfiles', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%PROGRAMFILES%\*'}]}]}, {'Id' => 'a8cdb667-143d-127e-32a9-b9e641c19f39', 'Name' => 'Exec %OSDRIVE/temp/%', 'Description' => 'Allow all users to run apps in osdrive temp', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%OSDRIVE%\temp\doge\*'}]}]}, {'Id' => 'd2b6b159-3d42-470c-4108-2a1d43be39cc', 'Name' => 'Exec %OSDRIVE/CHOCO/%', 'Description' => 'Allow all users to run apps in osdrive choco', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%OSDRIVE%\CHOCO\*'}]}]}, {'Id' => 'fd042c8a-c663-028d-8e61-7adf35f86da0', 'Name' => 'Exec %windir/%', 'Description' => 'Allow all users to run apps in windir', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%WINDIR%\*'}]}], 'Exceptions' => [{'FilePathCondition' => [{'Path' => '%System32%\Microsoft\Crypto\RSA\MachineKeys\*'}, {'Path' => '%SYSTEM32%\spool\drivers\color\*'}, {'Path' => '%SYSTEM32%\Tasks\*'}, {'Path' => '%WINDIR%\Tasks\*'}, {'Path' => '%WINDIR%\Temp\*'}]}]}]}, {'Type' => 'Msi', 'EnforcementMode' => 'AuditOnly', 'FilePublisherRule' => [{'Id' => '3088d67f-075c-4c08-c773-6bc75fd74381', 'Name' => 'MSI rule MS corp windows', 'Description' => 'Allow Package app rule Microsoft corporation (Windows)', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington, C=US', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}, {'Id' => 'd70f545d-8d7b-a801-6e4b-ce152ba570f2', 'Name' => 'MSI rule MS corp', 'Description' => 'Allow Package app rule Microsoft corporation', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}]}, {'Type' => 'Script', 'EnforcementMode' => 'Enabled', 'FilePathRule' => [{'Id' => '03dfa177-8b1a-6ef2-a6b2-07cbedc9a990', 'Name' => 'Script %PROGRAMFILES/%', 'Description' => 'Allow scripts in the programfiles directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%PROGRAMFILES%\*'}]}]}, {'Id' => '35ff3c00-3ede-6cba-13f4-c9de04a72a79', 'Name' => 'Script %WINDIR/%', 'Description' => 'Allow scripts in the windir directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%WINDIR%\*'}]}], 'Exceptions' => [{'FilePathCondition' => [{'Path' => '%SYSTEM32%\Com\dmp\*'}, {'Path' => '%SYSTEM32%\FxsTmp\*'}, {'Path' => '%System32%\Microsoft\Crypto\RSA\MachineKeys\*'}, {'Path' => '%SYSTEM32%\spool\drivers\color\*'}, {'Path' => '%SYSTEM32%\spool\PRINTERS\*'}, {'Path' => '%SYSTEM32%\spool\SERVERS\*'}, {'Path' => '%SYSTEM32%\Tasks\*'}, {'Path' => '%WINDIR%\Registration\CRMLog\*'}, {'Path' => '%WINDIR%\Tasks\*'}, {'Path' => '%WINDIR%\Temp\*'}, {'Path' => '%WINDIR%\tracing\*'}]}]}], 'FileHashRule' => [{'Id' => '778e4183-dec5-42df-e395-87173ace089d', 'Name' => 'Script powershell hash', 'Description' => 'random test powershell script', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FileHashCondition' => [{'FileHash' => [{'Type' => 'SHA256', 'Data' => '0x2057696D8662313670D36C3A3C8009FB038C8732C40C65275F158F63AAAD1629', 'SourceFileName' => 'powerfulshell.ps1', 'SourceFileLength' => '20'}]}]}]}]}]}).and_return({ 'Result' => false }) } + + it { is_expected.to run.with_params({'Version' => '1', 'RuleCollection' => [{'Type' => 'Appx', 'EnforcementMode' => 'AuditOnly', 'FilePublisherRule' => [{'Id' => '3ae31537-34e8-c52c-0363-df50388fea30', 'Name' => 'Packaged app MS corp windows', 'Description' => 'Allow Package app rule Microsoft corporation (Windows)', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington', 'C=US, ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}, {'Id' => 'cc1cc505-ce9a-6dd7-4d73-9d0204f9735d', 'Name' => 'Packaged app MS corp', 'Description' => 'Allow Package app rule Microsoft corporation', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}], 'Exceptions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Louis, O=Poodle, C=AU', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '3.0.0.0'}]}, {'PublisherName' => 'CN=doge, O=coin, C=AU', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}]}, {'Type' => 'Dll', 'EnforcementMode' => 'AuditOnly', 'FilePathRule' => [{'Id' => '81baaabe-4266-ffd4-ca79-6c66a2ea3e98', 'Name' => 'DLL %WINDIR/%', 'Description' => 'Allow dll in the programfiles directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%WINDIR%\*}]}]', 'Exceptions' => [{'FilePathCondition' => [{'Path' => '%SYSTEM32%\spool\drivers\color\*'}, {'Path' => '%SYSTEM32%\Tasks\*'}, {'Path' => '%WINDIR%\Tasks\*'}, {'Path' => '%WINDIR%\Temp\\'}, {'Path' => '%System32%\Microsoft\Crypto\RSA\MachineKeys\*'}]}]}, {'Id' => 'f9efadbf-0255-9e65-dbcf-11fcd8cb27d4', 'Name' => 'DLL %PROGRAMFILES/%', 'Description' => 'Allow dll in the programfiles directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%PROGRAMFILES%\*'}]}]}]}]}]}, {'Type' => 'Exe', 'EnforcementMode' => 'AuditOnly', 'FilePathRule' => [{'Id' => '93246af9-225e-01ab-a22b-2ea6defbac20', 'Name' => 'Exec %%PROGRAMFILES/%', 'Description' => 'Allow all users to run apps in programfiles', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%PROGRAMFILES%\*'}]}]}, {'Id' => 'a8cdb667-143d-127e-32a9-b9e641c19f39', 'Name' => 'Exec %OSDRIVE/temp/%', 'Description' => 'Allow all users to run apps in osdrive temp', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%OSDRIVE%\temp\doge\*'}]}]}, {'Id' => 'd2b6b159-3d42-470c-4108-2a1d43be39cc', 'Name' => 'Exec %OSDRIVE/CHOCO/%', 'Description' => 'Allow all users to run apps in osdrive choco', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%OSDRIVE%\CHOCO\*'}]}]}, {'Id' => 'fd042c8a-c663-028d-8e61-7adf35f86da0', 'Name' => 'Exec %windir/%', 'Description' => 'Allow all users to run apps in windir', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%WINDIR%\*'}]}], 'Exceptions' => [{'FilePathCondition' => [{'Path' => '%System32%\Microsoft\Crypto\RSA\MachineKeys\*'}, {'Path' => '%SYSTEM32%\spool\drivers\color\*'}, {'Path' => '%SYSTEM32%\Tasks\*'}, {'Path' => '%WINDIR%\Tasks\*'}, {'Path' => '%WINDIR%\Temp\*'}]}]}]}, {'Type' => 'Msi', 'EnforcementMode' => 'AuditOnly', 'FilePublisherRule' => [{'Id' => '3088d67f-075c-4c08-c773-6bc75fd74381', 'Name' => 'MSI rule MS corp windows', 'Description' => 'Allow Package app rule Microsoft corporation (Windows)', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Windows, O=Microsoft Corporation, L=Redmon1d, S=Washington, C=US', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}, {'Id' => 'd70f545d-8d7b-a801-6e4b-ce152ba570f2', 'Name' => 'MSI rule MS corp', 'Description' => 'Allow Package app rule Microsoft corporation', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}]}, {'Type' => 'Script', 'EnforcementMode' => 'Enabled', 'FilePathRule' => [{'Id' => '03dfa177-8b1a-6ef2-a6b2-07cbedc9a990', 'Name' => 'Script %PROGRAMFILES/%', 'Description' => 'Allow scripts in the programfiles directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%PROGRAMFILES%\*'}]}]}, {'Id' => '35ff3c00-3ede-6cba-13f4-c9de04a72a79', 'Name' => 'Script %WINDIR/%', 'Description' => 'Allow scripts in the windir directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%WINDIR%\*'}]}], 'Exceptions' => [{'FilePathCondition' => [{'Path' => '%SYSTEM32%\Com\dmp\*'}, {'Path' => '%SYSTEM32%\FxsTmp\*'}, {'Path' => '%System32%\Microsoft\Crypto\RSA\MachineKeys\*'}, {'Path' => '%SYSTEM32%\spool\drivers\color\*'}, {'Path' => '%SYSTEM32%\spool\PRINTERS\*'}, {'Path' => '%SYSTEM32%\spool\SERVERS\*'}, {'Path' => '%SYSTEM32%\Tasks\*'}, {'Path' => '%WINDIR%\Registration\CRMLog\*'}, {'Path' => '%WINDIR%\Tasks\*'}, {'Path' => '%WINDIR%\Temp\*'}, {'Path' => '%WINDIR%\tracing\*'}]}]}], 'FileHashRule' => [{'Id' => '778e4183-dec5-42df-e395-87173ace089d', 'Name' => 'Script powershell hash', 'Description' => 'random test powershell script', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FileHashCondition' => [{'FileHash' => [{'Type' => 'SHA256', 'Data' => '0x2057696D8662313670D36C3A3C8009FB038C8732C40C65275F158F63AAAD1629', 'SourceFileName' => 'powerfulshell.ps1', 'SourceFileLength' => '20'}]}]}]}]}]}, {'Version' => '1', 'RuleCollection' => [{'Type' => 'Appx', 'EnforcementMode' => 'AuditOnly', 'FilePublisherRule' => [{'Id' => '3ae31537-34e8-c52c-0363-df50388fea30', 'Name' => 'Packaged app MS corp windows', 'Description' => 'Allow Package app rule Microsoft corporation (Windows)', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington', 'C=US, ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}, {'Id' => 'cc1cc505-ce9a-6dd7-4d73-9d0204f9735d', 'Name' => 'Packaged app MS corp', 'Description' => 'Allow Package app rule Microsoft corporation', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}], 'Exceptions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Louis, O=Poodle, C=AU', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '3.0.0.0'}]}, {'PublisherName' => 'CN=doge, O=coin, C=AU', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}]}, {'Type' => 'Dll', 'EnforcementMode' => 'AuditOnly', 'FilePathRule' => [{'Id' => '81baaabe-4266-ffd4-ca79-6c66a2ea3e98', 'Name' => 'DLL %WINDIR/%', 'Description' => 'Allow dll in the programfiles directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%WINDIR%\*}]}]', 'Exceptions' => [{'FilePathCondition' => [{'Path' => '%SYSTEM32%\spool\drivers\color\*'}, {'Path' => '%SYSTEM32%\Tasks\*'}, {'Path' => '%WINDIR%\Tasks\*'}, {'Path' => '%WINDIR%\Temp\\'}, {'Path' => '%System32%\Microsoft\Crypto\RSA\MachineKeys\*'}]}]}, {'Id' => 'f9efadbf-0255-9e65-dbcf-11fcd8cb27d4', 'Name' => 'DLL %PROGRAMFILES/%', 'Description' => 'Allow dll in the programfiles directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%PROGRAMFILES%\*'}]}]}]}]}]}, {'Type' => 'Exe', 'EnforcementMode' => 'AuditOnly', 'FilePathRule' => [{'Id' => '93246af9-225e-01ab-a22b-2ea6defbac20', 'Name' => 'Exec %%PROGRAMFILES/%', 'Description' => 'Allow all users to run apps in programfiles', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%PROGRAMFILES%\*'}]}]}, {'Id' => 'a8cdb667-143d-127e-32a9-b9e641c19f39', 'Name' => 'Exec %OSDRIVE/temp/%', 'Description' => 'Allow all users to run apps in osdrive temp', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%OSDRIVE%\temp\doge\*'}]}]}, {'Id' => 'd2b6b159-3d42-470c-4108-2a1d43be39cc', 'Name' => 'Exec %OSDRIVE/CHOCO/%', 'Description' => 'Allow all users to run apps in osdrive choco', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%OSDRIVE%\CHOCO\*'}]}]}, {'Id' => 'fd042c8a-c663-028d-8e61-7adf35f86da0', 'Name' => 'Exec %windir/%', 'Description' => 'Allow all users to run apps in windir', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%WINDIR%\*'}]}], 'Exceptions' => [{'FilePathCondition' => [{'Path' => '%System32%\Microsoft\Crypto\RSA\MachineKeys\*'}, {'Path' => '%SYSTEM32%\spool\drivers\color\*'}, {'Path' => '%SYSTEM32%\Tasks\*'}, {'Path' => '%WINDIR%\Tasks\*'}, {'Path' => '%WINDIR%\Temp\*'}]}]}]}, {'Type' => 'Msi', 'EnforcementMode' => 'AuditOnly', 'FilePublisherRule' => [{'Id' => '3088d67f-075c-4c08-c773-6bc75fd74381', 'Name' => 'MSI rule MS corp windows', 'Description' => 'Allow Package app rule Microsoft corporation (Windows)', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington, C=US', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}, {'Id' => 'd70f545d-8d7b-a801-6e4b-ce152ba570f2', 'Name' => 'MSI rule MS corp', 'Description' => 'Allow Package app rule Microsoft corporation', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}]}, {'Type' => 'Script', 'EnforcementMode' => 'Enabled', 'FilePathRule' => [{'Id' => '03dfa177-8b1a-6ef2-a6b2-07cbedc9a990', 'Name' => 'Script %PROGRAMFILES/%', 'Description' => 'Allow scripts in the programfiles directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%PROGRAMFILES%\*'}]}]}, {'Id' => '35ff3c00-3ede-6cba-13f4-c9de04a72a79', 'Name' => 'Script %WINDIR/%', 'Description' => 'Allow scripts in the windir directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%WINDIR%\*'}]}], 'Exceptions' => [{'FilePathCondition' => [{'Path' => '%SYSTEM32%\Com\dmp\*'}, {'Path' => '%SYSTEM32%\FxsTmp\*'}, {'Path' => '%System32%\Microsoft\Crypto\RSA\MachineKeys\*'}, {'Path' => '%SYSTEM32%\spool\drivers\color\*'}, {'Path' => '%SYSTEM32%\spool\PRINTERS\*'}, {'Path' => '%SYSTEM32%\spool\SERVERS\*'}, {'Path' => '%SYSTEM32%\Tasks\*'}, {'Path' => '%WINDIR%\Registration\CRMLog\*'}, {'Path' => '%WINDIR%\Tasks\*'}, {'Path' => '%WINDIR%\Temp\*'}, {'Path' => '%WINDIR%\tracing\*'}]}]}], 'FileHashRule' => [{'Id' => '778e4183-dec5-42df-e395-87173ace089d', 'Name' => 'Script powershell hash', 'Description' => 'random test powershell script', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FileHashCondition' => [{'FileHash' => [{'Type' => 'SHA256', 'Data' => '0x2057696D8662313670D36C3A3C8009FB038C8732C40C65275F158F63AAAD1629', 'SourceFileName' => 'powerfulshell.ps1', 'SourceFileLength' => '20'}]}]}]}]}]}).and_return({ 'Result' => false, 'failing_rule' => 'Msi' }) } + + it { is_expected.to run.with_params({'Version' => '1', 'RuleCollection' => [{'Type' => 'Appx', 'EnforcementMode' => 'AuditOnly', 'FilePublisherRule' => [{'Id' => '3ae31537-34e8-c52c-0363-df50388fea30', 'Name' => 'Packaged app MS corp windows', 'Description' => 'Allow Package app rule Microsoft corporation (Windows)', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington', 'C=US, ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}, {'Id' => 'cc1cc505-ce9a-6dd7-4d73-9d0204f9735d', 'Name' => 'Packaged app MS corp', 'Description' => 'Allow Package app rule Microsoft corporation', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}], 'Exceptions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Louis, O=Poodle, C=AU', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '3.0.0.0'}]}, {'PublisherName' => 'CN=doge, O=coin, C=AU', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}]}, {'Type' => 'Dll', 'EnforcementMode' => 'AuditOnly', 'FilePathRule' => [{'Id' => '81baaabe-4266-ffd4-ca79-6c66a2ea3e98', 'Name' => 'DLL %WINDIR/%', 'Description' => 'Allow dll in the programfiles directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%WINDIR%\*}]}]', 'Exceptions' => [{'FilePathCondition' => [{'Path' => '%SYSTEM32%\spool\drivers\color\*'}, {'Path' => '%SYSTEM32%\Tasks\*'}, {'Path' => '%WINDIR%\Tasks\*'}, {'Path' => '%WINDIR%\Temp\\'}, {'Path' => '%System32%\Microsoft\Crypto\RSA\MachineKeys\*'}]}]}, {'Id' => 'f9efadbf-0255-9e65-dbcf-11fcd8cb27d4', 'Name' => 'DLL %PROGRAMFILES/%', 'Description' => 'Allow dll in the programfiles directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%PROGRAMFILES%\*'}]}]}]}]}]}, {'Type' => 'Exe', 'EnforcementMode' => 'AuditOnly', 'FilePathRule' => [{'Id' => '93246af9-225e-01ab-a22b-2ea6defbac20', 'Name' => 'Exec %%PROGRAMFILES/%', 'Description' => 'Allow all users to run apps in programfiles', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%PROGRAMFILES%\*'}]}]}, {'Id' => 'a8cdb667-143d-127e-32a9-b9e641c19f39', 'Name' => 'Exec %OSDRIVE/temp/%', 'Description' => 'Allow all users to run apps in osdrive temp', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%OSDRIVE%\temp\doge\*'}]}]}, {'Id' => 'd2b6b159-3d42-470c-4108-2a1d43be39cc', 'Name' => 'Exec %OSDRIVE/CHOCO/%', 'Description' => 'Allow all users to run apps in osdrive choco', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%OSDRIVE%\CHOCO\*'}]}]}, {'Id' => 'fd042c8a-c663-028d-8e61-7adf35f86da0', 'Name' => 'Exec %windir/%', 'Description' => 'Allow all users to run apps in windir', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%WINDIR%\*'}]}], 'Exceptions' => [{'FilePathCondition' => [{'Path' => '%System32%\Microsoft\Crypto\RSA\MachineKeys\*'}, {'Path' => '%SYSTEM32%\spool\drivers\color\*'}, {'Path' => '%SYSTEM32%\Tasks\*'}, {'Path' => '%WINDIR%\Tasks\*'}, {'Path' => '%WINDIR%\Temp\*'}]}]}]}, {'Type' => 'Msi', 'EnforcementMode' => 'AuditOnly', 'FilePublisherRule' => [{'Id' => '3088d67f-075c-4c08-c773-6bc75fd74381', 'Name' => 'MSI rule MS corp windows', 'Description' => 'Allow Package app rule Microsoft corporation (Windows)', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington, C=US', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}, {'Id' => 'd70f545d-8d7b-a801-6e4b-ce152ba570f2', 'Name' => 'MSI rule MS corp', 'Description' => 'Allow Package app rule Microsoft corporation', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}]}, {'Type' => 'Script', 'EnforcementMode' => 'Enabled', 'FilePathRule' => [{'Id' => '03dfa177-8b1a-6ef2-a6b2-07cbedc9a990', 'Name' => 'Script %PROGRAMFILES/%', 'Description' => 'Allow scripts in the programfiles directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%PROGRAMFILES%\*'}]}]}, {'Id' => '35ff3c00-3ede-6cba-13f4-c9de04a72a79', 'Name' => 'Script %WINDIR/%', 'Description' => 'Allow scripts in the windir directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%WINDIR%\*'}]}], 'Exceptions' => [{'FilePathCondition' => [{'Path' => '%SYSTEM32%\Com\dmp\*'}, {'Path' => '%SYSTEM32%\FxsTmp\*'}, {'Path' => '%System32%\Microsoft\Crypto\RSA\MachineKeys\*'}, {'Path' => '%SYSTEM32%\spool\drivers\color\*'}, {'Path' => '%SYSTEM32%\spool\PRINTERS\*'}, {'Path' => '%SYSTEM32%\spool\SERVERS\*'}, {'Path' => '%SYSTEM32%\Tasks\*'}, {'Path' => '%WINDIR%\Registration\CRMLog\*'}, {'Path' => '%WINDIR%\Tasks\*'}, {'Path' => '%WINDIR%\Temp\*'}, {'Path' => '%WINDIR%\tracing\*'}]}]}], 'FileHashRule' => [{'Id' => '778e4183-dec5-42df-e395-87173ace089d', 'Name' => 'Script powershell hash', 'Description' => 'random test powershell script', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FileHashCondition' => [{'FileHash' => [{'Type' => 'SHA256', 'Data' => '0x2057696D8662313670D36C3A3C8009FB038C8732C40C65275F158F63AAAD1629', 'SourceFileName' => 'powerfulshell.ps1', 'SourceFileLength' => '20'}]}]}]}]}]}, {'Version' => '1', 'RuleCollection' => [{'Type' => 'Appx', 'EnforcementMode' => 'AuditOnly', 'FilePublisherRule' => [{'Id' => '3ae31537-34e8-c52c-0363-df50388fea30', 'Name' => 'Packaged app MS corp windows', 'Description' => 'Allow Package app rule Microsoft corporation (Windows)', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington', 'C=US, ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}, {'Id' => 'cc1cc505-ce9a-6dd7-4d73-9d0204f9735d', 'Name' => 'Packaged app MS corp', 'Description' => 'Allow Package app rule Microsoft corporation', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}], 'Exceptions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Louis, O=Poodle, C=AU', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '3.0.0.0'}]}, {'PublisherName' => 'CN=doge, O=coin, C=AU', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}]}, {'Type' => 'Dll', 'EnforcementMode' => 'AuditOnly', 'FilePathRule' => [{'Id' => '81baaabe-4266-ffd4-ca79-6c66a2ea3e98', 'Name' => 'DLL %WINDIR/%', 'Description' => 'Allow dll in the programfiles directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%WINDIR%\*}]}]', 'Exceptions' => [{'FilePathCondition' => [{'Path' => '%SYSTEM32%\spool\drivers\color\*'}, {'Path' => '%SYSTEM32%\Tasks\*'}, {'Path' => '%WINDIR%\Tasks\*'}, {'Path' => '%WINDIR%\Temp\\'}, {'Path' => '%System32%\Microsoft\Crypto\RSA\MachineKeys\*'}]}]}, {'Id' => 'f9efadbf-0255-9e65-dbcf-11fcd8cb27d4', 'Name' => 'DLL %PROGRAMFILES/%', 'Description' => 'Allow dll in the programfiles directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%PROGRAMFILES%\*'}]}]}]}]}]}, {'Type' => 'Msi', 'EnforcementMode' => 'AuditOnly', 'FilePublisherRule' => [{'Id' => '3088d67f-075c-4c08-c773-6bc75fd74381', 'Name' => 'MSI rule MS corp windows', 'Description' => 'Allow Package app rule Microsoft corporation (Windows)', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington, C=US', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}, {'Id' => 'd70f545d-8d7b-a801-6e4b-ce152ba570f2', 'Name' => 'MSI rule MS corp', 'Description' => 'Allow Package app rule Microsoft corporation', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}]}, {'Type' => 'Script', 'EnforcementMode' => 'Enabled', 'FilePathRule' => [{'Id' => '03dfa177-8b1a-6ef2-a6b2-07cbedc9a990', 'Name' => 'Script %PROGRAMFILES/%', 'Description' => 'Allow scripts in the programfiles directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%PROGRAMFILES%\*'}]}]}, {'Id' => '35ff3c00-3ede-6cba-13f4-c9de04a72a79', 'Name' => 'Script %WINDIR/%', 'Description' => 'Allow scripts in the windir directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%WINDIR%\*'}]}], 'Exceptions' => [{'FilePathCondition' => [{'Path' => '%SYSTEM32%\Com\dmp\*'}, {'Path' => '%SYSTEM32%\FxsTmp\*'}, {'Path' => '%System32%\Microsoft\Crypto\RSA\MachineKeys\*'}, {'Path' => '%SYSTEM32%\spool\drivers\color\*'}, {'Path' => '%SYSTEM32%\spool\PRINTERS\*'}, {'Path' => '%SYSTEM32%\spool\SERVERS\*'}, {'Path' => '%SYSTEM32%\Tasks\*'}, {'Path' => '%WINDIR%\Registration\CRMLog\*'}, {'Path' => '%WINDIR%\Tasks\*'}, {'Path' => '%WINDIR%\Temp\*'}, {'Path' => '%WINDIR%\tracing\*'}]}]}], 'FileHashRule' => [{'Id' => '778e4183-dec5-42df-e395-87173ace089d', 'Name' => 'Script powershell hash', 'Description' => 'random test powershell script', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FileHashCondition' => [{'FileHash' => [{'Type' => 'SHA256', 'Data' => '0x2057696D8662313670D36C3A3C8009FB038C8732C40C65275F158F63AAAD1629', 'SourceFileName' => 'powerfulshell.ps1', 'SourceFileLength' => '20'}]}]}]}]}]}).and_return({ 'Result' => false, 'failing_rule' => 'Exe' }) } + + it { is_expected.to run.with_params({'Version' => '1', 'RuleCollection' => [{'Type' => 'Appx', 'EnforcementMode' => 'AuditOnly', 'FilePublisherRule' => [{'Id' => '3ae31537-34e8-c52c-0363-df50388fea30', 'Name' => 'Packaged app MS corp windows', 'Description' => 'Allow Package app rule Microsoft corporation (Windows)', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington', 'C=US, ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}, {'Id' => 'cc1cc505-ce9a-6dd7-4d73-9d0204f9735d', 'Name' => 'Packaged app MS corp', 'Description' => 'Allow Package app rule Microsoft corporation', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}], 'Exceptions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Louis, O=Poodle, C=AU', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '3.0.0.0'}]}, {'PublisherName' => 'CN=doge, O=coin, C=AU', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}]}, {'Type' => 'Dll', 'EnforcementMode' => 'AuditOnly', 'FilePathRule' => [{'Id' => '81baaabe-4266-ffd4-ca79-6c66a2ea3e98', 'Name' => 'DLL %WINDIR/%', 'Description' => 'Allow dll in the programfiles directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%WINDIR%\*}]}]', 'Exceptions' => [{'FilePathCondition' => [{'Path' => '%SYSTEM32%\spool\drivers\color\*'}, {'Path' => '%SYSTEM32%\Tasks\*'}, {'Path' => '%WINDIR%\Tasks\*'}, {'Path' => '%WINDIR%\Temp\\'}, {'Path' => '%System32%\Microsoft\Crypto\RSA\MachineKeys\*'}]}]}, {'Id' => 'f9efadbf-0255-9e65-dbcf-11fcd8cb27d4', 'Name' => 'DLL %PROGRAMFILES/%', 'Description' => 'Allow dll in the programfiles directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%PROGRAMFILES%\*'}]}]}]}]}]}, {'Type' => 'Msi', 'EnforcementMode' => 'AuditOnly', 'FilePublisherRule' => [{'Id' => '3088d67f-075c-4c08-c773-6bc75fd74381', 'Name' => 'MSI rule MS corp windows', 'Description' => 'Allow Package app rule Microsoft corporation (Windows)', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington, C=US', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}, {'Id' => 'd70f545d-8d7b-a801-6e4b-ce152ba570f2', 'Name' => 'MSI rule MS corp', 'Description' => 'Allow Package app rule Microsoft corporation', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}]}, {'Type' => 'Script', 'EnforcementMode' => 'Enabled', 'FilePathRule' => [{'Id' => '03dfa177-8b1a-6ef2-a6b2-07cbedc9a990', 'Name' => 'Script %PROGRAMFILES/%', 'Description' => 'Allow scripts in the programfiles directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%PROGRAMFILES%\*'}]}]}, {'Id' => '35ff3c00-3ede-6cba-13f4-c9de04a72a79', 'Name' => 'Script %WINDIR/%', 'Description' => 'Allow scripts in the windir directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%WINDIR%\*'}]}], 'Exceptions' => [{'FilePathCondition' => [{'Path' => '%SYSTEM32%\Com\dmp\*'}, {'Path' => '%SYSTEM32%\FxsTmp\*'}, {'Path' => '%System32%\Microsoft\Crypto\RSA\MachineKeys\*'}, {'Path' => '%SYSTEM32%\spool\drivers\color\*'}, {'Path' => '%SYSTEM32%\spool\PRINTERS\*'}, {'Path' => '%SYSTEM32%\spool\SERVERS\*'}, {'Path' => '%SYSTEM32%\Tasks\*'}, {'Path' => '%WINDIR%\Registration\CRMLog\*'}, {'Path' => '%WINDIR%\Tasks\*'}, {'Path' => '%WINDIR%\Temp\*'}, {'Path' => '%WINDIR%\tracing\*'}]}]}], 'FileHashRule' => [{'Id' => '778e4183-dec5-42df-e395-87173ace089d', 'Name' => 'Script powershell hash', 'Description' => 'random test powershell script', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FileHashCondition' => [{'FileHash' => [{'Type' => 'SHA256', 'Data' => '0x2057696D8662313670D36C3A3C8009FB038C8732C40C65275F158F63AAAD1629', 'SourceFileName' => 'powerfulshell.ps1', 'SourceFileLength' => '20'}]}]}]}]}]}, {'Version' => '1', 'RuleCollection' => [{'Type' => 'Appx', 'EnforcementMode' => 'AuditOnly', 'FilePublisherRule' => [{'Id' => '3ae31537-34e8-c52c-0363-df50388fea30', 'Name' => 'Packaged app MS corp windows', 'Description' => 'Allow Package app rule Microsoft corporation (Windows)', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington', 'C=US, ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}, {'Id' => 'cc1cc505-ce9a-6dd7-4d73-9d0204f9735d', 'Name' => 'Packaged app MS corp', 'Description' => 'Allow Package app rule Microsoft corporation', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}], 'Exceptions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Louis, O=Poodle, C=AU', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '3.0.0.0'}]}, {'PublisherName' => 'CN=doge, O=coin, C=AU', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}]}, {'Type' => 'Dll', 'EnforcementMode' => 'AuditOnly', 'FilePathRule' => [{'Id' => '81baaabe-4266-ffd4-ca79-6c66a2ea3e98', 'Name' => 'DLL %WINDIR/%', 'Description' => 'Allow dll in the programfiles directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%WINDIR%\*}]}]', 'Exceptions' => [{'FilePathCondition' => [{'Path' => '%SYSTEM32%\spool\drivers\color\*'}, {'Path' => '%SYSTEM32%\Tasks\*'}, {'Path' => '%WINDIR%\Tasks\*'}, {'Path' => '%WINDIR%\Temp\\'}, {'Path' => '%System32%\Microsoft\Crypto\RSA\MachineKeys\*'}]}]}, {'Id' => 'f9efadbf-0255-9e65-dbcf-11fcd8cb27d4', 'Name' => 'DLL %PROGRAMFILES/%', 'Description' => 'Allow dll in the programfiles directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%PROGRAMFILES%\*'}]}]}]}]}]}, {'Type' => 'Msi', 'EnforcementMode' => 'AuditOnly', 'FilePublisherRule' => [{'Id' => '3088d67f-075c-4c08-c773-6bc75fd74381', 'Name' => 'MSI rule MS corp windows', 'Description' => 'Allow Package app rule Microsoft corporation (Windows)', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington, C=US', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}, {'Id' => 'd70f545d-8d7b-a801-6e4b-ce152ba570f2', 'Name' => 'MSI rule MS corp', 'Description' => 'Allow Package app rule Microsoft corporation', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePublisherCondition' => [{'PublisherName' => 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US', 'ProductName' => '*', 'BinaryName' => '*', 'BinaryVersionRange' => [{'LowSection' => '*', 'HighSection' => '*'}]}]}]}]}, {'Type' => 'Script', 'EnforcementMode' => 'Enabled', 'FilePathRule' => [{'Id' => '03dfa177-8b1a-6ef2-a6b2-07cbedc9a990', 'Name' => 'Script %PROGRAMFILES/%', 'Description' => 'Allow scripts in the programfiles directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%PROGRAMFILES%\*'}]}]}, {'Id' => '35ff3c00-3ede-6cba-13f4-c9de04a72a79', 'Name' => 'Script %WINDIR/%', 'Description' => 'Allow scripts in the windir directory', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FilePathCondition' => [{'Path' => '%WINDIR%\*'}]}], 'Exceptions' => [{'FilePathCondition' => [{'Path' => '%SYSTEM32%\Com\dmp\*'}, {'Path' => '%SYSTEM32%\FxsTmp\*'}, {'Path' => '%System32%\Microsoft\Crypto\RSA\MachineKeys\*'}, {'Path' => '%SYSTEM32%\spool\drivers\color\*'}, {'Path' => '%SYSTEM32%\spool\PRINTERS\*'}, {'Path' => '%SYSTEM32%\spool\SERVERS\*'}, {'Path' => '%SYSTEM32%\Tasks\*'}, {'Path' => '%WINDIR%\Registration\CRMLog\*'}, {'Path' => '%WINDIR%\Tasks\*'}, {'Path' => '%WINDIR%\Temp\*'}, {'Path' => '%WINDIR%\tracing\*'}]}]}], 'FileHashRule' => [{'Id' => '778e4183-dec5-42df-e395-87173ace089d', 'Name' => 'Script powershell hash', 'Description' => 'random test powershell script', 'UserOrGroupSid' => 'S-1-1-0', 'Action' => 'Allow', 'Conditions' => [{'FileHashCondition' => [{'FileHash' => [{'Type' => 'SHA256', 'Data' => '0x2057696D8662313670D36C3A3C8009FB038C8732C40C65275F158F63AAAD1629', 'SourceFileName' => 'powerfulshell.ps1', 'SourceFileLength' => '20'}]}]}]}]}]}).and_return({ 'Result' => true }) } + + it { is_expected.to run.with_params({'Version' => '1'}, {'Version' => '1'}).and_return({ 'Result' => true }) } +end diff --git a/spec/functions/extract_rules_spec.rb b/spec/functions/extract_rules_spec.1rb similarity index 100% rename from spec/functions/extract_rules_spec.rb rename to spec/functions/extract_rules_spec.1rb diff --git a/spec/functions/get_id_spec.rb11 b/spec/functions/get_id_spec.1rb similarity index 100% rename from spec/functions/get_id_spec.rb11 rename to spec/functions/get_id_spec.1rb diff --git a/spec/functions/hash_toxml_spec.rb11 b/spec/functions/hash_toxml_spec.1rb similarity index 100% rename from spec/functions/hash_toxml_spec.rb11 rename to spec/functions/hash_toxml_spec.1rb diff --git a/spec/functions/xml_tohash_spec.rb11 b/spec/functions/xml_tohash_spec.1rb similarity index 100% rename from spec/functions/xml_tohash_spec.rb11 rename to spec/functions/xml_tohash_spec.1rb diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 9b1fa6f..6820ceb 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -25,8 +25,8 @@ next unless File.exist?(f) && File.readable?(f) && File.size?(f) begin - default_facts.merge!(YAML.safe_load(File.read(f), [], [], true)) - rescue => e + default_facts.merge!(YAML.safe_load(File.read(f), permitted_classes: [], permitted_symbols: [], aliases: true)) + rescue StandardError => e RSpec.configuration.reporter.message "WARNING: Unable to load #{f}: #{e}" end end @@ -46,6 +46,7 @@ end c.filter_run_excluding(bolt: true) unless ENV['GEM_BOLT'] c.after(:suite) do + RSpec::Puppet::Coverage.report!(0) end # Filter backtrace noise diff --git a/spec/unit/facter/applocker_rules_spec.rb b/spec/unit/facter/applocker_rules_spec.rb index e21e227..15e3150 100644 --- a/spec/unit/facter/applocker_rules_spec.rb +++ b/spec/unit/facter/applocker_rules_spec.rb @@ -10,9 +10,10 @@ before :each do # perform any action that should be run before every test Facter.clear + allow(Facter::Core::Execution).to receive(:execute).and_return('') end it 'returns a value' do - expect(fact.value).to eq(nil) + expect(fact.value).to eq('') end end diff --git a/templates/xmlrule.epp b/templates/xmlrule.epp index fed0e6d..31ef6be 100644 --- a/templates/xmlrule.epp +++ b/templates/xmlrule.epp @@ -13,28 +13,34 @@ <% if $appx_applocker_rules.length >= 1 { -%> <% $appx_applocker_rules.each | $key, $value | { -%> -<% if $value['rule_type'] == 'path' { -%> - +<%# File path rule ----- NOT REQUIRED for app, removed to avoid issues -%> +<%# File publisher rule -%> +<% if $value['rule_type'] == 'publisher' { -%> + -<% $value['conditions'].each | $condition, $path | { -%> - -<% } -%> + + + <% if $value['exceptions'] { -%> -<% $value['exceptions'].each | $index, $exception | { -%> - -<% } -%> + <% $value['exceptions'].each | $exception_value | { -%> + + + + <% } -%> <% } -%> - - <% } -%> + +<% } -%> +<%# File hash ----- NOT REQUIRED for appx -%> <% } -%> <% } -%> <% if $dll_applocker_rules.length >= 1 { -%> <% $dll_applocker_rules.each | $key, $value | { -%> +<%# File path rule -%> <% if $value['rule_type'] == 'path' { -%> @@ -51,12 +57,46 @@ <% } -%> <% } -%> +<%# File publisher rule -%> +<% if $value['rule_type'] == 'publisher' { -%> + + + + + + +<% if $value['exceptions'] { -%> + + <% $value['exceptions'].each | $exception_value | { -%> + + + + <% } -%> + +<% } -%> + +<% } -%> +<% if $value['rule_type'] == 'hash' { -%> +<%# File hash rule -%> + +<% if $value['conditions'] { -%> + + + <% $value['conditions'].each | $condition_value | { -%> + + <% } -%> + + + +<% } -%> +<% } -%> <% } -%> <% } -%> <% if $exec_applocker_rules.length >= 1 { -%> <% $exec_applocker_rules.each | $key, $value | { -%> +<%# File path rule -%> <% if $value['rule_type'] == 'path' { -%> @@ -73,12 +113,46 @@ <% } -%> <% } -%> +<%# File publisher rule -%> +<% if $value['rule_type'] == 'publisher' { -%> + + + + + + +<% if $value['exceptions'] { -%> + + <% $value['exceptions'].each | $exception_value | { -%> + + + + <% } -%> + +<% } -%> + +<% } -%> +<% if $value['rule_type'] == 'hash' { -%> +<%# File hash rule -%> + +<% if $value['conditions'] { -%> + + + <% $value['conditions'].each | $condition_value | { -%> + + <% } -%> + + + +<% } -%> +<% } -%> <% } -%> <% } -%> <% if $msi_applocker_rules.length >= 1 { -%> <% $msi_applocker_rules.each | $key, $value | { -%> +<%# File path rule -%> <% if $value['rule_type'] == 'path' { -%> @@ -95,12 +169,46 @@ <% } -%> <% } -%> +<%# File publisher rule -%> +<% if $value['rule_type'] == 'publisher' { -%> + + + + + + +<% if $value['exceptions'] { -%> + + <% $value['exceptions'].each | $exception_value | { -%> + + + + <% } -%> + +<% } -%> + +<% } -%> +<% if $value['rule_type'] == 'hash' { -%> +<%# File hash rule -%> + +<% if $value['conditions'] { -%> + + + <% $value['conditions'].each | $condition_value | { -%> + + <% } -%> + + + +<% } -%> +<% } -%> <% } -%> <% } -%> <% if $script_applocker_rules.length >= 1 { -%> <% $script_applocker_rules.each | $key, $value | { -%> +<%# File path rule -%> <% if $value['rule_type'] == 'path' { -%> @@ -117,6 +225,39 @@ <% } -%> <% } -%> +<%# File publisher rule -%> +<% if $value['rule_type'] == 'publisher' { -%> + + + + + + +<% if $value['exceptions'] { -%> + + <% $value['exceptions'].each | $exception_value | { -%> + + + + <% } -%> + +<% } -%> + +<% } -%> +<% if $value['rule_type'] == 'hash' { -%> +<%# File hash rule -%> + +<% if $value['conditions'] { -%> + + + <% $value['conditions'].each | $condition_value | { -%> + + <% } -%> + + + +<% } -%> +<% } -%> <% } -%> <% } -%>