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