#include "http_headers.h" #include "auth.h" #include "webhook_exec.h" #define HTTP_TEXT_BASE "HTTP/1.1 200 OK\r\nServer: CWebHook\r\nContent-Type: text/plain; charset=utf-8\r\n\r\n" #define HTTP_ERROR_HEADERS "HTTP/1.1 500 Internal Server Error\r\nServer: CWebHook\r\nContent-Type: text/plain; charset=utf-8\r\n\r\nError: failed to read some request data" #define HTTP_DISALLOWED_METHOD "HTTP/1.1 403 Forbidden\r\nServer: CWebHook\r\nContent-Type: text/plain; charset=utf-8\r\n\r\nError: disallowed request method" #define HTTP_MEM_ALLOC_ERROR "HTTP/1.1 500 Internal Server Error\r\nServer: CWebHook\r\nContent-Type: text/plain; charset=utf-8\r\n\r\nError: failed to allocate memory for webhook response" #define HTTP_MEM_WRITE_ERROR "HTTP/1.1 500 Internal Server Error\r\nServer: CWebHook\r\nContent-Type: text/plain; charset=utf-8\r\n\r\nError: failed to write to allocated memory" #define HTTP_UNKNOWN_ENDPOINT "HTTP/1.1 404 Not Found\r\nServer: CWebHook\r\nContent-Type: text/plain; charset=utf-8\r\n\r\nError: no such API endpoint found" #define HTTP_UNAUTHORIZED "HTTP/1.1 403 Forbidden\r\nServer: CWebHook\r\nContent-Type: text/plain; charset=utf-8\r\n\r\nUnauthorized" #define RES_SUCCESS 0 #define RES_FAILED -1 #define RES_UNAUTHORIZED -2 int send_response( server_socket_t *sdata, server_config_t *scf, webhooks_data_t *wdt, http_request_data_t *hdata, log_file_t *lfd ){ if ( get_request_data(hdata, sdata->recv_data) != REQ_READ_SUCCESS ){ clear_request_copy( hdata ); clear_request_data( hdata ); log_write( scf, lfd, "Error: failed to read headers" ); if ( (int64_t)SSL_write(sdata->tls_session, HTTP_ERROR_HEADERS, (size_t)strlen(HTTP_ERROR_HEADERS)) <= 0 ) return RES_FAILED; return RES_SUCCESS; } if ( strcmp((const char*)hdata->request_method, "GET") != 0 && strcmp((const char*)hdata->request_method, "POST") != 0 ){ clear_request_copy( hdata ); clear_request_data( hdata ); if ( (int64_t)SSL_write(sdata->tls_session, HTTP_DISALLOWED_METHOD, (size_t)strlen(HTTP_DISALLOWED_METHOD)) <= 0 ) return RES_FAILED; return RES_SUCCESS; } if ( hdata->request_body == NULL || (uint64_t)strlen(hdata->request_body) <= 0 ){ clear_request_copy( hdata ); clear_request_data( hdata ); if ( (int64_t)SSL_write(sdata->tls_session, HTTP_UNAUTHORIZED, (size_t)strlen(HTTP_UNAUTHORIZED)) <= 0 ) return RES_FAILED; return RES_UNAUTHORIZED; } if ( check_password(hdata->request_body, scf->server_password->valuestring) != AUTH_SUCCESS ){ clear_request_copy( hdata ); clear_request_data( hdata ); if ( (int64_t)SSL_write(sdata->tls_session, HTTP_UNAUTHORIZED, (size_t)strlen(HTTP_UNAUTHORIZED)) <= 0 ) return RES_FAILED; return RES_UNAUTHORIZED; } char *wh_exec_res = webhook_exec( wdt, hdata->request_path ); size_t r_size = (size_t)((size_t)strlen(HTTP_TEXT_BASE) + (size_t)strlen(wh_exec_res) + 1); sdata->send_buffer = (char*)calloc( r_size, sizeof(char) ); if ( sdata->send_buffer == NULL ){ r_size = 0; free_wh_output( wdt ); wh_exec_res = NULL; if ( (int64_t)SSL_write(sdata->tls_session, HTTP_MEM_ALLOC_ERROR, (size_t)strlen(HTTP_MEM_ALLOC_ERROR)) <= 0 ) return RES_FAILED; return RES_SUCCESS; } if ( snprintf(sdata->send_buffer, r_size * sizeof(char), "%s%s", HTTP_TEXT_BASE, wh_exec_res) <= 0 ){ free( sdata->send_buffer ); r_size = 0; free_wh_output( wdt ); wh_exec_res = NULL; if ( (int64_t)SSL_write(sdata->tls_session, HTTP_MEM_WRITE_ERROR, (size_t)strlen(HTTP_MEM_WRITE_ERROR)) <= 0 ) return RES_FAILED; return RES_SUCCESS; } if ( (int64_t)SSL_write(sdata->tls_session, sdata->send_buffer, r_size) <= 0 ){ free( sdata->send_buffer ); free_wh_output( wdt ); wh_exec_res = NULL; r_size = 0; return RES_FAILED; } free( sdata->send_buffer ); free_wh_output( wdt ); wh_exec_res = NULL; r_size = 0; return RES_SUCCESS; }