Skip to content
This repository has been archived by the owner on Oct 11, 2021. It is now read-only.

Commit

Permalink
(GH-143) Ensure checksum is used
Browse files Browse the repository at this point in the history
  • Loading branch information
gep13 committed Aug 8, 2016
1 parent 7023e5b commit 8eeea91
Show file tree
Hide file tree
Showing 5 changed files with 298 additions and 1 deletion.
Binary file added lib/PowerShell/System.Management.Automation.dll
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
<Compile Include="infrastructure.app\AdminHelpersShouldBeIncludedWhenUsingAdminTagGuideline.cs" />
<Compile Include="infrastructure.app\AdminTagShouldBeIncludedWhenUsingAdminHelpersGuidelineSpecs.cs" />
<Compile Include="infrastructure.app\BinariesAreIncludedNoteSpecs.cs" />
<Compile Include="infrastructure.app\ChecksumShouldBeUsedRequirementSpecs.cs" />
<Compile Include="infrastructure.app\CopyrightAndAuthorFieldsShouldntContainEmailRequirementSpecs.cs" />
<Compile Include="infrastructure.app\DependencyWithNoVersionGuidelineSpecs.cs" />
<Compile Include="infrastructure.app\DescriptionWordCountMinimum30GuidelineSpecs.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
// Copyright © 2015 - Present RealDimensions Software, LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
//
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

