+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(as->username, data, size);
+ as->username[size] = 0;
+ } else if (strncmp(key, "password", 9) == 0) {
+ if (size > 32) size = 32;
+ memcpy(as->password, data, size);
+ as->password[size] = 0;
+ }
+
+ return MHD_YES;
+}
+
+int process_auth(struct MHD_Connection *connection, const char *method, const char *upload_data, size_t *upload_data_size, void **ptr) {
+ struct auth_state *as = (struct auth_state *) *ptr;
+
+ if (as == NULL) {
+ if (strcmp(method, MHD_HTTP_METHOD_POST) != 0)
+ return respond_405(connection);
+
+ 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;
+ }
+
+ return MHD_NO;
+}
+
+int process_and_check_auth(struct MHD_Connection *connection, const char *method, const char *upload_data, size_t *upload_data_size, void **ptr) {
+ struct auth_state *as = (struct auth_state *) *ptr;
+
+ if (process_auth(connection, method, upload_data, upload_data_size, ptr) == MHD_YES)
+ return MHD_YES;
+
+ const char *given_token = MHD_lookup_connection_value(connection, MHD_COOKIE_KIND, "auth");
+ if (!auth_check_token(as->username, given_token))
+ return respond_403(connection);
+
+ return MHD_NO;
+}
+