示例#1
0
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;
};
示例#2
0
static int set_session_cookie(request_rec *r, modauthopenid_config *s_cfg, opkele::params_t& params, std::string identity) {
  // now set auth cookie, if we're doing session based auth
  std::string session_id, hostname, path, cookie_value, redirect_location, args;
  if(s_cfg->cookie_path != NULL) 
    path = std::string(s_cfg->cookie_path); 
  else 
    modauthopenid::base_dir(std::string(r->uri), path); 
  modauthopenid::make_rstring(32, session_id);
  modauthopenid::make_cookie_value(cookie_value, std::string(s_cfg->cookie_name), session_id, path, s_cfg->cookie_lifespan); 
  APDEBUG(r, "Setting cookie after authentication of user %s", identity.c_str());
  apr_table_set(r->err_headers_out, "Set-Cookie", cookie_value.c_str());
  hostname = std::string(r->hostname);

  // save session values
  modauthopenid::SessionManager sm(std::string(s_cfg->db_location));
  sm.store_session(session_id, hostname, path, identity, s_cfg->cookie_lifespan);
  sm.close();

  opkele::params_t ext_params;
  modauthopenid::get_extension_params(ext_params, params);
  modauthopenid::remove_openid_vars(params);
  modauthopenid::merge_params(ext_params, params);
  args = params.append_query("", "").substr(1);
  if(args.length() == 0)
    r->args = NULL;
  else
    apr_cpystrn(r->args, args.c_str(), 1024);
  full_uri(r, redirect_location, s_cfg);
  return modauthopenid::http_redirect(r, redirect_location);
};
static int start_authentication_session(request_rec *r, modauthopenid_config *s_cfg, opkele::params_t& params,
                                        std::string& return_to, std::string& trust_root) {
    // remove all openid GET query params (openid.*) - we don't want that maintained through
    // the redirection process.  We do, however, want to keep all other GET params.
    // also, add a nonce for security
    std::string identity = s_cfg->use_single_idp
                           ? s_cfg->single_idp_url
                           : params.get_param("openid_identifier");
    APDEBUG(r, "identity = %s, use_single_idp = %s", identity.c_str(), s_cfg->use_single_idp ? "true" : "false");
    // pull out the extension parameters before we get rid of openid.*
    opkele::params_t ext_params;
    modauthopenid::get_extension_params(ext_params, params);
    modauthopenid::remove_openid_vars(params);

    // if attribute directives are set, add AX stuff to extension params
    if(s_cfg->use_ax)
    {
        ext_params["openid.ns." DEFAULT_AX_NAMESPACE_ALIAS] = AX_NAMESPACE;
        ext_params["openid." DEFAULT_AX_NAMESPACE_ALIAS ".mode"] = "fetch_request";
        std::string required = "";
        bool first_alias = true;
        for(int i = 0; i < s_cfg->ax_attrs->nelts; ++i) {
            std::string alias = APR_ARRAY_IDX(s_cfg->ax_attrs, i, const char *);
            std::string uri = apr_table_get(s_cfg->ax_attr_uris, alias.c_str());
            ext_params["openid." DEFAULT_AX_NAMESPACE_ALIAS ".type." + alias] = uri;
            if(first_alias) {
                first_alias = false;
            } else {
                required += ',';
            }
            required += alias;
        }
        ext_params["openid." DEFAULT_AX_NAMESPACE_ALIAS ".required"] = required;
    }
示例#4
0
static bool is_distrusted_provider(modauthopenid_config *s_cfg, std::string url, request_rec *r) {
  if(apr_is_empty_array(s_cfg->distrusted))
    return false;
  char **distrusted_sites = (char **) s_cfg->distrusted->elts;
  std::string base_url = modauthopenid::get_queryless_url(url);
  for (int i = 0; i < s_cfg->distrusted->nelts; i++) {
    pcre * re = modauthopenid::make_regex(distrusted_sites[i]);
    if(re == NULL) {
      APERR(r, "regex compilation failed for regex: %s", distrusted_sites[i]);
    } else if(modauthopenid::regex_match(base_url, re)) {
      APWARN(r, "%s is a distrusted (on black list) identity provider", base_url.c_str());
      return true;
    }
  }
  APDEBUG(r, "%s is NOT a distrusted identity provider (not blacklisted)", base_url.c_str());
  return false;
};
示例#5
0
static int mod_authopenid_method_handler(request_rec *r) {
  modauthopenid_config *s_cfg;
  s_cfg = (modauthopenid_config *) ap_get_module_config(r->per_dir_config, &authopenid_module);

  // if we're not enabled for this location/dir, decline doing anything
  const char *current_auth = ap_auth_type(r);
  if (!current_auth || strcasecmp(current_auth, "openid"))
    return DECLINED;

  // make a record of our being called
  APDEBUG(r, "*** %s module has been called ***", PACKAGE_STRING);
  
  // if user has a valid session, they are authorized (OK)
  if(has_valid_session(r, s_cfg))
    return OK;

  // parse the get/post params
  opkele::params_t params;
  modauthopenid::get_request_params(r, params);

  // get our current url and trust root
  std::string return_to, trust_root;
  full_uri(r, return_to, s_cfg);
  if(s_cfg->trust_root == NULL)
    modauthopenid::base_dir(return_to, trust_root);
  else
    trust_root = std::string(s_cfg->trust_root);

  // if we're in SSO mode, force the openid_identifier to a specific value
  if(s_cfg->sso_url && !params.has_param("openid.assoc_handle"))
    params.set_field("openid_identifier", s_cfg->sso_url);

  // if user is posting id (only openid_identifier will contain a value)
  if(params.has_param("openid_identifier") && !params.has_param("openid.assoc_handle")) {
    return start_authentication_session(r, s_cfg, params, return_to, trust_root);
  } else if(params.has_param("openid.assoc_handle")) { // user has been redirected, authenticate them and set cookie
    return validate_authentication_session(r, s_cfg, params, return_to);
  } else { //display an input form
    if(params.has_param("openid.mode") && params.get_param("openid.mode") == "cancel")
      return show_input(r, s_cfg, modauthopenid::canceled);
    return show_input(r, s_cfg);
  }
}
示例#6
0
static int validate_authentication_session(request_rec *r, modauthopenid_config *s_cfg, opkele::params_t& params, std::string& return_to) {
  // make sure nonce is present
  if(!params.has_param("modauthopenid.nonce")) 
    return show_input(r, s_cfg, modauthopenid::invalid_nonce);

  modauthopenid::MoidConsumer consumer(std::string(s_cfg->db_location), params.get_param("modauthopenid.nonce"), return_to);
  try {
    consumer.id_res(modauthopenid::modauthopenid_message_t(params));
    
    // if no exception raised, check nonce
    if(!consumer.session_exists()) {
      consumer.close();
      return show_input(r, s_cfg, modauthopenid::invalid_nonce); 
    }

    // if we should be using a user specified auth program, run it to see if user is authorized
    if(s_cfg->use_auth_program) {
      std::string username = consumer.get_claimed_id();
      std::string progname = std::string(s_cfg->auth_program);
      modauthopenid::exec_result_t eresult = modauthopenid::exec_auth(progname, username);
      if(eresult != modauthopenid::id_accepted) {
	std::string error = modauthopenid::exec_error_to_string(eresult, progname, username);
	APERR(r, "Error in authentication: %s", error.c_str());	
	consumer.close();
	return show_input(r, s_cfg, modauthopenid::unauthorized);       
      } else {
	APDEBUG(r, "Authenticated %s using %s", username.c_str(), progname.c_str());	
      }
    }

    // Make sure that identity is set to the original one given by the user (in case of delegation
    // this will be different than openid_identifier GET param
    std::string identity;
    if (s_cfg->sso_url && s_cfg->sso_user_base) {
	std::string c_identity = consumer.get_claimed_id();
	if (strstr(c_identity.c_str(), s_cfg->sso_user_base) == c_identity.c_str()) {
		identity = strdup(c_identity.c_str() + strlen(s_cfg->sso_user_base));
	} else {
		std::string error = "SSOUserBase didn't match in the identity";
		APERR(r, "Error in authentication: %s", error.c_str());	
		consumer.close();
		return show_input(r, s_cfg, modauthopenid::unauthorized);       
	}
    } else
    	identity = consumer.get_claimed_id();

    consumer.kill_session();
    consumer.close();

    if(s_cfg->use_cookie) 
      return set_session_cookie(r, s_cfg, params, identity);
      
    // if we're not setting cookie - don't redirect, just show page
    APERR(r, "Setting REMOTE_USER to %s", identity.c_str());
    r->user = apr_pstrdup(r->pool, identity.c_str());
    return DECLINED;
  } catch(opkele::exception &e) {
    APERR(r, "Error in authentication: %s", e.what());
    consumer.close();
    return show_input(r, s_cfg, modauthopenid::unspecified);
  }
};