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