//native Handle:json_deep_copy(Handle:hObj); static cell_t Native_json_deep_copy(IPluginContext *pContext, const cell_t *params) { HandleError err; HandleSecurity sec; sec.pOwner = NULL; sec.pIdentity = myself->GetIdentity(); // Param 1: hObj json_t *object; Handle_t hndlObject = static_cast<Handle_t>(params[1]); if ((err=g_pHandleSys->ReadHandle(hndlObject, htJanssonObject, &sec, (void **)&object)) != HandleError_None) { pContext->ThrowNativeError("Invalid <JSON Object> handle %x (error %d)", hndlObject, err); return BAD_HANDLE; } if(object == NULL) { pContext->ThrowNativeError("JSON Object is NULL."); return BAD_HANDLE; } json_t *copy = json_deep_copy(object); if(copy == NULL) { pContext->ThrowNativeError("Could not deep copy JSON Object."); return BAD_HANDLE; } Handle_t hndlResult = g_pHandleSys->CreateHandle(htJanssonObject, copy, pContext->GetIdentity(), myself->GetIdentity(), NULL); if(hndlResult == BAD_HANDLE) { pContext->ThrowNativeError("Could not create handle for copied JSON Object."); } return hndlResult; }
void http_request_json_async(const http_json_request *request, void (*callback)(http_json_response*)) { struct TempThreadArgs { http_json_request request; void (*callback)(http_json_response*); }; TempThreadArgs *args = (TempThreadArgs*)malloc(sizeof(TempThreadArgs)); args->request.url = _strdup(request->url); args->request.method = request->method; args->request.body = json_deep_copy(request->body); args->request.tag = request->tag; args->callback = callback; SDL_Thread *thread = SDL_CreateThread([](void *ptr) -> int { TempThreadArgs *args = (TempThreadArgs*)ptr; http_json_response *response = http_request_json(&args->request); args->callback(response); free((char*)args->request.url); json_decref((json_t*)args->request.body); free(args); return 0; }, NULL, args); if (thread == NULL) { log_error("Unable to create thread!"); callback(NULL); } else { SDL_DetachThread(thread); } }
void LSCompiler::processExecutableConfig(AssemblyBuilder *ab) { lmAssert(loomConfigJSON, "loomConfigJSON not initialized"); utHashTable<utHashedString, utString> defs; for (UTsize i = 0; i < LSLuaState::getNumCommandlineArgs(); i++) { const char *arg = LSLuaState::getCommandlineArg(i).c_str(); if ((strlen(arg) >= 3) && (arg[0] == '-') && (arg[1] == 'D')) { char key[1024]; char value[1024]; lmAssert(strlen(arg) < 1023, "argument buffer overflow"); key[0] = value[0] = 0; strcpy(key, &arg[2]); if (strstr(arg, "=")) { key[strstr(arg, "=") - arg - 2] = 0; strcpy(value, strstr(arg, "=") + 1); } // value defaults to true if (!value[0]) { sprintf(value, "true"); } defs.insert(key, value); } } // Add command line defines to config json_t *json = json_deep_copy(loomConfigJSON); utHashTable<utHashedString, utString>::Iterator itr = defs.iterator(); while (itr.hasMoreElements()) { const char *key = itr.peekNextKey().str().c_str(); const char *value = itr.peekNextValue().c_str(); json_object_set_new(json, key, json_string(value)); itr.next(); } const char *out = json_dumps(json, JSON_INDENT(3) | JSON_COMPACT); ab->setLoomConfig(out); }
int CCPomelo::notify(const char*route,json_t *msg,CCObject* pTarget, SEL_CallFuncND pSelector){ pc_notify_t *notify = pc_notify_new(); CCPomeloContent_ *content = new CCPomeloContent_; content->pTarget = pTarget; content->pSelector = pSelector; notify_content[notify] = content; return pc_notify(client,notify, route, json_deep_copy(msg), cc_pomelo_on_notify_cb); }
int CCPomelo::request(const char*route,json_t *msg,CCObject* pTarget, SEL_CallFuncND pSelector){ pc_request_t *req = pc_request_new(); CCPomeloContent_ *content = new CCPomeloContent_; content->pTarget = pTarget; content->pSelector = pSelector; request_content[req] = content; return pc_request(client,req, route, json_deep_copy(msg), cc_pomelo_on_request_cb); }
/* * parse and (optionally) decrypt a JSON Web Token */ apr_byte_t oidc_jwt_parse(apr_pool_t *pool, const char *input_json, oidc_jwt_t **j_jwt, apr_hash_t *keys, oidc_jose_error_t *err) { cjose_err cjose_err; char *s_json = NULL; if (oidc_jwe_decrypt(pool, input_json, keys, &s_json, err, FALSE) == FALSE) return FALSE; *j_jwt = oidc_jwt_new(pool, FALSE, FALSE); oidc_jwt_t *jwt = *j_jwt; jwt->cjose_jws = cjose_jws_import(s_json, strlen(s_json), &cjose_err); if (jwt->cjose_jws == NULL) { oidc_jose_error(err, "cjose_jws_import failed: %s", oidc_cjose_e2s(pool, cjose_err)); oidc_jwt_destroy(jwt); *j_jwt = NULL; return FALSE; } cjose_header_t *hdr = cjose_jws_get_protected(jwt->cjose_jws); jwt->header.value.json = json_deep_copy((json_t *)hdr); char *str = json_dumps(jwt->header.value.json, JSON_PRESERVE_ORDER | JSON_COMPACT); jwt->header.value.str = apr_pstrdup(pool, str); free(str); jwt->header.alg = apr_pstrdup(pool, cjose_header_get(hdr, CJOSE_HDR_ALG, &cjose_err)); jwt->header.enc = apr_pstrdup(pool, cjose_header_get(hdr, CJOSE_HDR_ENC, &cjose_err)); jwt->header.kid = apr_pstrdup(pool, cjose_header_get(hdr, CJOSE_HDR_KID, &cjose_err)); uint8_t *plaintext = NULL; size_t plaintext_len = 0; if (cjose_jws_get_plaintext(jwt->cjose_jws, &plaintext, &plaintext_len, &cjose_err) == FALSE) { oidc_jose_error(err, "cjose_jws_get_plaintext failed: %s", oidc_cjose_e2s(pool, cjose_err)); return FALSE; } if (oidc_jose_parse_payload(pool, (const char *) plaintext, plaintext_len, &jwt->payload, err) == FALSE) { oidc_jwt_destroy(jwt); *j_jwt = NULL; } return TRUE; }
static json_t *json_array_deep_copy(json_t *array) { json_t *result; unsigned int i; result = json_array(); if(!result) return NULL; for(i = 0; i < json_array_size(array); i++) json_array_append_new(result, json_deep_copy(json_array_get(array, i))); return result; }
static bool alg_wrap_unw(const jose_hook_alg_t *alg, jose_cfg_t *cfg, const json_t *jwe, const json_t *rcp, const json_t *jwk, json_t *cek) { const json_t *epk = NULL; json_auto_t *exc = NULL; json_auto_t *der = NULL; json_auto_t *hdr = NULL; const char *wrap = NULL; hdr = jose_jwe_hdr(jwe, rcp); epk = json_object_get(hdr, "epk"); if (!hdr || !epk) return false; /* If the JWK has a private key, perform the normal exchange. */ if (json_object_get(jwk, "d")) { const jose_hook_alg_t *ecdh = NULL; ecdh = jose_hook_alg_find(JOSE_HOOK_ALG_KIND_EXCH, "ECDH"); if (!ecdh) return false; exc = ecdh->exch.exc(ecdh, cfg, jwk, epk); /* Otherwise, allow external exchanges. */ } else if (json_equal(json_object_get(jwk, "crv"), json_object_get(epk, "crv"))) { exc = json_deep_copy(jwk); } if (!exc) return false; der = derive(alg, cfg, hdr, cek, exc); if (!der) return false; wrap = strchr(alg->name, '+'); if (wrap) { const jose_hook_alg_t *kw = NULL; kw = jose_hook_alg_find(JOSE_HOOK_ALG_KIND_WRAP, &wrap[1]); if (!kw) return false; return kw->wrap.unw(kw, cfg, jwe, rcp, der, cek); } return json_object_update(cek, der) == 0; }
void http_request_async(const http_request_t *request, void (*callback)(http_response_t*)) { struct TempThreadArgs { http_request_t request; void (*callback)(http_response_t*); }; TempThreadArgs *args = (TempThreadArgs*)malloc(sizeof(TempThreadArgs)); args->request.url = _strdup(request->url); args->request.method = request->method; if (request->type == HTTP_DATA_JSON) { args->request.root = json_deep_copy(request->root); } else { char* bodyCopy = (char*) malloc(request->size); memcpy(bodyCopy, request->body, request->size); args->request.body = bodyCopy; } args->request.type = request->type; args->request.size = request->size; args->request.tag = request->tag; args->callback = callback; SDL_Thread *thread = SDL_CreateThread([](void *ptr) -> sint32 { TempThreadArgs *args2 = (TempThreadArgs*)ptr; http_response_t *response = http_request(&args2->request); args2->callback(response); free((char*)args2->request.url); if (args2->request.type == HTTP_DATA_JSON) { json_decref((json_t*) args2->request.root); } else { free(args2->request.body); } free(args2); return 0; }, NULL, args); if (thread == NULL) { log_error("Unable to create thread!"); callback(NULL); } else { SDL_DetachThread(thread); } }
HttpRequest2(const HttpRequest2 &request) { Tag = request.Tag; Method = request.Method; Url = request.Url; Type = request.Type; Size = request.Size; if (request.Type == HTTP_DATA_JSON) { Body.Json = json_deep_copy(request.Body.Json); } else { Body.Buffer = new char[request.Size]; memcpy(Body.Buffer, request.Body.Buffer, request.Size); } }
explicit HttpRequest2(const http_request_t * request) { Tag = request->tag; Method = std::string(request->method); Url = std::string(request->url); Type = request->type; Size = request->size; if (request->type == HTTP_DATA_JSON) { Body.Json = json_deep_copy(request->root); } else { Body.Buffer = new char[request->size]; memcpy(Body.Buffer, request->body, request->size); } }
int teamd_config_actual_dump(struct teamd_context *ctx, char **p_config_dump) { json_t *actual_json; struct teamd_port *tdport; json_t *ports_obj; void *iter; char *dump; int err; actual_json = json_deep_copy(ctx->config_json); if (!actual_json) return -ENOMEM; /* * Create json objects for all present ports */ teamd_for_each_tdport(tdport, ctx) { err = get_port_obj(NULL, actual_json, tdport->ifname); if (err) goto errout; }
static json_t *json_object_deep_copy(json_t *object) { json_t *result; void *iter; result = json_object(); if(!result) return NULL; iter = json_object_iter(object); while(iter) { const char *key; json_t *value; key = json_object_iter_key(iter); value = json_object_iter_value(iter); json_object_set_new_nocheck(result, key, json_deep_copy(value)); iter = json_object_iter_next(object, iter); } return result; }
static int _nd_accum_recursively_build_json(nd_accum_t a, json_t *j_rows, json_t *j_row, int axis_idx, int offset) { int i, j, idx, next_offset; json_t *x; json_t *j_row_next; nd_axis_struct *axis; int result; result = 0; /* define the current axis */ axis = a->axes + axis_idx; /* terminate recursion */ if (axis_idx == a->ndim) { double d; d = _arb_get_d(a->data + offset); if (j_row) { j_row_next = json_deep_copy(j_row); x = json_real(d); json_array_append_new(j_row_next, x); } else { j_row_next = json_pack("[f]", d); } json_array_append_new(j_rows, j_row_next); return result; } if (axis->agg_weights) { /* skip aggregated axes */ next_offset = offset; result = _nd_accum_recursively_build_json( a, j_rows, j_row, axis_idx+1, next_offset); } else { /* add selections to the row, and update the offset */ for (i = 0; i < axis->k; i++) { idx = axis->selection[i]; if (j_row) { j_row_next = json_deep_copy(j_row); } else { j_row_next = json_array(); } if (axis->component_axes != NULL) { for (j = 0; j < axis->component_axis_count; j++) { int component_idx; component_idx = axis->component_axes[j].indices[i]; x = json_integer(component_idx); json_array_append_new(j_row_next, x); } } else { x = json_integer(idx); json_array_append_new(j_row_next, x); } next_offset = offset + idx * a->strides[axis_idx]; result = _nd_accum_recursively_build_json( a, j_rows, j_row_next, axis_idx+1, next_offset); if (result) return result; json_decref(j_row_next); } } return result; }
static json_t *GET_JSON_OBJECT( const json_t *root, const std::string key ) { json_t *obj = json_object_get( root, key.c_str() ); return json_deep_copy(obj); };
struct ast_json *ast_json_deep_copy(const struct ast_json *value) { return (struct ast_json *)json_deep_copy((json_t *)value); }
static void spawn_command( const std::shared_ptr<w_root_t>& root, struct watchman_trigger_command* cmd, w_query_res* res, struct w_clockspec* since_spec) { char **envp = NULL; uint32_t i = 0; int ret; char **argv = NULL; uint32_t env_size; posix_spawn_file_actions_t actions; posix_spawnattr_t attr; #ifndef _WIN32 sigset_t mask; #endif long arg_max; size_t argspace_remaining; bool file_overflow = false; int result_log_level; w_string_t *working_dir = NULL; #ifdef _WIN32 arg_max = 32*1024; #else arg_max = sysconf(_SC_ARG_MAX); #endif if (arg_max <= 0) { argspace_remaining = UINT_MAX; } else { argspace_remaining = (uint32_t)arg_max; } // Allow some misc working overhead argspace_remaining -= 32; // Record an overflow before we call prepare_stdin(), which mutates // and resizes the results to fit the specified limit. if (cmd->max_files_stdin > 0 && res->resultsArray.array().size() > cmd->max_files_stdin) { file_overflow = true; } auto stdin_file = prepare_stdin(cmd, res); if (!stdin_file) { w_log( W_LOG_ERR, "trigger %s:%s %s\n", root->root_path.c_str(), cmd->triggername.c_str(), strerror(errno)); return; } // Assumption: that only one thread will be executing on a given // cmd instance so that mutation of cmd->envht is safe. // This is guaranteed in the current architecture. // It is way too much of a hassle to try to recreate the clock value if it's // not a relative clock spec, and it's only going to happen on the first run // anyway, so just skip doing that entirely. if (since_spec && since_spec->tag == w_cs_clock) { w_envp_set_cstring( cmd->envht, "WATCHMAN_SINCE", since_spec->clock.position.toClockString().c_str()); } else { w_envp_unset(cmd->envht, "WATCHMAN_SINCE"); } w_envp_set_cstring( cmd->envht, "WATCHMAN_CLOCK", res->clockAtStartOfQuery.toClockString().c_str()); if (cmd->query->relative_root) { w_envp_set(cmd->envht, "WATCHMAN_RELATIVE_ROOT", cmd->query->relative_root); } else { w_envp_unset(cmd->envht, "WATCHMAN_RELATIVE_ROOT"); } // Compute args auto args = json_deep_copy(cmd->command); if (cmd->append_files) { // Measure how much space the base args take up for (i = 0; i < json_array_size(args); i++) { const char *ele = json_string_value(json_array_get(args, i)); argspace_remaining -= strlen(ele) + 1 + sizeof(char*); } // Dry run with env to compute space envp = w_envp_make_from_ht(cmd->envht, &env_size); free(envp); envp = NULL; argspace_remaining -= env_size; for (const auto& item : res->dedupedFileNames) { // also: NUL terminator and entry in argv uint32_t size = item.size() + 1 + sizeof(char*); if (argspace_remaining < size) { file_overflow = true; break; } argspace_remaining -= size; json_array_append_new(args, w_string_to_json(item)); } } argv = w_argv_copy_from_json(args, 0); args = nullptr; w_envp_set_bool(cmd->envht, "WATCHMAN_FILES_OVERFLOW", file_overflow); envp = w_envp_make_from_ht(cmd->envht, &env_size); posix_spawnattr_init(&attr); #ifndef _WIN32 sigemptyset(&mask); posix_spawnattr_setsigmask(&attr, &mask); #endif posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGMASK| #ifdef POSIX_SPAWN_CLOEXEC_DEFAULT // Darwin: close everything except what we put in file actions POSIX_SPAWN_CLOEXEC_DEFAULT| #endif POSIX_SPAWN_SETPGROUP); posix_spawn_file_actions_init(&actions); #ifndef _WIN32 posix_spawn_file_actions_adddup2( &actions, stdin_file->getFileDescriptor(), STDIN_FILENO); #else posix_spawn_file_actions_adddup2_handle_np( &actions, stdin_file->getWindowsHandle(), STDIN_FILENO); #endif if (cmd->stdout_name) { posix_spawn_file_actions_addopen(&actions, STDOUT_FILENO, cmd->stdout_name, cmd->stdout_flags, 0666); } else { posix_spawn_file_actions_adddup2(&actions, STDOUT_FILENO, STDOUT_FILENO); } if (cmd->stderr_name) { posix_spawn_file_actions_addopen(&actions, STDERR_FILENO, cmd->stderr_name, cmd->stderr_flags, 0666); } else { posix_spawn_file_actions_adddup2(&actions, STDERR_FILENO, STDERR_FILENO); } // Figure out the appropriate cwd { const char *cwd = NULL; working_dir = NULL; if (cmd->query->relative_root) { working_dir = cmd->query->relative_root; } else { working_dir = root->root_path; } w_string_addref(working_dir); json_unpack(cmd->definition, "{s:s}", "chdir", &cwd); if (cwd) { w_string_t *cwd_str = w_string_new_typed(cwd, W_STRING_BYTE); if (w_is_path_absolute_cstr(cwd)) { w_string_delref(working_dir); working_dir = cwd_str; } else { w_string_t *joined; joined = w_string_path_cat(working_dir, cwd_str); w_string_delref(cwd_str); w_string_delref(working_dir); working_dir = joined; } } w_log(W_LOG_DBG, "using %.*s for working dir\n", working_dir->len, working_dir->buf); } #ifndef _WIN32 // This mutex is present to avoid fighting over the cwd when multiple // triggers run at the same time. It doesn't coordinate with all // possible chdir() calls, but this is the only place that we do this // in the watchman server process. static std::mutex cwdMutex; { std::unique_lock<std::mutex> lock(cwdMutex); ignore_result(chdir(working_dir->buf)); #else posix_spawnattr_setcwd_np(&attr, working_dir->buf); #endif w_string_delref(working_dir); working_dir = nullptr; ret = posix_spawnp(&cmd->current_proc, argv[0], &actions, &attr, argv, envp); if (ret != 0) { // On Darwin (at least), posix_spawn can fail but will still populate the // pid. Since we use the pid to gate future spawns, we need to ensure // that we clear out the pid on failure, otherwise the trigger would be // effectively disabled for the rest of the watch lifetime cmd->current_proc = 0; } #ifndef _WIN32 ignore_result(chdir("/")); } #endif // If failed, we want to make sure we log enough info to figure out why result_log_level = res == 0 ? W_LOG_DBG : W_LOG_ERR; w_log(result_log_level, "posix_spawnp: %s\n", cmd->triggername.c_str()); for (i = 0; argv[i]; i++) { w_log(result_log_level, "argv[%d] %s\n", i, argv[i]); } for (i = 0; envp[i]; i++) { w_log(result_log_level, "envp[%d] %s\n", i, envp[i]); } w_log( result_log_level, "trigger %s:%s pid=%d ret=%d %s\n", root->root_path.c_str(), cmd->triggername.c_str(), (int)cmd->current_proc, ret, strerror(ret)); free(argv); free(envp); posix_spawnattr_destroy(&attr); posix_spawn_file_actions_destroy(&actions); }
/* * resolve and validate an access_token against the configured Authorization Server */ static apr_byte_t oidc_oauth_resolve_access_token(request_rec *r, oidc_cfg *c, const char *access_token, json_t **token, char **response) { json_t *result = NULL; const char *json = NULL; /* see if we've got the claims for this access_token cached already */ c->cache->get(r, OIDC_CACHE_SECTION_ACCESS_TOKEN, access_token, &json); if (json == NULL) { /* not cached, go out and validate the access_token against the Authorization server and get the JSON claims back */ if (oidc_oauth_validate_access_token(r, c, access_token, &json) == FALSE) { oidc_error(r, "could not get a validation response from the Authorization server"); return FALSE; } /* decode and see if it is not an error response somehow */ if (oidc_util_decode_json_and_check_error(r, json, &result) == FALSE) return FALSE; json_t *active = json_object_get(result, "active"); if (active != NULL) { if ((!json_is_boolean(active)) || (!json_is_true(active))) { oidc_debug(r, "no \"active\" boolean object with value \"true\" found in response JSON object"); json_decref(result); return FALSE; } json_t *exp = json_object_get(result, "exp"); if ((exp != NULL) && (json_is_number(exp))) { /* set it in the cache so subsequent request don't need to validate the access_token and get the claims anymore */ c->cache->set(r, OIDC_CACHE_SECTION_ACCESS_TOKEN, access_token, json, apr_time_from_sec(json_integer_value(exp))); } else if (json_integer_value(exp) <= 0) { oidc_debug(r, "response JSON object did not contain an \"exp\" integer number; introspection result will not be cached"); } } else { /* assume PingFederate validation: get and check the expiry timestamp */ json_t *expires_in = json_object_get(result, "expires_in"); if ((expires_in == NULL) || (!json_is_number(expires_in))) { oidc_error(r, "response JSON object did not contain an \"expires_in\" number"); json_decref(result); return FALSE; } if (json_integer_value(expires_in) <= 0) { oidc_warn(r, "\"expires_in\" number <= 0 (%" JSON_INTEGER_FORMAT "); token already expired...", json_integer_value(expires_in)); json_decref(result); return FALSE; } /* set it in the cache so subsequent request don't need to validate the access_token and get the claims anymore */ c->cache->set(r, OIDC_CACHE_SECTION_ACCESS_TOKEN, access_token, json, apr_time_now() + apr_time_from_sec(json_integer_value(expires_in))); } } else { /* we got the claims for this access_token in our cache, decode it in to a JSON structure */ json_error_t json_error; result = json_loads(json, 0, &json_error); if (result == NULL) { oidc_error(r, "cached JSON was corrupted: %s", json_error.text); return FALSE; } } /* return the access_token JSON object */ json_t *tkn = json_object_get(result, "access_token"); if ((tkn != NULL) && (json_is_object(tkn))) { /* * assume PingFederate validation: copy over those claims from the access_token * that are relevant for authorization purposes */ json_object_set(tkn, "client_id", json_object_get(result, "client_id")); json_object_set(tkn, "scope", json_object_get(result, "scope")); //oidc_oauth_spaced_string_to_array(r, result, "scope", tkn, "scopes"); /* return only the pimped access_token results */ *token = json_deep_copy(tkn); char *s_token = json_dumps(*token, 0); *response = apr_pstrdup(r->pool, s_token); free(s_token); json_decref(result); } else { //oidc_oauth_spaced_string_to_array(r, result, "scope", result, "scopes"); /* assume spec compliant introspection */ *token = result; *response = apr_pstrdup(r->pool, json); } return TRUE; }
static void spawn_command(w_root_t *root, struct watchman_trigger_command *cmd, w_query_res *res, struct w_clockspec *since_spec) { char **envp = NULL; uint32_t i = 0; int ret; int stdin_fd = -1; json_t *args; char **argv = NULL; uint32_t env_size; posix_spawn_file_actions_t actions; posix_spawnattr_t attr; sigset_t mask; long arg_max; uint32_t argspace_remaining; bool file_overflow = false; int result_log_level; char clockbuf[128]; const char *cwd = NULL; arg_max = sysconf(_SC_ARG_MAX); if (arg_max <= 0) { argspace_remaining = UINT_MAX; } else { argspace_remaining = (uint32_t)arg_max; } // Allow some misc working overhead argspace_remaining -= 32; stdin_fd = prepare_stdin(cmd, res); // Assumption: that only one thread will be executing on a given // cmd instance so that mutation of cmd->envht is safe. // This is guaranteed in the current architecture. if (cmd->max_files_stdin > 0 && res->num_results > cmd->max_files_stdin) { file_overflow = true; } // It is way too much of a hassle to try to recreate the clock value if it's // not a relative clock spec, and it's only going to happen on the first run // anyway, so just skip doing that entirely. if (since_spec && since_spec->tag == w_cs_clock && clock_id_string(since_spec->clock.root_number, since_spec->clock.ticks, clockbuf, sizeof(clockbuf))) { w_envp_set_cstring(cmd->envht, "WATCHMAN_SINCE", clockbuf); } else { w_envp_unset(cmd->envht, "WATCHMAN_SINCE"); } if (clock_id_string(res->root_number, res->ticks, clockbuf, sizeof(clockbuf))) { w_envp_set_cstring(cmd->envht, "WATCHMAN_CLOCK", clockbuf); } else { w_envp_unset(cmd->envht, "WATCHMAN_CLOCK"); } if (cmd->query->relative_root) { w_envp_set(cmd->envht, "WATCHMAN_RELATIVE_ROOT", cmd->query->relative_root); } else { w_envp_unset(cmd->envht, "WATCHMAN_RELATIVE_ROOT"); } // Compute args args = json_deep_copy(cmd->command); if (cmd->append_files) { // Measure how much space the base args take up for (i = 0; i < json_array_size(args); i++) { const char *ele = json_string_value(json_array_get(args, i)); argspace_remaining -= strlen(ele) + 1 + sizeof(char*); } // Dry run with env to compute space envp = w_envp_make_from_ht(cmd->envht, &env_size); free(envp); envp = NULL; argspace_remaining -= env_size; for (i = 0; i < res->num_results; i++) { // also: NUL terminator and entry in argv uint32_t size = res->results[i].relname->len + 1 + sizeof(char*); if (argspace_remaining < size) { file_overflow = true; break; } argspace_remaining -= size; json_array_append_new( args, json_string_nocheck(res->results[i].relname->buf) ); } } argv = w_argv_copy_from_json(args, 0); json_decref(args); args = NULL; w_envp_set_bool(cmd->envht, "WATCHMAN_FILES_OVERFLOW", file_overflow); envp = w_envp_make_from_ht(cmd->envht, &env_size); posix_spawnattr_init(&attr); sigemptyset(&mask); posix_spawnattr_setsigmask(&attr, &mask); posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGMASK| #ifdef POSIX_SPAWN_CLOEXEC_DEFAULT // Darwin: close everything except what we put in file actions POSIX_SPAWN_CLOEXEC_DEFAULT| #endif POSIX_SPAWN_SETPGROUP); posix_spawn_file_actions_init(&actions); posix_spawn_file_actions_adddup2(&actions, stdin_fd, STDIN_FILENO); if (cmd->stdout_name) { posix_spawn_file_actions_addopen(&actions, STDOUT_FILENO, cmd->stdout_name, cmd->stdout_flags, 0666); } else { posix_spawn_file_actions_adddup2(&actions, STDOUT_FILENO, STDOUT_FILENO); } if (cmd->stderr_name) { posix_spawn_file_actions_addopen(&actions, STDERR_FILENO, cmd->stderr_name, cmd->stderr_flags, 0666); } else { posix_spawn_file_actions_adddup2(&actions, STDERR_FILENO, STDERR_FILENO); } pthread_mutex_lock(&spawn_lock); if (cmd->query->relative_root) { ignore_result(chdir(cmd->query->relative_root->buf)); } else { ignore_result(chdir(root->root_path->buf)); } json_unpack(cmd->definition, "{s:s}", "chdir", &cwd); if (cwd) { ignore_result(chdir(cwd)); } ret = posix_spawnp(&cmd->current_proc, argv[0], &actions, &attr, argv, envp); if (ret == 0) { w_root_addref(root); insert_running_pid(cmd->current_proc, root); } else { // On Darwin (at least), posix_spawn can fail but will still populate the // pid. Since we use the pid to gate future spawns, we need to ensure // that we clear out the pid on failure, otherwise the trigger would be // effectively disabled for the rest of the watch lifetime cmd->current_proc = 0; } ignore_result(chdir("/")); pthread_mutex_unlock(&spawn_lock); // If failed, we want to make sure we log enough info to figure out why result_log_level = res == 0 ? W_LOG_DBG : W_LOG_ERR; w_log(result_log_level, "posix_spawnp:\n"); for (i = 0; argv[i]; i++) { w_log(result_log_level, "argv[%d] %s\n", i, argv[i]); } for (i = 0; envp[i]; i++) { w_log(result_log_level, "envp[%d] %s\n", i, envp[i]); } w_log(result_log_level, "trigger %.*s:%s pid=%d ret=%d %s\n", (int)root->root_path->len, root->root_path->buf, cmd->triggername->buf, (int)cmd->current_proc, ret, strerror(ret)); free(argv); free(envp); posix_spawnattr_destroy(&attr); posix_spawn_file_actions_destroy(&actions); if (stdin_fd != -1) { close(stdin_fd); } }
/* * resolve and validate an access_token against the configured Authorization Server */ static apr_byte_t oidc_oauth_resolve_access_token(request_rec *r, oidc_cfg *c, const char *access_token, json_t **token, char **response) { json_t *result = NULL; const char *json = NULL; /* see if we've got the claims for this access_token cached already */ c->cache->get(r, OIDC_CACHE_SECTION_ACCESS_TOKEN, access_token, &json); if (json == NULL) { /* not cached, go out and validate the access_token against the Authorization server and get the JSON claims back */ if (oidc_oauth_validate_access_token(r, c, access_token, &json) == FALSE) { oidc_error(r, "could not get a validation response from the Authorization server"); return FALSE; } /* decode and see if it is not an error response somehow */ if (oidc_util_decode_json_and_check_error(r, json, &result) == FALSE) return FALSE; json_t *active = json_object_get(result, "active"); apr_time_t cache_until; if (active != NULL) { if (json_is_boolean(active)) { if (!json_is_true(active)) { oidc_debug(r, "\"active\" boolean object with value \"false\" found in response JSON object"); json_decref(result); return FALSE; } } else if (json_is_string(active)) { if (apr_strnatcasecmp(json_string_value(active), "true") != 0) { oidc_debug(r, "\"active\" string object with value that is not equal to \"true\" found in response JSON object: %s", json_string_value(active)); json_decref(result); return FALSE; } } else { oidc_debug(r, "no \"active\" boolean or string object found in response JSON object"); json_decref(result); return FALSE; } if (oidc_oauth_parse_and_cache_token_expiry(r, c, result, "exp", TRUE, FALSE, &cache_until) == FALSE) { json_decref(result); return FALSE; } /* set it in the cache so subsequent request don't need to validate the access_token and get the claims anymore */ c->cache->set(r, OIDC_CACHE_SECTION_ACCESS_TOKEN, access_token, json, cache_until); } else { if (oidc_oauth_parse_and_cache_token_expiry(r, c, result, c->oauth.introspection_token_expiry_claim_name, apr_strnatcmp( c->oauth.introspection_token_expiry_claim_format, "absolute") == 0, c->oauth.introspection_token_expiry_claim_required, &cache_until) == FALSE) { json_decref(result); return FALSE; } /* set it in the cache so subsequent request don't need to validate the access_token and get the claims anymore */ c->cache->set(r, OIDC_CACHE_SECTION_ACCESS_TOKEN, access_token, json, cache_until); } } else { /* we got the claims for this access_token in our cache, decode it in to a JSON structure */ json_error_t json_error; result = json_loads(json, 0, &json_error); if (result == NULL) { oidc_error(r, "cached JSON was corrupted: %s", json_error.text); return FALSE; } } /* return the access_token JSON object */ json_t *tkn = json_object_get(result, "access_token"); if ((tkn != NULL) && (json_is_object(tkn))) { /* * assume PingFederate validation: copy over those claims from the access_token * that are relevant for authorization purposes */ json_object_set(tkn, "client_id", json_object_get(result, "client_id")); json_object_set(tkn, "scope", json_object_get(result, "scope")); //oidc_oauth_spaced_string_to_array(r, result, "scope", tkn, "scopes"); /* return only the pimped access_token results */ *token = json_deep_copy(tkn); char *s_token = json_dumps(*token, 0); *response = apr_pstrdup(r->pool, s_token); free(s_token); json_decref(result); } else { //oidc_oauth_spaced_string_to_array(r, result, "scope", result, "scopes"); /* assume spec compliant introspection */ *token = result; *response = apr_pstrdup(r->pool, json); } return TRUE; }
json_t* maybe_deep(json_t* json) { if (by_value) {return json_deep_copy(json);} return json; }
la_codec_value_t *la_codec_deep_copy(la_codec_value_t *value) { return (la_codec_value_t *) json_deep_copy((json_t *) value); }