Skip to content

Commit

Permalink
Update winget server com security
Browse files Browse the repository at this point in the history
  • Loading branch information
yao-msft committed Jun 22, 2024
1 parent 38aac87 commit 12d58cc
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 13 deletions.
16 changes: 11 additions & 5 deletions src/AppInstallerCLIPackage/Package.appxmanifest
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?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"
Expand Down Expand Up @@ -61,7 +61,7 @@
</uap5:Extension>
<com:Extension Category="windows.comServer">
<com:ComServer>
<com:ExeServer Executable="WinGetServer\WindowsPackageManagerServer.exe" DisplayName="Windows Package Manager Server" LaunchAndActivationPermission="O:SYG:SYD:(A;;11;;;WD)(A;;11;;;RC)(A;;11;;;AC)(A;;11;;;AN)S:P(ML;;NX;;;S-1-16-0)">
<com:ExeServer Executable="WinGetServer\WindowsPackageManagerServer.exe" DisplayName="Windows Package Manager Server" LaunchAndActivationPermission="O:SYG:SYD:(A;;11;;;WD)(A;;11;;;AC)S:P(ML;;NX;;;S-1-16-4096)">
<com:Class Id ="74CB3139-B7C5-4B9E-9388-E6616DEA288C" DisplayName="PackageManager Server">
</com:Class>
<com:Class Id ="1BD8FF3A-EC50-4F69-AEEE-DF4C9D3BAA96" DisplayName="FindPackagesOptions Server">
Expand All @@ -74,15 +74,21 @@
</com:Class>
<com:Class Id ="AA2A5C04-1AD9-46C4-B74F-6B334AD7EB8C" DisplayName="UninstallOptions Server">
</com:Class>
<com:Class Id ="C9ED7917-66AB-4E31-A92A-F65F18EF7933" DisplayName="Configuration Statics Server">
</com:Class>
<com:Class Id ="8EF324ED-367C-4880-83E5-BB2ABD0B72F6" DisplayName="DownloadOptions Server">
</com:Class>
<com:Class Id ="6484A61D-50FA-41F0-B71E-F4370C6EB37C" DisplayName="AuthenticationArguments Server">
</com:Class>
</com:ExeServer>
</com:ComServer>
</com:Extension>
<com:Extension Category="windows.comServer">
<com:ComServer>
<com:ExeServer Executable="WinGetServer\WindowsPackageManagerServer.exe" DisplayName="Windows Package Manager Configuration Server" LaunchAndActivationPermission="O:SYG:SYD:(A;;11;;;WD)S:P(ML;;NX;;;S-1-16-8192)">
<com:Class Id ="C9ED7917-66AB-4E31-A92A-F65F18EF7933" DisplayName="Configuration Statics Server">
</com:Class>
</com:ExeServer>
</com:ComServer>
</com:Extension>
</Extensions>
</Application>
</Applications>
Expand Down Expand Up @@ -116,4 +122,4 @@
<rescap:Capability Name="packageManagement" />
<rescap:Capability Name="unvirtualizedResources" />
</Capabilities>
</Package>
</Package>
77 changes: 69 additions & 8 deletions src/WinGetServer/WinMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <memory>
#include <string>
#include <string_view>
#include <vector>

// Holds the wwinmain open until COM tells us there are no more server connections
wil::unique_event _comServerExitEvent;
Expand All @@ -35,10 +36,10 @@ HRESULT WindowsPackageManagerServerInitializeRPCServer()
RETURN_HR_IF(HRESULT_FROM_WIN32(status), status != RPC_S_OK);

// The goal of this security descriptor is to restrict RPC server access only to the user in admin mode.
// (ML;;NW;;;HI) specifies a high mandatory integrity level (requires admin).
// (ML;;NRNWNX;;;HI) specifies a high mandatory integrity level (requires admin).

Check failure on line 39 in src/WinGetServer/WinMain.cpp

View workflow job for this annotation

GitHub Actions / Check Spelling

`NRNWNX` is not a recognized word. (unrecognized-spelling)
// (A;;GA;;;UserSID) specifies access only for the user with the user SID (i.e. self).
wil::unique_hlocal_security_descriptor securityDescriptor;
std::string securityDescriptorString = "S:(ML;;NW;;;HI)D:(A;;GA;;;" + userSID + ")";
std::string securityDescriptorString = "S:(ML;;NRNWNX;;;HI)D:(A;;GA;;;" + userSID + ")";

Check failure on line 42 in src/WinGetServer/WinMain.cpp

View workflow job for this annotation

GitHub Actions / Check Spelling

`NRNWNX` is not a recognized word. (unrecognized-spelling)
RETURN_LAST_ERROR_IF(!ConvertStringSecurityDescriptorToSecurityDescriptorA(securityDescriptorString.c_str(), SDDL_REVISION_1, &securityDescriptor, nullptr));

status = RpcServerRegisterIf3(WinGetServerManualActivation_v1_0_s_ifspec, nullptr, nullptr, RPC_IF_ALLOW_LOCAL_ONLY | RPC_IF_AUTOLISTEN, RPC_C_LISTEN_MAX_CALLS_DEFAULT, 0, nullptr, securityDescriptor.get());
Expand Down Expand Up @@ -100,6 +101,49 @@ extern "C" HRESULT CreateInstance(
return S_OK;
}

