const char *readparamsvr(cmd_parms *cmd, void *cfg, const char *value) { mod_server_cfg *c = (mod_server_cfg*)cfg; int i; if(0 == apr_strnatcmp(cmd->directive->directive, STS_TIMEOUT)) { i = atoi(value); if(i >= 0) { c->stsTimeout = (unsigned int)i; } else { return apr_psprintf(cmd->pool, "MOD_SECURE_HEADERS: Invalid %s (%s) specified -- Must be 0 or greater", STS_TIMEOUT, value); } } else if(0 == apr_strnatcmp(cmd->directive->directive, STS_SUBDOMAINS)) { if(0 == apr_strnatcasecmp(value, "On")) { c->includeSubDomains = TRUE; } else if(0 == apr_strnatcasecmp(value, "Off")) { c->includeSubDomains = FALSE; } else { return apr_psprintf(cmd->pool, "MOD_SECURE_HEADERS: Invalid argument to %s - must be 'On' or 'Off'", STS_SUBDOMAINS); } } else { return apr_psprintf(cmd->pool, "MOD_SECURE_HEADERS: Invalid server directive '%s'", cmd->directive->directive); } return NULL; }
/* * parse the cache backend type */ const char *oidc_parse_cache_type(apr_pool_t *pool, const char *arg, oidc_cache_t **type) { static char *options[] = { OIDC_CACHE_TYPE_SHM, OIDC_CACHE_TYPE_MEMCACHE, #ifdef USE_LIBHIREDIS OIDC_CACHE_TYPE_REDIS, #endif OIDC_CACHE_TYPE_FILE, NULL }; const char *rv = oidc_valid_string_option(pool, arg, options); if (rv != NULL) return rv; if (apr_strnatcmp(arg, OIDC_CACHE_TYPE_SHM) == 0) { *type = &oidc_cache_shm; } else if (apr_strnatcmp(arg, OIDC_CACHE_TYPE_MEMCACHE) == 0) { *type = &oidc_cache_memcache; } else if (apr_strnatcmp(arg, OIDC_CACHE_TYPE_FILE) == 0) { *type = &oidc_cache_file; #ifdef USE_LIBHIREDIS } else if (apr_strnatcmp(arg, OIDC_CACHE_TYPE_REDIS) == 0) { *type = &oidc_cache_redis; #endif } return NULL; }
/* * parse a URL according to one of two schemes (NULL for any) */ static const char * oidc_valid_url_scheme(apr_pool_t *pool, const char *arg, const char *scheme1, const char *scheme2) { apr_uri_t uri; if (apr_uri_parse(pool, arg, &uri) != APR_SUCCESS) { return apr_psprintf(pool, "'%s' cannot be parsed as a URL", arg); } if (uri.scheme == NULL) { return apr_psprintf(pool, "'%s' cannot be parsed as a URL (no scheme set)", arg); } if ((scheme1 != NULL) && (apr_strnatcmp(uri.scheme, scheme1) != 0)) { if ((scheme2 != NULL) && (apr_strnatcmp(uri.scheme, scheme2) != 0)) { return apr_psprintf(pool, "'%s' cannot be parsed as a \"%s\" or \"%s\" URL (scheme == %s)!", arg, scheme1, scheme2, uri.scheme); } else if (scheme2 == NULL) { return apr_psprintf(pool, "'%s' cannot be parsed as a \"%s\" URL (scheme == %s)!", arg, scheme1, uri.scheme); } } if (uri.hostname == NULL) { return apr_psprintf(pool, "'%s' cannot be parsed as a valid URL (no hostname set, check your slashes)", arg); } return NULL; }
/* * parse the session mechanism type and the cookie persistency property */ const char *oidc_parse_session_type(apr_pool_t *pool, const char *arg, int *type, int *persistent) { static char *options[] = { OIDC_SESSION_TYPE_SERVER_CACHE_STR, OIDC_SESSION_TYPE_SERVER_CACHE_STR OIDC_SESSION_TYPE_SEPARATOR OIDC_SESSION_TYPE_PERSISTENT, OIDC_SESSION_TYPE_CLIENT_COOKIE_STR, OIDC_SESSION_TYPE_CLIENT_COOKIE_STR OIDC_SESSION_TYPE_SEPARATOR OIDC_SESSION_TYPE_PERSISTENT, NULL }; const char *rv = oidc_valid_string_option(pool, arg, options); if (rv != NULL) return rv; char *s = apr_pstrdup(pool, arg); char *p = strstr(s, OIDC_SESSION_TYPE_SEPARATOR); if (p) { *persistent = 1; *p = '\0'; } if (apr_strnatcmp(s, OIDC_SESSION_TYPE_SERVER_CACHE_STR) == 0) { *type = OIDC_SESSION_TYPE_SERVER_CACHE; } else if (apr_strnatcmp(s, OIDC_SESSION_TYPE_CLIENT_COOKIE_STR) == 0) { *type = OIDC_SESSION_TYPE_CLIENT_COOKIE; } return NULL; }
/* * Builds the session cookie from the given session ID and configuration. */ char * build_cookie(request_rec *r, mod_but_server_t *config, char *sid) { char *cookie = NULL; const char *cookiename = config->cookie_name; const char *domain = ""; const char *path = ""; const char *secure = ""; const char *httponly = ""; const char *expiration = ""; if (apr_strnatcmp(config->cookie_domain, "")) { domain = apr_psprintf(r->pool, "domain=%s; ", config->cookie_domain); } if (apr_strnatcmp(config->cookie_path, "")) { path = apr_psprintf(r->pool, "path=%s; ", config->cookie_path); } if (config->cookie_secure == 1) { secure = "secure; "; } if (config->cookie_httponly == 1) { httponly = "HttpOnly"; } if (apr_strnatcmp(config->cookie_expiration, "")) { expiration = apr_psprintf(r->pool, "expires=%s; ", config->cookie_expiration); } cookie = apr_psprintf(r->pool, "%s=%s; %s%s%s%s%s", cookiename, sid, domain, path, expiration, secure, httponly); ERRLOG_INFO("Built cookie string [%s]", cookie); return cookie; }
/* * parse a "set claims as" value from the provided string */ const char *oidc_parse_set_claims_as(apr_pool_t *pool, const char *arg, int *in_headers, int *in_env_vars) { static char *options[] = { OIDC_PASS_CLAIMS_AS_BOTH, OIDC_PASS_CLAIMS_AS_HEADERS, OIDC_PASS_CLAIMS_AS_ENV, OIDC_PASS_CLAIMS_AS_NONE, NULL }; const char *rv = oidc_valid_string_option(pool, arg, options); if (rv != NULL) return rv; if (apr_strnatcmp(arg, OIDC_PASS_CLAIMS_AS_BOTH) == 0) { *in_headers = 1; *in_env_vars = 1; } else if (apr_strnatcmp(arg, OIDC_PASS_CLAIMS_AS_HEADERS) == 0) { *in_headers = 1; *in_env_vars = 0; } else if (apr_strnatcmp(arg, OIDC_PASS_CLAIMS_AS_ENV) == 0) { *in_headers = 0; *in_env_vars = 1; } else if (apr_strnatcmp(arg, OIDC_PASS_CLAIMS_AS_NONE) == 0) { *in_headers = 0; *in_env_vars = 0; } return NULL; }
/* * return OpenSSL cipher for JWE encryption algorithm */ static const EVP_CIPHER *apr_jwe_enc_to_openssl_cipher(const char *enc) { if (apr_strnatcmp(enc, "A128CBC-HS256") == 0) { return EVP_aes_128_cbc(); } if (apr_strnatcmp(enc, "A256CBC-HS512") == 0) { return EVP_aes_256_cbc(); } return NULL; }
/* * return OpenSSL hash for JWE encryption algorithm */ static const EVP_MD *apr_jwe_enc_to_openssl_hash(const char *enc) { if (apr_strnatcmp(enc, "A128CBC-HS256") == 0) { return EVP_sha256(); } if (apr_strnatcmp(enc, "A256CBC-HS512") == 0) { return EVP_sha512(); } return NULL; }
/* * convert a "pass id token as" value to an integer */ static int oidc_parse_pass_idtoken_as_str2int(const char *v) { if (apr_strnatcmp(v, OIDC_PASS_ID_TOKEN_AS_CLAIMS_STR) == 0) return OIDC_PASS_IDTOKEN_AS_CLAIMS; if (apr_strnatcmp(v, OIDC_PASS_IDTOKEN_AS_PAYLOAD_STR) == 0) return OIDC_PASS_IDTOKEN_AS_PAYLOAD; if (apr_strnatcmp(v, OIDC_PASS_IDTOKEN_AS_SERIALIZED_STR) == 0) return OIDC_PASS_IDTOKEN_AS_SERIALIZED; return -1; }
/* * convert an "accept OAuth 2.0 token in" value to an integer */ static apr_byte_t oidc_parse_oauth_accept_token_in_str2byte(const char *v) { if (apr_strnatcmp(v, OIDC_OAUTH_ACCEPT_TOKEN_IN_HEADER_STR) == 0) return OIDC_OAUTH_ACCEPT_TOKEN_IN_HEADER; if (apr_strnatcmp(v, OIDC_OAUTH_ACCEPT_TOKEN_IN_POST_STR) == 0) return OIDC_OAUTH_ACCEPT_TOKEN_IN_POST; if (apr_strnatcmp(v, OIDC_OAUTH_ACCEPT_TOKEN_IN_QUERY_STR) == 0) return OIDC_OAUTH_ACCEPT_TOKEN_IN_QUERY; if (strstr(v, OIDC_OAUTH_ACCEPT_TOKEN_IN_COOKIE_STR) == v) return OIDC_OAUTH_ACCEPT_TOKEN_IN_COOKIE; return OIDC_OAUTH_ACCEPT_TOKEN_IN_DEFAULT; }
/* * parse the JSON client metadata in to a oidc_provider_t struct */ apr_byte_t oidc_metadata_client_parse(request_rec *r, oidc_cfg *cfg, json_t *j_client, oidc_provider_t *provider) { /* get a handle to the client_id we need to use for this provider */ oidc_json_object_get_string(r->pool, j_client, "client_id", &provider->client_id, NULL); /* get a handle to the client_secret we need to use for this provider */ oidc_json_object_get_string(r->pool, j_client, "client_secret", &provider->client_secret, NULL); /* see if the token endpoint auth method defined in the client metadata overrides the provider one */ char *token_endpoint_auth = NULL; oidc_json_object_get_string(r->pool, j_client, "token_endpoint_auth_method", &token_endpoint_auth, NULL); if (token_endpoint_auth != NULL) { if ((apr_strnatcmp(token_endpoint_auth, "client_secret_post") == 0) || (apr_strnatcmp(token_endpoint_auth, "client_secret_basic") == 0)) { provider->token_endpoint_auth = apr_pstrdup(r->pool, token_endpoint_auth); } else { oidc_warn(r, "unsupported client auth method \"%s\" in client metadata for entry \"token_endpoint_auth_method\"", token_endpoint_auth); } } /* determine the response type if not set by .conf */ if (provider->response_type == NULL) { provider->response_type = cfg->provider.response_type; /* "response_types" is an array in the client metadata as by spec */ json_t *j_response_types = json_object_get(j_client, "response_types"); if ((j_response_types != NULL) && (json_is_array(j_response_types))) { /* if there's an array we'll prefer the configured response_type if supported */ if (oidc_util_json_array_has_value(r, j_response_types, provider->response_type) == FALSE) { /* if the configured response_type is not supported, we'll fallback to the first one that is listed */ json_t *j_response_type = json_array_get(j_response_types, 0); if (json_is_string(j_response_type)) { provider->response_type = apr_pstrdup(r->pool, json_string_value(j_response_type)); } } } } return TRUE; }
/* * parse a userinfo token method string value to an integer */ const char *oidc_parse_userinfo_token_method(apr_pool_t *pool, const char *arg, int *int_value) { const char *rv = oidc_valid_userinfo_token_method(pool, arg); if (rv != NULL) return rv; if (apr_strnatcmp(arg, OIDC_USER_INFO_TOKEN_METHOD_HEADER_STR) == 0) *int_value = OIDC_USER_INFO_TOKEN_METHOD_HEADER; if (apr_strnatcmp(arg, OIDC_USER_INFO_TOKEN_METHOD_POST_STR) == 0) *int_value = OIDC_USER_INFO_TOKEN_METHOD_POST; return NULL; }
static const char * ftpd_dbm_cmd_dbmtype(cmd_parms *cmd, void *config, const char *arg) { ftpd_dbm_server_conf *conf = ap_get_module_config(cmd->server->module_config, &ftpd_dbm_module); conf->dbtype = apr_pstrdup(cmd->pool, arg); if (apr_strnatcmp(conf->dbtype, "default") && apr_strnatcmp(conf->dbtype, "DB") && apr_strnatcmp(conf->dbtype, "GDBM") && apr_strnatcmp(conf->dbtype, "SDBM") && apr_strnatcmp(conf->dbtype, "NDBM")) { return apr_pstrcat(cmd->pool, "Invalid FTPChrootDBMType: ", arg, NULL); } return NULL; }
/* * check a provided hash value (at_hash|c_hash) against a corresponding hash calculated for a specified value and algorithm */ static apr_byte_t oidc_proto_validate_hash(request_rec *r, const char *alg, const char *hash, const char *value, const char *type) { /* hash the provided access_token */ char *calc = NULL; unsigned int hash_len = 0; apr_jws_hash_string(r->pool, alg, value, &calc, &hash_len); /* calculate the base64url-encoded value of the hash */ char *encoded = NULL; oidc_base64url_encode(r, &encoded, calc, apr_jws_hash_length(alg) / 2, 1); /* compare the calculated hash against the provided hash */ if ((apr_strnatcmp(encoded, hash) != 0)) { oidc_error(r, "provided \"%s\" hash value (%s) does not match the calculated value (%s)", type, hash, encoded); return FALSE; } oidc_debug(r, "successfully validated the provided \"%s\" hash value (%s) against the calculated value (%s)", type, hash, encoded); return TRUE; }
dav_error *dbms_get_redirect_props(const dav_repos_db *d, dav_repos_resource *r) { dav_repos_query *q = NULL; dav_error *err = NULL; TRACE(); /* do nothing if we have already fetched redirect props */ if (r->redirect_lifetime && r->reftarget) { return NULL; } q = dbms_prepare(r->p, d->db, "SELECT lifetime, reftarget " "FROM redirectrefs WHERE resource_id = ?"); dbms_set_int(q, 1, r->serialno); if (dbms_execute(q) || (dbms_next(q) <=0)) { err = dav_new_error(r->p, HTTP_INTERNAL_SERVER_ERROR, 0, "DBMS error in reftargets lookup."); goto error; } if (0 == apr_strnatcmp(dbms_get_string(q, 1), "p")) r->redirect_lifetime = DAV_REDIRECTREF_PERMANENT; else r->redirect_lifetime = DAV_REDIRECTREF_TEMPORARY; r->reftarget = dbms_get_string(q, 2); error: dbms_query_destroy(q); return err; }
void cleaning_shm_from_expired_session(request_rec *r) { mod_but_server_t *config = ap_get_module_config(r->server->module_config, &but_module); int y; for (y = 0; y < MOD_BUT_SESSION_COUNT; y++) { mod_but_cookie *c = apr_rmm_addr_get(cs_rmm, off[y]); apr_time_t curtime = apr_time_now(); int tnow = (int)apr_time_sec(curtime); int tcreate = c->session_create_time; int tlastaccess = c->session_last_access_time; if (!apr_strnatcmp(c->session_name, config->cookie_name)) { if ((tnow - tcreate) > config->session_timeout) { ERRLOG_INFO("(SHM) Cleanup Task A: Delta between tnow and tcreate %d at shmoffset %d", tnow-tcreate, y); mod_but_delete_session(y, r); } else { if ((tnow - tlastaccess) > config->session_inactivity_timeout) { ERRLOG_INFO("(SHM) Cleanup Task B: Delta between tnow and tlastaccess %d at shmoffset %d", tnow-tlastaccess, y); mod_but_delete_session(y, r); } } } } }
static bool has_valid_session(request_rec *r, modauthopenid_config *s_cfg) { // test for valid session - if so, return DECLINED std::string session_id = ""; modauthopenid::get_session_id(r, std::string(s_cfg->cookie_name), session_id); if(session_id != "" && s_cfg->use_cookie) { modauthopenid::debug("found session_id in cookie: " + session_id); modauthopenid::session_t session; modauthopenid::SessionManager sm(std::string(s_cfg->db_location)); sm.get_session(session_id, session); sm.close(); // if session found if(std::string(session.identity) != "") { std::string uri_path; modauthopenid::base_dir(std::string(r->uri), uri_path); std::string valid_path(session.path); // if found session has a valid path if(valid_path == uri_path.substr(0, valid_path.size()) && apr_strnatcmp(session.hostname.c_str(), r->hostname)==0) { const char* idchar = std::string(session.identity).c_str(); APDEBUG(r, "setting REMOTE_USER to \"%s\"", idchar); r->user = apr_pstrdup(r->pool, idchar); return true; } else { APDEBUG(r, "session found for different path or hostname (cooke was for %s)", session.hostname.c_str()); } } } return false; };
/* * validate an access token against the validation endpoint of the Authorization server and gets a response back */ static int oidc_oauth_validate_access_token(request_rec *r, oidc_cfg *c, const char *token, const char **response) { /* get a handle to the directory config */ oidc_dir_cfg *dir_cfg = ap_get_module_config(r->per_dir_config, &auth_openidc_module); /* assemble parameters to call the token endpoint for validation */ apr_table_t *params = apr_table_make(r->pool, 4); /* add any configured extra static parameters to the introspection endpoint */ oidc_util_table_add_query_encoded_params(r->pool, params, c->oauth.introspection_endpoint_params); /* add the access_token itself */ apr_table_addn(params, "token", token); /* see if we want to do basic auth or post-param-based auth */ const char *basic_auth = NULL; if ((c->oauth.introspection_endpoint_auth != NULL) && (apr_strnatcmp(c->oauth.introspection_endpoint_auth, "client_secret_post") == 0)) { apr_table_addn(params, "client_id", c->oauth.client_id); apr_table_addn(params, "client_secret", c->oauth.client_secret); } else { basic_auth = apr_psprintf(r->pool, "%s:%s", c->oauth.client_id, c->oauth.client_secret); } /* call the endpoint with the constructed parameter set and return the resulting response */ return oidc_util_http_post_form(r, c->oauth.introspection_endpoint_url, params, basic_auth, NULL, c->oauth.ssl_validate_server, response, c->http_timeout_long, c->outgoing_proxy, dir_cfg->pass_cookies); }
/* * Create the required structures in the shared memory segment. * The following stuff goes to the shared memory: * a) Cookie Name * b) Cookie Value * c) First URL (which is later used for redirection) * * Note that it is important to save the unparsed URI here, so that URL encoding is preserved. * If we used the parsed URI here, we'd open up ourselves to a HTTP Response Splitting attack * through CR/LF injection. * * Function "searches" for free space within the shm section, and creates a new shm structure, * containing all relevant information a mod_but session requires. * * Writes SHM offset of newly generated session to shmoffset. * * Returns: * STATUS_OK and SHM offset in shmoffset * STATUS_ESHM if out of SHM space * STATUS_EHACKING if hacking is detected * STATUS_ERROR for all other internal errors */ apr_status_t create_new_shm_session(request_rec *r, char *sid, int *shmoffset) { mod_but_server_t *config = ap_get_module_config(r->server->module_config, &but_module); int i; for (i = 0; i < MOD_BUT_SESSION_COUNT; i++) { mod_but_cookie *c = apr_rmm_addr_get(cs_rmm, off[i]); ERRLOG_INFO("Existing session name [%s] and value [%s]", c->session_name, c->session_value); if (!apr_strnatcmp(c->session_name, "empty")) { ERRLOG_INFO("Setting-up new SHM session at offset [%d]", i); apr_cpystrn(c->session_name, config->cookie_name, sizeof(c->session_name)); apr_cpystrn(c->session_value, sid, sizeof(c->session_value)); /* Store r->unparsed_uri to prevent HTTP Response Splitting attacks */ apr_cpystrn(c->session_firsturl, r->unparsed_uri, sizeof(c->session_firsturl)); c->session_create_time = (int)apr_time_sec(apr_time_now()); c->session_last_access_time = c->session_create_time; c->link_to_cookiestore=-1; c->logon_state = 0; c->auth_strength = 0; apr_cpystrn(c->service_list, config->service_list_cookie_value, sizeof(c->service_list)); ERRLOG_CRIT("Session original URL is [%s]", c->session_firsturl); ERRLOG_INFO("Session name [%s] value [%s] ctime [%ds]", c->session_name, c->session_value, c->session_create_time); *shmoffset = i; return STATUS_OK; } } ERRLOG_INFO("No empty session slot found; all SHM used up"); return STATUS_ESHM; }
/* * check if a string is an element of an array of strings */ apr_byte_t apr_jwt_array_has_string(apr_array_header_t *haystack, const char *needle) { int i; for (i = 0; i < haystack->nelts; i++) { if (apr_strnatcmp(((const char**) haystack->elts)[i], needle) == 0) return TRUE; } return FALSE; }
static range* _expand_cluster(range_request* rr, const char* cluster, const char* section) { struct stat st; const char* res; libcrange* lr = range_request_lr(rr); set* cache = libcrange_get_cache(lr, "nodescf:cluster_keys"); apr_pool_t* req_pool = range_request_pool(rr); apr_pool_t* lr_pool = range_request_lr_pool(rr); const char* cluster_file; cache_entry* e; cluster_file = apr_psprintf(req_pool, "%s/%s.yaml", yaml_path, cluster); if (!cache) { cache = set_new(lr_pool, 0); libcrange_set_cache(lr, "nodescf:cluster_keys", cache); } if (stat(cluster_file, &st) == -1) { range_request_warn_type(rr, "NOCLUSTERDEF", cluster); return range_new(rr); } e = set_get_data(cache, cluster_file); if (!e) { e = apr_palloc(lr_pool, sizeof(struct cache_entry)); apr_pool_create(&e->pool, lr_pool); e->sections = _cluster_keys(rr, e->pool, cluster, cluster_file); e->mtime = st.st_mtime; set_add(cache, cluster_file, e); } else { time_t cached_mtime = e->mtime; if (cached_mtime != st.st_mtime) { apr_pool_clear(e->pool); e->sections = _cluster_keys(rr, e->pool, cluster, cluster_file); e->mtime = st.st_mtime; } } res = set_get_data(e->sections, section); if (!res) { if(!apr_strnatcmp(section, "CLUSTER")) { res = ""; } else { char* cluster_section = apr_psprintf(req_pool, "%s:%s", cluster, section); range_request_warn_type(rr, "NOCLUSTER", cluster_section); return range_new(rr); } } return do_range_expand(rr, res); }
/* * parse JSON JWK */ apr_byte_t apr_jwk_parse_json(apr_pool_t *pool, json_t *json, apr_jwk_t **j_jwk, apr_jwt_error_t *err) { /* check that we've actually got a JSON value back */ if (json == NULL) { apr_jwt_error(err, "JWK JSON is NULL"); return FALSE; } /* check that the value is a JSON object */ if (!json_is_object(json)) { apr_jwt_error(err, "JWK JSON is not a JSON object"); return FALSE; } /* allocate memory for the JWK */ *j_jwk = apr_pcalloc(pool, sizeof(apr_jwk_t)); apr_jwk_t *jwk = *j_jwk; /* get the mandatory key type */ char *kty = NULL; if (apr_jwt_get_string(pool, json, "kty", TRUE, &kty, err) == FALSE) return FALSE; /* get the optional kid */ apr_jwt_get_string(pool, json, "kid", FALSE, &jwk->kid, NULL); /* parse the key */ if (apr_strnatcmp(kty, "RSA") == 0) return apr_jwk_parse_rsa(pool, json, jwk, err); if (apr_strnatcmp(kty, "EC") == 0) return apr_jwk_parse_ec(pool, json, jwk, err); if (apr_strnatcmp(kty, "oct") == 0) return apr_jwk_parse_oct(pool, json, jwk, err); apr_jwt_error(err, "wrong or unsupported JWK key representation \"%s\" (\"RSA\", \"EC\" and \"oct\" are supported key types)", kty); return FALSE; }
/* * load a session from the cache/cookie */ apr_byte_t oidc_session_load(request_rec *r, oidc_session_t **zz) { oidc_cfg *c = ap_get_module_config(r->server->module_config, &auth_openidc_module); apr_byte_t rc = FALSE; const char *ses_p_tb_id = NULL, *env_p_tb_id = NULL; /* allocate space for the session object and fill it */ oidc_session_t *z = (*zz = apr_pcalloc(r->pool, sizeof(oidc_session_t))); oidc_session_clear(r, z); if (c->session_type == OIDC_SESSION_TYPE_SERVER_CACHE) /* load the session from the cache */ rc = oidc_session_load_cache(r, z); /* if we get here we configured client-cookie or retrieving from the cache failed */ if ((c->session_type == OIDC_SESSION_TYPE_CLIENT_COOKIE) || ((rc == FALSE) && oidc_cfg_session_cache_fallback_to_cookie(r))) /* load the session from a self-contained cookie */ rc = oidc_session_load_cookie(r, c, z); if ((rc == TRUE) && (z->state != NULL)) { json_t *j_expires = json_object_get(z->state, OIDC_SESSION_EXPIRY_KEY); if (j_expires) z->expiry = apr_time_from_sec(json_integer_value(j_expires)); /* check whether it has expired */ if (apr_time_now() > z->expiry) { oidc_warn(r, "session restored from cache has expired"); oidc_session_clear(r, z); } else { oidc_session_get(r, z, OIDC_SESSION_PROVIDED_TOKEN_BINDING_KEY, &ses_p_tb_id); if (ses_p_tb_id != NULL) { env_p_tb_id = oidc_util_get_provided_token_binding_id(r); if ((env_p_tb_id == NULL) || (apr_strnatcmp(env_p_tb_id, ses_p_tb_id) != 0)) { oidc_error(r, "the Provided Token Binding ID stored in the session doesn't match the one presented by the user agent"); oidc_session_clear(r, z); } } oidc_session_get(r, z, OIDC_SESSION_REMOTE_USER_KEY, &z->remote_user); } } return rc; }
static int find_cookie(request_rec *r,char **user,uint8_t *secret,int secretLen) { char *cookie=0l; char *cookie_expire=0l; char *cookie_valid=0l; ap_regmatch_t regmatch[AP_MAX_REG_MATCH]; authn_google_config_rec *conf = ap_get_module_config(r->per_dir_config, &authn_google_module); cookie = (char *) apr_table_get(r->headers_in, "Cookie"); if (cookie) { if (conf->debugLevel) ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Found cookie \"%s\"",cookie); if (!ap_regexec(cookie_regexp, cookie, AP_MAX_REG_MATCH, regmatch, 0)) { if (user) *user = ap_pregsub(r->pool, "$2", cookie,AP_MAX_REG_MATCH,regmatch); cookie_expire = ap_pregsub(r->pool, "$3", cookie,AP_MAX_REG_MATCH,regmatch); cookie_valid = ap_pregsub(r->pool, "$4", cookie,AP_MAX_REG_MATCH,regmatch); if (conf->debugLevel) ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Found cookie Expires \"%s\" Valid \"%s\"",cookie_expire,cookie_valid); if (cookie_expire && cookie_valid && *user) { long unsigned int exp = apr_atoi64(cookie_expire); long unsigned int now = apr_time_now()/1000000; if (exp < now) { if (conf->debugLevel) ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Expired. Now=%lu Expire=%lu\n",now,exp); return 0; /* Expired */ } if (!secret) { secret = getUserSecret(r,*user,&secretLen,0L); } char *h = hash_cookie(r->pool,secret,secretLen,exp); if (conf->debugLevel) ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Match cookie \"%s\" vs \"%s\"",h,cookie_valid); if (apr_strnatcmp(h,cookie_valid)==0) return 1; /* Valid Cookie */ else { if (conf->debugLevel) ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "MISMATCHED cookie \"%s\" vs \"%s\"",h,cookie_valid); return 0; /* Mismatched */ } } } } return 0; /* Not found */ }
/* * parse a "claim required" value from the provided string */ const char *oidc_parse_claim_required(apr_pool_t *pool, const char *arg, int *is_required) { static char *options[] = { OIDC_CLAIM_REQUIRED_MANDATORY, OIDC_CLAIM_REQUIRED_OPTIONAL, NULL }; const char *rv = oidc_valid_string_option(pool, arg, options); if (rv != NULL) return rv; *is_required = apr_strnatcmp(arg, OIDC_CLAIM_REQUIRED_MANDATORY); return NULL; }
static int twms_handler(request_rec *r) { twms_dir_conf *dcfg; const char *data; const char *val; apr_table_t *tab; apr_file_t *fh; apr_size_t nsend; apr_finfo_t info; if ((r->method_number != M_GET )||(r->args==0)) return DECLINED; data=r->args; // scfg=ap_get_module_config(r->server->module_config,&twms_module); dcfg=ap_get_module_config(r->per_dir_config,&twms_module); if (!dcfg) return DECLINED; // Does this ever happen? if (!ap_strstr(data,"GetTileService")) return DECLINED; // Do we have a config for this directory // ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"TWMS_handler: args %s, path %s scfg %x dcfg %x dir %s conf %s", // data,r->parsed_uri.path,scfg,dcfg,dcfg->path,dcfg->Config); if (!dcfg->Config) return DECLINED; // This is overkill here, but it works tab=apr_table_make(r->pool,0); while (*data && (val=ap_getword(r->pool, &data, '&'))) { char *key=apr_pstrdup(r->pool,ap_getword(r->pool, &val, '=')); char *ival=apr_pstrdup(r->pool,val); ap_unescape_url(key);ap_unescape_url(ival); apr_table_merge(tab,key,ival); } if (!(val=apr_table_get(tab,"request"))) return DECLINED; if (apr_strnatcmp(val,"GetTileService")) return DECLINED; if (APR_SUCCESS!=apr_file_open(&fh,apr_pstrcat(r->pool,dcfg->path,dcfg->Config,0), APR_READ,APR_OS_DEFAULT,r->pool)) { ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"TWMS file can't be read"); return HTTP_CONFLICT; } ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"TWMS Sending GTS file"); apr_file_info_get(&info,APR_FINFO_SIZE,fh); ap_set_content_type(r,"text/xml"); ap_send_fd(fh,r,0,info.size,&nsend); apr_file_close(fh); return OK; }
/* * get a value from the shared memory cache */ static apr_byte_t oidc_cache_shm_get(request_rec *r, const char *section, const char *key, const char **value) { oidc_debug(r, "enter, section=\"%s\", key=\"%s\"", section, key); oidc_cfg *cfg = ap_get_module_config(r->server->module_config, &auth_openidc_module); oidc_cache_cfg_shm_t *context = (oidc_cache_cfg_shm_t *) cfg->cache_cfg; int i; const char *section_key = oidc_cache_shm_get_key(r->pool, section, key); *value = NULL; /* grab the global lock */ if (oidc_cache_mutex_lock(r, context->mutex) == FALSE) return FALSE; /* get the pointer to the start of the shared memory block */ oidc_cache_shm_entry_t *t = apr_shm_baseaddr_get(context->shm); /* loop over the block, looking for the key */ for (i = 0; i < cfg->cache_shm_size_max; i++, OIDC_CACHE_SHM_ADD_OFFSET(t, cfg->cache_shm_entry_size_max)) { const char *tablekey = t->section_key; if ( (tablekey != NULL) && (apr_strnatcmp(tablekey, section_key) == 0) ) { /* found a match, check if it has expired */ if (t->expires > apr_time_now()) { /* update access timestamp */ t->access = apr_time_now(); *value = t->value; } else { /* clear the expired entry */ t->section_key[0] = '\0'; t->access = 0; } /* we safely can break now since we would not have found an expired match twice */ break; } } /* release the global lock */ oidc_cache_mutex_unlock(r, context->mutex); return (*value == NULL) ? FALSE : TRUE; }
/* * parse a key value based on the provided encoding: b64|b64url|hex|plain */ static const char *oidc_parse_key_value(apr_pool_t *pool, const char *enc, const char *input, char **key, int *key_len) { static char *options[] = { OIDC_KEY_ENCODING_BASE64, OIDC_KEY_ENCODING_BASE64_URL, OIDC_KEY_ENCODING_HEX, OIDC_KEY_ENCODING_PLAIN, NULL }; const char *rv = oidc_valid_string_option(pool, enc, options); if (rv != NULL) return rv; if (apr_strnatcmp(enc, OIDC_KEY_ENCODING_BASE64) == 0) return oidc_parse_base64(pool, input, key, key_len); if (apr_strnatcmp(enc, OIDC_KEY_ENCODING_BASE64_URL) == 0) return oidc_parse_base64url(pool, input, key, key_len); if (apr_strnatcmp(enc, OIDC_KEY_ENCODING_HEX) == 0) return oidc_parse_hex(pool, input, key, key_len); if (apr_strnatcmp(enc, OIDC_KEY_ENCODING_PLAIN) == 0) { *key = apr_pstrdup(pool, input); *key_len = strlen(*key); } return NULL; }
/* * parse an "unauthenticated action" value from the provided string */ const char *oidc_parse_unauth_action(apr_pool_t *pool, const char *arg, int *action) { static char *options[] = { OIDC_UNAUTH_ACTION_AUTH_STR, OIDC_UNAUTH_ACTION_PASS_STR, OIDC_UNAUTH_ACTION_401_STR, OIDC_UNAUTH_ACTION_410_STR, NULL }; const char *rv = oidc_valid_string_option(pool, arg, options); if (rv != NULL) return rv; if (apr_strnatcmp(arg, OIDC_UNAUTH_ACTION_AUTH_STR) == 0) *action = OIDC_UNAUTH_AUTHENTICATE; else if (apr_strnatcmp(arg, OIDC_UNAUTH_ACTION_PASS_STR) == 0) *action = OIDC_UNAUTH_PASS; else if (apr_strnatcmp(arg, OIDC_UNAUTH_ACTION_401_STR) == 0) *action = OIDC_UNAUTH_RETURN401; else if (apr_strnatcmp(arg, OIDC_UNAUTH_ACTION_410_STR) == 0) *action = OIDC_UNAUTH_RETURN410; return NULL; }
/* * parse JSON JWK */ apr_byte_t apr_jwk_parse_json(apr_pool_t *pool, json_t *j_json, const char *s_json, apr_jwk_t **j_jwk) { /* check that we've actually got a JSON value back */ if (j_json == NULL) return FALSE; /* check that the value is a JSON object */ if (!json_is_object(j_json)) return FALSE; /* allocate memory for the JWK */ *j_jwk = apr_pcalloc(pool, sizeof(apr_jwk_t)); apr_jwk_t *jwk = *j_jwk; /* set the raw JSON/string representations */ jwk->value.json = j_json; jwk->value.str = apr_pstrdup(pool, s_json); /* get the key type */ char *kty = NULL; if (apr_jwt_get_string(pool, &jwk->value, "kty", &kty) == FALSE) return FALSE; /* kty is mandatory */ if (kty == NULL) return FALSE; /* parse the key */ if (apr_strnatcmp(kty, "RSA") == 0) return apr_jwk_parse_rsa(pool, jwk); if (apr_strnatcmp(kty, "EC") == 0) return apr_jwk_parse_ec(pool, jwk); return FALSE; }