1 /*
2 * Copyright (C) 2021-2022 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 "auth_session_client.h"
17 #include "auth_session_common.h"
18 #include "auth_session_common_util.h"
19 #include "auth_session_util.h"
20 #include "dev_auth_module_manager.h"
21 #include "hc_log.h"
22 #include "hc_types.h"
23 #include "json_utils.h"
24 #include "session_common.h"
25 #include "string_util.h"
26
27 static int32_t ProcessClientAuthSession(Session *session, CJson *in);
28
CheckInputAuthParams(const CJson * authParam)29 int32_t CheckInputAuthParams(const CJson *authParam)
30 {
31 int32_t keyLen = DEFAULT_RETURN_KEY_LENGTH;
32 (void)GetIntFromJson(authParam, FIELD_KEY_LENGTH, &keyLen);
33 if ((keyLen < MIN_KEY_LENGTH) || (keyLen > MAX_KEY_LENGTH)) {
34 LOGE("The key length is invalid!");
35 return HC_ERR_INVALID_PARAMS;
36 }
37 const char *pkgName = GetStringFromJson(authParam, FIELD_SERVICE_PKG_NAME);
38 if (pkgName == NULL) {
39 LOGE("Pkg name is null, the input is invalid!");
40 return HC_ERR_INVALID_PARAMS;
41 }
42 return HC_SUCCESS;
43 }
44
ProcessClientAuthTask(AuthSession * session,int32_t moduleType,CJson * in,CJson * out)45 static int32_t ProcessClientAuthTask(AuthSession *session, int32_t moduleType, CJson *in, CJson *out)
46 {
47 int32_t status = 0;
48 CJson *paramInSession = (session->paramsList).get(&(session->paramsList), session->currentIndex);
49 if (paramInSession == NULL) {
50 LOGE("Failed to get param in session!");
51 return HC_ERR_NULL_PTR;
52 }
53 int32_t res = ProcessTask(session->curTaskId, in, out, &status, moduleType);
54 DeleteItemFromJson(in, FIELD_PAYLOAD);
55 if (res != HC_SUCCESS) {
56 DestroyTask(session->curTaskId, moduleType);
57 return InformAuthError(session, out, res);
58 }
59 return ProcessTaskStatusForAuth(session, paramInSession, out, status);
60 }
61
StartClientAuthTask(AuthSession * session)62 static int32_t StartClientAuthTask(AuthSession *session)
63 {
64 CJson *paramInSession = (session->paramsList).get(&(session->paramsList), session->currentIndex);
65 if (paramInSession == NULL) {
66 LOGE("Failed to get param in session!");
67 return HC_ERR_NULL_PTR;
68 }
69 CJson *out = CreateJson();
70 if (out == NULL) {
71 LOGE("Failed to create json!");
72 InformLocalAuthError(paramInSession, session->base.callback);
73 return HC_ERR_ALLOC_MEMORY;
74 }
75 int32_t status = 0;
76 int32_t res = CreateAndProcessTask(session, paramInSession, out, &status);
77 if (res != HC_SUCCESS) {
78 res = InformAuthError(session, out, res);
79 FreeJson(out);
80 LOGD("Start process client auth task, res = %d.", res);
81 return res;
82 }
83 res = ProcessTaskStatusForAuth(session, paramInSession, out, status);
84 FreeJson(out);
85 return res;
86 }
87
IsPeerGroupAuthError(const CJson * in)88 static bool IsPeerGroupAuthError(const CJson *in)
89 {
90 int32_t groupErrMsg = 0;
91 if (GetIntFromJson(in, FIELD_GROUP_ERROR_MSG, &groupErrMsg) != HC_SUCCESS) {
92 return false;
93 }
94 return true;
95 }
96
DealPeerGroupAuthError(AuthSession * session)97 static int32_t DealPeerGroupAuthError(AuthSession *session)
98 {
99 CJson *outData = CreateJson();
100 if (outData == NULL) {
101 LOGE("Failed to malloc for outData!");
102 return HC_ERR_ALLOC_MEMORY;
103 }
104 if (AddIntToJson(outData, FIELD_GROUP_ERROR_MSG, GROUP_ERR_MSG) != HC_SUCCESS) {
105 LOGE("Failed to add err msg to outData!");
106 FreeJson(outData);
107 return HC_ERR_JSON_FAIL;
108 }
109 int32_t res = InformAuthError(session, outData, HC_ERR_PEER_ERROR);
110 FreeJson(outData);
111 if (res != HC_SUCCESS) {
112 LOGE("Failed to inform auth error!");
113 }
114 return res;
115 }
116
PrintErrorInputInfo(const CJson * param)117 static void PrintErrorInputInfo(const CJson *param)
118 {
119 const char *peerUdid = GetStringFromJson(param, FIELD_PEER_CONN_DEVICE_ID);
120 const char *peerAuthId = GetStringFromJson(param, FIELD_PEER_AUTH_ID);
121 char *anonyPeerUdid = NULL;
122 char *anonyPeerAuthId = NULL;
123 ConvertToAnonymousStr(peerUdid, &anonyPeerUdid);
124 ConvertToAnonymousStr(peerAuthId, &anonyPeerAuthId);
125 LOGE("[PrintErrorInputInfo] [peerUdid]: %s", ((anonyPeerUdid == NULL) ? "NULL" : anonyPeerUdid));
126 LOGE("[PrintErrorInputInfo] [peerAuthId]: %s", ((anonyPeerAuthId == NULL) ? "NULL" : anonyPeerAuthId));
127 HcFree(anonyPeerUdid);
128 HcFree(anonyPeerAuthId);
129 }
130
ProcessClientAuthSession(Session * session,CJson * in)131 static int32_t ProcessClientAuthSession(Session *session, CJson *in)
132 {
133 LOGI("Begin process client authSession.");
134 if ((session == NULL) || (in == NULL)) {
135 LOGE("Invalid input params!");
136 return HC_ERR_INVALID_PARAMS;
137 }
138 AuthSession *realSession = (AuthSession *)session;
139 CJson *paramInSession = (realSession->paramsList).get(&(realSession->paramsList), realSession->currentIndex);
140 if (paramInSession == NULL) {
141 LOGE("Failed to get param in session!");
142 return HC_ERR_NULL_PTR;
143 }
144 ProcessDeviceLevel(in, paramInSession);
145
146 if (IsPeerGroupAuthError(in)) {
147 return DealPeerGroupAuthError(realSession);
148 }
149 CJson *out = CreateJson();
150 if (out == NULL) {
151 LOGE("Failed to create json for out!");
152 InformPeerAuthError(paramInSession, realSession->base.callback);
153 InformLocalAuthError(paramInSession, realSession->base.callback);
154 return HC_ERR_ALLOC_MEMORY;
155 }
156 int32_t res = ProcessClientAuthTask(realSession, GetAuthModuleType(paramInSession), in, out);
157 ClearSensitiveStringInJson(out, FIELD_SESSION_KEY);
158 FreeJson(out);
159 if (res == FINISH) {
160 LOGD("End process client authSession.");
161 }
162 return res;
163 }
164
CreateClientAuthSessionInner(int32_t osAccountId,CJson * param,const DeviceAuthCallback * callback)165 static Session *CreateClientAuthSessionInner(int32_t osAccountId, CJson *param, const DeviceAuthCallback *callback)
166 {
167 ParamsVec authParamsVec;
168 CreateAuthParamsVec(&authParamsVec);
169 int32_t res = GetAuthParamsList(osAccountId, param, &authParamsVec);
170 if ((res != HC_SUCCESS) || (authParamsVec.size(&authParamsVec) == 0)) {
171 LOGE("Failed to get auth param list, candidate group = %u!", authParamsVec.size(&authParamsVec));
172 DestroyAuthParamsVec(&authParamsVec);
173 PrintErrorInputInfo(param);
174 InformLocalAuthError(param, callback);
175 return NULL;
176 }
177
178 AuthSession *session = (AuthSession *)HcMalloc(sizeof(AuthSession), 0);
179 if (session == NULL) {
180 LOGE("Failed to allocate memory for session!");
181 DestroyAuthParamsVec(&authParamsVec);
182 InformLocalAuthError(param, callback);
183 return NULL;
184 }
185 session->base.type = TYPE_CLIENT_AUTH_SESSION;
186 session->base.process = ProcessClientAuthSession;
187 session->base.destroy = DestroyAuthSession;
188 session->base.callback = callback;
189 session->base.appId = GetDuplicateServicePkgName(param);
190 session->currentIndex = 0;
191 session->paramsList = authParamsVec;
192 res = GenerateSessionOrTaskId(&session->base.sessionId);
193 if (res != HC_SUCCESS) {
194 LOGE("Failed to generate session id!");
195 DestroyAuthSession((Session *)session);
196 InformLocalAuthError(param, callback);
197 return NULL;
198 }
199
200 res = StartClientAuthTask(session);
201 if (res != HC_SUCCESS) {
202 DestroyAuthSession((Session *)session);
203 return NULL;
204 }
205 return (Session *)session;
206 }
207
CreateClientAuthSession(CJson * param,const DeviceAuthCallback * callback)208 Session *CreateClientAuthSession(CJson *param, const DeviceAuthCallback *callback)
209 {
210 LOGD("Begin create client authSession.");
211 Session *session = NULL;
212 if (CheckInputAuthParams(param) != HC_SUCCESS) {
213 LOGE("Invalid input params!");
214 InformLocalAuthError(param, callback);
215 return NULL;
216 }
217 if (AddIntToJson(param, FIELD_OPERATION_CODE, AUTHENTICATE) != HC_SUCCESS) {
218 LOGE("Failed to add operation code to json!");
219 InformLocalAuthError(param, callback);
220 return NULL;
221 }
222 int32_t osAccountId = INVALID_OS_ACCOUNT;
223 if (GetIntFromJson(param, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
224 LOGE("Failed to get osAccountId for create client session!");
225 InformLocalAuthError(param, callback);
226 return NULL;
227 }
228 session = CreateClientAuthSessionInner(osAccountId, param, callback);
229 if (session == NULL) {
230 LOGE("Failed to create client auth session!");
231 return NULL;
232 }
233 LOGD("End create client authSession.");
234 return session;
235 }
236