pathl 2.1.7__tar.gz → 2.2.1b1__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.
pathl-2.2.1b1/PKG-INFO ADDED
@@ -0,0 +1,88 @@
1
+ Metadata-Version: 2.4
2
+ Name: pathl
3
+ Version: 2.2.1b1
4
+ Summary: General-purpose cybersecurity toolkit
5
+ Author: Alicja
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://pip.pathl.pl
8
+ Project-URL: Repository, https://github.com/AlicjaPathl/pathl
9
+ Project-URL: Documentation, https://pip.pathl.pl/docs
10
+ Project-URL: Issues, https://github.com/AlicjaPathl/pathl/issues
11
+ Requires-Python: >=3.8
12
+ Description-Content-Type: text/markdown
13
+ Requires-Dist: rsa
14
+ Requires-Dist: pycryptodome
15
+
16
+ # 📦 pathl 2.1.7
17
+
18
+ **pathl** to lekki i wydajny toolkit CLI oraz biblioteka programistyczna do zadań z zakresu cyberbezpieczeństwa i kryptografii, napisana w języku Python i C.
19
+
20
+ ---
21
+
22
+ ## 🚀 Szybki start
23
+
24
+ ### Instalacja i kompilacja
25
+ Upewnij się, że masz zainstalowanego Pythona w wersji 3.8 lub nowszej, kompilator GCC oraz nagłówki deweloperskie Pythona (np. `python3-devel` lub `python3-dev`).
26
+
27
+ 1. Zainstaluj bibliotekę wraz z zależnościami:
28
+ ```bash
29
+ pip install pathl
30
+ ```
31
+
32
+ 2. Skompiluj natywne rozszerzenie C (`fastscan`):
33
+ ```bash
34
+ make build-c
35
+ ```
36
+
37
+ ### Użycie CLI
38
+ Narzędzie udostępnia prosty interfejs wiersza poleceń:
39
+
40
+ ```bash
41
+ # Szybkie skanowanie portów w C z nieblokującymi gniazdami (np. porty 1-1024 z limitem 1000 połączeń współbieżnych)
42
+ pathl fastscan 192.168.0.1 --start 1 --end 1024 --concurrency 1000 --timeout 0.5
43
+
44
+ # Skanowanie portów TCP w wybranym przedziale w Pythonie (starsza metoda wielowątkowa)
45
+ pathl scan 192.168.0.1 --start 1 --end 1024 --threads 100
46
+
47
+ # Zapytanie DNS lookup (zwraca adresy IP domeny)
48
+ pathl dns google.com
49
+
50
+ # Wyświetlenie powitania
51
+ pathl hello
52
+ ```
53
+
54
+ ### Użycie jako biblioteka (Python API)
55
+ ```python
56
+ # Test instalacji
57
+ from pathl.hello import World
58
+ World().main() # Wypisze: "Hello Its My Packeg"
59
+
60
+ # Zarządzanie kluczami i szyfrowanie z podziałem na moduły
61
+ from pathl.crypto import aes, rsa, utils
62
+
63
+ # 1. Generowanie i ładowanie kluczy przy użyciu klasy FileOI
64
+ file_io = utils.FileOI(key_file="aes.key", pv_file="rsa.priv", pub_file="rsa.pub")
65
+ rsa_keys = file_io.load_RSA(f=1) # Wymusza generowanie, jeśli brak kluczy
66
+ aes_key = file_io.load_aes(f=1)
67
+
68
+ # 2. Szyfrowanie asymetryczne (RSA)
69
+ rsa_cipher = rsa.CryptoIORsa(rsa_keys)
70
+ encrypted_rsa = rsa_cipher.crypt("Tajna wiadomosc")
71
+ decrypted_rsa = rsa_cipher.decrypt(encrypted_rsa)
72
+
73
+ # 3. Szyfrowanie symetryczne (AES-ECB)
74
+ aes_cipher = aes.CryptoIOAes(aes_key)
75
+ encrypted_aes = aes_cipher.crypt("Tajna wiadomosc")
76
+ decrypted_aes = aes_cipher.decrypt(encrypted_aes)
77
+ ```
78
+
79
+ > [!NOTE]
80
+ > Klasy można również importować bezpośrednio z pakietu głównego:
81
+ > `from pathl.crypto import FileOI, CryptoIORsa, CryptoIOAes`
82
+
83
+ ---
84
+
85
+ ## 📚 Pełna dokumentacja
86
+
87
+ Szczegółowy opis architektury systemu, modułów API, zagadnień bezpieczeństwa oraz **analizy złożoności czasowej i pamięciowej algorytmów** znajduje się w pliku:
88
+ 👉 **[Docs.md](file:///home/neon/pathl/Docs.md)**
@@ -0,0 +1,73 @@
1
+ # 📦 pathl 2.1.7
2
+
3
+ **pathl** to lekki i wydajny toolkit CLI oraz biblioteka programistyczna do zadań z zakresu cyberbezpieczeństwa i kryptografii, napisana w języku Python i C.
4
+
5
+ ---
6
+
7
+ ## 🚀 Szybki start
8
+
9
+ ### Instalacja i kompilacja
10
+ Upewnij się, że masz zainstalowanego Pythona w wersji 3.8 lub nowszej, kompilator GCC oraz nagłówki deweloperskie Pythona (np. `python3-devel` lub `python3-dev`).
11
+
12
+ 1. Zainstaluj bibliotekę wraz z zależnościami:
13
+ ```bash
14
+ pip install pathl
15
+ ```
16
+
17
+ 2. Skompiluj natywne rozszerzenie C (`fastscan`):
18
+ ```bash
19
+ make build-c
20
+ ```
21
+
22
+ ### Użycie CLI
23
+ Narzędzie udostępnia prosty interfejs wiersza poleceń:
24
+
25
+ ```bash
26
+ # Szybkie skanowanie portów w C z nieblokującymi gniazdami (np. porty 1-1024 z limitem 1000 połączeń współbieżnych)
27
+ pathl fastscan 192.168.0.1 --start 1 --end 1024 --concurrency 1000 --timeout 0.5
28
+
29
+ # Skanowanie portów TCP w wybranym przedziale w Pythonie (starsza metoda wielowątkowa)
30
+ pathl scan 192.168.0.1 --start 1 --end 1024 --threads 100
31
+
32
+ # Zapytanie DNS lookup (zwraca adresy IP domeny)
33
+ pathl dns google.com
34
+
35
+ # Wyświetlenie powitania
36
+ pathl hello
37
+ ```
38
+
39
+ ### Użycie jako biblioteka (Python API)
40
+ ```python
41
+ # Test instalacji
42
+ from pathl.hello import World
43
+ World().main() # Wypisze: "Hello Its My Packeg"
44
+
45
+ # Zarządzanie kluczami i szyfrowanie z podziałem na moduły
46
+ from pathl.crypto import aes, rsa, utils
47
+
48
+ # 1. Generowanie i ładowanie kluczy przy użyciu klasy FileOI
49
+ file_io = utils.FileOI(key_file="aes.key", pv_file="rsa.priv", pub_file="rsa.pub")
50
+ rsa_keys = file_io.load_RSA(f=1) # Wymusza generowanie, jeśli brak kluczy
51
+ aes_key = file_io.load_aes(f=1)
52
+
53
+ # 2. Szyfrowanie asymetryczne (RSA)
54
+ rsa_cipher = rsa.CryptoIORsa(rsa_keys)
55
+ encrypted_rsa = rsa_cipher.crypt("Tajna wiadomosc")
56
+ decrypted_rsa = rsa_cipher.decrypt(encrypted_rsa)
57
+
58
+ # 3. Szyfrowanie symetryczne (AES-ECB)
59
+ aes_cipher = aes.CryptoIOAes(aes_key)
60
+ encrypted_aes = aes_cipher.crypt("Tajna wiadomosc")
61
+ decrypted_aes = aes_cipher.decrypt(encrypted_aes)
62
+ ```
63
+
64
+ > [!NOTE]
65
+ > Klasy można również importować bezpośrednio z pakietu głównego:
66
+ > `from pathl.crypto import FileOI, CryptoIORsa, CryptoIOAes`
67
+
68
+ ---
69
+
70
+ ## 📚 Pełna dokumentacja
71
+
72
+ Szczegółowy opis architektury systemu, modułów API, zagadnień bezpieczeństwa oraz **analizy złożoności czasowej i pamięciowej algorytmów** znajduje się w pliku:
73
+ 👉 **[Docs.md](file:///home/neon/pathl/Docs.md)**
@@ -0,0 +1,127 @@
1
+ import argparse
2
+ from pathl.scaner.scaner import run_scan
3
+ from pathl.dns.dns import run_dns
4
+
5
+ # reszta kodu bez zmian
6
+
7
+ def cmd_hello(args):
8
+ print("Hello from pathl 🔐")
9
+
10
+
11
+ def cmd_scan(args):
12
+ run_scan(
13
+ target=args.target,
14
+ start=args.start,
15
+ end=args.end,
16
+ threads=args.threads,
17
+ timeout=args.timeout,
18
+ output=args.output
19
+ )
20
+
21
+
22
+ def cmd_fastscan(args):
23
+ import sys
24
+ try:
25
+ from pathl.scaner import fastscan
26
+ except ImportError:
27
+ print("Error: fastscan C extension is not compiled. Please run 'make build-c' first.")
28
+ sys.exit(1)
29
+
30
+ import socket
31
+ print(f"[*] Target : {args.target}")
32
+ print(f"[*] Ports : {args.start}-{args.end}")
33
+ print(f"[*] Limit : {args.concurrency}")
34
+ print(f"[*] Timeout: {args.timeout}s\n")
35
+
36
+ timeout_ms = int(args.timeout * 1000)
37
+ open_ports = fastscan.scan(args.target, args.start, args.end, args.concurrency, timeout_ms)
38
+
39
+ print("\n[*] Scan finished")
40
+ for port in open_ports:
41
+ try:
42
+ service = socket.getservbyport(port)
43
+ except Exception:
44
+ service = "unknown"
45
+ print(f"[OPEN] {port}/tcp ({service})")
46
+
47
+ if args.output:
48
+ with open(args.output, "w") as f:
49
+ for port in open_ports:
50
+ f.write(f"{port}\n")
51
+ print(f"[*] Saved to {args.output}")
52
+
53
+
54
+ def cmd_sha256(args):
55
+ import sys
56
+ try:
57
+ from pathl.hash import sha256
58
+ except ImportError:
59
+ print("Error: sha256 C extension is not compiled. Run 'make build-c' first.")
60
+ sys.exit(1)
61
+
62
+ result = sha256.hash(args.text)
63
+ print(result)
64
+
65
+
66
+ def main():
67
+ parser = argparse.ArgumentParser(
68
+ prog="pathl",
69
+ description="General-purpose cybersecurity toolkit"
70
+ )
71
+
72
+ subparsers = parser.add_subparsers(dest="command")
73
+
74
+
75
+ # HELLO
76
+ parser_hello = subparsers.add_parser("hello")
77
+ parser_hello.set_defaults(func=cmd_hello)
78
+
79
+ #DNS
80
+ parser_dns = subparsers.add_parser("dns")
81
+ parser_dns.add_argument("domain")
82
+ parser_dns.add_argument("-p", action="store_true")
83
+ parser_dns.set_defaults(func=run_dns)
84
+
85
+
86
+ # SCAN
87
+ parser_scan = subparsers.add_parser("scan")
88
+
89
+ parser_scan.add_argument("target")
90
+
91
+ parser_scan.add_argument("--start", type=int, default=1)
92
+ parser_scan.add_argument("--end", type=int, default=1024)
93
+
94
+ parser_scan.add_argument("--threads", type=int, default=100)
95
+ parser_scan.add_argument("--timeout", type=float, default=0.3)
96
+
97
+ parser_scan.add_argument("--output")
98
+
99
+ parser_scan.set_defaults(func=cmd_scan)
100
+
101
+ # FASTSCAN
102
+ parser_fastscan = subparsers.add_parser("fastscan")
103
+ parser_fastscan.add_argument("target")
104
+ parser_fastscan.add_argument("--start", type=int, default=1)
105
+ parser_fastscan.add_argument("--end", type=int, default=1024)
106
+ parser_fastscan.add_argument("--concurrency", type=int, default=1000)
107
+ parser_fastscan.add_argument("--timeout", type=float, default=0.5)
108
+ parser_fastscan.add_argument("--output")
109
+ parser_fastscan.set_defaults(func=cmd_fastscan)
110
+
111
+ # SHA256
112
+ parser_sha256 = subparsers.add_parser("sha256", help="Haszuj tekst algorytmem SHA-256")
113
+ parser_sha256.add_argument("text", help="Tekst do zahaszowania")
114
+ parser_sha256.set_defaults(func=cmd_sha256)
115
+
116
+
117
+ args = parser.parse_args()
118
+
119
+ if not args.command:
120
+ parser.print_help()
121
+ return
122
+
123
+ args.func(args)
124
+
125
+
126
+ if __name__ == "__main__":
127
+ main()
@@ -0,0 +1,9 @@
1
+ from pathl.crypto import aes
2
+ from pathl.crypto import rsa
3
+ from pathl.crypto import utils
4
+
5
+ from pathl.crypto.utils import FileOI
6
+ from pathl.crypto.rsa import CryptoIORsa
7
+ from pathl.crypto.aes import CryptoIOAes
8
+
9
+ __all__ = ["aes", "rsa", "utils", "FileOI", "CryptoIORsa", "CryptoIOAes"]
@@ -0,0 +1,18 @@
1
+ import hashlib
2
+ import secrets
3
+ from Crypto.Cipher import AES
4
+ from Crypto.Util.Padding import pad, unpad
5
+
6
+ class CryptoIOAes:
7
+ def __init__(self, key):
8
+ self.key = key
9
+ self.cipher = AES.new(self.key, AES.MODE_ECB)
10
+
11
+ def crypt(self, msg):
12
+ return self.cipher.encrypt(pad(msg.encode(), 16))
13
+
14
+ def decrypt(self, text):
15
+ return unpad(self.cipher.decrypt(text), 16)
16
+
17
+ def gen_key(self, lengt=256):
18
+ return hashlib.sha256(secrets.token_bytes(2048)).digest()
@@ -0,0 +1,16 @@
1
+ import rsa
2
+ import hashlib
3
+ import secrets
4
+
5
+ class CryptoIORsa:
6
+ def __init__(self, load):
7
+ self.pv, self.pub = load
8
+
9
+ def crypt(self, msg):
10
+ return rsa.encrypt(msg.encode(), self.pub)
11
+
12
+ def decrypt(self, cipher):
13
+ return rsa.decrypt(cipher, self.pv)
14
+
15
+ def gen_challenge(self):
16
+ return hashlib.sha256(secrets.token_bytes(32)).hexdigest()
@@ -0,0 +1,49 @@
1
+ import os
2
+ import secrets
3
+ import hashlib
4
+ import rsa
5
+
6
+ class FileOI:
7
+ def __init__(self, key_file="key.key", pv_file="rsa2048", pub_file="rsa2048.pub"):
8
+ self.pv_file = pv_file
9
+ self.pub_file = pub_file
10
+ self.key_file = key_file
11
+
12
+ def check_file(self):
13
+ if not (os.path.exists(self.pv_file) and os.path.exists(self.pub_file)):
14
+ self.new_gen_rsa()
15
+
16
+ def new_gen_rsa(self):
17
+ pub, pv = rsa.newkeys(2048)
18
+
19
+ with open(self.pv_file, "wb") as w:
20
+ w.write(pv.save_pkcs1())
21
+ with open(self.pub_file, "wb") as w:
22
+ w.write(pub.save_pkcs1())
23
+ print("KEY")
24
+ del pub, pv
25
+
26
+ def load_RSA(self, f=0):
27
+ if f:
28
+ self.check_file()
29
+ with open(self.pv_file, "rb") as r:
30
+ pv = rsa.PrivateKey.load_pkcs1(r.read())
31
+ with open(self.pub_file, "rb") as r:
32
+ pub = rsa.PublicKey.load_pkcs1(r.read())
33
+ return pv, pub
34
+
35
+ def load_aes(self, f=0):
36
+ if f or not os.path.exists(self.key_file):
37
+ raw = secrets.token_bytes(32)
38
+ key = hashlib.sha256(raw).digest()
39
+
40
+ with open(self.key_file, "wb") as file:
41
+ file.write(key)
42
+
43
+ with open(self.key_file, "rb") as file:
44
+ key = file.read()
45
+
46
+ if len(key) != 32:
47
+ raise ValueError(f"Invalid key length: {len(key)}")
48
+
49
+ return key
@@ -0,0 +1,11 @@
1
+ """
2
+ pathl.hash — moduły haszujące napisane w C
3
+
4
+ Użycie:
5
+ from pathl.hash import sha256
6
+ print(sha256.hash("hello"))
7
+ # => 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
8
+
9
+ print(sha256.hash_bytes(b"hello"))
10
+ # => 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
11
+ """
@@ -0,0 +1,220 @@
1
+ /*
2
+ * pathl.hash.sha256 — SHA-256 w czystym C (bez OpenSSL)
3
+ * Użycie z Pythona:
4
+ * from pathl.hash import sha256
5
+ * print(sha256.hash("hello"))
6
+ */
7
+
8
+ #define PY_SSIZE_T_CLEAN
9
+ #include <Python.h>
10
+ #include <stdint.h>
11
+ #include <string.h>
12
+
13
+ /* ── SHA-256 stałe ───────────────────────────────────────────────────── */
14
+ static const uint32_t K[64] = {
15
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
16
+ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
17
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
18
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
19
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
20
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
21
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
22
+ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
23
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
24
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
25
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
26
+ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
27
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
28
+ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
29
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
30
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
31
+ };
32
+
33
+ /* ── makra ────────────────────────────────────────────────────────────── */
34
+ #define ROTR(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
35
+ #define CH(x, y, z) (((x) & (y)) ^ (~(x) & (z)))
36
+ #define MAJ(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
37
+ #define EP0(x) (ROTR(x,2) ^ ROTR(x,13) ^ ROTR(x,22))
38
+ #define EP1(x) (ROTR(x,6) ^ ROTR(x,11) ^ ROTR(x,25))
39
+ #define SIG0(x) (ROTR(x,7) ^ ROTR(x,18) ^ ((x) >> 3))
40
+ #define SIG1(x) (ROTR(x,17) ^ ROTR(x,19) ^ ((x) >> 10))
41
+
42
+ typedef struct {
43
+ uint8_t data[64];
44
+ uint32_t datalen;
45
+ uint64_t bitlen;
46
+ uint32_t state[8];
47
+ } SHA256_CTX;
48
+
49
+ static void sha256_transform(SHA256_CTX *ctx, const uint8_t *data)
50
+ {
51
+ uint32_t a, b, c, d, e, f, g, h, i, j, t1, t2, m[64];
52
+
53
+ for (i = 0, j = 0; i < 16; i++, j += 4)
54
+ m[i] = ((uint32_t)data[j] << 24) |
55
+ ((uint32_t)data[j + 1] << 16) |
56
+ ((uint32_t)data[j + 2] << 8) |
57
+ ((uint32_t)data[j + 3]);
58
+ for (; i < 64; i++)
59
+ m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];
60
+
61
+ a = ctx->state[0]; b = ctx->state[1];
62
+ c = ctx->state[2]; d = ctx->state[3];
63
+ e = ctx->state[4]; f = ctx->state[5];
64
+ g = ctx->state[6]; h = ctx->state[7];
65
+
66
+ for (i = 0; i < 64; i++) {
67
+ t1 = h + EP1(e) + CH(e, f, g) + K[i] + m[i];
68
+ t2 = EP0(a) + MAJ(a, b, c);
69
+ h = g; g = f; f = e; e = d + t1;
70
+ d = c; c = b; b = a; a = t1 + t2;
71
+ }
72
+
73
+ ctx->state[0] += a; ctx->state[1] += b;
74
+ ctx->state[2] += c; ctx->state[3] += d;
75
+ ctx->state[4] += e; ctx->state[5] += f;
76
+ ctx->state[6] += g; ctx->state[7] += h;
77
+ }
78
+
79
+ static void sha256_init(SHA256_CTX *ctx)
80
+ {
81
+ ctx->datalen = 0;
82
+ ctx->bitlen = 0;
83
+ ctx->state[0] = 0x6a09e667;
84
+ ctx->state[1] = 0xbb67ae85;
85
+ ctx->state[2] = 0x3c6ef372;
86
+ ctx->state[3] = 0xa54ff53a;
87
+ ctx->state[4] = 0x510e527f;
88
+ ctx->state[5] = 0x9b05688c;
89
+ ctx->state[6] = 0x1f83d9ab;
90
+ ctx->state[7] = 0x5be0cd19;
91
+ }
92
+
93
+ static void sha256_update(SHA256_CTX *ctx, const uint8_t *data, size_t len)
94
+ {
95
+ for (size_t i = 0; i < len; i++) {
96
+ ctx->data[ctx->datalen++] = data[i];
97
+ if (ctx->datalen == 64) {
98
+ sha256_transform(ctx, ctx->data);
99
+ ctx->bitlen += 512;
100
+ ctx->datalen = 0;
101
+ }
102
+ }
103
+ }
104
+
105
+ static void sha256_final(SHA256_CTX *ctx, uint8_t *hash)
106
+ {
107
+ uint32_t i = ctx->datalen;
108
+
109
+ if (ctx->datalen < 56) {
110
+ ctx->data[i++] = 0x80;
111
+ while (i < 56) ctx->data[i++] = 0x00;
112
+ } else {
113
+ ctx->data[i++] = 0x80;
114
+ while (i < 64) ctx->data[i++] = 0x00;
115
+ sha256_transform(ctx, ctx->data);
116
+ memset(ctx->data, 0, 56);
117
+ }
118
+
119
+ ctx->bitlen += (uint64_t)ctx->datalen * 8;
120
+ ctx->data[63] = (uint8_t)(ctx->bitlen);
121
+ ctx->data[62] = (uint8_t)(ctx->bitlen >> 8);
122
+ ctx->data[61] = (uint8_t)(ctx->bitlen >> 16);
123
+ ctx->data[60] = (uint8_t)(ctx->bitlen >> 24);
124
+ ctx->data[59] = (uint8_t)(ctx->bitlen >> 32);
125
+ ctx->data[58] = (uint8_t)(ctx->bitlen >> 40);
126
+ ctx->data[57] = (uint8_t)(ctx->bitlen >> 48);
127
+ ctx->data[56] = (uint8_t)(ctx->bitlen >> 56);
128
+ sha256_transform(ctx, ctx->data);
129
+
130
+ for (i = 0; i < 4; i++) {
131
+ hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0xff;
132
+ hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0xff;
133
+ hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0xff;
134
+ hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0xff;
135
+ hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0xff;
136
+ hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0xff;
137
+ hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0xff;
138
+ hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0xff;
139
+ }
140
+ }
141
+
142
+ /* ── Python API ───────────────────────────────────────────────────────── */
143
+
144
+ /*
145
+ * sha256.hash(text: str) -> str
146
+ * Zwraca hex-digest SHA-256 dla podanego tekstu (UTF-8).
147
+ */
148
+ static PyObject *py_sha256_hash(PyObject *self, PyObject *args)
149
+ {
150
+ const char *input;
151
+ Py_ssize_t input_len;
152
+
153
+ if (!PyArg_ParseTuple(args, "s#", &input, &input_len))
154
+ return NULL;
155
+
156
+ SHA256_CTX ctx;
157
+ uint8_t digest[32];
158
+ char hexbuf[65];
159
+
160
+ Py_BEGIN_ALLOW_THREADS
161
+ sha256_init(&ctx);
162
+ sha256_update(&ctx, (const uint8_t *)input, (size_t)input_len);
163
+ sha256_final(&ctx, digest);
164
+ for (int i = 0; i < 32; i++)
165
+ snprintf(hexbuf + i * 2, 3, "%02x", digest[i]);
166
+ hexbuf[64] = '\0';
167
+ Py_END_ALLOW_THREADS
168
+
169
+ return PyUnicode_FromString(hexbuf);
170
+ }
171
+
172
+ /*
173
+ * sha256.hash_bytes(data: bytes) -> str
174
+ * Zwraca hex-digest SHA-256 dla surowych bajtów.
175
+ */
176
+ static PyObject *py_sha256_hash_bytes(PyObject *self, PyObject *args)
177
+ {
178
+ const uint8_t *input;
179
+ Py_ssize_t input_len;
180
+
181
+ if (!PyArg_ParseTuple(args, "y#", &input, &input_len))
182
+ return NULL;
183
+
184
+ SHA256_CTX ctx;
185
+ uint8_t digest[32];
186
+ char hexbuf[65];
187
+
188
+ Py_BEGIN_ALLOW_THREADS
189
+ sha256_init(&ctx);
190
+ sha256_update(&ctx, input, (size_t)input_len);
191
+ sha256_final(&ctx, digest);
192
+ for (int i = 0; i < 32; i++)
193
+ snprintf(hexbuf + i * 2, 3, "%02x", digest[i]);
194
+ hexbuf[64] = '\0';
195
+ Py_END_ALLOW_THREADS
196
+
197
+ return PyUnicode_FromString(hexbuf);
198
+ }
199
+
200
+ /* ── Tabela metod ─────────────────────────────────────────────────────── */
201
+ static PyMethodDef Sha256Methods[] = {
202
+ {"hash", py_sha256_hash, METH_VARARGS,
203
+ "hash(text: str) -> str\n\nZwraca hex SHA-256 dla tekstu UTF-8."},
204
+ {"hash_bytes", py_sha256_hash_bytes, METH_VARARGS,
205
+ "hash_bytes(data: bytes) -> str\n\nZwraca hex SHA-256 dla surowych bajtów."},
206
+ {NULL, NULL, 0, NULL}
207
+ };
208
+
209
+ static struct PyModuleDef sha256module = {
210
+ PyModuleDef_HEAD_INIT,
211
+ "sha256",
212
+ "Moduł SHA-256 napisany w czystym C (bez OpenSSL).",
213
+ -1,
214
+ Sha256Methods
215
+ };
216
+
217
+ PyMODINIT_FUNC PyInit_sha256(void)
218
+ {
219
+ return PyModule_Create(&sha256module);
220
+ }
@@ -3,3 +3,5 @@ class World:
3
3
  self.msg = "Hello Its My Packeg"
4
4
  def main(self):
5
5
  print(self.msg)
6
+ def versin(self):
7
+ print("2.9.9")
@@ -0,0 +1,13 @@
1
+ import sys
2
+
3
+ try:
4
+ from pathl.math.math import add
5
+ except ImportError:
6
+ # Uprzejme powiadomienie użytkownika w razie braku kompilacji
7
+ def add(a, b):
8
+ raise ImportError(
9
+ "Moduł pathl.math.math (rozszerzenie C) nie został skompilowany. "
10
+ "Uruchom 'make build-c' w katalogu głównym projektu."
11
+ )
12
+
13
+ __all__ = ["add"]
@@ -0,0 +1,35 @@
1
+ #define PY_SSIZE_T_CLEAN
2
+ #include <Python.h>
3
+
4
+ /* Funkcja dodająca dwie liczby zmiennoprzecinkowe */
5
+ static PyObject* py_add(PyObject* self, PyObject* args) {
6
+ double a, b;
7
+
8
+ /* Parsowanie argumentów z Pythona ("dd" oznacza dwa typy double) */
9
+ if (!PyArg_ParseTuple(args, "dd", &a, &b)) {
10
+ return NULL;
11
+ }
12
+
13
+ /* Zwrócenie wyniku jako obiekt PyFloat */
14
+ return PyFloat_FromDouble(a + b);
15
+ }
16
+
17
+ /* Tablica metod dostępnych w module */
18
+ static PyMethodDef MathMethods[] = {
19
+ {"add", py_add, METH_VARARGS, "Dodaje dwie liczby zmiennoprzecinkowe."},
20
+ {NULL, NULL, 0, NULL} /* Znacznik końca tablicy */
21
+ };
22
+
23
+ /* Struktura definiująca moduł */
24
+ static struct PyModuleDef mathmodule = {
25
+ PyModuleDef_HEAD_INIT,
26
+ "math", /* Nazwa modułu */
27
+ "Prosty moduł matematyczny napisany w C.", /* Dokumentacja modułu */
28
+ -1, /* Moduł nie przechowuje stanu w zmiennych globalnych (-1) */
29
+ MathMethods
30
+ };
31
+
32
+ /* Funkcja inicjalizująca moduł - wywoływana automatycznie przy imporcie */
33
+ PyMODINIT_FUNC PyInit_math(void) {
34
+ return PyModule_Create(&mathmodule);
35
+ }
@@ -0,0 +1,200 @@
1
+ #define PY_SSIZE_T_CLEAN
2
+ #include <Python.h>
3
+ #include <sys/socket.h>
4
+ #include <netinet/in.h>
5
+ #include <arpa/inet.h>
6
+ #include <unistd.h>
7
+ #include <fcntl.h>
8
+ #include <sys/select.h>
9
+ #include <sys/time.h>
10
+ #include <netdb.h>
11
+ #include <errno.h>
12
+ #include <string.h>
13
+ #include <stdlib.h>
14
+
15
+ typedef struct {
16
+ int fd;
17
+ int port;
18
+ struct timeval start_time;
19
+ int active;
20
+ } ActiveSocket;
21
+
22
+ static PyObject* fastscan_scan(PyObject* self, PyObject* args) {
23
+ char *target;
24
+ int start_port, end_port, concurrency, timeout_ms;
25
+
26
+ if (!PyArg_ParseTuple(args, "siiii", &target, &start_port, &end_port, &concurrency, &timeout_ms)) {
27
+ return NULL;
28
+ }
29
+
30
+ if (start_port < 1 || end_port > 65535 || start_port > end_port) {
31
+ PyErr_SetString(PyExc_ValueError, "Invalid port range");
32
+ return NULL;
33
+ }
34
+
35
+ if (concurrency < 1) {
36
+ PyErr_SetString(PyExc_ValueError, "Concurrency must be >= 1");
37
+ return NULL;
38
+ }
39
+
40
+ struct hostent *he = gethostbyname(target);
41
+ if (!he) {
42
+ PyErr_SetString(PyExc_ValueError, "Could not resolve hostname");
43
+ return NULL;
44
+ }
45
+ struct in_addr target_ip = *(struct in_addr *)he->h_addr_list[0];
46
+
47
+ int total_ports = end_port - start_port + 1;
48
+ int *open_ports = malloc(sizeof(int) * total_ports);
49
+ if (!open_ports) {
50
+ return PyErr_NoMemory();
51
+ }
52
+ int open_ports_count = 0;
53
+
54
+ ActiveSocket *sockets = calloc(concurrency, sizeof(ActiveSocket));
55
+ if (!sockets) {
56
+ free(open_ports);
57
+ return PyErr_NoMemory();
58
+ }
59
+
60
+ // Release GIL for the duration of the scan
61
+ Py_BEGIN_ALLOW_THREADS
62
+
63
+ int next_port = start_port;
64
+ int active_count = 0;
65
+
66
+ while (next_port <= end_port || active_count > 0) {
67
+ // Fill active sockets up to concurrency
68
+ while (active_count < concurrency && next_port <= end_port) {
69
+ int port = next_port++;
70
+ int fd = socket(AF_INET, SOCK_STREAM, 0);
71
+ if (fd < 0) {
72
+ // Out of file descriptors? Wait for active ones to close
73
+ next_port--;
74
+ break;
75
+ }
76
+
77
+ // Non-blocking
78
+ int flags = fcntl(fd, F_GETFL, 0);
79
+ fcntl(fd, F_SETFL, flags | O_NONBLOCK);
80
+
81
+ struct sockaddr_in addr;
82
+ memset(&addr, 0, sizeof(addr));
83
+ addr.sin_family = AF_INET;
84
+ addr.sin_port = htons(port);
85
+ addr.sin_addr = target_ip;
86
+
87
+ int res = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
88
+ if (res == 0) {
89
+ open_ports[open_ports_count++] = port;
90
+ close(fd);
91
+ } else if (res < 0 && errno == EINPROGRESS) {
92
+ // Find empty slot
93
+ for (int i = 0; i < concurrency; i++) {
94
+ if (!sockets[i].active) {
95
+ sockets[i].fd = fd;
96
+ sockets[i].port = port;
97
+ gettimeofday(&sockets[i].start_time, NULL);
98
+ sockets[i].active = 1;
99
+ active_count++;
100
+ break;
101
+ }
102
+ }
103
+ } else {
104
+ close(fd);
105
+ }
106
+ }
107
+
108
+ if (active_count == 0) {
109
+ continue;
110
+ }
111
+
112
+ fd_set write_fds;
113
+ FD_ZERO(&write_fds);
114
+ int max_fd = -1;
115
+ for (int i = 0; i < concurrency; i++) {
116
+ if (sockets[i].active) {
117
+ FD_SET(sockets[i].fd, &write_fds);
118
+ if (sockets[i].fd > max_fd) {
119
+ max_fd = sockets[i].fd;
120
+ }
121
+ }
122
+ }
123
+
124
+ struct timeval sel_tv;
125
+ sel_tv.tv_sec = 0;
126
+ sel_tv.tv_usec = 10000; // 10ms select timeout
127
+
128
+ int sel_res = select(max_fd + 1, NULL, &write_fds, NULL, &sel_tv);
129
+
130
+ struct timeval now;
131
+ gettimeofday(&now, NULL);
132
+
133
+ for (int i = 0; i < concurrency; i++) {
134
+ if (!sockets[i].active) continue;
135
+
136
+ int fd = sockets[i].fd;
137
+ int port = sockets[i].port;
138
+ int closed = 0;
139
+
140
+ if (sel_res > 0 && FD_ISSET(fd, &write_fds)) {
141
+ int err = 0;
142
+ socklen_t len = sizeof(err);
143
+ if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &len) == 0) {
144
+ if (err == 0) {
145
+ open_ports[open_ports_count++] = port;
146
+ }
147
+ }
148
+ close(fd);
149
+ sockets[i].active = 0;
150
+ active_count--;
151
+ closed = 1;
152
+ }
153
+
154
+ if (!closed) {
155
+ long elapsed_ms = (now.tv_sec - sockets[i].start_time.tv_sec) * 1000 +
156
+ (now.tv_usec - sockets[i].start_time.tv_usec) / 1000;
157
+ if (elapsed_ms >= timeout_ms) {
158
+ close(fd);
159
+ sockets[i].active = 0;
160
+ active_count--;
161
+ }
162
+ }
163
+ }
164
+ }
165
+
166
+ free(sockets);
167
+
168
+ // Re-acquire GIL
169
+ Py_END_ALLOW_THREADS
170
+
171
+ PyObject *open_ports_list = PyList_New(open_ports_count);
172
+ if (!open_ports_list) {
173
+ free(open_ports);
174
+ return NULL;
175
+ }
176
+
177
+ for (int i = 0; i < open_ports_count; i++) {
178
+ PyList_SetItem(open_ports_list, i, PyLong_FromLong(open_ports[i]));
179
+ }
180
+
181
+ free(open_ports);
182
+ return open_ports_list;
183
+ }
184
+
185
+ static PyMethodDef FastscanMethods[] = {
186
+ {"scan", fastscan_scan, METH_VARARGS, "Scan ports using non-blocking C sockets."},
187
+ {NULL, NULL, 0, NULL}
188
+ };
189
+
190
+ static struct PyModuleDef fastscanmodule = {
191
+ PyModuleDef_HEAD_INIT,
192
+ "fastscan",
193
+ "Fast port scanner in C",
194
+ -1,
195
+ FastscanMethods
196
+ };
197
+
198
+ PyMODINIT_FUNC PyInit_fastscan(void) {
199
+ return PyModule_Create(&fastscanmodule);
200
+ }
@@ -0,0 +1,88 @@
1
+ Metadata-Version: 2.4
2
+ Name: pathl
3
+ Version: 2.2.1b1
4
+ Summary: General-purpose cybersecurity toolkit
5
+ Author: Alicja
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://pip.pathl.pl
8
+ Project-URL: Repository, https://github.com/AlicjaPathl/pathl
9
+ Project-URL: Documentation, https://pip.pathl.pl/docs
10
+ Project-URL: Issues, https://github.com/AlicjaPathl/pathl/issues
11
+ Requires-Python: >=3.8
12
+ Description-Content-Type: text/markdown
13
+ Requires-Dist: rsa
14
+ Requires-Dist: pycryptodome
15
+
16
+ # 📦 pathl 2.1.7
17
+
18
+ **pathl** to lekki i wydajny toolkit CLI oraz biblioteka programistyczna do zadań z zakresu cyberbezpieczeństwa i kryptografii, napisana w języku Python i C.
19
+
20
+ ---
21
+
22
+ ## 🚀 Szybki start
23
+
24
+ ### Instalacja i kompilacja
25
+ Upewnij się, że masz zainstalowanego Pythona w wersji 3.8 lub nowszej, kompilator GCC oraz nagłówki deweloperskie Pythona (np. `python3-devel` lub `python3-dev`).
26
+
27
+ 1. Zainstaluj bibliotekę wraz z zależnościami:
28
+ ```bash
29
+ pip install pathl
30
+ ```
31
+
32
+ 2. Skompiluj natywne rozszerzenie C (`fastscan`):
33
+ ```bash
34
+ make build-c
35
+ ```
36
+
37
+ ### Użycie CLI
38
+ Narzędzie udostępnia prosty interfejs wiersza poleceń:
39
+
40
+ ```bash
41
+ # Szybkie skanowanie portów w C z nieblokującymi gniazdami (np. porty 1-1024 z limitem 1000 połączeń współbieżnych)
42
+ pathl fastscan 192.168.0.1 --start 1 --end 1024 --concurrency 1000 --timeout 0.5
43
+
44
+ # Skanowanie portów TCP w wybranym przedziale w Pythonie (starsza metoda wielowątkowa)
45
+ pathl scan 192.168.0.1 --start 1 --end 1024 --threads 100
46
+
47
+ # Zapytanie DNS lookup (zwraca adresy IP domeny)
48
+ pathl dns google.com
49
+
50
+ # Wyświetlenie powitania
51
+ pathl hello
52
+ ```
53
+
54
+ ### Użycie jako biblioteka (Python API)
55
+ ```python
56
+ # Test instalacji
57
+ from pathl.hello import World
58
+ World().main() # Wypisze: "Hello Its My Packeg"
59
+
60
+ # Zarządzanie kluczami i szyfrowanie z podziałem na moduły
61
+ from pathl.crypto import aes, rsa, utils
62
+
63
+ # 1. Generowanie i ładowanie kluczy przy użyciu klasy FileOI
64
+ file_io = utils.FileOI(key_file="aes.key", pv_file="rsa.priv", pub_file="rsa.pub")
65
+ rsa_keys = file_io.load_RSA(f=1) # Wymusza generowanie, jeśli brak kluczy
66
+ aes_key = file_io.load_aes(f=1)
67
+
68
+ # 2. Szyfrowanie asymetryczne (RSA)
69
+ rsa_cipher = rsa.CryptoIORsa(rsa_keys)
70
+ encrypted_rsa = rsa_cipher.crypt("Tajna wiadomosc")
71
+ decrypted_rsa = rsa_cipher.decrypt(encrypted_rsa)
72
+
73
+ # 3. Szyfrowanie symetryczne (AES-ECB)
74
+ aes_cipher = aes.CryptoIOAes(aes_key)
75
+ encrypted_aes = aes_cipher.crypt("Tajna wiadomosc")
76
+ decrypted_aes = aes_cipher.decrypt(encrypted_aes)
77
+ ```
78
+
79
+ > [!NOTE]
80
+ > Klasy można również importować bezpośrednio z pakietu głównego:
81
+ > `from pathl.crypto import FileOI, CryptoIORsa, CryptoIOAes`
82
+
83
+ ---
84
+
85
+ ## 📚 Pełna dokumentacja
86
+
87
+ Szczegółowy opis architektury systemu, modułów API, zagadnień bezpieczeństwa oraz **analizy złożoności czasowej i pamięciowej algorytmów** znajduje się w pliku:
88
+ 👉 **[Docs.md](file:///home/neon/pathl/Docs.md)**
@@ -1,14 +1,25 @@
1
1
  README.md
2
2
  pyproject.toml
3
+ setup.py
3
4
  pathl/__init__.py
4
5
  pathl/cli.py
5
6
  pathl.egg-info/PKG-INFO
6
7
  pathl.egg-info/SOURCES.txt
7
8
  pathl.egg-info/dependency_links.txt
8
9
  pathl.egg-info/entry_points.txt
10
+ pathl.egg-info/requires.txt
9
11
  pathl.egg-info/top_level.txt
12
+ pathl/crypto/__init__.py
13
+ pathl/crypto/aes.py
14
+ pathl/crypto/rsa.py
15
+ pathl/crypto/utils.py
10
16
  pathl/dns/dns.py
17
+ pathl/hash/__init__.py
18
+ pathl/hash/sha256.c
11
19
  pathl/hello/__init__.py
12
20
  pathl/hello/welcome.py
13
21
  pathl/hello/world.py
22
+ pathl/math/__init__.py
23
+ pathl/math/math.c
24
+ pathl/scaner/fastscan.c
14
25
  pathl/scaner/scaner.py
@@ -0,0 +1,2 @@
1
+ rsa
2
+ pycryptodome
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pathl"
7
- version = "2.1.7"
7
+ version = "2.2.1b1"
8
8
  description = "General-purpose cybersecurity toolkit"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -16,7 +16,7 @@ authors = [
16
16
  # POPRAWIONE: licencja jako string, nie tabela
17
17
  license = "MIT"
18
18
 
19
- dependencies = []
19
+ dependencies = ["rsa","pycryptodome"]
20
20
 
21
21
  [project.urls]
22
22
  Homepage = "https://pip.pathl.pl"
pathl-2.2.1b1/setup.py ADDED
@@ -0,0 +1,18 @@
1
+ from setuptools import setup, Extension
2
+
3
+ setup(
4
+ ext_modules=[
5
+ Extension(
6
+ name="pathl.scaner.fastscan",
7
+ sources=["pathl/scaner/fastscan.c"]
8
+ ),
9
+ Extension(
10
+ name="pathl.math.math",
11
+ sources=["pathl/math/math.c"]
12
+ ),
13
+ Extension(
14
+ name="pathl.hash.sha256",
15
+ sources=["pathl/hash/sha256.c"]
16
+ ),
17
+ ]
18
+ )
pathl-2.1.7/PKG-INFO DELETED
@@ -1,14 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: pathl
3
- Version: 2.1.7
4
- Summary: General-purpose cybersecurity toolkit
5
- Author: Alicja
6
- License-Expression: MIT
7
- Project-URL: Homepage, https://pip.pathl.pl
8
- Project-URL: Repository, https://github.com/AlicjaPathl/pathl
9
- Project-URL: Documentation, https://pip.pathl.pl/docs
10
- Project-URL: Issues, https://github.com/AlicjaPathl/pathl/issues
11
- Requires-Python: >=3.8
12
- Description-Content-Type: text/markdown
13
-
14
- # pathl
pathl-2.1.7/README.md DELETED
@@ -1 +0,0 @@
1
- # pathl
pathl-2.1.7/pathl/cli.py DELETED
@@ -1,68 +0,0 @@
1
- import argparse
2
- from pathl.scaner.scaner import run_scan
3
- from pathl.dns.dns import run_dns
4
-
5
- # reszta kodu bez zmian
6
-
7
- def cmd_hello(args):
8
- print("Hello from pathl 🔐")
9
-
10
-
11
- def cmd_scan(args):
12
- run_scan(
13
- target=args.target,
14
- start=args.start,
15
- end=args.end,
16
- threads=args.threads,
17
- timeout=args.timeout,
18
- output=args.output
19
- )
20
-
21
-
22
- def main():
23
- parser = argparse.ArgumentParser(
24
- prog="pathl",
25
- description="General-purpose cybersecurity toolkit"
26
- )
27
-
28
- subparsers = parser.add_subparsers(dest="command")
29
-
30
-
31
- # HELLO
32
- parser_hello = subparsers.add_parser("hello")
33
- parser_hello.set_defaults(func=cmd_hello)
34
-
35
- #DNS
36
- parser_dns = subparsers.add_parser("dns")
37
- parser_dns.add_argument("domain")
38
- parser_dns.add_argument("-p", action="store_true")
39
- parser_dns.set_defaults(func=run_dns)
40
-
41
-
42
- # SCAN
43
- parser_scan = subparsers.add_parser("scan")
44
-
45
- parser_scan.add_argument("target")
46
-
47
- parser_scan.add_argument("--start", type=int, default=1)
48
- parser_scan.add_argument("--end", type=int, default=1024)
49
-
50
- parser_scan.add_argument("--threads", type=int, default=100)
51
- parser_scan.add_argument("--timeout", type=float, default=0.3)
52
-
53
- parser_scan.add_argument("--output")
54
-
55
- parser_scan.set_defaults(func=cmd_scan)
56
-
57
-
58
- args = parser.parse_args()
59
-
60
- if not args.command:
61
- parser.print_help()
62
- return
63
-
64
- args.func(args)
65
-
66
-
67
- if __name__ == "__main__":
68
- main()
@@ -1,14 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: pathl
3
- Version: 2.1.7
4
- Summary: General-purpose cybersecurity toolkit
5
- Author: Alicja
6
- License-Expression: MIT
7
- Project-URL: Homepage, https://pip.pathl.pl
8
- Project-URL: Repository, https://github.com/AlicjaPathl/pathl
9
- Project-URL: Documentation, https://pip.pathl.pl/docs
10
- Project-URL: Issues, https://github.com/AlicjaPathl/pathl/issues
11
- Requires-Python: >=3.8
12
- Description-Content-Type: text/markdown
13
-
14
- # pathl
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes