foxpipe 1.9.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.
- foxpipe-1.9.0/LICENSE +21 -0
- foxpipe-1.9.0/PKG-INFO +162 -0
- foxpipe-1.9.0/README.md +147 -0
- foxpipe-1.9.0/foxpipe.egg-info/PKG-INFO +162 -0
- foxpipe-1.9.0/foxpipe.egg-info/SOURCES.txt +10 -0
- foxpipe-1.9.0/foxpipe.egg-info/dependency_links.txt +1 -0
- foxpipe-1.9.0/foxpipe.egg-info/entry_points.txt +2 -0
- foxpipe-1.9.0/foxpipe.egg-info/requires.txt +1 -0
- foxpipe-1.9.0/foxpipe.egg-info/top_level.txt +1 -0
- foxpipe-1.9.0/foxpipe.py +323 -0
- foxpipe-1.9.0/pyproject.toml +27 -0
- foxpipe-1.9.0/setup.cfg +4 -0
foxpipe-1.9.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Fox Hackerz
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
foxpipe-1.9.0/PKG-INFO
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: foxpipe
|
|
3
|
+
Version: 1.9.0
|
|
4
|
+
Summary: Secure • Simple • Reliable data streaming. End-to-end encrypted Unix pipes.
|
|
5
|
+
Author: FoxHackerzDevs Team
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/foxhackerzdevs/FoxPipe
|
|
8
|
+
Project-URL: Repository, https://github.com/foxhackerzdevs/FoxPipe
|
|
9
|
+
Keywords: cli,encryption,aes-gcm,netcat,pipe,security
|
|
10
|
+
Requires-Python: >=3.8
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Requires-Dist: cryptography>=41.0.0
|
|
14
|
+
Dynamic: license-file
|
|
15
|
+
|
|
16
|
+
## 🦊 FoxPipe v1.9
|
|
17
|
+
|
|
18
|
+
**Secure • Simple • Reliable Data Streaming**
|
|
19
|
+
|
|
20
|
+
FoxPipe is a minimalist CLI tool for **end-to-end encrypted, optionally compressed data transfer** between two machines — no setup, no accounts, just a shared password.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 🚀 Why FoxPipe?
|
|
25
|
+
|
|
26
|
+
**Simple**
|
|
27
|
+
No servers, no login. Just run sender and receiver.
|
|
28
|
+
|
|
29
|
+
**Efficient**
|
|
30
|
+
Built-in `zlib` streaming compression reduces bandwidth usage automatically.
|
|
31
|
+
|
|
32
|
+
**Secure by Design**
|
|
33
|
+
Uses **AES-256-GCM (AEAD)** for encryption and **Scrypt** for strong key derivation.
|
|
34
|
+
|
|
35
|
+
**Resilient**
|
|
36
|
+
Includes chunk limits, decompression guards, session validation, and timeouts.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 📥 Installation
|
|
41
|
+
|
|
42
|
+
Install directly from PyPI:
|
|
43
|
+
```bash
|
|
44
|
+
pip install foxpipe
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 🛠️ Usage
|
|
50
|
+
|
|
51
|
+
### 1️⃣ Receiver (Destination)
|
|
52
|
+
|
|
53
|
+
Start this **first**:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
foxpipe receive 8080 -p "secure-pass" > backup.sql
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Allow external connections:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
foxpipe receive 8080 -p "secure-pass" --public > backup.sql
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
### 2️⃣ Sender (Source)
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
cat backup.sql | foxpipe send 192.168.1.5 8080 -p "secure-pass"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 📦 Advanced Usage
|
|
76
|
+
|
|
77
|
+
### 📁 Directory Transfer (Recommended)
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# Sender
|
|
81
|
+
tar -cf - ./project | foxpipe send 1.2.3.4 9000 -p secret
|
|
82
|
+
|
|
83
|
+
# Receiver
|
|
84
|
+
foxpipe receive 9000 -p secret | tar -xf -
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
### 📄 Direct File Transfer
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
foxpipe send 1.2.3.4 8080 -p secret --file image.iso
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
### 🚫 Disable Compression
|
|
98
|
+
|
|
99
|
+
For already compressed files:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
foxpipe send 1.2.3.4 8080 -p secret --file video.mp4 --no-compress
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## 🔒 Security Model (v1.9)
|
|
108
|
+
|
|
109
|
+
* **Encryption:** AES-256-GCM (authenticated encryption per chunk)
|
|
110
|
+
* **Key Derivation:** Scrypt (`N=2¹⁵`, `r=8`, `p=1`)
|
|
111
|
+
* **Handshake Authentication:** HMAC-SHA256
|
|
112
|
+
* **Session Binding:** Random session ID prevents replay across sessions
|
|
113
|
+
* **Integrity & Authenticity:** Provided by AES-GCM (AEAD)
|
|
114
|
+
|
|
115
|
+
> ⚠️ HMAC is used only for handshake authentication, not for data chunks.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## ⚠️ Safety Measures
|
|
120
|
+
|
|
121
|
+
* **Max Chunk Size:** 10 MB
|
|
122
|
+
* **Session Timeout:** 300 seconds (idle)
|
|
123
|
+
* **Connection Timeout:** 15 seconds
|
|
124
|
+
* **Safe Streaming Decompression:** Protects against zip-bomb style attacks
|
|
125
|
+
* **DoS Protection:** Receiver enforces a global transfer limit (default **5GB**).
|
|
126
|
+
Adjust using `--limit` (e.g., `--limit 100` for 100GB).
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## 🧠 Design Notes
|
|
131
|
+
|
|
132
|
+
* Uses **streaming compression (single zlib stream)**
|
|
133
|
+
* Uses **random nonce per chunk** (safe for AES-GCM usage)
|
|
134
|
+
* Uses **constant-time HMAC comparison**
|
|
135
|
+
* Avoids buffering entire files → supports large transfers
|
|
136
|
+
* Minimal protocol → low overhead, easy to audit
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## ⚡ Quick Example
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# Receiver
|
|
144
|
+
foxpipe receive 9000 -p pass --public > file.txt
|
|
145
|
+
|
|
146
|
+
# Sender
|
|
147
|
+
foxpipe send <IP> 9000 -p pass --file file.txt
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## ⚠️ Limitations
|
|
153
|
+
|
|
154
|
+
* Single connection only
|
|
155
|
+
* No resume support
|
|
156
|
+
* No file metadata (name/size handled externally)
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## 🦊 Philosophy
|
|
161
|
+
|
|
162
|
+
> Build simple tools that are hard to misuse and easy to trust.
|
foxpipe-1.9.0/README.md
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
## 🦊 FoxPipe v1.9
|
|
2
|
+
|
|
3
|
+
**Secure • Simple • Reliable Data Streaming**
|
|
4
|
+
|
|
5
|
+
FoxPipe is a minimalist CLI tool for **end-to-end encrypted, optionally compressed data transfer** between two machines — no setup, no accounts, just a shared password.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 🚀 Why FoxPipe?
|
|
10
|
+
|
|
11
|
+
**Simple**
|
|
12
|
+
No servers, no login. Just run sender and receiver.
|
|
13
|
+
|
|
14
|
+
**Efficient**
|
|
15
|
+
Built-in `zlib` streaming compression reduces bandwidth usage automatically.
|
|
16
|
+
|
|
17
|
+
**Secure by Design**
|
|
18
|
+
Uses **AES-256-GCM (AEAD)** for encryption and **Scrypt** for strong key derivation.
|
|
19
|
+
|
|
20
|
+
**Resilient**
|
|
21
|
+
Includes chunk limits, decompression guards, session validation, and timeouts.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 📥 Installation
|
|
26
|
+
|
|
27
|
+
Install directly from PyPI:
|
|
28
|
+
```bash
|
|
29
|
+
pip install foxpipe
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 🛠️ Usage
|
|
35
|
+
|
|
36
|
+
### 1️⃣ Receiver (Destination)
|
|
37
|
+
|
|
38
|
+
Start this **first**:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
foxpipe receive 8080 -p "secure-pass" > backup.sql
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Allow external connections:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
foxpipe receive 8080 -p "secure-pass" --public > backup.sql
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
### 2️⃣ Sender (Source)
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
cat backup.sql | foxpipe send 192.168.1.5 8080 -p "secure-pass"
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## 📦 Advanced Usage
|
|
61
|
+
|
|
62
|
+
### 📁 Directory Transfer (Recommended)
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# Sender
|
|
66
|
+
tar -cf - ./project | foxpipe send 1.2.3.4 9000 -p secret
|
|
67
|
+
|
|
68
|
+
# Receiver
|
|
69
|
+
foxpipe receive 9000 -p secret | tar -xf -
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
### 📄 Direct File Transfer
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
foxpipe send 1.2.3.4 8080 -p secret --file image.iso
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
### 🚫 Disable Compression
|
|
83
|
+
|
|
84
|
+
For already compressed files:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
foxpipe send 1.2.3.4 8080 -p secret --file video.mp4 --no-compress
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## 🔒 Security Model (v1.9)
|
|
93
|
+
|
|
94
|
+
* **Encryption:** AES-256-GCM (authenticated encryption per chunk)
|
|
95
|
+
* **Key Derivation:** Scrypt (`N=2¹⁵`, `r=8`, `p=1`)
|
|
96
|
+
* **Handshake Authentication:** HMAC-SHA256
|
|
97
|
+
* **Session Binding:** Random session ID prevents replay across sessions
|
|
98
|
+
* **Integrity & Authenticity:** Provided by AES-GCM (AEAD)
|
|
99
|
+
|
|
100
|
+
> ⚠️ HMAC is used only for handshake authentication, not for data chunks.
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## ⚠️ Safety Measures
|
|
105
|
+
|
|
106
|
+
* **Max Chunk Size:** 10 MB
|
|
107
|
+
* **Session Timeout:** 300 seconds (idle)
|
|
108
|
+
* **Connection Timeout:** 15 seconds
|
|
109
|
+
* **Safe Streaming Decompression:** Protects against zip-bomb style attacks
|
|
110
|
+
* **DoS Protection:** Receiver enforces a global transfer limit (default **5GB**).
|
|
111
|
+
Adjust using `--limit` (e.g., `--limit 100` for 100GB).
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## 🧠 Design Notes
|
|
116
|
+
|
|
117
|
+
* Uses **streaming compression (single zlib stream)**
|
|
118
|
+
* Uses **random nonce per chunk** (safe for AES-GCM usage)
|
|
119
|
+
* Uses **constant-time HMAC comparison**
|
|
120
|
+
* Avoids buffering entire files → supports large transfers
|
|
121
|
+
* Minimal protocol → low overhead, easy to audit
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## ⚡ Quick Example
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
# Receiver
|
|
129
|
+
foxpipe receive 9000 -p pass --public > file.txt
|
|
130
|
+
|
|
131
|
+
# Sender
|
|
132
|
+
foxpipe send <IP> 9000 -p pass --file file.txt
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## ⚠️ Limitations
|
|
138
|
+
|
|
139
|
+
* Single connection only
|
|
140
|
+
* No resume support
|
|
141
|
+
* No file metadata (name/size handled externally)
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## 🦊 Philosophy
|
|
146
|
+
|
|
147
|
+
> Build simple tools that are hard to misuse and easy to trust.
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: foxpipe
|
|
3
|
+
Version: 1.9.0
|
|
4
|
+
Summary: Secure • Simple • Reliable data streaming. End-to-end encrypted Unix pipes.
|
|
5
|
+
Author: FoxHackerzDevs Team
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/foxhackerzdevs/FoxPipe
|
|
8
|
+
Project-URL: Repository, https://github.com/foxhackerzdevs/FoxPipe
|
|
9
|
+
Keywords: cli,encryption,aes-gcm,netcat,pipe,security
|
|
10
|
+
Requires-Python: >=3.8
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Requires-Dist: cryptography>=41.0.0
|
|
14
|
+
Dynamic: license-file
|
|
15
|
+
|
|
16
|
+
## 🦊 FoxPipe v1.9
|
|
17
|
+
|
|
18
|
+
**Secure • Simple • Reliable Data Streaming**
|
|
19
|
+
|
|
20
|
+
FoxPipe is a minimalist CLI tool for **end-to-end encrypted, optionally compressed data transfer** between two machines — no setup, no accounts, just a shared password.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 🚀 Why FoxPipe?
|
|
25
|
+
|
|
26
|
+
**Simple**
|
|
27
|
+
No servers, no login. Just run sender and receiver.
|
|
28
|
+
|
|
29
|
+
**Efficient**
|
|
30
|
+
Built-in `zlib` streaming compression reduces bandwidth usage automatically.
|
|
31
|
+
|
|
32
|
+
**Secure by Design**
|
|
33
|
+
Uses **AES-256-GCM (AEAD)** for encryption and **Scrypt** for strong key derivation.
|
|
34
|
+
|
|
35
|
+
**Resilient**
|
|
36
|
+
Includes chunk limits, decompression guards, session validation, and timeouts.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 📥 Installation
|
|
41
|
+
|
|
42
|
+
Install directly from PyPI:
|
|
43
|
+
```bash
|
|
44
|
+
pip install foxpipe
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 🛠️ Usage
|
|
50
|
+
|
|
51
|
+
### 1️⃣ Receiver (Destination)
|
|
52
|
+
|
|
53
|
+
Start this **first**:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
foxpipe receive 8080 -p "secure-pass" > backup.sql
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Allow external connections:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
foxpipe receive 8080 -p "secure-pass" --public > backup.sql
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
### 2️⃣ Sender (Source)
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
cat backup.sql | foxpipe send 192.168.1.5 8080 -p "secure-pass"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 📦 Advanced Usage
|
|
76
|
+
|
|
77
|
+
### 📁 Directory Transfer (Recommended)
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# Sender
|
|
81
|
+
tar -cf - ./project | foxpipe send 1.2.3.4 9000 -p secret
|
|
82
|
+
|
|
83
|
+
# Receiver
|
|
84
|
+
foxpipe receive 9000 -p secret | tar -xf -
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
### 📄 Direct File Transfer
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
foxpipe send 1.2.3.4 8080 -p secret --file image.iso
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
### 🚫 Disable Compression
|
|
98
|
+
|
|
99
|
+
For already compressed files:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
foxpipe send 1.2.3.4 8080 -p secret --file video.mp4 --no-compress
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## 🔒 Security Model (v1.9)
|
|
108
|
+
|
|
109
|
+
* **Encryption:** AES-256-GCM (authenticated encryption per chunk)
|
|
110
|
+
* **Key Derivation:** Scrypt (`N=2¹⁵`, `r=8`, `p=1`)
|
|
111
|
+
* **Handshake Authentication:** HMAC-SHA256
|
|
112
|
+
* **Session Binding:** Random session ID prevents replay across sessions
|
|
113
|
+
* **Integrity & Authenticity:** Provided by AES-GCM (AEAD)
|
|
114
|
+
|
|
115
|
+
> ⚠️ HMAC is used only for handshake authentication, not for data chunks.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## ⚠️ Safety Measures
|
|
120
|
+
|
|
121
|
+
* **Max Chunk Size:** 10 MB
|
|
122
|
+
* **Session Timeout:** 300 seconds (idle)
|
|
123
|
+
* **Connection Timeout:** 15 seconds
|
|
124
|
+
* **Safe Streaming Decompression:** Protects against zip-bomb style attacks
|
|
125
|
+
* **DoS Protection:** Receiver enforces a global transfer limit (default **5GB**).
|
|
126
|
+
Adjust using `--limit` (e.g., `--limit 100` for 100GB).
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## 🧠 Design Notes
|
|
131
|
+
|
|
132
|
+
* Uses **streaming compression (single zlib stream)**
|
|
133
|
+
* Uses **random nonce per chunk** (safe for AES-GCM usage)
|
|
134
|
+
* Uses **constant-time HMAC comparison**
|
|
135
|
+
* Avoids buffering entire files → supports large transfers
|
|
136
|
+
* Minimal protocol → low overhead, easy to audit
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## ⚡ Quick Example
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# Receiver
|
|
144
|
+
foxpipe receive 9000 -p pass --public > file.txt
|
|
145
|
+
|
|
146
|
+
# Sender
|
|
147
|
+
foxpipe send <IP> 9000 -p pass --file file.txt
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## ⚠️ Limitations
|
|
153
|
+
|
|
154
|
+
* Single connection only
|
|
155
|
+
* No resume support
|
|
156
|
+
* No file metadata (name/size handled externally)
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## 🦊 Philosophy
|
|
161
|
+
|
|
162
|
+
> Build simple tools that are hard to misuse and easy to trust.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
cryptography>=41.0.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
foxpipe
|
foxpipe-1.9.0/foxpipe.py
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
FoxPipe v1.9 - Secure • Simple • Reliable Data Streaming
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import socket
|
|
7
|
+
import argparse
|
|
8
|
+
import sys
|
|
9
|
+
import secrets
|
|
10
|
+
import time
|
|
11
|
+
import hmac
|
|
12
|
+
import hashlib
|
|
13
|
+
import getpass
|
|
14
|
+
import zlib
|
|
15
|
+
|
|
16
|
+
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
|
|
17
|
+
from cryptography.hazmat.primitives.kdf.scrypt import Scrypt
|
|
18
|
+
from cryptography.hazmat.backends import default_backend
|
|
19
|
+
|
|
20
|
+
# =========================
|
|
21
|
+
# CONFIG
|
|
22
|
+
# =========================
|
|
23
|
+
CHUNK_SIZE = 65536
|
|
24
|
+
MAGIC = b"FOXPIPE"
|
|
25
|
+
VERSION = 1
|
|
26
|
+
TOOL_VERSION = "1.9"
|
|
27
|
+
|
|
28
|
+
FLAG_COMPRESS = 0b00000001
|
|
29
|
+
|
|
30
|
+
MAX_CHUNK = 10_000_000
|
|
31
|
+
TIMEOUT = 15
|
|
32
|
+
SESSION_TIMEOUT = 300
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# =========================
|
|
36
|
+
# KEY DERIVATION
|
|
37
|
+
# =========================
|
|
38
|
+
def derive_key(password, salt):
|
|
39
|
+
kdf = Scrypt(
|
|
40
|
+
salt=salt,
|
|
41
|
+
length=32,
|
|
42
|
+
n=2**15,
|
|
43
|
+
r=8,
|
|
44
|
+
p=1,
|
|
45
|
+
backend=default_backend()
|
|
46
|
+
)
|
|
47
|
+
return kdf.derive(password.encode())
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# =========================
|
|
51
|
+
# AUTH TAG
|
|
52
|
+
# =========================
|
|
53
|
+
def auth_tag(key, salt, flags, session_id):
|
|
54
|
+
return hmac.new(
|
|
55
|
+
key,
|
|
56
|
+
salt + session_id + MAGIC + bytes([VERSION]) + bytes([flags]),
|
|
57
|
+
hashlib.sha256
|
|
58
|
+
).digest()
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
# =========================
|
|
62
|
+
# ENCRYPT / DECRYPT
|
|
63
|
+
# =========================
|
|
64
|
+
def encrypt_data(aes, data):
|
|
65
|
+
nonce = secrets.token_bytes(12)
|
|
66
|
+
return nonce + aes.encrypt(nonce, data, None)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def decrypt_data(aes, data):
|
|
70
|
+
nonce = data[:12]
|
|
71
|
+
return aes.decrypt(nonce, data[12:], None)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
# =========================
|
|
75
|
+
# SOCKET UTIL
|
|
76
|
+
# =========================
|
|
77
|
+
def recv_exact(conn, n):
|
|
78
|
+
data = b""
|
|
79
|
+
while len(data) < n:
|
|
80
|
+
chunk = conn.recv(n - len(data))
|
|
81
|
+
if not chunk:
|
|
82
|
+
raise ConnectionError("Connection closed unexpectedly")
|
|
83
|
+
data += chunk
|
|
84
|
+
return data
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
# =========================
|
|
88
|
+
# SAFE DECOMPRESSION
|
|
89
|
+
# =========================
|
|
90
|
+
def safe_decompress_stream(decompressor, data, limit):
|
|
91
|
+
out = decompressor.decompress(data, limit)
|
|
92
|
+
if decompressor.unconsumed_tail:
|
|
93
|
+
raise ValueError("Decompression exceeded safe limit")
|
|
94
|
+
return out
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
# =========================
|
|
98
|
+
# SENDER
|
|
99
|
+
# =========================
|
|
100
|
+
def send_data(host, port, password, file_path=None, compress=True):
|
|
101
|
+
print(f"FoxPipe v{TOOL_VERSION} | SEND", file=sys.stderr)
|
|
102
|
+
|
|
103
|
+
try:
|
|
104
|
+
source = open(file_path, "rb") if file_path else sys.stdin.buffer
|
|
105
|
+
except Exception as e:
|
|
106
|
+
sys.exit(f"[-] File error: {e}")
|
|
107
|
+
|
|
108
|
+
flags = FLAG_COMPRESS if compress else 0
|
|
109
|
+
session_id = secrets.token_bytes(8)
|
|
110
|
+
|
|
111
|
+
compressor = zlib.compressobj() if compress else None
|
|
112
|
+
|
|
113
|
+
try:
|
|
114
|
+
with socket.create_connection((host, port), timeout=TIMEOUT) as sock:
|
|
115
|
+
sock.settimeout(TIMEOUT)
|
|
116
|
+
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
|
117
|
+
|
|
118
|
+
salt = secrets.token_bytes(16)
|
|
119
|
+
key = derive_key(password, salt)
|
|
120
|
+
aes = AESGCM(key)
|
|
121
|
+
|
|
122
|
+
# Handshake
|
|
123
|
+
sock.sendall(MAGIC + bytes([VERSION]) + bytes([flags]))
|
|
124
|
+
sock.sendall(session_id)
|
|
125
|
+
sock.sendall(salt)
|
|
126
|
+
sock.sendall(auth_tag(key, salt, flags, session_id))
|
|
127
|
+
|
|
128
|
+
print(f"[+] Connected → {host}:{port}", file=sys.stderr)
|
|
129
|
+
|
|
130
|
+
total = 0
|
|
131
|
+
start = time.time()
|
|
132
|
+
last = time.time()
|
|
133
|
+
|
|
134
|
+
while True:
|
|
135
|
+
if time.time() - last > SESSION_TIMEOUT:
|
|
136
|
+
sys.exit("\n[-] Session timeout")
|
|
137
|
+
|
|
138
|
+
chunk = source.read(CHUNK_SIZE)
|
|
139
|
+
if not chunk:
|
|
140
|
+
break
|
|
141
|
+
|
|
142
|
+
payload = compressor.compress(chunk) if compress else chunk
|
|
143
|
+
|
|
144
|
+
if payload:
|
|
145
|
+
encrypted = encrypt_data(aes, payload)
|
|
146
|
+
sock.sendall(len(encrypted).to_bytes(4, "big") + encrypted)
|
|
147
|
+
|
|
148
|
+
total += len(chunk)
|
|
149
|
+
last = time.time()
|
|
150
|
+
|
|
151
|
+
elapsed = time.time() - start
|
|
152
|
+
speed = (total / 1024) / elapsed if elapsed else 0
|
|
153
|
+
|
|
154
|
+
print(f"\r[>] {total/1024:.2f} KB | {speed:.2f} KB/s",
|
|
155
|
+
end="", file=sys.stderr)
|
|
156
|
+
|
|
157
|
+
# Flush compression
|
|
158
|
+
if compress:
|
|
159
|
+
final = compressor.flush()
|
|
160
|
+
if final:
|
|
161
|
+
encrypted = encrypt_data(aes, final)
|
|
162
|
+
sock.sendall(len(encrypted).to_bytes(4, "big") + encrypted)
|
|
163
|
+
|
|
164
|
+
sock.sendall((0).to_bytes(4, "big"))
|
|
165
|
+
sock.shutdown(socket.SHUT_WR)
|
|
166
|
+
|
|
167
|
+
print("\n[+] Done", file=sys.stderr)
|
|
168
|
+
|
|
169
|
+
except Exception as e:
|
|
170
|
+
sys.exit(f"\n[-] Sender error: {e}")
|
|
171
|
+
|
|
172
|
+
finally:
|
|
173
|
+
if file_path:
|
|
174
|
+
source.close()
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
# =========================
|
|
178
|
+
# RECEIVER
|
|
179
|
+
# =========================
|
|
180
|
+
def receive_data(port, password, public, max_gb):
|
|
181
|
+
print(f"FoxPipe v{TOOL_VERSION} | RECEIVE", file=sys.stderr)
|
|
182
|
+
print("[i] Start this FIRST, then run sender", file=sys.stderr)
|
|
183
|
+
|
|
184
|
+
bind = "0.0.0.0" if public else "127.0.0.1"
|
|
185
|
+
max_total = max_gb * 1024 * 1024 * 1024
|
|
186
|
+
decompressor = zlib.decompressobj()
|
|
187
|
+
|
|
188
|
+
try:
|
|
189
|
+
with socket.socket() as sock:
|
|
190
|
+
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
191
|
+
sock.bind((bind, port))
|
|
192
|
+
sock.listen(1)
|
|
193
|
+
|
|
194
|
+
print(f"[+] Listening on {bind}:{port}", file=sys.stderr)
|
|
195
|
+
|
|
196
|
+
conn, addr = sock.accept()
|
|
197
|
+
conn.settimeout(TIMEOUT)
|
|
198
|
+
conn.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
|
199
|
+
|
|
200
|
+
with conn:
|
|
201
|
+
print(f"[+] Connected ← {addr}", file=sys.stderr)
|
|
202
|
+
|
|
203
|
+
header = recv_exact(conn, len(MAGIC) + 2)
|
|
204
|
+
|
|
205
|
+
if header[:len(MAGIC)] != MAGIC:
|
|
206
|
+
sys.exit("[-] Invalid protocol")
|
|
207
|
+
|
|
208
|
+
version = header[len(MAGIC)]
|
|
209
|
+
flags = header[len(MAGIC) + 1]
|
|
210
|
+
|
|
211
|
+
if version != VERSION:
|
|
212
|
+
sys.exit("[-] Version mismatch")
|
|
213
|
+
|
|
214
|
+
session_id = recv_exact(conn, 8)
|
|
215
|
+
salt = recv_exact(conn, 16)
|
|
216
|
+
|
|
217
|
+
key = derive_key(password, salt)
|
|
218
|
+
|
|
219
|
+
recv_tag = recv_exact(conn, 32)
|
|
220
|
+
if not hmac.compare_digest(
|
|
221
|
+
recv_tag,
|
|
222
|
+
auth_tag(key, salt, flags, session_id)
|
|
223
|
+
):
|
|
224
|
+
sys.exit("[-] Authentication failed")
|
|
225
|
+
|
|
226
|
+
aes = AESGCM(key)
|
|
227
|
+
|
|
228
|
+
total = 0
|
|
229
|
+
start = time.time()
|
|
230
|
+
|
|
231
|
+
while True:
|
|
232
|
+
length = int.from_bytes(recv_exact(conn, 4), "big")
|
|
233
|
+
|
|
234
|
+
if length == 0:
|
|
235
|
+
break
|
|
236
|
+
|
|
237
|
+
if length <= 0 or length > MAX_CHUNK:
|
|
238
|
+
sys.exit("[-] Invalid size")
|
|
239
|
+
|
|
240
|
+
data = recv_exact(conn, length)
|
|
241
|
+
decrypted = decrypt_data(aes, data)
|
|
242
|
+
|
|
243
|
+
if flags & FLAG_COMPRESS:
|
|
244
|
+
output = safe_decompress_stream(decompressor, decrypted, MAX_CHUNK)
|
|
245
|
+
else:
|
|
246
|
+
output = decrypted
|
|
247
|
+
|
|
248
|
+
if output:
|
|
249
|
+
sys.stdout.buffer.write(output)
|
|
250
|
+
sys.stdout.buffer.flush()
|
|
251
|
+
total += len(output)
|
|
252
|
+
|
|
253
|
+
if total > max_total:
|
|
254
|
+
sys.exit("\n[-] Transfer exceeded safety limit")
|
|
255
|
+
|
|
256
|
+
elapsed = time.time() - start
|
|
257
|
+
speed = (total / 1024) / elapsed if elapsed else 0
|
|
258
|
+
|
|
259
|
+
print(f"\r[<] {total/1024:.2f} KB | {speed:.2f} KB/s",
|
|
260
|
+
end="", file=sys.stderr)
|
|
261
|
+
|
|
262
|
+
# Final flush
|
|
263
|
+
if flags & FLAG_COMPRESS:
|
|
264
|
+
remaining = decompressor.flush()
|
|
265
|
+
if remaining:
|
|
266
|
+
sys.stdout.buffer.write(remaining)
|
|
267
|
+
sys.stdout.buffer.flush()
|
|
268
|
+
|
|
269
|
+
print("\n[+] Done", file=sys.stderr)
|
|
270
|
+
|
|
271
|
+
except Exception as e:
|
|
272
|
+
sys.exit(f"\n[-] Receiver error: {e}")
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
# =========================
|
|
276
|
+
# MAIN
|
|
277
|
+
# =========================
|
|
278
|
+
def main():
|
|
279
|
+
parser = argparse.ArgumentParser(description="FoxPipe")
|
|
280
|
+
parser.add_argument('--version', action='version', version=f'FoxPipe {TOOL_VERSION}')
|
|
281
|
+
|
|
282
|
+
sub = parser.add_subparsers(dest="mode", required=True)
|
|
283
|
+
|
|
284
|
+
s = sub.add_parser("send")
|
|
285
|
+
s.add_argument("host")
|
|
286
|
+
s.add_argument("port", type=int)
|
|
287
|
+
s.add_argument("-p", "--password")
|
|
288
|
+
s.add_argument("--file")
|
|
289
|
+
s.add_argument("--no-compress", action="store_true")
|
|
290
|
+
|
|
291
|
+
r = sub.add_parser("receive")
|
|
292
|
+
r.add_argument("port", type=int)
|
|
293
|
+
r.add_argument("-p", "--password")
|
|
294
|
+
r.add_argument("--public", action="store_true")
|
|
295
|
+
r.add_argument("--limit", type=int, default=5, help="Total GB limit (default: 5)")
|
|
296
|
+
|
|
297
|
+
args = parser.parse_args()
|
|
298
|
+
|
|
299
|
+
password = args.password or getpass.getpass("Password: ")
|
|
300
|
+
if not password.strip():
|
|
301
|
+
sys.exit("[-] Password required")
|
|
302
|
+
|
|
303
|
+
if args.mode == "send":
|
|
304
|
+
send_data(
|
|
305
|
+
args.host,
|
|
306
|
+
args.port,
|
|
307
|
+
password,
|
|
308
|
+
args.file,
|
|
309
|
+
compress=not args.no_compress
|
|
310
|
+
)
|
|
311
|
+
else:
|
|
312
|
+
receive_data(args.port, password, args.public, args.limit)
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
# =========================
|
|
316
|
+
# ENTRY
|
|
317
|
+
# =========================
|
|
318
|
+
if __name__ == "__main__":
|
|
319
|
+
try:
|
|
320
|
+
main()
|
|
321
|
+
except KeyboardInterrupt:
|
|
322
|
+
print("\n[!] Interrupted", file=sys.stderr)
|
|
323
|
+
sys.exit(130)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "foxpipe"
|
|
7
|
+
version = "1.9.0"
|
|
8
|
+
description = "Secure • Simple • Reliable data streaming. End-to-end encrypted Unix pipes."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
license = {text = "MIT"}
|
|
12
|
+
authors = [{name = "FoxHackerzDevs Team"}]
|
|
13
|
+
keywords = ["cli", "encryption", "aes-gcm", "netcat", "pipe", "security"]
|
|
14
|
+
dependencies = [
|
|
15
|
+
"cryptography>=41.0.0",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
[project.scripts]
|
|
19
|
+
foxpipe = "foxpipe:main"
|
|
20
|
+
|
|
21
|
+
[project.urls]
|
|
22
|
+
Homepage = "https://github.com/foxhackerzdevs/FoxPipe"
|
|
23
|
+
Repository = "https://github.com/foxhackerzdevs/FoxPipe"
|
|
24
|
+
|
|
25
|
+
# This is the line you need to add
|
|
26
|
+
[tool.setuptools]
|
|
27
|
+
py-modules = ["foxpipe"]
|
foxpipe-1.9.0/setup.cfg
ADDED