HRESULT InitializeComSecurity()
{
wil::unique_hlocal_security_descriptor securityDescriptor;
// Allow Everyone and AppContainer access. 3 is COM_RIGHTS_EXECUTE | COM_RIGHTS_EXECUTE_LOCAL
std::string securityDescriptorString = "O:SYG:SYD:(A;;3;;;WD)(A;;3;;;AC)";
RETURN_LAST_ERROR_IF(!ConvertStringSecurityDescriptorToSecurityDescriptorA(securityDescriptorString.c_str(), SDDL_REVISION_1, &securityDescriptor, nullptr));

// Make absolute security descriptor as CoInitializeSecurity required
SECURITY_DESCRIPTOR absoluteSecurityDescriptor;
DWORD securityDescriptorSize = sizeof(SECURITY_DESCRIPTOR);

DWORD daclSize = 0;

Check failure on line 115 in src/WinGetServer/WinMain.cpp

View workflow job for this annotation

GitHub Actions / Check Spelling

`dacl` is not a recognized word. (unrecognized-spelling)
DWORD saclSize = 0;

Check failure on line 116 in src/WinGetServer/WinMain.cpp

View workflow job for this annotation

GitHub Actions / Check Spelling

`sacl` is not a recognized word. (unrecognized-spelling)
DWORD ownerSize = 0;
DWORD groupSize = 0;

// Get required size
BOOL result = MakeAbsoluteSD(securityDescriptor.get(), &absoluteSecurityDescriptor, &securityDescriptorSize, nullptr, &daclSize, nullptr, &saclSize, nullptr, &ownerSize, nullptr, &groupSize);

Check failure on line 121 in src/WinGetServer/WinMain.cpp

View workflow job for this annotation

GitHub Actions / Check Spelling

`sacl` is not a recognized word. (unrecognized-spelling)

Check failure on line 121 in src/WinGetServer/WinMain.cpp

View workflow job for this annotation

GitHub Actions / Check Spelling

`dacl` is not a recognized word. (unrecognized-spelling)
RETURN_HR_IF_MSG(E_FAIL, result || GetLastError() != ERROR_INSUFFICIENT_BUFFER, "MakeAbsoluteSD failed to return buffer sizes");

std::vector<BYTE> dacl(daclSize);

Check failure on line 124 in src/WinGetServer/WinMain.cpp

View workflow job for this annotation

GitHub Actions / Check Spelling

`dacl` is not a recognized word. (unrecognized-spelling)

Check failure on line 124 in src/WinGetServer/WinMain.cpp

View workflow job for this annotation

GitHub Actions / Check Spelling

`dacl` is not a recognized word. (unrecognized-spelling)
std::vector<BYTE> sacl(saclSize);

Check failure on line 125 in src/WinGetServer/WinMain.cpp

View workflow job for this annotation

GitHub Actions / Check Spelling

`sacl` is not a recognized word. (unrecognized-spelling)
std::vector<BYTE> owner(ownerSize);
std::vector<BYTE> group(groupSize);

RETURN_LAST_ERROR_IF(!MakeAbsoluteSD(securityDescriptor.get(), &absoluteSecurityDescriptor, &securityDescriptorSize, (PACL)dacl.data(), &daclSize, (PACL)sacl.data(), &saclSize, (PACL)owner.data(), &ownerSize, (PACL)group.data(), &groupSize));

// Initialize com security
RETURN_IF_FAILED(CoInitializeSecurity(
&absoluteSecurityDescriptor, // Security descriptor
-1, // Authentication services count. -1 is let com choose.
nullptr, // Authentication services array
nullptr, // Reserved
RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, // Authentication level. Validate client and data integrity.
RPC_C_IMP_LEVEL_IMPERSONATE, // Impersonation level. Can impersonate client.
nullptr, // Authentication list
EOAC_NONE, // Additional capabilities
nullptr // Reserved
));

return S_OK;
}

int __stdcall wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPWSTR cmdLine, _In_ int)
{
wil::SetResultLoggingCallback(&WindowsPackageManagerServerWilResultLoggingCallback);
Expand All @@ -115,8 +159,6 @@ int __stdcall wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPWSTR cmdLine,
RETURN_IF_FAILED(globalOptions->Set(COMGLB_EXCEPTION_HANDLING, COMGLB_EXCEPTION_DONOT_HANDLE_ANY));
}

RETURN_IF_FAILED(WindowsPackageManagerServerInitialize());

// Command line parsing
int argc = 0;
LPWSTR* argv = CommandLineToArgvW(cmdLine, &argc);
Expand All @@ -130,18 +172,29 @@ int __stdcall wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPWSTR cmdLine,
manualActivation = true;
}