namespace chocolatey.package.validator.tests.infrastructure.app
{
using System.Collections.Generic;
using chocolatey.package.validator.infrastructure.app.rules;
using chocolatey.package.validator.infrastructure.rules;
using Moq;
using NuGet;
using Should;

public abstract class ChecksumShouldBeUsedRequirementSpecsBase : TinySpec
{
protected ChecksumShouldBeUsedRequirement requirement;
protected Mock<IPackage> package = new Mock<IPackage>();
protected Mock<IPackageFile> packageFile = new Mock<IPackageFile>();

public override void Context()
{
requirement = new ChecksumShouldBeUsedRequirement();
}

public class when_inspecting_package_with_installation_script_with_checksum : ChecksumShouldBeUsedRequirementSpecsBase
{
private PackageValidationOutput result;

public override void Context()
{
base.Context();

packageFile.Setup(f => f.GetStream()).Returns(@"$packageName = '0ad'
$installerType = 'exe'
$silentArgs = '/S'
$url = 'http://releases.wildfiregames.com/0ad-0.0.20-alpha-win32.exe'
$checksum = '579942a0391947a86e63d649cd69d9c2615bcd3b'
$checksumType = 'sha256'
$validExitCodes = @(0)
Install-ChocolateyPackage -PackageName '$packageName' `
-FileType '$installerType' `
-SilentArgs '$silentArgs' `
-Url '$url' `
-ValidExitCodes $validExitCodes `
-Checksum '$checksum' `
-ChecksumType '$checksumType'".to_stream());
packageFile.Setup(f => f.Path).Returns("chocolateyInstall.ps1");

package.Setup(p => p.GetFiles()).Returns(new List<IPackageFile>() { packageFile.Object });
}

public override void Because()
{
result = this.requirement.is_valid(package.Object);
}

[Fact]
public void shoul_be_valid()
{
result.Validated.ShouldBeTrue();
}

[Fact]
public void should_not_override_the_base_message()
{
result.ValidationFailureMessageOverride.ShouldBeNull();
}
}

public class when_inspecting_package_with_installation_script_without_checksum : ChecksumShouldBeUsedRequirementSpecsBase
{
private PackageValidationOutput result;

public override void Context()
{
base.Context();

packageFile.Setup(f => f.GetStream()).Returns(@"$packageName = '0ad'
$installerType = 'exe'
$silentArgs = '/S'
$url = 'http://releases.wildfiregames.com/0ad-0.0.20-alpha-win32.exe'
$validExitCodes = @(0)
Install-ChocolateyPackage -PackageName '$packageName' `
-FileType '$installerType' `
-SilentArgs '$silentArgs' `
-Url '$url' `
-ValidExitCodes $validExitCodes".to_stream());
packageFile.Setup(f => f.Path).Returns("chocolateyInstall.ps1");

package.Setup(p => p.GetFiles()).Returns(new List<IPackageFile>() { packageFile.Object });
}

public override void Because()
{
result = this.requirement.is_valid(package.Object);
}

[Fact]
public void should_not_be_valid()
{
result.Validated.ShouldBeFalse();
}

[Fact]
public void should_not_override_the_base_message()
{
result.ValidationFailureMessageOverride.ShouldBeNull();
}
}

public class when_inspecting_package_with_installation_script_using_splatting_with_checksum : ChecksumShouldBeUsedRequirementSpecsBase
{
private PackageValidationOutput result;

public override void Context()
{
base.Context();

packageFile.Setup(f => f.GetStream()).Returns(@"$packageName = '0ad'
$fileType = 'exe'
$silentArgs = '/S'
$url = 'http://releases.wildfiregames.com/0ad-0.0.20-alpha-win32.exe'
$validExitCodes = @(0)
$checksum = '579942a0391947a86e63d649cd69d9c2615bcd3b'
$checksumType = 'sha256'
$packageArgs = @{
packageName = $packageName
fileType = $fileType
silentArgs = $silentArgs
url = $url
validExitCodes= $validExitCodes
checksum = $checksum
checksumType = $checksumType
}
Install-ChocolateyPackage @packageArgs".to_stream());
packageFile.Setup(f => f.Path).Returns("chocolateyInstall.ps1");

package.Setup(p => p.GetFiles()).Returns(new List<IPackageFile>() { packageFile.Object });
}

public override void Because()
{
result = this.requirement.is_valid(package.Object);
}

[Fact]
public void should_be_valid()
{
result.Validated.ShouldBeTrue();
}

[Fact]
public void should_not_override_the_base_message()
{
result.ValidationFailureMessageOverride.ShouldBeNull();
}
}

public class when_inspecting_package_with_installation_script_using_splatting_without_checksum : ChecksumShouldBeUsedRequirementSpecsBase
{
private PackageValidationOutput result;

public override void Context()
{
base.Context();

packageFile.Setup(f => f.GetStream()).Returns(@"$packageName = '0ad'
$fileType = 'exe'
$silentArgs = '/S'
$url = 'http://releases.wildfiregames.com/0ad-0.0.20-alpha-win32.exe'
$validExitCodes = @(0)
$packageArgs = @{
packageName = $packageName
fileType = $fileType
silentArgs = $silentArgs
url = $url
validExitCodes= $validExitCodes
}
Install-ChocolateyPackage @packageArgs".to_stream());
packageFile.Setup(f => f.Path).Returns("chocolateyInstall.ps1");

package.Setup(p => p.GetFiles()).Returns(new List<IPackageFile>() { packageFile.Object });
}

public override void Because()
{
result = this.requirement.is_valid(package.Object);
}

[Fact]
public void should_not_be_valid()
{
result.Validated.ShouldBeFalse();
}

[Fact]
public void should_not_override_the_base_message()
{
result.ValidationFailureMessageOverride.ShouldBeNull();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Management.Automation">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\lib\PowerShell\System.Management.Automation.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http" />
<Reference Include="System.Reactive.Core">
<HintPath>..\packages\Rx-Core.2.2.5\lib\net40\System.Reactive.Core.dll</HintPath>
Expand Down Expand Up @@ -131,6 +135,7 @@
<Compile Include="infrastructure.app\rules\AdminTagShouldBeIncludedWhenUsingAdminHelpersGuideline.cs" />
<Compile Include="infrastructure.app\rules\AuthorDoesNotMatchMaintainerNote.cs" />
<Compile Include="infrastructure.app\rules\BinariesAreIncludedNote.cs" />
<Compile Include="infrastructure.app\rules\ChecksumShouldBeUsedRequirement.cs" />
<Compile Include="infrastructure.app\rules\ChocoInstallShouldntCallChocoUninstallRequirement.cs" />
<Compile Include="infrastructure.app\rules\CommentsShouldBeCleanedUpRequirement.cs" />
<Compile Include="infrastructure.app\rules\CopyrightAndAuthorFieldsShouldntContainEmailRequirement.cs" />
Expand Down Expand Up @@ -295,7 +300,7 @@
</None>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright © 2015 - Present RealDimensions Software, LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
//
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

namespace chocolatey.package.validator.infrastructure.app.rules
{
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Management.Automation;
using chocolatey.package.validator.infrastructure.rules;
using NuGet;

public class ChecksumShouldBeUsedRequirement : BasePackageRule
{
public override string ValidationFailureMessage { get { return
@"To provide additional security for package installations, checkbums for downloaded binaries should be provided. Your script does not have this, and it will need to be changed. [More...](https://github.com/chocolatey/package-validator/wiki/ChecksumShouldBeUsed)";
}
}

public override PackageValidationOutput is_valid(IPackage package)
{
var valid = true;

foreach (var file in package.GetFiles().or_empty_list_if_null())
{
string extension = Path.GetExtension(file.Path).to_lower();
if (extension != ".ps1" && extension != ".psm1") continue;

var contents = file.GetStream().ReadToEnd().to_lower();

Collection<PSParseError> errors = null;
var tokens = PSParser.Tokenize(contents, out errors);

var methodsThatRequireChecksums = tokens.Where(
p => p.Type == PSTokenType.Command && (
p.Content.to_lower().Contains("get-chocolateywebfile") ||
p.Content.to_lower().Contains("install-chocolateypackage") ||
p.Content.to_lower().Contains("install-chocolateypowershellcommand") ||
p.Content.to_lower().Contains("install-chocolateyvsixpackage") ||
p.Content.to_lower().Contains("install-chocolateyzippackage"))
);

if (methodsThatRequireChecksums.Any())
{
// find all variables and parameters, and check to see if any of them are named checksum
var variables = tokens.Where(p => p.Type == PSTokenType.Variable && p.Content.to_lower() == "checksum");
var parameters = tokens.Where(p => p.Type == PSTokenType.CommandParameter && p.Content.to_lower() == "checksum");

if (!variables.Any() && !parameters.Any())
{
valid = false;
}
}
}

return valid;
}
}
}

0 comments on commit 8eeea91

Please sign in to comment.