* @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
* @version 1.0
*/
+
+#include "socket-2-id.h"
+
+#include "access-control.h"
+#include "dpl/log/log.h"
+#include "protocols.h"
+#include "security-manager.h"
+
#include <sys/smack.h>
#include <sys/types.h>
-#include <sys/socket.h>
-
-#include <security-manager.h>
-#include <dpl/log/log.h>
-#include <protocols.h>
-#include <socket-2-id.h>
namespace CKM {
} // namespace anonymous
-int Socket2Id::getCredentialsFromSocket(int sock, std::string &res)
+int Socket2Id::getPeerCred(int sock, ucred &peerCred)
+{
+ socklen_t length = sizeof(ucred);
+
+ if (0 > getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &peerCred, &length)) {
+ LogError("getsockopt failed");
+ return -1;
+ }
+ return 0;
+}
+
+int Socket2IdSmack::getCredentialsFromSocket(int sock, std::string &res)
{
std::vector<char> result(SMACK_LABEL_LEN + 1);
socklen_t length = SMACK_LABEL_LEN;
return assignToString(result, length, res);
if (errno != ERANGE) {
- LogError("getsockopt failed");
+ LogError("getsockopt failed with errno: " << errno);
return -1;
}
return assignToString(result, length, res);
}
-void Socket2Id::mapToDomainClient(std::string &pkgId)
+void Socket2IdSmack::mapToDomainClient(std::string &pkgId)
{
static const std::string subdomainSep = "::";
static const auto systemClientLen = strlen(CLIENT_ID_SYSTEM);
}
}
-void Socket2Id::resetCache()
+int Socket2IdSmack::translate(int sock, CKM::Credentials &creds)
{
- m_stringMap.clear();
-}
+ ucred peerCred;
+ if (0 > Socket2Id::getPeerCred(sock, peerCred))
+ return -1;
+
+ creds.clientUid = peerCred.uid;
-int Socket2Id::translate(int sock, std::string &result)
-{
std::string smack;
if (0 > getCredentialsFromSocket(sock, smack))
return -1;
- StringMap::iterator it = m_stringMap.find(smack);
+ auto it = m_smack2pkgId.find(smack);
- if (it != m_stringMap.end()) {
- result = it->second;
+ if (it != m_smack2pkgId.end()) {
+ creds.client = it->second;
return 0;
}
mapToDomainClient(pkgId);
- result = pkgId;
- m_stringMap.emplace(std::move(smack), std::move(pkgId));
+ creds.client = pkgId;
+ m_smack2pkgId.emplace(std::move(smack), std::move(pkgId));
return 0;
}
+int Socket2IdDac::translate(int sock, CKM::Credentials &creds)
+{
+ ucred peerCred;
+ if (0 > Socket2Id::getPeerCred(sock, peerCred))
+ return -1;
+
+ int ret = security_manager_get_app_owner_uid(peerCred.pid, &creds.clientUid);
+ if (ret == SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT) {
+ if (AccessControl::isSystemService(peerCred.uid)) {
+ LogInfo("System service client");
+ creds.client = CLIENT_ID_SYSTEM;
+ } else {
+ LogInfo("Unrecognized application");
+ creds.client = CLIENT_ID_UNKNOWN;
+ }
+ creds.clientUid = peerCred.uid;
+ return 0;
+ } else if (ret != SECURITY_MANAGER_SUCCESS) {
+ LogError("security_manager_get_app_owner_uid failed");
+ return -1;
+ }
+
+ int retCode = getPkgIdFromSocket(sock, creds.client);
+ return retCode < 0 ? -1: 0;
+}
+
} // namespace CKM
*/
#pragma once
+#include "credentials.h"
+
#include <map>
#include <string>
+#include <sys/socket.h>
+
namespace CKM {
class Socket2Id {
public:
Socket2Id() {}
- int translate(int sock, std::string &result);
- void resetCache();
+ virtual int translate(int sock, CKM::Credentials &creds) = 0;
- virtual ~Socket2Id() {}
+ virtual ~Socket2Id() = default;
+
+protected:
+ int getPeerCred(int sock, ucred &peerCred);
+};
+
+class Socket2IdSmack : public Socket2Id {
+public:
+ int translate(int sock, CKM::Credentials &creds) override;
private:
int getCredentialsFromSocket(int sock, std::string &res);
void mapToDomainClient(std::string &label);
- typedef std::map<std::string, std::string> StringMap;
- StringMap m_stringMap;
+ std::map<std::string, std::string> m_smack2pkgId;
+};
+
+class Socket2IdDac : public Socket2Id {
+public:
+ int translate(int sock, CKM::Credentials &creds) override;
};
} // namespace CKM
#include <systemd/sd-daemon.h>
+#include <security-manager.h>
+
#include <dpl/errno_string.h>
#include <dpl/log/log.h>
#include <cynara.h>
+#include "access-control.h"
+
+
namespace {
#ifdef OVERRIDE_SOCKET_TIMEOUT
int getCredentialsFromSocket(int sock, CKM::Credentials &cred)
{
- static CKM::Socket2Id sock2id;
+ static auto sock2id =
+ CKM::smack_check() ?
+ std::unique_ptr<CKM::Socket2Id>(new CKM::Socket2IdSmack()) :
+ std::unique_ptr<CKM::Socket2Id>(new CKM::Socket2IdDac());
CKM::ClientId client;
- if (0 > sock2id.translate(sock, client))
+ if (0 > sock2id->translate(sock, cred))
return -1;
- ucred peerCred;
- socklen_t length = sizeof(ucred);
-
- if (0 > getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &peerCred, &length)) {
- LogError("getsockopt failed");
- return -1;
- }
-
- cred = CKM::Credentials(peerCred.uid, std::move(client));
return 0;
}