Restrict authentication cookie information from audio service

Signed-off-by: Sulav Mulmi <sulav.mulmi@huawei.com>
This commit is contained in:
Sulav Mulmi 2022-02-23 09:17:19 +05:30
parent 4d19b7218f
commit f2eb802792
21 changed files with 181 additions and 27 deletions

View File

@ -13,6 +13,7 @@
import("//build/ohos.gni")
import("//drivers/adapter/uhdf2/uhdf.gni")
import("//foundation/appexecfwk/standard/appexecfwk.gni")
pulseaudio_dir = "//third_party/pulseaudio"
pulseaudio_build_path =
@ -27,6 +28,7 @@ group("audio_client_test_packages") {
config("audio_client_public_config") {
include_dirs = [
"//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_core/include/bundlemgr",
"//foundation/multimedia/audio_standard/frameworks/native/audiopolicy/include",
"//foundation/multimedia/audio_standard/frameworks/native/audiosession/include",
"//foundation/multimedia/audio_standard/frameworks/native/audiostream/include",
@ -71,6 +73,7 @@ ohos_shared_library("audio_client") {
public_configs = [ ":audio_client_public_config" ]
deps = [
"//foundation/aafwk/standard/interfaces/innerkits/want:want",
"//foundation/multimedia/audio_standard/frameworks/native/audiopolicy:audio_policy_client",
"//foundation/multimedia/audio_standard/frameworks/native/pulseaudio/src/pulse:pulse",
"//third_party/bounds_checking_function:libsec_static",
@ -78,6 +81,8 @@ ohos_shared_library("audio_client") {
]
external_deps = [
"bundle_framework:appexecfwk_base",
"bundle_framework:appexecfwk_core",
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
"samgr_standard:samgr_proxy",

View File

@ -174,6 +174,7 @@ public:
std::vector<sptr<AudioDeviceDescriptor>> GetDevices(DeviceFlag deviceFlag);
const std::string GetAudioParameter(const std::string key) const;
void SetAudioParameter(const std::string key, const std::string value) const;
const char *RetrieveCookie(int32_t &size) const;
int32_t SetDeviceActive(ActiveDeviceType deviceType, bool flag) const;
bool IsDeviceActive(ActiveDeviceType deviceType) const;
bool IsStreamActive(AudioSystemManager::AudioVolumeType volumeType) const;

View File

@ -4,13 +4,10 @@
"cmds" : [
"rm /data/data/.pulse_dir/runtime/pid",
"mkdir /data/data/.pulse_dir",
"chmod 777 /data/data/.pulse_dir",
"chown system shell /data/data/.pulse_dir",
"mkdir /data/data/.pulse_dir/runtime",
"chmod 777 /data/data/.pulse_dir/runtime",
"chown system shell /data/data/.pulse_dir/runtime",
"mkdir /data/data/.pulse_dir/state",
"chmod 777 /data/data/.pulse_dir/state",
"chown system shell /data/data/.pulse_dir/state",
"export PULSE_STATE_PATH /data/data/.pulse_dir/state",
"export PULSE_RUNTIME_PATH /data/data/.pulse_dir/runtime",

View File

@ -102,6 +102,13 @@ public:
*/
virtual int32_t ReleaseAudioRoute() = 0;
/**
* Retrieve cookie information from the service
*
* @return Returns cookie information, null if failed.
*/
virtual const char *RetrieveCookie(int32_t &size) = 0;
enum {
GET_MAX_VOLUME = 0,
GET_MIN_VOLUME = 1,
@ -111,8 +118,9 @@ public:
SET_MICROPHONE_MUTE = 5,
IS_MICROPHONE_MUTE = 6,
SET_AUDIO_SCENE = 7,
UPDATE_ROUTE_REQ,
RELEASE_ROUTE_REQ
UPDATE_ROUTE_REQ = 8,
RELEASE_ROUTE_REQ = 9,
RETRIEVE_COOKIE = 10,
};
public:

View File

@ -36,6 +36,7 @@ public:
void SetAudioParameter(const std::string key, const std::string value) override;
int32_t UpdateAudioRoute() override;
int32_t ReleaseAudioRoute() override;
const char *RetrieveCookie(int32_t &size) override;
private:
static inline BrokerDelegator<AudioManagerProxy> delegator_;
};

View File

@ -504,6 +504,8 @@ private:
bool isContextConnected;
bool isStreamConnected;
std::string appCookiePath = "";
float mVolumeFactor;
AudioStreamType mStreamType;
AudioSystemManager *mAudioSystemMgr;
@ -592,7 +594,6 @@ private:
// Resets PA audio client and free up resources if any with this API
void ResetPAAudioClient();
// For setting some environment variables required while running from hap
void SetEnv();
int32_t CorkStream();
// Callbacks to be implemented

View File

@ -44,6 +44,7 @@ public:
static void *paDaemonThread(void *arg);
void SetAudioParameter(const std::string key, const std::string value) override;
const std::string GetAudioParameter(const std::string key) override;
const char *RetrieveCookie(int32_t &size) override;
int32_t UpdateAudioRoute() override;
int32_t ReleaseAudioRoute() override;
private:

View File

@ -63,6 +63,7 @@ int AudioPolicyManagerListenerStub::OnRemoteRequest(
uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
{
if (data.ReadInterfaceToken() != GetDescriptor()) {
MEDIA_ERR_LOG("AudioPolicyManagerListenerStub: ReadInterfaceToken failed");
return -1;
}
switch (code) {

View File

@ -88,6 +88,7 @@ AudioRingerMode AudioPolicyProxy::GetRingerMode()
if (!data.WriteInterfaceToken(GetDescriptor())) {
MEDIA_ERR_LOG("AudioPolicyProxy: WriteInterfaceToken failed");
return RINGER_MODE_NORMAL;
}
int32_t error = Remote()->SendRequest(GET_RINGER_MODE, data, reply, option);
if (error != ERR_NONE) {
@ -124,6 +125,7 @@ AudioScene AudioPolicyProxy::GetAudioScene()
if (!data.WriteInterfaceToken(GetDescriptor())) {
MEDIA_ERR_LOG("AudioPolicyProxy: WriteInterfaceToken failed");
return AUDIO_SCENE_DEFAULT;
}
int32_t error = Remote()->SendRequest(GET_AUDIO_SCENE, data, reply, option);
if (error != ERR_NONE) {
@ -179,12 +181,13 @@ bool AudioPolicyProxy::GetStreamMute(AudioStreamType streamType)
if (!data.WriteInterfaceToken(GetDescriptor())) {
MEDIA_ERR_LOG("AudioPolicyProxy: WriteInterfaceToken failed");
return false;
}
data.WriteInt32(static_cast<int32_t>(streamType));
int32_t error = Remote()->SendRequest(GET_STREAM_MUTE, data, reply, option);
if (error != ERR_NONE) {
MEDIA_ERR_LOG("get mute failed, error: %d", error);
return error;
return false;
}
return reply.ReadBool();
}
@ -197,6 +200,7 @@ bool AudioPolicyProxy::IsStreamActive(AudioStreamType streamType)
if (!data.WriteInterfaceToken(GetDescriptor())) {
MEDIA_ERR_LOG("AudioPolicyProxy: WriteInterfaceToken failed");
return false;
}
data.WriteInt32(static_cast<int32_t>(streamType));
int32_t error = Remote()->SendRequest(IS_STREAM_ACTIVE, data, reply, option);
@ -212,13 +216,14 @@ std::vector<sptr<AudioDeviceDescriptor>> AudioPolicyProxy::GetDevices(DeviceFlag
MessageParcel data;
MessageParcel reply;
MessageOption option;
std::vector<sptr<AudioDeviceDescriptor>> deviceInfo;
if (!data.WriteInterfaceToken(GetDescriptor())) {
MEDIA_ERR_LOG("AudioPolicyProxy: WriteInterfaceToken failed");
return deviceInfo;
}
data.WriteInt32(static_cast<int32_t>(deviceFlag));
int32_t error = Remote()->SendRequest(GET_DEVICES, data, reply, option);
std::vector<sptr<AudioDeviceDescriptor>> deviceInfo;
if (error != ERR_NONE) {
MEDIA_ERR_LOG("Get devices failed, error: %d", error);
return deviceInfo;
@ -260,6 +265,7 @@ bool AudioPolicyProxy::IsDeviceActive(InternalDeviceType deviceType)
if (!data.WriteInterfaceToken(GetDescriptor())) {
MEDIA_ERR_LOG("AudioPolicyProxy: WriteInterfaceToken failed");
return false;
}
data.WriteInt32(static_cast<int32_t>(deviceType));
int32_t error = Remote()->SendRequest(IS_DEVICE_ACTIVE, data, reply, option);
@ -432,6 +438,7 @@ AudioStreamType AudioPolicyProxy::GetStreamInFocus()
if (!data.WriteInterfaceToken(GetDescriptor())) {
MEDIA_ERR_LOG("AudioPolicyProxy: WriteInterfaceToken failed");
return STREAM_DEFAULT;
}
int32_t error = Remote()->SendRequest(GET_STREAM_IN_FOCUS, data, reply, option);
if (error != ERR_NONE) {

View File

@ -35,6 +35,7 @@ int AudioRingerModeUpdateListenerStub::OnRemoteRequest(
uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
{
if (data.ReadInterfaceToken() != GetDescriptor()) {
MEDIA_ERR_LOG("AudioRingerModeUpdateListenerStub: ReadInterfaceToken failed");
return -1;
}
switch (code) {

View File

@ -31,6 +31,7 @@ int AudioVolumeKeyEventCallbackStub::OnRemoteRequest(
{
MEDIA_DEBUG_LOG("AudioVolumeKeyEventCallbackStub::OnRemoteRequest");
if (data.ReadInterfaceToken() != GetDescriptor()) {
MEDIA_ERR_LOG("AudioVolumeKeyEventCallbackStub: ReadInterfaceToken failed");
return -1;
}
switch (code) {

View File

@ -241,6 +241,7 @@ int AudioPolicyManagerStub::OnRemoteRequest(
uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
{
if (data.ReadInterfaceToken() != GetDescriptor()) {
MEDIA_ERR_LOG("AudioPolicyManagerStub: ReadInterfaceToken failed");
return -1;
}
switch (code) {

View File

@ -38,6 +38,7 @@ void AudioRingerModeUpdateListenerProxy::OnRingerModeUpdated(const AudioRingerMo
if (!data.WriteInterfaceToken(GetDescriptor())) {
MEDIA_ERR_LOG("AudioRingerModeListenerCallback: WriteInterfaceToken failed");
return;
}
data.WriteInt32(static_cast<int32_t>(ringerMode));
int error = Remote()->SendRequest(ON_RINGERMODE_UPDATE, data, reply, option);

View File

@ -30,6 +30,7 @@ void AudioVolumeKeyEventCallbackProxy::OnVolumeKeyEvent(AudioStreamType streamTy
if (!data.WriteInterfaceToken(GetDescriptor())) {
MEDIA_ERR_LOG("AudioVolumeKeyEventCallbackProxy: WriteInterfaceToken failed");
return;
}
data.WriteInt32(static_cast<int32_t>(streamType));
data.WriteInt32(volumeLevel);

View File

@ -36,6 +36,7 @@ public:
void SetAudioParameter(const std::string key, const std::string value) override;
int32_t UpdateAudioRoute() override;
int32_t ReleaseAudioRoute() override;
const char *RetrieveCookie(int32_t &size) override;
private:
static inline BrokerDelegator<AudioPolicyServiceProxy> delegator_;
};

View File

@ -124,19 +124,25 @@ int32_t AudioPolicyServiceProxy::ReleaseAudioRoute()
return result;
}
const char *AudioPolicyServiceProxy::RetrieveCookie(int32_t &size)
{
return nullptr;
}
std::vector<sptr<AudioDeviceDescriptor>> AudioPolicyServiceProxy::GetDevices(DeviceFlag deviceFlag)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
std::vector<sptr<AudioDeviceDescriptor>> deviceInfo;
if (!data.WriteInterfaceToken(GetDescriptor())) {
MEDIA_ERR_LOG("AudioPolicyServiceProxy: WriteInterfaceToken failed");
return deviceInfo;
}
data.WriteInt32(static_cast<int32_t>(deviceFlag));
int32_t error = Remote()->SendRequest(GET_DEVICES, data, reply, option);
std::vector<sptr<AudioDeviceDescriptor>> deviceInfo;
if (error != ERR_NONE) {
MEDIA_ERR_LOG("Get devices failed, error: %d", error);
return deviceInfo;

View File

@ -97,6 +97,7 @@ bool AudioManagerProxy::IsMicrophoneMute()
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
MEDIA_ERR_LOG("AudioManagerProxy: WriteInterfaceToken failed");
return false;
}
int32_t error = Remote()->SendRequest(IS_MICROPHONE_MUTE, data, reply, option);
if (error != ERR_NONE) {
@ -150,6 +151,7 @@ const std::string AudioManagerProxy::GetAudioParameter(const std::string key)
if (!data.WriteInterfaceToken(GetDescriptor())) {
MEDIA_ERR_LOG("AudioManagerProxy: WriteInterfaceToken failed");
return "";
}
data.WriteString(static_cast<std::string>(key));
int32_t error = Remote()->SendRequest(GET_AUDIO_PARAMETER, data, reply, option);
@ -171,6 +173,7 @@ void AudioManagerProxy::SetAudioParameter(const std::string key, const std::stri
if (!data.WriteInterfaceToken(GetDescriptor())) {
MEDIA_ERR_LOG("AudioManagerProxy: WriteInterfaceToken failed");
return;
}
data.WriteString(static_cast<std::string>(key));
data.WriteString(static_cast<std::string>(value));
@ -181,6 +184,32 @@ void AudioManagerProxy::SetAudioParameter(const std::string key, const std::stri
}
}
const char *AudioManagerProxy::RetrieveCookie(int32_t &size)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
const char *cookieInfo = nullptr;
if (!data.WriteInterfaceToken(GetDescriptor())) {
MEDIA_ERR_LOG("AudioManagerProxy: WriteInterfaceToken failed");
return nullptr;
}
int32_t error = Remote()->SendRequest(RETRIEVE_COOKIE, data, reply, option);
if (error != ERR_NONE) {
MEDIA_ERR_LOG("retrieve cookie failed, error: %d", error);
return nullptr;
}
size = reply.ReadInt32();
if (size > 0) {
cookieInfo = reinterpret_cast<const char *>(reply.ReadRawData(size));
}
return cookieInfo;
}
int32_t AudioManagerProxy::UpdateAudioRoute()
{
return ERR_NONE;

View File

@ -14,12 +14,19 @@
*/
#include "audio_service_client.h"
#include <fstream>
#include "bundle_mgr_interface.h"
#include "iservice_registry.h"
#include "media_log.h"
#include "securec.h"
#include "system_ability_definition.h"
#include "unistd.h"
using namespace std;
using namespace OHOS::AppExecFwk;
using namespace OHOS::AAFwk;
namespace OHOS {
namespace AudioStandard {
@ -33,6 +40,9 @@ const uint32_t MAX_LENGTH_FACTOR = 5;
const uint32_t T_LENGTH_FACTOR = 4;
const uint64_t MIN_BUF_DURATION_IN_USEC = 92880;
const string APP_DATA_BASE_PATH = "/data/accounts/account_0/appdata/";
const string APP_COOKIE_FILE_PATH = "/cache/cookie";
#define CHECK_AND_RETURN_IFINVALID(expr) \
do { \
if (!(expr)) { \
@ -437,6 +447,11 @@ void AudioServiceClient::ResetPAAudioClient()
}
}
if (appCookiePath.compare("")) {
remove(appCookiePath.c_str());
appCookiePath = "";
}
isMainLoopStarted = false;
isContextConnected = false;
isStreamConnected = false;
@ -474,26 +489,35 @@ AudioServiceClient::~AudioServiceClient()
ResetPAAudioClient();
}
void AudioServiceClient::SetEnv()
static std::string GetClientBundle(int uid)
{
int ret = 0;
const char *env_home_pa = getenv("HOME");
if (!env_home_pa) {
ret = setenv("HOME", PA_HOME_DIR, 1);
MEDIA_INFO_LOG("set env HOME: %{public}d", ret);
std::string bundleName = "";
auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (samgr == nullptr) {
MEDIA_ERR_LOG("Get ability manager failed");
return bundleName;
}
const char *env_runtime_pa = getenv("PULSE_RUNTIME_PATH");
if (!env_runtime_pa) {
ret = setenv("PULSE_RUNTIME_PATH", PA_RUNTIME_DIR, 1);
MEDIA_INFO_LOG("set env PULSE_RUNTIME_DIR: %{public}d", ret);
sptr<IRemoteObject> object = samgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
if (object == nullptr) {
MEDIA_DEBUG_LOG("object is NULL.");
return bundleName;
}
const char *env_state_pa = getenv("PULSE_STATE_PATH");
if (!env_state_pa) {
ret = setenv("PULSE_STATE_PATH", PA_STATE_DIR, 1);
MEDIA_INFO_LOG("set env PULSE_STATE_PATH: %{public}d", ret);
sptr<AppExecFwk::IBundleMgr> bms = iface_cast<AppExecFwk::IBundleMgr>(object);
if (bms == nullptr) {
MEDIA_DEBUG_LOG("bundle manager service is NULL.");
return bundleName;
}
auto result = bms->GetBundleNameForUid(uid, bundleName);
if (!result) {
MEDIA_ERR_LOG("GetBundleNameForUid fail");
return "";
}
MEDIA_INFO_LOG("bundle name is %{public}s ", bundleName.c_str());
return bundleName;
}
int32_t AudioServiceClient::Initialize(ASClientType eClientType)
@ -507,7 +531,7 @@ int32_t AudioServiceClient::Initialize(ASClientType eClientType)
mTotalBytesRead = 0;
mFramePeriodRead = 0;
SetEnv();
mAudioSystemMgr = AudioSystemManager::GetInstance();
mainLoop = pa_threaded_mainloop_new();
if (mainLoop == NULL)
@ -527,6 +551,27 @@ int32_t AudioServiceClient::Initialize(ASClientType eClientType)
pa_context_set_state_callback(context, PAContextStateCb, mainLoop);
string bundleName = GetClientBundle(getuid());
if (bundleName.compare("")) {
int32_t size = 0;
const char *cookieData = mAudioSystemMgr->RetrieveCookie(size);
if (size <= 0) {
MEDIA_ERR_LOG("Error retrieving cookie");
return AUDIO_CLIENT_INIT_ERR;
}
appCookiePath = APP_DATA_BASE_PATH;
appCookiePath.append(bundleName);
appCookiePath.append(APP_COOKIE_FILE_PATH);
MEDIA_DEBUG_LOG("cookie file path: %{public}s", appCookiePath.c_str());
ofstream cookieCache(appCookiePath.c_str(), std::ofstream::binary);
cookieCache.write(cookieData, size);
cookieCache.close();
pa_context_load_cookie_from_file(context, appCookiePath.c_str());
}
if (pa_context_connect(context, NULL, PA_CONTEXT_NOFAIL, NULL) < 0) {
error = pa_context_errno(context);
MEDIA_ERR_LOG("context connect error: %{public}s", pa_strerror(error));
@ -534,8 +579,6 @@ int32_t AudioServiceClient::Initialize(ASClientType eClientType)
return AUDIO_CLIENT_INIT_ERR;
}
mAudioSystemMgr = AudioSystemManager::GetInstance();
isContextConnected = true;
pa_threaded_mainloop_lock(mainLoop);
@ -562,6 +605,11 @@ int32_t AudioServiceClient::Initialize(ASClientType eClientType)
pa_threaded_mainloop_wait(mainLoop);
}
if (appCookiePath.compare("")) {
remove(appCookiePath.c_str());
appCookiePath = "";
}
pa_threaded_mainloop_unlock(mainLoop);
return AUDIO_CLIENT_SUCCESS;
}

View File

@ -155,6 +155,11 @@ void AudioSystemManager::SetAudioParameter(const std::string key, const std::str
g_sProxy->SetAudioParameter(key, value);
}
const char *AudioSystemManager::RetrieveCookie(int32_t &size) const
{
return g_sProxy->RetrieveCookie(size);
}
int32_t AudioSystemManager::SetVolume(AudioSystemManager::AudioVolumeType volumeType, int32_t volume) const
{
/* Validate and return INVALID_PARAMS error */

View File

@ -26,6 +26,7 @@ int AudioManagerStub::OnRemoteRequest(
{
MEDIA_DEBUG_LOG("OnRemoteRequest, cmd = %{public}u", code);
if (data.ReadInterfaceToken() != GetDescriptor()) {
MEDIA_ERR_LOG("AudioManagerStub: ReadInterfaceToken failed");
return -1;
}
if (!IsPermissionValid()) {
@ -73,6 +74,18 @@ int AudioManagerStub::OnRemoteRequest(
reply.WriteString(value);
return MEDIA_OK;
}
case RETRIEVE_COOKIE: {
MEDIA_DEBUG_LOG("RETRIEVE_COOKIE AudioManagerStub");
int32_t size = 0;
const char *cookieInfo = RetrieveCookie(size);
reply.WriteInt32(size);
if (size > 0) {
MEDIA_DEBUG_LOG("cookie received from server");
reply.WriteRawData(static_cast<const void *>(cookieInfo), size);
}
return MEDIA_OK;
}
case SET_MICROPHONE_MUTE: {
MEDIA_DEBUG_LOG("SET_MICROPHONE_MUTE AudioManagerStub");
bool isMute = data.ReadBool();

View File

@ -21,6 +21,9 @@
#include "system_ability_definition.h"
#include "audio_server.h"
#include <fstream>
#include <sstream>
#define PA
#ifdef PA
extern "C" {
@ -33,6 +36,7 @@ using namespace std;
namespace OHOS {
namespace AudioStandard {
std::map<std::string, std::string> AudioServer::audioParameters;
const string DEFAULT_COOKIE_PATH = "/data/data/.pulse_dir/state/cookie";
REGISTER_SYSTEM_ABILITY_BY_ID(AudioServer, AUDIO_DISTRIBUTED_SERVICE_ID, true)
@ -100,6 +104,27 @@ const std::string AudioServer::GetAudioParameter(const std::string key)
}
}
const char *AudioServer::RetrieveCookie(int32_t &size)
{
char *cookieInfo = nullptr;
size = 0;
std::ifstream cookieFile(DEFAULT_COOKIE_PATH, std::ifstream::binary);
if (cookieFile) {
cookieFile.seekg (0, cookieFile.end);
size = cookieFile.tellg();
cookieFile.seekg (0, cookieFile.beg);
if ((size > 0) && (size < PATH_MAX)) {
cookieInfo = (char *)malloc(size * sizeof(char));
MEDIA_DEBUG_LOG("Reading: %{public}d characters...", size);
cookieFile.read(cookieInfo, size);
}
cookieFile.close();
}
return cookieInfo;
}
int32_t AudioServer::GetMaxVolume(AudioSystemManager::AudioVolumeType volumeType)
{
MEDIA_DEBUG_LOG("GetMaxVolume server");