+/* Blerg is (C) 2011 The Dominion of Awesome, and is distributed under a
+ * BSD-style license. Please see the COPYING file for details.
+ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
yajl_gen_config yajl_c = { 0, 0 };
-struct create_state {
+struct auth_state {
struct MHD_PostProcessor *pp;
char username[33];
char password[33];
struct put_state {
struct MHD_PostProcessor *pp;
+ char username[33];
char *data;
int data_size;
};
}
/* Snarf one record */
- json_generate_one_record(gs->g, NULL, gs->b, gs->entries[gs->i]);
+ json_generate_one_record(gs->g, NULL, gs->b, gs->entries[gs->i], 0);
if (gs->i == 0) {
yajl_gen_array_close(gs->g);
/* Snarf one record */
b = blerg_open(ts->results[ts->i].author);
if (b != NULL) {
- json_generate_one_record(ts->g, ts->results[ts->i].author, b, ts->results[ts->i].record);
+ json_generate_one_record(ts->g, ts->results[ts->i].author, b, ts->results[ts->i].record, 0);
blerg_close(b);
}
free(ts);
}
-int POST_create_iterator(void *cls, enum MHD_ValueKind kind, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, size_t size) {
- struct create_state *cs = cls;
+int POST_auth_iterator(void *cls, enum MHD_ValueKind kind, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, size_t size) {
+ struct auth_state *as = cls;
if (strncmp(key, "username", 9) == 0) {
if (size > 32) size = 32;
- memcpy(cs->username, data, size);
- cs->username[size] = 0;
+ memcpy(as->username, data, size);
+ as->username[size] = 0;
} else if (strncmp(key, "password", 9) == 0) {
if (size > 32) size = 32;
- memcpy(cs->password, data, size);
- cs->password[size] = 0;
+ memcpy(as->password, data, size);
+ as->password[size] = 0;
}
return MHD_YES;
memcpy(ps->data + off, data, size);
if (ps->data_size == MAX_RECORD_SIZE)
return MHD_NO;
+ } else if (strncmp(key, "username", 9) == 0) {
+ if (size > 32) size = 32;
+ memcpy(ps->username, data, size);
+ ps->username[size] = 0;
}
return MHD_YES;
return ret;
} else if (strncmp(url, "/put", 4) == 0) {
struct put_state *ps = (struct put_state *) *ptr;
- char *username;
- char password[33];
-
if (*ptr == NULL) {
if (strcmp(method, MHD_HTTP_METHOD_POST) != 0)
return respond_405(connection);
*ptr = (void *) 1;
- username = MHD_digest_auth_get_username(connection);
- if (username == NULL)
- return respond_401(connection, MHD_NO);
- auth_get_password(username, password);
-
- ret = MHD_digest_auth_check(connection, REALM, username, password, 300);
- free(username);
-
- if (ret == MHD_INVALID_NONCE || ret == MHD_NO)
- return respond_401(connection, (ret == MHD_INVALID_NONCE) ? MHD_YES : MHD_NO);
-
struct put_state *ps = malloc(sizeof(struct put_state));
ps->data = NULL;
ps->data_size = 0;
ps->pp = MHD_create_post_processor(connection, 16384, &POST_put_iterator, ps);
+ ps->username[0] = 0;
*ptr = ps;
return MHD_YES;
}
return MHD_YES;
}
- if (ps->data == NULL || ps->data_size == 0)
+ if (ps->data == NULL || ps->data_size == 0 || ps->username[0] == 0)
return respond_JSON_Failure(connection);
- username = MHD_digest_auth_get_username(connection);
- struct blerg *b = blerg_open(username);
- if (b == NULL)
+ const char *given_token = MHD_lookup_connection_value(connection, MHD_COOKIE_KIND, "auth");
+ if (!auth_check_token(ps->username, given_token))
return respond_JSON_Failure(connection);
- if (blerg_store(b, ps->data, ps->data_size) == -1) {
- blerg_close(b);
+
+ struct blerg *b = blerg_open(ps->username);
+ if (b == NULL)
return respond_JSON_Failure(connection);
- }
+ ret = blerg_store(b, ps->data, ps->data_size);
blerg_close(b);
+ if (ret == -1)
+ return respond_JSON_Failure(connection);
MHD_destroy_post_processor(ps->pp);
- free(username);
free(ps->data);
free(ps);
*ptr = NULL;
return ret;
} else if (strncmp(url, "/create", 8) == 0) {
- struct create_state *cs = (struct create_state *) *ptr;
+ struct auth_state *as = (struct auth_state *) *ptr;
- if (cs == NULL) {
+ if (as == NULL) {
if (strcmp(method, MHD_HTTP_METHOD_POST) != 0)
return respond_405(connection);
- struct create_state *cs = malloc(sizeof(struct create_state));
- cs->username[0] = cs->password[0] = 0;
- cs->pp = MHD_create_post_processor(connection, 1024, &POST_create_iterator, cs);
- *ptr = cs;
+ struct auth_state *as = malloc(sizeof(struct auth_state));
+ as->username[0] = as->password[0] = 0;
+ as->pp = MHD_create_post_processor(connection, 1024, &POST_auth_iterator, as);
+ *ptr = as;
return MHD_YES;
}
if (*upload_data_size) {
- MHD_post_process(cs->pp, upload_data, *upload_data_size);
+ MHD_post_process(as->pp, upload_data, *upload_data_size);
*upload_data_size = 0;
return MHD_YES;
}
- if (cs->username[0] == 0 || cs->password[0] == 0)
+ if (as->username[0] == 0 || as->password[0] == 0)
return respond_JSON_Failure(connection);
- if (blerg_exists(cs->username))
+ if (blerg_exists(as->username))
return respond_JSON_Failure(connection);
- struct blerg *b = blerg_open(cs->username);
+ struct blerg *b = blerg_open(as->username);
blerg_close(b);
- auth_set_password(cs->username, cs->password);
+ auth_set_password(as->username, as->password);
- MHD_destroy_post_processor(cs->pp);
- free(cs);
+ MHD_destroy_post_processor(as->pp);
+ free(as);
*ptr = NULL;
return respond_JSON_Success(connection);
+ } else if (strncmp(url, "/login", 7) == 0) {
+ struct auth_state *as = (struct auth_state *) *ptr;
+
+ if (as == NULL) {
+ if (strcmp(method, MHD_HTTP_METHOD_POST) != 0)
+ return respond_405(connection);
+
+ struct auth_state *as = malloc(sizeof(struct auth_state));
+ as->username[0] = as->password[0] = 0;
+ as->pp = MHD_create_post_processor(connection, 1024, &POST_auth_iterator, as);
+ *ptr = as;
+ return MHD_YES;
+ }
+
+ if (*upload_data_size) {
+ MHD_post_process(as->pp, upload_data, *upload_data_size);
+ *upload_data_size = 0;
+ return MHD_YES;
+ }
+
+ if (as->username[0] == 0 || as->password[0] == 0)
+ return respond_JSON_Failure(connection);
+
+ if (!auth_login(as->username, as->password))
+ return respond_JSON_Failure(connection);
+
+ response = MHD_create_response_from_data(strlen(JSON_SUCCESS), JSON_SUCCESS, MHD_NO, MHD_NO);
+
+ char *token = auth_get_token(as->username);
+ data = malloc(512);
+ snprintf(data, 512, "auth=%s", token);
+ MHD_add_response_header(response, "Set-Cookie", data);
+ free(token);
+ free(data);
+
+ MHD_destroy_post_processor(as->pp);
+ free(as);
+ *ptr = NULL;
+
+ ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
+ MHD_destroy_response(response);
+
+ return ret;
+ } else if (strncmp(url, "/logout", 8) == 0) {
+ struct auth_state *as = (struct auth_state *) *ptr;
+
+ if (as == NULL) {
+ if (strcmp(method, MHD_HTTP_METHOD_POST) != 0)
+ return respond_405(connection);
+
+ struct auth_state *as = malloc(sizeof(struct auth_state));
+ as->username[0] = as->password[0] = 0;
+ as->pp = MHD_create_post_processor(connection, 1024, &POST_auth_iterator, as);
+ *ptr = as;
+ return MHD_YES;
+ }
+
+ if (*upload_data_size) {
+ MHD_post_process(as->pp, upload_data, *upload_data_size);
+ *upload_data_size = 0;
+ return MHD_YES;
+ }
+
+ const char *given_token = MHD_lookup_connection_value(connection, MHD_COOKIE_KIND, "auth");
+ if (auth_check_token(as->username, given_token)) {
+ auth_logout(as->username);
+ return respond_JSON_Success(connection);
+ } else {
+ return respond_JSON_Failure(connection);
+ }
} else {
return respond_404(connection);
}
init_responses();
- daemon = MHD_start_daemon(MHD_USE_DEBUG, 8080, NULL, NULL, &ahc_derp, NULL, MHD_OPTION_END);
+ daemon = MHD_start_daemon(MHD_USE_DEBUG, HTTP_BLERG_PORT, NULL, NULL, &ahc_derp, NULL, MHD_OPTION_END);
if (daemon == NULL) {
fprintf(stderr, "Could not start web server\n");
return 1;