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