2 * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Bumjin Im <bj.im@samsung.com>
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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
20 * @author Zbigniew Jasinski (z.jasinski@samsung.com)
21 * @author Lukasz Kostyra (l.kostyra@partner.samsung.com)
23 * @brief Implementation of password service
29 #include <dpl/log/log.h>
30 #include <dpl/serialization.h>
34 #include <security-server.h>
35 #include <password-exception.h>
37 namespace SecurityServer {
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.
47 // Please note: SocketManager does not use it and
48 // does not check it in any way.
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;
57 } // namespace anonymous
59 GenericSocketService::ServiceDescriptionVector PasswordService::GetServiceDescription()
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}
68 void PasswordService::accept(const AcceptEvent &event)
70 LogSecureDebug("Accept event. ConnectionID.sock: " << event.connectionID.sock
71 << " ConnectionID.counter: " << event.connectionID.counter
72 << " ServiceID: " << event.interfaceID);
74 auto &info = m_connectionInfoMap[event.connectionID.counter];
75 info.interfaceID = event.interfaceID;
78 void PasswordService::write(const WriteEvent &event)
80 LogSecureDebug("WriteEvent. ConnectionID: " << event.connectionID.sock <<
81 " Size: " << event.size << " Left: " << event.left);
83 m_serviceManager->Close(event.connectionID);
86 void PasswordService::process(const ReadEvent &event)
88 LogSecureDebug("Read event for counter: " << event.connectionID.counter);
89 auto &info = m_connectionInfoMap[event.connectionID.counter];
90 info.buffer.Push(event.rawBuffer);
92 // We can get several requests in one package.
93 // Extract and process them all
94 while(processOne(event.connectionID, info.buffer, info.interfaceID));
97 void PasswordService::close(const CloseEvent &event)
99 LogSecureDebug("CloseEvent. ConnectionID: " << event.connectionID.sock);
100 m_connectionInfoMap.erase(event.connectionID.counter);
103 int PasswordService::processCheckFunctions(PasswordHdrs hdr, MessageBuffer& buffer,
104 unsigned int &cur_att, unsigned int &max_att,
105 unsigned int &exp_time)
107 int result = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
110 case PasswordHdrs::HDR_IS_PWD_VALID:
111 result = m_pwdManager.isPwdValid(cur_att, max_att, exp_time);
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);
122 LogError("Unknown msg header.");
123 Throw(Exception::IncorrectHeader);
129 int PasswordService::processSetFunctions(PasswordHdrs hdr, MessageBuffer& buffer)
131 int result = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
133 std::string curPwd, newPwd;
134 unsigned int rec_att = 0, rec_days = 0, rec_max_challenge = 0, rec_history = 0;
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);
145 case PasswordHdrs::HDR_SET_PWD_VALIDITY:
146 Deserialization::Deserialize(buffer, rec_days);
147 result = m_pwdManager.setPasswordValidity(rec_days);
150 case PasswordHdrs::HDR_SET_PWD_MAX_CHALLENGE:
151 Deserialization::Deserialize(buffer, rec_max_challenge);
152 result = m_pwdManager.setPasswordMaxChallenge(rec_max_challenge);
155 case PasswordHdrs::HDR_SET_PWD_HISTORY:
156 Deserialization::Deserialize(buffer, rec_history);
157 result = m_pwdManager.setPasswordHistory(rec_history);
161 LogError("Unknown msg header.");
162 Throw(Exception::IncorrectHeader);
168 int PasswordService::processResetFunctions(PasswordHdrs hdr, MessageBuffer& buffer)
170 int result = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
173 unsigned int rec_att = 0, rec_days = 0;
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);
184 LogError("Unknown msg header.");
185 Throw(Exception::IncorrectHeader);
191 bool PasswordService::processOne(const ConnectionID &conn, MessageBuffer &buffer,
192 InterfaceID interfaceID)
194 LogSecureDebug("Iteration begin");
196 MessageBuffer sendBuffer;
198 int retCode = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
199 unsigned int cur_att = 0, max_att = 0, exp_time = 0;
204 Try { //try..catch for MessageBuffer errors, closes connection when exception is thrown
206 Deserialization::Deserialize(buffer, tempHdr);
207 PasswordHdrs hdr = static_cast<PasswordHdrs>(tempHdr);
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);
216 retCode = processSetFunctions(hdr, buffer);
219 case SOCKET_ID_RESET:
220 retCode = processResetFunctions(hdr, buffer);
224 LogError("Wrong interfaceID.");
225 Throw(Exception::IncorrectHeader);
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;
235 //everything is OK, send return code and extra data
236 Serialization::Serialize(sendBuffer, retCode);
238 //Returning additional information should occur only when checking functions
239 //are called, and under certain return values
240 if(interfaceID == SOCKET_ID_CHECK)
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);
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);
266 m_serviceManager->Write(conn, sendBuffer.Pop());
267 } Catch (MessageBuffer::Exception::Base) {
268 LogError("Broken protocol. Closing socket.");
269 m_serviceManager->Close(conn);
271 } Catch (PasswordService::Exception::Base) {
272 LogError("Incorrect message header. Closing socket.");
273 m_serviceManager->Close(conn);
282 } // namespace SecurityServer