diff --git a/Changes b/Changes index 7a4e44891..efa8b1d34 100644 --- a/Changes +++ b/Changes @@ -1,3 +1,10 @@ +shadowsocks-libev (2.6.0-1) unstable; urgency=medium + + * Add HTTP/TLS obfuscating. + * Add support of aunch_activate_socket on macOS. + + -- Max Lv Tue, 27 Dec 2016 16:37:23 +0800 + shadowsocks-libev (2.5.6-1) unstable; urgency=medium * Add outbound ACL for server. diff --git a/Makefile.in b/Makefile.in index c72c38886..f51d2ecf5 100644 --- a/Makefile.in +++ b/Makefile.in @@ -303,7 +303,6 @@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ -RM = @RM@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ diff --git a/README.md b/README.md index ea69e7166..8d93f31ce 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ It is a port of [Shadowsocks](https://github.com/shadowsocks/shadowsocks) created by [@clowwindy](https://github.com/clowwindy), which is maintained by [@madeye](https://github.com/madeye) and [@linusyang](https://github.com/linusyang). -Current version: 2.5.6 | [Changelog](debian/changelog) +Current version: 2.6.0 | [Changelog](debian/changelog) Travis CI: [![Travis CI](https://travis-ci.org/shadowsocks/shadowsocks-libev.svg?branch=master)](https://travis-ci.org/shadowsocks/shadowsocks-libev) diff --git a/config.h.in b/config.h.in index 03ee29c60..cbc528e7c 100644 --- a/config.h.in +++ b/config.h.in @@ -79,6 +79,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LANGINFO_H +/* Define to 1 if you have the `ev' library (-lev). */ +#undef HAVE_LIBEV + /* Compiling with pcre support */ #undef HAVE_LIBPCRE @@ -88,6 +91,12 @@ /* Define to 1 if you have the `socket' library (-lsocket). */ #undef HAVE_LIBSOCKET +/* Define to 1 if you have the `sodium' library (-lsodium). */ +#undef HAVE_LIBSODIUM + +/* Define to 1 if you have the `udns' library (-ludns). */ +#undef HAVE_LIBUDNS + /* Define to 1 if you have the header file. */ #undef HAVE_LIMITS_H diff --git a/configure b/configure index a40b5e72b..9d32dc76e 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for shadowsocks-libev 2.5.6. +# Generated by GNU Autoconf 2.69 for shadowsocks-libev 2.6.0. # # Report bugs to . # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='shadowsocks-libev' PACKAGE_TARNAME='shadowsocks-libev' -PACKAGE_VERSION='2.5.6' -PACKAGE_STRING='shadowsocks-libev 2.5.6' +PACKAGE_VERSION='2.6.0' +PACKAGE_STRING='shadowsocks-libev 2.6.0' PACKAGE_BUGREPORT='max.c.lv@gmail.com' PACKAGE_URL='' @@ -649,7 +649,6 @@ PTHREAD_CC ax_pthread_config INET_NTOP_LIB MV -RM GZIP XMLTO ASCIIDOC @@ -1359,7 +1358,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures shadowsocks-libev 2.5.6 to adapt to many kinds of systems. +\`configure' configures shadowsocks-libev 2.6.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1430,7 +1429,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of shadowsocks-libev 2.5.6:";; + short | recursive ) echo "Configuration of shadowsocks-libev 2.6.0:";; esac cat <<\_ACEOF @@ -1567,7 +1566,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -shadowsocks-libev configure 2.5.6 +shadowsocks-libev configure 2.6.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2090,7 +2089,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by shadowsocks-libev $as_me 2.5.6, which was +It was created by shadowsocks-libev $as_me 2.6.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -4329,7 +4328,7 @@ fi # Define the identity of the package. PACKAGE='shadowsocks-libev' - VERSION='2.5.6' + VERSION='2.6.0' cat >>confdefs.h <<_ACEOF @@ -12494,47 +12493,6 @@ $as_echo "no" >&6; } fi - # Extract the first word of "rm", so it can be a program name with args. -set dummy rm; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_RM+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $RM in - [\\/]* | ?:[\\/]*) - ac_cv_path_RM="$RM" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_RM="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_path_RM" && ac_cv_path_RM="rm" - ;; -esac -fi -RM=$ac_cv_path_RM -if test -n "$RM"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RM" >&5 -$as_echo "$RM" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - # Extract the first word of "mv", so it can be a program name with args. set dummy mv; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -16204,7 +16162,58 @@ $as_echo "#define HAVE_IPv6 1" >>confdefs.h if test -z "$USE_SYSTEM_SHARED_LIB_TRUE"; then : - else + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sodium_init in -lsodium" >&5 +$as_echo_n "checking for sodium_init in -lsodium... " >&6; } +if ${ac_cv_lib_sodium_sodium_init+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsodium $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char sodium_init (); +int +main () +{ +return sodium_init (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_sodium_sodium_init=yes +else + ac_cv_lib_sodium_sodium_init=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sodium_sodium_init" >&5 +$as_echo "$ac_cv_lib_sodium_sodium_init" >&6; } +if test "x$ac_cv_lib_sodium_sodium_init" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSODIUM 1 +_ACEOF + + LIBS="-lsodium $LIBS" + +else + + as_fn_error $? "Couldn't find libsodium. Try installing libsodium-dev[el]." "$LINENO" 5 + +fi + + +else subdirs="$subdirs libsodium" fi @@ -16212,7 +16221,103 @@ fi ac_config_files="$ac_config_files shadowsocks-libev.pc Makefile libcork/Makefile libipset/Makefile src/Makefile" if test -z "$USE_SYSTEM_SHARED_LIB_TRUE"; then : - else + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dns_dnlen in -ludns" >&5 +$as_echo_n "checking for dns_dnlen in -ludns... " >&6; } +if ${ac_cv_lib_udns_dns_dnlen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ludns $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dns_dnlen (); +int +main () +{ +return dns_dnlen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_udns_dns_dnlen=yes +else + ac_cv_lib_udns_dns_dnlen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_udns_dns_dnlen" >&5 +$as_echo "$ac_cv_lib_udns_dns_dnlen" >&6; } +if test "x$ac_cv_lib_udns_dns_dnlen" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBUDNS 1 +_ACEOF + + LIBS="-ludns $LIBS" + +else + as_fn_error $? "Couldn't find libudns. Try installing libudns-dev or udns-devel." "$LINENO" 5 +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ev_loop_destroy in -lev" >&5 +$as_echo_n "checking for ev_loop_destroy in -lev... " >&6; } +if ${ac_cv_lib_ev_ev_loop_destroy+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lev $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ev_loop_destroy (); +int +main () +{ +return ev_loop_destroy (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_ev_ev_loop_destroy=yes +else + ac_cv_lib_ev_ev_loop_destroy=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ev_ev_loop_destroy" >&5 +$as_echo "$ac_cv_lib_ev_ev_loop_destroy" >&6; } +if test "x$ac_cv_lib_ev_ev_loop_destroy" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBEV 1 +_ACEOF + + LIBS="-lev $LIBS" + +else + as_fn_error $? "Couldn't find libev. Try installing libev-dev[el]." "$LINENO" 5 +fi + + +else ac_config_files="$ac_config_files libudns/Makefile libev/Makefile" fi @@ -16778,7 +16883,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by shadowsocks-libev $as_me 2.5.6, which was +This file was extended by shadowsocks-libev $as_me 2.6.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -16844,7 +16949,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -shadowsocks-libev config.status 2.5.6 +shadowsocks-libev config.status 2.6.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 6586f2b3e..69a805543 100755 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl -*- Autoconf -*- dnl Process this file with autoconf to produce a configure script. AC_PREREQ([2.67]) -AC_INIT([shadowsocks-libev], [2.5.6], [max.c.lv@gmail.com]) +AC_INIT([shadowsocks-libev], [2.6.0], [max.c.lv@gmail.com]) AC_CONFIG_SRCDIR([src/encrypt.c]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_AUX_DIR(auto) diff --git a/debian/changelog b/debian/changelog index 7a4e44891..efa8b1d34 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +shadowsocks-libev (2.6.0-1) unstable; urgency=medium + + * Add HTTP/TLS obfuscating. + * Add support of aunch_activate_socket on macOS. + + -- Max Lv Tue, 27 Dec 2016 16:37:23 +0800 + shadowsocks-libev (2.5.6-1) unstable; urgency=medium * Add outbound ACL for server. diff --git a/doc/Makefile.in b/doc/Makefile.in index 5cd165418..111fc04af 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -218,7 +218,6 @@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ -RM = @RM@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -287,6 +286,7 @@ ASCIIDOC_EXTRA = MANPAGE_XSL = manpage-normal.xsl XMLTO_EXTRA = -m manpage-bold-literal.xsl GZIPCMD = @GZIP@ +RM = @RM@ @ENABLE_DOCUMENTATION_FALSE@MAN1_DOC = # Guard against environment variables diff --git a/doc/ss-local.asciidoc b/doc/ss-local.asciidoc index 9c481cf83..2a665df35 100644 --- a/doc/ss-local.asciidoc +++ b/doc/ss-local.asciidoc @@ -115,6 +115,13 @@ Enable Multipath TCP. + Only available with MPTCP enabled Linux kernel. +--obfs :: +Enable HTTP or TLS obfuscating. (Experimental) + +--obfs-host :: +Specify the hostname for obfuscating. (Experimental) + + -v:: Enable verbose mode. diff --git a/doc/ss-manager.asciidoc b/doc/ss-manager.asciidoc index 6183b9230..9dca51aed 100644 --- a/doc/ss-manager.asciidoc +++ b/doc/ss-manager.asciidoc @@ -105,6 +105,12 @@ Specify the executable path of ss-server. + Only available in manager mode. +--obfs :: +Enable HTTP or TLS obfuscating. (Experimental) + +--obfs-host :: +Specify the hostname for obfuscating. (Experimental) + -v:: Enable verbose mode. diff --git a/doc/ss-redir.asciidoc b/doc/ss-redir.asciidoc index 5993ceafc..1a574029a 100644 --- a/doc/ss-redir.asciidoc +++ b/doc/ss-redir.asciidoc @@ -101,6 +101,12 @@ Enable Multipath TCP. + Only available with MPTCP enabled Linux kernel. +--obfs :: +Enable HTTP or TLS obfuscating. (Experimental) + +--obfs-host :: +Specify the hostname for obfuscating. (Experimental) + -v:: Enable verbose mode. diff --git a/doc/ss-server.asciidoc b/doc/ss-server.asciidoc index 7a38f11e0..52acabf79 100644 --- a/doc/ss-server.asciidoc +++ b/doc/ss-server.asciidoc @@ -130,6 +130,9 @@ Enable Multipath TCP. + Only available with MPTCP enabled Linux kernel. +--obfs :: +Enable HTTP or TLS obfuscating. (Experimental) + -v:: Enable verbose mode. diff --git a/doc/ss-tunnel.asciidoc b/doc/ss-tunnel.asciidoc index d8505d465..3c319564a 100644 --- a/doc/ss-tunnel.asciidoc +++ b/doc/ss-tunnel.asciidoc @@ -112,6 +112,12 @@ Enable Multipath TCP. + Only available with MPTCP enabled Linux kernel. +--obfs :: +Enable HTTP or TLS obfuscating. (Experimental) + +--obfs-host :: +Specify the hostname for obfuscating. (Experimental) + -v:: Enable verbose mode. diff --git a/docker/alpine/Dockerfile b/docker/alpine/Dockerfile index 474307fba..6cd06d622 100644 --- a/docker/alpine/Dockerfile +++ b/docker/alpine/Dockerfile @@ -5,7 +5,7 @@ FROM alpine MAINTAINER kev -ARG SS_VER=2.5.6 +ARG SS_VER=2.6.0 ARG SS_URL=https://github.com/shadowsocks/shadowsocks-libev/archive/v$SS_VER.tar.gz ENV SERVER_ADDR 0.0.0.0 diff --git a/libcork/Makefile.in b/libcork/Makefile.in index 4106b3e03..e8e1e5f83 100644 --- a/libcork/Makefile.in +++ b/libcork/Makefile.in @@ -253,7 +253,6 @@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ -RM = @RM@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ diff --git a/libev/Makefile.in b/libev/Makefile.in index acfaa82e0..d5b17286a 100644 --- a/libev/Makefile.in +++ b/libev/Makefile.in @@ -238,7 +238,6 @@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ -RM = @RM@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ diff --git a/libipset/Makefile.in b/libipset/Makefile.in index 16ac8b619..227eb7006 100644 --- a/libipset/Makefile.in +++ b/libipset/Makefile.in @@ -249,7 +249,6 @@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ -RM = @RM@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ diff --git a/libudns/Makefile.in b/libudns/Makefile.in index 7ae615394..8a2c4bbaf 100644 --- a/libudns/Makefile.in +++ b/libudns/Makefile.in @@ -241,7 +241,6 @@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ -RM = @RM@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ diff --git a/rpm/genrpm.sh b/rpm/genrpm.sh index df9f480c9..e1cf275c1 100755 --- a/rpm/genrpm.sh +++ b/rpm/genrpm.sh @@ -7,7 +7,7 @@ show_help() echo echo -e "Options:" echo -e " -h show this help." - echo -e " -v with argument version (2.5.6 by default)." + echo -e " -v with argument version (2.6.0 by default)." echo -e " -f with argument format (tar.xz by default) used by git archive." echo echo -e "Examples:" @@ -38,7 +38,7 @@ do esac done -: ${version:=2.5.6} +: ${version:=2.6.0} : ${format:=tar.gz} name="shadowsocks-libev" diff --git a/src/Makefile.am b/src/Makefile.am index b08517d4f..b3c43f1ff 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -30,6 +30,10 @@ sni_src = http.c \ tls.c \ rule.c +obfs_src = obfs_http.c \ + obfs_tls.c \ + base64.c + ss_local_SOURCES = utils.c \ jconf.c \ json.c \ @@ -39,6 +43,7 @@ ss_local_SOURCES = utils.c \ acl.c \ netutils.c \ local.c \ + $(obfs_src) \ $(sni_src) ss_tunnel_SOURCES = utils.c \ @@ -48,6 +53,7 @@ ss_tunnel_SOURCES = utils.c \ udprelay.c \ cache.c \ netutils.c \ + $(obfs_src) \ tunnel.c ss_server_SOURCES = utils.c \ @@ -60,6 +66,7 @@ ss_server_SOURCES = utils.c \ acl.c \ resolv.c \ server.c \ + $(obfs_src) \ $(sni_src) ss_manager_SOURCES = utils.c \ @@ -102,7 +109,9 @@ ss_redir_SOURCES = utils.c \ cache.c \ udprelay.c \ redir.c \ + $(obfs_src) \ $(sni_src) + ss_redir_CFLAGS = $(AM_CFLAGS) -DMODULE_REDIR ss_redir_LDADD = $(SS_COMMON_LIBS) if USE_SYSTEM_SHARED_LIB diff --git a/src/Makefile.in b/src/Makefile.in index 39ca17035..f8e8d1f19 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -159,13 +159,16 @@ am__DEPENDENCIES_3 = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \ $(am__append_8) libshadowsocks_libev_la_DEPENDENCIES = $(am__DEPENDENCIES_3) am__libshadowsocks_libev_la_SOURCES_DIST = utils.c jconf.c json.c \ - encrypt.c udprelay.c cache.c acl.c netutils.c local.c http.c \ - tls.c rule.c win32.c -am__objects_1 = libshadowsocks_libev_la-http.lo \ + encrypt.c udprelay.c cache.c acl.c netutils.c local.c \ + obfs_http.c obfs_tls.c base64.c http.c tls.c rule.c win32.c +am__objects_1 = libshadowsocks_libev_la-obfs_http.lo \ + libshadowsocks_libev_la-obfs_tls.lo \ + libshadowsocks_libev_la-base64.lo +am__objects_2 = libshadowsocks_libev_la-http.lo \ libshadowsocks_libev_la-tls.lo libshadowsocks_libev_la-rule.lo -@BUILD_WINCOMPAT_TRUE@am__objects_2 = \ +@BUILD_WINCOMPAT_TRUE@am__objects_3 = \ @BUILD_WINCOMPAT_TRUE@ libshadowsocks_libev_la-win32.lo -am__objects_3 = libshadowsocks_libev_la-utils.lo \ +am__objects_4 = libshadowsocks_libev_la-utils.lo \ libshadowsocks_libev_la-jconf.lo \ libshadowsocks_libev_la-json.lo \ libshadowsocks_libev_la-encrypt.lo \ @@ -174,8 +177,8 @@ am__objects_3 = libshadowsocks_libev_la-utils.lo \ libshadowsocks_libev_la-acl.lo \ libshadowsocks_libev_la-netutils.lo \ libshadowsocks_libev_la-local.lo $(am__objects_1) \ - $(am__objects_2) -am_libshadowsocks_libev_la_OBJECTS = $(am__objects_3) + $(am__objects_2) $(am__objects_3) +am_libshadowsocks_libev_la_OBJECTS = $(am__objects_4) libshadowsocks_libev_la_OBJECTS = \ $(am_libshadowsocks_libev_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) @@ -191,17 +194,19 @@ libshadowsocks_libev_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ @BUILD_REDIRECTOR_TRUE@am__EXEEXT_2 = ss-redir$(EXEEXT) PROGRAMS = $(bin_PROGRAMS) am__ss_local_SOURCES_DIST = utils.c jconf.c json.c encrypt.c \ - udprelay.c cache.c acl.c netutils.c local.c http.c tls.c \ - rule.c win32.c -am__objects_4 = ss_local-http.$(OBJEXT) ss_local-tls.$(OBJEXT) \ + udprelay.c cache.c acl.c netutils.c local.c obfs_http.c \ + obfs_tls.c base64.c http.c tls.c rule.c win32.c +am__objects_5 = ss_local-obfs_http.$(OBJEXT) \ + ss_local-obfs_tls.$(OBJEXT) ss_local-base64.$(OBJEXT) +am__objects_6 = ss_local-http.$(OBJEXT) ss_local-tls.$(OBJEXT) \ ss_local-rule.$(OBJEXT) -@BUILD_WINCOMPAT_TRUE@am__objects_5 = ss_local-win32.$(OBJEXT) +@BUILD_WINCOMPAT_TRUE@am__objects_7 = ss_local-win32.$(OBJEXT) am_ss_local_OBJECTS = ss_local-utils.$(OBJEXT) \ ss_local-jconf.$(OBJEXT) ss_local-json.$(OBJEXT) \ ss_local-encrypt.$(OBJEXT) ss_local-udprelay.$(OBJEXT) \ ss_local-cache.$(OBJEXT) ss_local-acl.$(OBJEXT) \ ss_local-netutils.$(OBJEXT) ss_local-local.$(OBJEXT) \ - $(am__objects_4) $(am__objects_5) + $(am__objects_5) $(am__objects_6) $(am__objects_7) ss_local_OBJECTS = $(am_ss_local_OBJECTS) ss_local_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \ $(am__append_8) @@ -217,8 +222,11 @@ ss_manager_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(ss_manager_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__ss_redir_SOURCES_DIST = utils.c jconf.c json.c encrypt.c \ - netutils.c cache.c udprelay.c redir.c http.c tls.c rule.c -am__objects_6 = ss_redir-http.$(OBJEXT) ss_redir-tls.$(OBJEXT) \ + netutils.c cache.c udprelay.c redir.c obfs_http.c obfs_tls.c \ + base64.c http.c tls.c rule.c +am__objects_8 = ss_redir-obfs_http.$(OBJEXT) \ + ss_redir-obfs_tls.$(OBJEXT) ss_redir-base64.$(OBJEXT) +am__objects_9 = ss_redir-http.$(OBJEXT) ss_redir-tls.$(OBJEXT) \ ss_redir-rule.$(OBJEXT) @BUILD_REDIRECTOR_TRUE@am_ss_redir_OBJECTS = ss_redir-utils.$(OBJEXT) \ @BUILD_REDIRECTOR_TRUE@ ss_redir-jconf.$(OBJEXT) \ @@ -228,21 +236,23 @@ am__objects_6 = ss_redir-http.$(OBJEXT) ss_redir-tls.$(OBJEXT) \ @BUILD_REDIRECTOR_TRUE@ ss_redir-cache.$(OBJEXT) \ @BUILD_REDIRECTOR_TRUE@ ss_redir-udprelay.$(OBJEXT) \ @BUILD_REDIRECTOR_TRUE@ ss_redir-redir.$(OBJEXT) \ -@BUILD_REDIRECTOR_TRUE@ $(am__objects_6) +@BUILD_REDIRECTOR_TRUE@ $(am__objects_8) $(am__objects_9) ss_redir_OBJECTS = $(am_ss_redir_OBJECTS) @BUILD_REDIRECTOR_TRUE@ss_redir_DEPENDENCIES = $(am__DEPENDENCIES_2) \ @BUILD_REDIRECTOR_TRUE@ $(am__DEPENDENCIES_1) $(am__append_15) ss_redir_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(ss_redir_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -am__objects_7 = ss_server-http.$(OBJEXT) ss_server-tls.$(OBJEXT) \ +am__objects_10 = ss_server-obfs_http.$(OBJEXT) \ + ss_server-obfs_tls.$(OBJEXT) ss_server-base64.$(OBJEXT) +am__objects_11 = ss_server-http.$(OBJEXT) ss_server-tls.$(OBJEXT) \ ss_server-rule.$(OBJEXT) am_ss_server_OBJECTS = ss_server-utils.$(OBJEXT) \ ss_server-netutils.$(OBJEXT) ss_server-jconf.$(OBJEXT) \ ss_server-json.$(OBJEXT) ss_server-encrypt.$(OBJEXT) \ ss_server-udprelay.$(OBJEXT) ss_server-cache.$(OBJEXT) \ ss_server-acl.$(OBJEXT) ss_server-resolv.$(OBJEXT) \ - ss_server-server.$(OBJEXT) $(am__objects_7) + ss_server-server.$(OBJEXT) $(am__objects_10) $(am__objects_11) ss_server_OBJECTS = $(am_ss_server_OBJECTS) ss_server_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \ $(am__append_10) @@ -250,13 +260,16 @@ ss_server_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(ss_server_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__ss_tunnel_SOURCES_DIST = utils.c jconf.c json.c encrypt.c \ - udprelay.c cache.c netutils.c tunnel.c win32.c -@BUILD_WINCOMPAT_TRUE@am__objects_8 = ss_tunnel-win32.$(OBJEXT) + udprelay.c cache.c netutils.c obfs_http.c obfs_tls.c base64.c \ + tunnel.c win32.c +am__objects_12 = ss_tunnel-obfs_http.$(OBJEXT) \ + ss_tunnel-obfs_tls.$(OBJEXT) ss_tunnel-base64.$(OBJEXT) +@BUILD_WINCOMPAT_TRUE@am__objects_13 = ss_tunnel-win32.$(OBJEXT) am_ss_tunnel_OBJECTS = ss_tunnel-utils.$(OBJEXT) \ ss_tunnel-jconf.$(OBJEXT) ss_tunnel-json.$(OBJEXT) \ ss_tunnel-encrypt.$(OBJEXT) ss_tunnel-udprelay.$(OBJEXT) \ ss_tunnel-cache.$(OBJEXT) ss_tunnel-netutils.$(OBJEXT) \ - ss_tunnel-tunnel.$(OBJEXT) $(am__objects_8) + $(am__objects_12) ss_tunnel-tunnel.$(OBJEXT) $(am__objects_13) ss_tunnel_OBJECTS = $(am_ss_tunnel_OBJECTS) ss_tunnel_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \ $(am__append_9) @@ -398,7 +411,6 @@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ -RM = @RM@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ @@ -474,10 +486,15 @@ sni_src = http.c \ tls.c \ rule.c +obfs_src = obfs_http.c \ + obfs_tls.c \ + base64.c + ss_local_SOURCES = utils.c jconf.c json.c encrypt.c udprelay.c cache.c \ - acl.c netutils.c local.c $(sni_src) $(am__append_11) + acl.c netutils.c local.c $(obfs_src) $(sni_src) \ + $(am__append_11) ss_tunnel_SOURCES = utils.c jconf.c json.c encrypt.c udprelay.c \ - cache.c netutils.c tunnel.c $(am__append_12) + cache.c netutils.c $(obfs_src) tunnel.c $(am__append_12) ss_server_SOURCES = utils.c \ netutils.c \ jconf.c \ @@ -488,6 +505,7 @@ ss_server_SOURCES = utils.c \ acl.c \ resolv.c \ server.c \ + $(obfs_src) \ $(sni_src) ss_manager_SOURCES = utils.c \ @@ -512,6 +530,7 @@ ss_manager_CFLAGS = $(AM_CFLAGS) -DMODULE_MANAGER @BUILD_REDIRECTOR_TRUE@ cache.c \ @BUILD_REDIRECTOR_TRUE@ udprelay.c \ @BUILD_REDIRECTOR_TRUE@ redir.c \ +@BUILD_REDIRECTOR_TRUE@ $(obfs_src) \ @BUILD_REDIRECTOR_TRUE@ $(sni_src) @BUILD_REDIRECTOR_TRUE@ss_redir_CFLAGS = $(AM_CFLAGS) -DMODULE_REDIR @@ -707,6 +726,7 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-acl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-base64.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-cache.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-encrypt.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-http.Plo@am__quote@ @@ -714,12 +734,15 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-json.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-local.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-netutils.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-obfs_http.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-obfs_tls.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-rule.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-tls.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-udprelay.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-win32.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_local-acl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_local-base64.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_local-cache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_local-encrypt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_local-http.Po@am__quote@ @@ -727,6 +750,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_local-json.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_local-local.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_local-netutils.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_local-obfs_http.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_local-obfs_tls.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_local-rule.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_local-tls.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_local-udprelay.Po@am__quote@ @@ -736,35 +761,44 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_manager-json.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_manager-manager.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_manager-utils.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_redir-base64.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_redir-cache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_redir-encrypt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_redir-http.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_redir-jconf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_redir-json.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_redir-netutils.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_redir-obfs_http.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_redir-obfs_tls.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_redir-redir.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_redir-rule.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_redir-tls.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_redir-udprelay.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_redir-utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-acl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-base64.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-cache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-encrypt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-http.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-jconf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-json.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-netutils.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-obfs_http.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-obfs_tls.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-resolv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-rule.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-server.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-tls.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-udprelay.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-utils.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_tunnel-base64.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_tunnel-cache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_tunnel-encrypt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_tunnel-jconf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_tunnel-json.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_tunnel-netutils.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_tunnel-obfs_http.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_tunnel-obfs_tls.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_tunnel-tunnel.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_tunnel-udprelay.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_tunnel-utils.Po@am__quote@ @@ -857,6 +891,27 @@ libshadowsocks_libev_la-local.lo: local.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libshadowsocks_libev_la_CFLAGS) $(CFLAGS) -c -o libshadowsocks_libev_la-local.lo `test -f 'local.c' || echo '$(srcdir)/'`local.c +libshadowsocks_libev_la-obfs_http.lo: obfs_http.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libshadowsocks_libev_la_CFLAGS) $(CFLAGS) -MT libshadowsocks_libev_la-obfs_http.lo -MD -MP -MF $(DEPDIR)/libshadowsocks_libev_la-obfs_http.Tpo -c -o libshadowsocks_libev_la-obfs_http.lo `test -f 'obfs_http.c' || echo '$(srcdir)/'`obfs_http.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libshadowsocks_libev_la-obfs_http.Tpo $(DEPDIR)/libshadowsocks_libev_la-obfs_http.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='obfs_http.c' object='libshadowsocks_libev_la-obfs_http.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libshadowsocks_libev_la_CFLAGS) $(CFLAGS) -c -o libshadowsocks_libev_la-obfs_http.lo `test -f 'obfs_http.c' || echo '$(srcdir)/'`obfs_http.c + +libshadowsocks_libev_la-obfs_tls.lo: obfs_tls.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libshadowsocks_libev_la_CFLAGS) $(CFLAGS) -MT libshadowsocks_libev_la-obfs_tls.lo -MD -MP -MF $(DEPDIR)/libshadowsocks_libev_la-obfs_tls.Tpo -c -o libshadowsocks_libev_la-obfs_tls.lo `test -f 'obfs_tls.c' || echo '$(srcdir)/'`obfs_tls.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libshadowsocks_libev_la-obfs_tls.Tpo $(DEPDIR)/libshadowsocks_libev_la-obfs_tls.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='obfs_tls.c' object='libshadowsocks_libev_la-obfs_tls.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libshadowsocks_libev_la_CFLAGS) $(CFLAGS) -c -o libshadowsocks_libev_la-obfs_tls.lo `test -f 'obfs_tls.c' || echo '$(srcdir)/'`obfs_tls.c + +libshadowsocks_libev_la-base64.lo: base64.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libshadowsocks_libev_la_CFLAGS) $(CFLAGS) -MT libshadowsocks_libev_la-base64.lo -MD -MP -MF $(DEPDIR)/libshadowsocks_libev_la-base64.Tpo -c -o libshadowsocks_libev_la-base64.lo `test -f 'base64.c' || echo '$(srcdir)/'`base64.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libshadowsocks_libev_la-base64.Tpo $(DEPDIR)/libshadowsocks_libev_la-base64.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='base64.c' object='libshadowsocks_libev_la-base64.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libshadowsocks_libev_la_CFLAGS) $(CFLAGS) -c -o libshadowsocks_libev_la-base64.lo `test -f 'base64.c' || echo '$(srcdir)/'`base64.c + libshadowsocks_libev_la-http.lo: http.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libshadowsocks_libev_la_CFLAGS) $(CFLAGS) -MT libshadowsocks_libev_la-http.lo -MD -MP -MF $(DEPDIR)/libshadowsocks_libev_la-http.Tpo -c -o libshadowsocks_libev_la-http.lo `test -f 'http.c' || echo '$(srcdir)/'`http.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libshadowsocks_libev_la-http.Tpo $(DEPDIR)/libshadowsocks_libev_la-http.Plo @@ -1011,6 +1066,48 @@ ss_local-local.obj: local.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -c -o ss_local-local.obj `if test -f 'local.c'; then $(CYGPATH_W) 'local.c'; else $(CYGPATH_W) '$(srcdir)/local.c'; fi` +ss_local-obfs_http.o: obfs_http.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -MT ss_local-obfs_http.o -MD -MP -MF $(DEPDIR)/ss_local-obfs_http.Tpo -c -o ss_local-obfs_http.o `test -f 'obfs_http.c' || echo '$(srcdir)/'`obfs_http.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_local-obfs_http.Tpo $(DEPDIR)/ss_local-obfs_http.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='obfs_http.c' object='ss_local-obfs_http.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -c -o ss_local-obfs_http.o `test -f 'obfs_http.c' || echo '$(srcdir)/'`obfs_http.c + +ss_local-obfs_http.obj: obfs_http.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -MT ss_local-obfs_http.obj -MD -MP -MF $(DEPDIR)/ss_local-obfs_http.Tpo -c -o ss_local-obfs_http.obj `if test -f 'obfs_http.c'; then $(CYGPATH_W) 'obfs_http.c'; else $(CYGPATH_W) '$(srcdir)/obfs_http.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_local-obfs_http.Tpo $(DEPDIR)/ss_local-obfs_http.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='obfs_http.c' object='ss_local-obfs_http.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -c -o ss_local-obfs_http.obj `if test -f 'obfs_http.c'; then $(CYGPATH_W) 'obfs_http.c'; else $(CYGPATH_W) '$(srcdir)/obfs_http.c'; fi` + +ss_local-obfs_tls.o: obfs_tls.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -MT ss_local-obfs_tls.o -MD -MP -MF $(DEPDIR)/ss_local-obfs_tls.Tpo -c -o ss_local-obfs_tls.o `test -f 'obfs_tls.c' || echo '$(srcdir)/'`obfs_tls.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_local-obfs_tls.Tpo $(DEPDIR)/ss_local-obfs_tls.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='obfs_tls.c' object='ss_local-obfs_tls.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -c -o ss_local-obfs_tls.o `test -f 'obfs_tls.c' || echo '$(srcdir)/'`obfs_tls.c + +ss_local-obfs_tls.obj: obfs_tls.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -MT ss_local-obfs_tls.obj -MD -MP -MF $(DEPDIR)/ss_local-obfs_tls.Tpo -c -o ss_local-obfs_tls.obj `if test -f 'obfs_tls.c'; then $(CYGPATH_W) 'obfs_tls.c'; else $(CYGPATH_W) '$(srcdir)/obfs_tls.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_local-obfs_tls.Tpo $(DEPDIR)/ss_local-obfs_tls.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='obfs_tls.c' object='ss_local-obfs_tls.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -c -o ss_local-obfs_tls.obj `if test -f 'obfs_tls.c'; then $(CYGPATH_W) 'obfs_tls.c'; else $(CYGPATH_W) '$(srcdir)/obfs_tls.c'; fi` + +ss_local-base64.o: base64.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -MT ss_local-base64.o -MD -MP -MF $(DEPDIR)/ss_local-base64.Tpo -c -o ss_local-base64.o `test -f 'base64.c' || echo '$(srcdir)/'`base64.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_local-base64.Tpo $(DEPDIR)/ss_local-base64.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='base64.c' object='ss_local-base64.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -c -o ss_local-base64.o `test -f 'base64.c' || echo '$(srcdir)/'`base64.c + +ss_local-base64.obj: base64.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -MT ss_local-base64.obj -MD -MP -MF $(DEPDIR)/ss_local-base64.Tpo -c -o ss_local-base64.obj `if test -f 'base64.c'; then $(CYGPATH_W) 'base64.c'; else $(CYGPATH_W) '$(srcdir)/base64.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_local-base64.Tpo $(DEPDIR)/ss_local-base64.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='base64.c' object='ss_local-base64.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -c -o ss_local-base64.obj `if test -f 'base64.c'; then $(CYGPATH_W) 'base64.c'; else $(CYGPATH_W) '$(srcdir)/base64.c'; fi` + ss_local-http.o: http.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -MT ss_local-http.o -MD -MP -MF $(DEPDIR)/ss_local-http.Tpo -c -o ss_local-http.o `test -f 'http.c' || echo '$(srcdir)/'`http.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_local-http.Tpo $(DEPDIR)/ss_local-http.Po @@ -1235,6 +1332,48 @@ ss_redir-redir.obj: redir.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_redir_CFLAGS) $(CFLAGS) -c -o ss_redir-redir.obj `if test -f 'redir.c'; then $(CYGPATH_W) 'redir.c'; else $(CYGPATH_W) '$(srcdir)/redir.c'; fi` +ss_redir-obfs_http.o: obfs_http.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_redir_CFLAGS) $(CFLAGS) -MT ss_redir-obfs_http.o -MD -MP -MF $(DEPDIR)/ss_redir-obfs_http.Tpo -c -o ss_redir-obfs_http.o `test -f 'obfs_http.c' || echo '$(srcdir)/'`obfs_http.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_redir-obfs_http.Tpo $(DEPDIR)/ss_redir-obfs_http.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='obfs_http.c' object='ss_redir-obfs_http.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_redir_CFLAGS) $(CFLAGS) -c -o ss_redir-obfs_http.o `test -f 'obfs_http.c' || echo '$(srcdir)/'`obfs_http.c + +ss_redir-obfs_http.obj: obfs_http.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_redir_CFLAGS) $(CFLAGS) -MT ss_redir-obfs_http.obj -MD -MP -MF $(DEPDIR)/ss_redir-obfs_http.Tpo -c -o ss_redir-obfs_http.obj `if test -f 'obfs_http.c'; then $(CYGPATH_W) 'obfs_http.c'; else $(CYGPATH_W) '$(srcdir)/obfs_http.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_redir-obfs_http.Tpo $(DEPDIR)/ss_redir-obfs_http.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='obfs_http.c' object='ss_redir-obfs_http.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_redir_CFLAGS) $(CFLAGS) -c -o ss_redir-obfs_http.obj `if test -f 'obfs_http.c'; then $(CYGPATH_W) 'obfs_http.c'; else $(CYGPATH_W) '$(srcdir)/obfs_http.c'; fi` + +ss_redir-obfs_tls.o: obfs_tls.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_redir_CFLAGS) $(CFLAGS) -MT ss_redir-obfs_tls.o -MD -MP -MF $(DEPDIR)/ss_redir-obfs_tls.Tpo -c -o ss_redir-obfs_tls.o `test -f 'obfs_tls.c' || echo '$(srcdir)/'`obfs_tls.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_redir-obfs_tls.Tpo $(DEPDIR)/ss_redir-obfs_tls.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='obfs_tls.c' object='ss_redir-obfs_tls.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_redir_CFLAGS) $(CFLAGS) -c -o ss_redir-obfs_tls.o `test -f 'obfs_tls.c' || echo '$(srcdir)/'`obfs_tls.c + +ss_redir-obfs_tls.obj: obfs_tls.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_redir_CFLAGS) $(CFLAGS) -MT ss_redir-obfs_tls.obj -MD -MP -MF $(DEPDIR)/ss_redir-obfs_tls.Tpo -c -o ss_redir-obfs_tls.obj `if test -f 'obfs_tls.c'; then $(CYGPATH_W) 'obfs_tls.c'; else $(CYGPATH_W) '$(srcdir)/obfs_tls.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_redir-obfs_tls.Tpo $(DEPDIR)/ss_redir-obfs_tls.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='obfs_tls.c' object='ss_redir-obfs_tls.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_redir_CFLAGS) $(CFLAGS) -c -o ss_redir-obfs_tls.obj `if test -f 'obfs_tls.c'; then $(CYGPATH_W) 'obfs_tls.c'; else $(CYGPATH_W) '$(srcdir)/obfs_tls.c'; fi` + +ss_redir-base64.o: base64.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_redir_CFLAGS) $(CFLAGS) -MT ss_redir-base64.o -MD -MP -MF $(DEPDIR)/ss_redir-base64.Tpo -c -o ss_redir-base64.o `test -f 'base64.c' || echo '$(srcdir)/'`base64.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_redir-base64.Tpo $(DEPDIR)/ss_redir-base64.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='base64.c' object='ss_redir-base64.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_redir_CFLAGS) $(CFLAGS) -c -o ss_redir-base64.o `test -f 'base64.c' || echo '$(srcdir)/'`base64.c + +ss_redir-base64.obj: base64.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_redir_CFLAGS) $(CFLAGS) -MT ss_redir-base64.obj -MD -MP -MF $(DEPDIR)/ss_redir-base64.Tpo -c -o ss_redir-base64.obj `if test -f 'base64.c'; then $(CYGPATH_W) 'base64.c'; else $(CYGPATH_W) '$(srcdir)/base64.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_redir-base64.Tpo $(DEPDIR)/ss_redir-base64.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='base64.c' object='ss_redir-base64.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_redir_CFLAGS) $(CFLAGS) -c -o ss_redir-base64.obj `if test -f 'base64.c'; then $(CYGPATH_W) 'base64.c'; else $(CYGPATH_W) '$(srcdir)/base64.c'; fi` + ss_redir-http.o: http.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_redir_CFLAGS) $(CFLAGS) -MT ss_redir-http.o -MD -MP -MF $(DEPDIR)/ss_redir-http.Tpo -c -o ss_redir-http.o `test -f 'http.c' || echo '$(srcdir)/'`http.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_redir-http.Tpo $(DEPDIR)/ss_redir-http.Po @@ -1417,6 +1556,48 @@ ss_server-server.obj: server.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-server.obj `if test -f 'server.c'; then $(CYGPATH_W) 'server.c'; else $(CYGPATH_W) '$(srcdir)/server.c'; fi` +ss_server-obfs_http.o: obfs_http.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-obfs_http.o -MD -MP -MF $(DEPDIR)/ss_server-obfs_http.Tpo -c -o ss_server-obfs_http.o `test -f 'obfs_http.c' || echo '$(srcdir)/'`obfs_http.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-obfs_http.Tpo $(DEPDIR)/ss_server-obfs_http.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='obfs_http.c' object='ss_server-obfs_http.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-obfs_http.o `test -f 'obfs_http.c' || echo '$(srcdir)/'`obfs_http.c + +ss_server-obfs_http.obj: obfs_http.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-obfs_http.obj -MD -MP -MF $(DEPDIR)/ss_server-obfs_http.Tpo -c -o ss_server-obfs_http.obj `if test -f 'obfs_http.c'; then $(CYGPATH_W) 'obfs_http.c'; else $(CYGPATH_W) '$(srcdir)/obfs_http.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-obfs_http.Tpo $(DEPDIR)/ss_server-obfs_http.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='obfs_http.c' object='ss_server-obfs_http.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-obfs_http.obj `if test -f 'obfs_http.c'; then $(CYGPATH_W) 'obfs_http.c'; else $(CYGPATH_W) '$(srcdir)/obfs_http.c'; fi` + +ss_server-obfs_tls.o: obfs_tls.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-obfs_tls.o -MD -MP -MF $(DEPDIR)/ss_server-obfs_tls.Tpo -c -o ss_server-obfs_tls.o `test -f 'obfs_tls.c' || echo '$(srcdir)/'`obfs_tls.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-obfs_tls.Tpo $(DEPDIR)/ss_server-obfs_tls.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='obfs_tls.c' object='ss_server-obfs_tls.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-obfs_tls.o `test -f 'obfs_tls.c' || echo '$(srcdir)/'`obfs_tls.c + +ss_server-obfs_tls.obj: obfs_tls.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-obfs_tls.obj -MD -MP -MF $(DEPDIR)/ss_server-obfs_tls.Tpo -c -o ss_server-obfs_tls.obj `if test -f 'obfs_tls.c'; then $(CYGPATH_W) 'obfs_tls.c'; else $(CYGPATH_W) '$(srcdir)/obfs_tls.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-obfs_tls.Tpo $(DEPDIR)/ss_server-obfs_tls.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='obfs_tls.c' object='ss_server-obfs_tls.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-obfs_tls.obj `if test -f 'obfs_tls.c'; then $(CYGPATH_W) 'obfs_tls.c'; else $(CYGPATH_W) '$(srcdir)/obfs_tls.c'; fi` + +ss_server-base64.o: base64.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-base64.o -MD -MP -MF $(DEPDIR)/ss_server-base64.Tpo -c -o ss_server-base64.o `test -f 'base64.c' || echo '$(srcdir)/'`base64.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-base64.Tpo $(DEPDIR)/ss_server-base64.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='base64.c' object='ss_server-base64.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-base64.o `test -f 'base64.c' || echo '$(srcdir)/'`base64.c + +ss_server-base64.obj: base64.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-base64.obj -MD -MP -MF $(DEPDIR)/ss_server-base64.Tpo -c -o ss_server-base64.obj `if test -f 'base64.c'; then $(CYGPATH_W) 'base64.c'; else $(CYGPATH_W) '$(srcdir)/base64.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-base64.Tpo $(DEPDIR)/ss_server-base64.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='base64.c' object='ss_server-base64.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-base64.obj `if test -f 'base64.c'; then $(CYGPATH_W) 'base64.c'; else $(CYGPATH_W) '$(srcdir)/base64.c'; fi` + ss_server-http.o: http.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-http.o -MD -MP -MF $(DEPDIR)/ss_server-http.Tpo -c -o ss_server-http.o `test -f 'http.c' || echo '$(srcdir)/'`http.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-http.Tpo $(DEPDIR)/ss_server-http.Po @@ -1557,6 +1738,48 @@ ss_tunnel-netutils.obj: netutils.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_tunnel_CFLAGS) $(CFLAGS) -c -o ss_tunnel-netutils.obj `if test -f 'netutils.c'; then $(CYGPATH_W) 'netutils.c'; else $(CYGPATH_W) '$(srcdir)/netutils.c'; fi` +ss_tunnel-obfs_http.o: obfs_http.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_tunnel_CFLAGS) $(CFLAGS) -MT ss_tunnel-obfs_http.o -MD -MP -MF $(DEPDIR)/ss_tunnel-obfs_http.Tpo -c -o ss_tunnel-obfs_http.o `test -f 'obfs_http.c' || echo '$(srcdir)/'`obfs_http.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_tunnel-obfs_http.Tpo $(DEPDIR)/ss_tunnel-obfs_http.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='obfs_http.c' object='ss_tunnel-obfs_http.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_tunnel_CFLAGS) $(CFLAGS) -c -o ss_tunnel-obfs_http.o `test -f 'obfs_http.c' || echo '$(srcdir)/'`obfs_http.c + +ss_tunnel-obfs_http.obj: obfs_http.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_tunnel_CFLAGS) $(CFLAGS) -MT ss_tunnel-obfs_http.obj -MD -MP -MF $(DEPDIR)/ss_tunnel-obfs_http.Tpo -c -o ss_tunnel-obfs_http.obj `if test -f 'obfs_http.c'; then $(CYGPATH_W) 'obfs_http.c'; else $(CYGPATH_W) '$(srcdir)/obfs_http.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_tunnel-obfs_http.Tpo $(DEPDIR)/ss_tunnel-obfs_http.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='obfs_http.c' object='ss_tunnel-obfs_http.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_tunnel_CFLAGS) $(CFLAGS) -c -o ss_tunnel-obfs_http.obj `if test -f 'obfs_http.c'; then $(CYGPATH_W) 'obfs_http.c'; else $(CYGPATH_W) '$(srcdir)/obfs_http.c'; fi` + +ss_tunnel-obfs_tls.o: obfs_tls.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_tunnel_CFLAGS) $(CFLAGS) -MT ss_tunnel-obfs_tls.o -MD -MP -MF $(DEPDIR)/ss_tunnel-obfs_tls.Tpo -c -o ss_tunnel-obfs_tls.o `test -f 'obfs_tls.c' || echo '$(srcdir)/'`obfs_tls.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_tunnel-obfs_tls.Tpo $(DEPDIR)/ss_tunnel-obfs_tls.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='obfs_tls.c' object='ss_tunnel-obfs_tls.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_tunnel_CFLAGS) $(CFLAGS) -c -o ss_tunnel-obfs_tls.o `test -f 'obfs_tls.c' || echo '$(srcdir)/'`obfs_tls.c + +ss_tunnel-obfs_tls.obj: obfs_tls.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_tunnel_CFLAGS) $(CFLAGS) -MT ss_tunnel-obfs_tls.obj -MD -MP -MF $(DEPDIR)/ss_tunnel-obfs_tls.Tpo -c -o ss_tunnel-obfs_tls.obj `if test -f 'obfs_tls.c'; then $(CYGPATH_W) 'obfs_tls.c'; else $(CYGPATH_W) '$(srcdir)/obfs_tls.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_tunnel-obfs_tls.Tpo $(DEPDIR)/ss_tunnel-obfs_tls.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='obfs_tls.c' object='ss_tunnel-obfs_tls.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_tunnel_CFLAGS) $(CFLAGS) -c -o ss_tunnel-obfs_tls.obj `if test -f 'obfs_tls.c'; then $(CYGPATH_W) 'obfs_tls.c'; else $(CYGPATH_W) '$(srcdir)/obfs_tls.c'; fi` + +ss_tunnel-base64.o: base64.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_tunnel_CFLAGS) $(CFLAGS) -MT ss_tunnel-base64.o -MD -MP -MF $(DEPDIR)/ss_tunnel-base64.Tpo -c -o ss_tunnel-base64.o `test -f 'base64.c' || echo '$(srcdir)/'`base64.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_tunnel-base64.Tpo $(DEPDIR)/ss_tunnel-base64.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='base64.c' object='ss_tunnel-base64.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_tunnel_CFLAGS) $(CFLAGS) -c -o ss_tunnel-base64.o `test -f 'base64.c' || echo '$(srcdir)/'`base64.c + +ss_tunnel-base64.obj: base64.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_tunnel_CFLAGS) $(CFLAGS) -MT ss_tunnel-base64.obj -MD -MP -MF $(DEPDIR)/ss_tunnel-base64.Tpo -c -o ss_tunnel-base64.obj `if test -f 'base64.c'; then $(CYGPATH_W) 'base64.c'; else $(CYGPATH_W) '$(srcdir)/base64.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_tunnel-base64.Tpo $(DEPDIR)/ss_tunnel-base64.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='base64.c' object='ss_tunnel-base64.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_tunnel_CFLAGS) $(CFLAGS) -c -o ss_tunnel-base64.obj `if test -f 'base64.c'; then $(CYGPATH_W) 'base64.c'; else $(CYGPATH_W) '$(srcdir)/base64.c'; fi` + ss_tunnel-tunnel.o: tunnel.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_tunnel_CFLAGS) $(CFLAGS) -MT ss_tunnel-tunnel.o -MD -MP -MF $(DEPDIR)/ss_tunnel-tunnel.Tpo -c -o ss_tunnel-tunnel.o `test -f 'tunnel.c' || echo '$(srcdir)/'`tunnel.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_tunnel-tunnel.Tpo $(DEPDIR)/ss_tunnel-tunnel.Po diff --git a/src/base64.c b/src/base64.c new file mode 100644 index 000000000..a3ea0664f --- /dev/null +++ b/src/base64.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2006 Ryan Martell. (rdm4@martellventures.com) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * @brief Base64 encode/decode + * @author Ryan Martell (with lots of Michael) + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "base64.h" + +/* ---------------- private code */ +static const uint8_t map2[] = +{ + 0x3e, 0xff, 0xff, 0xff, 0x3f, 0x34, 0x35, 0x36, + 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33 +}; + +int base64_decode(uint8_t *out, const char *in, int out_size) +{ + int i, v; + uint8_t *dst = out; + + v = 0; + for (i = 0; in[i] && in[i] != '='; i++) { + unsigned int index= in[i]-43; + if (index >= sizeof(map2) || map2[index] == 0xff) + return -1; + v = (v << 6) + map2[index]; + if (i & 3) { + if (dst - out < out_size) { + *dst++ = v >> (6 - 2 * (i & 3)); + } + } + } + + return dst - out; +} + +/***************************************************************************** +* b64_encode: Stolen from VLC's http.c. +* Simplified by Michael. +* Fixed edge cases and made it work from data (vs. strings) by Ryan. +*****************************************************************************/ + +char *base64_encode(char *out, int out_size, const uint8_t *in, int in_size) +{ + static const char b64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + char *ret, *dst; + unsigned i_bits = 0; + int i_shift = 0; + int bytes_remaining = in_size; + + if (in_size >= UINT_MAX / 4 || + out_size < BASE64_SIZE(in_size)) + return NULL; + ret = dst = out; + while (bytes_remaining) { + i_bits = (i_bits << 8) + *in++; + bytes_remaining--; + i_shift += 8; + + do { + *dst++ = b64[(i_bits << 6 >> i_shift) & 0x3f]; + i_shift -= 6; + } while (i_shift > 6 || (bytes_remaining == 0 && i_shift > 0)); + } + while ((dst - ret) & 3) + *dst++ = '='; + *dst = '\0'; + + return ret; +} diff --git a/src/base64.h b/src/base64.h new file mode 100644 index 000000000..01bcda574 --- /dev/null +++ b/src/base64.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2006 Ryan Martell. (rdm4@martellventures.com) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef BASE64_H +#define BASE64_H + +#include + +/** + * Decode a base64-encoded string. + * + * @param out buffer for decoded data + * @param in null-terminated input string + * @param out_size size in bytes of the out buffer, must be at + * least 3/4 of the length of in + * @return number of bytes written, or a negative value in case of + * invalid input + */ +int base64_decode(uint8_t *out, const char *in, int out_size); + +/** + * Encode data to base64 and null-terminate. + * + * @param out buffer for encoded data + * @param out_size size in bytes of the output buffer, must be at + * least BASE64_SIZE(in_size) + * @param in_size size in bytes of the 'in' buffer + * @return 'out' or NULL in case of error + */ +char *base64_encode(char *out, int out_size, const uint8_t *in, int in_size); + +/** + * Calculate the output size needed to base64-encode x bytes. + */ +#define BASE64_SIZE(x) (((x)+2) / 3 * 4 + 1) + +#endif /* BASE64_H */ diff --git a/src/encrypt.c b/src/encrypt.c index d204f1048..d1ac77954 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -251,7 +251,7 @@ int balloc(buffer_t *ptr, size_t capacity) { sodium_memzero(ptr, sizeof(buffer_t)); - ptr->array = ss_malloc(capacity); + ptr->data = ss_malloc(capacity); ptr->capacity = capacity; return capacity; } @@ -263,7 +263,7 @@ brealloc(buffer_t *ptr, size_t len, size_t capacity) return -1; size_t real_capacity = max(len, capacity); if (ptr->capacity < real_capacity) { - ptr->array = ss_realloc(ptr->array, real_capacity); + ptr->data = ss_realloc(ptr->data, real_capacity); ptr->capacity = real_capacity; } return real_capacity; @@ -277,8 +277,8 @@ bfree(buffer_t *ptr) ptr->idx = 0; ptr->len = 0; ptr->capacity = 0; - if (ptr->array != NULL) { - ss_free(ptr->array); + if (ptr->data != NULL) { + ss_free(ptr->data); } } @@ -357,7 +357,7 @@ merge(uint8_t *left, int llength, uint8_t *right, } static void -merge_sort(uint8_t array[], int length, +merge_sort(uint8_t data[], int length, uint32_t salt, uint64_t key) { uint8_t middle; @@ -372,8 +372,8 @@ merge_sort(uint8_t array[], int length, llength = length - middle; - left = array; - right = array + llength; + left = data; + right = data + llength; merge_sort(left, llength, salt, key); merge_sort(right, middle, salt, key); @@ -593,7 +593,7 @@ bytes_to_key(const cipher_t *cipher, const digest_type_t *md, } int -rand_bytes(uint8_t *output, int len) +rand_bytes(void *output, int len) { randombytes_buf(output, len); // always return success @@ -926,16 +926,16 @@ ss_onetimeauth(buffer_t *buf, uint8_t *iv, size_t capacity) brealloc(buf, ONETIMEAUTH_BYTES + buf->len, capacity); #if defined(USE_CRYPTO_OPENSSL) - HMAC(EVP_sha1(), auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->array, buf->len, (uint8_t *)hash, NULL); + HMAC(EVP_sha1(), auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->data, buf->len, (uint8_t *)hash, NULL); #elif defined(USE_CRYPTO_MBEDTLS) mbedtls_md_hmac(mbedtls_md_info_from_type( - MBEDTLS_MD_SHA1), auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->array, buf->len, + MBEDTLS_MD_SHA1), auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->data, buf->len, (uint8_t *)hash); #else - sha1_hmac(auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->array, buf->len, (uint8_t *)hash); + sha1_hmac(auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->data, buf->len, (uint8_t *)hash); #endif - memcpy(buf->array + buf->len, hash, ONETIMEAUTH_BYTES); + memcpy(buf->data + buf->len, hash, ONETIMEAUTH_BYTES); buf->len += ONETIMEAUTH_BYTES; return 0; @@ -951,15 +951,15 @@ ss_onetimeauth_verify(buffer_t *buf, uint8_t *iv) size_t len = buf->len - ONETIMEAUTH_BYTES; #if defined(USE_CRYPTO_OPENSSL) - HMAC(EVP_sha1(), auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->array, len, hash, NULL); + HMAC(EVP_sha1(), auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->data, len, hash, NULL); #elif defined(USE_CRYPTO_MBEDTLS) mbedtls_md_hmac(mbedtls_md_info_from_type( - MBEDTLS_MD_SHA1), auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->array, len, hash); + MBEDTLS_MD_SHA1), auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->data, len, hash); #else - sha1_hmac(auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->array, len, hash); + sha1_hmac(auth_key, enc_iv_len + enc_key_len, (uint8_t *)buf->data, len, hash); #endif - return safe_memcmp(buf->array + len, hash, ONETIMEAUTH_BYTES); + return safe_memcmp(buf->data + len, hash, ONETIMEAUTH_BYTES); } int @@ -981,7 +981,7 @@ ss_encrypt_all(buffer_t *plain, int method, int auth, size_t capacity) rand_bytes(iv, iv_len); cipher_context_set_iv(&evp, iv, iv_len, 1); - memcpy(cipher->array, iv, iv_len); + memcpy(cipher->data, iv, iv_len); if (auth) { ss_onetimeauth(plain, iv, capacity); @@ -989,13 +989,13 @@ ss_encrypt_all(buffer_t *plain, int method, int auth, size_t capacity) } if (method >= SALSA20) { - crypto_stream_xor_ic((uint8_t *)(cipher->array + iv_len), - (const uint8_t *)plain->array, (uint64_t)(plain->len), + crypto_stream_xor_ic((uint8_t *)(cipher->data + iv_len), + (const uint8_t *)plain->data, (uint64_t)(plain->len), (const uint8_t *)iv, 0, enc_key, method); } else { - err = cipher_context_update(&evp, (uint8_t *)(cipher->array + iv_len), - &cipher->len, (const uint8_t *)plain->array, + err = cipher_context_update(&evp, (uint8_t *)(cipher->data + iv_len), + &cipher->len, (const uint8_t *)plain->data, plain->len); } @@ -1006,20 +1006,20 @@ ss_encrypt_all(buffer_t *plain, int method, int auth, size_t capacity) } #ifdef DEBUG - dump("PLAIN", plain->array, plain->len); - dump("CIPHER", cipher->array + iv_len, cipher->len); + dump("PLAIN", plain->data, plain->len); + dump("CIPHER", cipher->data + iv_len, cipher->len); #endif cipher_context_release(&evp); brealloc(plain, iv_len + cipher->len, capacity); - memcpy(plain->array, cipher->array, iv_len + cipher->len); + memcpy(plain->data, cipher->data, iv_len + cipher->len); plain->len = iv_len + cipher->len; return 0; } else { - char *begin = plain->array; - char *ptr = plain->array; + char *begin = plain->data; + char *ptr = plain->data; while (ptr < begin + plain->len) { *ptr = (char)enc_table[(uint8_t)*ptr]; ptr++; @@ -1046,7 +1046,7 @@ ss_encrypt(buffer_t *plain, enc_ctx_t *ctx, size_t capacity) if (!ctx->init) { cipher_context_set_iv(&ctx->evp, ctx->evp.iv, iv_len, 1); - memcpy(cipher->array, ctx->evp.iv, iv_len); + memcpy(cipher->data, ctx->evp.iv, iv_len); ctx->counter = 0; ctx->init = 1; } @@ -1056,25 +1056,25 @@ ss_encrypt(buffer_t *plain, enc_ctx_t *ctx, size_t capacity) brealloc(cipher, iv_len + (padding + cipher->len) * 2, capacity); if (padding) { brealloc(plain, plain->len + padding, capacity); - memmove(plain->array + padding, plain->array, plain->len); - sodium_memzero(plain->array, padding); + memmove(plain->data + padding, plain->data, plain->len); + sodium_memzero(plain->data, padding); } - crypto_stream_xor_ic((uint8_t *)(cipher->array + iv_len), - (const uint8_t *)plain->array, + crypto_stream_xor_ic((uint8_t *)(cipher->data + iv_len), + (const uint8_t *)plain->data, (uint64_t)(plain->len + padding), (const uint8_t *)ctx->evp.iv, ctx->counter / SODIUM_BLOCK_SIZE, enc_key, enc_method); ctx->counter += plain->len; if (padding) { - memmove(cipher->array + iv_len, - cipher->array + iv_len + padding, cipher->len); + memmove(cipher->data + iv_len, + cipher->data + iv_len + padding, cipher->len); } } else { err = cipher_context_update(&ctx->evp, - (uint8_t *)(cipher->array + iv_len), - &cipher->len, (const uint8_t *)plain->array, + (uint8_t *)(cipher->data + iv_len), + &cipher->len, (const uint8_t *)plain->data, plain->len); if (!err) { return -1; @@ -1082,18 +1082,18 @@ ss_encrypt(buffer_t *plain, enc_ctx_t *ctx, size_t capacity) } #ifdef DEBUG - dump("PLAIN", plain->array, plain->len); - dump("CIPHER", cipher->array + iv_len, cipher->len); + dump("PLAIN", plain->data, plain->len); + dump("CIPHER", cipher->data + iv_len, cipher->len); #endif brealloc(plain, iv_len + cipher->len, capacity); - memcpy(plain->array, cipher->array, iv_len + cipher->len); + memcpy(plain->data, cipher->data, iv_len + cipher->len); plain->len = iv_len + cipher->len; return 0; } else { - char *begin = plain->array; - char *ptr = plain->array; + char *begin = plain->data; + char *ptr = plain->data; while (ptr < begin + plain->len) { *ptr = (char)enc_table[(uint8_t)*ptr]; ptr++; @@ -1122,21 +1122,21 @@ ss_decrypt_all(buffer_t *cipher, int method, int auth, size_t capacity) plain->len = cipher->len - iv_len; uint8_t iv[MAX_IV_LENGTH]; - memcpy(iv, cipher->array, iv_len); + memcpy(iv, cipher->data, iv_len); cipher_context_set_iv(&evp, iv, iv_len, 0); if (method >= SALSA20) { - crypto_stream_xor_ic((uint8_t *)plain->array, - (const uint8_t *)(cipher->array + iv_len), + crypto_stream_xor_ic((uint8_t *)plain->data, + (const uint8_t *)(cipher->data + iv_len), (uint64_t)(cipher->len - iv_len), (const uint8_t *)iv, 0, enc_key, method); } else { - ret = cipher_context_update(&evp, (uint8_t *)plain->array, &plain->len, - (const uint8_t *)(cipher->array + iv_len), + ret = cipher_context_update(&evp, (uint8_t *)plain->data, &plain->len, + (const uint8_t *)(cipher->data + iv_len), cipher->len - iv_len); } - if (auth || (plain->array[0] & ONETIMEAUTH_FLAG)) { + if (auth || (plain->data[0] & ONETIMEAUTH_FLAG)) { if (plain->len > ONETIMEAUTH_BYTES) { ret = !ss_onetimeauth_verify(plain, iv); if (ret) { @@ -1154,20 +1154,20 @@ ss_decrypt_all(buffer_t *cipher, int method, int auth, size_t capacity) } #ifdef DEBUG - dump("PLAIN", plain->array, plain->len); - dump("CIPHER", cipher->array + iv_len, cipher->len - iv_len); + dump("PLAIN", plain->data, plain->len); + dump("CIPHER", cipher->data + iv_len, cipher->len - iv_len); #endif cipher_context_release(&evp); brealloc(cipher, plain->len, capacity); - memcpy(cipher->array, plain->array, plain->len); + memcpy(cipher->data, plain->data, plain->len); cipher->len = plain->len; return 0; } else { - char *begin = cipher->array; - char *ptr = cipher->array; + char *begin = cipher->data; + char *ptr = cipher->data; while (ptr < begin + cipher->len) { *ptr = (char)dec_table[(uint8_t)*ptr]; ptr++; @@ -1194,7 +1194,7 @@ ss_decrypt(buffer_t *cipher, enc_ctx_t *ctx, size_t capacity) iv_len = enc_iv_len; plain->len -= iv_len; - memcpy(iv, cipher->array, iv_len); + memcpy(iv, cipher->data, iv_len); cipher_context_set_iv(&ctx->evp, iv, iv_len, 0); ctx->counter = 0; ctx->init = 1; @@ -1215,23 +1215,23 @@ ss_decrypt(buffer_t *cipher, enc_ctx_t *ctx, size_t capacity) if (padding) { brealloc(cipher, cipher->len + padding, capacity); - memmove(cipher->array + iv_len + padding, cipher->array + iv_len, + memmove(cipher->data + iv_len + padding, cipher->data + iv_len, cipher->len - iv_len); - sodium_memzero(cipher->array + iv_len, padding); + sodium_memzero(cipher->data + iv_len, padding); } - crypto_stream_xor_ic((uint8_t *)plain->array, - (const uint8_t *)(cipher->array + iv_len), + crypto_stream_xor_ic((uint8_t *)plain->data, + (const uint8_t *)(cipher->data + iv_len), (uint64_t)(cipher->len - iv_len + padding), (const uint8_t *)ctx->evp.iv, ctx->counter / SODIUM_BLOCK_SIZE, enc_key, enc_method); ctx->counter += cipher->len - iv_len; if (padding) { - memmove(plain->array, plain->array + padding, plain->len); + memmove(plain->data, plain->data + padding, plain->len); } } else { - err = cipher_context_update(&ctx->evp, (uint8_t *)plain->array, &plain->len, - (const uint8_t *)(cipher->array + iv_len), + err = cipher_context_update(&ctx->evp, (uint8_t *)plain->data, &plain->len, + (const uint8_t *)(cipher->data + iv_len), cipher->len - iv_len); } @@ -1241,18 +1241,18 @@ ss_decrypt(buffer_t *cipher, enc_ctx_t *ctx, size_t capacity) } #ifdef DEBUG - dump("PLAIN", plain->array, plain->len); - dump("CIPHER", cipher->array + iv_len, cipher->len - iv_len); + dump("PLAIN", plain->data, plain->len); + dump("CIPHER", cipher->data + iv_len, cipher->len - iv_len); #endif brealloc(cipher, plain->len, capacity); - memcpy(cipher->array, plain->array, plain->len); + memcpy(cipher->data, plain->data, plain->len); cipher->len = plain->len; return 0; } else { - char *begin = cipher->array; - char *ptr = cipher->array; + char *begin = cipher->data; + char *ptr = cipher->data; while (ptr < begin + cipher->len) { *ptr = (char)dec_table[(uint8_t)*ptr]; ptr++; @@ -1397,10 +1397,10 @@ ss_check_hash(buffer_t *buf, chunk_t *chunk, enc_ctx_t *ctx, size_t capacity) brealloc(buf, chunk->len + blen, capacity); for (i = 0, j = 0, k = 0; i < blen; i++) { - chunk->buf->array[cidx++] = buf->array[k++]; + chunk->buf->data[cidx++] = buf->data[k++]; if (cidx == CLEN_BYTES) { - uint16_t clen = ntohs(*((uint16_t *)chunk->buf->array)); + uint16_t clen = ntohs(*((uint16_t *)chunk->buf->data)); brealloc(chunk->buf, clen + AUTH_BYTES, capacity); chunk->len = clen; } @@ -1415,22 +1415,22 @@ ss_check_hash(buffer_t *buf, chunk_t *chunk, enc_ctx_t *ctx, size_t capacity) memcpy(key + enc_iv_len, &c, sizeof(uint32_t)); #if defined(USE_CRYPTO_OPENSSL) HMAC(EVP_sha1(), key, enc_iv_len + sizeof(uint32_t), - (uint8_t *)chunk->buf->array + AUTH_BYTES, chunk->len, hash, NULL); + (uint8_t *)chunk->buf->data + AUTH_BYTES, chunk->len, hash, NULL); #elif defined(USE_CRYPTO_MBEDTLS) mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), key, enc_iv_len + sizeof(uint32_t), - (uint8_t *)chunk->buf->array + AUTH_BYTES, chunk->len, hash); + (uint8_t *)chunk->buf->data + AUTH_BYTES, chunk->len, hash); #else sha1_hmac(key, enc_iv_len + sizeof(uint32_t), - (uint8_t *)chunk->buf->array + AUTH_BYTES, chunk->len, hash); + (uint8_t *)chunk->buf->data + AUTH_BYTES, chunk->len, hash); #endif - if (safe_memcmp(hash, chunk->buf->array + CLEN_BYTES, ONETIMEAUTH_BYTES) != 0) { + if (safe_memcmp(hash, chunk->buf->data + CLEN_BYTES, ONETIMEAUTH_BYTES) != 0) { return 0; } // Copy chunk back to buffer - memmove(buf->array + j + chunk->len, buf->array + k, blen - i - 1); - memcpy(buf->array + j, chunk->buf->array + AUTH_BYTES, chunk->len); + memmove(buf->data + j + chunk->len, buf->data + k, blen - i - 1); + memcpy(buf->data + j, chunk->buf->data + AUTH_BYTES, chunk->len); // Reset the base offset j += chunk->len; @@ -1458,17 +1458,17 @@ ss_gen_hash(buffer_t *buf, uint32_t *counter, enc_ctx_t *ctx, size_t capacity) memcpy(key, ctx->evp.iv, enc_iv_len); memcpy(key + enc_iv_len, &c, sizeof(uint32_t)); #if defined(USE_CRYPTO_OPENSSL) - HMAC(EVP_sha1(), key, enc_iv_len + sizeof(uint32_t), (uint8_t *)buf->array, blen, hash, NULL); + HMAC(EVP_sha1(), key, enc_iv_len + sizeof(uint32_t), (uint8_t *)buf->data, blen, hash, NULL); #elif defined(USE_CRYPTO_MBEDTLS) mbedtls_md_hmac(mbedtls_md_info_from_type( - MBEDTLS_MD_SHA1), key, enc_iv_len + sizeof(uint32_t), (uint8_t *)buf->array, blen, hash); + MBEDTLS_MD_SHA1), key, enc_iv_len + sizeof(uint32_t), (uint8_t *)buf->data, blen, hash); #else - sha1_hmac(key, enc_iv_len + sizeof(uint32_t), (uint8_t *)buf->array, blen, hash); + sha1_hmac(key, enc_iv_len + sizeof(uint32_t), (uint8_t *)buf->data, blen, hash); #endif - memmove(buf->array + AUTH_BYTES, buf->array, blen); - memcpy(buf->array + CLEN_BYTES, hash, ONETIMEAUTH_BYTES); - memcpy(buf->array, &chunk_len, CLEN_BYTES); + memmove(buf->data + AUTH_BYTES, buf->data, blen); + memcpy(buf->data + CLEN_BYTES, hash, ONETIMEAUTH_BYTES); + memcpy(buf->data, &chunk_len, CLEN_BYTES); *counter = *counter + 1; buf->len = blen + AUTH_BYTES; diff --git a/src/encrypt.h b/src/encrypt.h index bfa5c2aec..836ed0fbd 100644 --- a/src/encrypt.h +++ b/src/encrypt.h @@ -164,7 +164,7 @@ typedef struct buffer { size_t idx; size_t len; size_t capacity; - char *array; + char *data; } buffer_t; typedef struct chunk { @@ -201,4 +201,6 @@ int balloc(buffer_t *ptr, size_t capacity); int brealloc(buffer_t *ptr, size_t len, size_t capacity); void bfree(buffer_t *ptr); +int rand_bytes(void *output, int len); + #endif // _ENCRYPT_H diff --git a/src/jconf.c b/src/jconf.c index bb9cbc9e4..c653f2439 100644 --- a/src/jconf.c +++ b/src/jconf.c @@ -199,6 +199,10 @@ read_jconf(const char *file) conf.timeout = to_string(value); } else if (strcmp(name, "user") == 0) { conf.user = to_string(value); + } else if (strcmp(name, "obfs") == 0) { + conf.obfs = to_string(value); + } else if (strcmp(name, "obfs_host") == 0) { + conf.obfs_host = to_string(value); } else if (strcmp(name, "fast_open") == 0) { check_json_value_type(value, json_boolean, "invalid config file: option 'fast_open' must be a boolean"); diff --git a/src/jconf.h b/src/jconf.h index f8dc1f567..f2eb0d8ac 100644 --- a/src/jconf.h +++ b/src/jconf.h @@ -56,6 +56,8 @@ typedef struct { char *method; char *timeout; char *user; + char *obfs; + char *obfs_host; int auth; int fast_open; int nofile; diff --git a/src/local.c b/src/local.c index c3423694b..05c884077 100644 --- a/src/local.c +++ b/src/local.c @@ -66,6 +66,8 @@ #include "acl.h" #include "http.h" #include "tls.h" +#include "obfs_http.h" +#include "obfs_tls.h" #include "local.h" #ifndef LIB_ONLY @@ -102,18 +104,19 @@ char *prefix; #endif static int acl = 0; +static int auth = 0; static int mode = TCP_ONLY; static int ipv6first = 0; - static int fast_open = 0; + +static obfs_para_t *obfs_para = NULL; + #ifdef HAVE_SETRLIMIT #ifndef LIB_ONLY static int nofile = 0; #endif #endif -static int auth = 0; - static void server_recv_cb(EV_P_ ev_io *w, int revents); static void server_send_cb(EV_P_ ev_io *w, int revents); static void remote_recv_cb(EV_P_ ev_io *w, int revents); @@ -260,7 +263,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) buf = remote->buf; } - r = recv(server->fd, buf->array + buf->len, BUF_SIZE - buf->len, 0); + r = recv(server->fd, buf->data + buf->len, BUF_SIZE - buf->len, 0); if (r == 0) { // connection closed @@ -309,6 +312,9 @@ server_recv_cb(EV_P_ ev_io *w, int revents) close_and_free_server(EV_A_ server); return; } + + if (obfs_para) + obfs_para->obfs_request(remote->buf, BUF_SIZE, server->obfs); } if (!remote->send_ctx->connected) { @@ -361,10 +367,10 @@ server_recv_cb(EV_P_ ev_io *w, int revents) CONNECT_RESUME_ON_READ_WRITE | CONNECT_DATA_IDEMPOTENT, NULL, 0, NULL, NULL); if (s == 0) { - s = send(remote->fd, remote->buf->array, remote->buf->len, 0); + s = send(remote->fd, remote->buf->data, remote->buf->len, 0); } #else - int s = sendto(remote->fd, remote->buf->array, remote->buf->len, MSG_FASTOPEN, + int s = sendto(remote->fd, remote->buf->data, remote->buf->len, MSG_FASTOPEN, (struct sockaddr *)&(remote->addr), remote->addr_len); #endif if (s == -1) { @@ -416,7 +422,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) #endif } } else { - int s = send(remote->fd, remote->buf->array, remote->buf->len, 0); + int s = send(remote->fd, remote->buf->data, remote->buf->len, 0); if (s == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { // no data, wait for send @@ -452,9 +458,9 @@ server_recv_cb(EV_P_ ev_io *w, int revents) send(server->fd, send_buf, sizeof(response), 0); server->stage = STAGE_HANDSHAKE; - int off = (buf->array[1] & 0xff) + 2; - if (buf->array[0] == 0x05 && off < (int)(buf->len)) { - memmove(buf->array, buf->array + off, buf->len - off); + int off = (buf->data[1] & 0xff) + 2; + if (buf->data[0] == 0x05 && off < (int)(buf->len)) { + memmove(buf->data, buf->data + off, buf->len - off); buf->len -= off; continue; } @@ -463,7 +469,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) return; } else if (server->stage == STAGE_HANDSHAKE || server->stage == STAGE_PARSE) { - struct socks5_request *request = (struct socks5_request *)buf->array; + struct socks5_request *request = (struct socks5_request *)buf->data; struct sockaddr_in sock_addr; memset(&sock_addr, 0, sizeof(sock_addr)); @@ -503,17 +509,17 @@ server_recv_cb(EV_P_ ev_io *w, int revents) buffer_t *resp_buf = &resp_to_send; balloc(resp_buf, BUF_SIZE); - memcpy(resp_buf->array, &response, sizeof(struct socks5_response)); - memcpy(resp_buf->array + sizeof(struct socks5_response), + memcpy(resp_buf->data, &response, sizeof(struct socks5_response)); + memcpy(resp_buf->data + sizeof(struct socks5_response), &sock_addr.sin_addr, sizeof(sock_addr.sin_addr)); - memcpy(resp_buf->array + sizeof(struct socks5_response) + + memcpy(resp_buf->data + sizeof(struct socks5_response) + sizeof(sock_addr.sin_addr), &sock_addr.sin_port, sizeof(sock_addr.sin_port)); int reply_size = sizeof(struct socks5_response) + sizeof(sock_addr.sin_addr) + sizeof(sock_addr.sin_port); - int s = send(server->fd, resp_buf->array, reply_size, 0); + int s = send(server->fd, resp_buf->data, reply_size, 0); bfree(resp_buf); @@ -536,45 +542,45 @@ server_recv_cb(EV_P_ ev_io *w, int revents) buffer_t *abuf = &ss_addr_to_send; balloc(abuf, BUF_SIZE); - abuf->array[abuf->len++] = request->atyp; + abuf->data[abuf->len++] = request->atyp; int atyp = request->atyp; // get remote addr and port if (atyp == 1) { // IP V4 size_t in_addr_len = sizeof(struct in_addr); - memcpy(abuf->array + abuf->len, buf->array + 4, in_addr_len + 2); + memcpy(abuf->data + abuf->len, buf->data + 4, in_addr_len + 2); abuf->len += in_addr_len + 2; if (acl || verbose) { - uint16_t p = ntohs(*(uint16_t *)(buf->array + 4 + in_addr_len)); - dns_ntop(AF_INET, (const void *)(buf->array + 4), + uint16_t p = ntohs(*(uint16_t *)(buf->data + 4 + in_addr_len)); + dns_ntop(AF_INET, (const void *)(buf->data + 4), ip, INET_ADDRSTRLEN); sprintf(port, "%d", p); } } else if (atyp == 3) { // Domain name - uint8_t name_len = *(uint8_t *)(buf->array + 4); - abuf->array[abuf->len++] = name_len; - memcpy(abuf->array + abuf->len, buf->array + 4 + 1, name_len + 2); + uint8_t name_len = *(uint8_t *)(buf->data + 4); + abuf->data[abuf->len++] = name_len; + memcpy(abuf->data + abuf->len, buf->data + 4 + 1, name_len + 2); abuf->len += name_len + 2; if (acl || verbose) { uint16_t p = - ntohs(*(uint16_t *)(buf->array + 4 + 1 + name_len)); - memcpy(host, buf->array + 4 + 1, name_len); + ntohs(*(uint16_t *)(buf->data + 4 + 1 + name_len)); + memcpy(host, buf->data + 4 + 1, name_len); host[name_len] = '\0'; sprintf(port, "%d", p); } } else if (atyp == 4) { // IP V6 size_t in6_addr_len = sizeof(struct in6_addr); - memcpy(abuf->array + abuf->len, buf->array + 4, in6_addr_len + 2); + memcpy(abuf->data + abuf->len, buf->data + 4, in6_addr_len + 2); abuf->len += in6_addr_len + 2; if (acl || verbose) { - uint16_t p = ntohs(*(uint16_t *)(buf->array + 4 + in6_addr_len)); - dns_ntop(AF_INET6, (const void *)(buf->array + 4), + uint16_t p = ntohs(*(uint16_t *)(buf->data + 4 + in6_addr_len)); + dns_ntop(AF_INET6, (const void *)(buf->data + 4), ip, INET6_ADDRSTRLEN); sprintf(port, "%d", p); } @@ -591,13 +597,13 @@ server_recv_cb(EV_P_ ev_io *w, int revents) if (atyp == 1 || atyp == 4) { char *hostname; - uint16_t p = ntohs(*(uint16_t *)(abuf->array + abuf->len - 2)); + uint16_t p = ntohs(*(uint16_t *)(abuf->data + abuf->len - 2)); int ret = 0; if (p == http_protocol->default_port) - ret = http_protocol->parse_packet(buf->array + 3 + abuf->len, + ret = http_protocol->parse_packet(buf->data + 3 + abuf->len, buf->len - 3 - abuf->len, &hostname); else if (p == tls_protocol->default_port) - ret = tls_protocol->parse_packet(buf->array + 3 + abuf->len, + ret = tls_protocol->parse_packet(buf->data + 3 + abuf->len, buf->len - 3 - abuf->len, &hostname); if (ret == -1 && buf->len < BUF_SIZE) { server->stage = STAGE_PARSE; @@ -607,13 +613,13 @@ server_recv_cb(EV_P_ ev_io *w, int revents) sni_detected = 1; // Reconstruct address buffer - abuf->len = 0; - abuf->array[abuf->len++] = 3; - abuf->array[abuf->len++] = ret; - memcpy(abuf->array + abuf->len, hostname, ret); + abuf->len = 0; + abuf->data[abuf->len++] = 3; + abuf->data[abuf->len++] = ret; + memcpy(abuf->data + abuf->len, hostname, ret); abuf->len += ret; p = htons(p); - memcpy(abuf->array + abuf->len, &p, 2); + memcpy(abuf->data + abuf->len, &p, 2); abuf->len += 2; if (acl || verbose) { @@ -629,7 +635,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) buf->len -= (3 + abuf_len); if (buf->len > 0) { - memmove(buf->array, buf->array + 3 + abuf_len, buf->len); + memmove(buf->data, buf->data + 3 + abuf_len, buf->len); } if (verbose) { @@ -679,7 +685,8 @@ server_recv_cb(EV_P_ ev_io *w, int revents) int err = get_sockaddr(ip, port, &storage, 0, ipv6first); if (err != -1) { remote = create_remote(server->listener, (struct sockaddr *)&storage); - if (remote != NULL) remote->direct = 1; + if (remote != NULL) + remote->direct = 1; } } } @@ -698,7 +705,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) if (!remote->direct) { if (auth) { - abuf->array[0] |= ONETIMEAUTH_FLAG; + abuf->data[0] |= ONETIMEAUTH_FLAG; ss_onetimeauth(abuf, server->e_ctx->evp.iv, BUF_SIZE); } @@ -707,15 +714,15 @@ server_recv_cb(EV_P_ ev_io *w, int revents) } brealloc(remote->buf, buf->len + abuf->len, BUF_SIZE); - memcpy(remote->buf->array, abuf->array, abuf->len); + memcpy(remote->buf->data, abuf->data, abuf->len); remote->buf->len = buf->len + abuf->len; if (buf->len > 0) { - memcpy(remote->buf->array + abuf->len, buf->array, buf->len); + memcpy(remote->buf->data + abuf->len, buf->data, buf->len); } } else { if (buf->len > 0) { - memcpy(remote->buf->array, buf->array, buf->len); + memcpy(remote->buf->data, buf->data, buf->len); remote->buf->len = buf->len; } } @@ -741,7 +748,7 @@ server_send_cb(EV_P_ ev_io *w, int revents) return; } else { // has data to send - ssize_t s = send(server->fd, server->buf->array + server->buf->idx, + ssize_t s = send(server->fd, server->buf->data + server->buf->idx, server->buf->len, 0); if (s == -1) { if (errno != EAGAIN && errno != EWOULDBLOCK) { @@ -809,7 +816,7 @@ remote_recv_cb(EV_P_ ev_io *w, int revents) stat_update_cb(); #endif - ssize_t r = recv(remote->fd, server->buf->array, BUF_SIZE, 0); + ssize_t r = recv(remote->fd, server->buf->data, BUF_SIZE, 0); if (r == 0) { // connection closed @@ -835,6 +842,15 @@ remote_recv_cb(EV_P_ ev_io *w, int revents) #ifdef ANDROID rx += server->buf->len; #endif + if (obfs_para) { + if (obfs_para->deobfs_response(server->buf, BUF_SIZE, server->obfs)) { + LOGE("invalid obfuscating"); + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); + return; + } + } + int err = ss_decrypt(server->buf, server->d_ctx, BUF_SIZE); if (err) { LOGE("invalid password or cipher"); @@ -844,7 +860,7 @@ remote_recv_cb(EV_P_ ev_io *w, int revents) } } - int s = send(server->fd, server->buf->array, server->buf->len, 0); + int s = send(server->fd, server->buf->data, server->buf->len, 0); if (s == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { @@ -913,7 +929,7 @@ remote_send_cb(EV_P_ ev_io *w, int revents) return; } else { // has data to send - ssize_t s = send(remote->fd, remote->buf->array + remote->buf->idx, + ssize_t s = send(remote->fd, remote->buf->data + remote->buf->idx, remote->buf->len, 0); if (s == -1) { if (errno != EAGAIN && errno != EWOULDBLOCK) { @@ -946,9 +962,9 @@ new_remote(int fd, int timeout) memset(remote, 0, sizeof(remote_t)); - remote->buf = ss_malloc(sizeof(buffer_t)); - remote->recv_ctx = ss_malloc(sizeof(remote_ctx_t)); - remote->send_ctx = ss_malloc(sizeof(remote_ctx_t)); + remote->buf = ss_malloc(sizeof(buffer_t)); + remote->recv_ctx = ss_malloc(sizeof(remote_ctx_t)); + remote->send_ctx = ss_malloc(sizeof(remote_ctx_t)); balloc(remote->buf, BUF_SIZE); memset(remote->recv_ctx, 0, sizeof(remote_ctx_t)); memset(remote->send_ctx, 0, sizeof(remote_ctx_t)); @@ -1004,9 +1020,9 @@ new_server(int fd, int method) memset(server, 0, sizeof(server_t)); - server->recv_ctx = ss_malloc(sizeof(server_ctx_t)); - server->send_ctx = ss_malloc(sizeof(server_ctx_t)); - server->buf = ss_malloc(sizeof(buffer_t)); + server->recv_ctx = ss_malloc(sizeof(server_ctx_t)); + server->send_ctx = ss_malloc(sizeof(server_ctx_t)); + server->buf = ss_malloc(sizeof(buffer_t)); balloc(server->buf, BUF_SIZE); memset(server->recv_ctx, 0, sizeof(server_ctx_t)); memset(server->send_ctx, 0, sizeof(server_ctx_t)); @@ -1017,6 +1033,11 @@ new_server(int fd, int method) server->recv_ctx->server = server; server->send_ctx->server = server; + if (obfs_para != NULL) { + server->obfs = (obfs_t *)ss_malloc(sizeof(obfs_t)); + memset(server->obfs, 0, sizeof(obfs_t)); + } + if (method) { server->e_ctx = ss_malloc(sizeof(struct enc_ctx)); server->d_ctx = ss_malloc(sizeof(struct enc_ctx)); @@ -1040,6 +1061,12 @@ free_server(server_t *server) { cork_dllist_remove(&server->entries); + if (server->obfs != NULL) { + bfree(server->obfs->buf); + if (server->obfs->extra != NULL) + ss_free(server->obfs->extra); + ss_free(server->obfs); + } if (server->remote != NULL) { server->remote->server = NULL; } @@ -1180,6 +1207,7 @@ main(int argc, char **argv) char *pid_path = NULL; char *conf_path = NULL; char *iface = NULL; + char *obfs_host = NULL; srand(time(NULL)); @@ -1193,6 +1221,8 @@ main(int argc, char **argv) { "acl", required_argument, 0, 0 }, { "mtu", required_argument, 0, 0 }, { "mptcp", no_argument, 0, 0 }, + { "obfs", required_argument, 0, 0 }, + { "obfs-host", required_argument, 0, 0 }, { "help", no_argument, 0, 0 }, { 0, 0, 0, 0 } }; @@ -1222,6 +1252,14 @@ main(int argc, char **argv) mptcp = 1; LOGI("enable multipath TCP"); } else if (option_index == 4) { + if (strcmp(optarg, obfs_http->name) == 0) + obfs_para = obfs_http; + else if (strcmp(optarg, obfs_tls->name) == 0) + obfs_para = obfs_tls; + LOGI("obfuscating enabled"); + } else if (option_index == 5) { + obfs_host = optarg; + } else if (option_index == 6) { usage(); exit(EXIT_SUCCESS); } @@ -1340,6 +1378,15 @@ main(int argc, char **argv) if (user == NULL) { user = conf->user; } + if (obfs_para == NULL && conf->obfs != NULL) { + if (strcmp(conf->obfs, obfs_http->name) == 0) + obfs_para = obfs_http; + else if (strcmp(conf->obfs, obfs_tls->name) == 0) + obfs_para = obfs_tls; + } + if (obfs_host == NULL) { + obfs_host = conf->obfs_host; + } if (auth == 0) { auth = conf->auth; } @@ -1417,6 +1464,15 @@ main(int argc, char **argv) LOGI("onetime authentication enabled"); } + if (obfs_para) { + if (obfs_host != NULL) + obfs_para->host = obfs_host; + else + obfs_para->host = "cloudfront.net"; + obfs_para->port = atoi(remote_port); + LOGI("obfuscating arg: %s", obfs_host); + } + #ifdef __MINGW32__ winsock_init(); #else @@ -1502,12 +1558,12 @@ main(int argc, char **argv) LOGI("listening at %s:%s", local_addr, local_port); // setuid - if (user != NULL && ! run_as(user)) { + if (user != NULL && !run_as(user)) { FATAL("failed to switch user"); } #ifndef __MINGW32__ - if (geteuid() == 0){ + if (geteuid() == 0) { LOGI("running from root user"); } #endif diff --git a/src/local.h b/src/local.h index 4487afb96..dc1335b85 100644 --- a/src/local.h +++ b/src/local.h @@ -51,7 +51,10 @@ typedef struct server_ctx { typedef struct server { int fd; - char stage; + int stage; + + obfs_t *obfs; + struct enc_ctx *e_ctx; struct enc_ctx *d_ctx; struct server_ctx *recv_ctx; @@ -67,20 +70,22 @@ typedef struct server { typedef struct remote_ctx { ev_io io; ev_timer watcher; + int connected; struct remote *remote; } remote_ctx_t; typedef struct remote { int fd; - buffer_t *buf; int direct; + int addr_len; + uint32_t counter; + + buffer_t *buf; struct remote_ctx *recv_ctx; struct remote_ctx *send_ctx; struct server *server; struct sockaddr_storage addr; - int addr_len; - uint32_t counter; } remote_t; #endif // _LOCAL_H diff --git a/src/manager.c b/src/manager.c index f76c4dda3..3a9aa9d6c 100644 --- a/src/manager.c +++ b/src/manager.c @@ -172,6 +172,10 @@ construct_command_line(struct manager_ctx *manager, struct server *server) int len = strlen(cmd); snprintf(cmd + len, BUF_SIZE - len, " --mtu %d", manager->mtu); } + if (manager->obfs) { + int len = strlen(cmd); + snprintf(cmd + len, BUF_SIZE - len, " --obfs %s", manager->obfs); + } for (i = 0; i < manager->nameserver_num; i++) { int len = strlen(cmd); snprintf(cmd + len, BUF_SIZE - len, " -d %s", manager->nameservers[i]); @@ -611,6 +615,7 @@ main(int argc, char **argv) char *conf_path = NULL; char *iface = NULL; char *manager_address = NULL; + char *obfs = NULL; int auth = 0; int fast_open = 0; @@ -636,6 +641,7 @@ main(int argc, char **argv) { "manager-address", required_argument, 0, 0 }, { "executable", required_argument, 0, 0 }, { "mtu", required_argument, 0, 0 }, + { "obfs", required_argument, 0, 0 }, { "help", no_argument, 0, 0 }, { 0, 0, 0, 0 } }; @@ -658,8 +664,9 @@ main(int argc, char **argv) executable = optarg; } else if (option_index == 4) { mtu = atoi(optarg); - LOGI("set MTU to %d", mtu); } else if (option_index == 5) { + obfs = optarg; + } else if (option_index == 6) { usage(); exit(EXIT_SUCCESS); } @@ -764,6 +771,9 @@ main(int argc, char **argv) if (mtu == 0) { mtu = conf->mtu; } + if (obfs == 0) { + obfs = conf->obfs; + } #ifdef HAVE_SETRLIMIT if (nofile == 0) { nofile = conf->nofile; @@ -840,6 +850,7 @@ main(int argc, char **argv) manager.nameservers = nameservers; manager.nameserver_num = nameserver_num; manager.mtu = mtu; + manager.obfs = obfs; #ifdef HAVE_SETRLIMIT manager.nofile = nofile; #endif diff --git a/src/manager.h b/src/manager.h index 50416fe6f..9f93da858 100644 --- a/src/manager.h +++ b/src/manager.h @@ -44,6 +44,7 @@ struct manager_ctx { char *iface; char *acl; char *user; + char *obfs; char *manager_address; char **hosts; int host_num; diff --git a/src/obfs.h b/src/obfs.h new file mode 100644 index 000000000..a158f180d --- /dev/null +++ b/src/obfs.h @@ -0,0 +1,54 @@ +/* + * obfs.h - Interfaces of obfuscating function + * + * Copyright (C) 2013 - 2016, Max Lv + * + * This file is part of the shadowsocks-libev. + * + * shadowsocks-libev is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * shadowsocks-libev is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shadowsocks-libev; see the file COPYING. If not, see + * . + */ + +#ifndef OBFS_H +#define OBFS_H + +#include "encrypt.h" + +#define OBFS_OK 0 +#define OBFS_NEED_MORE -1 +#define OBFS_ERROR -2 + +typedef struct obfs { + int obfs_stage; + int deobfs_stage; + buffer_t *buf; + void *extra; +} obfs_t; + +typedef struct obfs_para { + const char *name; + const char *host; + uint16_t port; + + int(*const obfs_request)(buffer_t *, size_t, obfs_t *); + int(*const obfs_response)(buffer_t *, size_t, obfs_t *); + int(*const deobfs_request)(buffer_t *, size_t, obfs_t *); + int(*const deobfs_response)(buffer_t *, size_t, obfs_t *); + int(*const check_obfs)(buffer_t *); + void(*const disable)(obfs_t *); + int(*const is_enable)(obfs_t *); +} obfs_para_t; + + +#endif diff --git a/src/obfs_http.c b/src/obfs_http.c new file mode 100644 index 000000000..d2f31fac9 --- /dev/null +++ b/src/obfs_http.c @@ -0,0 +1,213 @@ +/* + * obfs_http.c - Implementation of http obfuscating + * + * Copyright (C) 2013 - 2016, Max Lv + * + * This file is part of the shadowsocks-libev. + * + * shadowsocks-libev is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * shadowsocks-libev is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shadowsocks-libev; see the file COPYING. If not, see + * . + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "base64.h" +#include "utils.h" +#include "obfs_http.h" + +static const char *http_request_template = + "GET / HTTP/1.1\r\n" + "Host: %s\r\n" + "User-Agent: curl/7.%d.%d\r\n" + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n" + "Sec-WebSocket-Key: %s\r\n" + "\r\n"; + +static const char *http_response_template = + "HTTP/1.1 101 Switching Protocols\r\n" + "Server: nginx/1.%d.%d\r\n" + "Date: %s\r\n" + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n" + "Sec-WebSocket-Accept: %s\r\n" + "\r\n"; + +static int obfs_http_request(buffer_t *, size_t, obfs_t *); +static int obfs_http_response(buffer_t *, size_t, obfs_t *); +static int deobfs_http_header(buffer_t *, size_t, obfs_t *); +static int check_http_header(buffer_t *buf); +static void disable_http(obfs_t *obfs); +static int is_enable_http(obfs_t *obfs); + +static obfs_para_t obfs_http_st = { + .name = "http", + .port = 80, + .obfs_request = &obfs_http_request, + .obfs_response = &obfs_http_response, + .deobfs_request = &deobfs_http_header, + .deobfs_response = &deobfs_http_header, + .check_obfs = &check_http_header, + .disable = &disable_http, + .is_enable = &is_enable_http +}; + +obfs_para_t *const obfs_http = &obfs_http_st; + +static int +obfs_http_request(buffer_t *buf, size_t cap, obfs_t *obfs) +{ + + if (obfs == NULL || obfs->obfs_stage != 0) return 0; + obfs->obfs_stage++; + + static int major_version = 0; + static int minor_version = 0; + + major_version = major_version ? major_version : rand() % 51; + minor_version = minor_version ? minor_version : rand() % 2; + + char host_port[256]; + char http_header[512]; + uint8_t key[16]; + char b64[64]; + + if (obfs_http->port != 80) + snprintf(host_port, sizeof(host_port), "%s:%d", obfs_http->host, obfs_http->port); + else + snprintf(host_port, sizeof(host_port), "%s", obfs_http->host); + + rand_bytes(key, 16); + base64_encode(b64, 64, key, 16); + + size_t obfs_len = + snprintf(http_header, sizeof(http_header), http_request_template, + host_port, major_version, minor_version, b64); + size_t buf_len = buf->len; + + brealloc(buf, obfs_len + buf_len, cap); + + memmove(buf->data + obfs_len, buf->data, buf_len); + memcpy(buf->data, http_header, obfs_len); + + buf->len = obfs_len + buf_len; + + return buf->len; +} + +static int +obfs_http_response(buffer_t *buf, size_t cap, obfs_t *obfs) +{ + if (obfs == NULL || obfs->obfs_stage != 0) return 0; + obfs->obfs_stage++; + + static int major_version = 0; + static int minor_version = 0; + + major_version = major_version ? major_version : rand() % 11; + minor_version = minor_version ? minor_version : rand() % 12; + + char http_header[512]; + char datetime[64]; + uint8_t key[16]; + char b64[64]; + + time_t now; + struct tm *tm_now; + + time(&now); + tm_now = localtime(&now); + strftime(datetime, 64, "%a, %d %b %Y %H:%M:%S GMT", tm_now); + + rand_bytes(key, 16); + base64_encode(b64, 64, key, 16); + + size_t buf_len = buf->len; + size_t obfs_len = + snprintf(http_header, sizeof(http_header), http_response_template, + major_version, minor_version, datetime, b64); + + brealloc(buf, obfs_len + buf_len, cap); + + memmove(buf->data + obfs_len, buf->data, buf_len); + memcpy(buf->data, http_header, obfs_len); + + buf->len = obfs_len + buf_len; + + return buf->len; +} + +static int +deobfs_http_header(buffer_t *buf, size_t cap, obfs_t *obfs) +{ + if (obfs == NULL || obfs->deobfs_stage != 0) return 0; + + char *data = buf->data; + int len = buf->len; + int err = -1; + + while (len > 4) { + if (data[0] == '\r' && data[1] == '\n' + && data[2] == '\r' && data[3] == '\n') { + len -= 4; + data += 4; + err = 0; + break; + } + len--; + data++; + } + + if (!err) { + memmove(buf->data, data, len); + buf->len = len; + obfs->deobfs_stage++; + } + + return err; +} + +static int +check_http_header(buffer_t *buf) +{ + char *data = buf->data; + int len = buf->len; + + if (len < 4) + return -1; + + if (strncasecmp(data, "GET", 3) == 0) + return 1; + else if (strncasecmp(data, "HTTP", 4) == 0) + return 1; + + return 0; +} + +static void +disable_http(obfs_t *obfs) +{ + obfs->obfs_stage = -1; + obfs->deobfs_stage = -1; +} + +static int +is_enable_http(obfs_t *obfs) +{ + return obfs->obfs_stage == 0 && obfs->deobfs_stage == 0; +} diff --git a/src/obfs_http.h b/src/obfs_http.h new file mode 100644 index 000000000..d80f939d0 --- /dev/null +++ b/src/obfs_http.h @@ -0,0 +1,30 @@ +/* + * obfs_http.h - Interfaces of http obfuscating function + * + * Copyright (C) 2013 - 2016, Max Lv + * + * This file is part of the shadowsocks-libev. + * + * shadowsocks-libev is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * shadowsocks-libev is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shadowsocks-libev; see the file COPYING. If not, see + * . + */ + +#ifndef OBFS_HTTP_H +#define OBFS_HTTP_H + +#include "obfs.h" + +obfs_para_t *const obfs_http; + +#endif diff --git a/src/obfs_tls.c b/src/obfs_tls.c new file mode 100644 index 000000000..1c882c5c2 --- /dev/null +++ b/src/obfs_tls.c @@ -0,0 +1,524 @@ +/* + * obfs_tls.c - Implementation of tls obfuscating + * + * Copyright (C) 2013 - 2016, Max Lv + * + * This file is part of the shadowsocks-libev. + * + * shadowsocks-libev is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * shadowsocks-libev is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shadowsocks-libev; see the file COPYING. If not, see + * . + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "base64.h" +#include "utils.h" +#include "obfs_tls.h" + +static const struct tls_client_hello +tls_client_hello_template = { + .content_type = 0x16, + .version = CT_HTONS(0x0301), + .len = 0, + + .handshake_type = 1, + .handshake_len_1 = 0, + .handshake_len_2 = 0, + .handshake_version = CT_HTONS(0x0303), + + .random_unix_time = 0, + .random_bytes = { 0 }, + + .session_id_len = 32, + .session_id = { 0 }, + + .cipher_suites_len = CT_HTONS(56), + .cipher_suites = { + 0xc0, 0x2c, 0xc0, 0x30, 0x00, 0x9f, 0xcc, 0xa9, 0xcc, 0xa8, 0xcc, 0xaa, 0xc0, 0x2b, 0xc0, 0x2f, + 0x00, 0x9e, 0xc0, 0x24, 0xc0, 0x28, 0x00, 0x6b, 0xc0, 0x23, 0xc0, 0x27, 0x00, 0x67, 0xc0, 0x0a, + 0xc0, 0x14, 0x00, 0x39, 0xc0, 0x09, 0xc0, 0x13, 0x00, 0x33, 0x00, 0x9d, 0x00, 0x9c, 0x00, 0x3d, + 0x00, 0x3c, 0x00, 0x35, 0x00, 0x2f, 0x00, 0xff + }, + + .comp_methods_len = 1, + .comp_methods = { 0 }, + + .ext_len = 0, +}; + +static const struct tls_ext_server_name +tls_ext_server_name_template = { + .ext_type = 0, + .ext_len = 0, + .server_name_list_len = 0, + .server_name_type = 0, + .server_name_len = 0 + // char server_name[server_name_len]; +}; + +static const struct tls_ext_session_ticket +tls_ext_session_ticket_template = { + .session_ticket_type = CT_HTONS(0x0023), + .session_ticket_ext_len = 0, + // char session_ticket[session_ticket_ext_len]; +}; + +static const struct tls_ext_others +tls_ext_others_template = { + .ec_point_formats_ext_type = CT_HTONS(0x000B), + .ec_point_formats_ext_len = CT_HTONS(4), + .ec_point_formats_len = 3, + .ec_point_formats = { 0x01, 0x00, 0x02 }, + + .elliptic_curves_type = CT_HTONS(0x000a), + .elliptic_curves_ext_len = CT_HTONS(10), + .elliptic_curves_len = CT_HTONS(8), + .elliptic_curves = { 0x00, 0x1d, 0x00, 0x17, 0x00, 0x19, 0x00, 0x18 }, + + .sig_algos_type = CT_HTONS(0x000d), + .sig_algos_ext_len = CT_HTONS(32), + .sig_algos_len = CT_HTONS(30), + .sig_algos = { + 0x06, 0x01, 0x06, 0x02, 0x06, 0x03, 0x05, 0x01, 0x05, 0x02, 0x05, 0x03, 0x04, 0x01, 0x04, 0x02, + 0x04, 0x03, 0x03, 0x01, 0x03, 0x02, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x03 + }, + + .encrypt_then_mac_type = CT_HTONS(0x0016), + .encrypt_then_mac_ext_len = 0, + + .extended_master_secret_type = CT_HTONS(0x0017), + .extended_master_secret_ext_len = 0 +}; + +static const struct tls_server_hello +tls_server_hello_template = { + .content_type = 0x16, + .version = CT_HTONS(0x0301), + .len = CT_HTONS(91), + + .handshake_type = 2, + .handshake_len_1 = 0, + .handshake_len_2 = CT_HTONS(87), + .handshake_version = CT_HTONS(0x0303), + + .random_unix_time = 0, + .random_bytes = { 0 }, + + .session_id_len = 32, + .session_id = { 0 }, + + .cipher_suite = CT_HTONS(0xCCA8), + .comp_method = 0, + .ext_len = 0, + + .ext_renego_info_type = CT_HTONS(0xFF01), + .ext_renego_info_ext_len = CT_HTONS(1), + .ext_renego_info_len = 0, + + .extended_master_secret_type = CT_HTONS(0x0017), + .extended_master_secret_ext_len = 0, + + .ec_point_formats_ext_type = CT_HTONS(0x000B), + .ec_point_formats_ext_len = CT_HTONS(2), + .ec_point_formats_len = 1, + .ec_point_formats = { 0 } +}; + +static const struct tls_change_cipher_spec +tls_change_cipher_spec_template = { + .content_type = 0x14, + .version = CT_HTONS(0x0303), + .len = CT_HTONS(1), + .msg = 0x01 +}; + +static const struct tls_encrypted_handshake +tls_encrypted_handshake_template = { + .content_type = 0x16, + .version = CT_HTONS(0x0303), + .len = 0 + // char msg[len]; +}; + +const char tls_data_header[3] = {0x17, 0x03, 0x03}; + + +static int obfs_tls_request(buffer_t *, size_t, obfs_t *); +static int obfs_tls_response(buffer_t *, size_t, obfs_t *); +static int deobfs_tls_request(buffer_t *, size_t, obfs_t *); +static int deobfs_tls_response(buffer_t *, size_t, obfs_t *); +static int obfs_app_data(buffer_t *, size_t, obfs_t *); +static int deobfs_app_data(buffer_t *, size_t, obfs_t *); +static int check_tls_request(buffer_t *buf); +static void disable_tls(obfs_t *obfs); +static int is_enable_tls(obfs_t *obfs); + +static obfs_para_t obfs_tls_st = { + .name = "tls", + .port = 443, + .obfs_request = &obfs_tls_request, + .obfs_response = &obfs_tls_response, + .deobfs_request = &deobfs_tls_request, + .deobfs_response = &deobfs_tls_response, + .check_obfs = &check_tls_request, + .disable = &disable_tls, + .is_enable = &is_enable_tls +}; + +obfs_para_t *const obfs_tls = &obfs_tls_st; + +static int +obfs_app_data(buffer_t *buf, size_t cap, obfs_t *obfs) +{ + size_t buf_len = buf->len; + + brealloc(buf, buf_len + 5, cap); + memmove(buf->data + 5, buf->data, buf_len); + memcpy(buf->data, tls_data_header, 3); + + *(uint16_t*)(buf->data + 3) = CT_HTONS(buf_len); + buf->len = buf_len + 5; + + return 0; +} + +static int +deobfs_app_data(buffer_t *buf, size_t idx, obfs_t *obfs) +{ + int bidx = idx, bofst = idx; + + frame_t *frame = (frame_t *)obfs->extra; + + while (bidx < buf->len) { + if (frame->len == 0) { + if (frame->idx >= 0 && frame->idx < 3 + && buf->data[bidx] != tls_data_header[frame->idx]) { + return OBFS_ERROR; + } else if (frame->idx >= 3 && frame->idx < 5) { + memcpy(frame->buf + frame->idx - 3, buf->data + bidx, 1); + } else if (frame->idx < 0) { + bofst++; + } + frame->idx++; + bidx++; + if (frame->idx == 5) { + frame->len = CT_NTOHS(*(uint16_t *)(frame->buf)); + frame->idx = 0; + } + continue; + } + + int left_len = buf->len - bidx; + + if (left_len > frame->len) { + memmove(buf->data + bofst, buf->data + bidx, frame->len); + bidx += frame->len; + bofst += frame->len; + frame->len = 0; + } else { + memmove(buf->data + bofst, buf->data + bidx, left_len); + bidx = buf->len; + bofst += left_len; + frame->len -= left_len; + } + } + + buf->len = bofst; + + return OBFS_OK; +} + + +static int +obfs_tls_request(buffer_t *buf, size_t cap, obfs_t *obfs) +{ + + if (obfs == NULL || obfs->obfs_stage < 0) return 0; + + static buffer_t tmp = { 0, 0, 0, NULL }; + + if (obfs->obfs_stage == 0) { + + size_t buf_len = buf->len; + size_t hello_len = sizeof(struct tls_client_hello); + size_t server_name_len = sizeof(struct tls_ext_server_name); + size_t host_len = strlen(obfs_tls->host); + size_t ticket_len = sizeof(struct tls_ext_session_ticket); + size_t other_ext_len = sizeof(struct tls_ext_others); + size_t tls_len = buf_len + hello_len + server_name_len + + host_len + ticket_len + other_ext_len; + + brealloc(&tmp, buf_len, cap); + brealloc(buf, tls_len, cap); + + memcpy(tmp.data, buf->data, buf_len); + + /* Client Hello Header */ + struct tls_client_hello *hello = (struct tls_client_hello *) buf->data; + memcpy(hello, &tls_client_hello_template, hello_len); + hello->len = CT_HTONS(tls_len - 5); + hello->handshake_len_2 = CT_HTONS(tls_len - 9); + hello->random_unix_time = CT_HTONL((uint32_t)time(NULL)); + rand_bytes(hello->random_bytes, 28); + rand_bytes(hello->session_id, 32); + hello->ext_len = CT_HTONS(server_name_len + host_len + ticket_len + buf_len + other_ext_len); + + /* Session Ticket */ + struct tls_ext_session_ticket *ticket = + (struct tls_ext_session_ticket *)((char *)hello + hello_len); + memcpy(ticket, &tls_ext_session_ticket_template, sizeof(struct tls_ext_session_ticket)); + ticket->session_ticket_ext_len = CT_HTONS(buf_len); + memcpy((char *)ticket + ticket_len, tmp.data, buf_len); + + /* SNI */ + struct tls_ext_server_name *server_name = + (struct tls_ext_server_name *)((char *)ticket + ticket_len + buf_len); + memcpy(server_name, &tls_ext_server_name_template, server_name_len); + server_name->ext_len = CT_HTONS(host_len + 3 + 2); + server_name->server_name_list_len = CT_HTONS(host_len + 3); + server_name->server_name_len = CT_HTONS(host_len); + memcpy((char *)server_name + server_name_len, obfs_tls->host, host_len); + + /* Other Extensions */ + memcpy((char *)server_name + server_name_len + host_len, &tls_ext_others_template, + other_ext_len); + + buf->len = tls_len; + + obfs->obfs_stage++; + + } else if (obfs->obfs_stage == 1) { + + obfs_app_data(buf, cap, obfs); + + } + + return buf->len; +} + +static int +obfs_tls_response(buffer_t *buf, size_t cap, obfs_t *obfs) +{ + if (obfs == NULL || obfs->obfs_stage < 0) return 0; + + static buffer_t tmp = { 0, 0, 0, NULL }; + + if (obfs->obfs_stage == 0) { + + size_t buf_len = buf->len; + size_t hello_len = sizeof(struct tls_server_hello); + size_t change_cipher_spec_len = sizeof(struct tls_change_cipher_spec); + size_t encrypted_handshake_len = sizeof(struct tls_encrypted_handshake); + size_t tls_len = hello_len + change_cipher_spec_len + encrypted_handshake_len + buf_len; + + brealloc(&tmp, buf_len, cap); + brealloc(buf, tls_len, cap); + + memcpy(tmp.data, buf->data, buf_len); + + /* Server Hello */ + memcpy(buf->data, &tls_server_hello_template, hello_len); + struct tls_server_hello *hello = (struct tls_server_hello *)buf->data; + hello->random_unix_time = CT_HTONL((uint32_t)time(NULL)); + rand_bytes(hello->random_bytes, 28); + if (obfs->buf != NULL) { + memcpy(hello->session_id, obfs->buf->data, 32); + } else { + rand_bytes(hello->session_id, 32); + } + + /* Change Cipher Spec */ + memcpy(buf->data + hello_len, &tls_change_cipher_spec_template, change_cipher_spec_len); + + /* Encrypted Handshake */ + memcpy(buf->data + hello_len + change_cipher_spec_len, &tls_encrypted_handshake_template, + encrypted_handshake_len); + memcpy(buf->data + hello_len + change_cipher_spec_len + encrypted_handshake_len, + tmp.data, buf_len); + + struct tls_encrypted_handshake *encrypted_handshake = + (struct tls_encrypted_handshake *)(buf->data + hello_len + change_cipher_spec_len); + encrypted_handshake->len = CT_HTONS(buf_len); + + buf->len = tls_len; + + obfs->obfs_stage++; + + } else if (obfs->obfs_stage == 1) { + + obfs_app_data(buf, cap, obfs); + + } + + return buf->len; +} + +static int +deobfs_tls_request(buffer_t *buf, size_t cap, obfs_t *obfs) +{ + if (obfs == NULL || obfs->deobfs_stage < 0) return 0; + + if (obfs->extra == NULL) { + obfs->extra = ss_malloc(sizeof(frame_t)); + memset(obfs->extra, 0, sizeof(frame_t)); + } + + if (obfs->buf == NULL) { + obfs->buf = (buffer_t *)ss_malloc(sizeof(buffer_t)); + balloc(obfs->buf, 32); + obfs->buf->len = 32; + } + + if (obfs->deobfs_stage == 0) { + + int len = buf->len; + + len -= sizeof(struct tls_client_hello); + if (len <= 0) return OBFS_NEED_MORE; + + struct tls_client_hello *hello = (struct tls_client_hello *) buf->data; + if (hello->content_type != tls_client_hello_template.content_type) + return OBFS_ERROR; + + size_t hello_len = CT_NTOHS(hello->len) + 5; + + memcpy(obfs->buf->data, hello->session_id, 32); + + len -= sizeof(struct tls_ext_session_ticket); + if (len <= 0) return OBFS_NEED_MORE; + + struct tls_ext_session_ticket *ticket = + (struct tls_ext_session_ticket *)(buf->data + sizeof(struct tls_client_hello)); + if (ticket->session_ticket_type != tls_ext_session_ticket_template.session_ticket_type) + return OBFS_ERROR; + + size_t ticket_len = CT_NTOHS(ticket->session_ticket_ext_len); + if (len < ticket_len) + return OBFS_NEED_MORE; + + memmove(buf->data, (char *)ticket + sizeof(struct tls_ext_session_ticket), ticket_len); + + if (buf->len > hello_len) { + memmove(buf->data + ticket_len, buf->data + hello_len, buf->len - hello_len); + } + + buf->len = ticket_len + buf->len - hello_len; + + obfs->deobfs_stage++; + + if (buf->len > ticket_len) { + return deobfs_app_data(buf, ticket_len, obfs); + } else { + ((frame_t*)obfs->extra)->idx = buf->len - ticket_len; + } + + } else if (obfs->deobfs_stage == 1) { + + return deobfs_app_data(buf, 0, obfs); + + } + + return 0; +} + +static int +deobfs_tls_response(buffer_t *buf, size_t cap, obfs_t *obfs) +{ + if (obfs == NULL || obfs->deobfs_stage < 0) return 0; + + if (obfs->extra == NULL) { + obfs->extra = ss_malloc(sizeof(frame_t)); + memset(obfs->extra, 0, sizeof(frame_t)); + } + + if (obfs->deobfs_stage == 0) { + + size_t hello_len = sizeof(struct tls_server_hello); + + char *data = buf->data; + int len = buf->len; + + len -= hello_len; + if (len <= 0) return OBFS_NEED_MORE; + + struct tls_server_hello *hello = (struct tls_server_hello*) data; + if (hello->content_type != tls_server_hello_template.content_type) + return OBFS_ERROR; + + size_t change_cipher_spec_len = sizeof(struct tls_change_cipher_spec); + size_t encrypted_handshake_len = sizeof(struct tls_encrypted_handshake); + + len -= change_cipher_spec_len + encrypted_handshake_len; + if (len <= 0) return OBFS_NEED_MORE; + + size_t tls_len = hello_len + change_cipher_spec_len + encrypted_handshake_len; + struct tls_encrypted_handshake *encrypted_handshake = + (struct tls_encrypted_handshake *)(buf->data + hello_len + change_cipher_spec_len); + size_t msg_len = CT_NTOHS(encrypted_handshake->len); + + memmove(buf->data, buf->data + tls_len, buf->len - tls_len); + + buf->len = buf->len - tls_len; + + obfs->deobfs_stage++; + + if (buf->len > msg_len) { + return deobfs_app_data(buf, msg_len, obfs); + } else { + ((frame_t*)obfs->extra)->idx = buf->len - msg_len; + } + + } else if (obfs->deobfs_stage == 1) { + + return deobfs_app_data(buf, 0, obfs); + + } + + + return 0; +} + +static int +check_tls_request(buffer_t *buf) +{ + char *data = buf->data; + int len = buf->len; + + if (len < 11) + return OBFS_NEED_MORE; + + return data[0] == 0x16 + && data[1] == 0x03 + && data[2] == 0x01 + && data[5] == 0x01 + && data[9] == 0x03 + && data[10] == 0x03; +} + +static void +disable_tls(obfs_t *obfs) +{ + obfs->obfs_stage = -1; + obfs->deobfs_stage = -1; +} + +static int +is_enable_tls(obfs_t *obfs) +{ + return obfs->obfs_stage == 0 && obfs->deobfs_stage == 0; +} diff --git a/src/obfs_tls.h b/src/obfs_tls.h new file mode 100644 index 000000000..ad78f17f5 --- /dev/null +++ b/src/obfs_tls.h @@ -0,0 +1,145 @@ +/* + * obfs_tls.h - Interfaces of tls obfuscating + * + * Copyright (C) 2013 - 2016, Max Lv + * + * This file is part of the shadowsocks-libev. + * + * shadowsocks-libev is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * shadowsocks-libev is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shadowsocks-libev; see the file COPYING. If not, see + * . + */ + +#ifndef OBFS_TLS_H +#define OBFS_TLS_H + +#include "obfs.h" + +#pragma pack(push) +#pragma pack(1) + +struct tls_client_hello { + char content_type; + short version; + short len; + + char handshake_type; + char handshake_len_1; + short handshake_len_2; + short handshake_version; + + int random_unix_time; + char random_bytes[28]; + char session_id_len; + char session_id[32]; + short cipher_suites_len; + char cipher_suites[56]; + char comp_methods_len; + char comp_methods[1]; + short ext_len; +}; + +struct tls_ext_server_name { + short ext_type; + short ext_len; + short server_name_list_len; + char server_name_type; + short server_name_len; + // char server_name[server_name_len]; +}; + +struct tls_ext_session_ticket { + short session_ticket_type; + short session_ticket_ext_len; + // char session_ticket[session_ticket_ext_len]; +}; + +struct tls_ext_others { + short ec_point_formats_ext_type; + short ec_point_formats_ext_len; + char ec_point_formats_len; + char ec_point_formats[3]; + + short elliptic_curves_type; + short elliptic_curves_ext_len; + short elliptic_curves_len; + char elliptic_curves[8]; + + short sig_algos_type; + short sig_algos_ext_len; + short sig_algos_len; + char sig_algos[30]; + + short encrypt_then_mac_type; + short encrypt_then_mac_ext_len; + + short extended_master_secret_type; + short extended_master_secret_ext_len; +}; + +struct tls_server_hello { + char content_type; + short version; + short len; + + char handshake_type; + char handshake_len_1; + short handshake_len_2; + short handshake_version; + + int random_unix_time; + char random_bytes[28]; + char session_id_len; + char session_id[32]; + short cipher_suite; + char comp_method; + short ext_len; + + short ext_renego_info_type; + short ext_renego_info_ext_len; + char ext_renego_info_len; + + short extended_master_secret_type; + short extended_master_secret_ext_len; + + short ec_point_formats_ext_type; + short ec_point_formats_ext_len; + char ec_point_formats_len; + char ec_point_formats[1]; +}; + +struct tls_change_cipher_spec { + char content_type; + short version; + short len; + char msg; +}; + +struct tls_encrypted_handshake { + char content_type; + short version; + short len; + // char msg[len]; +}; + +typedef struct frame { + short idx; + short len; + char buf[2]; +} frame_t; + +#pragma pack(pop) + +obfs_para_t *const obfs_tls; + +#endif diff --git a/src/redir.c b/src/redir.c index 9ec73e319..3ce899315 100644 --- a/src/redir.c +++ b/src/redir.c @@ -50,6 +50,8 @@ #include "http.h" #include "tls.h" +#include "obfs_http.h" +#include "obfs_tls.h" #include "netutils.h" #include "utils.h" #include "common.h" @@ -92,9 +94,11 @@ static int ipv6first = 0; static int mode = TCP_ONLY; static int auth = 0; #ifdef HAVE_SETRLIMIT -static int nofile = 0; +static int nofile = 0; #endif +static obfs_para_t *obfs_para = NULL; + int getdestaddr(int fd, struct sockaddr_storage *destaddr) { @@ -182,7 +186,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) server_t *server = server_recv_ctx->server; remote_t *remote = server->remote; - ssize_t r = recv(server->fd, remote->buf->array + remote->buf->len, + ssize_t r = recv(server->fd, remote->buf->data + remote->buf->len, BUF_SIZE - remote->buf->len, 0); if (r == 0) { @@ -240,10 +244,10 @@ server_recv_cb(EV_P_ ev_io *w, int revents) port = ntohs(((struct sockaddr_in *)&(server->destaddr))->sin_port); } if (port == http_protocol->default_port) - ret = http_protocol->parse_packet(remote->buf->array, + ret = http_protocol->parse_packet(remote->buf->data, remote->buf->len, &server->hostname); else if (port == tls_protocol->default_port) - ret = tls_protocol->parse_packet(remote->buf->array, + ret = tls_protocol->parse_packet(remote->buf->data, remote->buf->len, &server->hostname); if (ret > 0) { server->hostname_len = ret; @@ -263,7 +267,11 @@ server_recv_cb(EV_P_ ev_io *w, int revents) return; } - int s = send(remote->fd, remote->buf->array, remote->buf->len, 0); + if (obfs_para) { + obfs_para->obfs_request(remote->buf, BUF_SIZE, server->obfs); + } + + int s = send(remote->fd, remote->buf->data, remote->buf->len, 0); if (s == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { @@ -303,7 +311,7 @@ server_send_cb(EV_P_ ev_io *w, int revents) return; } else { // has data to send - ssize_t s = send(server->fd, server->buf->array + server->buf->idx, + ssize_t s = send(server->fd, server->buf->data + server->buf->idx, server->buf->len, 0); if (s == -1) { if (errno != EAGAIN && errno != EWOULDBLOCK) { @@ -351,7 +359,7 @@ remote_recv_cb(EV_P_ ev_io *w, int revents) ev_timer_again(EV_A_ & remote->recv_ctx->watcher); - ssize_t r = recv(remote->fd, server->buf->array, BUF_SIZE, 0); + ssize_t r = recv(remote->fd, server->buf->data, BUF_SIZE, 0); if (r == 0) { // connection closed @@ -373,6 +381,15 @@ remote_recv_cb(EV_P_ ev_io *w, int revents) server->buf->len = r; + if (obfs_para) { + if (obfs_para->deobfs_response(server->buf, BUF_SIZE, server->obfs)) { + LOGE("invalid obfuscating"); + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); + return; + } + } + int err = ss_decrypt(server->buf, server->d_ctx, BUF_SIZE); if (err) { LOGE("invalid password or cipher"); @@ -380,7 +397,7 @@ remote_recv_cb(EV_P_ ev_io *w, int revents) close_and_free_server(EV_A_ server); return; } - int s = send(server->fd, server->buf->array, server->buf->len, 0); + int s = send(server->fd, server->buf->data, server->buf->len, 0); if (s == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { @@ -442,43 +459,43 @@ remote_send_cb(EV_P_ ev_io *w, int revents) port = (((struct sockaddr_in *)&(server->destaddr))->sin_port); } - abuf->array[abuf->len++] = 3; // Type 3 is hostname - abuf->array[abuf->len++] = server->hostname_len; - memcpy(abuf->array + abuf->len, server->hostname, server->hostname_len); + abuf->data[abuf->len++] = 3; // Type 3 is hostname + abuf->data[abuf->len++] = server->hostname_len; + memcpy(abuf->data + abuf->len, server->hostname, server->hostname_len); abuf->len += server->hostname_len; - memcpy(abuf->array + abuf->len, &port, 2); + memcpy(abuf->data + abuf->len, &port, 2); } else if (AF_INET6 == server->destaddr.ss_family) { // IPv6 - abuf->array[abuf->len++] = 4; // Type 4 is IPv6 address + abuf->data[abuf->len++] = 4; // Type 4 is IPv6 address size_t in6_addr_len = sizeof(struct in6_addr); - memcpy(abuf->array + abuf->len, + memcpy(abuf->data + abuf->len, &(((struct sockaddr_in6 *)&(server->destaddr))->sin6_addr), in6_addr_len); abuf->len += in6_addr_len; - memcpy(abuf->array + abuf->len, + memcpy(abuf->data + abuf->len, &(((struct sockaddr_in6 *)&(server->destaddr))->sin6_port), 2); } else { // IPv4 - abuf->array[abuf->len++] = 1; // Type 1 is IPv4 address + abuf->data[abuf->len++] = 1; // Type 1 is IPv4 address size_t in_addr_len = sizeof(struct in_addr); - memcpy(abuf->array + abuf->len, + memcpy(abuf->data + abuf->len, &((struct sockaddr_in *)&(server->destaddr))->sin_addr, in_addr_len); abuf->len += in_addr_len; - memcpy(abuf->array + abuf->len, + memcpy(abuf->data + abuf->len, &((struct sockaddr_in *)&(server->destaddr))->sin_port, 2); } abuf->len += 2; if (auth) { - abuf->array[0] |= ONETIMEAUTH_FLAG; + abuf->data[0] |= ONETIMEAUTH_FLAG; ss_onetimeauth(abuf, server->e_ctx->evp.iv, BUF_SIZE); } brealloc(remote->buf, remote->buf->len + abuf->len, BUF_SIZE); - memmove(remote->buf->array + abuf->len, remote->buf->array, remote->buf->len); - memcpy(remote->buf->array, abuf->array, abuf->len); + memmove(remote->buf->data + abuf->len, remote->buf->data, remote->buf->len); + memcpy(remote->buf->data, abuf->data, abuf->len); remote->buf->len += abuf->len; bfree(abuf); @@ -490,6 +507,10 @@ remote_send_cb(EV_P_ ev_io *w, int revents) return; } + if (obfs_para) { + obfs_para->obfs_request(remote->buf, BUF_SIZE, server->obfs); + } + ev_io_start(EV_A_ & remote->recv_ctx->io); } else { ERROR("getpeername"); @@ -507,7 +528,7 @@ remote_send_cb(EV_P_ ev_io *w, int revents) return; } else { // has data to send - ssize_t s = send(remote->fd, remote->buf->array + remote->buf->idx, + ssize_t s = send(remote->fd, remote->buf->data + remote->buf->idx, remote->buf->len, 0); if (s == -1) { if (errno != EAGAIN && errno != EWOULDBLOCK) { @@ -538,9 +559,9 @@ new_remote(int fd, int timeout) remote_t *remote = ss_malloc(sizeof(remote_t)); memset(remote, 0, sizeof(remote_t)); - remote->recv_ctx = ss_malloc(sizeof(remote_ctx_t)); - remote->send_ctx = ss_malloc(sizeof(remote_ctx_t)); - remote->buf = ss_malloc(sizeof(buffer_t)); + remote->recv_ctx = ss_malloc(sizeof(remote_ctx_t)); + remote->send_ctx = ss_malloc(sizeof(remote_ctx_t)); + remote->buf = ss_malloc(sizeof(buffer_t)); balloc(remote->buf, BUF_SIZE); memset(remote->recv_ctx, 0, sizeof(remote_ctx_t)); memset(remote->send_ctx, 0, sizeof(remote_ctx_t)); @@ -563,18 +584,16 @@ new_remote(int fd, int timeout) static void free_remote(remote_t *remote) { - if (remote != NULL) { - if (remote->server != NULL) { - remote->server->remote = NULL; - } - if (remote->buf != NULL) { - bfree(remote->buf); - ss_free(remote->buf); - } - ss_free(remote->recv_ctx); - ss_free(remote->send_ctx); - ss_free(remote); + if (remote->server != NULL) { + remote->server->remote = NULL; } + if (remote->buf != NULL) { + bfree(remote->buf); + ss_free(remote->buf); + } + ss_free(remote->recv_ctx); + ss_free(remote->send_ctx); + ss_free(remote); } static void @@ -596,9 +615,9 @@ new_server(int fd, int method) server_t *server = ss_malloc(sizeof(server_t)); memset(server, 0, sizeof(server_t)); - server->recv_ctx = ss_malloc(sizeof(server_ctx_t)); - server->send_ctx = ss_malloc(sizeof(server_ctx_t)); - server->buf = ss_malloc(sizeof(buffer_t)); + server->recv_ctx = ss_malloc(sizeof(server_ctx_t)); + server->send_ctx = ss_malloc(sizeof(server_ctx_t)); + server->buf = ss_malloc(sizeof(buffer_t)); balloc(server->buf, BUF_SIZE); memset(server->recv_ctx, 0, sizeof(server_ctx_t)); memset(server->send_ctx, 0, sizeof(server_ctx_t)); @@ -611,6 +630,11 @@ new_server(int fd, int method) server->hostname = NULL; server->hostname_len = 0; + if (obfs_para != NULL) { + server->obfs = (obfs_t *)ss_malloc(sizeof(obfs_t)); + memset(server->obfs, 0, sizeof(obfs_t)); + } + if (method) { server->e_ctx = ss_malloc(sizeof(enc_ctx_t)); server->d_ctx = ss_malloc(sizeof(enc_ctx_t)); @@ -630,29 +654,33 @@ new_server(int fd, int method) static void free_server(server_t *server) { - if (server != NULL) { - if (server->hostname != NULL) { - ss_free(server->hostname); - } - if (server->remote != NULL) { - server->remote->server = NULL; - } - if (server->e_ctx != NULL) { - cipher_context_release(&server->e_ctx->evp); - ss_free(server->e_ctx); - } - if (server->d_ctx != NULL) { - cipher_context_release(&server->d_ctx->evp); - ss_free(server->d_ctx); - } - if (server->buf != NULL) { - bfree(server->buf); - ss_free(server->buf); - } - ss_free(server->recv_ctx); - ss_free(server->send_ctx); - ss_free(server); + if (server->obfs != NULL) { + bfree(server->obfs->buf); + if (server->obfs->extra != NULL) + ss_free(server->obfs->extra); + ss_free(server->obfs); + } + if (server->hostname != NULL) { + ss_free(server->hostname); } + if (server->remote != NULL) { + server->remote->server = NULL; + } + if (server->e_ctx != NULL) { + cipher_context_release(&server->e_ctx->evp); + ss_free(server->e_ctx); + } + if (server->d_ctx != NULL) { + cipher_context_release(&server->d_ctx->evp); + ss_free(server->d_ctx); + } + if (server->buf != NULL) { + bfree(server->buf); + ss_free(server->buf); + } + ss_free(server->recv_ctx); + ss_free(server->send_ctx); + ss_free(server); } static void @@ -775,6 +803,7 @@ main(int argc, char **argv) char *method = NULL; char *pid_path = NULL; char *conf_path = NULL; + char *obfs_host = NULL; int remote_num = 0; ss_addr_t remote_addr[MAX_REMOTE_NUM]; @@ -782,10 +811,12 @@ main(int argc, char **argv) int option_index = 0; static struct option long_options[] = { - { "mtu", required_argument, 0, 0 }, - { "mptcp", no_argument, 0, 0 }, - { "help", no_argument, 0, 0 }, - { 0, 0, 0, 0 } + { "mtu", required_argument, 0, 0 }, + { "mptcp", no_argument, 0, 0 }, + { "obfs", required_argument, 0, 0 }, + { "obfs-host", required_argument, 0, 0 }, + { "help", no_argument, 0, 0 }, + { 0, 0, 0, 0 } }; opterr = 0; @@ -803,6 +834,14 @@ main(int argc, char **argv) mptcp = 1; LOGI("enable multipath TCP"); } else if (option_index == 2) { + if (strcmp(optarg, obfs_http->name) == 0) + obfs_para = obfs_http; + else if (strcmp(optarg, obfs_tls->name) == 0) + obfs_para = obfs_tls; + LOGI("obfuscating enabled"); + } else if (option_index == 3) { + obfs_host = optarg; + } else if (option_index == 4) { usage(); exit(EXIT_SUCCESS); } @@ -911,6 +950,15 @@ main(int argc, char **argv) if (user == NULL) { user = conf->user; } + if (obfs_para == NULL && conf->obfs != NULL) { + if (strcmp(conf->obfs, obfs_http->name) == 0) + obfs_para = obfs_http; + else if (strcmp(conf->obfs, obfs_tls->name) == 0) + obfs_para = obfs_tls; + } + if (obfs_host == NULL) { + obfs_host = conf->obfs_host; + } if (auth == 0) { auth = conf->auth; } @@ -971,6 +1019,15 @@ main(int argc, char **argv) LOGI("onetime authentication enabled"); } + if (obfs_para) { + if (obfs_host != NULL) + obfs_para->host = obfs_host; + else + obfs_para->host = "cloudfront.net"; + obfs_para->port = atoi(remote_port); + LOGI("obfuscating arg: %s", obfs_host); + } + // ignore SIGPIPE signal(SIGPIPE, SIG_IGN); signal(SIGABRT, SIG_IGN); @@ -1035,11 +1092,11 @@ main(int argc, char **argv) LOGI("listening at %s:%s", local_addr, local_port); // setuid - if (user != NULL && ! run_as(user)) { + if (user != NULL && !run_as(user)) { FATAL("failed to switch user"); } - if (geteuid() == 0){ + if (geteuid() == 0) { LOGI("running from root user"); } diff --git a/src/redir.h b/src/redir.h index b3a9ecd59..d2592304f 100644 --- a/src/redir.h +++ b/src/redir.h @@ -45,6 +45,9 @@ typedef struct server_ctx { typedef struct server { int fd; + + obfs_t *obfs; + buffer_t *buf; struct sockaddr_storage destaddr; struct enc_ctx *e_ctx; diff --git a/src/server.c b/src/server.c index 0773552e6..892b8dd9e 100644 --- a/src/server.c +++ b/src/server.c @@ -61,6 +61,8 @@ #include "netutils.h" #include "utils.h" #include "acl.h" +#include "obfs_http.h" +#include "obfs_tls.h" #include "server.h" #ifndef EAGAIN @@ -113,8 +115,10 @@ static int acl = 0; static int mode = TCP_ONLY; static int auth = 0; static int ipv6first = 0; - static int fast_open = 0; + +static obfs_para_t *obfs_para = NULL; + #ifdef HAVE_SETRLIMIT static int nofile = 0; #endif @@ -246,7 +250,7 @@ is_header_complete(const buffer_t *buf) size_t header_len = 0; size_t buf_len = buf->len; - char atyp = buf->array[header_len]; + char atyp = buf->data[header_len]; // 1 byte for atyp header_len++; @@ -259,7 +263,7 @@ is_header_complete(const buffer_t *buf) // domain len + len of domain if (buf_len < header_len + 1) return 0; - uint8_t name_len = *(uint8_t *)(buf->array + header_len); + uint8_t name_len = *(uint8_t *)(buf->data + header_len); header_len += name_len + 1; } else if ((atyp & ADDRTYPE_MASK) == 4) { // IP V6 @@ -312,6 +316,7 @@ set_linger(int fd) so_linger.l_linger = 0; setsockopt(fd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof so_linger); } + #endif static void @@ -552,7 +557,7 @@ connect_to_remote(EV_P_ struct addrinfo *res, endpoints.sae_dstaddrlen = res->ai_addrlen; struct iovec iov; - iov.iov_base = server->buf->array + server->buf->idx; + iov.iov_base = server->buf->data + server->buf->idx; iov.iov_len = server->buf->len; size_t len; int s = connectx(sockfd, &endpoints, SAE_ASSOCID_ANY, CONNECT_DATA_IDEMPOTENT, @@ -561,7 +566,7 @@ connect_to_remote(EV_P_ struct addrinfo *res, s = len; } #else - ssize_t s = sendto(sockfd, server->buf->array + server->buf->idx, + ssize_t s = sendto(sockfd, server->buf->data + server->buf->idx, server->buf->len, MSG_FASTOPEN, res->ai_addr, res->ai_addrlen); #endif @@ -626,7 +631,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) return; } - ssize_t r = recv(server->fd, buf->array + len, BUF_SIZE - len, 0); + ssize_t r = recv(server->fd, buf->data + len, BUF_SIZE - len, 0); if (r == 0) { // connection closed @@ -660,12 +665,31 @@ server_recv_cb(EV_P_ ev_io *w, int revents) // handle incomplete header part 1 if (server->stage == STAGE_INIT) { buf->len += r; + + if (obfs_para && obfs_para->is_enable(server->obfs)) { + int ret = obfs_para->check_obfs(buf); + if (ret == OBFS_NEED_MORE) { + return; + } else if (ret) { + // obfs is enabled + ret = obfs_para->deobfs_request(buf, BUF_SIZE, server->obfs); + if (ret == OBFS_NEED_MORE) + return; + } else { + obfs_para->disable(server->obfs); + } + } + if (buf->len <= enc_get_iv_len() + 1) { // wait for more return; } } else { buf->len = r; + if (obfs_para) { + int ret = obfs_para->deobfs_request(buf, BUF_SIZE, server->obfs); + if (ret) LOGE("invalid obfuscating"); + } } int err = ss_decrypt(buf, server->d_ctx, BUF_SIZE); @@ -698,15 +722,15 @@ server_recv_cb(EV_P_ ev_io *w, int revents) if (server->stage == STAGE_HANDSHAKE) { size_t header_len = server->header_buf->len; brealloc(server->header_buf, server->buf->len + header_len, BUF_SIZE); - memcpy(server->header_buf->array + header_len, - server->buf->array, server->buf->len); + memcpy(server->header_buf->data + header_len, + server->buf->data, server->buf->len); server->header_buf->len = server->buf->len + header_len; int ret = is_header_complete(server->buf); if (ret == 1) { brealloc(server->buf, server->header_buf->len, BUF_SIZE); - memcpy(server->buf->array, server->header_buf->array, server->header_buf->len); + memcpy(server->buf->data, server->header_buf->data, server->header_buf->len); server->buf->len = server->header_buf->len; bfree(server->header_buf); ss_free(server->header_buf); @@ -729,7 +753,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) close_and_free_remote(EV_A_ remote); return; } - int s = send(remote->fd, remote->buf->array, remote->buf->len, 0); + int s = send(remote->fd, remote->buf->data, remote->buf->len, 0); if (s == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { // no data, wait for send @@ -780,7 +804,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) int offset = 0; int need_query = 0; - char atyp = server->buf->array[offset++]; + char atyp = server->buf->data[offset++]; char host[257] = { 0 }; uint16_t port = 0; struct addrinfo info; @@ -789,7 +813,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) memset(&storage, 0, sizeof(struct sockaddr_storage)); if (auth || (atyp & ONETIMEAUTH_FLAG)) { - size_t header_len = parse_header_len(atyp, server->buf->array, offset); + size_t header_len = parse_header_len(atyp, server->buf->data, offset); size_t len = server->buf->len; if (header_len == 0 || len < offset + header_len + ONETIMEAUTH_BYTES) { @@ -816,8 +840,8 @@ server_recv_cb(EV_P_ ev_io *w, int revents) size_t in_addr_len = sizeof(struct in_addr); addr->sin_family = AF_INET; if (server->buf->len >= in_addr_len + 3) { - addr->sin_addr = *(struct in_addr *)(server->buf->array + offset); - dns_ntop(AF_INET, (const void *)(server->buf->array + offset), + addr->sin_addr = *(struct in_addr *)(server->buf->data + offset); + dns_ntop(AF_INET, (const void *)(server->buf->data + offset), host, INET_ADDRSTRLEN); offset += in_addr_len; } else { @@ -826,7 +850,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) close_and_free_server(EV_A_ server); return; } - addr->sin_port = *(uint16_t *)(server->buf->array + offset); + addr->sin_port = *(uint16_t *)(server->buf->data + offset); info.ai_family = AF_INET; info.ai_socktype = SOCK_STREAM; info.ai_protocol = IPPROTO_TCP; @@ -834,9 +858,9 @@ server_recv_cb(EV_P_ ev_io *w, int revents) info.ai_addr = (struct sockaddr *)addr; } else if ((atyp & ADDRTYPE_MASK) == 3) { // Domain name - uint8_t name_len = *(uint8_t *)(server->buf->array + offset); + uint8_t name_len = *(uint8_t *)(server->buf->data + offset); if (name_len + 4 <= server->buf->len) { - memcpy(host, server->buf->array + offset + 1, name_len); + memcpy(host, server->buf->data + offset + 1, name_len); offset += name_len + 1; } else { LOGE("invalid name length: %d", name_len); @@ -857,7 +881,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) if (ip.version == 4) { struct sockaddr_in *addr = (struct sockaddr_in *)&storage; dns_pton(AF_INET, host, &(addr->sin_addr)); - addr->sin_port = *(uint16_t *)(server->buf->array + offset); + addr->sin_port = *(uint16_t *)(server->buf->data + offset); addr->sin_family = AF_INET; info.ai_family = AF_INET; info.ai_addrlen = sizeof(struct sockaddr_in); @@ -865,7 +889,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) } else if (ip.version == 6) { struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&storage; dns_pton(AF_INET6, host, &(addr->sin6_addr)); - addr->sin6_port = *(uint16_t *)(server->buf->array + offset); + addr->sin6_port = *(uint16_t *)(server->buf->data + offset); addr->sin6_family = AF_INET6; info.ai_family = AF_INET6; info.ai_addrlen = sizeof(struct sockaddr_in6); @@ -886,8 +910,8 @@ server_recv_cb(EV_P_ ev_io *w, int revents) size_t in6_addr_len = sizeof(struct in6_addr); addr->sin6_family = AF_INET6; if (server->buf->len >= in6_addr_len + 3) { - addr->sin6_addr = *(struct in6_addr *)(server->buf->array + offset); - dns_ntop(AF_INET6, (const void *)(server->buf->array + offset), + addr->sin6_addr = *(struct in6_addr *)(server->buf->data + offset); + dns_ntop(AF_INET6, (const void *)(server->buf->data + offset), host, INET6_ADDRSTRLEN); offset += in6_addr_len; } else { @@ -896,7 +920,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) close_and_free_server(EV_A_ server); return; } - addr->sin6_port = *(uint16_t *)(server->buf->array + offset); + addr->sin6_port = *(uint16_t *)(server->buf->data + offset); info.ai_family = AF_INET6; info.ai_socktype = SOCK_STREAM; info.ai_protocol = IPPROTO_TCP; @@ -911,7 +935,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) return; } - port = (*(uint16_t *)(server->buf->array + offset)); + port = (*(uint16_t *)(server->buf->data + offset)); offset += 2; @@ -925,7 +949,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) return; } else { server->buf->len -= offset; - memmove(server->buf->array, server->buf->array + offset, server->buf->len); + memmove(server->buf->data, server->buf->data + offset, server->buf->len); } if (verbose) { @@ -943,7 +967,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) } if (!need_query) { - remote_t *remote = connect_to_remote(EV_A_ &info, server); + remote_t *remote = connect_to_remote(EV_A_ & info, server); if (remote == NULL) { LOGE("connect error"); @@ -955,7 +979,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) // XXX: should handle buffer carefully if (server->buf->len > 0) { - memcpy(remote->buf->array, server->buf->array, server->buf->len); + memcpy(remote->buf->data, server->buf->data, server->buf->len); remote->buf->len = server->buf->len; remote->buf->idx = 0; server->buf->len = 0; @@ -1008,7 +1032,7 @@ server_send_cb(EV_P_ ev_io *w, int revents) return; } else { // has data to send - ssize_t s = send(server->fd, server->buf->array + server->buf->idx, + ssize_t s = send(server->fd, server->buf->data + server->buf->idx, server->buf->len, 0); if (s == -1) { if (errno != EAGAIN && errno != EWOULDBLOCK) { @@ -1114,7 +1138,7 @@ server_resolve_cb(struct sockaddr *addr, void *data) info.ai_addrlen = sizeof(struct sockaddr_in6); } - remote_t *remote = connect_to_remote(EV_A_ &info, server); + remote_t *remote = connect_to_remote(EV_A_ & info, server); if (remote == NULL) { close_and_free_server(EV_A_ server); @@ -1124,7 +1148,7 @@ server_resolve_cb(struct sockaddr *addr, void *data) // XXX: should handle buffer carefully if (server->buf->len > 0) { - memcpy(remote->buf->array, server->buf->array + server->buf->idx, + memcpy(remote->buf->data, server->buf->data + server->buf->idx, server->buf->len); remote->buf->len = server->buf->len; remote->buf->idx = 0; @@ -1153,7 +1177,7 @@ remote_recv_cb(EV_P_ ev_io *w, int revents) ev_timer_again(EV_A_ & server->recv_ctx->watcher); - ssize_t r = recv(remote->fd, server->buf->array, BUF_SIZE, 0); + ssize_t r = recv(remote->fd, server->buf->data, BUF_SIZE, 0); if (r == 0) { // connection closed @@ -1188,7 +1212,11 @@ remote_recv_cb(EV_P_ ev_io *w, int revents) return; } - int s = send(server->fd, server->buf->array, server->buf->len, 0); + if (obfs_para) { + obfs_para->obfs_response(server->buf, BUF_SIZE, server->obfs); + } + + int s = send(server->fd, server->buf->data, server->buf->len, 0); if (s == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { @@ -1271,7 +1299,7 @@ remote_send_cb(EV_P_ ev_io *w, int revents) return; } else { // has data to send - ssize_t s = send(remote->fd, remote->buf->array + remote->buf->idx, + ssize_t s = send(remote->fd, remote->buf->data + remote->buf->idx, remote->buf->len, 0); if (s == -1) { if (errno != EAGAIN && errno != EWOULDBLOCK) { @@ -1317,9 +1345,9 @@ new_remote(int fd) remote_t *remote = ss_malloc(sizeof(remote_t)); memset(remote, 0, sizeof(remote_t)); - remote->recv_ctx = ss_malloc(sizeof(remote_ctx_t)); - remote->send_ctx = ss_malloc(sizeof(remote_ctx_t)); - remote->buf = ss_malloc(sizeof(buffer_t)); + remote->recv_ctx = ss_malloc(sizeof(remote_ctx_t)); + remote->send_ctx = ss_malloc(sizeof(remote_ctx_t)); + remote->buf = ss_malloc(sizeof(buffer_t)); balloc(remote->buf, BUF_SIZE); memset(remote->recv_ctx, 0, sizeof(remote_ctx_t)); memset(remote->send_ctx, 0, sizeof(remote_ctx_t)); @@ -1378,10 +1406,10 @@ new_server(int fd, listen_ctx_t *listener) memset(server, 0, sizeof(server_t)); - server->recv_ctx = ss_malloc(sizeof(server_ctx_t)); - server->send_ctx = ss_malloc(sizeof(server_ctx_t)); - server->buf = ss_malloc(sizeof(buffer_t)); - server->header_buf = ss_malloc(sizeof(buffer_t)); + server->recv_ctx = ss_malloc(sizeof(server_ctx_t)); + server->send_ctx = ss_malloc(sizeof(server_ctx_t)); + server->buf = ss_malloc(sizeof(buffer_t)); + server->header_buf = ss_malloc(sizeof(buffer_t)); memset(server->recv_ctx, 0, sizeof(server_ctx_t)); memset(server->send_ctx, 0, sizeof(server_ctx_t)); balloc(server->buf, BUF_SIZE); @@ -1396,6 +1424,11 @@ new_server(int fd, listen_ctx_t *listener) server->listen_ctx = listener; server->remote = NULL; + if (obfs_para != NULL) { + server->obfs = (obfs_t *)ss_malloc(sizeof(obfs_t)); + memset(server->obfs, 0, sizeof(obfs_t)); + } + if (listener->method) { server->e_ctx = ss_malloc(sizeof(enc_ctx_t)); server->d_ctx = ss_malloc(sizeof(enc_ctx_t)); @@ -1429,6 +1462,12 @@ free_server(server_t *server) { cork_dllist_remove(&server->entries); + if (server->obfs != NULL) { + bfree(server->obfs->buf); + if (server->obfs->extra != NULL) + ss_free(server->obfs->extra); + ss_free(server->obfs); + } if (server->chunk != NULL) { if (server->chunk->buf != NULL) { bfree(server->chunk->buf); @@ -1571,6 +1610,7 @@ main(int argc, char **argv) { "manager-address", required_argument, 0, 0 }, { "mtu", required_argument, 0, 0 }, { "help", no_argument, 0, 0 }, + { "obfs", required_argument, 0, 0 }, #ifdef __linux__ { "mptcp", no_argument, 0, 0 }, { "firewall", no_argument, 0, 0 }, @@ -1600,9 +1640,15 @@ main(int argc, char **argv) usage(); exit(EXIT_SUCCESS); } else if (option_index == 5) { + if (strcmp(optarg, obfs_http->name) == 0) + obfs_para = obfs_http; + else if (strcmp(optarg, obfs_tls->name) == 0) + obfs_para = obfs_tls; + LOGI("obfuscating enabled"); + } else if (option_index == 6) { mptcp = 1; LOGI("enable multipath TCP"); - } else if (option_index == 6) { + } else if (option_index == 7) { firewall = 1; LOGI("enable firewall rules"); } @@ -1709,6 +1755,12 @@ main(int argc, char **argv) if (user == NULL) { user = conf->user; } + if (obfs_para == NULL && conf->obfs != NULL) { + if (strcmp(conf->obfs, obfs_http->name) == 0) + obfs_para = obfs_http; + else if (strcmp(conf->obfs, obfs_tls->name) == 0) + obfs_para = obfs_tls; + } if (auth == 0) { auth = conf->auth; } @@ -1890,12 +1942,12 @@ main(int argc, char **argv) ev_timer_start(EV_DEFAULT, &block_list_watcher); // setuid - if (user != NULL && ! run_as(user)) { + if (user != NULL && !run_as(user)) { FATAL("failed to switch user"); } #ifndef __MINGW32__ - if (geteuid() == 0){ + if (geteuid() == 0) { LOGI("running from root user"); } else if (firewall) { LOGE("firewall setup requires running from root user"); diff --git a/src/server.h b/src/server.h index 4388571d2..db5a2ba7e 100644 --- a/src/server.h +++ b/src/server.h @@ -52,10 +52,13 @@ typedef struct server_ctx { typedef struct server { int fd; int stage; + int auth; + + obfs_t *obfs; + buffer_t *buf; buffer_t *header_buf; - int auth; struct chunk *chunk; struct enc_ctx *e_ctx; diff --git a/src/tunnel.c b/src/tunnel.c index 1c694dddc..bc89d4428 100644 --- a/src/tunnel.c +++ b/src/tunnel.c @@ -57,6 +57,8 @@ #include "netutils.h" #include "utils.h" +#include "obfs_http.h" +#include "obfs_tls.h" #include "tunnel.h" #ifndef EAGAIN @@ -100,6 +102,8 @@ static int auth = 0; static int nofile = 0; #endif +static obfs_para_t *obfs_para = NULL; + #ifndef __MINGW32__ static int setnonblocking(int fd) @@ -179,7 +183,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) return; } - ssize_t r = recv(server->fd, remote->buf->array, BUF_SIZE, 0); + ssize_t r = recv(server->fd, remote->buf->data, BUF_SIZE, 0); if (r == 0) { // connection closed @@ -214,7 +218,11 @@ server_recv_cb(EV_P_ ev_io *w, int revents) return; } - int s = send(remote->fd, remote->buf->array, remote->buf->len, 0); + if (obfs_para) { + obfs_para->obfs_request(remote->buf, BUF_SIZE, server->obfs); + } + + int s = send(remote->fd, remote->buf->data, remote->buf->len, 0); if (s == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { @@ -251,7 +259,7 @@ server_send_cb(EV_P_ ev_io *w, int revents) return; } else { // has data to send - ssize_t s = send(server->fd, server->buf->array + server->buf->idx, + ssize_t s = send(server->fd, server->buf->data + server->buf->idx, server->buf->len, 0); if (s == -1) { if (errno != EAGAIN && errno != EWOULDBLOCK) { @@ -307,7 +315,7 @@ remote_recv_cb(EV_P_ ev_io *w, int revents) remote_t *remote = remote_recv_ctx->remote; server_t *server = remote->server; - ssize_t r = recv(remote->fd, server->buf->array, BUF_SIZE, 0); + ssize_t r = recv(remote->fd, server->buf->data, BUF_SIZE, 0); if (r == 0) { // connection closed @@ -329,6 +337,15 @@ remote_recv_cb(EV_P_ ev_io *w, int revents) server->buf->len = r; + if (obfs_para) { + if (obfs_para->deobfs_response(server->buf, BUF_SIZE, server->obfs)) { + LOGE("invalid obfuscating"); + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); + return; + } + } + int err = ss_decrypt(server->buf, server->d_ctx, BUF_SIZE); if (err) { @@ -338,7 +355,7 @@ remote_recv_cb(EV_P_ ev_io *w, int revents) return; } - int s = send(server->fd, server->buf->array, server->buf->len, 0); + int s = send(server->fd, server->buf->data, server->buf->len, 0); if (s == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { @@ -401,8 +418,8 @@ remote_send_cb(EV_P_ ev_io *w, int revents) if (dns_pton(AF_INET, sa->host, &host) == -1) { FATAL("IP parser error"); } - abuf->array[abuf->len++] = 1; - memcpy(abuf->array + abuf->len, &host, host_len); + abuf->data[abuf->len++] = 1; + memcpy(abuf->data + abuf->len, &host, host_len); abuf->len += host_len; } else if (ip.version == 6) { // send as IPv6 @@ -413,8 +430,8 @@ remote_send_cb(EV_P_ ev_io *w, int revents) if (dns_pton(AF_INET6, sa->host, &host) == -1) { FATAL("IP parser error"); } - abuf->array[abuf->len++] = 4; - memcpy(abuf->array + abuf->len, &host, host_len); + abuf->data[abuf->len++] = 4; + memcpy(abuf->data + abuf->len, &host, host_len); abuf->len += host_len; } else { FATAL("IP parser error"); @@ -423,22 +440,23 @@ remote_send_cb(EV_P_ ev_io *w, int revents) // send as domain int host_len = strlen(sa->host); - abuf->array[abuf->len++] = 3; - abuf->array[abuf->len++] = host_len; - memcpy(abuf->array + abuf->len, sa->host, host_len); + abuf->data[abuf->len++] = 3; + abuf->data[abuf->len++] = host_len; + memcpy(abuf->data + abuf->len, sa->host, host_len); abuf->len += host_len; } uint16_t port = htons(atoi(sa->port)); - memcpy(abuf->array + abuf->len, &port, 2); + memcpy(abuf->data + abuf->len, &port, 2); abuf->len += 2; if (auth) { - abuf->array[0] |= ONETIMEAUTH_FLAG; + abuf->data[0] |= ONETIMEAUTH_FLAG; ss_onetimeauth(abuf, server->e_ctx->evp.iv, BUF_SIZE); } int err = ss_encrypt(abuf, server->e_ctx, BUF_SIZE); + if (err) { bfree(abuf); LOGE("invalid password or cipher"); @@ -447,7 +465,11 @@ remote_send_cb(EV_P_ ev_io *w, int revents) return; } - int s = send(remote->fd, abuf->array, abuf->len, 0); + if (obfs_para) { + obfs_para->obfs_request(abuf, BUF_SIZE, server->obfs); + } + + int s = send(remote->fd, abuf->data, abuf->len, 0); bfree(abuf); @@ -477,7 +499,7 @@ remote_send_cb(EV_P_ ev_io *w, int revents) return; } else { // has data to send - ssize_t s = send(remote->fd, remote->buf->array + remote->buf->idx, + ssize_t s = send(remote->fd, remote->buf->data + remote->buf->idx, remote->buf->len, 0); if (s == -1) { if (errno != EAGAIN && errno != EWOULDBLOCK) { @@ -510,9 +532,9 @@ new_remote(int fd, int timeout) memset(remote, 0, sizeof(remote_t)); - remote->buf = ss_malloc(sizeof(buffer_t)); - remote->recv_ctx = ss_malloc(sizeof(remote_ctx_t)); - remote->send_ctx = ss_malloc(sizeof(remote_ctx_t)); + remote->buf = ss_malloc(sizeof(buffer_t)); + remote->recv_ctx = ss_malloc(sizeof(remote_ctx_t)); + remote->send_ctx = ss_malloc(sizeof(remote_ctx_t)); balloc(remote->buf, BUF_SIZE); memset(remote->recv_ctx, 0, sizeof(remote_ctx_t)); memset(remote->send_ctx, 0, sizeof(remote_ctx_t)); @@ -533,18 +555,16 @@ new_remote(int fd, int timeout) static void free_remote(remote_t *remote) { - if (remote != NULL) { - if (remote->server != NULL) { - remote->server->remote = NULL; - } - if (remote->buf) { - bfree(remote->buf); - ss_free(remote->buf); - } - ss_free(remote->recv_ctx); - ss_free(remote->send_ctx); - ss_free(remote); + if (remote->server != NULL) { + remote->server->remote = NULL; + } + if (remote->buf) { + bfree(remote->buf); + ss_free(remote->buf); } + ss_free(remote->recv_ctx); + ss_free(remote->send_ctx); + ss_free(remote); } static void @@ -565,9 +585,9 @@ new_server(int fd, int method) server_t *server = ss_malloc(sizeof(server_t)); memset(server, 0, sizeof(server_t)); - server->buf = ss_malloc(sizeof(buffer_t)); - server->recv_ctx = ss_malloc(sizeof(server_ctx_t)); - server->send_ctx = ss_malloc(sizeof(server_ctx_t)); + server->buf = ss_malloc(sizeof(buffer_t)); + server->recv_ctx = ss_malloc(sizeof(server_ctx_t)); + server->send_ctx = ss_malloc(sizeof(server_ctx_t)); balloc(server->buf, BUF_SIZE); memset(server->recv_ctx, 0, sizeof(server_ctx_t)); memset(server->send_ctx, 0, sizeof(server_ctx_t)); @@ -577,6 +597,11 @@ new_server(int fd, int method) server->send_ctx->server = server; server->send_ctx->connected = 0; + if (obfs_para != NULL) { + server->obfs = (obfs_t *)ss_malloc(sizeof(obfs_t)); + memset(server->obfs, 0, sizeof(obfs_t)); + } + if (method) { server->e_ctx = ss_malloc(sizeof(struct enc_ctx)); server->d_ctx = ss_malloc(sizeof(struct enc_ctx)); @@ -596,26 +621,30 @@ new_server(int fd, int method) static void free_server(server_t *server) { - if (server != NULL) { - if (server->remote != NULL) { - server->remote->server = NULL; - } - if (server->e_ctx != NULL) { - cipher_context_release(&server->e_ctx->evp); - ss_free(server->e_ctx); - } - if (server->d_ctx != NULL) { - cipher_context_release(&server->d_ctx->evp); - ss_free(server->d_ctx); - } - if (server->buf) { - bfree(server->buf); - ss_free(server->buf); - } - ss_free(server->recv_ctx); - ss_free(server->send_ctx); - ss_free(server); + if (server->obfs != NULL) { + bfree(server->obfs->buf); + if (server->obfs->extra != NULL) + ss_free(server->obfs->extra); + ss_free(server->obfs); + } + if (server->remote != NULL) { + server->remote->server = NULL; } + if (server->e_ctx != NULL) { + cipher_context_release(&server->e_ctx->evp); + ss_free(server->e_ctx); + } + if (server->d_ctx != NULL) { + cipher_context_release(&server->d_ctx->evp); + ss_free(server->d_ctx); + } + if (server->buf) { + bfree(server->buf); + ss_free(server->buf); + } + ss_free(server->recv_ctx); + ss_free(server->send_ctx); + ss_free(server); } static void @@ -738,6 +767,7 @@ main(int argc, char **argv) char *pid_path = NULL; char *conf_path = NULL; char *iface = NULL; + char *obfs_host = NULL; int remote_num = 0; ss_addr_t remote_addr[MAX_REMOTE_NUM]; @@ -748,10 +778,12 @@ main(int argc, char **argv) int option_index = 0; static struct option long_options[] = { - { "mtu", required_argument, 0, 0 }, - { "mptcp", no_argument, 0, 0 }, - { "help", no_argument, 0, 0 }, - { 0, 0, 0, 0 } + { "mtu", required_argument, 0, 0 }, + { "mptcp", no_argument, 0, 0 }, + { "obfs", required_argument, 0, 0 }, + { "obfs-host", required_argument, 0, 0 }, + { "help", no_argument, 0, 0 }, + { 0, 0, 0, 0 } }; opterr = 0; @@ -774,6 +806,14 @@ main(int argc, char **argv) mptcp = 1; LOGI("enable multipath TCP"); } else if (option_index == 2) { + if (strcmp(optarg, obfs_http->name) == 0) + obfs_para = obfs_http; + else if (strcmp(optarg, obfs_tls->name) == 0) + obfs_para = obfs_tls; + LOGI("obfuscating enabled"); + } else if (option_index == 3) { + obfs_host = optarg; + } else if (option_index == 4) { usage(); exit(EXIT_SUCCESS); } @@ -896,6 +936,15 @@ main(int argc, char **argv) if (user == NULL) { user = conf->user; } + if (obfs_para == NULL && conf->obfs != NULL) { + if (strcmp(conf->obfs, obfs_http->name) == 0) + obfs_para = obfs_http; + else if (strcmp(conf->obfs, obfs_tls->name) == 0) + obfs_para = obfs_tls; + } + if (obfs_host == NULL) { + obfs_host = conf->obfs_host; + } if (auth == 0) { auth = conf->auth; } @@ -962,6 +1011,15 @@ main(int argc, char **argv) LOGI("onetime authentication enabled"); } + if (obfs_para) { + if (obfs_host != NULL) + obfs_para->host = obfs_host; + else + obfs_para->host = "cloudfront.net"; + obfs_para->port = atoi(remote_port); + LOGI("obfuscating arg: %s", obfs_host); + } + // parse tunnel addr parse_addr(tunnel_addr_str, &tunnel_addr); @@ -1041,12 +1099,12 @@ main(int argc, char **argv) LOGI("listening at %s:%s", local_addr, local_port); // setuid - if (user != NULL && ! run_as(user)) { + if (user != NULL && !run_as(user)) { FATAL("failed to switch user"); } #ifndef __MINGW32__ - if (geteuid() == 0){ + if (geteuid() == 0) { LOGI("running from root user"); } #endif diff --git a/src/tunnel.h b/src/tunnel.h index 42dd95860..3b347f01a 100644 --- a/src/tunnel.h +++ b/src/tunnel.h @@ -49,6 +49,9 @@ typedef struct server_ctx { typedef struct server { int fd; + + obfs_t *obfs; + buffer_t *buf; struct enc_ctx *e_ctx; struct enc_ctx *d_ctx; diff --git a/src/udprelay.c b/src/udprelay.c index 0ccf276a2..9246aa81c 100644 --- a/src/udprelay.c +++ b/src/udprelay.c @@ -512,7 +512,7 @@ new_query_ctx(char *buf, size_t len) memset(ctx, 0, sizeof(struct query_ctx)); ctx->buf = ss_malloc(sizeof(buffer_t)); balloc(ctx->buf, len); - memcpy(ctx->buf->array, buf, len); + memcpy(ctx->buf->data, buf, len); ctx->buf->len = len; return ctx; } @@ -623,7 +623,7 @@ query_resolve_cb(struct sockaddr *addr, void *data) memcpy(&remote_ctx->dst_addr, addr, sizeof(struct sockaddr_storage)); size_t addr_len = get_sockaddr_len(addr); - int s = sendto(remote_ctx->fd, query_ctx->buf->array, query_ctx->buf->len, + int s = sendto(remote_ctx->fd, query_ctx->buf->data, query_ctx->buf->len, 0, addr, addr_len); if (s == -1) { @@ -675,7 +675,7 @@ remote_recv_cb(EV_P_ ev_io *w, int revents) balloc(buf, buf_size); // recv - r = recvfrom(remote_ctx->fd, buf->array, buf_size, 0, (struct sockaddr *)&src_addr, &src_addr_len); + r = recvfrom(remote_ctx->fd, buf->data, buf_size, 0, (struct sockaddr *)&src_addr, &src_addr_len); if (r == -1) { // error on recv @@ -699,14 +699,14 @@ remote_recv_cb(EV_P_ ev_io *w, int revents) #ifdef MODULE_REDIR struct sockaddr_storage dst_addr; memset(&dst_addr, 0, sizeof(struct sockaddr_storage)); - int len = parse_udprealy_header(buf->array, buf->len, NULL, NULL, &dst_addr); + int len = parse_udprealy_header(buf->data, buf->len, NULL, NULL, &dst_addr); if (dst_addr.ss_family != AF_INET && dst_addr.ss_family != AF_INET6) { LOGI("[udp] ss-redir does not support domain name"); goto CLEAN_UP; } #else - int len = parse_udprealy_header(buf->array, buf->len, NULL, NULL, NULL); + int len = parse_udprealy_header(buf->data, buf->len, NULL, NULL, NULL); #endif if (len == 0) { @@ -720,15 +720,15 @@ remote_recv_cb(EV_P_ ev_io *w, int revents) #if defined(MODULE_TUNNEL) || defined(MODULE_REDIR) // Construct packet buf->len -= len; - memmove(buf->array, buf->array + len, buf->len); + memmove(buf->data, buf->data + len, buf->len); #else #ifdef ANDROID rx += buf->len; #endif // Construct packet brealloc(buf, buf->len + 3, buf_size); - memmove(buf->array + 3, buf->array, buf->len); - memset(buf->array, 0, 3); + memmove(buf->data + 3, buf->data, buf->len); + memset(buf->data, 0, 3); buf->len += 3; #endif @@ -749,8 +749,8 @@ remote_recv_cb(EV_P_ ev_io *w, int revents) // Construct packet brealloc(buf, buf->len + addr_header_len, buf_size); - memmove(buf->array + addr_header_len, buf->array, buf->len); - memcpy(buf->array, addr_header, addr_header_len); + memmove(buf->data + addr_header_len, buf->data, buf->len); + memcpy(buf->data, addr_header, addr_header_len); buf->len += addr_header_len; int err = ss_encrypt_all(buf, server_ctx->method, 0, buf_size); @@ -799,7 +799,7 @@ remote_recv_cb(EV_P_ ev_io *w, int revents) goto CLEAN_UP; } - int s = sendto(src_fd, buf->array, buf->len, 0, + int s = sendto(src_fd, buf->data, buf->len, 0, (struct sockaddr *)&remote_ctx->src_addr, remote_src_addr_len); if (s == -1) { ERROR("[udp] remote_recv_sendto"); @@ -810,7 +810,7 @@ remote_recv_cb(EV_P_ ev_io *w, int revents) #else - int s = sendto(server_ctx->fd, buf->array, buf->len, 0, + int s = sendto(server_ctx->fd, buf->data, buf->len, 0, (struct sockaddr *)&remote_ctx->src_addr, remote_src_addr_len); if (s == -1) { ERROR("[udp] remote_recv_sendto"); @@ -855,7 +855,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) msg.msg_control = control_buffer; msg.msg_controllen = sizeof(control_buffer); - iov[0].iov_base = buf->array; + iov[0].iov_base = buf->data; iov[0].iov_len = buf_size; msg.msg_iov = iov; msg.msg_iovlen = 1; @@ -877,7 +877,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) src_addr_len = msg.msg_namelen; #else ssize_t r; - r = recvfrom(server_ctx->fd, buf->array, buf_size, + r = recvfrom(server_ctx->fd, buf->data, buf_size, 0, (struct sockaddr *)&src_addr, &src_addr_len); if (r == -1) { @@ -912,7 +912,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) #ifdef ANDROID tx += buf->len; #endif - uint8_t frag = *(uint8_t *)(buf->array + 2); + uint8_t frag = *(uint8_t *)(buf->data + 2); offset += 3; #endif #endif @@ -972,8 +972,8 @@ server_recv_cb(EV_P_ ev_io *w, int revents) // reconstruct the buffer brealloc(buf, buf->len + addr_header_len, buf_size); - memmove(buf->array + addr_header_len, buf->array, buf->len); - memcpy(buf->array, addr_header, addr_header_len); + memmove(buf->data + addr_header_len, buf->data, buf->len); + memcpy(buf->data, addr_header, addr_header_len); buf->len += addr_header_len; #elif MODULE_TUNNEL @@ -1028,8 +1028,8 @@ server_recv_cb(EV_P_ ev_io *w, int revents) // reconstruct the buffer brealloc(buf, buf->len + addr_header_len, buf_size); - memmove(buf->array + addr_header_len, buf->array, buf->len); - memcpy(buf->array, addr_header, addr_header_len); + memmove(buf->data + addr_header_len, buf->data, buf->len); + memcpy(buf->data, addr_header, addr_header_len); buf->len += addr_header_len; #else @@ -1039,14 +1039,14 @@ server_recv_cb(EV_P_ ev_io *w, int revents) struct sockaddr_storage dst_addr; memset(&dst_addr, 0, sizeof(struct sockaddr_storage)); - int addr_header_len = parse_udprealy_header(buf->array + offset, buf->len - offset, + int addr_header_len = parse_udprealy_header(buf->data + offset, buf->len - offset, host, port, &dst_addr); if (addr_header_len == 0) { // error in parse header goto CLEAN_UP; } - char *addr_header = buf->array + offset; + char *addr_header = buf->data + offset; #endif #ifdef MODULE_LOCAL @@ -1162,11 +1162,11 @@ server_recv_cb(EV_P_ ev_io *w, int revents) if (offset > 0) { buf->len -= offset; - memmove(buf->array, buf->array + offset, buf->len); + memmove(buf->data, buf->data + offset, buf->len); } if (server_ctx->auth) { - buf->array[0] |= ONETIMEAUTH_FLAG; + buf->data[0] |= ONETIMEAUTH_FLAG; } int err = ss_encrypt_all(buf, server_ctx->method, server_ctx->auth, buf_size); @@ -1181,7 +1181,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) goto CLEAN_UP; } - int s = sendto(remote_ctx->fd, buf->array, buf->len, 0, remote_addr, remote_addr_len); + int s = sendto(remote_ctx->fd, buf->data, buf->len, 0, remote_addr, remote_addr_len); if (s == -1) { ERROR("[udp] server_recv_sendto"); @@ -1245,7 +1245,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) if (remote_ctx != NULL && !need_query) { size_t addr_len = get_sockaddr_len((struct sockaddr *)&dst_addr); - int s = sendto(remote_ctx->fd, buf->array + addr_header_len, + int s = sendto(remote_ctx->fd, buf->data + addr_header_len, buf->len - addr_header_len, 0, (struct sockaddr *)&dst_addr, addr_len); @@ -1272,7 +1272,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; - struct query_ctx *query_ctx = new_query_ctx(buf->array + addr_header_len, + struct query_ctx *query_ctx = new_query_ctx(buf->data + addr_header_len, buf->len - addr_header_len); query_ctx->server_ctx = server_ctx; query_ctx->addr_header_len = addr_header_len; diff --git a/src/utils.c b/src/utils.c index 14a60c7f3..c7fc65137 100644 --- a/src/utils.c +++ b/src/utils.c @@ -358,6 +358,12 @@ usage() printf( " [--firewall] Setup firewall rules for auto blocking.\n"); #endif +#endif + printf( + " [--obfs ] Enable obfuscating: HTTP or TLS (Experimental).\n"); +#ifndef MODULE_REMOTE + printf( + " [--obfs-host ] Hostname for obfuscating (Experimental).\n"); #endif printf("\n"); printf( diff --git a/src/utils.h b/src/utils.h index 0fb7f5a2c..8fc0406d5 100644 --- a/src/utils.h +++ b/src/utils.h @@ -229,4 +229,27 @@ void *ss_realloc(void *ptr, size_t new_size); ptr = NULL; \ } while (0) +#if BYTE_ORDER == BIG_ENDIAN + +#define CT_HTONS(n) (n) +#define CT_NTOHS(n) (n) +#define CT_HTONL(n) (n) +#define CT_NTOHL(n) (n) + +#else + +#define CT_HTONS(n) (((((unsigned short)(n) & 0xFF)) << 8) | (((unsigned short)(n) & 0xFF00) >> 8)) +#define CT_NTOHS(n) (((((unsigned short)(n) & 0xFF)) << 8) | (((unsigned short)(n) & 0xFF00) >> 8)) + +#define CT_HTONL(n) (((((unsigned long)(n) & 0xFF)) << 24) | \ + ((((unsigned long)(n) & 0xFF00)) << 8) | \ + ((((unsigned long)(n) & 0xFF0000)) >> 8) | \ + ((((unsigned long)(n) & 0xFF000000)) >> 24)) + +#define CT_NTOHL(n) (((((unsigned long)(n) & 0xFF)) << 24) | \ + ((((unsigned long)(n) & 0xFF00)) << 8) | \ + ((((unsigned long)(n) & 0xFF0000)) >> 8) | \ + ((((unsigned long)(n) & 0xFF000000)) >> 24)) +#endif + #endif // _UTILS_H