summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjooseong lee <jooseong.lee@samsung.com>2016-08-10 14:56:50 +0900
committerjooseong lee <jooseong.lee@samsung.com>2016-08-24 18:13:33 +0900
commit0e3e87f1c1575ec776df45b31583bdbee86eb068 (patch)
tree579f685262df4bef47dfff6d67db7dd9657b09c1
parentde3c3d2d97c34fa27cb1778d2b81686317d026ef (diff)
downloadauth-fw-0e3e87f1c1575ec776df45b31583bdbee86eb068.tar.gz
auth-fw-0e3e87f1c1575ec776df45b31583bdbee86eb068.tar.bz2
auth-fw-0e3e87f1c1575ec776df45b31583bdbee86eb068.zip
Check whether client process label is allowed or not on whitelist
Only allowed client should call password APIs. Auth-fw can manage it based on whitelist. There are two whitelist files for general client and admin client. - client-whitelist : subject labels allowed to use password checking/setting ex. lockscreen, setting application - admin-client-whitelist : subject labels allowed to use password reset and password policy setting ex. device policy manager Change-Id: If4eebde05f690c8fd8a9e8c5adce08f0c7af5e47 Signed-off-by: jooseong lee <jooseong.lee@samsung.com>
-rw-r--r--CMakeLists.txt1
-rw-r--r--conf/CMakeLists.txt24
-rw-r--r--conf/admin-client-whitelist4
-rw-r--r--conf/client-whitelist5
-rw-r--r--conf/client-whitelist_mobile9
-rw-r--r--packaging/auth-fw.spec6
-rw-r--r--src/server/main/include/smack-check.h11
-rw-r--r--src/server/main/smack-check.cpp59
-rw-r--r--src/server/service/password.cpp21
-rw-r--r--src/server/service/policy-file.cpp2
10 files changed, 133 insertions, 9 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e0d0f4d..e3afdcc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -68,3 +68,4 @@ ENDIF (CMAKE_BUILD_TYPE MATCHES "DEBUG")
ADD_SUBDIRECTORY(src)
ADD_SUBDIRECTORY(pkgconfig)
ADD_SUBDIRECTORY(systemd)
+ADD_SUBDIRECTORY(conf)
diff --git a/conf/CMakeLists.txt b/conf/CMakeLists.txt
new file mode 100644
index 0000000..c0aaf8b
--- /dev/null
+++ b/conf/CMakeLists.txt
@@ -0,0 +1,24 @@
+# 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})
diff --git a/conf/admin-client-whitelist b/conf/admin-client-whitelist
new file mode 100644
index 0000000..5e88c28
--- /dev/null
+++ b/conf/admin-client-whitelist
@@ -0,0 +1,4 @@
+# subject labels allowed to use password reset and password policy setting
+# put each allowed label in new line
+System
+System::Privileged
diff --git a/conf/client-whitelist b/conf/client-whitelist
new file mode 100644
index 0000000..8e5a96c
--- /dev/null
+++ b/conf/client-whitelist
@@ -0,0 +1,5 @@
+# subject labels allowed to use password checking/setting
+# put each allowed label in new line
+System
+System::Privileged
+User
diff --git a/conf/client-whitelist_mobile b/conf/client-whitelist_mobile
new file mode 100644
index 0000000..362ee23
--- /dev/null
+++ b/conf/client-whitelist_mobile
@@ -0,0 +1,9 @@
+# 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
diff --git a/packaging/auth-fw.spec b/packaging/auth-fw.spec
index 99187ac..cefd5c9 100644
--- a/packaging/auth-fw.spec
+++ b/packaging/auth-fw.spec
@@ -84,6 +84,7 @@ export LDFLAGS+="-Wl,--rpath=%{_libdir}"
-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} \
@@ -91,7 +92,8 @@ export LDFLAGS+="-Wl,--rpath=%{_libdir}"
-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}
@@ -156,6 +158,8 @@ fi
%{_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
diff --git a/src/server/main/include/smack-check.h b/src/server/main/include/smack-check.h
index b2c9812..024c670 100644
--- a/src/server/main/include/smack-check.h
+++ b/src/server/main/include/smack-check.h
@@ -21,8 +21,13 @@
#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
@@ -30,6 +35,12 @@ namespace AuthPasswd {
*/
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_
diff --git a/src/server/main/smack-check.cpp b/src/server/main/smack-check.cpp
index 5c3b3b9..66b26f5 100644
--- a/src/server/main/smack-check.cpp
+++ b/src/server/main/smack-check.cpp
@@ -21,13 +21,20 @@
*/
#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;
@@ -54,4 +61,54 @@ int smack_check(void)
#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
diff --git a/src/server/service/password.cpp b/src/server/service/password.cpp
index f165c7f..005b6bc 100644
--- a/src/server/service/password.cpp
+++ b/src/server/service/password.cpp
@@ -30,6 +30,7 @@
#include <dpl/log/log.h>
#include <dpl/serialization.h>
+#include <smack-check.h>
#include <user-check.h>
#include <password.h>
@@ -313,27 +314,35 @@ bool PasswordService::processOne(const ConnectionID &conn, MessageBuffer &buffer
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:
diff --git a/src/server/service/policy-file.cpp b/src/server/service/policy-file.cpp
index 5e7f15a..cc3bf8a 100644
--- a/src/server/service/policy-file.cpp
+++ b/src/server/service/policy-file.cpp
@@ -122,7 +122,7 @@ std::string PolicyFile::createDir(const std::string &dir, unsigned int user) con
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);