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