1- // Copyright (C) 2017-2018 Egor Pugin <[email protected] >2- //
3- // This Source Code Form is subject to the terms of the Mozilla Public
4- // License, v. 2.0. If a copy of the MPL was not distributed with this
5- // file, You can obtain one at http://mozilla.org/MPL/2.0/.
1+ /*
2+ * SW - Build System and Package Manager
3+ * Copyright (C) 2017-2020 Egor Pugin
4+ *
5+ * This program is free software: you can redistribute it and/or modify
6+ * it under the terms of the GNU General Public License as published by
7+ * the Free Software Foundation, either version 3 of the License, or
8+ * (at your option) any later version.
9+ *
10+ * This program is distributed in the hope that it will be useful,
11+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+ * GNU General Public License for more details.
14+ *
15+ * You should have received a copy of the GNU General Public License
16+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
17+ */
618
719/*
820TODO:
1325#ifdef _WIN32
1426#undef _WIN32_WINNT
1527#define _WIN32_WINNT 0x0602
28+ #endif
29+
30+ #include " commands.h"
31+
32+ #include < sw/manager/storage.h>
33+
34+ #include < primitives/command.h>
1635
36+ #include < vector>
37+
38+ #ifdef _WIN32
1739#include < windows.h>
1840#include < strsafe.h>
1941#include < Sddl.h>
2446#pragma comment(lib, "Userenv.lib")
2547#endif
2648
27- # include " run.h "
49+ DEFINE_SUBCOMMAND (run, " Run target (if applicable). " );
2850
29- # include < sw/manager/storage.h >
51+ extern Strings targets_to_build;
3052
31- #include < primitives/command.h>
53+ static ::cl::opt<bool > run_app_in_container (" in-container" , ::cl::desc(" Run app in secure container" ), ::cl::sub(subcommand_run));
54+ static ::cl::opt<path> wdir (" wdir" , ::cl::desc(" Working directory" ), ::cl::sub(subcommand_run));
55+ // static ::cl::list<String> env("env", ::cl::desc("Env vars"), ::cl::sub(subcommand_run));
56+ static ::cl::opt<String> target (::cl::Positional, ::cl::Required, ::cl::desc(" Target to run" ), ::cl::sub(subcommand_run));
57+ static ::cl::list<String> args (::cl::Positional, ::cl::ConsumeAfter, ::cl::desc(" Command args" ), ::cl::sub(subcommand_run));
3258
33- bool gRunAppInContainer ;
34-
35- #include < vector>
59+ static void run (const sw::LocalPackage &pkg, primitives::Command &c);
3660
3761#ifdef _WIN32
3862using CreateAppF =
@@ -52,9 +76,6 @@ HRESULT
5276 _Outptr_ PSID *ppsidAppContainerSid);
5377#endif
5478
55- namespace sw
56- {
57-
5879#ifdef _WIN32
5980// List of allowed capabilities for the application
6081// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ne-winnt-well_known_sid_type
@@ -63,10 +84,10 @@ std::vector<WELL_KNOWN_SID_TYPE> app_capabilities
6384 // WinCapabilityPrivateNetworkClientServerSid,
6485};
6586
66- BOOL SetSecurityCapabilities (PSID container_sid, SECURITY_CAPABILITIES *capabilities, PDWORD num_capabilities);
67- BOOL GrantNamedObjectAccess (PSID appcontainer_sid, const path &object_name, SE_OBJECT_TYPE object_type, DWORD access_mask);
87+ static BOOL SetSecurityCapabilities (PSID container_sid, SECURITY_CAPABILITIES *capabilities, PDWORD num_capabilities);
88+ static BOOL GrantNamedObjectAccess (PSID appcontainer_sid, const path &object_name, SE_OBJECT_TYPE object_type, DWORD access_mask);
6889
69- void run (const LocalPackage &pkg, primitives::Command &c)
90+ static void run (const sw:: LocalPackage &pkg, primitives::Command &c)
7091{
7192 PSID sid = NULL ;
7293 SECURITY_CAPABILITIES SecurityCapabilities = { 0 };
@@ -95,12 +116,12 @@ void run(const LocalPackage &pkg, primitives::Command &c)
95116 throw SW_RUNTIME_ERROR (" Cannot load Userenv.dll" );
96117 auto create_app = (CreateAppF)GetProcAddress (userenv, " CreateAppContainerProfile" );
97118 auto derive_app = (DeriveAppF)GetProcAddress (userenv, " DeriveAppContainerSidFromAppContainerName" );
98- if (gRunAppInContainer && !(create_app && derive_app))
119+ if (run_app_in_container && !(create_app && derive_app))
99120 throw SW_RUNTIME_ERROR (" Cannot launch app in container" );
100121
101122 do
102123 {
103- if (gRunAppInContainer )
124+ if (run_app_in_container )
104125 {
105126 auto result = create_app (container_name, pkg_name, container_desc, NULL , 0 , &sid);
106127 if (!SUCCEEDED (result))
@@ -130,14 +151,14 @@ void run(const LocalPackage &pkg, primitives::Command &c)
130151 // set permissions
131152 auto paths = { c.working_directory /* , getStorage().storage_dir_bin*/ , pkg.getDirSrc2 () };
132153 if (!std::all_of (paths.begin (), paths.end (), [&sid, &err](auto &p)
154+ {
155+ if (!GrantNamedObjectAccess (sid, p, SE_FILE_OBJECT, FILE_ALL_ACCESS & ~DELETE))
133156 {
134- if (!GrantNamedObjectAccess (sid, p, SE_FILE_OBJECT, FILE_ALL_ACCESS & ~DELETE))
135- {
136- snprintf (err.data (), err.size (), " Failed to grant explicit access to %s\n " , p.u8string ().c_str ());
137- return false ;
138- }
139- return true ;
140- }))
157+ snprintf (err.data (), err.size (), " Failed to grant explicit access to %s\n " , p.u8string ().c_str ());
158+ return false ;
159+ }
160+ return true ;
161+ }))
141162 break ;
142163
143164 int n = 1 + 1 ; // +1 for uv std handles
@@ -187,7 +208,7 @@ void run(const LocalPackage &pkg, primitives::Command &c)
187208 }
188209}
189210
190- BOOL SetSecurityCapabilities (PSID container_sid, SECURITY_CAPABILITIES *capabilities, PDWORD num_capabilities)
211+ static BOOL SetSecurityCapabilities (PSID container_sid, SECURITY_CAPABILITIES *capabilities, PDWORD num_capabilities)
191212{
192213 DWORD sid_size = SECURITY_MAX_SID_SIZE;
193214 DWORD num_capabilities_ = app_capabilities.size () * sizeof (WELL_KNOWN_SID_TYPE) / sizeof (DWORD);
@@ -231,7 +252,7 @@ BOOL SetSecurityCapabilities(PSID container_sid, SECURITY_CAPABILITIES *capabili
231252 return success;
232253}
233254
234- BOOL GrantNamedObjectAccess (PSID appcontainer_sid, const path &object_name, SE_OBJECT_TYPE object_type, DWORD access_mask)
255+ static BOOL GrantNamedObjectAccess (PSID appcontainer_sid, const path &object_name, SE_OBJECT_TYPE object_type, DWORD access_mask)
235256{
236257 EXPLICIT_ACCESS explicit_access;
237258 PACL original_acl = NULL , new_acl = NULL ;
@@ -277,18 +298,38 @@ BOOL GrantNamedObjectAccess(PSID appcontainer_sid, const path &object_name, SE_O
277298
278299 // MSDN: no need to free original_acl
279300 // if (original_acl)
280- // LocalFree(original_acl);
301+ // LocalFree(original_acl);
281302
282303 if (new_acl)
283304 LocalFree (new_acl);
284305
285306 return success;
286307}
287308#else
288- void run (const PackageId &pkg, primitives::Command &c)
309+ static void run (const PackageId &pkg, primitives::Command &c)
289310{
290311 throw SW_RUNTIME_ERROR (" not implemented" );
291312}
292313#endif
293314
315+ SUBCOMMAND_DECL (run)
316+ {
317+ targets_to_build.push_back (target);
318+
319+ auto swctx = createSwContext ();
320+ auto b = setBuildArgsAndCreateBuildAndPrepare (*swctx, { " ." });
321+ b->build ();
322+
323+ // take last target
324+ auto i = b->getTargetsToBuild ()[sw::PackageId (target)].end () - 1 ;
325+
326+ primitives::Command c;
327+ if (!wdir.empty ())
328+ c.working_directory = wdir;
329+ c.setProgram ((*i)->getInterfaceSettings ()[" output_file" ].getValue ());
330+ for (auto &a : args)
331+ c.push_back (a);
332+
333+ sw::LocalPackage p (swctx->getLocalStorage (), target);
334+ run (p, c);
294335}
0 commit comments