flask-tor 1.0.3__tar.gz → 1.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.
- {flask-tor-1.0.3 → flask-tor-1.1.0}/PKG-INFO +8 -4
- {flask-tor-1.0.3 → flask-tor-1.1.0}/README.md +8 -2
- {flask-tor-1.0.3 → flask-tor-1.1.0}/flask_tor/__init__.py +1 -1
- {flask-tor-1.0.3 → flask-tor-1.1.0}/flask_tor/flask_tor.py +13 -3
- {flask-tor-1.0.3 → flask-tor-1.1.0}/flask_tor/onion.py +30 -7
- flask-tor-1.1.0/flask_tor/onionstart.py +67 -0
- {flask-tor-1.0.3 → flask-tor-1.1.0}/flask_tor.egg-info/PKG-INFO +8 -4
- flask-tor-1.0.3/flask_tor/onionstart.py +0 -36
- {flask-tor-1.0.3 → flask-tor-1.1.0}/LICENSE +0 -0
- {flask-tor-1.0.3 → flask-tor-1.1.0}/flask_tor/common.py +0 -0
- {flask-tor-1.0.3 → flask-tor-1.1.0}/flask_tor/settings.py +0 -0
- {flask-tor-1.0.3 → flask-tor-1.1.0}/flask_tor/torrc_template +0 -0
- {flask-tor-1.0.3 → flask-tor-1.1.0}/flask_tor/torrc_template-windows +0 -0
- {flask-tor-1.0.3 → flask-tor-1.1.0}/flask_tor.egg-info/SOURCES.txt +0 -0
- {flask-tor-1.0.3 → flask-tor-1.1.0}/flask_tor.egg-info/dependency_links.txt +0 -0
- {flask-tor-1.0.3 → flask-tor-1.1.0}/flask_tor.egg-info/not-zip-safe +0 -0
- {flask-tor-1.0.3 → flask-tor-1.1.0}/flask_tor.egg-info/requires.txt +0 -0
- {flask-tor-1.0.3 → flask-tor-1.1.0}/flask_tor.egg-info/top_level.txt +0 -0
- {flask-tor-1.0.3 → flask-tor-1.1.0}/setup.cfg +0 -0
- {flask-tor-1.0.3 → flask-tor-1.1.0}/setup.py +0 -0
@@ -1,13 +1,12 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: flask-tor
|
3
|
-
Version: 1.0
|
3
|
+
Version: 1.1.0
|
4
4
|
Summary: A simple way to run Flask apps on tor from your machine.
|
5
5
|
Home-page: https://github.com/jakbin/flask-tor
|
6
6
|
Author: Jak Bin
|
7
7
|
License: MIT License
|
8
8
|
Project-URL: Bug Tracker, https://github.com/jakbin/flask-tor/issues
|
9
9
|
Keywords: flask,tor,onion
|
10
|
-
Platform: UNKNOWN
|
11
10
|
Classifier: Development Status :: 4 - Beta
|
12
11
|
Classifier: Programming Language :: Python :: 3.6
|
13
12
|
Classifier: License :: OSI Approved :: MIT License
|
@@ -32,6 +31,7 @@ Use it only for educational purpose.
|
|
32
31
|
## Features
|
33
32
|
- No need root permission
|
34
33
|
- Multiple instances
|
34
|
+
- Optional persistent onion address (reuse the same .onion between runs)
|
35
35
|
|
36
36
|
## Compatability
|
37
37
|
Python 3.6+ is required.
|
@@ -52,7 +52,7 @@ from flask import Flask
|
|
52
52
|
from flask_tor import run_with_tor
|
53
53
|
|
54
54
|
app = Flask(__name__)
|
55
|
-
port = run_with_tor()
|
55
|
+
port = run_with_tor(persistent_key_file='~/.flask_tor/hidden_service_key')
|
56
56
|
|
57
57
|
@app.route("/")
|
58
58
|
def hello():
|
@@ -70,7 +70,11 @@ connecting_to_tor: 100% - Done
|
|
70
70
|
* Serving Flask app "main"
|
71
71
|
* Debug mode: off
|
72
72
|
* Running on http://127.0.0.1:<port>/
|
73
|
+
|
74
|
+
If you pass a persistent_key_file path, the first run will create a key file and subsequent runs will reuse it so the onion address stays the same. Set reuse_key=False to force a new address while still updating the stored key.
|
73
75
|
```
|
74
76
|
|
75
|
-
|
77
|
+
## Tutorial
|
78
|
+
[Watch Here](https://youtu.be/gmssaGzRT8M)
|
76
79
|
|
80
|
+
### Credit :- [onionshare](https://github.com/onionshare/onionshare)
|
@@ -14,6 +14,7 @@ Use it only for educational purpose.
|
|
14
14
|
## Features
|
15
15
|
- No need root permission
|
16
16
|
- Multiple instances
|
17
|
+
- Optional persistent onion address (reuse the same .onion between runs)
|
17
18
|
|
18
19
|
## Compatability
|
19
20
|
Python 3.6+ is required.
|
@@ -34,7 +35,7 @@ from flask import Flask
|
|
34
35
|
from flask_tor import run_with_tor
|
35
36
|
|
36
37
|
app = Flask(__name__)
|
37
|
-
port = run_with_tor()
|
38
|
+
port = run_with_tor(persistent_key_file='~/.flask_tor/hidden_service_key')
|
38
39
|
|
39
40
|
@app.route("/")
|
40
41
|
def hello():
|
@@ -52,6 +53,11 @@ connecting_to_tor: 100% - Done
|
|
52
53
|
* Serving Flask app "main"
|
53
54
|
* Debug mode: off
|
54
55
|
* Running on http://127.0.0.1:<port>/
|
56
|
+
|
57
|
+
If you pass a persistent_key_file path, the first run will create a key file and subsequent runs will reuse it so the onion address stays the same. Set reuse_key=False to force a new address while still updating the stored key.
|
55
58
|
```
|
56
59
|
|
57
|
-
|
60
|
+
## Tutorial
|
61
|
+
[Watch Here](https://youtu.be/gmssaGzRT8M)
|
62
|
+
|
63
|
+
### Credit :- [onionshare](https://github.com/onionshare/onionshare)
|
@@ -1,8 +1,18 @@
|
|
1
1
|
from .onion import *
|
2
2
|
from .onionstart import OnionStart
|
3
|
-
import sys, threading
|
3
|
+
import sys, threading, os
|
4
4
|
|
5
|
-
def run_with_tor():
|
5
|
+
def run_with_tor(persistent_key_file=None, reuse_key=True):
|
6
|
+
"""
|
7
|
+
Start Flask app with Tor hidden service.
|
8
|
+
|
9
|
+
Args:
|
10
|
+
persistent_key_file (str, optional): Path to a file for saving/loading the onion service private key. If provided, the same onion address will be reused across runs (unless reuse_key is False). If None, a new address is generated each run.
|
11
|
+
reuse_key (bool, optional): If True (default), reuse the key in persistent_key_file for the onion address. If False, always generate a new address and overwrite the file.
|
12
|
+
|
13
|
+
Returns:
|
14
|
+
int: The port number to use for the Flask app.
|
15
|
+
"""
|
6
16
|
# Start the Onion object
|
7
17
|
onion = Onion()
|
8
18
|
try:
|
@@ -15,7 +25,7 @@ def run_with_tor():
|
|
15
25
|
|
16
26
|
# Start the onionshare app
|
17
27
|
try:
|
18
|
-
app_tor = OnionStart(onion)
|
28
|
+
app_tor = OnionStart(onion, persistent_key_file=persistent_key_file, reuse_key=reuse_key)
|
19
29
|
# app_tor.set_stealth(stealth)
|
20
30
|
app_tor.start_onion_service()
|
21
31
|
except KeyboardInterrupt:
|
@@ -105,9 +105,11 @@ class Onion(object):
|
|
105
105
|
is necessary for status updates to reach the GUI.
|
106
106
|
"""
|
107
107
|
def __init__(self):
|
108
|
-
|
109
108
|
self.stealth = False
|
110
109
|
self.service_id = None
|
110
|
+
# Private key (eg: 'ED25519-V3:AAAA....') captured from ADD_ONION so it can
|
111
|
+
# optionally be reused to get the same onion address in future runs.
|
112
|
+
self.private_key = None
|
111
113
|
|
112
114
|
self.system = platform.system()
|
113
115
|
|
@@ -342,7 +344,7 @@ class Onion(object):
|
|
342
344
|
# ephemeral stealth onion services are not supported
|
343
345
|
self.supports_stealth = False
|
344
346
|
|
345
|
-
def start_onion_service(self, port):
|
347
|
+
def start_onion_service(self, port, existing_key=None):
|
346
348
|
"""
|
347
349
|
Start a onion service on port 80, pointing to the given port, and
|
348
350
|
return the onion hostname.
|
@@ -362,11 +364,22 @@ class Onion(object):
|
|
362
364
|
basic_auth = None
|
363
365
|
|
364
366
|
try:
|
365
|
-
if
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
367
|
+
if existing_key:
|
368
|
+
# Re-create an onion service using a previously saved key
|
369
|
+
try:
|
370
|
+
key_type, key_content = existing_key.split(':', 1)
|
371
|
+
except ValueError:
|
372
|
+
raise TorErrorInvalidSetting('invalid_saved_private_key')
|
373
|
+
if basic_auth is not None:
|
374
|
+
res = self.c.create_ephemeral_hidden_service({80: port}, key_type=key_type, key_content=key_content, await_publication=True, basic_auth=basic_auth)
|
375
|
+
else:
|
376
|
+
res = self.c.create_ephemeral_hidden_service({80: port}, key_type=key_type, key_content=key_content, await_publication=True)
|
377
|
+
else:
|
378
|
+
if basic_auth is not None:
|
379
|
+
res = self.c.create_ephemeral_hidden_service({ 80: port }, await_publication=True, basic_auth=basic_auth)
|
380
|
+
else:
|
381
|
+
# if the stem interface is older than 1.5.0, basic_auth isn't a valid keyword arg
|
382
|
+
res = self.c.create_ephemeral_hidden_service({ 80: port }, await_publication=True)
|
370
383
|
|
371
384
|
except ProtocolError:
|
372
385
|
raise TorErrorProtocolError('error_tor_protocol_error')
|
@@ -374,6 +387,16 @@ class Onion(object):
|
|
374
387
|
self.service_id = res.content()[0][2].split('=')[1]
|
375
388
|
onion_host = self.service_id + '.onion'
|
376
389
|
|
390
|
+
# Extract and store the private key if Tor returned it (Tor omits this
|
391
|
+
# line when we supplied our own existing key).
|
392
|
+
try:
|
393
|
+
for line in res.content():
|
394
|
+
if line[2].startswith('PrivateKey='):
|
395
|
+
self.private_key = line[2].split('=',1)[1]
|
396
|
+
break
|
397
|
+
except Exception:
|
398
|
+
pass
|
399
|
+
|
377
400
|
if self.stealth:
|
378
401
|
auth_cookie = res.content()[2][2].split('=')[1].split(':')[1]
|
379
402
|
self.auth_string = 'HidServAuth {} {}'.format(onion_host, auth_cookie)
|
@@ -0,0 +1,67 @@
|
|
1
|
+
import os, shutil
|
2
|
+
|
3
|
+
from . import common
|
4
|
+
|
5
|
+
class OnionStart(object):
|
6
|
+
"""
|
7
|
+
OnionShare is the main application class. Pass in options and run
|
8
|
+
start_onion_service and it will do the magic.
|
9
|
+
"""
|
10
|
+
def __init__(self, onion, local_only=False, stay_open=False, persistent_key_file=None, reuse_key=True):
|
11
|
+
"""
|
12
|
+
Args:
|
13
|
+
onion (Onion): The Onion controller object.
|
14
|
+
local_only (bool): If True, only bind to localhost (no Tor).
|
15
|
+
stay_open (bool): Unused, for compatibility.
|
16
|
+
persistent_key_file (str, optional): Path to file for saving/loading the onion service private key. If provided, the same onion address will be reused across runs (unless reuse_key is False).
|
17
|
+
reuse_key (bool, optional): If True (default), reuse the key in persistent_key_file for the onion address. If False, always generate a new address and overwrite the file.
|
18
|
+
"""
|
19
|
+
# The Onion object
|
20
|
+
self.onion = onion
|
21
|
+
self.hidserv_dir = None
|
22
|
+
self.onion_host = None
|
23
|
+
self.stealth = None
|
24
|
+
self.local_only = local_only
|
25
|
+
# Path to store/load persistent onion private key (text file containing 'ED25519-V3:...' format)
|
26
|
+
self.persistent_key_file = os.path.expanduser(persistent_key_file) if persistent_key_file else None
|
27
|
+
print(self.persistent_key_file)
|
28
|
+
self.reuse_key = reuse_key
|
29
|
+
|
30
|
+
def start_onion_service(self):
|
31
|
+
"""
|
32
|
+
Start the onionshare onion service.
|
33
|
+
"""
|
34
|
+
|
35
|
+
# Choose a random port
|
36
|
+
self.port = common.get_available_port(17600, 17650)
|
37
|
+
|
38
|
+
if self.local_only:
|
39
|
+
self.onion_host = '127.0.0.1:{0:d}'.format(self.port)
|
40
|
+
return
|
41
|
+
|
42
|
+
existing_key = None
|
43
|
+
if self.persistent_key_file and self.reuse_key and os.path.exists(self.persistent_key_file):
|
44
|
+
try:
|
45
|
+
with open(self.persistent_key_file, 'r') as f:
|
46
|
+
existing_key = f.read().strip() or None
|
47
|
+
except Exception:
|
48
|
+
existing_key = None
|
49
|
+
|
50
|
+
self.onion_host = self.onion.start_onion_service(self.port, existing_key=existing_key)
|
51
|
+
|
52
|
+
# Save newly generated key if we didn't reuse one
|
53
|
+
if self.persistent_key_file and (self.onion.private_key is not None):
|
54
|
+
# Only save if either no existing file or we generated a new key
|
55
|
+
if (not existing_key) or (existing_key and existing_key != self.onion.private_key):
|
56
|
+
try:
|
57
|
+
parent_dir = os.path.dirname(self.persistent_key_file)
|
58
|
+
if parent_dir:
|
59
|
+
os.makedirs(parent_dir, exist_ok=True)
|
60
|
+
with open(self.persistent_key_file, 'w') as f:
|
61
|
+
f.write(self.onion.private_key)
|
62
|
+
except Exception as e:
|
63
|
+
print(f"[flask-tor] Failed to save persistent key file '{self.persistent_key_file}': {e}")
|
64
|
+
|
65
|
+
if self.stealth:
|
66
|
+
self.auth_string = self.onion.auth_string
|
67
|
+
|
@@ -1,13 +1,12 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: flask-tor
|
3
|
-
Version: 1.0
|
3
|
+
Version: 1.1.0
|
4
4
|
Summary: A simple way to run Flask apps on tor from your machine.
|
5
5
|
Home-page: https://github.com/jakbin/flask-tor
|
6
6
|
Author: Jak Bin
|
7
7
|
License: MIT License
|
8
8
|
Project-URL: Bug Tracker, https://github.com/jakbin/flask-tor/issues
|
9
9
|
Keywords: flask,tor,onion
|
10
|
-
Platform: UNKNOWN
|
11
10
|
Classifier: Development Status :: 4 - Beta
|
12
11
|
Classifier: Programming Language :: Python :: 3.6
|
13
12
|
Classifier: License :: OSI Approved :: MIT License
|
@@ -32,6 +31,7 @@ Use it only for educational purpose.
|
|
32
31
|
## Features
|
33
32
|
- No need root permission
|
34
33
|
- Multiple instances
|
34
|
+
- Optional persistent onion address (reuse the same .onion between runs)
|
35
35
|
|
36
36
|
## Compatability
|
37
37
|
Python 3.6+ is required.
|
@@ -52,7 +52,7 @@ from flask import Flask
|
|
52
52
|
from flask_tor import run_with_tor
|
53
53
|
|
54
54
|
app = Flask(__name__)
|
55
|
-
port = run_with_tor()
|
55
|
+
port = run_with_tor(persistent_key_file='~/.flask_tor/hidden_service_key')
|
56
56
|
|
57
57
|
@app.route("/")
|
58
58
|
def hello():
|
@@ -70,7 +70,11 @@ connecting_to_tor: 100% - Done
|
|
70
70
|
* Serving Flask app "main"
|
71
71
|
* Debug mode: off
|
72
72
|
* Running on http://127.0.0.1:<port>/
|
73
|
+
|
74
|
+
If you pass a persistent_key_file path, the first run will create a key file and subsequent runs will reuse it so the onion address stays the same. Set reuse_key=False to force a new address while still updating the stored key.
|
73
75
|
```
|
74
76
|
|
75
|
-
|
77
|
+
## Tutorial
|
78
|
+
[Watch Here](https://youtu.be/gmssaGzRT8M)
|
76
79
|
|
80
|
+
### Credit :- [onionshare](https://github.com/onionshare/onionshare)
|
@@ -1,36 +0,0 @@
|
|
1
|
-
import os, shutil
|
2
|
-
|
3
|
-
from . import common
|
4
|
-
|
5
|
-
class OnionStart(object):
|
6
|
-
"""
|
7
|
-
OnionShare is the main application class. Pass in options and run
|
8
|
-
start_onion_service and it will do the magic.
|
9
|
-
"""
|
10
|
-
def __init__(self, onion, local_only=False, stay_open=False):
|
11
|
-
|
12
|
-
# The Onion object
|
13
|
-
self.onion = onion
|
14
|
-
|
15
|
-
self.hidserv_dir = None
|
16
|
-
self.onion_host = None
|
17
|
-
self.stealth = None
|
18
|
-
self.local_only = local_only
|
19
|
-
|
20
|
-
def start_onion_service(self):
|
21
|
-
"""
|
22
|
-
Start the onionshare onion service.
|
23
|
-
"""
|
24
|
-
|
25
|
-
# Choose a random port
|
26
|
-
self.port = common.get_available_port(17600, 17650)
|
27
|
-
|
28
|
-
if self.local_only:
|
29
|
-
self.onion_host = '127.0.0.1:{0:d}'.format(self.port)
|
30
|
-
return
|
31
|
-
|
32
|
-
self.onion_host = self.onion.start_onion_service(self.port)
|
33
|
-
|
34
|
-
if self.stealth:
|
35
|
-
self.auth_string = self.onion.auth_string
|
36
|
-
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|