diff --git a/assets/shadowsocks b/assets/shadowsocks index c7f2e590..507b7dff 100755 Binary files a/assets/shadowsocks and b/assets/shadowsocks differ diff --git a/jni/shadowsocks/encrypt.c b/jni/shadowsocks/encrypt.c index e31384c5..379b42ab 100755 --- a/jni/shadowsocks/encrypt.c +++ b/jni/shadowsocks/encrypt.c @@ -1,9 +1,6 @@ #include "encrypt.h" #include "android.h" -#include -#include - static int random_compare(const void *_x, const void *_y) { uint32_t i = _i; uint64_t a = _a; @@ -115,30 +112,42 @@ static void mergesort(uint8_t array[], int length) } void encrypt(char *buf, int len) { - char *end = buf + len; - while (buf < end) { - *buf = (char)encrypt_table[(uint8_t)*buf]; - buf++; + if (_method == RC4_ENC) { + unsigned char mybuf[BUF_SIZE]; + RC4(&rc4_key, len, (unsigned char *) buf, mybuf); + memcpy(buf, mybuf, len); + } else { + char *end = buf + len; + while (buf < end) { + *buf = (char)encrypt_table[(uint8_t)*buf]; + buf++; + } } } void decrypt(char *buf, int len) { - char *end = buf + len; - while (buf < end) { - *buf = (char)decrypt_table[(uint8_t)*buf]; - buf++; + if (_method == RC4_ENC) { + unsigned char mybuf[BUF_SIZE]; + RC4(&rc4_key, len, (unsigned char *) buf, mybuf); + memcpy(buf, mybuf, len); + } else { + char *end = buf + len; + while (buf < end) { + *buf = (char)decrypt_table[(uint8_t)*buf]; + buf++; + } } } int send_encrypt(int sock, char *buf, int len, int flags) { - char mybuf[4096]; + char mybuf[BUF_SIZE]; memcpy(mybuf, buf, len); encrypt(mybuf, len); return send(sock, mybuf, len, flags); } int recv_decrypt(int sock, char *buf, int len, int flags) { - char mybuf[4096]; + char mybuf[BUF_SIZE]; int result = recv(sock, mybuf, len, flags); memcpy(buf, mybuf, len); decrypt(buf, len); @@ -146,20 +155,24 @@ int recv_decrypt(int sock, char *buf, int len, int flags) { } void get_table(const char* key) { - uint8_t *table = encrypt_table; - uint8_t *tmp_hash = MD5((const uint8_t*)key, strlen(key), NULL); - _a = htole64(*(uint64_t *)tmp_hash); - uint32_t i; + if (_method == RC4_ENC) { + RC4_set_key(&rc4_key, strlen(key), (unsigned char *) key); + } else { + uint8_t *table = encrypt_table; + uint8_t *tmp_hash = MD5((const uint8_t*)key, strlen(key), NULL); + _a = htole64(*(uint64_t *)tmp_hash); + uint32_t i; - for(i = 0; i < 256; ++i) { - table[i] = i; - } - for(i = 1; i < 1024; ++i) { - _i = i; - mergesort(table, 256); - } - for(i = 0; i < 256; ++i) { - // gen decrypt table from encrypt table - decrypt_table[encrypt_table[i]] = i; + for(i = 0; i < 256; ++i) { + table[i] = i; + } + for(i = 1; i < 1024; ++i) { + _i = i; + mergesort(table, 256); + } + for(i = 0; i < 256; ++i) { + // gen decrypt table from encrypt table + decrypt_table[encrypt_table[i]] = i; + } } } diff --git a/jni/shadowsocks/encrypt.h b/jni/shadowsocks/encrypt.h index 700398d1..eb2ee1ff 100755 --- a/jni/shadowsocks/encrypt.h +++ b/jni/shadowsocks/encrypt.h @@ -4,9 +4,19 @@ #include #include #include +#include +#include +#include + +#define BUF_SIZE 4096 + +#define TABLE_ENC 0 +#define RC4_ENC 1 unsigned char encrypt_table[256]; unsigned char decrypt_table[256]; +RC4_KEY rc4_key; + void get_table(const char* key); void encrypt(char *buf, int len); void decrypt(char *buf, int len); @@ -15,4 +25,5 @@ int recv_decrypt(int sock, char *buf, int len, int flags); unsigned int _i; unsigned long long _a; +int _method; diff --git a/jni/shadowsocks/local.c b/jni/shadowsocks/local.c index 36f22150..d523273b 100644 --- a/jni/shadowsocks/local.c +++ b/jni/shadowsocks/local.c @@ -21,7 +21,6 @@ #include "local.h" #include "socks5.h" -#include "encrypt.h" #include "android.h" #define min(a,b) (((a)<(b))?(a):(b)) @@ -567,12 +566,13 @@ int main (int argc, char **argv) char *port = NULL; char *key = NULL; char* timeout = "10"; + char* method = NULL; int c; int f_flags = 0; opterr = 0; - while ((c = getopt (argc, argv, "fs:p:l:k:t:")) != -1) { + while ((c = getopt (argc, argv, "fs:p:l:k:t:m:")) != -1) { switch (c) { case 's': server = optarg; @@ -592,6 +592,9 @@ int main (int argc, char **argv) case 't': timeout = optarg; break; + case 'm': + method = optarg; + break; } } @@ -600,6 +603,12 @@ int main (int argc, char **argv) exit(EXIT_FAILURE); } + if (method != NULL) { + if (strcmp(method, "rc4") == 0) { + _method = RC4_ENC; + } + } + if (f_flags) { /* Our process ID and Session ID */ @@ -653,7 +662,7 @@ int main (int argc, char **argv) _remote_port = strdup(remote_port); _timeout = atoi(timeout); - LOGD("calculating ciphers"); + LOGD("calculating ciphers %d", _method); get_table(key); int listenfd; diff --git a/jni/shadowsocks/local.h b/jni/shadowsocks/local.h index db8042fc..60a94e6e 100644 --- a/jni/shadowsocks/local.h +++ b/jni/shadowsocks/local.h @@ -2,7 +2,7 @@ #include -#define BUF_SIZE 4096 +#include "encrypt.h" struct listen_ctx { ev_io io; diff --git a/libs/armeabi/shadowsocks b/libs/armeabi/shadowsocks index c7f2e590..507b7dff 100755 Binary files a/libs/armeabi/shadowsocks and b/libs/armeabi/shadowsocks differ diff --git a/res/values/strings.xml b/res/values/strings.xml index 95702f0c..afead46d 100755 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -61,10 +61,15 @@ Shadowsocks is an open source socks proxy.\n\nYou can find more details here:\ngithub.com/shadowsocks About - Proxy Type - - GAE - PaaS + + Encrypt Method + + Table + RC4 + + + table + rc4 diff --git a/res/xml/shadowsocks_preference.xml b/res/xml/shadowsocks_preference.xml index 9701c28b..3b026e80 100755 --- a/res/xml/shadowsocks_preference.xml +++ b/res/xml/shadowsocks_preference.xml @@ -39,6 +39,14 @@ android:summary="@string/sitekey_summary" android:title="@string/sitekey"> + +