masktunnel 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,18 @@
1
+ # Include Go source files in masktunnel_go directory
2
+ recursive-include masktunnel_go *.go
3
+ include go.mod
4
+ include go.sum
5
+
6
+ # Include documentation
7
+ include README.md
8
+
9
+ # Exclude unnecessary files
10
+ global-exclude __pycache__
11
+ global-exclude *.py[co]
12
+ global-exclude .git*
13
+ global-exclude *.so
14
+ global-exclude *.dylib
15
+ global-exclude *.dll
16
+
17
+ # Exclude existing bindings directory to force rebuild
18
+ prune masktunnellib
@@ -0,0 +1,38 @@
1
+ Metadata-Version: 2.4
2
+ Name: masktunnel
3
+ Version: 0.1.0
4
+ Summary: Python bindings for MaskTunnel (Go)
5
+ Home-page: https://github.com/cloudflyer-project/masktunnel
6
+ Author: cloudflyer-project
7
+ License: GPL-3.0
8
+ Platform: any
9
+ Requires-Python: >=3.9
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: setuptools>=40.0
12
+ Provides-Extra: dev
13
+ Requires-Dist: pytest>=6.0; extra == "dev"
14
+ Requires-Dist: pytest-xdist; extra == "dev"
15
+ Requires-Dist: build; extra == "dev"
16
+ Requires-Dist: wheel; extra == "dev"
17
+ Dynamic: author
18
+ Dynamic: description
19
+ Dynamic: description-content-type
20
+ Dynamic: home-page
21
+ Dynamic: license
22
+ Dynamic: platform
23
+ Dynamic: provides-extra
24
+ Dynamic: requires-dist
25
+ Dynamic: requires-python
26
+ Dynamic: summary
27
+
28
+ # masktunnel (Python bindings)
29
+
30
+ This directory contains the Python package that wraps MaskTunnel's Go implementation via gopy.
31
+
32
+ - Package name: `masktunnel`
33
+ - Native module directory (generated at build time): `masktunnellib/`
34
+
35
+ Build notes:
36
+
37
+ - Building from source requires Go and a C toolchain.
38
+ - Wheels are produced by CI for common platforms.
@@ -0,0 +1,11 @@
1
+ # masktunnel (Python bindings)
2
+
3
+ This directory contains the Python package that wraps MaskTunnel's Go implementation via gopy.
4
+
5
+ - Package name: `masktunnel`
6
+ - Native module directory (generated at build time): `masktunnellib/`
7
+
8
+ Build notes:
9
+
10
+ - Building from source requires Go and a C toolchain.
11
+ - Wheels are produced by CI for common platforms.
@@ -0,0 +1,46 @@
1
+ module github.com/cloudflyer-project/masktunnel
2
+
3
+ go 1.24.0
4
+
5
+ toolchain go1.24.4
6
+
7
+ require (
8
+ github.com/Noooste/azuretls-client v1.12.3
9
+ github.com/Noooste/fhttp v1.0.15
10
+ github.com/Noooste/utls v1.3.19
11
+ github.com/Noooste/websocket v1.0.3
12
+ github.com/andybalholm/brotli v1.2.0
13
+ github.com/cristalhq/base64 v0.1.2
14
+ github.com/gorilla/websocket v1.5.3
15
+ github.com/mileusna/useragent v1.3.4
16
+ github.com/rs/zerolog v1.34.0
17
+ github.com/spf13/pflag v1.0.10
18
+ github.com/valyala/fasthttp v1.65.0
19
+ )
20
+
21
+ require (
22
+ github.com/Noooste/go-socks4 v0.0.2 // indirect
23
+ github.com/Noooste/uquic-go v0.0.31 // indirect
24
+ github.com/bdandy/go-errors v1.2.2 // indirect
25
+ github.com/cloudflare/circl v1.6.1 // indirect
26
+ github.com/fatih/color v1.18.0 // indirect
27
+ github.com/gaukas/clienthellod v0.4.2 // indirect
28
+ github.com/gaukas/godicttls v0.0.4 // indirect
29
+ github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
30
+ github.com/google/gopacket v1.1.19 // indirect
31
+ github.com/klauspost/compress v1.18.0 // indirect
32
+ github.com/mattn/go-colorable v0.1.14 // indirect
33
+ github.com/mattn/go-isatty v0.0.20 // indirect
34
+ github.com/quic-go/qpack v0.5.1 // indirect
35
+ github.com/refraction-networking/utls v1.7.3 // indirect
36
+ github.com/valyala/bytebufferpool v1.0.0 // indirect
37
+ go.uber.org/automaxprocs v1.6.0 // indirect
38
+ go.uber.org/mock v0.5.2 // indirect
39
+ golang.org/x/crypto v0.41.0 // indirect
40
+ golang.org/x/mod v0.26.0 // indirect
41
+ golang.org/x/net v0.43.0 // indirect
42
+ golang.org/x/sync v0.16.0 // indirect
43
+ golang.org/x/sys v0.35.0 // indirect
44
+ golang.org/x/text v0.28.0 // indirect
45
+ golang.org/x/tools v0.35.0 // indirect
46
+ )
@@ -0,0 +1,116 @@
1
+ github.com/Noooste/azuretls-client v1.12.3 h1:4GYXdN7J+WbGkj4oseeBUS+Eng/wm7QnAwz6gpqMjio=
2
+ github.com/Noooste/azuretls-client v1.12.3/go.mod h1:9PYT3hB8DWHyuL5z/iXCEYhy6v3oKazjBO1x4lqvghA=
3
+ github.com/Noooste/fhttp v1.0.15 h1:sYRWOKgr1x4L+wA6REMJCs4Z/lFOSJmuQHSIXMXCcPs=
4
+ github.com/Noooste/fhttp v1.0.15/go.mod h1:YZtq+i2M11Y22UiOR6gjNSLMNLiPhURh6M44oFVQ1TE=
5
+ github.com/Noooste/go-socks4 v0.0.2 h1:DwHCYiCEAdjfNrQOFIid7qgKCll7ubhGS1ji5O8FYng=
6
+ github.com/Noooste/go-socks4 v0.0.2/go.mod h1:+oOgtOFRsU8FoK7NBOhHSjiH5pveY8LgYNF5XcqVgjE=
7
+ github.com/Noooste/uquic-go v0.0.31 h1:gYIyrpcH2Znykw1dj9vsOEu0ArT8RlN46rIAehnaqMU=
8
+ github.com/Noooste/uquic-go v0.0.31/go.mod h1:8UUkSe8ILdcVl0/vutpZDjySNlgajKod+xlS3T3GBnE=
9
+ github.com/Noooste/utls v1.3.19 h1:B4HjzRTXj6T/tMBgp/u8jsbgnlitaRHEz8+0FKgZYH0=
10
+ github.com/Noooste/utls v1.3.19/go.mod h1:XEy+VEbTxmH6krfSG5YT7wDbjHTEi2zUXTG33R0PAAg=
11
+ github.com/Noooste/websocket v1.0.3 h1:drW7tvZ3YqzqI9wApnaH1Q0syFMXO7gbLlsBWjZvMNA=
12
+ github.com/Noooste/websocket v1.0.3/go.mod h1:Qhw0Rtuju/fPPbcb3R5XGq7poa51qPDL462jTltl9nQ=
13
+ github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ=
14
+ github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
15
+ github.com/bdandy/go-errors v1.2.2 h1:WdFv/oukjTJCLa79UfkGmwX7ZxONAihKu4V0mLIs11Q=
16
+ github.com/bdandy/go-errors v1.2.2/go.mod h1:NkYHl4Fey9oRRdbB1CoC6e84tuqQHiqrOcZpqFEkBxM=
17
+ github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
18
+ github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
19
+ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
20
+ github.com/cristalhq/base64 v0.1.2 h1:edsefYyYDiac7Ytdh2xdaiiSSJzcI2f0yIkdGEf1qY0=
21
+ github.com/cristalhq/base64 v0.1.2/go.mod h1:sy4+2Hale2KbtSqkzpdMeYTP/IrB+HCvxVHWsh2VSYk=
22
+ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
23
+ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
24
+ github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
25
+ github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
26
+ github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
27
+ github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
28
+ github.com/gaukas/clienthellod v0.4.2 h1:LPJ+LSeqt99pqeCV4C0cllk+pyWmERisP7w6qWr7eqE=
29
+ github.com/gaukas/clienthellod v0.4.2/go.mod h1:M57+dsu0ZScvmdnNxaxsDPM46WhSEdPYAOdNgfL7IKA=
30
+ github.com/gaukas/godicttls v0.0.4 h1:NlRaXb3J6hAnTmWdsEKb9bcSBD6BvcIjdGdeb0zfXbk=
31
+ github.com/gaukas/godicttls v0.0.4/go.mod h1:l6EenT4TLWgTdwslVb4sEMOCf7Bv0JAK67deKr9/NCI=
32
+ github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
33
+ github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
34
+ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
35
+ github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
36
+ github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
37
+ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
38
+ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
39
+ github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
40
+ github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
41
+ github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a h1://KbezygeMJZCSHH+HgUZiTeSoiuFspbMg1ge+eFj18=
42
+ github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA=
43
+ github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
44
+ github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
45
+ github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
46
+ github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
47
+ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
48
+ github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
49
+ github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
50
+ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
51
+ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
52
+ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
53
+ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
54
+ github.com/mileusna/useragent v1.3.4 h1:MiuRRuvGjEie1+yZHO88UBYg8YBC/ddF6T7F56i3PCk=
55
+ github.com/mileusna/useragent v1.3.4/go.mod h1:3d8TOmwL/5I8pJjyVDteHtgDGcefrFUX4ccGOMKNYYc=
56
+ github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
57
+ github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
58
+ github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y=
59
+ github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
60
+ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
61
+ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
62
+ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
63
+ github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
64
+ github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
65
+ github.com/refraction-networking/utls v1.7.3 h1:L0WRhHY7Oq1T0zkdzVZMR6zWZv+sXbHB9zcuvsAEqCo=
66
+ github.com/refraction-networking/utls v1.7.3/go.mod h1:TUhh27RHMGtQvjQq+RyO11P6ZNQNBb3N0v7wsEjKAIQ=
67
+ github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
68
+ github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY=
69
+ github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ=
70
+ github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
71
+ github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
72
+ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
73
+ github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
74
+ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
75
+ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
76
+ github.com/valyala/fasthttp v1.65.0 h1:j/u3uzFEGFfRxw79iYzJN+TteTJwbYkru9uDp3d0Yf8=
77
+ github.com/valyala/fasthttp v1.65.0/go.mod h1:P/93/YkKPMsKSnATEeELUCkG8a7Y+k99uxNHVbKINr4=
78
+ github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
79
+ github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
80
+ go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
81
+ go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
82
+ go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko=
83
+ go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o=
84
+ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
85
+ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
86
+ golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
87
+ golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
88
+ golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 h1:y5zboxd6LQAqYIhHnB48p0ByQ/GnQx2BE33L8BOHQkI=
89
+ golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ=
90
+ golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
91
+ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
92
+ golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=
93
+ golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
94
+ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
95
+ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
96
+ golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
97
+ golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
98
+ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
99
+ golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
100
+ golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
101
+ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
102
+ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
103
+ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
104
+ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
105
+ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
106
+ golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
107
+ golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
108
+ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
109
+ golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
110
+ golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
111
+ golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
112
+ golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
113
+ golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
114
+ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
115
+ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
116
+ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
@@ -0,0 +1,11 @@
1
+ """masktunnel: Python bindings for MaskTunnel (Go).
2
+
3
+ This package provides a Python-friendly API on top of the generated native bindings.
4
+ """
5
+
6
+ __version__ = "0.1.0"
7
+
8
+ from ._server import Server
9
+ from ._utils import set_log_level
10
+
11
+ __all__ = ["Server", "set_log_level"]
@@ -0,0 +1,86 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ import logging
5
+ from dataclasses import dataclass
6
+ from typing import Optional
7
+
8
+ # Underlying Go bindings module (generated by gopy)
9
+ from masktunnellib import masktunnel as gomasktunnel # type: ignore
10
+
11
+ from ._utils import _logger
12
+
13
+
14
+ @dataclass
15
+ class ServerOptions:
16
+ addr: str = ""
17
+ port: str = "8080"
18
+ user_agent: str = ""
19
+ payload: str = ""
20
+ upstream_proxy: str = ""
21
+ username: str = ""
22
+ password: str = ""
23
+ verbose: int = 0
24
+
25
+
26
+ class Server:
27
+ """MaskTunnel proxy server.
28
+
29
+ Notes:
30
+ - `start()` is blocking, so typical usage is `asyncio.to_thread(server.start)`.
31
+ - Use `stop()` to shutdown.
32
+ """
33
+
34
+ def __init__(self, *, options: Optional[ServerOptions] = None, logger: Optional[logging.Logger] = None) -> None:
35
+ if logger is None:
36
+ logger = _logger
37
+ self._logger = logger
38
+
39
+ if options is None:
40
+ opt = gomasktunnel.DefaultServerOption()
41
+ else:
42
+ opt = gomasktunnel.DefaultServerOption()
43
+ opt.Addr = options.addr
44
+ opt.Port = options.port
45
+ opt.UserAgent = options.user_agent
46
+ opt.Payload = options.payload
47
+ opt.UpstreamProxy = options.upstream_proxy
48
+ opt.Username = options.username
49
+ opt.Password = options.password
50
+ opt.Verbose = int(options.verbose)
51
+
52
+ self._raw = gomasktunnel.NewServerHandle(opt)
53
+
54
+ @property
55
+ def addr(self) -> str:
56
+ return self._raw.Addr()
57
+
58
+ def start(self) -> None:
59
+ self._raw.Start()
60
+
61
+ async def async_start(self) -> None:
62
+ await asyncio.to_thread(self._raw.Start)
63
+
64
+ def stop(self) -> None:
65
+ self._raw.Stop()
66
+
67
+ async def async_stop(self) -> None:
68
+ await asyncio.to_thread(self._raw.Stop)
69
+
70
+ def reset_sessions(self) -> int:
71
+ return int(self._raw.ResetSessions())
72
+
73
+ def set_upstream_proxy(self, proxy_url: str) -> None:
74
+ self._raw.SetUpstreamProxy(proxy_url)
75
+
76
+ def get_ca_pem(self) -> bytes:
77
+ return bytes(self._raw.GetCAPEM() or b"")
78
+
79
+ def close(self) -> None:
80
+ try:
81
+ self._raw.Close()
82
+ except Exception:
83
+ pass
84
+
85
+ async def async_close(self) -> None:
86
+ await asyncio.to_thread(self.close)
@@ -0,0 +1,15 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+
5
+
6
+ _logger = logging.getLogger("masktunnel")
7
+
8
+
9
+ def set_log_level(level: int) -> None:
10
+ """Set python-side log level.
11
+
12
+ Go-side logging is currently controlled by the Go application.
13
+ This helper only adjusts the default Python logger used by the wrappers.
14
+ """
15
+ _logger.setLevel(level)
@@ -0,0 +1,38 @@
1
+ Metadata-Version: 2.4
2
+ Name: masktunnel
3
+ Version: 0.1.0
4
+ Summary: Python bindings for MaskTunnel (Go)
5
+ Home-page: https://github.com/cloudflyer-project/masktunnel
6
+ Author: cloudflyer-project
7
+ License: GPL-3.0
8
+ Platform: any
9
+ Requires-Python: >=3.9
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: setuptools>=40.0
12
+ Provides-Extra: dev
13
+ Requires-Dist: pytest>=6.0; extra == "dev"
14
+ Requires-Dist: pytest-xdist; extra == "dev"
15
+ Requires-Dist: build; extra == "dev"
16
+ Requires-Dist: wheel; extra == "dev"
17
+ Dynamic: author
18
+ Dynamic: description
19
+ Dynamic: description-content-type
20
+ Dynamic: home-page
21
+ Dynamic: license
22
+ Dynamic: platform
23
+ Dynamic: provides-extra
24
+ Dynamic: requires-dist
25
+ Dynamic: requires-python
26
+ Dynamic: summary
27
+
28
+ # masktunnel (Python bindings)
29
+
30
+ This directory contains the Python package that wraps MaskTunnel's Go implementation via gopy.
31
+
32
+ - Package name: `masktunnel`
33
+ - Native module directory (generated at build time): `masktunnellib/`
34
+
35
+ Build notes:
36
+
37
+ - Building from source requires Go and a C toolchain.
38
+ - Wheels are produced by CI for common platforms.
@@ -0,0 +1,27 @@
1
+ MANIFEST.in
2
+ README.md
3
+ go.mod
4
+ go.sum
5
+ setup.py
6
+ masktunnel/__init__.py
7
+ masktunnel/_server.py
8
+ masktunnel/_utils.py
9
+ masktunnel.egg-info/PKG-INFO
10
+ masktunnel.egg-info/SOURCES.txt
11
+ masktunnel.egg-info/dependency_links.txt
12
+ masktunnel.egg-info/not-zip-safe
13
+ masktunnel.egg-info/requires.txt
14
+ masktunnel.egg-info/top_level.txt
15
+ masktunnel_go/_python.go
16
+ masktunnel_go/basic.go
17
+ masktunnel_go/bindings.go
18
+ masktunnel_go/config.go
19
+ masktunnel_go/encoding.go
20
+ masktunnel_go/generator.go
21
+ masktunnel_go/manager.go
22
+ masktunnel_go/mitm.go
23
+ masktunnel_go/payload.go
24
+ masktunnel_go/python.go
25
+ masktunnel_go/server.go
26
+ masktunnel_go/ua_parser.go
27
+ tests/test_server.py
@@ -0,0 +1,7 @@
1
+ setuptools>=40.0
2
+
3
+ [dev]
4
+ pytest>=6.0
5
+ pytest-xdist
6
+ build
7
+ wheel
@@ -0,0 +1,2 @@
1
+ masktunnel
2
+ masktunnellib
@@ -0,0 +1,81 @@
1
+ package masktunnel
2
+
3
+ import (
4
+ "context"
5
+ "sync"
6
+ "time"
7
+ )
8
+
9
+ // This file provides small, gopy-friendly helpers for Python bindings.
10
+
11
+ // ========== Context helpers ==========
12
+
13
+ var (
14
+ globalCtx context.Context
15
+ globalCancel context.CancelFunc
16
+ globalOnce sync.Once
17
+ )
18
+
19
+ // Background returns a process-wide background context.
20
+ func Background() context.Context {
21
+ globalOnce.Do(func() {
22
+ globalCtx, globalCancel = context.WithCancel(context.Background())
23
+ })
24
+ return globalCtx
25
+ }
26
+
27
+ // ContextWithCancel wraps a context and its cancel function.
28
+ type ContextWithCancel struct {
29
+ ctx context.Context
30
+ cancel context.CancelFunc
31
+ }
32
+
33
+ // NewContextWithCancel creates a new cancellable context.
34
+ func NewContextWithCancel() *ContextWithCancel {
35
+ ctx, cancel := context.WithCancel(context.Background())
36
+ return &ContextWithCancel{ctx: ctx, cancel: cancel}
37
+ }
38
+
39
+ // Cancel cancels the underlying context.
40
+ func (c *ContextWithCancel) Cancel() {
41
+ if c != nil && c.cancel != nil {
42
+ c.cancel()
43
+ }
44
+ }
45
+
46
+ // Context returns the underlying context.
47
+ func (c *ContextWithCancel) Context() context.Context {
48
+ if c == nil {
49
+ return context.Background()
50
+ }
51
+ return c.ctx
52
+ }
53
+
54
+ // CancelGlobalContext cancels the global background context.
55
+ func CancelGlobalContext() {
56
+ if globalCancel != nil {
57
+ globalCancel()
58
+ }
59
+ }
60
+
61
+ // NewContext returns a new background-derived context.
62
+ func NewContext() context.Context {
63
+ ctx, _ := context.WithCancel(context.Background())
64
+ return ctx
65
+ }
66
+
67
+ // ========== Time constants ==========
68
+
69
+ var (
70
+ Nanosecond = time.Nanosecond
71
+ Microsecond = time.Microsecond
72
+ Millisecond = time.Millisecond
73
+ Second = time.Second
74
+ Minute = time.Minute
75
+ Hour = time.Hour
76
+ )
77
+
78
+ // ParseDuration parses a duration string (e.g. "300ms", "2h45m").
79
+ func ParseDuration(s string) (time.Duration, error) {
80
+ return time.ParseDuration(s)
81
+ }
@@ -0,0 +1,77 @@
1
+ package masktunnel
2
+
3
+ import (
4
+ "encoding/base64"
5
+ "net/http"
6
+ "strings"
7
+ )
8
+
9
+ // BasicAuth handles HTTP Basic Authentication for proxy
10
+ type BasicAuth struct {
11
+ username string
12
+ password string
13
+ enabled bool
14
+ }
15
+
16
+ // NewBasicAuth creates a new basic auth handler
17
+ func NewBasicAuth(username, password string) *BasicAuth {
18
+ return &BasicAuth{
19
+ username: username,
20
+ password: password,
21
+ enabled: username != "" || password != "",
22
+ }
23
+ }
24
+
25
+ // IsEnabled returns true if authentication is enabled
26
+ func (ba *BasicAuth) IsEnabled() bool {
27
+ return ba.enabled
28
+ }
29
+
30
+ // Validate validates the proxy authentication from request
31
+ func (ba *BasicAuth) Validate(req *http.Request) bool {
32
+ if !ba.enabled {
33
+ return true
34
+ }
35
+
36
+ authHeader := req.Header.Get("Proxy-Authorization")
37
+ if authHeader == "" {
38
+ return false
39
+ }
40
+
41
+ if !strings.HasPrefix(authHeader, "Basic ") {
42
+ return false
43
+ }
44
+
45
+ encoded := authHeader[6:] // Remove "Basic " prefix
46
+ decoded, err := base64.StdEncoding.DecodeString(encoded)
47
+ if err != nil {
48
+ return false
49
+ }
50
+
51
+ credentials := string(decoded)
52
+ parts := strings.SplitN(credentials, ":", 2)
53
+ if len(parts) != 2 {
54
+ return false
55
+ }
56
+
57
+ return parts[0] == ba.username && parts[1] == ba.password
58
+ }
59
+
60
+ // GetAuthRequiredResponse returns HTTP 407 response for auth required
61
+ func (ba *BasicAuth) GetAuthRequiredResponse() *http.Response {
62
+ resp := &http.Response{
63
+ StatusCode: http.StatusProxyAuthRequired,
64
+ Status: "407 Proxy Authentication Required",
65
+ Proto: "HTTP/1.1",
66
+ ProtoMajor: 1,
67
+ ProtoMinor: 1,
68
+ Header: make(http.Header),
69
+ Body: http.NoBody,
70
+ ContentLength: 0,
71
+ }
72
+
73
+ resp.Header.Set("Proxy-Authenticate", "Basic realm=\"MaskTunnel Proxy\"")
74
+ resp.Header.Set("Content-Type", "text/plain")
75
+
76
+ return resp
77
+ }