| 2387 | } |
| 2388 | |
| 2389 | static cbm_daemon_runtime_application_status_t application_set_context( |
| 2390 | cbm_daemon_application_session_t *session, const uint8_t *request, uint32_t request_length) { |
| 2391 | if (session->context_set || request_length < APPLICATION_CONTEXT_HEADER_SIZE) { |
| 2392 | return CBM_DAEMON_RUNTIME_APPLICATION_REJECTED; |
| 2393 | } |
| 2394 | uint32_t root_length = application_get_u32(request + 1); |
| 2395 | bool allowed_present = request[5] == 1; |
| 2396 | uint32_t allowed_length = application_get_u32(request + 6); |
| 2397 | uint8_t profile_value = request[10]; |
| 2398 | uint32_t event_length = application_get_u32(request + 11); |
| 2399 | uint32_t dialect_length = application_get_u32(request + 15); |
| 2400 | uint64_t expected = (uint64_t)APPLICATION_CONTEXT_HEADER_SIZE + root_length + allowed_length + |
| 2401 | event_length + dialect_length; |
| 2402 | if (request[5] > 1 || root_length == 0 || expected != request_length || |
| 2403 | (!allowed_present && allowed_length != 0) || |
| 2404 | profile_value > (uint8_t)CBM_MCP_TOOL_PROFILE_SCOUT || |
| 2405 | (profile_value != (uint8_t)CBM_MCP_TOOL_PROFILE_ALL && |
| 2406 | (event_length != 0 || dialect_length != 0))) { |
| 2407 | return CBM_DAEMON_RUNTIME_APPLICATION_REJECTED; |
| 2408 | } |
| 2409 | cbm_mcp_tool_profile_t tool_profile = (cbm_mcp_tool_profile_t)profile_value; |
| 2410 | const uint8_t *payload = request + APPLICATION_CONTEXT_HEADER_SIZE; |
| 2411 | char *root = application_text_copy(request + APPLICATION_CONTEXT_HEADER_SIZE, root_length); |
| 2412 | char *allowed = |
| 2413 | allowed_present ? application_text_copy(payload + root_length, allowed_length) : NULL; |
| 2414 | char *hook_event = |
| 2415 | event_length ? application_text_copy(payload + root_length + allowed_length, event_length) |
| 2416 | : NULL; |
| 2417 | char *hook_dialect = |
| 2418 | dialect_length ? application_text_copy( |
| 2419 | payload + root_length + allowed_length + event_length, dialect_length) |
| 2420 | : NULL; |
| 2421 | if (!root || (allowed_present && !allowed) || (event_length && !hook_event) || |
| 2422 | (dialect_length && !hook_dialect) || |
| 2423 | !cbm_hook_augment_invocation_supported(hook_event, hook_dialect)) { |
| 2424 | free(root); |
| 2425 | free(allowed); |
| 2426 | free(hook_event); |
| 2427 | free(hook_dialect); |
| 2428 | return CBM_DAEMON_RUNTIME_APPLICATION_REJECTED; |
| 2429 | } |
| 2430 | char canonical_root[APPLICATION_PATH_CAP] = {0}; |
| 2431 | char canonical_allowed[APPLICATION_PATH_CAP] = {0}; |
| 2432 | bool canonical = cbm_canonical_path(root, canonical_root, sizeof(canonical_root)); |
| 2433 | if (canonical && allowed_present) { |
| 2434 | canonical = cbm_canonical_path(allowed, canonical_allowed, sizeof(canonical_allowed)); |
| 2435 | } |
| 2436 | canonical = canonical && application_canonical_directory_exists(canonical_root); |
| 2437 | bool set = |
| 2438 | canonical && cbm_mcp_server_set_session_context(session->mcp, canonical_root, |
| 2439 | allowed_present ? canonical_allowed : NULL); |
| 2440 | free(root); |
| 2441 | free(allowed); |
| 2442 | if (!set) { |
| 2443 | free(hook_event); |
| 2444 | free(hook_dialect); |
| 2445 | return CBM_DAEMON_RUNTIME_APPLICATION_REJECTED; |
| 2446 | } |
no test coverage detected