// For packaged com activation, initialize com security.
// For manual activation, leave as default. We'll not register objects for manual activation.
if (!manualActivation)
{
// This must be called after IGlobalOptions (fast rundown setting cannot be changed after CoInitializeSecurity)
// This must be called before WindowsPackageManagerServerInitialize (when setting the logs
// to Windows.Storage folders, automatic CoInitilizeSecurity is triggered)

Check failure on line 181 in src/WinGetServer/WinMain.cpp

View workflow job for this annotation

GitHub Actions / Check Spelling

`Initilize` is not a recognized word. (unrecognized-spelling)
RETURN_IF_FAILED(InitializeComSecurity());
}

RETURN_IF_FAILED(WindowsPackageManagerServerInitialize());

_comServerExitEvent.create();
RETURN_IF_FAILED(WindowsPackageManagerServerModuleCreate(&_releaseNotifier));
try
{
// Register all the CoCreatableClassWrlCreatorMapInclude classes
RETURN_IF_FAILED(WindowsPackageManagerServerModuleRegister());

// Manual reset event to notify the client that the server is available.
wil::unique_event manualResetEvent;

if (manualActivation)
{
// For manual activation, do not register com objects
// so that only RPC channel can be used.
HANDLE hMutex = NULL;
hMutex = CreateMutex(NULL, FALSE, TEXT("WinGetServerMutex"));
RETURN_LAST_ERROR_IF_NULL(hMutex);
Expand All @@ -157,6 +210,11 @@ int __stdcall wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPWSTR cmdLine,
manualResetEvent = CreateOrOpenServerStartEvent();
manualResetEvent.SetEvent();
}
else
{
// Register all the CoCreatableClassWrlCreatorMapInclude classes
RETURN_IF_FAILED(WindowsPackageManagerServerModuleRegister());
}

_comServerExitEvent.wait();

Expand All @@ -165,7 +223,10 @@ int __stdcall wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPWSTR cmdLine,
manualResetEvent.reset();
}

RETURN_IF_FAILED(WindowsPackageManagerServerModuleUnregister());
if (!manualActivation)
{
RETURN_IF_FAILED(WindowsPackageManagerServerModuleUnregister());
}
}
CATCH_RETURN()

Expand Down

1 comment on commit 12d58cc

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@check-spelling-bot Report

🔴 Please review

See the 📜action log for details.

Unrecognized words (4)

dacl
Initilize
NRNWNX
sacl

Previously acknowledged words that are now absent ata bitspace DACL EPester epth hrow issuetitle mapview Mta oop PFM rzkzqaqjwj sfs STARTUPINFOW testdata visualstudiocode :arrow_right:
Some files were automatically ignored

These sample patterns would exclude them:

^\Qsrc/AppInstallerCLIE2ETests/TestData/AppInstallerTestMsiInstallerV2.msi\E$

You should consider adding them to:

.github/actions/spelling/excludes.txt

File matching is via Perl regular expressions.

To check these files, more of their words need to be in the dictionary than not. You can use patterns.txt to exclude portions, add items to the dictionary (e.g. by adding them to allow.txt), or fix typos.

To accept ✔️ these unrecognized words as correct and remove the previously acknowledged and now absent words, run the following commands

... in a clone of the git@github.com:yao-msft/winget-cli.git repository
on the comsec branch (ℹ️ how do I use this?):

curl -s -S -L 'https://raw.githubusercontent.com/check-spelling/check-spelling/v0.0.21/apply.pl' |
perl - 'https://github.com/yao-msft/winget-cli/actions/runs/9627832328/attempts/1'
Available 📚 dictionaries could cover words not in the 📘 dictionary

This includes both expected items (550) from .github/actions/spelling/expect.txt and unrecognized words (4)

Dictionary Entries Covers
cspell:win32/src/win32.txt 53509 20
cspell:python/src/python/python-lib.txt 3873 3
cspell:python/src/python/python.txt 453 2
cspell:python/src/common/extra.txt 741 2
cspell:php/php.txt 2597 2
cspell:npm/npm.txt 288 2
cspell:django/django.txt 859 2
cspell:csharp/csharp.txt 19 2
cspell:sql/src/tsql.txt 455 1
cspell:scala/scala.txt 833 1

Consider adding them using (in .github/workflows/spelling3.yml):

      with:
        extra_dictionaries:
          cspell:win32/src/win32.txt
          cspell:python/src/python/python-lib.txt
          cspell:python/src/python/python.txt
          cspell:python/src/common/extra.txt
          cspell:php/php.txt
          cspell:npm/npm.txt
          cspell:django/django.txt
          cspell:csharp/csharp.txt
          cspell:sql/src/tsql.txt
          cspell:scala/scala.txt

To stop checking additional dictionaries, add:

      with:
        check_extra_dictionaries: ''
Warnings (2)

See the 📜action log for details.

ℹ️ Warnings Count
ℹ️ binary-file 1
ℹ️ unexpected-line-ending 1

See ℹ️ Event descriptions for more information.

If the flagged items are 🤯 false positives

If items relate to a ...

  • binary file (or some other file you wouldn't want to check at all).

    Please add a file path to the excludes.txt file matching the containing file.

    File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

    ^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

  • well-formed pattern.

    If you can write a pattern that would match it,
    try adding it to the patterns.txt file.

    Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

    Note that patterns can't match multiline strings.

Please sign in to comment.