From: Bartlomiej Grzelewski Date: Thu, 1 Jun 2017 10:12:09 +0000 (+0200) Subject: Accept null as appId during license extraction X-Git-Tag: accepted/tizen/unified/20170703.064244~8 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=264ef0cba747a2849accd9cbec6df7d0989abc00;p=platform%2Fcore%2Fsecurity%2Fsecurity-manager.git Accept null as appId during license extraction In non-hybrid application appId is not placed inside smack label. Non-hybrid application could not be idenitified. We can only retrieve its pkgId. Change-Id: I52d35fab45dbf494dfc8a2de84c38d63d29b781d --- diff --git a/src/client/client-security-manager.cpp b/src/client/client-security-manager.cpp index b449b82..32037da 100644 --- a/src/client/client-security-manager.cpp +++ b/src/client/client-security-manager.cpp @@ -534,7 +534,7 @@ struct kernel_sigaction { }; #if __x86_64__ -void restore_rt(void) __asm__ ("__restore_rt"); +void restore_rt(void) __asm__("__restore_rt"); #define RESTORE(name, syscall) RESTORE2(name, syscall) #define RESTORE2(name, syscall) \ @@ -1705,21 +1705,23 @@ int security_manager_get_app_defined_privilege_license( SECURITY_MANAGER_API int security_manager_get_client_privilege_license( const char *privilege, + const char *pkg_name, const char *app_name, uid_t uid, char **license) { return try_catch([&]() -> int { using namespace SecurityManager; + std::string appName(app_name ? app_name : ""); LogDebug(__PRETTY_FUNCTION__ << " called"); - if (privilege == NULL || app_name == NULL || license == NULL) { - LogError("privilege, app_name, license could not be NULL"); + if (!privilege || !pkg_name || !license) { + LogError("privilege, pkg_name, license could not be NULL"); return SECURITY_MANAGER_ERROR_INPUT_PARAM; } ClientRequest request(SecurityModuleCall::GET_CLIENT_PRIVILEGE_LICENSE); - if (request.send(std::string(app_name), uid, std::string(privilege)).failed()) + if (request.send(appName, std::string(pkg_name), uid, std::string(privilege)).failed()) return request.getStatus(); std::string licenseString; diff --git a/src/common/include/privilege_db.h b/src/common/include/privilege_db.h index d4f4210..3465eb3 100644 --- a/src/common/include/privilege_db.h +++ b/src/common/include/privilege_db.h @@ -86,9 +86,10 @@ enum class StmtType { ERemoveAppDefinedPrivileges, ERemoveClientPrivileges, EGetAppDefinedPrivileges, - EGetAppAndLicenseForAppDefinedPrivilege, - EGetLicenseForClientPrivilege, - EIsUserAppInstalled, + EGetAppPkgLicenseForAppDefinedPrivilege, + EGetLicenseForClientPrivilegeAndApp, + EGetLicenseForClientPrivilegeAndPkg, + EIsUserPkgInstalled, }; // privilege, app_defined_privilege_type, license @@ -152,9 +153,10 @@ private: { StmtType::ERemoveAppDefinedPrivileges, "DELETE FROM app_defined_privilege_view WHERE app_name = ? AND uid = ?"}, { StmtType::ERemoveClientPrivileges, "DELETE FROM client_license_view WHERE app_name = ? AND uid = ?"}, { StmtType::EGetAppDefinedPrivileges, "SELECT privilege, type, license FROM app_defined_privilege_view WHERE app_name = ? AND uid = ?"}, - { StmtType::EGetAppAndLicenseForAppDefinedPrivilege, "SELECT app_name, license FROM app_defined_privilege_view WHERE uid = ? AND privilege = ?"}, - { StmtType::EGetLicenseForClientPrivilege, "SELECT license FROM client_license_view WHERE app_name = ? AND uid = ? AND privilege = ? "}, - { StmtType::EIsUserAppInstalled, "SELECT count(*) FROM user_app_pkg_view WHERE app_name = ? AND uid = ?"}, + { StmtType::EGetAppPkgLicenseForAppDefinedPrivilege, "SELECT app_name, pkg_name, license FROM app_defined_privilege_view WHERE uid = ? AND privilege = ?"}, + { StmtType::EGetLicenseForClientPrivilegeAndApp, "SELECT license FROM client_license_view WHERE app_name = ? AND uid = ? AND privilege = ? "}, + { StmtType::EGetLicenseForClientPrivilegeAndPkg, "SELECT license FROM client_license_view WHERE pkg_name = ? AND uid = ? AND privilege = ? "}, + { StmtType::EIsUserPkgInstalled, "SELECT count(*) FROM user_app_pkg_view WHERE pkg_name = ? AND uid = ?"}, }; /** @@ -627,15 +629,17 @@ public: * @param[in] uid - user identifier * @param[in] privilege - privilege identifier * @param[out] appName - application identifier + * @param[out] pkgName - application package * @param[out] license - verification factor required by license-manager * * @exception PrivilegeDb::Exception::InternalError on internal error * @exception PrivilegeDb::Exception::ConstraintError on constraint violation * @return true if data were found in the database */ - bool GetAppAndLicenseForAppDefinedPrivilege(uid_t uid, + bool GetAppPkgLicenseForAppDefinedPrivilege(uid_t uid, const std::string &privilege, std::string &appName, + std::string &pkgName, std::string &license); /** @@ -650,18 +654,35 @@ public: * @exception PrivilegeDb::Exception::ConstraintError on constraint violation * @return true if data were found in the database */ - bool GetLicenseForClientPrivilege(const std::string &appName, - uid_t uid, - const std::string &privilege, - std::string &license); + bool GetLicenseForClientPrivilegeAndApp(const std::string &appName, + uid_t uid, + const std::string &privilege, + std::string &license); + /** + * Retrieve license of client application + * + * @param[in] pkgName - application package + * @param[in] uid - user identifier + * @param[in] privilege - privilege identifier + * @param[out] license - verification factor required by license-manager + * + * @exception PrivilegeDb::Exception::InternalError on internal error + * @exception PrivilegeDb::Exception::ConstraintError on constraint violation + * @return true if data were found in the database + */ + bool GetLicenseForClientPrivilegeAndPkg(const std::string &pkgName, + uid_t uid, + const std::string &privilege, + std::string &license); + /** - * Check whether user has installed application + * Check whether user has installed package * * @exception PrivilegeDb::Exception::InternalError on internal error * @exception PrivilegeDb::Exception::ConstraintError on constraint violation */ - bool IsUserAppInstalled(const std::string& appName, uid_t uid); + bool IsUserPkgInstalled(const std::string& pkgName, uid_t uid); }; } //namespace SecurityManager diff --git a/src/common/include/service_impl.h b/src/common/include/service_impl.h index 7366867..782dff0 100644 --- a/src/common/include/service_impl.h +++ b/src/common/include/service_impl.h @@ -277,14 +277,16 @@ public: * Retrieves the license associated with given privilege and uid. * * @param[in] appName application identifier + * @param[in] pkgName package identifier + * * @param[in] uid user identifier * @param[in] privilege privilege name * @param[out] license returns license information connected with privilege * * @return API return code, as defined in protocols.h */ - int getClientPrivilegeLicense(const std::string &appName, uid_t uid, - const std::string &privilege, + int getClientPrivilegeLicense(const std::string &appName, const std::string &pkgName, + uid_t uid, const std::string &privilege, std::string &license); private: @@ -345,6 +347,8 @@ private: int validatePolicy(const Credentials &creds, policy_entry &policyEntry, CynaraAdminPolicy &cyap); + int getAppDefinedPrivilegeDescription(uid_t uid, const std::string &privilege, std::string &appName, std::string &pkgName, std::string &license); + Cynara m_cynara; PrivilegeDb m_privilegeDb; CynaraAdmin m_cynaraAdmin; diff --git a/src/common/privilege_db.cpp b/src/common/privilege_db.cpp index 9ee6569..3f955e8 100644 --- a/src/common/privilege_db.cpp +++ b/src/common/privilege_db.cpp @@ -687,24 +687,27 @@ void PrivilegeDb::GetAppDefinedPrivileges(const std::string &appName, uid_t uid, }); } -bool PrivilegeDb::GetAppAndLicenseForAppDefinedPrivilege( +bool PrivilegeDb::GetAppPkgLicenseForAppDefinedPrivilege( uid_t uid, const std::string &privilege, std::string &appName, + std::string &pkgName, std::string &license) { return try_catch([&] { appName.clear(); + pkgName.clear(); license.clear(); - auto command = getStatement(StmtType::EGetAppAndLicenseForAppDefinedPrivilege); + auto command = getStatement(StmtType::EGetAppPkgLicenseForAppDefinedPrivilege); command->BindInteger(1, uid); command->BindString(2, privilege); if (command->Step()) { appName = command->GetColumnString(0); - license = command->GetColumnString(1); - LogDebug("Privilege: " << privilege << " defined by " << appName); + pkgName = command->GetColumnString(1); + license = command->GetColumnString(2); + LogDebug("Privilege: " << privilege << " defined by " << appName << " " << pkgName); return true; } @@ -713,7 +716,7 @@ bool PrivilegeDb::GetAppAndLicenseForAppDefinedPrivilege( }); } -bool PrivilegeDb::GetLicenseForClientPrivilege( +bool PrivilegeDb::GetLicenseForClientPrivilegeAndApp( const std::string &appName, uid_t uid, const std::string &privilege, @@ -722,7 +725,7 @@ bool PrivilegeDb::GetLicenseForClientPrivilege( return try_catch([&] { license.clear(); - auto command = getStatement(StmtType::EGetLicenseForClientPrivilege); + auto command = getStatement(StmtType::EGetLicenseForClientPrivilegeAndApp); command->BindString(1, appName); command->BindInteger(2, uid); command->BindString(3, privilege); @@ -740,11 +743,38 @@ bool PrivilegeDb::GetLicenseForClientPrivilege( }); } -bool PrivilegeDb::IsUserAppInstalled(const std::string& appName, uid_t uid) +bool PrivilegeDb::GetLicenseForClientPrivilegeAndPkg( + const std::string &pkgName, + uid_t uid, + const std::string &privilege, + std::string &license) +{ + return try_catch([&] { + license.clear(); + + auto command = getStatement(StmtType::EGetLicenseForClientPrivilegeAndPkg); + command->BindString(1, pkgName); + command->BindInteger(2, uid); + command->BindString(3, privilege); + + if (command->Step()) { + license = command->GetColumnString(0); + LogDebug("License found for pkg: " << pkgName << " privilege: " << + privilege << " uid: " << uid << " License: " << license); + return true; + } + + LogDebug("License not found for pkg: " << pkgName << " privilege: " << + privilege << " uid: " << uid); + return false; + }); +} + +bool PrivilegeDb::IsUserPkgInstalled(const std::string& pkgName, uid_t uid) { return try_catch([&]() -> bool { - auto command = getStatement(StmtType::EIsUserAppInstalled); - command->BindString(1, appName); + auto command = getStatement(StmtType::EIsUserPkgInstalled); + command->BindString(1, pkgName); command->BindInteger(2, uid); int isInstalled = 0; diff --git a/src/common/service_impl.cpp b/src/common/service_impl.cpp index 0e49485..a46c0de 100644 --- a/src/common/service_impl.cpp +++ b/src/common/service_impl.cpp @@ -1756,79 +1756,112 @@ int ServiceImpl::shmAppName(const Credentials &creds, const std::string &shmName return SECURITY_MANAGER_SUCCESS; } -int ServiceImpl::getAppDefinedPrivilegeProvider(uid_t uid, const std::string &privilege, - std::string &appName, std::string &pkgName) +int ServiceImpl::getAppDefinedPrivilegeDescription( + uid_t uid, + const std::string &privilege, + std::string &appName, + std::string &pkgName, + std::string &license) { - std::string appNameString, pkgNameString, licenseString; try { - // Get appName and License - if (!m_privilegeDb.GetAppAndLicenseForAppDefinedPrivilege(uid, privilege, appNameString, licenseString) && - !m_privilegeDb.GetAppAndLicenseForAppDefinedPrivilege(getGlobalUserId(), privilege, appNameString, licenseString)) + // Local provider have priority. Search for local provider. + if (m_privilegeDb.GetAppPkgLicenseForAppDefinedPrivilege(uid, privilege, appName, pkgName, license)) + { + // We found local provider. We may return it. + return SECURITY_MANAGER_SUCCESS; + } + + // Local provider not found. Search for global provider. + std::string localAppName, localPkgName, localLicense; + if (!m_privilegeDb.GetAppPkgLicenseForAppDefinedPrivilege(getGlobalUserId(), privilege, localAppName, localPkgName, localLicense)) { LogDebug("Privilege " << privilege << " not found in database"); return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT; } - // Convert appName to pkgName - m_privilegeDb.GetAppPkgName(appNameString, pkgNameString); - - if (appNameString.empty() || pkgNameString.empty()) { - LogWarning("Could not translate appName to pkgName. appName: " << appName); + // Global provider found. Check if it's not hidden by local installation of application with same pkgName. + if (m_privilegeDb.IsUserPkgInstalled(localPkgName, uid)) + { + // Ups. There is local installation of application with the same pkgId (it does not provide privilege). + // Global provider could not be used! + LogDebug("Local installation hiddes global one. Local installation of pkg: " << localPkgName << " does not support: " << privilege); return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT; } - LogDebug("Privilege: " << privilege << " provided by app: " << appNameString << " pkg: " << pkgNameString); + // Return result + appName = std::move(localAppName); + pkgName = std::move(localPkgName); + license = std::move(localLicense); } catch (const PrivilegeDb::Exception::Base &e) { LogError("Error while getting appName or pkgName from database: " << e.DumpToString()); return SECURITY_MANAGER_ERROR_SERVER_ERROR; } - - appName = appNameString; - pkgName = pkgNameString; return SECURITY_MANAGER_SUCCESS; } -int ServiceImpl::getAppDefinedPrivilegeLicense(uid_t uid, const std::string &privilege, - std::string &license) +int ServiceImpl::getAppDefinedPrivilegeProvider( + uid_t uid, + const std::string &privilege, + std::string &appName, + std::string &pkgName) { - std::string appNameString, licenseString; - try { - if (!m_privilegeDb.GetAppAndLicenseForAppDefinedPrivilege(uid, privilege, appNameString, licenseString) && - !m_privilegeDb.GetAppAndLicenseForAppDefinedPrivilege(getGlobalUserId(), privilege, appNameString, licenseString)) - { - LogDebug("Privilege " << privilege << " is not found in database"); - return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT; - } + std::string localLicense; + return getAppDefinedPrivilegeDescription(uid, privilege, appName, pkgName, localLicense); +} - if (licenseString.empty()) { - LogWarning("Empty license was found in database for privlege: " << privilege); - return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT; - } - } catch (const PrivilegeDb::Exception::Base &e) { - LogError("Error while getting license from database: " << e.DumpToString()); - return SECURITY_MANAGER_ERROR_SERVER_ERROR; +int ServiceImpl::getAppDefinedPrivilegeLicense( + uid_t uid, + const std::string &privilege, + std::string &license) +{ + std::string localAppName, localPkgName, localLicense; + int ret = getAppDefinedPrivilegeDescription(uid, privilege, localAppName, localPkgName, localLicense); + + if (ret != SECURITY_MANAGER_SUCCESS) { + return ret; + } + + if (localLicense.empty()) { + return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT; } - license = licenseString; + license = std::move(localLicense); return SECURITY_MANAGER_SUCCESS; } -int ServiceImpl::getClientPrivilegeLicense(const std::string &appName, uid_t uid, const std::string &privilege, - std::string &license) +int ServiceImpl::getClientPrivilegeLicense( + const std::string &appName, + const std::string &pkgName, + uid_t uid, + const std::string &privilege, + std::string &license) { - std::string licenseString; try { - uid_t requestUid = m_privilegeDb.IsUserAppInstalled(appName, uid) ? uid : getGlobalUserId(); + std::string licenseString; + uid_t requestUid = m_privilegeDb.IsUserPkgInstalled(pkgName, uid) ? uid : getGlobalUserId(); + + if (m_privilegeDb.IsPackageHybrid(pkgName)) { + if (appName.empty()) { + LogDebug("appName could not be empty if you ask about hybrid application"); + return SECURITY_MANAGER_ERROR_INPUT_PARAM; + } - if (!m_privilegeDb.GetLicenseForClientPrivilege(appName, requestUid, privilege, licenseString)) { + if (!m_privilegeDb.GetLicenseForClientPrivilegeAndApp(appName, requestUid, privilege, licenseString)) { + LogDebug("License was not found for privilege: " << privilege << " appId: " << appName << " and uid: " << requestUid); + return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT; + } + } else if (!m_privilegeDb.GetLicenseForClientPrivilegeAndPkg(pkgName, requestUid, privilege, licenseString)) { + LogDebug("License was not found for privilege: " << privilege << " pkgId: " << pkgName << " and uid: " << requestUid); return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT; } + + license = std::move(licenseString); + } catch (const PrivilegeDb::Exception::Base &e) { LogError("Error while getting license for app: " << e.DumpToString()); return SECURITY_MANAGER_ERROR_SERVER_ERROR; } - license = licenseString; return SECURITY_MANAGER_SUCCESS; } diff --git a/src/include/app-runtime.h b/src/include/app-runtime.h index 945b6a9..fa4226d 100644 --- a/src/include/app-runtime.h +++ b/src/include/app-runtime.h @@ -264,11 +264,13 @@ int security_manager_get_app_defined_privilege_license(const char *privilege, * * On successful call license should be freed when caller is done with them. * license parameter will be allocated with malloc so it should be freed with free() function. - * When privilege/app_id/uid is incorrect or not related to any license, this function will - * return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT. + * When privilege/pkg_id/app_id/uid is incorrect or not related to any license, this function + * will return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT. * * \param[in] privilege Privilege name - * \param[in] app_id Id of application that request access to privilege. + * \param[in] pkg_id Package Id of application that request of license. + * \param[in] app_id Id of application that request access to privilege (null for + * non-hybrid application). * \param[in] uid User identifier * \param[out] license Data that will be used to verify access to privilege. If privilege * type is SM_APP_DEFINED_PRIVILEGE_TYPE_UNTRUSTED this value will be @@ -276,6 +278,7 @@ int security_manager_get_app_defined_privilege_license(const char *privilege, * \return API return code or error code */ int security_manager_get_client_privilege_license(const char *privilege, + const char *pkg_id, const char *app_id, uid_t uid, char **license); diff --git a/src/license-manager/agent/agent_logic.cpp b/src/license-manager/agent/agent_logic.cpp index eb96d32..76c1038 100644 --- a/src/license-manager/agent/agent_logic.cpp +++ b/src/license-manager/agent/agent_logic.cpp @@ -101,6 +101,7 @@ int verify(const std::string &smack, int uid, const std::string &privilege) { if (SECURITY_MANAGER_SUCCESS != security_manager_get_client_privilege_license( privilege.c_str(), + clientPkgId, clientAppId, uid, &clientLicensePath)) diff --git a/src/server/service/service.cpp b/src/server/service/service.cpp index 16511bf..983d86b 100644 --- a/src/server/service/service.cpp +++ b/src/server/service/service.cpp @@ -460,11 +460,11 @@ void Service::processGetAppDefinedPrivilegeLicense(MessageBuffer &buffer, Messag void Service::processGetClientPrivilegeLicense(MessageBuffer &buffer, MessageBuffer &send) { int ret; - std::string appName, privilege, license; + std::string appName, pkgName, privilege, license; uid_t uid; - Deserialization::Deserialize(buffer, appName, uid, privilege); - ret = serviceImpl.getClientPrivilegeLicense(appName, uid, privilege, license); + Deserialization::Deserialize(buffer, appName, pkgName, uid, privilege); + ret = serviceImpl.getClientPrivilegeLicense(appName, pkgName, uid, privilege, license); Serialization::Serialize(send, ret); if (ret == SECURITY_MANAGER_SUCCESS) Serialization::Serialize(send, license); diff --git a/test/test_privilege_db_app_defined_privileges.cpp b/test/test_privilege_db_app_defined_privileges.cpp index 82eca27..da33da6 100644 --- a/test/test_privilege_db_app_defined_privileges.cpp +++ b/test/test_privilege_db_app_defined_privileges.cpp @@ -61,7 +61,7 @@ void AppDefinedPrivilegeFixture::checkClientLicense(const std::string &app, uid_ for (unsigned int i = 0; i < privileges.size(); ++i) { std::string license; - BOOST_REQUIRE(expected[i].first == testPrivDb->GetLicenseForClientPrivilege(app, uid, privileges[i], license)); + BOOST_REQUIRE(expected[i].first == testPrivDb->GetLicenseForClientPrivilegeAndApp(app, uid, privileges[i], license)); BOOST_REQUIRE(license == expected[i].second); } } @@ -102,11 +102,12 @@ BOOST_AUTO_TEST_CASE(T1300_app_defined_privileges) PrivilegeDb::Exception::ConstraintError); // check non-existing privilege - std::string appName, license; + std::string appName, pkgName, license; BOOST_REQUIRE_NO_THROW( - testPrivDb->GetAppAndLicenseForAppDefinedPrivilege(uid(1), std::get<0>(privileges[1]), - appName, license)); + testPrivDb->GetAppPkgLicenseForAppDefinedPrivilege(uid(1), std::get<0>(privileges[1]), + appName, pkgName, license)); BOOST_REQUIRE(appName.empty()); + BOOST_REQUIRE(pkgName.empty()); BOOST_REQUIRE(license.empty()); // first application defines second privilege @@ -114,9 +115,10 @@ BOOST_AUTO_TEST_CASE(T1300_app_defined_privileges) // check existing privilege application name BOOST_REQUIRE_NO_THROW( - testPrivDb->GetAppAndLicenseForAppDefinedPrivilege(uid(1), std::get<0>(privileges[1]), - appName, license)); + testPrivDb->GetAppPkgLicenseForAppDefinedPrivilege(uid(1), std::get<0>(privileges[1]), + appName, pkgName, license)); BOOST_REQUIRE(appName == app(1)); + BOOST_REQUIRE(pkgName == pkg(1)); BOOST_REQUIRE(license == std::get<2>(privileges[1])); // check first application privileges @@ -193,7 +195,7 @@ BOOST_AUTO_TEST_CASE(T1400_client_license) // check non-existing privilege std::string license; - BOOST_REQUIRE_NO_THROW(testPrivDb->GetLicenseForClientPrivilege(app(1), uid(1), privilegesA[1].first, license)); + BOOST_REQUIRE_NO_THROW(testPrivDb->GetLicenseForClientPrivilegeAndApp(app(1), uid(1), privilegesA[1].first, license)); BOOST_REQUIRE(license.empty()); // first application use second privilege/license @@ -213,7 +215,7 @@ BOOST_AUTO_TEST_CASE(T1400_client_license) BOOST_REQUIRE_NO_THROW(testPrivDb->AddClientPrivilege(app(2), uid(2), privilegesB[0].first, privilegesB[0].second)); // check non-existing privilege - BOOST_REQUIRE_NO_THROW(testPrivDb->GetLicenseForClientPrivilege(app(2), uid(2), privilegesB[1].first, license)); + BOOST_REQUIRE_NO_THROW(testPrivDb->GetLicenseForClientPrivilegeAndApp(app(2), uid(2), privilegesB[1].first, license)); BOOST_REQUIRE(license.empty()); // second application use second privilege/license