Add smackfs check to Installer service.
[platform/core/security/security-manager.git] / src / server / service / password.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        password.cpp
20  * @author      Zbigniew Jasinski (z.jasinski@samsung.com)
21  * @author      Lukasz Kostyra (l.kostyra@partner.samsung.com)
22  * @version     1.0
23  * @brief       Implementation of password service
24  */
25
26 #include <iostream>
27 #include <string>
28
29 #include <dpl/log/log.h>
30 #include <dpl/serialization.h>
31
32 #include <password.h>
33
34 #include <security-server.h>
35 #include <password-exception.h>
36
37 namespace SecurityServer {
38
39 namespace {
40 // Service may open more than one socket.
41 // These ID's will be assigned to sockets
42 // and will be used only by service.
43 // When new connection arrives, AcceptEvent
44 // will be generated with proper ID to inform
45 // service about input socket.
46 //
47 // Please note: SocketManager does not use it and
48 // does not check it in any way.
49 //
50 // If your service requires only one socket
51 // (uses only one socket labeled with smack)
52 // you may ignore this ID (just pass 0)
53 const InterfaceID SOCKET_ID_CHECK   = 0;
54 const InterfaceID SOCKET_ID_SET     = 1;
55 const InterfaceID SOCKET_ID_RESET   = 2;
56
57 } // namespace anonymous
58
59 GenericSocketService::ServiceDescriptionVector PasswordService::GetServiceDescription()
60 {
61     return ServiceDescriptionVector {
62         {SERVICE_SOCKET_PASSWD_CHECK, "security-server::api-password-check", SOCKET_ID_CHECK},
63         {SERVICE_SOCKET_PASSWD_SET,   "security-server::api-password-set",   SOCKET_ID_SET},
64         {SERVICE_SOCKET_PASSWD_RESET, "security-server::api-password-reset", SOCKET_ID_RESET}
65     };
66 }
67
68 void PasswordService::accept(const AcceptEvent &event)
69 {
70     LogSecureDebug("Accept event. ConnectionID.sock: " << event.connectionID.sock
71         << " ConnectionID.counter: " << event.connectionID.counter
72         << " ServiceID: " << event.interfaceID);
73
74     auto &info = m_connectionInfoMap[event.connectionID.counter];
75     info.interfaceID = event.interfaceID;
76 }
77
78 void PasswordService::write(const WriteEvent &event)
79 {
80     LogSecureDebug("WriteEvent. ConnectionID: " << event.connectionID.sock <<
81         " Size: " << event.size << " Left: " << event.left);
82     if (event.left == 0)
83         m_serviceManager->Close(event.connectionID);
84 }
85
86 void PasswordService::process(const ReadEvent &event)
87 {
88     LogSecureDebug("Read event for counter: " << event.connectionID.counter);
89     auto &info = m_connectionInfoMap[event.connectionID.counter];
90     info.buffer.Push(event.rawBuffer);
91
92     // We can get several requests in one package.
93     // Extract and process them all
94     while(processOne(event.connectionID, info.buffer, info.interfaceID));
95 }
96
97 void PasswordService::close(const CloseEvent &event)
98 {
99     LogSecureDebug("CloseEvent. ConnectionID: " << event.connectionID.sock);
100     m_connectionInfoMap.erase(event.connectionID.counter);
101 }
102
103 int PasswordService::processCheckFunctions(PasswordHdrs hdr, MessageBuffer& buffer,
104                                             unsigned int &cur_att, unsigned int &max_att,
105                                             unsigned int &exp_time)
106 {
107     int result = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
108
109     switch (hdr) {
110         case PasswordHdrs::HDR_IS_PWD_VALID:
111             result = m_pwdManager.isPwdValid(cur_att, max_att, exp_time);
112             break;
113
114         case PasswordHdrs::HDR_CHK_PWD: {
115             std::string challenge;
116             Deserialization::Deserialize(buffer, challenge);
117             result = m_pwdManager.checkPassword(challenge, cur_att, max_att, exp_time);
118             break;
119         }
120
121         default:
122             LogError("Unknown msg header.");
123             Throw(Exception::IncorrectHeader);
124     }
125
126     return result;
127 }
128
129 int PasswordService::processSetFunctions(PasswordHdrs hdr, MessageBuffer& buffer)
130 {
131     int result = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
132
133     std::string curPwd, newPwd;
134     unsigned int rec_att = 0, rec_days = 0, rec_max_challenge = 0, rec_history = 0;
135
136     switch(hdr) {
137         case PasswordHdrs::HDR_SET_PWD:
138             Deserialization::Deserialize(buffer, curPwd);
139             Deserialization::Deserialize(buffer, newPwd);
140             Deserialization::Deserialize(buffer, rec_att);
141             Deserialization::Deserialize(buffer, rec_days);
142             result = m_pwdManager.setPassword(curPwd, newPwd, rec_att, rec_days);
143             break;
144
145         case PasswordHdrs::HDR_SET_PWD_VALIDITY:
146             Deserialization::Deserialize(buffer, rec_days);
147             result = m_pwdManager.setPasswordValidity(rec_days);
148             break;
149
150         case PasswordHdrs::HDR_SET_PWD_MAX_CHALLENGE:
151             Deserialization::Deserialize(buffer, rec_max_challenge);
152             result = m_pwdManager.setPasswordMaxChallenge(rec_max_challenge);
153             break;
154
155         case PasswordHdrs::HDR_SET_PWD_HISTORY:
156             Deserialization::Deserialize(buffer, rec_history);
157             result = m_pwdManager.setPasswordHistory(rec_history);
158             break;
159
160         default:
161             LogError("Unknown msg header.");
162             Throw(Exception::IncorrectHeader);
163     }
164
165     return result;
166 }
167
168 int PasswordService::processResetFunctions(PasswordHdrs hdr, MessageBuffer& buffer)
169 {
170     int result = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
171
172     std::string newPwd;
173     unsigned int rec_att = 0, rec_days = 0;
174
175     switch(hdr) {
176         case PasswordHdrs::HDR_RST_PWD:
177             Deserialization::Deserialize(buffer, newPwd);
178             Deserialization::Deserialize(buffer, rec_att);
179             Deserialization::Deserialize(buffer, rec_days);
180             result = m_pwdManager.resetPassword(newPwd, rec_att, rec_days);
181             break;
182
183         default:
184             LogError("Unknown msg header.");
185             Throw(Exception::IncorrectHeader);
186     }
187
188     return result;
189 }
190
191 bool PasswordService::processOne(const ConnectionID &conn, MessageBuffer &buffer,
192                                  InterfaceID interfaceID)
193 {
194     LogSecureDebug("Iteration begin");
195
196     MessageBuffer sendBuffer;
197
198     int retCode = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
199     unsigned int cur_att = 0, max_att = 0, exp_time = 0;
200
201     if (!buffer.Ready())
202         return false;
203
204     Try {       //try..catch for MessageBuffer errors, closes connection when exception is thrown
205         int tempHdr;
206         Deserialization::Deserialize(buffer, tempHdr);
207         PasswordHdrs hdr = static_cast<PasswordHdrs>(tempHdr);
208
209         try {   //try..catch for internal service errors, assigns error code for returning.
210             switch (interfaceID) {
211                 case SOCKET_ID_CHECK:
212                     retCode = processCheckFunctions(hdr, buffer, cur_att, max_att, exp_time);
213                     break;
214
215                 case SOCKET_ID_SET:
216                     retCode = processSetFunctions(hdr, buffer);
217                     break;
218
219                 case SOCKET_ID_RESET:
220                     retCode = processResetFunctions(hdr, buffer);
221                     break;
222
223                 default:
224                     LogError("Wrong interfaceID.");
225                     Throw(Exception::IncorrectHeader);
226             }
227         } catch (PasswordException::Base &e) {
228             LogError("Password error: " << e.DumpToString());
229             retCode = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
230         } catch (std::exception &e) {
231             LogError("STD error: " << e.what());
232             retCode = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
233         }
234
235         //everything is OK, send return code and extra data
236         Serialization::Serialize(sendBuffer, retCode);
237
238         //Returning additional information should occur only when checking functions
239         //are called, and under certain return values
240         if(interfaceID == SOCKET_ID_CHECK)
241         {
242             switch(retCode)
243             {
244             case SECURITY_SERVER_API_ERROR_PASSWORD_EXIST:
245             case SECURITY_SERVER_API_ERROR_PASSWORD_MISMATCH:
246             case SECURITY_SERVER_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED:
247             case SECURITY_SERVER_API_ERROR_PASSWORD_EXPIRED:
248                 Serialization::Serialize(sendBuffer, cur_att);
249                 Serialization::Serialize(sendBuffer, max_att);
250                 Serialization::Serialize(sendBuffer, exp_time);
251                 break;
252
253             case SECURITY_SERVER_API_SUCCESS:
254                 if(hdr == PasswordHdrs::HDR_CHK_PWD) {
255                     Serialization::Serialize(sendBuffer, cur_att);
256                     Serialization::Serialize(sendBuffer, max_att);
257                     Serialization::Serialize(sendBuffer, exp_time);
258                 }
259                 break;
260
261             default:
262                 break;
263             }
264         }
265
266         m_serviceManager->Write(conn, sendBuffer.Pop());
267     } Catch (MessageBuffer::Exception::Base) {
268         LogError("Broken protocol. Closing socket.");
269         m_serviceManager->Close(conn);
270         return false;
271     } Catch (PasswordService::Exception::Base) {
272         LogError("Incorrect message header. Closing socket.");
273         m_serviceManager->Close(conn);
274         return false;
275     }
276
277
278
279     return true;
280 }
281
282 } // namespace SecurityServer
283