Skip to content

Commit

Permalink
Add tests. Improve functions.
Browse files Browse the repository at this point in the history
  • Loading branch information
preslavgerchev committed Nov 1, 2024
1 parent f994fc7 commit fd95c69
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 10 deletions.
100 changes: 100 additions & 0 deletions providers/os/resources/packages/windows_appx_manifest_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copyright (c) Mondoo, Inc.
// SPDX-License-Identifier: BUSL-1.1

package packages

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestParseWindowsAppxManifest(t *testing.T) {
manifest := `<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
xmlns:wincap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/windowscapabilities"
IgnorableNamespaces="uap rescap wincap">
<!--
Manual versioning is used for this app.
Appx version should be in sync with version used for the app name in microsoft-windows-diagnosticcomposerhost.appxsetup.man
See https://osgwiki.com/wiki/System_Apps#Servicing
-->
<Identity Name="Microsoft.AAD.BrokerPlugin"
Publisher="CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
ProcessorArchitecture="neutral"
ResourceId="neutral"
Version="1000.19580.1000.0" />
<Properties>
<DisplayName>ms-resource:PackageDisplayName</DisplayName>
<PublisherDisplayName>ms-resource:PublisherDisplayName</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
</Properties>
<Resources>
<Resource Language="en-us" />
</Resources>
<Applications>
<Application Id="App" Executable="Microsoft.AAD.BrokerPlugin.exe" EntryPoint="BrokerPlugin.App">
<uap:VisualElements DisplayName="ms-resource:PackageDisplayName" Square150x150Logo="Assets\Logo.png" Square44x44Logo="Assets\SmallLogo.png" Description="ms-resource:PackageDescription" BackgroundColor="#ffffff" AppListEntry="none">
<uap:SplashScreen Image="Assets\SplashScreen.png" />
</uap:VisualElements>
<Extensions>
<uap:Extension Category="windows.webAccountProvider">
<uap:WebAccountProvider Url="https://login.windows.net" BackgroundEntryPoint="AAD.Core.TokenBackground" />
</uap:Extension>
<uap:Extension Category="windows.appService" EntryPoint="AAD.Core.AppService">
<uap:AppService Name="TBAuthAppService" />
</uap:Extension>
<uap:Extension Category="windows.protocol">
<uap:Protocol Name="ms-aad-brokerplugin">
<uap:DisplayName>ms-resource:PackageDisplayName</uap:DisplayName>
</uap:Protocol>
</uap:Extension>
</Extensions>
</Application>
</Applications>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.10587.0"/>
</Dependencies>
<Capabilities>
<Capability Name="internetClient" />
<uap:Capability Name="enterpriseAuthentication" />
<Capability Name="privateNetworkClientServer" />
<uap:Capability Name="sharedUserCertificates" />
<rescap:Capability Name="deviceManagementAdministrator" />
<rescap:Capability Name="deviceManagementRegistration" />
<rescap:Capability Name="remotePassportAuthentication" />
<rescap:Capability Name="userPrincipalName" />
<rescap:Capability Name="windowsHelloCredentialAccess" />
<!-- needed for detection of Visitor accounts using Windows::System::Internal::UserManager::GetProfileForUser -->
<wincap:Capability Name="userSigninSupport" />
</Capabilities>
<Extensions>
<Extension Category="windows.activatableClass.inProcessServer">
<InProcessServer>
<Path>AAD.Core.dll</Path>
<!-- Value of ActivatableClassId should be the same as BackgroundEntryPoint
value in WebAccountProvider extension.
-->
<ActivatableClass ActivatableClassId="AAD.Core.TokenBackground" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="AAD.Core.AppService" ThreadingModel="both" />
<ActivatableClass ActivatableClassId="AAD.Core.WebAccountProcessor" ThreadingModel="both" />
</InProcessServer>
</Extension>
</Extensions>
</Package>`

man, err := parseAppxManifest([]byte(manifest))
require.NoError(t, err)

require.Equal(t, "neutral", man.arch)
require.Equal(t, "Microsoft.AAD.BrokerPlugin", man.Name)
require.Equal(t, "CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington, C=US", man.Publisher)
require.Equal(t, "1000.19580.1000.0", man.Version)
}
25 changes: 15 additions & 10 deletions providers/os/resources/packages/windows_packages.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,18 +295,22 @@ func (w *WinPkgManager) getAppxPackages() ([]Package, error) {
return nil, err
}

