Work on Authentication System(s)
[matches/MCTX3420.git] / server / fastcgi.c
index 05dae34..08c413b 100644 (file)
 #include "actuator.h"
 #include "control.h"
 #include "options.h"
+#include "image.h"
+#include "pin_test.h"
+#include "login.h"
 
 /**The time period (in seconds) before the control key expires */
 #define CONTROL_TIMEOUT 180
 
-/**Contextual information related to FCGI requests*/
-struct FCGIContext {
-       /**The time of last valid user access possessing the control key*/
-       time_t control_timestamp;
-       char control_key[41];
-       char control_ip[16];
-       /**The name of the current module**/
-       const char *current_module;
-       /**For debugging purposes?**/
-       int response_number;
-};
+
 
 /**
  * Identifies build information and the current API version to the user.
@@ -92,7 +85,8 @@ void FCGI_LockControl(FCGIContext *context, bool force) {
        time_t now = time(NULL);
        bool expired = now - context->control_timestamp > CONTROL_TIMEOUT;
        
-       if (force || !*(context->control_key) || expired) {
+       if (force || !*(context->control_key) || expired) 
+       {
                SHA_CTX sha1ctx;
                unsigned char sha1[20];
                int i = rand();
@@ -106,18 +100,6 @@ void FCGI_LockControl(FCGIContext *context, bool force) {
                for (i = 0; i < 20; i++)
                        sprintf(context->control_key + i * 2, "%02x", sha1[i]);
                snprintf(context->control_ip, 16, "%s", getenv("REMOTE_ADDR"));
-               FCGI_BeginJSON(context, STATUS_OK);
-               FCGI_JSONPair("key", context->control_key);
-               FCGI_EndJSON();         
-       } else {
-               char buf[128];
-               strftime(buf, 128, "%H:%M:%S %d-%m-%Y",
-                       localtime(&(context->control_timestamp))); 
-               FCGI_BeginJSON(context, STATUS_UNAUTHORIZED);
-               FCGI_JSONPair("description", "Another user already has control");
-               FCGI_JSONPair("current_user", context->control_ip); 
-               FCGI_JSONPair("when", buf);
-               FCGI_EndJSON();
        }
 }
 
@@ -226,7 +208,16 @@ bool FCGI_ParseRequest(FCGIContext *context, char *params, FCGIValue values[], s
 
                                switch(FCGI_TYPE(val->flags)) {
                                        case FCGI_BOOL_T:
-                                               *((bool*) val->value) = true;
+                                               if (!*value) //No value: Default true
+                                                       *((bool*) val->value) = true;
+                                               else {
+                                                       *((bool*) val->value) = !!(strtol(value, &ptr, 10));
+                                                       if (*ptr) {
+                                                               snprintf(buf, BUFSIZ, "Expected bool for '%s' but got '%s'", key, value);
+                                                               FCGI_RejectJSON(context, buf);
+                                                               return false;
+                                                       }
+                                               }
                                                break;
                                        case FCGI_INT_T: case FCGI_LONG_T: {
                                                long parsed = strtol(value, &ptr, 10);
@@ -293,6 +284,7 @@ void FCGI_BeginJSON(FCGIContext *context, StatusCodes status_code)
        FCGI_JSONDouble("start_time", TIMEVAL_TO_DOUBLE(g_options.start_time));
        FCGI_JSONDouble("current_time", TIMEVAL_TO_DOUBLE(now));
        FCGI_JSONDouble("running_time", TIMEVAL_DIFF(now, g_options.start_time));
+       FCGI_JSONPair("control_state", Control_GetModeName());
 }
 
 /**
@@ -393,6 +385,17 @@ void FCGI_PrintRaw(const char *format, ...)
        va_end(list);
 }
 
+
+/**
+ * Write binary data
+ * See fwrite
+ */
+void FCGI_WriteBinary(void * data, size_t size, size_t num_elem)
+{
+       Log(LOGDEBUG,"Writing!");
+       fwrite(data, size, num_elem, stdout);
+}
+
 /**
  * Escapes a string so it can be used safely.
  * Currently escapes to ensure the validity for use as a JSON string
@@ -434,15 +437,21 @@ void * FCGI_RequestLoop (void *data)
 {
        FCGIContext context = {0};
        
-       Log(LOGDEBUG, "First request...");
+       Log(LOGDEBUG, "Start loop");
        while (FCGI_Accept() >= 0) {
-               Log(LOGDEBUG, "Got request #%d", context.response_number);
+               
                ModuleHandler module_handler = NULL;
-               char module[BUFSIZ], params[BUFSIZ];
+               char module[BUFSIZ], params[BUFSIZ], cookie[BUFSIZ];
                
                //strncpy doesn't zero-truncate properly
                snprintf(module, BUFSIZ, "%s", getenv("DOCUMENT_URI_LOCAL"));
                snprintf(params, BUFSIZ, "%s", getenv("QUERY_STRING"));
+               snprintf(cookie, BUFSIZ, "%s", getenv("COOKIE_STRING"));
+
+               Log(LOGDEBUG, "Got request #%d - Module %s, params %s", context.response_number, module, params);
+               Log(LOGDEBUG, "Cookie: %s", cookie);
+
+
                
                //Remove trailing slashes (if present) from module query
                size_t lastchar = strlen(module) - 1;
@@ -464,17 +473,46 @@ void * FCGI_RequestLoop (void *data)
                        module_handler = Sensor_Handler;
                } else if (!strcmp("actuators", module)) {
                        module_handler = Actuator_Handler;
+               } else if (!strcmp("image", module)) {
+                       module_handler = Image_Handler;
+               } else if (!strcmp("pin", module)) { 
+                       module_handler = Pin_Handler; // *Debug only* pin test module
+               } else if (!strcmp("bind", module)) {
+                       module_handler = Login_Handler;
+               } else if (!strcmp("unbind", module)) {
+                       module_handler = Logout_Handler;
                }
 
                context.current_module = module;
-               if (module_handler) {
+               context.response_number++;
+               
+
+
+               if (module_handler) 
+               {
+                       if (module_handler != Login_Handler)
+                       {
+                               if (cookie[0] == '\0')
+                               {
+                                       FCGI_RejectJSON(&context, "Please login.");
+                                       continue;
+                               }
+                               if (!FCGI_HasControl(&context, cookie))
+                               {
+                                       FCGI_RejectJSON(&context, "Invalid control key.");
+                                       continue;       
+                               }
+                       }
+
                        module_handler(&context, params);
-               } else {
+               } 
+               else 
+               {
                        FCGI_RejectJSON(&context, "Unhandled module");
                }
-               context.response_number++;
+               
 
-               Log(LOGDEBUG, "Waiting for request #%d", context.response_number);
+               
        }
 
        Log(LOGDEBUG, "Thread exiting.");

UCC git Repository :: git.ucc.asn.au