From: Pawel Polawski
Date: Tue, 3 Sep 2013 15:23:38 +0000 (+0200)
Subject: Implement new API for get GID and UID by cookie
X-Git-Tag: submit/tizen/20140307.131547~75
X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=43b6d1b615b4b027048663f232fce6f8a247c1bc;p=platform%2Fcore%2Fsecurity%2Fsecurity-server.git
Implement new API for get GID and UID by cookie
[Issue#] SSDWSSP-399
[Bug/Feature] New API to security-server
[Cause] Missing API to get UID and GID by cookie
[Solution] New API added
[Verification] Compile, run tests
Change-Id: Ie6f65378a31e65840b682b3a6dc2c9ab3f931ec2
---
diff --git a/packaging/security-server.spec b/packaging/security-server.spec
index bed2e2d..2502a42 100644
--- a/packaging/security-server.spec
+++ b/packaging/security-server.spec
@@ -87,6 +87,7 @@ ln -s ../security-server-get-object-name.socket %{buildroot}/usr/lib/systemd/sys
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}
@@ -133,7 +134,8 @@ systemctl daemon-reload
%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}
diff --git a/src/include/security-server.h b/src/include/security-server.h
index 8561a8f..6ce0934 100644
--- a/src/include/security-server.h
+++ b/src/include/security-server.h
@@ -986,6 +986,26 @@ int security_server_app_enable_permissions(const char *app_id, app_type_t app_ty
*/
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
}
diff --git a/src/server2/client/client-cookie.cpp b/src/server2/client/client-cookie.cpp
index 0c72aa7..27f2201 100644
--- a/src/server2/client/client-cookie.cpp
+++ b/src/server2/client/client-cookie.cpp
@@ -63,7 +63,7 @@ int security_server_request_cookie(char *cookie, size_t bufferSize)
}
//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);
@@ -115,7 +115,7 @@ int security_server_get_cookie_pid(const char *cookie)
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
@@ -162,7 +162,7 @@ char * security_server_get_smacklabel_cookie(const char *cookie)
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
@@ -209,7 +209,7 @@ int security_server_check_privilege(const char *cookie, gid_t privilege)
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);
@@ -255,7 +255,7 @@ int security_server_check_privilege_by_cookie(const char *cookie, const char *ob
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);
@@ -281,3 +281,100 @@ int security_server_check_privilege_by_cookie(const char *cookie, const char *ob
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 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(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 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(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;
+}
+
diff --git a/src/server2/common/protocols.cpp b/src/server2/common/protocols.cpp
index cc9ac5a..6978181 100644
--- a/src/server2/common/protocols.cpp
+++ b/src/server2/common/protocols.cpp
@@ -45,6 +45,10 @@ char const * const SERVICE_SOCKET_COOKIE_GET =
"/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;
diff --git a/src/server2/common/protocols.h b/src/server2/common/protocols.h
index 8eead85..29ee384 100644
--- a/src/server2/common/protocols.h
+++ b/src/server2/common/protocols.h
@@ -38,17 +38,19 @@ extern char const * const SERVICE_SOCKET_GET_OBJECT_NAME;
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;
diff --git a/src/server2/service/cookie-jar.cpp b/src/server2/service/cookie-jar.cpp
index 5b1ff50..0c80aea 100644
--- a/src/server2/service/cookie-jar.cpp
+++ b/src/server2/service/cookie-jar.cpp
@@ -108,30 +108,35 @@ const Cookie * CookieJar::GenerateCookie(int pid)
//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(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++)
@@ -207,6 +212,12 @@ bool CookieJar::CompareCookies(const Cookie &c1, const Cookie &c2, CompareType c
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;
diff --git a/src/server2/service/cookie-jar.h b/src/server2/service/cookie-jar.h
index 416b3d1..3921ff2 100644
--- a/src/server2/service/cookie-jar.h
+++ b/src/server2/service/cookie-jar.h
@@ -41,7 +41,9 @@ enum class CompareType
PID,
PATH,
SMACKLABEL,
- PERMISSIONS
+ PERMISSIONS,
+ UID,
+ GID
};
@@ -49,6 +51,8 @@ struct Cookie
{
std::vector 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 permissions; //owner GIDs
diff --git a/src/server2/service/cookie.cpp b/src/server2/service/cookie.cpp
index ac5d8fe..cadba47 100644
--- a/src/server2/service/cookie.cpp
+++ b/src/server2/service/cookie.cpp
@@ -36,6 +36,7 @@
//interfaces ID
const int INTERFACE_GET = 0;
const int INTERFACE_CHECK = 1;
+const int INTERFACE_CHECK_TMP = 3;
namespace SecurityServer {
@@ -50,9 +51,15 @@ GenericSocketService::ServiceDescriptionVector CookieService::GetServiceDescript
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;
}
@@ -116,7 +123,7 @@ bool CookieService::readOne(const ConnectionID &conn, SocketBuffer &buffer, int
//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;
@@ -128,26 +135,44 @@ bool CookieService::readOne(const ConnectionID &conn, SocketBuffer &buffer, int
};
} 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;
+ default:
+ LogDebug("Error, unknown function called by client");
+ 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;
@@ -208,7 +233,7 @@ bool CookieService::pidByCookieRequest(SocketBuffer &buffer, SocketBuffer &send)
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);
}
@@ -308,5 +333,57 @@ bool CookieService::privilegeByCookieRequest(SocketBuffer &buffer, SocketBuffer
return true;
}
+bool CookieService::uidByCookieRequest(SocketBuffer &buffer, SocketBuffer &send)
+{
+ std::vector 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 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
diff --git a/src/server2/service/cookie.h b/src/server2/service/cookie.h
index 05507f2..78ee0fd 100644
--- a/src/server2/service/cookie.h
+++ b/src/server2/service/cookie.h
@@ -71,6 +71,9 @@ private:
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;
diff --git a/systemd/CMakeLists.txt b/systemd/CMakeLists.txt
index 006e4a3..f0151fc 100644
--- a/systemd/CMakeLists.txt
+++ b/systemd/CMakeLists.txt
@@ -9,6 +9,7 @@ INSTALL(FILES
${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
)
diff --git a/systemd/security-server-cookie-check-tmp.socket b/systemd/security-server-cookie-check-tmp.socket
new file mode 100644
index 0000000..803609b
--- /dev/null
+++ b/systemd/security-server-cookie-check-tmp.socket
@@ -0,0 +1,12 @@
+#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
diff --git a/systemd/security-server.service b/systemd/security-server.service
index c36ed9d..610e6ff 100644
--- a/systemd/security-server.service
+++ b/systemd/security-server.service
@@ -13,6 +13,7 @@ Sockets=security-server-get-object-name.socket
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