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
ln -s ../security-server-app-privilege-by-name.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/security-server-app-privilege-by-name.socket
+ln -s ../security-server-open-for.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/security-server-open-for.socket
%clean
rm -rf %{buildroot}
%attr(-,root,root) /usr/lib/systemd/system/security-server-cookie-check-tmp.socket
%attr(-,root,root) /usr/lib/systemd/system/sockets.target.wants/security-server-app-privilege-by-name.socket
%attr(-,root,root) /usr/lib/systemd/system/security-server-app-privilege-by-name.socket
+%attr(-,root,root) /usr/lib/systemd/system/sockets.target.wants/security-server-open-for.socket
+%attr(-,root,root) /usr/lib/systemd/system/security-server-open-for.socket
%attr(-,root,root) /etc/security/security-server-audit.conf
%{_datadir}/license/%{name}
${SERVER2_PATH}/service/cookie-jar.cpp
${SERVER2_PATH}/service/privilege-by-pid.cpp
${SERVER2_PATH}/service/get-object-name.cpp
+ ${SERVER2_PATH}/service/open-for.cpp
+ ${SERVER2_PATH}/service/open-for-manager.cpp
)
SET_SOURCE_FILES_PROPERTIES(
${SECURITY_SERVER_PATH}/server2/client/client-privilege-by-pid.cpp
${SECURITY_SERVER_PATH}/server2/client/client-socket-privilege.cpp
${SECURITY_SERVER_PATH}/server2/client/client-get-object-name.cpp
+ ${SECURITY_SERVER_PATH}/server2/client/client-open-for.cpp
${SECURITY_SERVER_PATH}/client/security-server-client.c
${SECURITY_SERVER_PATH}/communication/security-server-comm.c
${SECURITY_SERVER_PATH}/util/smack-check.c
*/
int security_server_get_gid_by_cookie(const char *cookie, gid_t *gid);
+/*
+ * This function allows to create, if doesn't exist, or open existing file by
+ * Security Server on behalf of calling process in secured directory.
+ *
+ * \param[in] File name to create/open
+ * \param[out] File descriptor
+ *
+ * \return SECURITY_SERVER_API_SUCCESS on success or error code on fail
+ *
+ * Access to this function requires SMACK rule: "<app_label> security-server::api-open-for w"
+ */
+int security_server_open_for(const char *filename, int *fd);
+
#ifdef __cplusplus
}
return SECURITY_SERVER_API_SUCCESS;
}
+int sendToServerAncData(char const * const interface, const RawBuffer &send, struct msghdr &hdr) {
+ int ret;
+ SockRAII sock;
+ ssize_t done = 0;
+
+ if (SECURITY_SERVER_API_SUCCESS != (ret = sock.Connect(interface))) {
+ LogError("Error in SockRAII");
+ return ret;
+ }
+
+ while ((send.size() - done) > 0) {
+ if (0 >= waitForSocket(sock.Get(), POLLOUT, POLL_TIMEOUT)) {
+ LogError("Error in poll(POLLOUT)");
+ return SECURITY_SERVER_API_ERROR_SOCKET;
+ }
+ ssize_t temp = TEMP_FAILURE_RETRY(write(sock.Get(), &send[done], send.size() - done));
+ if (-1 == temp) {
+ int err = errno;
+ LogError("Error in write: " << strerror(err));
+ return SECURITY_SERVER_API_ERROR_SOCKET;
+ }
+ done += temp;
+ }
+
+ if (0 >= waitForSocket(sock.Get(), POLLIN, POLL_TIMEOUT)) {
+ LogError("Error in poll(POLLIN)");
+ return SECURITY_SERVER_API_ERROR_SOCKET;
+ }
+
+ ssize_t temp = TEMP_FAILURE_RETRY(recvmsg(sock.Get(), &hdr, MSG_CMSG_CLOEXEC));
+
+ if (temp < 0) {
+ int err = errno;
+ LogError("Error in recvmsg(): " << strerror(err) << " errno: " << err);
+ return SECURITY_SERVER_API_ERROR_SOCKET;
+ }
+
+ if (0 == temp) {
+ LogError("Read return 0/Connection closed by server(?)");
+ return SECURITY_SERVER_API_ERROR_SOCKET;
+ }
+
+ return SECURITY_SERVER_API_SUCCESS;
+}
+
+
} // namespace SecurityServer
static void init_lib(void) __attribute__ ((constructor));
#include <message-buffer.h>
+extern "C" {
+ struct msghdr;
+}
+
namespace SecurityServer {
typedef std::vector<unsigned char> RawBuffer;
int sendToServer(char const * const interface, const RawBuffer &send, MessageBuffer &recv);
+/*
+ * sendToServerAncData is special case when we want to receive file descriptor
+ * passed by Security Server on behalf of calling process. We can't get it with
+ * MessageBuffer.
+ *
+ * This function should be called _ONLY_ in this particular case.
+ *
+ */
+int sendToServerAncData(char const * const interface, const RawBuffer &send, struct msghdr &hdr);
+
} // namespace SecuritySever
#endif // _SECURITY_SERVER_CLIENT_
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Bumjin Im <bj.im@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-open-for-cookie.cpp
+ * @author Zbigniew Jasinski (z.jasinski@samsung.com)
+ * @version 1.0
+ * @brief This file contains implementation of security-server API
+ * for file opening.
+ */
+
+#include <cstring>
+
+#include <dpl/log/log.h>
+#include <dpl/exception.h>
+
+#include <message-buffer.h>
+#include <client-common.h>
+#include <protocols.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <security-server.h>
+#include <security-server-common.h>
+
+SECURITY_SERVER_API
+int security_server_open_for(const char *filename, int *fd)
+{
+ using namespace SecurityServer;
+ try {
+ if (NULL == filename || std::string(filename).empty()) {
+ LogError("Error input param.");
+ return SECURITY_SERVER_ERROR_INPUT_PARAM;
+ }
+
+ MessageBuffer send;
+
+ Serialization::Serialize(send, std::string(filename));
+
+ struct msghdr hdr;
+ struct iovec iov;
+ struct cmsghdr *cmsg = NULL;
+ int retcode = -1;
+ int result = -1;
+ unsigned char cmsgbuf[CMSG_SPACE(sizeof(int))];
+
+ memset(&hdr, 0, sizeof(struct msghdr));
+ memset(cmsgbuf, 0, CMSG_SPACE(sizeof(int)));
+
+ iov.iov_base = &retcode;
+ iov.iov_len = sizeof(retcode);
+ hdr.msg_iov = &iov;
+ hdr.msg_iovlen = 1;
+
+ hdr.msg_control = cmsgbuf;
+ hdr.msg_controllen = CMSG_SPACE(sizeof(int));
+
+ result = sendToServerAncData(SERVICE_SOCKET_OPEN_FOR, send.Pop(), hdr);
+ if (result != SECURITY_SERVER_API_SUCCESS) {
+ *fd = -1;
+ return result;
+ }
+
+ if ((hdr.msg_flags & MSG_CTRUNC) == MSG_CTRUNC) {
+ LogError("Not enough space for ancillary element array.");
+ *fd = -1;
+ return SECURITY_SERVER_API_ERROR_BUFFER_TOO_SMALL;
+ }
+
+ for(cmsg = CMSG_FIRSTHDR(&hdr); cmsg != NULL; cmsg = CMSG_NXTHDR(&hdr, cmsg)) {
+ if((SOL_SOCKET == cmsg->cmsg_level) && (SCM_RIGHTS == cmsg->cmsg_type)) {
+ memmove(fd, CMSG_DATA(cmsg), sizeof(int));
+ }
+ }
+
+ return retcode;
+ } catch (MessageBuffer::Exception::Base &e) {
+ LogDebug("SecurityServer::MessageBuffer::Exception " << e.DumpToString());
+ } catch (std::exception &e) {
+ LogDebug("STD exception " << e.what());
+ } catch (...) {
+ LogDebug("Unknown exception occured");
+ }
+ return SECURITY_SERVER_API_ERROR_UNKNOWN;
+}
//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";
+char const * const SERVICE_SOCKET_OPEN_FOR =
+ "/tmp/.security-server-api-open-for.sock";
const size_t COOKIE_SIZE = 20;
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;
+extern char const * const SERVICE_SOCKET_OPEN_FOR;
enum class AppPermissionsAction { ENABLE, DISABLE };
m_hdr.msg_iov = &m_iov;
m_hdr.msg_iovlen = 1;
- m_hdr.msg_control = m_cmsgbuf;
- m_hdr.msg_controllen = CMSG_SPACE(sizeof(int));
- m_cmsg = CMSG_FIRSTHDR(&m_hdr);
- m_cmsg->cmsg_len = CMSG_LEN(sizeof(int));
- m_cmsg->cmsg_level = SOL_SOCKET;
- m_cmsg->cmsg_type = SCM_RIGHTS;
+ if (fileDesc != -1) {
+ m_hdr.msg_control = m_cmsgbuf;
+ m_hdr.msg_controllen = CMSG_SPACE(sizeof(int));
- memmove(CMSG_DATA(m_cmsg), &m_fileDesc, sizeof(int));
+ m_cmsg = CMSG_FIRSTHDR(&m_hdr);
+ m_cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+ m_cmsg->cmsg_level = SOL_SOCKET;
+ m_cmsg->cmsg_type = SCM_RIGHTS;
+
+ memmove(CMSG_DATA(m_cmsg), &m_fileDesc, sizeof(int));
+ }
}
msghdr* data() { return &m_hdr; }
#include <get-object-name.h>
#include <app-permissions.h>
#include <cookie.h>
+#include <open-for.h>
#include <echo.h>
IMPLEMENT_SAFE_SINGLETON(SecurityServer::Log::LogSystem);
// echoService->Create();
// manager.RegisterSocketService(echoService);
+
+ SecurityServer::OpenForService *openForService = new SecurityServer::OpenForService;
+ openForService->Create();
+ manager.RegisterSocketService(openForService);
+
SecurityServer::CookieService *cookieService = new SecurityServer::CookieService;
cookieService->Create();
manager.RegisterSocketService(cookieService);
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Bumjin Im <bj.im@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 open-for-manager.cpp
+ * @author Zbigniew Jasinski (z.jasinski@samsung.com)
+ * @version 1.0
+ * @brief Implementation of open-for management functions
+ */
+
+#include "open-for-manager.h"
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <fcntl.h>
+
+#include <sys/smack.h>
+#include <smack-check.h>
+
+#include <dpl/log/log.h>
+#include <dpl/serialization.h>
+
+#include <security-server.h>
+#include <security-server-util.h>
+#include <security-server-comm.h>
+
+const std::string DATA_DIR = "/var/run/security-server";
+const std::string PROHIBITED_STR = "..";
+const std::string ALLOWED_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ \
+ abcdefghijklmnopqrstuvwxyz \
+ 0123456789._-";
+
+namespace SecurityServer
+{
+ // SockCred implementations
+ SockCred::SockCred()
+ {
+ m_len = sizeof(struct ucred);
+ memset(&m_cr, 0, m_len);
+ }
+
+ bool SockCred::getCred(int socket)
+ {
+ if (getsockopt(socket, SOL_SOCKET, SO_PEERCRED, &m_cr, &m_len)) {
+ int err = errno;
+ LogError("Unable to get client credentials: " << strerror(err));
+ return true;
+ }
+
+ if (smack_check()) {
+ char label[SMACK_LABEL_LEN + 1];
+ if (PC_OPERATION_SUCCESS != get_smack_label_from_process(m_cr.pid, label)) {
+ LogError("Unable to get smack label of process.");
+ return true;
+ }
+ m_sockSmackLabel = label;
+ } else
+ m_sockSmackLabel = "";
+
+ return false;
+ }
+
+ std::string SockCred::getLabel() const
+ {
+ return m_sockSmackLabel;
+ }
+
+ // SharedFile implementations
+ SharedFile::SharedFile()
+ {
+ if (!dirExist(DATA_DIR.c_str()))
+ mkdir(DATA_DIR.c_str(), 0700);
+ else {
+ deleteDir(DATA_DIR.c_str());
+ mkdir(DATA_DIR.c_str(), 0700);
+ }
+ }
+
+ bool SharedFile::fileExist(const std::string &filename) const
+ {
+ std::string filepath = DATA_DIR + "/" + filename;
+ struct stat buf;
+
+ return ((lstat(filepath.c_str(), &buf) == 0) &&
+ (((buf.st_mode) & S_IFMT) != S_IFLNK));
+ }
+
+ bool SharedFile::dirExist(const std::string &dirpath) const
+ {
+ struct stat buf;
+
+ return ((lstat(dirpath.c_str(), &buf) == 0) &&
+ (((buf.st_mode) & S_IFMT) == S_IFDIR));
+ }
+
+ bool SharedFile::deleteDir(const std::string &dirpath) const
+ {
+ DIR *dirp;
+ struct dirent *dp;
+ char path[PATH_MAX];
+
+ if ((dirp = opendir(dirpath.c_str())) == NULL) {
+ int err = errno;
+ LogError("Cannot open data directory. " << strerror(err));
+ return true;
+ }
+
+ while ((dp = readdir(dirp)) != NULL) {
+ if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
+ snprintf(path, (size_t) PATH_MAX, "%s/%s", dirpath.c_str(), dp->d_name);
+ if (dp->d_type == DT_DIR) {
+ deleteDir(path);
+ } else {
+ unlink(path);
+ }
+ }
+ }
+ closedir(dirp);
+ rmdir(dirpath.c_str());
+
+ return false;
+ }
+
+ bool SharedFile::createFile(const std::string &filename)
+ {
+ int fd = -1;
+ std::string filepath = DATA_DIR + "/" + filename;
+
+ fd = TEMP_FAILURE_RETRY(open(filepath.c_str(), O_CREAT | O_WRONLY | O_EXCL, 0600));
+ int err = errno;
+ if (-1 == fd) {
+ LogError("Cannot create file. Error in open(): " << strerror(err));
+ return true;
+ }
+
+ TEMP_FAILURE_RETRY(close(fd));
+
+ return false;
+ }
+
+ int SharedFile::openFile(const std::string &filename)
+ {
+ int fd = -1;
+ std::string filepath = DATA_DIR + "/" + filename;
+
+ fd = TEMP_FAILURE_RETRY(open(filepath.c_str(), O_CREAT | O_RDWR, 0600));
+ int err = errno;
+ if (-1 == fd) {
+ LogError("Cannot open file. Error in open(): " << strerror(err));
+ return SECURITY_SERVER_API_ERROR_SERVER_ERROR;
+ }
+
+ return fd;
+ }
+
+ bool SharedFile::setFileLabel(const std::string &filename, const std::string &label) const
+ {
+ std::string filepath = DATA_DIR + "/" + filename;
+
+ if (smack_setlabel(filepath.c_str(), label.c_str(), SMACK_LABEL_ACCESS)) {
+ LogError("Cannot set SMACK label on file.");
+ return true;
+ }
+
+ return false;
+ }
+
+ bool SharedFile::getFileLabel(const std::string &filename)
+ {
+ std::string filepath = DATA_DIR + "/" + filename;
+
+ if (smack_check()) {
+ char *label = NULL;
+ if (PC_OPERATION_SUCCESS != smack_getlabel(filepath.c_str(), &label, SMACK_LABEL_ACCESS)) {
+ LogError("Unable to get smack label of process.");
+ return true;
+ }
+ m_fileSmackLabel = label;
+ free(label);
+ } else
+ m_fileSmackLabel.clear();
+
+ return false;
+ }
+
+ bool SharedFile::checkFileNameSyntax(const std::string &filename) const
+ {
+ std::size_t found = filename.find_first_not_of(ALLOWED_CHARS);
+
+ if (found != std::string::npos || '-' == filename[0] ||
+ '.' == filename[0]) {
+ LogError("Illegal character in filename.");
+ return true;
+ }
+
+ found = filename.find(PROHIBITED_STR);
+ if (found != std::string::npos) {
+ LogError("Illegal string in filename.");
+ return true;
+ }
+
+ return false;
+ }
+
+ int SharedFile::getFD(const std::string &filename, int socket, int &fd)
+ {
+ if (checkFileNameSyntax(filename))
+ return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
+
+ if (m_sockCred.getCred(socket))
+ return SECURITY_SERVER_API_ERROR_AUTHENTICATION_FAILED;
+
+ if (!fileExist(filename)) {
+ LogSecureDebug("File: " << filename.c_str() << " does not exist.");
+
+ if (createFile(filename))
+ return SECURITY_SERVER_API_ERROR_SERVER_ERROR;
+ }
+
+ if (getFileLabel(filename))
+ return SECURITY_SERVER_API_ERROR_SERVER_ERROR;
+
+ if (setFileLabel(filename, m_sockCred.getLabel()))
+ return SECURITY_SERVER_API_ERROR_SERVER_ERROR;
+
+ fd = openFile(filename);
+
+ if (setFileLabel(filename, m_fileSmackLabel))
+ return SECURITY_SERVER_API_ERROR_SERVER_ERROR;
+
+ return SECURITY_SERVER_API_SUCCESS;
+ }
+
+} //namespace SecurityServer
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Bumjin Im <bj.im@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 open-for-manager.h
+ * @author Zbigniew Jasinski (z.jasinski@samsung.com)
+ * @version 1.0
+ * @brief Implementation of open-for management functions
+ */
+
+#ifndef _OPEN_FOR_MANAGER_H_
+#define _OPEN_FOR_MANAGER_H_
+
+#include "security-server-common.h"
+
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include <string>
+
+namespace SecurityServer
+{
+ // classess
+ class SockCred
+ {
+ public:
+ SockCred();
+ bool getCred(int socket);
+ std::string getLabel(void) const;
+
+ private:
+ struct ucred m_cr;
+ unsigned m_len;
+ std::string m_sockSmackLabel;
+ };
+
+ class SharedFile
+ {
+ public:
+ SharedFile();
+ int getFD(const std::string &filename, int socket, int &fd);
+
+ private:
+ bool fileExist(const std::string &filename) const;
+ bool dirExist(const std::string &dirpath) const;
+ bool deleteDir(const std::string &dirpath) const;
+ int openFile(const std::string &filename);
+ bool createFile(const std::string &filename);
+ bool setFileLabel(const std::string &filename, const std::string &label) const;
+ bool getFileLabel(const std::string &filename);
+ bool checkFileNameSyntax(const std::string &filename) const;
+
+ uid_t m_fileUID;
+ gid_t m_fileGID;
+ mode_t m_fileMode;
+ std::string m_fileSmackLabel;
+
+ SockCred m_sockCred;
+ };
+}
+
+#endif // _OPEN_FOR_MANAGER_H_
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Bumjin Im <bj.im@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 open-for.cpp
+ * @author Zbigniew Jasinski (z.jasinski@samsung.com)
+ * @version 1.0
+ * @brief Implementation of open-for service
+ */
+
+#include <dpl/log/log.h>
+#include <dpl/serialization.h>
+
+#include <protocols.h>
+#include <open-for.h>
+#include <unistd.h>
+
+#include <security-server.h>
+#include <security-server-util.h>
+#include <security-server-comm.h>
+
+namespace {
+// Service may open more than one socket.
+// These ID's will be assigned to sockets
+// and will be used only by service.
+// When new connection arrives, AcceptEvent
+// will be generated with proper ID to inform
+// service about input socket.
+//
+// Please note: SocketManaged does not use it and
+// does not check it in any way.
+//
+// If your service require only one socket
+// (uses only one socket labeled with smack)
+// you may ignore this ID (just pass 0)
+const int SERVICE_SOCKET_ID = 0;
+
+} // namespace anonymous
+
+namespace SecurityServer {
+
+GenericSocketService::ServiceDescriptionVector OpenForService::GetServiceDescription() {
+ return ServiceDescriptionVector
+ {{SERVICE_SOCKET_OPEN_FOR, "security-server::api-open-for", SERVICE_SOCKET_ID, true}};
+}
+
+void OpenForService::accept(const AcceptEvent &event)
+{
+ LogDebug("Accept event. ConnectionID.sock: " << event.connectionID.sock
+ << " ConnectionID.counter: " << event.connectionID.counter
+ << " ServiceID: " << event.interfaceID);
+}
+
+void OpenForService::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 OpenForService::process(const ReadEvent &event)
+{
+ LogDebug("Read event for counter: " << event.connectionID.counter);
+ auto &info = m_socketInfoMap[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.descriptorsVector));
+}
+
+void OpenForService::close(const CloseEvent &event)
+{
+ LogDebug("CloseEvent. ConnectionID: " << event.connectionID.sock);
+ auto &descVector = m_socketInfoMap[event.connectionID.counter].descriptorsVector;
+
+ for (auto iter = descVector.begin(); iter != descVector.end(); ++iter)
+ TEMP_FAILURE_RETRY(::close(*iter));
+
+ m_socketInfoMap.erase(event.connectionID.counter);
+}
+
+bool OpenForService::processOne(const ConnectionID &conn, MessageBuffer &buffer, std::vector<int> &descVector)
+{
+ LogDebug("Iteration begin");
+
+ std::string filename;
+ MessageBuffer sendBuffer;
+
+ int retCode = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
+ int fd = -1;
+
+ if (!buffer.Ready())
+ return false;
+
+ Try {
+ Deserialization::Deserialize(buffer, filename);
+ } Catch (MessageBuffer::Exception::Base) {
+ LogError("Broken protocol. Closing socket.");
+ m_serviceManager->Close(conn);
+ return false;
+ }
+
+ retCode = m_sharedFile.getFD(filename, conn.sock, fd);
+ if (fd != -1)
+ descVector.push_back(fd);
+ SendMsgData sendMsgData(retCode, fd);
+
+ m_serviceManager->Write(conn, sendMsgData);
+
+ return true;
+}
+
+} // namespace SecurityServer
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Bumjin Im <bj.im@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 open-for.h
+ * @author Zigniew Jasinski (z.jasinski@samsung.com)
+ * @version 1.0
+ * @brief Implementation of open-for service
+ */
+
+#ifndef _SECURITY_SERVER_OPEN_FOR_
+#define _SECURITY_SERVER_OPEN_FOR_
+
+#include <service-thread.h>
+#include <generic-socket-manager.h>
+#include <message-buffer.h>
+
+#include "security-server-common.h"
+#include "open-for-manager.h"
+
+namespace SecurityServer
+{
+ typedef std::vector<int> DescriptorVector;
+
+ struct SocketInfo {
+ DescriptorVector descriptorsVector;
+ MessageBuffer buffer;
+ };
+
+ typedef std::map<int, SocketInfo> SocketInfoMap;
+
+ class OpenForService
+ : public SecurityServer::GenericSocketService
+ , public SecurityServer::ServiceThread<OpenForService>
+ {
+ public:
+ //service functions
+ 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:
+ //internal service functions
+ bool processOne(const ConnectionID &conn, MessageBuffer &buffer, DescriptorVector &descVector);
+
+ SocketInfoMap m_socketInfoMap;
+ SharedFile m_sharedFile;
+ };
+} // namespace SecurityServer
+
+#endif // _SECURITY_SERVER_OPEN_FOR_
${CMAKE_SOURCE_DIR}/systemd/security-server-cookie-check.socket
${CMAKE_SOURCE_DIR}/systemd/security-server-app-privilege-by-name.socket
${CMAKE_SOURCE_DIR}/systemd/security-server-cookie-check-tmp.socket
+ ${CMAKE_SOURCE_DIR}/systemd/security-server-open-for.socket
DESTINATION
/usr/lib/systemd/system
)
--- /dev/null
+[Socket]
+ListenStream=/tmp/.security-server-api-open-for.sock
+SocketMode=0777
+SmackLabelIPIn=security-server::api-open-for
+SmackLabelIPOut=@
+
+Service=security-server.service
+
+[Install]
+WantedBy=sockets.target
Sockets=security-server-cookie-get.socket
Sockets=security-server-cookie-check.socket
Sockets=security-server-cookie-check-tmp.socket
+Sockets=security-server-open-for.socket
[Install]
WantedBy=multi-user.target