b94a38b48698483d1c468b8f2e31bc92ef5f4959
[platform/core/security/key-manager.git] / src / manager / main / socket-manager.cpp
1 /*
2  *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Contact: Bumjin Im <bj.im@samsung.com>
5  *
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License
17  */
18 /*
19  * @file        socket-manager.cpp
20  * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
21  * @version     1.0
22  * @brief       Implementation of SocketManager.
23  */
24
25 #include <set>
26
27 #include <signal.h>
28 #include <sys/select.h>
29 #include <sys/signalfd.h>
30 #include <sys/types.h>
31 #include <sys/socket.h>
32 #include <sys/smack.h>
33 #include <sys/un.h>
34 #include <sys/stat.h>
35 #include <unistd.h>
36 #include <fcntl.h>
37 #include <signal.h>
38 #include <errno.h>
39 #include <time.h>
40
41 #include <systemd/sd-daemon.h>
42
43 #include <dpl/errno_string.h>
44 #include <dpl/log/log.h>
45 #include <dpl/assert.h>
46
47 #include <smack-check.h>
48 #include <socket-manager.h>
49
50 namespace {
51
52 const time_t SOCKET_TIMEOUT = 1000;
53
54 int getCredentialsFromSocket(int sock, CKM::Credentials &cred) {
55     std::vector<char> result(1);
56     socklen_t length = 1;
57     ucred peerCred;
58
59     if ((0 > getsockopt(sock, SOL_SOCKET, SO_PEERSEC, result.data(), &length))
60         && errno != ERANGE)
61     {
62         LogError("getsockopt failed");
63         return -1;
64     }
65
66     result.resize(length);
67
68     if (0 > getsockopt(sock, SOL_SOCKET, SO_PEERSEC, result.data(), &length)) {
69         LogError("getsockopt failed");
70         return -1;
71     }
72
73     length = sizeof(ucred);
74
75     if (0 > getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &peerCred, &length)) {
76         LogError("getsockopt failed");
77         return -1;
78     }
79
80     result.push_back('\0');
81     cred = CKM::Credentials(peerCred.uid, result.data());
82     return 0;
83 }
84
85 } // namespace anonymous
86
87 namespace CKM {
88
89 struct DummyService : public GenericSocketService {
90     ServiceDescriptionVector GetServiceDescription() {
91         return ServiceDescriptionVector();
92     }
93
94     void Start() {}
95     void Stop() {}
96
97     void Event(const AcceptEvent &) {}
98     void Event(const WriteEvent &) {}
99     void Event(const ReadEvent &) {}
100     void Event(const CloseEvent &) {}
101 };
102
103 struct SignalService : public GenericSocketService {
104     int GetDescriptor() {
105         LogInfo("set up");
106         sigset_t mask;
107         sigemptyset(&mask);
108         sigaddset(&mask, SIGTERM);
109         if (-1 == pthread_sigmask(SIG_BLOCK, &mask, NULL))
110             return -1;
111         return signalfd(-1, &mask, 0);
112     }
113
114     ServiceDescriptionVector GetServiceDescription() {
115         return ServiceDescriptionVector();
116     }
117
118     void Start() {}
119     void Stop() {}
120
121     void Event(const AcceptEvent &) {} // not supported
122     void Event(const WriteEvent &) {}  // not supported
123     void Event(const CloseEvent &) {}  // not supported
124
125     void Event(const ReadEvent &event) {
126         LogDebug("Get signal information");
127
128         if(sizeof(struct signalfd_siginfo) != event.rawBuffer.size()) {
129             LogError("Wrong size of signalfd_siginfo struct. Expected: "
130                 << sizeof(signalfd_siginfo) << " Get: "
131                 << event.rawBuffer.size());
132             return;
133         }
134
135         signalfd_siginfo *siginfo = (signalfd_siginfo*)(&(event.rawBuffer[0]));
136
137         if (siginfo->ssi_signo == SIGTERM) {
138             LogInfo("Got signal: SIGTERM");
139             static_cast<SocketManager*>(m_serviceManager)->MainLoopStop();
140             return;
141         }
142
143         LogInfo("This should not happend. Got signal: " << siginfo->ssi_signo);
144     }
145 };
146
147 SocketManager::SocketDescription&
148 SocketManager::CreateDefaultReadSocketDescription(int sock, bool timeout)
149 {
150     if ((int)m_socketDescriptionVector.size() <= sock)
151         m_socketDescriptionVector.resize(sock+20);
152
153     auto &desc = m_socketDescriptionVector[sock];
154     desc.isListen = false;
155     desc.isOpen = true;
156     desc.interfaceID = 0;
157     desc.service = NULL;
158     desc.counter = ++m_counter;
159
160     if (timeout) {
161         desc.timeout = time(NULL) + SOCKET_TIMEOUT;
162         if (false == desc.isTimeout) {
163             Timeout tm;
164             tm.time = desc.timeout;
165             tm.sock = sock;
166             m_timeoutQueue.push(tm);
167         }
168     }
169
170     desc.isTimeout = timeout;
171
172     FD_SET(sock, &m_readSet);
173     m_maxDesc = sock > m_maxDesc ? sock : m_maxDesc;
174     return desc;
175 }
176
177 SocketManager::SocketManager()
178   : m_maxDesc(0)
179   , m_counter(0)
180 {
181     FD_ZERO(&m_readSet);
182     FD_ZERO(&m_writeSet);
183     if (-1 == pipe(m_notifyMe)) {
184         int err = errno;
185         ThrowMsg(Exception::InitFailed, "Error in pipe: " << GetErrnoString(err));
186     }
187     LogInfo("Pipe: Read desc: " << m_notifyMe[0] << " Write desc: " << m_notifyMe[1]);
188
189     auto &desc = CreateDefaultReadSocketDescription(m_notifyMe[0], false);
190     desc.service = new DummyService;
191
192     // std::thread bases on pthread so this should work fine
193     sigset_t set;
194     sigemptyset(&set);
195     sigaddset(&set, SIGPIPE);
196     pthread_sigmask(SIG_BLOCK, &set, NULL);
197
198     // add support for TERM signal (passed from systemd)
199     auto *signalService = new SignalService;
200     signalService->SetSocketManager(this);
201     int filefd = signalService->GetDescriptor();
202     if (-1 == filefd) {
203         LogError("Error in SignalService.GetDescriptor()");
204         delete signalService;
205     } else {
206         auto &desc2 = CreateDefaultReadSocketDescription(filefd, false);
207         desc2.service = signalService;
208         LogInfo("SignalService mounted on " << filefd << " descriptor");
209     }
210 }
211
212 SocketManager::~SocketManager() {
213     std::set<GenericSocketService*> serviceMap;
214
215     // Find all services. Set is used to remove duplicates.
216     // In this implementation, services are not able to react in any way.
217     for (size_t i=0; i < m_socketDescriptionVector.size(); ++i)
218         if (m_socketDescriptionVector[i].isOpen)
219             serviceMap.insert(m_socketDescriptionVector[i].service);
220
221     // Time to destroy all services.
222     for (auto service : serviceMap) {
223         LogDebug("delete " << (void*)(service));
224         service->Stop();
225         delete service;
226     }
227
228     for (size_t i = 0; i < m_socketDescriptionVector.size(); ++i)
229         if (m_socketDescriptionVector[i].isOpen)
230             close(i);
231
232     // All socket except one were closed. Now pipe input must be closed.
233     close(m_notifyMe[1]);
234 }
235
236 void SocketManager::ReadyForAccept(int sock) {
237     struct sockaddr_un clientAddr;
238     unsigned int clientLen = sizeof(clientAddr);
239     int client = accept4(sock, (struct sockaddr*) &clientAddr, &clientLen, SOCK_NONBLOCK);
240 //    LogInfo("Accept on sock: " << sock << " Socket opended: " << client);
241     if (-1 == client) {
242         int err = errno;
243         LogDebug("Error in accept: " << GetErrnoString(err));
244         return;
245     }
246
247     Credentials peerCred;
248     if (0 > getCredentialsFromSocket(client, peerCred)) {
249         LogDebug("Error in getCredentialsFromSocket. Socket closed.");
250         TEMP_FAILURE_RETRY(close(client));
251         return;
252     }
253
254     auto &desc = CreateDefaultReadSocketDescription(client, true);
255     desc.interfaceID = m_socketDescriptionVector[sock].interfaceID;
256     desc.service = m_socketDescriptionVector[sock].service;
257
258     GenericSocketService::AcceptEvent event;
259     event.connectionID.sock = client;
260     event.connectionID.counter = desc.counter;
261     event.interfaceID = desc.interfaceID;
262     event.credentials = peerCred;
263     desc.service->Event(event);
264 }
265
266 void SocketManager::ReadyForRead(int sock) {
267     if (m_socketDescriptionVector[sock].isListen) {
268         ReadyForAccept(sock);
269         return;
270     }
271
272     GenericSocketService::ReadEvent event;
273     event.connectionID.sock = sock;
274     event.connectionID.counter = m_socketDescriptionVector[sock].counter;
275     event.rawBuffer.resize(4096);
276
277     auto &desc = m_socketDescriptionVector[sock];
278     desc.timeout = time(NULL) + SOCKET_TIMEOUT;
279
280     ssize_t size = read(sock, &event.rawBuffer[0], 4096);
281
282     if (size == 0) {
283         CloseSocket(sock);
284     } else if (size >= 0) {
285         event.rawBuffer.resize(size);
286         desc.service->Event(event);
287     } else if (size == -1) {
288         int err = errno;
289         switch(err) {
290             case EAGAIN:
291             case EINTR:
292                 break;
293             default:
294                 LogDebug("Reading sock error: " << GetErrnoString(err));
295                 CloseSocket(sock);
296         }
297     }
298 }
299
300 void SocketManager::ReadyForWriteBuffer(int sock) {
301     auto &desc = m_socketDescriptionVector[sock];
302     size_t size = desc.rawBuffer.size();
303     ssize_t result = write(sock, &desc.rawBuffer[0], size);
304     if (result == -1) {
305         int err = errno;
306         switch(err) {
307         case EAGAIN:
308         case EINTR:
309             // select will trigger write once again, nothing to do
310             break;
311         case EPIPE:
312         default:
313             LogDebug("Error during write: " << GetErrnoString(err));
314             CloseSocket(sock);
315             break;
316         }
317         return; // We do not want to propagate error to next layer
318     }
319
320     desc.rawBuffer.erase(desc.rawBuffer.begin(), desc.rawBuffer.begin()+result);
321
322     desc.timeout = time(NULL) + SOCKET_TIMEOUT;
323
324     if (desc.rawBuffer.empty())
325         FD_CLR(sock, &m_writeSet);
326
327     GenericSocketService::WriteEvent event;
328     event.connectionID.sock = sock;
329     event.connectionID.counter = desc.counter;
330     event.size = result;
331     event.left = desc.rawBuffer.size();
332
333     desc.service->Event(event);
334 }
335
336 void SocketManager::ReadyForWrite(int sock) {
337         ReadyForWriteBuffer(sock);
338 }
339
340 void SocketManager::MainLoop() {
341     // remove evironment values passed by systemd
342     sd_listen_fds(1);
343
344     // Daemon is ready to work.
345     sd_notify(0, "READY=1");
346
347     m_working = true;
348     while(m_working) {
349         fd_set readSet = m_readSet;
350         fd_set writeSet = m_writeSet;
351
352         timeval localTempTimeout;
353         timeval *ptrTimeout = &localTempTimeout;
354
355         // I need to extract timeout from priority_queue.
356         // Timeout in priority_queue may be deprecated.
357         // I need to find some actual one.
358         while(!m_timeoutQueue.empty()) {
359             auto &top = m_timeoutQueue.top();
360             auto &desc = m_socketDescriptionVector[top.sock];
361
362             if (top.time == desc.timeout) {
363                 // This timeout matches timeout from socket.
364                 // It can be used.
365                 break;
366             } else {
367                 // This socket was used after timeout in priority queue was set up.
368                 // We need to update timeout and find some useable one.
369                 Timeout tm = { desc.timeout , top.sock};
370                 m_timeoutQueue.pop();
371                 m_timeoutQueue.push(tm);
372             }
373         }
374
375         if (m_timeoutQueue.empty()) {
376             LogDebug("No usaable timeout found.");
377             ptrTimeout = NULL; // select will wait without timeout
378         } else {
379             time_t currentTime = time(NULL);
380             auto &pqTimeout = m_timeoutQueue.top();
381
382             // 0 means that select won't block and socket will be closed ;-)
383             ptrTimeout->tv_sec =
384               currentTime < pqTimeout.time ? pqTimeout.time - currentTime : 0;
385             ptrTimeout->tv_usec = 0;
386 //            LogDebug("Set up timeout: " << (int)ptrTimeout->tv_sec
387 //                << " seconds. Socket: " << pqTimeout.sock);
388         }
389
390         int ret = select(m_maxDesc+1, &readSet, &writeSet, NULL, ptrTimeout);
391
392         if (0 == ret) { // timeout
393             Assert(!m_timeoutQueue.empty());
394
395             Timeout pqTimeout = m_timeoutQueue.top();
396             m_timeoutQueue.pop();
397
398             auto &desc = m_socketDescriptionVector[pqTimeout.sock];
399
400             if (!desc.isTimeout || !desc.isOpen) {
401                 // Connection was closed. Timeout is useless...
402                 desc.isTimeout = false;
403                 continue;
404             }
405
406             if (pqTimeout.time < desc.timeout) {
407                 // Is it possible?
408                 // This socket was used after timeout. We need to update timeout.
409                 pqTimeout.time = desc.timeout;
410                 m_timeoutQueue.push(pqTimeout);
411                 continue;
412             }
413
414             // timeout from m_timeoutQueue matches with socket.timeout
415             // and connection is open. Time to close it!
416             // Putting new timeout in queue here is pointless.
417             desc.isTimeout = false;
418             CloseSocket(pqTimeout.sock);
419
420             // All done. Now we should process next select ;-)
421             continue;
422         }
423
424         if (-1 == ret) {
425             switch(errno) {
426             case EINTR:
427                 LogDebug("EINTR in select");
428                 break;
429             default:
430                 int err = errno;
431                 LogError("Error in select: " << GetErrnoString(err));
432                 return;
433             }
434             continue;
435         }
436         for(int i = 0; i<m_maxDesc+1 && ret; ++i) {
437             if (FD_ISSET(i, &readSet)) {
438                 ReadyForRead(i);
439                 --ret;
440             }
441             if (FD_ISSET(i, &writeSet)) {
442                 ReadyForWrite(i);
443                 --ret;
444             }
445         }
446         ProcessQueue();
447     }
448 }
449
450 void SocketManager::MainLoopStop()
451 {
452     m_working = false;
453     NotifyMe();
454 }
455
456 int SocketManager::GetSocketFromSystemD(
457     const GenericSocketService::ServiceDescription &desc)
458 {
459     int fd;
460
461     // TODO optimalization - do it once in object constructor
462     //                       and remember all information path->sockfd
463     int n = sd_listen_fds(0);
464
465     LogInfo("sd_listen_fds returns: " << n);
466
467     if (n < 0) {
468         LogError("Error in sd_listend_fds");
469         ThrowMsg(Exception::InitFailed, "Error in sd_listend_fds");
470     }
471
472     for(fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START+n; ++fd) {
473         if (0 < sd_is_socket_unix(fd, SOCK_STREAM, 1,
474                                   desc.serviceHandlerPath.c_str(), 0))
475         {
476             LogInfo("Useable socket " << desc.serviceHandlerPath <<
477                 " was passed by SystemD under descriptor " << fd);
478             return fd;
479         }
480     }
481     LogError("No useable sockets were passed by systemd.");
482     return -1;
483 }
484
485 int SocketManager::CreateDomainSocketHelp(
486     const GenericSocketService::ServiceDescription &desc)
487 {
488     int sockfd;
489
490     if(desc.serviceHandlerPath.size()*sizeof(decltype(desc.serviceHandlerPath)::value_type) >=
491          sizeof(static_cast<sockaddr_un*>(0)->sun_path))
492     {
493         LogError("Service handler path too long: " << desc.serviceHandlerPath.size());
494         ThrowMsg(Exception::InitFailed,
495                  "Service handler path too long: " << desc.serviceHandlerPath.size());
496     }
497
498     if (-1 == (sockfd = socket(AF_UNIX, SOCK_STREAM, 0))) {
499         int err = errno;
500         LogError("Error in socket: " << GetErrnoString(err));
501         ThrowMsg(Exception::InitFailed, "Error in socket: " << GetErrnoString(err));
502     }
503
504     if (smack_check()) {
505         LogInfo("Set up smack label: " << desc.smackLabel);
506
507         if (0 != smack_fsetlabel(sockfd, desc.smackLabel.c_str(), SMACK_LABEL_IPIN)) {
508             LogError("Error in smack_fsetlabel");
509             ThrowMsg(Exception::InitFailed, "Error in smack_fsetlabel");
510         }
511     } else {
512         LogInfo("No smack on platform. Socket won't be securied with smack label!");
513     }
514
515     int flags;
516     if (-1 == (flags = fcntl(sockfd, F_GETFL, 0)))
517         flags = 0;
518
519     if (-1 == fcntl(sockfd, F_SETFL, flags | O_NONBLOCK)) {
520         int err = errno;
521         close(sockfd);
522         LogError("Error in fcntl: " << GetErrnoString(err));
523         ThrowMsg(Exception::InitFailed, "Error in fcntl: " << GetErrnoString(err));
524     }
525
526     sockaddr_un serverAddress;
527     memset(&serverAddress, 0, sizeof(serverAddress));
528     serverAddress.sun_family = AF_UNIX;
529     strcpy(serverAddress.sun_path, desc.serviceHandlerPath.c_str());
530     unlink(serverAddress.sun_path);
531
532     mode_t originalUmask;
533     originalUmask = umask(0);
534
535     if (-1 == bind(sockfd, (struct sockaddr*)&serverAddress, sizeof(serverAddress))) {
536         int err = errno;
537         close(sockfd);
538         LogError("Error in bind: " << GetErrnoString(err));
539         ThrowMsg(Exception::InitFailed, "Error in bind: " << GetErrnoString(err));
540     }
541
542     umask(originalUmask);
543
544     if (-1 == listen(sockfd, 5)) {
545         int err = errno;
546         close(sockfd);
547         LogError("Error in listen: " << GetErrnoString(err));
548         ThrowMsg(Exception::InitFailed, "Error in listen: " << GetErrnoString(err));
549     }
550
551     return sockfd;
552 }
553
554 void SocketManager::CreateDomainSocket(
555     GenericSocketService *service,
556     const GenericSocketService::ServiceDescription &desc)
557 {
558     int sockfd = GetSocketFromSystemD(desc);
559     if (-1 == sockfd)
560         sockfd = CreateDomainSocketHelp(desc);
561
562     auto &description = CreateDefaultReadSocketDescription(sockfd, false);
563
564     description.isListen = true;
565     description.interfaceID = desc.interfaceID;
566     description.service = service;
567
568     LogDebug("Listen on socket: " << sockfd <<
569         " Handler: " << desc.serviceHandlerPath.c_str());
570 }
571
572 void SocketManager::RegisterSocketService(GenericSocketService *service) {
573     service->SetSocketManager(this);
574     service->SetCommManager(&m_commMgr);
575     auto serviceVector = service->GetServiceDescription();
576     Try {
577         for (auto iter = serviceVector.begin(); iter != serviceVector.end(); ++iter)
578             CreateDomainSocket(service, *iter);
579     } Catch (Exception::Base) {
580         for (int i =0; i < (int)m_socketDescriptionVector.size(); ++i)
581         {
582             auto &desc = m_socketDescriptionVector[i];
583             if (desc.service == service && desc.isOpen) {
584                 close(i);
585                 desc.isOpen = false;
586             }
587         }
588         ReThrow(Exception::Base);
589     }
590 }
591
592 void SocketManager::Close(ConnectionID connectionID) {
593     {
594         std::lock_guard<std::mutex> ulock(m_eventQueueMutex);
595         m_closeQueue.push(connectionID);
596     }
597     NotifyMe();
598 }
599
600 void SocketManager::Write(ConnectionID connectionID, const RawBuffer &rawBuffer) {
601     WriteBuffer buffer;
602     buffer.connectionID = connectionID;
603     buffer.rawBuffer = rawBuffer;
604     {
605         std::lock_guard<std::mutex> ulock(m_eventQueueMutex);
606         m_writeBufferQueue.push(buffer);
607     }
608     NotifyMe();
609 }
610
611 void SocketManager::NotifyMe() {
612     TEMP_FAILURE_RETRY(write(m_notifyMe[1], "You have message ;-)", 1));
613 }
614
615 void SocketManager::ProcessQueue() {
616     WriteBuffer buffer;
617     {
618         std::lock_guard<std::mutex> ulock(m_eventQueueMutex);
619         while (!m_writeBufferQueue.empty()) {
620             buffer = m_writeBufferQueue.front();
621             m_writeBufferQueue.pop();
622
623             auto &desc = m_socketDescriptionVector[buffer.connectionID.sock];
624
625             if (!desc.isOpen) {
626                 LogDebug("Received packet for write but connection is closed. Packet ignored!");
627                 continue;
628             }
629
630             if (desc.counter != buffer.connectionID.counter)
631             {
632                 LogDebug("Received packet for write but counter is broken. Packet ignored!");
633                 continue;
634             }
635
636             std::copy(
637                 buffer.rawBuffer.begin(),
638                 buffer.rawBuffer.end(),
639                 std::back_inserter(desc.rawBuffer));
640
641             FD_SET(buffer.connectionID.sock, &m_writeSet);
642         }
643
644     }
645
646     while (1) {
647         ConnectionID connection;
648         {
649             std::lock_guard<std::mutex> ulock(m_eventQueueMutex);
650             if (m_closeQueue.empty())
651                 return;
652             connection = m_closeQueue.front();
653             m_closeQueue.pop();
654         }
655
656         if (!m_socketDescriptionVector[connection.sock].isOpen)
657             continue;
658
659         if (connection.counter != m_socketDescriptionVector[connection.sock].counter)
660             continue;
661
662         CloseSocket(connection.sock);
663     }
664 }
665
666 void SocketManager::CloseSocket(int sock) {
667 //    LogInfo("Closing socket: " << sock);
668     auto &desc = m_socketDescriptionVector[sock];
669
670     if (!(desc.isOpen)) {
671         // This may happend when some information was waiting for write to the
672         // socket and in the same time socket was closed by the client.
673         LogError("Socket " << sock << " is not open. Nothing to do!");
674         return;
675     }
676
677     GenericSocketService::CloseEvent event;
678     event.connectionID.sock = sock;
679     event.connectionID.counter = desc.counter;
680     auto service = desc.service;
681
682     desc.isOpen = false;
683     desc.service = NULL;
684     desc.interfaceID = -1;
685     desc.rawBuffer.clear();
686
687     if (service)
688         service->Event(event);
689     else
690         LogError("Critical! Service is NULL! This should never happend!");
691
692     TEMP_FAILURE_RETRY(close(sock));
693     FD_CLR(sock, &m_readSet);
694     FD_CLR(sock, &m_writeSet);
695 }
696
697 } // namespace CKM