-
-
Save dawei1/769379564917dca6af2dee45dc943e02 to your computer and use it in GitHub Desktop.
OpenVPN 2.3.0 obfs patch based on https://gist.github.com/4372285. AUR https://aur.archlinux.org/packages/openvpn-obfs/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- options_orig.c 2016-09-29 11:30:57.761475911 +0800 | |
+++ options.c 2016-09-29 11:37:34.348475911 +0800 | |
@@ -59,6 +59,9 @@ | |
#include <ctype.h> | |
#include "memdbg.h" | |
+extern char* _socket_obfs_salt; | |
+extern int _socket_obfs_salt_len; | |
+extern int _socket_obfs_padlen; | |
const char title_string[] = | |
PACKAGE_STRING | |
@@ -7115,6 +7118,19 @@ | |
options->persist_config = true; | |
options->persist_mode = 1; | |
} | |
+ else if (streq (p[0], "obfs-salt") && p[1]) | |
+ { | |
+ VERIFY_PERMISSION (OPT_P_GENERAL); | |
+ _socket_obfs_salt = p[1]; | |
+ _socket_obfs_salt_len = strlen(_socket_obfs_salt); | |
+ } | |
+ else if (streq (p[0], "obfs-padlen") && p[1]) | |
+ { | |
+ VERIFY_PERMISSION (OPT_P_GENERAL); | |
+ _socket_obfs_padlen = atoi(p[1]); | |
+ if (_socket_obfs_padlen < 0) | |
+ msg(M_ERR, "--obfs-padlen must be positive"); | |
+ } | |
else if (streq (p[0], "peer-id") && p[1]) | |
{ | |
VERIFY_PERMISSION (OPT_P_PEER_ID); | |
--- socket_orig.c 2016-09-29 11:31:22.406475911 +0800 | |
+++ socket.c 2016-09-29 11:40:04.790475911 +0800 | |
@@ -40,6 +40,9 @@ | |
#include "misc.h" | |
#include "memdbg.h" | |
+const char* _socket_obfs_salt = NULL; | |
+int _socket_obfs_salt_len = 0; | |
+int _socket_obfs_padlen = 0; | |
const int proto_overhead[] = { /* indexed by PROTO_x */ | |
0, | |
@@ -51,6 +54,48 @@ | |
IPv6_TCP_HEADER_SIZE, | |
IPv6_TCP_HEADER_SIZE, | |
}; | |
+/** | |
+ * @return int The length of the random string that should be padding to the packet | |
+ */ | |
+int obfs_buffer(const struct buffer* buf, const void* rand, int randlen, int maxpadlen) { | |
+ unsigned char md[SHA_DIGEST_LENGTH]; | |
+ unsigned char iv[randlen + _socket_obfs_salt_len + SHA_DIGEST_LENGTH]; | |
+ unsigned char *c; | |
+ int i, len, pad_len = 0; | |
+ | |
+ if (maxpadlen > 255) | |
+ maxpadlen = 255; | |
+ | |
+ /* key_1 = SHA1(rand + obfs_salt) */ | |
+ /* pad_len = Low _rand_pad_level_ bits of (unsigned char)MD5(rand + obfs_salt)[0] */ | |
+ memcpy(iv, rand, randlen); | |
+ memcpy(iv + randlen, _socket_obfs_salt, _socket_obfs_salt_len); | |
+ | |
+ /* Caculate length of padding string */ | |
+ ASSERT(SHA_DIGEST_LENGTH >= MD5_DIGEST_LENGTH); | |
+ MD5(iv, randlen + _socket_obfs_salt_len, md); /* SHA_DIGEST_LENGTH is bigger than MD5_DIGEST_LENGTH, it's safe here */ | |
+ if (maxpadlen <= 0) | |
+ pad_len = 0; | |
+ else | |
+ pad_len = md[0] % (maxpadlen + 1); | |
+ | |
+ /* Obsfucation data */ | |
+ len = BLEN(buf); | |
+ SHA1(iv, randlen + _socket_obfs_salt_len, md); | |
+ for (i = 0, c = BPTR(buf); i < len; i++, c++) | |
+ { | |
+ *c ^= md[i % SHA_DIGEST_LENGTH]; | |
+ | |
+ /* Regenerate obsfuction key: key_n+1 = SHA1(key_n) */ | |
+ if (i % SHA_DIGEST_LENGTH == SHA_DIGEST_LENGTH - 1) | |
+ { | |
+ memcpy(iv, md, SHA_DIGEST_LENGTH); | |
+ SHA1(iv, SHA_DIGEST_LENGTH, md); | |
+ } | |
+ } | |
+ | |
+ return pad_len; | |
+} | |
/* | |
* Convert sockflags/getaddr_flags into getaddr_flags | |
--- socket_orig.h 2016-09-29 11:31:29.433475911 +0800 | |
+++ socket.h 2016-09-29 11:47:24.982475911 +0800 | |
@@ -35,6 +35,10 @@ | |
#include "proxy.h" | |
#include "socks.h" | |
#include "misc.h" | |
+extern int _socket_obfs_salt_len; | |
+extern int _socket_obfs_padlen; | |
+ | |
+int obfs_buffer(const struct buffer* buf, const void* rand, int randlen, int rand_pad_level); | |
/* | |
* OpenVPN's default port number as assigned by IANA. | |
@@ -875,28 +879,57 @@ | |
struct buffer *buf, | |
struct link_socket_actual *from) | |
{ | |
+ int res; | |
+ | |
+ struct buffer tbuf; | |
+ | |
if (proto_is_udp(sock->info.proto)) /* unified UDPv4 and UDPv6 */ | |
{ | |
- int res; | |
- | |
#ifdef WIN32 | |
res = link_socket_read_udp_win32 (sock, buf, from); | |
#else | |
res = link_socket_read_udp_posix (sock, buf, from); | |
#endif | |
- return res; | |
} | |
else if (proto_is_tcp(sock->info.proto)) /* unified TCPv4 and TCPv6 */ | |
{ | |
/* from address was returned by accept */ | |
addr_copy_sa(&from->dest, &sock->info.lsa->actual.dest); | |
- return link_socket_read_tcp (sock, buf); | |
+ res = link_socket_read_tcp (sock, buf); | |
} | |
else | |
{ | |
ASSERT (0); | |
return -1; /* NOTREACHED */ | |
} | |
+ /* Decode obsfucated traffic */ | |
+ if (_socket_obfs_salt_len > 0 && BLEN(buf) > 4) | |
+ { | |
+ int r; | |
+ int pad_len = 0; | |
+ | |
+ memcpy((void*)&r, BPTR(buf), 4); | |
+ | |
+ msg(D_LINK_RW_VERBOSE, "1, read buflen=%d", BLEN(buf)); | |
+ | |
+ tbuf = alloc_buf(BLEN(buf) - 4); | |
+ buf_copy_range(&tbuf, 0, buf, 4, BLEN(buf) - 4); | |
+ pad_len = obfs_buffer(&tbuf, &r, 4, _socket_obfs_padlen); | |
+ | |
+ /* Remove padding random string */ | |
+ buf_clear(buf); | |
+ buf_prepend(buf, BLEN(&tbuf) - pad_len); | |
+ buf_copy_range(buf, 0, &tbuf, 0, BLEN(&tbuf) - pad_len); | |
+ | |
+ msg(D_LINK_RW_VERBOSE, "1, read buflen=%d, padlen=%d", BLEN(buf), pad_len); | |
+ free_buf(&tbuf); | |
+ | |
+ res -= 4; | |
+ res -= pad_len; | |
+ | |
+ } | |
+ | |
+ return res; | |
} | |
/* | |
@@ -939,6 +972,35 @@ | |
struct buffer *buf, | |
struct link_socket_actual *to) | |
{ | |
+ struct buffer tbuf; | |
+ | |
+ /* Obsfucate traffic */ | |
+ if (_socket_obfs_salt_len > 0) | |
+ { | |
+ int pad_len, i; | |
+ int r = rand(); | |
+ | |
+ msg(D_LINK_RW_VERBOSE, "1, write buflen=%d", BLEN(buf)); | |
+ | |
+ pad_len = obfs_buffer(buf, &r, sizeof(r), _socket_obfs_padlen); | |
+ | |
+ tbuf = alloc_buf(BLEN(buf) + 4 + pad_len); | |
+ buf_write(&tbuf, (void*)&r, 4); | |
+ buf_copy_range(&tbuf, 4, buf, 0, BLEN(buf)); | |
+ for (i = 0; i < pad_len; i++) | |
+ { | |
+ if (unlikely(i % 4 == 0)) | |
+ r = rand(); | |
+ | |
+ buf_write(&tbuf, (void*)&r + i % 4, 1); | |
+ } | |
+ | |
+ buf_copy_range(buf, 0, &tbuf, 0, BLEN(&tbuf)); | |
+ msg(D_LINK_RW_VERBOSE, "2, write buflen=%d", BLEN(buf)); | |
+ | |
+ free_buf(&tbuf); | |
+ } | |
+ | |
#if ENABLE_IP_PKTINFO | |
int link_socket_write_udp_posix_sendmsg (struct link_socket *sock, | |
struct buffer *buf, |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
然并卵