Keep It Simple Stupid. Started using the CherryPy server and made classes from the parts.
This commit is contained in:
parent
6db5290cca
commit
e620c28648
14
kiss/toml-manager/Pipfile
Normal file
14
kiss/toml-manager/Pipfile
Normal file
@ -0,0 +1,14 @@
|
||||
[[source]]
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
cherrypy = "*"
|
||||
cryptography = "*"
|
||||
toml = "*"
|
||||
|
||||
[dev-packages]
|
||||
|
||||
[requires]
|
||||
python_version = "3.12"
|
258
kiss/toml-manager/Pipfile.lock
generated
Normal file
258
kiss/toml-manager/Pipfile.lock
generated
Normal file
@ -0,0 +1,258 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "3904278bc410034de66233bf5207dbd20ea354ea27293021e91dd2ec82110050"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_version": "3.12"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"autocommand": {
|
||||
"hashes": [
|
||||
"sha256:710afe251075e038e19e815e25f8155cabe02196cfb545b2185e0d9c8b2b0459",
|
||||
"sha256:878de9423c5596491167225c2a455043c3130fb5b7286ac83443d45e74955f34"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==2.2.2"
|
||||
},
|
||||
"cffi": {
|
||||
"hashes": [
|
||||
"sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8",
|
||||
"sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2",
|
||||
"sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1",
|
||||
"sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15",
|
||||
"sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36",
|
||||
"sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824",
|
||||
"sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8",
|
||||
"sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36",
|
||||
"sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17",
|
||||
"sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf",
|
||||
"sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc",
|
||||
"sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3",
|
||||
"sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed",
|
||||
"sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702",
|
||||
"sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1",
|
||||
"sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8",
|
||||
"sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903",
|
||||
"sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6",
|
||||
"sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d",
|
||||
"sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b",
|
||||
"sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e",
|
||||
"sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be",
|
||||
"sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c",
|
||||
"sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683",
|
||||
"sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9",
|
||||
"sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c",
|
||||
"sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8",
|
||||
"sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1",
|
||||
"sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4",
|
||||
"sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655",
|
||||
"sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67",
|
||||
"sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595",
|
||||
"sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0",
|
||||
"sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65",
|
||||
"sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41",
|
||||
"sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6",
|
||||
"sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401",
|
||||
"sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6",
|
||||
"sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3",
|
||||
"sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16",
|
||||
"sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93",
|
||||
"sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e",
|
||||
"sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4",
|
||||
"sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964",
|
||||
"sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c",
|
||||
"sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576",
|
||||
"sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0",
|
||||
"sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3",
|
||||
"sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662",
|
||||
"sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3",
|
||||
"sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff",
|
||||
"sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5",
|
||||
"sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd",
|
||||
"sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f",
|
||||
"sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5",
|
||||
"sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14",
|
||||
"sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d",
|
||||
"sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9",
|
||||
"sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7",
|
||||
"sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382",
|
||||
"sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a",
|
||||
"sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e",
|
||||
"sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a",
|
||||
"sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4",
|
||||
"sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99",
|
||||
"sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87",
|
||||
"sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"
|
||||
],
|
||||
"markers": "platform_python_implementation != 'PyPy'",
|
||||
"version": "==1.17.1"
|
||||
},
|
||||
"cheroot": {
|
||||
"hashes": [
|
||||
"sha256:6ea332f20bfcede14e66174d112b30e9807492320d737ca628badc924d997595",
|
||||
"sha256:e0b82f797658d26b8613ec8eb563c3b08e6bd6a7921e9d5089bd1175ad1b1740"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==10.0.1"
|
||||
},
|
||||
"cherrypy": {
|
||||
"hashes": [
|
||||
"sha256:129e444b9a63cea4e765481b156376f1cfe319e64caaaec2485636532373b298",
|
||||
"sha256:6c70e78ee11300e8b21c0767c542ae6b102a49cac5cfd4e3e313d7bb907c5891"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==18.10.0"
|
||||
},
|
||||
"cryptography": {
|
||||
"hashes": [
|
||||
"sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362",
|
||||
"sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4",
|
||||
"sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa",
|
||||
"sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83",
|
||||
"sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff",
|
||||
"sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805",
|
||||
"sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6",
|
||||
"sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664",
|
||||
"sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08",
|
||||
"sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e",
|
||||
"sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18",
|
||||
"sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f",
|
||||
"sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73",
|
||||
"sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5",
|
||||
"sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984",
|
||||
"sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd",
|
||||
"sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3",
|
||||
"sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e",
|
||||
"sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405",
|
||||
"sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2",
|
||||
"sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c",
|
||||
"sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995",
|
||||
"sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73",
|
||||
"sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16",
|
||||
"sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7",
|
||||
"sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd",
|
||||
"sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==43.0.3"
|
||||
},
|
||||
"jaraco.collections": {
|
||||
"hashes": [
|
||||
"sha256:0e4829409d39ad18a40aa6754fee2767f4d9730c4ba66dc9df89f1d2756994c2",
|
||||
"sha256:a9480be7fe741d34639b3c32049066d7634b520746552d1a5d0fcda07ada1020"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==5.1.0"
|
||||
},
|
||||
"jaraco.context": {
|
||||
"hashes": [
|
||||
"sha256:9bae4ea555cf0b14938dc0aee7c9f32ed303aa20a3b73e7dc80111628792d1b3",
|
||||
"sha256:f797fc481b490edb305122c9181830a3a5b76d84ef6d1aef2fb9b47ab956f9e4"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==6.0.1"
|
||||
},
|
||||
"jaraco.functools": {
|
||||
"hashes": [
|
||||
"sha256:70f7e0e2ae076498e212562325e805204fc092d7b4c17e0e86c959e249701a9d",
|
||||
"sha256:ad159f13428bc4acbf5541ad6dec511f91573b90fba04df61dafa2a1231cf649"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==4.1.0"
|
||||
},
|
||||
"jaraco.text": {
|
||||
"hashes": [
|
||||
"sha256:08de508939b5e681b14cdac2f1f73036cd97f6f8d7b25e96b8911a9a428ca0d1",
|
||||
"sha256:5b71fecea69ab6f939d4c906c04fee1eda76500d1641117df6ec45b865f10db0"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==4.0.0"
|
||||
},
|
||||
"more-itertools": {
|
||||
"hashes": [
|
||||
"sha256:037b0d3203ce90cca8ab1defbbdac29d5f993fc20131f3664dc8d6acfa872aef",
|
||||
"sha256:5482bfef7849c25dc3c6dd53a6173ae4795da2a41a80faea6700d9f5846c5da6"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==10.5.0"
|
||||
},
|
||||
"portend": {
|
||||
"hashes": [
|
||||
"sha256:5250a352c19c959d767cac878b829d93e5dc7625a5143399a2a00dc6628ffb72",
|
||||
"sha256:8b3fe3f78779df906559a21d9eaa6e21c8fa5a7a8cc76362cbbe1e16777399cf"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==3.2.0"
|
||||
},
|
||||
"pycparser": {
|
||||
"hashes": [
|
||||
"sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6",
|
||||
"sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==2.22"
|
||||
},
|
||||
"python-dateutil": {
|
||||
"hashes": [
|
||||
"sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3",
|
||||
"sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
|
||||
"version": "==2.9.0.post0"
|
||||
},
|
||||
"setuptools": {
|
||||
"hashes": [
|
||||
"sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec",
|
||||
"sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==75.2.0"
|
||||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
"sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
|
||||
"sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
|
||||
"version": "==1.16.0"
|
||||
},
|
||||
"tempora": {
|
||||
"hashes": [
|
||||
"sha256:888190a2dbe3255ff26dfa9fcecb25f4d38434c0f1943cd61de98bb41c410c50",
|
||||
"sha256:93dac0d33825e66c8314d7bd206b9ecb959075c8728bb05b9b050b2726d0442a"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==5.7.0"
|
||||
},
|
||||
"toml": {
|
||||
"hashes": [
|
||||
"sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b",
|
||||
"sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'",
|
||||
"version": "==0.10.2"
|
||||
},
|
||||
"zc.lockfile": {
|
||||
"hashes": [
|
||||
"sha256:adb2ee6d9e6a2333c91178dcb2c9b96a5744c78edb7712dc784a7d75648e81ec",
|
||||
"sha256:ddb2d71088c061dc8a5edbaa346b637d742ca1e1564be75cb98e7dcae715de19"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==3.0.post1"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
}
|
18
kiss/toml-manager/app.py
Normal file
18
kiss/toml-manager/app.py
Normal file
@ -0,0 +1,18 @@
|
||||
import cherrypy
|
||||
from config.config_loader import load_config
|
||||
from controllers.wireguard_controller import WireGuardController
|
||||
|
||||
def start_server():
|
||||
config = load_config()
|
||||
cherrypy.config.update({
|
||||
'server.socket_host': config['server']['host'],
|
||||
'server.socket_port': config['server']['port'],
|
||||
})
|
||||
|
||||
cherrypy.tree.mount(WireGuardController(), '/api/wireguard')
|
||||
|
||||
cherrypy.engine.start()
|
||||
cherrypy.engine.block()
|
||||
|
||||
if __name__ == "__main__":
|
||||
start_server()
|
36
kiss/toml-manager/auth/token_auth.py
Normal file
36
kiss/toml-manager/auth/token_auth.py
Normal file
@ -0,0 +1,36 @@
|
||||
import json
|
||||
import base64
|
||||
from utils.crypto_utils import decrypt_symmetric_key, decrypt_data, encrypt_data, CLIENT_PUBLIC_KEY
|
||||
from cryptography.exceptions import InvalidSignature
|
||||
import logging
|
||||
|
||||
def validate_token(auth_header, encrypted_data):
|
||||
if not auth_header or not auth_header.startswith("Bearer "):
|
||||
raise ValueError("Invalid Authorization header")
|
||||
|
||||
# Extract JWE token
|
||||
jwe_token = auth_header.split(" ")[1]
|
||||
payload = json.loads(base64.b64decode(jwe_token.split('.')[1]))
|
||||
|
||||
# Extract the encrypted symmetric key from the token payload
|
||||
encrypted_symmetric_key = base64.b64decode(payload['enc_sym_key'])
|
||||
|
||||
# Decrypt the symmetric key
|
||||
symmetric_key = decrypt_symmetric_key(encrypted_symmetric_key)
|
||||
|
||||
# Decrypt the data using the symmetric key
|
||||
decrypted_data = decrypt_data(encrypted_data, symmetric_key)
|
||||
|
||||
# Verify client's signature
|
||||
signature = base64.b64decode(payload['signature'])
|
||||
try:
|
||||
CLIENT_PUBLIC_KEY.verify(
|
||||
signature,
|
||||
decrypted_data.encode(),
|
||||
ec.ECDSA(hashes.SHA256())
|
||||
)
|
||||
except InvalidSignature:
|
||||
raise ValueError("Invalid client signature")
|
||||
|
||||
# Return both decrypted data and the symmetric key for response encryption
|
||||
return json.loads(decrypted_data), symmetric_key
|
18
kiss/toml-manager/config.toml
Normal file
18
kiss/toml-manager/config.toml
Normal file
@ -0,0 +1,18 @@
|
||||
[server]
|
||||
host = "127.0.0.1" # IP address to bind to
|
||||
port = 8080 # Port to bind to
|
||||
|
||||
[wireguard]
|
||||
config_file = "../wireguard_example_server_config.conf"
|
||||
|
||||
[logging]
|
||||
log_file = "../wpm.log" # Optional: Log file location
|
||||
debug = true # Enable debug logging
|
||||
|
||||
[client_keys]
|
||||
public_key = """
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE0t+2/KJ7+YOHu4DmR20YtisenovD
|
||||
tvJKywNdAWX5uqnA7UsYWPVKN827afMkgZuGKgZ5wtVM4DvQCq8MyRDHgw==
|
||||
-----END PUBLIC KEY-----
|
||||
""" # example public key
|
28
kiss/toml-manager/config/config_loader.py
Normal file
28
kiss/toml-manager/config/config_loader.py
Normal file
@ -0,0 +1,28 @@
|
||||
import tomllib
|
||||
import logging
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
"server": {
|
||||
"host": "0.0.0.0",
|
||||
"port": 8000,
|
||||
},
|
||||
"wireguard": {
|
||||
"config_file": "/etc/wireguard/wg0.conf",
|
||||
},
|
||||
"logging": {
|
||||
"log_file": None,
|
||||
"debug": False,
|
||||
}
|
||||
}
|
||||
|
||||
def load_config(config_file: str = "config.toml") -> dict:
|
||||
try:
|
||||
with open(config_file, "rb") as f:
|
||||
config = tomllib.load(f)
|
||||
return {**DEFAULT_CONFIG, **config}
|
||||
except FileNotFoundError:
|
||||
logging.warning(f"Config file {config_file} not found. Using default configuration.")
|
||||
return DEFAULT_CONFIG
|
||||
except tomllib.TOMLDecodeError as e:
|
||||
logging.error(f"Error parsing config file: {e}")
|
||||
exit(1)
|
35
kiss/toml-manager/controllers/toml_controller.py
Normal file
35
kiss/toml-manager/controllers/toml_controller.py
Normal file
@ -0,0 +1,35 @@
|
||||
import cherrypy
|
||||
from services.topic_service import TopicService
|
||||
from auth.token_auth import validate_token
|
||||
|
||||
class GeneralTOMLController:
|
||||
@cherrypy.expose
|
||||
@cherrypy.tools.json_in()
|
||||
@cherrypy.tools.json_out()
|
||||
def index(self):
|
||||
if cherrypy.request.method != "POST":
|
||||
raise cherrypy.HTTPError(405, "Method Not Allowed. Use POST.")
|
||||
|
||||
auth_header = cherrypy.request.headers.get('Authorization')
|
||||
encrypted_data = cherrypy.request.body.read()
|
||||
|
||||
try:
|
||||
decrypted_data = validate_token(auth_header, encrypted_data)
|
||||
action = decrypted_data.get('action')
|
||||
file_path = decrypted_data.get('file_path')
|
||||
|
||||
# Handle any TOML file actions
|
||||
if action == 'read_file':
|
||||
config = read_toml_file(file_path)
|
||||
return {"content": config}
|
||||
elif action == 'write_file':
|
||||
data_to_write = decrypted_data.get('data')
|
||||
write_toml_file(file_path, data_to_write)
|
||||
return {"message": f"File {file_path} updated successfully"}
|
||||
else:
|
||||
return {"error": "Invalid action"}
|
||||
|
||||
except Exception as e:
|
||||
cherrypy.log(f"Error processing request: {str(e)}")
|
||||
return {"error": "Invalid request"}, 400
|
||||
|
43
kiss/toml-manager/controllers/wireguard_controller.py
Normal file
43
kiss/toml-manager/controllers/wireguard_controller.py
Normal file
@ -0,0 +1,43 @@
|
||||
import cherrypy
|
||||
from services.wireguard_service import read_config, write_config, create_backup, reload_wireguard_service
|
||||
from auth.token_auth import validate_token
|
||||
from utils.crypto_utils import encrypt_data
|
||||
|
||||
class WireGuardController:
|
||||
@cherrypy.expose
|
||||
@cherrypy.tools.json_in()
|
||||
@cherrypy.tools.json_out()
|
||||
def index(self):
|
||||
if cherrypy.request.method != "POST":
|
||||
raise cherrypy.HTTPError(405, "Method Not Allowed. Use POST.")
|
||||
|
||||
auth_header = cherrypy.request.headers.get('Authorization')
|
||||
encrypted_data = cherrypy.request.body.read()
|
||||
|
||||
try:
|
||||
# Decrypt the request and get the symmetric key
|
||||
decrypted_data, symmetric_key = validate_token(auth_header, encrypted_data)
|
||||
action = decrypted_data.get('action')
|
||||
|
||||
response_data = {}
|
||||
|
||||
# Handle different actions (as an example, adding a peer)
|
||||
if action == 'add_peer':
|
||||
create_backup()
|
||||
new_peer = decrypted_data.get('peer')
|
||||
config = read_config("/etc/wireguard/wg0.conf")
|
||||
config += "\n\n" + peer_to_string(new_peer)
|
||||
write_config("/etc/wireguard/wg0.conf", config)
|
||||
reload_wireguard_service("/etc/wireguard/wg0.conf")
|
||||
response_data = {"message": "Peer added successfully"}
|
||||
else:
|
||||
response_data = {"error": "Invalid action"}
|
||||
|
||||
# Encrypt the response data before sending
|
||||
encrypted_response = encrypt_data(response_data, symmetric_key)
|
||||
return {"data": encrypted_response}
|
||||
|
||||
except Exception as e:
|
||||
cherrypy.log(f"Error processing request: {str(e)}")
|
||||
return {"error": "Invalid request"}, 400
|
||||
|
29
kiss/toml-manager/services/toml_service.py
Normal file
29
kiss/toml-manager/services/toml_service.py
Normal file
@ -0,0 +1,29 @@
|
||||
import tomllib
|
||||
from pathlib import Path
|
||||
import logging
|
||||
|
||||
def read_toml_file(file_path: str) -> dict:
|
||||
try:
|
||||
with open(file_path, "rb") as file:
|
||||
return tomllib.load(file)
|
||||
except FileNotFoundError:
|
||||
logging.error(f"File {file_path} not found.")
|
||||
return {}
|
||||
except tomllib.TOMLDecodeError as e:
|
||||
logging.error(f"Error parsing {file_path}: {e}")
|
||||
return {}
|
||||
|
||||
def write_toml_file(file_path: str, data: dict) -> None:
|
||||
with open(file_path, "w") as file:
|
||||
toml.dump(data, file)
|
||||
|
||||
def create_backup(file_path: str) -> str:
|
||||
config_path = Path(file_path)
|
||||
backup_dir = config_path.parent / "backups"
|
||||
backup_dir.mkdir(exist_ok=True)
|
||||
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
backup_file = backup_dir / f"{config_path.stem}_{timestamp}.toml"
|
||||
shutil.copy2(file_path, backup_file)
|
||||
logging.info(f"Backup created: {backup_file}")
|
||||
return backup_file
|
36
kiss/toml-manager/services/wireguard_service.py
Normal file
36
kiss/toml-manager/services/wireguard_service.py
Normal file
@ -0,0 +1,36 @@
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import logging
|
||||
import subprocess
|
||||
from datetime import datetime
|
||||
|
||||
def read_config(config_file: str) -> str:
|
||||
with open(config_file, 'r') as file:
|
||||
return file.read()
|
||||
|
||||
def write_config(config_file: str, content: str) -> None:
|
||||
with open(config_file, 'w') as file:
|
||||
file.write(content)
|
||||
|
||||
def create_backup(config_file: str) -> str:
|
||||
config_path = Path(config_file)
|
||||
backup_dir = config_path.parent / "backups"
|
||||
backup_dir.mkdir(exist_ok=True)
|
||||
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
backup_file = backup_dir / f"{config_path.stem}_{timestamp}.conf"
|
||||
shutil.copy2(config_file, backup_file)
|
||||
logging.info(f"Backup created: {backup_file}")
|
||||
return backup_file
|
||||
|
||||
def reload_wireguard_service(config_file: str):
|
||||
interface = Path(config_file).stem
|
||||
try:
|
||||
subprocess.run(["wg-quick", "down", interface], check=True)
|
||||
subprocess.run(["wg-quick", "up", interface], check=True)
|
||||
logging.info(f"WireGuard service for interface {interface} restarted successfully")
|
||||
return True
|
||||
except subprocess.CalledProcessError as e:
|
||||
logging.error(f"Failed to reload WireGuard service: {str(e)}")
|
||||
return False
|
||||
|
24
kiss/toml-manager/topics.toml
Normal file
24
kiss/toml-manager/topics.toml
Normal file
@ -0,0 +1,24 @@
|
||||
[Interface]
|
||||
PrivateKey = PrivateKey123=
|
||||
Address = 10.37.1.1/24
|
||||
ListenPort = 51820
|
||||
|
||||
[Peer]
|
||||
PublicKey = PublicKey123=
|
||||
AllowedIPs = 10.37.1.2/32
|
||||
|
||||
[Peer]
|
||||
PublicKey = PublicKey1234=
|
||||
AllowedIPs = 10.37.2.2/32
|
||||
|
||||
[Peer]
|
||||
PublicKey = PublicKey12345
|
||||
AllowedIPs = 10.37.3.2/32
|
||||
|
||||
[Peer]
|
||||
PublicKey = PublicKey123456
|
||||
AllowedIPs = 10.37.4.2/32
|
||||
|
||||
[Peer]
|
||||
PublicKey = PublicKey321
|
||||
AllowedIPs = 0.0.0.0
|
61
kiss/toml-manager/utils/crypto_utils.py
Normal file
61
kiss/toml-manager/utils/crypto_utils.py
Normal file
@ -0,0 +1,61 @@
|
||||
import os
|
||||
from cryptography.hazmat.primitives.asymmetric import ec
|
||||
from cryptography.hazmat.primitives import hashes, serialization
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
|
||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
import json
|
||||
import base64
|
||||
from config.config_loader import load_config
|
||||
|
||||
def encrypt_data(data, symmetric_key):
|
||||
# Convert the data to a JSON string
|
||||
json_data = json.dumps(data).encode('utf-8')
|
||||
|
||||
# Generate a random IV for encryption
|
||||
iv = os.urandom(16)
|
||||
|
||||
# Create AES Cipher and encrypt the data
|
||||
cipher = Cipher(algorithms.AES(symmetric_key), modes.CFB(iv), backend=default_backend())
|
||||
encryptor = cipher.encryptor()
|
||||
encrypted_data = encryptor.update(json_data) + encryptor.finalize()
|
||||
|
||||
# Combine IV and encrypted data
|
||||
encrypted_payload = iv + encrypted_data
|
||||
|
||||
# Encode the result in base64 to make it JSON-compatible
|
||||
return base64.b64encode(encrypted_payload).decode('utf-8')
|
||||
|
||||
# AES Decryption
|
||||
def decrypt_data(encrypted_data, symmetric_key):
|
||||
# Decode base64
|
||||
encrypted_data = base64.b64decode(encrypted_data)
|
||||
|
||||
iv = encrypted_data[:16]
|
||||
cipher = Cipher(algorithms.AES(symmetric_key), modes.CFB(iv), backend=default_backend())
|
||||
decryptor = cipher.decryptor()
|
||||
decrypted_data = decryptor.update(encrypted_data[16:]) + decryptor.finalize()
|
||||
return decrypted_data.decode('utf-8')
|
||||
|
||||
def generate_ecc_key_pair():
|
||||
private_key = ec.generate_private_key(ec.SECP256R1(), default_backend())
|
||||
public_key = private_key.public_key()
|
||||
return private_key, public_key
|
||||
|
||||
def load_client_public_key(config):
|
||||
client_public_key_pem = config.get('client_keys', {}).get('public_key')
|
||||
if not client_public_key_pem:
|
||||
raise ValueError("Client public key not found")
|
||||
return serialization.load_pem_public_key(client_public_key_pem.encode(), backend=default_backend())
|
||||
|
||||
def decrypt_symmetric_key(encrypted_symmetric_key, private_key):
|
||||
return private_key.decrypt(
|
||||
encrypted_symmetric_key,
|
||||
ec.ECIES(hashes.SHA256())
|
||||
)
|
||||
|
||||
# Load server/client public and private keys
|
||||
SERVER_PRIVATE_KEY, SERVER_PUBLIC_KEY = generate_ecc_key_pair()
|
||||
CONFIG = load_config("config.toml")
|
||||
CLIENT_PUBLIC_KEY = load_client_public_key(CONFIG)
|
Loading…
Reference in New Issue
Block a user