Name: security-server
Description: Security Server Package
Version: 1.0.1
-Requires: openssl libsmack
-Libs: -L${libdir} -lsecurity-server-client -lsmack
+Requires: openssl libsmack libprivilege-control
+Libs: -L${libdir} -lsecurity-server-client
Cflags: -I${includedir}/security-server
ln -s ../security-server-data-share.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/security-server-data-share.socket
ln -s ../security-server-get-gid.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/security-server-get-gid.socket
ln -s ../security-server-privilege-by-pid.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/security-server-privilege-by-pid.socket
+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-app-privilege-by-name.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/security-server-app-privilege-by-name.socket
%attr(-,root,root) /usr/lib/systemd/system/security-server-get-gid.socket
%attr(-,root,root) /usr/lib/systemd/system/sockets.target.wants/security-server-privilege-by-pid.socket
%attr(-,root,root) /usr/lib/systemd/system/security-server-privilege-by-pid.socket
+%attr(-,root,root) /usr/lib/systemd/system/sockets.target.wants/security-server-app-permissions.socket
+%attr(-,root,root) /usr/lib/systemd/system/security-server-app-permissions.socket
%attr(-,root,root) /usr/lib/systemd/system/sockets.target.wants/security-server-cookie-get.socket
%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
${SERVER2_PATH}/main/server2-main.cpp
${SERVER2_PATH}/service/data-share.cpp
${SERVER2_PATH}/service/get-gid.cpp
+ ${SERVER2_PATH}/service/app-permissions.cpp
${SERVER2_PATH}/service/cookie.cpp
${SERVER2_PATH}/service/cookie-jar.cpp
${SERVER2_PATH}/service/cookie-common.cpp
${SERVER2_PATH}/client/client-common.cpp
${SERVER2_PATH}/client/client-shared-memory.cpp
${SERVER2_PATH}/client/client-get-gid.cpp
+ ${SERVER2_PATH}/client/client-app-permissions.cpp
${SERVER2_PATH}/client/client-cookie.cpp
${SERVER2_PATH}/client/client-privilege-by-pid.cpp
${SERVER2_PATH}/client/client-socket-privilege.cpp
#define SECURITY_SERVER_H
#include <sys/types.h>
-
+#include <privilege-control.h>
/**
* @file security-server.h
const char *object,
const char *access_rights);
+/*
+ * This function allows middleware to check if an app has the specified privilege
+ * enabled.
+ *
+ * \param[in] Application ID
+ * \param[in] Application type
+ * \param[in] Privilege name
+ * \param[out] Handler to store the result. It is set to 1 (true) if privilege is enabled, 0 (false) otherwise
+ *
+ * \return SECURITY_SERVER_API_SUCCESS on success or error code on fail
+ *
+ * Access to this function requires SMACK rule: "<app_label> security-server::api-app-privilege-by-name w"
+ */
+int security_server_app_has_privilege(const char *app_id,
+ app_type_t app_type,
+ const char *privilege_name,
+ int *result);
+
#ifdef __cplusplus
}
#endif
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Bartlomiej Grzelewski <b.grzelewski@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+/*
+ * @file client-app-permissions.cpp
+ * @author Pawel Polawski (pawel.polawski@partner.samsung.com)
+ * @version 1.0
+ * @brief This file contains implementation of
+ * security_server_app_has_privilege function
+ */
+
+
+#include <dpl/log/log.h>
+#include <dpl/exception.h>
+
+#include <message-buffer.h>
+#include <client-common.h>
+#include <protocols.h>
+
+#include <privilege-control.h>
+#include <security-server.h>
+
+SECURITY_SERVER_API
+int security_server_app_has_privilege(const char *app_id,
+ app_type_t app_type,
+ const char *privilege_name,
+ int *result)
+{
+ using namespace SecurityServer;
+ MessageBuffer send, recv;
+
+ LogDebug("security_server_app_has_privilege() called");
+
+ try {
+ if ((NULL == app_id) || (strlen(app_id) == 0)) {
+ LogError("app_id is NULL or empty");
+ return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
+ }
+ if ((NULL == privilege_name) || (strlen(privilege_name) == 0)) {
+ LogError("privilege_name is NULL or empty");
+ return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
+ }
+ if (NULL == result) {
+ LogError("result is NULL");
+ return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
+ }
+
+ LogDebug("app_id: " << app_id);
+ LogDebug("app_type: " << static_cast<int>(app_type));
+ LogDebug("privilege_name: " << privilege_name);
+
+ //put data into buffer
+ Serialization::Serialize(send, static_cast<int>(PrivilegeCheckHdrs::CHECK_GIVEN_APP));
+ Serialization::Serialize(send, std::string(app_id));
+ Serialization::Serialize(send, static_cast<int>(app_type));
+ Serialization::Serialize(send, std::string(privilege_name));
+
+ //send buffer to server
+ int apiResult = sendToServer(SERVICE_SOCKET_APP_PRIVILEGE_BY_NAME, send.Pop(), recv);
+ if (apiResult != SECURITY_SERVER_API_SUCCESS) {
+ LogError("Error in sendToServer. Error code: " << apiResult);
+ return apiResult;
+ }
+
+ //receive response from server
+ Deserialization::Deserialize(recv, apiResult);
+ if (apiResult == SECURITY_SERVER_API_SUCCESS) {
+ Deserialization::Deserialize(recv, *result);
+ }
+ return apiResult;
+
+ } catch (MessageBuffer::Exception::Base &e) {
+ LogError("SecurityServer::MessageBuffer::Exception " << e.DumpToString());
+ } catch (std::exception &e) {
+ LogError("STD exception " << e.what());
+ } catch (...) {
+ LogError("Unknown exception occured");
+ }
+
+ return SECURITY_SERVER_API_ERROR_UNKNOWN;
+}
"/tmp/.security-server-api-get-gid.sock";
char const * const SERVICE_SOCKET_PRIVILEGE_BY_PID =
"/tmp/.security-server-api-privilege-by-pid.sock";
+char const * const SERVICE_SOCKET_APP_PERMISSIONS =
+ "/tmp/.security-server-api-app-permissions.sock";
char const * const SERVICE_SOCKET_APP_PRIVILEGE_BY_NAME =
"/tmp/.security-server-api-app-privilege-by-name.sock";
char const * const SERVICE_SOCKET_COOKIE_GET =
extern char const * const SERVICE_SOCKET_SHARED_MEMORY;
extern char const * const SERVICE_SOCKET_GET_GID;
extern char const * const SERVICE_SOCKET_PRIVILEGE_BY_PID;
+extern char const * const SERVICE_SOCKET_APP_PERMISSIONS;
extern char const * const SERVICE_SOCKET_APP_PRIVILEGE_BY_NAME;
extern char const * const SERVICE_SOCKET_COOKIE_GET;
extern char const * const SERVICE_SOCKET_COOKIE_CHECK;
CHECK_UID
};
+enum class PrivilegeCheckHdrs
+{
+ CHECK_GIVEN_APP,
+ CHECK_CALLER_APP
+};
extern const size_t COOKIE_SIZE;
enum class PasswordHdrs
#include <data-share.h>
#include <get-gid.h>
#include <privilege-by-pid.h>
+#include <app-permissions.h>
#include <cookie.h>
#include <password.h>
#include <installer.h>
REGISTER_SOCKET_SERVICE(manager, SecurityServer::SharedMemoryService);
REGISTER_SOCKET_SERVICE(manager, SecurityServer::GetGidService);
REGISTER_SOCKET_SERVICE(manager, SecurityServer::PrivilegeByPidService);
+ REGISTER_SOCKET_SERVICE(manager, SecurityServer::AppPermissionsService);
REGISTER_SOCKET_SERVICE(manager, SecurityServer::PasswordService);
REGISTER_SOCKET_SERVICE(manager, SecurityServer::InstallerService);
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Bartlomiej Grzelewski <b.grzelewski@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+/*
+ * @file app-permissions.cpp
+ * @author Pawel Polawski (pawel.polawski@partner.samsung.com)
+ * @version 1.0
+ * @brief This file contains implementation of security_server_app_has_permission
+ * on server side
+ */
+
+#include <memory>
+#include <dpl/log/log.h>
+#include <dpl/serialization.h>
+#include <privilege-control.h>
+
+#include <sys/smack.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <app-permissions.h>
+#include <protocols.h>
+#include <security-server.h>
+#include <privilege-control.h>
+
+namespace {
+
+int privilegeToSecurityServerError(int error) {
+ switch (error) {
+ case PC_OPERATION_SUCCESS: return SECURITY_SERVER_API_SUCCESS;
+ case PC_ERR_FILE_OPERATION: return SECURITY_SERVER_API_ERROR_UNKNOWN;
+ case PC_ERR_MEM_OPERATION: return SECURITY_SERVER_API_ERROR_OUT_OF_MEMORY;
+ case PC_ERR_NOT_PERMITTED: return SECURITY_SERVER_API_ERROR_ACCESS_DENIED;
+ case PC_ERR_INVALID_PARAM: return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
+ case PC_ERR_INVALID_OPERATION:
+ case PC_ERR_DB_OPERATION:
+ default:
+ ;
+ }
+ return SECURITY_SERVER_API_ERROR_UNKNOWN;
+}
+
+// interface ids
+const SecurityServer::InterfaceID CHANGE_APP_PERMISSIONS = 0;
+const SecurityServer::InterfaceID CHECK_APP_PRIVILEGE = 1;
+
+} // namespace anonymous
+
+namespace SecurityServer {
+
+GenericSocketService::ServiceDescriptionVector AppPermissionsService::GetServiceDescription() {
+ return ServiceDescriptionVector {
+ { SERVICE_SOCKET_APP_PERMISSIONS,
+ "security-server::api-app-permissions",
+ CHANGE_APP_PERMISSIONS },
+ { SERVICE_SOCKET_APP_PRIVILEGE_BY_NAME,
+ "security-server::api-app-privilege-by-name",
+ CHECK_APP_PRIVILEGE }
+ };
+}
+
+void AppPermissionsService::accept(const AcceptEvent &event) {
+ LogDebug("Accept event. ConnectionID.sock: " << event.connectionID.sock
+ << " ConnectionID.counter: " << event.connectionID.counter
+ << " ServiceID: " << event.interfaceID);
+ auto &info = m_connectionInfoMap[event.connectionID.counter];
+ info.interfaceID = event.interfaceID;
+}
+
+void AppPermissionsService::write(const WriteEvent &event) {
+ LogDebug("WriteEvent. ConnectionID: " << event.connectionID.sock <<
+ " Size: " << event.size << " Left: " << event.left);
+ if (event.left == 0)
+ m_serviceManager->Close(event.connectionID);
+}
+
+void AppPermissionsService::process(const ReadEvent &event) {
+ LogDebug("Read event for counter: " << event.connectionID.counter);
+ auto &info = m_connectionInfoMap[event.connectionID.counter];
+ info.buffer.Push(event.rawBuffer);
+
+ // We can get several requests in one package.
+ // Extract and process them all
+ while(processOne(event.connectionID, info.buffer, info.interfaceID));
+}
+
+void AppPermissionsService::close(const CloseEvent &event) {
+ LogDebug("CloseEvent. ConnectionID: " << event.connectionID.sock);
+ m_connectionInfoMap.erase(event.connectionID.counter);
+}
+
+bool AppPermissionsService::processOne(const ConnectionID &conn,
+ MessageBuffer &buffer,
+ InterfaceID interfaceID)
+{
+ LogDebug("Begin of an iteration");
+
+ //waiting for all data
+ if (!buffer.Ready()) {
+ return false;
+ }
+
+ LogDebug("Entering app_permissions server side handler");
+
+ switch(interfaceID) {
+
+ case CHECK_APP_PRIVILEGE:
+ return processCheckAppPrivilege(conn, buffer);
+
+ default:
+ LogDebug("Unknown interfaceId. Closing socket.");
+ m_serviceManager->Close(conn);
+ return false;
+ }
+}
+
+bool AppPermissionsService::processCheckAppPrivilege(const ConnectionID &conn, MessageBuffer &buffer)
+{
+ MessageBuffer send;
+ std::string privilege_name;
+ std::string app_id;
+ int result = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
+ app_type_t app_type;
+ bool has_permission = false;
+ PrivilegeCheckHdrs checkType = PrivilegeCheckHdrs::CHECK_GIVEN_APP;
+
+ LogDebug("Processing app privilege check request");
+
+ //receive data from buffer
+ Try {
+ int temp;
+ Deserialization::Deserialize(buffer, temp); // call type
+ checkType = static_cast<PrivilegeCheckHdrs>(temp);
+ LogDebug("App privilege check call type: "
+ << (checkType == PrivilegeCheckHdrs::CHECK_GIVEN_APP ?
+ "CHECK_GIVEN_APP":"CHECK_CALLER_APP"));
+ if (checkType == PrivilegeCheckHdrs::CHECK_GIVEN_APP) { //app_id present only in this case
+ Deserialization::Deserialize(buffer, app_id); //get app id
+ }
+ Deserialization::Deserialize(buffer, temp); //get app type
+ app_type = static_cast<app_type_t>(temp);
+
+ Deserialization::Deserialize(buffer, privilege_name); //get privilege name
+ } Catch (MessageBuffer::Exception::Base) {
+ LogDebug("Broken protocol. Closing socket.");
+ m_serviceManager->Close(conn);
+ return false;
+ }
+
+ if (checkType == PrivilegeCheckHdrs::CHECK_CALLER_APP) { //get sender app_id in this case
+ char *label = NULL;
+ if (smack_new_label_from_socket(conn.sock, &label) < 0) {
+ LogDebug("Error in smack_new_label_from_socket(): "
+ "client label is unknown. Sending error response.");
+ Serialization::Serialize(send, SECURITY_SERVER_API_ERROR_GETTING_SOCKET_LABEL_FAILED);
+ m_serviceManager->Write(conn, send.Pop());
+ return false;
+ } else {
+ app_id = label;
+ free(label);
+ }
+ } //end if
+
+ //print received data
+ LogDebug("app_id: " << app_id);
+ LogDebug("app_type: " << static_cast<int>(app_type));
+ LogDebug("privilege_name: " << privilege_name);
+
+ LogDebug("Calling perm_app_has_permission()");
+ result = perm_app_has_permission(app_id.c_str(), app_type, privilege_name.c_str(), &has_permission);
+ LogDebug("perm_app_has_permission() returned: " << result << " , permission enabled: " << has_permission);
+
+ //send response
+ Serialization::Serialize(send, privilegeToSecurityServerError(result));
+ Serialization::Serialize(send, static_cast<int>(has_permission));
+ m_serviceManager->Write(conn, send.Pop());
+ return true;
+}
+
+} // namespace SecurityServer
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Bartlomiej Grzelewski <b.grzelewski@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+/*
+ * @file app-permissions.h
+ * @author Pawel Polawski (p.polawski@partner.samsung.com)
+ * @version 1.0
+ * @brief This function contains header for implementation of
+ * security_server_app_has_permissions on server side
+ */
+
+#ifndef _SECURITY_SERVER_APP_PERMISSIONS_
+#define _SECURITY_SERVER_APP_PERMISSIONS_
+
+#include <service-thread.h>
+#include <generic-socket-manager.h>
+#include <dpl/serialization.h>
+#include <message-buffer.h>
+#include <connection-info.h>
+
+namespace SecurityServer {
+
+class AppPermissionsService :
+ public SecurityServer::GenericSocketService
+ , public SecurityServer::ServiceThread<AppPermissionsService>
+{
+public:
+ ServiceDescriptionVector GetServiceDescription();
+
+ DECLARE_THREAD_EVENT(AcceptEvent, accept)
+ DECLARE_THREAD_EVENT(WriteEvent, write)
+ DECLARE_THREAD_EVENT(ReadEvent, process)
+ DECLARE_THREAD_EVENT(CloseEvent, close)
+
+ void accept(const AcceptEvent &event);
+ void write(const WriteEvent &event);
+ void process(const ReadEvent &event);
+ void close(const CloseEvent &event);
+
+private:
+ bool processOne(const ConnectionID &conn, MessageBuffer &buffer, InterfaceID interfaceID);
+
+ bool processCheckAppPrivilege(const ConnectionID &conn, MessageBuffer &buffer);
+
+ ConnectionInfoMap m_connectionInfoMap;
+};
+
+} // namespace SecurityServer
+
+#endif // _SECURITY_SERVER_APP_ENABLE_PERMISSIONS_
${CMAKE_SOURCE_DIR}/systemd/security-server-data-share.socket
${CMAKE_SOURCE_DIR}/systemd/security-server-get-gid.socket
${CMAKE_SOURCE_DIR}/systemd/security-server-privilege-by-pid.socket
+ ${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-app-privilege-by-name.socket
--- /dev/null
+[Socket]
+ListenStream=/tmp/.security-server-api-app-permissions.sock
+SocketMode=0777
+SmackLabelIPIn=*
+SmackLabelIPOut=@
+
+Service=security-server.service
+
+[Unit]
+Wants=security-server.target
+Before=security-server.target
+
+[Install]
+WantedBy=sockets.target
Sockets=security-server-data-share.socket
Sockets=security-server-get-gid.socket
Sockets=security-server-privilege-by-pid.socket
+Sockets=security-server-app-permissions.socket
Sockets=security-server-app-privilege-by-name.socket
Sockets=security-server-cookie-get.socket
Sockets=security-server-cookie-check.socket