ln -s ../security-server-app-permissions.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/security-server-app-permissions.socket
ln -s ../security-server-cookie-get.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/security-server-cookie-get.socket
ln -s ../security-server-cookie-check.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/security-server-cookie-check.socket
+ln -s ../security-server-cookie-check-tmp.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/security-server-cookie-check-tmp.socket
%clean
rm -rf %{buildroot}
%attr(-,root,root) /usr/lib/systemd/system/security-server-cookie-get.socket
%attr(-,root,root) /usr/lib/systemd/system/sockets.target.wants/security-server-cookie-check.socket
%attr(-,root,root) /usr/lib/systemd/system/security-server-cookie-check.socket
-
+%attr(-,root,root) /usr/lib/systemd/system/sockets.target.wants/security-server-cookie-check-tmp.socket
+%attr(-,root,root) /usr/lib/systemd/system/security-server-cookie-check-tmp.socket
%{_datadir}/license/%{name}
*/
int security_server_app_disable_permissions(const char *app_id, app_type_t app_type, const char **perm_list);
+/*
+ * This function allows middleware to get UID assigned to cookie
+ *
+ * \param[in] Cookie
+ * \param[out] Handler to store UID
+ *
+ * \return SECURITY_SERVER_SUCCESS on success or error code on fail
+ */
+int security_server_get_uid_by_cookie(const char *cookie, uid_t *uid);
+
+/*
+ * This function allows middleware to get GID assigned to cookie
+ *
+ * \param[in] Cookie
+ * \param[out] Handler to store GID
+ *
+ * \return SECURITY_SERVER_SUCCESS on success or error code on fail
+ */
+int security_server_get_gid_by_cookie(const char *cookie, gid_t *gid);
+
#ifdef __cplusplus
}
}
//put data into buffer
- Serialization::Serialize(send, (int)CookieGet::COOKIE);
+ Serialization::Serialize(send, (int)CookieCall::GET_COOKIE);
//send buffer to server
int retval = sendToServer(SERVICE_SOCKET_COOKIE_GET, send.Pop(), recv);
try {
//put data into buffer
- Serialization::Serialize(send, (int)CookieGet::PID);
+ Serialization::Serialize(send, (int)CookieCall::CHECK_PID);
Serialization::Serialize(send, key);
//send buffer to server
try {
//put data into buffer
- Serialization::Serialize(send, (int)CookieGet::SMACKLABEL);
+ Serialization::Serialize(send, (int)CookieCall::CHECK_SMACKLABEL);
Serialization::Serialize(send, key);
//send buffer to server
try {
//put data into buffer
- Serialization::Serialize(send, (int)CookieGet::PRIVILEGE_GID);
+ Serialization::Serialize(send, (int)CookieCall::CHECK_PRIVILEGE_GID);
Serialization::Serialize(send, key);
Serialization::Serialize(send, (int)privilege);
try {
//put data into buffer
- Serialization::Serialize(send, (int)CookieGet::PRIVILEGE);
+ Serialization::Serialize(send, (int)CookieCall::CHECK_PRIVILEGE);
Serialization::Serialize(send, key);
Serialization::Serialize(send, obj);
Serialization::Serialize(send, access);
return SECURITY_SERVER_API_ERROR_UNKNOWN;
}
+
+SECURITY_SERVER_API
+int security_server_get_uid_by_cookie(const char *cookie, uid_t *uid)
+{
+ using namespace SecurityServer;
+ SocketBuffer send, recv;
+ int retval = SECURITY_SERVER_API_ERROR_UNKNOWN;
+
+ LogDebug("security_server_get_uid_by_cookie() called");
+
+ if ((cookie == NULL) || (uid == NULL))
+ return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
+
+ //preprae cookie to send
+ std::vector<char> key(cookie, cookie + COOKIE_SIZE);
+
+ try {
+ //put data into buffer
+ Serialization::Serialize(send, (int)CookieCall::CHECK_UID);
+ Serialization::Serialize(send, key);
+
+ //send buffer to server
+ retval = sendToServer(SERVICE_SOCKET_COOKIE_CHECK, send.Pop(), recv);
+ if (retval != SECURITY_SERVER_API_SUCCESS) {
+ LogDebug("Error in sendToServer. Error code: " << retval);
+ return retval;
+ }
+
+ //receive response from server
+ Deserialization::Deserialize(recv, retval);
+ if (retval == SECURITY_SERVER_API_SUCCESS) {
+ int tmp;
+ Deserialization::Deserialize(recv, tmp);
+ *uid = static_cast<uid_t>(tmp);
+ }
+
+ return retval;
+
+ } catch (SocketBuffer::Exception::Base &e) {
+ LogDebug("SecurityServer::SocketBuffer::Exception " << e.DumpToString());
+ } catch (std::exception &e) {
+ LogDebug("STD exception " << e.what());
+ } catch (...) {
+ LogDebug("Unknown exception occured");
+ }
+
+ return SECURITY_SERVER_API_ERROR_UNKNOWN;
+}
+
+SECURITY_SERVER_API
+int security_server_get_gid_by_cookie(const char *cookie, gid_t *gid)
+{
+ using namespace SecurityServer;
+ SocketBuffer send, recv;
+ int retval = SECURITY_SERVER_API_ERROR_UNKNOWN;
+
+ LogDebug("security_server_get_uid_by_cookie() called");
+
+ if ((cookie == NULL) || (gid == NULL))
+ return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
+
+ //preprae cookie to send
+ std::vector<char> key(cookie, cookie + COOKIE_SIZE);
+
+ try {
+ //put data into buffer
+ Serialization::Serialize(send, (int)CookieCall::CHECK_GID);
+ Serialization::Serialize(send, key);
+
+ //send buffer to server
+ retval = sendToServer(SERVICE_SOCKET_COOKIE_CHECK, send.Pop(), recv);
+ if (retval != SECURITY_SERVER_API_SUCCESS) {
+ LogDebug("Error in sendToServer. Error code: " << retval);
+ return retval;
+ }
+
+ //receive response from server
+ Deserialization::Deserialize(recv, retval);
+ if (retval == SECURITY_SERVER_API_SUCCESS) {
+ int tmp;
+ Deserialization::Deserialize(recv, tmp);
+ *gid = static_cast<gid_t>(tmp);
+ }
+
+ return retval;
+
+ } catch (SocketBuffer::Exception::Base &e) {
+ LogDebug("SecurityServer::SocketBuffer::Exception " << e.DumpToString());
+ } catch (std::exception &e) {
+ LogDebug("STD exception " << e.what());
+ } catch (...) {
+ LogDebug("Unknown exception occured");
+ }
+
+ return SECURITY_SERVER_API_ERROR_UNKNOWN;
+}
+
"/tmp/.security-server-api-cookie-get.sock";
char const * const SERVICE_SOCKET_COOKIE_CHECK =
"/tmp/.security-server-api-cookie-check.sock";
+//TODO: Merge bellow socket with the one above. This should be done
+//after security-server-api-cookie-check.sock will be protected by smack and has proper label
+char const * const SERVICE_SOCKET_COOKIE_CHECK_TMP =
+ "/tmp/.security-server-api-cookie-check-tmp.sock";
const size_t COOKIE_SIZE = 20;
extern char const * const SERVICE_SOCKET_APP_PERMISSIONS;
extern char const * const SERVICE_SOCKET_COOKIE_GET;
extern char const * const SERVICE_SOCKET_COOKIE_CHECK;
+extern char const * const SERVICE_SOCKET_COOKIE_CHECK_TMP;
enum class AppPermissionsAction { ENABLE, DISABLE };
-enum class CookieGet
+enum class CookieCall
{
- COOKIE_SIZE,
- COOKIE,
- PID,
- SMACKLABEL,
- PRIVILEGE_GID,
- PRIVILEGE
+ GET_COOKIE,
+ CHECK_PID,
+ CHECK_SMACKLABEL,
+ CHECK_PRIVILEGE_GID,
+ CHECK_PRIVILEGE,
+ CHECK_GID,
+ CHECK_UID
};
extern const size_t COOKIE_SIZE;
//get GID list
- const int LINE_LEN = 128;
const int NAME_SIZE = 64;
- char line[LINE_LEN]; //for storing parsed lines
char filename[NAME_SIZE];
snprintf(filename, NAME_SIZE, "/proc/%d/status", pid);
std::ifstream status(filename, std::ifstream::binary);
-
- while (status.getline(line, LINE_LEN)) { //read line from file
- if (strncmp(line, "Groups:", 7) == 0)
- break;
- }
-
- char delim[] = ": "; //separators for strtok: ' ' and ':'
- char *token = strtok(line, delim); //1st string is "Group:"
- while ((token = strtok(NULL, delim))) {
- int gid = atoi(token);
- newCookie.permissions.push_back(gid);
+ std::string line;
+
+ while (std::getline(status, line)) { //read line from file
+ const char *tmp = line.c_str();
+ if (strncmp(line.c_str(), "Uid:", 4) == 0)
+ newCookie.uid = atoi(&tmp[5]);
+ else if (strncmp(line.c_str(), "Gid:", 4) == 0)
+ newCookie.gid = atoi(&tmp[5]);
+ else if (strncmp(line.c_str(), "Groups:", 7) == 0) {
+ char delim[] = ": "; //separators for strtok: ' ' and ':'
+ char *token = strtok(const_cast<char *>(tmp), delim); //1st string is "Group:"
+ while ((token = strtok(NULL, delim))) {
+ int gid = atoi(token);
+ newCookie.permissions.push_back(gid);
+ }
+ }
}
//DEBUG ONLY
//print info about cookie
LogDebug("Cookie created");
LogDebug("PID: " << newCookie.pid);
+ LogDebug("UID: " << newCookie.uid);
+ LogDebug("GID: " << newCookie.gid);
LogDebug("PATH: " << newCookie.binaryPath);
LogDebug("LABEL: " << newCookie.smackLabel);
for (size_t k = 0; k < newCookie.permissions.size(); k++)
return true;
return false;
+ case CompareType::UID:
+ return (c1.uid == c2.uid);
+
+ case CompareType::GID:
+ return (c1.gid == c2.gid);
+
default:
LogDebug("Wrong function parameters");
return false;
PID,
PATH,
SMACKLABEL,
- PERMISSIONS
+ PERMISSIONS,
+ UID,
+ GID
};
{
std::vector<char> cookieId; //ID key
pid_t pid; //owner PID
+ uid_t uid; //owner UID
+ gid_t gid; //owner GID
std::string binaryPath; //path to owner binary
std::string smackLabel; //owner SMACK label
std::vector<int> permissions; //owner GIDs
//interfaces ID
const int INTERFACE_GET = 0;
const int INTERFACE_CHECK = 1;
+const int INTERFACE_CHECK_TMP = 3;
namespace SecurityServer {
INTERFACE_CHECK,
SERVICE_SOCKET_COOKIE_CHECK
};
+ ServiceDescription sd3 = {
+ "security-server::api-cookie-check",
+ INTERFACE_CHECK_TMP,
+ SERVICE_SOCKET_COOKIE_CHECK_TMP
+ };
ServiceDescriptionVector v;
v.push_back(sd1);
v.push_back(sd2);
+ v.push_back(sd3);
return v;
}
//use received data
if (interfaceID == INTERFACE_GET) {
switch(msgType) {
- case CookieGet::COOKIE:
+ case CookieCall::GET_COOKIE:
LogDebug("Entering get-cookie server side handler");
retval = cookieRequest(send, conn.sock);
break;
};
} else if (interfaceID == INTERFACE_CHECK) {
switch(msgType) {
- case CookieGet::PID:
+ case CookieCall::CHECK_PID:
LogDebug("Entering pid-by-cookie server side handler");
retval = pidByCookieRequest(buffer, send);
break;
- case CookieGet::SMACKLABEL:
+ case CookieCall::CHECK_SMACKLABEL:
LogDebug("Entering smacklabel-by-cookie server side handler");
retval = smackLabelByCookieRequest(buffer, send);
break;
- case CookieGet::PRIVILEGE_GID:
+ case CookieCall::CHECK_PRIVILEGE_GID:
LogDebug("Entering check-privilege-by-cookie-gid server side handler");
retval = privilegeByCookieGidRequest(buffer, send);
break;
- case CookieGet::PRIVILEGE:
+ case CookieCall::CHECK_PRIVILEGE:
LogDebug("Entering check-privilege-by-cookie side handler");
retval = privilegeByCookieRequest(buffer, send);
break;
retval = false;
break;
};
+ } else if (interfaceID == INTERFACE_CHECK_TMP) {
+ //TODO: Merge this interface with INTERFACE_CHECK after INTERFACE_CHECK will be secured by smack
+ switch(msgType) {
+ case CookieCall::CHECK_UID:
+ LogDebug("Entering get-uid-by-cookie side handler");
+ retval = uidByCookieRequest(buffer, send);
+ break;
+
+ case CookieCall::CHECK_GID:
+ LogDebug("Entering get-gid-by-cookie side handler");
+ retval = gidByCookieRequest(buffer, send);
+ break;
+
+ default:
+ LogDebug("Error, unknown function called by client");
+ retval = false;
+ break;
+ };
} else {
LogDebug("Error, wrong interface");
retval = false;
if (searchResult != NULL) {
Serialization::Serialize(send, (int)SECURITY_SERVER_API_SUCCESS);
- Serialization::Serialize(send, searchResult->pid);
+ Serialization::Serialize(send, (int)searchResult->pid);
} else {
Serialization::Serialize(send, (int)SECURITY_SERVER_API_ERROR_NO_SUCH_COOKIE);
}
return true;
}
+bool CookieService::uidByCookieRequest(SocketBuffer &buffer, SocketBuffer &send)
+{
+ std::vector<char> cookieKey;
+
+ Try {
+ Deserialization::Deserialize(buffer, cookieKey);
+ } Catch (SocketBuffer::Exception::Base) {
+ LogDebug("Broken protocol. Closing socket.");
+ return false;
+ }
+
+ Cookie searchPattern;
+ searchPattern.cookieId = cookieKey;
+
+ const Cookie *searchResult = m_cookieJar.SearchCookie(searchPattern, CompareType::COOKIE_ID);
+
+ if (searchResult != NULL) {
+ Serialization::Serialize(send, (int)SECURITY_SERVER_API_SUCCESS);
+ Serialization::Serialize(send, (int)searchResult->uid);
+ } else {
+ Serialization::Serialize(send, (int)SECURITY_SERVER_API_ERROR_NO_SUCH_COOKIE);
+ }
+
+ return true;
+}
+
+bool CookieService::gidByCookieRequest(SocketBuffer &buffer, SocketBuffer &send)
+{
+ std::vector<char> cookieKey;
+
+ Try {
+ Deserialization::Deserialize(buffer, cookieKey);
+ } Catch (SocketBuffer::Exception::Base) {
+ LogDebug("Broken protocol. Closing socket.");
+ return false;
+ }
+
+ Cookie searchPattern;
+ searchPattern.cookieId = cookieKey;
+
+ const Cookie *searchResult = m_cookieJar.SearchCookie(searchPattern, CompareType::COOKIE_ID);
+
+ if (searchResult != NULL) {
+ Serialization::Serialize(send, (int)SECURITY_SERVER_API_SUCCESS);
+ Serialization::Serialize(send, (int)searchResult->gid);
+ } else {
+ Serialization::Serialize(send, (int)SECURITY_SERVER_API_ERROR_NO_SUCH_COOKIE);
+ }
+
+ return true;
+}
+
} // namespace SecurityServer
bool privilegeByCookieGidRequest(SocketBuffer &buffer, SocketBuffer &send);
bool privilegeByCookieRequest(SocketBuffer &buffer, SocketBuffer &send);
+ bool uidByCookieRequest(SocketBuffer &buffer, SocketBuffer &send);
+ bool gidByCookieRequest(SocketBuffer &buffer, SocketBuffer &send);
+
CookieJar m_cookieJar;
SocketInfoMap m_socketInfoMap;
${CMAKE_SOURCE_DIR}/systemd/security-server-app-permissions.socket
${CMAKE_SOURCE_DIR}/systemd/security-server-cookie-get.socket
${CMAKE_SOURCE_DIR}/systemd/security-server-cookie-check.socket
+ ${CMAKE_SOURCE_DIR}/systemd/security-server-cookie-check-tmp.socket
DESTINATION
/usr/lib/systemd/system
)
--- /dev/null
+#This socket should be removed when security-server-api-cookie-check.sock
+#will be protected by smack and has proper label (at the moment it is '*')
+[Socket]
+ListenStream=/tmp/.security-server-api-cookie-check-tmp.sock
+SocketMode=0777
+SmackLabelIPIn=security-server::api-cookie-check
+SmackLabelIPOut=@
+
+Service=security-server.service
+
+[Install]
+WantedBy=sockets.target
Sockets=security-server-app-permissions.socket
Sockets=security-server-cookie-get.socket
Sockets=security-server-cookie-check.socket
+Sockets=security-server-cookie-check-tmp.socket
[Install]
WantedBy=multi-user.target