From 623cecbcfa1c5ddaef992a3a814e858bcbf90f17 Mon Sep 17 00:00:00 2001 From: zzhcharmer Date: Sat, 21 Jun 2025 12:10:29 +0800 Subject: [PATCH] sudo Signed-off-by: zzhcharmer --- bundle.json | 3 +- hdc.gni | 1 + sudo/BUILD.gn | 5 +- sudo/src/main.cpp | 196 ++++++++++++++++++++++++++---------------- sudo/src/sudo_iam.cpp | 32 ++++--- sudo/src/sudo_iam.h | 30 ++++--- 6 files changed, 168 insertions(+), 99 deletions(-) diff --git a/bundle.json b/bundle.json index e596389f..d78aafd3 100644 --- a/bundle.json +++ b/bundle.json @@ -43,7 +43,8 @@ "pin_auth", "rust_rust-openssl", "huks", - "rust_libc" + "rust_libc", + "access_control_level_manager" ], "third_party": [] }, diff --git a/hdc.gni b/hdc.gni index ecf8e930..b5a84f0d 100644 --- a/hdc.gni +++ b/hdc.gni @@ -24,6 +24,7 @@ declare_args() { hdc_version_check = false support_hdcd_user_permit = false hdc_feature_support_sudo = false + hdc_support_account_constraint = false if (defined(global_parts_info)) { if (defined(global_parts_info.ability_ability_base)) { diff --git a/sudo/BUILD.gn b/sudo/BUILD.gn index 5ecac3a9..5c94c111 100644 --- a/sudo/BUILD.gn +++ b/sudo/BUILD.gn @@ -36,6 +36,7 @@ ohos_executable("exec_sudo") { "os_account:os_account_innerkits", "pin_auth:pinauth_framework", "user_auth_framework:userauth_client", + "access_control_level_manager:aclmgr_sdk", ] defines = [ "HAS_PIN_AUTH_PART" ] @@ -44,7 +45,9 @@ ohos_executable("exec_sudo") { external_deps += [ "selinux:libselinux" ] defines += [ "SURPPORT_SELINUX" ] } - + if (hdc_support_account_constraint) { + defines += [ "SURPPORT_ACCOUNT_CONSTRAINT" ] + } subsystem_name = "developtools" output_name = "sudo" part_name = "hdc" diff --git a/sudo/src/main.cpp b/sudo/src/main.cpp index 91943f84..3de132e3 100644 --- a/sudo/src/main.cpp +++ b/sudo/src/main.cpp @@ -25,22 +25,36 @@ #if defined(SURPPORT_SELINUX) #include "selinux/selinux.h" #endif -#include "account_iam_client.h" #include "os_account_manager.h" #include "sudo_iam.h" +#include "user_auth_client.h" +#include "pinauth_register.h" +#include "user_access_ctrl_client.h" +#include "aclmgr_system_api.h" #define PWD_BUF_LEN 128 +#define CHALLENGE_LEN 32 #define DEFAULT_PATH "/system/bin" #define DEFAULT_BASH "/system/bin/sh" using namespace OHOS::UserIam; using namespace OHOS::AccountSA; +using namespace OHOS::UserIam::PinAuth; +using namespace OHOS::UserIam::UserAuth; static FILE *g_ttyFp = nullptr; static const char *OUT_OF_MEM = "[E0001] out of memory\n"; static const char *COMMAND_NOT_FOUND = "[E0002] command not found\n"; static const char *USER_VERIFY_FAILED = "[E0003] Sorry, try again. If screen lock password not set, set it first.\n"; +static const char *HELP = "sudo - execute command as root\n\n" + "usage: sudo command ...\n" + "usage: sudo sh -c command ...\n"; + +static int32_t g_userId = -1; +static std::vector g_challenge(CHALLENGE_LEN, 0); +static std::vector g_authToken; +static const std::string CONSTRAINT_SUDO = "constraint.sudo"; static void WriteStdErr(const char *str) { @@ -247,74 +261,73 @@ static void WaitForAuth(void) g_condVarForAuth.wait(lock, [] { return g_authFinish; }); } -static bool VerifyAccount(int32_t userId) +static bool GetChallenge() +{ + int32_t res = InitChallengeForCommand(g_challenge.data(), g_challenge.size()); + if (res != 0) { + WriteStdErr("init challenge failed\n"); + return false; + } + return true; +} + +static bool VerifyAccount() { - std::vector challenge; - AuthOptions authOptions; bool verifyResult = false; - AccountIAMClient &sudoIAMClient = AccountIAMClient::GetInstance(); - std::shared_ptr callback = std::make_shared(); - authOptions.accountId = userId; - sudoIAMClient.AuthUser(authOptions, challenge, AuthType::PIN, AuthTrustLevel::ATL1, callback); + AccountIAMClient &sudoIAMClient = UserAuthClient::GetInstance(); + std::shared_ptr callback = std::make_shared(); + + OHOS::UserIam::UserAuth::AuthParam authParam; + authParam.userId = g_userId; + authParam.challenge = g_challenge; + authParam.authType = AuthType::PIN; + authParam.AuthTrustLevel = AuthTrustLevel::ATL1; + + sudoIAMClient.BeginAuthentication(authParam, callback); std::shared_ptr sudoCallback = std::static_pointer_cast(callback); WaitForAuth(); verifyResult = sudoCallback->GetVerifyResult(); + g_authToken = sudoCallback->GetAuthToken(); return verifyResult; } -static bool UserAccountVerify(char *pwd, int pwdLen) +static bool GetUserId() { - std::shared_ptr inputer = nullptr; - OHOS::ErrCode err; - int verifyResult = 0; - pid_t pid; - int fds[2]; + std::vector ids; - if (pipe(fds) != 0) { - WriteStdErr("exec pipe failed\n"); + OHOS::ErrCode err = OsAccountManager::QueryActiveOsAccountIds(ids); + if (err != 0) { + WriteStdErr("get os account local id failed\n"); return false; } - pid = fork(); - if (pid == -1) { - WriteStdErr("exec fork failed\n"); - close(fds[0]); - close(fds[1]); + + g_userId = ids[0]; + return true; +} + +static bool UserAccountVerify(char *pwd, int pwdLen) +{ + bool verifyResult = false; + std::shared_ptr inputer = nullptr; + + inputer = std::make_shared(); + std::shared_ptr sudoInputer = std::static_pointer_cast(inputer); + sudoInputer->SetPasswd(pwd, pwdLen); + if (!PinAuthRegister::GetInstance().RegisterInputer(inputer)) { + WriteStdErr("register pin inputer failed\n"); return false; } - if (pid == 0) { - int32_t userId = -1; - close(fds[0]); - err = OsAccountManager::GetForegroundOsAccountLocalId(userId); - if (err != 0) { - WriteStdErr("get os account local id failed\n"); - exit(1); - } - inputer = std::make_shared(); - std::shared_ptr sudoInputer = std::static_pointer_cast(inputer); - sudoInputer->SetPasswd(pwd, pwdLen); - err = AccountIAMClient::GetInstance().RegisterPINInputer(inputer); - if (err != 0) { - WriteStdErr("register pin inputer failed\n"); - exit(1); - } - if (VerifyAccount(userId)) { - verifyResult = 1; - } - AccountIAMClient::GetInstance().UnregisterPINInputer(); - write(fds[1], &verifyResult, sizeof(verifyResult)); - close(fds[1]); - exit(0); - } else { - close(fds[1]); - waitpid(pid, nullptr, 0); - read(fds[0], &verifyResult, sizeof(verifyResult)); - close(fds[0]); - return (verifyResult == 1); + + if (VerifyAccount()) { + verifyResult = true; } + + PinAuthRegister::GetInstance().UnRegisterInputer(); + return verifyResult; } -static bool VerifyUserPin(void) +static bool VerifyUserPin() { char passwd[PWD_BUF_LEN] = {0}; bool pwdVerifyResult = false; @@ -332,49 +345,86 @@ static bool VerifyUserPin(void) return pwdVerifyResult; } +static bool SetPSL() +{ + int32_t res = SetProcessLevelByCommand(g_authToken.data(), g_authToken.size()); + if (res != 0) { + WriteStdErr("set psl failed\n"); + return false; + } + return true; +} + +#if defined(SURPPORT_ACCOUNT_CONSTRAINT) +static bool CheckUserLimitation() +{ + bool isNotEnabled = false; + OHOS::ErrCode err = OsAccountManager::CheckOsAccountConstraintEnabled( + g_userId, CONSTRAINT_SUDO, isNotEnabled); + if (err != 0) { + WriteStdErr("check account constrain failed.\n"); + return false; + } + + if (isNotEnabled) { + WriteStdErr("no permision.\n"); + return false; + } + + return true; +} +#endif + int main(int argc, char* argv[], char* env[]) { - char execCmd[PATH_MAX + 1] = {0}; - char **argvNew = nullptr; - const char *help = "sudo - execute command as root\n\n" - "usage: sudo command ...\n" - "usage: sudo sh -c command ...\n"; - if (argc < 2) { //2:argc check number - WriteStdErr(help); + if (!GetUserId()) { + return 1; + } + +#if defined(SURPPORT_ACCOUNT_CONSTRAINT) + if (!CheckUserLimitation()) { + return 1; + } +#endif + + if (argc < 2) { // 2:argc check number + WriteStdErr(HELP); + return 1; + } + + if (!GetChallenge()) { return 1; } - /* - * Get and verify user pwd - */ if (!VerifyUserPin()) { return 1; } - /* - * Make exec cmd and the args - */ - argvNew = ParseCmd(argc, argv, env, execCmd, PATH_MAX + 1); + if (!SetPSL()) { + return 1; + } + + char execCmd[PATH_MAX + 1] = {0}; + char **argvNew = ParseCmd(argc, argv, env, execCmd, PATH_MAX + 1); CloseTty(); if (argvNew == nullptr) { return 1; } - /* - * set uid, gid, egid - */ if (!SetUidGid()) { FreeArgvNew(argvNew); - WriteStdErr("setuid failed\n"); + WriteStdErr("setuid failed.\n"); return 1; } #if defined(SURPPORT_SELINUX) - setcon("u:r:privilege_app:s0"); + if (setcon("u:r:sudo_execv_label:s0") != 0) { + WriteStdErr("set SEHarmony failed.\n"); + return 1; + } #endif execvp(execCmd, argvNew); - - WriteStdErr("execvp failed\n"); + WriteStdErr("execvp failed.\n"); return 1; -} +} \ No newline at end of file diff --git a/sudo/src/sudo_iam.cpp b/sudo/src/sudo_iam.cpp index 9ed2290b..d7d4f2e5 100644 --- a/sudo/src/sudo_iam.cpp +++ b/sudo/src/sudo_iam.cpp @@ -14,10 +14,11 @@ */ #include "sudo_iam.h" -#include "account_iam_client.h" -#include "account_iam_info.h" -#include "account_iam_client_callback.h" #include "i_inputer.h" +#include "user_auth_client_callback.h" + +using namespace OHOS::UserIam::PinAuth; +using namespace OHOS::UserIam::UserAuth; std::condition_variable g_condVarForAuth; bool g_authFinish; @@ -47,12 +48,9 @@ SudoIInputer::~SudoIInputer() passwd_[i] = 0; } } +} // PinAuth -} //PinAuth -} //UserIam - -namespace AccountSA { - +namespace UserAuth { SudoIDMCallback::SudoIDMCallback() { verifyResult_ = false; @@ -70,6 +68,10 @@ void SudoIDMCallback::OnResult(int32_t result, const Attributes &extraInfo) verifyResult_ = true; } + if (!extraInfo.GetUint8ArrayValue(Attributes::ATTR_SIGNATURE, authToken_)) { + verifyResult_ = false; + } + std::unique_lock lock { g_mutexForAuth }; g_authFinish = true; g_condVarForAuth.notify_all(); @@ -80,5 +82,15 @@ bool SudoIDMCallback::GetVerifyResult(void) return verifyResult_; } -} // AccountSA -} //OHOS +std::vector SudoIDMCallback::GetAuthToken() +{ + return authToken_; +} + +SudoIDMCallback::~SudoIDMCallback() +{ + authToken_.assign(authToken_.size(), 0); +} +} // UserAuth +} // UserIam +} // OHOS diff --git a/sudo/src/sudo_iam.h b/sudo/src/sudo_iam.h index 0a5313a7..3abf91d3 100644 --- a/sudo/src/sudo_iam.h +++ b/sudo/src/sudo_iam.h @@ -17,10 +17,8 @@ #define SUDO_IAM_H #include #include -#include "account_iam_client.h" -#include "account_iam_info.h" -#include "account_iam_client_callback.h" #include "i_inputer.h" +#include "user_auth_client_callback.h" extern std::condition_variable g_condVarForAuth; extern bool g_authFinish; @@ -40,21 +38,25 @@ private: std::vector passwd_; }; -} //PinAuth -} //UserIam +} // PinAuth -namespace AccountSA { - -class SudoIDMCallback : public IDMCallback { +namespace UserAuth { +class SudoIDMCallback : public AuthenticationCallback { public: - virtual ~SudoIDMCallback() = default; + virtual ~SudoIDMCallback(); SudoIDMCallback(); - void OnAcquireInfo(int32_t module, uint32_t acquireInfo, const Attributes &extraInfo) override; - void OnResult(int32_t result, const Attributes &extraInfo) override; + void OnAcquireInfo(int32_t module, uint32_t acquireInfo, + const OHOS::UserIam::UserAuth::Attributes &extraInfo) override; + void OnResult(int32_t result, + const OHOS::UserIam::UserAuth::Attributes &extraInfo) override bool GetVerifyResult(void); + std::vector GetAuthToken(); private: bool verifyResult_; + std::vector autnToken_; }; -} // AccountSA -} //OHOS -#endif //SUDO_IAM_H + +} // UserAuth +} // UserIam +} // OHOS +#endif // SUDO_IAM_H -- Gitee