From 96ec261b36bdbb701e05f5ee1aab70dec44085f9 Mon Sep 17 00:00:00 2001 From: Chip Black Date: Thu, 30 Dec 2010 23:35:58 -0600 Subject: [PATCH] Sanitize username inputs in the database layer --- Makefile | 2 +- common/auth.c | 13 ++++++++++++- database/database.c | 23 ++++++++++++----------- database/tags.c | 15 +++++++-------- database/util.c | 15 +++++++++++++++ database/util.h | 1 + tools/blergtool.c | 2 +- 7 files changed, 49 insertions(+), 22 deletions(-) create mode 100644 database/util.c create mode 100644 database/util.h diff --git a/Makefile b/Makefile index 5113e70..2e49315 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ HTTP_LIBDIRS = -Llibmicrohttpd-0.9.3/src/daemon/.libs -Lyajl/build/yajl-1.0.11/l CGI_LIBDIRS = -Lcgi-util-2.2.1 -Lyajl/build/yajl-1.0.11/lib targets = blerg.a blergtool http_blerg cgi_blerg -blerg_a_objects = database/database.o database/tags.o +blerg_a_objects = database/database.o database/tags.o database/util.o blergtool_objects = tools/blergtool.o blerg.a http_blerg_objects = http/http_blerg.o http/canned_responses.o common/app.o common/auth.o blerg.a cgi_blerg_objects = cgi/cgi_blerg.o common/app.o common/auth.o blerg.a diff --git a/common/auth.c b/common/auth.c index 1b6ecb6..cdfbf85 100644 --- a/common/auth.c +++ b/common/auth.c @@ -6,6 +6,7 @@ #include #include "config.h" #include "auth.h" +#include "util.h" #define TOKEN_SIZE 16 @@ -13,7 +14,7 @@ int auth_set_password(const char *username, const char *password) { char filename[512]; int fd; - if (!blerg_exists(username)) + if (!valid_name(username) || !blerg_exists(username)) return 0; snprintf(filename, 512, "%s/%s/password", DATA_PATH, username); @@ -29,6 +30,9 @@ int auth_get_password(const char *username, char *password) { int fd; int len = 0; + if (!valid_name(username)) + return 0; + sprintf(filename, "%s/%s/password", DATA_PATH, username); fd = open(filename, O_RDONLY); if (fd == -1) @@ -107,6 +111,10 @@ int auth_login(const char *username, const char *password) { int auth_logout(const char *username) { char filename[512]; + + if (!valid_name(username)) + return 0; + sprintf(filename, "%s/%s/token", DATA_PATH, username); if (unlink(filename) == -1) return 0; @@ -119,6 +127,9 @@ char *auth_get_token(const char *username) { char *token; int token_fd; + if (!valid_name(username)) + return 0; + sprintf(filename, "%s/%s/token", DATA_PATH, username); token_fd = open(filename, O_RDONLY, 0600); if (token_fd == -1) { diff --git a/database/database.c b/database/database.c index 1e33811..585f508 100644 --- a/database/database.c +++ b/database/database.c @@ -10,6 +10,7 @@ #include #include #include "database.h" +#include "util.h" #include "config.h" uint64_t blerg_get_record_count(struct blerg *blerg) { @@ -111,8 +112,8 @@ int blerg_exists(const char *name) { int namelen = strlen(name); char filename[512]; - if (namelen > 32) { - perror("Name too long"); + if (!valid_name(name)) { + fprintf(stderr, "Invalid name\n"); return 0; } @@ -129,8 +130,8 @@ struct blerg *blerg_open(const char *name) { struct stat st; uint64_t sequence; - if (namelen > 32) { - perror("Name too long"); + if (!valid_name(name)) { + fprintf(stderr, "Invalid name\n"); return NULL; } struct blerg *blerg = malloc(sizeof(struct blerg)); @@ -203,7 +204,7 @@ int blerg_close(struct blerg *blerg) { int blerg_store(struct blerg *blerg, const char *data, int len) { if (len > MAX_RECORD_SIZE) { - printf("len > 64K\n"); + fprintf(stderr, "len > 64K\n"); return -1; } @@ -212,7 +213,7 @@ int blerg_store(struct blerg *blerg, const char *data, int len) { uint64_t record = blerg_increment_record_count(blerg); if (record == -1) { - printf("Could not find free record\n"); + fprintf(stderr, "Could not find free record\n"); return -1; } int segment = record / RECORDS_PER_SEGMENT; @@ -252,7 +253,7 @@ int blerg_store(struct blerg *blerg, const char *data, int len) { int blerg_fetch(struct blerg *blerg, int record, char **data, int *length) { if (record < 0) { - printf("Invalid record\n"); + fprintf(stderr, "Invalid record\n"); return 0; } @@ -262,7 +263,7 @@ int blerg_fetch(struct blerg *blerg, int record, char **data, int *length) { int seg_rec = record % RECORDS_PER_SEGMENT; if ((blerg->index[seg_rec].flags & 0x1) == 0) { - printf("Invalid record\n"); + fprintf(stderr, "Invalid record\n"); return 0; } @@ -275,7 +276,7 @@ int blerg_fetch(struct blerg *blerg, int record, char **data, int *length) { fstat(blerg->data_fd, &st); blerg->data_size = st.st_size; if (rec_offset > blerg->data_size) { - printf("Record offset outside of data!?"); + fprintf(stderr, "Record offset outside of data!?"); return 0; } @@ -302,7 +303,7 @@ int blerg_fetch(struct blerg *blerg, int record, char **data, int *length) { time_t blerg_get_timestamp(struct blerg *blerg, int record) { if (record < 0) { - printf("Invalid record\n"); + fprintf(stderr, "Invalid record\n"); return 0; } @@ -312,7 +313,7 @@ time_t blerg_get_timestamp(struct blerg *blerg, int record) { int seg_rec = record % RECORDS_PER_SEGMENT; if ((blerg->index[seg_rec].flags & 0x1) == 0) { - printf("Invalid record\n"); + fprintf(stderr, "Invalid record\n"); return 0; } diff --git a/database/tags.c b/database/tags.c index dc51c4f..356ef88 100644 --- a/database/tags.c +++ b/database/tags.c @@ -8,6 +8,7 @@ #include #include #include "tags.h" +#include "util.h" #include "config.h" #define MAX_TAG_LENGTH 64 @@ -98,6 +99,9 @@ struct tag * tag_list(const char *tag, uint64_t offset, int *count, int directio struct tag *taglist; struct tag *retlist; uint64_t n_tag_records; + + if (!valid_name(tag + 1)) + return NULL; switch(tag[0]) { case '#': @@ -108,7 +112,7 @@ struct tag * tag_list(const char *tag, uint64_t offset, int *count, int directio break; default: fprintf(stderr, "Invalid tag type: %s\n", tag); - return 0; + return NULL; } int tag_fd = open(filename, O_RDONLY, 0600); @@ -164,16 +168,11 @@ tag_list_open_failed: } int tag_exists(const char *tag) { - int taglen = strlen(tag); char filename[512]; - if (taglen < 2) { - fprintf(stderr, "Tag too short\n"); + if (!valid_name(tag + 1)) return 0; - } else if (taglen > 33) { - fprintf(stderr, "Tag too long\n"); - return 0; - } + if (!(tag[0] == '@' || tag[0] == '#')) { fprintf(stderr, "Invalid tag: %s\n", tag); return 0; diff --git a/database/util.c b/database/util.c new file mode 100644 index 0000000..ede0450 --- /dev/null +++ b/database/util.c @@ -0,0 +1,15 @@ +#define VALID_CHAR(x) (x == ' ' || x == '\'' || x == '-' || x == '.' || (x >= '0' && x <= '9') || (x >= 'A' && x <= 'Z') || x == '_' || (x >= 'a' && x <= 'z')) + +int valid_name(const char *name) { + int i; + + for (i = 0; i < 32; i++) { + if (name[i] == 0) break; + if (!VALID_CHAR(name[i])) return 0; + } + + if (i >= 32) + return 0; + + return 1; +} diff --git a/database/util.h b/database/util.h new file mode 100644 index 0000000..e046f19 --- /dev/null +++ b/database/util.h @@ -0,0 +1 @@ +int valid_name(const char *name); diff --git a/tools/blergtool.c b/tools/blergtool.c index d5aef50..cc78c7d 100644 --- a/tools/blergtool.c +++ b/tools/blergtool.c @@ -53,7 +53,7 @@ int main(int argc, char *argv[]) { free(data); } else if (strncmp(argv[1], "list", 4) == 0) { char *tag = argv[2]; - uint64_t count = 50; + int count = 50; struct tag *list = tag_list(tag, 0, &count, -1); if (list == NULL) { printf("No entries"); -- 2.25.1