summaryrefslogtreecommitdiff
path: root/https_server.h
diff options
context:
space:
mode:
Diffstat (limited to 'https_server.h')
-rw-r--r--https_server.h152
1 files changed, 152 insertions, 0 deletions
diff --git a/https_server.h b/https_server.h
new file mode 100644
index 0000000..4b1776f
--- /dev/null
+++ b/https_server.h
@@ -0,0 +1,152 @@
+#include "https_response.h"
+
+char *get_client_ip( server_socket_t *svd, client_info_t *cl_info ){
+ cl_info->client_ip = (char*)malloc( 8192 * sizeof(char) );
+ if ( inet_ntop(AF_INET, &svd->client_info.sin_addr, cl_info->client_ip, (socklen_t)(8192 * sizeof(char))) != NULL )
+ return cl_info->client_ip;
+ return "Unknown";
+}
+
+void clear_client_ip( client_info_t *clf ){
+ if ( clf->client_ip != NULL ){
+ free( clf->client_ip );
+ clf->client_ip = NULL;
+ }
+ return;
+}
+
+void https_server_event_loop( server_socket_t *sv, client_info_t *cl, server_config_t *svcfg, webhooks_data_t *wdata, http_request_data_t *http_req_data, log_file_t *logf ){
+ int ev_count = 0;
+ socklen_t cl_info_len = (socklen_t)sizeof( sv->client_info );
+ while ( (ev_count = poll(sv->pstruct, 1, 0)) != -1 ){
+ if ( ev_count > 0 ){
+ sv->client_socket_fd = accept( sv->socket_fd, (struct sockaddr*)&sv->client_info, &cl_info_len );
+ if ( sv->client_socket_fd == -1 ){
+ log_write( svcfg, logf, "Error: failed to accept connection" );
+ continue;
+ }
+ sv->tls_session = SSL_new( sv->tls_context );
+ if ( sv->tls_session == NULL ){
+ shutdown( sv->client_socket_fd, SHUT_RDWR );
+ close( sv->client_socket_fd );
+ log_write( svcfg, logf, "Error: failed to create TLS session" );
+ continue;
+ }
+ if ( SSL_set_fd(sv->tls_session, sv->client_socket_fd) != 1 ){
+ shutdown( sv->client_socket_fd, SHUT_RDWR );
+ close( sv->client_socket_fd );
+ if ( sv->tls_session != NULL )
+ SSL_free( sv->tls_session );
+ log_write( svcfg, logf, "Error: failed to set client file descriptor" );
+ continue;
+ }
+ SSL_set_accept_state( sv->tls_session );
+ if ( SSL_accept(sv->tls_session) != 1 ){
+ if ( sv->tls_session != NULL )
+ SSL_shutdown( sv->tls_session );
+ shutdown( sv->client_socket_fd, SHUT_RDWR );
+ close( sv->client_socket_fd );
+ if ( sv->tls_session != NULL )
+ SSL_free( sv->tls_session );
+ log_write( svcfg, logf, "Error: failed to initiate handshake" );
+ continue;
+ }
+ if ( strcmp((const char*)svcfg->log_enabled->valuestring, "yes") == 0 ){
+ fprintf( logf->log_file, "Received connection from %s\n", get_client_ip(sv, cl) );
+ clear_client_ip( cl );
+ }
+ sv->recv_peek = (char*)calloc( (size_t)((uint64_t)MAX_PEEK_BYTES), sizeof(char) );
+ if ( sv->recv_peek == NULL ){
+ SSL_shutdown( sv->tls_session );
+ shutdown( sv->client_socket_fd, SHUT_RDWR );
+ close( sv->client_socket_fd );
+ if ( sv->tls_session != NULL )
+ SSL_free( sv->tls_session );
+ log_write( svcfg, logf, "Error: failed to allocate memory for reading amount of incoming data" );
+ continue;
+ }
+ sv->recv_pending_bytes = (long long int)SSL_peek( sv->tls_session, sv->recv_peek, (long long int)MAX_PEEK_BYTES );
+ if ( sv->recv_pending_bytes <= 0 || SSL_get_error(sv->tls_session, sv->recv_pending_bytes) != SSL_ERROR_NONE ){
+ free( sv->recv_peek );
+ sv->recv_peek = NULL;
+ SSL_shutdown( sv->tls_session );
+ shutdown( sv->client_socket_fd, SHUT_RDWR );
+ close( sv->client_socket_fd );
+ if ( sv->tls_session != NULL )
+ SSL_free( sv->tls_session );
+ sv->recv_pending_bytes = 0;
+ log_write( svcfg, logf, "Error: no bytes were received" );
+ continue;
+ }
+ free( sv->recv_peek );
+ sv->recv_peek = NULL;
+ if ( sv->recv_pending_bytes > (long long int)MAX_RECV_BYTES ){
+ SSL_shutdown( sv->tls_session );
+ shutdown( sv->client_socket_fd, SHUT_RDWR );
+ close( sv->client_socket_fd );
+ if ( sv->tls_session != NULL )
+ SSL_free( sv->tls_session );
+ log_write( svcfg, logf, "Error: too many bytes received" );
+ continue;
+ }
+ sv->recv_data = (char*)calloc( (size_t)sv->recv_pending_bytes, sizeof(char) );
+ if ( sv->recv_data == NULL ){
+ SSL_shutdown( sv->tls_session );
+ close( sv->client_socket_fd );
+ if ( sv->tls_session != NULL )
+ SSL_free( sv->tls_session );
+ log_write( svcfg, logf, "Error: failed to allocate memory for received bytes" );
+ continue;
+ }
+ sv->recv_read_bytes = (long long int)SSL_read( sv->tls_session, sv->recv_data, sv->recv_pending_bytes );
+ if ( sv->recv_read_bytes > 0 && SSL_get_error(sv->tls_session, sv->recv_read_bytes) == SSL_ERROR_NONE ){
+ int res_status = send_response( sv, svcfg, wdata, http_req_data, logf );
+ if ( res_status == RES_SUCCESS ){
+ log_write( svcfg, logf, "Success, response sent" );
+ }
+ else if ( res_status == RES_UNAUTHORIZED ){
+ log_write( svcfg, logf, "Error: unauthorized request" );
+ }
+ else
+ {
+ log_write( svcfg, logf, "Error: failed to send response" );
+ }
+ res_status = 0;
+ }
+ else
+ {
+ log_write( svcfg, logf, "Error: no bytes received" );
+ }
+ sv->recv_pending_bytes = 0;
+ sv->recv_read_bytes = 0;
+ free( sv->recv_data );
+ sv->recv_data = NULL;
+ SSL_shutdown( sv->tls_session );
+ shutdown( sv->client_socket_fd, SHUT_RDWR );
+ close( sv->client_socket_fd );
+ if ( sv->tls_session != NULL )
+ SSL_free( sv->tls_session );
+ }
+ }
+ perror( "poll" );
+ cl_info_len = 0;
+ ev_count = 0;
+ return;
+}
+
+void server_start( server_socket_t *srv, client_info_t *cli, server_config_t *sconf, webhooks_data_t *whdata, http_request_data_t *hreq, log_file_t *lfdt ){
+ fputs( "Starting server\n", stdout );
+ memset( &srv->client_info, 0, sizeof(srv->client_info) );
+ whdata->wh_command = NULL;
+ whdata->wh_response = NULL;
+ whdata->wh_output = NULL;
+ srv->pstruct[0].fd = srv->socket_fd;
+ srv->pstruct[0].events = POLLIN;
+ if ( listen(srv->socket_fd, 1024) == -1 ){
+ fputs( "Failed to start listening for connections\n", stderr );
+ return;
+ }
+ fputs( "Server started\n", stdout );
+ https_server_event_loop( srv, cli, sconf, whdata, hreq, lfdt );
+ return;
+}