Unverified Commit f39e4796 authored by orignal's avatar orignal Committed by GitHub
Browse files

Merge pull request #5 from orignal/revert-4-master

Revert "sync with upstream"
parents c0d6d00e a1a2cbf6
Pipeline #63 failed with stages
......@@ -40,23 +40,10 @@ add_definitions(-DBOOST_COROUTINE_NO_DEPRECATION_WARNING)
# https://www.boost.org/doc/libs/1_67_0/doc/html/boost_asio/using.html#boost_asio.using.optional_separate_compilation
add_definitions(-DBOOST_ASIO_SEPARATE_COMPILATION)
################################################################################
set(GOROOT "${CMAKE_BINARY_DIR}/golang")
externalproject_add(golang
URL https://dl.google.com/go/go1.11.2.linux-amd64.tar.gz
URL_MD5 5630231012b6d02b821af51f04c2776c
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
SOURCE_DIR ${GOROOT}
)
################################################################################
option(ASIO_IPFS_WITH_EXAMPLE_BINARIES "" OFF)
add_subdirectory(./modules/asio-ipfs)
add_subdirectory(./modules/obfs4proxy)
add_subdirectory(./src/ouiservice/i2p)
################################################################################
......@@ -163,12 +150,8 @@ file(GLOB client_sources
"./src/ouiservice.cpp"
"./src/ssl/ca_certificate.cpp"
"./src/ssl/dummy_certificate.cpp"
"./src/ouiservice/pt-obfs2.cpp"
"./src/ouiservice/pt-obfs3.cpp"
"./src/ouiservice/pt-obfs4.cpp"
"./src/ouiservice/tcp.cpp"
"./src/ouiservice/tls.cpp"
"./src/ouiservice/pluggable-transports/*.cpp"
"./src/logger.cpp"
"./src/cache/*.cpp"
"./src/bittorrent/*.cpp"
......@@ -215,12 +198,8 @@ if (WITH_INJECTOR)
"./src/connect_to_host.cpp"
"./src/cache_control.cpp"
"./src/ouiservice.cpp"
"./src/ouiservice/pt-obfs2.cpp"
"./src/ouiservice/pt-obfs3.cpp"
"./src/ouiservice/pt-obfs4.cpp"
"./src/ouiservice/tcp.cpp"
"./src/ouiservice/tls.cpp"
"./src/ouiservice/pluggable-transports/*.cpp"
"./src/ssl/ca_certificate.cpp"
"./src/logger.cpp"
"./src/cache/*.cpp"
......
......@@ -23,9 +23,7 @@ android {
sourceSets {
main {
jniLibs.srcDirs = ["$libdir"]
assets.srcDirs = ["$assetsdir"]
}
}
buildTypes {
release {
......
......@@ -15,7 +15,6 @@
#include <condition_variable>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include "debug.h"
......@@ -36,40 +35,13 @@ ouinet::asio::io_service g_ios;
thread g_client_thread;
bool g_crypto_initialized = false;
void start_client_thread(const vector<string>& args, const vector<string>& extra_path)
void start_client_thread(const vector<string>& args)
{
if (g_crypto_initialized) {
ouinet::util::crypto_init();
g_crypto_initialized = true;
}
char* old_path_c = getenv("PATH");
if (old_path_c) {
std::string old_path(old_path_c);
std::set<std::string> old_path_entries;
size_t index = 0;
while (true) {
size_t pos = old_path.find(':', index);
if (pos == std::string::npos) {
old_path_entries.insert(old_path.substr(index));
break;
} else {
old_path_entries.insert(old_path.substr(index, pos - index));
index = pos;
}
}
std::string new_path;
for (size_t i = 0; i < extra_path.size(); i++) {
if (!old_path_entries.count(extra_path[i])) {
new_path += extra_path[i];
new_path += ":";
}
}
new_path += old_path;
setenv("PATH", new_path.c_str(), 1);
}
if (g_client_thread.get_id() != thread::id()) return;
g_client_thread = thread([=] {
......@@ -112,10 +84,10 @@ JNIEXPORT void JNICALL
Java_ie_equalit_ouinet_Ouinet_nStartClient(
JNIEnv* env,
jobject /* this */,
jobjectArray jargs,
jobjectArray jpath)
jobjectArray jargs)
{
size_t argn = env->GetArrayLength(jargs);
vector<string> args;
args.reserve(argn);
......@@ -126,19 +98,7 @@ Java_ie_equalit_ouinet_Ouinet_nStartClient(
env->ReleaseStringUTFChars(jstr, arg);
}
size_t pathn = env->GetArrayLength(jpath);
vector<string> path;
path.reserve(pathn);
for (size_t i = 0; i < pathn; ++i) {
jstring jstr = (jstring) env->GetObjectArrayElement(jpath, i);
const char* dir = env->GetStringUTFChars(jstr, 0);
path.push_back(dir);
env->ReleaseStringUTFChars(jstr, dir);
}
start_client_thread(args, path);
start_client_thread(args);
}
extern "C"
......
......@@ -23,7 +23,7 @@ public class Ouinet {
System.setProperty("https.proxyHost", "127.0.0.1");
System.setProperty("https.proxyPort", "8080");
}
private static final String TAG = "Ouinet";
private Context _ctx;
private WifiManager.MulticastLock _lock = null;
......@@ -41,9 +41,7 @@ public class Ouinet {
public Ouinet(Context ctx, Config conf) {
_ctx = ctx;
List<String> args = new ArrayList<String>();
List<String> path = new ArrayList<String>();
Vector<String> args = new Vector<String>();
new File(dir()).mkdirs();
......@@ -52,13 +50,14 @@ public class Ouinet {
// repository and fails if this conf file isn't there.
new File(dir() + "/ouinet-client.conf").createNewFile();
} catch (IOException e) {
Log.d(TAG, "Exception thrown while creating ouinet config file: ", e);
Log.d("Ouinet",
"Exception thrown while creating ouinet config file: " + e);
}
args.add("ouinet-client"); // App name
args.add("--repo=" + dir());
args.add("--listen-on-tcp=127.0.0.1:8080");
args.add("--front-end-ep=0.0.0.0:8081");
args.addElement("ouinet-client"); // App name
args.addElement("--repo=" + dir());
args.addElement("--listen-on-tcp=127.0.0.1:8080");
args.addElement("--front-end-ep=0.0.0.0:8081");
maybeAdd(args, "--injector-ep", conf.injector_endpoint);
maybeAdd(args, "--injector-credentials", conf.injector_credentials);
......@@ -77,7 +76,7 @@ public class Ouinet {
String asset = conf.tls_ca_cert_store_path.substring(assetPrefix.length());
ca_cert_path = dir() + "/assets/" + asset;
if (copyAssetToFile(asset, ca_cert_path)) {
if (copyAssetToFile(ctx, asset, ca_cert_path)) {
maybeAdd(args, "--tls-ca-cert-store-path", ca_cert_path);
}
}
......@@ -90,21 +89,15 @@ public class Ouinet {
if (conf.injector_tls_cert != null) {
String cert_path = dir() + "/injector-tls-cert.pem";
writeToFile(cert_path, conf.injector_tls_cert.getBytes());
args.add("--injector-tls-cert-file=" + cert_path);
args.addElement("--injector-tls-cert-file=" + cert_path);
}
} catch (IOException e) {
Log.d(TAG, "Exception thrown while creating injector's cert file: ", e);
}
String objfs4proxy_path = dir() + "/objfs4proxy";
if (copyExecutableToFile("obfs4proxy", objfs4proxy_path)) {
Log.d(TAG, "objfs4proxy copied to " + objfs4proxy_path);
path.add(dir());
} else {
Log.d(TAG, "objfs4proxy not copied");
Log.d("Ouinet",
"Exception thrown while creating injector's cert file: " + e);
e.printStackTrace();
}
nStartClient(args.toArray(new String[0]), path.toArray(new String[0]));
nStartClient(listToArray(args));
}
public String pathToCARootCert()
......@@ -112,35 +105,24 @@ public class Ouinet {
return nPathToCARootCert();
}
public boolean copyAssetToFile(String asset, String path)
public boolean copyAssetToFile(Context ctx, String asset, String path)
{
try {
java.io.InputStream stream = _ctx.getAssets().open(asset);
java.io.InputStream stream = ctx.getAssets().open(asset);
int size = stream.available();
byte[] buffer = new byte[size];
stream.read(buffer);
stream.close();
writeToFile(path, buffer);
} catch (IOException e) {
Log.d(TAG, "Failed to write asset \"" + asset + "\" to file \"" + path + "\"", e);
Log.d("Ouinet", "Failed to write asset \"" + asset + "\" to file \"" + path + "\"");
e.printStackTrace();
return false;
}
return true;
}
public boolean copyExecutableToFile(String asset, String path) {
if (!copyAssetToFile(asset, path)) {
return false;
}
File executable = new File(path);
if (!executable.setExecutable(true)) {
Log.d(TAG, "Failed to set executable for file: " + path);
return false;
}
return true;
}
// If this succeeds, we should be able to do UDP multicasts
// from inside ouinet (currently know to be needed by IPFS' mDNS
// but that's not essential for WAN).
......@@ -188,9 +170,16 @@ public class Ouinet {
}
//----------------------------------------------------------------
private void maybeAdd(List<String> args, String key, String value) {
private String[] listToArray(List<String> list) {
String[] ret = new String[list.size()];
int i = 0;
for (String s : list) { ret[i] = s; i += 1; }
return ret;
}
private void maybeAdd(Vector<String> args, String key, String value) {
if (value == null || value.isEmpty()) return;
args.add(key + "=" + value);
args.addElement(key + "=" + value);
}
private void writeToFile(String path, byte[] bytes) throws IOException {
......@@ -217,7 +206,7 @@ public class Ouinet {
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
private native void nStartClient(String[] args, String[] path);
private native void nStartClient(String[] args);
private native void nStopClient();
private native void nSetInjectorEP(String endpoint);
......
Subproject commit cffde1f77da95be90808e6260c34fa400802a8d1
Subproject commit 1fcf2855ee7ca9e6cb48150d4624c2989b8bb1f1
cmake_minimum_required (VERSION 3.5)
include(ExternalProject)
################################################################################
project(obfs4proxy)
# Convert system name into GOOS.
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
set(GOOS "linux")
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Android")
set(GOOS "android")
else()
message(FATAL_ERROR "unsupported system name ${CMAKE_SYSTEM_NAME}")
endif()
# Convert system processor into GOARCH (and maybe GOARM).
if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64")
set(GOARCH "amd64")
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64")
set(GOARCH "arm64")
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7-a")
set(GOARCH "arm")
set(GOARM "7")
elseif("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "^arm.*")
set(GOARCH "arm")
set(GOARM "6")
else()
message(FATAL_ERROR "unsupported system processor ${CMAKE_SYSTEM_PROCESSOR}")
endif()
# Build target tag with the Android API version if relevant.
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Android")
set(TARGET "${CMAKE_SYSTEM_NAME}${CMAKE_SYSTEM_VERSION}--${CMAKE_SYSTEM_PROCESSOR}")
else()
set(TARGET "${CMAKE_SYSTEM_NAME}--${CMAKE_SYSTEM_PROCESSOR}")
endif()
set(GOPATH "${CMAKE_CURRENT_BINARY_DIR}/go-workspace")
#
# Using CGO_ENABLED causes go to use the external linker shipped by the
# android ndk. This is almost certainly the wrong way to do it, but it
# seems to work for now.
#
externalproject_add(obfs4proxy
URL https://github.com/Yawning/obfs4/archive/obfs4proxy-0.0.9.tar.gz
URL_MD5 5ec7e4d96bf57fa0b269083076aacd02
DEPENDS golang
CONFIGURE_COMMAND ""
BUILD_IN_SOURCE 1
BUILD_COMMAND mkdir -p ${GOPATH}
&& export PATH=${GOROOT}/bin:$ENV{PATH}
&& export GOPATH=${GOPATH}
&& export GOOS=${GOOS}
&& export GOARCH=${GOARCH}
&& export GOARM=${GOARM}
&& export CC=${CMAKE_C_COMPILER}
&& export CGO_ENABLED=1
&& go build -o ${CMAKE_CURRENT_BINARY_DIR}/obfs4proxy ./obfs4proxy
INSTALL_COMMAND ""
)
#!/bin/bash
set -e
set -x
DIR=`pwd`
SCRIPT_DIR=$(dirname -- "$(readlink -f -- "$BASH_SOURCE")")
......@@ -128,22 +127,6 @@ function add_library {
done
}
######################################################################
# This variable shall contain paths to generated binaries which
# must all be included in the final Android package.
OUT_BINARIES=()
function add_binary {
local binaries=("$@") binaries
for binary in "${binaries[@]}"; do
if [ ! -f "$binary" ]; then
echo "Cannot add binary \"$binary\": File doesn't exist"
exit 1
fi
OUT_BINARIES+=("$binary")
done
}
######################################################################
MODES=
ALLOWED_MODES="build emu abiclean"
......@@ -299,9 +282,9 @@ function maybe_install_ndk_toolchain {
function maybe_install_gradle {
GRADLE_REQUIRED_MAJOR_VERSION=4
GRADLE_REQUIRED_MINOR_VERSION=6
NEED_GRADLE=false
if ! which gradle 1> /dev/null 2>&1; then
NEED_GRADLE=true
else
......@@ -421,7 +404,6 @@ add_library $DIR/build-ouinet/libclient.so
add_library $DIR/build-ouinet/modules/asio-ipfs/ipfs_bindings/libipfs_bindings.so
add_library $DIR/build-ouinet/gcrypt/src/gcrypt/src/.libs/libgcrypt.so
add_library $DIR/build-ouinet/gpg_error/out/lib/libgpg-error.so
add_binary $DIR/build-ouinet/modules/obfs4proxy/obfs4proxy
}
######################################################################
......@@ -436,18 +418,6 @@ for lib in "${OUT_LIBS[@]}"; do
done
}
######################################################################
function copy_binaries {
local binary_dst_dir="${DIR}"/build-android/builddir/assets/
rm -rf "${binary_dst_dir}"
mkdir -p "${binary_dst_dir}"
local binary
for binary in "${OUT_BINARIES[@]}"; do
echo "Copying $binary to $binary_dst_dir"
cp $binary $binary_dst_dir/
done
}
######################################################################
# Unpolished code to build the debug APK
function build_ouinet_apk {
......@@ -459,8 +429,7 @@ gradle --no-daemon build \
-Pboost_includedir=${BOOST_INCLUDEDIR} \
-Pandroid_abi=${ABI} \
-Pouinet_clientlib_path="${DIR}"/build-android/builddir/deps/${ABI}/libclient.so \
-Plibdir="${DIR}"/build-android/builddir/deps \
-Passetsdir="${DIR}"/build-android/builddir/assets
-Plibdir="${DIR}"/build-android/builddir/deps
echo "---------------------------------"
echo "Your Android package is ready at:"
......@@ -538,7 +507,6 @@ if check_mode build; then
# TODO: miniupnp
build_ouinet_libs
copy_jni_libs
copy_binaries
build_ouinet_apk
fi
......
......@@ -45,9 +45,6 @@
#include "ouiservice.h"
#include "ouiservice/i2p.h"
#include "ouiservice/pt-obfs2.h"
#include "ouiservice/pt-obfs3.h"
#include "ouiservice/pt-obfs4.h"
#include "ouiservice/tcp.h"
#include "ouiservice/tls.h"
......@@ -1402,55 +1399,28 @@ void Client::State::setup_injector(asio::yield_context yield)
cout << "Setting up injector: " << *injector_ep << endl;
std::unique_ptr<OuiServiceImplementationClient> client;
if (injector_ep->type == Endpoint::I2pEndpoint) {
if (is_i2p_endpoint(*injector_ep)) {
std::string ep = boost::get<I2PEndpoint>(*injector_ep).pubkey;
auto i2p_service = make_shared<ouiservice::I2pOuiService>((_config.repo_root()/"i2p").string(), _ios);
auto i2p_client = i2p_service->build_client(injector_ep->endpoint_string);
/*
if (!i2p_client->verify_endpoint()) {
return or_throw(yield, asio::error::invalid_argument);
}
*/
client = std::move(i2p_client);
} else if (injector_ep->type == Endpoint::TcpEndpoint) {
auto tcp_client = make_unique<ouiservice::TcpOuiServiceClient>(_ios, injector_ep->endpoint_string);
std::unique_ptr<ouiservice::I2pOuiServiceClient> i2p_client = i2p_service->build_client(ep);
if (!tcp_client->verify_endpoint()) {
return or_throw(yield, asio::error::invalid_argument);
}
client = std::move(tcp_client);
} else if (injector_ep->type == Endpoint::Obfs2Endpoint) {
auto obfs2_client = make_unique<ouiservice::Obfs2OuiServiceClient>(_ios, injector_ep->endpoint_string, _config.repo_root()/"obfs2-client");
_injector->add(std::move(i2p_client));
} else {
tcp::endpoint tcp_endpoint
= boost::get<asio::ip::tcp::endpoint>(*injector_ep);
if (!obfs2_client->verify_endpoint()) {
return or_throw(yield, asio::error::invalid_argument);
}
client = std::move(obfs2_client);
} else if (injector_ep->type == Endpoint::Obfs3Endpoint) {
auto obfs3_client = make_unique<ouiservice::Obfs3OuiServiceClient>(_ios, injector_ep->endpoint_string, _config.repo_root()/"obfs3-client");
auto tcp_client
= make_unique<ouiservice::TcpOuiServiceClient>(_ios, tcp_endpoint);
if (!obfs3_client->verify_endpoint()) {
return or_throw(yield, asio::error::invalid_argument);
}
client = std::move(obfs3_client);
} else if (injector_ep->type == Endpoint::Obfs4Endpoint) {
auto obfs4_client = make_unique<ouiservice::Obfs4OuiServiceClient>(_ios, injector_ep->endpoint_string, _config.repo_root()/"obfs4-client");
bool enable_injector_tls = !_config.tls_injector_cert_path().empty();
if (!obfs4_client->verify_endpoint()) {
return or_throw(yield, asio::error::invalid_argument);
if (!enable_injector_tls) {
_injector->add(std::move(tcp_client));
} else {
auto tls_client
= make_unique<ouiservice::TlsOuiServiceClient>(move(tcp_client), inj_ctx);
_injector->add(std::move(tls_client));
}
client = std::move(obfs4_client);
}
bool enable_injector_tls = !_config.tls_injector_cert_path().empty();
if (!enable_injector_tls) {
_injector->add(std::move(client));
} else {
auto tls_client
= make_unique<ouiservice::TlsOuiServiceClient>(move(client), inj_ctx);
_injector->add(std::move(tls_client));
}
_injector->start(yield);
......@@ -1478,14 +1448,10 @@ void Client::State::set_injector(string injector_ep_str)
_config.set_injector_endpoint(*injector_ep);
asio::spawn(_ios, [self = shared_from_this(), injector_ep_str] (auto yield) {
asio::spawn(_ios, [self = shared_from_this()] (auto yield) {
if (self->was_stopped()) return;
sys::error_code ec;
self->setup_injector(yield[ec]);
if (ec == asio::error::invalid_argument) {
cerr << "Failed to parse endpoint \"" << injector_ep_str << "\"" << endl;
}
});
}
......
......@@ -6,6 +6,7 @@
#include <boost/intrusive/list.hpp>
#include <chrono>
#include "namespaces.h"
#include "endpoint.h"
#include "ssl/ca_certificate.h"
namespace ouinet { class CacheClient; }
......
......@@ -2,58 +2,40 @@
namespace ouinet {
boost::optional<Endpoint> parse_endpoint(beast::string_view endpoint)
{
size_t pos = endpoint.find(':');
if (pos == std::string::npos) {
return boost::none;
}
beast::string_view type = endpoint.substr(0, pos);
Endpoint output;
output.endpoint_string = endpoint.substr(pos + 1).to_string();
if (type == "tcp") {
output.type = Endpoint::TcpEndpoint;
} else if (type == "i2p") {
output.type = Endpoint::I2pEndpoint;
#ifdef USE_GNUNET
} else if (type == "gnunet") {
output.type = Endpoint::GnunetEndpoint;
std::ostream& operator<<(std::ostream& os, const GnunetEndpoint& ep)
{
return os << ep.host << ":" << ep.port;
}
#endif
} else if (type == "obfs2") {
output.type = Endpoint::Obfs2Endpoint;
} else if (type == "obfs3") {
output.type = Endpoint::Obfs3Endpoint;
} else if (type == "obfs4") {
output.type = Endpoint::Obfs4Endpoint;
} else {
return boost::none;
}
return output;
std::ostream& operator<<(std::ostream& os, const I2PEndpoint& ep)
{
return os << ep.pubkey;
}
std::ostream& operator<<(std::ostream& os, const Endpoint& ep)
{
if (ep.type == Endpoint::TcpEndpoint) {
os << "tcp";
} else if (ep.type == Endpoint::I2pEndpoint) {
os << "i2p";
struct Visitor {
std::ostream& os;
void operator()(const asio::ip::tcp::endpoint& ep) {
os << ep;
}
#ifdef USE_GNUNET
} else if (ep.type == Endpoint::GnunetEndpoint) {
os << "i2p";
void operator()(const GnunetEndpoint& ep) {
os << ep;
}
#endif
} else if (ep.