diff options
author | Timo Teräs <timo.teras@iki.fi> | 2010-08-19 14:25:00 +0300 |
---|---|---|
committer | Timo Teräs <timo.teras@iki.fi> | 2010-08-19 14:25:00 +0300 |
commit | d4c65ad0235bc8c964d9376410e517c748add147 (patch) | |
tree | 2c68b5ec1fe298a776ce32bfbb6702ed8a73c41b | |
parent | 2c4ddb6620101ebad2bff0c007a99aea97a15de1 (diff) | |
download | squark-d4c65ad0235bc8c964d9376410e517c748add147.tar.bz2 squark-d4c65ad0235bc8c964d9376410e517c748add147.tar.xz |
filter: url encoding of block script parameters
and pass the denied url too.
-rw-r--r-- | blob.c | 107 | ||||
-rw-r--r-- | blob.h | 2 | ||||
-rw-r--r-- | squark-filter.c | 6 |
3 files changed, 110 insertions, 5 deletions
@@ -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; @@ -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); |