// only win 10+ are compatible with app x packages
if b.Build > 10240 {
// only win 10+ are compatible with app x packages
cmd, err := w.conn.RunCommand(powershell.Wrap(WINDOWS_QUERY_APPX_PACKAGES))
if err != nil {
return nil, fmt.Errorf("could not read appx package list")
}
return ParseWindowsAppxPackages(cmd.Stdout)
return w.getPwshAppxPackages()
}

return []Package{}, nil
}

func (w *WinPkgManager) getPwshAppxPackages() ([]Package, error) {
cmd, err := w.conn.RunCommand(powershell.Wrap(WINDOWS_QUERY_APPX_PACKAGES))
if err != nil {
return nil, fmt.Errorf("could not read appx package list")
}
return ParseWindowsAppxPackages(cmd.Stdout)
}

func (w *WinPkgManager) getFsInstalledApps() ([]Package, error) {
rh := registry.NewRegistryHandler()
defer func() {
Expand Down Expand Up @@ -383,30 +387,31 @@ func (w *WinPkgManager) getFsAppxPackages() ([]Package, error) {
log.Debug().Err(err).Str("path", p).Msg("could not read appx manifest")
continue
}
pkg, err := parseAppxManifest(res)
winAppxPkg, err := parseAppxManifest(res)
if err != nil {
log.Debug().Err(err).Str("path", p).Msg("could not parse appx manifest")
continue
}
pkg := winAppxPkg.toPackage()
pkgs = append(pkgs, pkg)

}
return pkgs, nil
}

func parseAppxManifest(input []byte) (Package, error) {
func parseAppxManifest(input []byte) (winAppxPackages, error) {
manifest := &AppxManifest{}
err := xml.Unmarshal(input, manifest)
if err != nil {
return Package{}, err
return winAppxPackages{}, err
}
pkg := winAppxPackages{
Name: manifest.Identity.Name,
Version: manifest.Identity.Version,
Publisher: manifest.Identity.Publisher,
arch: manifest.Identity.ProcessorArchitecture,
}
return pkg.toPackage(), nil
return pkg, nil
}

func getPackageFromRegistryKey(key registry.RegistryKeyChild) (*Package, error) {
Expand Down
25 changes: 25 additions & 0 deletions providers/os/resources/packages/windows_packages_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,28 @@ func TestGetPackageFromRegistryKeyItems(t *testing.T) {
assert.Equal(t, expected, p)
})
}

func TestToPackage(t *testing.T) {
winAppxPkg := winAppxPackages{
Name: "Microsoft.Windows.Cortana",
Version: "1.11.5.17763",
Publisher: "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
Architecture: 0,
}

pkg := winAppxPkg.toPackage()

expected := Package{
Name: "Microsoft.Windows.Cortana",
Version: "1.11.5.17763",
Arch: "x86",
Format: "windows/appx",
Vendor: "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
CPEs: []string{
"cpe:2.3:a:cn\\=microsoft_corporation\\,_o\\=microsoft_corporation\\,_l\\=redmond\\,_s\\=washington\\,_c\\=us:microsoft.windows.cortana:1.11.5.17763:*:*:*:*:*:*:*",
"cpe:2.3:a:cn\\=microsoft_corporation\\,_o\\=microsoft_corporation\\,_l\\=redmond\\,_s\\=washington\\,_c\\=us:microsoft.windows.cortana:1.11.5:*:*:*:*:*:*:*",
},
}

assert.Equal(t, expected, pkg)
}

0 comments on commit fd95c69

Please sign in to comment.