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, [[maybe_unused]] 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, [[maybe_unused]] 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 WRITE_LOG(LOG_FATAL, "RemoveInstanceTask taskClass is null channelId:%u", hTask->channelId);
926 return ret;
927 }
928
929 switch (hTask->taskType) {
930 case TYPE_UNITY:
931 ret = DoTaskRemove<HdcDaemonUnity>(hTask, op);
932 break;
933 case TYPE_SHELL:
934 ret = DoTaskRemove<HdcShell>(hTask, op);
935 break;
936 case TASK_FILE:
937 ret = DoTaskRemove<HdcTransferBase>(hTask, op);
938 break;
939 case TASK_FORWARD:
940 ret = DoTaskRemove<HdcDaemonForward>(hTask, op);
941 break;
942 case TASK_APP:
943 ret = DoTaskRemove<HdcDaemonApp>(hTask, op);
944 break;
945 default:
946 ret = false;
947 break;
948 }
949 return ret;
950 }
951
952 bool HdcDaemon::ServerCommand(const uint32_t sessionId, const uint32_t channelId, const uint16_t command,
953 uint8_t *bufPtr, const int size)
954 {
955 return Send(sessionId, channelId, command, reinterpret_cast<uint8_t *>(bufPtr), size) > 0;
956 }
957
958 void HdcDaemon::JdwpNewFileDescriptor(const uint8_t *buf, const int bytesIO)
959 {
960 uint8_t spcmd = *const_cast<uint8_t *>(buf);
961 if (spcmd == SP_JDWP_NEWFD) {
962 int cnt = sizeof(uint8_t) + sizeof(uint32_t) * 2;
963 if (bytesIO < cnt) {
964 WRITE_LOG(LOG_FATAL, "jdwp newfd data insufficient bytesIO:%d", bytesIO);
965 return;
966 }
967 uint32_t pid = *reinterpret_cast<uint32_t *>(const_cast<uint8_t *>(buf + 1));
968 uint32_t fd = *reinterpret_cast<uint32_t *>(const_cast<uint8_t *>(buf + 5)); // 5 : fd offset
969 ((HdcJdwp *)clsJdwp)->SendJdwpNewFD(pid, fd);
970 } else if (spcmd == SP_ARK_NEWFD) {
971 // SP_ARK_NEWFD | fd[1] | ark:pid@tid@Debugger
972 int cnt = sizeof(uint8_t) + sizeof(uint32_t);
973 if (bytesIO < cnt) {
974 WRITE_LOG(LOG_FATAL, "ark newfd data insufficient bytesIO:%d", bytesIO);
975 return;
976 }
977 int32_t fd = *reinterpret_cast<int32_t *>(const_cast<uint8_t *>(buf + 1));
978 std::string arkstr = std::string(
979 reinterpret_cast<char *>(const_cast<uint8_t *>(buf + 5)), bytesIO - 5); // 5 : fd offset
980 WRITE_LOG(LOG_DEBUG, "JdwpNewFileDescriptor arkstr:%s fd:%d", arkstr.c_str(), fd);
981 ((HdcJdwp *)clsJdwp)->SendArkNewFD(arkstr, fd);
982 }
983 }
984
985 void HdcDaemon::NotifyInstanceSessionFree(HSession hSession, bool freeOrClear)
986 {
987 if (!freeOrClear) {
988 WRITE_LOG(LOG_WARN, "NotifyInstanceSessionFree freeOrClear false");
989 return; // ignore step 1
990 }
991 if (clsUSBServ != nullptr) {
992 auto clsUsbModule = reinterpret_cast<HdcDaemonUSB *>(clsUSBServ);
993 clsUsbModule->OnSessionFreeFinally(hSession);
994 }
995 }
996
997 void HdcDaemon::InitSessionAuthInfo(uint32_t sessionid, string token)
998 {
999 HdcDaemonAuthInfo info = {
1000 AUTH_NONE,
1001 token,
1002 "",
1003 ""
1004 };
1005 mapAuthStatusMutex.lock();
1006 mapAuthStatus[sessionid] = info;
1007 mapAuthStatusMutex.unlock();
1008 }
1009 void HdcDaemon::UpdateSessionAuthOk(uint32_t sessionid)
1010 {
1011 HdcDaemonAuthInfo info;
1012 mapAuthStatusMutex.lock();
1013 info = mapAuthStatus[sessionid];
1014 info.authtype = AUTH_OK;
1015 info.token = "";
1016 info.pubkey = "";
1017 mapAuthStatus[sessionid] = info;
1018 mapAuthStatusMutex.unlock();
1019 }
1020 void HdcDaemon::UpdateSessionAuthPubkey(uint32_t sessionid, string pubkey)
1021 {
1022 HdcDaemonAuthInfo info;
1023 mapAuthStatusMutex.lock();
1024 info = mapAuthStatus[sessionid];
1025 info.authtype = AUTH_PUBLICKEY;
1026 info.pubkey = pubkey;
1027 mapAuthStatus[sessionid] = info;
1028 mapAuthStatusMutex.unlock();
1029 }
1030 void HdcDaemon::UpdateSessionAuthmsg(uint32_t sessionid, string authmsg)
1031 {
1032 HdcDaemonAuthInfo info;
1033 mapAuthStatusMutex.lock();
1034 info = mapAuthStatus[sessionid];
1035 info.authtype = AUTH_FAIL;
1036 info.authmsg = authmsg;
1037 mapAuthStatus[sessionid] = info;
1038 mapAuthStatusMutex.unlock();
1039 }
1040 void HdcDaemon::DeleteSessionAuthStatus(uint32_t sessionid)
1041 {
1042 mapAuthStatusMutex.lock();
1043 mapAuthStatus.erase(sessionid);
1044 mapAuthStatusMutex.unlock();
1045 }
1046 HdcSessionBase::AuthType HdcDaemon::GetSessionAuthStatus(uint32_t sessionid)
1047 {
1048 HdcDaemonAuthInfo info;
1049
1050 mapAuthStatusMutex.lock();
1051 info = mapAuthStatus[sessionid];
1052 mapAuthStatusMutex.unlock();
1053
1054 return info.authtype;
1055 }
1056 string HdcDaemon::GetSessionAuthToken(uint32_t sessionid)
1057 {
1058 HdcDaemonAuthInfo info;
1059
1060 mapAuthStatusMutex.lock();
1061 info = mapAuthStatus[sessionid];
1062 mapAuthStatusMutex.unlock();
1063
1064 return info.token;
1065 }
1066 string HdcDaemon::GetSessionAuthPubkey(uint32_t sessionid)
1067 {
1068 HdcDaemonAuthInfo info;
1069
1070 mapAuthStatusMutex.lock();
1071 info = mapAuthStatus[sessionid];
1072 mapAuthStatusMutex.unlock();
1073
1074 return info.pubkey;
1075 }
1076 string HdcDaemon::GetSessionAuthmsg(uint32_t sessionid)
1077 {
1078 HdcDaemonAuthInfo info;
1079
1080 mapAuthStatusMutex.lock();
1081 info = mapAuthStatus[sessionid];
1082 mapAuthStatusMutex.unlock();
1083
1084 return info.authmsg;
1085 }
1086 void HdcDaemon::SendAuthOkMsg(SessionHandShake &handshake, uint32_t channelid,
1087 uint32_t sessionid, string msg, string daemonAuthResult)
1088 {
1089 char hostname[BUF_SIZE_MEDIUM] = { 0 };
1090 if (gethostname(hostname, BUF_SIZE_MEDIUM) != 0) {
1091 WRITE_LOG(LOG_FATAL, "get hostname failed %s", strerror(errno));
1092 }
1093 if (handshake.version < "Ver: 3.0.0b") {
1094 if (msg.empty()) {
1095 msg = hostname;
1096 }
1097 handshake.buf = msg;
1098 } else {
1099 string emgmsg;
1100 Base::TlvAppend(emgmsg, TAG_EMGMSG, msg);
1101 Base::TlvAppend(emgmsg, TAG_DEVNAME, hostname);
1102 Base::TlvAppend(emgmsg, TAG_DAEOMN_AUTHSTATUS, daemonAuthResult);
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 } // namespace Hdc
1135