1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // This file contains unit tests for the sid class.
6 
7 #include "sandbox/win/src/sid.h"
8 
9 #include <sddl.h>
10 
11 #include "base/win/atl.h"
12 #include "base/win/windows_version.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 
15 namespace sandbox {
16 
17 namespace {
18 
EqualSid(const Sid & sid,const ATL::CSid & compare_sid)19 bool EqualSid(const Sid& sid, const ATL::CSid& compare_sid) {
20   if (!sid.IsValid())
21     return false;
22   return !!::EqualSid(sid.GetPSID(), const_cast<SID*>(compare_sid.GetPSID()));
23 }
24 
EqualSid(const Sid & sid,const wchar_t * sddl_sid)25 bool EqualSid(const Sid& sid, const wchar_t* sddl_sid) {
26   PSID compare_sid;
27   if (!sid.IsValid())
28     return false;
29   if (!::ConvertStringSidToSid(sddl_sid, &compare_sid))
30     return false;
31   bool equal = !!::EqualSid(sid.GetPSID(), compare_sid);
32   ::LocalFree(compare_sid);
33   return equal;
34 }
35 
36 struct KnownCapabilityTestEntry {
37   WellKnownCapabilities capability;
38   const wchar_t* sddl_sid;
39 };
40 
41 struct NamedCapabilityTestEntry {
42   const wchar_t* capability_name;
43   const wchar_t* sddl_sid;
44 };
45 
46 }  // namespace
47 
48 // Tests the creation of a Sid.
TEST(SidTest,Constructors)49 TEST(SidTest, Constructors) {
50   ATL::CSid sid_world = ATL::Sids::World();
51   PSID sid_world_pointer = const_cast<SID*>(sid_world.GetPSID());
52 
53   // Check the SID* constructor.
54   Sid sid_sid_star(sid_world_pointer);
55   ASSERT_TRUE(EqualSid(sid_sid_star, sid_world));
56 
57   // Check the copy constructor.
58   Sid sid_copy(sid_sid_star);
59   ASSERT_TRUE(EqualSid(sid_copy, sid_world));
60 
61   Sid sid_sddl = Sid::FromSddlString(L"S-1-1-0");
62   ASSERT_TRUE(sid_sddl.IsValid());
63   ASSERT_TRUE(EqualSid(sid_sddl, sid_world));
64 
65   Sid sid_sddl_invalid = Sid::FromSddlString(L"X-1-1-0");
66   ASSERT_FALSE(sid_sddl_invalid.IsValid());
67 
68   Sid sid_sddl_empty = Sid::FromSddlString(L"");
69   ASSERT_FALSE(sid_sddl_empty.IsValid());
70 
71   // Note that the WELL_KNOWN_SID_TYPE constructor is tested in the GetPSID
72   // test. AppContainer related constructors are tested in AppContainer.
73 }
74 
75 // Tests the method GetPSID
TEST(SidTest,GetPSID)76 TEST(SidTest, GetPSID) {
77   // Check for non-null result;
78   ASSERT_NE(nullptr, Sid(::WinLocalSid).GetPSID());
79   ASSERT_NE(nullptr, Sid(::WinCreatorOwnerSid).GetPSID());
80   ASSERT_NE(nullptr, Sid(::WinBatchSid).GetPSID());
81 
82   ASSERT_TRUE(EqualSid(Sid(::WinNullSid), ATL::Sids::Null()));
83 
84   ASSERT_TRUE(EqualSid(Sid(::WinWorldSid), ATL::Sids::World()));
85 
86   ASSERT_TRUE(EqualSid(Sid(::WinDialupSid), ATL::Sids::Dialup()));
87 
88   ASSERT_TRUE(EqualSid(Sid(::WinNetworkSid), ATL::Sids::Network()));
89 
90   ASSERT_TRUE(
91       EqualSid(Sid(::WinBuiltinAdministratorsSid), ATL::Sids::Admins()));
92 
93   ASSERT_TRUE(EqualSid(Sid(::WinBuiltinUsersSid), ATL::Sids::Users()));
94 
95   ASSERT_TRUE(EqualSid(Sid(::WinBuiltinGuestsSid), ATL::Sids::Guests()));
96 
97   ASSERT_TRUE(EqualSid(Sid(::WinProxySid), ATL::Sids::Proxy()));
98 }
99 
TEST(SidTest,KnownCapability)100 TEST(SidTest, KnownCapability) {
101   if (base::win::GetVersion() < base::win::Version::WIN8)
102     return;
103 
104   Sid sid_invalid_well_known =
105       Sid::FromKnownCapability(kMaxWellKnownCapability);
106   EXPECT_FALSE(sid_invalid_well_known.IsValid());
107 
108   const KnownCapabilityTestEntry capabilities[] = {
109       {kInternetClient, L"S-1-15-3-1"},
110       {kInternetClientServer, L"S-1-15-3-2"},
111       {kPrivateNetworkClientServer, L"S-1-15-3-3"},
112       {kPicturesLibrary, L"S-1-15-3-4"},
113       {kVideosLibrary, L"S-1-15-3-5"},
114       {kMusicLibrary, L"S-1-15-3-6"},
115       {kDocumentsLibrary, L"S-1-15-3-7"},
116       {kEnterpriseAuthentication, L"S-1-15-3-8"},
117       {kSharedUserCertificates, L"S-1-15-3-9"},
118       {kRemovableStorage, L"S-1-15-3-10"},
119       {kAppointments, L"S-1-15-3-11"},
120       {kContacts, L"S-1-15-3-12"},
121   };
122 
123   for (auto capability : capabilities) {
124     EXPECT_TRUE(EqualSid(Sid::FromKnownCapability(capability.capability),
125                          capability.sddl_sid))
126         << "Known Capability: " << capability.sddl_sid;
127   }
128 }
129 
TEST(SidTest,NamedCapability)130 TEST(SidTest, NamedCapability) {
131   if (base::win::GetVersion() < base::win::Version::WIN10)
132     return;
133 
134   Sid sid_nullptr = Sid::FromNamedCapability(nullptr);
135   EXPECT_FALSE(sid_nullptr.IsValid());
136 
137   Sid sid_empty = Sid::FromNamedCapability(L"");
138   EXPECT_FALSE(sid_empty.IsValid());
139 
140   const NamedCapabilityTestEntry capabilities[] = {
141       {L"internetClient", L"S-1-15-3-1"},
142       {L"internetClientServer", L"S-1-15-3-2"},
143       {L"registryRead",
144        L"S-1-15-3-1024-1065365936-1281604716-3511738428-"
145        "1654721687-432734479-3232135806-4053264122-3456934681"},
146       {L"lpacCryptoServices",
147        L"S-1-15-3-1024-3203351429-2120443784-2872670797-"
148        "1918958302-2829055647-4275794519-765664414-2751773334"},
149       {L"enterpriseAuthentication", L"S-1-15-3-8"},
150       {L"privateNetworkClientServer", L"S-1-15-3-3"}};
151 
152   for (auto capability : capabilities) {
153     EXPECT_TRUE(EqualSid(Sid::FromNamedCapability(capability.capability_name),
154                          capability.sddl_sid))
155         << "Named Capability: " << capability.sddl_sid;
156   }
157 }
158 
TEST(SidTest,Sddl)159 TEST(SidTest, Sddl) {
160   Sid sid_sddl = Sid::FromSddlString(L"S-1-1-0");
161   ASSERT_TRUE(sid_sddl.IsValid());
162   std::wstring sddl_str;
163   ASSERT_TRUE(sid_sddl.ToSddlString(&sddl_str));
164   ASSERT_EQ(L"S-1-1-0", sddl_str);
165 }
166 
TEST(SidTest,SubAuthorities)167 TEST(SidTest, SubAuthorities) {
168   DWORD world_subauthorities[] = {0};
169   SID_IDENTIFIER_AUTHORITY world_authority = {SECURITY_WORLD_SID_AUTHORITY};
170   Sid sid_world =
171       Sid::FromSubAuthorities(&world_authority, 1, world_subauthorities);
172   ASSERT_TRUE(EqualSid(sid_world, ATL::Sids::World()));
173   ASSERT_TRUE(Sid::FromSubAuthorities(&world_authority, 0, nullptr).IsValid());
174 
175   DWORD admin_subauthorities[] = {32, 544};
176   SID_IDENTIFIER_AUTHORITY nt_authority = {SECURITY_NT_AUTHORITY};
177   Sid sid_admin =
178       Sid::FromSubAuthorities(&nt_authority, 2, admin_subauthorities);
179   ASSERT_TRUE(EqualSid(sid_admin, ATL::Sids::Admins()));
180 }
181 
182 }  // namespace sandbox
183