/* This function fetches a value from a session. * If multiple values are available, the first one is returned. * * Parameters: * am_cache_entry_t *t The current session. * const char *var The name of the value to be stored. * * Returns: * The first value, NULL if it does not exist. */ const char *am_cache_env_fetch_first(am_cache_entry_t *t, const char *var) { const char *str; int i; for (i = 0; i < t->size; i++) { str = am_cache_entry_get_string(t, &t->env[i].varname); if (str == NULL) break; if (strcmp(str, var) == 0) return am_cache_entry_get_string(t, &t->env[i].value); } return NULL; }
/* Retrieve a session from the cache and validate its cookie settings * * Parameters: * request_rec *r The request we received from the user. * am_cache_key_t type AM_CACHE_SESSION or AM_CACHE_NAMEID * const char *key The session key or user * * Returns: * The session associated, or NULL if unable to retrieve the given session. */ am_cache_entry_t *am_lock_and_validate(request_rec *r, am_cache_key_t type, const char *key) { am_cache_entry_t *session = NULL; am_diag_printf(r, "searching for session with key %s (%s) ... ", key, am_diag_cache_key_type_str(type)); session = am_cache_lock(r, type, key); if (session == NULL) { am_diag_printf(r, "not found\n"); return NULL; } else { am_diag_printf(r, "found.\n"); am_diag_log_cache_entry(r, 0, session, "Session Cache Entry"); } const char *cookie_token_session = am_cache_entry_get_string( session, &session->cookie_token); const char *cookie_token_target = am_cookie_token(r); if (strcmp(cookie_token_session, cookie_token_target)) { AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r, "Session cookie parameter mismatch. " "Session created with {%s}, but current " "request has {%s}.", cookie_token_session, cookie_token_target); am_cache_unlock(r, session); return NULL; } return session; }
/* This function retrieves a lasso session dump from the session object. * * Parameters: * am_cache_entry_t *session The session object. * * Returns: * The session dump, or NULL if we don't have a session dump. */ const char *am_cache_get_lasso_session(am_cache_entry_t *session) { return am_cache_entry_get_string(session, &session->lasso_session); }
/* This function populates the subprocess environment with data received * from the IdP. * * Parameters: * request_rec *r The request we should add the data to. * am_cache_entry_t *t The session data. * * Returns: * Nothing. */ void am_cache_env_populate(request_rec *r, am_cache_entry_t *t) { am_dir_cfg_rec *d; int i; apr_hash_t *counters; am_envattr_conf_t *env_varname_conf; const char *varname; const char *varname_prefix; const char *value; int *count; int status; d = am_get_dir_cfg(r); /* Check if the user attribute has been set, and set it if it * hasn't been set. */ if (am_cache_entry_slot_is_empty(&t->user)) { for(i = 0; i < t->size; ++i) { varname = am_cache_entry_get_string(t, &t->env[i].varname); if (strcmp(varname, d->userattr) == 0) { value = am_cache_entry_get_string(t, &t->env[i].value); status = am_cache_entry_store_string(t, &t->user, value); if (status != 0) { ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, "Unable to store the user name because there" " is no more space in the session. " "Username = \"%s\".", value); } } } } /* Allocate a set of counters for duplicate variables in the list. */ counters = apr_hash_make(r->pool); /* Populate the subprocess environment with the attributes we * received from the IdP. */ for(i = 0; i < t->size; ++i) { varname = am_cache_entry_get_string(t, &t->env[i].varname); varname_prefix = "MELLON_"; /* Check if we should map this name into another name. */ env_varname_conf = (am_envattr_conf_t *)apr_hash_get( d->envattr, varname, APR_HASH_KEY_STRING); if(env_varname_conf != NULL) { varname = env_varname_conf->name; if (!env_varname_conf->prefixed) { varname_prefix = ""; } } value = am_cache_entry_get_string(t, &t->env[i].value); /* * If we find a variable remapping to MellonUser, use it. */ if (am_cache_entry_slot_is_empty(&t->user) && (strcmp(varname, d->userattr) == 0)) { status = am_cache_entry_store_string(t, &t->user, value); if (status != 0) { ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, "Unable to store the user name because there" " is no more space in the session. " "Username = \"%s\".", value); } } /* Find the number of times this variable has been set. */ count = apr_hash_get(counters, varname, APR_HASH_KEY_STRING); if(count == NULL) { /* This is the first time. Create a counter for this variable. */ count = apr_palloc(r->pool, sizeof(int)); *count = 0; apr_hash_set(counters, varname, APR_HASH_KEY_STRING, count); /* Add the variable without a suffix. */ apr_table_set(r->subprocess_env, apr_pstrcat(r->pool, varname_prefix, varname, NULL), value); } /* Add the variable with a suffix indicating how many times it has * been added before. */ apr_table_set(r->subprocess_env, apr_psprintf(r->pool, "%s%s_%d", varname_prefix, varname, *count), value); /* Increase the count. */ ++(*count); } if (!am_cache_entry_slot_is_empty(&t->user)) { /* We have a user-"name". Set r->user and r->ap_auth_type. */ r->user = apr_pstrdup(r->pool, am_cache_entry_get_string(t, &t->user)); r->ap_auth_type = apr_pstrdup(r->pool, "Mellon"); } else { /* We don't have a user-"name". Log error. */ ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, "Didn't find the attribute \"%s\" in the attributes" " which were received from the IdP. Cannot set a user" " for this request without a valid user attribute.", d->userattr); } /* Populate with the session? */ if (d->dump_session) { char *session; const char *srcstr; int srclen, dstlen; srcstr = am_cache_entry_get_string(t, &t->lasso_session); srclen = strlen(srcstr); dstlen = apr_base64_encode_len(srclen); session = apr_palloc(r->pool, dstlen); (void)apr_base64_encode(session, srcstr, srclen); apr_table_set(r->subprocess_env, "MELLON_SESSION", session); } if (d->dump_saml_response) { const char *sr = am_cache_entry_get_string(t, &t->lasso_saml_response); if (sr) { apr_table_set(r->subprocess_env, "MELLON_SAML_RESPONSE", sr); } } }