Drop all encryption requests upon disconnection
[platform/core/security/key-manager.git] / src / manager / service / encryption-service.cpp
1 /*
2  *  Copyright (c) 2015 - 2020 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License
15  */
16 /*
17  * @file       encryption-service.cpp
18  * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
19  * @version    1.0
20  */
21
22 #include <stdexcept>
23 #include <utility>
24 #include <encryption-service.h>
25 #include <protocols.h>
26 #include <dpl/log/log.h>
27 #include <dpl/serialization.h>
28 #include <crypto-request.h>
29
30 namespace {
31 const CKM::InterfaceID SOCKET_ID_ENCRYPTION = 0;
32 } // namespace anonymous
33
34 namespace CKM {
35
36 EncryptionService::EncryptionService() :
37         m_logic(*this)
38 {
39 }
40
41 EncryptionService::~EncryptionService()
42 {
43 }
44
45 void EncryptionService::RespondToClient(const CryptoRequest &request,
46                                                                                 int retCode,
47                                                                                 const RawBuffer &data)
48 {
49         try {
50                 RawBuffer response = SerializeMessage(request.msgId, retCode, data);
51                 m_serviceManager->Write(request.conn, response);
52         } catch (...) {
53                 LogError("Failed to send response to the client");
54         }
55 }
56
57 void EncryptionService::RequestKey(unsigned id, const CryptoRequest &request)
58 {
59         MsgKeyRequest kReq(id, request.cred, request.name,
60                                            request.explicitOwner, request.password);
61
62         if (!m_commMgr->SendMessage(kReq))
63                 throw std::runtime_error("No listener found");// TODO
64 }
65
66 GenericSocketService::ServiceDescriptionVector
67 EncryptionService::GetServiceDescription()
68 {
69         return ServiceDescriptionVector {
70                 {SERVICE_SOCKET_ENCRYPTION, "http://tizen.org/privilege/keymanager", SOCKET_ID_ENCRYPTION}
71         };
72 }
73
74 void EncryptionService::Start()
75 {
76         Create();
77 }
78
79 void EncryptionService::Stop()
80 {
81         Join();
82 }
83
84 void EncryptionService::SetCommManager(CommMgr *manager)
85 {
86         ThreadService::SetCommManager(manager);
87         Register(*manager);
88 }
89
90 // Encryption Service does not support any kind of security-check
91 // and 3rd parameter is not required
92 bool EncryptionService::ProcessOne(
93         const ConnectionID &conn,
94         ConnectionInfo &info,
95         bool /*allowed*/)
96 {
97         LogDebug("process One");
98
99         try {
100                 if (!info.buffer.Ready())
101                         return false;
102
103                 ProcessEncryption(conn, info.credentials, info.buffer);
104                 return true;
105         } catch (MessageBuffer::Exception::Base &) {
106                 LogError("Broken protocol. Closing socket.");
107         } catch (const std::exception &e) {
108                 LogError("Std exception:: " << e.what());
109         } catch (...) {
110                 LogError("Unknown exception. Closing socket.");
111         }
112
113         m_serviceManager->Close(conn);
114         return false;
115 }
116
117 void EncryptionService::ProcessMessage(MsgKeyResponse msg)
118 {
119         m_logic.KeyRetrieved(std::move(msg));
120 }
121
122 void EncryptionService::ProcessEncryption(const ConnectionID &conn,
123                 const Credentials &cred,
124                 MessageBuffer &buffer)
125 {
126         int tmpCmd = 0;
127         CryptoRequest req;
128
129         buffer.Deserialize(tmpCmd, req.msgId, req.cas, req.name, req.explicitOwner,
130                                            req.password, req.input);
131         req.command = static_cast<EncryptionCommand>(tmpCmd);
132
133         if (req.command != EncryptionCommand::ENCRYPT &&
134                         req.command != EncryptionCommand::DECRYPT)
135                 throw std::runtime_error("Unsupported command: " + tmpCmd);
136
137         req.conn = conn;
138         req.cred = cred;
139         m_logic.Crypt(req);
140 }
141
142 void EncryptionService::CustomHandle(const ReadEvent &event)
143 {
144         auto &info = m_connectionInfoMap[event.connectionID.counter];
145         info.buffer.Push(RawBuffer(event.rawBuffer));
146
147         while (ProcessOne(event.connectionID, info, true));
148 }
149
150 void EncryptionService::CustomHandle(const SecurityEvent &/*event*/)
151 {
152         LogError("This should not happend! SecurityEvent was called on EncryptionService!");
153 }
154
155 void EncryptionService::CustomHandle(const CloseEvent &event)
156 {
157         // call the default handler
158         ThreadService::Handle(event);
159
160         m_logic.DropRequests(event.connectionID);
161 }
162
163 } /* namespace CKM */