Commit 6139e52a authored by Max Lv's avatar Max Lv

remove unnecessary packges

parent ecd8d7c6
......@@ -64,46 +64,6 @@ LOCAL_CFLAGS := -O2 -std=gnu99 -g -I$(LOCAL_PATH)/redsocks \
include $(BUILD_EXECUTABLE)
########################################################
## obfsproxy
########################################################
# include $(CLEAR_VARS)
#
# OBFSPROXY_SOURCES := container.c crypt.c external.c \
# main.c managed.c network.c \
# obfs_main.c protocol.c sha256.c \
# socks.c status.c util.c \
# protocols/dummy.c protocols/obfs2.c
#
# LOCAL_STATIC_LIBRARIES := libevent libcrypto
#
# LOCAL_MODULE := obfsproxy
# LOCAL_SRC_FILES := $(addprefix obfsproxy/, $(OBFSPROXY_SOURCES))
# LOCAL_CFLAGS := -O2 -g -I$(LOCAL_PATH)/obfsproxy \
# -I$(LOCAL_PATH)/libevent/include \
# -I$(LOCAL_PATH)/libevent \
# -I$(LOCAL_PATH)/openssl/include
#
# include $(BUILD_EXECUTABLE)
########################################################
## polipo
########################################################
# include $(CLEAR_VARS)
# POLIPO_SOURCES := util.c event.c io.c chunk.c atom.c object.c log.c diskcache.c main.c \
# config.c local.c http.c client.c server.c auth.c tunnel.c \
# http_parse.c parse_time.c dns.c forbidden.c \
# md5.c fts_compat.c socks.c mingw.c
#
# LOCAL_MODULE := polipo
# LOCAL_SRC_FILES := $(addprefix polipo/, $(POLIPO_SOURCES))
# LOCAL_CFLAGS := -O2 -g -DHAS_STDINT_H -DNO_DISK_CACHE -DNO_SYSLOG -I$(LOCAL_PATH)/polipo
#
# include $(BUILD_EXECUTABLE)
########################################################
## pdnsd
########################################################
......
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the <netinet/in.h> header file. */
#define HAVE_NETINET_IN_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/socket.h> header file. */
#define HAVE_SYS_SOCKET_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* True if this platform has the standard va_copy macro */
#define HAVE_VA_COPY 1
/* Name of package */
#define PACKAGE "obfsproxy"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""
/* Define to the full name of this package. */
#define PACKAGE_NAME "obfsproxy"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "obfsproxy 0.1.4"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "obfsproxy"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "0.1.4"
/* The size of `int', as computed by sizeof. */
#define SIZEOF_INT 4
/* The size of `size_t', as computed by sizeof. */
#define SIZEOF_SIZE_T 8
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "0.1.4"
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
/* #undef inline */
#endif
This diff is collapsed.
This diff is collapsed.
/* Copyright 2011 Nick Mathewson, George Kadianakis
See LICENSE for other credits and copying information
*/
/**
* \file crypt.c
* \headerfile crypt.h
* \brief Cryptographic functions.
*
* \details Most functions here are wrappers of OpenSSL functions.
**/
#include "util.h"
#define CRYPT_PRIVATE
#include "crypt.h"
#include <fcntl.h>
#include <unistd.h>
#include <openssl/opensslv.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#if OPENSSL_VERSION_NUMBER >= 0x0090800f
#define USE_OPENSSL_RANDPOLL 1
#define USE_OPENSSL_SHA256 1
#include <openssl/sha.h>
#else
#include "sha256.h"
#endif
/**
Initializes the crypto subsystem.
*/
int
initialize_crypto(void)
{
ERR_load_crypto_strings();
#ifdef USE_OPENSSL_RANDPOLL
return RAND_poll() == 1 ? 0 : -1;
#else
/* XXX Or maybe fall back to the arc4random implementation in libevent2? */
{
char buf[32];
int fd, n;
fd = open("/dev/urandom", O_RDONLY);
if (fd == -1) {
perror("open");
return -1;
}
n = read(fd, buf, sizeof(buf));
if (n != sizeof(buf)) {
close(fd);
return -1;
}
RAND_seed(buf, sizeof(buf));
close(fd);
return 0;
}
#endif
}
/**
Cleans up the crypto subsystem.
*/
void
cleanup_crypto(void)
{
ERR_free_strings();
}
/* =====
Digests
===== */
#ifndef USE_OPENSSL_SHA256
#define SHA256_CTX sha256_state
#define SHA256_Init(ctx) sha256_init(ctx)
#define SHA256_Update(ctx, buf, len) sha256_process(ctx, buf, len)
#define SHA256_Final(buf, ctx) sha256_done(ctx, buf)
#endif
struct digest_t {
SHA256_CTX ctx;
};
/**
Returns a new SHA256 digest container.
*/
digest_t *
digest_new(void)
{
digest_t *d = xmalloc(sizeof(digest_t));
SHA256_Init(&d->ctx);
return d;
}
/**
Updates the contents of the SHA256 container 'd' with the first
'len' bytes of 'buf'.
*/
void
digest_update(digest_t *d, const uchar *buf, size_t len)
{
SHA256_Update(&d->ctx, buf, len);
}
/**
Returns the digest stored in 'd' into 'buf' of length 'len'.
*/
size_t
digest_getdigest(digest_t *d, uchar *buf, size_t len)
{
if (len >= SHA256_LENGTH) {
SHA256_Final(buf, &d->ctx);
return SHA256_LENGTH;
} else {
uchar tmp[SHA256_LENGTH];
SHA256_Final(tmp, &d->ctx);
memcpy(buf, tmp, len);
memset(tmp, 0, SHA256_LENGTH);
return len;
}
}
void
digest_free(digest_t *d)
{
memset(d, 0, sizeof(digest_t));
free(d);
}
/* =====
Stream crypto
===== */
/**
Initializes the AES cipher with 'key'.
*/
crypt_t *
crypt_new(const uchar *key, size_t keylen)
{
crypt_t *k;
obfs_assert(keylen == AES_BLOCK_SIZE);
k = xzalloc(sizeof(crypt_t));
AES_set_encrypt_key(key, AES_BLOCK_SIZE * CHAR_BIT, &k->key);
return k;
}
/**
Sets the IV of 'key' to 'iv'.
*/
void
crypt_set_iv(crypt_t *key, const uchar *iv, size_t ivlen)
{
obfs_assert(ivlen == sizeof(key->ivec));
memcpy(key->ivec, iv, ivlen);
}
/*
In-place encrypts 'buf' with 'key'.
*/
void
stream_crypt(crypt_t *key, uchar *buf, size_t len)
{
AES_ctr128_encrypt(buf, buf, len,
&key->key, key->ivec, key->ecount_buf,
&key->pos);
}
/**
Deallocates memory space of 'key'.
*/
void
crypt_free(crypt_t *key)
{
memset(key, 0, sizeof(crypt_t));
free(key);
}
/* =====
PRNG
===== */
/**
Fills 'buf' with 'buflen' random bytes and returns 0 on success.
Returns -1 on failure.
*/
int
random_bytes(uchar *buf, size_t buflen)
{
return RAND_bytes(buf, buflen) == 1 ? 0 : -1;
}
/** Return a pseudorandom integer, chosen uniformly from the values
* between 0 and <b>max</b>-1 inclusive. <b>max</b> must be between 1 and
* INT_MAX+1, inclusive. */
int
random_int(unsigned int max)
{
unsigned int val;
unsigned int cutoff;
obfs_assert(max <= ((unsigned int)INT_MAX)+1);
obfs_assert(max > 0); /* don't div by 0 */
/* We ignore any values that are >= 'cutoff,' to avoid biasing the
* distribution with clipping at the upper end of unsigned int's
* range.
*/
cutoff = UINT_MAX - (UINT_MAX%max);
while (1) {
random_bytes((uchar*)&val, sizeof(val));
if (val < cutoff)
return val % max;
}
}
/* Copyright 2011 Nick Mathewson, George Kadianakis
See LICENSE for other credits and copying information
*/
/**
* \file crypt.h
* \brief Headers for crypt.c.
**/
#ifndef CRYPT_H
#define CRYPT_H
#define SHA256_LENGTH 32
/* Stream cipher state */
typedef struct crypt_t crypt_t;
/* Digest state */
typedef struct digest_t digest_t;
typedef unsigned char uchar;
/** Initialize global crypto state. Returrn 0 on success, -1 on failure */
int initialize_crypto(void);
/** Clean up global crypto state */
void cleanup_crypto(void);
/** Return a newly allocated digest state; cannot fail. */
digest_t *digest_new(void);
/** Add n bytes from b to the digest state. */
void digest_update(digest_t *, const uchar *b, size_t n);
/** Get a digest from the digest state. Put it in up the first n bytes of the
buffer b. Return the number of bytes actually written.*/
size_t digest_getdigest(digest_t *, uchar *b, size_t n);
/** Clear and free a digest state */
void digest_free(digest_t *);
/** Return a new stream cipher state using 'key' as the symmetric key.
* The data length must be exactly 16 bytes. Cannot fail. */
crypt_t *crypt_new(const uchar *key, size_t);
/* Set the IV of a stream-cipher state. Cannot fail. */
void crypt_set_iv(crypt_t *, const uchar *iv, size_t ivlen);
/** Encrypt n bytes of data in the buffer b, in place. */
void stream_crypt(crypt_t *, uchar *b, size_t n);
/** Clear and free a stream cipher state. */
void crypt_free(crypt_t *);
/** Set b to contain n random bytes. */
int random_bytes(uchar *b, size_t n);
/** Return a random integer in the range [0, max).
* 'max' must be between 1 and INT_MAX+1, inclusive.
*/
int random_int(unsigned int max);
#ifdef CRYPT_PRIVATE
#include <openssl/aes.h>
/* ==========
These definitions are not part of the crypt interface.
They're exposed here so that the unit tests can use them.
==========
*/
struct crypt_t {
AES_KEY key;
uchar ivec[AES_BLOCK_SIZE];
uchar ecount_buf[AES_BLOCK_SIZE];
unsigned int pos;
};
#endif
#endif
/* Copyright 2011 Nick Mathewson, George Kadianakis
See LICENSE for other credits and copying information
*/
/**
* \file external.c
* \headerfile external.h
* \brief Implements the 'external proxy' mode of obfsproxy.
**/
#include "util.h"
#include "container.h"
#include "crypt.h"
#include "network.h"
#include "protocol.h"
#include "managed.h"
#include "main.h"
#include <event2/event.h>
/**
Launch external proxy.
*/
int
launch_external_proxy(const char *const *begin)
{
smartlist_t *configs = smartlist_create();
const char *const *end;
/* Find the subsets of argv that define each configuration.
Each configuration's subset consists of the entries in argv from
its recognized protocol name, up to but not including the next
recognized protocol name. */
if (!*begin || !is_supported_protocol(*begin))
usage();
do {
end = begin+1;
while (*end && !is_supported_protocol(*end))
end++;
if (log_do_debug()) {
smartlist_t *s = smartlist_create();
char *joined;
const char *const *p;
for (p = begin; p < end; p++)
smartlist_add(s, (void *)*p);
joined = smartlist_join_strings(s, " ", 0, NULL);
log_debug("Configuration %d: %s", smartlist_len(configs)+1, joined);
free(joined);
smartlist_free(s);
}
if (end == begin+1) {
log_warn("No arguments for configuration %d", smartlist_len(configs)+1);
usage();
} else {
config_t *cfg = config_create(end - begin, begin);
if (!cfg) {
smartlist_free(configs);
return -1; /* diagnostic already issued */
}
smartlist_add(configs, cfg);
}
begin = end;
} while (*begin);
obfs_assert(smartlist_len(configs) > 0);
/* Configurations have been established; proceed with initialization. */
obfsproxy_init();
/* Open listeners for each configuration. */
SMARTLIST_FOREACH(configs, config_t *, cfg, {
if (!open_listeners(get_event_base(), cfg)) {
log_error("Failed to open listeners for configuration %d", cfg_sl_idx+1);
}
});
/* We are go for launch. */
event_base_dispatch(get_event_base());
/* Cleanup and exit! */
obfsproxy_cleanup();
SMARTLIST_FOREACH(configs, config_t *, cfg, config_free(cfg));
smartlist_free(configs);
return 0;
}
/* Copyright 2011 Nick Mathewson, George Kadianakis
See LICENSE for other credits and copying information
*/
/**
* \file external.h
* \brief Headers for external.c.
**/
#ifndef EXTERNAL_H
#define EXTERNAL_H
int launch_external_proxy(const char *const *begin);
#endif
This diff is collapsed.
/* Copyright 2011 Nick Mathewson, George Kadianakis
See LICENSE for other credits and copying information
*/
/**
* \file main.c
* \headerfile main.h
* \brief Entry point of obfsproxy. Does command-line parsing, and
* switches into 'external' or 'managed' proxy mode.
*
* \details Practically, obfs_main.c is the actual entry point of
* obfsproxy, but all it really does is call obfs_main().
**/
#include "util.h"
#include "container.h"
#include "crypt.h"
#include "network.h"
#include "protocol.h"
#include "managed.h"
#include "external.h"
#include "status.h"
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <event2/event.h>
#include <event2/dns.h>
/** String describing which obfsproxy git repository version the
* source was built from. This string is generated by a bit of shell
* kludging in Makefile.am, and is usually right.
*/
const char obfs_git_revision[] =
#ifndef _MSC_VER
#include "micro-revision.i"
#endif
"";
static struct event_base *the_event_base;
static struct event *sig_int;
static struct event *sig_term;
static struct event *heartbeat;
/* Pluggable transport proxy mode. ('External' or 'Managed') */
static int is_external_proxy=1;
/* Whether to scrub connection addresses -- on by default */
int safe_logging=1;
static char *the_obfsproxy_version = NULL;
/** Return the current obfsproxy version. */
static const char *
get_version(void)
{
if (!the_obfsproxy_version) {
if (strlen(obfs_git_revision))
obfs_asprintf(&the_obfsproxy_version, "%s (git-%s)", VERSION, obfs_git_revision);
else
the_obfsproxy_version = xstrdup(VERSION);
}
return the_obfsproxy_version;
}
/**
Prints the obfsproxy usage instructions then exits.
*/
void ATTR_NORETURN
usage(void)
{
int i;
fputs("Usage: obfsproxy [obfsproxy_args] protocol_name [protocol_args] "
"protocol_options protocol_name ...\n"
"* Available protocols:\n", stderr);
/* this is awful. */
for (i=0;i<n_supported_protocols;i++)
fprintf(stderr,"[%s] ", supported_protocols[i]->name);
fprintf(stderr, "\n* obfsproxy_args:\n"
"--log-file=<file> ~ set logfile\n"
"--log-min-severity=warn|notice|info|debug ~ "
"set minimum logging severity (default: notice)\n"
"--no-log ~ disable logging\n"
"--no-safe-logging ~ disable safe (scrubbed address) logging\n");
if (the_obfsproxy_version)
free(the_obfsproxy_version);
exit(1);
}
/** Prints the obfsproxy version then exits. */
static void ATTR_NORETURN
version(void)
{
printf("obfsproxy %s\n", get_version());
if (the_obfsproxy_version)
free(the_obfsproxy_version);
exit(1);
}
/**
This is called when we receive a signal.
It figures out the signal type and acts accordingly.
Current behavior:
SIGINT: On a single SIGINT we stop accepting new connections,
keep the already existing connections open,
and terminate when they all close.
On a second SIGINT we shut down immediately but cleanly.
SIGTERM: Shut down obfsproxy immediately but cleanly.
*/
static void
handle_signal_cb(evutil_socket_t fd, short what, void *arg)
{
int signum = (int) fd;
static int got_sigint=0;
switch (signum) {
case SIGINT:
close_all_listeners();
if (!got_sigint) {
log_notice("Got SIGINT. Preparing shutdown.");
start_shutdown(0);
got_sigint++;
} else {
log_notice("Got SIGINT for the second time. Terminating.");
start_shutdown(1);
}
break;
case SIGTERM:
log_notice("Got SIGTERM. Terminating.");
start_shutdown(1);
break;
}
}
/**
Returns the libevent event base used by obfsproxy.
*/
struct event_base *
get_event_base(void)
{
return the_event_base;
}
/** Stop obfsproxy's event loop. Final cleanup happens in main(). */
void
finish_shutdown(void)
{
log_debug("Finishing shutdown.");
event_base_loopexit(the_event_base, NULL);
}
/** Return 1 if 'name' is the name of a supported protocol, otherwise 0. */
int
is_supported_protocol(const char *name)
{
int i;
for (i = 0; i < n_supported_protocols; i++)
if (!strcmp(name, supported_protocols[i]->name))
return 1;
return 0;
}
/**
Receives 'argv' and scans for any obfsproxy optional arguments and
tries to set them in effect.
If it succeeds it returns the number of argv arguments its caller
should skip to get past the optional arguments we already handled.
If it fails, it exits obfsproxy.
*/
static int
handle_obfsproxy_args(const char *const *argv)
{
int logfile_set=0;
int logsev_set=0;
int i=1;
while (argv[i] &&
!strncmp(argv[i],"--",2)) {
if (!strncmp(argv[i], "--log-file=", 11)) {
if (logfile_set)
log_error("You've already set a log file!");
if (log_set_method(LOG_METHOD_FILE, (char *)argv[i]+11) < 0)
log_error("Failed creating logfile.");
logfile_set=1;
} else if (!strncmp(argv[i], "--log-min-severity=", 19)) {
if (logsev_set)
log_error("You've already set a min. log severity!");
if (log_set_min_severity((char *)argv[i]+19) < 0)
log_error("Error at setting logging severity");
logsev_set=1;
} else if (!strncmp(argv[i], "--no-log", 9)) {
if (logsev_set) {
printf("You've already set a min. log severity!\n");
exit(1);
}
if (log_set_method(LOG_METHOD_NULL, NULL) < 0) {
printf("Error at setting logging severity.\n");
exit(1);
}
logsev_set=1;
} else if (!strncmp(argv[i], "--no-safe-logging", 18)) {
safe_logging=0;
} else if (!strncmp(argv[i], "--managed", 10)) {
is_external_proxy=0;
} else if (!strncmp(argv[i], "--version", 10)) {
version();
} else if (!strncmp(argv[i], "--help", 7)) {
usage();
} else {
log_error("Unrecognizable obfsproxy argument '%s'", argv[i]);
}
i++;
}
if (!is_external_proxy && !logfile_set && logsev_set) {
printf("obfsproxy in managed proxy mode can only log to a file.\n");
exit(1);
} else if (!is_external_proxy && !logfile_set) { /* && !logsev_set */
/* managed proxies without a log file must not log at all. */
if (log_set_method(LOG_METHOD_NULL, NULL) < 0) {
printf("Error at setting logging severity.\n");
exit(1);
}
}
return i;
}
/** Libevent callback: Log heartbeat message once every hour. */
static void
heartbeat_cb(evutil_socket_t fd, short what, void *arg)
{
(void) fd;
(void) what;
(void) arg;
status_log_heartbeat();
}
/**
Initialize basic components of obfsproxy.
*/
void
obfsproxy_init()
{
/* Ugly method to fix a Windows problem:
http://archives.seul.org/libevent/users/Oct-2010/msg00049.html */
#ifdef _WIN32
WSADATA wsaData;
WSAStartup(0x101, &wsaData);
#endif
/* Initialize crypto */
if (initialize_crypto() < 0) {
log_error("Failed to initialize cryptography.");
}
/* Initialize libevent */
the_event_base = event_base_new();
if (!the_event_base) {
log_error("Failed to initialize networking.");
}
/* ASN should this happen only when SOCKS is enabled? */
if (init_evdns_base(the_event_base)) {
log_error("Failed to initialize DNS resolver.");
}
/* Handle signals. */
#ifdef SIGPIPE
signal(SIGPIPE, SIG_IGN);
#endif
sig_int = evsignal_new(the_event_base, SIGINT,
handle_signal_cb, NULL);
sig_term = evsignal_new(the_event_base, SIGTERM,
handle_signal_cb, NULL);
if (event_add(sig_int,NULL) || event_add(sig_term,NULL)) {
log_error("Failed to initialize signal handling.");
}
/* Initialize hourly heartbeat messages. */
struct timeval one_hour;
one_hour.tv_sec = 3600;
one_hour.tv_usec = 0;
status_init();
heartbeat = event_new(the_event_base, -1, EV_PERSIST, heartbeat_cb, NULL);
if (event_add(heartbeat, &one_hour)) {
log_error("Failed to initialize heartbeat logs.");
}
}
/**
Clean the mess that obfsproxy made all over this computer's memory.
*/
void
obfsproxy_cleanup()
{
/* We have landed. */
log_notice("Exiting.");
close_all_listeners();
evdns_base_free(get_evdns_base(), 0);
event_free(sig_int);
event_free(sig_term);
if (heartbeat)
event_free(heartbeat);
event_base_free(get_event_base());
cleanup_crypto();
status_connections_cleanup();
close_obfsproxy_logfile();
if (the_obfsproxy_version)
free(the_obfsproxy_version);
}
/** Entry point */
int
obfs_main(int argc, const char *const *argv)
{
const char *const *begin;
/* Handle optional obfsproxy arguments. */
begin = argv + handle_obfsproxy_args(argv);
log_notice("Starting (obfsproxy version: %s).", get_version());
if (is_external_proxy) {
if (launch_external_proxy(begin) < 0)
return 1;
} else {
if (launch_managed_proxy() < 0)
return 1;
}
return 0;
}
/* Copyright 2011 Nick Mathewson, George Kadianakis
See LICENSE for other credits and copying information
*/
/**
* \file main.h
* \brief Headers for main.c.
**/
#ifndef MAIN_H
#define MAIN_H
void finish_shutdown(void);
void obfsproxy_init();
void obfsproxy_cleanup();
int is_supported_protocol(const char *name);
void ATTR_NORETURN usage(void);
struct event_base *get_event_base(void);
#endif
This diff is collapsed.
/* Copyright 2011 Nick Mathewson, George Kadianakis
See LICENSE for other credits and copying information
*/
/**
* \file managed.h
* \brief Headers for managed.c.
**/
#ifndef MANAGED_H
#define MANAGED_H
int launch_managed_proxy();
#ifdef MANAGED_PRIVATE
int validate_bindaddrs(const char *all_bindaddrs, const char *all_transports);
#endif /* MANAGED_PRIVATE */
#endif
This diff is collapsed.
/* Copyright 2011 Nick Mathewson, George Kadianakis
See LICENSE for other credits and copying information
*/
/**
* \file network.h
* \brief Headers for network.c.
**/
#ifndef NETWORK_H
#define NETWORK_H
/* returns 1 on success, 0 on failure */
int open_listeners(struct event_base *base, config_t *cfg);
void close_all_listeners(void);
struct evconnlistener *get_evconnlistener_by_config(config_t *cfg);
void start_shutdown(int barbaric);
/**
This struct defines the state of one socket-level connection. Each
protocol may extend this structure with additional private data by
embedding it as the first member of a larger structure. The
protocol's conn_create() method is responsible only for filling in
the |cfg| and |mode| fields of this structure, plus any private
data of course.
An incoming connection is not associated with a circuit until the
destination for the other side of the circuit is known. An outgoing
connection is associated with a circuit from its creation.
*/
struct conn_t {
config_t *cfg;
char *peername;
circuit_t *circuit;
struct bufferevent *buffer;
enum listen_mode mode;
};
/**
This struct defines a pair of established connections.
The "upstream" connection is to the higher-level client or server
that we are proxying traffic for. The "downstream" connection is
to the remote peer. Circuits always have an upstream connection,
and normally also have a downstream connection; however, a circuit
that's waiting for SOCKS directives from its upstream will have a
non-null socks_state field instead.
A circuit is "open" if both its upstream and downstream connections
have been established (not just if both conn_t objects exist).
It is "flushing" if one of the two connections has hit either EOF
or an error, and we are clearing out the other side's pending
transmissions before closing it. Both of these flags are used
near-exclusively for assertion checks; the actual behavior is
controlled by changing bufferevent callbacks on the connections.
*/
struct circuit_t {
conn_t *upstream;
conn_t *downstream;
socks_state_t *socks_state;
unsigned int is_open : 1;
unsigned int is_flushing : 1;
};
#ifdef NETWORK_PRIVATE
int circuit_create(conn_t *up, conn_t *down);
#endif
#endif
/* Copyright 2011 Nick Mathewson, George Kadianakis
See LICENSE for other credits and copying information
*/
/**
* \file obfs_main.c
* \brief Real entry point of obfsproxy. Immediately calls
* main.c:obfs_main().
*
* \details This all happens so that our unittests binary can link
* against main.c.
**/
int obfs_main(int argc, char *argv[]);
/**
Simply calls obfs_main() from main.c;
it allows our unittests binary to link against main.c.
*/
int
main(int argc, char *argv[])
{
return obfs_main(argc, argv);
}
/* Copyright 2011 Nick Mathewson, George Kadianakis
See LICENSE for other credits and copying information
*/
/**
* \file protocol.c
* \headerfile protocol.h
* \brief Pluggable transports-related functions.
*
* \details Acts as an intermediary between generic obfsproxy code,
* and pluggable transports code. Provides wrappers for
* transport-specific configuration, and callbacks.
*
* Note that in obfsproxy code, 'protocol' is a synonym to 'pluggable
* transport'.
**/
#include "util.h"
#include "network.h"
#include "protocol.h"
#include "protocols/dummy.h"
#include "protocols/obfs2.h"
/**
All supported protocols should be put in this array.
It's used by main.c.
*/
const protocol_vtable *const supported_protocols[] =
{
&dummy_vtable,
&obfs2_vtable
};
const size_t n_supported_protocols =
sizeof(supported_protocols)/sizeof(supported_protocols[0]);
/**
This function dispatches (by name) creation of a |config_t|
to the appropriate protocol-specific initalization function.
*/
config_t *
config_create(int n_options, const char *const *options)
{
size_t i;
for (i = 0; i < n_supported_protocols; i++)
if (!strcmp(*options, supported_protocols[i]->name))
/* Remove the first element of 'options' (which is always the
protocol name) from the list passed to the init method. */
return supported_protocols[i]->config_create(n_options - 1, options + 1);
return NULL;
}
/**
Return the transport name for 'cfg'.
*/
const char *
get_transport_name_from_config(config_t *cfg)
{
obfs_assert(cfg);
obfs_assert(cfg->vtable);
obfs_assert(cfg->vtable->name);
return cfg->vtable->name;
}
/**
Create a config_t for a managed proxy listener.
*/
config_t *
config_create_managed(int is_server, const char *protocol,
const char *bindaddr, const char *orport)
{
size_t i;
for (i = 0; i < n_supported_protocols; i++)
if (!strcmp(protocol, supported_protocols[i]->name)) {
/* Remove the first element of 'options' (which is always the
protocol name) from the list passed to the init method. */
return supported_protocols[i]->config_create_managed(is_server,
protocol,
bindaddr, orport);
}
return NULL;
}
/**
This function destroys the protocol-specific part of a listener object.
*/
void
config_free(config_t *cfg)
{
obfs_assert(cfg);
obfs_assert(cfg->vtable);
obfs_assert(cfg->vtable->config_free);
cfg->vtable->config_free(cfg);
}
struct evutil_addrinfo *
config_get_listen_addrs(config_t *cfg, size_t n)
{
obfs_assert(cfg);
obfs_assert(cfg->vtable);
obfs_assert(cfg->vtable->config_get_listen_addrs);
return cfg->vtable->config_get_listen_addrs(cfg, n);
}
struct evutil_addrinfo *
config_get_target_addr(config_t *cfg)
{
obfs_assert(cfg);
obfs_assert(cfg->vtable);
obfs_assert(cfg->vtable->config_get_target_addr);
return cfg->vtable->config_get_target_addr(cfg);
}
/**
This function is called once per connection and creates a protocol
object to be used during the session.
Return a 'protocol_t' if successful, NULL otherwise.
*/
conn_t *
proto_conn_create(config_t *cfg)
{
obfs_assert(cfg);
obfs_assert(cfg->vtable);
obfs_assert(cfg->vtable->conn_create);
return cfg->vtable->conn_create(cfg);
}
/**
This function does the protocol handshake.
Not all protocols have a handshake.
*/
int
proto_handshake(conn_t *conn, void *buf) {
obfs_assert(conn);
obfs_assert(conn->cfg);
obfs_assert(conn->cfg->vtable);
obfs_assert(conn->cfg->vtable->handshake);
return conn->cfg->vtable->handshake(conn, buf);
}
/**
This function is responsible for sending protocol data.
*/
int
proto_send(conn_t *conn, void *source, void *dest) {
obfs_assert(conn);
obfs_assert(conn->cfg);
obfs_assert(conn->cfg->vtable);
obfs_assert(conn->cfg->vtable->send);
return conn->cfg->vtable->send(conn, source, dest);
}
/**
This function is responsible for receiving protocol data.
*/
enum recv_ret
proto_recv(conn_t *conn, void *source, void *dest) {
obfs_assert(conn);
obfs_assert(conn->cfg);
obfs_assert(conn->cfg->vtable);
obfs_assert(conn->cfg->vtable->recv);
return conn->cfg->vtable->recv(conn, source, dest);
}
/**
This function destroys 'conn'.
It's called everytime we close a connection.
*/
void
proto_conn_free(conn_t *conn) {
obfs_assert(conn);
obfs_assert(conn->cfg);
obfs_assert(conn->cfg->vtable);
obfs_assert(conn->cfg->vtable->conn_free);
conn->cfg->vtable->conn_free(conn);
}
/**
This protocol is called everytime a circuit has to be created.
Return a circuit_t on success or a NULL on fail.
*/
circuit_t *
proto_circuit_create(config_t *cfg)
{
obfs_assert(cfg);
obfs_assert(cfg->vtable);
obfs_assert(cfg->vtable->circuit_create);
return cfg->vtable->circuit_create(cfg);
}
/**
This function destroys 'circuit', using the vtable off 'cfg'.
*/
void
proto_circuit_free(circuit_t *circuit, config_t *cfg) {
obfs_assert(cfg);
obfs_assert(cfg->vtable);
obfs_assert(cfg->vtable->circuit_free);
cfg->vtable->circuit_free(circuit);
}
/* Copyright 2011 Nick Mathewson, George Kadianakis
See LICENSE for other credits and copying information
*/
/**
* \file protocol.h
* \brief Headers for protocol.c.
**/
#ifndef PROTOCOL_H
#define PROTOCOL_H
/**
This struct defines a "configuration" of the proxy.
A configuration is a set of addresses to listen on, and what to do
when connections are received. Almost all of a configuration is
protocol-private data, stored in the larger structure in which this
struct is embedded.
*/
struct config_t
{
const struct protocol_vtable *vtable;
};
const char *get_transport_name_from_config(config_t *cfg);
/**
This struct defines a protocol and its methods; note that not all
of them are methods on the same object in the C++ sense.
A filled-in, statically allocated protocol_vtable object is the
principal interface between each individual protocol and generic
code. At present there is a static list of these objects in protocol.c.
*/
struct protocol_vtable
{
/** The short name of this protocol. */
const char *name;
/** Allocate a 'config_t' object and fill it in from the provided
'options' array. */
config_t *(*config_create)(int n_options, const char *const *options);
config_t *(*config_create_managed)(int is_server, const char *protocol,
const char *bindaddr, const char *orport);
/** Destroy the provided 'config_t' object. */
void (*config_free)(config_t *cfg);
/** Return a set of addresses to listen on, in the form of an
'evutil_addrinfo' linked list. There may be more than one list;
users of this function should call it repeatedly with successive
values of N, starting from zero, until it returns NULL, and
create listeners for every address returned. */
struct evutil_addrinfo *(*config_get_listen_addrs)(config_t *cfg, size_t n);
/** Return a set of addresses to attempt an outbound connection to,
in the form of an 'evutil_addrinfo' linked list. There is only
one such list. */
struct evutil_addrinfo *(*config_get_target_addr)(config_t *cfg);
/** A connection has just been made to one of 'cfg's listener
addresses. Return an extended 'conn_t' object, filling in the
'cfg' and 'mode' fields of the generic structure. */
conn_t *(*conn_create)(config_t *cfg);
/** Destroy per-connection, protocol-specific state. */
void (*conn_free)(conn_t *state);
/** A 'circuit_t' needs to be created. */
circuit_t *(*circuit_create)(config_t *cfg);
/** Destroy a 'circuit_t'. */
void (*circuit_free)(circuit_t *circuit);
/** Perform a connection handshake. Not all protocols have a handshake. */
int (*handshake)(conn_t *state, struct evbuffer *buf);
/** Send data coming downstream from 'source' along to 'dest'. */
int (*send)(conn_t *state,
struct evbuffer *source,
struct evbuffer *dest);
/** Receive data from 'source' and pass it upstream to 'dest'. */
enum recv_ret (*recv)(conn_t *state,
struct evbuffer *source,
struct evbuffer *dest);
};
/**
Use this macro to define protocol_vtable objects; it ensures all
the methods are in the correct order and enforces a consistent
naming convention on protocol implementations.
*/
#define DEFINE_PROTOCOL_VTABLE(name) \
const protocol_vtable name##_vtable = { \
#name, \
name##_config_create, \
name##_config_create_managed, \
name##_config_free, \
name##_config_get_listen_addrs, \
name##_config_get_target_addr, \
name##_conn_create, \
name##_conn_free, \
name##_circuit_create, \
name##_circuit_free, \
name##_handshake, name##_send, name##_recv \
}
config_t *config_create(int n_options, const char *const *options);
config_t *config_create_managed(int is_server, const char *protocol,
const char *bindaddr, const char *orport);
void config_free(config_t *cfg);
struct evutil_addrinfo *config_get_listen_addrs(config_t *cfg, size_t n);
struct evutil_addrinfo *config_get_target_addr(config_t *cfg);
conn_t *proto_conn_create(config_t *cfg);
void proto_conn_free(conn_t *conn);
circuit_t *proto_circuit_create(config_t *cfg);
void proto_circuit_free(circuit_t *conn, config_t *cfg);
int proto_handshake(conn_t *conn, void *buf);
int proto_send(conn_t *conn, void *source, void *dest);
enum recv_ret proto_recv(conn_t *conn, void *source, void *dest);
extern const protocol_vtable *const supported_protocols[];
extern const size_t n_supported_protocols;
#endif
/* Copyright 2011 Nick Mathewson, George Kadianakis
See LICENSE for other credits and copying information
*/
/**
* \file dummy.c
* \headerfile dummy.h
* \brief Implements the 'dummy' pluggable transport. A testing-only
* pluggable transport that leaves traffic intact
**/
#include "util.h"
#define PROTOCOL_DUMMY_PRIVATE
#include "dummy.h"
#include <event2/buffer.h>
/* type-safe downcast wrappers */
static inline dummy_config_t *
downcast_config(config_t *p)
{
return DOWNCAST(dummy_config_t, super, p);
}
static inline dummy_conn_t *
downcast_conn(conn_t *p)
{
return DOWNCAST(dummy_conn_t, super, p);
}
static inline dummy_circuit_t *
downcast_circuit(circuit_t *p)
{
return DOWNCAST(dummy_circuit_t, super, p);
}
/**
Helper: Parses 'options' and fills 'cfg'.
*/
static int
parse_and_set_options(int n_options, const char *const *options,
dummy_config_t *cfg)
{
const char* defport;
if (n_options < 1)
return -1;
if (!strcmp(options[0], "client")) {
defport = "48988"; /* bf5c */
cfg->mode = LSN_SIMPLE_CLIENT;
} else if (!strcmp(options[0], "socks")) {
defport = "23548"; /* 5bf5 */
cfg->mode = LSN_SOCKS_CLIENT;
} else if (!strcmp(options[0], "server")) {
defport = "11253"; /* 2bf5 */
cfg->mode = LSN_SIMPLE_SERVER;
} else
return -1;
if (n_options != (cfg->mode == LSN_SOCKS_CLIENT ? 2 : 3))
return -1;
cfg->listen_addr = resolve_address_port(options[1], 1, 1, defport);
if (!cfg->listen_addr)
return -1;
if (cfg->mode != LSN_SOCKS_CLIENT) {
cfg->target_addr = resolve_address_port(options[2], 1, 0, NULL);
if (!cfg->target_addr)
return -1;
}
return 0;
}
/* Deallocate 'cfg'. */
static void
dummy_config_free(config_t *c)
{
dummy_config_t *cfg = downcast_config(c);
if (cfg->listen_addr)
evutil_freeaddrinfo(cfg->listen_addr);
if (cfg->target_addr)
evutil_freeaddrinfo(cfg->target_addr);
free(cfg);
}
/**
Populate 'cfg' according to 'options', which is an array like this:
{"socks","127.0.0.1:6666"}
*/
static config_t *
dummy_config_create(int n_options, const char *const *options)
{
dummy_config_t *cfg = xzalloc(sizeof(dummy_config_t));
cfg->super.vtable = &dummy_vtable;
if (parse_and_set_options(n_options, options, cfg) == 0)
return &cfg->super;
dummy_config_free(&cfg->super);
log_warn("dummy syntax:\n"
"\tdummy <mode> <listen_address> [<target_address>]\n"
"\t\tmode ~ server|client|socks\n"
"\t\tlisten_address, target_address ~ host:port\n"
"\ttarget_address is required for server and client mode,\n"
"\tand forbidden for socks mode.\n"
"Examples:\n"
"\tobfsproxy dummy socks 127.0.0.1:5000\n"
"\tobfsproxy dummy client 127.0.0.1:5000 192.168.1.99:11253\n"
"\tobfsproxy dummy server 192.168.1.99:11253 127.0.0.1:9005");
return NULL;
}
/**
Return a config_t for a managed proxy listener.
*/
static config_t *
dummy_config_create_managed(int is_server, const char *protocol,
const char *bindaddr, const char *orport)
{
const char* defport;
dummy_config_t *cfg = xzalloc(sizeof(dummy_config_t));
cfg->super.vtable = &dummy_vtable;
if (is_server) {
defport = "11253"; /* 2bf5 */
cfg->mode = LSN_SIMPLE_SERVER;
} else {
defport = "23548"; /* 5bf5 */
cfg->mode = LSN_SOCKS_CLIENT;
}
cfg->listen_addr = resolve_address_port(bindaddr, 1, 1, defport);
if (!cfg->listen_addr)
goto err;
if (is_server) {
cfg->target_addr = resolve_address_port(orport, 1, 0, NULL);
if (!cfg->target_addr)
goto err;
}
return &cfg->super;
err:
dummy_config_free(&cfg->super);
return NULL;
}
/** Retrieve the 'n'th set of listen addresses for this configuration. */
static struct evutil_addrinfo *
dummy_config_get_listen_addrs(config_t *cfg, size_t n)
{
if (n > 0)
return 0;
return downcast_config(cfg)->listen_addr;
}
/* Retrieve the target address for this configuration. */
static struct evutil_addrinfo *
dummy_config_get_target_addr(config_t *cfg)
{
return downcast_config(cfg)->target_addr;
}
/*
This is called everytime we get a connection for the dummy
protocol.
*/
static conn_t *
dummy_conn_create(config_t *cfg)
{
dummy_conn_t *proto = xzalloc(sizeof(dummy_conn_t));
proto->super.cfg = cfg;
proto->super.mode = downcast_config(cfg)->mode;
return &proto->super;
}
static void
dummy_conn_free(conn_t *proto)
{
free(downcast_conn(proto));
}
static circuit_t *
dummy_circuit_create(config_t *cfg)
{
dummy_circuit_t *circuit = xzalloc(sizeof(dummy_circuit_t));
return &circuit->super;
}
static void
dummy_circuit_free(circuit_t *circ)
{
free(downcast_circuit(circ));
}
/** Dummy has no handshake */
static int
dummy_handshake(conn_t *proto, struct evbuffer *buf)
{
return 0;
}
/** send, receive - just copy */
static int
dummy_send(conn_t *proto, struct evbuffer *source, struct evbuffer *dest)
{
return evbuffer_add_buffer(dest,source);
}
static enum recv_ret
dummy_recv(conn_t *proto, struct evbuffer *source, struct evbuffer *dest)
{
if (evbuffer_add_buffer(dest,source)<0)
return RECV_BAD;
else
return RECV_GOOD;
}
DEFINE_PROTOCOL_VTABLE(dummy);
/* Copyright 2011 Nick Mathewson, George Kadianakis
See LICENSE for other credits and copying information
*/
/**
* \file dummy.h
* \brief Headers for dummy.c.
**/
#ifndef PROTOCOL_DUMMY_H
#define PROTOCOL_DUMMY_H
extern const protocol_vtable dummy_vtable;
#ifdef PROTOCOL_DUMMY_PRIVATE
/* ==========
These definitions are not part of the dummy protocol interface.
They're exposed here so that the unit tests can use them.
==========
*/
#include "network.h"
#include "protocol.h"
/* Dummy presently needs only the obligatory extensions to the generic
protocol structures, but we have shims for future expansion, and
also because, if you're using dummy as a template, you probably
will want to extend the generic structures. */
/** \private \extends config_t */
typedef struct dummy_config_t {
config_t super;
struct evutil_addrinfo *listen_addr;
struct evutil_addrinfo *target_addr;
enum listen_mode mode;
} dummy_config_t;
/** \private \extends conn_t */
typedef struct dummy_conn_t {
conn_t super;
} dummy_conn_t;
/** \private \extends circuit_t */
typedef struct dummy_circuit_t {
circuit_t super;
} dummy_circuit_t;
#endif
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* Copyright (c) 2009-2012, The Tor Project, Inc. */
/* See the LICENSE file for licensing information */
/**
* \file sha256.h
* \brief Headers for sha256.c.
*
* \details This SHA256 implementation is adapted from the public
* domain one in LibTomCrypt, version 1.6. Tor uses it on platforms
* where OpenSSL doesn't have a SHA256.
**/
#ifndef SHA256_H
#define SHA256_H
typedef struct sha256_state {
uint64_t length;
uint32_t state[8], curlen;
unsigned char buf[64];
} sha256_state;
int sha256_init(sha256_state * md);
int sha256_process(sha256_state * md, const unsigned char *in,
unsigned long inlen);
int sha256_done(sha256_state * md, unsigned char *out);
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* Copyright 2012 The Tor Project
See LICENSE for other credits and copying information
*/
/**
* \file status.h
* \brief Headers for status.c.
**/
void status_init(void);
void status_cleanup(void);
void status_note_connection(const char *addrport);
void status_log_heartbeat(void);
void status_connections_clear(int reinit);
#define status_connections_cleanup() status_connections_clear(0)
#define status_connections_reinit() status_connections_clear(1)
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment