diff options
Diffstat (limited to 'fluent-bit/lib/monkey/plugins')
76 files changed, 0 insertions, 8965 deletions
diff --git a/fluent-bit/lib/monkey/plugins/CMakeLists.txt b/fluent-bit/lib/monkey/plugins/CMakeLists.txt deleted file mode 100644 index a78d83695..000000000 --- a/fluent-bit/lib/monkey/plugins/CMakeLists.txt +++ /dev/null @@ -1,111 +0,0 @@ -set(static_plugins "" CACHE INTERNAL "static_plugins") -set(CMAKE_POSITION_INDEPENDENT_CODE ON) - -# CHECK_STATIC_PLUGIN: Check if a plugin will be linked statically -macro(CHECK_STATIC_PLUGIN name) - string(REPLACE "," ";" plugins ${MK_STATIC_PLUGINS}) - list(FIND plugins ${name} found) - if(NOT found EQUAL -1) - set(IS_STATIC TRUE) - else() - set(IS_STATIC FALSE) - endif() -endmacro() - -# MONKEY_PLUGIN: Used by plugins to register and create the targets -macro(MONKEY_PLUGIN name src) - CHECK_STATIC_PLUGIN(${name}) - if(IS_STATIC) - add_library(monkey-${name}-static STATIC ${src}) - set_target_properties(monkey-${name}-static PROPERTIES OUTPUT_NAME monkey-${name}) - set_target_properties(monkey-${name}-static PROPERTIES PREFIX "") - else() - if(APPLE) - add_library(monkey-${name}-shared MODULE ${src}) - else() - add_library(monkey-${name}-shared SHARED ${src}) - endif() - set_target_properties(monkey-${name}-shared PROPERTIES OUTPUT_NAME monkey-${name}) - set_target_properties(monkey-${name}-shared PROPERTIES PREFIX "") - - if(NOT MK_LOCAL) - if(CMAKE_INSTALL_LIBDIR) - install(TARGETS monkey-${name}-shared LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) - else() - install(TARGETS monkey-${name}-shared LIBRARY DESTINATION lib) - endif() - endif() - endif() -endmacro() - -# MK_BUILD_PLUGIN: This macro determinate if the plugin is enabled through the -# option MK_PLUGIN_NAME defined on the root CMakeLists.txt -macro(MK_BUILD_PLUGIN name) - set(mode "") - string(TOUPPER ${name} NAME) - - # Check if the plugin is enabled - set(option MK_PLUGIN_${NAME}) - if(${option}) - add_subdirectory(${name}) - - # Is this a static plugin ? - CHECK_STATIC_PLUGIN(${name}) - if(IS_STATIC) - # Let Monkey and CMake aware about this is a static plugin. A static plugin - # requires a different handling: link the object and register the plugin - # struct reference on mk_static_plugins.h - set(static_plugins "${static_plugins}monkey-${name}-static;") - set(STATIC_PLUGINS_INIT "${STATIC_PLUGINS_INIT}\n mk_static_plugin_attach(plugins, &mk_plugin_${name});\n") - set(STATIC_PLUGINS_DECL "${STATIC_PLUGINS_DECL}extern struct mk_plugin mk_plugin_${name};\n") - - # append message to stdout - set(mode "[== static ==]") - else() - if(MK_LOCAL) - set(MK_LOAD_PLUGINS "${MK_LOAD_PLUGINS} # Load ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/monkey-${name}.so\n") - else() - set(MK_LOAD_PLUGINS "${MK_LOAD_PLUGINS} # Load ${CMAKE_INSTALL_FULL_LIBDIR}/monkey-${name}.so\n") - endif() - endif() - message(STATUS "Plugin ${name} enabled ${mode}") - endif() -endmacro() - - -macro(MONKEY_PLUGIN_LINK_LIB target lib) - CHECK_STATIC_PLUGIN(${target}) - if(IS_STATIC) - target_link_libraries(monkey-${target}-static ${lib}) - else() - target_link_libraries(monkey-${target}-shared ${lib}) - endif() -endmacro() - -# Try to configure/build all plugins -MK_BUILD_PLUGIN("auth") -MK_BUILD_PLUGIN("cgi") -MK_BUILD_PLUGIN("cheetah") -MK_BUILD_PLUGIN("dirlisting") -MK_BUILD_PLUGIN("fastcgi") -MK_BUILD_PLUGIN("liana") -MK_BUILD_PLUGIN("logger") -MK_BUILD_PLUGIN("mandril") -MK_BUILD_PLUGIN("tls") -MK_BUILD_PLUGIN("duda") - -# Generate include/monkey/mk_static_plugins.h -configure_file( - "${PROJECT_SOURCE_DIR}/include/monkey/mk_static_plugins.h.in" - "${PROJECT_SOURCE_DIR}/include/monkey/mk_static_plugins.h" - ) - -# Generate conf/plugins.load -if(NOT MK_WITHOUT_CONF) - configure_file( - "${PROJECT_SOURCE_DIR}/conf/plugins.load.in" - "${PROJECT_BINARY_DIR}/conf/plugins.load" - ) -endif() - -set(STATIC_PLUGINS_LIBS "${static_plugins}" PARENT_SCOPE) diff --git a/fluent-bit/lib/monkey/plugins/README b/fluent-bit/lib/monkey/plugins/README deleted file mode 100644 index 0daa023cb..000000000 --- a/fluent-bit/lib/monkey/plugins/README +++ /dev/null @@ -1,61 +0,0 @@ -Monkey Plugins -============== -Plugins are extra features which modifies the Monkey behavior, all of them -are shared libraries which are loaded on runtime. - -Each plugin is loaded per configuration instruction and it will work on a -defined stage or event depending of it's type. - -Please review the file API.txt for more details - - - -MK_PLUGIN_STAGE_10: Server has not yet entered in the server loop, no - listeners yet available ---------------------------------------------------------------------- - Return Values > - - -MK_PLUGIN_STAGE_20: Accepted connection has not been assigned to worker thread ------------------------------------------------------------------------------- - Return Values > - - * MK_PLUGIN_RET_CLOSE_CONX: The connection must be closed. - - -MK_PLUGIN_STAGE_30: HTTP Request received ------------------------------------------ - Return Values > - * MK_PLUGIN_RET_CLOSE_CONX: The connection must be closed. - - -MK_PLUGIN_STAGE_40: Object Handler ------------------------------------------ - Extra functions > - * _mk_plugin_stage_40_loop(): if _mk_plugin_stage_40() has - returned MK_PLUGIN_RET_CONTINUE, the server will wait - for an event and call _mk_plugin_stage_40() until it - returns MK_PLUGIN_RET_END. - - Return Values > - * MK_PLUGIN_RET_END - * MK_PLUGIN_RET_CONTINUE - - Return Values > - * MK_PLUGIN_RET_NOT_ME: Plugin will not handle this request. - - * MK_PLUGIN_RET_END: Plugin has taken some action and - has finished the work, the handler will no take the request - again. - - * MK_PLUGIN_RET_CONTINUE:: Plugin has taken some action and - will continue in the next loop. - - -MK_PLUGIN_STAGE_50: Request ended ------------------------------------------ - - -MK_PLUGIN_STAGE_60: The Connection has been closed --------------------------------------------------- - diff --git a/fluent-bit/lib/monkey/plugins/auth/ABOUT b/fluent-bit/lib/monkey/plugins/auth/ABOUT deleted file mode 100644 index 66a5384c3..000000000 --- a/fluent-bit/lib/monkey/plugins/auth/ABOUT +++ /dev/null @@ -1,2 +0,0 @@ -HTTP Basic Authentication -========================= diff --git a/fluent-bit/lib/monkey/plugins/auth/CMakeLists.txt b/fluent-bit/lib/monkey/plugins/auth/CMakeLists.txt deleted file mode 100644 index a6fd27a06..000000000 --- a/fluent-bit/lib/monkey/plugins/auth/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -set(src - auth.c - base64.c - conf.c - sha1.c - ) - -add_subdirectory(tools) - -MONKEY_PLUGIN(auth "${src}") diff --git a/fluent-bit/lib/monkey/plugins/auth/OPTIONAL b/fluent-bit/lib/monkey/plugins/auth/OPTIONAL deleted file mode 100644 index e69de29bb..000000000 --- a/fluent-bit/lib/monkey/plugins/auth/OPTIONAL +++ /dev/null diff --git a/fluent-bit/lib/monkey/plugins/auth/auth.c b/fluent-bit/lib/monkey/plugins/auth/auth.c deleted file mode 100644 index b0f983bfb..000000000 --- a/fluent-bit/lib/monkey/plugins/auth/auth.c +++ /dev/null @@ -1,254 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <monkey/mk_api.h> - -#include <sys/stat.h> - -#include "auth.h" -#include "conf.h" -#include "sha1.h" -#include "base64.h" - -static int mk_auth_validate_user(struct users_file *users, - const char *credentials, unsigned int len) -{ - int sep; - size_t auth_len; - unsigned char *decoded = NULL; - unsigned char digest[SHA1_DIGEST_LEN]; - struct mk_list *head; - struct user *entry; - - SHA_CTX sha; /* defined in sha1/sha1.h */ - - /* Validate value length */ - if (len <= auth_header_basic.len + 1) { - return -1; - } - - /* Validate 'basic' credential type */ - if (strncmp(credentials, auth_header_basic.data, - auth_header_basic.len) != 0) { - return -1; - } - - /* Decode credentials: incoming credentials comes in base64 encode */ - decoded = base64_decode((unsigned char *) credentials + auth_header_basic.len, - len - auth_header_basic.len, - &auth_len); - if (decoded == NULL) { - PLUGIN_TRACE("Failed to decode credentials."); - goto error; - } - - if (auth_len <= 3) { - goto error; - } - - sep = mk_api->str_search_n((char *) decoded, ":", 1, auth_len); - if (sep == -1 || sep == 0 || (unsigned int) sep == auth_len - 1) { - goto error; - } - - /* Get SHA1 hash */ - SHA1_Init(&sha); - SHA1_Update(&sha, (unsigned char *) decoded + sep + 1, auth_len - (sep + 1)); - SHA1_Final(digest, &sha); - - mk_list_foreach(head, &users->_users) { - entry = mk_list_entry(head, struct user, _head); - /* match user */ - if (strlen(entry->user) != (unsigned int) sep) { - continue; - } - if (strncmp(entry->user, (char *) decoded, sep) != 0) { - continue; - } - - PLUGIN_TRACE("User match '%s'", entry->user); - - /* match password */ - if (memcmp(entry->passwd_decoded, digest, SHA1_DIGEST_LEN) == 0) { - PLUGIN_TRACE("User '%s' matched password", entry->user); - mk_api->mem_free(decoded); - return 0; - } - PLUGIN_TRACE("Invalid password"); - break; - } - - error: - if (decoded) { - mk_api->mem_free(decoded); - } - return -1; -} - -int mk_auth_plugin_init(struct plugin_api **api, char *confdir) -{ - (void) confdir; - - mk_api = *api; - - /* Init and load global users list */ - mk_list_init(&vhosts_list); - mk_list_init(&users_file_list); - mk_auth_conf_init_users_list(); - - /* Set HTTP headers key */ - auth_header_basic.data = MK_AUTH_HEADER_BASIC; - auth_header_basic.len = sizeof(MK_AUTH_HEADER_BASIC) - 1; - - return 0; -} - -int mk_auth_plugin_exit() -{ - return 0; -} - -void mk_auth_worker_init() -{ - char *user; - - /* Init thread buffer for given credentials */ - user = mk_api->mem_alloc(MK_AUTH_CREDENTIALS_LEN - 1); - pthread_setspecific(_mkp_data, (void *) user); -} - -/* Object handler */ -int mk_auth_stage30(struct mk_plugin *plugin, - struct mk_http_session *cs, - struct mk_http_request *sr, - int n_params, - struct mk_list *params) -{ - int val; - short int is_restricted = MK_FALSE; - struct mk_list *vh_head; - struct mk_list *loc_head; - struct vhost *vh_entry = NULL; - struct location *loc_entry; - struct mk_http_header *header; - (void) plugin; - (void) n_params; - (void) params; - - PLUGIN_TRACE("[FD %i] Handler received request"); - - /* Match auth_vhost with global vhost */ - mk_list_foreach(vh_head, &vhosts_list) { - vh_entry = mk_list_entry(vh_head, struct vhost, _head); - if (vh_entry->host == sr->host_conf) { - PLUGIN_TRACE("[FD %i] host matched %s", - cs->socket, - mk_api->config->server_signature); - break; - } - } - - if (!vh_entry) { - return MK_PLUGIN_RET_NOT_ME; - } - - /* Check vhost locations */ - mk_list_foreach(loc_head, &vh_entry->locations) { - loc_entry = mk_list_entry(loc_head, struct location, _head); - if (sr->uri_processed.len < loc_entry->path.len) { - continue; - } - if (strncmp(sr->uri_processed.data, - loc_entry->path.data, loc_entry->path.len) == 0) { - is_restricted = MK_TRUE; - PLUGIN_TRACE("[FD %i] Location matched %s", - cs->socket, - loc_entry->path.data); - break; - } - } - - /* For non-restricted location do not take any action, just returns */ - if (is_restricted == MK_FALSE) { - return MK_PLUGIN_RET_NOT_ME; - } - - /* Check authorization header */ - header = mk_api->header_get(MK_HEADER_AUTHORIZATION, - sr, NULL, 0); - - if (header) { - /* Validate user */ - val = mk_auth_validate_user(loc_entry->users, - header->val.data, header->val.len); - if (val == 0) { - /* user validated, success */ - PLUGIN_TRACE("[FD %i] user validated!", cs->socket); - return MK_PLUGIN_RET_NOT_ME; - } - } - - /* Restricted access: requires auth */ - PLUGIN_TRACE("[FD %i] unauthorized user, credentials required", - cs->socket); - - sr->headers.content_length = 0; - mk_api->header_set_http_status(sr, MK_CLIENT_UNAUTH); - mk_api->header_add(sr, - loc_entry->auth_http_header.data, - loc_entry->auth_http_header.len); - - mk_api->header_prepare(plugin, cs, sr); - return MK_PLUGIN_RET_END; -} - -int mk_auth_stage30_hangup(struct mk_plugin *plugin, - struct mk_http_session *cs, - struct mk_http_request *sr) -{ - (void) plugin; - (void) cs; - (void) sr; - - return 0; -} - -struct mk_plugin_stage mk_plugin_stage_auth = { - .stage30 = &mk_auth_stage30, - .stage30_hangup = &mk_auth_stage30_hangup -}; - -struct mk_plugin mk_plugin_auth = { - /* Identification */ - .shortname = "auth", - .name = "Basic Authentication", - .version = MK_VERSION_STR, - .hooks = MK_PLUGIN_STAGE, - - /* Init / Exit */ - .init_plugin = mk_auth_plugin_init, - .exit_plugin = mk_auth_plugin_exit, - - /* Init Levels */ - .master_init = NULL, - .worker_init = mk_auth_worker_init, - - /* Type */ - .stage = &mk_plugin_stage_auth -}; diff --git a/fluent-bit/lib/monkey/plugins/auth/auth.h b/fluent-bit/lib/monkey/plugins/auth/auth.h deleted file mode 100644 index f6eebe83e..000000000 --- a/fluent-bit/lib/monkey/plugins/auth/auth.h +++ /dev/null @@ -1,106 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MK_AUTH_H -#define MK_AUTH_H - -#include <monkey/mk_api.h> - -/* Header stuff */ -#define MK_AUTH_HEADER_BASIC "Basic " -#define MK_AUTH_HEADER_TITLE "WWW-Authenticate: Basic realm=\"%s\"" - -/* Credentials length */ -#define MK_AUTH_CREDENTIALS_LEN 256 - -/* - * The plugin hold one struct per virtual host and link to the - * locations and users file associated: - * - * +---------------------------------+ - * struct vhost > vhost (1:N) | - * | +---------+----------+ | - * | | | | | - * struct location > location location location | - * | | | | | - * | +----+----+ + | - * | | | | - * struct users > users users | - * +---------------------------------+ - * - */ - -/* List of virtual hosts to handle locations */ -struct mk_list vhosts_list; - -/* main index for locations under a virtualhost */ -struct vhost { - struct mk_vhost *host; - struct mk_list locations; - struct mk_list _head; -}; - -/* - * A location restrict a filesystem path with a list - * of allowed users - */ -struct location { - mk_ptr_t path; - mk_ptr_t title; - mk_ptr_t auth_http_header; - - struct users_file *users; - struct mk_list _head; -}; - -/* Head index for user files list */ -struct mk_list users_file_list; - -/* - * Represents a users file, each entry represents a physical - * file and belongs to a node of the users_file_list list - */ -struct users_file { - time_t last_updated; /* last time this entry was modified */ - char *path; /* file path */ - struct mk_list _users; /* list of users */ - struct mk_list _head; /* head for main mk_list users_file_list */ -}; - -/* - * a list of users, this list belongs to a - * struct location - */ -struct user { - char user[128]; - char passwd_raw[256]; - unsigned char *passwd_decoded; - - struct mk_list _head; -}; - -struct mk_list users_file_list; - -/* Thread key */ -mk_ptr_t auth_header_request; -mk_ptr_t auth_header_basic; - -#define SHA1_DIGEST_LEN 20 - -#endif diff --git a/fluent-bit/lib/monkey/plugins/auth/base64.c b/fluent-bit/lib/monkey/plugins/auth/base64.c deleted file mode 100644 index e3149fe73..000000000 --- a/fluent-bit/lib/monkey/plugins/auth/base64.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Base64 encoding/decoding (RFC1341) - * Copyright (c) 2005-2011, Jouni Malinen <j@w1.fi> - * - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ - -#ifdef _FORCE_SYSMALLOC -#undef MALLOC_JEMALLOC -#endif - -#include <monkey/mk_api.h> -#include "base64.h" - -#if defined(MALLOC_JEMALLOC) -#define __mem_alloc mk_api->mem_alloc -#define __mem_free mk_api->mem_free -#else -#define __mem_alloc malloc -#define __mem_free free -#endif - -static const unsigned char base64_table[65] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -/** - * base64_encode - Base64 encode - * @src: Data to be encoded - * @len: Length of the data to be encoded - * @out_len: Pointer to output length variable, or %NULL if not used - * Returns: Allocated buffer of out_len bytes of encoded data, - * or %NULL on failure - * - * Caller is responsible for freeing the returned buffer. Returned buffer is - * nul terminated to make it easier to use as a C string. The nul terminator is - * not included in out_len. - */ -unsigned char * base64_encode(const unsigned char *src, size_t len, - size_t *out_len) -{ - unsigned char *out, *pos; - const unsigned char *end, *in; - size_t olen; - int line_len; - - olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */ - olen += olen / 72; /* line feeds */ - olen++; /* nul termination */ - if (olen < len) - return NULL; /* integer overflow */ - if (mk_api != NULL) { - out = __mem_alloc(olen); - } - else { - out = __mem_alloc(olen); - } - - if (out == NULL) - return NULL; - - end = src + len; - in = src; - pos = out; - line_len = 0; - while (end - in >= 3) { - *pos++ = base64_table[in[0] >> 2]; - *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; - *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)]; - *pos++ = base64_table[in[2] & 0x3f]; - in += 3; - line_len += 4; - if (line_len >= 72) { - *pos++ = '\n'; - line_len = 0; - } - } - - if (end - in) { - *pos++ = base64_table[in[0] >> 2]; - if (end - in == 1) { - *pos++ = base64_table[(in[0] & 0x03) << 4]; - *pos++ = '='; - } else { - *pos++ = base64_table[((in[0] & 0x03) << 4) | - (in[1] >> 4)]; - *pos++ = base64_table[(in[1] & 0x0f) << 2]; - } - *pos++ = '='; - line_len += 4; - } - - if (line_len) - *pos++ = '\n'; - - *pos = '\0'; - if (out_len) - *out_len = pos - out; - return out; -} - - -/** - * base64_decode - Base64 decode - * @src: Data to be decoded - * @len: Length of the data to be decoded - * @out_len: Pointer to output length variable - * Returns: Allocated buffer of out_len bytes of decoded data, - * or %NULL on failure - * - * Caller is responsible for freeing the returned buffer. - */ -unsigned char * base64_decode(const unsigned char *src, size_t len, - size_t *out_len) -{ - unsigned char dtable[256], *out, *pos, block[4], tmp; - size_t i, count, olen; - int pad = 0; - - memset(dtable, 0x80, 256); - for (i = 0; i < sizeof(base64_table) - 1; i++) - dtable[base64_table[i]] = (unsigned char) i; - dtable['='] = 0; - - count = 0; - for (i = 0; i < len; i++) { - if (dtable[src[i]] != 0x80) - count++; - } - - if (count == 0 || count % 4) - return NULL; - - olen = (count / 4 * 3) + 1; - pos = out = __mem_alloc(olen); - if (out == NULL) - return NULL; - - count = 0; - for (i = 0; i < len; i++) { - tmp = dtable[src[i]]; - if (tmp == 0x80) - continue; - - if (src[i] == '=') - pad++; - block[count] = tmp; - count++; - if (count == 4) { - *pos++ = (block[0] << 2) | (block[1] >> 4); - *pos++ = (block[1] << 4) | (block[2] >> 2); - *pos++ = (block[2] << 6) | block[3]; - count = 0; - if (pad) { - if (pad == 1) - pos--; - else if (pad == 2) - pos -= 2; - else { - /* Invalid padding */ - __mem_free(out); - return NULL; - } - break; - } - } - } - *pos = '\0'; - - *out_len = pos - out; - return out; -} diff --git a/fluent-bit/lib/monkey/plugins/auth/base64.h b/fluent-bit/lib/monkey/plugins/auth/base64.h deleted file mode 100644 index 45001d47f..000000000 --- a/fluent-bit/lib/monkey/plugins/auth/base64.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef AUTH_BASE64_H -#define AUTH_BASE64_H - - -unsigned char * base64_encode(const unsigned char *src, size_t len, - size_t *out_len); -unsigned char *base64_decode(const unsigned char *src, size_t len, - size_t *out_len); - - -#endif diff --git a/fluent-bit/lib/monkey/plugins/auth/conf.c b/fluent-bit/lib/monkey/plugins/auth/conf.c deleted file mode 100644 index 6dede1dd4..000000000 --- a/fluent-bit/lib/monkey/plugins/auth/conf.c +++ /dev/null @@ -1,244 +0,0 @@ - /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <monkey/mk_api.h> -#include "base64.h" -#include "auth.h" -#include "conf.h" - -/* - * Register a users file into the main list, if the users - * file already exists it just return the node in question, - * otherwise add the node to the list and return the node - * created. - */ -static struct users_file *mk_auth_conf_add_users(char *users_path) -{ - struct file_info finfo; - struct mk_list *head; - struct users_file *entry; - struct user *cred; - int i, sep, len; - int offset = 0; - size_t decoded_len; - char *buf; - - mk_list_foreach(head, &users_file_list) { - entry = mk_list_entry(head, struct users_file, _head); - if (strcmp(entry->path, users_path) == 0) { - return entry; - } - } - - if (mk_api->file_get_info(users_path, &finfo, MK_FILE_READ) != 0) { - mk_warn("Auth: Invalid users file '%s'", users_path); - return NULL; - } - - if (finfo.is_directory == MK_TRUE) { - mk_warn("Auth: Not a credentials file '%s'", users_path); - return NULL; - } - - if (finfo.read_access == MK_FALSE) { - mk_warn("Auth: Could not read file '%s'", users_path); - return NULL; - } - - /* We did not find the path in our list, let's create a new node */ - entry = mk_api->mem_alloc(sizeof(struct users_file)); - entry->last_updated = finfo.last_modification; - entry->path = users_path; - - /* Read file and add users to the list */ - mk_list_init(&entry->_users); - - /* Read credentials file */ - buf = mk_api->file_to_buffer(users_path); - if (!buf) { - mk_warn("Auth: No users loaded '%s'", users_path); - return NULL; - } - - /* Read users list buffer lines */ - len = strlen(buf); - for (i = 0; i < len; i++) { - if (buf[i] == '\n' || (i) == len -1) { - sep = mk_api->str_search(buf + offset, ":", 1); - - if (sep >= (int)sizeof(cred->user)) { - mk_warn("Auth: username too long"); - offset = i + 1; - continue; - } - if (i - offset - sep - 1 - 5 >= (int)sizeof(cred->passwd_raw)) { - mk_warn("Auth: password hash too long"); - offset = i + 1; - continue; - } - - cred = mk_api->mem_alloc(sizeof(struct user)); - - /* Copy username */ - strncpy(cred->user, buf + offset, sep); - cred->user[sep] = '\0'; - - /* Copy raw password */ - offset += sep + 1 + 5; - strncpy(cred->passwd_raw, - buf + offset, - i - (offset)); - cred->passwd_raw[i - offset] = '\0'; - - /* Decode raw password */ - cred->passwd_decoded = base64_decode((unsigned char *)(cred->passwd_raw), - strlen(cred->passwd_raw), - &decoded_len); - - offset = i + 1; - - if (!cred->passwd_decoded) { - mk_warn("Auth: invalid user '%s' in '%s'", - cred->user, users_path); - mk_api->mem_free(cred); - continue; - } - mk_list_add(&cred->_head, &entry->_users); - } - } - mk_api->mem_free(buf); - - /* Link node to global list */ - mk_list_add(&entry->_head, &users_file_list); - - return entry; -} - -/* - * Read all vhost configuration nodes and looks for users files under an [AUTH] - * section, if present, it add that file to the unique list. It parse all user's - * files mentioned to avoid duplicated lists in memory. - */ -int mk_auth_conf_init_users_list() -{ - /* Section data */ - char *location; - char *title; - char *users_path; - /* auth vhost list */ - struct vhost *auth_vhost; - - /* vhost configuration */ - struct mk_list *head_hosts; - struct mk_list *hosts = &mk_api->config->hosts; - struct mk_list *head_sections; - struct mk_vhost *entry_host; - struct mk_rconf_section *section; - - /* vhost [AUTH] locations */ - struct location *loc; - - /* User files list */ - struct users_file *uf; - - PLUGIN_TRACE("Loading user's files"); - - mk_list_foreach(head_hosts, hosts) { - entry_host = mk_list_entry(head_hosts, struct mk_vhost, _head); - if (!entry_host->config) { - continue; - } - - auth_vhost = mk_api->mem_alloc(sizeof(struct vhost)); - auth_vhost->host = entry_host; /* link virtual host entry */ - mk_list_init(&auth_vhost->locations); /* init locations list */ - - /* - * check vhost 'config' and look for [AUTH] sections, we don't use - * mk_config_section_get() because we can have multiple [AUTH] - * sections. - */ - mk_list_foreach(head_sections, &entry_host->config->sections) { - section = mk_list_entry(head_sections, struct mk_rconf_section, _head); - - if (strcasecmp(section->name, "AUTH") == 0) { - location = NULL; - title = NULL; - users_path = NULL; - - /* Get section keys */ - location = mk_api->config_section_get_key(section, - "Location", - MK_RCONF_STR); - title = mk_api->config_section_get_key(section, - "Title", - MK_RCONF_STR); - - users_path = mk_api->config_section_get_key(section, - "Users", - MK_RCONF_STR); - - /* get or create users file entry */ - uf = mk_auth_conf_add_users(users_path); - if (!uf) { - continue; - } - - /* Location node */ - loc = mk_api->mem_alloc(sizeof(struct location)); - mk_api->pointer_set(&loc->path, location); - mk_api->pointer_set(&loc->title, title); - - loc->auth_http_header.data = NULL; - mk_api->str_build(&loc->auth_http_header.data, - &loc->auth_http_header.len, - MK_AUTH_HEADER_TITLE, title); - - loc->users = uf; - - /* Add new location to auth_vhost node */ - mk_list_add(&loc->_head, &auth_vhost->locations); - } - } - - /* Link auth_vhost node to global list vhosts_list */ - mk_list_add(&auth_vhost->_head, &vhosts_list); - } - -#ifdef TRACE - struct mk_list *vh_head, *loc_head; - struct vhost *vh_entry; - struct location *loc_entry; - - mk_list_foreach(vh_head, &vhosts_list) { - vh_entry = mk_list_entry(vh_head, struct vhost, _head); - PLUGIN_TRACE("Auth VHost: %p", vh_entry->host); - - mk_list_foreach(loc_head, &vh_entry->locations) { - loc_entry = mk_list_entry(loc_head, struct location, _head); - PLUGIN_TRACE("---"); - PLUGIN_TRACE(" location: %s", loc_entry->path); - PLUGIN_TRACE(" title : %s", loc_entry->title); - PLUGIN_TRACE(" users : %s", loc_entry->users->path); - } - } -#endif - - return 0; -} diff --git a/fluent-bit/lib/monkey/plugins/auth/conf.h b/fluent-bit/lib/monkey/plugins/auth/conf.h deleted file mode 100644 index 90fd8f79a..000000000 --- a/fluent-bit/lib/monkey/plugins/auth/conf.h +++ /dev/null @@ -1,25 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MK_AUTH_CONF_H -#define MK_AUTH_CONF_H - -int mk_auth_conf_init_users_list(); - -#endif diff --git a/fluent-bit/lib/monkey/plugins/auth/sha1.c b/fluent-bit/lib/monkey/plugins/auth/sha1.c deleted file mode 100644 index 53c7946e8..000000000 --- a/fluent-bit/lib/monkey/plugins/auth/sha1.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Code adapted to fill Monkey Project requirements, no big changes - * just a few header files added - */ - -#include <arpa/inet.h> -#include <string.h> - -/* - * SHA1 routine optimized to do word accesses rather than byte accesses, - * and to avoid unnecessary copies into the context array. - * - * This was initially based on the Mozilla SHA1 implementation, although - * none of the original Mozilla code remains. - */ - -#include "sha1.h" - -#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) - -/* - * Force usage of rol or ror by selecting the one with the smaller constant. - * It _can_ generate slightly smaller code (a constant of 1 is special), but - * perhaps more importantly it's possibly faster on any uarch that does a - * rotate with a loop. - */ - -#define SHA_ASM(op, x, n) ({ unsigned int __res; __asm__(op " %1,%0":"=r" (__res):"i" (n), "0" (x)); __res; }) -#define SHA_ROL(x,n) SHA_ASM("rol", x, n) -#define SHA_ROR(x,n) SHA_ASM("ror", x, n) - -#else - -#define SHA_ROT(X,l,r) (((X) << (l)) | ((X) >> (r))) -#define SHA_ROL(X,n) SHA_ROT(X,n,32-(n)) -#define SHA_ROR(X,n) SHA_ROT(X,32-(n),n) - -#endif - -/* - * If you have 32 registers or more, the compiler can (and should) - * try to change the array[] accesses into registers. However, on - * machines with less than ~25 registers, that won't really work, - * and at least gcc will make an unholy mess of it. - * - * So to avoid that mess which just slows things down, we force - * the stores to memory to actually happen (we might be better off - * with a 'W(t)=(val);asm("":"+m" (W(t))' there instead, as - * suggested by Artur Skawina - that will also make gcc unable to - * try to do the silly "optimize away loads" part because it won't - * see what the value will be). - * - * Ben Herrenschmidt reports that on PPC, the C version comes close - * to the optimized asm with this (ie on PPC you don't want that - * 'volatile', since there are lots of registers). - * - * On ARM we get the best code generation by forcing a full memory barrier - * between each SHA_ROUND, otherwise gcc happily get wild with spilling and - * the stack frame size simply explode and performance goes down the drain. - */ - -#if defined(__i386__) || defined(__x86_64__) - #define setW(x, val) (*(volatile unsigned int *)&W(x) = (val)) -#elif defined(__GNUC__) && defined(__arm__) - #define setW(x, val) do { W(x) = (val); __asm__("":::"memory"); } while (0) -#else - #define setW(x, val) (W(x) = (val)) -#endif - -/* - * Performance might be improved if the CPU architecture is OK with - * unaligned 32-bit loads and a fast ntohl() is available. - * Otherwise fall back to byte loads and shifts which is portable, - * and is faster on architectures with memory alignment issues. - */ - -#if defined(__i386__) || defined(__x86_64__) || \ - defined(_M_IX86) || defined(_M_X64) || \ - defined(__ppc__) || defined(__ppc64__) || \ - defined(__powerpc__) || defined(__powerpc64__) || \ - defined(__s390__) || defined(__s390x__) - -#define get_be32(p) ntohl(*(unsigned int *)(p)) -#define put_be32(p, v) do { *(unsigned int *)(p) = htonl(v); } while (0) - -#else - -#define get_be32(p) ( \ - (*((unsigned char *)(p) + 0) << 24) | \ - (*((unsigned char *)(p) + 1) << 16) | \ - (*((unsigned char *)(p) + 2) << 8) | \ - (*((unsigned char *)(p) + 3) << 0) ) -#define put_be32(p, v) do { \ - unsigned int __v = (v); \ - *((unsigned char *)(p) + 0) = __v >> 24; \ - *((unsigned char *)(p) + 1) = __v >> 16; \ - *((unsigned char *)(p) + 2) = __v >> 8; \ - *((unsigned char *)(p) + 3) = __v >> 0; } while (0) - -#endif - -/* This "rolls" over the 512-bit array */ -#define W(x) (array[(x)&15]) - -/* - * Where do we get the source from? The first 16 iterations get it from - * the input data, the next mix it from the 512-bit array. - */ -#define SHA_SRC(t) get_be32(data + t) -#define SHA_MIX(t) SHA_ROL(W(t+13) ^ W(t+8) ^ W(t+2) ^ W(t), 1) - -#define SHA_ROUND(t, input, fn, constant, A, B, C, D, E) do { \ - unsigned int TEMP = input(t); setW(t, TEMP); \ - E += TEMP + SHA_ROL(A,5) + (fn) + (constant); \ - B = SHA_ROR(B, 2); } while (0) - -#define T_0_15(t, A, B, C, D, E) SHA_ROUND(t, SHA_SRC, (((C^D)&B)^D) , 0x5a827999, A, B, C, D, E ) -#define T_16_19(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (((C^D)&B)^D) , 0x5a827999, A, B, C, D, E ) -#define T_20_39(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B^C^D) , 0x6ed9eba1, A, B, C, D, E ) -#define T_40_59(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, ((B&C)+(D&(B^C))) , 0x8f1bbcdc, A, B, C, D, E ) -#define T_60_79(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B^C^D) , 0xca62c1d6, A, B, C, D, E ) - -static void blk_SHA1_Block(blk_SHA_CTX *ctx, const unsigned int *data) -{ - unsigned int A,B,C,D,E; - unsigned int array[16]; - - A = ctx->H[0]; - B = ctx->H[1]; - C = ctx->H[2]; - D = ctx->H[3]; - E = ctx->H[4]; - - /* Round 1 - iterations 0-16 take their input from 'data' */ - T_0_15( 0, A, B, C, D, E); - T_0_15( 1, E, A, B, C, D); - T_0_15( 2, D, E, A, B, C); - T_0_15( 3, C, D, E, A, B); - T_0_15( 4, B, C, D, E, A); - T_0_15( 5, A, B, C, D, E); - T_0_15( 6, E, A, B, C, D); - T_0_15( 7, D, E, A, B, C); - T_0_15( 8, C, D, E, A, B); - T_0_15( 9, B, C, D, E, A); - T_0_15(10, A, B, C, D, E); - T_0_15(11, E, A, B, C, D); - T_0_15(12, D, E, A, B, C); - T_0_15(13, C, D, E, A, B); - T_0_15(14, B, C, D, E, A); - T_0_15(15, A, B, C, D, E); - - /* Round 1 - tail. Input from 512-bit mixing array */ - T_16_19(16, E, A, B, C, D); - T_16_19(17, D, E, A, B, C); - T_16_19(18, C, D, E, A, B); - T_16_19(19, B, C, D, E, A); - - /* Round 2 */ - T_20_39(20, A, B, C, D, E); - T_20_39(21, E, A, B, C, D); - T_20_39(22, D, E, A, B, C); - T_20_39(23, C, D, E, A, B); - T_20_39(24, B, C, D, E, A); - T_20_39(25, A, B, C, D, E); - T_20_39(26, E, A, B, C, D); - T_20_39(27, D, E, A, B, C); - T_20_39(28, C, D, E, A, B); - T_20_39(29, B, C, D, E, A); - T_20_39(30, A, B, C, D, E); - T_20_39(31, E, A, B, C, D); - T_20_39(32, D, E, A, B, C); - T_20_39(33, C, D, E, A, B); - T_20_39(34, B, C, D, E, A); - T_20_39(35, A, B, C, D, E); - T_20_39(36, E, A, B, C, D); - T_20_39(37, D, E, A, B, C); - T_20_39(38, C, D, E, A, B); - T_20_39(39, B, C, D, E, A); - - /* Round 3 */ - T_40_59(40, A, B, C, D, E); - T_40_59(41, E, A, B, C, D); - T_40_59(42, D, E, A, B, C); - T_40_59(43, C, D, E, A, B); - T_40_59(44, B, C, D, E, A); - T_40_59(45, A, B, C, D, E); - T_40_59(46, E, A, B, C, D); - T_40_59(47, D, E, A, B, C); - T_40_59(48, C, D, E, A, B); - T_40_59(49, B, C, D, E, A); - T_40_59(50, A, B, C, D, E); - T_40_59(51, E, A, B, C, D); - T_40_59(52, D, E, A, B, C); - T_40_59(53, C, D, E, A, B); - T_40_59(54, B, C, D, E, A); - T_40_59(55, A, B, C, D, E); - T_40_59(56, E, A, B, C, D); - T_40_59(57, D, E, A, B, C); - T_40_59(58, C, D, E, A, B); - T_40_59(59, B, C, D, E, A); - - /* Round 4 */ - T_60_79(60, A, B, C, D, E); - T_60_79(61, E, A, B, C, D); - T_60_79(62, D, E, A, B, C); - T_60_79(63, C, D, E, A, B); - T_60_79(64, B, C, D, E, A); - T_60_79(65, A, B, C, D, E); - T_60_79(66, E, A, B, C, D); - T_60_79(67, D, E, A, B, C); - T_60_79(68, C, D, E, A, B); - T_60_79(69, B, C, D, E, A); - T_60_79(70, A, B, C, D, E); - T_60_79(71, E, A, B, C, D); - T_60_79(72, D, E, A, B, C); - T_60_79(73, C, D, E, A, B); - T_60_79(74, B, C, D, E, A); - T_60_79(75, A, B, C, D, E); - T_60_79(76, E, A, B, C, D); - T_60_79(77, D, E, A, B, C); - T_60_79(78, C, D, E, A, B); - T_60_79(79, B, C, D, E, A); - - ctx->H[0] += A; - ctx->H[1] += B; - ctx->H[2] += C; - ctx->H[3] += D; - ctx->H[4] += E; -} - -void blk_SHA1_Init(blk_SHA_CTX *ctx) -{ - ctx->size = 0; - - /* Initialize H with the magic constants (see FIPS180 for constants) */ - ctx->H[0] = 0x67452301; - ctx->H[1] = 0xefcdab89; - ctx->H[2] = 0x98badcfe; - ctx->H[3] = 0x10325476; - ctx->H[4] = 0xc3d2e1f0; -} - -void blk_SHA1_Update(blk_SHA_CTX *ctx, const void *data, unsigned long len) -{ - unsigned int lenW = ctx->size & 63; - - ctx->size += len; - - /* Read the data into W and process blocks as they get full */ - if (lenW) { - unsigned int left = 64 - lenW; - if (len < left) - left = len; - memcpy(lenW + (char *)ctx->W, data, left); - lenW = (lenW + left) & 63; - len -= left; - data = ((const char *)data + left); - if (lenW) - return; - blk_SHA1_Block(ctx, ctx->W); - } - while (len >= 64) { - blk_SHA1_Block(ctx, data); - data = ((const char *)data + 64); - len -= 64; - } - if (len) - memcpy(ctx->W, data, len); -} - -void blk_SHA1_Final(unsigned char hashout[20], blk_SHA_CTX *ctx) -{ - static const unsigned char pad[64] = { 0x80 }; - unsigned int padlen[2]; - int i; - - /* Pad with a binary 1 (ie 0x80), then zeroes, then length */ - padlen[0] = htonl((uint32_t)(ctx->size >> 29)); - padlen[1] = htonl((uint32_t)(ctx->size << 3)); - - i = ctx->size & 63; - blk_SHA1_Update(ctx, pad, 1+ (63 & (55 - i))); - blk_SHA1_Update(ctx, padlen, 8); - - /* Output hash */ - for (i = 0; i < 5; i++) - put_be32(hashout + i*4, ctx->H[i]); -} diff --git a/fluent-bit/lib/monkey/plugins/auth/sha1.h b/fluent-bit/lib/monkey/plugins/auth/sha1.h deleted file mode 100644 index 4a75ab351..000000000 --- a/fluent-bit/lib/monkey/plugins/auth/sha1.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * SHA1 routine optimized to do word accesses rather than byte accesses, - * and to avoid unnecessary copies into the context array. - * - * This was initially based on the Mozilla SHA1 implementation, although - * none of the original Mozilla code remains. - */ - -typedef struct { - unsigned long long size; - unsigned int H[5]; - unsigned int W[16]; -} blk_SHA_CTX; - -void blk_SHA1_Init(blk_SHA_CTX *ctx); -void blk_SHA1_Update(blk_SHA_CTX *ctx, const void *dataIn, unsigned long len); -void blk_SHA1_Final(unsigned char hashout[20], blk_SHA_CTX *ctx); - -#define SHA_CTX blk_SHA_CTX -#define SHA1_Init blk_SHA1_Init -#define SHA1_Update blk_SHA1_Update -#define SHA1_Final blk_SHA1_Final diff --git a/fluent-bit/lib/monkey/plugins/auth/tools/CMakeLists.txt b/fluent-bit/lib/monkey/plugins/auth/tools/CMakeLists.txt deleted file mode 100644 index 63b445cf7..000000000 --- a/fluent-bit/lib/monkey/plugins/auth/tools/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -set(src - ../sha1.c - ../base64.c - mk_passwd.c - ) - -include_directories(../) -add_definitions(-D_FORCE_SYSMALLOC) -add_executable(mk_passwd ${src}) - -if(BUILD_LOCAL) - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/") -else() - install(TARGETS mk_passwd RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_SBINDIR}) -endif() diff --git a/fluent-bit/lib/monkey/plugins/auth/tools/mk_passwd.c b/fluent-bit/lib/monkey/plugins/auth/tools/mk_passwd.c deleted file mode 100644 index 6dba1d3f1..000000000 --- a/fluent-bit/lib/monkey/plugins/auth/tools/mk_passwd.c +++ /dev/null @@ -1,209 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#ifdef MALLOC_JEMALLOC -#undef MALLOC_JEMALLOC -#endif - -#include <monkey/monkey.h> -#include <monkey/mk_core.h> - -#include <getopt.h> - -#include "sha1.h" -#include "base64.h" - -#define MAX_LINE_LEN 256 - -struct mk_passwd_user { - char *row; - struct mk_list _head; -}; - -/* Store a file as a linked list of its lines */ -static struct mk_list passwd_file; - -/* Load file to memory from disk - * If create_file == MK_TRUE, the file will be rewritten */ -void read_file(char *filename, int create_file) -{ - FILE *filein = fopen(filename, "r"); - char line[MAX_LINE_LEN]; - struct mk_passwd_user *entry; - - mk_list_init(&passwd_file); - - if (filein == NULL && create_file == MK_FALSE) { - printf("Error opening file %s\n", filename); - exit(1); - } - - if (filein == NULL || create_file == MK_TRUE) { - if (filein != NULL) - fclose(filein); - return; - } - - while (fgets(line, MAX_LINE_LEN, filein) != NULL) { - entry = malloc(sizeof(*entry)); - entry->row = strdup(line); - mk_list_add(&entry->_head, &passwd_file); - } - fclose(filein); -} - -/* Store data to disk */ -void dump_file(char *filename) -{ - FILE *fileout = fopen(filename, "w"); - struct mk_list *it, *tmp; - struct mk_passwd_user *entry; - - if (!fileout) { - printf("Error opening: %s", filename); - exit(EXIT_FAILURE); - } - - mk_list_foreach_safe(it, tmp, &passwd_file) { - entry = mk_list_entry(it, struct mk_passwd_user, _head); - fprintf(fileout, "%s", entry->row); - mk_list_del(&entry->_head); - free(entry->row); - free(entry); - } - fclose(fileout); -} - -/* Return sha1 hash of password - * A new line is appended at the hash */ -unsigned char *sha1_hash(const char *password) -{ - - unsigned char sha_hash[20]; - blk_SHA_CTX sha; - - blk_SHA1_Init(&sha); - blk_SHA1_Update(&sha, password, strlen(password)); - blk_SHA1_Final(sha_hash, &sha); - - return base64_encode(sha_hash, 20, NULL); -} - -void update_user(const char *username, const char *password, int create_user) -{ - struct mk_list *it, *tmp; - struct mk_passwd_user *entry; - unsigned char *hash_passwd; - int i; - - mk_list_foreach_safe(it, tmp, &passwd_file) { - entry = mk_list_entry(it, struct mk_passwd_user, _head); - for (i = 0; entry->row[i] != '\0' && entry->row[i] != ':' && username[i] != '\0' && entry->row[i] == username[i]; i++); - if (entry->row[i] != ':' || username[i] != '\0') - continue; - - /* Found a match */ - - /* Delete user */ - if (create_user == MK_FALSE) { - printf("[-] Deleting user %s\n", username); - mk_list_del(&entry->_head); - free(entry->row); - free(entry); - return; - } - - /* Update user */ - printf("[+] Password changed for user %s\n", username); - hash_passwd = sha1_hash(password); - free(entry->row); - entry->row = malloc(512); - snprintf(entry->row, 512, "%s:{SHA1}%s", username, hash_passwd); - free(hash_passwd); - - return; - } - - /* Create user */ - if (create_user == MK_TRUE) { - printf("[+] Adding user %s\n", username); - entry = malloc(sizeof(struct mk_passwd_user)); - entry->row = malloc(512); - hash_passwd = sha1_hash(password); - snprintf(entry->row, 512, "%s:{SHA1}%s", username, hash_passwd); - free(hash_passwd); - - mk_list_add(&entry->_head, &passwd_file); - } -} - -static void print_help(int full_help) -{ - printf("Usage: mk_passwd [-c] [-D] filename username password\n"); - if (full_help == MK_TRUE) { - printf("\nOptions:\n"); - printf(" -h, --help\tshow this help message and exit\n"); - printf(" -c\t\tCreate a new mkpasswd file, overwriting any existing file.\n"); - printf(" -D\t\tRemove the given user from the password file.\n"); - } -} - -int main(int argc, char *argv[]) -{ - int opt; - int create_user = MK_TRUE; - int create_file = MK_FALSE; - int show_help = MK_FALSE; - char *filename = NULL; - char *username = NULL; - char *password = NULL; - - /* Command line options */ - static const struct option long_opts[] = { - {"create", no_argument, NULL, 'c'}, - {"delete_user", no_argument, NULL, 'D'}, - {"help", no_argument, NULL, 'h'}, - }; - - /* Parse options */ - while ((opt = getopt_long(argc, argv, "hbDc", long_opts, NULL)) != -1) { - switch (opt) { - case 'c': - create_file = MK_TRUE; - break; - case 'D': - create_user = MK_FALSE; - break; - case 'h': - show_help = MK_TRUE; - break; - } - } - - /* Retrieve filename, username and password */ - while (optind < argc) { - if (filename == NULL) - filename = argv[optind++]; - else if (username == NULL) - username = argv[optind++]; - else if (password == NULL) - password = argv[optind++]; - } - - if (show_help == MK_TRUE) { - print_help(MK_TRUE); - exit(0); - } - - /* If delete_user option is provided, do not provide a password */ - if ((password != NULL) ^ (create_user == MK_TRUE)) { - print_help(MK_FALSE); - exit(1); - } - - /* Process request */ - read_file(filename, create_file); - update_user(username, password, create_user); - dump_file(filename); - - return 0; -} diff --git a/fluent-bit/lib/monkey/plugins/cgi/CMakeLists.txt b/fluent-bit/lib/monkey/plugins/cgi/CMakeLists.txt deleted file mode 100644 index 121144aa1..000000000 --- a/fluent-bit/lib/monkey/plugins/cgi/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -set(src - cgi.c - event.c - request.c - ) - -MONKEY_PLUGIN(cgi "${src}") diff --git a/fluent-bit/lib/monkey/plugins/cgi/cgi.c b/fluent-bit/lib/monkey/plugins/cgi/cgi.c deleted file mode 100644 index 58c7a647f..000000000 --- a/fluent-bit/lib/monkey/plugins/cgi/cgi.c +++ /dev/null @@ -1,501 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * Copyright (C) 2012-2013, Lauri Kasanen - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <monkey/mk_stream.h> -#include "cgi.h" - -#include <sys/types.h> -#include <sys/wait.h> -#include <sys/time.h> -#include <sys/resource.h> -#include <sys/stat.h> - -void cgi_finish(struct cgi_request *r) -{ - /* - * Unregister & close the CGI child process pipe reader fd from the - * thread event loop, otherwise we may get unexpected notifications. - */ - mk_api->ev_del(mk_api->sched_loop(), (struct mk_event *) r); - close(r->fd); - if (r->chunked && r->active == MK_TRUE) { - PLUGIN_TRACE("CGI sending Chunked EOF"); - channel_write(r, "0\r\n\r\n", 5); - } - - /* Try to kill any child process */ - if (r->child > 0) { - kill(r->child, SIGKILL); - r->child = 0; - } - - /* Invalidte our socket handler */ - requests_by_socket[r->socket] = NULL; - if (r->active == MK_TRUE) { - mk_api->http_request_end(r->plugin, r->cs, r->hangup); - } - cgi_req_del(r); -} - -int swrite(const int fd, const void *buf, const size_t count) -{ - ssize_t pos = count, ret = 0; - - while (pos > 0 && ret >= 0) { - ret = write(fd, buf, pos); - if (ret < 0) { - return ret; - } - - pos -= ret; - buf += ret; - } - return count; -} - -int channel_write(struct cgi_request *r, void *buf, size_t count) -{ - int ret; - - if (r->active == MK_FALSE) { - return -1; - } - - MK_TRACE("channel write: %d bytes", count); - mk_stream_in_raw(&r->sr->stream, - NULL, - buf, count, - NULL, NULL); - - ret = mk_api->channel_flush(r->sr->session->channel); - if (ret & MK_CHANNEL_ERROR) { - r->active = MK_FALSE; - cgi_finish(r); - } - return 0; -} - -static void cgi_write_post(void *p) -{ - const struct post_t * const in = p; - - swrite(in->fd, in->buf, in->len); - close(in->fd); -} - -static int do_cgi(const char *const __restrict__ file, - const char *const __restrict__ url, - struct mk_http_request *sr, - struct mk_http_session *cs, - struct mk_plugin *plugin, - char *interpreter, - char *mimetype) -{ - int ret; - int devnull; - const int socket = cs->socket; - struct file_info finfo; - struct cgi_request *r = NULL; - struct mk_event *event; - char *env[30]; - int writepipe[2], readpipe[2]; - (void) plugin; - - /* Unchanging env vars */ - env[0] = "PATH_INFO="; - env[1] = "GATEWAY_INTERFACE=CGI/1.1"; - env[2] = "REDIRECT_STATUS=200"; - const int env_start = 3; - char *protocol; - unsigned long len; - - /* Dynamic env vars */ - unsigned short envpos = env_start; - - char method[SHORTLEN]; - char *query = NULL; - char request_uri[PATHLEN]; - char script_filename[PATHLEN]; - char script_name[PATHLEN]; - char query_string[PATHLEN]; - char remote_addr[INET6_ADDRSTRLEN+SHORTLEN]; - char tmpaddr[INET6_ADDRSTRLEN], *ptr = tmpaddr; - char remote_port[SHORTLEN]; - char content_length[SHORTLEN]; - char content_type[SHORTLEN]; - char server_software[SHORTLEN]; - char server_protocol[SHORTLEN]; - char http_host[SHORTLEN]; - - /* Check the interpreter exists */ - if (interpreter) { - ret = mk_api->file_get_info(interpreter, &finfo, MK_FILE_EXEC); - if (ret == -1 || - (finfo.is_file == MK_FALSE && finfo.is_link == MK_FALSE) || - finfo.exec_access == MK_FALSE) { - return 500; - } - } - - if (mimetype) { - sr->content_type.data = mimetype; - sr->content_type.len = strlen(mimetype); - } - - snprintf(method, SHORTLEN, "REQUEST_METHOD=%.*s", (int) sr->method_p.len, sr->method_p.data); - env[envpos++] = method; - - snprintf(server_software, SHORTLEN, "SERVER_SOFTWARE=%s", - mk_api->config->server_signature); - env[envpos++] = server_software; - - snprintf(http_host, SHORTLEN, "HTTP_HOST=%.*s", (int) sr->host.len, sr->host.data); - env[envpos++] = http_host; - - if (sr->protocol == MK_HTTP_PROTOCOL_11) - protocol = MK_HTTP_PROTOCOL_11_STR; - else - protocol = MK_HTTP_PROTOCOL_10_STR; - - snprintf(server_protocol, SHORTLEN, "SERVER_PROTOCOL=%s", protocol); - env[envpos++] = server_protocol; - - if (sr->query_string.len) { - query = mk_api->mem_alloc_z(sr->query_string.len + 1); - memcpy(query, sr->query_string.data, sr->query_string.len); - snprintf(request_uri, PATHLEN, "REQUEST_URI=%s?%s", url, query); - } - else { - snprintf(request_uri, PATHLEN, "REQUEST_URI=%s", url); - } - env[envpos++] = request_uri; - - snprintf(script_filename, PATHLEN, "SCRIPT_FILENAME=%s", file); - env[envpos++] = script_filename; - - snprintf(script_name, PATHLEN, "SCRIPT_NAME=%s", url); - env[envpos++] = script_name; - - if (query) { - snprintf(query_string, PATHLEN, "QUERY_STRING=%s", query); - env[envpos++] = query_string; - mk_api->mem_free(query); - } - - if (mk_api->socket_ip_str(socket, &ptr, INET6_ADDRSTRLEN, &len) < 0) - tmpaddr[0] = '\0'; - snprintf(remote_addr, INET6_ADDRSTRLEN+SHORTLEN, "REMOTE_ADDR=%s", tmpaddr); - env[envpos++] = remote_addr; - - snprintf(remote_port, SHORTLEN, "REMOTE_PORT=%ld", sr->port); - env[envpos++] = remote_port; - - if (sr->data.len) { - snprintf(content_length, SHORTLEN, "CONTENT_LENGTH=%lu", sr->data.len); - env[envpos++] = content_length; - } - - if (sr->content_type.len) { - snprintf(content_type, SHORTLEN, "CONTENT_TYPE=%.*s", (int)sr->content_type.len, sr->content_type.data); - env[envpos++] = content_type; - } - - - /* Must be NULL-terminated */ - env[envpos] = NULL; - - /* pipes, from monkey's POV */ - if (pipe(writepipe) || pipe(readpipe)) { - mk_err("Failed to create pipe"); - return 403; - } - - pid_t pid = vfork(); - if (pid < 0) { - mk_err("Failed to fork"); - return 403; - } - - /* Child */ - if (pid == 0) { - close(writepipe[1]); - close(readpipe[0]); - - /* Our stdin is the read end of monkey's writing */ - if (dup2(writepipe[0], 0) < 0) { - mk_err("dup2 failed"); - _exit(1); - } - close(writepipe[0]); - - /* Our stdout is the write end of monkey's reading */ - if (dup2(readpipe[1], 1) < 0) { - mk_err("dup2 failed"); - _exit(1); - } - close(readpipe[1]); - - /* Our stderr goes to /dev/null */ - devnull = open("/dev/null", O_WRONLY); - if (devnull == -1) { - perror("open"); - _exit(1); - } - - if (dup2(devnull, 2) < 0) { - mk_err("dup2 failed"); - _exit(1); - } - close(devnull); - - char *argv[3] = { NULL }; - - char *tmp = mk_api->str_dup(file); - if (chdir(dirname(tmp))) - _exit(1); - - char *tmp2 = mk_api->str_dup(file); - argv[0] = basename(tmp2); - - /* Restore signals for the child */ - signal(SIGPIPE, SIG_DFL); - signal(SIGCHLD, SIG_DFL); - - if (!interpreter) { - execve(file, argv, env); - } - else { - argv[0] = basename(interpreter); - argv[1] = (char *) file; - execve(interpreter, argv, env); - } - /* Exec failed, return */ - _exit(1); - } - - /* Yay me */ - close(writepipe[0]); - close(readpipe[1]); - - /* If we have POST data to write, spawn a thread to do that */ - if (sr->data.len) { - struct post_t p; - pthread_t tid; - - p.fd = writepipe[1]; - p.buf = sr->data.data; - p.len = sr->data.len; - - ret = mk_api->worker_spawn(cgi_write_post, &p, &tid); - if (ret != 0) { - return 403; - } - } - else { - close(writepipe[1]); - } - - r = cgi_req_create(readpipe[0], socket, plugin, sr, cs); - if (!r) { - return 403; - } - r->child = pid; - - /* - * Hang up?: by default Monkey assumes the CGI scripts generate - * content dynamically (no Content-Length header), so for such HTTP/1.0 - * clients we should close the connection as KeepAlive is not supported - * by specification, only on HTTP/1.1 where the Chunked Transfer encoding - * exists. - */ - if (r->sr->protocol >= MK_HTTP_PROTOCOL_11) { - r->hangup = MK_FALSE; - } - - /* Set transfer encoding */ - if (r->sr->protocol >= MK_HTTP_PROTOCOL_11 && - (r->sr->headers.status < MK_REDIR_MULTIPLE || - r->sr->headers.status > MK_REDIR_USE_PROXY)) { - r->sr->headers.transfer_encoding = MK_HEADER_TE_TYPE_CHUNKED; - r->chunked = 1; - } - - /* Register the 'request' context */ - cgi_req_add(r); - - /* Prepare the built-in event structure */ - event = &r->event; - event->fd = readpipe[0]; - event->type = MK_EVENT_CUSTOM; - event->mask = MK_EVENT_EMPTY; - event->data = r; - event->handler = cb_cgi_read; - - /* Register the event into the worker event-loop */ - ret = mk_api->ev_add(mk_api->sched_loop(), - readpipe[0], - MK_EVENT_CUSTOM, MK_EVENT_READ, r); - if (ret != 0) { - return 403; - } - - - /* XXX Fixme: this needs to be atomic */ - requests_by_socket[socket] = r; - return 200; -} - -int mk_cgi_plugin_init(struct plugin_api **api, char *confdir) -{ - struct rlimit lim; - (void) confdir; - - mk_api = *api; - mk_list_init(&cgi_global_matches); - pthread_key_create(&cgi_request_list, NULL); - - /* - * We try to perform some quick lookup over the list of CGI - * instances. We do this with a fixed length array, if you use CGI - * you don't care too much about performance anyways. - */ - getrlimit(RLIMIT_NOFILE, &lim); - requests_by_socket = mk_api->mem_alloc_z(sizeof(struct cgi_request *) * lim.rlim_cur); - - /* Make sure we act good if the child dies */ - signal(SIGPIPE, SIG_IGN); - signal(SIGCHLD, SIG_IGN); - - return 0; -} - -int mk_cgi_plugin_exit() -{ - regfree(&match_regex); - mk_api->mem_free(requests_by_socket); - - return 0; -} - -int mk_cgi_stage30(struct mk_plugin *plugin, - struct mk_http_session *cs, - struct mk_http_request *sr, - int n_params, - struct mk_list *params) -{ - char *interpreter = NULL; - char *mimetype = NULL; - struct mk_vhost_handler_param *param; - (void) plugin; - - const char *const file = sr->real_path.data; - - if (!sr->file_info.is_file) { - return MK_PLUGIN_RET_NOT_ME; - } - - /* start running the CGI */ - if (cgi_req_get(cs->socket)) { - PLUGIN_TRACE("Error, someone tried to retry\n"); - return MK_PLUGIN_RET_CONTINUE; - } - - if (n_params > 0) { - /* Interpreter */ - param = mk_api->handler_param_get(0, params); - if (param) { - interpreter = param->p.data; - } - - /* Mimetype */ - param = mk_api->handler_param_get(0, params); - if (param) { - mimetype = param->p.data; - } - } - - int status = do_cgi(file, sr->uri_processed.data, - sr, cs, plugin, interpreter, mimetype); - - /* These are just for the other plugins, such as logger; bogus data */ - mk_api->header_set_http_status(sr, status); - if (status != 200) { - return MK_PLUGIN_RET_CLOSE_CONX; - } - - sr->headers.cgi = SH_CGI; - return MK_PLUGIN_RET_CONTINUE; -} - -/* - * Invoked everytime a remote client drop the active connection, this - * callback is triggered by the Monkey Scheduler - */ -int mk_cgi_stage30_hangup(struct mk_plugin *plugin, - struct mk_http_session *cs, - struct mk_http_request *sr) -{ - struct cgi_request *r; - (void) sr; - (void) plugin; - - PLUGIN_TRACE("CGI / Parent connection closed (hangup)"); - r = requests_by_socket[cs->socket]; - if (!r) { - return -1; - } - - r->active = MK_FALSE; - cgi_finish(r); - return 0; -} - -void mk_cgi_worker_init() -{ - struct mk_list *list = mk_api->mem_alloc_z(sizeof(struct mk_list)); - - mk_list_init(list); - pthread_setspecific(cgi_request_list, (void *) list); -} - - -struct mk_plugin_stage mk_plugin_stage_cgi = { - .stage30 = &mk_cgi_stage30, - .stage30_hangup = &mk_cgi_stage30_hangup -}; - -struct mk_plugin mk_plugin_cgi = { - /* Identification */ - .shortname = "cgi", - .name = "Common Gateway Interface", - .version = MK_VERSION_STR, - .hooks = MK_PLUGIN_STAGE, - - /* Init / Exit */ - .init_plugin = mk_cgi_plugin_init, - .exit_plugin = mk_cgi_plugin_exit, - - /* Init Levels */ - .master_init = NULL, - .worker_init = mk_cgi_worker_init, - - /* Type */ - .stage = &mk_plugin_stage_cgi -}; diff --git a/fluent-bit/lib/monkey/plugins/cgi/cgi.h b/fluent-bit/lib/monkey/plugins/cgi/cgi.h deleted file mode 100644 index 27123b7ae..000000000 --- a/fluent-bit/lib/monkey/plugins/cgi/cgi.h +++ /dev/null @@ -1,133 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * Copyright (C) 2012-2013, Lauri Kasanen - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MK_CGI_H -#define MK_CGI_H - -#include <monkey/mk_api.h> - -#include <sys/types.h> -#include <regex.h> -#include <signal.h> -#include <libgen.h> - -enum { - BUFLEN = 4096, - PATHLEN = 1024, - SHORTLEN = 64 -}; - -regex_t match_regex; - -struct cgi_request **requests_by_socket; - -struct post_t { - int fd; - void *buf; - unsigned long len; -}; - -struct cgi_match_t { - regex_t match; - char *bin; - mk_ptr_t content_type; - - struct mk_list _head; -}; - -struct cgi_vhost_t { - struct mk_vhost *host; - struct mk_list matches; -}; - -struct cgi_vhost_t *cgi_vhosts; -struct mk_list cgi_global_matches; - - -struct cgi_request { - /* Built-in reference for the event loop */ - struct mk_event event; - - char in_buf[BUFLEN]; - - struct mk_list _head; - - struct mk_plugin *plugin; - struct mk_http_request *sr; - struct mk_http_session *cs; - - unsigned int in_len; - - int fd; /* Pipe the CGI proc */ - int socket; /* Client connection */ - int hangup; /* Should close connection when done ? */ - int active; /* Active session ? */ - pid_t child; /* child process ID */ - unsigned char status_done; - unsigned char all_headers_done; - unsigned char chunked; -}; - -/* Global list per worker */ -pthread_key_t cgi_request_list; - -extern struct cgi_request **requests_by_socket; - -void cgi_finish(struct cgi_request *r); - -int swrite(const int fd, const void *buf, const size_t count); -int channel_write(struct cgi_request *r, void *buf, size_t count); - -struct cgi_request *cgi_req_create(int fd, int socket, - struct mk_plugin *plugin, - struct mk_http_request *sr, - struct mk_http_session *cs); -void cgi_req_add(struct cgi_request *r); -int cgi_req_del(struct cgi_request *r); - -// Get the CGI request by the client socket -static inline struct cgi_request *cgi_req_get(int socket) -{ - struct cgi_request *r = requests_by_socket[socket]; - return r; -} - -// Get the CGI request by the CGI app's fd -static inline struct cgi_request *cgi_req_get_by_fd(int fd) -{ - struct mk_list *list, *node; - struct cgi_request *r; - - list = pthread_getspecific(cgi_request_list); - if (mk_list_is_empty(list) == 0) - return NULL; - - mk_list_foreach(node, list) { - r = mk_list_entry(node, struct cgi_request, _head); - if (r->fd == fd) - return r; - } - - return NULL; -} - -int cb_cgi_read(void *data); - -#endif diff --git a/fluent-bit/lib/monkey/plugins/cgi/event.c b/fluent-bit/lib/monkey/plugins/cgi/event.c deleted file mode 100644 index b8d395260..000000000 --- a/fluent-bit/lib/monkey/plugins/cgi/event.c +++ /dev/null @@ -1,170 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * Copyright (C) 2012-2013, Lauri Kasanen - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "cgi.h" - -/* - * The reason for this function is that some CGI apps - * - * use LFLF and some use CRLFCRLF. - * - * If that app then sends content that has the other break - * in the beginning, monkey can accidentally send part of the - * content as headers. - */ - -static char *getearliestbreak(const char buf[], const unsigned bufsize, - unsigned char * const advance) - { - char * const crend = memmem(buf, bufsize, MK_IOV_CRLFCRLF, - sizeof(MK_IOV_CRLFCRLF) - 1); - char * const lfend = memmem(buf, bufsize, MK_IOV_LFLF, - sizeof(MK_IOV_LFLF) - 1); - - if (!crend && !lfend) - return NULL; - - /* If only one found, return that one */ - if (!crend) { - *advance = 2; - return lfend; - } - if (!lfend) - return crend; - - /* Both found, return the earlier one - the latter one is part of content */ - if (lfend < crend) { - *advance = 2; - return lfend; - } - return crend; -} - -int process_cgi_data(struct cgi_request *r) -{ - int ret; - int len; - int status; - char *buf = r->in_buf; - char *outptr = r->in_buf; - char *end; - char *endl; - unsigned char advance; - - mk_api->socket_cork_flag(r->cs->socket, TCP_CORK_OFF); - if (!r->status_done && r->in_len >= 8) { - if (memcmp(buf, "Status: ", 8) == 0) { - status = atoi(buf + 8); - mk_api->header_set_http_status(r->sr, status); - endl = memchr(buf + 8, '\n', r->in_len - 8); - if (!endl) { - return MK_PLUGIN_RET_EVENT_OWNED; - } - else { - endl++; - outptr = endl; - r->in_len -= endl - buf; - } - } - else if (memcmp(buf, "HTTP", 4) == 0) { - status = atoi(buf + 9); - mk_api->header_set_http_status(r->sr, status); - - endl = memchr(buf + 8, '\n', r->in_len - 8); - if (!endl) { - return MK_PLUGIN_RET_EVENT_OWNED; - } - else { - endl++; - outptr = endl; - r->in_len -= endl - buf; - } - } - mk_api->header_prepare(r->plugin, r->cs, r->sr); - r->status_done = 1; - } - - if (!r->all_headers_done) { - advance = 4; - - /* Write the rest of the headers without chunking */ - end = getearliestbreak(outptr, r->in_len, &advance); - if (!end) { - /* Let's return until we have the headers break */ - return MK_PLUGIN_RET_EVENT_OWNED; - } - end += advance; - len = end - outptr; - channel_write(r, outptr, len); - outptr += len; - r->in_len -= len; - - r->all_headers_done = 1; - if (r->in_len == 0) { - return MK_PLUGIN_RET_EVENT_OWNED; - } - } - - if (r->chunked) { - char tmp[16]; - len = snprintf(tmp, 16, "%x\r\n", r->in_len); - ret = channel_write(r, tmp, len); - if (ret < 0) - return MK_PLUGIN_RET_EVENT_CLOSE; - } - - ret = channel_write(r, outptr, r->in_len); - if (ret < 0) { - return MK_PLUGIN_RET_EVENT_CLOSE; - } - - r->in_len = 0; - if (r->chunked) { - channel_write(r, MK_CRLF, 2); - } - return MK_PLUGIN_RET_EVENT_OWNED; -} - -int cb_cgi_read(void *data) -{ - int n; - struct cgi_request *r = data; - - if (r->active == MK_FALSE) { - return -1; - } - - if ((BUFLEN - r->in_len) < 1) { - PLUGIN_TRACE("CLOSE BY SIZE"); - cgi_finish(r); - return -1; - } - - n = read(r->fd, r->in_buf + r->in_len, BUFLEN - r->in_len); - PLUGIN_TRACE("FD=%i CGI READ=%d", r->fd, n); - if (n <= 0) { - /* It most of cases this means the child process finished */ - cgi_finish(r); - return MK_PLUGIN_RET_EVENT_CLOSE; - } - r->in_len += n; - process_cgi_data(r); - return 0; -} diff --git a/fluent-bit/lib/monkey/plugins/cgi/request.c b/fluent-bit/lib/monkey/plugins/cgi/request.c deleted file mode 100644 index c51a13831..000000000 --- a/fluent-bit/lib/monkey/plugins/cgi/request.c +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * Copyright (C) 2012-2013, Lauri Kasanen - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "cgi.h" - -struct cgi_request *cgi_req_create(int fd, int socket, - struct mk_plugin *plugin, - struct mk_http_request *sr, - struct mk_http_session *cs) -{ - struct cgi_request *cgi; - - cgi = mk_api->mem_alloc_z(sizeof(struct cgi_request)); - if (!cgi) { - return NULL; - } - - cgi->fd = fd; - cgi->socket = socket; - cgi->plugin = plugin; - cgi->sr = sr; - cgi->cs = cs; - cgi->hangup = MK_TRUE; - cgi->active = MK_TRUE; - cgi->in_len = 0; - - cgi->event.mask = MK_EVENT_EMPTY; - cgi->event.status = MK_EVENT_NONE; - - return cgi; -} - -void cgi_req_add(struct cgi_request *r) -{ - struct mk_list *list; - - list = pthread_getspecific(cgi_request_list); - mk_list_add(&r->_head, list); -} - -int cgi_req_del(struct cgi_request *r) -{ - PLUGIN_TRACE("Delete request child_fd=%i child_pid=%lu", - r->fd, r->child); - - mk_list_del(&r->_head); - if (r->active == MK_FALSE) { - mk_api->sched_event_free(&r->event); - } - else { - mk_mem_free(r); - } - - return 0; -} diff --git a/fluent-bit/lib/monkey/plugins/cheetah/ABOUT b/fluent-bit/lib/monkey/plugins/cheetah/ABOUT deleted file mode 100644 index 229bf62c2..000000000 --- a/fluent-bit/lib/monkey/plugins/cheetah/ABOUT +++ /dev/null @@ -1,4 +0,0 @@ -Cheetah! Plugin -=============== -This plugin provides a command line interface for Monkey, -it works like a shell. diff --git a/fluent-bit/lib/monkey/plugins/cheetah/CMakeLists.txt b/fluent-bit/lib/monkey/plugins/cheetah/CMakeLists.txt deleted file mode 100644 index ca760c337..000000000 --- a/fluent-bit/lib/monkey/plugins/cheetah/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -set(src - cheetah.c - loop.c - cmd.c - cutils.c - ) - -MONKEY_PLUGIN(cheetah "${src}") -add_subdirectory(conf) diff --git a/fluent-bit/lib/monkey/plugins/cheetah/OPTIONAL b/fluent-bit/lib/monkey/plugins/cheetah/OPTIONAL deleted file mode 100644 index e69de29bb..000000000 --- a/fluent-bit/lib/monkey/plugins/cheetah/OPTIONAL +++ /dev/null diff --git a/fluent-bit/lib/monkey/plugins/cheetah/cheetah.c b/fluent-bit/lib/monkey/plugins/cheetah/cheetah.c deleted file mode 100644 index 489e73422..000000000 --- a/fluent-bit/lib/monkey/plugins/cheetah/cheetah.c +++ /dev/null @@ -1,162 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* Monkey Plugin Interface */ -#include <monkey/mk_api.h> - -/* Local header files */ -#include "cmd.h" -#include "cutils.h" -#include "cheetah.h" -#include "loop.h" - -void mk_cheetah_welcome_msg() -{ - CHEETAH_WRITE("\n%s%s***%s Welcome to %sCheetah!%s, the %sMonkey Shell %s:) %s***%s\n", - ANSI_BOLD, ANSI_YELLOW, - ANSI_WHITE, ANSI_GREEN, - ANSI_WHITE, ANSI_RED, ANSI_WHITE, ANSI_YELLOW, ANSI_RESET); - CHEETAH_WRITE("\n << %sType 'help' or '\\h' for help%s >>\n\n", - ANSI_BLUE, ANSI_RESET); - CHEETAH_FLUSH(); -} - -static int mk_cheetah_config(char *path) -{ - unsigned long len; - char *listen = NULL; - char *default_file = NULL; - struct mk_rconf *conf; - struct mk_rconf_section *section; - - /* this variable is defined in cheetah.h and points to - * the FILE *descriptor where to write out the data - */ - cheetah_output = NULL; - - /* read configuration file */ - mk_api->str_build(&default_file, &len, "%scheetah.conf", path); - conf = mk_api->config_open(default_file); - if (!conf) { - return -1; - } - - section = mk_api->config_section_get(conf, "CHEETAH"); - - if (!section) { - CHEETAH_WRITE("\nError, could not find CHEETAH tag"); - return -1; - } - - /* no longer needed */ - mk_api->mem_free(default_file); - - /* Listen directive */ - listen = mk_api->config_section_get_key(section, "Listen", MK_RCONF_STR); - - if (strcasecmp(listen, LISTEN_STDIN_STR) == 0) { - listen_mode = LISTEN_STDIN; - } - else if (strcasecmp(listen, LISTEN_SERVER_STR) == 0) { - listen_mode = LISTEN_SERVER; - } - else { - printf("\nCheetah! Error: Invalid LISTEN value"); - return -1; - } - - /* Cheetah cannot work in STDIN mode if Monkey is working in background */ - if (listen_mode == LISTEN_STDIN && mk_api->config->is_daemon == MK_TRUE) { - printf("\nCheetah!: Forcing SERVER mode as Monkey is running in background\n"); - fflush(stdout); - listen_mode = LISTEN_SERVER; - } - - return 0; -} - -static void mk_cheetah_init(void *args) -{ - struct mk_server *server = args; - - /* Rename worker */ - mk_api->worker_rename("monkey: cheetah"); - - /* Open right FDs for I/O */ - if (listen_mode == LISTEN_STDIN) { - cheetah_input = stdin; - cheetah_output = stdout; - mk_cheetah_loop_stdin(server); - } - else if (listen_mode == LISTEN_SERVER) { - mk_cheetah_loop_server(server); - } -} - -/* This function is called when the plugin is loaded, it must - * return - */ -int mk_cheetah_plugin_init(struct plugin_api **api, char *confdir) -{ - int ret; - mk_api = *api; - init_time = time(NULL); - - ret = mk_cheetah_config(confdir); - return ret; -} - -int mk_cheetah_plugin_exit() -{ - if (listen_mode == LISTEN_SERVER) { - /* Remote named pipe */ - unlink(cheetah_server); - mk_api->mem_free(cheetah_server); - } - - return 0; -} - -int mk_cheetah_master_init(struct mk_server *server) -{ - int ret; - pthread_t tid; - - ret = mk_api->worker_spawn(mk_cheetah_init, server, &tid); - if (ret != 0) { - return -1; - } - - return 0; -} - -struct mk_plugin mk_plugin_cheetah = { - /* Identification */ - .shortname = "cheetah", - .name = "Cheetah! Shell", - .version = MK_VERSION_STR, - - /* Init / Exit */ - .init_plugin = mk_cheetah_plugin_init, - .exit_plugin = mk_cheetah_plugin_exit, - - /* Init Levels */ - .master_init = mk_cheetah_master_init, - .worker_init = NULL -}; diff --git a/fluent-bit/lib/monkey/plugins/cheetah/cheetah.h b/fluent-bit/lib/monkey/plugins/cheetah/cheetah.h deleted file mode 100644 index 5bf6c14e5..000000000 --- a/fluent-bit/lib/monkey/plugins/cheetah/cheetah.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MK_CHEETAH_H -#define MK_CHEETAH_H - -/* Commands */ -#define MK_CHEETAH_CLEAR "clear" -#define MK_CHEETAH_CLEAR_SC "\\c" - -#define MK_CHEETAH_CONFIG "config" -#define MK_CHEETAH_CONFIG_SC "\\f" - -#define MK_CHEETAH_STATUS "status" -#define MK_CHEETAH_STATUS_SC "\\s" - -#define MK_CHEETAH_HELP "help" -#define MK_CHEETAH_HELP_SC "\\h" - -#define MK_CHEETAH_SHELP "?" -#define MK_CHEETAH_SHELP_SC "\\?" - -#define MK_CHEETAH_UPTIME "uptime" -#define MK_CHEETAH_UPTIME_SC "\\u" - -#define MK_CHEETAH_PLUGINS "plugins" -#define MK_CHEETAH_PLUGINS_SC "\\g" - -#define MK_CHEETAH_VHOSTS "vhosts" -#define MK_CHEETAH_VHOSTS_SC "\\v" - -#define MK_CHEETAH_WORKERS "workers" -#define MK_CHEETAH_WORKERS_SC "\\w" - -#define MK_CHEETAH_QUIT "quit" -#define MK_CHEETAH_QUIT_SC "\\q" - -/* Constants */ -#define MK_CHEETAH_PROMPT "%s%scheetah>%s " -#define MK_CHEETAH_PROC_TASK "/proc/%i/task/%i/stat" -#define MK_CHEETAH_ONEDAY 86400 -#define MK_CHEETAH_ONEHOUR 3600 -#define MK_CHEETAH_ONEMINUTE 60 - -/* Configurarion: Listen */ -#define LISTEN_STDIN_STR "STDIN" -#define LISTEN_SERVER_STR "SERVER" - -#define LISTEN_STDIN 0 -#define LISTEN_SERVER 1 - -int listen_mode; - -char *cheetah_server; - -int cheetah_socket; -FILE *cheetah_input; -FILE *cheetah_output; - -/* functions */ -void mk_cheetah_welcome_msg(); - -#endif diff --git a/fluent-bit/lib/monkey/plugins/cheetah/cmd.c b/fluent-bit/lib/monkey/plugins/cheetah/cmd.c deleted file mode 100644 index 6f02dad23..000000000 --- a/fluent-bit/lib/monkey/plugins/cheetah/cmd.c +++ /dev/null @@ -1,472 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <monkey/mk_api.h> - -#include <pwd.h> -#include <ctype.h> - -#include "cheetah.h" -#include "cutils.h" -#include "cmd.h" - -/* strip leading and trailing space from input command line. */ -static char *strip_whitespace(char *cmd) -{ - char *end; - while (isspace(*cmd)) - cmd++; - if (*cmd == 0) - return cmd; - end = cmd + strlen(cmd) - 1; - while (end > cmd && isspace(*end)) - end--; - end++; - *end = '\0'; - return cmd; -} - -int mk_cheetah_cmd(char *raw_cmd, struct mk_server *server) -{ - char *cmd = strip_whitespace(raw_cmd); - if (strcmp(cmd, MK_CHEETAH_CONFIG) == 0 || - strcmp(cmd, MK_CHEETAH_CONFIG_SC) == 0) { - mk_cheetah_cmd_config(server); - } - else if (strcmp(cmd, MK_CHEETAH_STATUS) == 0 || - strcmp(cmd, MK_CHEETAH_STATUS_SC) == 0) { - mk_cheetah_cmd_status(server); - } - else if (strcmp(cmd, MK_CHEETAH_CLEAR) == 0 || - strcmp(cmd, MK_CHEETAH_CLEAR_SC) == 0) { - mk_cheetah_cmd_clear(); - } - else if (strcmp(cmd, MK_CHEETAH_UPTIME) == 0 || - strcmp(cmd, MK_CHEETAH_UPTIME_SC) == 0) { - mk_cheetah_cmd_uptime(server); - } - else if (strcmp(cmd, MK_CHEETAH_PLUGINS) == 0 || - strcmp(cmd, MK_CHEETAH_PLUGINS_SC) == 0) { - mk_cheetah_cmd_plugins(server); - } - else if (strcmp(cmd, MK_CHEETAH_WORKERS) == 0 || - strcmp(cmd, MK_CHEETAH_WORKERS_SC) == 0) { - mk_cheetah_cmd_workers(server); - } - else if (strcmp(cmd, MK_CHEETAH_VHOSTS) == 0 || - strcmp(cmd, MK_CHEETAH_VHOSTS_SC) == 0) { - mk_cheetah_cmd_vhosts(server); - } - else if (strcmp(cmd, MK_CHEETAH_HELP) == 0 || - strcmp(cmd, MK_CHEETAH_HELP_SC) == 0 || - strcmp(cmd, MK_CHEETAH_SHELP) == 0 || - strcmp(cmd, MK_CHEETAH_SHELP_SC) == 0) { - mk_cheetah_cmd_help(); - } - else if (strcmp(cmd, MK_CHEETAH_QUIT) == 0 || - strcmp(cmd, MK_CHEETAH_QUIT_SC) == 0) { - return mk_cheetah_cmd_quit(); - } - else if (strlen(cmd) == 0) { - return 0; - } - else { - CHEETAH_WRITE("Invalid command, type 'help' for a list of available commands\n"); - } - - CHEETAH_FLUSH(); - return 0; -} - -void mk_cheetah_cmd_clear() -{ - CHEETAH_WRITE("\033[2J\033[1;1H"); -} - -void mk_cheetah_cmd_uptime(struct mk_server *server) -{ - int days; - int hours; - int minutes; - int seconds; - long int upmind; - long int upminh; - long int uptime; - (void) server; - - /* uptime in seconds */ - uptime = time(NULL) - init_time; - - /* days */ - days = uptime / MK_CHEETAH_ONEDAY; - upmind = uptime - (days * MK_CHEETAH_ONEDAY); - - /* hours */ - hours = upmind / MK_CHEETAH_ONEHOUR; - upminh = upmind - hours * MK_CHEETAH_ONEHOUR; - - /* minutes */ - minutes = upminh / MK_CHEETAH_ONEMINUTE; - seconds = upminh - minutes * MK_CHEETAH_ONEMINUTE; - - CHEETAH_WRITE - ("Server has been running: %i day%s, %i hour%s, %i minute%s and %i second%s\n\n", - days, (days > 1) ? "s" : "", hours, (hours > 1) ? "s" : "", minutes, - (minutes > 1) ? "s" : "", seconds, (seconds > 1) ? "s" : ""); -} - -void mk_cheetah_cmd_plugins_print_core(struct mk_list *list) -{ - struct mk_plugin *p; - struct mk_list *head; - - CHEETAH_WRITE("\n%s[MASTER INIT]%s", ANSI_BOLD ANSI_BLUE, ANSI_RESET); - - mk_list_foreach(head, list) { - p = mk_list_entry(head, struct mk_plugin, _head); - - if (p->master_init) { - CHEETAH_WRITE("\n [%s] %s v%s on \"%s\"", - p->shortname, p->name, p->version, p->path); - } - } - - CHEETAH_WRITE("\n\n%s[WORKER INIT]%s", ANSI_BOLD ANSI_BLUE, ANSI_RESET); - - mk_list_foreach(head, list) { - p = mk_list_entry(head, struct mk_plugin, _head); - - if (p->worker_init) { - CHEETAH_WRITE("\n [%s] %s v%s on \"%s\"", - p->shortname, p->name, p->version, p->path); - } - } - - CHEETAH_WRITE("\n\n"); -} - -void mk_cheetah_cmd_plugins_print_network(struct mk_list *list) -{ - struct mk_plugin *p; - struct mk_list *head; - - CHEETAH_WRITE("%s[NETWORK I/O]%s", ANSI_BOLD ANSI_RED, ANSI_RESET); - - mk_list_foreach(head, list) { - p = mk_list_entry(head, struct mk_plugin, _head); - if (p->hooks & MK_PLUGIN_NETWORK_LAYER) { - CHEETAH_WRITE("\n [%s] %s v%s on \"%s\"", - p->shortname, p->name, p->version, p->path); - } - } - - CHEETAH_WRITE("\n"); -} - -void mk_cheetah_cmd_plugins(struct mk_server *server) -{ - struct mk_plugin *p; - struct mk_plugin_stage *s; - struct mk_list *head; - - if (mk_list_is_empty(&server->stage10_handler)) { - CHEETAH_WRITE("%s[%sSTAGE_10%s]%s", - ANSI_BOLD, ANSI_YELLOW, ANSI_WHITE, ANSI_RESET); - mk_list_foreach(head, &mk_api->config->stage10_handler) { - s = mk_list_entry(head, struct mk_plugin_stage, _head); - p = s->plugin; - CHEETAH_WRITE("\n [%s] %s v%s on \"%s\"", - p->shortname, p->name, p->version, p->path); - } - } - - if (mk_list_is_empty(&mk_api->config->stage20_handler)) { - CHEETAH_WRITE("%s[%sSTAGE_20%s]%s", - ANSI_BOLD, ANSI_YELLOW, ANSI_WHITE, ANSI_RESET); - mk_list_foreach(head, &mk_api->config->stage20_handler) { - s = mk_list_entry(head, struct mk_plugin_stage, _head); - p = s->plugin; - CHEETAH_WRITE("\n [%s] %s v%s on \"%s\"", - p->shortname, p->name, p->version, p->path); - } - } - - if (mk_list_is_empty(&mk_api->config->stage30_handler)) { - CHEETAH_WRITE("%s[%sSTAGE_30%s]%s", - ANSI_BOLD, ANSI_YELLOW, ANSI_WHITE, ANSI_RESET); - mk_list_foreach(head, &mk_api->config->stage30_handler) { - s = mk_list_entry(head, struct mk_plugin_stage, _head); - p = s->plugin; - CHEETAH_WRITE("\n [%s] %s v%s on \"%s\"", - p->shortname, p->name, p->version, p->path); - } - } - - if (mk_list_is_empty(&mk_api->config->stage40_handler)) { - CHEETAH_WRITE("%s[%sSTAGE_40%s]%s", - ANSI_BOLD, ANSI_YELLOW, ANSI_WHITE, ANSI_RESET); - mk_list_foreach(head, &mk_api->config->stage40_handler) { - s = mk_list_entry(head, struct mk_plugin_stage, _head); - p = s->plugin; - CHEETAH_WRITE("\n [%s] %s v%s on \"%s\"", - p->shortname, p->name, p->version, p->path); - } - } - - if (mk_list_is_empty(&mk_api->config->stage50_handler)) { - CHEETAH_WRITE("%s[%sSTAGE_50%s]%s", - ANSI_BOLD, ANSI_YELLOW, ANSI_WHITE, ANSI_RESET); - mk_list_foreach(head, &mk_api->config->stage50_handler) { - s = mk_list_entry(head, struct mk_plugin_stage, _head); - p = s->plugin; - CHEETAH_WRITE("\n [%s] %s v%s on \"%s\"", - p->shortname, p->name, p->version, p->path); - } - } - - CHEETAH_WRITE("\n\n"); -} - -void mk_cheetah_cmd_vhosts(struct mk_server *server) -{ - struct mk_vhost *entry_host; - struct mk_vhost_alias *entry_alias; - struct mk_rconf_section *section; - struct mk_rconf_entry *entry; - struct mk_list *hosts = &server->hosts; - struct mk_list *aliases; - struct mk_list *head_host; - struct mk_list *head_alias; - struct mk_list *head_sections; - struct mk_list *head_entries; - - mk_list_foreach(head_host, hosts) { - entry_host = mk_list_entry(head_host, struct mk_vhost, _head); - - aliases = &entry_host->server_names; - entry_alias = mk_list_entry_first(aliases, struct mk_vhost_alias, _head); - CHEETAH_WRITE("%s[%sVHost '%s'%s%s]%s\n", - ANSI_BOLD, ANSI_YELLOW, - entry_alias->name, ANSI_BOLD, ANSI_WHITE, ANSI_RESET); - - CHEETAH_WRITE(" - Names : "); - mk_list_foreach(head_alias, aliases) { - entry_alias = mk_list_entry(head_alias, struct mk_vhost_alias, _head); - CHEETAH_WRITE("%s ", entry_alias->name); - } - CHEETAH_WRITE("\n"); - - CHEETAH_WRITE(" - Document root : %s\n", entry_host->documentroot.data); - CHEETAH_WRITE(" - Config file : %s\n", entry_host->file); - - if (!entry_host->config) { - continue; - } - - mk_list_foreach(head_sections, &entry_host->config->sections) { - section = mk_list_entry(head_sections, struct mk_rconf_section, _head); - CHEETAH_WRITE(" %s+%s [%s]\n", ANSI_GREEN, ANSI_RESET, - section->name); - - mk_list_foreach(head_entries, §ion->entries) { - entry = mk_list_entry(head_entries, struct mk_rconf_entry, _head); - CHEETAH_WRITE(" - %11.10s : %s\n", entry->key, entry->val); - } - } - } - - CHEETAH_WRITE("\n"); -} - -void mk_cheetah_cmd_workers(struct mk_server *server) -{ - int i; - unsigned long long active_connections; - struct mk_sched_worker *node; - struct mk_sched_ctx *ctx; - - ctx = server->sched_ctx; - node = ctx->workers; - for (i=0; i < server->workers; i++) { - active_connections = (node[i].accepted_connections - node[i].closed_connections); - - CHEETAH_WRITE("* Worker %i\n", node[i].idx); - CHEETAH_WRITE(" - Task ID : %i\n", node[i].pid); - CHEETAH_WRITE(" - Active Connections: %llu\n", active_connections); - } - - CHEETAH_WRITE("\n"); -} - -int mk_cheetah_cmd_quit() -{ - CHEETAH_WRITE("Cheeta says: Good Bye!\n"); - if (listen_mode == LISTEN_STDIN) { - pthread_exit(NULL); - return 0; - } - else { - return -1; - } -} - -void mk_cheetah_cmd_help() -{ - CHEETAH_WRITE("List of available commands for Cheetah Shell\n"); - CHEETAH_WRITE("\ncommand shortcut description"); - CHEETAH_WRITE("\n----------------------------------------------------"); - CHEETAH_WRITE("\n? (\\?) Synonym for 'help'"); - CHEETAH_WRITE("\nconfig (\\f) Display global configuration"); - CHEETAH_WRITE("\nplugins (\\g) List loaded plugins and associated stages"); - CHEETAH_WRITE("\nstatus (\\s) Display general web server information"); - CHEETAH_WRITE("\nuptime (\\u) Display how long the web server has been running"); - CHEETAH_WRITE("\nvhosts (\\v) List virtual hosts configured"); - CHEETAH_WRITE("\nworkers (\\w) Show thread workers information\n"); - CHEETAH_WRITE("\nclear (\\c) Clear screen"); - CHEETAH_WRITE("\nhelp (\\h) Print this help"); - CHEETAH_WRITE("\nquit (\\q) Exit Cheetah shell :_(\n\n"); -} - -static void mk_cheetah_listen_config(struct mk_server *server) -{ - struct mk_list *head; - struct mk_config_listener *listener; - - mk_list_foreach(head, &server->listeners) { - listener = mk_list_entry(head, struct mk_config_listener, _head); - CHEETAH_WRITE("\nListen on : %s:%s", - listener->address, - listener->port); - } -} - -void mk_cheetah_cmd_config(struct mk_server *server) -{ - struct mk_string_line *entry; - struct mk_list *head; - struct mk_config_listener *listener; - - listener = mk_list_entry_first(&server->listeners, - struct mk_config_listener, - _head); - - CHEETAH_WRITE("Basic configuration"); - CHEETAH_WRITE("\n-------------------"); - mk_cheetah_listen_config(server); - CHEETAH_WRITE("\nWorkers : %i threads", mk_api->config->workers); - CHEETAH_WRITE("\nTimeout : %i seconds", mk_api->config->timeout); - CHEETAH_WRITE("\nPidFile : %s.%s", - mk_api->config->path_conf_pidfile, - listener->port); - CHEETAH_WRITE("\nUserDir : %s", - mk_api->config->conf_user_pub); - - - if (mk_list_is_empty(mk_api->config->index_files) == 0) { - CHEETAH_WRITE("\nIndexFile : No index files defined"); - } - else { - CHEETAH_WRITE("\nIndexFile : "); - mk_list_foreach(head, mk_api->config->index_files) { - entry = mk_list_entry(head, struct mk_string_line, _head); - CHEETAH_WRITE("%s ", entry->val); - } - - } - - CHEETAH_WRITE("\nHideVersion : "); - if (mk_api->config->hideversion == MK_TRUE) { - CHEETAH_WRITE("On"); - } - else { - CHEETAH_WRITE("Off"); - } - - CHEETAH_WRITE("\nResume : "); - if (mk_api->config->resume == MK_TRUE) { - CHEETAH_WRITE("On"); - } - else { - CHEETAH_WRITE("Off"); - } - - CHEETAH_WRITE("\nUser : %s", mk_api->config->user); - CHEETAH_WRITE("\n\nAdvanced configuration"); - CHEETAH_WRITE("\n----------------------"); - CHEETAH_WRITE("\nKeepAlive : "); - if (mk_api->config->keep_alive == MK_TRUE) { - CHEETAH_WRITE("On"); - } - else { - CHEETAH_WRITE("Off"); - } - CHEETAH_WRITE("\nMaxKeepAliveRequest : %i req/connection", - mk_api->config->max_keep_alive_request); - CHEETAH_WRITE("\nKeepAliveTimeout : %i seconds", mk_api->config->keep_alive_timeout); - CHEETAH_WRITE("\nMaxRequestSize : %i KB", - mk_api->config->max_request_size/1024); - CHEETAH_WRITE("\nSymLink : "); - if (mk_api->config->symlink == MK_TRUE) { - CHEETAH_WRITE("On"); - } - else { - CHEETAH_WRITE("Off"); - } - CHEETAH_WRITE("\n\n"); -} - -void mk_cheetah_cmd_status(struct mk_server *server) -{ - int nthreads = server->workers; - char tmp[64]; - - CHEETAH_WRITE("Monkey Version : %s\n", MK_VERSION_STR); - CHEETAH_WRITE("Configuration path : %s\n", server->path_conf_root); - - CHEETAH_WRITE("Cheetah! mode : "); - if (listen_mode == LISTEN_STDIN) { - CHEETAH_WRITE("STDIN\n"); - } - else { - CHEETAH_WRITE("SERVER @ %s\n", cheetah_server); - } - - CHEETAH_WRITE("Process ID : %i\n", getpid()); - CHEETAH_WRITE("Process User : "); - mk_cheetah_print_running_user(); - mk_cheetah_listen_config(server); - - CHEETAH_WRITE("\n"); - CHEETAH_WRITE("Worker Threads : %i (per configuration: %i)\n", - nthreads, server->workers); - - CHEETAH_WRITE("Memory Allocator : "); -#ifdef MALLOC_LIBC - CHEETAH_WRITE("libc, system default\n"); -#else - CHEETAH_WRITE("Jemalloc\n"); -#endif - - if (mk_api->kernel_features_print(tmp, sizeof(tmp), server) > 0) { - CHEETAH_WRITE("Kernel Features : %s\n", tmp); - } - - CHEETAH_WRITE("Events backend : %s\n", mk_api->ev_backend()); - CHEETAH_WRITE("\n"); -} diff --git a/fluent-bit/lib/monkey/plugins/cheetah/cmd.h b/fluent-bit/lib/monkey/plugins/cheetah/cmd.h deleted file mode 100644 index 617a88be1..000000000 --- a/fluent-bit/lib/monkey/plugins/cheetah/cmd.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -time_t init_time; - -/* commands */ -int mk_cheetah_cmd(char *cmd, struct mk_server *server); - -void mk_cheetah_cmd_clear(); -void mk_cheetah_cmd_uptime(struct mk_server *server); - -/* Plugins commands */ -void mk_cheetah_cmd_plugins_print_stage(struct mk_list *list, const char *stage, - int stage_bw); -void mk_cheetah_cmd_plugins_print_core(struct mk_list *list); -void mk_cheetah_cmd_plugins_print_network(struct mk_list *list); -void mk_cheetah_cmd_plugins(struct mk_server *server); - -void mk_cheetah_cmd_vhosts(struct mk_server *server); -void mk_cheetah_cmd_workers(struct mk_server *server); - -int mk_cheetah_cmd_quit(); -void mk_cheetah_cmd_help(); -void mk_cheetah_cmd_config(struct mk_server *server); -void mk_cheetah_cmd_status(struct mk_server *server); diff --git a/fluent-bit/lib/monkey/plugins/cheetah/conf/CMakeLists.txt b/fluent-bit/lib/monkey/plugins/cheetah/conf/CMakeLists.txt deleted file mode 100644 index b7224f351..000000000 --- a/fluent-bit/lib/monkey/plugins/cheetah/conf/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -set(conf_dir "${MK_PATH_CONF}/plugins/cheetah/") - -install(DIRECTORY DESTINATION ${conf_dir}) - -if(BUILD_LOCAL) - file(COPY cheetah.conf DESTINATION ${conf_dir}) -else() - install(FILES cheetah.conf DESTINATION ${conf_dir}) -endif() diff --git a/fluent-bit/lib/monkey/plugins/cheetah/conf/cheetah.conf b/fluent-bit/lib/monkey/plugins/cheetah/conf/cheetah.conf deleted file mode 100644 index d9448926e..000000000 --- a/fluent-bit/lib/monkey/plugins/cheetah/conf/cheetah.conf +++ /dev/null @@ -1,17 +0,0 @@ -# Cheetah! configuration -# ====================== -# Cheetah! is the Monkey Sheel and in this file you can define -# the basic setup and behavior expected. -# - -[CHEETAH] - # Listen : - # -------- - # Cheetah! listen for input commands as any shell, this can be done - # using the standard keyboard input or through a unix pipe where you - # need to connect using the Cheetah! client. - # - # The Listen directive allows you to define which input method to use. - # Valid values for Listen are STDIN or SERVER. - # - Listen SERVER diff --git a/fluent-bit/lib/monkey/plugins/cheetah/cutils.c b/fluent-bit/lib/monkey/plugins/cheetah/cutils.c deleted file mode 100644 index 3c0bd825f..000000000 --- a/fluent-bit/lib/monkey/plugins/cheetah/cutils.c +++ /dev/null @@ -1,117 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <monkey/mk_api.h> - -#include <pwd.h> -#include <stdarg.h> -#include <string.h> - -#include "cheetah.h" -#include "cutils.h" - -void mk_cheetah_print_worker_memory_usage(pid_t pid) -{ - int s = 1024; - char *buf; - pid_t ppid; - FILE *f; - - ppid = getpid(); - buf = mk_api->mem_alloc(s); - sprintf(buf, MK_CHEETAH_PROC_TASK, ppid, pid); - - f = fopen(buf, "r"); - if (!f) { - CHEETAH_WRITE("Cannot get details\n"); - return; - } - - buf = fgets(buf, s, f); - fclose(f); - if (!buf) { - CHEETAH_WRITE("Cannot format details\n"); - return; - } - - CHEETAH_WRITE("\n"); - return; - -/* - int n, c; - int init = 0; - int last = 0; - char *value; - - while ((n = mk_api->str_search(buf + last, " ", MK_STR_SENSITIVE)) > 0) { - if (c == 23) { - value = mk_api->str_copy_substr(buf, init, last + n); - printf("%s\n", value); - mk_mem_free(buf); - mk_mem_free(value); - return; - } - init = last + n + 1; - last += n + 1; - c++; - }*/ -} - -void mk_cheetah_print_running_user() -{ - struct passwd pwd; - struct passwd *result; - char *buf; - long bufsize; - uid_t uid; - - bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); - if (bufsize == -1) { - bufsize = 16384; - } - - buf = mk_api->mem_alloc_z(bufsize); - uid = getuid(); - getpwuid_r(uid, &pwd, buf, bufsize, &result); - - CHEETAH_WRITE("%s", pwd.pw_name); - mk_api->mem_free(buf); -} - -int mk_cheetah_write(const char *format, ...) -{ - int len = 0; - char buf[1024]; - va_list ap; - - va_start(ap, format); - len = vsprintf(buf, format, ap); - - if (listen_mode == LISTEN_STDIN) { - len = fprintf(cheetah_output, buf, NULL); - } - else if (listen_mode == LISTEN_SERVER) { - len = write(cheetah_socket, buf, len); - } - - memset(buf, '\0', sizeof(buf)); - va_end(ap); - - return len; -} diff --git a/fluent-bit/lib/monkey/plugins/cheetah/cutils.h b/fluent-bit/lib/monkey/plugins/cheetah/cutils.h deleted file mode 100644 index c6948a55a..000000000 --- a/fluent-bit/lib/monkey/plugins/cheetah/cutils.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MK_CHEETAH_CUTILS_H -#define MK_CHEETAH_CUTILS_H - -#include <stdio.h> - -#define CHEETAH_WRITE(...) mk_cheetah_write(__VA_ARGS__); -#define CHEETAH_FLUSH() fflush(cheetah_output);fflush(cheetah_input); - -void mk_cheetah_print_worker_memory_usage(pid_t pid); -void mk_cheetah_print_running_user(); -int mk_cheetah_write(const char *format, ...); - -#endif diff --git a/fluent-bit/lib/monkey/plugins/cheetah/loop.c b/fluent-bit/lib/monkey/plugins/cheetah/loop.c deleted file mode 100644 index e30f26f2c..000000000 --- a/fluent-bit/lib/monkey/plugins/cheetah/loop.c +++ /dev/null @@ -1,149 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <monkey/mk_api.h> - -#include <sys/socket.h> -#include <sys/un.h> - -/* Monkey Plugin Interface */ -#include "cheetah.h" -#include "cutils.h" -#include "cmd.h" -#include "loop.h" - -void mk_cheetah_loop_stdin(struct mk_server *server) -{ - int len; - char cmd[200]; - char line[200]; - char *rcmd; - - mk_cheetah_welcome_msg(); - - while (1) { - CHEETAH_WRITE(MK_CHEETAH_PROMPT, ANSI_BOLD, ANSI_GREEN, ANSI_RESET); - - rcmd = fgets(line, sizeof(line), cheetah_input); - if (!rcmd) { - continue; - } - - len = strlen(line); - - if (len == 0){ - CHEETAH_WRITE("\n"); - mk_cheetah_cmd_quit(); - } - - strncpy(cmd, line, len - 1); - cmd[len - 1] = '\0'; - - mk_cheetah_cmd(cmd, server); - memset(line, '\0', sizeof(line)); - } -} - -void mk_cheetah_loop_server(struct mk_server *server) -{ - int n, ret; - int buf_len; - unsigned long len; - char buf[1024]; - char cmd[1024]; - int server_fd; - int remote_fd; - size_t address_length; - struct sockaddr_un address; - socklen_t socket_size = sizeof(struct sockaddr_in); - struct mk_config_listener *listener; - - /* Create listening socket */ - server_fd = socket(PF_UNIX, SOCK_STREAM, 0); - if (server_fd < 0) { - perror("socket() failed"); - exit(EXIT_FAILURE); - } - - listener = mk_list_entry_first(&mk_api->config->listeners, - struct mk_config_listener, - _head); - cheetah_server = NULL; - mk_api->str_build(&cheetah_server, &len, "/tmp/cheetah.%s", - listener->port); - unlink(cheetah_server); - - address.sun_family = AF_UNIX; - sprintf(address.sun_path, "%s", cheetah_server); - address_length = sizeof(address.sun_family) + len + 1; - - if (bind(server_fd, (struct sockaddr *) &address, address_length) != 0) { - perror("bind"); - mk_err("Cheetah: could not bind address %s", address.sun_path); - exit(EXIT_FAILURE); - } - - if (listen(server_fd, 5) != 0) { - perror("listen"); - exit(EXIT_FAILURE); - } - - while (1) { - /* Listen for incoming connections */ - remote_fd = accept(server_fd, (struct sockaddr *) &address, &socket_size); - cheetah_socket = remote_fd; - - buf_len = 0; - memset(buf, '\0', 1024); - - /* Send welcome message and prompt */ - mk_cheetah_welcome_msg(); - CHEETAH_WRITE(MK_CHEETAH_PROMPT, ANSI_BOLD, ANSI_GREEN, ANSI_RESET); - - while (1) { - /* Read incoming data */ - n = read(remote_fd, buf+buf_len, 1024 - buf_len); - if (n <= 0) { - break; - } - else { - buf_len += n; - if (buf[buf_len-1] == '\n') { - /* Filter command */ - strncpy(cmd, buf, buf_len - 1); - cmd[buf_len - 1] = '\0'; - - /* Run command */ - ret = mk_cheetah_cmd(cmd, server); - - if (ret == -1) { - break; - } - - /* Write prompt */ - CHEETAH_WRITE(MK_CHEETAH_PROMPT, ANSI_BOLD, ANSI_GREEN, ANSI_RESET); - buf_len = 0; - memset(buf, '\0', 1024); - } - } - } - - close(remote_fd); - } -} diff --git a/fluent-bit/lib/monkey/plugins/cheetah/loop.h b/fluent-bit/lib/monkey/plugins/cheetah/loop.h deleted file mode 100644 index 232a00b61..000000000 --- a/fluent-bit/lib/monkey/plugins/cheetah/loop.h +++ /dev/null @@ -1,26 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MK_CHEETAH_LOOP_H -#define MK_CHEETAH_LOOP_H - -void mk_cheetah_loop_stdin(); -void mk_cheetah_loop_server(); - -#endif diff --git a/fluent-bit/lib/monkey/plugins/dirlisting/ABOUT b/fluent-bit/lib/monkey/plugins/dirlisting/ABOUT deleted file mode 100644 index 2d71cb77e..000000000 --- a/fluent-bit/lib/monkey/plugins/dirlisting/ABOUT +++ /dev/null @@ -1,4 +0,0 @@ -Directory Listing Plugin -======================== -When a directory is requested, this plugin will show -an HTML list of the available content to the client. diff --git a/fluent-bit/lib/monkey/plugins/dirlisting/CMakeLists.txt b/fluent-bit/lib/monkey/plugins/dirlisting/CMakeLists.txt deleted file mode 100644 index 7432e1091..000000000 --- a/fluent-bit/lib/monkey/plugins/dirlisting/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -set(src - dirlisting.c - ) - -MONKEY_PLUGIN(dirlisting "${src}") - -add_subdirectory(conf)
\ No newline at end of file diff --git a/fluent-bit/lib/monkey/plugins/dirlisting/OPTIONAL b/fluent-bit/lib/monkey/plugins/dirlisting/OPTIONAL deleted file mode 100644 index e69de29bb..000000000 --- a/fluent-bit/lib/monkey/plugins/dirlisting/OPTIONAL +++ /dev/null diff --git a/fluent-bit/lib/monkey/plugins/dirlisting/conf/CMakeLists.txt b/fluent-bit/lib/monkey/plugins/dirlisting/conf/CMakeLists.txt deleted file mode 100644 index 4faf80a4d..000000000 --- a/fluent-bit/lib/monkey/plugins/dirlisting/conf/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -set(conf_dir "${MK_PATH_CONF}/plugins/dirlisting/") - -install(DIRECTORY DESTINATION ${conf_dir}) - -if(BUILD_LOCAL) - file(COPY dirhtml.conf DESTINATION ${conf_dir}) - file(COPY themes DESTINATION ${conf_dir}) -else() - install(FILES dirhtml.conf DESTINATION ${conf_dir}) - install(DIRECTORY themes DESTINATION ${conf_dir}) -endif()
\ No newline at end of file diff --git a/fluent-bit/lib/monkey/plugins/dirlisting/conf/dirhtml.conf b/fluent-bit/lib/monkey/plugins/dirlisting/conf/dirhtml.conf deleted file mode 100644 index c73188df2..000000000 --- a/fluent-bit/lib/monkey/plugins/dirlisting/conf/dirhtml.conf +++ /dev/null @@ -1,2 +0,0 @@ -[DIRLISTING] - Theme bootstrap diff --git a/fluent-bit/lib/monkey/plugins/dirlisting/conf/themes/bootstrap/entry.theme b/fluent-bit/lib/monkey/plugins/dirlisting/conf/themes/bootstrap/entry.theme deleted file mode 100644 index 8c1ef026d..000000000 --- a/fluent-bit/lib/monkey/plugins/dirlisting/conf/themes/bootstrap/entry.theme +++ /dev/null @@ -1,5 +0,0 @@ -<tr> - <td><a title='%_target_title_%' href='%_target_url_%'>%_target_name_%</a></td> - <td>%_target_time_%</td> - <td>%_target_size_%</td> -</tr> diff --git a/fluent-bit/lib/monkey/plugins/dirlisting/conf/themes/bootstrap/footer.theme b/fluent-bit/lib/monkey/plugins/dirlisting/conf/themes/bootstrap/footer.theme deleted file mode 100644 index 88290ac8b..000000000 --- a/fluent-bit/lib/monkey/plugins/dirlisting/conf/themes/bootstrap/footer.theme +++ /dev/null @@ -1,8 +0,0 @@ - <tbody> -</table> -</div> -</div> -<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> -<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script> -</body> -</HTML> diff --git a/fluent-bit/lib/monkey/plugins/dirlisting/conf/themes/bootstrap/header.theme b/fluent-bit/lib/monkey/plugins/dirlisting/conf/themes/bootstrap/header.theme deleted file mode 100644 index f7f6cfcfd..000000000 --- a/fluent-bit/lib/monkey/plugins/dirlisting/conf/themes/bootstrap/header.theme +++ /dev/null @@ -1,27 +0,0 @@ -<html> - <head> - <meta http-equiv="content-type" content="text/html; charset=UTF-8"> - <title>Index of %_html_title_%</title> - <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"> - <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css"> - <link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet"> - </head> - <body> - <div class="container"> - <h1>Index of %_html_title_%</h1> - <div class="table-responsive"> - <table class="table table-hover table-bordered"> - <thead> - <tr> - <th> - Name - </th> - <th> - Last time modified - </th> - <th> - Size - </th> - </tr> - </thead> - <tbody> diff --git a/fluent-bit/lib/monkey/plugins/dirlisting/conf/themes/guineo/entry.theme b/fluent-bit/lib/monkey/plugins/dirlisting/conf/themes/guineo/entry.theme deleted file mode 100644 index af00e250c..000000000 --- a/fluent-bit/lib/monkey/plugins/dirlisting/conf/themes/guineo/entry.theme +++ /dev/null @@ -1,14 +0,0 @@ -<TR> -<TD class="row"> - <A title='%_target_title_%' href='%_target_url_%'> - %_target_name_% - </A> -</TD> -<TD class="row"> - %_target_time_% -</TD> -<TD class="row"> - %_target_size_% - %_theme_path_% -</TD> -</TR> diff --git a/fluent-bit/lib/monkey/plugins/dirlisting/conf/themes/guineo/footer.theme b/fluent-bit/lib/monkey/plugins/dirlisting/conf/themes/guineo/footer.theme deleted file mode 100644 index c785ba97f..000000000 --- a/fluent-bit/lib/monkey/plugins/dirlisting/conf/themes/guineo/footer.theme +++ /dev/null @@ -1,7 +0,0 @@ -</TABLE> - -</TD> -</TR> -</TABLE> -</BODY></HTML> - diff --git a/fluent-bit/lib/monkey/plugins/dirlisting/conf/themes/guineo/header.theme b/fluent-bit/lib/monkey/plugins/dirlisting/conf/themes/guineo/header.theme deleted file mode 100644 index 6a11a458f..000000000 --- a/fluent-bit/lib/monkey/plugins/dirlisting/conf/themes/guineo/header.theme +++ /dev/null @@ -1,58 +0,0 @@ -<HTML> - <HEAD> - <META http-equiv="content-type" content="text/html; charset=UTF-8"> - <STYLE type="text/css"> - H1.header { - text-align: center; - color: #4a77a0; - font-size: 12pt; - font-weight: bold; - } - .row { - color: #6c95bc; - font-size: 10pt; - background-color: #ffffff; - padding-left: 0.4em; - } - .title {color: #617691; font-size: 10pt; font-weight: bold;} - - a:link { - color: #475f7e; - } - a:visited { - color: #ac7a2a; - } - a:hover { - color: #475f7e; - background-color: #dbdbdb; - text-decoration: none; - } - a:active { - color: #333333; - } - </STYLE> - - <TITLE>Index of %_html_title_%</TITLE> - </HEAD> -<BODY> - -<CENTER> -<IMG src="/imgs/monkey_logo.png"> -<BR> -<h1 class="header">Index of %_html_title_%</h1> -<TABLE cellpadding="0" cellspacing="0" border="0" bgcolor="#000000" width="50%"> -<TR> -<TD> - -<TABLE cellpadding="2" cellspacing="1" border="0" bgcolor="#e7e7e7" width="100%"> -<TR bgcolor="#ececec"> - <TD class="title"> - Name - </TD> - <TD class="title"> - Last time modified - </TD> - <TD class="title"> - Size - </TD> -</TR> diff --git a/fluent-bit/lib/monkey/plugins/dirlisting/dirlisting.c b/fluent-bit/lib/monkey/plugins/dirlisting/dirlisting.c deleted file mode 100644 index 1ffd3fac4..000000000 --- a/fluent-bit/lib/monkey/plugins/dirlisting/dirlisting.c +++ /dev/null @@ -1,949 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Some history about this plugin - * ------------------------------ - * 2008 - Rewrite module, suport dynamic themes by Eduardo Silva - * 2008 - Felipe Astroza (max) provided the mk_dirhtml_human_readable_size_func() - * 2007 - Add struct client_request support by Eduardo - * 2002 - Original version written by Daniel R. Ome - */ - -#include <monkey/mk_api.h> -#include <monkey/mk_stream.h> -#include "dirlisting.h" - -#include <time.h> -#include <dirent.h> -#include <sys/stat.h> - -const mk_ptr_t mk_dirhtml_default_mime = mk_ptr_init(MK_DIRHTML_DEFAULT_MIME); -const mk_ptr_t mk_dir_iov_dash = mk_ptr_init("-"); -const mk_ptr_t mk_dir_iov_none = mk_ptr_init(""); -const mk_ptr_t mk_dir_iov_slash = mk_ptr_init("/"); - -void mk_dirhtml_cb_body_rows(struct mk_stream_input *in); - -/* Function wrote by Max (Felipe Astroza), thanks! */ -static char *mk_dirhtml_human_readable_size(char *buf, size_t size, int len) -{ - unsigned long u = 1024, i; - static const char *__units[] = { - "b", "K", "M", "G", - "T", "P", "E", "Z", "Y", NULL - }; - - for (i = 0; __units[i] != NULL; i++) { - if ((size / u) == 0) { - break; - } - u *= 1024; - } - if (!i) { - snprintf(buf, size, "%lu%s", (long unsigned int) len, __units[0]); - } - else { - float fsize = (float) ((double) len / (u / 1024)); - snprintf(buf, size, "%.1f%s", fsize, __units[i]); - } - - return buf; -} - -static struct mk_f_list *mk_dirhtml_create_element(char *file, - unsigned char type, - char *full_path, - unsigned long *list_len) -{ - int n; - struct tm *st_time; - struct mk_f_list *entry; - - entry = mk_api->mem_alloc_z(sizeof(struct mk_f_list)); - - if (mk_api->file_get_info(full_path, &entry->info, MK_FILE_READ) != 0) { - mk_api->mem_free(entry); - return NULL; - } - - strcpy(entry->name, file); - entry->type = type; - - st_time = localtime((time_t *) & entry->info.last_modification); - n = strftime(entry->ft_modif, MK_DIRHTML_FMOD_LEN, "%d-%b-%G %H:%M", st_time); - if (n == 0) { - mk_mem_free(entry); - return NULL; - } - - if (type != DT_DIR) { - mk_dirhtml_human_readable_size(entry->size, - sizeof(entry->size), - entry->info.size); - } - else { - entry->size[0] = '-'; - entry->size[1] = '\0'; - } - - *list_len = *list_len + 1; - - return entry; -} - -static struct mk_list *mk_dirhtml_create_list(DIR * dir, char *path, - unsigned long *list_len) -{ - char full_path[PATH_MAX]; - struct mk_list *list; - struct dirent *ent; - struct mk_f_list *entry = 0; - - list = mk_api->mem_alloc(sizeof(struct mk_list)); - mk_list_init(list); - - while ((ent = readdir(dir)) != NULL) { - if ((ent->d_name[0] == '.') && (strcmp(ent->d_name, "..") != 0)) - continue; - - /* Look just for files and dirs */ - if (ent->d_type != DT_REG && ent->d_type != DT_DIR - && ent->d_type != DT_LNK && ent->d_type != DT_UNKNOWN) { - continue; - } - - snprintf(full_path, PATH_MAX, "%s%s", path, ent->d_name); - entry = mk_dirhtml_create_element(ent->d_name, - ent->d_type, full_path, list_len); - if (!entry) { - continue; - } - - mk_list_add(&entry->_head, list); - } - - return list; -} - -/* Read dirhtml config and themes */ -int mk_dirhtml_conf(char *confdir) -{ - int ret = 0; - unsigned long len; - char *conf_file = NULL; - - mk_api->str_build(&conf_file, &len, "%s", confdir); - - /* Read configuration */ - ret = mk_dirhtml_read_config(conf_file); - if (ret < 0) { - mk_mem_free(conf_file); - return -1; - } - - /* - * This function will load the default theme setted in dirhtml_conf struct - */ - mk_mem_free(conf_file); - return mk_dirhtml_theme_load(); -} - -/* - * Read the main configuration file for dirhtml: dirhtml.conf, - * it will alloc the dirhtml_conf struct -*/ -int mk_dirhtml_read_config(char *path) -{ - unsigned long len; - char *default_file = NULL; - struct mk_rconf *conf; - struct mk_rconf_section *section; - struct file_info finfo; - - mk_api->str_build(&default_file, &len, "%sdirhtml.conf", path); - conf = mk_api->config_open(default_file); - if (!conf) { - return -1; - } - - section = mk_api->config_section_get(conf, "DIRLISTING"); - if (!section) { - mk_err_ex(mk_api, "Could not find DIRLISTING tag in configuration file"); - exit(EXIT_FAILURE); - } - - /* alloc dirhtml config struct */ - dirhtml_conf = mk_api->mem_alloc(sizeof(struct dirhtml_config)); - dirhtml_conf->theme = mk_api->config_section_get_key(section, "Theme", - MK_RCONF_STR); - dirhtml_conf->theme_path = NULL; - - mk_api->str_build(&dirhtml_conf->theme_path, &len, - "%sthemes/%s/", path, dirhtml_conf->theme); - mk_api->mem_free(default_file); - - if (mk_api->file_get_info(dirhtml_conf->theme_path, - &finfo, MK_FILE_READ) != 0) { - mk_warn_ex(mk_api, "Dirlisting: cannot load theme from '%s'", dirhtml_conf->theme_path); - mk_warn_ex(mk_api, "Dirlisting: unloading plugin"); - return -1; - } - - mk_api->config_free(conf); - return 0; -} - -int mk_dirhtml_theme_load() -{ - /* Data */ - char *header, *entry, *footer; - - /* Load theme files */ - header = mk_dirhtml_load_file(MK_DIRHTML_FILE_HEADER); - entry = mk_dirhtml_load_file(MK_DIRHTML_FILE_ENTRY); - footer = mk_dirhtml_load_file(MK_DIRHTML_FILE_FOOTER); - - if (!header || !entry || !footer) { - mk_api->mem_free(header); - mk_api->mem_free(entry); - mk_api->mem_free(footer); - return -1; - } - - /* Parse themes */ - mk_dirhtml_tpl_header = mk_dirhtml_template_create(header); - mk_dirhtml_tpl_entry = mk_dirhtml_template_create(entry); - mk_dirhtml_tpl_footer = mk_dirhtml_template_create(footer); - -#ifdef DEBUG_THEME - /* Debug data */ - mk_dirhtml_theme_debug(&mk_dirhtml_tpl_header); - mk_dirhtml_theme_debug(&mk_dirhtml_tpl_entry); - mk_dirhtml_theme_debug(&mk_dirhtml_tpl_footer); - -#endif - mk_api->mem_free(header); - mk_api->mem_free(entry); - mk_api->mem_free(footer); - - return 0; -} - -#ifdef DEBUG_THEME -int mk_dirhtml_theme_debug(struct dirhtml_template **st_tpl) -{ - int i = 0; - struct dirhtml_template *aux; - - aux = *st_tpl; - - printf("\n** DEBUG_THEME **"); - fflush(stdout); - - while (aux) { - printf("\n%i) len=%i, tag_id=%i", i, aux->len, aux->tag_id); - if (aux->tag_id >= 0) { - printf(" (%s) ", aux->tags[aux->tag_id]); - } - fflush(stdout); - aux = aux->next; - i++; - } - return 0; -} -#endif - -/* Search which tag exists first in content : - * ex: %_html_title_% - */ -static int mk_dirhtml_theme_match_tag(char *content, char *tpl[]) -{ - int i, len, match; - - for (i = 0; tpl[i]; i++) { - len = strlen(tpl[i]); - match = (int) mk_api->str_search_n(content, tpl[i], MK_STR_INSENSITIVE, len); - if (match >= 0) { - return i; - } - } - - return -1; -} - -struct dirhtml_template *mk_dirhtml_template_create(char *content) -{ - int i = 0, cont_len; - int pos, last = 0; /* 0=search init, 1=search end */ - int n_tags = 0, tpl_idx = 0; - - char *_buf; - int _len; - - /* Global keys */ - char **_tpl = 0; - - /* Template to return */ - struct dirhtml_template *st_tpl = 0; - - cont_len = strlen(content); - if (cont_len <= 0) { - return NULL; - } - - /* Parsing content */ - while (i < cont_len) { - pos = (int) mk_api->str_search(content + i, - MK_DIRHTML_TAG_INIT, MK_STR_INSENSITIVE); - - if (pos < 0) { - break; - } - - /* Checking global tag, if it's not found, proceed with - * 'entry tags' - */ - _tpl = (char **) _tags_global; - tpl_idx = mk_dirhtml_theme_match_tag(content + i + pos, _tpl); - - /* if global template do not match, use the entry tags */ - if (tpl_idx < 0) { - _tpl = (char **) _tags_entry; - tpl_idx = mk_dirhtml_theme_match_tag(content + i + pos, _tpl); - } - - /* if tag found is known, we add them to our list */ - if (tpl_idx >= 0) { - - _buf = mk_api->str_copy_substr(content, i, i + pos); - _len = strlen(_buf); - - /* Dummy if/else to create or pass a created st_tpl */ - if (!st_tpl) { - st_tpl = mk_dirhtml_template_list_add(NULL, - _buf, _len, _tpl, -1); - } - else { - mk_dirhtml_template_list_add(&st_tpl, _buf, _len, _tpl, -1); - } - i += (pos + strlen(_tpl[tpl_idx])); - - /* This means that a value need to be replaced */ - mk_dirhtml_template_list_add(&st_tpl, NULL, -1, _tpl, tpl_idx); - n_tags++; - } - else { - i++; - } - } - - if (last < cont_len) { - _buf = mk_api->str_copy_substr(content, i, cont_len); - _len = strlen(_buf); - - if (n_tags <= 0) { - st_tpl = mk_dirhtml_template_list_add(NULL, _buf, _len, _tpl, -1); - } - else { - mk_dirhtml_template_list_add(&st_tpl, _buf, _len, _tpl, -1); - } - } - - return st_tpl; -} - -struct dirhtml_template *mk_dirhtml_template_list_add(struct dirhtml_template **header, - char *buf, int len, char **tpl, - int tag_id) -{ - struct dirhtml_template *node, *aux; - - node = mk_api->mem_alloc_z(sizeof(struct dirhtml_template)); - if (!node) { - return NULL; - } - - node->buf = buf; - node->len = len; - node->tag_id = tag_id; - node->tags = tpl; - node->next = NULL; - - if (!header || !(*header)) { - return (struct dirhtml_template *) node; - } - - aux = *header; - while ((*aux).next != NULL) { - aux = (*aux).next; - } - - (*aux).next = node; - return (struct dirhtml_template *) node; -} - -static int mk_dirhtml_template_len(struct dirhtml_template *tpl) -{ - int len = 0; - struct dirhtml_template *aux; - - aux = tpl; - while (aux) { - len++; - aux = aux->next; - } - - return len; -} - -static struct mk_iov *mk_dirhtml_theme_compose(struct dirhtml_template *template, - struct mk_list *list) -{ - /* - * template = struct { char buf ; int len, int tag } - * values = struct {int tag, char *value, struct *next} - */ - struct mk_iov *iov; - struct dirhtml_template *tpl = template; - struct dirhtml_value *val; - struct mk_list *head; - - int tpl_len; - - tpl_len = mk_dirhtml_template_len(template); - - /* we duplicate the lenght in case we get separators */ - iov = mk_api->iov_create(1 + tpl_len * 2, 1); - tpl = template; - - while (tpl) { - /* check for dynamic value */ - if (!tpl->buf && tpl->tag_id >= 0) { - mk_list_foreach(head, list) { - val = mk_list_entry(head, struct dirhtml_value, _head); - if (val->tags == tpl->tags && val->tag_id == tpl->tag_id) { - mk_api->iov_add(iov, - val->value, val->len, - MK_FALSE); - mk_api->iov_add(iov, - val->sep.data, val->sep.len, - MK_FALSE); - break; - } - } - } - /* static */ - else { - mk_api->iov_add(iov, - tpl->buf, tpl->len, - MK_FALSE); - } - tpl = tpl->next; - } - - return iov; -} - -struct dirhtml_value *mk_dirhtml_tag_assign(struct mk_list *list, - int tag_id, mk_ptr_t sep, - char *value, char **tags) -{ - struct dirhtml_value *aux = NULL; - - aux = mk_api->mem_alloc(sizeof(struct dirhtml_value)); - if (!aux) { - return NULL; - } - - aux->tag_id = tag_id; - aux->value = value; - aux->sep = sep; - aux->tags = tags; - - if (value) { - aux->len = strlen(value); - } - else { - aux->len = -1; - } - - mk_list_add(&aux->_head, list); - return (struct dirhtml_value *) aux; -} - -static void mk_dirhtml_tag_free_list(struct mk_list *list) -{ - struct mk_list *head; - struct mk_list *tmp; - struct dirhtml_value *target; - - mk_list_foreach_safe(head, tmp, list) { - target = mk_list_entry(head, struct dirhtml_value, _head); - mk_list_del(&target->_head); - mk_api->mem_free(target); - } -} - -char *mk_dirhtml_load_file(char *filename) -{ - char *tmp = 0, *data = 0; - unsigned long len; - - mk_api->str_build(&tmp, &len, "%s%s", dirhtml_conf->theme_path, filename); - - if (!tmp) { - return NULL; - } - - data = mk_api->file_to_buffer(tmp); - mk_api->mem_free(tmp); - - if (!data) { - return NULL; - } - - return (char *) data; -} - -static int mk_dirhtml_entry_cmp(const void *a, const void *b) -{ - struct mk_f_list *const *f_a = a; - struct mk_f_list *const *f_b = b; - - return strcasecmp((*f_a)->name, (*f_b)->name); -} - -static void mk_dirhtml_free_list(struct mk_dirhtml_request *request) -{ - struct mk_list *tmp; - struct mk_list *head; - struct mk_f_list *entry; - - mk_list_foreach_safe(head, tmp, request->file_list) { - entry = mk_list_entry(head, struct mk_f_list, _head); - mk_list_del(&entry->_head); - mk_api->mem_free(entry); - } - - mk_api->mem_free(request->file_list); - mk_api->mem_free(request->toc); -} - -static inline struct mk_iov *enqueue_row(int i, struct mk_dirhtml_request *request) -{ - mk_ptr_t sep; - struct mk_list list; - struct mk_iov *iov_entry; - - /* %_target_title_% */ - if (request->toc[i]->type == DT_DIR) { - sep = mk_dir_iov_slash; - } - else { - sep = mk_dir_iov_none; - } - - mk_list_init(&list); - - /* target title */ - mk_dirhtml_tag_assign(&list, 0, sep, - request->toc[i]->name, - (char **) _tags_entry); - - /* target url */ - mk_dirhtml_tag_assign(&list, 1, sep, - request->toc[i]->name, (char **) _tags_entry); - - /* target name */ - mk_dirhtml_tag_assign(&list, 2, sep, - request->toc[i]->name, (char **) _tags_entry); - - /* target modification time */ - mk_dirhtml_tag_assign(&list, 3, mk_dir_iov_none, - request->toc[i]->ft_modif, (char **) _tags_entry); - - /* target size */ - mk_dirhtml_tag_assign(&list, 4, mk_dir_iov_none, - request->toc[i]->size, (char **) _tags_entry); - - iov_entry = mk_dirhtml_theme_compose(mk_dirhtml_tpl_entry, &list); - - /* free entry list */ - mk_dirhtml_tag_free_list(&list); - return iov_entry; -} - -/* Release all resources for a given Request context */ -void mk_dirhtml_cleanup(struct mk_dirhtml_request *req) -{ - PLUGIN_TRACE("release resources"); - - if (req->iov_header) { - mk_api->iov_free(req->iov_header); - req->iov_header = NULL; - } - if (req->iov_entry) { - mk_api->iov_free(req->iov_entry); - req->iov_entry = NULL; - } - if (req->iov_footer) { - mk_api->iov_free(req->iov_footer); - req->iov_footer = NULL; - } - mk_dirhtml_free_list(req); - closedir(req->dir); - - req->sr->handler_data = NULL; - mk_api->mem_free(req); - req = NULL; -} - -void mk_dirhtml_cb_complete(struct mk_stream_input *in) -{ - struct mk_stream *stream; - struct mk_dirhtml_request *req; - - stream = in->stream; - req = stream->context; - if (req) { - mk_dirhtml_cleanup(req); - } -} - -void mk_dirhtml_cb_error(struct mk_stream *stream, int status) -{ -#ifndef TRACE - (void) status; -#endif - struct mk_dirhtml_request *req = stream->context; - - PLUGIN_TRACE("exception: %i", status); - - if (req) { - mk_dirhtml_cleanup(req); - } -} - -void mk_dirhtml_cb_chunk_body_rows(struct mk_stream_input *in, long bytes) -{ - (void) bytes; - - mk_dirhtml_cb_body_rows(in); -} - -void mk_dirhtml_cb_body_rows(struct mk_stream_input *in) -{ - int len; - char tmp[16]; - struct mk_stream *stream = in->stream; - struct mk_dirhtml_request *req = stream->context; - void (*cb_ok)(struct mk_stream_input *) = NULL; - - if (req->iov_entry) { - mk_api->iov_free(req->iov_entry); - req->iov_entry = NULL; - } - - if (req->toc_idx >= req->toc_len) { - if (req->chunked) { - len = snprintf(tmp, sizeof(tmp), "%x\r\n", - (int) req->iov_footer->total_len); - mk_stream_in_raw(req->stream, - NULL, - tmp, len, - NULL, NULL); - cb_ok = NULL; - } - else { - cb_ok = mk_dirhtml_cb_complete; - } - - mk_stream_in_iov(req->stream, - NULL, - req->iov_footer, - NULL, NULL); - if (req->chunked) { - mk_stream_in_raw(req->stream, - NULL, - "\r\n0\r\n\r\n", 7, - NULL, mk_dirhtml_cb_complete); - } - - return; - } - - req->iov_entry = enqueue_row(req->toc_idx, req); - if (req->chunked) { - len = snprintf(tmp, sizeof(tmp), "%x\r\n", - (int) req->iov_entry->total_len); - mk_stream_in_raw(req->stream, - NULL, - tmp, len, - NULL, NULL); - cb_ok = NULL; - } - else { - cb_ok = mk_dirhtml_cb_body_rows; - } - - mk_stream_in_iov(req->stream, - NULL, - req->iov_entry, - NULL, cb_ok); - - if (req->chunked) { - mk_stream_in_raw(req->stream, - NULL, - "\r\n", 2, - mk_dirhtml_cb_chunk_body_rows, NULL); - } - req->toc_idx++; -} - -/* - * The HTTP Headers were sent, now start registering the - * rows for each directory entry. - */ -void cb_header_finish(struct mk_stream_input *in) -{ - struct mk_stream *stream = in->stream; - struct mk_dirhtml_request *req; - - req = stream->context; - if (req->iov_header) { - mk_api->iov_free(req->iov_header); - req->iov_header = NULL; - } - mk_dirhtml_cb_body_rows(in); -} - -static int mk_dirhtml_init(struct mk_plugin *plugin, - struct mk_http_session *cs, struct mk_http_request *sr) -{ - DIR *dir; - int len; - char tmp[16]; - unsigned int i = 0; - struct mk_list *head; - struct mk_list list; - struct mk_f_list *entry; - struct mk_dirhtml_request *request; - struct mk_stream *stream; - - if (!(dir = opendir(sr->real_path.data))) { - return -1; - } - - /* Create the main context */ - request = mk_api->mem_alloc(sizeof(struct mk_dirhtml_request)); - if (!request) { - closedir(dir); - return -1; - } - - stream = mk_stream_set(NULL, cs->channel, request, - NULL, NULL, mk_dirhtml_cb_error); - if (!stream) { - closedir(dir); - free(request); - return -1; - } - - request->stream = stream; - request->state = MK_DIRHTML_STATE_HTTP_HEADER; - request->dir = dir; - request->toc_idx = 0; - request->cs = cs; - request->sr = sr; - request->toc_len = 0; - request->chunked = MK_FALSE; - request->iov_header = NULL; - request->iov_entry = NULL; - request->iov_footer = NULL; - - sr->handler_data = request; - - request->file_list = mk_dirhtml_create_list(dir, sr->real_path.data, - &request->toc_len); - - /* Building headers */ - mk_api->header_set_http_status(sr, MK_HTTP_OK); - sr->headers.cgi = SH_CGI; - sr->headers.breakline = MK_HEADER_BREAKLINE; - sr->headers.content_type = mk_dirhtml_default_mime; - sr->headers.content_length = -1; - - if (sr->protocol >= MK_HTTP_PROTOCOL_11) { - sr->headers.transfer_encoding = MK_HEADER_TE_TYPE_CHUNKED; - request->chunked = MK_TRUE; - } - - /* - * Creating response template - */ - - mk_list_init(&list); - - /* Set %_html_title_% */ - mk_dirhtml_tag_assign(&list, 0, mk_dir_iov_none, - sr->uri_processed.data, - (char **) _tags_global); - - /* Set %_theme_path_% */ - mk_dirhtml_tag_assign(&list, 1, mk_dir_iov_none, - dirhtml_conf->theme_path, (char **) _tags_global); - - /* HTML Header */ - request->iov_header = mk_dirhtml_theme_compose(mk_dirhtml_tpl_header, - &list); - - /* HTML Footer */ - request->iov_footer = mk_dirhtml_theme_compose(mk_dirhtml_tpl_footer, - &list); - mk_dirhtml_tag_free_list(&list); - - /* Creating table of contents and sorting */ - request->toc = mk_api->mem_alloc(sizeof(struct mk_f_list *) * request->toc_len); - - i = 0; - mk_list_foreach(head, request->file_list) { - entry = mk_list_entry(head, struct mk_f_list, _head); - request->toc[i] = entry; - i++; - } - - qsort(request->toc, - request->toc_len, - sizeof(*request->toc), - mk_dirhtml_entry_cmp); - - /* Prepare HTTP response headers */ - mk_api->header_prepare(plugin, cs, sr); - - if (request->chunked) { - len = snprintf(tmp, sizeof(tmp), "%x\r\n", - (int) request->iov_header->total_len); - mk_stream_in_raw(request->stream, - NULL, - tmp, len, - NULL, mk_dirhtml_cb_complete); - } - - mk_stream_in_iov(request->stream, - NULL, - request->iov_header, - NULL, cb_header_finish); - - if (request->chunked) { - mk_stream_in_raw(request->stream, - NULL, - "\r\n", 2, - NULL, NULL); - } - return 0; -} - -int mk_dirlisting_plugin_init(struct mk_plugin *plugin, char *confdir) -{ - mk_api = plugin->api; - - return mk_dirhtml_conf(confdir); -} - -int mk_dirlisting_plugin_exit(struct mk_plugin *plugin) -{ - (void) plugin; - - mk_api->mem_free(dirhtml_conf->theme); - mk_api->mem_free(dirhtml_conf->theme_path); - mk_api->mem_free(dirhtml_conf); - - return 0; -} - -int mk_dirlisting_stage30(struct mk_plugin *plugin, - struct mk_http_session *cs, - struct mk_http_request *sr, - int n_param, - struct mk_list *params) -{ - (void) plugin; - (void) n_param; - (void) params; - - /* validate file_info */ - if (sr->file_info.size == 0) { - return MK_PLUGIN_RET_NOT_ME; - } - - /* This plugin just handle directories */ - if (sr->file_info.is_directory == MK_FALSE) { - return MK_PLUGIN_RET_NOT_ME; - } - - PLUGIN_TRACE("Dirlisting attending socket %i", cs->socket); - if (mk_dirhtml_init(plugin, cs, sr)) { - /* - * If we failed here, we cannot return RET_END - that causes a mk_bug. - * dirhtml_init only fails if opendir fails. Usually we're at full - * capacity then and can't open new files. - */ - return MK_PLUGIN_RET_CLOSE_CONX; - } - - return MK_PLUGIN_RET_END; -} - -int mk_dirlisting_stage30_hangup(struct mk_plugin *plugin, - struct mk_http_session *cs, - struct mk_http_request *sr) -{ - (void) cs; - (void) plugin; - - if (sr->handler_data) { - mk_dirhtml_cleanup(sr->handler_data); - } - return 0; -} - -struct mk_plugin_stage mk_plugin_stage_dirlisting = { - .stage30 = &mk_dirlisting_stage30, - .stage30_hangup = &mk_dirlisting_stage30_hangup -}; - -struct mk_plugin mk_plugin_dirlisting = { - /* Identification */ - .shortname = "dirlisting", - .name = "Directory Listing", - .version = MK_VERSION_STR, - .hooks = MK_PLUGIN_STAGE, - - /* Init / Exit */ - .init_plugin = mk_dirlisting_plugin_init, - .exit_plugin = mk_dirlisting_plugin_exit, - - /* Init Levels */ - .master_init = NULL, - .worker_init = NULL, - - /* Type */ - .stage = &mk_plugin_stage_dirlisting -}; diff --git a/fluent-bit/lib/monkey/plugins/dirlisting/dirlisting.h b/fluent-bit/lib/monkey/plugins/dirlisting/dirlisting.h deleted file mode 100644 index 678a4887b..000000000 --- a/fluent-bit/lib/monkey/plugins/dirlisting/dirlisting.h +++ /dev/null @@ -1,181 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* dir_html.c */ -#ifndef MK_DIRHTML_H -#define MK_DIRHTML_H - -#include <dirent.h> -#include <limits.h> - -#define MK_DIRHTML_URL "/_mktheme" -#define MK_DIRHTML_DEFAULT_MIME "Content-Type: text/html\r\n" - -/* For every directory requested, don't send more than - * this limit of entries. - */ -#define MK_DIRHTML_BUFFER_LIMIT 30 -#define MK_DIRHTML_BUFFER_GROW 5 - -#define MK_HEADER_CHUNKED "Transfer-Encoding: Chunked\r\n\r\n" -#define MK_DIRHTML_FMOD_LEN 24 - -/* Theme files */ -#define MK_DIRHTML_FILE_HEADER "header.theme" -#define MK_DIRHTML_FILE_ENTRY "entry.theme" -#define MK_DIRHTML_FILE_FOOTER "footer.theme" - -#define MK_DIRHTML_TAG_INIT "%_" -#define MK_DIRHTML_TAG_END "_%" -#define MK_DIRHTML_SIZE_DIR "-" - -/* Stream state */ -#define MK_DIRHTML_STATE_HTTP_HEADER 0 -#define MK_DIRHTML_STATE_TPL_HEADER 1 -#define MK_DIRHTML_STATE_BODY 2 -#define MK_DIRHTML_STATE_FOOTER 3 - -char *_tags_global[] = { "%_html_title_%", - "%_theme_path_%", - NULL -}; - -char *_tags_entry[] = { "%_target_title_%", - "%_target_url_%", - "%_target_name_%", - "%_target_time_%", - "%_target_size_%", - NULL -}; - -struct plugin_api *mk_api; - -struct mk_f_list -{ - char ft_modif[MK_DIRHTML_FMOD_LEN]; - struct file_info info; - char name[NAME_MAX + 1]; /* The name can be up to NAME_MAX long; include NULL. */ - char size[16]; - unsigned char type; - - struct mk_list _head; -}; - -/* Main configuration of dirhtml module */ -struct dirhtml_config -{ - char *theme; - char *theme_path; -}; - -/* Represent a request context */ -struct mk_dirhtml_request -{ - /* State */ - int state; - int chunked; - - /* Target directory */ - DIR *dir; - - /* Table of Content */ - unsigned int toc_idx; - unsigned long toc_len; - struct mk_f_list **toc; - struct mk_list *file_list; - - /* Stream handler */ - struct mk_stream *stream; - - /* Reference IOV stuff */ - struct mk_iov *iov_header; - struct mk_iov *iov_entry; - struct mk_iov *iov_footer; - - /* Session data */ - struct mk_http_session *cs; - struct mk_http_request *sr; -}; - - -extern const mk_ptr_t mk_dirhtml_default_mime; -extern const mk_ptr_t mk_iov_dash; - -/* Global config */ -struct dirhtml_config *dirhtml_conf; - -/* Used to keep splitted content of every template */ -struct dirhtml_template -{ - char *buf; - int tag_id; - int len; - struct dirhtml_template *next; - char **tags; /* array of theme tags: [%_xaa__%, %_xyz_%] */ -}; - -/* Templates for header, entries and footer */ -struct dirhtml_template *mk_dirhtml_tpl_header; -struct dirhtml_template *mk_dirhtml_tpl_entry; -struct dirhtml_template *mk_dirhtml_tpl_footer; - -struct dirhtml_value -{ - int tag_id; - mk_ptr_t sep; /* separator code after value */ - - /* string data */ - int len; - char *value; - - /* next node */ - struct mk_list _head; - - char **tags; /* array of tags which values correspond */ -}; - -struct dirhtml_value *mk_dirhtml_value_global; - -/* Configuration struct */ -struct mk_config *conf; - -char *check_string(char *str); -char *read_header_footer_file(char *file_path); - -int mk_dirhtml_conf(); -char *mk_dirhtml_load_file(char *filename); - -struct dirhtml_template *mk_dirhtml_template_create(char *content); - -struct dirhtml_template - *mk_dirhtml_template_list_add(struct dirhtml_template **header, - char *buf, int len, char **tpl, int tag); - -int mk_dirhtml_read_config(char *path); -int mk_dirhtml_theme_load(); -int mk_dirhtml_theme_debug(struct dirhtml_template **st_tpl); - -struct dirhtml_value *mk_dirhtml_tag_assign(struct mk_list *list, - int tag_id, mk_ptr_t sep, - char *value, char **tags); - -struct f_list *get_dir_content(struct mk_http_request *sr, char *path); - - -#endif diff --git a/fluent-bit/lib/monkey/plugins/fastcgi/CMakeLists.txt b/fluent-bit/lib/monkey/plugins/fastcgi/CMakeLists.txt deleted file mode 100644 index 46056eead..000000000 --- a/fluent-bit/lib/monkey/plugins/fastcgi/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -set(src - fastcgi.c - fcgi_handler.c - ) - -MONKEY_PLUGIN(fastcgi "${src}") -add_subdirectory(conf) diff --git a/fluent-bit/lib/monkey/plugins/fastcgi/conf/CMakeLists.txt b/fluent-bit/lib/monkey/plugins/fastcgi/conf/CMakeLists.txt deleted file mode 100644 index 0623bf68b..000000000 --- a/fluent-bit/lib/monkey/plugins/fastcgi/conf/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -set(conf_dir "${MK_PATH_CONF}/plugins/fastcgi/") - -install(DIRECTORY DESTINATION ${conf_dir}) - -if(BUILD_LOCAL) - file(COPY fastcgi.conf DESTINATION ${conf_dir}) -else() - install(FILES fastcgi.conf DESTINATION ${conf_dir}) -endif() diff --git a/fluent-bit/lib/monkey/plugins/fastcgi/conf/fastcgi.conf b/fluent-bit/lib/monkey/plugins/fastcgi/conf/fastcgi.conf deleted file mode 100644 index c5651c748..000000000 --- a/fluent-bit/lib/monkey/plugins/fastcgi/conf/fastcgi.conf +++ /dev/null @@ -1,16 +0,0 @@ -# FastCGI -# ======= -# To enable this plugin you'll need at least one [FASTCGI_SERVER]. -# -# This configuration handles php scripts using php5-fpm running on -# localhost or over the network. - -[FASTCGI_SERVER] - # Each server must have a unique name, this is mandatory. - ServerName php5-fpm1 - - # Depending on your version of php5-fpm, one of these should be - # enabled. - # - # ServerAddr 127.0.0.1:9000 - ServerPath /var/run/php5-fpm.sock diff --git a/fluent-bit/lib/monkey/plugins/fastcgi/fastcgi.c b/fluent-bit/lib/monkey/plugins/fastcgi/fastcgi.c deleted file mode 100644 index 1c0e716a2..000000000 --- a/fluent-bit/lib/monkey/plugins/fastcgi/fastcgi.c +++ /dev/null @@ -1,233 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <monkey/mk_api.h> - -#include "fastcgi.h" -#include "fcgi_handler.h" - -static int mk_fastcgi_config(char *path) -{ - int ret; - int sep; - char *file = NULL; - char *cnf_srv_name = NULL; - char *cnf_srv_addr = NULL; - char *cnf_srv_port = NULL; - char *cnf_srv_path = NULL; - unsigned long len; - struct file_info finfo; - struct mk_rconf *conf; - struct mk_rconf_section *section; - - mk_api->str_build(&file, &len, "%sfastcgi.conf", path); - conf = mk_api->config_open(file); - if (!conf) { - return -1; - } - - section = mk_api->config_section_get(conf, "FASTCGI_SERVER"); - if (!section) { - return -1; - } - - /* Get section values */ - cnf_srv_name = mk_api->config_section_get_key(section, - "ServerName", - MK_RCONF_STR); - cnf_srv_addr = mk_api->config_section_get_key(section, - "ServerAddr", - MK_RCONF_STR); - cnf_srv_path = mk_api->config_section_get_key(section, - "ServerPath", - MK_RCONF_STR); - - /* Validations */ - if (!cnf_srv_name) { - mk_warn("[fastcgi] Invalid ServerName in configuration."); - return -1; - } - - /* Split the address, try to lookup the TCP port */ - if (cnf_srv_addr) { - sep = mk_api->str_char_search(cnf_srv_addr, ':', strlen(cnf_srv_addr)); - if (sep <= 0) { - mk_warn("[fastcgi] Missing TCP port con ServerAddress key"); - return -1; - } - - cnf_srv_port = mk_api->str_dup(cnf_srv_addr + sep + 1); - cnf_srv_addr[sep] = '\0'; - } - - /* Just one mode can exist (for now) */ - if (cnf_srv_path && cnf_srv_addr) { - mk_warn("[fastcgi] Use ServerAddr or ServerPath, not both"); - return -1; - } - - /* Unix socket path */ - if (cnf_srv_path) { - ret = mk_api->file_get_info(cnf_srv_path, &finfo, MK_FILE_READ); - if (ret == -1) { - mk_warn("[fastcgi] Cannot open unix socket: %s", cnf_srv_path); - return -1; - } - } - - /* Set the global configuration */ - fcgi_conf.server_name = cnf_srv_name; - fcgi_conf.server_addr = cnf_srv_addr; - fcgi_conf.server_port = cnf_srv_port; - fcgi_conf.server_path = cnf_srv_path; - - return 0; -} - - -/* Entry point for thread/co-routine */ -static void mk_fastcgi_stage30_thread(struct mk_plugin *plugin, - struct mk_http_session *cs, - struct mk_http_request *sr, - int n_params, - struct mk_list *params) -{ - struct fcgi_handler *handler; - (void) plugin; - (void) n_params; - (void) params; - - printf("entering thread\n"); - handler = fcgi_handler_new(cs, sr); - if (!handler) { - fprintf(stderr, "Could not create handler"); - } -} - -/* Callback handler */ -int mk_fastcgi_stage30(struct mk_plugin *plugin, - struct mk_http_session *cs, - struct mk_http_request *sr, - int n_params, - struct mk_list *params) -{ - (void) n_params; - (void) params; - struct fcgi_handler *handler; - - /* - * This plugin uses the Monkey Thread model (co-routines), for hence - * upon return MK_PLUGIN_RET_CONTINUE, Monkey core will create a - * new thread (co-routine) and defer the control to the stage30_thread - * callback function (mk_fastcgi_stage30_thread). - * - * We don't do any validation, so we are OK with MK_PLUGIN_RET_CONTINUE. - */ - - return MK_PLUGIN_RET_CONTINUE; - - ret = mk_fastcgi_start_processing(cs, sr); - if (ret == 0) { - return MK_PLUGIN_RET_CONTINUE; - } - - return MK_PLUGIN_RET_CONTINUE; -} - -int mk_fastcgi_stage30_hangup(struct mk_plugin *plugin, - struct mk_http_session *cs, - struct mk_http_request *sr) -{ - (void) plugin; - (void) cs; - struct fcgi_handler *handler; - - handler = sr->handler_data; - if (!handler) { - return -1; - } - - if (handler->hangup == MK_TRUE) { - return 0; - } - - handler->active = MK_FALSE; - handler->hangup = MK_TRUE; - - fcgi_exit(sr->handler_data); - - return 0; -} - -int mk_fastcgi_plugin_init(struct plugin_api **api, char *confdir) -{ - int ret; - - mk_api = *api; - - /* read global configuration */ - ret = mk_fastcgi_config(confdir); - if (ret == -1) { - mk_warn("[fastcgi] configuration error/missing, plugin disabled."); - } - return ret; -} - -int mk_fastcgi_plugin_exit() -{ - return 0; -} - -int mk_fastcgi_master_init(struct mk_server *server) -{ - (void) server; - return 0; -} - -void mk_fastcgi_worker_init() -{ -} - -struct mk_plugin_stage mk_plugin_stage_fastcgi = { - .stage30 = &mk_fastcgi_stage30, - .stage30_thread = &mk_fastcgi_stage30_thread, - .stage30_hangup = &mk_fastcgi_stage30_hangup -}; - -struct mk_plugin mk_plugin_fastcgi = { - /* Identification */ - .shortname = "fastcgi", - .name = "FastCGI Client", - .version = "1.0", - .hooks = MK_PLUGIN_STAGE, - - /* Init / Exit */ - .init_plugin = mk_fastcgi_plugin_init, - .exit_plugin = mk_fastcgi_plugin_exit, - - /* Init Levels */ - .master_init = mk_fastcgi_master_init, - .worker_init = mk_fastcgi_worker_init, - - /* Type */ - .stage = &mk_plugin_stage_fastcgi, - - /* Flags */ - .flags = MK_PLUGIN_THREAD -}; diff --git a/fluent-bit/lib/monkey/plugins/fastcgi/fastcgi.h b/fluent-bit/lib/monkey/plugins/fastcgi/fastcgi.h deleted file mode 100644 index a367f761c..000000000 --- a/fluent-bit/lib/monkey/plugins/fastcgi/fastcgi.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MK_FASTCGI_H -#define MK_FASTCGI_H - -struct mk_fcgi_conf { - char *server_name; - - /* Unix Socket */ - char *server_path; - - /* TCP Server */ - char *server_addr; - char *server_port; -}; - -struct mk_fcgi_conf fcgi_conf; - -#endif diff --git a/fluent-bit/lib/monkey/plugins/fastcgi/fcgi_handler.c b/fluent-bit/lib/monkey/plugins/fastcgi/fcgi_handler.c deleted file mode 100644 index 0c7881309..000000000 --- a/fluent-bit/lib/monkey/plugins/fastcgi/fcgi_handler.c +++ /dev/null @@ -1,967 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <monkey/mk_api.h> -#include <monkey/mk_net.h> -#include <monkey/mk_stream.h> - -#include "fastcgi.h" -#include "fcgi_handler.h" - -#define FCGI_BUF(h) (char *) h->buf_data + h->buf_len -#define FCGI_PARAM_DYN(str) str, strlen(str), MK_FALSE -#define FCGI_PARAM_CONST(str) str, sizeof(str) -1, MK_FALSE -#define FCGI_PARAM_PTR(ptr) ptr.data, ptr.len, MK_FALSE -#define FCGI_PARAM_DUP(str) mk_api->str_dup(str), strlen(str), MK_TRUE - -int fcgi_pad[256] = {0}; - -static inline void fcgi_build_header(struct fcgi_record_header *rec, - uint8_t type, uint16_t request_id, - uint16_t content_length) -{ - rec->version = FCGI_VERSION_1; - rec->type = type; - fcgi_encode16(&rec->request_id, request_id); - fcgi_encode16(&rec->content_length, content_length); - rec->padding_length = 0; - rec->reserved = 0; -} - -static inline void fcgi_build_request_body(struct fcgi_begin_request_body *body) -{ - fcgi_encode16(&body->role, FCGI_RESPONDER); - body->flags = 0; - memset(body->reserved, '\0', sizeof(body->reserved)); -} - -static inline size_t fcgi_write_length(char *p, size_t len) -{ - if (len < 127) { - *p++ = len; - return 1; - } - else{ - *p++ = (len >> 24) | 0x80; - *p++ = (len >> 16) & 0xff; - *p++ = (len >> 8) & 0xff; - *p++ = (len) & 0xff; - return 4; - } -} - -static inline int fcgi_add_param_empty(struct fcgi_handler *handler) -{ - char *p; - - p = FCGI_BUF(handler); - fcgi_build_header((struct fcgi_record_header *) p, FCGI_PARAMS, 1, 0); - mk_api->iov_add(handler->iov, p, - sizeof(struct fcgi_record_header), MK_FALSE); - handler->buf_len += sizeof(struct fcgi_record_header); - return 0; -} - -static inline int fcgi_add_param(struct fcgi_handler *handler, - char *key, int key_len, int key_free, - char *val, int val_len, int val_free) -{ - int ret; - int len; - int diff; - int padding; - char *p; - char *buf; - struct fcgi_record_header *h; - - buf = p = (char * ) handler->buf_data + handler->buf_len; - - len = key_len + val_len; - len += key_len > 127 ? 4 : 1; - len += val_len > 127 ? 4 : 1; - - fcgi_build_header((struct fcgi_record_header *) p, FCGI_PARAMS, 1, len); - padding = ~(len - 1) & 7; - if (padding) { - h = (struct fcgi_record_header *) p; - h->padding_length = padding; - } - - p += sizeof(struct fcgi_record_header); - p += fcgi_write_length(p, key_len); - p += fcgi_write_length(p, val_len); - - diff = (p - buf); - handler->buf_len += diff; - ret = mk_api->iov_add(handler->iov, buf, diff, MK_FALSE); - if (ret == -1) { - return -1; - } - - mk_api->iov_add(handler->iov, key, key_len, key_free); - mk_api->iov_add(handler->iov, val, val_len, val_free); - - if (padding) { - mk_api->iov_add(handler->iov, fcgi_pad, h->padding_length, MK_FALSE); - } - - return 0; -} - -static inline int fcgi_add_param_http_header(struct fcgi_handler *handler, - struct mk_http_header *header) -{ - unsigned int i; - int avail; - int req; - int diff; - char *p; - char *buf; - - avail = (sizeof(handler->buf_data) - handler->buf_len); - req = sizeof(struct fcgi_record_header) + 8; - req += header->key.len + 5; - - if (avail < req) { - return -1; - } - - buf = p = (handler->buf_data + handler->buf_len); - *p++ = 'H'; - *p++ = 'T'; - *p++ = 'T'; - *p++ = 'P'; - *p++ = '_'; - - for (i = 0; i < header->key.len; i++) { - if (header->key.data[i] == '-') { - *p++ = '_'; - } - else { - *p++ = toupper(header->key.data[i]); - } - } - - diff = (p - buf); - handler->buf_len += diff; - fcgi_add_param(handler, - buf, diff, MK_FALSE, - header->val.data, header->val.len, MK_FALSE); - - return 0; -} - -static inline int fcgi_add_param_net(struct fcgi_handler *handler) -{ - int ret; - const char *p; - char buffer[256]; - - /* This is to identify whether its IPV4 or IPV6 */ - struct sockaddr_storage addr; - int port = 0; - socklen_t addr_len = sizeof(struct sockaddr_in); - - ret = getsockname(handler->cs->socket, (struct sockaddr *)&addr, &addr_len); - if (ret == -1) { -#ifdef TRACE - perror("getsockname"); -#endif - if (errno == EBADF) { - MK_TRACE("[fastcgi=%i] network connection broken", - handler->cs->socket); - } - return -1; - } - - if (addr.ss_family == AF_INET) { - struct sockaddr_in *s = (struct sockaddr_in *)&addr; - port = ntohs(s->sin_port); - p = inet_ntop(AF_INET, &s->sin_addr, buffer, sizeof(buffer)); - if (!p) { - perror("inet_ntop"); - return -1; - } - } else { /* AF_INET6 */ - struct sockaddr_in6 *s = (struct sockaddr_in6 *)&addr; - port = ntohs(s->sin6_port); - p = inet_ntop(AF_INET6, &s->sin6_addr, buffer, sizeof(buffer)); - if (!p) { - perror("inet_ntop"); - return -1; - } - } - - /* Server Address */ - fcgi_add_param(handler, - FCGI_PARAM_CONST("SERVER_ADDR"), - FCGI_PARAM_DUP(buffer)); - - /* Server Port */ - snprintf(buffer, 256, "%d", port); - fcgi_add_param(handler, - FCGI_PARAM_CONST("SERVER_PORT"), - FCGI_PARAM_DUP(buffer)); - - - ret = getpeername(handler->cs->socket, (struct sockaddr *)&addr, &addr_len); - if (ret == -1) { - perror("getpeername"); - return -1; - } - - if (addr.ss_family == AF_INET) { - struct sockaddr_in *s = (struct sockaddr_in *)&addr; - port = ntohs(s->sin_port); - p = inet_ntop(AF_INET, &s->sin_addr, buffer, sizeof(buffer)); - if (!p) { - perror("inet_ntop"); - return -1; - } - } else { /* AF_INET6 */ - struct sockaddr_in6 *s = (struct sockaddr_in6 *)&addr; - port = ntohs(s->sin6_port); - - if (IN6_IS_ADDR_V4MAPPED(&s->sin6_addr)) { - /* This is V4-Mapped-V6 - Lets convert it to plain IPV4 address. - * E.g. we would have received like this ::ffff:10.106.146.73. - * This would be converted to 10.106.146.73. - */ - struct sockaddr_in addr4; - struct sockaddr_in *s4 = (struct sockaddr_in *)&addr4; - memset(&addr4, 0, sizeof(addr4)); - addr4.sin_family = AF_INET; - addr4.sin_port = &s->sin6_port; - memcpy(&addr4.sin_addr.s_addr, - s->sin6_addr.s6_addr + 12, - sizeof(addr4.sin_addr.s_addr)); - p = inet_ntop(AF_INET, &s4->sin_addr, buffer, sizeof(buffer)); - if (!p) { - perror("inet_ntop"); - return -1; - } - } else { - p = inet_ntop(AF_INET6, &s->sin6_addr, buffer, sizeof(buffer)); - if (!p) { - perror("inet_ntop"); - return -1; - } - } - } - - /* Remote Addr */ - fcgi_add_param(handler, - FCGI_PARAM_CONST("REMOTE_ADDR"), - FCGI_PARAM_DUP(buffer)); - - /* Remote Port */ - snprintf(buffer, 256, "%d", port); - fcgi_add_param(handler, - FCGI_PARAM_CONST("REMOTE_PORT"), - FCGI_PARAM_DUP(buffer)); - - return 0; -} - -static inline int fcgi_stdin_chunk(struct fcgi_handler *handler) -{ - int padding = 0; - uint16_t max = 65535; - uint16_t chunk; - uint64_t total; - char *p; - char *eof; - struct fcgi_record_header *h; - - total = handler->stdin_length - handler->stdin_offset; - if (total > max) { - chunk = max; - } - else { - chunk = total; - } - - p = FCGI_BUF(handler); - h = (struct fcgi_record_header *) p; - fcgi_build_header(h, FCGI_STDIN, 1, chunk); - h->padding_length = ~(chunk - 1) & 7; - - MK_TRACE("[fastcgi] STDIN: length=%i", chunk); - - mk_api->iov_add(handler->iov, p, FCGI_RECORD_HEADER_SIZE, MK_FALSE); - handler->buf_len += FCGI_RECORD_HEADER_SIZE; - - - if (chunk > 0) { - mk_api->iov_add(handler->iov, - handler->stdin_buffer + handler->stdin_offset, - chunk, - MK_FALSE); - } - - if (h->padding_length > 0) { - mk_api->iov_add(handler->iov, - fcgi_pad, h->padding_length, - MK_FALSE); - } - - if (handler->stdin_offset + chunk == handler->stdin_length) { - eof = FCGI_BUF(handler); - fcgi_build_header((struct fcgi_record_header *) eof, FCGI_STDIN, 1, 0); - mk_api->iov_add(handler->iov, eof, FCGI_RECORD_HEADER_SIZE, MK_FALSE); - handler->buf_len += FCGI_RECORD_HEADER_SIZE + padding; - } - - handler->stdin_offset += chunk; - return 0; -} - -static inline int fcgi_add_stdin(struct fcgi_handler *handler) -{ - uint64_t bytes = handler->sr->data.len; - - if (bytes <= 0) { - return -1; - } - - handler->stdin_length = bytes; - handler->stdin_offset = 0; - handler->stdin_buffer = handler->sr->data.data; - fcgi_stdin_chunk(handler); - - return 0; -} - -static int fcgi_encode_request(struct fcgi_handler *handler) -{ - int ret; - struct mk_http_header *header; - struct fcgi_begin_request_record *request; - - MK_TRACE("ENCODE REQUEST"); - - request = &handler->header_request; - fcgi_build_header(&request->header, FCGI_BEGIN_REQUEST, 1, - FCGI_BEGIN_REQUEST_BODY_SIZE); - - fcgi_build_request_body(&request->body); - - /* BEGIN_REQUEST */ - mk_api->iov_add(handler->iov, - &handler->header_request, - sizeof(handler->header_request), - MK_FALSE); - - /* Server Software */ - fcgi_add_param(handler, - FCGI_PARAM_CONST("GATEWAY_INTERFACE"), - FCGI_PARAM_CONST("CGI/1.1")); - - /* Server Software */ - fcgi_add_param(handler, - FCGI_PARAM_CONST("REDIRECT_STATUS"), - FCGI_PARAM_CONST("200")); - - /* Server Software */ - fcgi_add_param(handler, - FCGI_PARAM_CONST("SERVER_SOFTWARE"), - FCGI_PARAM_DYN(mk_api->config->server_signature)); - - /* Server Name */ - fcgi_add_param(handler, - FCGI_PARAM_CONST("SERVER_PROTOCOL"), - FCGI_PARAM_CONST("HTTP/1.1")); - - /* Server Name */ - fcgi_add_param(handler, - FCGI_PARAM_CONST("SERVER_NAME"), - handler->sr->host_alias->name, - handler->sr->host_alias->len, - MK_FALSE); - - /* Document Root */ - fcgi_add_param(handler, - FCGI_PARAM_CONST("DOCUMENT_ROOT"), - FCGI_PARAM_PTR(handler->sr->host_conf->documentroot)); - - /* Network params: SERVER_ADDR, SERVER_PORT, REMOTE_ADDR & REMOTE_PORT */ - ret = fcgi_add_param_net(handler); - if (ret == -1) { - return -1; - } - - /* Script Filename */ - fcgi_add_param(handler, - FCGI_PARAM_CONST("SCRIPT_FILENAME"), - FCGI_PARAM_PTR(handler->sr->real_path)); - - /* Script Filename */ - fcgi_add_param(handler, - FCGI_PARAM_CONST("SCRIPT_NAME"), - FCGI_PARAM_PTR(handler->sr->uri_processed)); - - /* Request Method */ - fcgi_add_param(handler, - FCGI_PARAM_CONST("REQUEST_METHOD"), - FCGI_PARAM_PTR(handler->sr->method_p)); - - - /* Request URI */ - fcgi_add_param(handler, - FCGI_PARAM_CONST("REQUEST_URI"), - FCGI_PARAM_PTR(handler->sr->uri)); - - /* Query String */ - if (handler->sr->query_string.len > 0) { - fcgi_add_param(handler, - FCGI_PARAM_CONST("QUERY_STRING"), - FCGI_PARAM_PTR(handler->sr->query_string)); - } - - /* HTTPS */ - if (MK_SCHED_CONN_PROP(handler->cs->conn) & MK_CAP_SOCK_TLS) { - fcgi_add_param(handler, - FCGI_PARAM_CONST("HTTPS"), - FCGI_PARAM_CONST("on")); - } - - /* Content Length */ - if (handler->sr->_content_length.data) { - fcgi_add_param(handler, - FCGI_PARAM_CONST("CONTENT_LENGTH"), - FCGI_PARAM_PTR(handler->sr->_content_length)); - } - - /* Content Length */ - header = &handler->cs->parser.headers[MK_HEADER_CONTENT_TYPE]; - if (header->type == MK_HEADER_CONTENT_TYPE) { - fcgi_add_param(handler, - FCGI_PARAM_CONST("CONTENT_TYPE"), - FCGI_PARAM_PTR(header->val)); - - } - - /* Append HTTP request headers */ - struct mk_list *head; - struct mk_http_header *http_header; - mk_list_foreach(head, &handler->cs->parser.header_list) { - http_header = mk_list_entry(head, struct mk_http_header, _head); - fcgi_add_param_http_header(handler, http_header); - } - - /* Append the empty params record */ - fcgi_add_param_empty(handler); - - /* Data for FCGI_STDIN */ - fcgi_add_stdin(handler); - - return 0; -} - -size_t fcgi_read_header(void *p, struct fcgi_record_header *h) -{ - memcpy(h, p, sizeof(struct fcgi_record_header)); - h->request_id = htons(h->request_id); - h->content_length = htons(h->content_length); - - return sizeof(*h); -} - -static inline int fcgi_buffer_consume(struct fcgi_handler *handler, size_t bytes) -{ - if (bytes >= handler->buf_len) { - handler->buf_len = 0; - return 0; - } - - memmove(handler->buf_data, handler->buf_data + bytes, - handler->buf_len - bytes); - handler->buf_len -= bytes; - return 0; -} - -static char *getearliestbreak(const char buf[], const unsigned bufsize, - unsigned char * const advance) -{ - char *crend; - char *lfend; - - crend = memmem(buf, bufsize, "\r\n\r\n", 4); - lfend = memmem(buf, bufsize, "\n\n", 2); - - if (!crend && !lfend) - return NULL; - - /* If only one found, return that one */ - if (!crend) { - *advance = 2; - return lfend; - } - if (!lfend) - return crend; - - /* Both found, return the earlier one - the latter one is part of content */ - if (lfend < crend) { - *advance = 2; - return lfend; - } - return crend; -} - -static int fcgi_write(struct fcgi_handler *handler, char *buf, size_t len) -{ - mk_stream_in_raw(handler->stream, - NULL, - buf, len, - NULL, NULL); - - if (handler->headers_set == MK_TRUE) { - mk_stream_in_raw(handler->stream, - NULL, - "\r\n", 2, - NULL, NULL); - } - return 0; -} - -void fcgi_stream_eof(struct mk_stream_input *in) -{ - (void) in; - // FIXME - //struct fcgi_handler *handler; - - //handler = stream->data; - //if (handler->hangup == MK_FALSE) { - // fcgi_exit(handler); - //} -} - -int fcgi_exit(struct fcgi_handler *handler) -{ - /* Always disable any backend notification first */ - if (handler->server_fd > 0) { - mk_api->ev_del(mk_api->sched_loop(), &handler->event); - close(handler->server_fd); - handler->server_fd = -1; - } - - /* - * Before to exit our handler, we need to verify that our parent - * channel have sent the whole information, otherwise we may face - * some corruption. If there is still some data enqueued, just - * defer the exit process. - */ - if (mk_channel_is_empty(handler->cs->channel) != 0 && - handler->eof == MK_FALSE && - handler->active == MK_TRUE) { - MK_TRACE("[fastcgi=%i] deferring exit, EOF stream", - handler->server_fd); - - /* Now set an EOF stream/callback to resume the exiting process */ - mk_stream_in_eof(handler->stream, - NULL, - fcgi_stream_eof); - handler->eof = MK_TRUE; - return 1; - } - - MK_TRACE("[fastcgi] exiting"); - - if (handler->iov) { - mk_api->iov_free(handler->iov); - mk_api->sched_event_free((struct mk_event *) handler); - handler->iov = NULL; - } - - if (handler->active == MK_TRUE) { - handler->active = MK_FALSE; - mk_api->http_request_end(handler->plugin, handler->cs, handler->hangup); - } - - return 1; -} - -int fcgi_error(struct fcgi_handler *handler) -{ - fcgi_exit(handler); - mk_api->http_request_error(500, handler->cs, handler->sr, handler->plugin); - return 0; -} - -static int fcgi_response(struct fcgi_handler *handler, char *buf, size_t len) -{ - int status; - int diff; - int xlen; - char tmp[16]; - char *p; - char *end; - size_t p_len; - unsigned char advance; - - MK_TRACE("[fastcgi=%i] process response len=%lu", - handler->server_fd, len); - - p = buf; - p_len = len; - - if (len == 0 && handler->chunked && handler->headers_set == MK_TRUE) { - MK_TRACE("[fastcgi=%i] sending EOF", handler->server_fd); - mk_stream_in_raw(handler->stream, - NULL, - "0\r\n\r\n", 5, - NULL, NULL); - mk_api->channel_flush(handler->cs->channel); - return 0; - } - - if (handler->headers_set == MK_FALSE) { - advance = 4; - - if (!buf) { - return -1; - } - - end = getearliestbreak(buf, len, &advance); - if (!end) { - /* we need more data */ - return -1; - } - - handler->sr->headers.cgi = MK_TRUE; - if (strncasecmp(buf, "Status: ", 8) == 0) { - sscanf(buf + 8, "%d", &status); - MK_TRACE("FastCGI status %i", status); - mk_api->header_set_http_status(handler->sr, status); - } - else { - mk_api->header_set_http_status(handler->sr, 200); - } - - /* Set transfer encoding */ - if (handler->sr->protocol >= MK_HTTP_PROTOCOL_11) { - handler->sr->headers.transfer_encoding = MK_HEADER_TE_TYPE_CHUNKED; - handler->chunked = MK_TRUE; - } - - mk_api->header_prepare(handler->plugin, handler->cs, handler->sr); - - diff = (end - buf) + advance; - fcgi_write(handler, buf, diff); - - p = buf + diff; - p_len -= diff; - handler->write_rounds++; - handler->headers_set = MK_TRUE; - } - - if (p_len > 0) { - xlen = snprintf(tmp, 16, "%x\r\n", (unsigned int) p_len); - mk_stream_in_raw(handler->stream, - NULL, - tmp, xlen, - NULL, NULL); - fcgi_write(handler, p, p_len); - } - - return 0; -} - -int cb_fastcgi_on_read(void *data) -{ - int n; - int ret = 0; - int avail; - char *body; - size_t offset; - struct fcgi_handler *handler = data; - struct fcgi_record_header header; - - if (handler->active == MK_FALSE) { - fcgi_exit(handler); - return -1; - } - - avail = FCGI_BUF_SIZE - handler->buf_len; - n = read(handler->server_fd, handler->buf_data + handler->buf_len, avail); - MK_TRACE("[fastcgi=%i] read()=%i", handler->server_fd, n); - if (n <= 0) { - MK_TRACE("[fastcgi=%i] FastCGI server ended", handler->server_fd); - fcgi_exit(handler); - return -1; - } - else { - handler->buf_len += n; - } - - if ((unsigned) handler->buf_len < FCGI_RECORD_HEADER_SIZE) { - /* wait for more data */ - return n; - } - - while (1) { - /* decode the header */ - fcgi_read_header(&handler->buf_data, &header); - - if (header.type != FCGI_STDOUT && header.type != FCGI_STDERR && - header.type != FCGI_END_REQUEST) { - fcgi_exit(handler); - return -1; - } - - /* Check if the package is complete */ - if (handler->buf_len < (FCGI_RECORD_HEADER_SIZE + header.content_length)) { - /* we need more data */ - return n; - } - - body = handler->buf_data + FCGI_RECORD_HEADER_SIZE; - switch (header.type) { - case FCGI_STDOUT: - MK_TRACE("[fastcgi=%i] FCGI_STDOUT content_length=%i", - handler->server_fd, header.content_length); - /* - * Issue seen with Chrome & Firefox browsers: - * Sometimes content length is coming as ZERO and we are encoding a - * HTTP response packet with ZERO size data. This makes Chrome & Firefox - * browsers fail to proceed furhter and subsequent content loading fails. - * However, IE/Safari discards the packets with ZERO size data. - */ - if (0 != header.content_length) { - ret = fcgi_response(handler, body, header.content_length); - } - else { - MK_TRACE("[fastcgi=%i] ZERO byte content length in FCGI_STDOUT, discard!!", - handler->server_fd); - ret = 0; - } - break; - case FCGI_STDERR: - MK_TRACE("[fastcgi=%i] FCGI_STDERR content_length=%i", - handler->server_fd, header.content_length); - break; - case FCGI_END_REQUEST: - MK_TRACE("[fastcgi=%i] FCGI_END_REQUEST content_length=%i", - handler->server_fd, header.content_length); - ret = fcgi_response(handler, NULL, 0); - break; - default: - //fcgi_exit(handler); - return -1; - } - - if (ret == -1) { - /* Missing header breaklines ? */ - return n; - } - - /* adjust buffer content */ - offset = FCGI_RECORD_HEADER_SIZE + - header.content_length + header.padding_length; - - fcgi_buffer_consume(handler, offset); - } - return n; -} - -int cb_fastcgi_request_flush(void *data) -{ - int ret; - size_t count = 0; - struct fcgi_handler *handler = data; - - ret = mk_api->channel_write(&handler->fcgi_channel, &count); - - MK_TRACE("[fastcgi=%i] %lu bytes, ret=%i", - handler->server_fd, count, ret); - - if (ret == MK_CHANNEL_DONE || ret == MK_CHANNEL_EMPTY) { - /* Do we have more data for the stdin ? */ - if (handler->stdin_length - handler->stdin_offset > 0) { - mk_api->iov_free(handler->iov); - handler->iov = mk_api->iov_create(64, 0); - fcgi_stdin_chunk(handler); - - mk_api->stream_set(&handler->fcgi_stream, - MK_STREAM_IOV, - &handler->fcgi_channel, - handler->iov, - -1, - handler, - NULL, NULL, NULL); - return MK_CHANNEL_FLUSH; - } - - /* Request done, switch the event side to receive the FCGI response */ - handler->buf_len = 0; - handler->event.handler = cb_fastcgi_on_read; - ret = mk_api->ev_add(mk_api->sched_loop(), - handler->server_fd, - MK_EVENT_CUSTOM, MK_EVENT_READ, handler); - if (ret == -1) { - goto error; - } - } - else if (ret == MK_CHANNEL_ERROR) { - fcgi_exit(handler); - } - else if (ret == MK_CHANNEL_BUSY) { - return -1; - } - - return ret; - - error: - return -1; -} - -/* Callback: on connect to the backend server */ -static int fastcgi_on_connect(struct fcgi_handler *handler) -{ - int ret; - int s_err; - size_t count; - socklen_t s_len = sizeof(s_err); - struct mk_list *head; - struct mk_plugin *pio; - struct mk_channel *channel; - - /* Convert the original request to FCGI format */ - ret = fcgi_encode_request(handler); - if (ret == -1) { - goto error; - } - - /* Prepare the channel */ - channel = &handler->fcgi_channel; - channel->type = MK_CHANNEL_SOCKET; - channel->fd = handler->server_fd; - - /* FIXME: Discovery process needs to be fast */ - mk_list_foreach(head, &mk_api->config->plugins) { - pio = mk_list_entry(head, struct mk_plugin, _head); - if (strncmp(pio->shortname, "liana", 5) == 0) { - break; - } - pio = NULL; - } - channel->io = pio->network; - - mk_list_init(&channel->streams); - mk_api->stream_set(&handler->fcgi_stream, - MK_STREAM_IOV, - &handler->fcgi_channel, - handler->iov, - -1, - handler, - NULL, NULL, NULL); - - handler->event.handler = cb_fastcgi_request_flush; - handler->event.data = handler; - - return 0; - - error: - fcgi_error(handler); - mk_api->channel_write(handler->cs->channel, &count); - return 0; -} - -struct fcgi_handler *fcgi_handler_new(struct mk_plugin *plugin, - struct mk_http_session *cs, - struct mk_http_request *sr) -{ - int ret; - int entries; - struct fcgi_handler *h = NULL; - struct mk_net_connection *conn = NULL; - - /* Allocate handler instance and set fields */ - h = mk_api->mem_alloc_z(sizeof(struct fcgi_handler)); - if (!h) { - return NULL; - } - - stream = mk_stream_set(NULL, cs->channel, h, - NULL, NULL, NULL); - if (!stream) { - mk_api->mem_free(h); - return NULL; - } - - h->stream = stream; - h->plugin = plugin; - h->cs = cs; - h->sr = sr; - h->write_rounds = 0; - h->active = MK_TRUE; - h->server_fd = -1; - h->eof = MK_FALSE; - h->stdin_length = 0; - h->stdin_offset = 0; - h->stdin_buffer = NULL; - h->conn = NULL; - - /* Allocate enough space for our data */ - entries = 128 + (cs->parser.header_count * 3); - h->iov = mk_api->iov_create(entries, 0); - - /* Associate the handler with the Session Request */ - sr->handler_data = h; - - if (sr->protocol >= MK_HTTP_PROTOCOL_11) { - h->hangup = MK_FALSE; - } - else { - h->hangup = MK_TRUE; - } - - /* Params buffer set an offset to include the header */ - h->buf_len = FCGI_RECORD_HEADER_SIZE; - - /* Request and async connection to the server */ - if (fcgi_conf.server_addr) { - conn = mk_api->net_conn_create(fcgi_conf.server_addr, - atoi(fcgi_conf.server_port)); - if (!conn) { - goto error; - } - h->conn = conn; - h->server_fd = conn->fd; - } - else if (fcgi_conf.server_path) { - /* FIXME: unix socket connection NOT FUNCTIONAL for now */ - h->server_fd = mk_api->socket_open(fcgi_conf.server_path, MK_TRUE); - } - - if (h->server_fd == -1) { - goto error; - } - - fastcgi_on_connect(h); - return h; - - error: - mk_api->iov_free(h->iov); - mk_api->mem_free(h); - sr->handler_data = NULL; - mk_api->http_request_error(500, cs, sr, plugin); - - return NULL; -} diff --git a/fluent-bit/lib/monkey/plugins/fastcgi/fcgi_handler.h b/fluent-bit/lib/monkey/plugins/fastcgi/fcgi_handler.h deleted file mode 100644 index a0083ac7d..000000000 --- a/fluent-bit/lib/monkey/plugins/fastcgi/fcgi_handler.h +++ /dev/null @@ -1,128 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MK_FASTCGI_HANDLER_H -#define MK_FASTCGI_HANDLER_H - -#include <monkey/mk_api.h> - -/* - * Based on the information provided by the FastCGI spec, we use the - * following adapted structures: - * - * http://www.fastcgi.com/drupal/node/6?q=node/22 - */ -struct fcgi_record_header { - uint8_t version; - uint8_t type; - uint16_t request_id; - uint16_t content_length; - uint8_t padding_length; - uint8_t reserved; -}; - -struct fcgi_begin_request_body { - uint16_t role; - uint8_t flags; - uint8_t reserved[5]; -}; - -struct fcgi_begin_request_record { - struct fcgi_record_header header; - struct fcgi_begin_request_body body; -}; - -#define FCGI_VERSION_1 1 -#define FCGI_RECORD_MAX_SIZE 65535 -#define FCGI_RECORD_HEADER_SIZE sizeof(struct fcgi_record_header) -#define FCGI_BUF_SIZE FCGI_RECORD_MAX_SIZE + FCGI_RECORD_HEADER_SIZE -#define FCGI_BEGIN_REQUEST_BODY_SIZE sizeof(struct fcgi_begin_request_body) -#define FCGI_RESPONDER 1 -#define FCGI_AUTHORIZER 2 -#define FCGI_FILTER 3 - -/* - * Values for type component of FCGI_Header - */ -#define FCGI_BEGIN_REQUEST 1 -#define FCGI_ABORT_REQUEST 2 -#define FCGI_END_REQUEST 3 -#define FCGI_PARAMS 4 -#define FCGI_STDIN 5 -#define FCGI_STDOUT 6 -#define FCGI_STDERR 7 -#define FCGI_DATA 8 -#define FCGI_GET_VALUES 9 -#define FCGI_GET_VALUES_RESULT 10 - -/* - * FastCGI Handler context, it keeps information of states and other - * request/response references. - */ -struct fcgi_handler { - struct mk_event event; /* built-in event-loop data */ - - int server_fd; /* backend FastCGI server */ - int chunked; /* chunked response ? */ - int active; /* is this handler active ? */ - int hangup; /* hangup connection once ready ? */ - int headers_set; /* headers set ? */ - int eof; /* exiting: MK_TRUE / MK_FALSE */ - - /* stdin data */ - uint64_t stdin_length; - uint64_t stdin_offset; - char *stdin_buffer; - - struct mk_http_session *cs; /* HTTP session context */ - struct mk_http_request *sr; /* HTTP request context */ - - /* FastCGI */ - struct fcgi_begin_request_record header_request; - - uint64_t write_rounds; - unsigned int buf_len; - char buf_data[FCGI_BUF_SIZE]; - - /* Channel to stream request to the FCGI server */ - struct mk_channel fcgi_channel; - struct mk_stream fcgi_stream; - - struct mk_iov *iov; - struct mk_list _head; - - /* TCP connection context */ - struct mk_net_connection *conn; -}; - -static inline void fcgi_encode16(void *a, unsigned b) -{ - unsigned char *c = a; - - c[0] = (unsigned char) (b >> 8); - c[1] = (unsigned char) b; -} - -struct fcgi_handler *fcgi_handler_new(struct mk_plugin *plugin, - struct mk_http_session *cs, - struct mk_http_request *sr); - -int fcgi_exit(struct fcgi_handler *handler); - -#endif diff --git a/fluent-bit/lib/monkey/plugins/liana/ABOUT b/fluent-bit/lib/monkey/plugins/liana/ABOUT deleted file mode 100644 index 1c1407ba4..000000000 --- a/fluent-bit/lib/monkey/plugins/liana/ABOUT +++ /dev/null @@ -1,4 +0,0 @@ -Liana Plugin -============ -Liana gives network layer to Monkey so you can build your own -network layer for Monkey. diff --git a/fluent-bit/lib/monkey/plugins/liana/CMakeLists.txt b/fluent-bit/lib/monkey/plugins/liana/CMakeLists.txt deleted file mode 100644 index 1f3797dcd..000000000 --- a/fluent-bit/lib/monkey/plugins/liana/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -set(src - liana.c -) - -MONKEY_PLUGIN(liana "${src}") diff --git a/fluent-bit/lib/monkey/plugins/liana/MANDATORY b/fluent-bit/lib/monkey/plugins/liana/MANDATORY deleted file mode 100644 index e69de29bb..000000000 --- a/fluent-bit/lib/monkey/plugins/liana/MANDATORY +++ /dev/null diff --git a/fluent-bit/lib/monkey/plugins/liana/Makefile.in b/fluent-bit/lib/monkey/plugins/liana/Makefile.in deleted file mode 100644 index ef9fd4fc3..000000000 --- a/fluent-bit/lib/monkey/plugins/liana/Makefile.in +++ /dev/null @@ -1,18 +0,0 @@ -all: monkey-liana.so -include ../Make.common - -CC = @echo " CC $(_PATH)/$@"; $CC -CC_QUIET= @echo -n; $CC -AR = @echo " AR $(_PATH)/$@"; $AR -CFLAGS = $CFLAGS -LDFLAGS = $LDFLAGS -DEFS = $DEFS -LIANA_OBJECTS = liana.o - --include $(LIANA_OBJECTS:.o=.d) - -monkey-liana.so: $(LIANA_OBJECTS) - $(CC) $(CFLAGS) $(LDFLAGS) $(DEFS) -shared -o $@ $^ -lc - -monkey-liana.a: $(LIANA_OBJECTS) - $(AR) rcs $@ $(LIANA_OBJECTS) diff --git a/fluent-bit/lib/monkey/plugins/liana/README b/fluent-bit/lib/monkey/plugins/liana/README deleted file mode 100644 index 69a4760f9..000000000 --- a/fluent-bit/lib/monkey/plugins/liana/README +++ /dev/null @@ -1,7 +0,0 @@ -Liana Networking Plugin -======================= - -Liana is the base network plugin for Monkey, it provides the -most basic socket calls such as: accept(), read(), write() etc. - -Without Liana do not expect a default HTTP Server working :) diff --git a/fluent-bit/lib/monkey/plugins/liana/STATIC b/fluent-bit/lib/monkey/plugins/liana/STATIC deleted file mode 100644 index e69de29bb..000000000 --- a/fluent-bit/lib/monkey/plugins/liana/STATIC +++ /dev/null diff --git a/fluent-bit/lib/monkey/plugins/liana/liana.c b/fluent-bit/lib/monkey/plugins/liana/liana.c deleted file mode 100644 index 3bfe288b8..000000000 --- a/fluent-bit/lib/monkey/plugins/liana/liana.c +++ /dev/null @@ -1,221 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define _GNU_SOURCE - -#include <stdio.h> -#include <string.h> - -#include <sys/types.h> -#include <fcntl.h> - -#ifdef _WIN32 -#include <winsock2.h> -#else -#include <arpa/inet.h> -#include <sys/socket.h> -#include <netdb.h> -#endif - -#if defined (__linux__) -#include <sys/sendfile.h> -#endif - -#include <monkey/mk_api.h> - -int mk_liana_plugin_init(struct mk_plugin *plugin, char *confdir) -{ - (void) confdir; - (void) plugin; - - return 0; -} - -int mk_liana_plugin_exit(struct mk_plugin *plugin) -{ - (void) plugin; - - return 0; -} - -int mk_liana_read(struct mk_plugin *plugin, int socket_fd, void *buf, int count) -{ - (void) plugin; - - return recv(socket_fd, (void*)buf, count, 0); -} - -int mk_liana_write(struct mk_plugin *plugin, int socket_fd, const void *buf, size_t count ) -{ - ssize_t bytes_sent = -1; - - (void) plugin; - - bytes_sent = send(socket_fd, buf, count, 0); - - return bytes_sent; -} - -int mk_liana_writev(struct mk_plugin *plugin, int socket_fd, struct mk_iov *mk_io) -{ - ssize_t bytes_sent = -1; - - (void) plugin; - - bytes_sent = plugin->api->iov_send(socket_fd, mk_io); - - return bytes_sent; -} - -int mk_liana_close(struct mk_plugin *plugin, int socket_fd) -{ - (void) plugin; - -#ifdef _WIN32 - return closesocket(socket_fd); -#else - return close(socket_fd); -#endif -} - -int mk_liana_send_file(struct mk_plugin *plugin, int socket_fd, int file_fd, off_t *file_offset, - size_t file_count) -{ - ssize_t ret = -1; - - (void) plugin; - -#if defined (__linux__) - ret = sendfile(socket_fd, file_fd, file_offset, file_count); - if (ret == -1 && errno != EAGAIN) { - PLUGIN_TRACE("[FD %i] error from sendfile(): %s", - socket_fd, strerror(errno)); - } - return ret; -#elif defined (__APPLE__) - off_t offset = *file_offset; - off_t len = (off_t) file_count; - - ret = sendfile(file_fd, socket_fd, offset, &len, NULL, 0); - if (ret == -1 && errno != EAGAIN) { - PLUGIN_TRACE("[FD %i] error from sendfile(): %s", - socket_fd, strerror(errno)); - } - else if (len > 0) { - *file_offset += len; - return len; - } - return ret; -#elif defined (__FreeBSD__) - off_t offset = *file_offset; - off_t len = (off_t) file_count; - - ret = sendfile(file_fd, socket_fd, offset, len, NULL, 0, 0); - if (ret == -1 && errno != EAGAIN) { - PLUGIN_TRACE("[FD %i] error from sendfile(): %s", - socket_fd, strerror(errno)); - } - else if (len > 0) { - *file_offset += len; - return len; - } - return ret; -#else - #pragma message ("This is a terrible sendfile \"implementation\" and just a crutch") - - ssize_t bytes_written = 0; - ssize_t to_be_sent = -1; - ssize_t send_ret = -1; - uint8_t temporary_buffer[1024]; - - if (NULL != file_offset) { - lseek(file_fd, *file_offset, SEEK_SET); - } - - while (1) { - memset(temporary_buffer, 0, sizeof(temporary_buffer)); - - ret = read(file_fd, temporary_buffer, sizeof(temporary_buffer)); - - if (0 == ret) - { - return bytes_written; - } - else if (0 > ret) - { - return -1; - } - else if (0 < ret) - { - to_be_sent = ret; - - while (to_be_sent > 0) - { - send_ret = send(file_fd, &temporary_buffer[ret - to_be_sent], to_be_sent, 0); - - if (-1 == send_ret) - { - if (EAGAIN != errno && - EWOULDBLOCK != errno) - { - return -1; - } - } - else - { - bytes_written += send_ret; - to_be_sent -= send_ret; - } - } - } - } -#endif -} - -/* Network Layer plugin Callbacks */ -struct mk_plugin_network mk_plugin_network_liana = { - .read = mk_liana_read, - .write = mk_liana_write, - .writev = mk_liana_writev, - .close = mk_liana_close, - .send_file = mk_liana_send_file, - .buffer_size = MK_REQUEST_CHUNK -}; - -struct mk_plugin mk_plugin_liana = { - /* Identification */ - .shortname = "liana", - .name = "Liana Network Layer", - .version = MK_VERSION_STR, - .hooks = MK_PLUGIN_NETWORK_LAYER, - - /* Init / Exit */ - .init_plugin = mk_liana_plugin_init, - .exit_plugin = mk_liana_plugin_exit, - - /* Init Levels */ - .master_init = NULL, - .worker_init = NULL, - - /* Type */ - .network = &mk_plugin_network_liana, - - /* Capabilities */ - .capabilities = MK_CAP_SOCK_PLAIN -}; diff --git a/fluent-bit/lib/monkey/plugins/logger/CMakeLists.txt b/fluent-bit/lib/monkey/plugins/logger/CMakeLists.txt deleted file mode 100644 index 156a0847f..000000000 --- a/fluent-bit/lib/monkey/plugins/logger/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -set(src - pointers.c - logger.c - ) - -# Validate splice() -check_c_source_compiles(" - #define _GNU_SOURCE - #include <stdio.h> - #include <fcntl.h> - int main() { - return splice(0, NULL, 1, - NULL, 1, SPLICE_F_MOVE); - }" HAVE_SPLICE) - -if (HAVE_SPLICE) - MK_DEFINITION(MK_HAVE_SPLICE) -endif() - -MONKEY_PLUGIN(logger "${src}") -add_subdirectory(conf) diff --git a/fluent-bit/lib/monkey/plugins/logger/conf/CMakeLists.txt b/fluent-bit/lib/monkey/plugins/logger/conf/CMakeLists.txt deleted file mode 100644 index 2c4e9b069..000000000 --- a/fluent-bit/lib/monkey/plugins/logger/conf/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -set(conf_dir "${MK_PATH_CONF}/plugins/logger/") - -install(DIRECTORY DESTINATION ${conf_dir}) -configure_file( - "${PROJECT_SOURCE_DIR}/plugins/logger/conf/logger.conf.in" - "${PROJECT_BINARY_DIR}/conf/plugins/logger/logger.conf" - ) - -if(NOT BUILD_LOCAL) - install(FILES ${PROJECT_BINARY_DIR}/conf/plugins/logger/logger.conf DESTINATION ${conf_dir}) -endif() diff --git a/fluent-bit/lib/monkey/plugins/logger/conf/logger.conf.in b/fluent-bit/lib/monkey/plugins/logger/conf/logger.conf.in deleted file mode 100644 index 5e06a8d6c..000000000 --- a/fluent-bit/lib/monkey/plugins/logger/conf/logger.conf.in +++ /dev/null @@ -1,22 +0,0 @@ -# Logger: -# ------- -# This plugin allows the creation of log files for each request that arrives. -# It uses an access and error file which are defined inside every virtual -# host file, this section set just global directives for the plugin. - -[LOGGER] - # FlushTimeout - # ------------ - # This key define in seconds, the waiting time before to flush the - # data to the log file. - # Allowed values must be greater than zero (FlushTimeout > 0). - - FlushTimeout 3 - - # MasterLog - # --------- - # This key define a master log file which is used when Monkey runs in daemon - # mode, so any Monkey output (stdout) will be redirected to the file - # specified here. The server port will be appended to the filename. - - MasterLog @MK_PATH_LOG@/master.log diff --git a/fluent-bit/lib/monkey/plugins/logger/logger.c b/fluent-bit/lib/monkey/plugins/logger/logger.c deleted file mode 100644 index 4dfcfb001..000000000 --- a/fluent-bit/lib/monkey/plugins/logger/logger.c +++ /dev/null @@ -1,852 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define _GNU_SOURCE - -#include <monkey/mk_api.h> - -/* System Headers */ -#include <time.h> -#include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/stat.h> - -/* Local Headers */ -#include "logger.h" -#include "pointers.h" - -struct status_response { - int i_status; - char *s_status; -}; - -static struct status_response response_codes[] = { - /* Common matches first */ - {200, "200"}, {404, "404"}, - - {100, "100"}, {101, "101"}, - {201, "201"}, {202, "202"}, {203, "203"}, {204, "204"}, - {205, "205"}, {206, "206"}, - {300, "300"}, {301, "301"}, {302, "302"}, {303, "303"}, {304, "304"}, - {305, "305"}, - {400, "400"}, {401, "401"}, {402, "402"}, {403, "403"}, - {405, "405"}, {406, "406"}, {407, "407"}, {408, "408"}, {409, "409"}, - {410, "410"}, {411, "411"}, {412, "412"}, {413, "413"}, {414, "414"}, - {415, "415"}, - {500, "500"}, {501, "501"}, {502, "502"}, {503, "503"}, {504, "504"}, - {505, "505"}, -}; - -static struct log_target *mk_logger_match_by_host(struct mk_vhost *host, int is_ok) -{ - struct mk_list *head; - struct log_target *entry; - - mk_list_foreach(head, &targets_list) { - entry = mk_list_entry(head, struct log_target, _head); - if (entry->host == host && entry->is_ok == is_ok) { - return entry; - } - } - - return NULL; -} - -static struct iov *mk_logger_get_cache() -{ - return pthread_getspecific(cache_iov); -} - -static ssize_t _mk_logger_append(int pipe_fd_in, - int file_fd_out, - size_t bytes) -{ - ssize_t ret; -#ifdef MK_HAVE_SPLICE - ret = splice(pipe_fd_in, NULL, file_fd_out, - NULL, bytes, SPLICE_F_MOVE); - return ret; -#else - unsigned char buffer[4096]; - ssize_t buffer_used; - size_t bytes_written = 0; - - while (bytes_written < bytes) { - ret = read(pipe_fd_in, buffer, sizeof(buffer)); - if (ret < 0) { - break; - } - buffer_used = ret; - ret = write(file_fd_out, buffer, buffer_used); - if (ret < 0) { - break; - } - bytes_written += ret; - } - if (ret < 0 && bytes_written == 0) - return -1; - else - return bytes_written; -#endif -} - -static void mk_logger_start_worker(void *args) -{ - int fd; - int bytes, err; - int max_events = mk_api->config->nhosts; - int flog; - int clk; - long slen; - int timeout; - char *target; - (void) args; - struct mk_list *head; - struct log_target *entry; - struct mk_event *event; - struct mk_event_loop *evl; - - /* pipe_size: - * ---------- - * Linux set a pipe size usingto the PAGE_SIZE, - * check linux/include/pipe_fs_i.h for details: - * - * #define PIPE_SIZE PAGE_SIZE - * - * In the same header file we can found that every - * pipe has 16 pages, so our real memory allocation - * is: (PAGE_SIZE*PIPE_BUFFERS) - */ - long pipe_size; - - /* buffer_limit: - * ------------- - * it means the maximum data that a monkey log pipe can contain. - */ - long buffer_limit; - - mk_api->worker_rename("monkey: logger"); - - /* Monkey allow just 75% of a pipe capacity */ - pipe_size = sysconf(_SC_PAGESIZE) * 16; - buffer_limit = (pipe_size * MK_LOGGER_PIPE_LIMIT); - - /* Creating poll */ - evl = mk_api->ev_loop_create(max_events); - - /* Registering targets for virtualhosts */ - mk_list_foreach(head, &targets_list) { - entry = mk_list_entry(head, struct log_target, _head); - event = &entry->event; - event->mask = MK_EVENT_EMPTY; - event->data = entry; - event->handler = NULL; - event->status = MK_EVENT_NONE; - - /* Add access log file */ - if (entry->pipe[0] > 0) { - event->fd = entry->pipe[0]; - mk_api->ev_add(evl, entry->pipe[0], - MK_EVENT_CONNECTION, MK_EVENT_READ, entry); - } - } - - /* Set initial timeout */ - timeout = time(NULL) + mk_logger_timeout; - - /* Reading pipe buffer */ - while (1) { - usleep(1200); - - /* wait for events */ - mk_api->ev_wait(evl); - - /* get current time */ - clk = mk_api->time_unix(); - - /* translate the backend events triggered */ - mk_event_foreach(event, evl) { - entry = (struct log_target *) event; - target = entry->file; - fd = entry->pipe[0]; - - err = ioctl(fd, FIONREAD, &bytes); - if (mk_unlikely(err == -1)){ - perror("ioctl"); - } - - if (bytes < buffer_limit && clk <= timeout) { - continue; - } - - timeout = clk + mk_logger_timeout; - - flog = open(target, O_WRONLY | O_CREAT | O_CLOEXEC, 0644); - if (mk_unlikely(flog == -1)) { - mk_warn("Could not open logfile '%s' (%s)", target, strerror(errno)); - - int consumed = 0; - char buf[255]; - do { - slen = read(fd, buf, 255); - if (slen > 0) { - consumed += slen; - } - else { - break; - } - } while (consumed < bytes); - - continue; - } - - lseek(flog, 0, SEEK_END); - slen = _mk_logger_append(fd, flog, bytes); - if (mk_unlikely(slen == -1)) { - mk_warn("Could not write to log file: splice() = %ld", slen); - } - - MK_TRACE("written %i bytes", bytes); - close(flog); - } - } -} - -static int mk_logger_read_config(char *path) -{ - int timeout; - char *logfilename = NULL; - unsigned long len; - char *default_file = NULL; - struct mk_rconf *conf; - struct mk_rconf_section *section; - - mk_api->str_build(&default_file, &len, "%slogger.conf", path); - conf = mk_api->config_open(default_file); - if (!conf) { - return -1; - } - - section = mk_api->config_section_get(conf, "LOGGER"); - if (section) { - - /* FlushTimeout */ - timeout = (size_t) mk_api->config_section_get_key(section, - "FlushTimeout", - MK_RCONF_NUM); - if (timeout <= 0) { - mk_err("FlushTimeout does not have a proper value"); - exit(EXIT_FAILURE); - } - mk_logger_timeout = timeout; - MK_TRACE("FlushTimeout %i seconds", mk_logger_timeout); - - /* MasterLog */ - logfilename = mk_api->config_section_get_key(section, - "MasterLog", - MK_RCONF_STR); - if (logfilename == NULL) { - mk_err("MasterLog does not have a proper value"); - exit(EXIT_FAILURE); - } - - mk_logger_master_path = logfilename; - MK_TRACE("MasterLog '%s'", mk_logger_master_path); - } - - mk_api->mem_free(default_file); - mk_api->config_free(conf); - - return 0; -} - -static void mk_logger_print_listeners() -{ - struct mk_list *head; - struct mk_config_listener *listener; - - mk_list_foreach(head, &mk_api->config->listeners) { - listener = mk_list_entry(head, struct mk_config_listener, _head); - printf(" listen on %s:%s\n", - listener->address, - listener->port); - } -} - -static void mk_logger_print_details(void) -{ - time_t now; - struct tm *current; - - now = time(NULL); - current = localtime(&now); - printf("[%i/%02i/%02i %02i:%02i:%02i] Monkey Started\n", - current->tm_year + 1900, - current->tm_mon + 1, - current->tm_mday, - current->tm_hour, - current->tm_min, - current->tm_sec); - printf(" version : %s\n", MK_VERSION_STR); - printf(" number of workers: %i\n", mk_api->config->workers); - mk_logger_print_listeners(); - fflush(stdout); -} - -int mk_logger_plugin_init(struct plugin_api **api, char *confdir) -{ - int fd; - mk_api = *api; - - /* Specific thread key */ - pthread_key_create(&cache_iov, NULL); - pthread_key_create(&cache_content_length, NULL); - pthread_key_create(&cache_status, NULL); - pthread_key_create(&cache_ip_str, NULL); - - /* Global configuration */ - mk_logger_timeout = MK_LOGGER_TIMEOUT_DEFAULT; - mk_logger_master_path = NULL; - mk_logger_read_config(confdir); - - /* Check masterlog */ - if (mk_logger_master_path) { - fd = open(mk_logger_master_path, O_WRONLY | O_CREAT | O_CLOEXEC, 0644); - if (fd == -1) { - mk_err("Could not open/create master logfile %s", mk_logger_master_path); - exit(EXIT_FAILURE); - - } - else { - /* Close test FD for MasterLog */ - close(fd); - } - } - - return 0; -} - -int mk_logger_plugin_exit() -{ - struct mk_list *head, *tmp; - struct log_target *entry; - - mk_list_foreach_safe(head, tmp, &targets_list) { - entry = mk_list_entry(head, struct log_target, _head); - mk_list_del(&entry->_head); - if (entry->pipe[0] > 0) close(entry->pipe[0]); - if (entry->pipe[1] > 0) close(entry->pipe[1]); - mk_api->mem_free(entry->file); - mk_api->mem_free(entry); - } - - mk_api->mem_free(mk_logger_master_path); - - return 0; -} - -int mk_logger_master_init(struct mk_server_config *config) -{ - int ret; - struct log_target *new; - struct mk_vhost *entry_host; - struct mk_list *hosts = &mk_api->config->hosts; - struct mk_list *head_host; - struct mk_rconf_section *section; - char *access_file_name = NULL; - char *error_file_name = NULL; - pthread_t tid; - (void) config; - - /* Restore STDOUT if we are in background mode */ - if (mk_logger_master_path != NULL && mk_api->config->is_daemon == MK_TRUE) { - mk_logger_master_stdout = freopen(mk_logger_master_path, "ae", stdout); - mk_logger_master_stderr = freopen(mk_logger_master_path, "ae", stderr); - mk_logger_print_details(); - } - - MK_TRACE("Reading virtual hosts"); - - mk_list_init(&targets_list); - - mk_list_foreach(head_host, hosts) { - entry_host = mk_list_entry(head_host, struct mk_vhost, _head); - - /* Read logger section from virtual host configuration */ - section = mk_api->config_section_get(entry_host->config, "LOGGER"); - if (section) { - /* Read configuration entries */ - access_file_name = (char *) mk_api->config_section_get_key(section, - "AccessLog", - MK_RCONF_STR); - error_file_name = (char *) mk_api->config_section_get_key(section, - "ErrorLog", - MK_RCONF_STR); - - if (access_file_name) { - new = mk_api->mem_alloc(sizeof(struct log_target)); - new->is_ok = MK_TRUE; - - /* Set access pipe */ - if (pipe(new->pipe) < 0) { - mk_err("Could not create pipe"); - exit(EXIT_FAILURE); - } - if (fcntl(new->pipe[1], F_SETFL, O_NONBLOCK) == -1) { - perror("fcntl"); - } - if (fcntl(new->pipe[0], F_SETFD, FD_CLOEXEC) == -1) { - perror("fcntl"); - } - if (fcntl(new->pipe[1], F_SETFD, FD_CLOEXEC) == -1) { - perror("fcntl"); - } - new->file = access_file_name; - new->host = entry_host; - mk_list_add(&new->_head, &targets_list); - } - - /* Set error pipe */ - if (error_file_name) { - new = mk_api->mem_alloc(sizeof(struct log_target)); - new->is_ok = MK_FALSE; - - if (pipe(new->pipe) < 0) { - mk_err("Could not create pipe"); - exit(EXIT_FAILURE); - } - if (fcntl(new->pipe[1], F_SETFL, O_NONBLOCK) == -1) { - perror("fcntl"); - } - if (fcntl(new->pipe[0], F_SETFD, FD_CLOEXEC) == -1) { - perror("fcntl"); - } - if (fcntl(new->pipe[1], F_SETFD, FD_CLOEXEC) == -1 ){ - perror("fcntl"); - } - new->file = error_file_name; - new->host = entry_host; - mk_list_add(&new->_head, &targets_list); - - } - } - } - - ret = mk_api->worker_spawn((void *) mk_logger_start_worker, NULL, &tid); - if (ret == -1) { - return -1; - } - - return 0; -} - -void mk_logger_worker_init() -{ - struct mk_iov *iov_log; - mk_ptr_t *content_length; - mk_ptr_t *status; - mk_ptr_t *ip_str; - - - MK_TRACE("Creating thread cache"); - - /* Cache iov log struct */ - iov_log = mk_api->iov_create(15, 0); - pthread_setspecific(cache_iov, (void *) iov_log); - - /* Cache content length */ - content_length = mk_api->mem_alloc_z(sizeof(mk_ptr_t)); - content_length->data = mk_api->mem_alloc_z(MK_UTILS_INT2MKP_BUFFER_LEN); - content_length->len = -1; - pthread_setspecific(cache_content_length, (void *) content_length); - - /* Cahe status */ - status = mk_api->mem_alloc_z(sizeof(mk_ptr_t)); - status->data = mk_api->mem_alloc_z(MK_UTILS_INT2MKP_BUFFER_LEN); - status->len = -1; - pthread_setspecific(cache_status, (void *) status); - - /* Cache IP address */ - ip_str = mk_api->mem_alloc_z(sizeof(mk_ptr_t)); - ip_str->data = mk_api->mem_alloc_z(INET6_ADDRSTRLEN + 1); - ip_str->len = -1; - pthread_setspecific(cache_ip_str, (void *) ip_str); -} - -int mk_logger_stage40(struct mk_http_session *cs, struct mk_http_request *sr) -{ - int i, http_status, ret, tmp; - int array_len = ARRAY_SIZE(response_codes); - int access; - struct log_target *target; - struct mk_iov *iov; - mk_ptr_t *date; - mk_ptr_t *content_length; - mk_ptr_t *ip_str; - mk_ptr_t status; - - /* Set response status */ - http_status = sr->headers.status; - - if (http_status < 400) { - access = MK_TRUE; - } - else { - access = MK_FALSE; - } - - /* Look for target log file */ - target = mk_logger_match_by_host(sr->host_conf, access); - if (!target) { - MK_TRACE("No target found"); - return 0; - } - - /* Get iov cache struct and reset indexes */ - iov = (struct mk_iov *) mk_logger_get_cache(); - iov->iov_idx = 0; - iov->buf_idx = 0; - iov->total_len = 0; - - /* Format IP string */ - ip_str = pthread_getspecific(cache_ip_str); - ret = mk_api->socket_ip_str(cs->socket, - &ip_str->data, - INET6_ADDRSTRLEN + 1, - &ip_str->len); - /* - * If the socket is not longer available ip_str can be null, - * so we must check this condition and return - */ - if (mk_unlikely(ret < 0)) { - return 0; - } - - /* Add IP to IOV */ - mk_api->iov_add(iov, - ip_str->data, ip_str->len, - MK_FALSE); - mk_api->iov_add(iov, - mk_logger_iov_dash.data, - mk_logger_iov_dash.len, - MK_FALSE); - - /* Date/time when object was requested */ - date = mk_api->time_human(cs->server); - mk_api->iov_add(iov, - date->data, date->len, - MK_FALSE); - mk_api->iov_add(iov, - mk_logger_iov_space.data, - mk_logger_iov_space.len, - MK_FALSE); - - /* Access Log */ - if (http_status < 400) { - /* No access file defined */ - if (!target->file) { - return 0; - } - - /* HTTP Method */ - mk_api->iov_add(iov, - sr->method_p.data, - sr->method_p.len, - MK_FALSE); - mk_api->iov_add(iov, - mk_logger_iov_space.data, - mk_logger_iov_space.len, - MK_FALSE); - - /* HTTP URI required */ - mk_api->iov_add(iov, - sr->uri.data, sr->uri.len, - MK_FALSE); - mk_api->iov_add(iov, - mk_logger_iov_space.data, - mk_logger_iov_space.len, - MK_FALSE); - - /* HTTP Protocol */ - mk_api->iov_add(iov, - sr->protocol_p.data, sr->protocol_p.len, - MK_FALSE); - mk_api->iov_add(iov, - mk_logger_iov_space.data, - mk_logger_iov_space.len, - MK_FALSE); - - /* HTTP Status code response */ - for (i=0; i < array_len; i++) { - if (response_codes[i].i_status == http_status) { - break; - } - } - - if (array_len == i) { - mk_api->str_itop(http_status, &status); - status.len -= 2; - } - else { - status.data = response_codes[i].s_status; - status.len = 3; - } - mk_api->iov_add(iov, - status.data, - status.len, - MK_FALSE); - mk_api->iov_add(iov, - mk_logger_iov_space.data, - mk_logger_iov_space.len, - MK_FALSE); - - /* Content Length */ - if (sr->method != MK_METHOD_HEAD) { - /* Int to mk_ptr_t */ - content_length = pthread_getspecific(cache_content_length); - - tmp = sr->headers.content_length; - if (tmp < 0) { - tmp = 0; - } - - mk_api->str_itop(tmp, content_length); - - mk_api->iov_add(iov, - content_length->data, content_length->len - 2, - MK_FALSE); - mk_api->iov_add(iov, - mk_logger_iov_lf.data, - mk_logger_iov_lf.len, - MK_FALSE); - } - else { - mk_api->iov_add(iov, - mk_logger_iov_empty.data, - mk_logger_iov_empty.len, - MK_FALSE); - mk_api->iov_add(iov, - mk_logger_iov_lf.data, - mk_logger_iov_lf.len, - MK_FALSE); - } - - /* Write iov array to pipe */ - mk_api->iov_send(target->pipe[1], iov); - } - else { - if (mk_unlikely(!target->file)) { - return 0; - } - - /* For unknown errors. Needs to exist until iov_send. */ - char err_str[80]; - - switch (http_status) { - case MK_CLIENT_BAD_REQUEST: - mk_api->iov_add(iov, - error_msg_400.data, - error_msg_400.len, - MK_FALSE); - mk_api->iov_add(iov, - mk_logger_iov_lf.data, - mk_logger_iov_lf.len, - MK_FALSE); - break; - case MK_CLIENT_FORBIDDEN: - mk_api->iov_add(iov, - error_msg_403.data, - error_msg_403.len, - MK_FALSE); - mk_api->iov_add(iov, - mk_logger_iov_space.data, - mk_logger_iov_space.len, - MK_FALSE); - mk_api->iov_add(iov, - sr->uri.data, - sr->uri.len, - MK_FALSE); - mk_api->iov_add(iov, - mk_logger_iov_lf.data, - mk_logger_iov_lf.len, - MK_FALSE); - - break; - case MK_CLIENT_NOT_FOUND: - mk_api->iov_add(iov, - error_msg_404.data, - error_msg_404.len, - MK_FALSE); - mk_api->iov_add(iov, - mk_logger_iov_space.data, - mk_logger_iov_space.len, - MK_FALSE); - - mk_api->iov_add(iov, - sr->uri.data, - sr->uri.len, - MK_FALSE); - mk_api->iov_add(iov, - mk_logger_iov_lf.data, - mk_logger_iov_lf.len, - MK_FALSE); - - break; - case MK_CLIENT_METHOD_NOT_ALLOWED: - mk_api->iov_add(iov, - error_msg_405.data, - error_msg_405.len, - MK_FALSE); - mk_api->iov_add(iov, - mk_logger_iov_space.data, - mk_logger_iov_space.len, - MK_FALSE); - mk_api->iov_add(iov, - sr->method_p.data, - sr->method_p.len, - MK_FALSE); - mk_api->iov_add(iov, - mk_logger_iov_lf.data, - mk_logger_iov_lf.len, - MK_FALSE); - break; - case MK_CLIENT_REQUEST_TIMEOUT: - mk_api->iov_add(iov, - error_msg_408.data, - error_msg_408.len, - MK_FALSE); - mk_api->iov_add(iov, - mk_logger_iov_lf.data, - mk_logger_iov_lf.len, - MK_FALSE); - break; - case MK_CLIENT_LENGTH_REQUIRED: - mk_api->iov_add(iov, - error_msg_411.data, - error_msg_411.len, - MK_FALSE); - mk_api->iov_add(iov, - mk_logger_iov_lf.data, - mk_logger_iov_lf.len, - MK_FALSE); - break; - case MK_CLIENT_REQUEST_ENTITY_TOO_LARGE: - mk_api->iov_add(iov, - error_msg_413.data, - error_msg_413.len, - MK_FALSE); - mk_api->iov_add(iov, - mk_logger_iov_lf.data, - mk_logger_iov_lf.len, - MK_FALSE); - break; - case MK_SERVER_NOT_IMPLEMENTED: - mk_api->iov_add(iov, - error_msg_501.data, - error_msg_501.len, - MK_FALSE); - mk_api->iov_add(iov, - mk_logger_iov_space.data, - mk_logger_iov_space.len, - MK_FALSE); - mk_api->iov_add(iov, - sr->method_p.data, - sr->method_p.len, - MK_FALSE); - mk_api->iov_add(iov, - mk_logger_iov_lf.data, - mk_logger_iov_lf.len, - MK_FALSE); - break; - case MK_SERVER_INTERNAL_ERROR: - mk_api->iov_add(iov, - error_msg_500.data, - error_msg_500.len, - MK_FALSE); - mk_api->iov_add(iov, - mk_logger_iov_space.data, - mk_logger_iov_space.len, - MK_FALSE); - break; - case MK_SERVER_HTTP_VERSION_UNSUP: - mk_api->iov_add(iov, - error_msg_505.data, - error_msg_505.len, - MK_FALSE); - mk_api->iov_add(iov, - mk_logger_iov_lf.data, - mk_logger_iov_lf.len, - MK_FALSE); - break; - default: - { - int len = snprintf(err_str, 80, "[error %u] (no description)", http_status); - err_str[79] = '\0'; - if (len > 79) len = 79; - - mk_api->iov_add(iov, - err_str, - len, - MK_FALSE); - mk_api->iov_add(iov, - mk_logger_iov_space.data, - mk_logger_iov_space.len, - MK_FALSE); - mk_api->iov_add(iov, - sr->uri.data, - sr->uri.len, - MK_FALSE); - mk_api->iov_add(iov, - mk_logger_iov_lf.data, - mk_logger_iov_lf.len, - MK_FALSE); - } - break; - } - - - /* Write iov array to pipe */ - mk_api->iov_send(target->pipe[1], iov); - } - - return 0; -} - -struct mk_plugin_stage mk_plugin_stage_logger = { - .stage40 = &mk_logger_stage40 -}; - -struct mk_plugin mk_plugin_logger = { - /* Identification */ - .shortname = "logger", - .name = "Log Writer", - .version = MK_VERSION_STR, - .hooks = MK_PLUGIN_STAGE, - - /* Init / Exit */ - .init_plugin = mk_logger_plugin_init, - .exit_plugin = mk_logger_plugin_exit, - - /* Init Levels */ - .master_init = mk_logger_master_init, - .worker_init = mk_logger_worker_init, - - /* Type */ - .stage = &mk_plugin_stage_logger -}; diff --git a/fluent-bit/lib/monkey/plugins/logger/logger.h b/fluent-bit/lib/monkey/plugins/logger/logger.h deleted file mode 100644 index 6c9668bf4..000000000 --- a/fluent-bit/lib/monkey/plugins/logger/logger.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* s_log status */ -#ifndef MK_LOGGER_H -#define MK_LOGGER_H - -#include <stdio.h> -#include <monkey/mk_api.h> - -#define MK_LOGGER_PIPE_LIMIT 0.75 -#define MK_LOGGER_TIMEOUT_DEFAULT 3 - -int mk_logger_timeout; - -/* MasterLog variables */ -char *mk_logger_master_path; -FILE *mk_logger_master_stdout; -FILE *mk_logger_master_stderr; - -pthread_key_t cache_content_length; -pthread_key_t cache_status; -pthread_key_t cache_ip_str; -pthread_key_t cache_iov; - -struct log_target -{ - struct mk_event event; - - /* Pipes */ - int is_ok; - int pipe[2]; - char *file; - - struct mk_vhost *host; - struct mk_list _head; -}; - -struct mk_list targets_list; - - -#endif diff --git a/fluent-bit/lib/monkey/plugins/logger/pointers.c b/fluent-bit/lib/monkey/plugins/logger/pointers.c deleted file mode 100644 index 11c48906a..000000000 --- a/fluent-bit/lib/monkey/plugins/logger/pointers.c +++ /dev/null @@ -1,43 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <monkey/mk_plugin.h> - -#include "logger.h" -#include "pointers.h" - -const mk_ptr_t mk_logger_iov_none = mk_ptr_init(""); - -/* Writter helpers */ -const mk_ptr_t mk_logger_iov_dash = mk_ptr_init(MK_LOGGER_IOV_DASH); -const mk_ptr_t mk_logger_iov_space = mk_ptr_init(MK_IOV_SPACE); -const mk_ptr_t mk_logger_iov_lf = mk_ptr_init(MK_IOV_LF); -const mk_ptr_t mk_logger_iov_empty = mk_ptr_init(MK_LOGGER_IOV_EMPTY); - -/* Error messages */ -const mk_ptr_t error_msg_400 = mk_ptr_init(ERROR_MSG_400); -const mk_ptr_t error_msg_403 = mk_ptr_init(ERROR_MSG_403); -const mk_ptr_t error_msg_404 = mk_ptr_init(ERROR_MSG_404); -const mk_ptr_t error_msg_405 = mk_ptr_init(ERROR_MSG_405); -const mk_ptr_t error_msg_408 = mk_ptr_init(ERROR_MSG_408); -const mk_ptr_t error_msg_411 = mk_ptr_init(ERROR_MSG_411); -const mk_ptr_t error_msg_413 = mk_ptr_init(ERROR_MSG_413); -const mk_ptr_t error_msg_500 = mk_ptr_init(ERROR_MSG_500); -const mk_ptr_t error_msg_501 = mk_ptr_init(ERROR_MSG_501); -const mk_ptr_t error_msg_505 = mk_ptr_init(ERROR_MSG_505); diff --git a/fluent-bit/lib/monkey/plugins/logger/pointers.h b/fluent-bit/lib/monkey/plugins/logger/pointers.h deleted file mode 100644 index d353c2583..000000000 --- a/fluent-bit/lib/monkey/plugins/logger/pointers.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MK_LOGGER_POINTERS_H -#define MK_LOGGER_POINTERS_H - -#include <memory.h> - -/* Request error messages for log file */ -#define ERROR_MSG_400 "[error 400] Bad Request" -#define ERROR_MSG_403 "[error 403] Forbidden" -#define ERROR_MSG_404 "[error 404] Not Found" -#define ERROR_MSG_405 "[error 405] Method Not Allowed" -#define ERROR_MSG_408 "[error 408] Request Timeout" -#define ERROR_MSG_411 "[error 411] Length Required" -#define ERROR_MSG_413 "[error 413] Request Entity Too Large" -#define ERROR_MSG_500 "[error 500] Internal Server Error" -#define ERROR_MSG_501 "[error 501] Not Implemented" -#define ERROR_MSG_505 "[error 505] HTTP Version Not Supported" - -#define MK_LOGGER_IOV_DASH " - " -#define MK_LOGGER_IOV_SPACE " " -#define MK_LOGGER_IOV_EMPTY "-" - -/* mk pointers for errors */ -extern const mk_ptr_t error_msg_400; -extern const mk_ptr_t error_msg_403; -extern const mk_ptr_t error_msg_404; -extern const mk_ptr_t error_msg_405; -extern const mk_ptr_t error_msg_408; -extern const mk_ptr_t error_msg_411; -extern const mk_ptr_t error_msg_413; -extern const mk_ptr_t error_msg_500; -extern const mk_ptr_t error_msg_501; -extern const mk_ptr_t error_msg_505; - -/* mk pointer for IOV */ -extern const mk_ptr_t mk_logger_iov_dash; -extern const mk_ptr_t mk_logger_iov_space; -extern const mk_ptr_t mk_logger_iov_lf; -extern const mk_ptr_t mk_logger_iov_empty; - -#endif diff --git a/fluent-bit/lib/monkey/plugins/mandril/CMakeLists.txt b/fluent-bit/lib/monkey/plugins/mandril/CMakeLists.txt deleted file mode 100644 index ba2e95717..000000000 --- a/fluent-bit/lib/monkey/plugins/mandril/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -set(src - mandril.c - ) - -MONKEY_PLUGIN(mandril "${src}") -add_subdirectory(conf) diff --git a/fluent-bit/lib/monkey/plugins/mandril/conf/CMakeLists.txt b/fluent-bit/lib/monkey/plugins/mandril/conf/CMakeLists.txt deleted file mode 100644 index 44e95175c..000000000 --- a/fluent-bit/lib/monkey/plugins/mandril/conf/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -set(conf_dir "${MK_PATH_CONF}/plugins/mandril/") - -install(DIRECTORY DESTINATION ${conf_dir}) - -if(BUILD_LOCAL) - file(COPY mandril.conf DESTINATION ${conf_dir}) -else() - install(FILES mandril.conf DESTINATION ${conf_dir}) -endif() diff --git a/fluent-bit/lib/monkey/plugins/mandril/conf/mandril.conf b/fluent-bit/lib/monkey/plugins/mandril/conf/mandril.conf deleted file mode 100644 index efeaf5d9a..000000000 --- a/fluent-bit/lib/monkey/plugins/mandril/conf/mandril.conf +++ /dev/null @@ -1,57 +0,0 @@ -# Monkey HTTP Daemon - Mandril -# ============================ -# Mandril Plugin provide security rules to be applied to the incomming -# connections. If the client is rejected by some rule, it will get the -# 403 Forbidden error status. -# -# It supports two restriction modes, by request URI and by IP (or network -# range), make sure all your rules are defined under the section [RULES]: -# -# a) Restriction by request URI: -# -# You can define multiple keywords to restrict a specific incoming -# request which hold that string. Check this example: -# -# [RULES] -# URL documents -# URL pictures -# URL /private -# -# b) Restriction by IP or network range: -# -# Multiple rules can be defined to deny the access to specific incoming -# clients: -# -# [RULES] -# IP 10.20.1.1/24 -# IP 192.168.3.150 -# -# In the first rule we are blocking a range of IPs from 10.20.1.1 to -# 10.20.1.255. In the second example just one specific IP address. -# -# It also supports denying hotlinking from other domains. -# -# c) -# -# [RULES] -# deny_hotlink /imgs -# -# This rule will prevent access to all files under /imgs if the -# request's Referer header is not from the same domain or its -# subdomains. -# If the Referer header is missing, the request will be accepted. -# -# You can mix the rules type under the [RULE] section, so the following example -# is totally valid: -# -# [RULES] -# URL documents -# URL pictures -# URL /private -# IP 10.20.1.1/24 -# IP 192.168.3.150 -# - -[RULES] - # IP 127.0.0.1 - # URL /imgs diff --git a/fluent-bit/lib/monkey/plugins/mandril/mandril.c b/fluent-bit/lib/monkey/plugins/mandril/mandril.c deleted file mode 100644 index e8a988d08..000000000 --- a/fluent-bit/lib/monkey/plugins/mandril/mandril.c +++ /dev/null @@ -1,403 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * Copyright 2012, Sonny Karlsson - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* Monkey API */ -#include <monkey/mk_api.h> - - -/* system */ -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <sys/stat.h> - -#include "mandril.h" - -static struct mk_rconf *conf; - -/* Read database configuration parameters */ -static int mk_security_conf(struct mk_plugin *plugin, char *confdir) -{ - int n; - int ret = 0; - unsigned long len; - char *conf_path = NULL; - char *_net, *_mask; - - struct mk_secure_ip_t *new_ip; - struct mk_secure_url_t *new_url; - struct mk_secure_deny_hotlink_t *new_deny_hotlink; - - struct mk_rconf_section *section; - struct mk_rconf_entry *entry; - struct mk_list *head; - - /* Read configuration */ - plugin->api->str_build(&conf_path, &len, "%s/mandril.conf", confdir); - conf = plugin->api->config_open(conf_path); - if (!conf) { - return -1; - } - - section = plugin->api->config_section_get(conf, "RULES"); - if (!section) { - return -1; - } - - mk_list_foreach(head, §ion->entries) { - entry = mk_list_entry(head, struct mk_rconf_entry, _head); - - /* Passing to internal struct */ - if (strcasecmp(entry->key, "IP") == 0) { - new_ip = plugin->api->mem_alloc(sizeof(struct mk_secure_ip_t)); - n = plugin->api->str_search(entry->val, "/", 1); - - /* subnet */ - if (n > 0) { - /* split network addr and netmask */ - _net = plugin->api->str_copy_substr(entry->val, 0, n); - _mask = plugin->api->str_copy_substr(entry->val, - n + 1, - strlen(entry->val)); - - /* validations... */ - if (!_net || !_mask) { - mk_warn_ex(plugin->api, - "Mandril: cannot parse entry '%s' in RULES section", - entry->val); - goto ip_next; - } - - /* convert ip string to network address */ - if (inet_aton(_net, &new_ip->ip) == 0) { - mk_warn_ex(plugin->api, - "Mandril: invalid ip address '%s' in RULES section", - entry->val); - goto ip_next; - } - - /* parse mask */ - new_ip->netmask = strtol(_mask, (char **) NULL, 10); - if (new_ip->netmask <= 0 || new_ip->netmask >= 32) { - mk_warn_ex(plugin->api, - "Mandril: invalid mask value '%s' in RULES section", - entry->val); - goto ip_next; - } - - /* complete struct data */ - new_ip->is_subnet = MK_TRUE; - new_ip->network = MK_NET_NETWORK(new_ip->ip.s_addr, new_ip->netmask); - new_ip->hostmin = MK_NET_HOSTMIN(new_ip->ip.s_addr, new_ip->netmask); - new_ip->hostmax = MK_NET_HOSTMAX(new_ip->ip.s_addr, new_ip->netmask); - - /* link node with main list */ - mk_list_add(&new_ip->_head, &mk_secure_ip); - - /* - * I know, you were instructed to hate 'goto' statements!, ok, show this - * code to your teacher and let him blame :P - */ - ip_next: - if (_net) { - plugin->api->mem_free(_net); - } - if (_mask) { - plugin->api->mem_free(_mask); - } - } - else { /* normal IP address */ - - /* convert ip string to network address */ - if (inet_aton(entry->val, &new_ip->ip) == 0) { - mk_warn_ex(plugin->api, - "Mandril: invalid ip address '%s' in RULES section", - entry->val); - } - else { - new_ip->is_subnet = MK_FALSE; - mk_list_add(&new_ip->_head, &mk_secure_ip); - } - } - } - else if (strcasecmp(entry->key, "URL") == 0) { - /* simple allcotion and data association */ - new_url = plugin->api->mem_alloc(sizeof(struct mk_secure_url_t)); - new_url->criteria = entry->val; - - /* link node with main list */ - mk_list_add(&new_url->_head, &mk_secure_url); - } - else if (strcasecmp(entry->key, "deny_hotlink") == 0) { - new_deny_hotlink = plugin->api->mem_alloc(sizeof(*new_deny_hotlink)); - new_deny_hotlink->criteria = entry->val; - - mk_list_add(&new_deny_hotlink->_head, &mk_secure_deny_hotlink); - } - } - - plugin->api->mem_free(conf_path); - - return ret; -} - -static int mk_security_check_ip(int socket) -{ - int network; - struct mk_secure_ip_t *entry; - struct mk_list *head; - struct in_addr *addr; - struct sockaddr_in addr_t = {0}; - socklen_t len = sizeof(addr_t); - - if (getpeername(socket, (struct sockaddr *) &addr_t, &len) != 0) { - perror("getpeername"); - return -1; - } - - addr = &(addr_t).sin_addr; - - PLUGIN_TRACE("[FD %i] Mandril validating IP address", socket); - mk_list_foreach(head, &mk_secure_ip) { - entry = mk_list_entry(head, struct mk_secure_ip_t, _head); - - if (entry->is_subnet == MK_TRUE) { - /* Validate network */ - network = MK_NET_NETWORK(addr->s_addr, entry->netmask); - if (network != entry->network) { - continue; - } - /* Validate host range */ - if (addr->s_addr <= entry->hostmax && addr->s_addr >= entry->hostmin) { - PLUGIN_TRACE("[FD %i] Mandril closing by rule in ranges", socket); - return -1; - } - } - else { - if (addr->s_addr == entry->ip.s_addr) { - PLUGIN_TRACE("[FD %i] Mandril closing by rule in IP match", socket); - return -1; - } - } - } - return 0; -} - -/* Check if the incoming URL is restricted for some rule */ -static int mk_security_check_url(struct mk_plugin *plugin, mk_ptr_t url) -{ - int n; - struct mk_list *head; - struct mk_secure_url_t *entry; - - mk_list_foreach(head, &mk_secure_url) { - entry = mk_list_entry(head, struct mk_secure_url_t, _head); - n = plugin->api->str_search_n(url.data, entry->criteria, MK_STR_INSENSITIVE, url.len); - if (n >= 0) { - return -1; - } - } - - return 0; -} - -mk_ptr_t parse_referer_host(struct mk_http_header *header) -{ - unsigned int i, beginHost, endHost; - mk_ptr_t host; - - host.data = NULL; - host.len = 0; - - // Find end of "protocol://" - for (i = 0; i < header->val.len && !(header->val.data[i] == '/' && header->val.data[i+1] == '/'); i++); - if (i == header->val.len) { - goto error; - } - beginHost = i + 2; - - // Find end of any "user:password@" - for (; i < header->val.len && header->val.data[i] != '@'; i++); - if (i < header->val.len) { - beginHost = i + 1; - } - - // Find end of "host", (beginning of :port or /path) - for (i = beginHost; i < header->val.len && header->val.data[i] != ':' && header->val.data[i] != '/'; i++); - endHost = i; - - host.data = header->val.data + beginHost; - host.len = endHost - beginHost; - return host; -error: - host.data = NULL; - host.len = 0; - return host; -} - -static int mk_security_check_hotlink(struct mk_plugin *plugin, - mk_ptr_t url, mk_ptr_t host, - struct mk_http_header *referer) -{ - mk_ptr_t ref_host = parse_referer_host(referer); - unsigned int domains_matched = 0; - int i = 0; - const char *curA, *curB; - struct mk_list *head; - struct mk_secure_deny_hotlink_t *entry; - - if (ref_host.data == NULL) { - return 0; - } - else if (host.data == NULL) { - mk_err_ex(plugin->api, "No host data."); - return -1; - } - - mk_list_foreach(head, &mk_secure_url) { - entry = mk_list_entry(head, struct mk_secure_deny_hotlink_t, _head); - i = plugin->api->str_search_n(url.data, entry->criteria, MK_STR_INSENSITIVE, url.len); - if (i >= 0) { - break; - } - } - if (i < 0) { - return 0; - } - - curA = host.data + host.len; - curB = ref_host.data + ref_host.len; - - // Match backwards from root domain. - while (curA > host.data && curB > ref_host.data) { - i++; - curA--; - curB--; - - if ((*curA == '.' && *curB == '.') || - curA == host.data || curB == ref_host.data) { - if (i < 1) { - break; - } - else if (curA == host.data && - !(curB == ref_host.data || *(curB - 1) == '.')) { - break; - } - else if (curB == ref_host.data && - !(curA == host.data || *(curA - 1) == '.')) { - break; - } - else if (strncasecmp(curA, curB, i)) { - break; - } - domains_matched += 1; - i = 0; - } - } - - // Block connection if none or only top domain matched. - return domains_matched >= 2 ? 0 : -1; -} - -int mk_mandril_plugin_init(struct mk_plugin *plugin, char *confdir) -{ - /* Init security lists */ - mk_list_init(&mk_secure_ip); - mk_list_init(&mk_secure_url); - mk_list_init(&mk_secure_deny_hotlink); - - /* Read configuration */ - mk_security_conf(plugin, confdir); - - return 0; -} - -int mk_mandril_plugin_exit() -{ - return 0; -} - -int mk_mandril_stage10(int socket) -{ - /* Validate ip address with Mandril rules */ - if (mk_security_check_ip(socket) != 0) { - PLUGIN_TRACE("[FD %i] Mandril close connection", socket); - return MK_PLUGIN_RET_CLOSE_CONX; - } - - return MK_PLUGIN_RET_CONTINUE; -} - -int mk_mandril_stage30(struct mk_plugin *p, - struct mk_http_session *cs, - struct mk_http_request *sr, - int n_params, - struct mk_list *params) -{ - (void) p; - (void) cs; - (void) n_params; - (void) params; - - struct mk_http_header *header; - - PLUGIN_TRACE("[FD %i] Mandril validating URL", cs->socket); - - if (mk_security_check_url(p, sr->uri_processed) < 0) { - PLUGIN_TRACE("[FD %i] Close connection, blocked URL", cs->socket); - p->api->header_set_http_status(sr, MK_CLIENT_FORBIDDEN); - return MK_PLUGIN_RET_CLOSE_CONX; - } - - PLUGIN_TRACE("[FD %d] Mandril validating hotlinking", cs->socket); - - header = p->api->header_get(MK_HEADER_REFERER, sr, NULL, 0); - if (mk_security_check_hotlink(p, sr->uri_processed, sr->host, header) < 0) { - PLUGIN_TRACE("[FD %i] Close connection, deny hotlinking.", cs->socket); - p->api->header_set_http_status(sr, MK_CLIENT_FORBIDDEN); - return MK_PLUGIN_RET_CLOSE_CONX; - } - - return MK_PLUGIN_RET_NOT_ME; -} - -struct mk_plugin_stage mk_plugin_stage_mandril = { - .stage10 = &mk_mandril_stage10, - .stage30 = &mk_mandril_stage30 -}; - -struct mk_plugin mk_plugin_mandril = { - /* Identification */ - .shortname = "mandril", - .name = "Mandril Security", - .version = MK_VERSION_STR, - .hooks = MK_PLUGIN_STAGE, - - /* Init / Exit */ - .init_plugin = mk_mandril_plugin_init, - .exit_plugin = mk_mandril_plugin_exit, - - /* Init Levels */ - .master_init = NULL, - .worker_init = NULL, - - /* Type */ - .stage = &mk_plugin_stage_mandril -}; diff --git a/fluent-bit/lib/monkey/plugins/mandril/mandril.h b/fluent-bit/lib/monkey/plugins/mandril/mandril.h deleted file mode 100644 index 6cadf3857..000000000 --- a/fluent-bit/lib/monkey/plugins/mandril/mandril.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * Copyright 2012, Sonny Karlsson - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* security.c */ -#ifndef MK_SECURITY_H -#define MK_SECURITY_H - -struct mk_secure_ip_t -{ - struct in_addr ip; - - /* if subnet is true, next fields are populated */ - int is_subnet; - - int network; - int netmask; - unsigned int hostmin; - unsigned int hostmax; - - /* list head linker */ - struct mk_list _head; -}; - -struct mk_secure_url_t -{ - char *criteria; - struct mk_list _head; -}; - -struct mk_secure_deny_hotlink_t -{ - char *criteria; - struct mk_list _head; -}; - -struct mk_list mk_secure_ip; -struct mk_list mk_secure_url; -struct mk_list mk_secure_deny_hotlink; - -#endif diff --git a/fluent-bit/lib/monkey/plugins/tls/CMakeLists.txt b/fluent-bit/lib/monkey/plugins/tls/CMakeLists.txt deleted file mode 100644 index 2bde86cac..000000000 --- a/fluent-bit/lib/monkey/plugins/tls/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -set(src - tls.c -) - -if(NOT WITH_MBEDTLS_SHARED) - option(ENABLE_TESTING OFF) - option(ENABLE_PROGRAMS OFF) - option(INSTALL_MBEDTLS_HEADERS OFF) - set(MK_MBEDTLS_SRC ../../deps/mbedtls-2.4.2) - add_subdirectory(${MK_MBEDTLS_SRC} ${CMAKE_BINARY_DIR}/mbedtls-2.4.2) - include_directories(${MK_MBEDTLS_SRC}/include) -endif() - -MONKEY_PLUGIN(tls "${src}") - -MONKEY_PLUGIN_LINK_LIB(tls mbedtls) -add_subdirectory(conf) diff --git a/fluent-bit/lib/monkey/plugins/tls/conf/CMakeLists.txt b/fluent-bit/lib/monkey/plugins/tls/conf/CMakeLists.txt deleted file mode 100644 index c1886d340..000000000 --- a/fluent-bit/lib/monkey/plugins/tls/conf/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -set(conf_dir "${MK_PATH_CONF}/plugins/tls/") - -install(DIRECTORY DESTINATION ${conf_dir}) - -if(BUILD_LOCAL) - file(COPY tls.conf DESTINATION ${conf_dir}) -else() - install(FILES tls.conf DESTINATION ${conf_dir}) -endif() diff --git a/fluent-bit/lib/monkey/plugins/tls/conf/tls.conf b/fluent-bit/lib/monkey/plugins/tls/conf/tls.conf deleted file mode 100644 index fcf00517a..000000000 --- a/fluent-bit/lib/monkey/plugins/tls/conf/tls.conf +++ /dev/null @@ -1,25 +0,0 @@ -[TLS] - # If no absolute path is given, files are assumed to be located - # in plugin configuration directory. All files are assumed to be - # stored in PEM format. - - # Server certificate - # - CertificateFile srv_cert.pem - - # Certificate chain - # - # Not required, but can speed-up handshakes. - # - # CertificateChainFile srv_cert_chain.pem - - # Server RSA key - # - RSAKeyFile rsa_key.pem - - # Diffie-Hellman parameters - # - # Generate using openssl: - # $ openssl dhparam -out dhparam.pem 1024 - # - DHParameterFile dhparam.pem diff --git a/fluent-bit/lib/monkey/plugins/tls/tls.c b/fluent-bit/lib/monkey/plugins/tls/tls.c deleted file mode 100644 index 94c2afc58..000000000 --- a/fluent-bit/lib/monkey/plugins/tls/tls.c +++ /dev/null @@ -1,862 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Monkey HTTP Server - * ================== - * Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define _GNU_SOURCE - -#include <stdio.h> -#include <errno.h> -#include <assert.h> -#include <unistd.h> - -#include <arpa/inet.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netdb.h> -#include <pthread.h> - -#include <mbedtls/version.h> -#include <mbedtls/error.h> -#include <mbedtls/net.h> -#include <mbedtls/ssl.h> -#include <mbedtls/bignum.h> -#include <mbedtls/entropy.h> -#include <mbedtls/ctr_drbg.h> -#include <mbedtls/certs.h> -#include <mbedtls/x509.h> -#include <mbedtls/ssl_cache.h> -#include <mbedtls/pk.h> -#include <mbedtls/dhm.h> -#include <monkey/mk_api.h> - -#ifndef SENDFILE_BUF_SIZE -#define SENDFILE_BUF_SIZE MBEDTLS_SSL_MAX_CONTENT_LEN -#endif - -#ifndef POLAR_DEBUG_LEVEL -#define POLAR_DEBUG_LEVEL 0 -#endif - -#if (!defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_ENTROPY_C) || \ - !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_SRV_C) || \ - !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_RSA_C) || \ - !defined(MBEDTLS_CTR_DRBG_C)) -#error "One or more required POLARSSL modules not built." -#endif - -struct polar_config { - char *cert_file; - char *cert_chain_file; - char *key_file; - char *dh_param_file; - int8_t check_client_cert; -}; - -#if defined(MBEDTLS_SSL_CACHE_C) -struct polar_sessions { - pthread_mutex_t _mutex; - mbedtls_ssl_cache_context cache; -}; - -static struct polar_sessions global_sessions = { - ._mutex = PTHREAD_MUTEX_INITIALIZER, -}; - -#endif - -struct polar_context_head { - mbedtls_ssl_context context; - int fd; - struct polar_context_head *_next; -}; - -struct polar_thread_context { - - struct polar_context_head *contexts; - mbedtls_ctr_drbg_context ctr_drbg; - mbedtls_pk_context pkey; - mbedtls_ssl_config conf; - - struct mk_list _head; -}; - -struct polar_server_context { - - struct polar_config config; - mbedtls_x509_crt cert; - mbedtls_x509_crt ca_cert; - pthread_mutex_t mutex; - mbedtls_dhm_context dhm; - mbedtls_entropy_context entropy; - struct polar_thread_context threads; -}; - -struct polar_server_context *server_context; -static const char *my_dhm_P = MBEDTLS_DHM_RFC5114_MODP_2048_P; -static const char *my_dhm_G = MBEDTLS_DHM_RFC5114_MODP_2048_G; - -static pthread_key_t local_context; - -/* - * The following function is taken from PolarSSL sources to get - * the number of available bytes to read from a buffer. - * - * We copy this to make it inline and avoid extra context switches - * on each read routine. - */ -static inline size_t polar_get_bytes_avail(const mbedtls_ssl_context *ssl) -{ - return (ssl->in_offt == NULL ? 0 : ssl->in_msglen); -} - -static struct polar_thread_context *local_thread_context(void) -{ - return pthread_getspecific(local_context); -} - -#if (POLAR_DEBUG_LEVEL > 0) -static void polar_debug(void *ctx, int level, const char *str) -{ - (void)ctx; - - if (level < POLAR_DEBUG_LEVEL) { - mk_warn("%.*s", (int)strlen(str) - 1, str); - } -} -#endif - -static int handle_return(int ret) -{ -#if defined(TRACE) - char err_buf[72]; - if (ret < 0) { - mbedtls_strerror(ret, err_buf, sizeof(err_buf)); - PLUGIN_TRACE("[tls] SSL error: %s", err_buf); - } -#endif - if (ret < 0) { - switch( ret ) - { - case MBEDTLS_ERR_SSL_WANT_READ: - case MBEDTLS_ERR_SSL_WANT_WRITE: - if (errno != EAGAIN) - errno = EAGAIN; - return -1; - case MBEDTLS_ERR_SSL_CONN_EOF: - return 0; - default: - if (errno == EAGAIN) - errno = 0; - return -1; - } - } - else { - return ret; - } -} - -static int tls_cache_get(void *p, mbedtls_ssl_session *session) -{ - struct polar_sessions *session_cache; - int ret; - - session_cache = p; - pthread_mutex_lock(&session_cache->_mutex); - ret = mbedtls_ssl_cache_get(&session_cache->cache, session); - pthread_mutex_unlock(&session_cache->_mutex); - - return ret; -} - -static int tls_cache_set(void *p, const mbedtls_ssl_session *session) -{ - struct polar_sessions *session_cache; - int ret; - - session_cache = p; - pthread_mutex_lock(&session_cache->_mutex); - ret = mbedtls_ssl_cache_set(&session_cache->cache, session); - pthread_mutex_unlock(&session_cache->_mutex); - - return ret; -} - -static int config_parse(const char *confdir, struct polar_config *conf) -{ - long unsigned int len; - char *conf_path = NULL; - char *cert_file = NULL; - char *cert_chain_file = NULL; - char *key_file = NULL; - char *dh_param_file = NULL; - int8_t check_client_cert = MK_FALSE; - struct mk_rconf_section *section; - struct mk_rconf *conf_head; - - mk_api->str_build(&conf_path, &len, "%stls.conf", confdir); - conf_head = mk_api->config_open(conf_path); - mk_api->mem_free(conf_path); - - if (conf_head == NULL) { - goto fallback; - } - - section = mk_api->config_section_get(conf_head, "TLS"); - if (!section) { - goto fallback; - } - - cert_file = mk_api->config_section_get_key(section, - "CertificateFile", - MK_RCONF_STR); - cert_chain_file = mk_api->config_section_get_key(section, - "CertificateChainFile", - MK_RCONF_STR); - key_file = mk_api->config_section_get_key(section, - "RSAKeyFile", - MK_RCONF_STR); - dh_param_file = mk_api->config_section_get_key(section, - "DHParameterFile", - MK_RCONF_STR); - - check_client_cert = mk_api->config_section_get_key(section, - "CheckClientCert", - MK_RCONF_BOOL); -fallback: - /* Set default name if not specified */ - if (!cert_file) { - mk_api->str_build(&conf->cert_file, &len, - "%ssrv_cert.pem", confdir); - } - else { - /* Set absolute path or compose a new one based on the relative */ - if (*cert_file == '/') { - conf->cert_file = cert_file; - } - else { - mk_api->str_build(&conf->cert_file, &len, - "%s/%s", confdir, cert_file); - } - } - - /* Set default name if not specified */ - if (cert_chain_file) { - /* Set absolute path or compose a new one based on the relative */ - if (*cert_chain_file == '/') { - conf->cert_chain_file = cert_chain_file; - } - else { - mk_api->str_build(&conf->cert_chain_file, &len, - "%s/%s", confdir, cert_chain_file); - } - } - else { - conf->cert_chain_file = NULL; - } - - /* Set default name if not specified */ - if (!key_file) { - mk_api->str_build(&conf->key_file, &len, - "%srsa.pem", confdir); - } - else { - /* Set absolute path or compose a new one based on the relative */ - if (*key_file == '/') { - conf->key_file = key_file; - } - else { - mk_api->str_build(&conf->key_file, &len, - "%s/%s", confdir, key_file); - } - } - - /* Set default name if not specified */ - if (!dh_param_file) { - mk_api->str_build(&conf->dh_param_file, &len, - "%sdhparam.pem", confdir); - } - else { - /* Set absolute path or compose a new one based on the relative */ - if (*dh_param_file == '/') { - conf->dh_param_file = dh_param_file; - } - else { - mk_api->str_build(&conf->dh_param_file, &len, - "%s/%s", confdir, dh_param_file); - } - } - - /* Set client cert check */ - conf->check_client_cert = check_client_cert; - - if (conf_head) { - mk_api->config_free(conf_head); - } - - return 0; -} - -static int polar_load_certs(const struct polar_config *conf) -{ - char err_buf[72]; - int ret = -1; - - ret = mbedtls_x509_crt_parse_file(&server_context->cert, conf->cert_file); - if (ret < 0) { - mbedtls_strerror(ret, err_buf, sizeof(err_buf)); - mk_warn("[tls] Load cert '%s' failed: %s", - conf->cert_file, - err_buf); - -#if defined(MBEDTLS_CERTS_C) - mk_warn("[tls] Using test certificates, " - "please set 'CertificateFile' in tls.conf"); - - ret = mbedtls_x509_crt_parse(&server_context->cert, - (unsigned char *)mbedtls_test_srv_crt, strlen(mbedtls_test_srv_crt)); - - if (ret) { - mbedtls_strerror(ret, err_buf, sizeof(err_buf)); - mk_warn("[tls] Load built-in cert failed: %s", err_buf); - return -1; - } - - return 0; -#else - return -1; -#endif // defined(MBEDTLS_CERTS_C) - } - else if (conf->cert_chain_file != NULL) { - ret = mbedtls_x509_crt_parse_file(&server_context->ca_cert, - conf->cert_chain_file); - - if (ret) { - mbedtls_strerror(ret, err_buf, sizeof(err_buf)); - mk_warn("[tls] Load cert chain '%s' failed: %s", - conf->cert_chain_file, - err_buf); - } - } - - return 0; -} - -static int polar_load_key(struct polar_thread_context *thread_context, - const struct polar_config *conf) -{ - char err_buf[72]; - int ret; - - assert(conf->key_file); - - ret = mbedtls_pk_parse_keyfile(&thread_context->pkey, conf->key_file, NULL); - if (ret < 0) { - mbedtls_strerror(ret, err_buf, sizeof(err_buf)); - MK_TRACE("[tls] Load key '%s' failed: %s", - conf->key_file, - err_buf); - -#if defined(MBEDTLS_CERTS_C) - - ret = mbedtls_pk_parse_key(&thread_context->pkey, - (unsigned char *)mbedtls_test_srv_key, - strlen(mbedtls_test_srv_key), NULL, 0); - if (ret) { - mbedtls_strerror(ret, err_buf, sizeof(err_buf)); - mk_err("[tls] Failed to load built-in RSA key: %s", err_buf); - return -1; - } -#else - return -1; -#endif // defined(MBEDTLS_CERTS_C) - } - return 0; -} - -static int polar_load_dh_param(const struct polar_config *conf) -{ - char err_buf[72]; - int ret; - - assert(conf->dh_param_file); - - ret = mbedtls_dhm_parse_dhmfile(&server_context->dhm, conf->dh_param_file); - if (ret < 0) { - mbedtls_strerror(ret, err_buf, sizeof(err_buf)); - - ret = mbedtls_mpi_read_string(&server_context->dhm.P, 16, my_dhm_P); - if (ret < 0) { - mbedtls_strerror(ret, err_buf, sizeof(err_buf)); - mk_err("[tls] Load DH parameter failed: %s", err_buf); - return -1; - } - ret = mbedtls_mpi_read_string(&server_context->dhm.G, 16, my_dhm_G); - if (ret < 0) { - mbedtls_strerror(ret, err_buf, sizeof(err_buf)); - mk_err("[tls] Load DH parameter failed: %s", err_buf); - return -1; - } - } - - return 0; -} - -static int mk_tls_init() -{ - pthread_key_create(&local_context, NULL); - -#if defined(MBEDTLS_SSL_CACHE_C) - mbedtls_ssl_cache_init(&global_sessions.cache); -#endif - - pthread_mutex_lock(&server_context->mutex); - mk_list_init(&server_context->threads._head); - mbedtls_entropy_init(&server_context->entropy); - pthread_mutex_unlock(&server_context->mutex); - - PLUGIN_TRACE("[tls] Load certificates."); - if (polar_load_certs(&server_context->config)) { - return -1; - } - PLUGIN_TRACE("[tls] Load DH parameters."); - if (polar_load_dh_param(&server_context->config)) { - return -1; - } - - return 0; -} - - -static int entropy_func_safe(void *data, unsigned char *output, size_t len) -{ - int ret; - - pthread_mutex_lock(&server_context->mutex); - ret = mbedtls_entropy_func(data, output, len); - pthread_mutex_unlock(&server_context->mutex); - - return ret; -} - -static void contexts_free(struct polar_context_head *ctx) -{ - struct polar_context_head *cur, *next; - - if (ctx != NULL) { - cur = ctx; - next = cur->_next; - - for (; next; cur = next, next = next->_next) { - mbedtls_ssl_free(&cur->context); - memset(cur, 0, sizeof(*cur)); - mk_api->mem_free(cur); - } - - mbedtls_ssl_free(&cur->context); - memset(cur, 0, sizeof(*cur)); - mk_api->mem_free(cur); - } -} - -static void config_free(struct polar_config *conf) -{ - if (conf->cert_file) mk_api->mem_free(conf->cert_file); - if (conf->cert_chain_file) mk_api->mem_free(conf->cert_chain_file); - if (conf->key_file) mk_api->mem_free(conf->key_file); - if (conf->dh_param_file) mk_api->mem_free(conf->dh_param_file); -} - -/* Contexts may be requested from outside workers on exit so we should - * be prepared for an empty context. - */ -static mbedtls_ssl_context *context_get(int fd) -{ - struct polar_thread_context *thctx = local_thread_context(); - struct polar_context_head **cur = &thctx->contexts; - - if (cur == NULL) { - return NULL; - } - - for (; *cur; cur = &(*cur)->_next) { - if ((*cur)->fd == fd) { - return &(*cur)->context; - } - } - - return NULL; -} - -static mbedtls_ssl_context *context_new(int fd) -{ - struct polar_thread_context *thctx = local_thread_context(); - struct polar_context_head **cur = &thctx->contexts; - mbedtls_ssl_context *ssl = NULL; - mbedtls_ssl_cache_context cache; - - mbedtls_ssl_cache_init(&cache); - - assert(cur != NULL); - - for (; *cur; cur = &(*cur)->_next) { - if ((*cur)->fd == -1) { - break; - } - } - - if (*cur == NULL) { - PLUGIN_TRACE("[polarssl %d] New ssl context.", fd); - - *cur = mk_api->mem_alloc(sizeof(**cur)); - if (*cur == NULL) { - return NULL; - } - (*cur)->_next = NULL; - - ssl = &(*cur)->context; - - mbedtls_ssl_init(ssl); - mbedtls_ssl_setup(ssl, &thctx->conf); - - mbedtls_ssl_conf_session_cache(&thctx->conf, - &global_sessions, - tls_cache_get, - tls_cache_set); - - mbedtls_ssl_set_bio(ssl, &(*cur)->fd, - mbedtls_net_send, mbedtls_net_recv, NULL); - - mbedtls_ssl_conf_rng(&thctx->conf, mbedtls_ctr_drbg_random, - &thctx->ctr_drbg); - -#if (POLAR_DEBUG_LEVEL > 0) - mbedtls_ssl_conf_dbg(ssl, polar_debug, 0); -#endif - - mbedtls_ssl_conf_own_cert(&thctx->conf, &server_context->cert, &thctx->pkey); - mbedtls_ssl_conf_ca_chain(&thctx->conf, &server_context->ca_cert, NULL); - mbedtls_ssl_conf_dh_param_ctx(&thctx->conf, &server_context->dhm); - - if (server_context->config.check_client_cert == MK_TRUE) { - mbedtls_ssl_conf_authmode(&thctx->conf, MBEDTLS_SSL_VERIFY_REQUIRED); - } - } - else { - ssl = &(*cur)->context; - } - - (*cur)->fd = fd; - - return ssl; -} - -static int context_unset(int fd, mbedtls_ssl_context *ssl) -{ - struct polar_context_head *head; - - head = container_of(ssl, struct polar_context_head, context); - - if (head->fd == fd) { - head->fd = -1; - mbedtls_ssl_session_reset(ssl); - } - else { - mk_err("[polarssl %d] Context already unset.", fd); - } - - return 0; -} - -int mk_tls_read(int fd, void *buf, int count) -{ - size_t avail; - mbedtls_ssl_context *ssl = context_get(fd); - - if (!ssl) { - ssl = context_new(fd); - } - - int ret = handle_return(mbedtls_ssl_read(ssl, buf, count)); - PLUGIN_TRACE("IN: %i SSL READ: %i ; CORE COUNT: %i", - ssl->in_msglen, - ret, count); - - /* Check if the caller read less than the available data */ - if (ret > 0) { - avail = polar_get_bytes_avail(ssl); - if (avail > 0) { - /* - * A read callback would never read in buffer more than - * the size specified in 'count', but it aims to return - * as value the total information read in the buffer plugin - */ - ret += avail; - } - } - return ret; -} - -int mk_tls_write(int fd, const void *buf, size_t count) -{ - mbedtls_ssl_context *ssl = context_get(fd); - if (!ssl) { - ssl = context_new(fd); - } - - return handle_return(mbedtls_ssl_write(ssl, buf, count)); -} - -int mk_tls_writev(int fd, struct mk_iov *mk_io) -{ - mbedtls_ssl_context *ssl = context_get(fd); - const int iov_len = mk_io->iov_idx; - const struct iovec *io = mk_io->io; - const size_t len = mk_io->total_len; - unsigned char *buf; - size_t used = 0; - int ret = 0, i; - - if (!ssl) { - ssl = context_new(fd); - } - - buf = mk_api->mem_alloc(len); - if (buf == NULL) { - mk_err("malloc failed: %s", strerror(errno)); - return -1; - } - - for (i = 0; i < iov_len; i++) { - memcpy(buf + used, io[i].iov_base, io[i].iov_len); - used += io[i].iov_len; - } - - assert(used == len); - ret = mbedtls_ssl_write(ssl, buf, len); - mk_api->mem_free(buf); - - return handle_return(ret); -} - -int mk_tls_send_file(int fd, int file_fd, off_t *file_offset, - size_t file_count) -{ - mbedtls_ssl_context *ssl = context_get(fd); - unsigned char *buf; - ssize_t used, remain = file_count, sent = 0; - int ret; - - if (!ssl) { - ssl = context_new(fd); - } - - buf = mk_api->mem_alloc(SENDFILE_BUF_SIZE); - if (buf == NULL) { - return -1; - } - - do { - used = pread(file_fd, buf, SENDFILE_BUF_SIZE, *file_offset); - if (used == 0) { - ret = 0; - } - else if (used < 0) { - mk_err("[tls] Read from file failed: %s", strerror(errno)); - ret = -1; - } - else if (remain > 0) { - ret = mbedtls_ssl_write(ssl, buf, used < remain ? used : remain); - } - else { - ret = mbedtls_ssl_write(ssl, buf, used); - } - - if (ret > 0) { - if (remain > 0) { - remain -= ret; - } - sent += ret; - *file_offset += ret; - } - } while (ret > 0); - - mk_api->mem_free(buf); - - if (sent > 0) { - return sent; - } - else { - return handle_return(ret); - } -} - -int mk_tls_close(int fd) -{ - mbedtls_ssl_context *ssl = context_get(fd); - - PLUGIN_TRACE("[fd %d] Closing connection", fd); - - if (ssl) { - mbedtls_ssl_close_notify(ssl); - context_unset(fd, ssl); - } - - close(fd); - return 0; -} - -int mk_tls_plugin_init(struct plugin_api **api, char *confdir) -{ - int used; - struct mk_list *head; - struct mk_config_listener *listen; - - /* Evil global config stuff */ - mk_api = *api; - - /* Check if the plugin will be used by some listener */ - used = MK_FALSE; - mk_list_foreach(head, &mk_api->config->listeners) { - listen = mk_list_entry(head, struct mk_config_listener, _head); - if (listen->flags & MK_CAP_SOCK_TLS) { - used = MK_TRUE; - break; - } - } - - if (used) { - /* If it's used, load certificates.. mandatory */ - server_context = mk_api->mem_alloc_z(sizeof(struct polar_server_context)); - config_parse(confdir, &server_context->config); - return mk_tls_init(); - } - else { - /* Plugin is not used, just unregister in silence */ - return -2; - } -} - -void mk_tls_worker_init(void) -{ - int ret; - struct polar_thread_context *thctx; - const char *pers = "monkey"; - - PLUGIN_TRACE("[tls] Init thread context."); - - thctx = mk_api->mem_alloc(sizeof(*thctx)); - if (thctx == NULL) { - goto error; - } - thctx->contexts = NULL; - mk_list_init(&thctx->_head); - - - /* SSL confniguration */ - mbedtls_ssl_config_init(&thctx->conf); - mbedtls_ssl_config_defaults(&thctx->conf, - MBEDTLS_SSL_IS_SERVER, - MBEDTLS_SSL_TRANSPORT_STREAM, - MBEDTLS_SSL_PRESET_DEFAULT); - - pthread_mutex_lock(&server_context->mutex); - mk_list_add(&thctx->_head, &server_context->threads._head); - pthread_mutex_unlock(&server_context->mutex); - - mbedtls_ctr_drbg_init(&thctx->ctr_drbg); - ret = mbedtls_ctr_drbg_seed(&thctx->ctr_drbg, - entropy_func_safe, &server_context->entropy, - (const unsigned char *) pers, - strlen(pers)); - if (ret != 0) { - goto error; - } - - mbedtls_pk_init(&thctx->pkey); - - PLUGIN_TRACE("[tls] Load RSA key."); - if (polar_load_key(thctx, &server_context->config)) { - goto error; - } - - PLUGIN_TRACE("[tls] Set local thread context."); - pthread_setspecific(local_context, thctx); - - return; - - error: - exit(EXIT_FAILURE); -} - -int mk_tls_plugin_exit() -{ - struct mk_list *cur, *tmp; - struct polar_thread_context *thctx; - - mbedtls_x509_crt_free(&server_context->cert); - mbedtls_x509_crt_free(&server_context->ca_cert); - mbedtls_dhm_free(&server_context->dhm); - - mk_list_foreach_safe(cur, tmp, &server_context->threads._head) { - thctx = mk_list_entry(cur, struct polar_thread_context, _head); - contexts_free(thctx->contexts); - mk_api->mem_free(thctx); - - mbedtls_pk_free(&thctx->pkey); - } - pthread_mutex_destroy(&server_context->mutex); - -#if defined(MBEDTLS_SSL_CACHE_C) - mbedtls_ssl_cache_free(&global_sessions.cache); -#endif - - config_free(&server_context->config); - mk_api->mem_free(server_context); - - return 0; -} - -/* Network Layer plugin Callbacks */ -struct mk_plugin_network mk_plugin_network_tls = { - .read = mk_tls_read, - .write = mk_tls_write, - .writev = mk_tls_writev, - .close = mk_tls_close, - .send_file = mk_tls_send_file, - .buffer_size = MBEDTLS_SSL_MAX_CONTENT_LEN -}; - -struct mk_plugin mk_plugin_tls = { - /* Identification */ - .shortname = "tls", - .name = "SSL/TLS Network Layer", - .version = MK_VERSION_STR, - .hooks = MK_PLUGIN_NETWORK_LAYER, - - /* Init / Exit */ - .init_plugin = mk_tls_plugin_init, - .exit_plugin = mk_tls_plugin_exit, - - /* Init Levels */ - .master_init = NULL, - .worker_init = mk_tls_worker_init, - - /* Type */ - .network = &mk_plugin_network_tls, - .capabilities = MK_CAP_SOCK_TLS -}; |