• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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