ADD_SUBDIRECTORY(src)
ADD_SUBDIRECTORY(pkgconfig)
ADD_SUBDIRECTORY(systemd)
+ADD_SUBDIRECTORY(conf)
--- /dev/null
+# Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# @file CMakeLists.txt
+# @author Jooseong Lee <jooseong.lee@samsung.com>
+#
+IF("${PROFILE}" STREQUAL "mobile")
+ INSTALL(FILES client-whitelist_mobile DESTINATION ${SYS_CONFIG_DIR}/${SERVICE_NAME} RENAME client-whitelist)
+ELSE("${PROFILE}" STREQUAL "mobile")
+ INSTALL(FILES client-whitelist DESTINATION ${SYS_CONFIG_DIR}/${SERVICE_NAME})
+ENDIF()
+
+INSTALL(FILES admin-client-whitelist DESTINATION ${SYS_CONFIG_DIR}/${SERVICE_NAME})
--- /dev/null
+# subject labels allowed to use password reset and password policy setting
+# put each allowed label in new line
+System
+System::Privileged
--- /dev/null
+# subject labels allowed to use password checking/setting
+# put each allowed label in new line
+System
+System::Privileged
+User
--- /dev/null
+# subject labels allowed to use password checking/setting
+# put each allowed label in new line
+System
+System::Privileged
+User
+User::App::org.tizen.keyguard
+User::App::org.tizen.lockscreen
+User::App::setting-password-efl
+User::App::setting-locktype-efl
-DSERVICE_NAME=%{name} \
-DBIN_DIR:PATH=%{bin_dir} \
-DSBIN_DIR:PATH=%{sbin_dir} \
+ -DSYS_CONFIG_DIR:PATH=%{_sysconfdir} \
-DRUN_DIR:PATH=%{run_dir} \
-DRW_DATA_DIR:PATH=%{rw_data_dir} \
-DSYSTEMD_UNIT_DIR:PATH=%{_unitdir} \
-DSOCK_PASSWD_CHECK=%{sock_passwd_check} \
-DSOCK_PASSWD_SET=%{sock_passwd_set} \
-DSOCK_PASSWD_RESET=%{sock_passwd_reset} \
- -DSOCK_PASSWD_POLICY=%{sock_passwd_policy}
+ -DSOCK_PASSWD_POLICY=%{sock_passwd_policy} \
+ -DPROFILE=%{profile}
make %{?jobs:-j%jobs}
%{_unitdir}/sockets.target.wants/%{sock_passwd_set}
%{_unitdir}/sockets.target.wants/%{sock_passwd_reset}
%{_unitdir}/sockets.target.wants/%{sock_passwd_policy}
+%{_sysconfdir}/%{name}/client-whitelist
+%{_sysconfdir}/%{name}/admin-client-whitelist
%dir %attr(770, %{user_name}, %{group_name}) %{rw_data_dir}
%files -n lib%{name}-client
#ifndef _SMACK_CHECK_H_
#define _SMACK_CHECK_H_
+#include <string>
+
namespace AuthPasswd {
+extern const std::string CLIENT_WHITELIST;
+extern const std::string ADMIN_CLIENT_WHITELIST;
+
/*
* A very simple runtime check for SMACK on the platform
* Returns 1 if SMACK is present, 0 otherwise. If SMACK_ENABLED is not defined
*/
int smack_check(void);
+/*
+ * Check whether client is allowed or not on whitelist.
+ * Returns true if client label is present, fail otherwise.
+ */
+bool checkClientOnWhitelist(int sockfd, std::string whitelistPath);
+
} // namespace AuthPasswd
#endif // _SMACK_CHECK_H_
*/
#include "smack-check.h"
-#include <stdlib.h>
+#include <fstream>
#include <sys/smack.h>
+#include <sys/socket.h>
+#include <sys/un.h>
#include <dpl/log/log.h>
+#include <error-description.h>
namespace AuthPasswd {
+const char COMMENT = '#';
+const std::string CLIENT_WHITELIST = "/etc/auth-fw/client-whitelist";
+const std::string ADMIN_CLIENT_WHITELIST = "/etc/auth-fw/admin-client-whitelist";
+
int smack_runtime_check(void)
{
static int smack_present = -1;
#endif
}
+bool checkClientOnWhitelist(int sockfd, std::string whitelistPath)
+{
+ struct ucred cr;
+ socklen_t len = sizeof(struct ucred);
+
+ // get client smack label from socket
+ if (getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &cr, &len)) {
+ int err = errno;
+ LogError("getsockopt() failed: " << errnoToString(err));
+ return false;
+ }
+
+ std::string clientSmackLabel;
+ std::string path("/proc/" + std::to_string(cr.pid) + "/attr/current");
+ std::ifstream file(path.c_str());
+ if (!file.is_open()) {
+ LogError("failed to open " << path);
+ return false;
+ }
+
+ std::getline(file, clientSmackLabel);
+ file.close();
+ if (clientSmackLabel.empty())
+ return false;
+
+ // compare with whitelist labels
+ std::string line;
+ std::ifstream whitelistFile(whitelistPath.c_str());
+ if (!whitelistFile.is_open()) {
+ LogError("failed to open " << whitelistPath);
+ return false;
+ }
+
+ while (std::getline(whitelistFile, line)) {
+ if (line.empty())
+ continue;
+ if (line.at(0) == COMMENT)
+ continue;
+ if (line.compare(clientSmackLabel) == 0) {
+ whitelistFile.close();
+ LogDebug("Client " << clientSmackLabel << " is on whitelist");
+ return true;
+ }
+ }
+ whitelistFile.close();
+ LogError("Client " << clientSmackLabel << " is not on whitelist");
+
+ return false;
+}
+
} // namespace AuthPasswd
#include <dpl/log/log.h>
#include <dpl/serialization.h>
+#include <smack-check.h>
#include <user-check.h>
#include <password.h>
try { //try..catch for internal service errors, assigns error code for returning.
switch (interfaceID) {
case SOCKET_ID_CHECK:
- if (socket_get_user(conn.sock, cur_user))
+ if (!checkClientOnWhitelist(conn.sock, CLIENT_WHITELIST))
+ retCode = AUTH_PASSWD_API_ERROR_ACCESS_DENIED;
+ else if (socket_get_user(conn.sock, cur_user))
retCode = AUTH_PASSWD_API_ERROR_NO_USER;
else
retCode = processCheckFunctions(hdr, buffer, cur_user, cur_att, max_att, exp_time);
-
break;
case SOCKET_ID_SET:
- if (socket_get_user(conn.sock, cur_user))
+ if (!checkClientOnWhitelist(conn.sock, CLIENT_WHITELIST))
+ retCode = AUTH_PASSWD_API_ERROR_ACCESS_DENIED;
+ else if (socket_get_user(conn.sock, cur_user))
retCode = AUTH_PASSWD_API_ERROR_NO_USER;
else
retCode = processSetFunctions(hdr, buffer, cur_user, isPwdReused);
-
break;
case SOCKET_ID_RESET:
- retCode = processResetFunctions(hdr, buffer);
+ if (!checkClientOnWhitelist(conn.sock, ADMIN_CLIENT_WHITELIST))
+ retCode = AUTH_PASSWD_API_ERROR_ACCESS_DENIED;
+ else
+ retCode = processResetFunctions(hdr, buffer);
break;
case SOCKET_ID_POLICY:
- retCode = processPolicyFunctions(hdr, buffer);
+ if (!checkClientOnWhitelist(conn.sock, ADMIN_CLIENT_WHITELIST))
+ retCode = AUTH_PASSWD_API_ERROR_ACCESS_DENIED;
+ else
+ retCode = processPolicyFunctions(hdr, buffer);
break;
default:
void PolicyFile::writeMemoryToFile() const
{
PasswordFileBuffer policyBuffer;
- LogSecureDebug("User: " << m_user << "Policy: " << m_policy.info());
+ LogSecureDebug("User: " << m_user << " Policy: " << m_policy.info());
// serialize policy attributes
Serialization::Serialize(policyBuffer, CURRENT_FILE_VERSION);
Serialization::Serialize(policyBuffer, m_enable);