1 /*
2 * Copyright (C) 2021 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 #include "daemon.h"
16 #ifndef TEST_HASH
17 #include "hdc_hash_gen.h"
18 #endif
19 #include "serial_struct.h"
20 #include <openssl/sha.h>
21 #include <openssl/bio.h>
22 #include <openssl/evp.h>
23 #include <openssl/err.h>
24 #include <openssl/pem.h>
25 #include <fstream>
26 #include <unistd.h>
27 #include <sys/wait.h>
28
29 namespace Hdc {
30 #ifdef USE_CONFIG_UV_THREADS
HdcDaemon(bool serverOrDaemonIn,size_t uvThreadSize)31 HdcDaemon::HdcDaemon(bool serverOrDaemonIn, size_t uvThreadSize)
32 : HdcSessionBase(serverOrDaemonIn, uvThreadSize)
33 #else
34 HdcDaemon::HdcDaemon(bool serverOrDaemonIn)
35 : HdcSessionBase(serverOrDaemonIn, -1)
36 #endif
37 {
38 clsTCPServ = nullptr;
39 clsUSBServ = nullptr;
40 #ifdef HDC_EMULATOR
41 clsBridgeServ = nullptr;
42 #endif
43 #ifdef HDC_SUPPORT_UART
44 clsUARTServ = nullptr;
45 #endif
46 clsJdwp = nullptr;
47 authEnable = false;
48 }
49
~HdcDaemon()50 HdcDaemon::~HdcDaemon()
51 {
52 WRITE_LOG(LOG_DEBUG, "~HdcDaemon");
53 }
54
ClearInstanceResource()55 void HdcDaemon::ClearInstanceResource()
56 {
57 TryStopInstance();
58 Base::TryCloseLoop(&loopMain, "HdcDaemon::~HdcDaemon");
59 if (clsTCPServ) {
60 delete (HdcDaemonTCP *)clsTCPServ;
61 clsTCPServ = nullptr;
62 }
63 if (clsUSBServ) {
64 delete (HdcDaemonUSB *)clsUSBServ;
65 clsUSBServ = nullptr;
66 }
67 #ifdef HDC_EMULATOR
68 if (clsBridgeServ) {
69 delete (HdcDaemonBridge *)clsBridgeServ;
70 }
71 #endif
72 #ifdef HDC_SUPPORT_UART
73 if (clsUARTServ) {
74 delete (HdcDaemonUART *)clsUARTServ;
75 }
76 clsUARTServ = nullptr;
77 #endif
78 if (clsJdwp) {
79 delete (HdcJdwp *)clsJdwp;
80 clsJdwp = nullptr;
81 }
82 WRITE_LOG(LOG_DEBUG, "~HdcDaemon finish");
83 }
84
TryStopInstance()85 void HdcDaemon::TryStopInstance()
86 {
87 ClearSessions();
88 if (clsTCPServ) {
89 WRITE_LOG(LOG_DEBUG, "Stop TCP");
90 ((HdcDaemonTCP *)clsTCPServ)->Stop();
91 }
92 if (clsUSBServ) {
93 WRITE_LOG(LOG_DEBUG, "Stop USB");
94 ((HdcDaemonUSB *)clsUSBServ)->Stop();
95 }
96 #ifdef HDC_EMULATOR
97 if (clsBridgeServ) {
98 WRITE_LOG(LOG_DEBUG, "Stop Bridge");
99 ((HdcDaemonBridge *)clsBridgeServ)->Stop();
100 }
101 #endif
102 #ifdef HDC_SUPPORT_UART
103 if (clsUARTServ) {
104 WRITE_LOG(LOG_DEBUG, "Stop UART");
105 ((HdcDaemonUART *)clsUARTServ)->Stop();
106 }
107 #endif
108 ((HdcJdwp *)clsJdwp)->Stop();
109 // workaround temply remove MainLoop instance clear
110 ReMainLoopForInstanceClear();
111 WRITE_LOG(LOG_DEBUG, "Stop loopmain");
112 }
113
GetAuthByPassValue()114 bool HdcDaemon::GetAuthByPassValue()
115 {
116 // enable security
117 string secure;
118 #ifdef CONFIG_HDC_OSPM_AUTH_DISABLE
119 WRITE_LOG(LOG_INFO, "Get param secure failed caused by hdc ospm auth disable");
120 return false;
121 #endif
122 if (!SystemDepend::GetDevItem("const.hdc.secure", secure)) {
123 WRITE_LOG(LOG_INFO, "Get param secure failed");
124 return true;
125 }
126 if (Base::Trim(secure) != "1") {
127 WRITE_LOG(LOG_INFO, "Authentication is not required in root mode");
128 return false;
129 }
130
131 string oemmode;
132 if (!SystemDepend::GetDevItem("const.boot.oemmode", oemmode)) {
133 WRITE_LOG(LOG_INFO, "Get param oemmode failed");
134 return true;
135 }
136 if (Base::Trim(oemmode) != "rd") {
137 WRITE_LOG(LOG_INFO, "The device is locked, Authentication is required");
138 return true;
139 }
140
141 string authbypass;
142 if (!SystemDepend::GetDevItem("persist.hdc.auth_bypass", authbypass)) {
143 WRITE_LOG(LOG_INFO, "Get param auth_bypass failed");
144 return true;
145 }
146 if (Base::Trim(authbypass) == "1") {
147 WRITE_LOG(LOG_INFO, "Auth bypass, allow access");
148 return false;
149 }
150
151 return true;
152 }
153
154 #ifdef HDC_SUPPORT_UART
InitMod(bool bEnableTCP,bool bEnableUSB,bool bEnableUART)155 void HdcDaemon::InitMod(bool bEnableTCP, bool bEnableUSB, [[maybe_unused]] bool bEnableUART)
156 #else
157 void HdcDaemon::InitMod(bool bEnableTCP, bool bEnableUSB)
158 #endif
159 {
160 WRITE_LOG(LOG_DEBUG, "HdcDaemon InitMod");
161 #ifdef HDC_SUPPORT_UART
162 WRITE_LOG(LOG_DEBUG, "bEnableTCP:%d,bEnableUSB:%d", bEnableTCP, bEnableUSB);
163 #endif
164 if (bEnableTCP) {
165 // tcp
166 clsTCPServ = new(std::nothrow) HdcDaemonTCP(false, this);
167 if (clsTCPServ == nullptr) {
168 WRITE_LOG(LOG_FATAL, "InitMod new clsTCPServ failed");
169 return;
170 }
171 ((HdcDaemonTCP *)clsTCPServ)->Initial();
172 }
173 if (bEnableUSB) {
174 // usb
175 clsUSBServ = new(std::nothrow) HdcDaemonUSB(false, this);
176 if (clsUSBServ == nullptr) {
177 WRITE_LOG(LOG_FATAL, "InitMod new clsUSBServ failed");
178 return;
179 }
180 ((HdcDaemonUSB *)clsUSBServ)->Initial();
181 }
182 #ifdef HDC_SUPPORT_UART
183 WRITE_LOG(LOG_DEBUG, "bEnableUART:%d", bEnableUART);
184 if (bEnableUART) {
185 // UART
186 clsUARTServ = new(std::nothrow) HdcDaemonUART(*this);
187 if (clsUARTServ == nullptr) {
188 WRITE_LOG(LOG_FATAL, "InitMod new clsUARTServ failed");
189 return;
190 }
191 ((HdcDaemonUART *)clsUARTServ)->Initial();
192 }
193 #endif
194 clsJdwp = new(std::nothrow) HdcJdwp(&loopMain, &loopMainStatus);
195 if (clsJdwp == nullptr) {
196 WRITE_LOG(LOG_FATAL, "InitMod new clsJdwp failed");
197 return;
198 }
199 ((HdcJdwp *)clsJdwp)->Initial();
200 #ifndef HDC_EMULATOR
201 authEnable = GetAuthByPassValue();
202 #endif
203 }
204
205 #ifdef HDC_EMULATOR
206 #ifdef HDC_SUPPORT_UART
InitMod(bool bEnableTCP,bool bEnableUSB,bool bEnableBridge,bool bEnableUART)207 void HdcDaemon::InitMod(bool bEnableTCP, bool bEnableUSB, bool bEnableBridge, [[maybe_unused]] bool bEnableUART)
208 {
209 InitMod(bEnableTCP, bEnableUSB, bEnableUART);
210 #else
211 void HdcDaemon::InitMod(bool bEnableTCP, bool bEnableUSB, bool bEnableBridge)
212 {
213 InitMod(bEnableTCP, bEnableUSB);
214 #endif
215 if (bEnableBridge) {
216 clsBridgeServ = new(std::nothrow) HdcDaemonBridge(false, this);
217 if (clsBridgeServ == nullptr) {
218 WRITE_LOG(LOG_FATAL, "InitMod new clsBridgeServ failed");
219 return;
220 }
221 ((HdcDaemonBridge *)clsBridgeServ)->Initial();
222 }
223 }
224 #endif
225
226 // clang-format off
227 bool HdcDaemon::RedirectToTask(HTaskInfo hTaskInfo, HSession hSession, const uint32_t channelId,
228 const uint16_t command, uint8_t *payload, const int payloadSize)
229 {
230 StartTraceScope("HdcDaemon::RedirectToTask");
231 bool ret = true;
232 hTaskInfo->ownerSessionClass = this;
233 switch (command) {
234 case CMD_UNITY_EXECUTE:
235 case CMD_UNITY_REMOUNT:
236 case CMD_UNITY_REBOOT:
237 case CMD_UNITY_RUNMODE:
238 case CMD_UNITY_HILOG:
239 case CMD_UNITY_ROOTRUN:
240 case CMD_UNITY_BUGREPORT_INIT:
241 case CMD_JDWP_LIST:
242 case CMD_JDWP_TRACK:
243 case CMD_UNITY_EXECUTE_EX:
244 ret = TaskCommandDispatch<HdcDaemonUnity>(hTaskInfo, TYPE_UNITY, command, payload, payloadSize);
245 break;
246 case CMD_SHELL_INIT:
247 case CMD_SHELL_DATA:
248 ret = TaskCommandDispatch<HdcShell>(hTaskInfo, TYPE_SHELL, command, payload, payloadSize);
249 break;
250 case CMD_FILE_CHECK:
251 case CMD_FILE_DATA:
252 case CMD_FILE_FINISH:
253 case CMD_FILE_INIT:
254 case CMD_FILE_BEGIN:
255 case CMD_FILE_MODE:
256 case CMD_DIR_MODE:
257 ret = TaskCommandDispatch<HdcFile>(hTaskInfo, TASK_FILE, command, payload, payloadSize);
258 break;
259 // One-way function, so fewer options
260 case CMD_APP_CHECK:
261 case CMD_APP_DATA:
262 case CMD_APP_UNINSTALL:
263 ret = TaskCommandDispatch<HdcDaemonApp>(hTaskInfo, TASK_APP, command, payload, payloadSize);
264 break;
265 case CMD_FORWARD_INIT:
266 case CMD_FORWARD_CHECK:
267 case CMD_FORWARD_ACTIVE_MASTER:
268 case CMD_FORWARD_ACTIVE_SLAVE:
269 case CMD_FORWARD_DATA:
270 case CMD_FORWARD_FREE_CONTEXT:
271 case CMD_FORWARD_CHECK_RESULT:
272 ret = TaskCommandDispatch<HdcDaemonForward>(hTaskInfo, TASK_FORWARD, command, payload, payloadSize);
273 break;
274 default:
275 // ignore unknown command
276 break;
277 }
278 return ret;
279 }
280 // clang-format on
281
282 bool HdcDaemon::ShowPermitDialog()
283 {
284 pid_t pid;
285 int fds[2];
286 pipe(fds);
287
288 if ((pid = fork()) == -1) {
289 WRITE_LOG(LOG_FATAL, "fork failed %s", strerror(errno));
290 return false;
291 }
292 if (pid == 0) {
293 Base::DeInitProcess();
294 // close the child read channel
295 close(fds[0]);
296 // redirect the child write channel
297 dup2(fds[1], STDOUT_FILENO);
298 dup2(fds[1], STDERR_FILENO);
299
300 setsid();
301 setpgid(pid, pid);
302
303 int ret = execl("/system/bin/hdcd_user_permit", "hdcd_user_permit", NULL);
304 if (ret < 0) {
305 // if execl failed need return false
306 WRITE_LOG(LOG_FATAL, "start user_permit failed %d: %s", ret, strerror(errno));
307 return false;
308 }
309 } else {
310 Base::CloseFd(fds[1]);
311 waitpid(pid, nullptr, 0);
312 char buf[1024] = { 0 };
313 int nbytes = read(fds[0], buf, sizeof(buf) - 1);
314 WRITE_LOG(LOG_FATAL, "user_permit put %d bytes: %s", nbytes, buf);
315 close(fds[0]);
316 }
317
318 return true;
319 }
320
321 UserPermit HdcDaemon::PostUIConfirm(string hostname, string pubkey)
322 {
323 // clear result first
324 if (!SystemDepend::SetDevItem("persist.hdc.daemon.auth_result", "auth_result_none")) {
325 WRITE_LOG(LOG_FATAL, "debug auth result failed, so refuse this connect");
326 return REFUSE;
327 }
328
329 // then write para for setting
330 if (!SystemDepend::SetDevItem("persist.hdc.client.hostname", hostname.c_str())) {
331 WRITE_LOG(LOG_FATAL, "set param(%s) failed", hostname.c_str());
332 return REFUSE;
333 }
334
335 uint8_t sha256Result[SHA256_DIGEST_LENGTH] = { 0 };
336 if (SHA256(reinterpret_cast<const uint8_t *>(pubkey.c_str()), pubkey.length(), sha256Result) == nullptr) {
337 WRITE_LOG(LOG_FATAL, "sha256 pubkey failed");
338 return REFUSE;
339 }
340
341 string hex = Base::Convert2HexStr(sha256Result, SHA256_DIGEST_LENGTH);
342 if (!SystemDepend::SetDevItem("persist.hdc.client.pubkey_sha256", hex.c_str())) {
343 WRITE_LOG(LOG_DEBUG, "Failed to set pubkey prop.");
344 return REFUSE;
345 }
346
347 if (!ShowPermitDialog()) {
348 WRITE_LOG(LOG_FATAL, "show dialog failed, so refuse this connect.");
349 return REFUSE;
350 }
351
352 string authResult;
353 if (!SystemDepend::GetDevItem("persist.hdc.daemon.auth_result", authResult)) {
354 WRITE_LOG(LOG_FATAL, "user refuse [%s] this developer [%s]", authResult.c_str(), hostname.c_str());
355 return REFUSE;
356 }
357 WRITE_LOG(LOG_FATAL, "user permit_result [%s] for this developer [%s]", authResult.c_str(), hostname.c_str());
358 string prifix = "auth_result:";
359 string result = authResult.substr(prifix.length());
360 if (result == "1") {
361 return ALLOWONCE;
362 }
363 if (result == "2") {
364 return ALLOWFORVER;
365 }
366 return REFUSE;
367 }
368
369 bool HdcDaemon::GetHostPubkeyInfo(const string& buf, string& hostname, string& pubkey)
370 {
371 // "\f" asicc is 0x0C
372 char separator = '\x0C';
373
374 hostname = buf.substr(0, buf.find(separator));
375 pubkey = buf.substr(buf.find(separator) + 1);
376 WRITE_LOG(LOG_INFO, "hostname is [%s], pubkey is [%s]", hostname.c_str(),
377 pubkey.substr(0, pubkey.size() / 2).c_str());
378
379 return (!hostname.empty() && !pubkey.empty());
380 }
381
382 void HdcDaemon::ClearKnownHosts()
383 {
384 char const *keyfile = "/data/service/el1/public/hdc/hdc_keys";
385
386 if (!authEnable || HandDaemonAuthBypass()) {
387 WRITE_LOG(LOG_INFO, "not enable secure, noneed clear keyfile");
388 return;
389 }
390
391 string authcancel;
392 if (!SystemDepend::GetDevItem("persist.hdc.daemon.auth_cancel", authcancel)) {
393 WRITE_LOG(LOG_FATAL, "get param auth_cancel failed");
394 return;
395 }
396 if (authcancel != "true") {
397 WRITE_LOG(LOG_FATAL, "param auth_cancel is not true: %s", authcancel.c_str());
398 return;
399 }
400 if (!SystemDepend::SetDevItem("persist.hdc.daemon.auth_cancel", "false")) {
401 WRITE_LOG(LOG_FATAL, "set param auth_cancel failed");
402 }
403
404 std::ofstream keyofs(keyfile, std::ios::out | std::ios::trunc);
405 if (!keyofs.is_open()) {
406 WRITE_LOG(LOG_FATAL, "open keyfile %s error", keyfile);
407 return;
408 }
409
410 keyofs.flush();
411 keyofs.close();
412
413 WRITE_LOG(LOG_FATAL, "clear keyfile %s over", keyfile);
414
415 return;
416 }
417
418 void HdcDaemon::UpdateKnownHosts(const string& key)
419 {
420 char const *keyfile = "/data/service/el1/public/hdc/hdc_keys";
421
422 std::ofstream keyofs(keyfile, std::ios::app);
423 if (!keyofs.is_open()) {
424 WRITE_LOG(LOG_FATAL, "open keyfile %s error", keyfile);
425 return;
426 }
427
428 string keytmp = key + "\n";
429 keyofs.write(keytmp.c_str(), keytmp.length());
430 keyofs.flush();
431 keyofs.close();
432
433 WRITE_LOG(LOG_FATAL, "save new key [%s] into keyfile %s over", key.substr(0, key.size() / 2).c_str(), keyfile);
434
435 return;
436 }
437
438 bool HdcDaemon::AlreadyInKnownHosts(const string& key)
439 {
440 char const *keyfile = "/data/service/el1/public/hdc/hdc_keys";
441
442 std::ifstream keyifs(keyfile);
443 if (!keyifs.is_open()) {
444 WRITE_LOG(LOG_FATAL, "open keyfile %s error", keyfile);
445 return false;
446 }
447
448 std::string keys((std::istreambuf_iterator<char>(keyifs)), std::istreambuf_iterator<char>());
449 // the length of pubkey is 625
450 const int keyLength = 625;
451 if (key.size() == keyLength && keys.find(key) != string::npos) {
452 keyifs.close();
453 return true;
454 }
455
456 WRITE_LOG(LOG_FATAL, "key [%s] not in keyfile %s", key.substr(0, key.size() / 2).c_str(), keyfile);
457
458 keyifs.close();
459 return false;
460 }
461
462 bool HdcDaemon::HandDaemonAuthInit(HSession hSession, const uint32_t channelId, SessionHandShake &handshake)
463 {
464 hSession->tokenRSA = Base::GetSecureRandomString(SHA_DIGEST_LENGTH);
465 handshake.authType = AUTH_PUBLICKEY;
466 /*
467 * If we know client support RSA_3072_SHA512 in AUTH_NONE phase
468 * Then told client that the server also support RSA_3072_SHA512 auth
469 * Notice, before here is "handshake.buf = hSession->tokenRSA", but the server not use it
470 */
471 if (hSession->verifyType == AuthVerifyType::RSA_3072_SHA512) {
472 handshake.buf.clear();
473 Base::TlvAppend(handshake.buf, TAG_AUTH_TYPE, std::to_string(AuthVerifyType::RSA_3072_SHA512));
474 WRITE_LOG(LOG_INFO, "client support RSA_3072_SHA512 auth for %u session", hSession->sessionId);
475 }
476 string bufString = SerialStruct::SerializeToString(handshake);
477 Send(hSession->sessionId, channelId, CMD_KERNEL_HANDSHAKE,
478 reinterpret_cast<uint8_t *>(const_cast<char *>(bufString.c_str())),
479 bufString.size());
480
481 InitSessionAuthInfo(hSession->sessionId, hSession->tokenRSA);
482 return true;
483 }
484
485 bool HdcDaemon::HandDaemonAuthPubkey(HSession hSession, const uint32_t channelId, SessionHandShake &handshake)
486 {
487 bool ret = false;
488 string hostname, pubkey;
489
490 do {
491 if (!GetHostPubkeyInfo(handshake.buf, hostname, pubkey)) {
492 WRITE_LOG(LOG_FATAL, "get pubkey failed for %u", hSession->sessionId);
493 break;
494 }
495 if (AlreadyInKnownHosts(pubkey)) {
496 ret = true;
497 break;
498 }
499
500 string confirmmsg = "[E000002]:The device unauthorized.\r\n"\
501 "This server's public key is not set.\r\n"\
502 "Please check for a confirmation dialog on your device.\r\n"\
503 "Otherwise try 'hdc kill' if that seems wrong.";
504 std::thread notifymsg([this, &handshake, channelId, sessionId = hSession->sessionId, &confirmmsg]() {
505 this->EchoHandshakeMsg(handshake, channelId, sessionId, confirmmsg);
506 });
507 notifymsg.detach();
508
509 UserPermit permit = PostUIConfirm(hostname, pubkey);
510 if (permit == ALLOWONCE) {
511 WRITE_LOG(LOG_FATAL, "user allow onece for %u", hSession->sessionId);
512 ret = true;
513 } else if (permit == ALLOWFORVER) {
514 WRITE_LOG(LOG_FATAL, "user allow forever for %u", hSession->sessionId);
515 UpdateKnownHosts(pubkey);
516 ret = true;
517 } else {
518 WRITE_LOG(LOG_FATAL, "user refuse for %u", hSession->sessionId);
519 ret = false;
520 }
521 } while (0);
522
523 if (ret) {
524 SendAuthMsg(handshake, channelId, hSession, pubkey);
525 } else {
526 string notifymsg = "[E000003]:The device unauthorized.\r\n"\
527 "The user denied the access for the device.\r\n"\
528 "Please execute 'hdc kill' and redo your command,\r\n"\
529 "then check for a confirmation dialog on your device.";
530 EchoHandshakeMsg(handshake, channelId, hSession->sessionId, notifymsg);
531 }
532 return true;
533 }
534
535 /*
536 * tokenSignBase64 is Base64 encode of the signing from server
537 * token is the source data same of server for signing
538 */
539 bool HdcDaemon::RsaSignVerify(HSession hSession, EVP_PKEY_CTX *ctx, const string &tokenSignBase64, const string &token)
540 {
541 unsigned char tokenSha512[SHA512_DIGEST_LENGTH];
542 try {
543 std::unique_ptr<unsigned char[]> tokenRsaSign = std::make_unique<unsigned char[]>(tokenSignBase64.length());
544 // Get the real token sign
545 int tokenRsaSignLen = EVP_DecodeBlock(tokenRsaSign.get(),
546 reinterpret_cast<const unsigned char *>(tokenSignBase64.c_str()), tokenSignBase64.length());
547 if (tokenRsaSignLen <= 0) {
548 WRITE_LOG(LOG_FATAL, "base64 decode token sign failed for session %u", hSession->sessionId);
549 return false;
550 }
551 SHA512(reinterpret_cast<const unsigned char *>(token.c_str()), token.size(), tokenSha512);
552 if (EVP_PKEY_verify(ctx, tokenRsaSign.get(), tokenRsaSignLen, tokenSha512, sizeof(tokenSha512)) < 0) {
553 WRITE_LOG(LOG_FATAL, "verify failed for session %u", hSession->sessionId);
554 return false;
555 }
556 } catch (std::exception &e) {
557 WRITE_LOG(LOG_FATAL, "sign verify failed for session %u with exception %s", hSession->sessionId, e.what());
558 return false;
559 }
560
561 WRITE_LOG(LOG_FATAL, "sign verify success for session %u", hSession->sessionId);
562 return true;
563 }
564
565 bool HdcDaemon::AuthVerifyRsaSign(HSession hSession, const string &tokenSign, const string &token, RSA *rsa)
566 {
567 EVP_PKEY *signKey = nullptr;
568 EVP_PKEY_CTX *ctx = nullptr;
569 bool signRet = false;
570
571 signKey = EVP_PKEY_new();
572 if (signKey == nullptr) {
573 WRITE_LOG(LOG_FATAL, "EVP_PKEY_new failed");
574 return false;
575 }
576 do {
577 if (EVP_PKEY_set1_RSA(signKey, rsa) <= 0) {
578 WRITE_LOG(LOG_FATAL, "EVP_PKEY_new failed");
579 break;
580 }
581 // the length of vaild sign result for BASE64 can't bigger than EVP_PKEY_size(signKey) * 2
582 if (tokenSign.size() > ((size_t)EVP_PKEY_size(signKey) * (size_t)2)) {
583 WRITE_LOG(LOG_FATAL, "invalid base64 sign size %zd for session %u", tokenSign.size(), hSession->sessionId);
584 break;
585 }
586 ctx = EVP_PKEY_CTX_new(signKey, nullptr);
587 if (ctx == nullptr) {
588 WRITE_LOG(LOG_FATAL, "EVP_PKEY_CTX_new failed");
589 break;
590 }
591 if (EVP_PKEY_verify_init(ctx) <= 0) {
592 WRITE_LOG(LOG_FATAL, "EVP_PKEY_CTX_new failed");
593 break;
594 }
595 if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING) <= 0 ||
596 EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, RSA_PSS_SALTLEN_AUTO) <= 0) {
597 WRITE_LOG(LOG_FATAL, "set saltlen or padding failed");
598 break;
599 }
600 if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha512()) <= 0) {
601 WRITE_LOG(LOG_FATAL, "EVP_PKEY_CTX_set_signature_md failed");
602 break;
603 }
604 signRet = RsaSignVerify(hSession, ctx, tokenSign, token);
605 } while (0);
606
607 if (ctx != nullptr) {
608 EVP_PKEY_CTX_free(ctx);
609 }
610 if (signKey != nullptr) {
611 EVP_PKEY_free(signKey);
612 }
613 return signRet;
614 }
615
616 bool HdcDaemon::AuthVerify(HSession hSession, const string &encryptToken, const string &token, const string &pubkey)
617 {
618 BIO *bio = nullptr;
619 RSA *rsa = nullptr;
620 const unsigned char *pubkeyp = reinterpret_cast<const unsigned char *>(pubkey.c_str());
621 bool verifyResult = false;
622
623 do {
624 bio = BIO_new(BIO_s_mem());
625 if (bio == nullptr) {
626 WRITE_LOG(LOG_FATAL, "bio failed for session %u", hSession->sessionId);
627 break;
628 }
629 int wbytes = BIO_write(bio, pubkeyp, pubkey.length());
630 if (wbytes <= 0) {
631 WRITE_LOG(LOG_FATAL, "bio write failed %d for session %u", wbytes, hSession->sessionId);
632 break;
633 }
634 rsa = PEM_read_bio_RSA_PUBKEY(bio, nullptr, nullptr, nullptr);
635 if (rsa == nullptr) {
636 WRITE_LOG(LOG_FATAL, "rsa failed for session %u", hSession->sessionId);
637 break;
638 }
639 if (hSession->verifyType == AuthVerifyType::RSA_3072_SHA512) {
640 verifyResult = AuthVerifyRsaSign(hSession, encryptToken, token, rsa);
641 } else {
642 verifyResult = AuthVerifyRsa(hSession, encryptToken, token, rsa);
643 }
644 } while (0);
645
646 if (bio) {
647 BIO_free(bio);
648 }
649 if (rsa) {
650 RSA_free(rsa);
651 }
652
653 return verifyResult;
654 }
655
656 bool HdcDaemon::AuthVerifyRsa(HSession hSession, const string &encryptToken, const string &token, RSA *rsa)
657 {
658 const unsigned char *tokenp = reinterpret_cast<const unsigned char *>(encryptToken.c_str());
659 unsigned char tokenDecode[BUF_SIZE_DEFAULT] = { 0 };
660 unsigned char decryptToken[BUF_SIZE_DEFAULT] = { 0 };
661
662 // for rsa encrypt, the length of encryptToken can't bigger than BUF_SIZE_DEFAULT
663 // Base64 divides every 3 bytes(8 bits) of the original data into 4 segments(6 bits),
664 // each of which is then mapped to a new character.
665 const int scaleOfEncrypt = 4;
666 const int scaleOfDecode = 3;
667 if (encryptToken.length() > BUF_SIZE_DEFAULT / scaleOfDecode * scaleOfEncrypt) {
668 WRITE_LOG(LOG_FATAL, "invalid encryptToken, length is %zd", encryptToken.length());
669 return false;
670 }
671 int tbytes = EVP_DecodeBlock(tokenDecode, tokenp, encryptToken.length());
672 if (tbytes <= 0) {
673 WRITE_LOG(LOG_FATAL, "base64 decode pubkey failed");
674 return false;
675 }
676 int bytes = RSA_public_decrypt(tbytes, tokenDecode, decryptToken, rsa, RSA_PKCS1_PADDING);
677 if (bytes < 0) {
678 WRITE_LOG(LOG_FATAL, "decrypt failed(%lu) for session %u", ERR_get_error(), hSession->sessionId);
679 return false;
680 }
681 string sdecryptToken(reinterpret_cast<const char *>(decryptToken), bytes);
682 if (sdecryptToken != token) {
683 WRITE_LOG(LOG_FATAL, "auth failed for session %u)", hSession->sessionId);
684 return false;
685 }
686 return true;
687 }
688
689 bool HdcDaemon::HandDaemonAuthSignature(HSession hSession, const uint32_t channelId, SessionHandShake &handshake)
690 {
691 // When Host is first connected to the device, the signature authentication is inevitable, and the
692 // certificate verification must be triggered.
693 //
694 // When the certificate is verified, the client sends a public key to the device, triggered the system UI
695 // jump out dialog, and click the system, the system will store the Host public key certificate in the
696 // device locally, and the signature authentication will be correct when the subsequent connection is
697 // connected.
698 string token = GetSessionAuthToken(hSession->sessionId);
699 string pubkey = GetSessionAuthPubkey(hSession->sessionId);
700 if (!AuthVerify(hSession, handshake.buf, token, pubkey)) {
701 WRITE_LOG(LOG_FATAL, "auth failed for session %u", hSession->sessionId);
702 // Next auth
703 EchoHandshakeMsg(handshake, channelId, hSession->sessionId, "[E000010]:Auth failed, cannt login the device.");
704 return true;
705 }
706
707 WRITE_LOG(LOG_FATAL, "auth success for session %u", hSession->sessionId);
708
709 UpdateSessionAuthOk(hSession->sessionId);
710 SendAuthOkMsg(handshake, channelId, hSession->sessionId);
711 return true;
712 }
713
714 bool HdcDaemon::HandDaemonAuthBypass(void)
715 {
716 // persist.hdc.auth_bypass 1 is bypass orelse(0 or not set) not bypass
717 string authbypass;
718 SystemDepend::GetDevItem("persist.hdc.auth_bypass", authbypass);
719 return Base::Trim(authbypass) == "1";
720 }
721
722 bool HdcDaemon::HandDaemonAuth(HSession hSession, const uint32_t channelId, SessionHandShake &handshake)
723 {
724 if (!authEnable) {
725 WRITE_LOG(LOG_INFO, "not enable secure, allow access for %u", hSession->sessionId);
726 UpdateSessionAuthOk(hSession->sessionId);
727 SendAuthOkMsg(handshake, channelId, hSession->sessionId);
728 return true;
729 } else if (handshake.version < "Ver: 3.0.0b") {
730 WRITE_LOG(LOG_INFO, "session %u client version %s is too low %u authType %d",
731 hSession->sessionId, handshake.version.c_str(), handshake.authType);
732 AuthRejectLowClient(handshake, channelId, hSession->sessionId);
733 return true;
734 } else if (GetSessionAuthStatus(hSession->sessionId) == AUTH_OK) {
735 WRITE_LOG(LOG_INFO, "session %u already auth ok", hSession->sessionId);
736 return true;
737 }
738
739 if (handshake.authType == AUTH_NONE) {
740 return HandDaemonAuthInit(hSession, channelId, handshake);
741 } else if (GetSessionAuthStatus(hSession->sessionId) == AUTH_NONE
742 && GetSessionAuthToken(hSession->sessionId).size() > 0
743 && handshake.authType == AUTH_PUBLICKEY) {
744 return HandDaemonAuthPubkey(hSession, channelId, handshake);
745 } else if (GetSessionAuthStatus(hSession->sessionId) == AUTH_PUBLICKEY && handshake.authType == AUTH_SIGNATURE) {
746 return HandDaemonAuthSignature(hSession, channelId, handshake);
747 #ifdef HDC_SUPPORT_ENCRYPT_TCP
748 } else if (GetSessionAuthStatus(hSession->sessionId) == AUTH_PUBLICKEY && handshake.authType == AUTH_SSL_TLS_PSK) {
749 return DaemonSSLHandshake(hSession, channelId, handshake);
750 #endif
751 } else {
752 WRITE_LOG(LOG_FATAL, "invalid auth state %d for session %u", handshake.authType, hSession->sessionId);
753 return false;
754 }
755 }
756
757 /*
758 * For daemon, if server add new capability, we can parse it here
759 */
760 void HdcDaemon::GetServerCapability(HSession &hSession, SessionHandShake &handshake)
761 {
762 /*
763 * Check if server support RSA_3072_SHA512 for auth
764 * if the value not contain RSA_3072_SHA512, We treat it not support
765 */
766 std::map<string, string> tlvMap;
767 hSession->verifyType = AuthVerifyType::RSA_ENCRYPT;
768 if (!Base::TlvToStringMap(handshake.buf, tlvMap)) {
769 WRITE_LOG(LOG_INFO, "maybe old version client for %u session", hSession->sessionId);
770 return;
771 }
772 if (tlvMap.find(TAG_AUTH_TYPE) != tlvMap.end() &&
773 tlvMap[TAG_AUTH_TYPE] == std::to_string(AuthVerifyType::RSA_3072_SHA512)) {
774 hSession->verifyType = AuthVerifyType::RSA_3072_SHA512;
775 }
776 WRITE_LOG(LOG_INFO, "client auth type is %u for %u session", hSession->verifyType, hSession->sessionId);
777
778 //Get server support features
779 ParsePeerSupportFeatures(hSession, tlvMap);
780 }
781
782 void HdcDaemon::DaemonSessionHandshakeInit(HSession &hSession, SessionHandShake &handshake)
783 {
784 // daemon handshake 1st packet
785 uint32_t unOld = hSession->sessionId;
786 hSession->sessionId = handshake.sessionId;
787 hSession->connectKey = handshake.connectKey;
788 hSession->handshakeOK = false;
789 AdminSession(OP_UPDATE, unOld, hSession);
790 #ifdef HDC_SUPPORT_UART
791 if (hSession->connType == CONN_SERIAL and clsUARTServ!= nullptr) {
792 WRITE_LOG(LOG_DEBUG, " HdcDaemon::DaemonSessionHandshake %s",
793 handshake.ToDebugString().c_str());
794 if (clsUARTServ != nullptr) {
795 (static_cast<HdcDaemonUART *>(clsUARTServ))->OnNewHandshakeOK(hSession->sessionId);
796 }
797 } else
798 #endif // HDC_SUPPORT_UART
799 if (clsUSBServ != nullptr && hSession->connType == CONN_USB) {
800 (reinterpret_cast<HdcDaemonUSB *>(clsUSBServ))->OnNewHandshakeOK(hSession->sessionId);
801 }
802
803 handshake.sessionId = 0;
804 handshake.connectKey = "";
805 // Get server capability
806 GetServerCapability(hSession, handshake);
807 }
808
809 // host( ) ---(TLS handshake client hello )--> hdcd( ) step 1
810 // host( ) <--(TLS handshake server hello )--- hdcd( ) step 2
811 // host(ok) ---(TLS handshake change cipher)--> hdcd( ) step 3
812 // host(ok) <--(TLS handshake change cipher)--- hdcd(ok) step 4
813 #ifdef HDC_SUPPORT_ENCRYPT_TCP
814 bool HdcDaemon::DaemonSSLHandshake(HSession hSession, const uint32_t channelId, SessionHandShake &handshake)
815 {
816 uint8_t *payload = reinterpret_cast<uint8_t*>(handshake.buf.data());
817 int payloadSize = static_cast<int>(handshake.buf.size());
818 if (!hSession->classSSL) {
819 WRITE_LOG(LOG_WARN, "DaemonSSLHandshake classSSL is nullptr");
820 return false;
821 }
822 HdcSSLBase *hssl = static_cast<HdcSSLBase *>(hSession->classSSL);
823 if (!hssl) {
824 WRITE_LOG(LOG_WARN, "hssl is null");
825 return false;
826 }
827 if (payloadSize > 0) {
828 int retw = hssl->DoBIOWrite(payload, payloadSize);
829 if (retw != payloadSize) {
830 WRITE_LOG(LOG_WARN, "BIO_write failed, payloadsize is %d", payloadSize);
831 return false;
832 }
833 }
834 vector<uint8_t> buf;
835 int ret = hssl->PerformHandshake(buf);
836 if (ret == RET_SUCCESS) { // SSL handshake step 2 and step 4
837 if (buf.size() == 0) { // no handshake data
838 WRITE_LOG(LOG_WARN, "SSL PerformHandshake failed, buffer data size is 0");
839 return false;
840 }
841 handshake.buf.assign(buf.begin(), buf.end());
842 string bufString = SerialStruct::SerializeToString(handshake);
843 Send(hSession->sessionId, channelId, CMD_KERNEL_HANDSHAKE,
844 reinterpret_cast<uint8_t *>(const_cast<char *>(bufString.c_str())), bufString.size());
845 }
846 if (hssl->SetHandshakeLabel(hSession)) {
847 std::this_thread::sleep_for(std::chrono::milliseconds(SSL_HANDSHAKE_FINISHED_WAIT_TIME));
848 UpdateSessionAuthOk(hSession->sessionId);
849 SendAuthOkMsg(handshake, channelId, hSession->sessionId);
850 if (!hssl->ClearPsk()) {
851 WRITE_LOG(LOG_WARN, "clear Pre Shared Key failed");
852 ret = ERR_GENERIC;
853 }
854 }
855 fill(buf.begin(), buf.end(), 0);
856 return ret == RET_SUCCESS;
857 }
858 #endif
859
860 bool HdcDaemon::DaemonSessionHandshake(HSession hSession, const uint32_t channelId, uint8_t *payload, int payloadSize)
861 {
862 StartTraceScope("HdcDaemon::DaemonSessionHandshake");
863 // session handshake step2
864 string s = string(reinterpret_cast<char *>(payload), payloadSize);
865 SessionHandShake handshake;
866 string err;
867 SerialStruct::ParseFromString(handshake, s);
868 #ifdef HDC_DEBUG
869 WRITE_LOG(LOG_DEBUG, "session %s try to handshake", hSession->ToDebugString().c_str());
870 #endif
871 // banner to check is parse ok...
872 if (handshake.banner != HANDSHAKE_MESSAGE) {
873 hSession->availTailIndex = 0;
874 WRITE_LOG(LOG_FATAL, "Recv server-hello failed");
875 return false;
876 }
877 if (handshake.authType == AUTH_NONE) {
878 if (GetSessionAuthStatus(handshake.sessionId) != AUTH_NONE) {
879 WRITE_LOG(LOG_FATAL, "session %u is already, But now session is %u, refused!",
880 handshake.sessionId, hSession->sessionId);
881 return false;
882 }
883 DaemonSessionHandshakeInit(hSession, handshake);
884 }
885 if (!HandDaemonAuth(hSession, channelId, handshake)) {
886 WRITE_LOG(LOG_FATAL, "auth failed");
887 return false;
888 }
889 string version = Base::GetVersion() + HDC_MSG_HASH;
890
891 WRITE_LOG(LOG_DEBUG, "receive hs version = %s", handshake.version.c_str());
892
893 if (!handshake.version.empty() && handshake.version != version) {
894 WRITE_LOG(LOG_FATAL, "DaemonSessionHandshake failed! version not match [%s] vs [%s]",
895 handshake.version.c_str(), version.c_str());
896 #ifdef HDC_CHECK_CHECK
897 hSession->availTailIndex = 0;
898 handshake.banner = HANDSHAKE_FAILED;
899 string failedString = SerialStruct::SerializeToString(handshake);
900 Send(hSession->sessionId, channelId, CMD_KERNEL_HANDSHAKE, (uint8_t *)failedString.c_str(),
901 failedString.size());
902 return false;
903 #endif
904 }
905 if (handshake.version.empty()) {
906 handshake.version = Base::GetVersion();
907 WRITE_LOG(LOG_FATAL, "set version if check mode = %s", handshake.version.c_str());
908 }
909 // handshake auth OK.Can append the sending device information to HOST
910 #ifdef HDC_DEBUG
911 WRITE_LOG(LOG_INFO, "session %u handshakeOK send back CMD_KERNEL_HANDSHAKE", hSession->sessionId);
912 #endif
913 hSession->handshakeOK = true;
914 return true;
915 }
916
917 bool HdcDaemon::IsExpectedParam(const string& param, const string& expect)
918 {
919 string out;
920 SystemDepend::GetDevItem(param.c_str(), out);
921 return (out.empty() || out == expect); // default empty
922 }
923
924 bool HdcDaemon::CheckControl(const uint16_t command)
925 {
926 bool ret = false; // default no debug
927 switch (command) { // this switch is match RedirectToTask function
928 case CMD_UNITY_EXECUTE:
929 case CMD_UNITY_EXECUTE_EX:
930 case CMD_UNITY_REMOUNT:
931 case CMD_UNITY_REBOOT:
932 case CMD_UNITY_RUNMODE:
933 case CMD_UNITY_HILOG:
934 case CMD_UNITY_ROOTRUN:
935 case CMD_UNITY_BUGREPORT_INIT:
936 case CMD_JDWP_LIST:
937 case CMD_JDWP_TRACK:
938 case CMD_SHELL_INIT:
939 case CMD_SHELL_DATA: {
940 ret = IsExpectedParam("persist.hdc.control.shell", "true");
941 break;
942 }
943 case CMD_FILE_CHECK:
944 case CMD_FILE_DATA:
945 case CMD_FILE_FINISH:
946 case CMD_FILE_INIT:
947 case CMD_FILE_BEGIN:
948 case CMD_FILE_MODE:
949 case CMD_DIR_MODE:
950 case CMD_APP_CHECK:
951 case CMD_APP_DATA:
952 case CMD_APP_UNINSTALL: {
953 ret = IsExpectedParam("persist.hdc.control.file", "true");
954 break;
955 }
956 case CMD_FORWARD_INIT:
957 case CMD_FORWARD_CHECK:
958 case CMD_FORWARD_ACTIVE_MASTER:
959 case CMD_FORWARD_ACTIVE_SLAVE:
960 case CMD_FORWARD_DATA:
961 case CMD_FORWARD_FREE_CONTEXT:
962 case CMD_FORWARD_CHECK_RESULT: {
963 ret = IsExpectedParam("persist.hdc.control.fport", "true");
964 break;
965 }
966 default:
967 ret = true; // other ECHO_RAW and so on
968 }
969 return ret;
970 }
971
972 bool HdcDaemon::CheckAuthStatus(HSession hSession, const uint32_t channelId, const uint16_t command)
973 {
974 if (authEnable && (GetSessionAuthStatus(hSession->sessionId) != AUTH_OK) &&
975 command != CMD_KERNEL_HANDSHAKE && command != CMD_KERNEL_CHANNEL_CLOSE && command != CMD_SSL_HANDSHAKE) {
976 string authmsg = GetSessionAuthmsg(hSession->sessionId);
977 WRITE_LOG(LOG_WARN, "session %u auth failed: %s for command %u",
978 hSession->sessionId, authmsg.c_str(), command);
979 if (!authmsg.empty()) {
980 LogMsg(hSession->sessionId, channelId, MSG_FAIL, authmsg.c_str());
981 }
982 uint8_t count = 1;
983 Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, &count, 1);
984 return false;
985 }
986 return true;
987 }
988
989 bool HdcDaemon::FetchCommand(HSession hSession, const uint32_t channelId, const uint16_t command, uint8_t *payload,
990 const int payloadSize)
991 {
992 StartTraceScope("HdcDaemon::FetchCommand");
993 bool ret = true;
994 if (!CheckAuthStatus(hSession, channelId, command)) {
995 return true;
996 }
997 if (command != CMD_UNITY_BUGREPORT_DATA &&
998 command != CMD_SHELL_DATA &&
999 command != CMD_FORWARD_DATA &&
1000 command != CMD_FILE_DATA &&
1001 command != CMD_APP_DATA) {
1002 WRITE_LOG(LOG_DEBUG, "FetchCommand channelId:%u command:%u", channelId, command);
1003 }
1004 switch (command) {
1005 case CMD_KERNEL_HANDSHAKE: {
1006 // session handshake step2
1007 ret = DaemonSessionHandshake(hSession, channelId, payload, payloadSize);
1008 break;
1009 }
1010 case CMD_KERNEL_CHANNEL_CLOSE: { // Daemon is only cleaning up the Channel task
1011 ClearOwnTasks(hSession, channelId);
1012 if (payloadSize >= 1 && *payload != 0) {
1013 --(*payload);
1014 Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, payload, 1);
1015 }
1016 ret = true;
1017 break;
1018 }
1019 case CMD_HEARTBEAT_MSG: {
1020 // heartbeat msg
1021 std::string str = hSession->heartbeat.HandleRecvHeartbeatMsg(payload, payloadSize);
1022 WRITE_LOG(LOG_INFO, "recv %s for session %u", str.c_str(), hSession->sessionId);
1023 break;
1024 }
1025 default:
1026 ret = true;
1027 if (CheckControl(command)) {
1028 ret = DispatchTaskData(hSession, channelId, command, payload, payloadSize);
1029 } else {
1030 LogMsg(hSession->sessionId, channelId, MSG_FAIL, "debugging is not allowed");
1031 uint8_t count = 1;
1032 Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, &count, 1);
1033 }
1034 break;
1035 }
1036 return ret;
1037 }
1038
1039 bool HdcDaemon::RemoveInstanceTask(const uint8_t op, HTaskInfo hTask)
1040 {
1041 bool ret = true;
1042
1043 if (!hTask->taskClass) {
1044 WRITE_LOG(LOG_FATAL, "RemoveInstanceTask taskClass is null channelId:%u", hTask->channelId);
1045 return ret;
1046 }
1047
1048 switch (hTask->taskType) {
1049 case TYPE_UNITY:
1050 ret = DoTaskRemove<HdcDaemonUnity>(hTask, op);
1051 break;
1052 case TYPE_SHELL:
1053 ret = DoTaskRemove<HdcShell>(hTask, op);
1054 break;
1055 case TASK_FILE:
1056 ret = DoTaskRemove<HdcTransferBase>(hTask, op);
1057 break;
1058 case TASK_FORWARD:
1059 ret = DoTaskRemove<HdcDaemonForward>(hTask, op);
1060 break;
1061 case TASK_APP:
1062 ret = DoTaskRemove<HdcDaemonApp>(hTask, op);
1063 break;
1064 default:
1065 ret = false;
1066 break;
1067 }
1068 return ret;
1069 }
1070
1071 bool HdcDaemon::ServerCommand(const uint32_t sessionId, const uint32_t channelId, const uint16_t command,
1072 uint8_t *bufPtr, const int size)
1073 {
1074 return Send(sessionId, channelId, command, reinterpret_cast<uint8_t *>(bufPtr), size) > 0;
1075 }
1076
1077 void HdcDaemon::JdwpNewFileDescriptor(const uint8_t *buf, const int bytesIO)
1078 {
1079 uint8_t spcmd = *const_cast<uint8_t *>(buf);
1080 if (spcmd == SP_JDWP_NEWFD) {
1081 int cnt = sizeof(uint8_t) + sizeof(uint32_t) * 2;
1082 if (bytesIO < cnt) {
1083 WRITE_LOG(LOG_FATAL, "jdwp newfd data insufficient bytesIO:%d", bytesIO);
1084 return;
1085 }
1086 uint32_t pid = *reinterpret_cast<uint32_t *>(const_cast<uint8_t *>(buf + 1));
1087 uint32_t fd = *reinterpret_cast<uint32_t *>(const_cast<uint8_t *>(buf + 5)); // 5 : fd offset
1088 ((HdcJdwp *)clsJdwp)->SendJdwpNewFD(pid, fd);
1089 } else if (spcmd == SP_ARK_NEWFD) {
1090 // SP_ARK_NEWFD | fd[1] | ark:pid@tid@Debugger
1091 int cnt = sizeof(uint8_t) + sizeof(uint32_t);
1092 if (bytesIO < cnt) {
1093 WRITE_LOG(LOG_FATAL, "ark newfd data insufficient bytesIO:%d", bytesIO);
1094 return;
1095 }
1096 int32_t fd = *reinterpret_cast<int32_t *>(const_cast<uint8_t *>(buf + 1));
1097 std::string arkstr = std::string(
1098 reinterpret_cast<char *>(const_cast<uint8_t *>(buf + 5)), bytesIO - 5); // 5 : fd offset
1099 WRITE_LOG(LOG_DEBUG, "JdwpNewFileDescriptor arkstr:%s fd:%d", arkstr.c_str(), fd);
1100 ((HdcJdwp *)clsJdwp)->SendArkNewFD(arkstr, fd);
1101 }
1102 }
1103
1104 void HdcDaemon::NotifyInstanceSessionFree(HSession hSession, bool freeOrClear)
1105 {
1106 if (!freeOrClear) {
1107 WRITE_LOG(LOG_WARN, "NotifyInstanceSessionFree freeOrClear false");
1108 return; // ignore step 1
1109 }
1110 if (clsUSBServ != nullptr) {
1111 auto clsUsbModule = reinterpret_cast<HdcDaemonUSB *>(clsUSBServ);
1112 clsUsbModule->OnSessionFreeFinally(hSession);
1113 }
1114 }
1115
1116 void HdcDaemon::InitSessionAuthInfo(uint32_t sessionid, string token)
1117 {
1118 HdcDaemonAuthInfo info = {
1119 AUTH_NONE,
1120 token
1121 };
1122 mapAuthStatusMutex.lock();
1123 mapAuthStatus[sessionid] = info;
1124 mapAuthStatusMutex.unlock();
1125 }
1126 void HdcDaemon::UpdateSessionAuthOk(uint32_t sessionid)
1127 {
1128 HdcDaemonAuthInfo info;
1129 mapAuthStatusMutex.lock();
1130 info = mapAuthStatus[sessionid];
1131 info.authtype = AUTH_OK;
1132 info.token = "";
1133 info.pubkey = "";
1134 mapAuthStatus[sessionid] = info;
1135 mapAuthStatusMutex.unlock();
1136 }
1137 void HdcDaemon::UpdateSessionAuthPubkey(uint32_t sessionid, string pubkey)
1138 {
1139 HdcDaemonAuthInfo info;
1140 mapAuthStatusMutex.lock();
1141 info = mapAuthStatus[sessionid];
1142 info.authtype = AUTH_PUBLICKEY;
1143 info.pubkey = pubkey;
1144 mapAuthStatus[sessionid] = info;
1145 mapAuthStatusMutex.unlock();
1146 }
1147 void HdcDaemon::UpdateSessionAuthmsg(uint32_t sessionid, string authmsg)
1148 {
1149 HdcDaemonAuthInfo info;
1150 mapAuthStatusMutex.lock();
1151 info = mapAuthStatus[sessionid];
1152 info.authtype = AUTH_FAIL;
1153 info.authmsg = authmsg;
1154 mapAuthStatus[sessionid] = info;
1155 mapAuthStatusMutex.unlock();
1156 }
1157 void HdcDaemon::DeleteSessionAuthStatus(uint32_t sessionid)
1158 {
1159 mapAuthStatusMutex.lock();
1160 mapAuthStatus.erase(sessionid);
1161 mapAuthStatusMutex.unlock();
1162 }
1163 HdcSessionBase::AuthType HdcDaemon::GetSessionAuthStatus(uint32_t sessionid)
1164 {
1165 HdcDaemonAuthInfo info;
1166 info.authtype = AUTH_NONE;
1167
1168 mapAuthStatusMutex.lock();
1169 if (mapAuthStatus.count(sessionid) > 0) {
1170 info = mapAuthStatus[sessionid];
1171 }
1172 mapAuthStatusMutex.unlock();
1173
1174 return info.authtype;
1175 }
1176 string HdcDaemon::GetSessionAuthToken(uint32_t sessionid)
1177 {
1178 HdcDaemonAuthInfo info;
1179
1180 mapAuthStatusMutex.lock();
1181 if (mapAuthStatus.count(sessionid) > 0) {
1182 info = mapAuthStatus[sessionid];
1183 }
1184 mapAuthStatusMutex.unlock();
1185
1186 return info.token;
1187 }
1188 string HdcDaemon::GetSessionAuthPubkey(uint32_t sessionid)
1189 {
1190 HdcDaemonAuthInfo info;
1191
1192 mapAuthStatusMutex.lock();
1193 if (mapAuthStatus.count(sessionid) > 0) {
1194 info = mapAuthStatus[sessionid];
1195 }
1196 mapAuthStatusMutex.unlock();
1197
1198 return info.pubkey;
1199 }
1200 string HdcDaemon::GetSessionAuthmsg(uint32_t sessionid)
1201 {
1202 HdcDaemonAuthInfo info;
1203
1204 mapAuthStatusMutex.lock();
1205 if (mapAuthStatus.count(sessionid) > 0) {
1206 info = mapAuthStatus[sessionid];
1207 }
1208 mapAuthStatusMutex.unlock();
1209
1210 return info.authmsg;
1211 }
1212 void HdcDaemon::SendAuthOkMsg(SessionHandShake &handshake, uint32_t channelid,
1213 uint32_t sessionid, string msg, string daemonAuthResult)
1214 {
1215 char hostname[BUF_SIZE_MEDIUM] = { 0 };
1216 if (gethostname(hostname, BUF_SIZE_MEDIUM) != 0) {
1217 WRITE_LOG(LOG_FATAL, "get hostname failed %s", strerror(errno));
1218 }
1219 if (handshake.version < "Ver: 3.0.0b") {
1220 if (msg.empty()) {
1221 msg = hostname;
1222 }
1223 handshake.buf = msg;
1224 } else {
1225 string emgmsg;
1226 Base::TlvAppend(emgmsg, TAG_EMGMSG, msg);
1227 Base::TlvAppend(emgmsg, TAG_DEVNAME, hostname);
1228 Base::TlvAppend(emgmsg, TAG_DAEOMN_AUTHSTATUS, daemonAuthResult);
1229 AddFeatureTagToEmgmsg(emgmsg);
1230 handshake.buf = emgmsg;
1231 }
1232
1233 handshake.authType = AUTH_OK;
1234 string bufString = SerialStruct::SerializeToString(handshake);
1235 Send(sessionid, channelid, CMD_KERNEL_HANDSHAKE,
1236 reinterpret_cast<uint8_t *>(const_cast<char *>(bufString.c_str())), bufString.size());
1237 uint8_t count = 1;
1238 Send(sessionid, channelid, CMD_KERNEL_CHANNEL_CLOSE, &count, 1);
1239 }
1240 void HdcDaemon::SendAuthSignMsg(SessionHandShake &handshake,
1241 uint32_t channelId, uint32_t sessionid, string pubkey, string token)
1242 {
1243 UpdateSessionAuthPubkey(sessionid, pubkey);
1244 handshake.authType = AUTH_SIGNATURE;
1245 handshake.buf = token;
1246 string bufString = SerialStruct::SerializeToString(handshake);
1247 Send(sessionid, channelId, CMD_KERNEL_HANDSHAKE,
1248 reinterpret_cast<uint8_t *>(const_cast<char *>(bufString.c_str())), bufString.size());
1249 }
1250 void HdcDaemon::SendAuthMsg(SessionHandShake &handshake, const uint32_t channelId,
1251 HSession &hSession, string pubkey)
1252 {
1253 #ifdef HDC_SUPPORT_ENCRYPT_TCP
1254 if (hSession->connType == CONN_TCP && hSession->supportEncrypt) {
1255 SendAuthEncryptPsk(handshake, channelId, hSession, pubkey);
1256 return;
1257 }
1258 #endif
1259 SendAuthSignMsg(handshake, channelId, hSession->sessionId, pubkey, hSession->tokenRSA);
1260 }
1261 #ifdef HDC_SUPPORT_ENCRYPT_TCP
1262 void HdcDaemon::SendAuthEncryptPsk(SessionHandShake &handshake, const uint32_t channelId,
1263 HSession &hSession, string pubkey)
1264 {
1265 UpdateSessionAuthPubkey(hSession->sessionId, pubkey);
1266 handshake.authType = AUTH_SSL_TLS_PSK;
1267 if (!hSession->classSSL) {
1268 SSLInfoPtr hSSLInfo = new (std::nothrow) HdcSSLInfo();
1269 if (!hSSLInfo) {
1270 WRITE_LOG(LOG_FATAL, "SendAuthEncryptPsk new HdcSSLInfo failed");
1271 return;
1272 }
1273 HdcSSLBase::SetSSLInfo(hSSLInfo, hSession);
1274 hSession->classSSL = new (std::nothrow) HdcDaemonSSL(hSSLInfo); // long lifetime with session.
1275 delete hSSLInfo;
1276 if (!hSession->classSSL) {
1277 WRITE_LOG(LOG_FATAL, "SendAuthEncryptPsk new HdcDaemonSSL failed");
1278 return;
1279 }
1280 }
1281 HdcSSLBase *hssl = static_cast<HdcSSLBase *>(hSession->classSSL);
1282 if (!hssl) {
1283 WRITE_LOG(LOG_WARN, "hssl is null");
1284 return;
1285 }
1286 if (!hssl->GenPsk()) {
1287 WRITE_LOG(LOG_WARN, "gen psk failed");
1288 return;
1289 }
1290 std::unique_ptr<unsigned char[]> payload(std::make_unique<unsigned char[]>(BUF_SIZE_DEFAULT2));
1291 int payloadSize = hssl->GetPskEncrypt(payload.get(), BUF_SIZE_DEFAULT2, pubkey);
1292 if (payloadSize <= 0) {
1293 WRITE_LOG(LOG_WARN, "RsaPubkeyEncrpt failed");
1294 return;
1295 }
1296
1297 handshake.buf = string(reinterpret_cast<const char*>(payload.get()), payloadSize);
1298 string bufString = SerialStruct::SerializeToString(handshake);
1299 Send(hSession->sessionId, channelId, CMD_KERNEL_HANDSHAKE,
1300 reinterpret_cast<uint8_t *>(const_cast<char *>(bufString.c_str())), bufString.size());
1301 hssl->InitSSL();
1302 }
1303 #endif
1304 void HdcDaemon::EchoHandshakeMsg(SessionHandShake &handshake, uint32_t channelid, uint32_t sessionid, string msg)
1305 {
1306 SendAuthOkMsg(handshake, channelid, sessionid, msg, DAEOMN_UNAUTHORIZED);
1307 LogMsg(sessionid, channelid, MSG_FAIL, msg.c_str());
1308 UpdateSessionAuthmsg(sessionid, msg);
1309 }
1310 void HdcDaemon::AuthRejectLowClient(SessionHandShake &handshake, uint32_t channelid, uint32_t sessionid)
1311 {
1312 string msg = "[E000001]:The sdk hdc.exe version is too low, please upgrade to the latest version.";
1313 EchoHandshakeMsg(handshake, channelid, sessionid, msg);
1314 }
1315 void HdcDaemon::AddFeatureTagToEmgmsg(string &emgmsg)
1316 {
1317 Base::TlvAppend(emgmsg, TAG_FEATURE_SHELL_OPT, "enable");
1318 //told server, we support features
1319 Base::TlvAppend(emgmsg, TAG_SUPPORT_FEATURE, Base::FeatureToString(Base::GetSupportFeature()));
1320 }
1321 } // namespace Hdc
1322