summaryrefslogtreecommitdiffstats
path: root/sca-cpp/trunk/modules/server/mod-eval.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'sca-cpp/trunk/modules/server/mod-eval.hpp')
-rw-r--r--sca-cpp/trunk/modules/server/mod-eval.hpp258
1 files changed, 197 insertions, 61 deletions
diff --git a/sca-cpp/trunk/modules/server/mod-eval.hpp b/sca-cpp/trunk/modules/server/mod-eval.hpp
index ac5bf55698..ee99baa039 100644
--- a/sca-cpp/trunk/modules/server/mod-eval.hpp
+++ b/sca-cpp/trunk/modules/server/mod-eval.hpp
@@ -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& uri, const gc_pool& p) {
*/
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& ref) {
/**
* 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, const list<value>& impls, const SSLConf
// 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& prop) {
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& contribPath, const value& comp, const li
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& contribPath, const value& comp, const li
/**
* 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> > readComponents(const string& path) {
}
/**
- * 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(const list<value>& c) {
/**
* 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(const string& contribPath, const string
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>& rpath, request_rec* r, const lambda<v
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>& rpath, request_rec* r, const lambda<v
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* r, const list<value>& rpath, const list<
// 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>& rpath, request_rec *r, const list<val
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 ServerConf& mainsc, server_rec* s) {
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_pool_t *plog, unused apr_pool_t *ptemp,
}
// 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_pool_t *plog, unused apr_pool_t *ptemp,
}
/**
+ * 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_parms *cmd, unused void *c, const char *
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_parms *cmd, unused void *c, const char *arg
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 *cmd, unused void *c, const char *arg) {
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);
}
}