Sanitize username inputs in the database layer
authorChip Black <bytex64@bytex64.net>
Fri, 31 Dec 2010 05:35:58 +0000 (23:35 -0600)
committerChip Black <bytex64@bytex64.net>
Fri, 31 Dec 2010 05:35:58 +0000 (23:35 -0600)
Makefile
common/auth.c
database/database.c
database/tags.c
database/util.c [new file with mode: 0644]
database/util.h [new file with mode: 0644]
tools/blergtool.c

index 5113e70..2e49315 100644 (file)
--- 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
index 1b6ecb6..cdfbf85 100644 (file)
@@ -6,6 +6,7 @@
 #include <stdlib.h>
 #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) {
index 1e33811..585f508 100644 (file)
@@ -10,6 +10,7 @@
 #include <sys/file.h>
 #include <fcntl.h>
 #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;
        }
 
index dc51c4f..356ef88 100644 (file)
@@ -8,6 +8,7 @@
 #include <sys/file.h>
 #include <sys/mman.h>
 #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 (file)
index 0000000..ede0450
--- /dev/null
@@ -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 (file)
index 0000000..e046f19
--- /dev/null
@@ -0,0 +1 @@
+int valid_name(const char *name);
index d5aef50..cc78c7d 100644 (file)
@@ -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");