• 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     enableSecure = 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 
114 #ifdef HDC_SUPPORT_UART
InitMod(bool bEnableTCP,bool bEnableUSB,bool bEnableUART)115 void HdcDaemon::InitMod(bool bEnableTCP, bool bEnableUSB, [[maybe_unused]] bool bEnableUART)
116 #else
117 void HdcDaemon::InitMod(bool bEnableTCP, bool bEnableUSB)
118 #endif
119 {
120     WRITE_LOG(LOG_DEBUG, "HdcDaemon InitMod");
121 #ifdef HDC_SUPPORT_UART
122     WRITE_LOG(LOG_DEBUG, "bEnableTCP:%d,bEnableUSB:%d", bEnableTCP, bEnableUSB);
123 #endif
124     if (bEnableTCP) {
125         // tcp
126         clsTCPServ = new(std::nothrow) HdcDaemonTCP(false, this);
127         if (clsTCPServ == nullptr) {
128             WRITE_LOG(LOG_FATAL, "InitMod new clsTCPServ failed");
129             return;
130         }
131         ((HdcDaemonTCP *)clsTCPServ)->Initial();
132     }
133     if (bEnableUSB) {
134         // usb
135         clsUSBServ = new(std::nothrow) HdcDaemonUSB(false, this);
136         if (clsUSBServ == nullptr) {
137             WRITE_LOG(LOG_FATAL, "InitMod new clsUSBServ failed");
138             return;
139         }
140         ((HdcDaemonUSB *)clsUSBServ)->Initial();
141     }
142 #ifdef HDC_SUPPORT_UART
143     WRITE_LOG(LOG_DEBUG, "bEnableUART:%d", bEnableUART);
144     if (bEnableUART) {
145         // UART
146         clsUARTServ = new(std::nothrow) HdcDaemonUART(*this);
147         if (clsUARTServ == nullptr) {
148             WRITE_LOG(LOG_FATAL, "InitMod new clsUARTServ failed");
149             return;
150         }
151         ((HdcDaemonUART *)clsUARTServ)->Initial();
152     }
153 #endif
154     clsJdwp = new(std::nothrow) HdcJdwp(&loopMain);
155     if (clsJdwp == nullptr) {
156         WRITE_LOG(LOG_FATAL, "InitMod new clsJdwp failed");
157         return;
158     }
159     ((HdcJdwp *)clsJdwp)->Initial();
160     // enable security
161     string secure;
162     SystemDepend::GetDevItem("const.hdc.secure", secure);
163     string authbypass;
164     SystemDepend::GetDevItem("persist.hdc.auth_bypass", authbypass);
165 #ifndef HDC_EMULATOR
166     enableSecure = ((Base::Trim(secure) == "1") && (Base::Trim(authbypass) != "1"));
167 #endif
168 }
169 
170 #ifdef HDC_EMULATOR
171 #ifdef HDC_SUPPORT_UART
InitMod(bool bEnableTCP,bool bEnableUSB,bool bEnableBridge,bool bEnableUART)172 void HdcDaemon::InitMod(bool bEnableTCP, bool bEnableUSB, bool bEnableBridge, [[maybe_unused]] bool bEnableUART)
173 {
174     InitMod(bEnableTCP, bEnableUSB, bEnableUART);
175 #else
176 void HdcDaemon::InitMod(bool bEnableTCP, bool bEnableUSB, bool bEnableBridge)
177 {
178     InitMod(bEnableTCP, bEnableUSB);
179 #endif
180     if (bEnableBridge) {
181         clsBridgeServ = new(std::nothrow) HdcDaemonBridge(false, this);
182         if (clsBridgeServ == nullptr) {
183             WRITE_LOG(LOG_FATAL, "InitMod new clsBridgeServ failed");
184             return;
185         }
186         ((HdcDaemonBridge *)clsBridgeServ)->Initial();
187     }
188 }
189 #endif
190 
191 // clang-format off
192 bool HdcDaemon::RedirectToTask(HTaskInfo hTaskInfo, HSession hSession, const uint32_t channelId,
193                                const uint16_t command, uint8_t *payload, const int payloadSize)
194 {
195     StartTraceScope("HdcDaemon::RedirectToTask");
196     bool ret = true;
197     hTaskInfo->ownerSessionClass = this;
198     switch (command) {
199         case CMD_UNITY_EXECUTE:
200         case CMD_UNITY_REMOUNT:
201         case CMD_UNITY_REBOOT:
202         case CMD_UNITY_RUNMODE:
203         case CMD_UNITY_HILOG:
204         case CMD_UNITY_ROOTRUN:
205         case CMD_UNITY_BUGREPORT_INIT:
206         case CMD_JDWP_LIST:
207         case CMD_JDWP_TRACK:
208             ret = TaskCommandDispatch<HdcDaemonUnity>(hTaskInfo, TYPE_UNITY, command, payload, payloadSize);
209             break;
210         case CMD_SHELL_INIT:
211         case CMD_SHELL_DATA:
212             ret = TaskCommandDispatch<HdcShell>(hTaskInfo, TYPE_SHELL, command, payload, payloadSize);
213             break;
214         case CMD_FILE_CHECK:
215         case CMD_FILE_DATA:
216         case CMD_FILE_FINISH:
217         case CMD_FILE_INIT:
218         case CMD_FILE_BEGIN:
219         case CMD_FILE_MODE:
220         case CMD_DIR_MODE:
221             ret = TaskCommandDispatch<HdcFile>(hTaskInfo, TASK_FILE, command, payload, payloadSize);
222             break;
223         // One-way function, so fewer options
224         case CMD_APP_CHECK:
225         case CMD_APP_DATA:
226         case CMD_APP_UNINSTALL:
227             ret = TaskCommandDispatch<HdcDaemonApp>(hTaskInfo, TASK_APP, command, payload, payloadSize);
228             break;
229         case CMD_FORWARD_INIT:
230         case CMD_FORWARD_CHECK:
231         case CMD_FORWARD_ACTIVE_MASTER:
232         case CMD_FORWARD_ACTIVE_SLAVE:
233         case CMD_FORWARD_DATA:
234         case CMD_FORWARD_FREE_CONTEXT:
235         case CMD_FORWARD_CHECK_RESULT:
236             ret = TaskCommandDispatch<HdcDaemonForward>(hTaskInfo, TASK_FORWARD, command, payload, payloadSize);
237             break;
238         default:
239         // ignore unknown command
240             break;
241     }
242     return ret;
243 }
244 // clang-format on
245 
246 bool HdcDaemon::ShowPermitDialog()
247 {
248     pid_t pid;
249     int fds[2];
250     pipe(fds);
251 
252     if ((pid = fork()) == -1) {
253         WRITE_LOG(LOG_FATAL, "fork failed %s", strerror(errno));
254         return false;
255     }
256     if (pid == 0) {
257         Base::DeInitProcess();
258         // close the child read channel
259         close(fds[0]);
260         // redirect the child write channel
261         dup2(fds[1], STDOUT_FILENO);
262         dup2(fds[1], STDERR_FILENO);
263 
264         setsid();
265         setpgid(pid, pid);
266 
267         int ret = execl("/system/bin/hdcd_user_permit", "hdcd_user_permit", NULL);
268         // if execl failed need return false
269         WRITE_LOG(LOG_FATAL, "start user_permit failed %d: %s", ret, strerror(errno));
270         return false;
271     } else {
272             Base::CloseFd(fds[1]);
273             waitpid(pid, nullptr, 0);
274             char buf[1024] = { 0 };
275             int nbytes = read(fds[0], buf, sizeof(buf) - 1);
276             WRITE_LOG(LOG_FATAL, "user_permit put %d bytes: %s", nbytes, buf);
277             close(fds[0]);
278     }
279 
280     return true;
281 }
282 
283 UserPermit HdcDaemon::PostUIConfirm(string hostname, string pubkey)
284 {
285     // clear result first
286     if (!SystemDepend::SetDevItem("persist.hdc.daemon.auth_result", "auth_result_none")) {
287         WRITE_LOG(LOG_FATAL, "debug auth result failed, so refuse this connect");
288         return REFUSE;
289     }
290 
291     // then write para for setting
292     if (!SystemDepend::SetDevItem("persist.hdc.client.hostname", hostname.c_str())) {
293         WRITE_LOG(LOG_FATAL, "set param(%s) failed", hostname.c_str());
294         return REFUSE;
295     }
296 
297     uint8_t sha256Result[SHA256_DIGEST_LENGTH] = { 0 };
298     if (SHA256(reinterpret_cast<const uint8_t *>(pubkey.c_str()), pubkey.length(), sha256Result) == nullptr) {
299         WRITE_LOG(LOG_FATAL, "sha256 pubkey failed");
300         return REFUSE;
301     }
302 
303     string hex = Base::Convert2HexStr(sha256Result, SHA256_DIGEST_LENGTH);
304     if (!SystemDepend::SetDevItem("persist.hdc.client.pubkey_sha256", hex.c_str())) {
305         WRITE_LOG(LOG_DEBUG, "Failed to set pubkey prop.");
306         return REFUSE;
307     }
308 
309     if (!ShowPermitDialog()) {
310         WRITE_LOG(LOG_FATAL, "show dialog failed, so refuse this connect.");
311         return REFUSE;
312     }
313 
314     string authResult;
315     if (!SystemDepend::GetDevItem("persist.hdc.daemon.auth_result", authResult)) {
316         WRITE_LOG(LOG_FATAL, "user refuse [%s] this developer [%s]", authResult.c_str(), hostname.c_str());
317         return REFUSE;
318     }
319     WRITE_LOG(LOG_FATAL, "user permit_result [%s] for this developer [%s]", authResult.c_str(), hostname.c_str());
320     string prifix = "auth_result:";
321     string result = authResult.substr(prifix.length());
322     if (result == "1") {
323         return ALLOWONCE;
324     }
325     if (result == "2") {
326         return ALLOWFORVER;
327     }
328     return REFUSE;
329 }
330 
331 bool HdcDaemon::GetHostPubkeyInfo(const string& buf, string& hostname, string& pubkey)
332 {
333     // "\f" asicc is 0x0C
334     char separator = '\x0C';
335 
336     hostname = buf.substr(0, buf.find(separator));
337     pubkey = buf.substr(buf.find(separator) + 1);
338     WRITE_LOG(LOG_INFO, "hostname is [%s], pubkey is [%s]", hostname.c_str(),
339         pubkey.substr(0, pubkey.size() / 2).c_str());
340 
341     return (!hostname.empty() && !pubkey.empty());
342 }
343 
344 void HdcDaemon::ClearKnownHosts()
345 {
346     char const *keyfile = "/data/service/el1/public/hdc/hdc_keys";
347 
348     if (!enableSecure || HandDaemonAuthBypass()) {
349         WRITE_LOG(LOG_INFO, "not enable secure, noneed clear keyfile");
350         return;
351     }
352 
353     string authcancel;
354     if (!SystemDepend::GetDevItem("persist.hdc.daemon.auth_cancel", authcancel)) {
355         WRITE_LOG(LOG_FATAL, "get param auth_cancel failed");
356         return;
357     }
358     if (authcancel != "true") {
359         WRITE_LOG(LOG_FATAL, "param auth_cancel is not true: %s", authcancel.c_str());
360         return;
361     }
362     if (!SystemDepend::SetDevItem("persist.hdc.daemon.auth_cancel", "false")) {
363         WRITE_LOG(LOG_FATAL, "set param auth_cancel failed");
364     }
365 
366     std::ofstream keyofs(keyfile, std::ios::out | std::ios::trunc);
367     if (!keyofs.is_open()) {
368         WRITE_LOG(LOG_FATAL, "open keyfile %s error", keyfile);
369         return;
370     }
371 
372     keyofs.flush();
373     keyofs.close();
374 
375     WRITE_LOG(LOG_FATAL, "clear keyfile %s over", keyfile);
376 
377     return;
378 }
379 
380 void HdcDaemon::UpdateKnownHosts(const string& key)
381 {
382     char const *keyfile = "/data/service/el1/public/hdc/hdc_keys";
383 
384     std::ofstream keyofs(keyfile, std::ios::app);
385     if (!keyofs.is_open()) {
386         WRITE_LOG(LOG_FATAL, "open keyfile %s error", keyfile);
387         return;
388     }
389 
390     string keytmp = key + "\n";
391     keyofs.write(keytmp.c_str(), keytmp.length());
392     keyofs.flush();
393     keyofs.close();
394 
395     WRITE_LOG(LOG_FATAL, "save new key [%s] into keyfile %s over", key.substr(0, key.size() / 2).c_str(), keyfile);
396 
397     return;
398 }
399 
400 bool HdcDaemon::AlreadyInKnownHosts(const string& key)
401 {
402     char const *keyfile = "/data/service/el1/public/hdc/hdc_keys";
403 
404     std::ifstream keyifs(keyfile);
405     if (!keyifs.is_open()) {
406         WRITE_LOG(LOG_FATAL, "open keyfile %s error", keyfile);
407         return false;
408     }
409 
410     std::string keys((std::istreambuf_iterator<char>(keyifs)), std::istreambuf_iterator<char>());
411     if (keys.find(key) != string::npos) {
412         keyifs.close();
413         return true;
414     }
415 
416     WRITE_LOG(LOG_FATAL, "key [%s] not in keyfile %s", key.substr(0, key.size() / 2).c_str(), keyfile);
417 
418     keyifs.close();
419     return false;
420 }
421 
422 bool HdcDaemon::HandDaemonAuthInit(HSession hSession, const uint32_t channelId, SessionHandShake &handshake)
423 {
424     hSession->tokenRSA = Base::GetSecureRandomString(SHA_DIGEST_LENGTH);
425     handshake.authType = AUTH_PUBLICKEY;
426     /*
427      * If we know client support RSA_3072_SHA512 in AUTH_NONE phase
428      * Then told client that the server also support RSA_3072_SHA512 auth
429      * Notice, before here is "handshake.buf = hSession->tokenRSA", but the server not use it
430     */
431     if (hSession->verifyType == AuthVerifyType::RSA_3072_SHA512) {
432         handshake.buf.clear();
433         Base::TlvAppend(handshake.buf, TAG_AUTH_TYPE, std::to_string(AuthVerifyType::RSA_3072_SHA512));
434         WRITE_LOG(LOG_INFO, "client support RSA_3072_SHA512 auth for %u session", hSession->sessionId);
435     }
436     string bufString = SerialStruct::SerializeToString(handshake);
437     Send(hSession->sessionId, channelId, CMD_KERNEL_HANDSHAKE,
438             reinterpret_cast<uint8_t *>(const_cast<char *>(bufString.c_str())),
439             bufString.size());
440 
441     InitSessionAuthInfo(hSession->sessionId, hSession->tokenRSA);
442     return true;
443 }
444 
445 bool HdcDaemon::HandDaemonAuthPubkey(HSession hSession, const uint32_t channelId, SessionHandShake &handshake)
446 {
447     bool ret = false;
448     string hostname, pubkey;
449 
450     do {
451         if (!GetHostPubkeyInfo(handshake.buf, hostname, pubkey)) {
452             WRITE_LOG(LOG_FATAL, "get pubkey failed for %u", hSession->sessionId);
453             break;
454         }
455         if (AlreadyInKnownHosts(pubkey)) {
456             ret = true;
457             break;
458         }
459 
460         string confirmmsg = "[E000002]:The device unauthorized.\r\n"\
461                              "This server's public key is not set.\r\n"\
462                              "Please check for a confirmation dialog on your device.\r\n"\
463                              "Otherwise try 'hdc kill' if that seems wrong.";
464         std::thread notifymsg([this, &handshake, channelId, sessionId = hSession->sessionId, &confirmmsg]() {
465             this->EchoHandshakeMsg(handshake, channelId, sessionId, confirmmsg);
466         });
467         notifymsg.detach();
468 
469         UserPermit permit = PostUIConfirm(hostname, pubkey);
470         if (permit == ALLOWONCE) {
471             WRITE_LOG(LOG_FATAL, "user allow onece for %u", hSession->sessionId);
472             ret = true;
473         } else if (permit == ALLOWFORVER) {
474             WRITE_LOG(LOG_FATAL, "user allow forever for %u", hSession->sessionId);
475             UpdateKnownHosts(pubkey);
476             ret = true;
477         } else {
478             WRITE_LOG(LOG_FATAL, "user refuse for %u", hSession->sessionId);
479             ret = false;
480         }
481     } while (0);
482 
483     if (ret) {
484         SendAuthSignMsg(handshake, channelId, hSession->sessionId, pubkey, hSession->tokenRSA);
485     } else {
486         string notifymsg = "[E000003]:The device unauthorized.\r\n"\
487                             "The user denied the access for the device.\r\n"\
488                              "Please execute 'hdc kill' and redo your command,\r\n"\
489                              "then check for a confirmation dialog on your device.";
490         EchoHandshakeMsg(handshake, channelId, hSession->sessionId, notifymsg);
491     }
492     return true;
493 }
494 
495 /*
496  * tokenSignBase64 is Base64 encode of the signing from server
497  * token is the source data same of server for signing
498  */
499 bool HdcDaemon::RsaSignVerify(HSession hSession, EVP_PKEY_CTX *ctx, const string &tokenSignBase64, const string &token)
500 {
501     unsigned char tokenSha512[SHA512_DIGEST_LENGTH];
502     try {
503         std::unique_ptr<unsigned char[]> tokenRsaSign = std::make_unique<unsigned char[]>(tokenSignBase64.length());
504         // Get the real token sign
505         int tokenRsaSignLen = EVP_DecodeBlock(tokenRsaSign.get(),
506             reinterpret_cast<const unsigned char *>(tokenSignBase64.c_str()), tokenSignBase64.length());
507         if (tokenRsaSignLen <= 0) {
508             WRITE_LOG(LOG_FATAL, "base64 decode token sign failed for session %u", hSession->sessionId);
509             return false;
510         }
511         SHA512(reinterpret_cast<const unsigned char *>(token.c_str()), token.size(), tokenSha512);
512         if (EVP_PKEY_verify(ctx, tokenRsaSign.get(), tokenRsaSignLen, tokenSha512, sizeof(tokenSha512)) < 0) {
513             WRITE_LOG(LOG_FATAL, "verify failed for session %u", hSession->sessionId);
514             return false;
515         }
516     } catch (std::exception &e) {
517         WRITE_LOG(LOG_FATAL, "sign verify failed for session %u with exception %s", hSession->sessionId, e.what());
518         return false;
519     }
520 
521     WRITE_LOG(LOG_FATAL, "sign verify success for session %u", hSession->sessionId);
522     return true;
523 }
524 
525 bool HdcDaemon::AuthVerifyRsaSign(HSession hSession, const string &tokenSign, const string &token, RSA *rsa)
526 {
527     EVP_PKEY *signKey = nullptr;
528     EVP_PKEY_CTX *ctx = nullptr;
529     bool signRet = false;
530 
531     signKey = EVP_PKEY_new();
532     if (signKey == nullptr) {
533         WRITE_LOG(LOG_FATAL, "EVP_PKEY_new failed");
534         return false;
535     }
536     do {
537         if (EVP_PKEY_set1_RSA(signKey, rsa) <= 0) {
538             WRITE_LOG(LOG_FATAL, "EVP_PKEY_new failed");
539             break;
540         }
541         // the length of vaild sign result for BASE64 can't bigger than  EVP_PKEY_size(signKey) * 2
542         if (tokenSign.size() > ((size_t)EVP_PKEY_size(signKey) * (size_t)2)) {
543             WRITE_LOG(LOG_FATAL, "invalid base64 sign size %zd for session %u", tokenSign.size(), hSession->sessionId);
544             break;
545         }
546         ctx = EVP_PKEY_CTX_new(signKey, nullptr);
547         if (ctx == nullptr) {
548             WRITE_LOG(LOG_FATAL, "EVP_PKEY_CTX_new failed");
549             break;
550         }
551         if (EVP_PKEY_verify_init(ctx) <= 0) {
552             WRITE_LOG(LOG_FATAL, "EVP_PKEY_CTX_new failed");
553             break;
554         }
555         if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING) <= 0 ||
556             EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, RSA_PSS_SALTLEN_AUTO) <= 0) {
557             WRITE_LOG(LOG_FATAL, "set saltlen or padding failed");
558             break;
559         }
560         if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha512()) <= 0) {
561             WRITE_LOG(LOG_FATAL, "EVP_PKEY_CTX_set_signature_md failed");
562             break;
563         }
564         signRet = RsaSignVerify(hSession, ctx, tokenSign, token);
565     } while (0);
566 
567     if (ctx != nullptr) {
568         EVP_PKEY_CTX_free(ctx);
569     }
570     if (signKey != nullptr) {
571         EVP_PKEY_free(signKey);
572     }
573     return signRet;
574 }
575 
576 bool HdcDaemon::AuthVerify(HSession hSession, const string &encryptToken, const string &token, const string &pubkey)
577 {
578     BIO *bio = nullptr;
579     RSA *rsa = nullptr;
580     const unsigned char *pubkeyp = reinterpret_cast<const unsigned char *>(pubkey.c_str());
581     bool verifyResult = false;
582 
583     do {
584         bio = BIO_new(BIO_s_mem());
585         if (bio == nullptr) {
586             WRITE_LOG(LOG_FATAL, "bio failed for session %u", hSession->sessionId);
587             break;
588         }
589         int wbytes = BIO_write(bio, pubkeyp, pubkey.length());
590         if (wbytes <= 0) {
591             WRITE_LOG(LOG_FATAL, "bio write failed %d for session %u", wbytes, hSession->sessionId);
592             break;
593         }
594         rsa = PEM_read_bio_RSA_PUBKEY(bio, nullptr, nullptr, nullptr);
595         if (rsa == nullptr) {
596             WRITE_LOG(LOG_FATAL, "rsa failed for session %u", hSession->sessionId);
597             break;
598         }
599         if (hSession->verifyType == AuthVerifyType::RSA_3072_SHA512) {
600             verifyResult = AuthVerifyRsaSign(hSession, encryptToken, token, rsa);
601         } else {
602             verifyResult = AuthVerifyRsa(hSession, encryptToken, token, rsa);
603         }
604     } while (0);
605 
606     if (bio) {
607         BIO_free(bio);
608     }
609     if (rsa) {
610         RSA_free(rsa);
611     }
612 
613     return verifyResult;
614 }
615 
616 bool HdcDaemon::AuthVerifyRsa(HSession hSession, const string &encryptToken, const string &token, RSA *rsa)
617 {
618     const unsigned char *tokenp = reinterpret_cast<const unsigned char *>(encryptToken.c_str());
619     unsigned char tokenDecode[BUF_SIZE_DEFAULT] = { 0 };
620     unsigned char decryptToken[BUF_SIZE_DEFAULT] = { 0 };
621 
622     // for rsa encrypt, the length of encryptToken can't bigger than BUF_SIZE_DEFAULT
623     if (encryptToken.length() > BUF_SIZE_DEFAULT2) {
624         WRITE_LOG(LOG_FATAL, "invalid encryptToken, length is %zd", encryptToken.length());
625         return false;
626     }
627     int tbytes = EVP_DecodeBlock(tokenDecode, tokenp, encryptToken.length());
628     if (tbytes <= 0) {
629         WRITE_LOG(LOG_FATAL, "base64 decode pubkey failed");
630         return false;
631     }
632     int bytes = RSA_public_decrypt(tbytes, tokenDecode, decryptToken, rsa, RSA_PKCS1_PADDING);
633     if (bytes < 0) {
634         WRITE_LOG(LOG_FATAL, "decrypt failed(%lu) for session %u", ERR_get_error(), hSession->sessionId);
635         return false;
636     }
637     string sdecryptToken(reinterpret_cast<const char *>(decryptToken), bytes);
638     if (sdecryptToken != token) {
639         WRITE_LOG(LOG_FATAL, "auth failed for session %u)", hSession->sessionId);
640         return false;
641     }
642     return true;
643 }
644 
645 bool HdcDaemon::HandDaemonAuthSignature(HSession hSession, const uint32_t channelId, SessionHandShake &handshake)
646 {
647     // When Host is first connected to the device, the signature authentication is inevitable, and the
648     // certificate verification must be triggered.
649     //
650     // When the certificate is verified, the client sends a public key to the device, triggered the system UI
651     // jump out dialog, and click the system, the system will store the Host public key certificate in the
652     // device locally, and the signature authentication will be correct when the subsequent connection is
653     // connected.
654     string token = GetSessionAuthToken(hSession->sessionId);
655     string pubkey = GetSessionAuthPubkey(hSession->sessionId);
656     if (!AuthVerify(hSession, handshake.buf, token, pubkey)) {
657         WRITE_LOG(LOG_FATAL, "auth failed for session %u", hSession->sessionId);
658         // Next auth
659         EchoHandshakeMsg(handshake, channelId, hSession->sessionId, "[E000010]:Auth failed, cannt login the device.");
660         return true;
661     }
662 
663     WRITE_LOG(LOG_FATAL, "auth success for session %u", hSession->sessionId);
664 
665     UpdateSessionAuthOk(hSession->sessionId);
666     SendAuthOkMsg(handshake, channelId, hSession->sessionId);
667     return true;
668 }
669 
670 bool HdcDaemon::HandDaemonAuthBypass(void)
671 {
672     // persist.hdc.auth_bypass 1 is bypass orelse(0 or not set) not bypass
673     string authbypass;
674     SystemDepend::GetDevItem("persist.hdc.auth_bypass", authbypass);
675     return Base::Trim(authbypass) == "1";
676 }
677 
678 bool HdcDaemon::HandDaemonAuth(HSession hSession, const uint32_t channelId, SessionHandShake &handshake)
679 {
680     if (!enableSecure) {
681         WRITE_LOG(LOG_INFO, "not enable secure, allow access for %u", hSession->sessionId);
682         UpdateSessionAuthOk(hSession->sessionId);
683         SendAuthOkMsg(handshake, channelId, hSession->sessionId);
684         return true;
685     } else if (HandDaemonAuthBypass()) {
686         WRITE_LOG(LOG_INFO, "auth bypass, allow access for %u", hSession->sessionId);
687         UpdateSessionAuthOk(hSession->sessionId);
688         SendAuthOkMsg(handshake, channelId, hSession->sessionId);
689         return true;
690     } else if (handshake.version < "Ver: 3.0.0b") {
691         WRITE_LOG(LOG_INFO, "session %u client version %s is too low %u authType %d",
692                     hSession->sessionId, handshake.version.c_str(), handshake.authType);
693         AuthRejectLowClient(handshake, channelId, hSession->sessionId);
694         return true;
695     } else if (GetSessionAuthStatus(hSession->sessionId) == AUTH_OK) {
696         WRITE_LOG(LOG_INFO, "session %u already auth ok", hSession->sessionId);
697         return true;
698     }
699 
700     if (handshake.authType == AUTH_NONE) {
701         return HandDaemonAuthInit(hSession, channelId, handshake);
702     } else if (handshake.authType == AUTH_PUBLICKEY) {
703         return HandDaemonAuthPubkey(hSession, channelId, handshake);
704     } else if (handshake.authType == AUTH_SIGNATURE) {
705         return HandDaemonAuthSignature(hSession, channelId, handshake);
706     } else {
707         WRITE_LOG(LOG_FATAL, "invalid auth state %d for session %u", handshake.authType, hSession->sessionId);
708         return false;
709     }
710 }
711 
712 /*
713  * For daemon, if server add new capability, we can parse it here
714  */
715 void HdcDaemon::GetServerCapability(HSession &hSession, SessionHandShake &handshake)
716 {
717     /*
718      * Check if server support RSA_3072_SHA512 for auth
719      * if the value not contain RSA_3072_SHA512, We treat it not support
720     */
721     std::map<string, string> tlvMap;
722     hSession->verifyType = AuthVerifyType::RSA_ENCRYPT;
723     if (!Base::TlvToStringMap(handshake.buf, tlvMap)) {
724         WRITE_LOG(LOG_INFO, "maybe old version client for %u session", hSession->sessionId);
725         return;
726     }
727     if (tlvMap.find(TAG_AUTH_TYPE) != tlvMap.end() &&
728         tlvMap[TAG_AUTH_TYPE] == std::to_string(AuthVerifyType::RSA_3072_SHA512)) {
729         hSession->verifyType = AuthVerifyType::RSA_3072_SHA512;
730     }
731     WRITE_LOG(LOG_INFO, "client auth type is %u for %u session", hSession->verifyType, hSession->sessionId);
732 }
733 
734 void HdcDaemon::DaemonSessionHandshakeInit(HSession &hSession, SessionHandShake &handshake)
735 {
736     // daemon handshake 1st packet
737     uint32_t unOld = hSession->sessionId;
738     hSession->sessionId = handshake.sessionId;
739     hSession->connectKey = handshake.connectKey;
740     hSession->handshakeOK = false;
741     AdminSession(OP_UPDATE, unOld, hSession);
742 #ifdef HDC_SUPPORT_UART
743     if (hSession->connType == CONN_SERIAL and clsUARTServ!= nullptr) {
744         WRITE_LOG(LOG_DEBUG, " HdcDaemon::DaemonSessionHandshake %s",
745                     handshake.ToDebugString().c_str());
746         if (clsUARTServ != nullptr) {
747             (static_cast<HdcDaemonUART *>(clsUARTServ))->OnNewHandshakeOK(hSession->sessionId);
748         }
749     } else
750 #endif // HDC_SUPPORT_UART
751     if (clsUSBServ != nullptr && hSession->connType == CONN_USB) {
752         (reinterpret_cast<HdcDaemonUSB *>(clsUSBServ))->OnNewHandshakeOK(hSession->sessionId);
753     }
754 
755     handshake.sessionId = 0;
756     handshake.connectKey = "";
757     // Get server capability
758     GetServerCapability(hSession, handshake);
759 }
760 
761 bool HdcDaemon::DaemonSessionHandshake(HSession hSession, const uint32_t channelId, uint8_t *payload, int payloadSize)
762 {
763     StartTraceScope("HdcDaemon::DaemonSessionHandshake");
764     // session handshake step2
765     string s = string(reinterpret_cast<char *>(payload), payloadSize);
766     SessionHandShake handshake;
767     string err;
768     SerialStruct::ParseFromString(handshake, s);
769 #ifdef HDC_DEBUG
770     WRITE_LOG(LOG_DEBUG, "session %s try to handshake", hSession->ToDebugString().c_str());
771 #endif
772     // banner to check is parse ok...
773     if (handshake.banner != HANDSHAKE_MESSAGE) {
774         hSession->availTailIndex = 0;
775         WRITE_LOG(LOG_FATAL, "Recv server-hello failed");
776         return false;
777     }
778     if (handshake.authType == AUTH_NONE) {
779         DaemonSessionHandshakeInit(hSession, handshake);
780     }
781     if (!HandDaemonAuth(hSession, channelId, handshake)) {
782         WRITE_LOG(LOG_FATAL, "auth failed");
783         return false;
784     }
785     string version = Base::GetVersion() + HDC_MSG_HASH;
786 
787     WRITE_LOG(LOG_DEBUG, "receive hs version = %s", handshake.version.c_str());
788 
789     if (!handshake.version.empty() && handshake.version != version) {
790         WRITE_LOG(LOG_FATAL, "DaemonSessionHandshake failed! version not match [%s] vs [%s]",
791             handshake.version.c_str(), version.c_str());
792 #ifdef HDC_CHECK_CHECK
793         hSession->availTailIndex = 0;
794         handshake.banner = HANDSHAKE_FAILED;
795         string failedString = SerialStruct::SerializeToString(handshake);
796         Send(hSession->sessionId, channelId, CMD_KERNEL_HANDSHAKE, (uint8_t *)failedString.c_str(),
797              failedString.size());
798         return false;
799 #endif
800     }
801     if (handshake.version.empty()) {
802         handshake.version = Base::GetVersion();
803         WRITE_LOG(LOG_FATAL, "set version if check mode = %s", handshake.version.c_str());
804     }
805     // handshake auth OK.Can append the sending device information to HOST
806 #ifdef HDC_DEBUG
807     WRITE_LOG(LOG_INFO, "session %u handshakeOK send back CMD_KERNEL_HANDSHAKE", hSession->sessionId);
808 #endif
809     hSession->handshakeOK = true;
810     return true;
811 }
812 
813 bool HdcDaemon::IsExpectedParam(const string& param, const string& expect)
814 {
815     string out;
816     SystemDepend::GetDevItem(param.c_str(), out);
817     return (out.empty() || out == expect); // default empty
818 }
819 
820 bool HdcDaemon::CheckControl(const uint16_t command)
821 {
822     bool ret = false; // default no debug
823     switch (command) { // this switch is match RedirectToTask function
824         case CMD_UNITY_EXECUTE:
825         case CMD_UNITY_REMOUNT:
826         case CMD_UNITY_REBOOT:
827         case CMD_UNITY_RUNMODE:
828         case CMD_UNITY_HILOG:
829         case CMD_UNITY_ROOTRUN:
830         case CMD_UNITY_BUGREPORT_INIT:
831         case CMD_JDWP_LIST:
832         case CMD_JDWP_TRACK:
833         case CMD_SHELL_INIT:
834         case CMD_SHELL_DATA: {
835             ret = IsExpectedParam("persist.hdc.control.shell", "true");
836             break;
837         }
838         case CMD_FILE_CHECK:
839         case CMD_FILE_DATA:
840         case CMD_FILE_FINISH:
841         case CMD_FILE_INIT:
842         case CMD_FILE_BEGIN:
843         case CMD_FILE_MODE:
844         case CMD_DIR_MODE:
845         case CMD_APP_CHECK:
846         case CMD_APP_DATA:
847         case CMD_APP_UNINSTALL: {
848             ret = IsExpectedParam("persist.hdc.control.file", "true");
849             break;
850         }
851         case CMD_FORWARD_INIT:
852         case CMD_FORWARD_CHECK:
853         case CMD_FORWARD_ACTIVE_MASTER:
854         case CMD_FORWARD_ACTIVE_SLAVE:
855         case CMD_FORWARD_DATA:
856         case CMD_FORWARD_FREE_CONTEXT:
857         case CMD_FORWARD_CHECK_RESULT: {
858             ret = IsExpectedParam("persist.hdc.control.fport", "true");
859             break;
860         }
861         default:
862             ret = true; // other ECHO_RAW and so on
863     }
864     return ret;
865 }
866 
867 bool HdcDaemon::FetchCommand(HSession hSession, const uint32_t channelId, const uint16_t command, uint8_t *payload,
868                              const int payloadSize)
869 {
870     StartTraceScope("HdcDaemon::FetchCommand");
871     bool ret = true;
872     if (enableSecure && (GetSessionAuthStatus(hSession->sessionId) != AUTH_OK) &&
873         command != CMD_KERNEL_HANDSHAKE && command != CMD_KERNEL_CHANNEL_CLOSE) {
874         string authmsg = GetSessionAuthmsg(hSession->sessionId);
875         WRITE_LOG(LOG_WARN, "session %u auth failed: %s for command %u",
876                   hSession->sessionId, authmsg.c_str(), command);
877         if (!authmsg.empty()) {
878             LogMsg(hSession->sessionId, channelId, MSG_FAIL, authmsg.c_str());
879         }
880         uint8_t count = 1;
881         Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, &count, 1);
882         return true;
883     }
884     if (command != CMD_UNITY_BUGREPORT_DATA &&
885         command != CMD_SHELL_DATA &&
886         command != CMD_FORWARD_DATA &&
887         command != CMD_FILE_DATA &&
888         command != CMD_APP_DATA) {
889         WRITE_LOG(LOG_DEBUG, "FetchCommand channelId:%u command:%u", channelId, command);
890     }
891     switch (command) {
892         case CMD_KERNEL_HANDSHAKE: {
893             // session handshake step2
894             ret = DaemonSessionHandshake(hSession, channelId, payload, payloadSize);
895             break;
896         }
897         case CMD_KERNEL_CHANNEL_CLOSE: {  // Daemon is only cleaning up the Channel task
898             ClearOwnTasks(hSession, channelId);
899             if (*payload != 0) {
900                 --(*payload);
901                 Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, payload, 1);
902             }
903             ret = true;
904             break;
905         }
906         default:
907             ret = true;
908             if (CheckControl(command)) {
909                 ret = DispatchTaskData(hSession, channelId, command, payload, payloadSize);
910             } else {
911                 LogMsg(hSession->sessionId, channelId, MSG_FAIL, "debugging is not allowed");
912                 uint8_t count = 1;
913                 Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, &count, 1);
914             }
915             break;
916     }
917     return ret;
918 }
919 
920 bool HdcDaemon::RemoveInstanceTask(const uint8_t op, HTaskInfo hTask)
921 {
922     bool ret = true;
923 
924     if (!hTask->taskClass) {
925         return ret;
926     }
927 
928     switch (hTask->taskType) {
929         case TYPE_UNITY:
930             ret = DoTaskRemove<HdcDaemonUnity>(hTask, op);
931             break;
932         case TYPE_SHELL:
933             ret = DoTaskRemove<HdcShell>(hTask, op);
934             break;
935         case TASK_FILE:
936             ret = DoTaskRemove<HdcTransferBase>(hTask, op);
937             break;
938         case TASK_FORWARD:
939             ret = DoTaskRemove<HdcDaemonForward>(hTask, op);
940             break;
941         case TASK_APP:
942             ret = DoTaskRemove<HdcDaemonApp>(hTask, op);
943             break;
944         default:
945             ret = false;
946             break;
947     }
948     return ret;
949 }
950 
951 bool HdcDaemon::ServerCommand(const uint32_t sessionId, const uint32_t channelId, const uint16_t command,
952                               uint8_t *bufPtr, const int size)
953 {
954     return Send(sessionId, channelId, command, reinterpret_cast<uint8_t *>(bufPtr), size) > 0;
955 }
956 
957 void HdcDaemon::JdwpNewFileDescriptor(const uint8_t *buf, const int bytesIO)
958 {
959     uint8_t spcmd = *const_cast<uint8_t *>(buf);
960     if (spcmd == SP_JDWP_NEWFD) {
961         int cnt = sizeof(uint8_t) + sizeof(uint32_t) * 2;
962         if (bytesIO < cnt) {
963             WRITE_LOG(LOG_FATAL, "jdwp newfd data insufficient bytesIO:%d", bytesIO);
964             return;
965         }
966         uint32_t pid = *reinterpret_cast<uint32_t *>(const_cast<uint8_t *>(buf + 1));
967         uint32_t fd = *reinterpret_cast<uint32_t *>(const_cast<uint8_t *>(buf + 5));  // 5 : fd offset
968         ((HdcJdwp *)clsJdwp)->SendJdwpNewFD(pid, fd);
969     } else if (spcmd == SP_ARK_NEWFD) {
970         // SP_ARK_NEWFD | fd[1] | ark:pid@tid@Debugger
971         int cnt = sizeof(uint8_t) + sizeof(uint32_t);
972         if (bytesIO < cnt) {
973             WRITE_LOG(LOG_FATAL, "ark newfd data insufficient bytesIO:%d", bytesIO);
974             return;
975         }
976         int32_t fd = *reinterpret_cast<int32_t *>(const_cast<uint8_t *>(buf + 1));
977         std::string arkstr = std::string(
978             reinterpret_cast<char *>(const_cast<uint8_t *>(buf + 5)), bytesIO - 5);  // 5 : fd offset
979         WRITE_LOG(LOG_DEBUG, "JdwpNewFileDescriptor arkstr:%s fd:%d", arkstr.c_str(), fd);
980         ((HdcJdwp *)clsJdwp)->SendArkNewFD(arkstr, fd);
981     }
982 }
983 
984 void HdcDaemon::NotifyInstanceSessionFree(HSession hSession, bool freeOrClear)
985 {
986     if (!freeOrClear) {
987         WRITE_LOG(LOG_WARN, "NotifyInstanceSessionFree freeOrClear false");
988         return;  // ignore step 1
989     }
990     if (clsUSBServ != nullptr) {
991         auto clsUsbModule = reinterpret_cast<HdcDaemonUSB *>(clsUSBServ);
992         clsUsbModule->OnSessionFreeFinally(hSession);
993     }
994 }
995 
996 void HdcDaemon::InitSessionAuthInfo(uint32_t sessionid, string token)
997 {
998     HdcDaemonAuthInfo info = {
999         AUTH_NONE,
1000         token
1001     };
1002     mapAuthStatusMutex.lock();
1003     mapAuthStatus[sessionid] = info;
1004     mapAuthStatusMutex.unlock();
1005 }
1006 void HdcDaemon::UpdateSessionAuthOk(uint32_t sessionid)
1007 {
1008     HdcDaemonAuthInfo info;
1009     mapAuthStatusMutex.lock();
1010     info = mapAuthStatus[sessionid];
1011     info.authtype = AUTH_OK;
1012     info.token = "";
1013     info.pubkey = "";
1014     mapAuthStatus[sessionid] = info;
1015     mapAuthStatusMutex.unlock();
1016 }
1017 void HdcDaemon::UpdateSessionAuthPubkey(uint32_t sessionid, string pubkey)
1018 {
1019     HdcDaemonAuthInfo info;
1020     mapAuthStatusMutex.lock();
1021     info = mapAuthStatus[sessionid];
1022     info.authtype = AUTH_PUBLICKEY;
1023     info.pubkey = pubkey;
1024     mapAuthStatus[sessionid] = info;
1025     mapAuthStatusMutex.unlock();
1026 }
1027 void HdcDaemon::UpdateSessionAuthmsg(uint32_t sessionid, string authmsg)
1028 {
1029     HdcDaemonAuthInfo info;
1030     mapAuthStatusMutex.lock();
1031     info = mapAuthStatus[sessionid];
1032     info.authtype = AUTH_FAIL;
1033     info.authmsg = authmsg;
1034     mapAuthStatus[sessionid] = info;
1035     mapAuthStatusMutex.unlock();
1036 }
1037 void HdcDaemon::DeleteSessionAuthStatus(uint32_t sessionid)
1038 {
1039     mapAuthStatusMutex.lock();
1040     mapAuthStatus.erase(sessionid);
1041     mapAuthStatusMutex.unlock();
1042 }
1043 HdcSessionBase::AuthType HdcDaemon::GetSessionAuthStatus(uint32_t sessionid)
1044 {
1045     HdcDaemonAuthInfo info;
1046 
1047     mapAuthStatusMutex.lock();
1048     info = mapAuthStatus[sessionid];
1049     mapAuthStatusMutex.unlock();
1050 
1051     return info.authtype;
1052 }
1053 string HdcDaemon::GetSessionAuthToken(uint32_t sessionid)
1054 {
1055     HdcDaemonAuthInfo info;
1056 
1057     mapAuthStatusMutex.lock();
1058     info = mapAuthStatus[sessionid];
1059     mapAuthStatusMutex.unlock();
1060 
1061     return info.token;
1062 }
1063 string HdcDaemon::GetSessionAuthPubkey(uint32_t sessionid)
1064 {
1065     HdcDaemonAuthInfo info;
1066 
1067     mapAuthStatusMutex.lock();
1068     info = mapAuthStatus[sessionid];
1069     mapAuthStatusMutex.unlock();
1070 
1071     return info.pubkey;
1072 }
1073 string HdcDaemon::GetSessionAuthmsg(uint32_t sessionid)
1074 {
1075     HdcDaemonAuthInfo info;
1076 
1077     mapAuthStatusMutex.lock();
1078     info = mapAuthStatus[sessionid];
1079     mapAuthStatusMutex.unlock();
1080 
1081     return info.authmsg;
1082 }
1083 void HdcDaemon::SendAuthOkMsg(SessionHandShake &handshake, uint32_t channelid,
1084                               uint32_t sessionid, string msg, string daemonAuthResult)
1085 {
1086     char hostname[BUF_SIZE_MEDIUM] = { 0 };
1087     if (gethostname(hostname, BUF_SIZE_MEDIUM) != 0) {
1088         WRITE_LOG(LOG_FATAL, "get hostname failed %s", strerror(errno));
1089     }
1090     if (handshake.version < "Ver: 3.0.0b") {
1091         if (msg.empty()) {
1092             msg = hostname;
1093         }
1094         handshake.buf = msg;
1095     } else {
1096         string emgmsg;
1097         Base::TlvAppend(emgmsg, TAG_EMGMSG, msg);
1098         Base::TlvAppend(emgmsg, TAG_DEVNAME, hostname);
1099         Base::TlvAppend(emgmsg, TAG_DAEOMN_AUTHSTATUS, daemonAuthResult);
1100         handshake.buf = emgmsg;
1101     }
1102 
1103     handshake.authType = AUTH_OK;
1104     string bufString = SerialStruct::SerializeToString(handshake);
1105     Send(sessionid, channelid, CMD_KERNEL_HANDSHAKE,
1106             reinterpret_cast<uint8_t *>(const_cast<char *>(bufString.c_str())), bufString.size());
1107     uint8_t count = 1;
1108     Send(sessionid, channelid, CMD_KERNEL_CHANNEL_CLOSE, &count, 1);
1109 }
1110 void HdcDaemon::SendAuthSignMsg(SessionHandShake &handshake,
1111         uint32_t channelId, uint32_t sessionid, string pubkey, string token)
1112 {
1113     UpdateSessionAuthPubkey(sessionid, pubkey);
1114     handshake.authType = AUTH_SIGNATURE;
1115     handshake.buf = token;
1116     string bufString = SerialStruct::SerializeToString(handshake);
1117     Send(sessionid, channelId, CMD_KERNEL_HANDSHAKE,
1118             reinterpret_cast<uint8_t *>(const_cast<char *>(bufString.c_str())), bufString.size());
1119 }
1120 void HdcDaemon::EchoHandshakeMsg(SessionHandShake &handshake, uint32_t channelid, uint32_t sessionid, string msg)
1121 {
1122     SendAuthOkMsg(handshake, channelid, sessionid, msg, DAEOMN_UNAUTHORIZED);
1123     LogMsg(sessionid, channelid, MSG_FAIL, msg.c_str());
1124     UpdateSessionAuthmsg(sessionid, msg);
1125 }
1126 void HdcDaemon::AuthRejectLowClient(SessionHandShake &handshake, uint32_t channelid, uint32_t sessionid)
1127 {
1128     string msg = "[E000001]:The sdk hdc.exe version is too low, please upgrade to the latest version.";
1129     EchoHandshakeMsg(handshake, channelid, sessionid, msg);
1130 }
1131 }  // namespace Hdc
1132