protox-gatekeeper 0.1.1__py3-none-any.whl → 0.2.0__py3-none-any.whl
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.
- protox_gatekeeper/core.py +25 -0
- {protox_gatekeeper-0.1.1.dist-info → protox_gatekeeper-0.2.0.dist-info}/METADATA +71 -14
- {protox_gatekeeper-0.1.1.dist-info → protox_gatekeeper-0.2.0.dist-info}/RECORD +6 -6
- {protox_gatekeeper-0.1.1.dist-info → protox_gatekeeper-0.2.0.dist-info}/WHEEL +0 -0
- {protox_gatekeeper-0.1.1.dist-info → protox_gatekeeper-0.2.0.dist-info}/licenses/LICENSE +0 -0
- {protox_gatekeeper-0.1.1.dist-info → protox_gatekeeper-0.2.0.dist-info}/top_level.txt +0 -0
protox_gatekeeper/core.py
CHANGED
|
@@ -69,6 +69,31 @@ class GateKeeper:
|
|
|
69
69
|
""" Returns the Tor exit IP address. """
|
|
70
70
|
return self.exit_ip
|
|
71
71
|
|
|
72
|
+
def get(self, url: str, **kwargs) -> requests.Response:
|
|
73
|
+
"""
|
|
74
|
+
Passes a GET request to the Tor Gatekeeper.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
url (str): The url to request.
|
|
78
|
+
**kwargs: Additional parameters to pass to the GET request.
|
|
79
|
+
"""
|
|
80
|
+
logger.info(f'[Tor {self.tor_exit}] GET {url}')
|
|
81
|
+
return self._session.get(url=url, **kwargs)
|
|
82
|
+
|
|
83
|
+
def post(self, url: str, data=None, json=None,
|
|
84
|
+
**kwargs) -> requests.Response:
|
|
85
|
+
"""
|
|
86
|
+
Passes a POST request to the Tor Gatekeeper.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
url (str): The url to post to.
|
|
90
|
+
data (dict, optional): The data to post.
|
|
91
|
+
json (dict, optional): The json data to post.
|
|
92
|
+
**kwargs: Additional parameters to pass to the POST request.
|
|
93
|
+
"""
|
|
94
|
+
logger.info(f'[Tor {self.tor_exit}] POST {url}')
|
|
95
|
+
return self._session.post(url=url, data=data, json=json, **kwargs)
|
|
96
|
+
|
|
72
97
|
def download(self, url: str, target_path: str, timeout: int = 30,
|
|
73
98
|
chunk_size: int = 8192):
|
|
74
99
|
"""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: protox-gatekeeper
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Fail-closed Tor session enforcement for Python HTTP(S) traffic
|
|
5
5
|
Author: Tom Erik Harnes
|
|
6
6
|
License: MIT License
|
|
@@ -25,6 +25,16 @@ License: MIT License
|
|
|
25
25
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
26
|
SOFTWARE.
|
|
27
27
|
|
|
28
|
+
Project-URL: Homepage, https://github.com/ProtoXCode/protox-gatekeeper
|
|
29
|
+
Project-URL: Repository, https://github.com/ProtoXCode/protox-gatekeeper
|
|
30
|
+
Project-URL: Issues, https://github.com/ProtoXCode/protox-gatekeeper/issues
|
|
31
|
+
Keywords: tor,privacy,networking,security,proxy
|
|
32
|
+
Classifier: Programming Language :: Python :: 3
|
|
33
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
34
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
35
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
36
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
37
|
+
Classifier: Operating System :: OS Independent
|
|
28
38
|
Requires-Python: >=3.10
|
|
29
39
|
Description-Content-Type: text/markdown
|
|
30
40
|
License-File: LICENSE
|
|
@@ -32,24 +42,28 @@ Requires-Dist: requests
|
|
|
32
42
|
Requires-Dist: pysocks
|
|
33
43
|
Dynamic: license-file
|
|
34
44
|
|
|
45
|
+
[](https://pypi.org/project/protox-gatekeeper/)
|
|
46
|
+
[](https://pypi.org/project/protox-gatekeeper/)
|
|
47
|
+
[](https://pypi.org/project/protox-gatekeeper/)
|
|
48
|
+
|
|
35
49
|
# ProtoX GateKeeper
|
|
36
50
|
|
|
37
51
|
**ProtoX GateKeeper** is a small, opinionated Python library that enforces
|
|
38
|
-
**fail
|
|
52
|
+
**fail-closed Tor routing** for HTTP(S) traffic.
|
|
39
53
|
|
|
40
54
|
The goal is simple:
|
|
41
55
|
|
|
42
56
|
> If Tor is not active and verified, **nothing runs**.
|
|
43
57
|
|
|
44
|
-
GateKeeper is designed to be *fire
|
|
58
|
+
GateKeeper is designed to be *fire-and-forget*: create a client once, then perform network operations with a hard guarantee that traffic exits through the Tor network.
|
|
45
59
|
|
|
46
60
|
---
|
|
47
61
|
|
|
48
62
|
## What GateKeeper Is
|
|
49
63
|
|
|
50
|
-
- A **Tor
|
|
51
|
-
- A thin wrapper around `requests.Session`
|
|
52
|
-
- Fail
|
|
64
|
+
- A **Tor-verified HTTP client**
|
|
65
|
+
- A thin wrapper around `requests.Session` with safe helpers
|
|
66
|
+
- Fail-closed by default (no silent clearnet fallback)
|
|
53
67
|
- Observable (exit IP, optional geo info)
|
|
54
68
|
- Suitable for scripts, tooling, and automation
|
|
55
69
|
|
|
@@ -77,6 +91,12 @@ On Windows this usually means **Tor Browser** running in the background.
|
|
|
77
91
|
|
|
78
92
|
## Installation
|
|
79
93
|
|
|
94
|
+
### From PyPI
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
pip install protox-gatekeeper
|
|
98
|
+
```
|
|
99
|
+
|
|
80
100
|
### From source (development)
|
|
81
101
|
|
|
82
102
|
```bash
|
|
@@ -121,6 +141,20 @@ This confirms:
|
|
|
121
141
|
|
|
122
142
|
---
|
|
123
143
|
|
|
144
|
+
### HTTP requests
|
|
145
|
+
|
|
146
|
+
GateKeeper can also be used as a Tor-verified HTTP client:
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
with GateKeeper() as gk:
|
|
150
|
+
response = gk.get("https://httpbin.org/ip")
|
|
151
|
+
print(response.json())
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
All requests are guaranteed to use the verified Tor session.
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
124
158
|
## API Overview
|
|
125
159
|
|
|
126
160
|
### `GateKeeper(...)`
|
|
@@ -134,7 +168,7 @@ gk = GateKeeper(
|
|
|
134
168
|
|
|
135
169
|
**Parameters**:
|
|
136
170
|
- `socks_port` *(int)* – Tor SOCKS port (default: `9150`)
|
|
137
|
-
- `geo` *(bool)* – Enable best
|
|
171
|
+
- `geo` *(bool)* – Enable best-effort Tor exit geolocation (optional)
|
|
138
172
|
|
|
139
173
|
Raises `RuntimeError` if Tor routing cannot be verified.
|
|
140
174
|
|
|
@@ -153,13 +187,37 @@ gk.download(url, target_path)
|
|
|
153
187
|
|
|
154
188
|
---
|
|
155
189
|
|
|
190
|
+
### `get(url, **kwargs)`
|
|
191
|
+
|
|
192
|
+
Performs a Tor-verified HTTP GET request.
|
|
193
|
+
|
|
194
|
+
```python
|
|
195
|
+
response = gk.get(url, timeout=10)
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Returns a standard `requests.Response`.
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
### `post(url, data=None, json=None, **kwargs)`
|
|
203
|
+
|
|
204
|
+
Performs a Tor-verified HTTP POST request.
|
|
205
|
+
|
|
206
|
+
```python
|
|
207
|
+
response = gk.post(url, json={"key": "value"})
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Returns a standard `requests.Response`.
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
156
214
|
## Design Principles
|
|
157
215
|
|
|
158
216
|
- **Fail closed**: no Tor → no execution
|
|
159
217
|
- **Single verification point** (during construction)
|
|
160
218
|
- **No global state**
|
|
161
219
|
- **No logging configuration inside the library**
|
|
162
|
-
- **Session reuse without re
|
|
220
|
+
- **Session reuse without re-verification**
|
|
163
221
|
|
|
164
222
|
Logging is emitted by the library, but **configured by the application**.
|
|
165
223
|
|
|
@@ -181,8 +239,8 @@ The library does **not** call `logging.basicConfig()` internally.
|
|
|
181
239
|
## Security Notes
|
|
182
240
|
|
|
183
241
|
- Tor exit IPs may rotate over time
|
|
184
|
-
- Geo information is best
|
|
185
|
-
- GateKeeper guarantees routing, not anonymity
|
|
242
|
+
- Geo information is best-effort and may be unavailable (rate-limits, CAPTCHAs)
|
|
243
|
+
- GateKeeper guarantees transport routing, not anonymity
|
|
186
244
|
|
|
187
245
|
---
|
|
188
246
|
|
|
@@ -194,14 +252,13 @@ MIT License
|
|
|
194
252
|
|
|
195
253
|
## Status
|
|
196
254
|
|
|
197
|
-
- Version: **v0.
|
|
198
|
-
- Phase
|
|
255
|
+
- Version: **v0.2.0**
|
|
256
|
+
- Phase 2 in progress
|
|
199
257
|
- API intentionally minimal
|
|
200
258
|
|
|
201
259
|
Future versions may add optional features such as:
|
|
202
260
|
- circuit rotation
|
|
203
261
|
- ControlPort support
|
|
204
|
-
- higher
|
|
262
|
+
- higher-level request helpers
|
|
205
263
|
|
|
206
264
|
Without breaking the core contract.
|
|
207
|
-
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
protox_gatekeeper/__init__.py,sha256=HisDC-NCbMlkrNkrLRdANILoBqw03ssqFp6BTsXm6Us,75
|
|
2
|
-
protox_gatekeeper/core.py,sha256=
|
|
2
|
+
protox_gatekeeper/core.py,sha256=SALDt7IhalzkOBQ2amjsmcMTf3IMiZYaWqQDU9B8FLo,4010
|
|
3
3
|
protox_gatekeeper/geo.py,sha256=AdjHfZqjP0w5ujHFI_WV7c5XWnDTzqkVL32KeJQojYo,641
|
|
4
4
|
protox_gatekeeper/ops.py,sha256=Kmr8lU8Ohe81URHHNUlUJ0S71aZ1uGgyiztLBPsOUO4,690
|
|
5
5
|
protox_gatekeeper/session.py,sha256=0qGZF44EHr7CP-bSM0awtq4F-5LWiIb4w87mV7Yocfk,235
|
|
6
6
|
protox_gatekeeper/verify.py,sha256=bsHK3f16sRV8cHo30AY82SB1vb_Svu-US7IhghTSQ6E,452
|
|
7
|
-
protox_gatekeeper-0.
|
|
8
|
-
protox_gatekeeper-0.
|
|
9
|
-
protox_gatekeeper-0.
|
|
10
|
-
protox_gatekeeper-0.
|
|
11
|
-
protox_gatekeeper-0.
|
|
7
|
+
protox_gatekeeper-0.2.0.dist-info/licenses/LICENSE,sha256=EE75Vy9_csDDBRXBF4uVQWxYu1YpzXTcmaeuVcPOjl4,1093
|
|
8
|
+
protox_gatekeeper-0.2.0.dist-info/METADATA,sha256=0V4NABFLpC2NOWg_2v6gLWJTqfqRhrBP6_2h8GcJ4Uc,6890
|
|
9
|
+
protox_gatekeeper-0.2.0.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
|
|
10
|
+
protox_gatekeeper-0.2.0.dist-info/top_level.txt,sha256=KOVL4YUpiWQLGjCvx2SmP8VSsA6hPcEvKCd4k6kPl8s,18
|
|
11
|
+
protox_gatekeeper-0.2.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|