summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2009-08-19 17:38:46 +0000
committerStef Walter <stef@memberwebs.com>2009-08-19 17:38:46 +0000
commit2ba9d4412caec104410637674b179820eced7f02 (patch)
tree46643528390b55b2dc60138eaa275b3f6f44983a
parentc7c67be49fb2b7307900db7e3da4b460f5603ac6 (diff)
Support POST responses back from the provider
-rw-r--r--module/consumer.cc8
-rw-r--r--module/mod_auth_singleid.c93
-rw-r--r--module/mod_auth_singleid.h2
3 files changed, 102 insertions, 1 deletions
diff --git a/module/consumer.cc b/module/consumer.cc
index cbdcfe3..c750771 100644
--- a/module/consumer.cc
+++ b/module/consumer.cc
@@ -570,7 +570,13 @@ sid_consumer_authenticate(sid_request_t *req, sid_storage_t *store,
assert (req);
- const char *qs = sid_request_qs (req);
+ const char *qs;
+
+ if (strcmp (sid_request_method (req), "POST") == 0)
+ qs = sid_request_form (req);
+ else
+ qs = sid_request_qs (req);
+
parse_query_string (qs, params);
filter_prefixed_params (params, openid, "openid.");
diff --git a/module/mod_auth_singleid.c b/module/mod_auth_singleid.c
index 5847829..53b1f04 100644
--- a/module/mod_auth_singleid.c
+++ b/module/mod_auth_singleid.c
@@ -75,6 +75,8 @@ extern module AP_MODULE_DECLARE_DATA auth_singleid_module;
#define VALID_NAME "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-."
#define VALID_ALIAS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-"
+#define MAX_POST_SIZE 256 * 1024
+
enum {
NONE = 0,
SUFFIX = 1,
@@ -759,6 +761,97 @@ sid_request_qs (sid_request_t *req)
}
const char*
+sid_request_form (sid_request_t *req)
+{
+ int bytes, eos;
+ apr_size_t count;
+ apr_status_t rv;
+ apr_bucket_brigade *bb;
+ apr_bucket_brigade *bbin;
+ char *buf;
+ apr_bucket *b;
+ apr_bucket *nextb;
+ apr_bucket *copied;
+ const char *clen;
+ const char *data;
+ apr_size_t len;
+ request_rec *r = req->rec;
+
+ clen = apr_table_get (r->headers_in, "Content-Length");
+ if (clen != NULL) {
+ bytes = strtol (clen, NULL, 0);
+ if (bytes >= MAX_POST_SIZE) {
+ ap_log_rerror (APLOG_MARK, APLOG_ERR, 0, r,
+ "Request too big (%d bytes; limit %d)",
+ bytes, MAX_POST_SIZE);
+ return NULL;
+ }
+ } else {
+ bytes = MAX_POST_SIZE;
+ }
+
+ bb = apr_brigade_create (r->pool, r->connection->bucket_alloc);
+ bbin = apr_brigade_create (r->pool, r->connection->bucket_alloc);
+ count = eos = 0;
+
+ do {
+ rv = ap_get_brigade (r->input_filters, bbin, AP_MODE_READBYTES,
+ APR_BLOCK_READ, bytes);
+ if (rv != APR_SUCCESS)
+ return NULL;
+ for (b = APR_BRIGADE_FIRST (bbin);
+ b != APR_BRIGADE_SENTINEL (bbin);
+ b = nextb) {
+ nextb = APR_BUCKET_NEXT (b);
+ if (APR_BUCKET_IS_EOS (b))
+ eos = 1;
+ if (!APR_BUCKET_IS_METADATA (b)) {
+ if (b->length != (apr_size_t)(-1)) {
+ count += b->length;
+ if (count > MAX_POST_SIZE)
+ apr_bucket_delete (b);
+ }
+ }
+ if (count <= MAX_POST_SIZE) {
+ if (b->length != 0) {
+ rv = apr_bucket_read (b, &data, &len, APR_BLOCK_READ);
+ if (rv != APR_SUCCESS) {
+ ap_log_rerror (APLOG_MARK, APLOG_ERR, rv, r,
+ "Error reading post data in apr_bucket_read.");
+ return NULL;
+ }
+ if (len > 0) {
+ copied = apr_bucket_transient_create (apr_pmemdup (r->pool, data, len),
+ len, r->connection->bucket_alloc);
+ apr_bucket_delete (b);
+ APR_BRIGADE_INSERT_TAIL (bb, copied);
+ }
+ }
+ }
+ }
+ apr_brigade_cleanup (bbin);
+ } while (!eos);
+
+ if (count > MAX_POST_SIZE) {
+ ap_log_rerror (APLOG_MARK, APLOG_ERR, 0, r,
+ "Request too big (%d bytes; limit %d)",
+ bytes, MAX_POST_SIZE);
+ return NULL;
+ }
+
+ buf = apr_palloc (r->pool, count + 1);
+ rv = apr_brigade_flatten (bb, buf, &count);
+ if (rv != APR_SUCCESS) {
+ ap_log_rerror (APLOG_MARK, APLOG_ERR, rv, r,
+ "Error flattenning reading form data");
+ return NULL;
+ }
+
+ buf[count] = '\0';
+ return buf;
+}
+
+const char*
sid_request_method (sid_request_t *req)
{
return req->rec->method;
diff --git a/module/mod_auth_singleid.h b/module/mod_auth_singleid.h
index 2619c3f..4ad3500 100644
--- a/module/mod_auth_singleid.h
+++ b/module/mod_auth_singleid.h
@@ -28,6 +28,8 @@ void sid_request_log_error (sid_request_t *req,
const char* sid_request_qs (sid_request_t *req);
+const char* sid_request_form (sid_request_t *req);
+
const char* sid_request_url (sid_request_t *req,
int with_path);