char *aes_decrypt(char *str_ciphertext_base64, int *ptr_int_ciphertext_length) { DEFINE_VAR_ALL(str_ciphertext); char *str_return = NULL; //base64 //printf("test1>%d<\n", *ciphertext_len); str_ciphertext = b64decode(str_ciphertext_base64, ptr_int_ciphertext_length); //printf("str_ciphertext: %s\n", str_ciphertext); //initialize set_aes_key_iv(); AES_KEY AESkey; ERROR_SALLOC(str_return, *ptr_int_ciphertext_length + 1); memset(str_return, 0, *ptr_int_ciphertext_length); //printf("test2>%d<\n", *ptr_int_ciphertext_length); //encrypt AES_set_decrypt_key((const unsigned char *) str_global_aes_key, 256, &AESkey); AES_cbc_encrypt((const unsigned char *)str_ciphertext, (unsigned char *)str_return, *ptr_int_ciphertext_length, &AESkey, (unsigned char *)str_global_aes_iv, AES_DECRYPT); //aes_crypt_cbc(&aes, AES_DECRYPT, *ciphertext_len, (unsigned char *)iv, (unsigned char *)str_ciphertext, (unsigned char *)str_return); //printf("test3>%d<\n", *ciphertext_len); SFREE_ALL(); return str_return; error: SFREE_ALL(); SFREE_PWORD(str_return); return NULL; }
char *aes_encrypt(char *str_plaintext, int *ptr_int_plaintext_length) { DEFINE_VAR_ALL(str_output); char *str_return = NULL; //initialize set_aes_key_iv(); AES_KEY AESkey; //int int_new_length = *ptr_int_plaintext_length; *ptr_int_plaintext_length = ((*ptr_int_plaintext_length + AES_BLOCK_SIZE) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE; int int_aes_length = *ptr_int_plaintext_length; //*ptr_int_plaintext_length = (*ptr_int_plaintext_length) - ((*ptr_int_plaintext_length) % 16) + 16; ERROR_SALLOC(str_output, int_aes_length + 1); memset(str_output, 0, int_aes_length); AES_set_encrypt_key((const unsigned char *) str_global_aes_key, 256, &AESkey); AES_cbc_encrypt((const unsigned char *)str_plaintext, (unsigned char *)str_output, int_aes_length, &AESkey, (unsigned char *)str_global_aes_iv, AES_ENCRYPT); /* AES_cbc_encrypt((const unsigned char *)str_plaintext, (unsigned char *)str_output, int_new_length, &AESkey, (unsigned char *)str_global_aes_iv, AES_ENCRYPT); */ //int int_original_length = int_new_length; //int_new_length = (int_new_length & 0xFFFFFFF0) + ((int_new_length & 0x0F) ? 16 : 0); //*(str_output + int_new_length) = (int_new_length - int_original_length); //printf("str_output: %s\n", str_output); //encrypt //aes_setkey_enc(&aes, (unsigned char *)key, 256); //aes_crypt_cbc(&aes, AES_ENCRYPT, *plaintext_len, (unsigned char *)iv, (unsigned char *)plaintext, (unsigned char *)str_output); //base64 str_return = b64encode(str_output, ptr_int_plaintext_length); SFREE_ALL(); return str_return; error: SFREE_ALL(); SFREE_PWORD(str_return); return NULL; }
char *request_header(char *str_request, char *str_name) { char *str_return = NULL; DEFINE_VAR_ALL(str_full_name); ERROR_CAT_CSTR(str_full_name, str_name, ": "); // find the cookie char *ptr_header = strstr(str_request, str_full_name); WARN_CHECK(ptr_header != NULL, "no %s found", str_name); ptr_header = ptr_header + strlen(str_full_name); // advance cursor past "referer: " // get cookie length char *ptr_header_end_return = strstr(ptr_header, "\r\n"); int int_header_len; if (ptr_header_end_return == NULL) { ptr_header_end_return = strstr(ptr_header, "\r"); if (ptr_header_end_return == NULL) { ptr_header_end_return = strstr(ptr_header, "\n"); if (ptr_header_end_return == NULL) { int_header_len = strlen(ptr_header); } else { int_header_len = ptr_header_end_return - ptr_header; } } else { int_header_len = ptr_header_end_return - ptr_header; } } else { int_header_len = ptr_header_end_return - ptr_header; } // return just the host ERROR_SALLOC(str_return, int_header_len + 1); memcpy(str_return, ptr_header, int_header_len); str_return[int_header_len] = '\0'; SFREE_ALL(); return str_return; error: SFREE_ALL(); SFREE(str_return); return NULL; }
char *query(char *str_request) { char *str_return = NULL; DEFINE_VAR_ALL(str_uri); // find the form_data by request type if (strncmp(str_request, "GET ", 4 ) == 0) { str_uri = str_uri_path(str_request); ERROR_CHECK(str_uri != NULL, "str_uri_path failed"); char *ptr_query = strstr(str_uri, "?"); ERROR_CHECK(ptr_query != NULL, "no form data"); ERROR_CAT_CSTR(str_return, ptr_query + 1); // advance cursor past "?" SFREE(str_uri); } else { //rewritten to work with safari, still doesn't work char *temp1 = strstr(str_request, "\r\n\r\n"); char *temp2 = strstr(str_request, "\n\n"); char *ptr_query = NULL; if (temp1 == 0 && temp2 == 0) { ERROR("no form data"); } else if (temp1 != 0 && temp2 == 0) { ptr_query = temp1 + 4; } else if (temp1 == 0 && temp2 != 0) { ptr_query = temp2 + 2; } else { if (temp1 < temp2) { ptr_query = temp1 + 4; } else { ptr_query = temp2 + 2; } } ERROR_CAT_CSTR(str_return, ptr_query); } // return just the form_data SFREE_ALL(); return str_return; error: SFREE_ALL(); return NULL; }
// Check path environment variable for a program char *where_is_program(char *str_program_name) { DEFINE_VAR_ALL(str_PATH, str_PATH2); char *str_return = NULL; ERROR_CAT_CSTR(str_PATH, getenv("PATH")); char *ptr_PATH = str_PATH; char *ptr_PATH_end = str_PATH + strlen(str_PATH); int int_next_colon; while (ptr_PATH < ptr_PATH_end) { //DEBUG("%s", ptr_PATH); int_next_colon = strcspn(ptr_PATH, ":"); ERROR_SALLOC(str_PATH2, int_next_colon + 2); memcpy(str_PATH2, ptr_PATH, int_next_colon); str_PATH2[int_next_colon] = '/'; str_PATH2[int_next_colon + 1] = '\0'; //DEBUG("%s", str_ptr_PATH); str_return = canonical(str_PATH2, str_program_name, "read_dir_or_file"); //"read_file"); SFREE(str_PATH2); if (str_return != NULL) { SFREE_ALL(); return str_return; } //DEBUG("%i", int_next_colon); ptr_PATH += int_next_colon + 1; } WARN("Could not find program: %s", str_program_name); //ERROR("Could not find program: %s", str_program_name); error: SFREE_ALL(); SFREE(str_return); return NULL; }
char *link_system_postage(PGconn *cnxn, int csock, char *str_uri, char *str_request, int int_request_len) { char *str_response = NULL; DEFINE_VAR_ALL(str_form_data, str_uri_part); // uri comes in looking like: /system_postage/action_aggregates?test=testanswer // we use uri to fill a new variable uri_part to just have the part we want: action_aggregates\0 char *ptr_uri = str_uri + 9; //go past /postage/ int int_uri_len = strcspn(ptr_uri, "?"); FINISH_SALLOC(str_uri_part, int_uri_len + 1); memcpy(str_uri_part, ptr_uri, int_uri_len); str_uri_part[int_uri_len] = '\0'; // we use uri to fill form_data with str_query(uri) // str_query() will pull the query string or in case of a POST it will get the form data str_form_data = query(str_request); DEBUG("str_uri_part: %s", str_uri_part); DEBUG("str_form_data: %s", str_form_data); str_response = main_action_postage(cnxn, csock, str_uri_part, str_form_data, str_request, int_request_len); FINISH_CHECK(str_response != NULL, "main_action_postage failed"); finish: SFREE_ALL(); return str_response; }
sun_upload *get_sun_upload(char *str_request, int int_request_length) { sun_upload *sun_return = NULL; DEFINE_VAR_ALL(str_boundary, str_full_boundary, str_name, str_file_content); ////GET BOUNDARY //get boundary length char *ptr_boundary = strstr(str_request, "Content-Type: multipart/form-data; boundary=") + 44; ERROR_CHECK(ptr_boundary != NULL, "No Boundary"); int int_boundary_carriage = strchr(ptr_boundary, '\r') - ptr_boundary; int int_boundary_newline = strchr(ptr_boundary, '\n') - ptr_boundary; int int_boundary_length = int_boundary_carriage < int_boundary_newline ? int_boundary_carriage : int_boundary_newline; //copy boundary ERROR_SALLOC(str_boundary, int_boundary_length + 1); memcpy(str_boundary, ptr_boundary, int_boundary_length); str_boundary[int_boundary_length] = '\0'; ERROR_CAT_CSTR(str_full_boundary, "--", str_boundary); DEBUG(">BOUNDARY|%s<", str_boundary); SFREE(str_boundary); ////GET FILE NAME //get file name char *ptr_name = bstrstr(str_request, int_request_length, "Content-Disposition: form-data; name=\"file_name\"", 48); ERROR_CHECK(ptr_name != NULL, "No Content Disposition for File Name, (Maybe there is no file name?)"); ptr_name = ptr_name + 48; char *ptr_name_dos = strstr(ptr_name, "\r\n\r\n"); char *ptr_name_unix = strstr(ptr_name, "\n\n"); char *ptr_name_mac = strstr(ptr_name, "\r\r"); ptr_name = ptr_name_dos > ptr_name_unix ? ptr_name_dos + 4 : ptr_name_dos > ptr_name_mac ? ptr_name_dos + 4 : ptr_name_unix > ptr_name_mac ? ptr_name_unix + 2 : ptr_name_mac + 2; //copy file name int int_name_carriage = strchr(ptr_name, '\r') - ptr_name; int int_name_newline = strchr(ptr_name, '\n') - ptr_name; int int_name_boundary = strstr(ptr_name, str_full_boundary) - ptr_name; int int_name_length = int_name_carriage < int_name_newline ? int_name_carriage : int_name_carriage < int_name_boundary ? int_name_carriage : int_name_boundary < int_name_carriage ? int_name_boundary : int_name_boundary; ERROR_SALLOC(str_name, int_name_length + 1); memcpy(str_name, ptr_name, int_name_length); str_name[int_name_length] = '\0'; DEBUG(">FILE NAME|%s<", str_name); ////GET FILE //get file content DEBUG("str_request: %20.20s", str_request); char *ptr_file_content = bstrstr(str_request, int_request_length, "Content-Disposition: form-data; name=\"file_content\"", 51); ERROR_CHECK(ptr_file_content != NULL, "No Content Disposition for File Content, (Maybe there is no file content?)"); ptr_file_content = ptr_file_content + 51; DEBUG("str_request + int_request_length d: %d", str_request + int_request_length); DEBUG("ptr_file_content: %20.20s", ptr_file_content); char *ptr_file_content_dos = strstr(ptr_file_content, "\r\n\r\n"); char *ptr_file_content_unix = strstr(ptr_file_content, "\n\n"); char *ptr_file_content_mac = strstr(ptr_file_content, "\r\r"); ptr_file_content = ptr_file_content_dos > ptr_file_content_unix ? ptr_file_content_dos + 4 : ptr_file_content_dos > ptr_file_content_mac ? ptr_file_content_dos + 4 : ptr_file_content_unix > ptr_file_content_mac ? ptr_file_content_unix + 2 : ptr_file_content_mac + 2; //copy file content int int_file_content_length = bstrstr(ptr_file_content, (str_request + int_request_length) - ptr_file_content, str_full_boundary, int_boundary_length + 2) - ptr_file_content; ERROR_SALLOC(str_file_content, int_file_content_length + 1); memcpy(str_file_content, ptr_file_content, int_file_content_length); str_file_content[int_file_content_length] = '\0'; DEBUG(">FILE CONTENT|%s<", str_file_content); DEBUG(">FILE CONTENT LENGTH|%i<", int_file_content_length); ////RETURN ERROR_SALLOC(sun_return, sizeof(sun_upload)); SFREE(str_full_boundary); sun_return->str_name = str_name; str_name = NULL; sun_return->str_file_content = str_file_content; str_file_content = NULL; sun_return->int_file_content_length = int_file_content_length; SFREE_ALL(); return sun_return; error: SFREE_ALL(); SFREE(sun_return); return NULL; }
bool handle(int csock) { NOTICE("################# REQUEST"); PGconn *cnxn = NULL; char buf[BUF_LEN + 2]; buf[0] = 0; DEFINE_VAR_ALL(str_response, str_request, str_uri, str_temp, str_form_data); DEFINE_VAR_MORE(str_correct_referer_start1, str_correct_referer_start2); DEFINE_VAR_MORE(str_referer, str_host, str_request_len, str_boundary); DEFINE_VAR_MORE(str_cookie_envelope, str_complete_response, str_buffer); DEBUG("### get the str_request\n"); //########################################## //### get the str_request //DEBUG(">%d|%d<", SSIZE_MAX, BUF_LEN); int int_request_len = BUF_LEN; memset(buf, 0, BUF_LEN + 1); int_request_len = read(csock, buf, BUF_LEN); FINISH_SALLOC(str_request, int_request_len + 1); memcpy(str_request, buf, int_request_len); str_request[int_request_len] = '\0'; //HERE BE DRAGONS //Maintainer: joseph //This code reads from the socket only for as long as is necessary. //If we have just one extra read command, it will hang until the browser //sends more data. Which it won't. So read until end of request. //@@@@@@@@@@@@@@@@@@@@@**^^""~~~"^@@^*@*@@**@@@@@@@@@ //@@@@@@@@@@@@@*^^'"~ , - ' '; ,@@b. ' -e@@@@@@@@@ //@@@@@@@@*^"~ . ' . ' ,@@@@( e@*@@@@@@@@@@ //@@@@@^~ . . ' @@@@@@, ~^@@@@@@@@@@@ //@@@~ ,e**@@*e, ,e**e, . ' '@@@@@@e, "*@@@@@'^@ //@',e@@@@@@@@@@ e@@@@@@ ' '*@@@@@@ @@@' 0 //@@@@@@@@@@@@@@@@@@@@@',e, ; ~^*^' ;^~ ' 0 //@@@@@@@@@@@@@@@^""^@@e@@@ .' ,' .' @ //@@@@@@@@@@@@@@' '@@@@@ ' , ,e' . ;@ //@@@@@@@@@@@@@' ,&&, ^@*' , . i^"@e, ,e@e @@ //@@@@@@@@@@@@' ,@@@@, ; ,& !,,@@@e@@@@ e@@ //@@@@@,~*@@*' ,@@@@@@e, ', e^~^@, ~'@@@@@@,@@@ //@@@@@@, ~" ,e@@@@@@@@@*e*@* ,@e @@""@e,,@@@@@@@@@ //@@@@@@@@ee@@@@@@@@@@@@@@@" ,e@' ,e@' e@@@@@@@@@@@@@ //@@@@@@@@@@@@@@@@@@@@@@@@" ,@" ,e@@e,,@@@@@@@@@@@@@@ //@@@@@@@@@@@@@@@@@@@@@@@~ ,@@@,,0@@@@@@@@@@@@@@@@@@@ //@@@@@@@@@@@@@@@@@@@@@@@@,,@@@@@@@@@@@@@@@@@@@@@@@@@ //""""""""""""""""""""""""""""""""""""""""""""""""""" char *ptr_boundary_start = strstr(str_request, "Content-Type: multipart/form-data; boundary="); if (ptr_boundary_start != NULL && strchr(ptr_boundary_start, 13) == NULL) { memset(buf, 0, BUF_LEN + 1); int int_current_length = read(csock, buf, BUF_LEN); FINISH_SREALLOC(str_request, int_current_length + int_request_len + 1); memcpy(str_request + int_request_len, buf, int_current_length); str_request[int_current_length + int_request_len] = '\0'; int_request_len = int_request_len + int_current_length; } //DEBUG("test0>%s|%i<", str_request, int_request_len); char *request_ptr; //// ****if upload then special case if (strstr(str_request, "Content-Type: multipart/form-data; boundary=") != 0) { //get boundary char *boundary_ptr = strstr(str_request, "Content-Type: multipart/form-data; boundary=") + 44; char *boundary_end_ptr = strchr(boundary_ptr, 13) != 0 ? strchr(boundary_ptr, 13) : strchr(boundary_ptr, 10); DEBUG("str_boundary: %d %d", boundary_end_ptr, boundary_ptr); int int_boundary_length = boundary_end_ptr - boundary_ptr; DEBUG("str_boundary: %d", int_boundary_length); FINISH_SALLOC(str_boundary, int_boundary_length + 3); //extra and null byte DEBUG("TESTING1"); memcpy(str_boundary, boundary_ptr, int_boundary_length); DEBUG("TESTING2"); str_boundary[int_boundary_length + 0] = '-'; DEBUG("TESTING3"); str_boundary[int_boundary_length + 1] = '-'; DEBUG("TESTING4"); str_boundary[int_boundary_length + 2] = '\0'; DEBUG("TESTING5"); int int_current_length = BUF_LEN; DEBUG("TESTING6"); //DEBUG("str_boundary: %s", str_boundary); //DEBUG("str_request: %s", str_request); DEBUG("bstrstr(\"%-10s\", %d, \"%s\", %d", str_request, int_request_len, str_boundary, int_boundary_length + 2); /* DEBUG("test0>%s<", bstrstr( str_request, int_request_len, str_boundary, int_boundary_length + 2) == NULL ? "NULL" : "NOT NULL"); while (bstrstr( str_request, int_request_len, str_boundary, int_boundary_length + 2) == NULL) {//while null DEBUG("test1"); memset(buf, 0, BUF_LEN + 1); //FINISH_SALLOC(str_buffer, BUF_LEN + 2); DEBUG("test2"); int_current_length = read(csock, buf, BUF_LEN); DEBUG("test3"); FINISH_SREALLOC(str_request, int_request_len + int_current_length + 1); DEBUG("test4>%s<", str_request); memcpy(str_request + int_request_len, buf, int_current_length); int_request_len = int_request_len + int_current_length; str_request[int_request_len] = '\0'; //SFREE(str_buffer); DEBUG("test5>%i<", int_request_len); } */ DEBUG(">%s<", bstrstr( str_request + int_request_len - int_current_length - int_boundary_length, int_current_length + int_boundary_length, str_boundary, int_boundary_length + 2) == NULL ? "NULL" : "NOT NULL"); while (bstrstr( str_request + int_request_len - int_current_length - int_boundary_length, int_current_length + int_boundary_length, str_boundary, int_boundary_length + 2) == NULL) {//while null memset(buf, 0, BUF_LEN + 1); //DEBUG("test1"); int_current_length = read(csock, buf, BUF_LEN); //DEBUG("test2"); FINISH_SREALLOC(str_request, int_request_len + int_current_length + 1); //DEBUG("test3>%s<", str_request); memcpy(str_request + int_request_len, buf, int_current_length); int_request_len = int_request_len + int_current_length; str_request[int_request_len] = '\0'; //DEBUG("test4>%i<", int_request_len); } DEBUG("test5>%s<", bstrstr( str_request, int_request_len, str_boundary, int_boundary_length + 2) - 25); SFREE(str_boundary); //// **** // if post or put, then get content length and receive that amount after two newlines, then break } else if (strncmp(str_request, "P", 1) == 0) { //we need Content-Length: before we can continue while (! strstr(str_request, "Content-Length:")) { memset(buf, 0, BUF_LEN + 1); //DEBUG("test1"); int_request_len = read(csock, buf, BUF_LEN); //DEBUG("test2>%i<", int_request_len); //buf[request_len] = 0; FINISH_CAT_APPEND(str_request, buf); //DEBUG("#request_len:%d", int_request_len); } request_ptr = strstr(str_request, "Content-Length:"); // if we didn't find anything we need to stop, len("Content-Length")==15 if (strlen(request_ptr) < 16) { // error bad str_request FINISH("Bad str_request"); } // move pointer to start of content length value request_ptr = request_ptr + 15; //DEBUG("request_ptr>%s<", request_ptr); // step through the buffer and see if we can get the length int req_len = 0; while (request_ptr != 0 && *request_ptr != '\r' && *request_ptr != '\n') { if (request_ptr == 0 && req_len == 0) { // error bad str_request } //do not comment next line!!!!!!!! give inconsistent output without this line!!!!!! idk why!!!!!!! //DEBUG("test1>%c<", *request_ptr); /////////////// if (*request_ptr != '\r' && *request_ptr != '\n') { request_ptr = request_ptr + 1; req_len = req_len + 1; } } FINISH_SALLOC(str_request_len, req_len + 1); request_ptr = request_ptr - req_len; memcpy(str_request_len, request_ptr, req_len); str_request_len[req_len] = '\0'; //DEBUG("test2>%s|%s<", str_request_len, request_ptr, req_len); req_len = atoi(str_request_len); SFREE(str_request_len); while (strstr(str_request,"\r\n\r\n") == 0 && strstr(str_request, "\n\n") == 0 && strstr(str_request, "\r\r") == 0) { memset(buf,0,BUF_LEN + 1); int_request_len = read(csock, buf, BUF_LEN); FINISH_CAT_APPEND(str_request, buf); } request_ptr = strstr(str_request,"\r\n\r\n") != 0 ? strstr(str_request,"\r\n\r\n") + 4 : strstr(str_request,"\n\n") != 0 ? strstr(str_request,"\n\n") + 2 : strstr(str_request,"\r\r") != 0 ? strstr(str_request,"\r\r") + 2 : 0; unsigned int int_length_we_want = ((request_ptr - str_request) + req_len); //DEBUG("test3>%s|%s<", str_request, request_ptr); //DEBUG("test4>%i|%i|%i|%i<\n", int_length_we_want, strlen( str_request ), (request_ptr - str_request), req_len); while (int_length_we_want > strlen(str_request)) { memset(buf,0,BUF_LEN + 1); int_request_len = read(csock, buf, BUF_LEN); FINISH_CAT_APPEND(str_request, buf); //DEBUG("test4.1>%i|%i<\n", int_length_we_want, strlen( str_request )); } //DEBUG("test5\n"); int_request_len = strlen(str_request); // if not POST, then break at two newlines. // (only other request we accept is GET, we don't use any other methods of request) } else { while (strstr(str_request,"\r\n\r\n") == 0 && strstr(str_request,"\n\n") == 0 && strstr(str_request,"\r\r") == 0) { memset(buf, 0, BUF_LEN + 1); int_request_len = read(csock, buf, BUF_LEN); FINISH_CAT_APPEND(str_request, buf); } int_request_len = strlen(str_request); } DEBUG("request_len>%i<", strlen(str_request)); /* //for testing actions GS.ajaxJSON('URI', 'PARAMS', function (data, error) { if (!error) { console.log(data); } else { GS.ajaxErrorDialog(data); } }); */ str_uri = str_uri_path(str_request); FINISH_CHECK(str_uri != NULL, "str_uri_path failed"); INFO("### str_uri: %s", str_uri); str_host = request_header(str_request, "host"); INFO("### str_host: %s", str_host); //DEBUG("### REQUEST: %s", str_request); //check referer str_referer = request_header(str_request, "Referer"); INFO("### str_referer: %s", str_referer); //when we have a referer, we should make sure it matches our website, but we have a few exceptions. if (str_referer != NULL) { FINISH_CAT_CSTR(str_correct_referer_start1, "https://", str_host); FINISH_CAT_CSTR(str_correct_referer_start2, "http://" , str_host); FINISH_CHECK( strncmp(str_correct_referer_start1, str_referer, strlen(str_correct_referer_start1)) == 0 || strncmp(str_correct_referer_start2, str_referer, strlen(str_correct_referer_start2)) == 0 || strlen(str_referer) <= 0 || strncmp(str_uri, "/v1/" , 4 ) != 0 || //strncmp(str_uri, "/v1/env/auth", 12) == 0 || strncmp(str_uri, "/v1/cluster" , 11) == 0 || strncmp(str_uri, "/v1/app" , 7 ) == 0 || strncmp(str_uri, "/v1/dev" , 7 ) == 0, "Referer does not match host."); SFREE(str_correct_referer_start1); SFREE(str_correct_referer_start2); } //#################################################################################################### //######################################### MANAGE COOKIES ########################################### // set up database connection // FEAR NOT GCC! This will not be used uninitialized. //PQinitOpenSSL(0, 0); //prevent Libpq from initializing ssl bool bol_valid_subdomain = false; //if subdomain database configuration is active, then change int_global_current_conn_port //we use int_global_current_conn_port to connect to the postgres instance //if the subdomain is the default subdomain, we should connect to production //if the subdomain is not the default subdomain, we should connect to the correct developer area //if the subdomain is not recognized, we should connect to production if (strlen(str_global_developers) > 0) { char *temp = strchr(str_host, '.'); int int_length = temp - str_host; FINISH_SALLOC(str_current_subdomain, int_length + 1); DEBUG("### str_host: %s, temp: %s, char: %c, int_length: %d\n", str_host, temp, '.', int_length); memcpy(str_current_subdomain, str_host, int_length); str_current_subdomain[int_length] = '\0'; str_temp = getport(str_global_developers, str_current_subdomain); FINISH_CHECK(str_temp != NULL, "getport failed"); if (strlen(str_temp) > 0) { DEBUG("VALID SUBDOMAIN DETECTED >%s|%s<", str_global_developers, str_temp); int_global_current_conn_port = atoi(str_temp); bol_valid_subdomain = true; } SFREE(str_temp); } else { FINISH_CAT_CSTR(str_current_subdomain, ""); } DEBUG(">%s|%s|%i|%i<", str_uri, "/auth_envelope/accept_auth", strlen(str_uri), strncmp(str_uri, "/auth_envelope/accept_auth", 26) == 0); DEBUG("test0>str_request: %s", str_request); str_cookie_envelope = str_cookie(str_request, "envelope"); DEBUG("test1"); bol_global_public = false; DEBUG("str_uri: >%s< str_uri + 13 + strcspn(str_uri + 13, \"./\"): >%s<", str_uri, str_uri + 13 + strcspn(str_uri + 13, "./")); // if the URL does not start with /v1 // then serve from the web_root if (strncmp(str_uri, "/v1/", 4) != 0) { str_response = link_web_root(csock, str_uri, bol_valid_subdomain ? str_current_subdomain : ""); FINISH_CHECK(str_response != NULL, "link_web_root failed"); goto finish; // postgres functions that start with actionnc_ or acceptnc_ // these CAN have a COOKIE, but it WON'T BE USED // set up a public connection } else if (//str_cookie_envelope == NULL && strlen(str_uri) >= 13 && strncmp(str_uri, "/v1/cluster/", 12) == 0 && (strncmp(str_uri + 13 + strcspn(str_uri + 13, "./"), ".acceptnc_", 10) == 0 || strncmp(str_uri + 13 + strcspn(str_uri + 13, "./"), ".actionnc_", 10) == 0)) { cnxn = set_cnxn_public(csock, str_request); // built in envelope functions // these links CAN have a COOKIE, but if we don't then set up a public connection } else if (str_cookie_envelope == NULL && ((strlen(str_uri) >= 18 && strncmp(str_uri, "/v1/env/action_info" , 18) == 0) || (strlen(str_uri) >= 20 && strncmp(str_uri, "/v1/env/action_upload" , 20) == 0) || (strlen(str_uri) >= 22 && strncmp(str_uri, "/v1/env/accept_download" , 22) == 0) || (strlen(str_uri) >= 23 && strncmp(str_uri, "/v1/envelope/action_info" , 23) == 0) || (strlen(str_uri) >= 25 && strncmp(str_uri, "/v1/envelope/action_upload" , 25) == 0) || (strlen(str_uri) >= 27 && strncmp(str_uri, "/v1/envelope/accept_download", 27) == 0) || (strlen(str_uri) >= 21 && strncmp(str_uri, "/v1/env/action_select", 21) == 0) || (strlen(str_uri) >= 21 && strncmp(str_uri, "/v1/env/action_update", 21) == 0) || (strlen(str_uri) >= 21 && strncmp(str_uri, "/v1/env/action_insert", 21) == 0) || (strlen(str_uri) >= 21 && strncmp(str_uri, "/v1/env/action_delete", 21) == 0) || (strlen(str_uri) >= 20 && strncmp(str_uri, "/v1/env/action_order" , 20) == 0))) { cnxn = set_cnxn_public(csock, str_request); // authentication links for normal user, these CAN have a COOKIE } else if ((strlen(str_uri) >= 26 && strncmp(str_uri, "/auth_envelope/accept_auth", 26) == 0) || (strlen(str_uri) >= 12 && strncmp(str_uri, "/v1/env/auth", 12) == 0)) { /* FINISH_CHECK(strncmp(str_current_subdomain, str_global_subdomain, strlen(str_global_subdomain)) == 0, "Must be in \"%s\" subdomain.", str_global_subdomain); */ str_response = link_auth(cnxn, str_request); FINISH_CHECK(str_response != NULL, "link_auth failed"); goto finish; // authentication links for superuser, these REQUIRE a COOKIE } else if ((strlen(str_uri) >= 16 && strncmp(str_uri, "/v1/postage/auth", 16) == 0)) { str_response = link_auth_postage(str_request); FINISH_CHECK(str_response != NULL, "link_auth_postage failed"); goto finish; // superuser links, these REQUIRE a COOKIE } else if (strncmp(str_uri, "/v1/dev" , 7 ) == 0 || strncmp(str_uri, "/v1/postage", 11) == 0 || strncmp(str_uri, "/v1/sql" , 7 ) == 0) { cnxn = set_cnxn_postage(csock, str_uri, str_request); // subdomain links, these REQUIRE a COOKIE } else if (bol_valid_subdomain) { cnxn = set_cnxn_test(csock, str_uri, str_request); // production links, these REQUIRE a COOKIE } else { cnxn = set_cnxn(csock, str_uri, str_request); } //IF NULL THEN EXIT, CSOCK IS ALREADY WRITTEN TO BY set_cnxn AND set_cnxn_test if (cnxn == NULL) { //if we use FINISH_CHECK, there will be a sunlogf //we don't want a sunlogf cause there is no error. we just want to return goto finish; } // cnxn GARANTEED TO BE VALID HERE //if public cookie (or nocookie always) then public action if (bol_global_public) { str_response = main_public_action(cnxn, csock, str_uri, str_request, int_request_len, bol_valid_subdomain ? str_current_subdomain : ""); FINISH_CHECK(str_response != NULL, "link_auth failed"); goto finish; } //################################################################################################ //########################## HAVE COOKIE, HAVE CNXN, PARSE REQUESTS ############################## DEBUG("COOKIE IS VALID"); //not a webroot request if (strncmp(str_uri, "/v1/", 4) == 0) { char *ptr_uri = str_uri + 3; //this link is for accessing the database if (strlen(ptr_uri) >= 9 && strncmp(ptr_uri, "/cluster/", 9) == 0) { str_response = link_cluster(cnxn, ptr_uri, str_request, csock); FINISH_CHECK(str_response != NULL, "link_cluster failed"); //this link is for uploading a file to role } else if (strlen(ptr_uri) >= 16 && strncmp(ptr_uri, "/upload_envelope", 16) == 0) { str_response = link_upload(cnxn, str_request, int_request_len, bol_valid_subdomain ? str_current_subdomain : ""); FINISH_CHECK(str_response != NULL, "link_upload failed"); //this link is for builtin c actions like action_select (read from view) } else if (strlen(ptr_uri) >= 10 && strncmp(ptr_uri, "/envelope/", 10) == 0) { // link system is in envelope_handle_c.c str_response = link_system(cnxn, csock, ptr_uri + 5, str_request, int_request_len, bol_valid_subdomain ? str_current_subdomain : ""); FINISH_CHECK(str_response != NULL, "link_system failed"); //shorter version of the above link } else if (strlen(ptr_uri) >= 5 && strncmp(ptr_uri, "/env/", 5) == 0) { // link system is in envelope_handle_c.c str_response = link_system(cnxn, csock, ptr_uri, str_request, int_request_len, bol_valid_subdomain ? str_current_subdomain : ""); FINISH_CHECK(str_response != NULL, "link_system failed"); //read file from role } else if (strlen(ptr_uri) >= 6 && strncmp(ptr_uri, "/role/", 6) == 0) { str_response = link_role(csock, cnxn, ptr_uri, bol_valid_subdomain ? str_current_subdomain : ""); FINISH_CHECK(str_response != NULL, "link_role failed"); //read app file } else if (strncmp(ptr_uri, "/app/", 5) == 0) { str_response = link_apps(csock, cnxn, ptr_uri, bol_valid_subdomain ? str_current_subdomain : ""); FINISH_CHECK(str_response != NULL, "link_apps failed"); //read app file, but require superuser } else if (strncmp(ptr_uri, "/dev/", 5) == 0) { str_response = link_apps(csock, cnxn, ptr_uri, bol_valid_subdomain ? str_current_subdomain : ""); FINISH_CHECK(str_response != NULL, "link_apps failed"); //more builtin c actions, but require superuser } else if (strlen(ptr_uri) >= 9 && strncmp(ptr_uri, "/postage/", 9) == 0) { // link system is in postage_handle_c2.c str_response = link_system_postage(cnxn, csock, ptr_uri, str_request, int_request_len); FINISH_CHECK(str_response != NULL, "link_system_postage failed"); //run arbitrary sql, must be superuser } else if (strlen(ptr_uri) >= 4 && strncmp(ptr_uri, "/sql", 4) == 0) { str_response = link_sql(csock, cnxn, str_request); FINISH_CHECK(str_response != NULL, "link_sql failed"); //if none of these, error } else { NOTICE("REQUEST TYPE: UNHANDLED str_uri:%s", str_uri); FINISH_CAT_CSTR(str_response, "HTTP/1.1 303 See Other\r\nLocation: /index.html\r\n"); } //web_root request should already have been handled, error } else { NOTICE("REQUEST TYPE: UNHANDLED str_uri:%s", str_uri); FINISH_CAT_CSTR(str_response, "HTTP/1.1 303 See Other\r\nLocation: /index.html\r\n"); } finish: if (str_response != NULL) { INFO("REPLACE COOKIE IN str_response"); //replace cookie before expiration str_complete_response = replace_cookie(str_response, str_request); SFREE_PWORD(str_response); DEBUG("str_complete_response: %s", str_complete_response); if ((long)write(csock, str_complete_response, strlen(str_complete_response)) != (long)strlen(str_complete_response)) { str_complete_response = ERROR_RESPONSE("write failed: %d (%s)", errno, strerror(errno)); write(csock, str_complete_response, strlen(str_complete_response)); } } else { ERROR_NORESPONSE("no str_response"); } fsync(csock); NOTICE("RESPONSE SENT %d bytes", strlen(str_complete_response)); if (cnxn != NULL) PQfinish(cnxn); SFREE_PWORD(str_request); SFREE_ALL(); return true; }