Browse Source

Merge pull request #4 from madeye/openssl

Support more ciphers
pull/8/head
Max Lv 12 years ago
parent
commit
5a7a8eecdf
19 changed files with 410 additions and 356 deletions
  1. 26
      README.md
  2. 2
      ar-lib
  3. 59
      configure
  4. 4
      configure.ac
  5. 1
      debian/changelog
  6. 5
      shadowsocks.8
  7. 6
      src/Makefile.am
  8. 16
      src/Makefile.in
  9. 243
      src/encrypt.c
  10. 58
      src/encrypt.h
  11. 41
      src/local.c
  12. 15
      src/local.h
  13. 103
      src/rc4.c
  14. 55
      src/rc4.h
  15. 70
      src/redir.c
  16. 13
      src/redir.h
  17. 35
      src/server.c
  18. 11
      src/server.h
  19. 3
      src/utils.c

26
README.md

@ -11,7 +11,28 @@ It is a port of [shadowsocks](https://github.com/clowwindy/shadowsocks)
created by [@clowwindy](https://github.com/clowwindy) maintained by
[@madeye](https://github.com/madeye).
Current version: 1.2 [![Build Status](https://travis-ci.org/madeye/shadowsocks-libev.png?branch=master)](https://travis-ci.org/madeye/shadowsocks-libev)
Current version: 1.3 [![Build Status](https://travis-ci.org/madeye/shadowsocks-libev.png?branch=master)](https://travis-ci.org/madeye/shadowsocks-libev)
Changelog
---------
shadowsocks 1.3 -- Thu, 16 May 2013 10:51:15 +0800
* Able to bind connections to specific interface
* Support more ciphers: aes-128-cfb, aes-192-cfb, aes-256-cfb, bf-cfb, cast5-cfb, des-cfb
shadowsocks 1.2 -- Tue, 07 May 2013 14:10:33 +0800
* Close timeouted TCP connections
* Fix a high load issue
shadowsocks 1.1 -- Wed, 10 Apr 2013 12:11:36 +0800
* Fix a IPV6 resolve issue
shadowsocks 1.0 -- Sat, 06 Apr 2013 16:59:15 +0800
* Initial release
Features
--------
@ -52,7 +73,8 @@ usage:
options:
encrypt_method: table, rc4
encrypt_method: table, rc4, aes-128-cfb, aes-192-cfb, aes-256-cfb,
bf-cfb, cast5-cfb, des-cfb
pid_file: valid path to the pid file
timeout: socket timeout in senconds
config_file: json format config file

2
ar-lib

@ -4,7 +4,7 @@
me=ar-lib
scriptversion=2012-03-01.08; # UTC
# Copyright (C) 2010-2013 Free Software Foundation, Inc.
# Copyright (C) 2010, 2012 Free Software Foundation, Inc.
# Written by Peter Rosin <peda@lysator.liu.se>.
#
# This program is free software; you can redistribute it and/or modify

59
configure

@ -10850,6 +10850,65 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing MD5" >&5
$as_echo_n "checking for library containing MD5... " >&6; }
if test "${ac_cv_search_MD5+set}" = set; then :
$as_echo_n "(cached) " >&6
else
ac_func_search_save_LIBS=$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 MD5 ();
int
main ()
{
return MD5 ();
;
return 0;
}
_ACEOF
for ac_lib in '' crypto; do
if test -z "$ac_lib"; then
ac_res="none required"
else
ac_res=-l$ac_lib
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
fi
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_search_MD5=$ac_res
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext
if test "${ac_cv_search_MD5+set}" = set; then :
break
fi
done
if test "${ac_cv_search_MD5+set}" = set; then :
else
ac_cv_search_MD5=no
fi
rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_MD5" >&5
$as_echo "$ac_cv_search_MD5" >&6; }
ac_res=$ac_cv_search_MD5
if test "$ac_res" != no; then :
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
else
as_fn_error $? "libcrypto not found." "$LINENO" 5
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for what kind of host" >&5
$as_echo_n "checking for what kind of host... " >&6; }
case $host in

4
configure.ac

@ -16,8 +16,12 @@ AC_PROG_LIBTOOL
AC_PROG_LN_S
AC_PROG_MAKE_SET
dnl Checks for libev
m4_include([libev/libev.m4])
dnl Checks for openssl
AC_SEARCH_LIBS([MD5], [crypto], [ ], AC_MSG_ERROR([libcrypto not found.]))
dnl Checks for host.
AC_MSG_CHECKING(for what kind of host)
case $host in

1
debian/changelog

@ -1,6 +1,7 @@
shadowsocks (1.3-1) unstable; urgency=low
* Able to bind connections to specific interface
* Support more ciphers: aes-128-cfb, aes-192-cfb, aes-256-cfb, bf-cfb, cast5-cfb, des-cfb
-- Max Lv <max.c.lv@gmail.com> Thu, 16 May 2013 10:51:15 +0800

5
shadowsocks.8

@ -66,8 +66,9 @@ Set the shadowsocks password. The server and the client should use the same
password.
.TP
.B \-m \fIencrypt_method\fP
Set the shadowsocks encryption method. Currently, shadowsocks accepts two
encryption methods: table or rc4. And the default method is \fItable\fP.
Set the shadowsocks encryption method. Currently, shadowsocks accepts several
encryption methods: table, rc4, aes-128-cfb, aes-192-cfb, aes-256-cfb, bf-cfb,
cast5-cfb and des-cfb. The default method is \fItable\fP.
.TP
.B \-f \fIpid_file\fP
Start shadowsocks as a daemon with a specific pid file.

6
src/Makefile.am

@ -1,9 +1,9 @@
bin_PROGRAMS = ss-local ss-server
ss_local_SOURCES = utils.c jconf.c json.c \
rc4.c md5.c encrypt.c \
encrypt.c \
local.c
ss_server_SOURCES = utils.c jconf.c json.c \
rc4.c md5.c encrypt.c \
encrypt.c \
server.c
ss_local_LDADD = $(top_builddir)/libev/libev.la
ss_server_LDADD = $(top_builddir)/libev/libev.la
@ -12,7 +12,7 @@ ss_server_LDADD += $(top_builddir)/libasyncns/libasyncns.la
if BUILD_REDIRECTOR
bin_PROGRAMS += ss-redir
ss_redir_SOURCES = utils.c jconf.c json.c \
rc4.c md5.c encrypt.c \
encrypt.c \
redir.c
ss_redir_LDADD = $(top_builddir)/libev/libev.la
endif

16
src/Makefile.in

@ -54,20 +54,18 @@ CONFIG_CLEAN_VPATH_FILES =
am__installdirs = "$(DESTDIR)$(bindir)"
PROGRAMS = $(bin_PROGRAMS)
am_ss_local_OBJECTS = utils.$(OBJEXT) jconf.$(OBJEXT) json.$(OBJEXT) \
rc4.$(OBJEXT) md5.$(OBJEXT) encrypt.$(OBJEXT) local.$(OBJEXT)
encrypt.$(OBJEXT) local.$(OBJEXT)
ss_local_OBJECTS = $(am_ss_local_OBJECTS)
ss_local_DEPENDENCIES = $(top_builddir)/libev/libev.la
am__ss_redir_SOURCES_DIST = utils.c jconf.c json.c rc4.c md5.c \
encrypt.c redir.c
am__ss_redir_SOURCES_DIST = utils.c jconf.c json.c encrypt.c redir.c
@BUILD_REDIRECTOR_TRUE@am_ss_redir_OBJECTS = utils.$(OBJEXT) \
@BUILD_REDIRECTOR_TRUE@ jconf.$(OBJEXT) json.$(OBJEXT) \
@BUILD_REDIRECTOR_TRUE@ rc4.$(OBJEXT) md5.$(OBJEXT) \
@BUILD_REDIRECTOR_TRUE@ encrypt.$(OBJEXT) redir.$(OBJEXT)
ss_redir_OBJECTS = $(am_ss_redir_OBJECTS)
@BUILD_REDIRECTOR_TRUE@ss_redir_DEPENDENCIES = \
@BUILD_REDIRECTOR_TRUE@ $(top_builddir)/libev/libev.la
am_ss_server_OBJECTS = utils.$(OBJEXT) jconf.$(OBJEXT) json.$(OBJEXT) \
rc4.$(OBJEXT) md5.$(OBJEXT) encrypt.$(OBJEXT) server.$(OBJEXT)
encrypt.$(OBJEXT) server.$(OBJEXT)
ss_server_OBJECTS = $(am_ss_server_OBJECTS)
ss_server_DEPENDENCIES = $(top_builddir)/libev/libev.la \
$(top_builddir)/libasyncns/libasyncns.la
@ -206,18 +204,18 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
ss_local_SOURCES = utils.c jconf.c json.c \
rc4.c md5.c encrypt.c \
encrypt.c \
local.c
ss_server_SOURCES = utils.c jconf.c json.c \
rc4.c md5.c encrypt.c \
encrypt.c \
server.c
ss_local_LDADD = $(top_builddir)/libev/libev.la
ss_server_LDADD = $(top_builddir)/libev/libev.la \
$(top_builddir)/libasyncns/libasyncns.la
@BUILD_REDIRECTOR_TRUE@ss_redir_SOURCES = utils.c jconf.c json.c \
@BUILD_REDIRECTOR_TRUE@ rc4.c md5.c encrypt.c \
@BUILD_REDIRECTOR_TRUE@ encrypt.c \
@BUILD_REDIRECTOR_TRUE@ redir.c
@BUILD_REDIRECTOR_TRUE@ss_redir_LDADD = $(top_builddir)/libev/libev.la
@ -321,8 +319,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jconf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/json.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/local.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rc4.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/redir.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@

243
src/encrypt.c

@ -3,28 +3,48 @@
#endif
#include <stdint.h>
#include <openssl/md5.h>
#include "encrypt.h"
#include "utils.h"
#define OFFSET_ROL(p, o) ((uint64_t)(*(p + o)) << (8 * o))
static void md5(const uint8_t *text, uint8_t *digest) {
md5_state_t state;
md5_init(&state);
md5_append(&state, text, strlen((char*)text));
md5_finish(&state, digest);
static uint8_t *enc_table;
static uint8_t *dec_table;
static char *enc_pass;
#ifdef DEBUG
static dump(char *tag, char *text) {
int i, len;
len = strlen(text);
printf("%s: ", tag);
for (i = 0; i < len; i++) {
printf("0x%02x ", (uint8_t)text[i]);
}
printf("\n");
}
#endif
static const char* supported_ciphers[8] = {
"table",
"rc4",
"aes-128-cfb",
"aes-192-cfb",
"aes-256-cfb",
"bf-cfb",
"cast5-cfb",
"des-cfb"
};
static int random_compare(const void *_x, const void *_y) {
uint32_t i = enc_conf.ctx.table.salt;
uint64_t a = enc_conf.ctx.table.key;
static int random_compare(const void *_x, const void *_y, uint32_t i, uint64_t a) {
uint8_t x = *((uint8_t *) _x);
uint8_t y = *((uint8_t*) _y);
return (a % (x + i) - a % (y + i));
}
static void merge(uint8_t *left, int llength, uint8_t *right, int rlength)
{
static void merge(uint8_t *left, int llength, uint8_t *right,
int rlength, uint32_t salt, uint64_t key) {
uint8_t *ltmp = (uint8_t *) malloc(llength * sizeof(uint8_t));
uint8_t *rtmp = (uint8_t *) malloc(rlength * sizeof(uint8_t));
@ -37,7 +57,7 @@ static void merge(uint8_t *left, int llength, uint8_t *right, int rlength)
memcpy(rtmp, right, rlength * sizeof(uint8_t));
while (llength > 0 && rlength > 0) {
if (random_compare(ll, rr) <= 0) {
if (random_compare(ll, rr, salt, key) <= 0) {
*result = *ll;
++ll;
--llength;
@ -68,8 +88,8 @@ static void merge(uint8_t *left, int llength, uint8_t *right, int rlength)
free(rtmp);
}
static void merge_sort(uint8_t array[], int length)
{
static void merge_sort(uint8_t array[], int length,
uint32_t salt, uint64_t key) {
uint8_t middle;
uint8_t *left, *right;
int llength;
@ -84,87 +104,164 @@ static void merge_sort(uint8_t array[], int length)
left = array;
right = array + llength;
merge_sort(left, llength);
merge_sort(right, middle);
merge(left, llength, right, middle);
}
void encrypt_ctx(char *buf, int len, struct rc4_state *ctx) {
if (ctx != NULL) {
rc4_crypt(ctx, (uint8_t*) buf, (uint8_t*) buf, len);
} else {
char *end = buf + len;
while (buf < end) {
*buf = (char)enc_conf.ctx.table.encrypt_table[(uint8_t)*buf];
buf++;
}
}
}
void decrypt_ctx(char *buf, int len, struct rc4_state *ctx) {
if (ctx != NULL) {
rc4_crypt(ctx, (uint8_t*) buf, (uint8_t*) buf, len);
} else {
char *end = buf + len;
while (buf < end) {
*buf = (char)enc_conf.ctx.table.decrypt_table[(uint8_t)*buf];
buf++;
}
}
}
void enc_ctx_init(struct rc4_state *ctx, int enc) {
uint8_t *key = enc_conf.ctx.rc4.key;
int key_len = enc_conf.ctx.rc4.key_len;
rc4_init(ctx, key, key_len);
}
static void enc_rc4_init(const char *pass) {
enc_conf.ctx.rc4.key_len = 16;
enc_conf.ctx.rc4.key = malloc(16);
md5((const uint8_t*)pass, enc_conf.ctx.rc4.key);
merge_sort(left, llength, salt, key);
merge_sort(right, middle, salt, key);
merge(left, llength, right, middle, salt, key);
}
static void enc_table_init(const char *pass) {
uint8_t *enc_table = malloc(256);
uint8_t *dec_table = malloc(256);
uint8_t digest[16];
uint32_t *salt = &enc_conf.ctx.table.salt;
uint64_t *key = &enc_conf.ctx.table.key;
void enc_table_init(const char *pass) {
uint32_t i;
uint32_t salt;
uint64_t key = 0;
uint8_t *digest;
md5((const uint8_t*)pass, digest);
enc_table = malloc(256);
dec_table = malloc(256);
digest = MD5((const uint8_t *)pass, strlen(pass), NULL);
*key = 0;
for (i = 0; i < 8; i++) {
*key += OFFSET_ROL(digest, i);
key += OFFSET_ROL(digest, i);
}
for(i = 0; i < 256; ++i) {
enc_table[i] = i;
}
for(i = 1; i < 1024; ++i) {
*salt = i;
merge_sort(enc_table, 256);
salt = i;
merge_sort(enc_table, 256, salt, key);
}
for(i = 0; i < 256; ++i) {
// gen decrypt table from encrypt table
dec_table[enc_table[i]] = i;
}
}
char* encrypt(char *plaintext, ssize_t *len, struct enc_ctx *ctx) {
if (ctx != NULL) {
int c_len = *len + BLOCK_SIZE;
int iv_len = ctx->iv_len;
char *ciphertext = malloc(max(iv_len + c_len, BUF_SIZE));
if (!ctx->init) {
uint8_t iv[EVP_MAX_IV_LENGTH];
int i;
for (i = 0; i < iv_len; i++) {
iv[i] = rand() % 256;
}
EVP_CipherInit_ex(&ctx->evp, NULL, NULL, ctx->key, iv, 1);
memcpy(ciphertext, iv, iv_len);
ctx->iv_len = 0;
ctx->init = 1;
#ifdef DEBUG
dump("IV", ctx->iv);
#endif
}
EVP_EncryptUpdate(&ctx->evp, (uint8_t*)(ciphertext+iv_len),
&c_len, (const uint8_t *)plaintext, *len);
#ifdef DEBUG
dump("PLAIN", plaintext);
dump("CIPHER", ciphertext);
#endif
*len = iv_len + c_len;
free(plaintext);
return ciphertext;
} else {
char *begin = plaintext;
while (plaintext < begin + *len) {
*plaintext = (char)enc_table[(uint8_t)*plaintext];
plaintext++;
}
return begin;
}
}
char* decrypt(char *ciphertext, ssize_t *len, struct enc_ctx *ctx) {
if (ctx != NULL) {
int p_len = *len + BLOCK_SIZE;
int iv_len = ctx->iv_len;
char *plaintext = malloc(max(p_len, BUF_SIZE));
if (!ctx->init) {
uint8_t iv[EVP_MAX_IV_LENGTH];
memcpy(iv, ciphertext, iv_len);
EVP_CipherInit_ex(&ctx->evp, NULL, NULL, ctx->key, iv, 0);
ctx->iv_len = 0;
ctx->init = 1;
#ifdef DEBUG
dump("IV", ctx->iv);
#endif
}
EVP_DecryptUpdate(&ctx->evp, (uint8_t*)plaintext, &p_len,
(const uint8_t*)(ciphertext + iv_len), *len - iv_len);
#ifdef DEBUG
dump("PLAIN", plaintext);
dump("CIPHER", ciphertext);
#endif
enc_conf.ctx.table.encrypt_table = enc_table;
enc_conf.ctx.table.decrypt_table = dec_table;
*len = p_len;
free(ciphertext);
return plaintext;
} else {
char *begin = ciphertext;
while (ciphertext < begin + *len) {
*ciphertext = (char)dec_table[(uint8_t)*ciphertext];
ciphertext++;
}
return begin;
}
}
void enc_conf_init(const char *pass, const char *method) {
enc_conf.method = TABLE;
if (method != NULL && strcmp(method, "rc4") == 0) {
enc_conf.method = RC4;
void enc_ctx_init(int method, struct enc_ctx *ctx, int enc) {
uint8_t *key = ctx->key;
uint8_t iv[EVP_MAX_IV_LENGTH];
int key_len;
memset(ctx, 0, sizeof(struct enc_ctx));
EVP_CIPHER_CTX *evp = &ctx->evp;
OpenSSL_add_all_algorithms();
const EVP_CIPHER *cipher = EVP_get_cipherbyname(supported_ciphers[method]);
ctx->iv_len = EVP_CIPHER_iv_length(cipher);
key_len = EVP_BytesToKey(cipher, EVP_md5(), NULL, (uint8_t *)enc_pass,
strlen(enc_pass), 1, key, iv);
EVP_CIPHER_CTX_init(evp);
EVP_CipherInit_ex(evp, cipher, NULL, NULL, NULL, enc);
if (!EVP_CIPHER_CTX_set_key_length(evp, key_len)) {
EVP_CIPHER_CTX_cleanup(evp);
LOGE("Invalid key length: %d", key_len);
exit(EXIT_FAILURE);
}
if (enc_conf.method == TABLE) {
enc_table_init(pass);
} else if (enc_conf.method == RC4) {
enc_rc4_init(pass);
EVP_CIPHER_CTX_set_padding(evp, 1);
}
int enc_init(const char *pass, const char *method) {
enc_pass = strdup(pass);
if (method == NULL || strcmp(method, "table") == 0) {
enc_table_init(enc_pass);
return TABLE;
} else if (strcmp(method, "aes-128-cfb") == 0) {
return AES_128_CFB;
} else if (strcmp(method, "aes-192-cfb") == 0) {
return AES_192_CFB;
} else if (strcmp(method, "aes-256-cfb") == 0) {
return AES_256_CFB;
} else if (strcmp(method, "bf-cfb") == 0) {
return BF_CFB;
} else if (strcmp(method, "cast5-cfb") == 0) {
return CAST5_CFB;
} else if (strcmp(method, "des-cfb") == 0) {
return DES_CFB;
} else if (strcmp(method, "rc4") == 0) {
return RC4;
}
return TABLE;
}

58
src/encrypt.h

@ -8,40 +8,40 @@
#include <stdlib.h>
#include <stdio.h>
#include <openssl/evp.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#elif HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#include "md5.h"
#include "rc4.h"
#define BUF_SIZE 4096
#define TABLE 0
#define RC4 1
struct {
int method;
union {
struct {
uint8_t *encrypt_table;
uint8_t *decrypt_table;
uint32_t salt;
uint64_t key;
} table;
struct {
uint8_t *key;
int key_len;
} rc4;
} ctx;
} enc_conf;
void encrypt_ctx(char *buf, int len, struct rc4_state *ctx);
void decrypt_ctx(char *buf, int len, struct rc4_state *ctx);
void enc_ctx_init(struct rc4_state *ctx, int enc);
void enc_conf_init(const char *pass, const char *method);
#define BUF_SIZE 512
#define BLOCK_SIZE 32
#define NONE -1
#define TABLE 0
#define RC4 1
#define AES_128_CFB 2
#define AES_192_CFB 3
#define AES_256_CFB 4
#define BF_CFB 5
#define CAST5_CFB 6
#define DES_CFB 7
#define min(a,b) (((a)<(b))?(a):(b))
#define max(a,b) (((a)>(b))?(a):(b))
struct enc_ctx {
uint8_t init;
uint8_t iv_len;
uint8_t key[EVP_MAX_KEY_LENGTH];
EVP_CIPHER_CTX evp;
};
char* encrypt(char *plaintext, ssize_t *len, struct enc_ctx *ctx);
char* decrypt(char *ciphertext, ssize_t *len, struct enc_ctx *ctx);
void enc_ctx_init(int method, struct enc_ctx *ctx, int enc);
int enc_init(const char *pass, const char *method);
#endif // _ENCRYPT_H

41
src/local.c

@ -36,8 +36,6 @@
#define EWOULDBLOCK EAGAIN
#endif
#define min(a,b) (((a)<(b))?(a):(b))
int setnonblocking(int fd) {
int flags;
if (-1 ==(flags = fcntl(fd, F_GETFL, 0)))
@ -140,7 +138,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
// local socks5 server
if (server->stage == 5) {
encrypt_ctx(remote->buf, r, server->e_ctx);
remote->buf = encrypt(remote->buf, &r, server->e_ctx);
int s = send(remote->fd, remote->buf, r, 0);
if(s == -1) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
@ -188,8 +186,8 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
return;
}
char addr_to_send[256];
uint8_t addr_len = 0;
char *addr_to_send = malloc(BUF_SIZE);
ssize_t addr_len = 0;
addr_to_send[addr_len++] = request->atyp;
// get remote addr and port
@ -223,8 +221,10 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
return;
}
encrypt_ctx(addr_to_send, addr_len, server->e_ctx);
addr_to_send = encrypt(addr_to_send, &addr_len, server->e_ctx);
int s = send(remote->fd, addr_to_send, addr_len, 0);
free(addr_to_send);
if (s < addr_len) {
LOGE("failed to send remote addr.");
close_and_free_remote(EV_A_ remote);
@ -352,7 +352,7 @@ static void remote_recv_cb (EV_P_ ev_io *w, int revents) {
}
}
decrypt_ctx(server->buf, r, server->d_ctx);
server->buf = decrypt(server->buf, &r, server->d_ctx);
int s = send(server->fd, server->buf, r, 0);
if (s == -1) {
@ -445,6 +445,7 @@ static void remote_send_cb (EV_P_ ev_io *w, int revents) {
struct remote* new_remote(int fd, int timeout) {
struct remote *remote;
remote = malloc(sizeof(struct remote));
remote->buf = malloc(BUF_SIZE);
remote->recv_ctx = malloc(sizeof(struct remote_ctx));
remote->send_ctx = malloc(sizeof(struct remote_ctx));
remote->fd = fd;
@ -465,6 +466,7 @@ void free_remote(struct remote *remote) {
if (remote->server != NULL) {
remote->server->remote = NULL;
}
free(remote->buf);
free(remote->recv_ctx);
free(remote->send_ctx);
free(remote);
@ -481,9 +483,10 @@ void close_and_free_remote(EV_P_ struct remote *remote) {
}
}
struct server* new_server(int fd) {
struct server* new_server(int fd, int method) {
struct server *server;
server = malloc(sizeof(struct server));
server->buf = malloc(BUF_SIZE);
server->recv_ctx = malloc(sizeof(struct server_ctx));
server->send_ctx = malloc(sizeof(struct server_ctx));
server->fd = fd;
@ -494,11 +497,11 @@ struct server* new_server(int fd) {
server->send_ctx->server = server;
server->send_ctx->connected = 0;
server->stage = 0;
if (enc_conf.method == RC4) {
server->e_ctx = malloc(sizeof(struct rc4_state));
server->d_ctx = malloc(sizeof(struct rc4_state));
enc_ctx_init(server->e_ctx, 1);
enc_ctx_init(server->d_ctx, 0);
if (method) {
server->e_ctx = malloc(sizeof(struct enc_ctx));
server->d_ctx = malloc(sizeof(struct enc_ctx));
enc_ctx_init(method, server->e_ctx, 1);
enc_ctx_init(method, server->d_ctx, 0);
} else {
server->e_ctx = NULL;
server->d_ctx = NULL;
@ -513,10 +516,15 @@ void free_server(struct server *server) {
if (server->remote != NULL) {
server->remote->server = NULL;
}
if (enc_conf.method == RC4) {
if (server->e_ctx != NULL) {
EVP_CIPHER_CTX_cleanup(&server->e_ctx->evp);
free(server->e_ctx);
}
if (server->d_ctx != NULL) {
EVP_CIPHER_CTX_cleanup(&server->d_ctx->evp);
free(server->d_ctx);
}
free(server->buf);
free(server->recv_ctx);
free(server->send_ctx);
free(server);
@ -577,7 +585,7 @@ static void accept_cb (EV_P_ ev_io *w, int revents) {
if (listener->iface) setinterface(sockfd, listener->iface);
#endif
struct server *server = new_server(serverfd);
struct server *server = new_server(serverfd, listener->method);
struct remote *remote = new_remote(sockfd, listener->timeout);
server->remote = remote;
remote->server = server;
@ -676,7 +684,7 @@ int main (int argc, char **argv) {
// Setup keys
LOGD("calculating ciphers...");
enc_conf_init(password, method);
int m = enc_init(password, method);
// Setup socket
int listenfd;
@ -702,6 +710,7 @@ int main (int argc, char **argv) {
listen_ctx.timeout = atoi(timeout);
listen_ctx.fd = listenfd;
listen_ctx.iface = iface;
listen_ctx.method = m;
struct ev_loop *loop = ev_default_loop(0);
if (!loop) {

15
src/local.h

@ -8,9 +8,10 @@
struct listen_ctx {
ev_io io;
char **remote_host;
int remote_num;
char *remote_port;
char *iface;
int remote_num;
int method;
int timeout;
int fd;
struct sockaddr sock;
@ -24,12 +25,12 @@ struct server_ctx {
struct server {
int fd;
char buf[BUF_SIZE]; // server send from, remote recv into
char stage;
int buf_len;
int buf_idx;
struct rc4_state *e_ctx;
struct rc4_state *d_ctx;
char *buf; // server send from, remote recv into
char stage;
struct enc_ctx *e_ctx;
struct enc_ctx *d_ctx;
struct server_ctx *recv_ctx;
struct server_ctx *send_ctx;
struct remote *remote;
@ -44,9 +45,9 @@ struct remote_ctx {
struct remote {
int fd;
char buf[BUF_SIZE]; // remote send from, server recv into
int buf_len;
int buf_idx;
char *buf; // remote send from, server recv into
struct remote_ctx *recv_ctx;
struct remote_ctx *send_ctx;
struct server *server;
@ -61,7 +62,7 @@ static void remote_send_cb (EV_P_ ev_io *w, int revents);
struct remote* new_remote(int fd, int timeout);
void free_remote(struct remote *remote);
void close_and_free_remote(EV_P_ struct remote *remote);
struct server* new_server(int fd);
struct server* new_server(int fd, int method);
void free_server(struct server *server);
void close_and_free_server(EV_P_ struct server *server);

103
src/rc4.c

@ -1,103 +0,0 @@
/*
* rc4.c
*
* Copyright (c) 1996-2000 Whistle Communications, Inc.
* All rights reserved.
*
* Subject to the following obligations and disclaimer of warranty, use and
* redistribution of this software, in source or object code forms, with or
* without modifications are expressly permitted by Whistle Communications;
* provided, however, that:
* 1. Any and all reproductions of the source or object code must include the
* copyright notice above and the following disclaimer of warranties; and
* 2. No rights are granted, in any manner or form, to use Whistle
* Communications, Inc. trademarks, including the mark "WHISTLE
* COMMUNICATIONS" on advertising, endorsements, or otherwise except as
* such appears in the above copyright notice or in the software.
*
* THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
* TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
* REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
* INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
* WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
* REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
* SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
* IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
* RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
* WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* $FreeBSD: src/sys/crypto/rc4/rc4.c,v 1.2.2.1 2000/04/18 04:48:31 archie Exp $
*/
#include <stdint.h>
#include "rc4.h"
static inline void
swap_bytes(u_char *a, u_char *b)
{
u_char temp;
temp = *a;
*a = *b;
*b = temp;
}
/*
* Initialize an RC4 state buffer using the supplied key,
* which can have arbitrary length.
*/
void
rc4_init(struct rc4_state *const state, const u_char *key, int keylen)
{
u_char j;
int i;
/* Initialize state with identity permutation */
for (i = 0; i < 256; i++)
state->perm[i] = (u_char)i;
state->index1 = 0;
state->index2 = 0;
/* Randomize the permutation using key data */
for (j = i = 0; i < 256; i++) {
j += state->perm[i] + key[i % keylen];
swap_bytes(&state->perm[i], &state->perm[j]);
}
}
/*
* Encrypt some data using the supplied RC4 state buffer.
* The input and output buffers may be the same buffer.
* Since RC4 is a stream cypher, this function is used
* for both encryption and decryption.
*/
void
rc4_crypt(struct rc4_state *const state,
const u_char *inbuf, u_char *outbuf, int buflen)
{
int i;
u_char j;
for (i = 0; i < buflen; i++) {
/* Update modification indicies */
state->index1++;
state->index2 += state->perm[state->index1];
/* Modify permutation */
swap_bytes(&state->perm[state->index1],
&state->perm[state->index2]);
/* Encrypt/decrypt next byte */
j = state->perm[state->index1] + state->perm[state->index2];
outbuf[i] = inbuf[i] ^ state->perm[j];
}
}

55
src/rc4.h

@ -1,55 +0,0 @@
/*
* rc4.h
*
* Copyright (c) 1996-2000 Whistle Communications, Inc.
* All rights reserved.
*
* Subject to the following obligations and disclaimer of warranty, use and
* redistribution of this software, in source or object code forms, with or
* without modifications are expressly permitted by Whistle Communications;
* provided, however, that:
* 1. Any and all reproductions of the source or object code must include the
* copyright notice above and the following disclaimer of warranties; and
* 2. No rights are granted, in any manner or form, to use Whistle
* Communications, Inc. trademarks, including the mark "WHISTLE
* COMMUNICATIONS" on advertising, endorsements, or otherwise except as
* such appears in the above copyright notice or in the software.
*
* THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
* TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
* REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
* INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
* WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
* REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
* SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
* IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
* RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
* WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* $FreeBSD: src/sys/crypto/rc4/rc4.h,v 1.2.2.1 2000/04/18 04:48:32 archie Exp $
*/
#ifndef RC4_H_
#define RC4_H_
typedef uint8_t u_char;
struct rc4_state {
u_char perm[256];
u_char index1;
u_char index2;
};
void rc4_init(struct rc4_state *state, const u_char *key, int keylen);
void rc4_crypt(struct rc4_state *state,
const u_char *inbuf, u_char *outbuf, int buflen);
#endif

70
src/redir.c

@ -31,8 +31,6 @@
#define EWOULDBLOCK EAGAIN
#endif
#define min(a,b) (((a)<(b))?(a):(b))
int getdestaddr(int fd, struct sockaddr_in *destaddr) {
socklen_t socklen = sizeof(*destaddr);
int error;
@ -72,10 +70,11 @@ int create_and_bind(const char *port) {
continue;
int opt = 1;
int err = setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
if (err) {
ERROR("setsocket");
}
setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
setsockopt(listen_sock, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
#ifdef SO_NOSIGPIPE
setsockopt(listen_sock, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
#endif
s = bind(listen_sock, rp->ai_addr, rp->ai_addrlen);
if (s == 0) {
@ -132,7 +131,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
}
}
encrypt_ctx(remote->buf, r, server->e_ctx);
remote->buf = encrypt(remote->buf, &r, server->e_ctx);
int s = send(remote->fd, remote->buf, r, 0);
if(s == -1) {
@ -252,7 +251,7 @@ static void remote_recv_cb (EV_P_ ev_io *w, int revents) {
}
}
decrypt_ctx(server->buf, r, server->d_ctx);
server->buf = decrypt(server->buf, &r, server->d_ctx);
int s = send(server->fd, server->buf, r, 0);
if (s == -1) {
@ -294,8 +293,8 @@ static void remote_send_cb (EV_P_ ev_io *w, int revents) {
ev_timer_stop(EV_A_ &remote_send_ctx->watcher);
// send destaddr
char addr_to_send[256];
uint8_t addr_len = 0;
char *addr_to_send = malloc(BUF_SIZE);
ssize_t addr_len = 0;
addr_to_send[addr_len++] = 1;
// handle IP V4 only
@ -304,9 +303,11 @@ static void remote_send_cb (EV_P_ ev_io *w, int revents) {
addr_len += in_addr_len;
memcpy(addr_to_send + addr_len, &server->destaddr.sin_port, 2);
addr_len += 2;
encrypt_ctx(addr_to_send, addr_len, server->e_ctx);
addr_to_send = encrypt(addr_to_send, &addr_len, server->e_ctx);
int s = send(remote->fd, addr_to_send, addr_len, 0);
free(addr_to_send);
if (s < addr_len) {
LOGE("failed to send remote addr.");
close_and_free_remote(EV_A_ remote);
@ -368,6 +369,7 @@ static void remote_send_cb (EV_P_ ev_io *w, int revents) {
struct remote* new_remote(int fd, int timeout) {
struct remote *remote;
remote = malloc(sizeof(struct remote));
remote->buf = malloc(BUF_SIZE);
remote->recv_ctx = malloc(sizeof(struct remote_ctx));
remote->send_ctx = malloc(sizeof(struct remote_ctx));
remote->fd = fd;
@ -388,6 +390,7 @@ void free_remote(struct remote *remote) {
if (remote->server != NULL) {
remote->server->remote = NULL;
}
free(remote->buf);
free(remote->recv_ctx);
free(remote->send_ctx);
free(remote);
@ -404,9 +407,10 @@ void close_and_free_remote(EV_P_ struct remote *remote) {
}
}
struct server* new_server(int fd) {
struct server* new_server(int fd, int method) {
struct server *server;
server = malloc(sizeof(struct server));
server->buf = malloc(BUF_SIZE);
server->recv_ctx = malloc(sizeof(struct server_ctx));
server->send_ctx = malloc(sizeof(struct server_ctx));
server->fd = fd;
@ -416,11 +420,11 @@ struct server* new_server(int fd) {
server->recv_ctx->connected = 0;
server->send_ctx->server = server;
server->send_ctx->connected = 0;
if (enc_conf.method == RC4) {
server->e_ctx = malloc(sizeof(struct rc4_state));
server->d_ctx = malloc(sizeof(struct rc4_state));
enc_ctx_init(server->e_ctx, 1);
enc_ctx_init(server->d_ctx, 0);
if (method) {
server->e_ctx = malloc(sizeof(struct enc_ctx));
server->d_ctx = malloc(sizeof(struct enc_ctx));
enc_ctx_init(method, server->e_ctx, 1);
enc_ctx_init(method, server->d_ctx, 0);
} else {
server->e_ctx = NULL;
server->d_ctx = NULL;
@ -435,10 +439,15 @@ void free_server(struct server *server) {
if (server->remote != NULL) {
server->remote->server = NULL;
}
if (enc_conf.method == RC4) {
if (server->e_ctx != NULL) {
EVP_CIPHER_CTX_cleanup(&server->e_ctx->evp);
free(server->e_ctx);
}
if (server->d_ctx != NULL) {
EVP_CIPHER_CTX_cleanup(&server->d_ctx->evp);
free(server->d_ctx);
}
free(server->buf);
free(server->recv_ctx);
free(server->send_ctx);
free(server);
@ -472,6 +481,11 @@ static void accept_cb (EV_P_ ev_io *w, int revents) {
}
setnonblocking(clientfd);
int opt = 1;
setsockopt(clientfd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
#ifdef SO_NOSIGPIPE
setsockopt(clientfd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
#endif
struct addrinfo hints, *res;
int sockfd;
@ -493,18 +507,15 @@ static void accept_cb (EV_P_ ev_io *w, int revents) {
return;
}
struct timeval timeout;
timeout.tv_sec = listener->timeout;
timeout.tv_usec = 0;
err = setsockopt(sockfd, SOL_SOCKET,
SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
if (err) ERROR("setsockopt");
err = setsockopt(sockfd, SOL_SOCKET,
SO_SNDTIMEO, (char *)&timeout, sizeof(timeout));
if (err) ERROR("setsockopt");
setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
#ifdef SO_NOSIGPIPE
setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
#endif
// Setup
setnonblocking(sockfd);
struct server *server = new_server(clientfd);
struct server *server = new_server(clientfd, listener->method);
struct remote *remote = new_remote(sockfd, listener->timeout);
server->remote = remote;
remote->server = server;
@ -601,7 +612,7 @@ int main (int argc, char **argv) {
// Setup keys
LOGD("calculating ciphers...");
enc_conf_init(password, method);
int m = enc_init(password, method);
// Setup socket
int listenfd;
@ -626,6 +637,7 @@ int main (int argc, char **argv) {
listen_ctx.remote_port = remote_port;
listen_ctx.timeout = atoi(timeout);
listen_ctx.fd = listenfd;
listen_ctx.method = m;
struct ev_loop *loop = ev_default_loop(0);
if (!loop) {

13
src/redir.h

@ -8,10 +8,11 @@
struct listen_ctx {
ev_io io;
char **remote_host;
int remote_num;
char *remote_port;
int remote_num;
int timeout;
int fd;
int method;
struct sockaddr sock;
};
@ -23,12 +24,12 @@ struct server_ctx {
struct server {
int fd;
char buf[BUF_SIZE]; // server send from, remote recv into
int buf_len;
int buf_idx;
char *buf; // server send from, remote recv into
struct sockaddr_in destaddr;
struct rc4_state *e_ctx;
struct rc4_state *d_ctx;
struct enc_ctx *e_ctx;
struct enc_ctx *d_ctx;
struct server_ctx *recv_ctx;
struct server_ctx *send_ctx;
struct remote *remote;
@ -43,9 +44,9 @@ struct remote_ctx {
struct remote {
int fd;
char buf[BUF_SIZE]; // remote send from, server recv into
int buf_len;
int buf_idx;
char *buf; // remote send from, server recv into
struct remote_ctx *recv_ctx;
struct remote_ctx *send_ctx;
struct server *server;
@ -60,7 +61,7 @@ static void remote_send_cb (EV_P_ ev_io *w, int revents);
struct remote* new_remote(int fd, int timeout);
void free_remote(struct remote *remote);
void close_and_free_remote(EV_P_ struct remote *remote);
struct server* new_server(int fd);
struct server* new_server(int fd, int method);
void free_server(struct server *server);
void close_and_free_server(EV_P_ struct server *server);

35
src/server.c

@ -35,8 +35,6 @@
#define EWOULDBLOCK EAGAIN
#endif
#define min(a,b) (((a)<(b))?(a):(b))
static int verbose = 0;
static int remote_conn = 0;
static int server_conn = 0;
@ -142,16 +140,16 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
struct server *server = server_recv_ctx->server;
struct remote *remote = NULL;
char *buf = server->buf;
char **buf = &server->buf;
ev_timer_again(EV_A_ &server->recv_ctx->watcher);
if (server->stage != 0) {
remote = server->remote;
buf = remote->buf;
buf = &remote->buf;
}
ssize_t r = recv(server->fd, buf, BUF_SIZE, 0);
ssize_t r = recv(server->fd, *buf, BUF_SIZE, 0);
if (r == 0) {
// connection closed
@ -174,7 +172,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
}
}
decrypt_ctx(buf, r, server->d_ctx);
*buf = decrypt(*buf, &r, server->d_ctx);
// handshake and transmit data
if (server->stage == 5) {
@ -482,7 +480,7 @@ static void remote_recv_cb (EV_P_ ev_io *w, int revents) {
}
}
encrypt_ctx(server->buf, r, server->e_ctx);
server->buf = encrypt(server->buf, &r, server->e_ctx);
int s = send(server->fd, server->buf, r, 0);
if (s == -1) {
@ -596,6 +594,7 @@ struct remote* new_remote(int fd) {
remote_conn++;
struct remote *remote;
remote = malloc(sizeof(struct remote));
remote->buf = malloc(BUF_SIZE);
remote->recv_ctx = malloc(sizeof(struct remote_ctx));
remote->send_ctx = malloc(sizeof(struct remote_ctx));
remote->fd = fd;
@ -617,6 +616,7 @@ void free_remote(struct remote *remote) {
if (remote->server != NULL) {
remote->server->remote = NULL;
}
free(remote->buf);
free(remote->recv_ctx);
free(remote->send_ctx);
free(remote);
@ -639,6 +639,7 @@ struct server* new_server(int fd, struct listen_ctx *listener) {
server_conn++;
struct server *server;
server = malloc(sizeof(struct server));
server->buf = malloc(BUF_SIZE);
server->recv_ctx = malloc(sizeof(struct server_ctx));
server->send_ctx = malloc(sizeof(struct server_ctx));
server->fd = fd;
@ -653,11 +654,11 @@ struct server* new_server(int fd, struct listen_ctx *listener) {
server->stage = 0;
server->query = NULL;
server->listen_ctx = listener;
if (enc_conf.method == RC4) {
server->e_ctx = malloc(sizeof(struct rc4_state));
server->d_ctx = malloc(sizeof(struct rc4_state));
enc_ctx_init(server->e_ctx, 1);
enc_ctx_init(server->d_ctx, 0);
if (listener->method) {
server->e_ctx = malloc(sizeof(struct enc_ctx));
server->d_ctx = malloc(sizeof(struct enc_ctx));
enc_ctx_init(listener->method, server->e_ctx, 1);
enc_ctx_init(listener->method, server->d_ctx, 0);
} else {
server->e_ctx = NULL;
server->d_ctx = NULL;
@ -674,10 +675,15 @@ void free_server(struct server *server) {
if (server->remote != NULL) {
server->remote->server = NULL;
}
if (enc_conf.method == RC4) {
if (server->e_ctx != NULL) {
EVP_CIPHER_CTX_cleanup(&server->e_ctx->evp);
free(server->e_ctx);
}
if (server->d_ctx != NULL) {
EVP_CIPHER_CTX_cleanup(&server->d_ctx->evp);
free(server->d_ctx);
}
free(server->buf);
free(server->recv_ctx);
free(server->send_ctx);
free(server);
@ -813,7 +819,7 @@ int main (int argc, char **argv) {
// Setup keys
LOGD("calculating ciphers...");
enc_conf_init(password, method);
int m = enc_init(password, method);
// Inilitialize ev loop
struct ev_loop *loop = EV_DEFAULT;
@ -840,6 +846,7 @@ int main (int argc, char **argv) {
listen_ctx.timeout = atoi(timeout);
listen_ctx.asyncns = asyncns;
listen_ctx.fd = listenfd;
listen_ctx.method = m;
listen_ctx.iface = iface;
ev_io_init (&listen_ctx.io, accept_cb, listenfd, EV_READ);

11
src/server.h

@ -12,6 +12,7 @@ struct listen_ctx {
ev_io io;
int fd;
int timeout;
int method;
char *iface;
asyncns_t *asyncns;
struct sockaddr sock;
@ -26,12 +27,12 @@ struct server_ctx {
struct server {
int fd;
char buf[BUF_SIZE]; // server send from, remote recv into
char stage;
int buf_len;
int buf_idx;
struct rc4_state *e_ctx;
struct rc4_state *d_ctx;
char *buf; // server send from, remote recv into
char stage;
struct enc_ctx *e_ctx;
struct enc_ctx *d_ctx;
struct server_ctx *recv_ctx;
struct server_ctx *send_ctx;
struct listen_ctx *listen_ctx;
@ -47,9 +48,9 @@ struct remote_ctx {
struct remote {
int fd;
char buf[BUF_SIZE]; // remote send from, server recv into
int buf_len;
int buf_idx;
char *buf; // remote send from, server recv into
struct remote_ctx *recv_ctx;
struct remote_ctx *send_ctx;
struct server *server;

3
src/utils.c

@ -70,7 +70,8 @@ void usage() {
printf(" [-m encrypt_method] [-f pid_file] [-t timeout] [-c config_file]\n");
printf("\n");
printf(" options:\n\n");
printf(" encrypt_method: table, rc4\n");
printf(" encrypt_method: table, rc4, aes-128-cfb, aes-192-cfb, aes-256-cfb,\n");
printf(" bf-cfb, cast5-cfb, des-cfb\n");
printf(" pid_file: valid path to the pid file\n");
printf(" timeout: socket timeout in senconds\n");
printf(" config_file: json format config file\n");

Loading…
Cancel
Save