#include <dpl/serialization.h>
#include <privilege-control.h>
+#include <sys/types.h>
+#include <sys/socket.h>
#include "installer.h"
#include "protocols.h"
m_connectionInfoMap.erase(event.connectionID.counter);
}
+static bool getPeerUserID(int sock, uid_t *uid) {
+ struct ucred cr;
+ socklen_t len = sizeof (cr);
+ if (!uid) {
+ return false;
+ }
+ if (!getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &cr, &len)) {
+ *uid = cr.uid;
+ return true;
+ }
+ return false;
+}
+
bool InstallerService::processOne(const ConnectionID &conn, MessageBuffer &buffer,
InterfaceID interfaceID)
{
MessageBuffer send;
bool retval = false;
+ uid_t uid;
+
+ if(!getPeerUserID(conn.sock, &uid)) {
+ LogError("Closing socket because of error: unable to get peer's uid");
+ m_serviceManager->Close(conn);
+ return false;
+ }
+
if (INSTALLER_IFACE == interfaceID) {
Try {
// deserialize API call type
switch (call_type) {
case SecurityModuleCall::APP_INSTALL:
LogDebug("call_type: SecurityModuleCall::APP_INSTALL");
- processAppInstall(buffer, send);
+ processAppInstall(buffer, send, uid);
break;
case SecurityModuleCall::APP_UNINSTALL:
LogDebug("call_type: SecurityModuleCall::APP_UNINSTALL");
- processAppUninstall(buffer, send);
+ processAppUninstall(buffer, send, uid);
break;
case SecurityModuleCall::APP_GET_PKGID:
processGetPkgId(buffer, send);
return retval;
}
-bool InstallerService::processAppInstall(MessageBuffer &buffer, MessageBuffer &send)
+static inline bool installRequestAuthCheck(const app_inst_req &req, uid_t uid)
+{
+ for (const auto &appPath : req.appPaths) {
+ app_install_path_type pathType = static_cast<app_install_path_type>(appPath.second);
+ if (pathType == SECURITY_MANAGER_PATH_PUBLIC && uid != 0) {
+ LogDebug("Only root can register SECURITY_MANAGER_PATH_PUBLIC path");
+ return false;
+ }
+ }
+ return true;
+}
+
+bool InstallerService::processAppInstall(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
{
bool pkgIdIsNew = false;
std::vector<std::string> addedPermissions;
Deserialization::Deserialize(buffer, req.privileges);
Deserialization::Deserialize(buffer, req.appPaths);
+ if(!installRequestAuthCheck(req, uid)) {
+ LogError("Request from uid " << uid << " for app installation denied");
+ Serialization::Serialize(send, SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED);
+ return false;
+ }
+
std::string smackLabel;
if (!generateAppLabel(req.pkgId, smackLabel)) {
LogError("Cannot generate Smack label for package: " << req.pkgId);
std::vector<std::string> oldPkgPrivileges, newPkgPrivileges;
m_privilegeDb.BeginTransaction();
- m_privilegeDb.GetPkgPrivileges(req.pkgId, oldPkgPrivileges);
- m_privilegeDb.AddApplication(req.appId, req.pkgId, pkgIdIsNew);
- m_privilegeDb.UpdateAppPrivileges(req.appId, req.privileges);
- m_privilegeDb.GetPkgPrivileges(req.pkgId, newPkgPrivileges);
+ m_privilegeDb.GetPkgPrivileges(req.pkgId, uid, oldPkgPrivileges);
+ m_privilegeDb.AddApplication(req.appId, req.pkgId, uid, pkgIdIsNew);
+ m_privilegeDb.UpdateAppPrivileges(req.appId, uid, req.privileges);
+ m_privilegeDb.GetPkgPrivileges(req.pkgId, uid, newPkgPrivileges);
// TODO: configure Cynara rules based on oldPkgPrivileges and newPkgPrivileges
m_privilegeDb.CommitTransaction();
LogDebug("Application installation commited to database");
return false;
}
-bool InstallerService::processAppUninstall(MessageBuffer &buffer, MessageBuffer &send)
+bool InstallerService::processAppUninstall(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
{
// deserialize request data
std::string appId;
LogDebug("Unnstall parameters: appId: " << appId << ", pkgId: " << pkgId
<< ", generated smack label: " << smackLabel);
- m_privilegeDb.GetPkgPrivileges(pkgId, oldPkgPrivileges);
- m_privilegeDb.UpdateAppPrivileges(appId, std::vector<std::string>());
- m_privilegeDb.RemoveApplication(appId, removePkg);
- m_privilegeDb.GetPkgPrivileges(pkgId, newPkgPrivileges);
+ m_privilegeDb.GetPkgPrivileges(pkgId, uid, oldPkgPrivileges);
+ m_privilegeDb.UpdateAppPrivileges(appId, uid, std::vector<std::string>());
+ m_privilegeDb.RemoveApplication(appId, uid, removePkg);
+ m_privilegeDb.GetPkgPrivileges(pkgId, uid, newPkgPrivileges);
// TODO: configure Cynara rules based on oldPkgPrivileges and newPkgPrivileges
m_privilegeDb.CommitTransaction();
LogDebug("Application uninstallation commited to database");