Permalink
Browse files

Implemented AuthOpenIDAXUsername and AuthOpenIDSecureCookie

  • Loading branch information...
1 parent 8930bee commit 9abe720891017860180d947c9b3bf06c529d66c1 Jeremy Ehrhardt committed Apr 6, 2012
Showing with 62 additions and 28 deletions.
  1. +12 −11 src/SessionManager.cpp
  2. +1 −1 src/SessionManager.h
  3. +48 −16 src/mod_auth_openid.cpp
  4. +1 −0 src/types.h
View
@@ -37,14 +37,14 @@ namespace modauthopenid {
return;
sqlite3_busy_timeout(db, 5000);
string query = "CREATE TABLE IF NOT EXISTS sessionmanager "
- "(session_id VARCHAR(33), hostname VARCHAR(255), path VARCHAR(255), identity VARCHAR(255), expires_on INT)";
+ "(session_id VARCHAR(33), hostname VARCHAR(255), path VARCHAR(255), identity VARCHAR(255), username VARCHAR(255), expires_on INT)";
rc = sqlite3_exec(db, query.c_str(), 0, 0, 0);
test_result(rc, "problem creating table if it didn't exist already");
};
void SessionManager::get_session(const string& session_id, session_t& session) {
ween_expired();
- const char *query = "SELECT session_id,hostname,path,identity,expires_on FROM sessionmanager WHERE session_id=%Q LIMIT 1";
+ const char *query = "SELECT session_id,hostname,path,identity,username,expires_on FROM sessionmanager WHERE session_id=%Q LIMIT 1";
char *sql = sqlite3_mprintf(query, session_id.c_str());
int nr, nc;
char **table;
@@ -55,11 +55,12 @@ namespace modauthopenid {
session.identity = "";
debug("could not find session id " + session_id + " in db: session probably just expired");
} else {
- session.session_id = string(table[5]);
- session.hostname = string(table[6]);
- session.path = string(table[7]);
- session.identity = string(table[8]);
- session.expires_on = strtol(table[9], 0, 0);
+ session.session_id = string(table[6]);
+ session.hostname = string(table[7]);
+ session.path = string(table[8]);
+ session.identity = string(table[9]);
+ session.username = string(table[10]);
+ session.expires_on = strtol(table[11], 0, 0);
}
sqlite3_free_table(table);
};
@@ -75,20 +76,20 @@ namespace modauthopenid {
return true;
};
- void SessionManager::store_session(const string& session_id, const string& hostname, const string& path, const string& identity, int lifespan) {
+ void SessionManager::store_session(const string& session_id, const string& hostname, const string& path, const string& identity, const string& username, int lifespan) {
ween_expired();
time_t rawtime;
time (&rawtime);
// lifespan will be 0 if not specified by user in config - so lasts as long as browser is open. In this case, make it last for up to a day.
int expires_on = (lifespan == 0) ? (rawtime + 86400) : (rawtime + lifespan);
- const char* url = "INSERT INTO sessionmanager (session_id,hostname,path,identity,expires_on) VALUES(%Q,%Q,%Q,%Q,%d)";
- char *query = sqlite3_mprintf(url, session_id.c_str(), hostname.c_str(), path.c_str(), identity.c_str(), expires_on);
+ const char* url = "INSERT INTO sessionmanager (session_id,hostname,path,identity,username,expires_on) VALUES(%Q,%Q,%Q,%Q,%Q,%d)";
+ char *query = sqlite3_mprintf(url, session_id.c_str(), hostname.c_str(), path.c_str(), identity.c_str(), username.c_str(), expires_on);
debug(query);
int rc = sqlite3_exec(db, query, 0, 0, 0);
sqlite3_free(query);
- test_result(rc, "problem inserting session into db");
+ test_result(rc, "problem inserting session into db");
};
void SessionManager::ween_expired() {
View
@@ -43,7 +43,7 @@ namespace modauthopenid {
// store given session information in a new session entry
// if lifespan is 0, let it expire in a day. otherwise, expire in "lifespan" seconds
// See issue 16 - http://trac.butterfat.net/public/mod_auth_openid/ticket/16
- void store_session(const string& session_id, const string& hostname, const string& path, const string& identity, int lifespan);
+ void store_session(const string& session_id, const string& hostname, const string& path, const string& identity, const string& username, int lifespan);
// print session table to stdout
void print_table();
View
@@ -51,6 +51,8 @@ typedef struct {
apr_array_header_t *ax_attrs;
apr_table_t *ax_attr_uris;
apr_table_t *ax_attr_patterns;
+ bool use_ax_username;
+ char *ax_username_attr;
bool use_single_idp;
char *single_idp_url;
} modauthopenid_config;
@@ -76,6 +78,8 @@ static void *create_modauthopenid_config(apr_pool_t *p, char *s) {
newcfg->ax_attrs = apr_array_make(p, 5, sizeof(char *));
newcfg->ax_attr_uris = apr_table_make(p, 5);
newcfg->ax_attr_patterns = apr_table_make(p, 5);
+ newcfg->use_ax_username = false;
+ newcfg->ax_username_attr = NULL;
newcfg->use_single_idp = false;
newcfg->single_idp_url = NULL;
return (void *) newcfg;
@@ -165,6 +169,13 @@ static const char *set_modauthopenid_ax_require(cmd_parms *parms, void *mconfig,
return NULL;
}
+static const char *set_modauthopenid_ax_username(cmd_parms *parms, void *mconfig, const char *arg) {
+ modauthopenid_config *s_cfg = (modauthopenid_config *) mconfig;
+ s_cfg->use_ax_username = true;
+ s_cfg->ax_username_attr = (char *) arg;
+ return NULL;
+}
+
static const char *set_modauthopenid_single_idp(cmd_parms *parms, void *mconfig, const char *arg) {
modauthopenid_config *s_cfg = (modauthopenid_config *) mconfig;
s_cfg->use_single_idp = true;
@@ -199,6 +210,8 @@ static const command_rec mod_authopenid_cmds[] = {
"AuthOpenIDUserProgram <full path to authentication program>"),
AP_INIT_TAKE3("AuthOpenIDAXRequire", (CMD_HAND_TYPE) set_modauthopenid_ax_require, NULL, OR_AUTHCFG,
"Add AuthOpenIDAXRequire <alias> <URI> <regex>"),
+ AP_INIT_TAKE1("AuthOpenIDAXUsername", (CMD_HAND_TYPE) set_modauthopenid_ax_username, NULL, OR_AUTHCFG,
+ "AuthOpenIDAXUsername <alias>"),
AP_INIT_TAKE1("AuthOpenIDSingleIdP", (CMD_HAND_TYPE) set_modauthopenid_single_idp, NULL, OR_AUTHCFG,
"AuthOpenIDSingleIdP <IdP URL>"),
{NULL}
@@ -317,14 +330,16 @@ static bool has_valid_session(request_rec *r, modauthopenid_config *s_cfg) {
sm.close();
// if session found
- if(std::string(session.identity) != "") {
+ if(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);
+ if(valid_path == uri_path.substr(0, valid_path.size()) && strcmp(session.hostname.c_str(), r->hostname)==0) {
+ const char* idchar = s_cfg->use_ax_username
+ ? session.username.c_str()
+ : session.identity.c_str();
+ APDEBUG(r, "setting REMOTE_USER to %s", idchar);
r->user = apr_pstrdup(r->pool, idchar);
return true;
} else {
@@ -405,7 +420,7 @@ static int start_authentication_session(request_rec *r, modauthopenid_config *s_
};
-static int set_session_cookie(request_rec *r, modauthopenid_config *s_cfg, opkele::params_t& params, std::string identity) {
+static int set_session_cookie(request_rec *r, modauthopenid_config *s_cfg, opkele::params_t& params, std::string identity, std::string username) {
// 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)
@@ -420,7 +435,7 @@ static int set_session_cookie(request_rec *r, modauthopenid_config *s_cfg, opkel
// 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.store_session(session_id, hostname, path, identity, username, s_cfg->cookie_lifespan);
sm.close();
opkele::params_t ext_params;
@@ -452,6 +467,7 @@ static int validate_authentication_session(request_rec *r, modauthopenid_config
}
// if we did an AX query, check the result
+ std::string ax_username;
if(s_cfg->use_ax) {
// get the AX namespace alias
std::string ns_pfx = "openid.ns.";
@@ -478,22 +494,35 @@ static int validate_authentication_session(request_rec *r, modauthopenid_config
const char *attr = APR_ARRAY_IDX(s_cfg->ax_attrs, i, const char *);
std::string param_name = ax_value_pfx + attr;
std::map<std::string, std::string>::iterator param = params.find(param_name);
- if (param == params.end())
+ if(param == params.end())
{
APERR(r, "AX: attribute %s not found", attr);
consumer.close();
return show_input(r, s_cfg, modauthopenid::ax_bad_response);
}
+ std::string& value = param->second;
std::string pattern = apr_table_get(s_cfg->ax_attr_patterns, attr);
pcre *re = modauthopenid::make_regex(pattern);
- bool match = modauthopenid::regex_match(param->second, re);
+ bool match = modauthopenid::regex_match(value, re);
pcre_free(re);
- if (!match) {
+ if(!match) {
consumer.close();
- APERR(r, "AX: %s attribute %s didn't match %s", attr, param->second.c_str(), pattern.c_str());
- return show_input(r, s_cfg, modauthopenid::unauthorized);
+ APERR(r, "AX: %s attribute %s didn't match %s", attr, value.c_str(), pattern.c_str());
+ return show_input(r, s_cfg, modauthopenid::unauthorized);
} else {
- APDEBUG(r, "AX: %s attribute %s matched %s", attr, param->second.c_str(), pattern.c_str());
+ APDEBUG(r, "AX: %s attribute %s matched %s", attr, value.c_str(), pattern.c_str());
+ if(s_cfg->use_ax_username && strcmp(attr, s_cfg->ax_username_attr) == 0) {
+ ax_username = value;
+ }
+ }
+ }
+ if(s_cfg->use_ax_username) {
+ if(ax_username.empty()) {
+ consumer.close();
+ APERR(r, "AX: username attribute %s not found", s_cfg->ax_username_attr);
+ return show_input(r, s_cfg, modauthopenid::unauthorized);
+ } else {
+ APDEBUG(r, "AX: username = %s", ax_username.c_str());
}
}
}
@@ -520,11 +549,14 @@ static int validate_authentication_session(request_rec *r, modauthopenid_config
consumer.close();
if(s_cfg->use_cookie)
- return set_session_cookie(r, s_cfg, params, identity);
-
+ return set_session_cookie(r, s_cfg, params, identity, ax_username);
+
+ std::string remote_user = s_cfg->use_ax_username
+ ? ax_username
+ : 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());
+ APDEBUG(r, "Setting REMOTE_USER to %s", remote_user.c_str());
+ r->user = apr_pstrdup(r->pool, remote_user.c_str());
return DECLINED;
} catch(opkele::exception &e) {
APERR(r, "Error in authentication: %s", e.what());
View
@@ -38,6 +38,7 @@ namespace modauthopenid {
string hostname; // name of server (this is in case there are virtual hosts on this server)
string path;
string identity;
+ string username; // optional - set by AuthOpenIDAXUsername
int expires_on; // exact moment it expires
} session_t;

0 comments on commit 9abe720

Please sign in to comment.