summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2010-08-19 14:25:00 +0300
committerTimo Teräs <timo.teras@iki.fi>2010-08-19 14:25:00 +0300
commitd4c65ad0235bc8c964d9376410e517c748add147 (patch)
tree2c68b5ec1fe298a776ce32bfbb6702ed8a73c41b
parent2c4ddb6620101ebad2bff0c007a99aea97a15de1 (diff)
downloadsquark-d4c65ad0235bc8c964d9376410e517c748add147.tar.bz2
squark-d4c65ad0235bc8c964d9376410e517c748add147.tar.xz
filter: url encoding of block script parameters
and pass the denied url too.
-rw-r--r--blob.c107
-rw-r--r--blob.h2
-rw-r--r--squark-filter.c6
3 files changed, 110 insertions, 5 deletions
diff --git a/blob.c b/blob.c
index f6daef1..8f630c2 100644
--- a/blob.c
+++ b/blob.c
@@ -1,7 +1,81 @@
#include "blob.h"
+/* RFC 3986 section 2.3 Unreserved Characters (January 2005) */
+#define CTYPE_UNRESERVED 1
+
static const char *xd = "0123456789abcdefghijklmnopqrstuvwxyz";
+static const unsigned char chartype[128] = {
+ ['a'] = CTYPE_UNRESERVED,
+ ['b'] = CTYPE_UNRESERVED,
+ ['c'] = CTYPE_UNRESERVED,
+ ['d'] = CTYPE_UNRESERVED,
+ ['e'] = CTYPE_UNRESERVED,
+ ['f'] = CTYPE_UNRESERVED,
+ ['g'] = CTYPE_UNRESERVED,
+ ['h'] = CTYPE_UNRESERVED,
+ ['i'] = CTYPE_UNRESERVED,
+ ['j'] = CTYPE_UNRESERVED,
+ ['k'] = CTYPE_UNRESERVED,
+ ['l'] = CTYPE_UNRESERVED,
+ ['m'] = CTYPE_UNRESERVED,
+ ['n'] = CTYPE_UNRESERVED,
+ ['o'] = CTYPE_UNRESERVED,
+ ['p'] = CTYPE_UNRESERVED,
+ ['q'] = CTYPE_UNRESERVED,
+ ['r'] = CTYPE_UNRESERVED,
+ ['s'] = CTYPE_UNRESERVED,
+ ['t'] = CTYPE_UNRESERVED,
+ ['u'] = CTYPE_UNRESERVED,
+ ['v'] = CTYPE_UNRESERVED,
+ ['w'] = CTYPE_UNRESERVED,
+ ['x'] = CTYPE_UNRESERVED,
+ ['y'] = CTYPE_UNRESERVED,
+ ['z'] = CTYPE_UNRESERVED,
+ ['A'] = CTYPE_UNRESERVED,
+ ['B'] = CTYPE_UNRESERVED,
+ ['C'] = CTYPE_UNRESERVED,
+ ['D'] = CTYPE_UNRESERVED,
+ ['E'] = CTYPE_UNRESERVED,
+ ['F'] = CTYPE_UNRESERVED,
+ ['G'] = CTYPE_UNRESERVED,
+ ['H'] = CTYPE_UNRESERVED,
+ ['I'] = CTYPE_UNRESERVED,
+ ['J'] = CTYPE_UNRESERVED,
+ ['K'] = CTYPE_UNRESERVED,
+ ['L'] = CTYPE_UNRESERVED,
+ ['M'] = CTYPE_UNRESERVED,
+ ['N'] = CTYPE_UNRESERVED,
+ ['O'] = CTYPE_UNRESERVED,
+ ['P'] = CTYPE_UNRESERVED,
+ ['Q'] = CTYPE_UNRESERVED,
+ ['R'] = CTYPE_UNRESERVED,
+ ['S'] = CTYPE_UNRESERVED,
+ ['T'] = CTYPE_UNRESERVED,
+ ['U'] = CTYPE_UNRESERVED,
+ ['V'] = CTYPE_UNRESERVED,
+ ['W'] = CTYPE_UNRESERVED,
+ ['X'] = CTYPE_UNRESERVED,
+ ['Y'] = CTYPE_UNRESERVED,
+ ['Z'] = CTYPE_UNRESERVED,
+
+ ['0'] = CTYPE_UNRESERVED,
+ ['1'] = CTYPE_UNRESERVED,
+ ['2'] = CTYPE_UNRESERVED,
+ ['3'] = CTYPE_UNRESERVED,
+ ['4'] = CTYPE_UNRESERVED,
+ ['5'] = CTYPE_UNRESERVED,
+ ['6'] = CTYPE_UNRESERVED,
+ ['7'] = CTYPE_UNRESERVED,
+ ['8'] = CTYPE_UNRESERVED,
+ ['9'] = CTYPE_UNRESERVED,
+
+ ['-'] = CTYPE_UNRESERVED,
+ ['_'] = CTYPE_UNRESERVED,
+ ['.'] = CTYPE_UNRESERVED,
+ ['~'] = CTYPE_UNRESERVED,
+};
+
static inline int dx(int c)
{
if (likely(c >= '0' && c <= '9'))
@@ -88,13 +162,24 @@ void blob_push(blob_t *b, blob_t d)
}
}
+void blob_push_byte(blob_t *b, unsigned char byte)
+{
+ if (b->len) {
+ b->ptr[0] = byte;
+ b->ptr ++;
+ b->len --;
+ } else {
+ *b = BLOB_NULL;
+ }
+}
+
void blob_push_uint(blob_t *to, unsigned int value, int radix)
{
char buf[64];
char *ptr = &buf[sizeof(buf)-1];
if (value == 0) {
- blob_push(to, BLOB_STR("0"));
+ blob_push_byte(to, '0');
return;
}
@@ -108,7 +193,6 @@ void blob_push_uint(blob_t *to, unsigned int value, int radix)
void blob_push_hexdump(blob_t *to, blob_t binary)
{
- static const char *xd = "0123456789abcdef";
char *d;
int i;
@@ -145,12 +229,29 @@ void blob_push_urldecode(blob_t *to, blob_t url)
blob_shrink_tail(to, blob_pushed(orig, b), '/');
} else {
/* copy decoded; FIXME decode percent encoding */
- blob_push(to, BLOB_STR("/"));
+ blob_push_byte(to, '/');
blob_push(to, b);
}
} while (1);
}
+void blob_push_urlencode(blob_t *to, blob_t url)
+{
+ unsigned char c;
+ int i;
+
+ for (i = 0; i < url.len; i++) {
+ c = url.ptr[i];
+
+ if (c <= 127 && (chartype[c] & CTYPE_UNRESERVED)) {
+ blob_push_byte(to, c);
+ } else {
+ blob_push_byte(to, '%');
+ blob_push_uint(to, c, 16);
+ }
+ }
+}
+
blob_t blob_pull(blob_t *b, int len)
{
blob_t r;
diff --git a/blob.h b/blob.h
index d1ef577..f5c57eb 100644
--- a/blob.h
+++ b/blob.h
@@ -42,9 +42,11 @@ unsigned long blob_inet_addr(blob_t buf);
blob_t blob_pushed(blob_t buffer, blob_t left);
void blob_push(blob_t *b, blob_t d);
+void blob_push_byte(blob_t *b, unsigned char byte);
void blob_push_uint(blob_t *to, unsigned int value, int radix);
void blob_push_hexdump(blob_t *to, blob_t binary);
void blob_push_urldecode(blob_t *to, blob_t url);
+void blob_push_urlencode(blob_t *to, blob_t url);
blob_t blob_pull(blob_t *b, int len);
void blob_pull_skip(blob_t *b, int len);
int blob_pull_matching(blob_t *b, blob_t e);
diff --git a/squark-filter.c b/squark-filter.c
index bc88e9a..8fab0bf 100644
--- a/squark-filter.c
+++ b/squark-filter.c
@@ -341,9 +341,11 @@ static void send_redirect(struct sqdb *db, blob_t tag, blob_t url, int categ, bl
blob_push(&b, BLOB_STR(" 302:"));
blob_push(&b, redirect_page);
blob_push(&b, BLOB_STR("?REASON="));
- blob_push(&b, get_category_name(db, categ));
+ blob_push_urlencode(&b, get_category_name(db, categ));
blob_push(&b, BLOB_STR("&USER="));
- blob_push(&b, username);
+ blob_push_urlencode(&b, username);
+ blob_push(&b, BLOB_STR("&DENIEDURL="));
+ blob_push_urlencode(&b, url);
blob_push(&b, lf);
b = blob_pushed(BLOB_BUF(buffer), b);