From: Krzysztof Jackiewicz Date: Fri, 17 Apr 2020 12:34:05 +0000 (+0200) Subject: Add smack-privilege tests X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Ftest%2Fsecurity-tests.git;a=commitdiff_plain;h=39db8e6cd80f6b9d73d7956b1ecf129c3e8fc80d Add smack-privilege tests Change-Id: Ic6b5535199e0b6095eda8539db847dc11aef356b --- diff --git a/src/security-manager-tests/CMakeLists.txt b/src/security-manager-tests/CMakeLists.txt index fad161e..e00b5c8 100644 --- a/src/security-manager-tests/CMakeLists.txt +++ b/src/security-manager-tests/CMakeLists.txt @@ -52,6 +52,7 @@ SET(SEC_MGR_SOURCES ${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_public_sharing.cpp ${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_register_paths.cpp ${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_shm.cpp + ${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_smack_privileges.cpp ${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_trusted_sharing.cpp ${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_prepare_app.cpp ${PROJECT_SOURCE_DIR}/src/security-manager-tests/security_manager_tests.cpp diff --git a/src/security-manager-tests/test_cases_smack_privileges.cpp b/src/security-manager-tests/test_cases_smack_privileges.cpp new file mode 100644 index 0000000..6f049ba --- /dev/null +++ b/src/security-manager-tests/test_cases_smack_privileges.cpp @@ -0,0 +1,683 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +using namespace SecurityManagerTest; +using namespace PrivilegeNames; + +namespace { + +const uid_t OWNER_ID = tzplatform_getuid(TZ_SYS_DEFAULT_USER); + +void changePolicy(const AppInstallHelper& app, const std::string& priv, const std::string &level) { + PolicyRequest policyRequest; + PolicyEntry entry(app.getAppId(), std::to_string(app.getUID()), priv); + entry.setLevel(level); + policyRequest.addEntry(entry); + Api::sendPolicy(policyRequest); +} + +} // namespace anonymous + +RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_SMACK_PRIVILEGES) + +RUNNER_CHILD_TEST(smack_privileges_10_no_privileges) +{ + AppInstallHelperExt app("sm_test_sp_10_app"); + { + ScopedInstaller appInstall(app); + app.checkAfterInstall(); + app.checkDeniedPrivileges({PRIV_INTERNET}); + app.checkSmackPrivileges({}, {PRIV_INTERNET}); + { + ScopedAppLauncher appLaunch(app); + app.checkSmackPrivileges({}, {PRIV_INTERNET}); + } + } + app.checkAfterUninstall(); +} + +RUNNER_CHILD_TEST(smack_privileges_20_internet_privilege) +{ + AppInstallHelperExt app("sm_test_sp_20_app"); + app.addPrivileges({PRIV_INTERNET}); + { + ScopedInstaller appInstall(app); + app.checkAfterInstall(); + + // rules absent before app is launched + app.checkSmackPrivileges({}, {PRIV_INTERNET}); + { + ScopedAppLauncher appLaunch(app); + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + } + // rules present after app is terminated + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + } + app.checkAfterUninstall(); + // rules removed after app uninstallation + app.checkSmackPrivileges({}, {PRIV_INTERNET}); +} + +RUNNER_CHILD_TEST(smack_privileges_30_one_after_another) +{ + AppInstallHelperExt app("sm_test_sp_30_app"); + app.addPrivileges({PRIV_INTERNET}); + { + ScopedInstaller appInstall(app); + app.checkAfterInstall(); + + // rules absent before app is launched + app.checkSmackPrivileges({}, {PRIV_INTERNET}); + { + ScopedAppLauncher appLaunch(app); + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + } + // rules present after app is terminated + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + + { + ScopedAppLauncher appLaunch(app); + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + } + // rules present after app is terminated + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + } + app.checkAfterUninstall(); + // rules removed after app uninstallation + app.checkSmackPrivileges({}, {PRIV_INTERNET}); +} + +RUNNER_CHILD_TEST(smack_privileges_40_different_users_one_after_another) +{ + TemporaryTestUser testUser("sm_test_40_user_name", GUM_USERTYPE_NORMAL, true); + testUser.create(); + + AppInstallHelperExt app("sm_test_sp_40_app"); + app.addPrivileges({PRIV_INTERNET}); + { + // global install + ScopedInstaller appInstall(app); + app.checkAfterInstall(); + + app.checkSmackPrivileges({}, {PRIV_INTERNET}); + + // owner launch + { + app.setUidGid(OWNER_ID); + ScopedAppLauncher appLaunch(app); + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + } + + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + + // test user launch + { + app.setUidGid(testUser.getUid()); + ScopedAppLauncher appLaunch(app); + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + } + + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + } + app.checkAfterUninstall(); + app.checkSmackPrivileges({}, {PRIV_INTERNET}); +} + +RUNNER_CHILD_TEST(smack_privileges_50_same_user_simultaneously) +{ + AppInstallHelperExt app("sm_test_sp_50_app", OWNER_ID); + app.addPrivileges({PRIV_INTERNET}); + { + ScopedInstaller appInstall(app); + app.checkAfterInstall(); + + app.checkSmackPrivileges({}, {PRIV_INTERNET}); + { + ScopedAppLauncher appLaunch1(app); + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + { + ScopedAppLauncher appLaunch2(app); + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + } + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + } + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + } + app.checkAfterUninstall(); + app.checkSmackPrivileges({}, {PRIV_INTERNET}); +} + +RUNNER_CHILD_TEST(smack_privileges_60_same_user_interchangeably) +{ + AppInstallHelperExt app("sm_test_sp_60_app", OWNER_ID); + app.addPrivileges({PRIV_INTERNET}); + { + // local install + ScopedInstaller appInstall(app); + app.checkAfterInstall(); + + app.checkSmackPrivileges({}, {PRIV_INTERNET}); + + // owner launch 1 + auto appLaunch1 = std::make_unique(app); + + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + + // owner launch 2 + auto appLaunch2 = std::make_unique(app); + + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + + // owner terminate 1 + appLaunch1.reset(); + + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + + // owner terminate 2 + appLaunch2.reset(); + } + app.checkAfterUninstall(); + app.checkSmackPrivileges({}, {PRIV_INTERNET}); +} + +RUNNER_CHILD_TEST(smack_privileges_70_different_users_simultaneously) +{ + TemporaryTestUser testUser("sm_test_70_user_name", GUM_USERTYPE_NORMAL, true); + testUser.create(); + + AppInstallHelperExt app("sm_test_sp_70_app"); + app.addPrivileges({PRIV_INTERNET}); + { + // global install + ScopedInstaller appInstall(app); + app.checkAfterInstall(); + + app.checkSmackPrivileges({}, {PRIV_INTERNET}); + + // owner launch + { + app.setUidGid(OWNER_ID); + ScopedAppLauncher appLaunch(app); + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + + // test user launch + { + app.setUidGid(testUser.getUid()); + ScopedAppLauncher appLaunch(app); + + // multiuser detected -> rules removed + app.checkSmackPrivileges({}, {PRIV_INTERNET}); + } + app.checkSmackPrivileges({}, {PRIV_INTERNET}); + } + app.checkSmackPrivileges({}, {PRIV_INTERNET}); + + // owner launch + { + app.setUidGid(OWNER_ID); + ScopedAppLauncher appLaunch(app); + + // rules restored + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + } + } + app.checkAfterUninstall(); + app.checkSmackPrivileges({}, {PRIV_INTERNET}); +} + +RUNNER_CHILD_TEST(smack_privileges_80_uninstall_local_while_running) +{ + AppInstallHelperExt app("sm_test_sp_80_app"); + app.addPrivileges({PRIV_INTERNET}); + { + // global install + ScopedInstaller appInstall1(app); + app.checkAfterInstall(); + + app.checkSmackPrivileges({}, {PRIV_INTERNET}); + + // local install + AppInstallHelperExt app2("sm_test_sp_80_app", OWNER_ID); + auto appInstall2 = std::make_unique(app2); + app2.checkAfterInstall(); + + // global launch + ScopedAppLauncher appLaunch(app); + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + + // local uninstall + appInstall2.reset(); + + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + } + app.checkAfterUninstall(); + app.checkSmackPrivileges({}, {PRIV_INTERNET}); +} + +RUNNER_CHILD_TEST(smack_privileges_90_user_removal) +{ + TemporaryTestUser testUser("sm_test_90_user_name", GUM_USERTYPE_NORMAL, true); + testUser.create(); + + AppInstallHelperExt app("sm_test_sp_90_app", testUser.getUid()); + app.addPrivileges({PRIV_INTERNET}); + { + // local install + ScopedInstaller appInstall(app); + app.checkAfterInstall(); + + app.checkSmackPrivileges({}, {PRIV_INTERNET}); + + // local launch + { + ScopedAppLauncher appLaunch(app); + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + } + + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + + // user removal + testUser.remove(); + + app.checkAfterUninstall(); + app.checkSmackPrivileges({}, {PRIV_INTERNET}); + } +} + +RUNNER_CHILD_TEST(smack_privileges_100_hybrid_app) +{ + AppInstallHelperExt app("sm_test_sp_100_app"); + app.addPrivileges({PRIV_INTERNET}); + app.setHybrid(); + { + ScopedInstaller appInstall(app); + app.checkAfterInstall(); + + app.checkSmackPrivileges({}, {PRIV_INTERNET}); + + // launch + { + ScopedAppLauncher appLaunch(app); + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + } + + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + } + app.checkAfterUninstall(); + app.checkSmackPrivileges({}, {PRIV_INTERNET}); +} + +RUNNER_CHILD_TEST(smack_privileges_110_hybridity_change) +{ + AppInstallHelperExt app("sm_test_sp_110_app"); + app.addPrivileges({PRIV_INTERNET}); + { + ScopedInstaller appInstall(app); + app.checkAfterInstall(); + + app.checkSmackPrivileges({}, {PRIV_INTERNET}); + + // launch + { + ScopedAppLauncher appLaunch(app); + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + } + + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + + app.setHybrid(); + + // make it hybrid + InstallRequest request; + request.setAppId(app.getAppId()); + request.setPkgId(app.getPkgId()); + request.setUid(app.getUID()); + request.setHybrid(); + for (const auto &priv: app.getPrivileges()) { + request.addPrivilege(priv); + } + Api::update(request); + + app.checkSmackPrivileges({}, {PRIV_INTERNET}); + + // launch + { + ScopedAppLauncher appLaunch(app); + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + } + + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + } + app.checkAfterUninstall(); + app.checkSmackPrivileges({}, {PRIV_INTERNET}); +} + +RUNNER_CHILD_TEST(smack_privileges_120_policy_change_while_running) +{ + TemporaryTestUser testUser("sm_test_120_user_name", GUM_USERTYPE_NORMAL, true); + testUser.create(); + + AppInstallHelperExt app("sm_test_sp_120_app", testUser.getUid()); + app.addPrivileges({PRIV_INTERNET}); + { + ScopedInstaller appInstall(app); + app.checkAfterInstall(); + + app.checkSmackPrivileges({}, {PRIV_INTERNET}); + + // launch + { + ScopedAppLauncher appLaunch(app); + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + + // change policy + changePolicy(app, PRIV_INTERNET, PolicyEntry::LEVEL_DENY); + + app.checkSmackPrivileges({}, {PRIV_INTERNET}); + + // change policy + changePolicy(app, PRIV_INTERNET, PolicyEntry::LEVEL_ALLOW); + + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + } + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + } + app.checkAfterUninstall(); + app.checkSmackPrivileges({}, {PRIV_INTERNET}); +} + +RUNNER_CHILD_TEST(smack_privileges_130_different_users_and_policies) +{ + TemporaryTestUser testUser("sm_test_130_user_name", GUM_USERTYPE_NORMAL, true); + testUser.create(); + + AppInstallHelperExt app("sm_test_sp_130_app"); + app.addPrivileges({PRIV_INTERNET}); + { + // global install + ScopedInstaller appInstall(app); + app.checkAfterInstall(); + + app.checkSmackPrivileges({}, {PRIV_INTERNET}); + + // test user launch with denied policy + { + app.setUidGid(testUser.getUid()); + changePolicy(app, PRIV_INTERNET, PolicyEntry::LEVEL_DENY); + ScopedAppLauncher appLaunch(app); + app.checkSmackPrivileges({}, {PRIV_INTERNET}); + } + + app.checkSmackPrivileges({}, {PRIV_INTERNET}); + + // owner launch + { + app.setUidGid(OWNER_ID); + ScopedAppLauncher appLaunch(app); + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + } + + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + } + app.checkAfterUninstall(); + app.checkSmackPrivileges({}, {PRIV_INTERNET}); +} + +RUNNER_CHILD_TEST(smack_privileges_140_two_users_sequence) +{ + TemporaryTestUser testUser("sm_test_140_user_name", GUM_USERTYPE_NORMAL, true); + testUser.create(); + + AppInstallHelperExt app("sm_test_sp_140_app"); + app.addPrivileges({PRIV_INTERNET}); + { + // global install + ScopedInstaller appInstall(app); + app.checkAfterInstall(); + app.checkSmackPrivileges({}, {PRIV_INTERNET}); + { + // owner launch -> allowed + app.setUidGid(OWNER_ID); + ScopedAppLauncher appLaunch1(app); + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + { + // test user launch -> denied + app.setUidGid(testUser.getUid()); + ScopedAppLauncher appLaunch2(app); + app.checkSmackPrivileges({}, {PRIV_INTERNET}); + + // owner launch -> denied + app.setUidGid(OWNER_ID); + ScopedAppLauncher appLaunch3(app); + app.checkSmackPrivileges({}, {PRIV_INTERNET}); + } + // test user launch -> still denied + app.setUidGid(testUser.getUid()); + ScopedAppLauncher appLaunch4(app); + app.checkSmackPrivileges({}, {PRIV_INTERNET}); + } + + // test user launch -> allowed + app.setUidGid(testUser.getUid()); + ScopedAppLauncher appLaunch5(app); + app.checkSmackPrivileges({PRIV_INTERNET}, {}); + } + app.checkAfterUninstall(); + app.checkSmackPrivileges({}, {PRIV_INTERNET}); +} + +RUNNER_CHILD_TEST(smack_privileges_150_independent_apps) +{ + TemporaryTestUser testUser("sm_test_150_user_name", GUM_USERTYPE_NORMAL, true); + testUser.create(); + + AppInstallHelperExt app1("sm_test_sp_150_app1", testUser.getUid()); + AppInstallHelperExt app2("sm_test_sp_150_app2", testUser.getUid()); + app1.addPrivileges({PRIV_INTERNET}); + { + ScopedInstaller appInstall1(app1); + ScopedInstaller appInstall2(app2); + + app1.checkAfterInstall(); + app2.checkAfterInstall(); + + app1.checkSmackPrivileges({}, {PRIV_INTERNET}); + app2.checkSmackPrivileges({}, {PRIV_INTERNET}); + + // launch + { + ScopedAppLauncher appLaunch1(app1); + ScopedAppLauncher appLaunch2(app2); + + app1.checkSmackPrivileges({PRIV_INTERNET}, {}); + app2.checkSmackPrivileges({}, {PRIV_INTERNET}); + } + } + app1.checkAfterUninstall(); + app2.checkAfterUninstall(); + app1.checkSmackPrivileges({}, {PRIV_INTERNET}); + app2.checkSmackPrivileges({}, {PRIV_INTERNET}); +} + +RUNNER_CHILD_TEST(smack_privileges_160_nonhybrid_package) +{ + TemporaryTestUser testUser("sm_test_160_user_name", GUM_USERTYPE_NORMAL, true); + testUser.create(); + + constexpr char pkgPrefix[] = "sm_test_sp_160_pkg"; + + AppInstallHelperExt app1("sm_test_sp_160_app1", pkgPrefix, testUser.getUid()); + app1.addPrivileges({PRIV_INTERNET}); + + AppInstallHelperExt app2("sm_test_sp_160_app2", pkgPrefix, testUser.getUid()); + app2.addPrivileges({PRIV_INTERNET}); + { + ScopedInstaller appInstall1(app1); + ScopedInstaller appInstall2(app2); + + app1.checkAfterInstall(); + app2.checkAfterInstall(); + + app1.checkSmackPrivileges({}, {PRIV_INTERNET}); + app2.checkSmackPrivileges({}, {PRIV_INTERNET}); + + // launch + { + ScopedAppLauncher appLaunch1(app1); + ScopedAppLauncher appLaunch2(app2); + + // both have access in non-hybrid package + app1.checkSmackPrivileges({PRIV_INTERNET}, {}); + app2.checkSmackPrivileges({PRIV_INTERNET}, {}); + + // change policy of single app + changePolicy(app1, PRIV_INTERNET, PolicyEntry::LEVEL_DENY); + + // both should lose the access + app1.checkSmackPrivileges({}, {PRIV_INTERNET}); + app2.checkSmackPrivileges({}, {PRIV_INTERNET}); + + changePolicy(app1, PRIV_INTERNET, PolicyEntry::LEVEL_ALLOW); + + app1.checkSmackPrivileges({PRIV_INTERNET}, {}); + app2.checkSmackPrivileges({PRIV_INTERNET}, {}); + } + } + app1.checkAfterUninstall(); + app2.checkAfterUninstall(); + app1.checkSmackPrivileges({}, {PRIV_INTERNET}); + app2.checkSmackPrivileges({}, {PRIV_INTERNET}); +} + + +RUNNER_CHILD_TEST(smack_privileges_170_hybrid_package) +{ + TemporaryTestUser testUser("sm_test_170_user_name", GUM_USERTYPE_NORMAL, true); + testUser.create(); + + constexpr char pkgPrefix[] = "sm_test_sp_170_pkg"; + + AppInstallHelperExt app1("sm_test_sp_170_app1", pkgPrefix, testUser.getUid()); + app1.addPrivileges({PRIV_INTERNET}); + app1.setHybrid(); + + AppInstallHelperExt app2("sm_test_sp_170_app2", pkgPrefix, testUser.getUid()); + app2.setHybrid(); + { + ScopedInstaller appInstall1(app1); + ScopedInstaller appInstall2(app2); + + app1.checkAfterInstall(); + app2.checkAfterInstall(); + + app1.checkSmackPrivileges({}, {PRIV_INTERNET}); + app2.checkSmackPrivileges({}, {PRIV_INTERNET}); + + // launch + { + ScopedAppLauncher appLaunch1(app1); + ScopedAppLauncher appLaunch2(app2); + + // only one have access in a hybrid package + app1.checkSmackPrivileges({PRIV_INTERNET}, {}); + app2.checkSmackPrivileges({}, {PRIV_INTERNET}); + + // change policy of single app + changePolicy(app1, PRIV_INTERNET, PolicyEntry::LEVEL_DENY); + + // both should have no access + app1.checkSmackPrivileges({}, {PRIV_INTERNET}); + app2.checkSmackPrivileges({}, {PRIV_INTERNET}); + + changePolicy(app1, PRIV_INTERNET, PolicyEntry::LEVEL_ALLOW); + + app1.checkSmackPrivileges({PRIV_INTERNET}, {}); + app2.checkSmackPrivileges({}, {PRIV_INTERNET}); + } + } + app1.checkAfterUninstall(); + app2.checkAfterUninstall(); + app1.checkSmackPrivileges({}, {PRIV_INTERNET}); + app2.checkSmackPrivileges({}, {PRIV_INTERNET}); +} + +RUNNER_CHILD_TEST(smack_privileges_180_hybrid_package_both_apps_privileged) +{ + TemporaryTestUser testUser("sm_test_180_user_name", GUM_USERTYPE_NORMAL, true); + testUser.create(); + + constexpr char pkgPrefix[] = "sm_test_sp_180_pkg"; + + AppInstallHelperExt app1("sm_test_sp_180_app1", pkgPrefix, testUser.getUid()); + app1.addPrivileges({PRIV_INTERNET}); + app1.setHybrid(); + + AppInstallHelperExt app2("sm_test_sp_180_app2", pkgPrefix, testUser.getUid()); + app2.addPrivileges({PRIV_INTERNET}); + app2.setHybrid(); + { + ScopedInstaller appInstall1(app1); + ScopedInstaller appInstall2(app2); + + app1.checkAfterInstall(); + app2.checkAfterInstall(); + + app1.checkSmackPrivileges({}, {PRIV_INTERNET}); + app2.checkSmackPrivileges({}, {PRIV_INTERNET}); + + // launch + { + ScopedAppLauncher appLaunch1(app1); + ScopedAppLauncher appLaunch2(app2); + + // only one have access in a hybrid package + app1.checkSmackPrivileges({PRIV_INTERNET}, {}); + app2.checkSmackPrivileges({PRIV_INTERNET}, {}); + + // change policy of single app + changePolicy(app1, PRIV_INTERNET, PolicyEntry::LEVEL_DENY); + + // both should have no access + app1.checkSmackPrivileges({}, {PRIV_INTERNET}); + app2.checkSmackPrivileges({PRIV_INTERNET}, {}); + + changePolicy(app1, PRIV_INTERNET, PolicyEntry::LEVEL_ALLOW); + + app1.checkSmackPrivileges({PRIV_INTERNET}, {}); + app2.checkSmackPrivileges({PRIV_INTERNET}, {}); + } + } + app1.checkAfterUninstall(); + app2.checkAfterUninstall(); + app1.checkSmackPrivileges({}, {PRIV_INTERNET}); + app2.checkSmackPrivileges({}, {PRIV_INTERNET}); +} + +// TODO custom smack privileges