Last active
March 22, 2023 09:17
Revisions
-
greensea revised this gist
Jan 24, 2013 . 1 changed file with 18 additions and 9 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -1,5 +1,5 @@ --- openvpn-2.2.2.orig/options.c 2011-12-14 00:58:56.000000000 +0800 +++ openvpn-2.2.2/options.c 2012-12-21 10:44:57.683130505 +0800 @@ -54,6 +54,10 @@ #include "memdbg.h" @@ -26,13 +26,13 @@ + 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 (file) --- openvpn-2.2.2.orig/socket.c 2011-12-14 00:58:56.000000000 +0800 +++ openvpn-2.2.2/socket.c 2012-12-21 10:44:57.707131191 +0800 @@ -35,6 +35,10 @@ #include "memdbg.h" @@ -95,7 +95,7 @@ * Convert sockflags/getaddr_flags into getaddr_flags */ --- openvpn-2.2.2.orig/socket.h 2011-12-14 00:58:56.000000000 +0800 +++ openvpn-2.2.2/socket.h 2013-01-24 10:48:37.559033278 +0800 @@ -36,6 +36,11 @@ #include "socks.h" #include "misc.h" @@ -108,12 +108,14 @@ /* * OpenVPN's default port number as assigned by IANA. */ @@ -740,28 +745,60 @@ int maxsize, struct link_socket_actual *from) { + int res; + + struct buffer tbuf; + + if (sock->info.proto == PROTO_UDPv4) { @@ -146,6 +148,8 @@ + int pad_len = 0; + + memcpy((void*)&r, BPTR(buf), 4); + + msg(M_DEBUG, "1, read buflen=%d", BLEN(buf)); + + tbuf = alloc_buf(BLEN(buf) - 4); + buf_copy_range(&tbuf, 0, buf, 4, BLEN(buf) - 4); @@ -156,6 +160,8 @@ + buf_prepend(buf, BLEN(&tbuf) - pad_len); + buf_copy_range(buf, 0, &tbuf, 0, BLEN(&tbuf) - pad_len); + + msg(M_DEBUG, "1, read buflen=%d, padlen=%d", BLEN(buf), pad_len); + + free_buf(&tbuf); + + res -= 4; @@ -167,7 +173,7 @@ } /* @@ -846,6 +883,37 @@ struct buffer *buf, struct link_socket_actual *to) { @@ -179,6 +185,8 @@ + int pad_len, i; + int r = rand(); + + msg(M_DEBUG, "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); @@ -192,8 +200,9 @@ + buf_write(&tbuf, (void*)&r + i % 4, 1); + } + + buf_copy_range(buf, 0, &tbuf, 0, BLEN(&tbuf)); + + msg(M_DEBUG, "2, write buflen=%d", BLEN(buf)); + + free_buf(&tbuf); + } -
greensea created this gist
Dec 25, 2012 .There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,204 @@ --- openvpn-2.2.2.orig/options.c 2011-12-14 00:58:56.000000000 +0800 +++ openvpn-2.2.2/options.c 2012-12-21 10:45:39.460326791 +0800 @@ -54,6 +54,10 @@ #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 " " TARGET_ALIAS @@ -6008,6 +6012,19 @@ options->persist_mode = 1; } #endif + 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, "Options error: --obfs-padlen must be positive"); + } else { if (file) --- openvpn-2.2.2.orig/socket.c 2011-12-14 00:58:56.000000000 +0800 +++ openvpn-2.2.2/socket.c 2012-12-21 10:17:48.461242936 +0800 @@ -35,6 +35,10 @@ #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 */ IPv4_UDP_HEADER_SIZE, IPv4_TCP_HEADER_SIZE, @@ -42,6 +46,49 @@ IPv4_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 */ --- openvpn-2.2.2.orig/socket.h 2011-12-14 00:58:56.000000000 +0800 +++ openvpn-2.2.2/socket.h 2012-12-21 14:47:38.102212066 +0800 @@ -36,6 +36,11 @@ #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. */ @@ -740,28 +745,54 @@ int maxsize, struct link_socket_actual *from) { + int res; + struct buffer tbuf; + if (sock->info.proto == PROTO_UDPv4) { - int res; - #ifdef WIN32 res = link_socket_read_udp_win32 (sock, buf, from); #else res = link_socket_read_udp_posix (sock, buf, maxsize, from); #endif - return res; } else if (sock->info.proto == PROTO_TCPv4_SERVER || sock->info.proto == PROTO_TCPv4_CLIENT) { /* from address was returned by accept */ from->dest.sa = sock->info.lsa->actual.dest.sa; - 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); + + 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); + + free_buf(&tbuf); + + res -= 4; + res -= pad_len; + + } + + return res; } /* @@ -846,6 +877,34 @@ 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(); + + 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_clear(buf); + buf_copy(buf, &tbuf); + + free_buf(&tbuf); + } + + if (sock->info.proto == PROTO_UDPv4) { return link_socket_write_udp (sock, buf, to);