1 /*
2 * Copyright (C) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "cred_listener.h"
17 #include "common_defs.h"
18 #include "device_auth_defines.h"
19 #include "hc_log.h"
20 #include "hc_mutex.h"
21 #include "hc_types.h"
22 #include "hc_vector.h"
23 #include "securec.h"
24 #include "string_util.h"
25
26 typedef struct {
27 char *appId;
28 CredChangeListener *listener;
29 } CredListenerEntry;
30
31 DECLARE_HC_VECTOR(CredListenerEntryVec, CredListenerEntry);
32 IMPLEMENT_HC_VECTOR(CredListenerEntryVec, CredListenerEntry, 1);
33 static CredListenerEntryVec g_credListenerVec;
34 static HcMutex *g_credListenerMutex = NULL;
35
OnCredAdd(const char * credId,const char * credInfo)36 void OnCredAdd(const char *credId, const char *credInfo)
37 {
38 if (credId == NULL) {
39 LOGE("[CredListener-CredAdd]: The credId is NULL!");
40 return;
41 }
42 if (credInfo == NULL) {
43 credInfo = "";
44 }
45 uint32_t index;
46 CredListenerEntry *entry = NULL;
47 (void)LockHcMutex(g_credListenerMutex);
48 FOR_EACH_HC_VECTOR(g_credListenerVec, index, entry) {
49 if (entry != NULL && entry->listener != NULL && entry->listener->onCredAdd != NULL) {
50 LOGI("[CredListener]: OnCredAdd! [AppId]: %" LOG_PUB "s", entry->appId);
51 entry->listener->onCredAdd(credId, credInfo);
52 }
53 }
54 UnlockHcMutex(g_credListenerMutex);
55 }
56
OnCredDelete(const char * credId,const char * credInfo)57 void OnCredDelete(const char *credId, const char *credInfo)
58 {
59 if (credId == NULL) {
60 LOGE("[CredListener-CredDelete]: The credId is NULL!");
61 return;
62 }
63 if (credInfo == NULL) {
64 credInfo = "";
65 }
66 uint32_t index;
67 CredListenerEntry *entry = NULL;
68 (void)LockHcMutex(g_credListenerMutex);
69 FOR_EACH_HC_VECTOR(g_credListenerVec, index, entry) {
70 if (entry != NULL && entry->listener != NULL && entry->listener->onCredDelete != NULL) {
71 LOGI("[CredListener]: OnCredDelete! [AppId]: %" LOG_PUB "s", entry->appId);
72 entry->listener->onCredDelete(credId, credInfo);
73 }
74 }
75 UnlockHcMutex(g_credListenerMutex);
76 }
77
OnCredUpdate(const char * credId,const char * credInfo)78 void OnCredUpdate(const char *credId, const char *credInfo)
79 {
80 if (credId == NULL) {
81 LOGE("[CredListener-CredUpdate]: The credId is NULL!");
82 return;
83 }
84 if (credInfo == NULL) {
85 credInfo = "";
86 }
87 uint32_t index;
88 CredListenerEntry *entry = NULL;
89 (void)LockHcMutex(g_credListenerMutex);
90 FOR_EACH_HC_VECTOR(g_credListenerVec, index, entry) {
91 if (entry != NULL && entry->listener != NULL && entry->listener->onCredUpdate != NULL) {
92 LOGI("[CredListener]: OnCredUpdate! [AppId]: %" LOG_PUB "s", entry->appId);
93 entry->listener->onCredUpdate(credId, credInfo);
94 }
95 }
96 UnlockHcMutex(g_credListenerMutex);
97 }
UpdateListenerIfExist(const char * appId,const CredChangeListener * listener)98 static int32_t UpdateListenerIfExist(const char *appId, const CredChangeListener *listener)
99 {
100 uint32_t index;
101 (void)LockHcMutex(g_credListenerMutex);
102 CredListenerEntry *entry = NULL;
103 FOR_EACH_HC_VECTOR(g_credListenerVec, index, entry) {
104 if (IsStrEqual(entry->appId, appId)) {
105 if (memcpy_s(entry->listener, sizeof(CredChangeListener),
106 listener, sizeof(CredChangeListener)) != IS_SUCCESS) {
107 UnlockHcMutex(g_credListenerMutex);
108 LOGE("[CredListener]: Failed to copy listener!");
109 return IS_ERR_MEMORY_COPY;
110 }
111 UnlockHcMutex(g_credListenerMutex);
112 LOGI("[CredListener]: Successfully updated a listener. [AppId]: %" LOG_PUB "s", appId);
113 return IS_SUCCESS;
114 }
115 }
116 UnlockHcMutex(g_credListenerMutex);
117 return IS_ERR_LISTENER_NOT_EXIST;
118 }
119
AddListenerIfNotExist(const char * appId,const CredChangeListener * listener)120 static int32_t AddListenerIfNotExist(const char *appId, const CredChangeListener *listener)
121 {
122 uint32_t appIdLen = HcStrlen(appId) + 1;
123 char *copyAppId = (char *)HcMalloc(appIdLen, 0);
124 if (copyAppId == NULL) {
125 LOGE("[CredListener]: Failed to allocate copyAppId memory!");
126 return IS_ERR_ALLOC_MEMORY;
127 }
128 if (strcpy_s(copyAppId, appIdLen, appId) != IS_SUCCESS) {
129 LOGE("[CredListener]: Failed to copy appId!");
130 HcFree(copyAppId);
131 return IS_ERR_MEMORY_COPY;
132 }
133 CredChangeListener *copyListener = (CredChangeListener *)HcMalloc(sizeof(CredChangeListener), 0);
134 if (copyListener == NULL) {
135 LOGE("[CredListener]: Failed to allocate saveCallback memory!");
136 HcFree(copyAppId);
137 return IS_ERR_ALLOC_MEMORY;
138 }
139 if (memcpy_s(copyListener, sizeof(CredChangeListener),
140 listener, sizeof(CredChangeListener)) != IS_SUCCESS) {
141 LOGE("[CredListener]: Failed to copy listener!");
142 HcFree(copyAppId);
143 HcFree(copyListener);
144 return IS_ERR_MEMORY_COPY;
145 }
146 CredListenerEntry entry;
147 entry.appId = copyAppId;
148 entry.listener = copyListener;
149 (void)LockHcMutex(g_credListenerMutex);
150 if (g_credListenerVec.pushBack(&g_credListenerVec, &entry) == NULL) {
151 HcFree(copyAppId);
152 HcFree(copyListener);
153 UnlockHcMutex(g_credListenerMutex);
154 return IS_ERR_MEMORY_COPY;
155 }
156 UnlockHcMutex(g_credListenerMutex);
157 LOGI("[CredListener]: Successfully added a listener. [AppId]: %" LOG_PUB "s", appId);
158 return IS_SUCCESS;
159 }
160
IsCredListenerSupported(void)161 bool IsCredListenerSupported(void)
162 {
163 return true;
164 }
165
InitCredListener(void)166 int32_t InitCredListener(void)
167 {
168 if (g_credListenerMutex == NULL) {
169 g_credListenerMutex = (HcMutex *)HcMalloc(sizeof(HcMutex), 0);
170 if (g_credListenerMutex == NULL) {
171 LOGE("[CredListener]: Failed to allocate cred listener mutex memory!");
172 return IS_ERR_ALLOC_MEMORY;
173 }
174 if (InitHcMutex(g_credListenerMutex, false) != IS_SUCCESS) {
175 LOGE("[CredListener]: Init mutex failed");
176 HcFree(g_credListenerMutex);
177 g_credListenerMutex = NULL;
178 return IS_ERR_INIT_FAILED;
179 }
180 }
181 g_credListenerVec = CREATE_HC_VECTOR(CredListenerEntryVec);
182 LOGI("[CredListener]: Init cred listener module successfully!");
183 return IS_SUCCESS;
184 }
185
DestroyCredListener(void)186 void DestroyCredListener(void)
187 {
188 (void)LockHcMutex(g_credListenerMutex);
189 uint32_t index;
190 CredListenerEntry *entry = NULL;
191 FOR_EACH_HC_VECTOR(g_credListenerVec, index, entry) {
192 if (entry == NULL) {
193 continue;
194 }
195 HcFree(entry->appId);
196 HcFree(entry->listener);
197 }
198 DESTROY_HC_VECTOR(CredListenerEntryVec, &g_credListenerVec);
199 UnlockHcMutex(g_credListenerMutex);
200 DestroyHcMutex(g_credListenerMutex);
201 HcFree(g_credListenerMutex);
202 g_credListenerMutex = NULL;
203 }
204
AddCredListener(const char * appId,const CredChangeListener * listener)205 int32_t AddCredListener(const char *appId, const CredChangeListener *listener)
206 {
207 if ((appId == NULL) || (listener == NULL)) {
208 LOGE("[CredListener]: The input appId or listener is NULL!");
209 return IS_ERR_INVALID_PARAMS;
210 }
211 if (UpdateListenerIfExist(appId, listener) == IS_SUCCESS) {
212 return IS_SUCCESS;
213 }
214 return AddListenerIfNotExist(appId, listener);
215 }
216
RemoveCredListener(const char * appId)217 int32_t RemoveCredListener(const char *appId)
218 {
219 if (appId == NULL) {
220 LOGE("[CredListener]: The input appId is NULL!");
221 return IS_ERR_INVALID_PARAMS;
222 }
223 uint32_t index;
224 CredListenerEntry *entry = NULL;
225 FOR_EACH_HC_VECTOR(g_credListenerVec, index, entry) {
226 if (entry != NULL && IsStrEqual(entry->appId, appId)) {
227 HcFree(entry->appId);
228 HcFree(entry->listener);
229 CredListenerEntry tempEntry;
230 HC_VECTOR_POPELEMENT(&g_credListenerVec, &tempEntry, index);
231 LOGI("[CredListener]: Successfully removed a cred listener. [AppId]: %" LOG_PUB "s", appId);
232 return IS_SUCCESS;
233 }
234 }
235 LOGI("[CredListener]: The cred listener does not exist! [AppId]: %" LOG_PUB "s", appId);
236 return IS_SUCCESS;
237 }
238