diff options
author | jooseong lee <jooseong.lee@samsung.com> | 2016-08-10 14:56:50 +0900 |
---|---|---|
committer | jooseong lee <jooseong.lee@samsung.com> | 2016-08-24 18:13:33 +0900 |
commit | 0e3e87f1c1575ec776df45b31583bdbee86eb068 (patch) | |
tree | 579f685262df4bef47dfff6d67db7dd9657b09c1 /src/server | |
parent | de3c3d2d97c34fa27cb1778d2b81686317d026ef (diff) | |
download | auth-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>
Diffstat (limited to 'src/server')
-rw-r--r-- | src/server/main/include/smack-check.h | 11 | ||||
-rw-r--r-- | src/server/main/smack-check.cpp | 59 | ||||
-rw-r--r-- | src/server/service/password.cpp | 21 | ||||
-rw-r--r-- | src/server/service/policy-file.cpp | 2 |
4 files changed, 85 insertions, 8 deletions
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); |