license-tool-ias 0.1.1__cp312-cp312-manylinux_2_28_aarch64.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.
- example/check_license.py +51 -0
- example/example.py +40 -0
- license_tool/__init__.py +9 -0
- license_tool/_version.py +34 -0
- license_tool/cli.cpython-312-aarch64-linux-gnu.so +0 -0
- license_tool/key/__init__.py +8 -0
- license_tool/key/signer.cpython-312-aarch64-linux-gnu.so +0 -0
- license_tool/key/verifier.cpython-312-aarch64-linux-gnu.so +0 -0
- license_tool/keygen.cpython-312-aarch64-linux-gnu.so +0 -0
- license_tool_ias-0.1.1.dist-info/METADATA +105 -0
- license_tool_ias-0.1.1.dist-info/RECORD +14 -0
- license_tool_ias-0.1.1.dist-info/WHEEL +5 -0
- license_tool_ias-0.1.1.dist-info/entry_points.txt +2 -0
- license_tool_ias-0.1.1.dist-info/top_level.txt +5 -0
example/check_license.py
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
import os
|
2
|
+
import sys
|
3
|
+
|
4
|
+
sys.path.append(os.getcwd())
|
5
|
+
from license_tool.key.verifier import verify_license
|
6
|
+
import json
|
7
|
+
|
8
|
+
LICENSE_FILE = os.path.join('example', 'license_out.json') # 授權檔路徑
|
9
|
+
PUBKEY_FILE = os.path.join('keys', 'public.pem') # 公鑰檔路徑
|
10
|
+
MACINFO_FILE = "/etc/macinfo/macaddr" # MAC 列表檔案
|
11
|
+
|
12
|
+
|
13
|
+
def normalize_mac(raw_mac: str) -> str:
|
14
|
+
"""將 C8D9D219FA2C 轉換成 C8:D9:D2:19:FA:2C"""
|
15
|
+
raw_mac = raw_mac.strip().upper() # 去除換行、統一大寫
|
16
|
+
return ":".join([raw_mac[i:i+2] for i in range(0, len(raw_mac), 2)])
|
17
|
+
|
18
|
+
def check_license():
|
19
|
+
# 讀取 macaddr 檔案
|
20
|
+
try:
|
21
|
+
with open(MACINFO_FILE) as f:
|
22
|
+
mac_list = [normalize_mac(line) for line in f if line.strip()]
|
23
|
+
except FileNotFoundError:
|
24
|
+
print(f"❌ 找不到 {MACINFO_FILE}")
|
25
|
+
return False
|
26
|
+
|
27
|
+
print(f"📋 從 {MACINFO_FILE} 讀取到 {len(mac_list)} 個 MAC:")
|
28
|
+
for mac in mac_list:
|
29
|
+
print(f" - {mac}")
|
30
|
+
|
31
|
+
# 逐一嘗試驗證,只要一個通過就合法
|
32
|
+
for mac in mac_list:
|
33
|
+
try:
|
34
|
+
verify_license(
|
35
|
+
license_path=LICENSE_FILE,
|
36
|
+
public_key_path=PUBKEY_FILE,
|
37
|
+
host_mac=mac
|
38
|
+
)
|
39
|
+
print(f"✅ 授權成功,合法 MAC:{mac}")
|
40
|
+
return True # 只要一個成功就結束
|
41
|
+
except Exception as e:
|
42
|
+
print(f"❌ 驗證失敗 ({mac}): {e}")
|
43
|
+
|
44
|
+
print("🚫 所有 MAC 都驗證失敗,授權不合法!")
|
45
|
+
return False
|
46
|
+
|
47
|
+
if __name__ == "__main__":
|
48
|
+
if check_license():
|
49
|
+
print("🎉 ✅ License 驗證通過!")
|
50
|
+
else:
|
51
|
+
print("❌ License 驗證失敗!")
|
example/example.py
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
from license_tool.keygen import generate_keys
|
2
|
+
from license_tool.key.signer import sign_license
|
3
|
+
from license_tool.key.verifier import verify_license
|
4
|
+
import os
|
5
|
+
|
6
|
+
# === 1️⃣ 生成 RSA 公私鑰 ===
|
7
|
+
keys_dir = "keys"
|
8
|
+
print("🔧 [Step 1] 生成金鑰...")
|
9
|
+
generate_keys(keys_dir) # keys/private.pem & keys/public.pem
|
10
|
+
|
11
|
+
# === 2️⃣ 建立一個測試用的 license.json ===
|
12
|
+
license_path = "license.json"
|
13
|
+
if not os.path.exists(license_path):
|
14
|
+
print("📝 建立 license.json...")
|
15
|
+
sample_license = {
|
16
|
+
"macs": ["aa:bb:cc:dd:ee:ff", "11:22:33:44:55:66"],
|
17
|
+
"expires": "2025-12-31",
|
18
|
+
"services": ["app", "db", "worker"],
|
19
|
+
"signature": "" # 先空著,簽名時會自動填上
|
20
|
+
}
|
21
|
+
import json
|
22
|
+
with open(license_path, "w") as f:
|
23
|
+
json.dump(sample_license, f, indent=2)
|
24
|
+
|
25
|
+
# === 3️⃣ 簽署 license.json ===
|
26
|
+
print("✍️ [Step 2] 簽署 License...")
|
27
|
+
sign_license(license_path, os.path.join(keys_dir, "private.pem"))
|
28
|
+
|
29
|
+
# === 4️⃣ 驗證 license.json ===
|
30
|
+
print("✅ [Step 3] 驗證 License...")
|
31
|
+
try:
|
32
|
+
verify_license(
|
33
|
+
license_path=license_path,
|
34
|
+
public_key_path=os.path.join(keys_dir, "public.pem"),
|
35
|
+
service_name="app",
|
36
|
+
host_mac="aa:bb:cc:dd:ee:ff"
|
37
|
+
)
|
38
|
+
print("🎉 驗證成功,授權通過!")
|
39
|
+
except Exception as e:
|
40
|
+
print("❌ 驗證失敗:", e)
|
license_tool/__init__.py
ADDED
license_tool/_version.py
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# file generated by setuptools-scm
|
2
|
+
# don't change, don't track in version control
|
3
|
+
|
4
|
+
__all__ = [
|
5
|
+
"__version__",
|
6
|
+
"__version_tuple__",
|
7
|
+
"version",
|
8
|
+
"version_tuple",
|
9
|
+
"__commit_id__",
|
10
|
+
"commit_id",
|
11
|
+
]
|
12
|
+
|
13
|
+
TYPE_CHECKING = False
|
14
|
+
if TYPE_CHECKING:
|
15
|
+
from typing import Tuple
|
16
|
+
from typing import Union
|
17
|
+
|
18
|
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
19
|
+
COMMIT_ID = Union[str, None]
|
20
|
+
else:
|
21
|
+
VERSION_TUPLE = object
|
22
|
+
COMMIT_ID = object
|
23
|
+
|
24
|
+
version: str
|
25
|
+
__version__: str
|
26
|
+
__version_tuple__: VERSION_TUPLE
|
27
|
+
version_tuple: VERSION_TUPLE
|
28
|
+
commit_id: COMMIT_ID
|
29
|
+
__commit_id__: COMMIT_ID
|
30
|
+
|
31
|
+
__version__ = version = '0.1.1'
|
32
|
+
__version_tuple__ = version_tuple = (0, 1, 1)
|
33
|
+
|
34
|
+
__commit_id__ = commit_id = 'g189f5eb8e'
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,105 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: license-tool-ias
|
3
|
+
Version: 0.1.1
|
4
|
+
Summary: Example algo package with Cython-compiled submodules
|
5
|
+
Author: Your Name
|
6
|
+
Classifier: Programming Language :: Python :: 3
|
7
|
+
Classifier: Programming Language :: Cython
|
8
|
+
Classifier: Programming Language :: C
|
9
|
+
Requires-Python: >=3.11
|
10
|
+
Description-Content-Type: text/markdown
|
11
|
+
Requires-Dist: cryptography==45.0.5
|
12
|
+
|
13
|
+
# 🔐 License Tool
|
14
|
+
|
15
|
+
License Tool 是一個 **基於 RSA 簽名驗證** 的授權管理套件,提供:
|
16
|
+
- ✅ License 簽署(sign)
|
17
|
+
- ✅ License 驗證(verify)
|
18
|
+
- ✅ RSA 金鑰自動生成(genkeys)
|
19
|
+
|
20
|
+
---
|
21
|
+
|
22
|
+
## 📚 目錄
|
23
|
+
|
24
|
+
- [安裝方式](#安裝方式)
|
25
|
+
- [使用方式](#使用方式)
|
26
|
+
- [金鑰產生](#金鑰產生)
|
27
|
+
- [License 生成](#license-生成)
|
28
|
+
- [License 驗證](#license-驗證)
|
29
|
+
- [提交內容](#提交內容)
|
30
|
+
|
31
|
+
## 🚀 安裝方式
|
32
|
+
|
33
|
+
### 1️⃣ 本地安裝(開發模式)
|
34
|
+
```bash
|
35
|
+
git clone https://your.repo/license_tool.git
|
36
|
+
|
37
|
+
cd license_tool
|
38
|
+
|
39
|
+
python -m venv .venv
|
40
|
+
|
41
|
+
source .venv/bin/activate
|
42
|
+
|
43
|
+
pip install -r requirements.txt
|
44
|
+
|
45
|
+
pip install -e .
|
46
|
+
```
|
47
|
+
|
48
|
+
|
49
|
+
## 使用方式
|
50
|
+
- 必須進入license_tool的虛擬環境
|
51
|
+
- 查看指令功能
|
52
|
+
```Bash
|
53
|
+
license-tool -h
|
54
|
+
|
55
|
+
license-tool genkeys -h
|
56
|
+
|
57
|
+
license-tool sign -h
|
58
|
+
|
59
|
+
license-tool verify -h
|
60
|
+
```
|
61
|
+
### 金鑰產生
|
62
|
+
**⚠️ gitlab clone下來的專案已經有keys**
|
63
|
+
|
64
|
+
**⚠️已經有金鑰就不要重複產生**,否則金鑰可能覆蓋,造成已經生成的license失效
|
65
|
+
- 指令:
|
66
|
+
```Bash
|
67
|
+
license-tool genkeys <output_dir>
|
68
|
+
```
|
69
|
+
- 範例: license-tool genkeys keys
|
70
|
+
- 📂 會產生以下兩個檔案:
|
71
|
+
- `keys/private.pem` (⚠️ private.pem 絕對不能給出)
|
72
|
+
- `keys/public.pem`
|
73
|
+
### License 生成
|
74
|
+
- 指令:
|
75
|
+
```Bash
|
76
|
+
license-tool sign <license_file_path> <private_key>
|
77
|
+
```
|
78
|
+
- 範例: license-tool sign example/license.json keys/private.pem
|
79
|
+
- License file 格式請參考下列範例
|
80
|
+
``` json
|
81
|
+
{
|
82
|
+
"custom_name": "IOTech",
|
83
|
+
"macs": [
|
84
|
+
"c8:d9:d2:19:fa:2c",
|
85
|
+
"08:00:27:a6:59:dd",
|
86
|
+
"08:00:27:6f:f7:c0"
|
87
|
+
],
|
88
|
+
"expire_date": "2025-12-31 23:59:59",
|
89
|
+
"deploy_cnt": "2",
|
90
|
+
"signature": ""
|
91
|
+
}
|
92
|
+
```
|
93
|
+
> ⚠️ `license.json` 是原始未簽名的檔案,`license_out.json` 是經簽名後產生的授權檔案,包含合法的 `signature` 欄位。
|
94
|
+
### License 驗證
|
95
|
+
- 指令:
|
96
|
+
```Bash
|
97
|
+
license-tool verify <license_path> <public_key> <host_mac>
|
98
|
+
```
|
99
|
+
- 範例: license-tool verify example/license_out.json keys/public.pem 08:00:27:6f:f7:c0
|
100
|
+
|
101
|
+
## 提交內容
|
102
|
+
- license檔案: 例如範例中的license_out.json
|
103
|
+
- Public Key: 例如範例中的public.pem
|
104
|
+
|
105
|
+
⚠️ Private Key 絕對不能給出
|
@@ -0,0 +1,14 @@
|
|
1
|
+
example/check_license.py,sha256=Yhnu3iehNCstAJC12wJXC9K7nCPeTabB5Y_CqlvyHVc,1666
|
2
|
+
example/example.py,sha256=IWBbGQvdNF4WAGDZ8L5OCA_NNQQanMrrgD9lhSD0-I8,1342
|
3
|
+
license_tool/__init__.py,sha256=6r7wkKrUL6Zy8PHacpKd7Tdm-EdcaxRPYxwX5XB49kw,263
|
4
|
+
license_tool/_version.py,sha256=aVKpqB9GzHFYyNg-U_86bWM04N0lsZwJxdX7g3m9U80,712
|
5
|
+
license_tool/cli.cpython-312-aarch64-linux-gnu.so,sha256=ghz94xTrwgDIGC6M1HAhlDFQo7jqIi3MYKpxTwbs4g4,214792
|
6
|
+
license_tool/keygen.cpython-312-aarch64-linux-gnu.so,sha256=cJ7Gyb-0ufbJOHf8LzQNQpIy0rCq_OMKnXBZ70bYZLk,216208
|
7
|
+
license_tool/key/__init__.py,sha256=vBJvjJ75w0UIG2muDzET9VkRZiorAeRo3dL9TXeiWFY,177
|
8
|
+
license_tool/key/signer.cpython-312-aarch64-linux-gnu.so,sha256=9ScBwF-JrxqefJyNn85IcLM1P-u0UzSTVRSJKtF-Xz4,216448
|
9
|
+
license_tool/key/verifier.cpython-312-aarch64-linux-gnu.so,sha256=nZUGXSTxGq55lRL_b28pydK9399hatA1Mhm9cdBrPcQ,216552
|
10
|
+
license_tool_ias-0.1.1.dist-info/METADATA,sha256=KdWuBiRMpXE1PYvDxAiiaRcXoQN9nt_pYb3z_-Tobwk,2694
|
11
|
+
license_tool_ias-0.1.1.dist-info/WHEEL,sha256=i7vxtqfgRxFyLYArziRyEI8rJr76D_-0mffvAh-Fj0g,114
|
12
|
+
license_tool_ias-0.1.1.dist-info/entry_points.txt,sha256=CanK69xH3QdAvNn4lv4p759H-KE0dL-35Z91CPaZcgE,55
|
13
|
+
license_tool_ias-0.1.1.dist-info/top_level.txt,sha256=zhbbr1zdaG4NoTfhLe_7payS4ARGfLUUKBc4bICEN64,43
|
14
|
+
license_tool_ias-0.1.1.dist-info/RECORD,,
|