diff options
| author | Lu <[email protected]> | 2018-04-27 11:09:01 +0800 |
|---|---|---|
| committer | Lu <[email protected]> | 2018-04-27 11:09:01 +0800 |
| commit | 3624b97fc62839e6f30493f22f982df9e179d4cb (patch) | |
| tree | 5ca117e6f1c2474be09dee7d73d461f627b50c7e | |
| parent | 8851fc2300f0cb1f39982b68b09940f8258e1e45 (diff) | |
引入http解析层,调整原实现,使用c++编译器编译。
| -rw-r--r-- | .idea/.name | 1 | ||||
| -rw-r--r-- | .idea/codeStyles/Project.xml | 70 | ||||
| -rw-r--r-- | .idea/codeStyles/codeStyleConfig.xml | 5 | ||||
| -rw-r--r-- | .idea/deployment.xml | 28 | ||||
| -rw-r--r-- | .idea/misc.xml | 7 | ||||
| -rw-r--r-- | .idea/modules.xml | 8 | ||||
| -rw-r--r-- | .idea/tfe-sslsplit.iml | 2 | ||||
| -rw-r--r-- | .idea/vcs.xml | 6 | ||||
| -rw-r--r-- | .idea/webServers.xml | 23 | ||||
| -rw-r--r-- | CMakeLists.txt | 17 | ||||
| -rw-r--r-- | opts.c | 560 | ||||
| -rw-r--r-- | proc.c | 462 | ||||
| -rw-r--r-- | proc.h | 65 | ||||
| -rw-r--r-- | pxyconn.h | 48 | ||||
| -rw-r--r-- | src/CMakeLists.txt | 15 | ||||
| -rw-r--r-- | src/attrib.h (renamed from attrib.h) | 0 | ||||
| -rw-r--r-- | src/base64.cc (renamed from base64.c) | 4 | ||||
| -rw-r--r-- | src/base64.h (renamed from base64.h) | 0 | ||||
| -rw-r--r-- | src/build.cc (renamed from build.c) | 0 | ||||
| -rw-r--r-- | src/build.h (renamed from build.h) | 0 | ||||
| -rw-r--r-- | src/cache.cc (renamed from cache.c) | 2 | ||||
| -rw-r--r-- | src/cache.h (renamed from cache.h) | 0 | ||||
| -rw-r--r-- | src/cachedsess.cc (renamed from cachedsess.c) | 12 | ||||
| -rw-r--r-- | src/cachedsess.h (renamed from cachedsess.h) | 0 | ||||
| -rw-r--r-- | src/cachefkcrt.cc (renamed from cachefkcrt.c) | 8 | ||||
| -rw-r--r-- | src/cachefkcrt.h (renamed from cachefkcrt.h) | 0 | ||||
| -rw-r--r-- | src/cachemgr.cc (renamed from cachemgr.c) | 2 | ||||
| -rw-r--r-- | src/cachemgr.h (renamed from cachemgr.h) | 0 | ||||
| -rw-r--r-- | src/cachessess.cc (renamed from cachessess.c) | 12 | ||||
| -rw-r--r-- | src/cachessess.h (renamed from cachessess.h) | 0 | ||||
| -rw-r--r-- | src/cachetgcrt.cc (renamed from cachetgcrt.c) | 8 | ||||
| -rw-r--r-- | src/cachetgcrt.h (renamed from cachetgcrt.h) | 0 | ||||
| -rw-r--r-- | src/cert.cc (renamed from cert.c) | 8 | ||||
| -rw-r--r-- | src/cert.h (renamed from cert.h) | 0 | ||||
| -rw-r--r-- | src/cfgparser.h | 123 | ||||
| -rw-r--r-- | src/defaults.h (renamed from defaults.h) | 0 | ||||
| -rw-r--r-- | src/dynbuf.cc (renamed from dynbuf.c) | 14 | ||||
| -rw-r--r-- | src/dynbuf.h (renamed from dynbuf.h) | 0 | ||||
| -rw-r--r-- | src/khash.h (renamed from khash.h) | 0 | ||||
| -rw-r--r-- | src/log.cc (renamed from log.c) | 35 | ||||
| -rw-r--r-- | src/log.h (renamed from log.h) | 7 | ||||
| -rw-r--r-- | src/logbuf.cc (renamed from logbuf.c) | 14 | ||||
| -rw-r--r-- | src/logbuf.h (renamed from logbuf.h) | 0 | ||||
| -rw-r--r-- | src/logger.cc (renamed from logger.c) | 6 | ||||
| -rw-r--r-- | src/logger.h (renamed from logger.h) | 0 | ||||
| -rw-r--r-- | src/main.cc (renamed from main.c) | 32 | ||||
| -rw-r--r-- | src/nat.cc (renamed from nat.c) | 5 | ||||
| -rw-r--r-- | src/nat.h (renamed from nat.h) | 0 | ||||
| -rw-r--r-- | src/opts.cc | 550 | ||||
| -rw-r--r-- | src/opts.h (renamed from opts.h) | 59 | ||||
| -rw-r--r-- | src/privsep.cc (renamed from privsep.c) | 24 | ||||
| -rw-r--r-- | src/privsep.h (renamed from privsep.h) | 4 | ||||
| -rw-r--r-- | src/proxy.cc (renamed from proxy.c) | 34 | ||||
| -rw-r--r-- | src/proxy.h (renamed from proxy.h) | 2 | ||||
| -rw-r--r-- | src/pxyconn.cc (renamed from pxyconn.c) | 256 | ||||
| -rw-r--r-- | src/pxyconn.h | 145 | ||||
| -rw-r--r-- | src/pxyhttp.cc | 182 | ||||
| -rw-r--r-- | src/pxyhttp.h | 4 | ||||
| -rw-r--r-- | src/pxysslshut.cc (renamed from pxysslshut.c) | 6 | ||||
| -rw-r--r-- | src/pxysslshut.h (renamed from pxysslshut.h) | 2 | ||||
| -rw-r--r-- | src/pxythrmgr.cc (renamed from pxythrmgr.c) | 6 | ||||
| -rw-r--r-- | src/pxythrmgr.h (renamed from pxythrmgr.h) | 2 | ||||
| -rw-r--r-- | src/ssl.cc (renamed from ssl.c) | 24 | ||||
| -rw-r--r-- | src/ssl.h (renamed from ssl.h) | 0 | ||||
| -rw-r--r-- | src/sys.cc (renamed from sys.c) | 5 | ||||
| -rw-r--r-- | src/sys.h (renamed from sys.h) | 5 | ||||
| -rw-r--r-- | src/thrqueue.cc (renamed from thrqueue.c) | 0 | ||||
| -rw-r--r-- | src/thrqueue.h (renamed from thrqueue.h) | 0 | ||||
| -rw-r--r-- | src/url.cc (renamed from url.c) | 0 | ||||
| -rw-r--r-- | src/url.h (renamed from url.h) | 0 | ||||
| -rw-r--r-- | src/util.cc (renamed from util.c) | 0 | ||||
| -rw-r--r-- | src/util.h (renamed from util.h) | 0 | ||||
| -rw-r--r-- | test/base64.t.c (renamed from base64.t.c) | 0 | ||||
| -rw-r--r-- | test/cachedsess.t.c (renamed from cachedsess.t.c) | 0 | ||||
| -rw-r--r-- | test/cachefkcrt.t.c (renamed from cachefkcrt.t.c) | 0 | ||||
| -rw-r--r-- | test/cachemgr.t.c (renamed from cachemgr.t.c) | 0 | ||||
| -rw-r--r-- | test/cachessess.t.c (renamed from cachessess.t.c) | 0 | ||||
| -rw-r--r-- | test/cachetgcrt.t.c (renamed from cachetgcrt.t.c) | 0 | ||||
| -rw-r--r-- | test/cert.t.c (renamed from cert.t.c) | 0 | ||||
| -rw-r--r-- | test/dynbuf.t.c (renamed from dynbuf.t.c) | 0 | ||||
| -rw-r--r-- | test/main.t.c (renamed from main.t.c) | 0 | ||||
| -rw-r--r-- | test/opts.t.c (renamed from opts.t.c) | 36 | ||||
| -rw-r--r-- | test/pxythrmgr.t.c (renamed from pxythrmgr.t.c) | 0 | ||||
| -rw-r--r-- | test/ssl.t.c (renamed from ssl.t.c) | 0 | ||||
| -rw-r--r-- | test/sys.t.c (renamed from sys.t.c) | 0 | ||||
| -rw-r--r-- | test/url.t.c (renamed from url.t.c) | 0 | ||||
| -rw-r--r-- | test/util.t.c (renamed from util.t.c) | 0 | ||||
| -rw-r--r-- | vendor/CMakeLists.txt | 103 | ||||
| -rw-r--r-- | vendor/MESA_prof_load-3b2bfd.tar.gz | bin | 0 -> 8125 bytes | |||
| -rw-r--r-- | vendor/check-0.12.0.tar.gz | bin | 0 -> 764043 bytes | |||
| -rw-r--r-- | vendor/googletest-release-1.8.0.tar.gz | bin | 0 -> 1281617 bytes | |||
| -rw-r--r-- | vendor/http-parser-2.8.1.tar.gz | bin | 0 -> 50731 bytes | |||
| -rw-r--r-- | vendor/libevent-2.1.8-stable.tar.gz | bin | 0 -> 1026485 bytes |
93 files changed, 1515 insertions, 1543 deletions
diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..4e3c827 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +tfe
\ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..910d7c2 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,70 @@ +<component name="ProjectCodeStyleConfiguration"> + <code_scheme name="Project" version="173"> + <option name="LINE_SEPARATOR" value=" " /> + <Objective-C> + <option name="INDENT_NAMESPACE_MEMBERS" value="0" /> + <option name="KEEP_STRUCTURES_IN_ONE_LINE" value="true" /> + <option name="KEEP_CASE_EXPRESSIONS_IN_ONE_LINE" value="true" /> + <option name="NAMESPACE_BRACE_PLACEMENT" value="2" /> + <option name="FUNCTION_BRACE_PLACEMENT" value="2" /> + <option name="BLOCK_BRACE_PLACEMENT" value="5" /> + <option name="FUNCTION_NON_TOP_AFTER_RETURN_TYPE_WRAP" value="0" /> + <option name="FUNCTION_TOP_AFTER_RETURN_TYPE_WRAP" value="0" /> + <option name="FUNCTION_PARAMETERS_WRAP" value="5" /> + <option name="FUNCTION_PARAMETERS_NEW_LINE_AFTER_LPAR" value="true" /> + <option name="TEMPLATE_CALL_ARGUMENTS_WRAP" value="5" /> + <option name="TEMPLATE_CALL_ARGUMENTS_ALIGN_MULTILINE" value="true" /> + <option name="CLASS_CONSTRUCTOR_INIT_LIST_WRAP" value="5" /> + <option name="SUPERCLASS_LIST_BEFORE_COLON" value="0" /> + <option name="ALIGN_INIT_LIST_IN_COLUMNS" value="false" /> + <option name="ADD_BRIEF_TAG" value="true" /> + </Objective-C> + <Objective-C-extensions> + <file> + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" /> + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" /> + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" /> + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" /> + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" /> + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" /> + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" /> + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" /> + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" /> + </file> + <class> + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" /> + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" /> + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" /> + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" /> + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" /> + <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" /> + </class> + <extensions> + <pair source="cc" header="h" fileNamingConvention="NONE" /> + <pair source="c" header="h" fileNamingConvention="NONE" /> + </extensions> + </Objective-C-extensions> + <codeStyleSettings language="ObjectiveC"> + <option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" /> + <option name="KEEP_BLANK_LINES_IN_CODE" value="1" /> + <option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1" /> + <option name="BLANK_LINES_BEFORE_IMPORTS" value="0" /> + <option name="BLANK_LINES_AFTER_IMPORTS" value="0" /> + <option name="BLANK_LINES_AROUND_CLASS" value="0" /> + <option name="BLANK_LINES_AROUND_METHOD" value="0" /> + <option name="BLANK_LINES_AROUND_METHOD_IN_INTERFACE" value="0" /> + <option name="BRACE_STYLE" value="5" /> + <option name="CLASS_BRACE_STYLE" value="2" /> + <option name="ALIGN_MULTILINE_BINARY_OPERATION" value="false" /> + <option name="ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION" value="false" /> + <option name="METHOD_CALL_CHAIN_WRAP" value="1" /> + <option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" /> + <option name="FOR_STATEMENT_WRAP" value="1" /> + <option name="ASSIGNMENT_WRAP" value="1" /> + <indentOptions> + <option name="CONTINUATION_INDENT_SIZE" value="4" /> + <option name="LABEL_INDENT_ABSOLUTE" value="true" /> + </indentOptions> + </codeStyleSettings> + </code_scheme> +</component>
\ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..79ee123 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ +<component name="ProjectCodeStyleConfiguration"> + <state> + <option name="USE_PER_PROJECT_SETTINGS" value="true" /> + </state> +</component>
\ No newline at end of file diff --git a/.idea/deployment.xml b/.idea/deployment.xml new file mode 100644 index 0000000..5984ae4 --- /dev/null +++ b/.idea/deployment.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="PublishConfigData" autoUpload="Always" serverName="192.168.10.8"> + <serverData> + <paths name="192.168.10.8"> + <serverdata> + <mappings> + <mapping deploy="/home/luqiuwen/tfe-sslsplit" local="$PROJECT_DIR$" web="/" /> + </mappings> + <excludedPaths> + <excludedPath local="true" path="$PROJECT_DIR$/cmake-build-debug" /> + </excludedPaths> + </serverdata> + </paths> + <paths name="tencent-server"> + <serverdata> + <mappings> + <mapping deploy="tfe-sslsplit" local="$PROJECT_DIR$" web="/" /> + </mappings> + <excludedPaths> + <excludedPath local="true" path="$PROJECT_DIR$/cmake-build-debug" /> + </excludedPaths> + </serverdata> + </paths> + </serverData> + <option name="myAutoUpload" value="ALWAYS" /> + </component> +</project>
\ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..8822db8 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" /> + <component name="JavaScriptSettings"> + <option name="languageLevel" value="ES6" /> + </component> +</project>
\ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..0bba2df --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="ProjectModuleManager"> + <modules> + <module fileurl="file://$PROJECT_DIR$/.idea/tfe-sslsplit.iml" filepath="$PROJECT_DIR$/.idea/tfe-sslsplit.iml" /> + </modules> + </component> +</project>
\ No newline at end of file diff --git a/.idea/tfe-sslsplit.iml b/.idea/tfe-sslsplit.iml new file mode 100644 index 0000000..f08604b --- /dev/null +++ b/.idea/tfe-sslsplit.iml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module classpath="CMake" type="CPP_MODULE" version="4" />
\ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="VcsDirectoryMappings"> + <mapping directory="$PROJECT_DIR$" vcs="Git" /> + </component> +</project>
\ No newline at end of file diff --git a/.idea/webServers.xml b/.idea/webServers.xml new file mode 100644 index 0000000..2aa1a52 --- /dev/null +++ b/.idea/webServers.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="WebServers"> + <option name="servers"> + <webServer id="6f5fcf3d-6a79-444e-983a-d7c3e9244f55" name="tencent-server" url="http://tcn.racimecore.org"> + <fileTransfer host="tcn.racimecore.org" port="22" privateKey="E:\我的坚果云\License\id_rsa_2048" rootFolder="/home/ubuntu" accessType="SFTP" keyPair="true"> + <advancedOptions> + <advancedOptions dataProtectionLevel="Private" /> + </advancedOptions> + <option name="port" value="22" /> + </fileTransfer> + </webServer> + <webServer id="c2739693-9faa-43db-93c3-ffb0f69c0233" name="192.168.10.8" url="http://192.168.10.8"> + <fileTransfer host="192.168.10.8" port="22" accessType="SFTP"> + <advancedOptions> + <advancedOptions dataProtectionLevel="Private" /> + </advancedOptions> + <option name="port" value="22" /> + </fileTransfer> + </webServer> + </option> + </component> +</project>
\ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a8909b..ec9885d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,8 @@ cmake_minimum_required(VERSION 3.5) project(tfe) -find_package(OpenSSL REQUIRED) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_C_STANDARD 11) add_definitions(-DPKGLABEL="tfe") add_definitions(-DBUILD_PKGNAME="tfe") @@ -12,13 +13,9 @@ add_definitions(-DBUILD_FEATURES="") ### GNU ### add_definitions(-D_GNU_SOURCE) -add_definitions(-fPIC) +add_definitions(-DHAVE_NETFILTER) +add_definitions(-fpermissive) -### Tango Frontend Target ### -add_executable(tfe base64.c build.c cache.c cachemgr.c cachessess.c cachedsess.c cachetgcrt.c cachefkcrt.c cert.c - dynbuf.c logbuf.c log.c logger.c main.c nat.c opts.c privsep.c proc.c proxy.c pxyconn.c pxythrmgr.c pxysslshut.c - ssl.c sys.c thrqueue.c url.c util.c) - -target_include_directories(tfe PRIVATE ${OPENSSL_INCLUDE_DIR}) -target_link_libraries(tfe ${OPENSSL_LIBRARIES}) -target_link_libraries(tfe event event_openssl event_pthreads pthread)
\ No newline at end of file +### +add_subdirectory(vendor) +add_subdirectory(src)
\ No newline at end of file @@ -1,560 +0,0 @@ -/*- - * SSLsplit - transparent SSL/TLS interception - * https://www.roe.ch/SSLsplit - * - * Copyright (c) 2009-2018, Daniel Roethlisberger <[email protected]>. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "opts.h" - -#include "sys.h" -#include "log.h" - -#include <string.h> -#include <sys/types.h> -#include <sys/socket.h> - -#ifndef OPENSSL_NO_DH -#include <openssl/dh.h> -#endif /* !OPENSSL_NO_DH */ -#include <openssl/x509.h> - -opts_t * -opts_new(void) -{ - opts_t *opts; - - opts = malloc(sizeof(opts_t)); - memset(opts, 0, sizeof(opts_t)); - - opts->sslcomp = 1; - opts->chain = sk_X509_new_null(); - opts->sslmethod = SSLv23_method; - - return opts; -} - -void -opts_free(opts_t *opts) -{ - sk_X509_pop_free(opts->chain, X509_free); - if (opts->cacrt) { - X509_free(opts->cacrt); - } - if (opts->cakey) { - EVP_PKEY_free(opts->cakey); - } - if (opts->key) { - EVP_PKEY_free(opts->key); - } -#ifndef OPENSSL_NO_DH - if (opts->dh) { - DH_free(opts->dh); - } -#endif /* !OPENSSL_NO_DH */ -#ifndef OPENSSL_NO_ECDH - if (opts->ecdhcurve) { - free(opts->ecdhcurve); - } -#endif /* !OPENSSL_NO_ECDH */ - if (opts->spec) { - proxyspec_free(opts->spec); - } - if (opts->ciphers) { - free(opts->ciphers); - } - if (opts->tgcrtdir) { - free(opts->tgcrtdir); - } - if (opts->crlurl) { - free(opts->crlurl); - } - if (opts->dropuser) { - free(opts->dropuser); - } - if (opts->dropgroup) { - free(opts->dropgroup); - } - if (opts->jaildir) { - free(opts->jaildir); - } - if (opts->pidfile) { - free(opts->pidfile); - } - if (opts->connectlog) { - free(opts->connectlog); - } - if (opts->contentlog) { - free(opts->contentlog); - } - if (opts->certgendir) { - free(opts->certgendir); - } - if (opts->contentlog_basedir) { - free(opts->contentlog_basedir); - } - if (opts->masterkeylog) { - free(opts->masterkeylog); - } - memset(opts, 0, sizeof(opts_t)); - free(opts); -} - -/* - * Return 1 if opts_t contains a proxyspec that (eventually) uses SSL/TLS, - * 0 otherwise. When 0, it is safe to assume that no SSL/TLS operations - * will take place with this configuration. - */ -int -opts_has_ssl_spec(opts_t *opts) -{ - proxyspec_t *p = opts->spec; - - while (p) { - if (p->ssl || p->upgrade) - return 1; - p = p->next; - } - - return 0; -} - -/* - * Return 1 if opts_t contains a proxyspec with dns, 0 otherwise. - */ -int -opts_has_dns_spec(opts_t *opts) -{ - proxyspec_t *p = opts->spec; - - while (p) { - if (p->dns) - return 1; - p = p->next; - } - - return 0; -} - -/* - * Parse SSL proto string in optarg and look up the corresponding SSL method. - * Calls exit() on failure. - */ -void -opts_proto_force(opts_t *opts, const char *optarg, const char *argv0) -{ -#if OPENSSL_VERSION_NUMBER < 0x10100000L - if (opts->sslmethod != SSLv23_method) { -#else /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ - if (opts->sslversion) { -#endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ - fprintf(stderr, "%s: cannot use -r multiple times\n", argv0); - exit(EXIT_FAILURE); - } - -#if OPENSSL_VERSION_NUMBER < 0x10100000L -#ifdef HAVE_SSLV2 - if (!strcmp(optarg, "ssl2")) { - opts->sslmethod = SSLv2_method; - } else -#endif /* HAVE_SSLV2 */ -#ifdef HAVE_SSLV3 - if (!strcmp(optarg, "ssl3")) { - opts->sslmethod = SSLv3_method; - } else -#endif /* HAVE_SSLV3 */ -#ifdef HAVE_TLSV10 - if (!strcmp(optarg, "tls10") || !strcmp(optarg, "tls1")) { - opts->sslmethod = TLSv1_method; - } else -#endif /* HAVE_TLSV10 */ -#ifdef HAVE_TLSV11 - if (!strcmp(optarg, "tls11")) { - opts->sslmethod = TLSv1_1_method; - } else -#endif /* HAVE_TLSV11 */ -#ifdef HAVE_TLSV12 - if (!strcmp(optarg, "tls12")) { - opts->sslmethod = TLSv1_2_method; - } else -#endif /* HAVE_TLSV12 */ -#else /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ -/* - * Support for SSLv2 and the corresponding SSLv2_method(), - * SSLv2_server_method() and SSLv2_client_method() functions were - * removed in OpenSSL 1.1.0. - */ -#ifdef HAVE_SSLV3 - if (!strcmp(optarg, "ssl3")) { - opts->sslversion = SSL3_VERSION; - } else -#endif /* HAVE_SSLV3 */ -#ifdef HAVE_TLSV10 - if (!strcmp(optarg, "tls10") || !strcmp(optarg, "tls1")) { - opts->sslversion = TLS1_VERSION; - } else -#endif /* HAVE_TLSV10 */ -#ifdef HAVE_TLSV11 - if (!strcmp(optarg, "tls11")) { - opts->sslversion = TLS1_1_VERSION; - } else -#endif /* HAVE_TLSV11 */ -#ifdef HAVE_TLSV12 - if (!strcmp(optarg, "tls12")) { - opts->sslversion = TLS1_2_VERSION; - } else -#endif /* HAVE_TLSV12 */ -#endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ - { - fprintf(stderr, "%s: Unsupported SSL/TLS protocol '%s'\n", - argv0, optarg); - exit(EXIT_FAILURE); - } -} - -/* - * Parse SSL proto string in optarg and set the corresponding no_foo bit. - * Calls exit() on failure. - */ -void -opts_proto_disable(opts_t *opts, const char *optarg, const char *argv0) -{ -#ifdef HAVE_SSLV2 - if (!strcmp(optarg, "ssl2")) { - opts->no_ssl2 = 1; - } else -#endif /* HAVE_SSLV2 */ -#ifdef HAVE_SSLV3 - if (!strcmp(optarg, "ssl3")) { - opts->no_ssl3 = 1; - } else -#endif /* HAVE_SSLV3 */ -#ifdef HAVE_TLSV10 - if (!strcmp(optarg, "tls10") || !strcmp(optarg, "tls1")) { - opts->no_tls10 = 1; - } else -#endif /* HAVE_TLSV10 */ -#ifdef HAVE_TLSV11 - if (!strcmp(optarg, "tls11")) { - opts->no_tls11 = 1; - } else -#endif /* HAVE_TLSV11 */ -#ifdef HAVE_TLSV12 - if (!strcmp(optarg, "tls12")) { - opts->no_tls12 = 1; - } else -#endif /* HAVE_TLSV12 */ - { - fprintf(stderr, "%s: Unsupported SSL/TLS protocol '%s'\n", - argv0, optarg); - exit(EXIT_FAILURE); - } -} - -/* - * Dump the SSL/TLS protocol related configuration to the debug log. - */ -void -opts_proto_dbg_dump(opts_t *opts) -{ - log_dbg_printf("SSL/TLS protocol: %s%s%s%s%s%s\n", -#if OPENSSL_VERSION_NUMBER < 0x10100000L -#ifdef HAVE_SSLV2 - (opts->sslmethod == SSLv2_method) ? "ssl2" : -#endif /* HAVE_SSLV2 */ -#ifdef HAVE_SSLV3 - (opts->sslmethod == SSLv3_method) ? "ssl3" : -#endif /* HAVE_SSLV3 */ -#ifdef HAVE_TLSV10 - (opts->sslmethod == TLSv1_method) ? "tls10" : -#endif /* HAVE_TLSV10 */ -#ifdef HAVE_TLSV11 - (opts->sslmethod == TLSv1_1_method) ? "tls11" : -#endif /* HAVE_TLSV11 */ -#ifdef HAVE_TLSV12 - (opts->sslmethod == TLSv1_2_method) ? "tls12" : -#endif /* HAVE_TLSV12 */ -#else /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ -#ifdef HAVE_SSLV3 - (opts->sslversion == SSL3_VERSION) ? "ssl3" : -#endif /* HAVE_SSLV3 */ -#ifdef HAVE_TLSV10 - (opts->sslversion == TLS1_VERSION) ? "tls10" : -#endif /* HAVE_TLSV10 */ -#ifdef HAVE_TLSV11 - (opts->sslversion == TLS1_1_VERSION) ? "tls11" : -#endif /* HAVE_TLSV11 */ -#ifdef HAVE_TLSV12 - (opts->sslversion == TLS1_2_VERSION) ? "tls12" : -#endif /* HAVE_TLSV12 */ -#endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ - "negotiate", -#ifdef HAVE_SSLV2 - opts->no_ssl2 ? " -ssl2" : -#endif /* HAVE_SSLV2 */ - "", -#ifdef HAVE_SSLV3 - opts->no_ssl3 ? " -ssl3" : -#endif /* HAVE_SSLV3 */ - "", -#ifdef HAVE_TLSV10 - opts->no_tls10 ? " -tls10" : -#endif /* HAVE_TLSV10 */ - "", -#ifdef HAVE_TLSV11 - opts->no_tls11 ? " -tls11" : -#endif /* HAVE_TLSV11 */ - "", -#ifdef HAVE_TLSV12 - opts->no_tls12 ? " -tls12" : -#endif /* HAVE_TLSV12 */ - ""); -} - - -/* - * Parse proxyspecs using a simple state machine. - * Returns NULL if parsing failed. - */ -proxyspec_t * -proxyspec_parse(int *argc, char **argv[], const char *natengine) -{ - proxyspec_t *curspec, *spec = NULL; - char *addr = NULL; - int af = AF_UNSPEC; - int state = 0; - - while ((*argc)--) { - switch (state) { - default: - case 0: - /* tcp | ssl | http | https | autossl */ - curspec = malloc(sizeof(proxyspec_t)); - memset(curspec, 0, sizeof(proxyspec_t)); - curspec->next = spec; - spec = curspec; - if (!strcmp(**argv, "tcp")) { - spec->ssl = 0; - spec->http = 0; - spec->upgrade = 0; - } else - if (!strcmp(**argv, "ssl")) { - spec->ssl = 1; - spec->http = 0; - spec->upgrade = 0; - } else - if (!strcmp(**argv, "http")) { - spec->ssl = 0; - spec->http = 1; - spec->upgrade = 0; - } else - if (!strcmp(**argv, "https")) { - spec->ssl = 1; - spec->http = 1; - spec->upgrade = 0; - } else - if (!strcmp(**argv, "autossl")) { - spec->ssl = 0; - spec->http = 0; - spec->upgrade = 1; - } else { - fprintf(stderr, "Unknown connection " - "type '%s'\n", **argv); - exit(EXIT_FAILURE); - } - state++; - break; - case 1: - /* listenaddr */ - addr = **argv; - state++; - break; - case 2: - /* listenport */ - if (strstr(addr, ":")) - af = AF_INET6; - else if (!strpbrk(addr, "abcdefghijklmnopqrstu" - "vwxyzABCDEFGHIJKLMNOP" - "QRSTUVWXYZ-")) - af = AF_INET; - else - af = AF_UNSPEC; - af = sys_sockaddr_parse(&spec->listen_addr, - &spec->listen_addrlen, - addr, **argv, af, - EVUTIL_AI_PASSIVE); - if (af == -1) { - exit(EXIT_FAILURE); - } - if (natengine) { - spec->natengine = strdup(natengine); - if (!spec->natengine) { - fprintf(stderr, - "Out of memory" - "\n"); - exit(EXIT_FAILURE); - } - } else { - spec->natengine = NULL; - } - state++; - break; - case 3: - /* [ natengine | dstaddr ] */ - if (!strcmp(**argv, "tcp") || - !strcmp(**argv, "ssl") || - !strcmp(**argv, "http") || - !strcmp(**argv, "https") || - !strcmp(**argv, "autossl")) { - /* implicit default natengine */ - (*argv)--; (*argc)++; /* rewind */ - state = 0; - } else - if (!strcmp(**argv, "sni")) { - free(spec->natengine); - spec->natengine = NULL; - if (!spec->ssl) { - fprintf(stderr, - "SNI hostname lookup " - "only works for ssl " - "and https proxyspecs" - "\n"); - exit(EXIT_FAILURE); - } - state = 5; - } else - if (nat_exist(**argv)) { - /* natengine */ - free(spec->natengine); - spec->natengine = strdup(**argv); - if (!spec->natengine) { - fprintf(stderr, - "Out of memory" - "\n"); - exit(EXIT_FAILURE); - } - state = 0; - } else { - /* explicit target address */ - free(spec->natengine); - spec->natengine = NULL; - addr = **argv; - state++; - } - break; - case 4: - /* dstport */ - af = sys_sockaddr_parse(&spec->connect_addr, - &spec->connect_addrlen, - addr, **argv, af, 0); - if (af == -1) { - exit(EXIT_FAILURE); - } - state = 0; - break; - case 5: - /* SNI dstport */ - spec->sni_port = atoi(**argv); - if (!spec->sni_port) { - fprintf(stderr, "Invalid port '%s'\n", - **argv); - exit(EXIT_FAILURE); - } - spec->dns = 1; - state = 0; - break; - } - (*argv)++; - } - if (state != 0 && state != 3) { - fprintf(stderr, "Incomplete proxyspec!\n"); - exit(EXIT_FAILURE); - } - - return spec; -} - -/* - * Clear and free a proxy spec. - */ -void -proxyspec_free(proxyspec_t *spec) -{ - do { - proxyspec_t *next = spec->next; - if (spec->natengine) - free(spec->natengine); - memset(spec, 0, sizeof(proxyspec_t)); - free(spec); - spec = next; - } while (spec); -} - -/* - * Return text representation of proxy spec for display to the user. - * Returned string must be freed by caller. - */ -char * -proxyspec_str(proxyspec_t *spec) -{ - char *s; - char *lhbuf, *lpbuf; - char *cbuf = NULL; - if (sys_sockaddr_str((struct sockaddr *)&spec->listen_addr, - spec->listen_addrlen, &lhbuf, &lpbuf) != 0) { - return NULL; - } - if (spec->connect_addrlen) { - char *chbuf, *cpbuf; - if (sys_sockaddr_str((struct sockaddr *)&spec->connect_addr, - spec->connect_addrlen, - &chbuf, &cpbuf) != 0) { - return NULL; - } - if (asprintf(&cbuf, "[%s]:%s", chbuf, cpbuf) < 0) { - return NULL; - } - free(chbuf); - free(cpbuf); - } - if (spec->sni_port) { - if (asprintf(&cbuf, "sni %i", spec->sni_port) < 0) { - return NULL; - } - } - if (asprintf(&s, "[%s]:%s %s%s%s %s", lhbuf, lpbuf, - (spec->ssl ? "ssl" : "tcp"), - (spec->upgrade ? "|upgrade" : ""), - (spec->http ? "|http" : ""), - (spec->natengine ? spec->natengine : cbuf)) < 0) { - s = NULL; - } - free(lhbuf); - free(lpbuf); - if (cbuf) - free(cbuf); - return s; -} - -/* vim: set noet ft=c: */ @@ -1,462 +0,0 @@ -/*- - * SSLsplit - transparent SSL/TLS interception - * https://www.roe.ch/SSLsplit - * - * Copyright (c) 2009-2018, Daniel Roethlisberger <[email protected]>. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifdef __FreeBSD__ -#include <sys/types.h> -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/socketvar.h> -#include <sys/sysctl.h> -#include <sys/file.h> -#include <sys/user.h> - -#include <netinet/in.h> -#include <netinet/in_pcb.h> -#include <netinet/tcp.h> -#include <netinet/tcp_seq.h> -#include <netinet/tcp_var.h> -#include <arpa/inet.h> -#endif /* __FreeBSD__ */ - -#include "proc.h" - -#include "log.h" -#include "attrib.h" - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> - -#ifdef HAVE_DARWIN_LIBPROC -#include <libproc.h> -#endif /* HAVE_DARWIN_LIBPROC */ - - -/* - * Local process lookup. - */ - - -#ifdef __FreeBSD__ - -/* - * Get the list of open files from the kernel and do basic consistency checks. - * If successful, returns 0, and *pxfiles will receive a pointer to the - * received xfiles structure and *pnxfiles the number of file records in it. - * If unsuccessful, returns -1 and *pxfiles will be NULL. - * Caller is responsible to free() *pxfiles after use. - */ -static int -proc_freebsd_getfiles(struct xfile **pxfiles, int *pnxfiles) -{ - int mib[4]; - size_t sz; - - mib[0] = CTL_KERN; - mib[1] = KERN_FILE; - mib[2] = mib[3] = 0; - - for (;;) { - if (sysctl(mib, 2, NULL, &sz, NULL, 0) < 0) { - *pxfiles = NULL; - return -1; - } - if (!(*pxfiles = malloc(sz))) { - return -1; - } - if (sysctl(mib, 2, *pxfiles, &sz, NULL, 0) < 0) { - free(*pxfiles); - if (errno == ENOMEM) - continue; - *pxfiles = NULL; - return -1; - } - break; - } - - if (sz > 0 && (*pxfiles)->xf_size != sizeof **pxfiles) { - log_err_printf("struct xfile size mismatch\n"); - return -1; - } - *pnxfiles = sz / sizeof **pxfiles; - - return 0; -} - -/* - * Get the list of active TCP connections and do basic consistency checks. - * If successful, returns 0, and *pxig will receive a pointer to the - * received data structure, *pexig a pointer to the end of the buffer. - * If unsuccessful, returns -1 and *pxig will be NULL. - * Caller is responsible to free() *pxig after use. - */ -static int -proc_freebsd_gettcppcblist(struct xinpgen **pxig, struct xinpgen **pexig) -{ - int mib[4]; - size_t sz; - int retry = 5; - - mib[0] = CTL_NET; - mib[1] = PF_INET; - mib[2] = IPPROTO_TCP; - mib[3] = TCPCTL_PCBLIST; - do { - for (;;) { - if (sysctl(mib, 4, NULL, &sz, NULL, 0) < 0) { - *pxig = NULL; - return -1; - } - if (!(*pxig = malloc(sz))) { - return -1; - } - if (sysctl(mib, 4, *pxig, &sz, NULL, 0) < 0) { - free(*pxig); - if (errno == ENOMEM) - continue; - *pxig = NULL; - return -1; - } - break; - } - - *pexig = (struct xinpgen *)(void *) - ((char *)(*pxig) + sz - sizeof(**pexig)); - if ((*pxig)->xig_len != sizeof(**pxig) || - (*pexig)->xig_len != sizeof(**pexig)) { - log_err_printf("struct xinpgen size mismatch\n"); - free(*pxig); - *pxig = NULL; - return -1; - } - } while ((*pxig)->xig_gen != (*pexig)->xig_gen && retry--); - - /* check if first and last record are from same generation */ - if ((*pxig)->xig_gen != (*pexig)->xig_gen) { - log_err_printf("Warning: data inconsistent " - "(xig->xig_gen != exig->xig_gen)\n"); - } - - return 0; -} - -int -proc_freebsd_pid_for_addr(pid_t *result, struct sockaddr *src_addr, - UNUSED socklen_t src_addrlen) -{ - struct xfile *xfiles; - int nxfiles; - struct xfile *xf; - - struct xinpgen *xig, *exig, *txig; - struct xtcpcb *xtp; -#if __FreeBSD_version >= 1200026 - struct xinpcb *inp; -#else - struct inpcb *inp; -#endif - struct xsocket *so; - - if (proc_freebsd_getfiles(&xfiles, &nxfiles) == -1) { - return -1; - } - - if (proc_freebsd_gettcppcblist(&xig, &exig) == -1) { - free(xfiles); - return -1; - } - - for (txig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len); - txig < exig; - txig = (struct xinpgen *)(void *)((char *)txig + txig->xig_len)) { - xtp = (struct xtcpcb *)txig; - if (xtp->xt_len != sizeof *xtp) { - free(xfiles); - free(xig); - return -1; - } - inp = &xtp->xt_inp; -#if __FreeBSD_version >= 1200026 - so = &inp->xi_socket; -#else - so = &xtp->xt_socket; -#endif - - if (!(so->so_state & SS_ISCONNECTED)) - /* we are only interested in connected sockets */ - continue; - - if ((inp->inp_vflag & INP_IPV4) && - (src_addr->sa_family == AF_INET)) { - struct sockaddr_in *src_sai = - (struct sockaddr_in *)src_addr; - - if (src_sai->sin_addr.s_addr != inp->inp_laddr.s_addr) { - continue; - } - - if (src_sai->sin_port != inp->inp_lport) { - continue; - } - } else if ((inp->inp_vflag & INP_IPV6) && - (src_addr->sa_family == AF_INET6)) { - struct sockaddr_in6 *src_sai = - (struct sockaddr_in6 *)src_addr; - - if (memcmp(src_sai->sin6_addr.s6_addr, inp->in6p_laddr.s6_addr, 16) != 0) { - continue; - } - - if (src_sai->sin6_port != inp->inp_lport) { - continue; - } - } else { - /* other address family */ - continue; - } - - /* valid match */ - - /* only do this if we have a match */ - xf = NULL; - for (int i = 0; i < nxfiles; ++i) { - if (so->xso_so == xfiles[i].xf_data) { - /* there can be several processes sharing a - * connected socket file descriptor */ - xf = &xfiles[i]; - } - } - if (!xf) - continue; - *result = xf->xf_pid; - break; - } - - free(xfiles); - free(xig); - return 0; -} - -int -proc_freebsd_get_info(pid_t pid, char **path, uid_t *uid, gid_t *gid) { - static struct kinfo_proc proc; - size_t len; - int mib[4]; - char buf[PATH_MAX + 1]; - - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PATHNAME; - mib[3] = (int)pid; - len = sizeof(buf); - if (sysctl(mib, 4, buf, &len, NULL, 0) == -1) { - if (errno != ESRCH) { - log_err_printf("Failed to get proc pathname: %s (%i)", - strerror(errno), errno); - } - *path = NULL; - } else { - *path = strdup(buf); - } - - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[3] = (int)pid; - len = sizeof proc; - if (sysctl(mib, 4, &proc, &len, NULL, 0) == -1) { - if (errno != ESRCH) { - log_err_printf("Failed to get proc info: %s (%i)", - strerror(errno), errno); - } - *uid = -1; - *gid = -1; - } else { - if (*path == NULL) - *path = strdup(proc.ki_comm); - *uid = proc.ki_uid; - *gid = proc.ki_groups[0]; - } - - return 0; -} - -#endif /* __FreeBSD__ */ - - -#ifdef HAVE_DARWIN_LIBPROC - -int -proc_darwin_pid_for_addr(pid_t *result, struct sockaddr *src_addr, - UNUSED socklen_t src_addrlen) -{ - pid_t *pids = NULL; - struct proc_fdinfo *fds = NULL; - int ret = -1; - - /* default result if no pid matches */ - *result = -1; - - /* iterate over all pids to find a matching socket */ - int pid_count = proc_listallpids(NULL, 0); - if (pid_count <= 0) - goto errout1; - pids = malloc(sizeof(pid_t) * pid_count); - if (!pids) { - goto errout1; - } - - pid_count = proc_listallpids(pids, sizeof(pid_t) * pid_count); - if (pid_count <= 0) - goto errout2; - - for (int i = 0; i < pid_count; i++) { - pid_t pid = pids[i]; - - /* fetch fd info for this pid */ - int fd_count = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0); - if (fd_count <= 0) { - /* failed to fetch pidinfo; process may have exited */ - continue; - } - - if (fds) { - free(fds); - } - fds = malloc(PROC_PIDLISTFD_SIZE * fd_count); - if (!fds) { - goto errout2; - } - fd_count = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fds, - sizeof(fds[0]) * fd_count); - - /* look for a matching socket file descriptor */ - for (int j = 0; j < fd_count; j++) { - struct proc_fdinfo *fd = &fds[j]; - struct socket_fdinfo sinfo; - - if (fd->proc_fdtype != PROX_FDTYPE_SOCKET) { - continue; - } - - if (proc_pidfdinfo(pid, fd->proc_fd, - PROC_PIDFDSOCKETINFO, - &sinfo, - sizeof(struct socket_fdinfo)) <= 0) { - /* process may have exited or socket may have - * been released. */ - continue; - } - - if (sinfo.psi.soi_kind != SOCKINFO_TCP) { - continue; - } - - uint16_t sock_lport = sinfo.psi.soi_proto.pri_tcp.tcpsi_ini.insi_lport; - if (sinfo.psi.soi_family == AF_INET && - src_addr->sa_family == AF_INET) { - struct sockaddr_in *src_sai = (struct sockaddr_in *)src_addr; - - if (src_sai->sin_addr.s_addr != sinfo.psi.soi_proto.pri_tcp.tcpsi_ini.insi_laddr.ina_46.i46a_addr4.s_addr) { - continue; - } - - if (src_sai->sin_port != sock_lport) { - continue; - } - } else if (sinfo.psi.soi_family == AF_INET6 && - src_addr->sa_family == AF_INET6) { - struct sockaddr_in6 *src_sai = (struct sockaddr_in6 *)src_addr; - - if (memcmp(src_sai->sin6_addr.s6_addr, sinfo.psi.soi_proto.pri_tcp.tcpsi_ini.insi_laddr.ina_6.s6_addr, 16) != 0) { - continue; - } - - if (src_sai->sin6_port != sock_lport) { - continue; - } - } else { - /* other address family */ - continue; - } - - /* valid match */ - *result = pid; - goto success; - } - } - -success: - ret = 0; - free(fds); -errout2: - free(pids); -errout1: - return ret; -} - -/* - * Fetch process info for the given pid. - * On success, returns 0 and fills in path, uid, and gid. - * Caller must free returned path string. - * Returns -1 on failure, or if unsupported on this platform. - */ -int -proc_darwin_get_info(pid_t pid, char **path, uid_t *uid, gid_t *gid) { - /* fetch process structure */ - struct proc_bsdinfo bsd_info; - if (proc_pidinfo(pid, PROC_PIDTBSDINFO, 0, &bsd_info, - sizeof(bsd_info)) <= 0) { - return -1; - } - - *uid = bsd_info.pbi_uid; - *gid = bsd_info.pbi_gid; - - /* fetch process path */ - *path = malloc(PROC_PIDPATHINFO_MAXSIZE); - if (!*path) { - return -1; - } - int path_len = proc_pidpath(pid, *path, PROC_PIDPATHINFO_MAXSIZE); - if (path_len <= 0) { - free(*path); - *path = NULL; - return -1; - } - - return 0; -} - -#endif /* HAVE_DARWIN_LIBPROC */ - -/* vim: set noet ft=c: */ - - - @@ -1,65 +0,0 @@ -/*- - * SSLsplit - transparent SSL/TLS interception - * https://www.roe.ch/SSLsplit - * - * Copyright (c) 2009-2018, Daniel Roethlisberger <[email protected]>. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef PROC_H -#define PROC_H - -#include "attrib.h" - -#include <sys/types.h> -#include <sys/socket.h> - -#include <event2/util.h> - -#if defined(HAVE_DARWIN_LIBPROC) || defined(__FreeBSD__) -#define HAVE_LOCAL_PROCINFO -#endif - -#ifdef HAVE_DARWIN_LIBPROC -#ifndef LOCAL_PROCINFO_STR -#define LOCAL_PROCINFO_STR "Darwin libproc" -#define proc_pid_for_addr(a,b,c) proc_darwin_pid_for_addr(a,b,c) -#define proc_get_info(a,b,c,d) proc_darwin_get_info(a,b,c,d) -#endif /* LOCAL_PROCINFO_STR */ -int proc_darwin_pid_for_addr(pid_t *, struct sockaddr *, socklen_t) WUNRES NONNULL(1,2); -int proc_darwin_get_info(pid_t, char **, uid_t *, gid_t *) WUNRES NONNULL(2,3,4); -#endif /* HAVE_DARWIN_LIBPROC */ - -#ifdef __FreeBSD__ -#ifndef LOCAL_PROCINFO_STR -#define LOCAL_PROCINFO_STR "FreeBSD sysctl" -#define proc_pid_for_addr(a,b,c) proc_freebsd_pid_for_addr(a,b,c) -#define proc_get_info(a,b,c,d) proc_freebsd_get_info(a,b,c,d) -#endif /* LOCAL_PROCINFO_STR */ -int proc_freebsd_pid_for_addr(pid_t *, struct sockaddr *, socklen_t) WUNRES NONNULL(1,2); -int proc_freebsd_get_info(pid_t, char **, uid_t *, gid_t *) WUNRES NONNULL(2,3,4); -#endif /* __FreeBSD__ */ - -#endif /* !PROC_H */ - -/* vim: set noet ft=c: */ diff --git a/pxyconn.h b/pxyconn.h deleted file mode 100644 index b02907e..0000000 --- a/pxyconn.h +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * SSLsplit - transparent SSL/TLS interception - * https://www.roe.ch/SSLsplit - * - * Copyright (c) 2009-2018, Daniel Roethlisberger <[email protected]>. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef PXYCONN_H -#define PXYCONN_H - -#include "opts.h" -#include "attrib.h" -#include "pxythrmgr.h" - -#include <sys/types.h> -#include <sys/socket.h> - -#include <event2/event.h> -#include <event2/util.h> - -void pxy_conn_setup(evutil_socket_t, struct sockaddr *, int, - pxy_thrmgr_ctx_t *, proxyspec_t *, opts_t *) - NONNULL(2,4,5,6); - -#endif /* !PXYCONN_H */ - -/* vim: set noet ft=c: */ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..7772e1c --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,15 @@ +find_package(OpenSSL REQUIRED) + +add_library(tfe-library base64.cc build.cc cache.cc cachemgr.cc cachessess.cc + cachedsess.cc cachetgcrt.cc cachefkcrt.cc cert.cc + dynbuf.cc logbuf.cc log.cc logger.cc nat.cc opts.cc + privsep.cc proxy.cc pxyconn.cc pxythrmgr.cc pxysslshut.cc + pxyhttp.cc ssl.cc sys.cc thrqueue.cc url.cc util.cc) + +target_include_directories(tfe-library PRIVATE ${OPENSSL_INCLUDE_DIR}) +target_link_libraries(tfe-library ${OPENSSL_LIBRARIES}) +target_link_libraries(tfe-library pthread libevent-static libevent-static-openssl + libevent-static-pthreads http-parser-static MESA_prof_load-static) + +add_executable(tfe main.cc) +target_link_libraries(tfe tfe-library)
\ No newline at end of file @@ -95,7 +95,7 @@ base64_dec(const char *in, size_t insz, size_t *outsz) *outsz = ((insz / 4) * 3) - 1; else *outsz = (insz / 4) * 3; - if (!(out = malloc((*outsz) + 1))) { + if (!(out = (unsigned char *)malloc((*outsz) + 1))) { *outsz = 0; return NULL; } @@ -161,7 +161,7 @@ base64_enc(const unsigned char *in, size_t insz, size_t *outsz) } *outsz = ((insz + 2) / 3) * 4; - if (!(out = malloc((*outsz) + 1))) { + if (!(out = (char *)malloc((*outsz) + 1))) { *outsz = 0; return NULL; } @@ -45,7 +45,7 @@ cache_new(cache_init_cb_t init_cb) { cache_t *cache; - if (!(cache = malloc(sizeof(cache_t)))) + if (!(cache = (cache_t *)malloc(sizeof(cache_t)))) return NULL; if (pthread_mutex_init(&cache->mutex, NULL)) { diff --git a/cachedsess.c b/src/cachedsess.cc index 12ea476..5bd70d8 100644 --- a/cachedsess.c +++ b/src/cachedsess.cc @@ -95,25 +95,25 @@ cachedsess_del_cb(cache_iter_t it) static cache_iter_t cachedsess_get_cb(cache_key_t key) { - return kh_get(dynbufmap_t, dstsessmap, key); + return kh_get(dynbufmap_t, dstsessmap, (dynbuf_t *)key); } static cache_iter_t cachedsess_put_cb(cache_key_t key, int *ret) { - return kh_put(dynbufmap_t, dstsessmap, key, ret); + return kh_put(dynbufmap_t, dstsessmap, (dynbuf_t *)key, ret); } static void cachedsess_free_key_cb(cache_key_t key) { - dynbuf_free(key); + dynbuf_free((dynbuf_t *)key); } static void cachedsess_free_val_cb(cache_val_t val) { - dynbuf_free(val); + dynbuf_free((dynbuf_t *)val); } static cache_key_t @@ -131,13 +131,13 @@ cachedsess_get_val_cb(cache_iter_t it) static void cachedsess_set_val_cb(cache_iter_t it, cache_val_t val) { - kh_val(dstsessmap, it) = val; + kh_val(dstsessmap, it) = (dynbuf_t *)val; } static cache_val_t cachedsess_unpackverify_val_cb(cache_val_t val, int copy) { - dynbuf_t *valbuf = val; + dynbuf_t *valbuf = (dynbuf_t *)val; SSL_SESSION *sess; const unsigned char *p; diff --git a/cachedsess.h b/src/cachedsess.h index c97fafe..c97fafe 100644 --- a/cachedsess.h +++ b/src/cachedsess.h diff --git a/cachefkcrt.c b/src/cachefkcrt.cc index 7bf30da..e6cd216 100644 --- a/cachefkcrt.c +++ b/src/cachefkcrt.cc @@ -103,7 +103,7 @@ cachefkcrt_free_key_cb(cache_key_t key) static void cachefkcrt_free_val_cb(cache_val_t val) { - X509_free(val); + X509_free((x509_st *)val); } static cache_key_t @@ -127,10 +127,10 @@ cachefkcrt_set_val_cb(cache_iter_t it, cache_val_t val) static cache_val_t cachefkcrt_unpackverify_val_cb(cache_val_t val, int copy) { - if (!ssl_x509_is_valid(val)) + if (!ssl_x509_is_valid((x509_st *)val)) return NULL; if (copy) { - ssl_x509_refcount_inc(val); + ssl_x509_refcount_inc((X509 *)val); return val; } return ((void*)-1); @@ -167,7 +167,7 @@ cachefkcrt_mkkey(X509 *keycrt) { unsigned char *fpr; - if (!(fpr = malloc(SSL_X509_FPRSZ))) + if (!(fpr = (unsigned char *)malloc(SSL_X509_FPRSZ))) return NULL; ssl_x509_fingerprint_sha1(keycrt, fpr); return fpr; diff --git a/cachefkcrt.h b/src/cachefkcrt.h index 47adab1..47adab1 100644 --- a/cachefkcrt.h +++ b/src/cachefkcrt.h diff --git a/cachemgr.c b/src/cachemgr.cc index ad00e0b..bdd3c00 100644 --- a/cachemgr.c +++ b/src/cachemgr.cc @@ -52,7 +52,7 @@ cache_t *cachemgr_dsess; static void * cachemgr_gc_thread(UNUSED void * arg) { - cache_gc(arg); + cache_gc((cache_t *)arg); return NULL; } diff --git a/cachemgr.h b/src/cachemgr.h index d66398c..d66398c 100644 --- a/cachemgr.h +++ b/src/cachemgr.h diff --git a/cachessess.c b/src/cachessess.cc index ae54ff4..9bff1c9 100644 --- a/cachessess.c +++ b/src/cachessess.cc @@ -93,25 +93,25 @@ cachessess_del_cb(cache_iter_t it) static cache_iter_t cachessess_get_cb(cache_key_t key) { - return kh_get(dynbufmap_t, srcsessmap, key); + return kh_get(dynbufmap_t, srcsessmap, (dynbuf_t *)key); } static cache_iter_t cachessess_put_cb(cache_key_t key, int *ret) { - return kh_put(dynbufmap_t, srcsessmap, key, ret); + return kh_put(dynbufmap_t, srcsessmap, (dynbuf_t *)key, ret); } static void cachessess_free_key_cb(cache_key_t key) { - dynbuf_free(key); + dynbuf_free((dynbuf_t *)key); } static void cachessess_free_val_cb(cache_val_t val) { - dynbuf_free(val); + dynbuf_free((dynbuf_t *)val); } static cache_key_t @@ -129,13 +129,13 @@ cachessess_get_val_cb(cache_iter_t it) static void cachessess_set_val_cb(cache_iter_t it, cache_val_t val) { - kh_val(srcsessmap, it) = val; + kh_val(srcsessmap, it) = (dynbuf_t *)val; } static cache_val_t cachessess_unpackverify_val_cb(cache_val_t val, int copy) { - dynbuf_t *valbuf = val; + dynbuf_t *valbuf = (dynbuf_t *)val; SSL_SESSION *sess; const unsigned char *p; diff --git a/cachessess.h b/src/cachessess.h index aacfd50..aacfd50 100644 --- a/cachessess.h +++ b/src/cachessess.h diff --git a/cachetgcrt.c b/src/cachetgcrt.cc index 6da107d..5244f0c 100644 --- a/cachetgcrt.c +++ b/src/cachetgcrt.cc @@ -70,13 +70,13 @@ cachetgcrt_del_cb(cache_iter_t it) static cache_iter_t cachetgcrt_get_cb(cache_key_t key) { - return kh_get(cstrmap_t, certmap, key); + return kh_get(cstrmap_t, certmap, (char *)key); } static cache_iter_t cachetgcrt_put_cb(cache_key_t key, int *ret) { - return kh_put(cstrmap_t, certmap, key, ret); + return kh_put(cstrmap_t, certmap, (char *)key, ret); } static void @@ -88,7 +88,7 @@ cachetgcrt_free_key_cb(cache_key_t key) static void cachetgcrt_free_val_cb(cache_val_t val) { - cert_free(val); + cert_free((cert_t *)val); } static cache_key_t @@ -113,7 +113,7 @@ static cache_val_t cachetgcrt_unpackverify_val_cb(cache_val_t val, int copy) { if (copy) { - cert_refcount_inc(val); + cert_refcount_inc((cert_t *)val); return val; } return ((void*)-1); diff --git a/cachetgcrt.h b/src/cachetgcrt.h index b570b55..b570b55 100644 --- a/cachetgcrt.h +++ b/src/cachetgcrt.h @@ -41,7 +41,7 @@ cert_new(void) { cert_t *c; - if (!(c = malloc(sizeof(cert_t)))) + if (!(c = (cert_t *)malloc(sizeof(cert_t)))) return NULL; memset(c, 0, sizeof(cert_t)); if (pthread_mutex_init(&c->mutex, NULL)) { @@ -61,7 +61,7 @@ cert_new3(EVP_PKEY *key, X509 *crt, STACK_OF(X509) *chain) { cert_t *c; - if (!(c = malloc(sizeof(cert_t)))) + if (!(c = (cert_t *)malloc(sizeof(cert_t)))) return NULL; if (pthread_mutex_init(&c->mutex, NULL)) { free(c); @@ -83,7 +83,7 @@ cert_new3_copy(EVP_PKEY *key, X509 *crt, STACK_OF(X509) *chain) { cert_t *c; - if (!(c = malloc(sizeof(cert_t)))) + if (!(c = (cert_t *)malloc(sizeof(cert_t)))) return NULL; if (pthread_mutex_init(&c->mutex, NULL)) { free(c); @@ -109,7 +109,7 @@ cert_new_load(const char *filename) { cert_t *c; - if (!(c = malloc(sizeof(cert_t)))) + if (!(c = (cert_t *)malloc(sizeof(cert_t)))) return NULL; memset(c, 0, sizeof(cert_t)); if (pthread_mutex_init(&c->mutex, NULL)) { diff --git a/src/cfgparser.h b/src/cfgparser.h new file mode 100644 index 0000000..c7f0063 --- /dev/null +++ b/src/cfgparser.h @@ -0,0 +1,123 @@ +// +// Created by luqiu on 2018-4-26. +// + +#ifndef TFE_CFGPARSER_H +#define TFE_CFGPARSER_H + +#ifndef TFE_STRING_MAX +#define TFE_STRING_MAX 2048 +#endif + +#include <stdexcept> +#include <string> +#include <cstring> + +extern "C" +{ +#include <MESA_prof_load.h> +} + +class TfeConfigParser +{ +public: + TfeConfigParser(std::string cfgfile) : str_cfgfile_(std::move(cfgfile)) + {} + ~TfeConfigParser() = default; + + /* 读入函数 */ + template<typename T> + T GetValue(const std::string &str_section, const std::string &str_entry); + template<typename T> + T GetValueWithDefault(const std::string &str_section, const std::string &str_entry, const T &default_value); + +private: + std::string str_cfgfile_; +}; + +struct tfe_expection_cfg_invalid_format : std::runtime_error +{ + explicit tfe_expection_cfg_invalid_format( + const std::string &file, + const std::string §ion, + const std::string &item, + const std::string &what) : file(file), section(section), item(item), runtime_error(what) + {} + + std::string file; + std::string section; + std::string item; +}; + +struct tfe_expection_cfg_lost_entry : std::runtime_error +{ + explicit tfe_expection_cfg_lost_entry( + const std::string &file, + const std::string §ion, + const std::string &item, + const std::string &what) : file(file), section(section), item(item), runtime_error(what) + {} + + std::string file; + std::string section; + std::string item; +}; + +template<> +std::string TfeConfigParser::GetValue(const std::string &str_section, const std::string &str_entry) +{ + char __str_buffer[TFE_STRING_MAX]; + memset(__str_buffer, 0, sizeof(__str_buffer)); + + int ret = MESA_load_profile_string_nodef(str_cfgfile_.c_str(), str_section.c_str(), str_entry.c_str(), + __str_buffer, sizeof(__str_buffer)); + + if (ret < 0) + throw tfe_expection_cfg_lost_entry(str_cfgfile_, str_section, str_entry, ""); + + return std::string(__str_buffer); +} + +template<> +unsigned long TfeConfigParser::GetValue(const std::string &str_section, const std::string &str_entry) +{ + char *__ptr = nullptr; + std::string __str_value = GetValue<std::string>(str_section, str_entry); + + unsigned long __value = strtoul(__str_value.c_str(), &__ptr, 0); + if (__ptr == __str_value.c_str()) + { + throw tfe_expection_cfg_invalid_format(str_cfgfile_, str_section, str_entry, + __str_value + " is not valid unsigned number. "); + } + + return __value; +} + +template<> +bool TfeConfigParser::GetValue(const std::string &str_section, const std::string &str_entry) +{ + return GetValue<unsigned long>(str_section, str_entry) != 0; +} + +template<typename T> +T TfeConfigParser::GetValueWithDefault( + const std::string &str_section, + const std::string &str_entry, + const T &default_value) +{ + T __value; + + try + { + __value = GetValue<T>(str_section, str_entry); + } + catch (...) + { + return default_value; + } + + return std::move(__value); +} + +#endif //TFE_CFGPARSER_H diff --git a/defaults.h b/src/defaults.h index baf28bd..baf28bd 100644 --- a/defaults.h +++ b/src/defaults.h @@ -44,9 +44,9 @@ dynbuf_new_alloc(size_t sz) { dynbuf_t *db; - if (!(db = malloc(sizeof(dynbuf_t)))) + if (!(db = (dynbuf_t *)malloc(sizeof(dynbuf_t)))) return NULL; - if (!(db->buf = malloc(sz))) { + if (!(db->buf = (unsigned char *)malloc(sz))) { free(db); return NULL; } @@ -62,9 +62,9 @@ dynbuf_new_copy(const unsigned char *buf, const size_t sz) { dynbuf_t *db; - if (!(db = malloc(sizeof(dynbuf_t)))) + if (!(db = (dynbuf_t *)malloc(sizeof(dynbuf_t)))) return NULL; - if (!(db->buf = malloc(sz))) { + if (!(db->buf = (unsigned char *)malloc(sz))) { free(db); return NULL; } @@ -83,7 +83,7 @@ dynbuf_new_file(const char *filename) dynbuf_t *db; FILE *f; - if (!(db = malloc(sizeof(dynbuf_t)))) + if (!(db = (dynbuf_t *)malloc(sizeof(dynbuf_t)))) return NULL; f = fopen(filename, "rb"); @@ -94,7 +94,7 @@ dynbuf_new_file(const char *filename) fseek(f, 0, SEEK_END); db->sz = ftell(f); fseek(f, 0, SEEK_SET); - if (!(db->buf = malloc(db->sz))) { + if (!(db->buf = (unsigned char *)malloc(db->sz))) { free(db); fclose(f); return NULL; @@ -118,7 +118,7 @@ dynbuf_new(unsigned char *buf, size_t sz) { dynbuf_t *db; - if (!(db = malloc(sizeof(dynbuf_t)))) + if (!(db = (dynbuf_t *)malloc(sizeof(dynbuf_t)))) return NULL; db->buf = buf; db->sz = sz; @@ -397,7 +397,7 @@ log_content_split_pathspec(const char *path, char **lhs, char **rhs) /* at last / terminating the static part of path */ p++; /* skip / */ - *lhs = malloc(p - path + 1 /* for terminating null */); + *lhs = (char *)malloc(p - path + 1 /* for terminating null */); if (!*lhs) return -1; memcpy(*lhs, path, p - path); @@ -424,7 +424,7 @@ log_content_format_pathspec(const char *logspec, { /* set up buffer to hold our generated file path */ size_t path_buflen = PATH_BUF_INC; - char *path_buf = malloc(path_buflen); + char *path_buf = (char *)malloc(path_buflen); if (path_buf == NULL) { log_err_printf("failed to allocate path buffer\n"); return NULL; @@ -543,7 +543,7 @@ log_content_format_pathspec(const char *logspec, * Note that the use of `PATH_BUF_INC' provides * our guaranteed space for a trailing '\0' */ path_buflen += elem_len + PATH_BUF_INC; - char *newbuf = realloc(path_buf, path_buflen); + char *newbuf = (char *)realloc(path_buf, path_buflen); if (newbuf == NULL) { log_err_printf("failed to reallocate" " path buffer\n"); @@ -566,7 +566,7 @@ log_content_format_pathspec(const char *logspec, #undef PATH_BUF_INC int -log_content_open(log_content_ctx_t **pctx, opts_t *opts, +log_content_open(log_content_ctx_t **pctx, struct tfe_config *opts, char *srchost, char *srcport, char *dsthost, char *dstport, char *exec_path, char *user, char *group) @@ -575,7 +575,8 @@ log_content_open(log_content_ctx_t **pctx, opts_t *opts, if (*pctx) return 0; - *pctx = malloc(sizeof(log_content_ctx_t)); + + *pctx = (log_content_ctx_t *)malloc(sizeof(log_content_ctx_t)); if (!*pctx) return -1; ctx = *pctx; @@ -720,7 +721,7 @@ out: static int log_content_dir_opencb(void *fh) { - log_content_ctx_t *ctx = fh; + log_content_ctx_t *ctx = (log_content_ctx_t *)fh; if ((ctx->u.dir.fd = privsep_client_openfile(content_clisock, ctx->u.dir.filename, @@ -735,7 +736,7 @@ log_content_dir_opencb(void *fh) static void log_content_dir_closecb(void *fh) { - log_content_ctx_t *ctx = fh; + log_content_ctx_t *ctx = (log_content_ctx_t *)fh; if (ctx->u.dir.filename) free(ctx->u.dir.filename); @@ -747,7 +748,7 @@ log_content_dir_closecb(void *fh) static ssize_t log_content_dir_writecb(void *fh, const void *buf, size_t sz) { - log_content_ctx_t *ctx = fh; + log_content_ctx_t *ctx = (log_content_ctx_t *)fh; if (write(ctx->u.dir.fd, buf, sz) == -1) { log_err_printf("Warning: Failed to write to content log: %s\n", @@ -760,7 +761,7 @@ log_content_dir_writecb(void *fh, const void *buf, size_t sz) static int log_content_spec_opencb(void *fh) { - log_content_ctx_t *ctx = fh; + log_content_ctx_t *ctx = (log_content_ctx_t *)fh; if ((ctx->u.spec.fd = privsep_client_openfile(content_clisock, ctx->u.spec.filename, @@ -775,7 +776,7 @@ log_content_spec_opencb(void *fh) static void log_content_spec_closecb(void *fh) { - log_content_ctx_t *ctx = fh; + log_content_ctx_t *ctx = (log_content_ctx_t *)fh; if (ctx->u.spec.filename) free(ctx->u.spec.filename); @@ -787,7 +788,7 @@ log_content_spec_closecb(void *fh) static ssize_t log_content_spec_writecb(void *fh, const void *buf, size_t sz) { - log_content_ctx_t *ctx = fh; + log_content_ctx_t *ctx = (log_content_ctx_t *)fh; if (write(ctx->u.spec.fd, buf, sz) == -1) { log_err_printf("Warning: Failed to write to content log: %s\n", @@ -858,7 +859,7 @@ log_content_file_opencb(void *fh) static void log_content_file_closecb(void *fh) { - log_content_ctx_t *ctx = fh; + log_content_ctx_t *ctx = (log_content_ctx_t *)fh; if (ctx->u.file.header_req) { free(ctx->u.file.header_req); @@ -873,7 +874,7 @@ log_content_file_closecb(void *fh) static ssize_t log_content_file_writecb(void *fh, const void *buf, size_t sz) { - UNUSED log_content_ctx_t *ctx = fh; + UNUSED log_content_ctx_t *ctx = (log_content_ctx_t *)fh; if (write(content_file_fd, buf, sz) == -1) { log_err_printf("Warning: Failed to write to content log: %s\n", @@ -886,7 +887,7 @@ log_content_file_writecb(void *fh, const void *buf, size_t sz) static logbuf_t * log_content_file_prepcb(void *fh, unsigned long prepflags, logbuf_t *lb) { - log_content_ctx_t *ctx = fh; + log_content_ctx_t *ctx = (log_content_ctx_t *)fh; int is_request = !!(prepflags & PREPFLAG_REQUEST); logbuf_t *head; time_t epoch; @@ -969,7 +970,7 @@ errout1: static ssize_t log_cert_writecb(void *fh, const void *buf, size_t sz) { - char *fn = fh; + char *fn = (char *)fh; int fd; if ((fd = privsep_client_certfile(cert_clisock, fn)) == -1) { @@ -1001,7 +1002,7 @@ log_cert_writecb(void *fh, const void *buf, size_t sz) * Return -1 on errors, 0 otherwise. */ int -log_preinit(opts_t *opts) +log_preinit(struct tfe_config *opts) { logger_reopen_func_t reopencb; logger_open_func_t opencb; @@ -1116,7 +1117,7 @@ log_preinit_undo(void) * Return -1 on errors, 0 otherwise. */ int -log_init(opts_t *opts, proxy_ctx_t *ctx, int clisock1, int clisock2) +log_init(struct tfe_config *opts, proxy_ctx_t *ctx, int clisock1, int clisock2) { proxy_ctx = ctx; if (err_log) @@ -71,8 +71,9 @@ extern logger_t *connect_log; logger_write_freebuf(connect_log, NULL, 0, (buf), (sz)) typedef struct log_content_ctx log_content_ctx_t; -int log_content_open(log_content_ctx_t **, opts_t *, char *, char *, char *, +int log_content_open(log_content_ctx_t **, struct tfe_config *, char *, char *, char *, char *, char *, char *, char *) NONNULL(1,2,3) WUNRES; + int log_content_submit(log_content_ctx_t *, logbuf_t *, int) NONNULL(1,2) WUNRES; int log_content_close(log_content_ctx_t **, int) NONNULL(1) WUNRES; @@ -81,9 +82,9 @@ int log_content_split_pathspec(const char *, char **, int log_cert_submit(const char *, X509 *) NONNULL(1,2) WUNRES; -int log_preinit(opts_t *) NONNULL(1) WUNRES; +int log_preinit(struct tfe_config *) NONNULL(1) WUNRES; void log_preinit_undo(void); -int log_init(opts_t *, proxy_ctx_t *, int, int) NONNULL(1,2) WUNRES; +int log_init(struct tfe_config *, proxy_ctx_t *, int, int) NONNULL(1,2) WUNRES; void log_fini(void); int log_reopen(void) WUNRES; void log_exceptcb(void); @@ -49,12 +49,12 @@ logbuf_new(void *buf, size_t sz, void *fh, logbuf_t *next) { logbuf_t *lb; - if (!(lb = malloc(sizeof(logbuf_t)))) { + if (!(lb = (logbuf_t *)malloc(sizeof(logbuf_t)))) { if (buf) free(buf); return NULL; } - lb->buf = buf; + lb->buf = (unsigned char *)buf; lb->sz = sz; lb->fh = fh; lb->ctl = 0; @@ -70,9 +70,9 @@ logbuf_new_alloc(size_t sz, void *fh, logbuf_t *next) { logbuf_t *lb; - if (!(lb = malloc(sizeof(logbuf_t)))) + if (!(lb = (logbuf_t *)malloc(sizeof(logbuf_t)))) return NULL; - if (!(lb->buf = malloc(sz))) { + if (!(lb->buf = (unsigned char *)malloc(sz))) { free(lb); return NULL; } @@ -91,9 +91,9 @@ logbuf_new_copy(const void *buf, size_t sz, void *fh, logbuf_t *next) { logbuf_t *lb; - if (!(lb = malloc(sizeof(logbuf_t)))) + if (!(lb = (logbuf_t *)malloc(sizeof(logbuf_t)))) return NULL; - if (!(lb->buf = malloc(sz))) { + if (!(lb->buf = (unsigned char *)malloc(sz))) { free(lb); return NULL; } @@ -114,7 +114,7 @@ logbuf_new_printf(void *fh, logbuf_t *next, const char *fmt, ...) va_list ap; logbuf_t *lb; - if (!(lb = malloc(sizeof(logbuf_t)))) + if (!(lb = (logbuf_t *)malloc(sizeof(logbuf_t)))) return NULL; va_start(ap, fmt); lb->sz = vasprintf((char**)&lb->buf, fmt, ap); @@ -76,7 +76,7 @@ logger_new(logger_reopen_func_t reopenfunc, logger_open_func_t openfunc, { logger_t *logger; - logger = malloc(sizeof(logger_t)); + logger = (logger_t *)malloc(sizeof(logger_t)); if (!logger) return NULL; logger_clear(logger); @@ -188,11 +188,11 @@ logger_close(logger_t *logger, void *fh) static void * logger_thread(void *arg) { - logger_t *logger = arg; + logger_t *logger = (logger_t *)arg; logbuf_t *lb; int e = 0; - while ((lb = thrqueue_dequeue(logger->queue))) { + while ((lb = (logbuf_t *)thrqueue_dequeue(logger->queue))) { if (logbuf_ctl_isset(lb, LBFLAG_REOPEN)) { if (logger->reopen() != 0) e = 1; @@ -36,7 +36,6 @@ #include "privsep.h" #include "ssl.h" #include "nat.h" -#include "proc.h" #include "cachemgr.h" #include "sys.h" #include "log.h" @@ -225,7 +224,7 @@ main_usage(void) static int main_loadtgcrt(const char *filename, void *arg) { - opts_t *opts = arg; + tfe_config *opts = arg; cert_t *cert; char **names; @@ -292,13 +291,15 @@ main(int argc, char *argv[]) { const char *argv0; int ch; - opts_t *opts; + tfe_config *opts; + proxy_ctx_t *proxy; + char *natengine; int pidfd = -1; int rv = EXIT_FAILURE; argv0 = argv[0]; - opts = opts_new(); + opts = tfe_config_new(); if (nat_getdefaultname()) { natengine = strdup(nat_getdefaultname()); if (!natengine) @@ -479,11 +480,9 @@ main(int argc, char *argv[]) if (!opts->ciphers) oom_die(argv0); break; - case 'r': - opts_proto_force(opts, optarg, argv0); + case 'r': tfe_config_proto_force(opts, optarg, argv0); break; - case 'R': - opts_proto_disable(opts, optarg, argv0); + case 'R': tfe_config_proto_disable(opts, optarg, argv0); break; case 'e': free(natengine); @@ -705,7 +704,8 @@ main(int argc, char *argv[]) } argc -= optind; argv += optind; - opts->spec = proxyspec_parse(&argc, &argv, natengine); + + tfe_config_load_from_file(opts, "./config.ini"); /* usage checks before defaults */ if (opts->detach && OPTS_DEBUG(opts)) { @@ -717,7 +717,7 @@ main(int argc, char *argv[]) fprintf(stderr, "%s: no proxyspec specified.\n", argv0); exit(EXIT_FAILURE); } - for (proxyspec_t *spec = opts->spec; spec; spec = spec->next) { + for (proxyspec *spec = opts->spec; spec; spec = spec->next) { if (spec->connect_addrlen || spec->sni_port) continue; if (!spec->natengine) { @@ -736,7 +736,7 @@ main(int argc, char *argv[]) spec->natlookup = nat_getlookupcb(spec->natengine); spec->natsocket = nat_getsocketcb(spec->natengine); } - if (opts_has_ssl_spec(opts)) { + if (tfe_config_has_ssl_spec(opts)) { if (ssl_init() == -1) { fprintf(stderr, "%s: failed to initialize OpenSSL.\n", argv0); @@ -801,7 +801,7 @@ main(int argc, char *argv[]) } #endif /* __APPLE__ */ } - if (opts_has_ssl_spec(opts) && opts->cakey && !opts->key) { + if (tfe_config_has_ssl_spec(opts) && opts->cakey && !opts->key) { /* * While browsers still generally accept it, use a leaf key * size of 1024 bit for leaf keys. When browsers start to @@ -865,9 +865,9 @@ main(int argc, char *argv[]) /* debugging */ if (OPTS_DEBUG(opts)) { main_version(); - opts_proto_dbg_dump(opts); + tfe_config_proto_dbg_dump(opts); log_dbg_printf("proxyspecs:\n"); - for (proxyspec_t *spec = opts->spec; spec; spec = spec->next) { + for (proxyspec *spec = opts->spec; spec; spec = spec->next) { char *specstr = proxyspec_str(spec); if (!specstr) { fprintf(stderr, "%s: out of memory\n", argv0); @@ -957,7 +957,7 @@ main(int argc, char *argv[]) close(pidfd); /* Initialize proxy before dropping privs */ - proxy_ctx_t *proxy = proxy_new(opts, clisock[0]); + proxy = proxy_new(opts, clisock[0]); if (!proxy) { log_err_printf("Failed to initialize proxy.\n"); exit(EXIT_FAILURE); @@ -1001,7 +1001,7 @@ out_cachemgr_failed: out_sslreinit_failed: out_log_failed: out_parent: - opts_free(opts); + tfe_config_free(opts); ssl_fini(); return rv; } @@ -64,11 +64,14 @@ #endif /* HAVE_IPFILTER */ #ifdef HAVE_NETFILTER +extern "C" +{ #include <limits.h> #include <linux/netfilter_ipv4.h> #include <linux/netfilter_ipv6.h> #include <linux/if.h> #include <linux/netfilter_ipv6/ip6_tables.h> +} #endif /* HAVE_NETFILTER */ @@ -405,7 +408,7 @@ nat_getsockname_lookup_cb(struct sockaddr *dst_addr, socklen_t *dst_addrlen, strerror(errno)); return -1; } - return 0; +// return 0; } #endif diff --git a/src/opts.cc b/src/opts.cc new file mode 100644 index 0000000..067b40c --- /dev/null +++ b/src/opts.cc @@ -0,0 +1,550 @@ +/*- + * SSLsplit - transparent SSL/TLS interception + * https://www.roe.ch/SSLsplit + * + * Copyright (c) 2009-2018, Daniel Roethlisberger <[email protected]>. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "opts.h" + +#include "sys.h" +#include "log.h" + +#include <string> +#include <vector> +#include <stdexcept> + +#include <string.h> +#include <sys/types.h> +#include <sys/socket.h> + +#include <openssl/dh.h> +#include <openssl/x509.h> +#include <MESA_prof_load.h> +#include <assert.h> + +#include "cfgparser.h" + +struct tfe_config *tfe_config_new() +{ + tfe_config *__config; + + __config = (tfe_config *) malloc(sizeof(tfe_config)); + memset(__config, 0, sizeof(tfe_config)); + + __config->sslcomp = 1; + __config->chain = sk_X509_new_null(); + __config->sslmethod = SSLv23_method; + + return __config; +} + +#define TFE_STRING_MAX 4096 + +static int __proxyspec_parse_each_entry( + tfe_config *cfg, + TfeConfigParser &ini_config_object, + const std::string &str_proxyspec) +{ + const std::string str_section = "proxyspec:" + str_proxyspec; + const char *cstr_str_section = str_section.c_str(); + + std::string str_listen_addr; + std::string str_listen_port; + std::string str_natengine; + std::string str_protocol; + + str_listen_addr = ini_config_object.GetValue<std::string>(str_section, "listen_addr"); + str_listen_port = ini_config_object.GetValue<std::string>(str_section, "listen_port"); + str_natengine = ini_config_object.GetValue<std::string>(str_section, "natengine"); + str_protocol = ini_config_object.GetValue<std::string>(str_section, "protocol"); + + struct proxyspec *__spec = (proxyspec *) malloc(sizeof(proxyspec)); + memset(__spec, 0, sizeof(proxyspec)); + + if (str_protocol == "http") + { + __spec->ssl = 0; + __spec->http = 1; + __spec->upgrade = 0; + } else if (str_protocol == "https") + { + __spec->ssl = 1; + __spec->http = 1; + __spec->upgrade = 0; + } else if (str_protocol == "ssl") + { + __spec->ssl = 1; + __spec->http = 0; + __spec->upgrade = 0; + } else if (str_protocol == "autossl") + { + __spec->ssl = 0; + __spec->http = 0; + __spec->upgrade = 1; + } + + __spec->natengine = strdup(str_natengine.c_str()); + assert(__spec->natengine != nullptr); + + int ret = sys_sockaddr_parse(&__spec->listen_addr, &__spec->listen_addrlen, str_listen_addr.c_str(), + str_listen_port.c_str(), AF_INET, EVUTIL_AI_PASSIVE); + if (ret < 0) + { + throw tfe_expection_cfg_invalid_format("", "", "", ""); + } + + log_dbg_printf("Proxyspec %s: Listen Address %s, Port %s, Protocol %s\n", str_proxyspec.c_str(), + str_listen_addr.c_str(), str_listen_port.c_str(), str_protocol.c_str()); + + + /* 插入到Spec链表头部 */ + __spec->next = cfg->spec; + cfg->spec = __spec; + + return 0; +} + +static int __ssl_protocol_load_from_file(tfe_config *cfg, TfeConfigParser &cfg_parser) +{ + bool __en_tls_1_0 = true; + bool __en_tls_1_1 = true; + bool __en_tls_1_2 = true; + bool __en_ssl_v2 = true; + bool __en_ssl_v3 = true; + + __en_tls_1_0 = cfg_parser.GetValueWithDefault("ssl_protocol", "tls_v1_0", __en_tls_1_0); + __en_tls_1_1 = cfg_parser.GetValueWithDefault("ssl_protocol", "tls_v1_1", __en_tls_1_1); + __en_tls_1_2 = cfg_parser.GetValueWithDefault("ssl_protocol", "tls_v1_2", __en_tls_1_2); + __en_ssl_v2 = cfg_parser.GetValueWithDefault("ssl_protocol", "ssl_v2", __en_ssl_v2); + __en_ssl_v3 = cfg_parser.GetValueWithDefault("ssl_protocol", "ssl_v3", __en_ssl_v3); + + if (!__en_tls_1_0) cfg->no_tls10 = 1; + if (!__en_tls_1_1) cfg->no_tls11 = 1; + if (!__en_tls_1_2) cfg->no_tls12 = 1; + if (!__en_ssl_v2) cfg->no_ssl2 = 1; + if (!__en_ssl_v3) cfg->no_ssl3 = 1; + + return 0; +} + +void tfe_config_load_from_file(tfe_config *cfg, const char *c_str_file) +{ + TfeConfigParser __config_parser(c_str_file); + + try + { + /* 读取ProxySpec列表 */ + std::string str_proxyspec_symbol = __config_parser.GetValue<std::string>("proxyspec", "symbol"); + char *__buffer_proxyspec = strdup(str_proxyspec_symbol.c_str()); + + /* 拆分列表,根据列表读取详细配置 */ + for (const char *__str_token = strtok(__buffer_proxyspec, ","); + __str_token != nullptr; __str_token = strtok(nullptr, ",")) + { + __proxyspec_parse_each_entry(cfg, __config_parser, std::string(__str_token)); + } + + /* 解析SSL/TLS版本功能开关 */ + __ssl_protocol_load_from_file(cfg, __config_parser); + } + catch (tfe_expection_cfg_invalid_format &e) + { + log_err_printf("Invalid format config entries in file %s, section %s, entry %s.", + e.file.c_str(), e.section.c_str(), e.item.c_str()); + goto __errout; + } + + catch (tfe_expection_cfg_lost_entry &e) + { + log_err_printf("Required config entries is not existed in file %s, section %s, entry %s.", + e.file.c_str(), e.section.c_str(), e.item.c_str()); + goto __errout; + } + + return; + +__errout: + exit(EXIT_FAILURE); +} + +void tfe_config_parse_args(tfe_config *tfe, int argc, char **argv) +{ + return; +} + +void tfe_config_free(tfe_config *opts) +{ + sk_X509_pop_free(opts->chain, X509_free); + + if (opts->cacrt) + X509_free(opts->cacrt); + + if (opts->cakey) + EVP_PKEY_free(opts->cakey); + + if (opts->key) + EVP_PKEY_free(opts->key); + + if (opts->dh) + DH_free(opts->dh); + + if (opts->ecdhcurve) + free(opts->ecdhcurve); + + if (opts->spec) + proxyspec_free(opts->spec); + + if (opts->ciphers) + free(opts->ciphers); + + if (opts->tgcrtdir) + free(opts->tgcrtdir); + + if (opts->crlurl) + free(opts->crlurl); + + if (opts->dropuser) + free(opts->dropuser); + + if (opts->dropgroup) + free(opts->dropgroup); + + if (opts->jaildir) + free(opts->jaildir); + + if (opts->pidfile) + free(opts->pidfile); + + if (opts->connectlog) + free(opts->connectlog); + + if (opts->contentlog) + free(opts->contentlog); + + if (opts->certgendir) + free(opts->certgendir); + + if (opts->contentlog_basedir) + free(opts->contentlog_basedir); + + if (opts->masterkeylog) + free(opts->masterkeylog); + + memset(opts, 0, sizeof(tfe_config)); + free(opts); +} + +/* + * Return 1 if opts_t contains a proxyspec that (eventually) uses SSL/TLS, + * 0 otherwise. When 0, it is safe to assume that no SSL/TLS operations + * will take place with this configuration. + */ +int +tfe_config_has_ssl_spec(tfe_config *opts) +{ + proxyspec *p = opts->spec; + + while (p) + { + if (p->ssl || p->upgrade) + return 1; + p = p->next; + } + + return 0; +} + +/* + * Return 1 if opts_t contains a proxyspec with dns, 0 otherwise. + */ +int +tfe_config_has_dns_spec(tfe_config *opts) +{ + proxyspec *p = opts->spec; + + while (p) + { + if (p->dns) + return 1; + p = p->next; + } + + return 0; +} + +/* + * Parse SSL proto string in optarg and look up the corresponding SSL method. + * Calls exit() on failure. + */ +void +tfe_config_proto_force(tfe_config *opts, const char *optarg, const char *argv0) +{ +#if OPENSSL_VERSION_NUMBER < 0x10100000L + if (opts->sslmethod != SSLv23_method) + { +#else /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ + if (opts->sslversion) { +#endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ + fprintf(stderr, "%s: cannot use -r multiple times\n", argv0); + exit(EXIT_FAILURE); + } + +#if OPENSSL_VERSION_NUMBER < 0x10100000L +#ifdef HAVE_SSLV2 + if (!strcmp(optarg, "ssl2")) { + opts->sslmethod = SSLv2_method; + } else +#endif /* HAVE_SSLV2 */ +#ifdef HAVE_SSLV3 + if (!strcmp(optarg, "ssl3")) + { + opts->sslmethod = SSLv3_method; + } else +#endif /* HAVE_SSLV3 */ +#ifdef HAVE_TLSV10 + if (!strcmp(optarg, "tls10") || !strcmp(optarg, "tls1")) + { + opts->sslmethod = TLSv1_method; + } else +#endif /* HAVE_TLSV10 */ +#ifdef HAVE_TLSV11 + if (!strcmp(optarg, "tls11")) + { + opts->sslmethod = TLSv1_1_method; + } else +#endif /* HAVE_TLSV11 */ +#ifdef HAVE_TLSV12 + if (!strcmp(optarg, "tls12")) + { + opts->sslmethod = TLSv1_2_method; + } else +#endif /* HAVE_TLSV12 */ +#else /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ + /* + * Support for SSLv2 and the corresponding SSLv2_method(), + * SSLv2_server_method() and SSLv2_client_method() functions were + * removed in OpenSSL 1.1.0. + */ +#ifdef HAVE_SSLV3 + if (!strcmp(optarg, "ssl3")) { + opts->sslversion = SSL3_VERSION; + } else +#endif /* HAVE_SSLV3 */ +#ifdef HAVE_TLSV10 + if (!strcmp(optarg, "tls10") || !strcmp(optarg, "tls1")) { + opts->sslversion = TLS1_VERSION; + } else +#endif /* HAVE_TLSV10 */ +#ifdef HAVE_TLSV11 + if (!strcmp(optarg, "tls11")) { + opts->sslversion = TLS1_1_VERSION; + } else +#endif /* HAVE_TLSV11 */ +#ifdef HAVE_TLSV12 + if (!strcmp(optarg, "tls12")) { + opts->sslversion = TLS1_2_VERSION; + } else +#endif /* HAVE_TLSV12 */ +#endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ + { + fprintf(stderr, "%s: Unsupported SSL/TLS protocol '%s'\n", + argv0, optarg); + exit(EXIT_FAILURE); + } +} + +/* + * Parse SSL proto string in optarg and set the corresponding no_foo bit. + * Calls exit() on failure. + */ +void +tfe_config_proto_disable(tfe_config *opts, const char *optarg, const char *argv0) +{ +#ifdef HAVE_SSLV2 + if (!strcmp(optarg, "ssl2")) { + opts->no_ssl2 = 1; + } else +#endif /* HAVE_SSLV2 */ +#ifdef HAVE_SSLV3 + if (!strcmp(optarg, "ssl3")) + { + opts->no_ssl3 = 1; + } else +#endif /* HAVE_SSLV3 */ +#ifdef HAVE_TLSV10 + if (!strcmp(optarg, "tls10") || !strcmp(optarg, "tls1")) + { + opts->no_tls10 = 1; + } else +#endif /* HAVE_TLSV10 */ +#ifdef HAVE_TLSV11 + if (!strcmp(optarg, "tls11")) + { + opts->no_tls11 = 1; + } else +#endif /* HAVE_TLSV11 */ +#ifdef HAVE_TLSV12 + if (!strcmp(optarg, "tls12")) + { + opts->no_tls12 = 1; + } else +#endif /* HAVE_TLSV12 */ + { + fprintf(stderr, "%s: Unsupported SSL/TLS protocol '%s'\n", + argv0, optarg); + exit(EXIT_FAILURE); + } +} + +/* + * Dump the SSL/TLS protocol related configuration to the debug log. + */ +void +tfe_config_proto_dbg_dump(tfe_config *opts) +{ + log_dbg_printf("SSL/TLS protocol: %s%s%s%s%s%s\n", +#if OPENSSL_VERSION_NUMBER < 0x10100000L +#ifdef HAVE_SSLV2 + (opts->sslmethod == SSLv2_method) ? "ssl2" : +#endif /* HAVE_SSLV2 */ +#ifdef HAVE_SSLV3 + (opts->sslmethod == SSLv3_method) ? "ssl3" : + #endif /* HAVE_SSLV3 */ + #ifdef HAVE_TLSV10 + (opts->sslmethod == TLSv1_method) ? "tls10" : + #endif /* HAVE_TLSV10 */ + #ifdef HAVE_TLSV11 + (opts->sslmethod == TLSv1_1_method) ? "tls11" : + #endif /* HAVE_TLSV11 */ + #ifdef HAVE_TLSV12 + (opts->sslmethod == TLSv1_2_method) ? "tls12" : + #endif /* HAVE_TLSV12 */ + #else /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ + #ifdef HAVE_SSLV3 + (opts->sslversion == SSL3_VERSION) ? "ssl3" : +#endif /* HAVE_SSLV3 */ +#ifdef HAVE_TLSV10 + (opts->sslversion == TLS1_VERSION) ? "tls10" : +#endif /* HAVE_TLSV10 */ +#ifdef HAVE_TLSV11 + (opts->sslversion == TLS1_1_VERSION) ? "tls11" : +#endif /* HAVE_TLSV11 */ +#ifdef HAVE_TLSV12 + (opts->sslversion == TLS1_2_VERSION) ? "tls12" : +#endif /* HAVE_TLSV12 */ + #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ + "negotiate", +#ifdef HAVE_SSLV2 + opts->no_ssl2 ? " -ssl2" : +#endif /* HAVE_SSLV2 */ + "", +#ifdef HAVE_SSLV3 + opts->no_ssl3 ? " -ssl3" : + #endif /* HAVE_SSLV3 */ + "", +#ifdef HAVE_TLSV10 + opts->no_tls10 ? " -tls10" : + #endif /* HAVE_TLSV10 */ + "", +#ifdef HAVE_TLSV11 + opts->no_tls11 ? " -tls11" : + #endif /* HAVE_TLSV11 */ + "", +#ifdef HAVE_TLSV12 + opts->no_tls12 ? " -tls12" : + #endif /* HAVE_TLSV12 */ + ""); +} + +/* + * Clear and free a proxy spec. + */ +void +proxyspec_free(proxyspec *spec) +{ + do + { + proxyspec *next = spec->next; + if (spec->natengine) + free(spec->natengine); + memset(spec, 0, sizeof(proxyspec)); + free(spec); + spec = next; + } while (spec); +} + +/* + * Return text representation of proxy spec for display to the user. + * Returned string must be freed by caller. + */ +char *proxyspec_str(proxyspec *spec) +{ + char *s; + char *lhbuf, *lpbuf; + char *cbuf = NULL; + if (sys_sockaddr_str((struct sockaddr *) &spec->listen_addr, + spec->listen_addrlen, &lhbuf, &lpbuf) != 0) + { + return NULL; + } + if (spec->connect_addrlen) + { + char *chbuf, *cpbuf; + if (sys_sockaddr_str((struct sockaddr *) &spec->connect_addr, + spec->connect_addrlen, + &chbuf, &cpbuf) != 0) + { + return NULL; + } + if (asprintf(&cbuf, "[%s]:%s", chbuf, cpbuf) < 0) + { + return NULL; + } + free(chbuf); + free(cpbuf); + } + if (spec->sni_port) + { + if (asprintf(&cbuf, "sni %i", spec->sni_port) < 0) + { + return NULL; + } + } + if (asprintf(&s, "[%s]:%s %s%s%s %s", lhbuf, lpbuf, + (spec->ssl ? "ssl" : "tcp"), + (spec->upgrade ? "|upgrade" : ""), + (spec->http ? "|http" : ""), + (spec->natengine ? spec->natengine : cbuf)) < 0) + { + s = NULL; + } + free(lhbuf); + free(lpbuf); + if (cbuf) + free(cbuf); + return s; +} + +/* vim: set noet ft=c: */ @@ -29,7 +29,6 @@ #ifndef OPTS_H #define OPTS_H -#include "proc.h" #include "nat.h" #include "ssl.h" #include "attrib.h" @@ -37,7 +36,8 @@ #include <sys/types.h> #include <sys/socket.h> -typedef struct proxyspec { +struct proxyspec +{ unsigned int ssl : 1; unsigned int http : 1; unsigned int upgrade: 1; @@ -54,35 +54,28 @@ typedef struct proxyspec { nat_lookup_cb_t natlookup; nat_socket_cb_t natsocket; struct proxyspec *next; -} proxyspec_t; +}; -typedef struct opts { +struct tfe_config +{ + /* Configure Files */ + char * cfgfile; + + /* Options */ unsigned int debug : 1; unsigned int detach : 1; unsigned int sslcomp : 1; -#ifdef HAVE_SSLV2 unsigned int no_ssl2 : 1; -#endif /* HAVE_SSLV2 */ -#ifdef HAVE_SSLV3 unsigned int no_ssl3 : 1; -#endif /* HAVE_SSLV3 */ -#ifdef HAVE_TLSV10 unsigned int no_tls10 : 1; -#endif /* HAVE_TLSV10 */ -#ifdef HAVE_TLSV11 unsigned int no_tls11 : 1; -#endif /* HAVE_TLSV11 */ -#ifdef HAVE_TLSV12 unsigned int no_tls12 : 1; -#endif /* HAVE_TLSV12 */ unsigned int passthrough : 1; unsigned int deny_ocsp : 1; unsigned int contentlog_isdir : 1; unsigned int contentlog_isspec : 1; -#ifdef HAVE_LOCAL_PROCINFO - unsigned int lprocinfo : 1; -#endif /* HAVE_LOCAL_PROCINFO */ unsigned int certgen_writeall: 1; + char *ciphers; char *certgendir; char *tgcrtdir; @@ -95,35 +88,31 @@ typedef struct opts { char *contentlog_basedir; /* static part of logspec, for privsep srv */ char *masterkeylog; CONST_SSL_METHOD *(*sslmethod)(void); -#if OPENSSL_VERSION_NUMBER >= 0x10100000L int sslversion; -#endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ X509 *cacrt; EVP_PKEY *cakey; EVP_PKEY *key; STACK_OF(X509) *chain; -#ifndef OPENSSL_NO_DH DH *dh; -#endif /* !OPENSSL_NO_DH */ -#ifndef OPENSSL_NO_ECDH char *ecdhcurve; -#endif /* !OPENSSL_NO_ECDH */ - proxyspec_t *spec; + + struct proxyspec * spec; char *crlurl; -} opts_t; +}; + +struct tfe_config *tfe_config_new(void) MALLOC; +void tfe_config_free(struct tfe_config *) NONNULL(1); +int tfe_config_has_ssl_spec(struct tfe_config *) NONNULL(1) WUNRES; +int tfe_config_has_dns_spec(struct tfe_config *) NONNULL(1) WUNRES; +void tfe_config_proto_force(struct tfe_config *, const char *, const char *) NONNULL(1,2,3); +void tfe_config_proto_disable(struct tfe_config *, const char *, const char *) NONNULL(1,2,3); +void tfe_config_proto_dbg_dump(struct tfe_config *) NONNULL(1); +void tfe_config_load_from_file(tfe_config *cfg, const char *c_str_file); -opts_t *opts_new(void) MALLOC; -void opts_free(opts_t *) NONNULL(1); -int opts_has_ssl_spec(opts_t *) NONNULL(1) WUNRES; -int opts_has_dns_spec(opts_t *) NONNULL(1) WUNRES; -void opts_proto_force(opts_t *, const char *, const char *) NONNULL(1,2,3); -void opts_proto_disable(opts_t *, const char *, const char *) NONNULL(1,2,3); -void opts_proto_dbg_dump(opts_t *) NONNULL(1); #define OPTS_DEBUG(opts) unlikely((opts)->debug) -proxyspec_t * proxyspec_parse(int *, char **[], const char *) MALLOC; -void proxyspec_free(proxyspec_t *) NONNULL(1); -char * proxyspec_str(proxyspec_t *) NONNULL(1) MALLOC; +void proxyspec_free(struct proxyspec *) NONNULL(1); +char * proxyspec_str(struct proxyspec *) NONNULL(1) MALLOC; #endif /* !OPTS_H */ diff --git a/privsep.c b/src/privsep.cc index 61d425f..794e2e2 100644 --- a/privsep.c +++ b/src/privsep.cc @@ -135,7 +135,7 @@ privsep_server_signal_handler(int sig) } static int WUNRES -privsep_server_openfile_verify(opts_t *opts, char *fn, int mkpath) +privsep_server_openfile_verify(tfe_config *opts, char *fn, int mkpath) { if (mkpath && !opts->contentlog_isspec) return -1; @@ -188,9 +188,9 @@ privsep_server_openfile(char *fn, int mkpath) } static int WUNRES -privsep_server_opensock_verify(opts_t *opts, void *arg) +privsep_server_opensock_verify(tfe_config *opts, void *arg) { - for (proxyspec_t *spec = opts->spec; spec; spec = spec->next) { + for (proxyspec *spec = opts->spec; spec; spec = spec->next) { if (spec == arg) return 0; } @@ -198,7 +198,7 @@ privsep_server_opensock_verify(opts_t *opts, void *arg) } static int WUNRES -privsep_server_opensock(proxyspec_t *spec) +privsep_server_opensock(proxyspec *spec) { evutil_socket_t fd; int on = 1; @@ -254,7 +254,7 @@ privsep_server_opensock(proxyspec_t *spec) } static int WUNRES -privsep_server_certfile_verify(opts_t *opts, char *fn) +privsep_server_certfile_verify(tfe_config *opts, char *fn) { if (!opts->certgendir) return -1; @@ -282,7 +282,7 @@ privsep_server_certfile(char *fn) * Returns 0 on success, 1 on EOF and -1 on error. */ static int WUNRES -privsep_server_handle_req(opts_t *opts, int srvsock) +privsep_server_handle_req(tfe_config *opts, int srvsock) { char req[PRIVSEP_MAX_REQ_SIZE]; char ans[PRIVSEP_MAX_ANS_SIZE]; @@ -374,7 +374,7 @@ privsep_server_handle_req(opts_t *opts, int srvsock) break; } case PRIVSEP_REQ_OPENSOCK: { - proxyspec_t *arg; + proxyspec *arg; int s; if (n != sizeof(char) + sizeof(arg)) { @@ -386,7 +386,7 @@ privsep_server_handle_req(opts_t *opts, int srvsock) } return 0; } - arg = *(proxyspec_t**)(&req[1]); + arg = *(proxyspec**)(&req[1]); if (privsep_server_opensock_verify(opts, arg) == -1) { ans[0] = PRIVSEP_ANS_DENIED; if (sys_sendmsgfd(srvsock, ans, 1, -1) == -1) { @@ -504,7 +504,7 @@ privsep_server_handle_req(opts_t *opts, int srvsock) * Returns 0 on a successful clean exit and -1 on errors. */ static int -privsep_server(opts_t *opts, int sigpipe, int srvsock[], size_t nsrvsock, +privsep_server(tfe_config *opts, int sigpipe, int srvsock[], size_t nsrvsock, pid_t childpid) { int srveof[nsrvsock]; @@ -697,7 +697,7 @@ privsep_client_openfile(int clisock, const char *fn, int mkpath) } int -privsep_client_opensock(int clisock, const proxyspec_t *spec) +privsep_client_opensock(int clisock, const proxyspec *spec) { char ans[PRIVSEP_MAX_ANS_SIZE]; char req[1 + sizeof(spec)]; @@ -705,7 +705,7 @@ privsep_client_opensock(int clisock, const proxyspec_t *spec) ssize_t n; req[0] = PRIVSEP_REQ_OPENSOCK; - *((const proxyspec_t **)&req[1]) = spec; + *((const proxyspec **)&req[1]) = spec; if (sys_sendmsgfd(clisock, req, sizeof(req), -1) == -1) { return -1; @@ -814,7 +814,7 @@ privsep_client_close(int clisock) * will not be touched. */ int -privsep_fork(opts_t *opts, int clisock[], size_t nclisock) +privsep_fork(tfe_config *opts, int clisock[], size_t nclisock) { int selfpipev[2]; /* self-pipe trick: signal handler -> select */ int chldpipev[2]; /* el cheapo interprocess sync early after fork */ diff --git a/privsep.h b/src/privsep.h index b59dab4..d12f8d8 100644 --- a/privsep.h +++ b/src/privsep.h @@ -32,10 +32,10 @@ #include "attrib.h" #include "opts.h" -int privsep_fork(opts_t *, int[], size_t); +int privsep_fork(struct tfe_config *, int[], size_t); int privsep_client_openfile(int, const char *, int); -int privsep_client_opensock(int, const proxyspec_t *spec); +int privsep_client_opensock(int, const proxyspec *spec); int privsep_client_certfile(int, const char *); int privsep_client_close(int); @@ -59,35 +59,38 @@ static int signals[] = { SIGTERM, SIGQUIT, SIGHUP, SIGINT, SIGPIPE, SIGUSR1 }; -struct proxy_ctx { +struct proxy_ctx +{ pxy_thrmgr_ctx_t *thrmgr; struct event_base *evbase; struct event *sev[sizeof(signals)/sizeof(int)]; struct event *gcev; struct proxy_listener_ctx *lctx; - opts_t *opts; + struct tfe_config *opts; }; /* * Listener context. */ -typedef struct proxy_listener_ctx { +typedef struct proxy_listener_ctx +{ pxy_thrmgr_ctx_t *thrmgr; - proxyspec_t *spec; - opts_t *opts; + struct proxyspec *spec; + struct tfe_config *opts; struct evconnlistener *evcl; struct proxy_listener_ctx *next; + } proxy_listener_ctx_t; static proxy_listener_ctx_t * -proxy_listener_ctx_new(pxy_thrmgr_ctx_t *thrmgr, proxyspec_t *spec, - opts_t *opts) MALLOC; +proxy_listener_ctx_new(pxy_thrmgr_ctx_t *thrmgr, proxyspec *spec, + tfe_config *opts) MALLOC; static proxy_listener_ctx_t * -proxy_listener_ctx_new(pxy_thrmgr_ctx_t *thrmgr, proxyspec_t *spec, - opts_t *opts) +proxy_listener_ctx_new(pxy_thrmgr_ctx_t *thrmgr, proxyspec *spec, + tfe_config *opts) { - proxy_listener_ctx_t *ctx = malloc(sizeof(proxy_listener_ctx_t)); + proxy_listener_ctx_t *ctx = (proxy_listener_ctx_t *)malloc(sizeof(proxy_listener_ctx_t)); if (!ctx) return NULL; memset(ctx, 0, sizeof(proxy_listener_ctx_t)); @@ -162,7 +165,7 @@ proxy_debug_base(const struct event_base *ev_base) */ static proxy_listener_ctx_t * proxy_listener_setup(struct event_base *evbase, pxy_thrmgr_ctx_t *thrmgr, - proxyspec_t *spec, opts_t *opts, int clisock) + proxyspec *spec, tfe_config *opts, int clisock) { proxy_listener_ctx_t *plc; int fd; @@ -251,13 +254,15 @@ proxy_gc_cb(UNUSED evutil_socket_t fd, UNUSED short what, void *arg) * Returns ctx on success, or NULL on error. */ proxy_ctx_t * -proxy_new(opts_t *opts, int clisock) +proxy_new(tfe_config *opts, int clisock) { proxy_listener_ctx_t *head; proxy_ctx_t *ctx; struct evdns_base *dnsbase; int rc; + struct timeval gc_delay = {60, 0}; + /* adds locking, only required if accessed from separate threads */ evthread_use_pthreads(); @@ -281,7 +286,7 @@ proxy_new(opts_t *opts, int clisock) goto leave1; } - if (opts_has_dns_spec(opts)) { + if (tfe_config_has_dns_spec(opts)) { /* create a dnsbase here purely for being able to test parsing * resolv.conf while we can still alert the user about it. */ dnsbase = evdns_base_new(ctx->evbase, 0); @@ -317,7 +322,7 @@ proxy_new(opts_t *opts, int clisock) } head = ctx->lctx = NULL; - for (proxyspec_t *spec = opts->spec; spec; spec = spec->next) { + for (proxyspec *spec = opts->spec; spec; spec = spec->next) { head = proxy_listener_setup(ctx->evbase, ctx->thrmgr, spec, opts, clisock); if (!head) @@ -334,7 +339,6 @@ proxy_new(opts_t *opts, int clisock) evsignal_add(ctx->sev[i], NULL); } - struct timeval gc_delay = {60, 0}; ctx->gcev = event_new(ctx->evbase, -1, EV_PERSIST, proxy_gc_cb, ctx); if (!ctx->gcev) goto leave4; @@ -34,7 +34,7 @@ typedef struct proxy_ctx proxy_ctx_t; -proxy_ctx_t * proxy_new(opts_t *, int) NONNULL(1) MALLOC; +proxy_ctx_t * proxy_new(struct tfe_config *, int) NONNULL(1) MALLOC; void proxy_run(proxy_ctx_t *) NONNULL(1); void proxy_loopbreak(proxy_ctx_t *) NONNULL(1); void proxy_free(proxy_ctx_t *) NONNULL(1); diff --git a/pxyconn.c b/src/pxyconn.cc index c9540a2..f6b0d93 100644 --- a/pxyconn.c +++ b/src/pxyconn.cc @@ -38,7 +38,6 @@ #include "url.h" #include "log.h" #include "attrib.h" -#include "proc.h" #include <netinet/in.h> #include <stdlib.h> @@ -79,21 +78,6 @@ static unsigned long ssl_session_context = 0x31415926; #endif /* USE_SSL_SESSION_ID_CONTEXT */ - -/* - * Proxy connection context state, describes a proxy connection - * with source and destination socket bufferevents, SSL context and - * other session state. One of these exists per handled proxy - * connection. - */ - -/* single dst or src socket bufferevent descriptor */ -typedef struct pxy_conn_desc { - struct bufferevent *bev; - SSL *ssl; - unsigned int closed : 1; -} pxy_conn_desc_t; - #ifdef HAVE_LOCAL_PROCINFO /* local process data - filled in iff pid != -1 */ typedef struct pxy_conn_lproc_desc { @@ -111,91 +95,15 @@ typedef struct pxy_conn_lproc_desc { } pxy_conn_lproc_desc_t; #endif /* HAVE_LOCAL_PROCINFO */ -/* actual proxy connection state consisting of two connection descriptors, - * connection-wide state and the specs and options */ -typedef struct pxy_conn_ctx { - /* per-connection state */ - struct pxy_conn_desc src; - struct pxy_conn_desc dst; - - /* status flags */ - unsigned int connected : 1; /* 0 until both ends are connected */ - unsigned int enomem : 1; /* 1 if out of memory */ - /* ssl */ - unsigned int sni_peek_retries : 6; /* max 64 SNI parse retries */ - unsigned int immutable_cert : 1; /* 1 if the cert cannot be changed */ - unsigned int generated_cert : 1; /* 1 if we generated a new cert */ - unsigned int passthrough : 1; /* 1 if SSL passthrough is active */ - /* http */ - unsigned int seen_req_header : 1; /* 0 until request header complete */ - unsigned int seen_resp_header : 1; /* 0 until response hdr complete */ - unsigned int sent_http_conn_close : 1; /* 0 until Conn: close sent */ - unsigned int ocsp_denied : 1; /* 1 if OCSP was denied */ - /* autossl */ - unsigned int clienthello_search : 1; /* 1 if waiting for hello */ - unsigned int clienthello_found : 1; /* 1 if conn upgrade to SSL */ - - /* server name indicated by client in SNI TLS extension */ - char *sni; - - /* log strings from socket */ - char *srchost_str; - char *srcport_str; - char *dsthost_str; - char *dstport_str; - - /* log strings from HTTP request */ - char *http_method; - char *http_uri; - char *http_host; - char *http_content_type; - - /* log strings from HTTP response */ - char *http_status_code; - char *http_status_text; - char *http_content_length; - - /* log strings related to SSL */ - char *ssl_names; - char *origcrtfpr; - char *usedcrtfpr; - -#ifdef HAVE_LOCAL_PROCINFO - /* local process information */ - pxy_conn_lproc_desc_t lproc; -#endif /* HAVE_LOCAL_PROCINFO */ - - /* content log context */ - log_content_ctx_t *logctx; - - /* store fd and fd event while connected is 0 */ - evutil_socket_t fd; - struct event *ev; - - /* original destination address, family and certificate */ - struct sockaddr_storage addr; - socklen_t addrlen; - int af; - X509 *origcrt; - - /* references to event base and configuration */ - struct event_base *evbase; - struct evdns_base *dnsbase; - int thridx; - pxy_thrmgr_ctx_t *thrmgr; - proxyspec_t *spec; - opts_t *opts; -} pxy_conn_ctx_t; - #define WANT_CONNECT_LOG(ctx) ((ctx)->opts->connectlog||!(ctx)->opts->detach) #define WANT_CONTENT_LOG(ctx) ((ctx)->opts->contentlog&&!(ctx)->passthrough) static pxy_conn_ctx_t * -pxy_conn_ctx_new(proxyspec_t *spec, opts_t *opts, +pxy_conn_ctx_new(proxyspec *spec, tfe_config *opts, pxy_thrmgr_ctx_t *thrmgr, evutil_socket_t fd) MALLOC NONNULL(1,2,3); static pxy_conn_ctx_t * -pxy_conn_ctx_new(proxyspec_t *spec, opts_t *opts, +pxy_conn_ctx_new(proxyspec *spec, tfe_config *opts, pxy_thrmgr_ctx_t *thrmgr, evutil_socket_t fd) { pxy_conn_ctx_t *ctx = malloc(sizeof(pxy_conn_ctx_t)); @@ -1155,7 +1063,7 @@ pxy_dstssl_create(pxy_conn_ctx_t *ctx) #endif /* SSL_MODE_RELEASE_BUFFERS */ /* session resuming based on remote endpoint address and port */ - sess = cachemgr_dsess_get((struct sockaddr *)&ctx->addr, + sess = (SSL_SESSION *)cachemgr_dsess_get((struct sockaddr *)&ctx->addr, ctx->addrlen, ctx->sni); /* new sess inst */ if (sess) { if (OPTS_DEBUG(ctx->opts)) { @@ -1625,12 +1533,13 @@ pxy_conn_terminate_free(pxy_conn_ctx_t *ctx, int is_requestor) pxy_conn_ctx_free(ctx, is_requestor); } +extern int pxy_http_read_cb(pxy_conn_ctx_t *ctx, struct bufferevent *bev); + /* * Callback for read events on the up- and downstream connection bufferevents. * Called when there is data ready in the input evbuffer. */ -static void -pxy_bev_readcb(struct bufferevent *bev, void *arg) +static void pxy_bev_readcb(struct bufferevent *bev, void *arg) { pxy_conn_ctx_t *ctx = arg; pxy_conn_desc_t *other = (bev==ctx->src.bev) ? &ctx->dst : &ctx->src; @@ -1642,122 +1551,40 @@ pxy_bev_readcb(struct bufferevent *bev, void *arg) } #endif /* DEBUG_PROXY */ - if (!ctx->connected) { + if (!ctx->connected) + { log_err_printf("readcb called when other end not connected - " "aborting.\n"); log_exceptcb(); return; } - if (ctx->clienthello_search) { - if (pxy_conn_autossl_peek_and_upgrade(ctx)) { - return; - } + if (ctx->clienthello_search && pxy_conn_autossl_peek_and_upgrade(ctx)) + { + return; } struct evbuffer *inbuf = bufferevent_get_input(bev); - if (other->closed) { - log_dbg_printf("Warning: Drained %zu bytes (conn closed)\n", - evbuffer_get_length(inbuf)); - evbuffer_drain(inbuf, evbuffer_get_length(inbuf)); - return; - } - struct evbuffer *outbuf = bufferevent_get_output(other->bev); - /* request header munging */ - if (ctx->spec->http && !ctx->seen_req_header && (bev == ctx->src.bev) - && !ctx->passthrough) { - logbuf_t *lb = NULL, *tail = NULL; - char *line; - while ((line = evbuffer_readln(inbuf, NULL, - EVBUFFER_EOL_CRLF))) { - char *replace; - if (WANT_CONTENT_LOG(ctx)) { - logbuf_t *tmp; - tmp = logbuf_new_printf(NULL, NULL, - "%s\r\n", line); - if (tail) { - if (tmp) { - tail->next = tmp; - tail = tail->next; - } - } else { - lb = tail = tmp; - } - } - replace = pxy_http_reqhdr_filter_line(line, ctx); - if (replace == line) { - evbuffer_add_printf(outbuf, "%s\r\n", line); - } else if (replace) { - evbuffer_add_printf(outbuf, "%s\r\n", replace); - free(replace); - } - free(line); - if (ctx->seen_req_header) { - /* request header complete */ - if (ctx->opts->deny_ocsp) { - pxy_ocsp_deny(ctx); - } - break; - } - } - if (lb && WANT_CONTENT_LOG(ctx)) { - if (log_content_submit(ctx->logctx, lb, - 1/*req*/) == -1) { - logbuf_free(lb); - log_err_printf("Warning: Content log " - "submission failed\n"); - } - } + if (other->closed) + { + log_dbg_printf("Warning: Drained %zu bytes (conn closed)\n", evbuffer_get_length(inbuf)); + evbuffer_drain(inbuf, evbuffer_get_length(inbuf)); + return; + } + + if (ctx->spec->http && !ctx->seen_req_header + && (bev == ctx->src.bev) && !ctx->passthrough) + { + pxy_http_read_cb(ctx, bev); if (!ctx->seen_req_header) return; - } else - /* response header munging */ - if (ctx->spec->http && !ctx->seen_resp_header && (bev == ctx->dst.bev) - && !ctx->passthrough) { - logbuf_t *lb = NULL, *tail = NULL; - char *line; - while ((line = evbuffer_readln(inbuf, NULL, - EVBUFFER_EOL_CRLF))) { - char *replace; - if (WANT_CONTENT_LOG(ctx)) { - logbuf_t *tmp; - tmp = logbuf_new_printf(NULL, NULL, - "%s\r\n", line); - if (tail) { - if (tmp) { - tail->next = tmp; - tail = tail->next; - } - } else { - lb = tail = tmp; - } - } - replace = pxy_http_resphdr_filter_line(line, ctx); - if (replace == line) { - evbuffer_add_printf(outbuf, "%s\r\n", line); - } else if (replace) { - evbuffer_add_printf(outbuf, "%s\r\n", replace); - free(replace); - } - free(line); - if (ctx->seen_resp_header) { - /* response header complete: log connection */ - if (WANT_CONNECT_LOG(ctx)) { - pxy_log_connect_http(ctx); - } - break; - } - } - if (lb && WANT_CONTENT_LOG(ctx)) { - if (log_content_submit(ctx->logctx, lb, - 0/*resp*/) == -1) { - logbuf_free(lb); - log_err_printf("Warning: Content log " - "submission failed\n"); - } - } + } + else if (ctx->spec->http && !ctx->seen_resp_header + && (bev == ctx->dst.bev) && !ctx->passthrough) + { + pxy_http_read_cb(ctx, bev); if (!ctx->seen_resp_header) return; } @@ -1839,7 +1666,7 @@ static void pxy_bev_eventcb(struct bufferevent *bev, short events, void *arg) { pxy_conn_ctx_t *ctx = arg; - pxy_conn_desc_t *this = (bev==ctx->src.bev) ? &ctx->src : &ctx->dst; + pxy_conn_desc_t *__this = (bev==ctx->src.bev) ? &ctx->src : &ctx->dst; pxy_conn_desc_t *other = (bev==ctx->src.bev) ? &ctx->dst : &ctx->src; int is_requestor = (bev == ctx->src.bev); @@ -1871,7 +1698,7 @@ pxy_bev_eventcb(struct bufferevent *bev, short events, void *arg) /* wrap client-side socket in an eventbuffer */ if ((ctx->spec->ssl || ctx->clienthello_found) && !ctx->passthrough) { - ctx->src.ssl = pxy_srcssl_create(ctx, this->ssl); + ctx->src.ssl = pxy_srcssl_create(ctx, __this->ssl); if (!ctx->src.ssl) { bufferevent_free_and_close_fd(bev, ctx); ctx->dst.bev = NULL; @@ -1980,13 +1807,13 @@ pxy_bev_eventcb(struct bufferevent *bev, short events, void *arg) connected: /* log connection if we don't analyze any headers */ - if ((!this->ssl || (bev == ctx->src.bev)) && + if ((!__this->ssl || (bev == ctx->src.bev)) && (!ctx->spec->http || ctx->passthrough) && WANT_CONNECT_LOG(ctx)) { pxy_log_connect_nonhttp(ctx); } - if (this->ssl) { + if (__this->ssl) { /* write SSL certificates to gendir */ if ((bev == ctx->src.bev) && ctx->opts->certgendir) { pxy_srccert_write(ctx); @@ -1995,7 +1822,7 @@ connected: /* log master key */ if (ctx->opts->masterkeylog) { char *keystr; - keystr = ssl_ssl_masterkey_to_str(this->ssl); + keystr = ssl_ssl_masterkey_to_str(__this->ssl); if ((keystr == NULL) || (log_masterkey_print_free(keystr) == -1)) { if (errno == ENOMEM) @@ -2007,7 +1834,7 @@ connected: } if (OPTS_DEBUG(ctx->opts)) { - if (this->ssl) { + if (__this->ssl) { char *keystr; /* for SSL, we get two connect events */ log_dbg_printf("SSL connected %s [%s]:%s" @@ -2020,9 +1847,10 @@ connected: bev == ctx->dst.bev ? ctx->dstport_str : ctx->srcport_str, - SSL_get_version(this->ssl), - SSL_get_cipher(this->ssl)); - keystr = ssl_ssl_masterkey_to_str(this->ssl); + SSL_get_version(__this->ssl), + SSL_get_cipher(__this->ssl), __this); + + keystr = ssl_ssl_masterkey_to_str(__this->ssl); if (keystr) { log_dbg_print_free(keystr); } @@ -2209,16 +2037,16 @@ leave: /* we only get a single disconnect event here for both connections */ if (OPTS_DEBUG(ctx->opts)) { log_dbg_printf("%s disconnected to [%s]:%s\n", - this->ssl ? "SSL" : "TCP", + __this->ssl ? "SSL" : "TCP", ctx->dsthost_str, ctx->dstport_str); log_dbg_printf("%s disconnected from [%s]:%s\n", - this->ssl ? "SSL" : "TCP", + __this->ssl ? "SSL" : "TCP", ctx->srchost_str, ctx->srcport_str); } - this->closed = 1; + __this->closed = 1; bufferevent_free_and_close_fd(bev, ctx); - this->bev = NULL; + __this->bev = NULL; if (other->closed) { pxy_conn_ctx_free(ctx, is_requestor); } @@ -2421,7 +2249,7 @@ void pxy_conn_setup(evutil_socket_t fd, struct sockaddr *peeraddr, int peeraddrlen, pxy_thrmgr_ctx_t *thrmgr, - proxyspec_t *spec, opts_t *opts) + proxyspec *spec, tfe_config *opts) { pxy_conn_ctx_t *ctx; diff --git a/src/pxyconn.h b/src/pxyconn.h new file mode 100644 index 0000000..13c0583 --- /dev/null +++ b/src/pxyconn.h @@ -0,0 +1,145 @@ +/*- + * SSLsplit - transparent SSL/TLS interception + * https://www.roe.ch/SSLsplit + * + * Copyright (c) 2009-2018, Daniel Roethlisberger <[email protected]>. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PXYCONN_H +#define PXYCONN_H + +#include "log.h" +#include "opts.h" +#include "attrib.h" +#include "pxythrmgr.h" + +#include <sys/types.h> +#include <sys/socket.h> + +#include <event2/event.h> +#include <event2/util.h> + +/* + * Proxy connection context state, describes a proxy connection + * with source and destination socket bufferevents, SSL context and + * other session state. One of these exists per handled proxy + * connection. + */ + +/* single dst or src socket bufferevent descriptor */ +typedef struct pxy_conn_desc { + struct bufferevent *bev; + SSL *ssl; + unsigned int closed : 1; +} pxy_conn_desc_t; + +/* actual proxy connection state consisting of two connection descriptors, + * connection-wide state and the specs and options */ + +typedef struct pxy_conn_ctx { + /* per-connection state */ + struct pxy_conn_desc src; + struct pxy_conn_desc dst; + + /* status flags */ + unsigned int connected : 1; /* 0 until both ends are connected */ + unsigned int enomem : 1; /* 1 if out of memory */ + /* ssl */ + unsigned int sni_peek_retries : 6; /* max 64 SNI parse retries */ + unsigned int immutable_cert : 1; /* 1 if the cert cannot be changed */ + unsigned int generated_cert : 1; /* 1 if we generated a new cert */ + unsigned int passthrough : 1; /* 1 if SSL passthrough is active */ + /* http */ + unsigned int seen_req_header : 1; /* 0 until request header complete */ + unsigned int seen_resp_header : 1; /* 0 until response hdr complete */ + unsigned int sent_http_conn_close : 1; /* 0 until Conn: close sent */ + unsigned int ocsp_denied : 1; /* 1 if OCSP was denied */ + /* autossl */ + unsigned int clienthello_search : 1; /* 1 if waiting for hello */ + unsigned int clienthello_found : 1; /* 1 if conn upgrade to SSL */ + + /* http request parser ctx */ + void * http_request_parser_ctx; + /* http response parser ctx */ + void * http_response_parser_ctx; + + /* server name indicated by client in SNI TLS extension */ + char *sni; + + /* log strings from socket */ + char *srchost_str; + char *srcport_str; + char *dsthost_str; + char *dstport_str; + + /* log strings from HTTP request */ + char *http_method; + char *http_uri; + char *http_host; + char *http_content_type; + + /* log strings from HTTP response */ + char *http_status_code; + char *http_status_text; + char *http_content_length; + + /* log strings related to SSL */ + char *ssl_names; + char *origcrtfpr; + char *usedcrtfpr; + +#ifdef HAVE_LOCAL_PROCINFO + /* local process information */ + pxy_conn_lproc_desc_t lproc; +#endif /* HAVE_LOCAL_PROCINFO */ + + /* content log context */ + log_content_ctx_t *logctx; + + /* store fd and fd event while connected is 0 */ + evutil_socket_t fd; + struct event *ev; + + /* original destination address, family and certificate */ + struct sockaddr_storage addr; + socklen_t addrlen; + int af; + X509 *origcrt; + + /* references to event base and configuration */ + struct event_base *evbase; + struct evdns_base *dnsbase; + int thridx; + pxy_thrmgr_ctx_t *thrmgr; + proxyspec *spec; + tfe_config *opts; +} pxy_conn_ctx_t; + +void pxy_conn_setup(evutil_socket_t, struct sockaddr *, int, + pxy_thrmgr_ctx_t *, proxyspec *, tfe_config *) + NONNULL(2,4,5,6); + +#endif /* !PXYCONN_H */ + +/* vim: set noet ft=c: */ diff --git a/src/pxyhttp.cc b/src/pxyhttp.cc new file mode 100644 index 0000000..1424fb4 --- /dev/null +++ b/src/pxyhttp.cc @@ -0,0 +1,182 @@ +/* HTTP/HTTP2 Protocol Handler + * + * Author: Lu Qiuwen<[email protected]> + * Date: 2018-04-08 + * + */ + +#include <assert.h> +#include <http_parser.h> +#include <event2/bufferevent.h> +#include <evdns.h> + +#include "pxyhttp.h" +#include "pxyconn.h" + +static int __http_request_cb_on_url(http_parser *parser, const char *at, size_t length) +{ + pxy_conn_ctx_t *ctx = (pxy_conn_ctx_t *) parser->data; + + /* 复制URI,注意补齐String的\0结尾 */ + ctx->http_uri = (char *) malloc(length + 1); + strncpy(ctx->http_uri, at, length); + ctx->http_uri[length] = '\0'; + + return 0; +} + +static int __http_request_cb_on_header_field(http_parser *parser, const char *at, size_t length) +{ + pxy_conn_ctx_t *ctx = (pxy_conn_ctx_t *) parser->data; + assert(ctx != NULL && at != NULL); + + /* 处理Host字段,置Host为0xffffffff,在value回调函数中处理的value即为host字段 */ + if (strncasecmp(at, "Host", length) == 0) + { + ctx->http_host = (char *) 0xffffffff; + goto __leave; + } + +__leave: + return 0; +} + +static int __http_request_cb_on_header_value(http_parser *parser, const char *at, size_t length) +{ + pxy_conn_ctx_t *ctx = (pxy_conn_ctx_t *) parser->data; + assert(ctx != NULL && at != NULL); + + /* 处理Host字段的值 */ + if (ctx->http_host == (void *) 0xffffffff) + { + ctx->http_host = (char *) malloc(length + 1); + strncpy(ctx->http_host, at, length); + ctx->http_host[length] = '\0'; + } + + return 0; +} + +static int __http_request_cb_on_headers_complete(http_parser *parser) +{ + pxy_conn_ctx_t *ctx = (pxy_conn_ctx_t *) parser->data; + ctx->seen_req_header = 1; + return 0; +} + +static int __http_resp_cb_on_status(http_parser *parser, const char *at, size_t length) +{ + return 0; +} + +static int __http_resp_cb_on_headers_complete(http_parser *parser) +{ + pxy_conn_ctx_t *ctx = (pxy_conn_ctx_t *) parser->data; + + /* HTTP状态码 */ + asprintf(&ctx->http_status_code, "%d", parser->status_code); + ctx->seen_resp_header = 1; + return 0; +} + +/* HTTP Request Handlers */ +const static struct http_parser_settings __setting_http_parser_request = +{ + nullptr, /* on_message_begin */ + __http_request_cb_on_url, /* on_url */ + nullptr, /* on_status */ + __http_request_cb_on_header_field, /* on_header_field */ + __http_request_cb_on_header_value, /* on_header_value */ + __http_request_cb_on_headers_complete, /* on_headers_complete */ + nullptr, /* on_body */ + nullptr /* on_message_complete */ +}; + +/* HTTP Response Handlers */ +const static struct http_parser_settings __setting_http_parser_resp = +{ + nullptr, /* on_message_begin */ + nullptr, /* on_url */ + __http_resp_cb_on_status, /* on_status */ + nullptr, /* on_header_field */ + nullptr, /* on_header_value */ + __http_resp_cb_on_headers_complete, /* on_headers_complete */ + nullptr, /* on_body */ + nullptr /* on_message_complete */ +}; + +int pxy_http_read_cb(pxy_conn_ctx_t *ctx, struct bufferevent *bev) +{ + pxy_conn_desc_t *other = (bev == ctx->src.bev) ? &ctx->dst : &ctx->src; + int is_http_request = (bev == ctx->src.bev); + + /* HTTP Parser Handler */ + http_parser *http_parser_ctx = is_http_request ? + (http_parser *)ctx->http_request_parser_ctx : + (http_parser *)ctx->http_response_parser_ctx; + + void **http_parser_ctx_ref = is_http_request ? + &ctx->http_request_parser_ctx : + &ctx->http_response_parser_ctx; + + /* HTTP Passer Type */ + enum http_parser_type http_parser_work_mode = is_http_request ? + HTTP_REQUEST : + HTTP_RESPONSE; + + const struct http_parser_settings *http_parser_cb = is_http_request ? + &__setting_http_parser_request : + &__setting_http_parser_resp; + + /* 第一次请求,解析器句柄为空,创建新的解析器上下文 */ + if (http_parser_ctx == NULL) + { + http_parser_ctx = (http_parser *)malloc(sizeof(http_parser)); + *http_parser_ctx_ref = http_parser_ctx; + + http_parser_ctx->data = ctx; + http_parser_init(http_parser_ctx, http_parser_work_mode); + } + + /* 已经处理了HTTP Header,转发其他数据 */ + if (is_http_request && ctx->seen_req_header) + return 0; + if (!is_http_request && ctx->seen_resp_header) + return 0; + + struct evbuffer *input_buffer = bufferevent_get_input(bev); + size_t input_buffer_len = evbuffer_get_length(input_buffer); + + if (input_buffer_len == 0) + return 0; + + /* 连续的副本,供http_parser扫描使用 */ + char *__buffer_copy = (char *)malloc(input_buffer_len); + assert(__buffer_copy != NULL); + + /* 从buffer中拷贝出来一个副本 */ + ssize_t __buffer_len = evbuffer_copyout(input_buffer, __buffer_copy, input_buffer_len); + if (__buffer_len < 0) goto __error; + + /* 送入HTTP解析器处理 */ + if (http_parser_execute(http_parser_ctx, http_parser_cb, __buffer_copy, __buffer_len) + != __buffer_len) + { + goto __error; + } + + /* 判断此时HTTP头部是否完整,若完整,即可调用业务层处理, + * 每个HTTP事务仅在此调用一次业务层处理逻辑,调用结束后即可进入转发流程 */ + if(is_http_request && ctx->seen_req_header) + { + //TODO: Call Biz + } + if(!is_http_request && ctx->seen_resp_header) + { + //TODO: Call Biz + } + +__error: + free(__buffer_copy); + return -1; +}
\ No newline at end of file diff --git a/src/pxyhttp.h b/src/pxyhttp.h new file mode 100644 index 0000000..2ad3c13 --- /dev/null +++ b/src/pxyhttp.h @@ -0,0 +1,4 @@ +#ifndef TFE_PXYHTTP_H +#define TFE_PXYHTTP_H + +#endif //TFE_PXYHTTP_H diff --git a/pxysslshut.c b/src/pxysslshut.cc index 8db900f..c48767f 100644 --- a/pxysslshut.c +++ b/src/pxysslshut.cc @@ -51,7 +51,7 @@ */ typedef struct pxy_ssl_shutdown_ctx { - opts_t *opts; + tfe_config *opts; struct event_base *evbase; struct event *ev; SSL *ssl; @@ -59,7 +59,7 @@ typedef struct pxy_ssl_shutdown_ctx { } pxy_ssl_shutdown_ctx_t; static pxy_ssl_shutdown_ctx_t * -pxy_ssl_shutdown_ctx_new(opts_t *opts, struct event_base *evbase, SSL *ssl) +pxy_ssl_shutdown_ctx_new(tfe_config *opts, struct event_base *evbase, SSL *ssl) { pxy_ssl_shutdown_ctx_t *ctx; @@ -165,7 +165,7 @@ complete: * socket is closed, eventually, or in the case of fatal errors, immediately. */ void -pxy_ssl_shutdown(opts_t *opts, struct event_base *evbase, SSL *ssl, +pxy_ssl_shutdown(tfe_config *opts, struct event_base *evbase, SSL *ssl, evutil_socket_t fd) { pxy_ssl_shutdown_ctx_t *sslshutctx; diff --git a/pxysslshut.h b/src/pxysslshut.h index a76d60c..9e3975b 100644 --- a/pxysslshut.h +++ b/src/pxysslshut.h @@ -36,7 +36,7 @@ #include <event2/event.h> #include <event2/util.h> -void pxy_ssl_shutdown(opts_t *, struct event_base *, SSL *, evutil_socket_t) +void pxy_ssl_shutdown(tfe_config *, struct event_base *, SSL *, evutil_socket_t) NONNULL(1,2,3); #endif /* !PXYSSLSHUT_H */ diff --git a/pxythrmgr.c b/src/pxythrmgr.cc index 5f867c7..a670732 100644 --- a/pxythrmgr.c +++ b/src/pxythrmgr.cc @@ -53,7 +53,7 @@ typedef struct pxy_thr_ctx { struct pxy_thrmgr_ctx { int num_thr; - opts_t *opts; + tfe_config *opts; pxy_thr_ctx_t **thr; pthread_mutex_t mutex; }; @@ -96,7 +96,7 @@ pxy_thrmgr_thr(void *arg) * This gets called before forking to background. */ pxy_thrmgr_ctx_t * -pxy_thrmgr_new(opts_t *opts) +pxy_thrmgr_new(tfe_config *opts) { pxy_thrmgr_ctx_t *ctx; @@ -120,7 +120,7 @@ pxy_thrmgr_run(pxy_thrmgr_ctx_t *ctx) { int idx = -1, dns = 0; - dns = opts_has_dns_spec(ctx->opts); + dns = tfe_config_has_dns_spec(ctx->opts); if (pthread_mutex_init(&ctx->mutex, NULL)) { log_dbg_printf("Failed to initialize mutex\n"); diff --git a/pxythrmgr.h b/src/pxythrmgr.h index 8cd2f7c..88f142d 100644 --- a/pxythrmgr.h +++ b/src/pxythrmgr.h @@ -40,7 +40,7 @@ typedef struct pxy_thrmgr_ctx pxy_thrmgr_ctx_t; -pxy_thrmgr_ctx_t * pxy_thrmgr_new(opts_t *) MALLOC; +pxy_thrmgr_ctx_t * pxy_thrmgr_new(tfe_config *) MALLOC; int pxy_thrmgr_run(pxy_thrmgr_ctx_t *) NONNULL(1) WUNRES; void pxy_thrmgr_free(pxy_thrmgr_ctx_t *) NONNULL(1); @@ -1958,6 +1958,15 @@ ssl_tls_clienthello_parse(const unsigned char *buf, ssize_t sz, int search, ssize_t n = sz; char *sn = NULL; + ssize_t tlsextslen; + ssize_t sidlen; + ssize_t suiteslen; + ssize_t compslen; + ssize_t msglen; + ssize_t recordlen; + + //===== + *clienthello = NULL; DBG_printf("parsing buffer of sz %zd\n", sz); @@ -2084,7 +2093,8 @@ ssl_tls_clienthello_parse(const unsigned char *buf, ssize_t sz, int search, return 1; } DBG_printf("length: %02x %02x\n", p[0], p[1]); - ssize_t recordlen = p[1] + (p[0] << 8); + + recordlen = p[1] + (p[0] << 8); DBG_printf("recordlen=%zd\n", recordlen); p += 2; n -= 2; if (recordlen < 36) /* arbitrary size too small for a c-h */ @@ -2109,7 +2119,7 @@ ssl_tls_clienthello_parse(const unsigned char *buf, ssize_t sz, int search, if (n < 3) continue; DBG_printf("message len: %02x %02x %02x\n", p[0], p[1], p[2]); - ssize_t msglen = p[2] + (p[1] << 8) + (p[0] << 16); + msglen = p[2] + (p[1] << 8) + (p[0] << 16); DBG_printf("msglen=%zd\n", msglen); p += 3; n -= 3; if (msglen < 32) /* arbitrary size too small for a c-h */ @@ -2141,7 +2151,7 @@ ssl_tls_clienthello_parse(const unsigned char *buf, ssize_t sz, int search, if (n < 1) continue; DBG_printf("clienthello sidlen %02x\n", *p); - ssize_t sidlen = *p; /* session id length, 0..32 */ + sidlen = *p; /* session id length, 0..32 */ p += 1; n -= 1; if (n < sidlen) continue; @@ -2151,7 +2161,8 @@ ssl_tls_clienthello_parse(const unsigned char *buf, ssize_t sz, int search, continue; DBG_printf("clienthello cipher suites length %02x %02x\n", p[0], p[1]); - ssize_t suiteslen = p[1] + (p[0] << 8); + + suiteslen = p[1] + (p[0] << 8); p += 2; n -= 2; if (n < suiteslen) continue; @@ -2161,7 +2172,8 @@ ssl_tls_clienthello_parse(const unsigned char *buf, ssize_t sz, int search, if (n < 1) continue; DBG_printf("clienthello compress methods length %02x\n", *p); - ssize_t compslen = *p; + + compslen = *p; p++; n--; if (n < compslen) continue; @@ -2180,7 +2192,7 @@ ssl_tls_clienthello_parse(const unsigned char *buf, ssize_t sz, int search, if (n < 2) continue; DBG_printf("tlsexts length %02x %02x\n", p[0], p[1]); - ssize_t tlsextslen = p[1] + (p[0] << 8); + tlsextslen = p[1] + (p[0] << 8); DBG_printf("tlsextslen %zd\n", tlsextslen); p += 2; n -= 2; if (n < tlsextslen) @@ -357,9 +357,8 @@ sys_group_str(gid_t gid) * On success, returns address family and fills in addr, addrlen. * Returns -1 on error. */ -int -sys_sockaddr_parse(struct sockaddr_storage *addr, socklen_t *addrlen, - char *naddr, char *nport, int af, int flags) +int sys_sockaddr_parse(struct sockaddr_storage *addr, socklen_t *addrlen, + const char *naddr, const char *nport, int af, int flags) { struct evutil_addrinfo hints; struct evutil_addrinfo *ai; @@ -46,8 +46,9 @@ int sys_isgroup(const char *) NONNULL(1) WUNRES; char * sys_user_str(uid_t) MALLOC; char * sys_group_str(gid_t) MALLOC; -int sys_sockaddr_parse(struct sockaddr_storage *, socklen_t *, - char *, char *, int, int) NONNULL(1,2,3,4) WUNRES; +int sys_sockaddr_parse( + struct sockaddr_storage *, socklen_t *, + const char *, const char *, int, int) NONNULL(1, 2, 3, 4) WUNRES; int sys_sockaddr_str(struct sockaddr *, socklen_t, char **, char **) NONNULL(1,3,4); char * sys_ip46str_sanitize(const char *) NONNULL(1) MALLOC; diff --git a/thrqueue.c b/src/thrqueue.cc index 1807bd7..1807bd7 100644 --- a/thrqueue.c +++ b/src/thrqueue.cc diff --git a/thrqueue.h b/src/thrqueue.h index 4bc6e8c..4bc6e8c 100644 --- a/thrqueue.h +++ b/src/thrqueue.h diff --git a/base64.t.c b/test/base64.t.c index f95f020..f95f020 100644 --- a/base64.t.c +++ b/test/base64.t.c diff --git a/cachedsess.t.c b/test/cachedsess.t.c index af031f2..af031f2 100644 --- a/cachedsess.t.c +++ b/test/cachedsess.t.c diff --git a/cachefkcrt.t.c b/test/cachefkcrt.t.c index 2930f59..2930f59 100644 --- a/cachefkcrt.t.c +++ b/test/cachefkcrt.t.c diff --git a/cachemgr.t.c b/test/cachemgr.t.c index 1229c88..1229c88 100644 --- a/cachemgr.t.c +++ b/test/cachemgr.t.c diff --git a/cachessess.t.c b/test/cachessess.t.c index a50b467..a50b467 100644 --- a/cachessess.t.c +++ b/test/cachessess.t.c diff --git a/cachetgcrt.t.c b/test/cachetgcrt.t.c index f4c4ad6..f4c4ad6 100644 --- a/cachetgcrt.t.c +++ b/test/cachetgcrt.t.c diff --git a/dynbuf.t.c b/test/dynbuf.t.c index db275c5..db275c5 100644 --- a/dynbuf.t.c +++ b/test/dynbuf.t.c @@ -86,7 +86,7 @@ static char *argv14[] = { START_TEST(proxyspec_parse_01) { - proxyspec_t *spec; + proxyspec *spec; int argc = 5; char **argv = argv01; @@ -110,7 +110,7 @@ END_TEST START_TEST(proxyspec_parse_02) { - proxyspec_t *spec; + proxyspec *spec; int argc = 5; char **argv = argv02; @@ -134,7 +134,7 @@ END_TEST START_TEST(proxyspec_parse_03) { - proxyspec_t *spec; + proxyspec *spec; int argc = 2; char **argv = argv01; @@ -147,7 +147,7 @@ END_TEST START_TEST(proxyspec_parse_04) { - proxyspec_t *spec; + proxyspec *spec; int argc = 4; char **argv = argv01; @@ -160,7 +160,7 @@ END_TEST START_TEST(proxyspec_parse_05) { - proxyspec_t *spec; + proxyspec *spec; int argc = 5; char **argv = argv03; @@ -184,7 +184,7 @@ END_TEST START_TEST(proxyspec_parse_06) { - proxyspec_t *spec; + proxyspec *spec; int argc = 5; char **argv = argv04; @@ -208,7 +208,7 @@ END_TEST START_TEST(proxyspec_parse_07) { - proxyspec_t *spec; + proxyspec *spec; int argc = 5; char **argv = argv05; @@ -232,7 +232,7 @@ END_TEST START_TEST(proxyspec_parse_08) { - proxyspec_t *spec; + proxyspec *spec; int argc = 5; char **argv = argv06; @@ -255,7 +255,7 @@ END_TEST START_TEST(proxyspec_parse_09) { - proxyspec_t *spec; + proxyspec *spec; int argc = 5; char **argv = argv07; @@ -268,7 +268,7 @@ END_TEST START_TEST(proxyspec_parse_10) { - proxyspec_t *spec; + proxyspec *spec; int argc = 4; char **argv = argv06; @@ -281,7 +281,7 @@ END_TEST START_TEST(proxyspec_parse_11) { - proxyspec_t *spec; + proxyspec *spec; int argc = 3; char **argv = argv08; @@ -305,7 +305,7 @@ END_TEST START_TEST(proxyspec_parse_12) { - proxyspec_t *spec; + proxyspec *spec; int argc = 4; char **argv = argv08; @@ -318,7 +318,7 @@ END_TEST START_TEST(proxyspec_parse_13) { - proxyspec_t *spec; + proxyspec *spec; int argc = 10; char **argv = argv09; @@ -353,7 +353,7 @@ END_TEST START_TEST(proxyspec_parse_14) { - proxyspec_t *spec; + proxyspec *spec; int argc = 6; char **argv = argv10; @@ -389,7 +389,7 @@ END_TEST START_TEST(proxyspec_parse_15) { - proxyspec_t *spec; + proxyspec *spec; int argc = 3; char **argv = argv11; @@ -412,7 +412,7 @@ END_TEST START_TEST(proxyspec_parse_16) { - proxyspec_t *spec; + proxyspec *spec; int argc = 10; char **argv = argv12; @@ -447,7 +447,7 @@ END_TEST START_TEST(proxyspec_parse_17) { - proxyspec_t *spec; + proxyspec *spec; int argc = 5; char **argv = argv13; @@ -460,7 +460,7 @@ END_TEST START_TEST(proxyspec_parse_18) { - proxyspec_t *spec; + proxyspec *spec; int argc = 8; char **argv = argv14; diff --git a/pxythrmgr.t.c b/test/pxythrmgr.t.c index 529b8b8..529b8b8 100644 --- a/pxythrmgr.t.c +++ b/test/pxythrmgr.t.c diff --git a/vendor/CMakeLists.txt b/vendor/CMakeLists.txt new file mode 100644 index 0000000..8042f02 --- /dev/null +++ b/vendor/CMakeLists.txt @@ -0,0 +1,103 @@ +# CMakeFiles for 3rd vendor library + +include(ExternalProject) + +### Libevent 2.1.8 +ExternalProject_Add(libevent + PREFIX libevent + URL ${CMAKE_CURRENT_SOURCE_DIR}/libevent-2.1.8-stable.tar.gz + URL_MD5 f3eeaed018542963b7d2416ef1135ecc + CONFIGURE_COMMAND ./configure --prefix=<INSTALL_DIR> --disable-shared + BUILD_IN_SOURCE 1) + +ExternalProject_Get_Property(libevent INSTALL_DIR) +set(LIBEVENT_INCLUDE_DIRECTORIES ${INSTALL_DIR}/include) +file(MAKE_DIRECTORY ${LIBEVENT_INCLUDE_DIRECTORIES}) + +add_library(libevent-static STATIC IMPORTED GLOBAL) +set_property(TARGET libevent-static PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/libevent.a) +set_property(TARGET libevent-static PROPERTY IMPORTED_INTERFACE_LINK_LIBRARIES pthread crypto) +set_property(TARGET libevent-static PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${INSTALL_DIR}/include) + +add_library(libevent-static-openssl STATIC IMPORTED GLOBAL) +set_property(TARGET libevent-static-openssl PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/libevent_openssl.a) +set_property(TARGET libevent-static-openssl PROPERTY IMPORTED_INTERFACE_LINK_LIBRARIES pthread crypto) +set_property(TARGET libevent-static-openssl PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${INSTALL_DIR}/include) + +add_library(libevent-static-pthreads STATIC IMPORTED GLOBAL) +set_property(TARGET libevent-static-pthreads PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/libevent_pthreads.a) +set_property(TARGET libevent-static-pthreads PROPERTY IMPORTED_INTERFACE_LINK_LIBRARIES pthread crypto) +set_property(TARGET libevent-static-pthreads PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${INSTALL_DIR}/include) + +### http parser +ExternalProject_Add(http-parser + PREFIX http-parser + URL ${CMAKE_CURRENT_SOURCE_DIR}/http-parser-2.8.1.tar.gz + URL_MD5 cb8cbe17d68c4101eebe80229e32efdb + CONFIGURE_COMMAND "" + BUILD_COMMAND make package + INSTALL_COMMAND "" + BUILD_IN_SOURCE 1) + +ExternalProject_Get_Property(http-parser SOURCE_DIR) +set(HTTP_PARSER_INCLUDE_DIRECTORIES ${SOURCE_DIR}) +file(MAKE_DIRECTORY ${HTTP_PARSER_INCLUDE_DIRECTORIES}) + +add_library(http-parser-static STATIC IMPORTED GLOBAL) +set_property(TARGET http-parser-static PROPERTY IMPORTED_LOCATION ${SOURCE_DIR}/libhttp_parser.a) +set_property(TARGET http-parser-static PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${SOURCE_DIR}) + +### libcheck +ExternalProject_Add(libcheck + PREFIX libcheck + URL ${CMAKE_CURRENT_SOURCE_DIR}/check-0.12.0.tar.gz + URL_MD5 31b17c6075820a434119592941186f70 + CONFIGURE_COMMAND ./configure --prefix=<INSTALL_DIR> --disable-shared + BUILD_IN_SOURCE 1) + +ExternalProject_Get_Property(libcheck INSTALL_DIR) +set(LIBCHECK_INCLUDE_DIRECTORIES ${INSTALL_DIR}/include) +file(MAKE_DIRECTORY ${LIBCHECK_INCLUDE_DIRECTORIES}) + +add_library(libcheck-static STATIC IMPORTED GLOBAL) +set_property(TARGET libcheck-static PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/libcheck.a) +set_property(TARGET libcheck-static PROPERTY IMPORTED_INTERFACE_LINK_LIBRARIES pthread rt m) +set_property(TARGET libcheck-static PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${INSTALL_DIR}/include) + +### MESA Prof Load +ExternalProject_Add(MESA_prof_load + PREFIX MESA_prof_load + URL ${CMAKE_CURRENT_SOURCE_DIR}/MESA_prof_load-3b2bfd.tar.gz + URL_MD5 411eedec773e6265bf9185846cab0f15 + CONFIGURE_COMMAND "" + BUILD_COMMAND make + INSTALL_COMMAND "" + BUILD_IN_SOURCE 1) + +ExternalProject_Get_Property(MESA_prof_load SOURCE_DIR) +set(MESA_PROF_LOAD_INCLUDE_DIRECTORIES ${SOURCE_DIR}/include) +file(MAKE_DIRECTORY ${MESA_PROF_LOAD_INCLUDE_DIRECTORIES}) + +add_library(MESA_prof_load-static STATIC IMPORTED GLOBAL) +set_property(TARGET MESA_prof_load-static PROPERTY IMPORTED_LOCATION ${SOURCE_DIR}/lib/libMESA_prof_load.a) +set_property(TARGET MESA_prof_load-static PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${SOURCE_DIR}/inc) + +#### GoogleTest +#ExternalProject_Add(googletest +# PREFIX googletest +# URL ${CMAKE_CURRENT_SOURCE_DIR}/googletest-release-1.8.0.tar.gz +# URL_MD5 16877098823401d1bf2ed7891d7dce36 +# CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR> -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}) +# +#ExternalProject_Get_Property(googletest INSTALL_DIR) +#set(GTEST_INCLUDE_DIRECTORIES ${INSTALL_DIR}/include) +#file(MAKE_DIRECTORY ${GTEST_INCLUDE_DIRECTORIES}) +# +#add_library(gtest STATIC IMPORTED GLOBAL) +#set_property(TARGET gtest PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/libgtest.a) +#set_property(TARGET gtest PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${INSTALL_DIR}/include) +# +#add_library(gmock STATIC IMPORTED GLOBAL) +#set_property(TARGET gmock PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/libgtest.a) +#set_property(TARGET gmock PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${INSTALL_DIR}/include) + diff --git a/vendor/MESA_prof_load-3b2bfd.tar.gz b/vendor/MESA_prof_load-3b2bfd.tar.gz Binary files differnew file mode 100644 index 0000000..8004fa3 --- /dev/null +++ b/vendor/MESA_prof_load-3b2bfd.tar.gz diff --git a/vendor/check-0.12.0.tar.gz b/vendor/check-0.12.0.tar.gz Binary files differnew file mode 100644 index 0000000..375dbce --- /dev/null +++ b/vendor/check-0.12.0.tar.gz diff --git a/vendor/googletest-release-1.8.0.tar.gz b/vendor/googletest-release-1.8.0.tar.gz Binary files differnew file mode 100644 index 0000000..a40df33 --- /dev/null +++ b/vendor/googletest-release-1.8.0.tar.gz diff --git a/vendor/http-parser-2.8.1.tar.gz b/vendor/http-parser-2.8.1.tar.gz Binary files differnew file mode 100644 index 0000000..85d2b5a --- /dev/null +++ b/vendor/http-parser-2.8.1.tar.gz diff --git a/vendor/libevent-2.1.8-stable.tar.gz b/vendor/libevent-2.1.8-stable.tar.gz Binary files differnew file mode 100644 index 0000000..2004f84 --- /dev/null +++ b/vendor/libevent-2.1.8-stable.tar.gz |
