#include <dpl/singleton_safe_impl.h>
#include <message-buffer.h>
-#include <smack-common.h>
#include <protocols.h>
namespace {
-const int POLL_TIMEOUT = 2000;
-
void securityClientEnableLogSystem(void) {
SecurityManager::Singleton<SecurityManager::Log::LogSystem>::Instance().SetTag("SECURITY_MANAGER_CLIENT");
}
-int waitForSocket(int sock, int event, int timeout) {
- int retval;
- pollfd desc[1];
- desc[0].fd = sock;
- desc[0].events = event;
-
- while((-1 == (retval = poll(desc, 1, timeout))) && (errno == EINTR)) {
- timeout >>= 1;
- errno = 0;
- }
-
- if (0 == retval) {
- LogDebug("Poll timeout");
- } else if (-1 == retval) {
- int err = errno;
- LogError("Error in poll: " << strerror(err));
- }
- return retval;
-}
-
-class SockRAII {
-public:
- SockRAII()
- : m_sock(-1)
- {}
-
- virtual ~SockRAII() {
- if (m_sock > -1)
- close(m_sock);
- }
-
- int Connect(char const * const interface) {
- sockaddr_un clientAddr;
- int flags;
-
- if (m_sock != -1) // guard
- close(m_sock);
-
- m_sock = socket(AF_UNIX, SOCK_STREAM, 0);
- if (m_sock < 0) {
- int err = errno;
- LogError("Error creating socket: " << strerror(err));
- return SECURITY_MANAGER_API_ERROR_SOCKET;
- }
-
- if ((flags = fcntl(m_sock, F_GETFL, 0)) < 0 ||
- fcntl(m_sock, F_SETFL, flags | O_NONBLOCK) < 0)
- {
- int err = errno;
- LogError("Error in fcntl: " << strerror(err));
- return SECURITY_MANAGER_API_ERROR_SOCKET;
- }
-
- memset(&clientAddr, 0, sizeof(clientAddr));
-
- clientAddr.sun_family = AF_UNIX;
-
- if (strlen(interface) >= sizeof(clientAddr.sun_path)) {
- LogError("Error: interface name " << interface << "is too long. Max len is:" << sizeof(clientAddr.sun_path));
- return SECURITY_MANAGER_API_ERROR_NO_SUCH_SERVICE;
- }
-
- strcpy(clientAddr.sun_path, interface);
-
- LogDebug("ClientAddr.sun_path = " << interface);
-
- int retval = TEMP_FAILURE_RETRY(connect(m_sock, (struct sockaddr*)&clientAddr, SUN_LEN(&clientAddr)));
- if ((retval == -1) && (errno == EINPROGRESS)) {
- if (0 >= waitForSocket(m_sock, POLLOUT, POLL_TIMEOUT)) {
- LogError("Error in waitForSocket.");
- return SECURITY_MANAGER_API_ERROR_SOCKET;
- }
- int error = 0;
- socklen_t len = sizeof(error);
- retval = getsockopt(m_sock, SOL_SOCKET, SO_ERROR, &error, &len);
-
- if (-1 == retval) {
- int err = errno;
- LogError("Error in getsockopt: " << strerror(err));
- return SECURITY_MANAGER_API_ERROR_SOCKET;
- }
-
- if (error == EACCES) {
- LogError("Access denied");
- return SECURITY_MANAGER_API_ERROR_ACCESS_DENIED;
- }
-
- if (error != 0) {
- LogError("Error in connect: " << strerror(error));
- return SECURITY_MANAGER_API_ERROR_SOCKET;
- }
-
- return SECURITY_MANAGER_API_SUCCESS;
- }
-
- if (-1 == retval) {
- int err = errno;
- LogError("Error connecting socket: " << strerror(err));
- if (err == EACCES)
- return SECURITY_MANAGER_API_ERROR_ACCESS_DENIED;
- if (err == ENOTSOCK)
- return SECURITY_MANAGER_API_ERROR_NO_SUCH_SERVICE;
- return SECURITY_MANAGER_API_ERROR_SOCKET;
- }
-
- return SECURITY_MANAGER_API_SUCCESS;
- }
-
- int Get() {
- return m_sock;
- }
-
-private:
- int m_sock;
-};
-
} // namespace anonymous
namespace SecurityManager {
-int sendToServer(char const * const interface, const RawBuffer &send, MessageBuffer &recv) {
- int ret;
- SockRAII sock;
- ssize_t done = 0;
- char buffer[2048];
-
- if (SECURITY_MANAGER_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_MANAGER_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_MANAGER_API_ERROR_SOCKET;
- }
- done += temp;
- }
-
- do {
- if (0 >= waitForSocket(sock.Get(), POLLIN, POLL_TIMEOUT)) {
- LogError("Error in poll(POLLIN)");
- return SECURITY_MANAGER_API_ERROR_SOCKET;
- }
- ssize_t temp = TEMP_FAILURE_RETRY(read(sock.Get(), buffer, 2048));
- if (-1 == temp) {
- int err = errno;
- LogError("Error in read: " << strerror(err));
- return SECURITY_MANAGER_API_ERROR_SOCKET;
- }
-
- if (0 == temp) {
- LogError("Read return 0/Connection closed by server(?)");
- return SECURITY_MANAGER_API_ERROR_SOCKET;
- }
-
- RawBuffer raw(buffer, buffer+temp);
- recv.Push(raw);
- } while(!recv.Ready());
- return SECURITY_MANAGER_API_SUCCESS;
-}
-
-int sendToServerAncData(char const * const interface, const RawBuffer &send, struct msghdr &hdr) {
- int ret;
- SockRAII sock;
- ssize_t done = 0;
-
- if (SECURITY_MANAGER_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_MANAGER_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_MANAGER_API_ERROR_SOCKET;
- }
- done += temp;
- }
-
- if (0 >= waitForSocket(sock.Get(), POLLIN, POLL_TIMEOUT)) {
- LogError("Error in poll(POLLIN)");
- return SECURITY_MANAGER_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_MANAGER_API_ERROR_SOCKET;
- }
-
- if (0 == temp) {
- LogError("Read return 0/Connection closed by server(?)");
- return SECURITY_MANAGER_API_ERROR_SOCKET;
- }
-
- return SECURITY_MANAGER_API_SUCCESS;
-}
-
int try_catch(const std::function<int()>& func)
{
try {