Example #1
0
//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;
}
Example #2
0
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);
	}
}
Example #3
0
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);
}
Example #4
0
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);
}
Example #5
0
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);
}
Example #6
0
/*
 * 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;
}
Example #7
0
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;
}
Example #8
0
File: ecdhes.c Project: simo5/jose
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;
}
Example #9
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);
    }
}
Example #10
0
 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);
     }
 }
Example #11
0
 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);
     }
 }
Example #12
0
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;
	}
Example #13
0
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;
}
Example #14
0
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;
}
Example #15
0
    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);

    };
Example #16
0
struct ast_json *ast_json_deep_copy(const struct ast_json *value)
{
	return (struct ast_json *)json_deep_copy((json_t *)value);
}
Example #17
0
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);
}
Example #18
0
/*
 * 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;
}
Example #19
0
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);
  }
}
Example #20
0
/*
 * 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;
}
Example #21
0
json_t* maybe_deep(json_t* json)
{
    if (by_value)
        {return json_deep_copy(json);}
    return json;
}
Example #22
0
la_codec_value_t *la_codec_deep_copy(la_codec_value_t *value)
{
    return (la_codec_value_t *) json_deep_copy((json_t *) value);
}