2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
17 #include <sys/types.h>
19 #include <unordered_map>
21 #include <dpm/pil/policy-context.h>
22 #include <dpm/pil/policy-model.h>
23 #include <dpm/pil/policy-storage.h>
24 #include <dpm/pil/app-bundle.h>
25 #include <dpm/pil/launchpad.h>
27 #include "password-manager.h"
30 DPM_PASSWORD_QUALITY_UNSPECIFIED = 0x00, /**< No requirements for password. */
31 DPM_PASSWORD_QUALITY_SIMPLE_PASSWORD = 0x01, /**< Eas requirement for simple password */
32 DPM_PASSWORD_QUALITY_SOMETHING = 0x10, /**< Some kind password is required, but doesn't care what it is */
33 DPM_PASSWORD_QUALITY_NUMERIC = 0x20, /**< Containing at least numeric characters */
34 DPM_PASSWORD_QUALITY_ALPHABETIC = 0x40, /**< Containing at least alphabetic (or other symbol) characters */
35 DPM_PASSWORD_QUALITY_ALPHANUMERIC = 0x80, /**< Containing at least numeric and alphabetic characters */
36 } PasswordPolicyQuality;
39 DPM_PASSWORD_STATUS_NORMAL, /**< Password normal status */
40 DPM_PASSWORD_STATUS_CHANGED, /**< Password successfully changed */
41 DPM_PASSWORD_STATUS_NOT_CHANGED, /**< Password not changed */
42 DPM_PASSWORD_STATUS_CHANGE_REQUIRED , /**< Password change required */
43 DPM_PASSWORD_STATUS_MAX_ATTEMPTS_EXCEEDED, /**< Password Max Attempts Exceeded*/
45 DPM_PASSWORD_STATUS_EXPIRED, /**< Password expired */
46 DPM_PASSWORD_STATUS_RECOVERY_PASSWORD_FAILED, /**< Device unlock failed by Password Recovery */
47 DPM_PASSWORD_STATUS_RECOVERY_PASSWORD_SUCCEEDED,/**< Device unlock succeeded by Password Recovery */
49 DPM_PASSWORD_STATUS_QUALITY_CHANGED, /**< Password quality successfully changed */
50 DPM_PASSWORD_STATUS_MIN_LENGTH_CHANGED, /**< Password min_length successfully changed */
51 DPM_PASSWORD_STATUS_COMPLEX_CHAR_CHANGED, /**< Password complex_char successfully changed */
52 DPM_PASSWORD_STATUS_PATTERN_CHANGED, /**< Password pattern successfully changed */
53 DPM_PASSWORD_STATUS_MAX
54 } PasswordPolicyStatus;
58 const int simplePasswordLength = 4;
59 const int infinite = 32767;
61 std::unordered_map<uid_t, int> passwordStatus;
63 inline int inverse(int value)
68 inline PasswordManager::QualityType getPasswordQualityType(int quality)
71 case DPM_PASSWORD_QUALITY_UNSPECIFIED:
72 return AUTH_PWD_QUALITY_UNSPECIFIED;
73 case DPM_PASSWORD_QUALITY_SIMPLE_PASSWORD:
74 return AUTH_PWD_QUALITY_UNSPECIFIED;
75 case DPM_PASSWORD_QUALITY_SOMETHING:
76 return AUTH_PWD_QUALITY_SOMETHING;
77 case DPM_PASSWORD_QUALITY_NUMERIC:
78 return AUTH_PWD_QUALITY_NUMERIC;
79 case DPM_PASSWORD_QUALITY_ALPHABETIC:
80 return AUTH_PWD_QUALITY_ALPHABETIC;
81 case DPM_PASSWORD_QUALITY_ALPHANUMERIC:
82 return AUTH_PWD_QUALITY_ALPHANUMERIC;
84 throw runtime::Exception("Unknown quality type: " + std::to_string(quality));
90 class PasswordQuality : public DomainPolicy<DataSetInt> {
92 PasswordQuality() : DomainPolicy("password-quality")
96 bool apply(const DataType& value, uid_t domain)
99 int auth = DPM_PASSWORD_QUALITY_UNSPECIFIED;
101 int quality = inverse(value);
102 if (quality & DPM_PASSWORD_QUALITY_SIMPLE_PASSWORD) {
103 auth = quality - DPM_PASSWORD_QUALITY_SIMPLE_PASSWORD;
106 PasswordManager::QualityType type = getPasswordQualityType(auth);
108 PasswordManager passwordManager(domain);
109 passwordManager.setQuality(type);
110 passwordManager.enforce();
111 } catch (runtime::Exception &e) {
120 class PasswordSequences : public DomainPolicy<DataSetInt> {
122 PasswordSequences() : DomainPolicy("password-numeric-sequences-length")
126 bool apply(const DataType& value, uid_t domain)
130 v = v == infinite ? 0 : v;
131 PasswordManager passwordManager(domain);
132 passwordManager.setMaximumNumericSequenceLength(v);
133 passwordManager.enforce();
134 } catch (runtime::Exception &e) {
143 class PasswordOccurrences : public DomainPolicy<DataSetInt> {
145 PasswordOccurrences() : DomainPolicy("password-maximum-character-occurrences")
149 bool apply(const DataType& value, uid_t domain)
153 v = v == infinite ? 0 : v;
154 PasswordManager passwordManager(domain);
155 passwordManager.setMaximumCharacterOccurrences(value);
156 passwordManager.enforce();
157 } catch (runtime::Exception &e) {
166 class PasswordHistory : public DomainPolicy<DataSetInt> {
168 PasswordHistory() : DomainPolicy("password-history")
172 bool apply(const DataType& value, uid_t domain)
175 PasswordManager passwordManager(domain);
176 passwordManager.setHistory(inverse(value));
177 passwordManager.enforce();
178 } catch (runtime::Exception &e) {
187 class PasswordExpire : public DomainPolicy<DataSetInt> {
189 PasswordExpire() : DomainPolicy("password-expired")
193 bool apply(const DataType& value, uid_t domain)
196 PasswordManager passwordManager(domain);
197 passwordManager.setExpires(value);
198 passwordManager.enforce();
199 } catch (runtime::Exception &e) {
208 class PasswordFailureCount : public DomainPolicy<DataSetInt> {
210 PasswordFailureCount() : DomainPolicy("password-maximum-failure-count")
214 bool apply(const DataType& value, uid_t domain)
217 PasswordManager passwordManager(domain);
218 passwordManager.setMaximumFailedForWipe(value);
219 passwordManager.enforce();
220 } catch (runtime::Exception &e) {
229 class PasswordComplexity : public DomainPolicy<DataSetInt> {
231 PasswordComplexity() : DomainPolicy("password-minimum-complexity")
235 bool apply(const DataType& value, uid_t domain)
238 PasswordManager passwordManager(domain);
239 passwordManager.setMinimumComplexCharacters(inverse(value));
240 passwordManager.enforce();
241 } catch (runtime::Exception &e) {
250 class PasswordLength : public DomainPolicy<DataSetInt> {
252 PasswordLength() : DomainPolicy("password-minimum-length")
256 bool apply(const DataType& value, uid_t domain)
259 PasswordManager passwordManager(domain);
260 passwordManager.setMinimumLength(inverse(value));
261 passwordManager.enforce();
262 } catch (runtime::Exception &e) {
271 class PasswordTimeout : public DomainPolicy<DataSetInt> {
273 PasswordTimeout() : DomainPolicy("password-inactivity-timeout")
277 bool apply(const DataType& value, uid_t domain)
283 class PasswordRecovery : public DomainPolicy<DataSetInt> {
285 PasswordRecovery() : DomainPolicy("password-recovery")
289 bool apply(const DataType& value, uid_t domain)
295 class Password : public AbstractPolicyProvider {
297 int setQuality(int quality);
299 int setMinimumLength(int value);
300 int getMinimumLength();
301 int setMinComplexChars(int value);
302 int getMinComplexChars();
303 int setMaximumFailedForWipe(int value);
304 int getMaximumFailedForWipe();
305 int setExpires(int value);
307 int setHistory(int value);
309 int setPattern(const std::string &pattern);
310 int reset(const std::string &passwd);
312 int setMaxInactivityTimeDeviceLock(int value);
313 int getMaxInactivityTimeDeviceLock();
314 int setStatus(int status);
317 std::string getPattern();
318 int setMaximumCharacterOccurrences(int value);
319 int getMaximumCharacterOccurrences();
320 int setMaximumNumericSequenceLength(int value);
321 int getMaximumNumericSequenceLength();
322 int setForbiddenStrings(const std::vector<std::string> &forbiddenStrings);
323 std::vector<std::string> getForbiddenStrings();
324 int setRecovery(int enable);
328 PasswordQuality quality;
329 PasswordHistory history;
330 PasswordLength length;
331 PasswordComplexity complexity;
332 PasswordTimeout timeout;
333 PasswordExpire expire;
334 PasswordFailureCount failureCount;
335 PasswordSequences sequences;
336 PasswordOccurrences occurrences;
337 PasswordRecovery recovery;
340 int Password::setQuality(int value)
343 quality.set(inverse(value));
344 if (value & DPM_PASSWORD_QUALITY_SIMPLE_PASSWORD) {
345 length.set(inverse(simplePasswordLength));
347 } catch (runtime::Exception& e) {
355 int Password::getQuality()
357 int value = quality.get();
358 return inverse(value);
361 int Password::setMinimumLength(int value)
364 value = inverse(value);
366 } catch (runtime::Exception& e) {
374 int Password::getMinimumLength()
376 int value = length.get();
377 return inverse(value);
380 int Password::setMinComplexChars(int value)
383 value = inverse(value);
384 complexity.set(value);
385 } catch (runtime::Exception& e) {
393 int Password::getMinComplexChars()
395 int value = complexity.get();
396 return inverse(value);
399 int Password::setMaximumFailedForWipe(int value)
402 value = value == 0 ? infinite : value;
403 failureCount.set(value);
404 } catch (runtime::Exception& e) {
412 int Password::getMaximumFailedForWipe()
414 int value = failureCount.get();
415 return value == infinite ? 0 : value;
418 int Password::setExpires(int value)
421 value = value == 0 ? infinite : value;
423 } catch (runtime::Exception& e) {
431 int Password::getExpires()
433 int value = expire.get();
434 return value == infinite ? 0 : value;
437 int Password::setHistory(int value)
440 value = inverse(value);
442 } catch (runtime::Exception& e) {
450 int Password::getHistory()
452 int value = history.get();
453 return inverse(value);
456 int Password::reset(const std::string &passwd)
459 PasswordManager passwordManager(rmi::Service::getPeerUid());
460 passwordManager.resetPassword(passwd);
461 } catch (runtime::Exception& e) {
469 int Password::enforceChange()
473 bundle.add("id", "password-enforce-change");
475 Launchpad launchpad(rmi::Service::getPeerUid());
476 launchpad.launch("org.tizen.dpm-syspopup", bundle);
477 passwordStatus[rmi::Service::getPeerUid()] = DPM_PASSWORD_STATUS_CHANGE_REQUIRED;
478 } catch (runtime::Exception& e) {
486 int Password::setMaxInactivityTimeDeviceLock(int value)
489 value = value == 0 ? infinite : value;
491 } catch (runtime::Exception& e) {
499 int Password::getMaxInactivityTimeDeviceLock()
501 int value = timeout.get();
502 return value == infinite ? 0 : value;
505 int Password::setStatus(int status)
507 if (status >= DPM_PASSWORD_STATUS_MAX) {
508 ERROR("Invalid password status");
512 passwordStatus[rmi::Service::getPeerUid()] = status;
513 //ctx.notify("password", "password-status");
518 int Password::getStatus()
520 return passwordStatus[rmi::Service::getPeerUid()];
523 int Password::setMaximumCharacterOccurrences(int value)
526 value = value == 0 ? infinite : value;
527 occurrences.set(value);
528 } catch (runtime::Exception& e) {
536 int Password::getMaximumCharacterOccurrences()
538 int value = occurrences.get();
539 return value == infinite ? 0 : value;
542 int Password::setMaximumNumericSequenceLength(int value)
545 value = value == 0 ? infinite : value;
546 sequences.set(value);
547 } catch (runtime::Exception& e) {
555 int Password::getMaximumNumericSequenceLength()
557 int value = sequences.get();
558 return value == infinite ? 0 : value;
561 int Password::setRecovery(int enable)
564 enable = inverse(enable);
565 recovery.set(enable);
566 } catch (runtime::Exception& e) {
574 int Password::getRecovery()
576 int value = recovery.get();
577 return inverse(value);
582 #define PRIVILEGE "http://tizen.org/privilege/dpm.password"
584 AbstractPolicyProvider *PolicyFactory(PolicyControlContext& context)
586 Password *policy = new Password();
588 context.expose(policy, PRIVILEGE, (int)(Password::setQuality)(int));
589 context.expose(policy, PRIVILEGE, (int)(Password::setMinimumLength)(int));
590 context.expose(policy, PRIVILEGE, (int)(Password::setMinComplexChars)(int));
591 context.expose(policy, PRIVILEGE, (int)(Password::setMaximumFailedForWipe)(int));
592 context.expose(policy, PRIVILEGE, (int)(Password::setExpires)(int));
593 context.expose(policy, PRIVILEGE, (int)(Password::setHistory)(int));
594 context.expose(policy, PRIVILEGE, (int)(Password::reset)(std::string));
595 context.expose(policy, PRIVILEGE, (int)(Password::enforceChange)());
596 context.expose(policy, PRIVILEGE, (int)(Password::setMaxInactivityTimeDeviceLock)(int));
597 context.expose(policy, PRIVILEGE, (int)(Password::setStatus)(int));
598 context.expose(policy, PRIVILEGE, (int)(Password::setMaximumCharacterOccurrences)(int));
599 context.expose(policy, PRIVILEGE, (int)(Password::setMaximumNumericSequenceLength)(int));
600 context.expose(policy, PRIVILEGE, (int)(Password::setRecovery)(int));
602 context.expose(policy, "", (int)(Password::getStatus)());
603 context.expose(policy, PRIVILEGE, (int)(Password::getQuality)());
604 context.expose(policy, PRIVILEGE, (int)(Password::getMinimumLength)());
605 context.expose(policy, PRIVILEGE, (int)(Password::getMinComplexChars)());
606 context.expose(policy, PRIVILEGE, (int)(Password::getMaximumFailedForWipe)());
607 context.expose(policy, PRIVILEGE, (int)(Password::getExpires)());
608 context.expose(policy, PRIVILEGE, (int)(Password::getHistory)());
609 context.expose(policy, PRIVILEGE, (int)(Password::getMaxInactivityTimeDeviceLock)());
610 context.expose(policy, PRIVILEGE, (int)(Password::getMaximumCharacterOccurrences)());
611 context.expose(policy, PRIVILEGE, (int)(Password::getMaximumNumericSequenceLength)());
612 context.expose(policy, "", (int)(Password::getRecovery)());