| 1472 | } |
| 1473 | |
| 1474 | static bool activation_source_open(const char *path, activation_native_file_t *file_out) { |
| 1475 | *file_out = ACTIVATION_INVALID_FILE; |
| 1476 | char *directory = NULL; |
| 1477 | char *name = NULL; |
| 1478 | if (!activation_target_parts(path, &directory, &name)) { |
| 1479 | return false; |
| 1480 | } |
| 1481 | #ifdef _WIN32 |
| 1482 | activation_file_identity_t directory_identity; |
| 1483 | activation_file_identity_t expected; |
| 1484 | bool exists = false; |
| 1485 | bool src_dir_ok = activation_source_directory_secure(directory, &directory_identity); |
| 1486 | /* The source (a downloaded release bundle) follows the machine's |
| 1487 | * default-owner policy; its bytes are pinned by identity recheck plus the |
| 1488 | * staged copy's build-fingerprint validation, so a trusted owner |
| 1489 | * (user/Administrators/SYSTEM) is sufficient here. Targets keep the |
| 1490 | * exact-current-owner rule. */ |
| 1491 | bool snapshot_ok = |
| 1492 | src_dir_ok && activation_external_snapshot_with_owner(path, false, &exists, &expected); |
| 1493 | if (!src_dir_ok || !snapshot_ok || !exists) { |
| 1494 | free(directory); |
| 1495 | free(name); |
| 1496 | return false; |
| 1497 | } |
| 1498 | wchar_t *wide = activation_utf8_to_wide(path); |
| 1499 | if (!wide) { |
| 1500 | free(directory); |
| 1501 | free(name); |
| 1502 | return false; |
| 1503 | } |
| 1504 | HANDLE file = |
| 1505 | CreateFileW(wide, GENERIC_READ | FILE_READ_ATTRIBUTES | READ_CONTROL, |
| 1506 | FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, |
| 1507 | FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_SEQUENTIAL_SCAN, NULL); |
| 1508 | free(wide); |
| 1509 | activation_file_identity_t actual; |
| 1510 | activation_file_identity_t directory_now; |
| 1511 | bool valid = file != INVALID_HANDLE_VALUE && activation_windows_identity(file, &actual, true) && |
| 1512 | activation_windows_owner_is_trusted(file) && activation_windows_acl_secure(file) && |
| 1513 | activation_identity_equal(&actual, &expected) && |
| 1514 | activation_source_directory_secure(directory, &directory_now) && |
| 1515 | activation_identity_equal(&directory_now, &directory_identity); |
| 1516 | if (!valid) { |
| 1517 | if (file != INVALID_HANDLE_VALUE) { |
| 1518 | (void)CloseHandle(file); |
| 1519 | } |
| 1520 | free(directory); |
| 1521 | free(name); |
| 1522 | return false; |
| 1523 | } |
| 1524 | #else |
| 1525 | int directory_fd = -1; |
| 1526 | activation_file_identity_t directory_identity; |
| 1527 | if (!activation_directory_secure(directory, &directory_fd, &directory_identity)) { |
| 1528 | free(directory); |
| 1529 | free(name); |
| 1530 | return false; |
| 1531 | } |
no test coverage detected