Modified: tuscany/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp
URL: 
http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp?rev=1361915&r1=1361914&r2=1361915&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp (original)
+++ tuscany/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp Mon Jul 16 06:47:49 2012
@@ -65,6 +65,20 @@ public:
 };
 
 /**
+ * Authentication provider configuration.
+ */
+class AuthnProviderConf {
+public:
+    AuthnProviderConf() : name(), provider(NULL) {
+    }
+    AuthnProviderConf(const string name, const authn_provider* provider) : 
name(name), provider(provider) {
+    }
+
+    string name;
+    const authn_provider* provider;
+};
+
+/**
  * Directory configuration.
  */
 class DirConf {
@@ -77,9 +91,39 @@ public:
     bool enabled;
     string login;
     list<list<value> > scopeattrs;
+    list<AuthnProviderConf> apcs;
 };
 
 /**
+ * Run the authnz hooks to authenticate a request.
+ */
+const failable<int> checkAuthnzProviders(const string& user, request_rec* r, 
const list<AuthnProviderConf>& apcs) {
+    if (isNil(apcs))
+        return mkfailure<int>("Authentication failure for: " + user, 
HTTP_UNAUTHORIZED);
+    const AuthnProviderConf apc = car<AuthnProviderConf>(apcs);
+    if (apc.provider == NULL || !apc.provider->check_password)
+        return checkAuthnzProviders(user, r, cdr(apcs));
+
+    apr_table_setn(r->notes, AUTHN_PROVIDER_NAME_NOTE, c_str(apc.name));
+    const authn_status auth_result = apc.provider->check_password(r, 
c_str(string("/oauth2/") + user), "password");
+    apr_table_unset(r->notes, AUTHN_PROVIDER_NAME_NOTE);
+    if (auth_result != AUTH_GRANTED)
+        return checkAuthnzProviders(user, r, cdr(apcs));
+    return OK;
+}
+
+const failable<int> checkAuthnz(const string& user, request_rec* r, const 
list<AuthnProviderConf>& apcs) {
+    if (substr(user, 0, 1) == "/")
+        return mkfailure<int>(string("Encountered FakeBasicAuth spoof: ") + 
user, HTTP_UNAUTHORIZED);
+
+    if (isNil(apcs)) {
+        const authn_provider* provider = (const 
authn_provider*)ap_lookup_provider(AUTHN_PROVIDER_GROUP, 
AUTHN_DEFAULT_PROVIDER, AUTHN_PROVIDER_VERSION);
+        return checkAuthnzProviders(user, r, 
mklist<AuthnProviderConf>(AuthnProviderConf(AUTHN_DEFAULT_PROVIDER, provider)));
+    }
+    return checkAuthnzProviders(user, r, apcs);
+}
+
+/**
  * Return the user info for a session.
  */
 const failable<value> userInfo(const value& sid, const memcache::MemCached& 
mc) {
@@ -89,13 +133,13 @@ const failable<value> userInfo(const val
 /**
  * Handle an authenticated request.
  */
-const failable<int> authenticated(const list<list<value> >& attrs, const 
list<list<value> >& info, request_rec* r) {
-    debug(info, "modoauth2::authenticated::info");
+const failable<int> authenticated(const list<list<value> >& userinfo, const 
bool check, request_rec* r, const list<list<value> >& scopeattrs, const 
list<AuthnProviderConf>& apcs) {
+    debug(userinfo, "modoauth2::authenticated::userinfo");
 
-    if (isNil(attrs)) {
+    if (isNil(scopeattrs)) {
 
         // Store user id in an environment variable
-        const list<value> id = assoc<value>("id", info);
+        const list<value> id = assoc<value>("id", userinfo);
         if (isNil(id) || isNil(cdr(id)))
             return mkfailure<int>("Couldn't retrieve user id");
         apr_table_set(r->subprocess_env, "OAUTH2_ID", apr_pstrdup(r->pool, 
c_str(cadr(id))));
@@ -104,12 +148,16 @@ const failable<int> authenticated(const 
         // OAuth id attribute to it
         if (r->user == NULL || r->user[0] == '\0')
             r->user = apr_pstrdup(r->pool, c_str(cadr(id)));
+
+        // Run the authnz hooks to check the authenticated user
+        if (check)
+            return checkAuthnz(r->user == NULL? "" : r->user, r, apcs);
         return OK;
     }
 
-    // Store each configure OAuth scope attribute in an environment variable
-    const list<value> a = car(attrs);
-    const list<value> v = assoc<value>(cadr(a), info);
+    // Store each configured OAuth scope attribute in an environment variable
+    const list<value> a = car(scopeattrs);
+    const list<value> v = assoc<value>(cadr(a), userinfo);
     if (!isNil(v) && !isNil(cdr(v))) {
 
         // Map the REMOTE_USER attribute to the request user field
@@ -118,7 +166,7 @@ const failable<int> authenticated(const 
         else
             apr_table_set(r->subprocess_env, apr_pstrdup(r->pool, 
c_str(car(a))), apr_pstrdup(r->pool, c_str(cadr(v))));
     }
-    return authenticated(cdr(attrs), info, r);
+    return authenticated(userinfo, check, r, cdr(scopeattrs), apcs);
 }
 
 /**
@@ -181,7 +229,8 @@ const failable<list<value> > profileUser
 /**
  * Handle an access_token request.
  */
-const failable<int> accessToken(const list<list<value> >& args, request_rec* 
r, const list<list<value> >& appkeys, const perthread_ptr<http::CURLSession>& 
cs, const memcache::MemCached& mc) {
+const failable<int> accessToken(const list<list<value> >& args, request_rec* 
r, const list<list<value> >& appkeys, const perthread_ptr<http::CURLSession>& 
cs, const list<list<value> >& scopeattrs, const list<AuthnProviderConf>& apcs, 
const memcache::MemCached& mc) {
+
     // Extract access_token URI, client ID and authorization code parameters
     const list<value> state = assoc<value>("state", args);
     if (isNil(state) || isNil(cdr(state)))
@@ -245,17 +294,22 @@ const failable<int> accessToken(const li
     debug(content(profres), "modoauth2::access_token::info");
 
     // Retrieve the user info from the profile
-    const failable<list<value> > iv = profileUserInfo(cadr(cid), 
content(profres));
-    if (!hasContent(iv))
-        return mkfailure<int>(iv);
+    const failable<list<value> > userinfo = profileUserInfo(cadr(cid), 
content(profres));
+    if (!hasContent(userinfo))
+        return mkfailure<int>(userinfo);
+
+    // Validate the authenticated user
+    const failable<int> authrc = authenticated(content(userinfo), true, r, 
scopeattrs, apcs);
+    if (!hasContent(authrc))
+        return authrc;
 
-    // Store user info in memcached keyed by session ID
+    // Store user info in memcached keyed by a session ID
     const value sid = string("OAuth2_") + mkrand();
-    const failable<bool> prc = memcache::put(mklist<value>("tuscanyOAuth2", 
sid), content(iv), mc);
+    const failable<bool> prc = memcache::put(mklist<value>("tuscanyOAuth2", 
sid), content(userinfo), mc);
     if (!hasContent(prc))
         return mkfailure<int>(prc);
 
-    // Send session ID to the client in a cookie
+    // Send the session ID to the client in a cookie
     debug(c_str(openauth::cookie("TuscanyOAuth2", sid, httpd::hostName(r))), 
"modoauth2::access_token::setcookie");
     apr_table_set(r->err_headers_out, "Set-Cookie", 
c_str(openauth::cookie("TuscanyOAuth2", sid, httpd::hostName(r))));
     return httpd::externalRedirect(httpd::url(httpd::unescape(cadr(ref)), r), 
r);
@@ -265,20 +319,19 @@ const failable<int> accessToken(const li
  * Check user authentication.
  */
 static int checkAuthn(request_rec *r) {
+    gc_scoped_pool pool(r->pool);
+
     // Decline if we're not enabled or AuthType is not set to Open
     const DirConf& dc = httpd::dirConf<DirConf>(r, &mod_tuscany_oauth2);
     if (!dc.enabled)
         return DECLINED;
     const char* atype = ap_auth_type(r);
-    debug(atype, "modopenauth::checkAuthn::auth_type");
     if (atype == NULL || strcasecmp(atype, "Open"))
         return DECLINED;
-
-    // Create a scoped memory pool
-    gc_scoped_pool pool(r->pool);
+    debug_httpdRequest(r, "modoauth2::checkAuthn::input");
+    debug(atype, "modopenauth::checkAuthn::auth_type");
 
     // Get the server configuration
-    debug_httpdRequest(r, "modoauth2::checkAuthn::input");
     const ServerConf& sc = httpd::serverConf<ServerConf>(r, 
&mod_tuscany_oauth2);
 
     // Get session id from the request
@@ -288,24 +341,33 @@ static int checkAuthn(request_rec *r) {
         if (substr(content(sid), 0, 7) != "OAuth2_")
             return DECLINED;
 
-        // If we're authenticated store the user info in the request
-        const failable<value> info = userInfo(content(sid), sc.mc);
-        if (hasContent(info)) {
-            r->ap_auth_type = const_cast<char*>(atype);
-            return httpd::reportStatus(authenticated(dc.scopeattrs, 
content(info), r));
-        }
+        // Extract the user info from the auth session
+        const failable<value> userinfo = userInfo(content(sid), sc.mc);
+        if (!hasContent(userinfo))
+            return httpd::reportStatus(mkfailure<int>(userinfo));
+        r->ap_auth_type = const_cast<char*>(atype);
+        return httpd::reportStatus(authenticated(content(userinfo), false, r, 
dc.scopeattrs, dc.apcs));
     }
 
+    // Get the request args
+    const list<list<value> > args = httpd::queryArgs(r);
+
     // Handle OAuth authorize request step
     if (string(r->uri) == "/oauth2/authorize/") {
         r->ap_auth_type = const_cast<char*>(atype);
-        return httpd::reportStatus(authorize(httpd::queryArgs(r), r, 
sc.appkeys));
+        return httpd::reportStatus(authorize(args, r, sc.appkeys));
     }
 
     // Handle OAuth access_token request step
     if (string(r->uri) == "/oauth2/access_token/") {
         r->ap_auth_type = const_cast<char*>(atype);
-        return httpd::reportStatus(accessToken(httpd::queryArgs(r), r, 
sc.appkeys, sc.cs, sc.mc));
+        const failable<int> authrc = accessToken(args, r, sc.appkeys, sc.cs, 
dc.scopeattrs, dc.apcs, sc.mc);
+
+        // Redirect to the login page if user is not authorized
+        if (!hasContent(authrc) && rcode(authrc) == HTTP_UNAUTHORIZED)
+            return httpd::reportStatus(openauth::login(dc.login, string("/"), 
1, r));
+
+        return httpd::reportStatus(authrc);
     }
 
     // Redirect to the login page, unless we have a session id or an 
authorization
@@ -316,10 +378,11 @@ static int checkAuthn(request_rec *r) {
         hasContent(openauth::sessionID(r, "TuscanyOpenAuth")) ||
         hasContent(openauth::sessionID(r, "TuscanyOAuth1")))
         return DECLINED;
-    if ((substr(string(r->uri), 0, 8) == "/oauth1/") || 
!isNil(assoc<value>("openid_identifier", httpd::queryArgs(r))))
+    if ((substr(string(r->uri), 0, 8) == "/oauth1/") || 
!isNil(assoc<value>("openid_identifier", args)))
         return DECLINED;
+
     r->ap_auth_type = const_cast<char*>(atype);
-    return httpd::reportStatus(openauth::login(dc.login, r));
+    return httpd::reportStatus(openauth::login(dc.login, value(), value(), r));
 }
 
 /**
@@ -344,6 +407,7 @@ int postConfigMerge(ServerConf& mainsc, 
 
 int postConfig(apr_pool_t* p, unused apr_pool_t* plog, unused apr_pool_t* 
ptemp, server_rec* s) {
     gc_scoped_pool pool(p);
+
     ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_oauth2);
     debug(httpd::serverName(s), "modoauth2::postConfig::serverName");
 
@@ -360,7 +424,7 @@ public:
     }
 
     const gc_ptr<http::CURLSession> operator()() const {
-        return new (gc_new<http::CURLSession>()) http::CURLSession(ca, cert, 
key, "");
+        return new (gc_new<http::CURLSession>()) http::CURLSession(ca, cert, 
key, "", 0);
     }
 
 private:
@@ -374,6 +438,7 @@ private:
  */
 void childInit(apr_pool_t* p, server_rec* s) {
     gc_scoped_pool pool(p);
+
     ServerConf* psc = (ServerConf*)ap_get_module_config(s->module_config, 
&mod_tuscany_oauth2);
     if(psc == NULL) {
         cfailure << "[Tuscany] Due to one or more errors mod_tuscany_oauth2 
loading failed. Causing apache to stop loading." << endl;
@@ -445,11 +510,25 @@ const char* confScopeAttr(cmd_parms *cmd
     dc.scopeattrs = cons<list<value> >(mklist<value>(arg1, arg2), 
dc.scopeattrs);
     return NULL;
 }
+const char* confAuthnProvider(cmd_parms *cmd, void *c, const char* arg) {
+    gc_scoped_pool pool(cmd->pool);
+    DirConf& dc = httpd::dirConf<DirConf>(c);
+
+    // Lookup and cache the Authn provider
+    const authn_provider* provider = 
(authn_provider*)ap_lookup_provider(AUTHN_PROVIDER_GROUP, arg, 
AUTHN_PROVIDER_VERSION);
+    if (provider == NULL)
+        return apr_psprintf(cmd->pool, "Unknown Authn provider: %s", arg);
+    if (!provider->check_password)
+        return apr_psprintf(cmd->pool, "The '%s' Authn provider doesn't 
support password authentication", arg);
+    dc.apcs = append<AuthnProviderConf>(dc.apcs, 
mklist<AuthnProviderConf>(AuthnProviderConf(arg, provider)));
+    return NULL;
+}
 
 /**
  * HTTP server module declaration.
  */
 const command_rec commands[] = {
+    AP_INIT_ITERATE("AuthOAuthProvider", (const char*(*)())confAuthnProvider, 
NULL, OR_AUTHCFG, "Auth providers for a directory or location"),
     AP_INIT_TAKE3("AddAuthOAuth2AppKey", (const char*(*)())confAppKey, NULL, 
RSRC_CONF, "OAuth 2.0 name app-id app-key"),
     AP_INIT_ITERATE("AddAuthOAuthMemcached", (const char*(*)())confMemcached, 
NULL, RSRC_CONF, "Memcached server host:port"),
     AP_INIT_FLAG("AuthOAuth", (const char*(*)())confEnabled, NULL, OR_AUTHCFG, 
"OAuth 2.0 authentication On | Off"),

Modified: tuscany/sca-cpp/trunk/modules/oauth/oauth-conf
URL: 
http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/oauth/oauth-conf?rev=1361915&r1=1361914&r2=1361915&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/oauth/oauth-conf (original)
+++ tuscany/sca-cpp/trunk/modules/oauth/oauth-conf Mon Jul 16 06:47:49 2012
@@ -39,18 +39,23 @@ else
     sslsuffix="-ssl"
 fi
 
+if [ "$2" = "" ]; then
+    providers="file"
+else
+    providers="$2 file"
+fi
+
 # Configure HTTPD mod_tuscany_oauth module
 cat >>$root/conf/modules.conf <<EOF
 # Generated by: oauth-conf $*
 # Load support for OAuth authentication
-LoadModule mod_tuscany_oauth1 $here/libmod_tuscany_oauth1$libsuffix
 LoadModule mod_tuscany_oauth2 $here/libmod_tuscany_oauth2$libsuffix
 
 EOF
 
 # Disallow public access to server resources
 cat >$root/conf/noauth$sslsuffix.conf <<EOF
-# Generated by: oauth-auth-conf $*
+# Generated by: oauth-conf $*
 # Disallow public access to server resources
 
 EOF
@@ -62,9 +67,12 @@ cat >>$root/conf/locauth$sslsuffix.conf 
 <Location />
 AuthType Open
 AuthName "$host"
+AuthOAuthProvider socache $providers
+AuthnCacheProvideFor $providers
+AuthnCacheContext /
 Require valid-user
 AuthOAuth On
-AuthOAuthLoginPage /login
+AuthOAuthLoginPage /login/
 AddAuthOAuth2ScopeAttr REALM realm
 AddAuthOAuth2ScopeAttr REMOTE_USER email
 AddAuthOAuth2ScopeAttr EMAIL email
@@ -72,13 +80,7 @@ AddAuthOAuth2ScopeAttr NICKNAME name
 AddAuthOAuth2ScopeAttr FULLNAME name
 AddAuthOAuth2ScopeAttr FIRSTNAME first_name
 AddAuthOAuth2ScopeAttr LASTNAME last_name
-AddAuthOAuth1ScopeAttr REALM realm
-AddAuthOAuth1ScopeAttr REMOTE_USER email
-AddAuthOAuth1ScopeAttr EMAIL email
-AddAuthOAuth1ScopeAttr NICKNAME screen_name
 AddAuthOAuth2ScopeAttr FULLNAME name
-AddAuthOAuth1ScopeAttr FIRSTNAME first-name
-AddAuthOAuth1ScopeAttr LASTNAME last-name
 </Location>
 
 EOF

Copied: tuscany/sca-cpp/trunk/modules/oauth/oauth12-conf (from r1361914, 
tuscany/sca-cpp/trunk/modules/oauth/oauth-conf)
URL: 
http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/oauth/oauth12-conf?p2=tuscany/sca-cpp/trunk/modules/oauth/oauth12-conf&p1=tuscany/sca-cpp/trunk/modules/oauth/oauth-conf&r1=1361914&r2=1361915&rev=1361915&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/oauth/oauth-conf (original)
+++ tuscany/sca-cpp/trunk/modules/oauth/oauth12-conf Mon Jul 16 06:47:49 2012
@@ -39,9 +39,15 @@ else
     sslsuffix="-ssl"
 fi
 
+if [ "$2" = "" ]; then
+    providers="file"
+else
+    providers="$2 file"
+fi
+
 # Configure HTTPD mod_tuscany_oauth module
 cat >>$root/conf/modules.conf <<EOF
-# Generated by: oauth-conf $*
+# Generated by: oauth12-conf $*
 # Load support for OAuth authentication
 LoadModule mod_tuscany_oauth1 $here/libmod_tuscany_oauth1$libsuffix
 LoadModule mod_tuscany_oauth2 $here/libmod_tuscany_oauth2$libsuffix
@@ -50,21 +56,24 @@ EOF
 
 # Disallow public access to server resources
 cat >$root/conf/noauth$sslsuffix.conf <<EOF
-# Generated by: oauth-auth-conf $*
+# Generated by: oauth12-conf $*
 # Disallow public access to server resources
 
 EOF
 
 # Configure OAuth authentication
 cat >>$root/conf/locauth$sslsuffix.conf <<EOF
-# Generated by: oauth-conf $*
+# Generated by: oauth12-conf $*
 # Enable OAuth authentication
 <Location />
 AuthType Open
 AuthName "$host"
+AuthOAuthProvider socache $providers
+AuthnCacheProvideFor $providers
+AuthnCacheContext /
 Require valid-user
 AuthOAuth On
-AuthOAuthLoginPage /login
+AuthOAuthLoginPage /login/
 AddAuthOAuth2ScopeAttr REALM realm
 AddAuthOAuth2ScopeAttr REMOTE_USER email
 AddAuthOAuth2ScopeAttr EMAIL email
@@ -91,7 +100,7 @@ EOF
 
 mkdir -p $root/cert
 cat >$root/cert/oauth-keys.conf <<EOF
-# Generated by: oauth-conf $*
+# Generated by: oauth12-conf $*
 # OAuth App keys
 
 EOF

Modified: tuscany/sca-cpp/trunk/modules/oauth/start-mixed-test
URL: 
http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/oauth/start-mixed-test?rev=1361915&r1=1361914&r2=1361915&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/oauth/start-mixed-test (original)
+++ tuscany/sca-cpp/trunk/modules/oauth/start-mixed-test Mon Jul 16 06:47:49 
2012
@@ -38,7 +38,7 @@ rm -rf tmp
 ../openid/openid-memcached-conf tmp www.example.com 11212
 ../openid/openid-memcached-conf tmp www.example.com 11213
 
-./oauth-conf tmp
+./oauth12-conf tmp
 ./oauth-memcached-conf tmp www.example.com 11212
 ./oauth-memcached-conf tmp www.example.com 11213
 
@@ -48,13 +48,16 @@ rm -rf tmp
 ./oauth2-appkey-conf tmp facebook.com app1234 secret6789
 ./oauth2-appkey-conf tmp github.com app5678 secret8901
 
-../http/open-auth-conf tmp
-../http/passwd-auth-conf tmp foo foo
+../../modules/http/open-auth-conf tmp
 
-# For this test to work you need to add your form, oauth and open id ids
-# to the authorized user group
+# For this test to work you need to add your oauth and openid user ids to
+# the password file with a dummy 'password' password, and to the group
+# of authorized users
+../../modules/http/passwd-auth-conf tmp foo foo
 ../../modules/http/group-auth-conf tmp foo
+../../modules/http/passwd-auth-conf tmp /openid/123456 password
 ../../modules/http/group-auth-conf tmp 123456
+../../modules/http/passwd-auth-conf tmp /oauth2/[email protected] password
 ../../modules/http/group-auth-conf tmp [email protected]
 
 ../../modules/server/server-conf tmp

Modified: tuscany/sca-cpp/trunk/modules/oauth/start-test
URL: 
http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/oauth/start-test?rev=1361915&r1=1361914&r2=1361915&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/oauth/start-test (original)
+++ tuscany/sca-cpp/trunk/modules/oauth/start-test Mon Jul 16 06:47:49 2012
@@ -33,7 +33,7 @@ rm -rf tmp
 ../../modules/http/httpd-conf tmp www.example.com 8090 htdocs
 ../../modules/http/httpd-ssl-conf tmp 8453
 
-./oauth-conf tmp
+./oauth12-conf tmp
 ./oauth-memcached-conf tmp www.example.com 11212
 ./oauth-memcached-conf tmp www.example.com 11213
 
@@ -44,7 +44,9 @@ rm -rf tmp
 ./oauth2-appkey-conf tmp github.com app5678 secret8901
 
 # For this test to work you need to add your oauth user id to the
-# authorized user group
+# password file with a dummy 'password' password, and to the group
+# of authorized users
+../../modules/http/passwd-auth-conf tmp /oauth2/[email protected] password
 ../../modules/http/group-auth-conf tmp [email protected]
 
 ../../modules/server/server-conf tmp

Modified: tuscany/sca-cpp/trunk/modules/openid/openid-conf
URL: 
http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/openid/openid-conf?rev=1361915&r1=1361914&r2=1361915&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/openid/openid-conf (original)
+++ tuscany/sca-cpp/trunk/modules/openid/openid-conf Mon Jul 16 06:47:49 2012
@@ -33,6 +33,12 @@ else
     sslsuffix="-ssl"
 fi
 
+if [ "$2" = "" ]; then
+    providers="file"
+else
+    providers="$2"
+fi
+
 # Configure HTTPD mod_auth_openid module
 cat >>$root/conf/modules.conf <<EOF
 # Generated by: openid-conf $*
@@ -55,6 +61,9 @@ cat >>$root/conf/locauth$sslsuffix.conf 
 <Location />
 AuthType Open
 AuthName "$host"
+#AuthOpenIDProvider socache $providers
+#AuthnCacheProvideFor $providers
+#AuthnCacheContext /
 Require valid-user
 AuthOpenIDEnabled On
 AuthOpenIDCookiePath /

Modified: tuscany/sca-cpp/trunk/modules/openid/start-test
URL: 
http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/openid/start-test?rev=1361915&r1=1361914&r2=1361915&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/openid/start-test (original)
+++ tuscany/sca-cpp/trunk/modules/openid/start-test Mon Jul 16 06:47:49 2012
@@ -32,8 +32,10 @@ rm -rf tmp
 ./openid-memcached-conf tmp localhost 11213
 ./openid-step2-conf tmp
 
-# For this test to work you need to add your openid (or email address if
-# available from your openid attributes to the the authorized user group
+# For this test to work you need to add your openid user id to the
+# password file with a dummy 'password' password, and to the group
+# of authorized users
+../../modules/http/passwd-auth-conf tmp /openid/[email protected] password
 ../../modules/http/group-auth-conf tmp [email protected]
 
 ../../modules/server/server-conf tmp

Modified: tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp
URL: 
http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp?rev=1361915&r1=1361914&r2=1361915&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp Mon Jul 16 06:47:49 2012
@@ -43,6 +43,10 @@
 #include "../http/http.hpp"
 #include "../http/httpd.hpp"
 
+#include "apr_md5.h"
+#include "ap_provider.h"
+#include "mod_auth.h"
+
 extern "C" {
 extern module AP_MODULE_DECLARE_DATA mod_tuscany_eval;
 }
@@ -75,8 +79,10 @@ public:
     string domain;
     string contribPath;
     string composName;
-    string providerName;
-    value provider;
+    string contributorName;
+    value contributor;
+    string authenticatorName;
+    value authenticator;
 };
 
 /**
@@ -115,7 +121,7 @@ public:
     ServerConf() {
     }
 
-    ServerConf(apr_pool_t* p, const server_rec* s) : p(p), server(s) {
+    ServerConf(apr_pool_t* p, const server_rec* s) : p(p), server(s), 
timeout(0) {
     }
 
     const gc_pool p;
@@ -123,6 +129,7 @@ public:
     lambda<value(const list<value>&)> lifecycle;
     ContribConf contribc;
     SSLConf sslc;
+    int timeout;
     VhostConf vhostc;
     Composite compos;
 };
@@ -145,7 +152,12 @@ public:
 };
 
 /**
- * Convert a result represented as a content + failure pair to a
+ * Authentication cache store function.
+ */
+static APR_OPTIONAL_FN_TYPE(ap_authn_cache_store) *authnCacheStore = NULL;
+
+/**
+ * Convert a result represented as a (content reason? code?) tuple to a
  * failable monad.
  */
 const failable<value> failableResult(const list<value>& v) {
@@ -177,9 +189,9 @@ public:
 /**
  * Make an HTTP proxy lambda to an absolute URI
  */
-const value mkhttpProxy(const string& uri, const gc_pool& p) {
+const value mkhttpProxy(const string& uri, const int timeout, const gc_pool& 
p) {
     debug(uri, "modeval::mkhttpProxy::uri");
-    return lambda<value(const list<value>&)>(http::proxy(uri, "", "", "", "", 
p));
+    return lambda<value(const list<value>&)>(http::proxy(uri, "", "", "", "", 
timeout, p));
 }
 
 /**
@@ -187,7 +199,7 @@ const value mkhttpProxy(const string& ur
  */
 class implProxy {
 public:
-    implProxy(const value& name, const list<value>& impls, const SSLConf& 
sslc) : name(name), impls(impls), sslc(sslc) {
+    implProxy(const value& name, const list<value>& impls, const SSLConf& 
sslc, const int timeout) : name(name), impls(impls), sslc(sslc), 
timeout(timeout) {
     }
 
     const value callImpl(const value& cname, const list<value>& aparams) const 
{
@@ -229,7 +241,7 @@ public:
                     ostringstream appuri;
                     appuri << httpd::scheme(currentRequest) << "://" << 
substr(uri, 6) << "." << http::topDomain(httpd::hostName(currentRequest)) << 
":" << httpd::port(currentRequest) << "/";
                     debug(str(appuri), 
"modeval::implProxy::httpproxy::appuri");
-                    const lambda<value(const list<value>&)> px = 
lambda<value(const list<value>&)>(http::proxy(str(appuri), sslc.ca, sslc.cert, 
sslc.key, httpd::cookie(currentRequest), p));
+                    const lambda<value(const list<value>&)> px = 
lambda<value(const list<value>&)>(http::proxy(str(appuri), sslc.ca, sslc.cert, 
sslc.key, httpd::cookie(currentRequest), timeout, p));
                     return px(aparams);
                 }
                 
@@ -237,13 +249,13 @@ public:
                 // only if the target is in the same top level domain
                 if (http::topDomain(http::hostName(uri, p)) == 
http::topDomain(httpd::hostName(currentRequest))) {
                     debug(uri, "modeval::implProxy::httpproxy::samedomain");
-                    const lambda<value(const list<value>&)> px = 
lambda<value(const list<value>&)>(http::proxy(uri, sslc.ca, sslc.cert, 
sslc.key, httpd::cookie(currentRequest), p));
+                    const lambda<value(const list<value>&)> px = 
lambda<value(const list<value>&)>(http::proxy(uri, sslc.ca, sslc.cert, 
sslc.key, httpd::cookie(currentRequest), timeout, p));
                     return px(aparams);
                 }
 
                 // No SSL certificate or cookie on a cross domain call
                 debug(uri, "modeval::implProxy::httpproxy::crossdomain");
-                const lambda<value(const list<value>&)> px = 
lambda<value(const list<value>&)>(http::proxy(uri, "", "", "", "", p));
+                const lambda<value(const list<value>&)> px = 
lambda<value(const list<value>&)>(http::proxy(uri, "", "", "", "", timeout, p));
                 return px(aparams);
             }
 
@@ -259,11 +271,12 @@ private:
     const value name;
     const list<value>& impls;
     const SSLConf& sslc;
+    const int timeout;
 };
 
-const value mkimplProxy(const value& name, const list<value>& impls, const 
SSLConf& sslc) {
+const value mkimplProxy(const value& name, const list<value>& impls, const 
SSLConf& sslc, const int timeout) {
     debug(name, "modeval::implProxy::impl");
-    return lambda<value(const list<value>&)>(implProxy(name, impls, sslc));
+    return lambda<value(const list<value>&)>(implProxy(name, impls, sslc, 
timeout));
 }
 
 /**
@@ -303,7 +316,7 @@ const value mkunwiredProxy(const string&
 /**
  * Convert a list of component references to a list of proxy lambdas.
  */
-const value mkrefProxy(const value& ref, const list<value>& impls, const 
SSLConf& sslc, const gc_pool& p) {
+const value mkrefProxy(const value& ref, const list<value>& impls, const 
SSLConf& sslc, const int timeout, const gc_pool& p) {
     const value target = scdl::target(ref);
     const bool wbyimpl = scdl::wiredByImpl(ref);
     debug(ref, "modeval::mkrefProxy::ref");
@@ -312,18 +325,18 @@ const value mkrefProxy(const value& ref,
 
     // Use an HTTP proxy or an internal proxy to the component implementation
     if (wbyimpl)
-        return mkimplProxy(value(), impls, sslc);
+        return mkimplProxy(value(), impls, sslc, timeout);
     if (isNil(target))
         return mkunwiredProxy(scdl::name(ref));
     if (http::isAbsolute(target))
-        return mkhttpProxy(target, p);
-    return mkimplProxy(car(pathValues(target)), impls, sslc);
+        return mkhttpProxy(target, timeout, p);
+    return mkimplProxy(car(pathValues(target)), impls, sslc, timeout);
 }
 
-const list<value> refProxies(const list<value>& refs, const list<value>& 
impls, const SSLConf& sslc, const gc_pool& p) {
+const list<value> refProxies(const list<value>& refs, const list<value>& 
impls, const SSLConf& sslc, const int timeout, const gc_pool& p) {
     if (isNil(refs))
         return refs;
-    return cons(mkrefProxy(car(refs), impls, sslc, p), refProxies(cdr(refs), 
impls, sslc, p));
+    return cons(mkrefProxy(car(refs), impls, sslc, timeout, p), 
refProxies(cdr(refs), impls, sslc, timeout, p));
 }
 
 /**
@@ -422,15 +435,29 @@ struct realmPropProxy {
         const char* env = apr_table_get(currentRequest->subprocess_env, 
"REALM");
         if (env == NULL)
             return v;
-        const char* realm = strncmp(env, "www.", 4) == 0? env + 4 : env;
-        if (*realm == '\0')
+        const string realm = httpd::realm(string(env));
+        if (length(realm) == 0)
             return v;
-        const value r = string(realm);
+        const value r = realm;
         debug(r, "modeval::realmPropProxy::value");
         return r;
     }
 };
 
+struct timeoutPropProxy {
+    const value v;
+    timeoutPropProxy(const value& v) : v(atoi(c_str((string)v))) {
+    }
+    const value operator()(unused const list<value>& params) const {
+        if (currentRequest == NULL)
+            return v;
+        const ServerConf& sc = httpd::serverConf<ServerConf>(currentRequest, 
&mod_tuscany_eval);
+        const value r = sc.timeout;
+        debug(r, "modeval::timeoutPropProxy::value");
+        return r;
+    }
+};
+
 struct userPropProxy {
     const value v;
     userPropProxy(const value& v) : v(v) {
@@ -461,6 +488,8 @@ const value mkpropProxy(const value& pro
         return lambda<value(const list<value>&)>(userPropProxy(v));
     if (n == "realm")
         return lambda<value(const list<value>&)>(realmPropProxy(v));
+    if (n == "timeout")
+        return lambda<value(const list<value>&)>(timeoutPropProxy(v));
     if (n == "email")
         return lambda<value(const list<value>&)>(envPropProxy("EMAIL", v));
     if (n == "nickname")
@@ -499,7 +528,7 @@ struct implementationFailure {
     }
 };
 
-const value evalComponent(const string& contribPath, const value& comp, const 
list<value>& impls, const lambda<value(const list<value>&)> lifecycle, const 
SSLConf& sslc, const gc_pool& p) {
+const value evalComponent(const string& contribPath, const value& comp, const 
list<value>& impls, const lambda<value(const list<value>&)> lifecycle, const 
SSLConf& sslc, const int timeout, const gc_pool& p) {
     extern const failable<lambda<value(const list<value>&)> > 
evalImplementation(const string& cpath, const value& impl, const list<value>& 
px, const lambda<value(const list<value>&)>& lifecycle);
 
     const value impl = scdl::implementation(comp);
@@ -507,7 +536,7 @@ const value evalComponent(const string& 
     debug(impl, "modeval::evalComponent::impl");
 
     // Convert component references to configured proxy lambdas
-    const list<value> rpx(refProxies(scdl::references(comp), impls, sslc, p));
+    const list<value> rpx(refProxies(scdl::references(comp), impls, sslc, 
timeout, p));
 
     // Convert component properties to configured proxy lambdas
     const list<value> ppx(propProxies(scdl::properties(comp)));
@@ -522,12 +551,12 @@ const value evalComponent(const string& 
 /**
  * Return a list of component-name + configured-implementation pairs.
  */
-const list<value> componentToImplementationAssoc(const list<value>& c, const 
string& contribPath, const list<value>& impls, const lambda<value(const 
list<value>&)> lifecycle, const SSLConf& sslc, const gc_pool& p) {
+const list<value> componentToImplementationAssoc(const list<value>& c, const 
string& contribPath, const list<value>& impls, const lambda<value(const 
list<value>&)> lifecycle, const SSLConf& sslc, const int timeout, const 
gc_pool& p) {
     if (isNil(c))
         return c;
     return cons<value>(mklist<value>(scdl::name(car(c)),
-                evalComponent(contribPath, car(c), impls, lifecycle, sslc, p)),
-                    componentToImplementationAssoc(cdr(c), contribPath, impls, 
lifecycle, sslc, p));
+                evalComponent(contribPath, car(c), impls, lifecycle, sslc, 
timeout, p)),
+                    componentToImplementationAssoc(cdr(c), contribPath, impls, 
lifecycle, sslc, timeout, p));
 }
 
 /**
@@ -541,16 +570,17 @@ const failable<list<value> > readCompone
 }
 
 /**
- * Get the components returned by a provider.
+ * Get the components returned by a contributor.
  */
-const failable<list<value> > getComponents(const lambda<value(const 
list<value>&)>& provider, const string& name) {
-    const failable<value> val = failableResult(provider(cons<value>("get", 
mklist<value>(mklist<value>(name)))));
+const failable<list<value> > getComponents(const lambda<value(const 
list<value>&)>& contributor, const string& name) {
+    const failable<value> val = failableResult(contributor(cons<value>("get", 
mklist<value>(mklist<value>(name)))));
     if (!hasContent(val))
         return mkfailure<list<value> >(val);
-    const list<value> c = assoc<value>(value("content"), (list<list<value> 
>)cdr<value>(content(val)));
+    const list<value> c = assoc<value>(value("composite"), 
assoc<value>(value("content"), (list<list<value> 
>)cdr<value>(car<value>(content(val)))));
+    debug(c, "modeval::getComponents::comp");
     if (isNil(c))
         return mkfailure<list<value> >(string("Could not get composite: ") + 
name);
-    const failable<list<string> > x = 
writeXML(car<value>(valuesToElements(mklist<value>(mklist<value>(cadr(c))))));
+    const failable<list<string> > x = 
writeXML(car<value>(valuesToElements(mklist<value>(mklist<value>(c)))));
     if (!hasContent(x))
         return mkfailure<list<value> >(x);
     return scdl::components(readXML(content(x)));
@@ -631,16 +661,16 @@ const list<value> uriToComponentAssoc(co
 /**
  * Configure the components declared in the deployed composite.
  */
-const failable<Composite> confComponents(const string& contribPath, const 
string& composName, const value& provider, const string& vhost, const 
list<value>& impls, const lambda<value(const list<value>&)> lifecycle, const 
SSLConf& sslc, const gc_pool& p) {
+const failable<Composite> confComponents(const string& contribPath, const 
string& composName, const value& contributor, const string& vhost, const 
list<value>& impls, const lambda<value(const list<value>&)> lifecycle, const 
SSLConf& sslc, const int timeout, const gc_pool& p) {
     debug(contribPath, "modeval::confComponents::contribPath");
     debug(composName, "modeval::confComponents::composName");
-    debug(provider, "modeval::confComponents::provider");
+    debug(contributor, "modeval::confComponents::contributor");
     debug(vhost, "modeval::confComponents::vhost");
     debug(impls, "modeval::confComponents::impls");
 
-    const failable<list<value> > fcomps = isNil(provider)?
+    const failable<list<value> > fcomps = isNil(contributor)?
         readComponents(scdl::resourcePath(length(vhost) != 0? contribPath + 
vhost + "/" : contribPath, composName)) :
-        getComponents(provider, vhost);
+        getComponents(contributor, vhost);
     if (!hasContent(fcomps))
         return mkfailure<Composite>(fcomps);
 
@@ -654,8 +684,8 @@ const failable<Composite> confComponents
     debug(flatten(svcs), "modeval::confComponents::svcs");
 
     const list<value> cimpls = 
mkbtree(sort(componentToImplementationAssoc(comps,
-                    isNil(provider)? length(vhost) != 0? contribPath + vhost + 
"/" : contribPath : contribPath,
-                    impls, lifecycle, sslc, p)));
+                    isNil(contributor)? length(vhost) != 0? contribPath + 
vhost + "/" : contribPath : contribPath,
+                    impls, lifecycle, sslc, timeout, p)));
     debug(flatten(cimpls), "modeval::confComponents::impls");
 
     return Composite(refs, svcs, cimpls);
@@ -720,6 +750,10 @@ const failable<int> get(const list<value
     const value c = content(val);
     debug(c, "modeval::get::content");
 
+    // Return a nil value as a not found status
+    if (!isList(c) && isNil(c))
+        return HTTP_NOT_FOUND;
+
     // Check if the client requested a specific format
     const list<value> fmt = assoc<value>("format", args);
 
@@ -735,6 +769,7 @@ const failable<int> get(const list<value
             debug(lc, "modeval::get::symbol");
             return httpd::writeResult(json::writeJSON(valuesToElements(lc), 
cx), "application/json; charset=utf-8", r);
         }
+
         const list<value> lc = mklist<value>(mklist<value>("value", c));
         debug(lc, "modeval::get::value");
         return httpd::writeResult(json::writeJSON(valuesToElements(lc), cx), 
"application/json; charset=utf-8", r);
@@ -1041,9 +1076,9 @@ const int translateRequest(request_rec* 
 
     // Attempt to map a request targeting the main host to an actual file
     if (isNil(vpath)) {
-        const failable<request_rec*, int> fnr = 
httpd::internalSubRequest(r->uri, r);
+        const failable<request_rec*> fnr = httpd::internalSubRequest(r->uri, 
r);
         if (!hasContent(fnr))
-            return HTTP_INTERNAL_SERVER_ERROR;
+            return rcode(fnr);
         request_rec* nr = content(fnr);
         nr->uri = r->filename;
         const int tr = ap_core_translate(nr);
@@ -1082,7 +1117,6 @@ int translate(request_rec *r) {
     if(r->method_number != M_GET && r->method_number != M_POST && 
r->method_number != M_PUT && r->method_number != M_DELETE)
         return DECLINED;
 
-    // Create a scoped memory pool
     gc_scoped_pool pool(r->pool);
 
     debug_httpdRequest(r, "modeval::translate::input");
@@ -1103,9 +1137,9 @@ int translate(request_rec *r) {
 
     // If the request is targeting a virtual host, configure the components
     // in that virtual host
-    if (length(sc.vhostc.domain) != 0 && (length(sc.vhostc.contribPath) != 0 
|| !isNil(sc.vhostc.provider)) && httpd::isVhostRequest(sc.server, 
sc.vhostc.domain, r)) {
+    if (length(sc.vhostc.domain) != 0 && (length(sc.vhostc.contribPath) != 0 
|| !isNil(sc.vhostc.contributor)) && httpd::isVhostRequest(sc.server, 
sc.vhostc.domain, r)) {
         const string vname = http::subDomain(httpd::hostName(r));
-        const failable<Composite> fvcompos = 
confComponents(sc.vhostc.contribPath, sc.vhostc.composName, sc.vhostc.provider, 
vname, reqc.impls, sc.lifecycle, sc.sslc, sc.p);
+        const failable<Composite> fvcompos = 
confComponents(sc.vhostc.contribPath, sc.vhostc.composName, 
sc.vhostc.contributor, vname, reqc.impls, sc.lifecycle, sc.sslc, sc.timeout, 
sc.p);
         if (!hasContent(fvcompos))
             return DECLINED;
         const Composite vcompos = content(fvcompos);
@@ -1124,9 +1158,9 @@ int translate(request_rec *r) {
         return rc;
 
     // Attempt to map the first segment of the request path to a virtual host
-    if (length(prefix) != 0 && (length(sc.vhostc.contribPath) != 0 || 
!isNil(sc.vhostc.provider))) {
+    if (length(prefix) != 0 && (length(sc.vhostc.contribPath) != 0 || 
!isNil(sc.vhostc.contributor))) {
         const string vname = prefix;
-        const failable<Composite> fvcompos = 
confComponents(sc.vhostc.contribPath, sc.vhostc.composName, sc.vhostc.provider, 
vname, reqc.impls, sc.lifecycle, sc.sslc, sc.p);
+        const failable<Composite> fvcompos = 
confComponents(sc.vhostc.contribPath, sc.vhostc.composName, 
sc.vhostc.contributor, vname, reqc.impls, sc.lifecycle, sc.sslc, sc.timeout, 
sc.p);
         if (!hasContent(fvcompos))
             return DECLINED;
         const Composite vcompos = content(fvcompos);
@@ -1150,9 +1184,9 @@ const int handleRequest(const list<value
         mkfailure<int>(string("Couldn't find component implementation: ") + 
cadr(rpath));
         return HTTP_NOT_FOUND;
     }
+    const lambda<value(const list<value>&)> l(cadr<value>(impl));
 
     // Handle HTTP method
-    const lambda<value(const list<value>&)> l(cadr<value>(impl));
     if (r->header_only)
          return OK;
     if(r->method_number == M_GET)
@@ -1182,7 +1216,7 @@ int handler(request_rec *r) {
     if(strcmp(r->handler, "mod_tuscany_eval"))
         return DECLINED;
 
-    // Create a scoped memory pool and a scope for the current request
+    // Create a scope for the current request
     gc_scoped_pool pool(r->pool);
     ScopedRequest sr(r);
 
@@ -1228,6 +1262,61 @@ int handler(request_rec *r) {
 }
 
 /**
+ * Call an authenticator component to check a user's password.
+ */
+authn_status checkPassword(request_rec* r, const char* u, const char* p) {
+    gc_scoped_pool pool(r->pool);
+
+    // Prevent FakeBasicAuth spoofing
+    const string user = u;
+    const string password = p;
+    debug(user, "modeval::checkPassword::user");
+    if (substr(user, 0, 1) != "/" && find(user, "/") != length(user) && 
password == "password") {
+        mkfailure<int>(string("Encountered FakeBasicAuth spoof: ") + user, 
HTTP_UNAUTHORIZED);
+        return AUTH_DENIED;
+    }
+
+    // Get the server configuration
+    const ServerConf& sc = httpd::serverConf<ServerConf>(r, &mod_tuscany_eval);
+    if (isNil(sc.vhostc.authenticator)) {
+        mkfailure<int>("SCA authenticator not configured");
+        return AUTH_GENERAL_ERROR;
+    }
+
+    // Retrieve the user's password hash
+    const list<value> uid = pathValues(user);
+    const failable<value> val = 
failableResult(sc.vhostc.authenticator(cons<value>("get", mklist<value>(uid))));
+    if (!hasContent(val)) {
+        mkfailure<int>(string("SCA authentication check user failed, user not 
found: ") + user);
+        return AUTH_USER_NOT_FOUND;
+    }
+    const value hval = content(val);
+    const list<value> hcontent = isList(hval) && !isNil(hval) && 
isList(car<value>(hval)) && !isNil(car<value>(hval))?  
assoc<value>(value("content"), cdr<value>(car<value>(hval))) : list<value>();
+    const list<value> hassoc = isNil(hcontent)? list<value>() : 
assoc<value>(value("hash"), cdr<value>(hcontent));
+    if (isNil(hassoc)) {
+        mkfailure<int>(string("SCA authentication check user failed, hash not 
found: ") + user);
+        return AUTH_USER_NOT_FOUND;
+    }
+    const string hash = cadr<value>(hassoc);
+    if (length(hash) == 0) {
+        mkfailure<int>(string("SCA authentication check user failed: ") + 
user);
+        return AUTH_USER_NOT_FOUND;
+    }
+
+    // Cache the hash in the auth cache provider, if available
+    if (authnCacheStore != NULL)
+        authnCacheStore(r, "component", u, NULL, c_str(hash));
+
+    // Validate the presented password against the hash
+    const apr_status_t rv = apr_password_validate(p, c_str(hash));
+    if (rv != APR_SUCCESS) {
+        mkfailure<int>(string("SCA authentication user password check failed: 
") + user);
+        return AUTH_DENIED;
+    }
+    return AUTH_GRANTED;
+}
+
+/**
  * Cleanup callback, called when the server is stopped or restarted.
  */
 apr_status_t serverCleanup(void* v) {
@@ -1262,6 +1351,7 @@ const int postConfigMerge(const ServerCo
     if (sc.sslc.ca == "") sc.sslc.ca = mainsc.sslc.ca;
     if (sc.sslc.cert == "") sc.sslc.cert = mainsc.sslc.cert;
     if (sc.sslc.key == "") sc.sslc.key = mainsc.sslc.key;
+    sc.timeout = mainsc.timeout;
     sc.compos = mainsc.compos;
     return postConfigMerge(mainsc, s->next);
 }
@@ -1311,7 +1401,7 @@ int postConfig(apr_pool_t *p, unused apr
     }
 
     // Configure the deployed components
-    const failable<Composite> compos = confComponents(sc.contribc.contribPath, 
sc.contribc.composName, value(), "", sc.compos.impls, sc.lifecycle, sc.sslc, 
sc.p);
+    const failable<Composite> compos = confComponents(sc.contribc.contribPath, 
sc.contribc.composName, value(), "", sc.compos.impls, sc.lifecycle, sc.sslc, 
sc.timeout, sc.p);
     if (!hasContent(compos)) {
         cfailure << "[Tuscany] Due to one or more errors mod_tuscany_eval 
loading failed. Causing apache to stop loading." << endl;
         return -1;
@@ -1326,28 +1416,49 @@ int postConfig(apr_pool_t *p, unused apr
 }
 
 /**
+ * Exit after a failure.
+ */
+void failureExitChild() {
+    cfailure << "[Tuscany] Due to one or more errors mod_tuscany_eval loading 
failed. Causing apache to stop loading." << endl;
+    exit(APEXIT_CHILDFATAL);
+}
+
+/**
  * Child process initialization.
  */
 void childInit(apr_pool_t* p, server_rec* s) {
     gc_scoped_pool pool(p);
+
     ServerConf* psc = (ServerConf*)ap_get_module_config(s->module_config, 
&mod_tuscany_eval);
-    if(psc == NULL) {
-        cfailure << "[Tuscany] Due to one or more errors mod_tuscany_eval 
loading failed. Causing apache to stop loading." << endl;
-        exit(APEXIT_CHILDFATAL);
-    }
+    if(psc == NULL)
+        failureExitChild();
     ServerConf& sc = *psc;
 
     // Start the components in the child process
     const failable<list<value> > fsimpls = startComponents(sc.compos.impls);
-    if (!hasContent(fsimpls)) {
-        cfailure << "[Tuscany] Due to one or more errors mod_tuscany_eval 
loading failed. Causing apache to stop loading." << endl;
-        exit(APEXIT_CHILDFATAL);
-    }
+    if (!hasContent(fsimpls))
+        failureExitChild();
     sc.compos.impls = content(fsimpls);
     
-    // Create a proxy for the vhost provider if needed
-    if (length(sc.vhostc.providerName) != 0) 
-        sc.vhostc.provider = mkimplProxy(sc.vhostc.providerName, 
sc.compos.impls, sc.sslc);
+    // Get the vhost contributor component implementation lambda
+    if (length(sc.vhostc.contributorName) != 0) {
+        const list<value> impl(assoctree<value>(sc.vhostc.contributorName, 
sc.compos.impls));
+        if (isNil(impl)) {
+            mkfailure<int>(string("Couldn't find contributor component 
implementation: ") + sc.vhostc.contributorName);
+            failureExitChild();
+        }
+        sc.vhostc.contributor = cadr<value>(impl);
+    }
+
+    // Get the vhost authenticator component implementation lambda
+    if (length(sc.vhostc.authenticatorName) != 0) {
+        const list<value> impl(assoctree<value>(sc.vhostc.authenticatorName, 
sc.compos.impls));
+        if (isNil(impl)) {
+            mkfailure<int>(string("Couldn't find authenticator component 
implementation: ") + sc.vhostc.authenticatorName);
+            failureExitChild();
+        }
+        sc.vhostc.authenticator = cadr<value>(impl);
+    }
 
     // Merge the updated configuration into the virtual hosts
     postConfigMerge(sc, s->next);
@@ -1383,10 +1494,10 @@ const char* confVirtualContribution(cmd_
     sc.vhostc.contribPath = arg;
     return NULL;
 }
-const char* confVirtualprovider(cmd_parms *cmd, unused void *c, const char 
*arg) {
+const char* confVirtualContributor(cmd_parms *cmd, unused void *c, const char 
*arg) {
     gc_scoped_pool pool(cmd->pool);
     ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval);
-    sc.vhostc.providerName = arg;
+    sc.vhostc.contributorName = arg;
     return NULL;
 }
 const char* confVirtualComposite(cmd_parms *cmd, unused void *c, const char 
*arg) {
@@ -1395,6 +1506,12 @@ const char* confVirtualComposite(cmd_par
     sc.vhostc.composName = arg;
     return NULL;
 }
+const char* confAuthenticator(cmd_parms *cmd, unused void *c, const char *arg) 
{
+    gc_scoped_pool pool(cmd->pool);
+    ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval);
+    sc.vhostc.authenticatorName = arg;
+    return NULL;
+}
 const char* confCAFile(cmd_parms *cmd, unused void *c, const char *arg) {
     gc_scoped_pool pool(cmd->pool);
     ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval);
@@ -1413,6 +1530,12 @@ const char* confCertKeyFile(cmd_parms *c
     sc.sslc.key = arg;
     return NULL;
 }
+const char* confTimeout(cmd_parms *cmd, unused void *c, const char *arg) {
+    gc_scoped_pool pool(cmd->pool);
+    ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval);
+    sc.timeout = atoi(arg);
+    return NULL;
+}
 const char* confEnv(unused cmd_parms *cmd, unused void *c, const char *name, 
const char *value) {
     gc_scoped_pool pool(cmd->pool);
     setenv(name, value != NULL? value : "", 1);
@@ -1427,20 +1550,33 @@ const command_rec commands[] = {
     AP_INIT_TAKE1("SCAComposite", (const char*(*)())confComposite, NULL, 
RSRC_CONF, "SCA composite location"),
     AP_INIT_TAKE1("SCAVirtualDomain", (const char*(*)())confVirtualDomain, 
NULL, RSRC_CONF, "SCA virtual host domain"),
     AP_INIT_TAKE1("SCAVirtualContribution", (const 
char*(*)())confVirtualContribution, NULL, RSRC_CONF, "SCA virtual host 
contribution path"),
-    AP_INIT_TAKE1("SCAVirtualContributor", (const 
char*(*)())confVirtualprovider, NULL, RSRC_CONF, "SCA virtual host provider 
component"),
+    AP_INIT_TAKE1("SCAVirtualContributor", (const 
char*(*)())confVirtualContributor, NULL, RSRC_CONF, "SCA virtual host 
contributor component"),
     AP_INIT_TAKE1("SCAVirtualComposite", (const 
char*(*)())confVirtualComposite, NULL, RSRC_CONF, "SCA virtual composite 
location"),
+    AP_INIT_TAKE1("SCAAuthenticator", (const char*(*)())confAuthenticator, 
NULL, RSRC_CONF, "SCA authenticator component"),
     AP_INIT_TAKE12("SCASetEnv", (const char*(*)())confEnv, NULL, OR_FILEINFO, 
"Environment variable name and optional value"),
     AP_INIT_TAKE1("SCAWiringSSLCACertificateFile", (const 
char*(*)())confCAFile, NULL, RSRC_CONF, "SCA wiring SSL CA certificate file"),
     AP_INIT_TAKE1("SCAWiringSSLCertificateFile", (const 
char*(*)())confCertFile, NULL, RSRC_CONF, "SCA wiring SSL certificate file"),
     AP_INIT_TAKE1("SCAWiringSSLCertificateKeyFile", (const 
char*(*)())confCertKeyFile, NULL, RSRC_CONF, "SCA wiring SSL certificate key 
file"),
+    AP_INIT_TAKE1("SCAWiringTimeout", (const char*(*)())confTimeout, NULL, 
RSRC_CONF, "SCA wiring timeout"),
     {NULL, NULL, NULL, 0, NO_ARGS, NULL}
 };
 
 
+const authn_provider AuthnProvider = {
+    &checkPassword,
+    NULL
+};
+
+void retrieveAuthnCacheStore() {
+    authnCacheStore = APR_RETRIEVE_OPTIONAL_FN(ap_authn_cache_store);
+}
+
 void registerHooks(unused apr_pool_t *p) {
     ap_hook_post_config(postConfig, NULL, NULL, APR_HOOK_MIDDLE);
     ap_hook_child_init(childInit, NULL, NULL, APR_HOOK_MIDDLE);
     ap_hook_handler(handler, NULL, NULL, APR_HOOK_MIDDLE);
+    ap_register_auth_provider(p, AUTHN_PROVIDER_GROUP, "component", 
AUTHN_PROVIDER_VERSION, &AuthnProvider, AP_AUTH_INTERNAL_PER_CONF);
+    ap_hook_optional_fn_retrieve(retrieveAuthnCacheStore, NULL, NULL, 
APR_HOOK_MIDDLE);
 }
 
 }

Modified: tuscany/sca-cpp/trunk/samples/store-cluster/tunnel-ssl-conf
URL: 
http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/samples/store-cluster/tunnel-ssl-conf?rev=1361915&r1=1361914&r2=1361915&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/samples/store-cluster/tunnel-ssl-conf (original)
+++ tuscany/sca-cpp/trunk/samples/store-cluster/tunnel-ssl-conf Mon Jul 16 
06:47:49 2012
@@ -28,5 +28,6 @@ set -x
 ../../modules/http/httpd-event-conf $root
 tar -C tmp/ssl -c `../../modules/http/ssl-cert-find tmp/ssl` | tar -C $root -x
 ../../modules/http/httpd-ssl-conf $root $sslport
+../../modules/http/httpd-tunnel-ssl-conf $root
 ../../modules/http/cert-auth-conf $root
 


Reply via email to