generated from PlexSheep/rs-base
Merge branch 'devel'
cargo devel CI / cargo CI (push) Successful in 2m59s
Details
cargo devel CI / cargo CI (push) Successful in 2m59s
Details
This commit is contained in:
commit
26521989be
11
Cargo.toml
11
Cargo.toml
|
@ -1,6 +1,7 @@
|
||||||
|
workspace = { members = ["spammer"] }
|
||||||
[package]
|
[package]
|
||||||
name = "netpong"
|
name = "netpong"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
publish = true
|
publish = true
|
||||||
authors = ["Christoph J. Scherr <software@cscherr.de>"]
|
authors = ["Christoph J. Scherr <software@cscherr.de>"]
|
||||||
|
@ -17,11 +18,13 @@ anyhow = "1.0.79"
|
||||||
clap = "4.4.18"
|
clap = "4.4.18"
|
||||||
clap-num = "1.0.2"
|
clap-num = "1.0.2"
|
||||||
clap-verbosity-flag = "2.1.2"
|
clap-verbosity-flag = "2.1.2"
|
||||||
libpt = { version = "0.3.10", features = ["net"] }
|
libpt = { version = "0.3.11", features = ["net"] }
|
||||||
thiserror = "1.0.56"
|
thiserror = "1.0.56"
|
||||||
threadpool = { version = "1.8.1", optional = true }
|
|
||||||
tokio = { version = "1.35.1", features = ["net", "rt", "macros"] }
|
tokio = { version = "1.35.1", features = ["net", "rt", "macros"] }
|
||||||
|
rustls-pemfile = "2.0.0"
|
||||||
|
tokio-rustls = "0.25.0"
|
||||||
|
webpki-roots = "0.26.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["server"]
|
default = ["server"]
|
||||||
server = ["dep:threadpool"]
|
server = []
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIEFDCCAvygAwIBAgITfl3NbK3jOj2V0yehJ0VkuBWlvDANBgkqhkiG9w0BAQsF
|
||||||
|
ADCBmTELMAkGA1UEBhMCREUxHTAbBgNVBAgMFEJhZGVuIFfDg8K8cnR0ZW1iZXJn
|
||||||
|
MREwDwYDVQQHDAhNYW5uaGVpbTEVMBMGA1UECgwMTmV0cG9uZyBUZWFtMR0wGwYD
|
||||||
|
VQQDDBROZXRwb25nLVRlc3QtQ0EgUm9vdDEiMCAGCSqGSIb3DQEJARYTc29mdHdh
|
||||||
|
cmVAY3NjaGVyci5kZTAeFw0yNDAxMjQxNDM3NTdaFw0zNDAxMjExNDM3NTdaMIGZ
|
||||||
|
MQswCQYDVQQGEwJERTEdMBsGA1UECAwUQmFkZW4gV8ODwrxydHRlbWJlcmcxETAP
|
||||||
|
BgNVBAcMCE1hbm5oZWltMRUwEwYDVQQKDAxOZXRwb25nIFRlYW0xHTAbBgNVBAMM
|
||||||
|
FE5ldHBvbmctVGVzdC1DQSBSb290MSIwIAYJKoZIhvcNAQkBFhNzb2Z0d2FyZUBj
|
||||||
|
c2NoZXJyLmRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjc443jjU
|
||||||
|
YZP4aVC0vD0WRpzC6G50wva3lLX2vOf6x1xAE/sVQ7F3j25s/oUUzHSf4/F4H3rC
|
||||||
|
R5ZmpyOBiW/1ZuQVb48HxzE7Vh/QQenTUVcPEdZcqf0vLogDzaSrq9uMXvmWHWgQ
|
||||||
|
IE0yYbEBd2/bE0k530EW5QZpKdUZI6m+Tf6k60Fk65skC4IZ684M6ahB9AQiBY0c
|
||||||
|
6DzJPN6AV33s6HjHqLJUeWwiEFXx7v/I3Fo81NHnoRZQw9bNel3rRa1Ovn1FIUz3
|
||||||
|
rKygXb3/Zcl3TKh2eRXb7bJmG35dh+Cx9OtPlYSiU45w5Kxa7+c1n2H+rDv5QlcH
|
||||||
|
tsUR2ONDDRG4MwIDAQABo1MwUTAdBgNVHQ4EFgQUj4dOxujhWUGrCG5xJNhrCXM0
|
||||||
|
JWEwHwYDVR0jBBgwFoAUj4dOxujhWUGrCG5xJNhrCXM0JWEwDwYDVR0TAQH/BAUw
|
||||||
|
AwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAcR6c5RMuEqO01TKfzXq0b2J8Rfqxe9WJ
|
||||||
|
6tgc7/3DatCYkytCq+fucZ2hUg/IxZ8wRpe1UyaK5iLd0kC8ag5RT5pl9ybHnVZZ
|
||||||
|
DsQNYlal71DaCwId+VhiZpqGVERruln7nBifNDrqbRy9U2da/q7ZoMlxkIOgUiBd
|
||||||
|
r4Ecv/J6l6LprIIjxGRQ6dC0TN0kDkJ5UFS7IMsM13eDtejA/mfHOamN6Ty0PzaY
|
||||||
|
HI9IeKzlFz0yzRyaYL/VrpBmiQF1goRpeIfEZw5F09hatkhSgzmV+GcMjTAnIVCU
|
||||||
|
h/s9q/mFKeWVWUA8endIx+3YXtIdMK6H16DGYNOIyzmc7XwpQkDqvg==
|
||||||
|
-----END CERTIFICATE-----
|
|
@ -0,0 +1 @@
|
||||||
|
V 340121145241Z 00 unknown /C=DE/ST=Baden W\xC3\x83\xC2\xBCrttemberg/O=Netpong Team/CN=localhost
|
|
@ -0,0 +1 @@
|
||||||
|
unique_subject = yes
|
|
@ -0,0 +1,93 @@
|
||||||
|
Certificate:
|
||||||
|
Data:
|
||||||
|
Version: 1 (0x0)
|
||||||
|
Serial Number: 0 (0x0)
|
||||||
|
Signature Algorithm: sha256WithRSAEncryption
|
||||||
|
Issuer: C=DE, ST=Baden W\xC3\x83\xC2\xBCrttemberg, L=Mannheim, O=Netpong Team, CN=Netpong-Test-CA Root/emailAddress=software@cscherr.de
|
||||||
|
Validity
|
||||||
|
Not Before: Jan 24 14:52:41 2024 GMT
|
||||||
|
Not After : Jan 21 14:52:41 2034 GMT
|
||||||
|
Subject: C=DE, ST=Baden W\xC3\x83\xC2\xBCrttemberg, O=Netpong Team, CN=localhost
|
||||||
|
Subject Public Key Info:
|
||||||
|
Public Key Algorithm: rsaEncryption
|
||||||
|
Public-Key: (4096 bit)
|
||||||
|
Modulus:
|
||||||
|
00:d5:e6:a4:18:a1:c2:a6:c6:f1:22:d7:c5:66:a6:
|
||||||
|
90:68:f6:2f:0e:2f:41:8c:9b:2e:f2:e4:64:9b:e1:
|
||||||
|
5f:28:64:4f:ea:a6:b5:68:67:e2:09:93:11:93:3d:
|
||||||
|
d8:0b:e7:06:50:38:1e:6c:fa:70:2c:32:fb:64:ba:
|
||||||
|
d3:43:8c:16:b0:78:39:e4:6f:05:da:e1:7b:c0:8c:
|
||||||
|
e0:79:90:4d:60:85:0e:13:5c:2b:03:a9:38:c9:20:
|
||||||
|
48:1b:41:a7:70:95:d2:ae:e9:96:5e:55:d7:a1:9b:
|
||||||
|
75:51:de:65:75:7c:0f:1f:71:29:88:6d:ca:82:d5:
|
||||||
|
9e:e6:09:78:4a:d3:10:f7:13:69:c8:3e:4e:7e:1f:
|
||||||
|
9b:9c:6b:a3:f6:da:2a:65:3d:41:e9:41:62:41:a7:
|
||||||
|
aa:5e:9e:5a:1b:e9:a0:ca:35:c4:7e:a0:93:48:0c:
|
||||||
|
cc:54:98:79:4b:97:20:0d:48:9f:9a:fb:24:16:6e:
|
||||||
|
ba:ad:04:5e:83:0c:a6:da:de:59:6a:29:c0:fd:77:
|
||||||
|
3b:d4:d1:f2:a7:a0:a1:64:66:32:52:11:08:5f:17:
|
||||||
|
35:14:11:ab:9a:ac:69:df:82:d0:05:7e:78:7e:45:
|
||||||
|
20:ea:da:0e:18:3b:22:72:e3:d6:ef:4a:00:aa:2a:
|
||||||
|
3d:42:3a:03:ae:6a:e6:cc:2a:fb:6c:eb:e0:13:3e:
|
||||||
|
ca:1d:a6:92:ed:14:25:a3:c3:d9:03:60:13:48:be:
|
||||||
|
32:c4:b3:09:df:68:b5:b3:7f:cd:13:c6:af:e0:49:
|
||||||
|
d2:91:40:d3:9d:6f:53:a5:08:23:5e:fb:b1:d6:20:
|
||||||
|
8f:a0:66:b1:ce:7d:8e:97:79:9c:ec:73:94:ca:60:
|
||||||
|
71:48:8e:0f:92:b7:5b:99:83:24:02:13:a3:f3:64:
|
||||||
|
92:25:2e:74:00:0d:b6:e4:85:41:95:12:af:93:39:
|
||||||
|
ed:ed:73:9e:00:a5:c6:1b:8a:3f:19:73:e8:e4:01:
|
||||||
|
4a:a4:f5:a6:3c:f8:ee:e3:74:21:fd:ab:53:17:2c:
|
||||||
|
72:74:b0:7e:87:23:b5:f2:dd:67:24:d1:8c:8d:75:
|
||||||
|
4b:d9:5b:d1:10:55:c0:6b:2d:22:7c:7f:a1:42:15:
|
||||||
|
12:4f:fd:70:b3:18:f5:78:a9:56:f7:2f:f2:91:54:
|
||||||
|
57:38:9f:11:31:20:dd:79:aa:fb:b6:8d:fc:58:25:
|
||||||
|
07:2b:b9:c7:8b:85:e3:39:77:6f:8e:51:fa:9c:6b:
|
||||||
|
c7:2a:ba:1e:59:28:e9:b8:07:1f:50:bc:89:3e:61:
|
||||||
|
55:9a:c5:c6:6d:54:09:9a:96:ec:97:d9:16:5b:4b:
|
||||||
|
60:d5:37:bf:9d:ad:72:09:4c:fc:c0:df:05:5c:2a:
|
||||||
|
51:92:e2:79:b0:c6:8c:91:26:a9:cb:3d:f9:1e:dd:
|
||||||
|
7f:19:e3
|
||||||
|
Exponent: 65537 (0x10001)
|
||||||
|
Signature Algorithm: sha256WithRSAEncryption
|
||||||
|
Signature Value:
|
||||||
|
3f:00:bc:70:77:c1:4d:f5:d2:f5:ea:23:7a:1d:ee:90:3a:1e:
|
||||||
|
16:3a:2b:25:56:8c:13:78:4e:a1:6c:32:49:68:3e:0e:9a:43:
|
||||||
|
e1:45:bf:85:a1:36:88:5f:9a:e1:9b:04:40:f8:a4:77:5f:cf:
|
||||||
|
a3:29:c5:fb:b0:2b:d1:cc:2b:97:04:d1:9e:4d:32:7d:bd:ff:
|
||||||
|
49:7b:b1:38:c7:77:be:74:73:2f:f2:e5:f8:af:34:05:f2:5e:
|
||||||
|
75:40:2a:d3:8f:d7:4f:aa:17:7d:09:f1:16:3e:1c:f7:e6:e9:
|
||||||
|
7a:bb:98:92:83:5a:b4:71:08:97:fc:6e:97:cf:07:73:48:de:
|
||||||
|
23:f6:58:06:b4:c9:c9:a7:11:8b:95:50:f0:2e:cb:25:85:b1:
|
||||||
|
30:79:6c:61:84:ee:b4:ea:1f:b1:a7:80:c5:09:2c:e3:ae:83:
|
||||||
|
f8:0a:3c:ef:d1:b8:fb:1e:2e:91:03:21:65:62:fe:fe:a6:c7:
|
||||||
|
cd:cf:7f:31:d4:99:cf:6e:39:63:df:1a:f2:fd:55:33:22:ef:
|
||||||
|
a8:26:2f:15:f6:d9:63:a2:ac:bb:f1:bf:e9:c1:c7:88:d1:4f:
|
||||||
|
d8:19:38:ce:8c:d3:bc:a8:15:32:ba:05:58:74:f5:8c:fa:aa:
|
||||||
|
9f:52:42:67:2e:73:57:04:ec:57:ca:6c:a6:f5:f2:84:b5:0d:
|
||||||
|
09:09:1a:64
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIEZTCCA00CAQAwDQYJKoZIhvcNAQELBQAwgZkxCzAJBgNVBAYTAkRFMR0wGwYD
|
||||||
|
VQQIDBRCYWRlbiBXw4PCvHJ0dGVtYmVyZzERMA8GA1UEBwwITWFubmhlaW0xFTAT
|
||||||
|
BgNVBAoMDE5ldHBvbmcgVGVhbTEdMBsGA1UEAwwUTmV0cG9uZy1UZXN0LUNBIFJv
|
||||||
|
b3QxIjAgBgkqhkiG9w0BCQEWE3NvZnR3YXJlQGNzY2hlcnIuZGUwHhcNMjQwMTI0
|
||||||
|
MTQ1MjQxWhcNMzQwMTIxMTQ1MjQxWjBXMQswCQYDVQQGEwJERTEdMBsGA1UECAwU
|
||||||
|
QmFkZW4gV8ODwrxydHRlbWJlcmcxFTATBgNVBAoMDE5ldHBvbmcgVGVhbTESMBAG
|
||||||
|
A1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA
|
||||||
|
1eakGKHCpsbxItfFZqaQaPYvDi9BjJsu8uRkm+FfKGRP6qa1aGfiCZMRkz3YC+cG
|
||||||
|
UDgebPpwLDL7ZLrTQ4wWsHg55G8F2uF7wIzgeZBNYIUOE1wrA6k4ySBIG0GncJXS
|
||||||
|
rumWXlXXoZt1Ud5ldXwPH3EpiG3KgtWe5gl4StMQ9xNpyD5Ofh+bnGuj9toqZT1B
|
||||||
|
6UFiQaeqXp5aG+mgyjXEfqCTSAzMVJh5S5cgDUifmvskFm66rQRegwym2t5ZainA
|
||||||
|
/Xc71NHyp6ChZGYyUhEIXxc1FBGrmqxp34LQBX54fkUg6toOGDsicuPW70oAqio9
|
||||||
|
QjoDrmrmzCr7bOvgEz7KHaaS7RQlo8PZA2ATSL4yxLMJ32i1s3/NE8av4EnSkUDT
|
||||||
|
nW9TpQgjXvux1iCPoGaxzn2Ol3mc7HOUymBxSI4PkrdbmYMkAhOj82SSJS50AA22
|
||||||
|
5IVBlRKvkznt7XOeAKXGG4o/GXPo5AFKpPWmPPju43Qh/atTFyxydLB+hyO18t1n
|
||||||
|
JNGMjXVL2VvREFXAay0ifH+hQhUST/1wsxj1eKlW9y/ykVRXOJ8RMSDdear7to38
|
||||||
|
WCUHK7nHi4XjOXdvjlH6nGvHKroeWSjpuAcfULyJPmFVmsXGbVQJmpbsl9kWW0tg
|
||||||
|
1Te/na1yCUz8wN8FXCpRkuJ5sMaMkSapyz35Ht1/GeMCAwEAATANBgkqhkiG9w0B
|
||||||
|
AQsFAAOCAQEAPwC8cHfBTfXS9eojeh3ukDoeFjorJVaME3hOoWwySWg+DppD4UW/
|
||||||
|
haE2iF+a4ZsEQPikd1/PoynF+7Ar0cwrlwTRnk0yfb3/SXuxOMd3vnRzL/Ll+K80
|
||||||
|
BfJedUAq04/XT6oXfQnxFj4c9+bperuYkoNatHEIl/xul88Hc0jeI/ZYBrTJyacR
|
||||||
|
i5VQ8C7LJYWxMHlsYYTutOofsaeAxQks466D+Ao879G4+x4ukQMhZWL+/qbHzc9/
|
||||||
|
MdSZz245Y98a8v1VMyLvqCYvFfbZY6Ksu/G/6cHHiNFP2Bk4zozTvKgVMroFWHT1
|
||||||
|
jPqqn1JCZy5zVwTsV8pspvXyhLUNCQkaZA==
|
||||||
|
-----END CERTIFICATE-----
|
|
@ -0,0 +1,28 @@
|
||||||
|
-----BEGIN CERTIFICATE REQUEST-----
|
||||||
|
MIIE1DCCArwCAQAwgY4xCzAJBgNVBAYTAkRFMR0wGwYDVQQIDBRCYWRlbiBXw4PC
|
||||||
|
vHJ0dGVtYmVyZzERMA8GA1UEBwwITWFubmhlaW0xFTATBgNVBAoMDE5ldHBvbmcg
|
||||||
|
VGVhbTESMBAGA1UEAwwJbG9jYWxob3N0MSIwIAYJKoZIhvcNAQkBFhNzb2Z0d2Fy
|
||||||
|
ZUBjc2NoZXJyLmRlMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1eak
|
||||||
|
GKHCpsbxItfFZqaQaPYvDi9BjJsu8uRkm+FfKGRP6qa1aGfiCZMRkz3YC+cGUDge
|
||||||
|
bPpwLDL7ZLrTQ4wWsHg55G8F2uF7wIzgeZBNYIUOE1wrA6k4ySBIG0GncJXSrumW
|
||||||
|
XlXXoZt1Ud5ldXwPH3EpiG3KgtWe5gl4StMQ9xNpyD5Ofh+bnGuj9toqZT1B6UFi
|
||||||
|
QaeqXp5aG+mgyjXEfqCTSAzMVJh5S5cgDUifmvskFm66rQRegwym2t5ZainA/Xc7
|
||||||
|
1NHyp6ChZGYyUhEIXxc1FBGrmqxp34LQBX54fkUg6toOGDsicuPW70oAqio9QjoD
|
||||||
|
rmrmzCr7bOvgEz7KHaaS7RQlo8PZA2ATSL4yxLMJ32i1s3/NE8av4EnSkUDTnW9T
|
||||||
|
pQgjXvux1iCPoGaxzn2Ol3mc7HOUymBxSI4PkrdbmYMkAhOj82SSJS50AA225IVB
|
||||||
|
lRKvkznt7XOeAKXGG4o/GXPo5AFKpPWmPPju43Qh/atTFyxydLB+hyO18t1nJNGM
|
||||||
|
jXVL2VvREFXAay0ifH+hQhUST/1wsxj1eKlW9y/ykVRXOJ8RMSDdear7to38WCUH
|
||||||
|
K7nHi4XjOXdvjlH6nGvHKroeWSjpuAcfULyJPmFVmsXGbVQJmpbsl9kWW0tg1Te/
|
||||||
|
na1yCUz8wN8FXCpRkuJ5sMaMkSapyz35Ht1/GeMCAwEAAaAAMA0GCSqGSIb3DQEB
|
||||||
|
CwUAA4ICAQBfGAE9+31BxgHeUbmC96QtOjEhpy5YkONNQWB8M8588NVExV4WBAmj
|
||||||
|
bqEdGf5/KnDEqEMctzxYt7vSCPT5p1OALAkExWI+tz0uup6pjoKq8Ar9A/Va9tfn
|
||||||
|
4Bw3Nyvg1LJ55j0dhCCT8APljGhlHV5eVeLuFX4zTXHt+MJj/Laaip/k6J2+PuJk
|
||||||
|
pRPA/f/A2zswhgrWU/4ovyYB6f8MjJFvh65wlBva1j4Bs9siV5VpNdORswEBVXK+
|
||||||
|
4JUvdSabitn3uFWDCnEW+z7xi9Kl5aqo6VmYC6W58k8qJw8PhGODYIgKE0MhBLsd
|
||||||
|
CrfU9luUOpmrjvczZfkLuuuJxdZClrfW0kWyOlkx1rB9OFDmJVGgm0Px+dTUv53A
|
||||||
|
MojK3fhVdP2aUzHMrCpkINmpvChRNHKWYPDgBeqHNuMq/qlGXeDPuKGSN3KI3Srk
|
||||||
|
LhiDOTfRMDYNgi9V8kZywv8iLiHYke2TWDP08baUy190b5MxKr2/BnTNDpTVyx2q
|
||||||
|
4Cw7PdcvvlQsG/gpWyD93DQ3QNFsO+D4ZX6DyCbOnGFh4ff0w8Gylehp7OCiPbLB
|
||||||
|
hQrxbLrfZWEe62FrBArdJgF6aawpxycrgjXaapzFQhwaJV3BHQI+ScFrzwHaGnEG
|
||||||
|
LsSnnt+U6WrGgPuss435JhnB9QUe2hq/DSzuabeIQrpb57BrD57yuA==
|
||||||
|
-----END CERTIFICATE REQUEST-----
|
|
@ -0,0 +1,93 @@
|
||||||
|
Certificate:
|
||||||
|
Data:
|
||||||
|
Version: 1 (0x0)
|
||||||
|
Serial Number: 0 (0x0)
|
||||||
|
Signature Algorithm: sha256WithRSAEncryption
|
||||||
|
Issuer: C=DE, ST=Baden W\xC3\x83\xC2\xBCrttemberg, L=Mannheim, O=Netpong Team, CN=Netpong-Test-CA Root/emailAddress=software@cscherr.de
|
||||||
|
Validity
|
||||||
|
Not Before: Jan 24 14:52:41 2024 GMT
|
||||||
|
Not After : Jan 21 14:52:41 2034 GMT
|
||||||
|
Subject: C=DE, ST=Baden W\xC3\x83\xC2\xBCrttemberg, O=Netpong Team, CN=localhost
|
||||||
|
Subject Public Key Info:
|
||||||
|
Public Key Algorithm: rsaEncryption
|
||||||
|
Public-Key: (4096 bit)
|
||||||
|
Modulus:
|
||||||
|
00:d5:e6:a4:18:a1:c2:a6:c6:f1:22:d7:c5:66:a6:
|
||||||
|
90:68:f6:2f:0e:2f:41:8c:9b:2e:f2:e4:64:9b:e1:
|
||||||
|
5f:28:64:4f:ea:a6:b5:68:67:e2:09:93:11:93:3d:
|
||||||
|
d8:0b:e7:06:50:38:1e:6c:fa:70:2c:32:fb:64:ba:
|
||||||
|
d3:43:8c:16:b0:78:39:e4:6f:05:da:e1:7b:c0:8c:
|
||||||
|
e0:79:90:4d:60:85:0e:13:5c:2b:03:a9:38:c9:20:
|
||||||
|
48:1b:41:a7:70:95:d2:ae:e9:96:5e:55:d7:a1:9b:
|
||||||
|
75:51:de:65:75:7c:0f:1f:71:29:88:6d:ca:82:d5:
|
||||||
|
9e:e6:09:78:4a:d3:10:f7:13:69:c8:3e:4e:7e:1f:
|
||||||
|
9b:9c:6b:a3:f6:da:2a:65:3d:41:e9:41:62:41:a7:
|
||||||
|
aa:5e:9e:5a:1b:e9:a0:ca:35:c4:7e:a0:93:48:0c:
|
||||||
|
cc:54:98:79:4b:97:20:0d:48:9f:9a:fb:24:16:6e:
|
||||||
|
ba:ad:04:5e:83:0c:a6:da:de:59:6a:29:c0:fd:77:
|
||||||
|
3b:d4:d1:f2:a7:a0:a1:64:66:32:52:11:08:5f:17:
|
||||||
|
35:14:11:ab:9a:ac:69:df:82:d0:05:7e:78:7e:45:
|
||||||
|
20:ea:da:0e:18:3b:22:72:e3:d6:ef:4a:00:aa:2a:
|
||||||
|
3d:42:3a:03:ae:6a:e6:cc:2a:fb:6c:eb:e0:13:3e:
|
||||||
|
ca:1d:a6:92:ed:14:25:a3:c3:d9:03:60:13:48:be:
|
||||||
|
32:c4:b3:09:df:68:b5:b3:7f:cd:13:c6:af:e0:49:
|
||||||
|
d2:91:40:d3:9d:6f:53:a5:08:23:5e:fb:b1:d6:20:
|
||||||
|
8f:a0:66:b1:ce:7d:8e:97:79:9c:ec:73:94:ca:60:
|
||||||
|
71:48:8e:0f:92:b7:5b:99:83:24:02:13:a3:f3:64:
|
||||||
|
92:25:2e:74:00:0d:b6:e4:85:41:95:12:af:93:39:
|
||||||
|
ed:ed:73:9e:00:a5:c6:1b:8a:3f:19:73:e8:e4:01:
|
||||||
|
4a:a4:f5:a6:3c:f8:ee:e3:74:21:fd:ab:53:17:2c:
|
||||||
|
72:74:b0:7e:87:23:b5:f2:dd:67:24:d1:8c:8d:75:
|
||||||
|
4b:d9:5b:d1:10:55:c0:6b:2d:22:7c:7f:a1:42:15:
|
||||||
|
12:4f:fd:70:b3:18:f5:78:a9:56:f7:2f:f2:91:54:
|
||||||
|
57:38:9f:11:31:20:dd:79:aa:fb:b6:8d:fc:58:25:
|
||||||
|
07:2b:b9:c7:8b:85:e3:39:77:6f:8e:51:fa:9c:6b:
|
||||||
|
c7:2a:ba:1e:59:28:e9:b8:07:1f:50:bc:89:3e:61:
|
||||||
|
55:9a:c5:c6:6d:54:09:9a:96:ec:97:d9:16:5b:4b:
|
||||||
|
60:d5:37:bf:9d:ad:72:09:4c:fc:c0:df:05:5c:2a:
|
||||||
|
51:92:e2:79:b0:c6:8c:91:26:a9:cb:3d:f9:1e:dd:
|
||||||
|
7f:19:e3
|
||||||
|
Exponent: 65537 (0x10001)
|
||||||
|
Signature Algorithm: sha256WithRSAEncryption
|
||||||
|
Signature Value:
|
||||||
|
3f:00:bc:70:77:c1:4d:f5:d2:f5:ea:23:7a:1d:ee:90:3a:1e:
|
||||||
|
16:3a:2b:25:56:8c:13:78:4e:a1:6c:32:49:68:3e:0e:9a:43:
|
||||||
|
e1:45:bf:85:a1:36:88:5f:9a:e1:9b:04:40:f8:a4:77:5f:cf:
|
||||||
|
a3:29:c5:fb:b0:2b:d1:cc:2b:97:04:d1:9e:4d:32:7d:bd:ff:
|
||||||
|
49:7b:b1:38:c7:77:be:74:73:2f:f2:e5:f8:af:34:05:f2:5e:
|
||||||
|
75:40:2a:d3:8f:d7:4f:aa:17:7d:09:f1:16:3e:1c:f7:e6:e9:
|
||||||
|
7a:bb:98:92:83:5a:b4:71:08:97:fc:6e:97:cf:07:73:48:de:
|
||||||
|
23:f6:58:06:b4:c9:c9:a7:11:8b:95:50:f0:2e:cb:25:85:b1:
|
||||||
|
30:79:6c:61:84:ee:b4:ea:1f:b1:a7:80:c5:09:2c:e3:ae:83:
|
||||||
|
f8:0a:3c:ef:d1:b8:fb:1e:2e:91:03:21:65:62:fe:fe:a6:c7:
|
||||||
|
cd:cf:7f:31:d4:99:cf:6e:39:63:df:1a:f2:fd:55:33:22:ef:
|
||||||
|
a8:26:2f:15:f6:d9:63:a2:ac:bb:f1:bf:e9:c1:c7:88:d1:4f:
|
||||||
|
d8:19:38:ce:8c:d3:bc:a8:15:32:ba:05:58:74:f5:8c:fa:aa:
|
||||||
|
9f:52:42:67:2e:73:57:04:ec:57:ca:6c:a6:f5:f2:84:b5:0d:
|
||||||
|
09:09:1a:64
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIEZTCCA00CAQAwDQYJKoZIhvcNAQELBQAwgZkxCzAJBgNVBAYTAkRFMR0wGwYD
|
||||||
|
VQQIDBRCYWRlbiBXw4PCvHJ0dGVtYmVyZzERMA8GA1UEBwwITWFubmhlaW0xFTAT
|
||||||
|
BgNVBAoMDE5ldHBvbmcgVGVhbTEdMBsGA1UEAwwUTmV0cG9uZy1UZXN0LUNBIFJv
|
||||||
|
b3QxIjAgBgkqhkiG9w0BCQEWE3NvZnR3YXJlQGNzY2hlcnIuZGUwHhcNMjQwMTI0
|
||||||
|
MTQ1MjQxWhcNMzQwMTIxMTQ1MjQxWjBXMQswCQYDVQQGEwJERTEdMBsGA1UECAwU
|
||||||
|
QmFkZW4gV8ODwrxydHRlbWJlcmcxFTATBgNVBAoMDE5ldHBvbmcgVGVhbTESMBAG
|
||||||
|
A1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA
|
||||||
|
1eakGKHCpsbxItfFZqaQaPYvDi9BjJsu8uRkm+FfKGRP6qa1aGfiCZMRkz3YC+cG
|
||||||
|
UDgebPpwLDL7ZLrTQ4wWsHg55G8F2uF7wIzgeZBNYIUOE1wrA6k4ySBIG0GncJXS
|
||||||
|
rumWXlXXoZt1Ud5ldXwPH3EpiG3KgtWe5gl4StMQ9xNpyD5Ofh+bnGuj9toqZT1B
|
||||||
|
6UFiQaeqXp5aG+mgyjXEfqCTSAzMVJh5S5cgDUifmvskFm66rQRegwym2t5ZainA
|
||||||
|
/Xc71NHyp6ChZGYyUhEIXxc1FBGrmqxp34LQBX54fkUg6toOGDsicuPW70oAqio9
|
||||||
|
QjoDrmrmzCr7bOvgEz7KHaaS7RQlo8PZA2ATSL4yxLMJ32i1s3/NE8av4EnSkUDT
|
||||||
|
nW9TpQgjXvux1iCPoGaxzn2Ol3mc7HOUymBxSI4PkrdbmYMkAhOj82SSJS50AA22
|
||||||
|
5IVBlRKvkznt7XOeAKXGG4o/GXPo5AFKpPWmPPju43Qh/atTFyxydLB+hyO18t1n
|
||||||
|
JNGMjXVL2VvREFXAay0ifH+hQhUST/1wsxj1eKlW9y/ykVRXOJ8RMSDdear7to38
|
||||||
|
WCUHK7nHi4XjOXdvjlH6nGvHKroeWSjpuAcfULyJPmFVmsXGbVQJmpbsl9kWW0tg
|
||||||
|
1Te/na1yCUz8wN8FXCpRkuJ5sMaMkSapyz35Ht1/GeMCAwEAATANBgkqhkiG9w0B
|
||||||
|
AQsFAAOCAQEAPwC8cHfBTfXS9eojeh3ukDoeFjorJVaME3hOoWwySWg+DppD4UW/
|
||||||
|
haE2iF+a4ZsEQPikd1/PoynF+7Ar0cwrlwTRnk0yfb3/SXuxOMd3vnRzL/Ll+K80
|
||||||
|
BfJedUAq04/XT6oXfQnxFj4c9+bperuYkoNatHEIl/xul88Hc0jeI/ZYBrTJyacR
|
||||||
|
i5VQ8C7LJYWxMHlsYYTutOofsaeAxQks466D+Ao879G4+x4ukQMhZWL+/qbHzc9/
|
||||||
|
MdSZz245Y98a8v1VMyLvqCYvFfbZY6Ksu/G/6cHHiNFP2Bk4zozTvKgVMroFWHT1
|
||||||
|
jPqqn1JCZy5zVwTsV8pspvXyhLUNCQkaZA==
|
||||||
|
-----END CERTIFICATE-----
|
|
@ -0,0 +1,28 @@
|
||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCNzjjeONRhk/hp
|
||||||
|
ULS8PRZGnMLobnTC9reUtfa85/rHXEAT+xVDsXePbmz+hRTMdJ/j8XgfesJHlman
|
||||||
|
I4GJb/Vm5BVvjwfHMTtWH9BB6dNRVw8R1lyp/S8uiAPNpKur24xe+ZYdaBAgTTJh
|
||||||
|
sQF3b9sTSTnfQRblBmkp1Rkjqb5N/qTrQWTrmyQLghnrzgzpqEH0BCIFjRzoPMk8
|
||||||
|
3oBXfezoeMeoslR5bCIQVfHu/8jcWjzU0eehFlDD1s16XetFrU6+fUUhTPesrKBd
|
||||||
|
vf9lyXdMqHZ5FdvtsmYbfl2H4LH060+VhKJTjnDkrFrv5zWfYf6sO/lCVwe2xRHY
|
||||||
|
40MNEbgzAgMBAAECggEAIMO52wqpc8RTPM4zfFzm9TjKRhcjblrADyG+GWbGSGL1
|
||||||
|
wUgd4S6zj9X1ZBeOtzDpMqs71JYyJoVHQa4QA5f1TSk9FLIpG2qyKZOfNGOY+m3R
|
||||||
|
ow7zCSnhSXCO5Gh8a/CF7fngJ/o/457CmdTioFydc0bTktSAvDkvekVtEhLp0C5C
|
||||||
|
jTxhOYFaSznpLccHVkZtu2hYqSInTLFk3YVBi1qHO8qGbnUCj1PWSxV1wTmu/Ilo
|
||||||
|
wVw3OFyCoZhjrSN3sjNYpOFJEAV5eb9AUGCum6r+Zo7GNPiM7jDShfRidD8mjcq9
|
||||||
|
YDDkInTETHVcmr1U5CByUagDl7//ifaRBoBy5E3GPQKBgQDDKneviwuCGt2y5qbN
|
||||||
|
PPILMXHwMxja77iDIily7Mg9cbi8Cmq4fcLcPs6SEoMmHHzuAFICrWXjJJ14npfv
|
||||||
|
PR/UnIqDo95PclsjHe1dou396eqrtNGUBp5c8lt8tZGbLcLdCZMOsKqCdiPTmw1T
|
||||||
|
vaGnx4GRaQIoOVeW0N8me0J9hQKBgQC6Acr6JP/tD40s04fQb6SBMz+mTiAGPoel
|
||||||
|
R0crnh6rqb4wvomX5yoT9JRI80+i/aqVtm7COb512nq2CLc4SKSOdVSEHaRTUmOC
|
||||||
|
lLnImM9rQoP13VEwuGnL7kMv7mNc2sOZl6WHGmAnHS27zDV+e74vUIyjAdqUAUsL
|
||||||
|
C19SU5nQVwKBgQCbo7pe29wJnbM/gIF1Gy1Lj9r1W0pvDs1uhkfXxszJc2+HRidl
|
||||||
|
iaVkTxIdm3XLZtyaUNcWG4Itan3KO2+e8nf37f7ojD41zVSw5KTvD4gL/gePd1vL
|
||||||
|
WJviM8SR55p+zjegXopQJMNV1zErB3PRXGEWlBvYAo4d1dzsARZ0ccfMoQKBgB+Z
|
||||||
|
AF8f++3Mb4IG6RJqdLqR9yUMLnqBEs/r3NY3BSTKMAndxEfuuAIt0SbXVlbs2paW
|
||||||
|
KBiMcKNamu/jaSSBipq8qb/LvUd+PnNHSoweEVY6NWqFzy4ElcxTzEwPJgf3DbVA
|
||||||
|
wpjBzUW3ujYlyYyT/snQ2CM0xGnSEmps4yN8Giv/AoGALsiOvNv/jUNU/RM+OznR
|
||||||
|
93Q7WsmjZxbPFLAdpiI+Fl8zcERlSGqBKSxQSdeD7Tke5Ywzc/LHqNhTJjnDjJCY
|
||||||
|
xWzDRe/ALUHCEEc4C6dd5qPmD30T8Fb8fRX6HVFHqT3VKb3KKrpZYvkNY8ihprq6
|
||||||
|
iLDnm4a9JQ3aGrzkgV6xxlo=
|
||||||
|
-----END PRIVATE KEY-----
|
|
@ -0,0 +1,52 @@
|
||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
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
|
||||||
|
nUyPrKRIgMlaQ+VkMxifhq9MzBqyB7I=
|
||||||
|
-----END PRIVATE KEY-----
|
|
@ -0,0 +1 @@
|
||||||
|
01
|
|
@ -0,0 +1 @@
|
||||||
|
00
|
|
@ -0,0 +1,32 @@
|
||||||
|
[ ca ]
|
||||||
|
default_ca = Netpong-Test-CA # The default ca section
|
||||||
|
|
||||||
|
[ Netpong-Test-CA ]
|
||||||
|
|
||||||
|
dir = ./Netpong-Test-CA # top dir
|
||||||
|
database = $dir/index.txt # index file.
|
||||||
|
new_certs_dir = $dir/newcerts # new certs dir
|
||||||
|
|
||||||
|
certificate = $dir/cacert.pem # The CA cert
|
||||||
|
serial = $dir/serial # serial no file
|
||||||
|
private_key = $dir/private/cakey.pem# CA private key
|
||||||
|
RANDFILE = $dir/private/.rand # random number file
|
||||||
|
|
||||||
|
default_days = 3650 # how long to certify for
|
||||||
|
default_crl_days= 30 # how long before next CRL
|
||||||
|
default_md = sha256 # md to use
|
||||||
|
|
||||||
|
policy = policy_any # default policy
|
||||||
|
email_in_dn = no # Don't add the email into cert DN
|
||||||
|
|
||||||
|
name_opt = ca_default # Subject name display option
|
||||||
|
cert_opt = ca_default # Certificate display option
|
||||||
|
copy_extensions = none # Don't copy extensions from request
|
||||||
|
|
||||||
|
[ policy_any ]
|
||||||
|
countryName = optional
|
||||||
|
stateOrProvinceName = optional
|
||||||
|
organizationName = optional
|
||||||
|
organizationalUnitName = optional
|
||||||
|
commonName = supplied
|
||||||
|
emailAddress = optional
|
|
@ -0,0 +1,27 @@
|
||||||
|
Using openssl to generate stuff is an endless hole, that will only make you
|
||||||
|
frustrated and waste your time. Don't even bother. You have been warned.
|
||||||
|
|
||||||
|
The stuff below is stolen from [here](https://stackoverflow.com/questions/60751795/unable-to-use-self-signed-certificates-with-tokio-rustls).
|
||||||
|
It just worked, after hours of trying to set up a selfsigned pki with v3 x509
|
||||||
|
(rustls decided not to support the regular v1)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
You probably used a CA certificate as a client certificate.
|
||||||
|
|
||||||
|
Create a CA:
|
||||||
|
|
||||||
|
openssl req -x509 -noenc -subj '/CN=example.com' -newkey rsa -keyout root.key -out root.crt
|
||||||
|
|
||||||
|
Create a certificate signing request (CSR):
|
||||||
|
|
||||||
|
openssl req -noenc -newkey rsa -keyout client.key -out client.csr -subj '/CN=example.com' -addext subjectAltName=DNS:example.com
|
||||||
|
|
||||||
|
Sign it using your CA:
|
||||||
|
|
||||||
|
openssl x509 -req -in client.csr -CA root.crt -CAkey root.key -days 365 -out client.crt -copy_extensions copy
|
||||||
|
|
||||||
|
And then you use the certificate client.crt and the key client.key. And the client should trust your root.crt.
|
||||||
|
|
||||||
|
The addext and copy_extensions flag ensure that they generated key is X509v3, otherwise webpki will start complaining. And subjectAltName is required to prevent rustls from complaining.
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDCTCCAfGgAwIBAgIUcD/jxH3qOc8VK/FXAeP6nimT0W4wDQYJKoZIhvcNAQEL
|
||||||
|
BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI0MDEyNDE0NTYzMloXDTI0MDIy
|
||||||
|
MzE0NTYzMlowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF
|
||||||
|
AAOCAQ8AMIIBCgKCAQEAmc0kWDjYQ9073nXLsGYN2ovyxOHKjWcREFbuTLp2qf+A
|
||||||
|
CpK6j+mBFngNNKlTJvQKhrULdUf61WeBwz0zYiExibd4jlGERjzK/5Aj1z+eUKBA
|
||||||
|
TiwfmvnpHGNvsU2WrfNd9wBjiJV/FB17JDYJZVfiswpbdV+9066fzQ0LImHBj1ON
|
||||||
|
vcwSPIrxwG3oe+zPGIO9CpQHUEzaMy6S5AUgDHwtiTwQwucu5Up4xM5WA1kVCiMq
|
||||||
|
Fc9qv84RxhhSOlWbCVeRMZP1qiWzMRs2vGVOfX/D6gL21qHliVLIP2lrs1ISdqM9
|
||||||
|
OMCCxMb8MAqtIECxVCm3cNE/YeBaoA7p2JlkY0BB+wIDAQABo1MwUTAdBgNVHQ4E
|
||||||
|
FgQUKAvw/RZZKZHpaxVLWVlijc+BROwwHwYDVR0jBBgwFoAUKAvw/RZZKZHpaxVL
|
||||||
|
WVlijc+BROwwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAeNmR
|
||||||
|
fTyPanTRdTYewpJZPRZ1SvROwfzAAwMu6CqMqnH1aLizG2DFNAeHoU+TezvgXb2u
|
||||||
|
lvuIqNuUdLDTUWIhZkCgL/TQhnKWfAv9jqP2h85TgRCNAzEHYgFtXuHYnTuB4KAg
|
||||||
|
AAsRsY6r5bTvr/eDBeufOn7+MIbPp795g5ffD6YFv5gRGlKDBudwA2N0upptiZT9
|
||||||
|
Vzzf6SdPyskIdtLLA4QeY0lCsqekpd3Bo0fM0D0LgIw4+R+D5iYLUNRCkYqj0ydj
|
||||||
|
tJQEOdWVKtEdbylYlFF0QFSEAtszOW9yRPbfIY7n84WC2Z9zCYTls8V0sgw9PfMs
|
||||||
|
P1J2bn37/RNoNykeTA==
|
||||||
|
-----END CERTIFICATE-----
|
|
@ -0,0 +1,28 @@
|
||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCZzSRYONhD3Tve
|
||||||
|
dcuwZg3ai/LE4cqNZxEQVu5Munap/4AKkrqP6YEWeA00qVMm9AqGtQt1R/rVZ4HD
|
||||||
|
PTNiITGJt3iOUYRGPMr/kCPXP55QoEBOLB+a+ekcY2+xTZat8133AGOIlX8UHXsk
|
||||||
|
NgllV+KzClt1X73Trp/NDQsiYcGPU429zBI8ivHAbeh77M8Yg70KlAdQTNozLpLk
|
||||||
|
BSAMfC2JPBDC5y7lSnjEzlYDWRUKIyoVz2q/zhHGGFI6VZsJV5Exk/WqJbMxGza8
|
||||||
|
ZU59f8PqAvbWoeWJUsg/aWuzUhJ2oz04wILExvwwCq0gQLFUKbdw0T9h4FqgDunY
|
||||||
|
mWRjQEH7AgMBAAECggEADkpu8Zmakre4S+PjIMliySdOz/dw9DGa9ss1CkEbLJGW
|
||||||
|
iqT2m8+lFHrkMzv2g3ySi9C/t06QYorjFkqV/yy5ZyP6mjK92S7l59gzVFlPcwto
|
||||||
|
3jqgVyyYefBNXQqqERC3bu+E0Bif/bT9j7BLsDR51owEUoQqZcRoicuH+NJfg1sp
|
||||||
|
ndoLSfS6HTewS0oVAHaXgS02BsBoWCfEmf4G5VXhJvwgRN+QHgrni8bvuXFzoD48
|
||||||
|
e+uv+LVMOYaG7bf3jOEun3kdvNtrocEVA5lsc8mIfz6ie/b703p3FsS7FuIrUUqN
|
||||||
|
raVkvwxBeqeXPf94IBRUuicn+tH0fT9g/Pwsd+zhvQKBgQC1Ku/cKxwguoHFWlwv
|
||||||
|
17rTmNYAPgEQ8PXai+05LjVBi0ZMKfRJ7jSbV/JZbZy9omGqvqo8w4rLE6uQDEXv
|
||||||
|
huKYqQP8azp6pav6mX+G/zxHw606QNw12vc98egGCQeOPRUa6O2GK8BZkbJ7OKvF
|
||||||
|
NQ0Vy0hDDAldzYOTPpGIWXTrfQKBgQDZVGy3Yb+ynB35g0qHpVxN0tLZhe29Vnrb
|
||||||
|
yyZ5Jpg0tIa1sce9vOF1eYj1W/HlnfNeKiJ4/Qd6SXZjM8MQAvuvwaRf/dsexF49
|
||||||
|
WQwTPVro+oDL7OEq/Bj3vjM7AuDs99TuEbqLk6pw+Tsrw1sSGiyNMe5hKxE4bRD4
|
||||||
|
4VKxIfks1wKBgQCjD6liZl7jylrBMeplmWtrxlVfVG+LOwZeFbGH1OJUQzIbnWtm
|
||||||
|
G4O4Cjl0amc4e+4iS4hYNrw2ulahyZos1CAhvYZ77FtvRqx7Wytga1xrT2EcXIKX
|
||||||
|
6qS8WX436GqniKz1Uo9vQvPW6n9VzxUz4+MKKbS5vBy2FCMIJbnBmprU1QKBgAwp
|
||||||
|
4XvSCLyiaDsS0hUNeEESz6JFEK1MLcwnbpvRQSuR/wgkTx2beLLufm/dGYjUck6O
|
||||||
|
5ScIYmbBvdKHjx9SS2vm1qBYwO7T5sJgPYDGKlRn0NWZCHEzcuJKzus6mgQpSs2Y
|
||||||
|
SGyPczanfFxSrsIwnNW6ObFOi8QwtoZ3df1b/Wo5AoGAFmiDM8D4G3DVkZaKwSgX
|
||||||
|
6KpyQL2Vl1lyDzFiiBMy7REqy6KruZivmxlFwepkyTFbQt7r3BtWwwEq4teZiPXx
|
||||||
|
JOdD5MnAUeoR5XvMN064IsLeC9ReTEBWrrh0XciAWTNpfsM0861V3OgX9NQIOXcc
|
||||||
|
wRZa4TAcJKBJO4+ftFKCi30=
|
||||||
|
-----END PRIVATE KEY-----
|
|
@ -0,0 +1,19 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDDjCCAfagAwIBAgIUCa25BV6Yb+yazosg/MltJOTnuhUwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI0MDEyNDE0NTcwOVoXDTI1MDEy
|
||||||
|
MzE0NTcwOVowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF
|
||||||
|
AAOCAQ8AMIIBCgKCAQEA8Z284xhdzPP6PfAmmy8TGtITFcRoARqWicOMBFGDuzNy
|
||||||
|
BKnU5oO/3mEt41C+ZllKgUodyx373WmKylV2l2JTQza2LZPXBVDUf/i4L7TwvqtR
|
||||||
|
Ia5w//EZ0kfozxTB0WXRutJqbxKizN/yLpzAKNgKYp73x8hOBD7cpKJ/wlZ4qFXq
|
||||||
|
cR7K+P4/HvTVCyqdnaG/UMVnnRnuOUu1XYPXhaTvsxh7Febxu7lShZeB/oyaaDCR
|
||||||
|
K9oA6eJV6lAWOqaMLWuHYfma0fjwEgr+tV3IkIVOfAdp91jo1bvgNdfoF1jxMmD5
|
||||||
|
v/0DpbkbcpOF8zQ3la+foloyQJuutx4bcj7sRfLMiwIDAQABo1gwVjAUBgNVHREE
|
||||||
|
DTALgglsb2NhbGhvc3QwHQYDVR0OBBYEFCCuIWcRm+7YgC8qmX87aWFc3l2qMB8G
|
||||||
|
A1UdIwQYMBaAFCgL8P0WWSmR6WsVS1lZYo3PgUTsMA0GCSqGSIb3DQEBCwUAA4IB
|
||||||
|
AQAkBR4fl1Vhx1WPCXdnyM5yocCUv3SfbzKJlevOqXWYzjCXUzB3LMqNrjjCcSUA
|
||||||
|
z42BYfv9cvmKfp5G77M3LEE9sUyKL+epyNBTgh5N/d1xZdITKuHL6c2OCaIHKowg
|
||||||
|
cP7kxFWFU5QDwYKhhkn6GRYoasS+B0jxCwW+k2pgUKxsMOZMmoBWVJL+MPyPBzV4
|
||||||
|
9oeYi50s+8RFAzsjXlHan6me6egbiJIn8DmBrshUG9LJzElPC6n6aixY9Ar0E6hR
|
||||||
|
O/25jHtFApXWzMsM5CwIRfb0JPMEB46+BUk89km2XYjFqUFp3PIjJz+/AMk07qEP
|
||||||
|
vykAMiOZ9ZP3XeZryzdLCIfd
|
||||||
|
-----END CERTIFICATE-----
|
|
@ -0,0 +1,16 @@
|
||||||
|
-----BEGIN CERTIFICATE REQUEST-----
|
||||||
|
MIICgDCCAWgCAQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0B
|
||||||
|
AQEFAAOCAQ8AMIIBCgKCAQEA8Z284xhdzPP6PfAmmy8TGtITFcRoARqWicOMBFGD
|
||||||
|
uzNyBKnU5oO/3mEt41C+ZllKgUodyx373WmKylV2l2JTQza2LZPXBVDUf/i4L7Tw
|
||||||
|
vqtRIa5w//EZ0kfozxTB0WXRutJqbxKizN/yLpzAKNgKYp73x8hOBD7cpKJ/wlZ4
|
||||||
|
qFXqcR7K+P4/HvTVCyqdnaG/UMVnnRnuOUu1XYPXhaTvsxh7Febxu7lShZeB/oya
|
||||||
|
aDCRK9oA6eJV6lAWOqaMLWuHYfma0fjwEgr+tV3IkIVOfAdp91jo1bvgNdfoF1jx
|
||||||
|
MmD5v/0DpbkbcpOF8zQ3la+foloyQJuutx4bcj7sRfLMiwIDAQABoCcwJQYJKoZI
|
||||||
|
hvcNAQkOMRgwFjAUBgNVHREEDTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQAD
|
||||||
|
ggEBAH5eaWnbsbys+CFHbzzpmXpnZpvCvrkvekJEm/21WAKGfcfl0o6IbyIGXePO
|
||||||
|
ASdWtiXcHhUIQ6c8V6nNIjP26sJR5Ol5qlPpHY+rP0CfKydwhOiu0Ty2Ceqqk2qV
|
||||||
|
AMG57tIR0XDNB8s1/cqIWqqX3vO4QEooBZlzY4Cu0HZKgnKNbV1XEjE4P4KbmEq2
|
||||||
|
DJUSO0ewqgYHdY227zjWVUFxicVOWiQQ9wLHl1ICBmHYzDiROSWzIswd8IZZvAGw
|
||||||
|
2+ulMnfEXKr04NN2AKj+DgZLyi7QhRL9MqnBAAGeQqmBVZjhn8dfuHUJFo6+xKe1
|
||||||
|
kB/FW9YU50Vt8mMxhwsA4XY0BEo=
|
||||||
|
-----END CERTIFICATE REQUEST-----
|
|
@ -0,0 +1,28 @@
|
||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDxnbzjGF3M8/o9
|
||||||
|
8CabLxMa0hMVxGgBGpaJw4wEUYO7M3IEqdTmg7/eYS3jUL5mWUqBSh3LHfvdaYrK
|
||||||
|
VXaXYlNDNrYtk9cFUNR/+LgvtPC+q1EhrnD/8RnSR+jPFMHRZdG60mpvEqLM3/Iu
|
||||||
|
nMAo2ApinvfHyE4EPtykon/CVnioVepxHsr4/j8e9NULKp2dob9QxWedGe45S7Vd
|
||||||
|
g9eFpO+zGHsV5vG7uVKFl4H+jJpoMJEr2gDp4lXqUBY6powta4dh+ZrR+PASCv61
|
||||||
|
XciQhU58B2n3WOjVu+A11+gXWPEyYPm//QOluRtyk4XzNDeVr5+iWjJAm663Hhty
|
||||||
|
PuxF8syLAgMBAAECggEAd2wAJvztq/YxSzjuVAiV+E06GqmrwFPscSZCiAXkRvxc
|
||||||
|
EDsDHHalOJyuyiqoGT1sCnBgPntQ+HSIoY5RYey6+79Il0l530o+5gvAue/EiHFz
|
||||||
|
1eJ7Pr3kBd/+DZCUZdPeMGl9Ku46omnUMb7PacCyjWFGVixGh2mstAEPhbYoyAZN
|
||||||
|
TyuGU1GQMtKlGOt9bibvzt/rMZlCZvQyCINOeU//9lGpmilvUbKFIxUzE1SRevXa
|
||||||
|
a1WZn4KEIphGPOF/dbgWhGMhVuoyaiLGriTsNUtky4dT/6e+IUEus9SkPDnooo18
|
||||||
|
ZN3cuNqZKB4IIXrlfBw7bBQQ4XsILVXKq5XAMhvlVQKBgQD2REmOWCkZQvzsTNj2
|
||||||
|
CxaOo5LsUqxQK1/eB5tgMf6qQVhodRZ3nMrSZGsGjJJDvRDyc6DtN1saLqr6KWdi
|
||||||
|
qGFySTA2dcoiSupFp7QqtGA5TARgy+lYh4QOYcUjobmCHH+OJtyzxWV+vsRF/wcI
|
||||||
|
RE0nbt9PkbN6K33HVUVMKsdxBwKBgQD7KmVrnPsSEygfV1tujf4a3pn1t4rOryej
|
||||||
|
yUQzd1YDc4QAkCuTZ9e2nMx5eyf57gIqjhFfThxe873a/wtKq9veDFiaBoZyOeL/
|
||||||
|
WAaP0YS0hpnOahrtcnaF3C/hvMbiF1Z0CCmIwL9UrxsS5PeC7qlsSObAMqXalPnR
|
||||||
|
oXBg6xUbXQKBgF6tqknbgxF/O5XthYwyfx2fraDFuBGqW1UVP5sgHXR/Yunl+hlK
|
||||||
|
Yn+4s5z09lasnZNY+Qm6OoA6aOl8eY7ohW5WzP5jEq9UdfUJoK66YjQlEZnVS4UJ
|
||||||
|
tK+CzzP/vT5UjoWsUzWaMocj+Hmgrqdy+uaqLZh9v668gcLc+aNq3vqJAoGAL4ec
|
||||||
|
Xbr9QDRj2Vp8sPUp6wfI9tje6bH3vGTwBRVGL60Cg+DEfkaeaa5Oe4a0z/Ucb9Um
|
||||||
|
sHRlpgpWGUU+a8kN+H05nxwxARi3Pj74LuslQ8xc+tTVd627hCVg4kUJFev4rkiF
|
||||||
|
I53mFy5z3yV5OUvUv+sjz6dF/5FFnUgBrjWObvkCgYASOqDXKOhMey2VgrHYCEGJ
|
||||||
|
VGlYG/NOTSOhvJKeS9LEgi4IaNWwbRSeR94AB749tZKCvz9jin+VJyxZsE/StCoS
|
||||||
|
Dg8xIC/lrB5S4FVoLUD/cn9k0SSI/AsnISpW21BUZPCwzOM4NDvyf3uGhRZXPOTk
|
||||||
|
8b+Chcc4BjK6X3oKgt4ztQ==
|
||||||
|
-----END PRIVATE KEY-----
|
|
@ -1,21 +0,0 @@
|
||||||
import socket
|
|
||||||
|
|
||||||
HOST = "127.0.0.1"
|
|
||||||
PORT = 9999
|
|
||||||
|
|
||||||
payload = b"ping\0"
|
|
||||||
|
|
||||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
|
||||||
s.connect((HOST, PORT))
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
s.sendall(payload)
|
|
||||||
print("> ping")
|
|
||||||
except Exception as e:
|
|
||||||
break
|
|
||||||
reply = s.recv(1024).decode()
|
|
||||||
if reply == "":
|
|
||||||
break
|
|
||||||
print(f"< {reply}")
|
|
||||||
print("connection shut down")
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/bash
|
||||||
|
mkdir data
|
||||||
|
echo create ca
|
||||||
|
# non-interactive and 10 years expiration
|
||||||
|
openssl req -x509 -nodes -newkey rsa:4096 -keyout data/key.pem -out data/cert.pem -sha256 -days 3650 -subj '/CN=localhost'
|
|
@ -0,0 +1,9 @@
|
||||||
|
[package]
|
||||||
|
name = "spammer"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
threadpool = "1.8.1"
|
|
@ -0,0 +1,18 @@
|
||||||
|
use threadpool::ThreadPool;
|
||||||
|
const MAX: usize = 20;
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let pool = ThreadPool::new(MAX);
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if pool.queued_count() < MAX {
|
||||||
|
pool.execute(|| {
|
||||||
|
let mut cmd = Command::new("/usr/bin/python3");
|
||||||
|
cmd.args(["../scripts/client.py"]);
|
||||||
|
let _ = cmd.output().unwrap();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1 +1,79 @@
|
||||||
|
#![cfg(feature = "server")]
|
||||||
|
use std::{fs::File, io::BufReader, sync::Arc};
|
||||||
|
|
||||||
|
use crate::{common::decode, Config};
|
||||||
|
|
||||||
|
use anyhow;
|
||||||
|
use libpt::log::{error, info, trace};
|
||||||
|
use rustls_pemfile::certs;
|
||||||
|
use tokio::{
|
||||||
|
io::{AsyncReadExt, AsyncWriteExt},
|
||||||
|
net::TcpStream,
|
||||||
|
};
|
||||||
|
use tokio_rustls::{
|
||||||
|
rustls::{self, pki_types},
|
||||||
|
TlsConnector,
|
||||||
|
};
|
||||||
|
use webpki_roots;
|
||||||
|
|
||||||
|
const BUF_SIZE: usize = 512;
|
||||||
|
|
||||||
|
pub struct Client {
|
||||||
|
cfg: Config,
|
||||||
|
stream: TcpStream,
|
||||||
|
connector: TlsConnector,
|
||||||
|
domain: pki_types::ServerName<'static>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Client {
|
||||||
|
pub async fn build(cfg: Config) -> anyhow::Result<Self> {
|
||||||
|
let mut root_cert_store = rustls::RootCertStore::empty();
|
||||||
|
root_cert_store.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
|
||||||
|
if cfg.certs.is_some() {
|
||||||
|
let mut reader = BufReader::new(File::open(cfg.certs.clone().unwrap())?);
|
||||||
|
for cert in certs(&mut reader) {
|
||||||
|
trace!("found custom cert: {cert:?}");
|
||||||
|
root_cert_store.add(cert?)?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
trace!("root cert store: {root_cert_store:?}");
|
||||||
|
let tls_config = rustls::ClientConfig::builder()
|
||||||
|
.with_root_certificates(root_cert_store)
|
||||||
|
.with_no_client_auth();
|
||||||
|
let connector = TlsConnector::from(Arc::new(tls_config));
|
||||||
|
let stream = TcpStream::connect(&cfg.addr).await?;
|
||||||
|
let domain = match pki_types::ServerName::try_from(cfg.hostname.clone()) {
|
||||||
|
Ok(domain) => domain,
|
||||||
|
Err(err) => {
|
||||||
|
error!("Could not resolve hostname '{}': {err:?}", cfg.hostname);
|
||||||
|
return Err(err.into());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Client {
|
||||||
|
cfg: cfg.clone(),
|
||||||
|
stream,
|
||||||
|
connector,
|
||||||
|
domain,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn run(self) -> anyhow::Result<()> {
|
||||||
|
let mut stream = self.connector.connect(self.domain, self.stream).await?;
|
||||||
|
let mut buf = [0; BUF_SIZE];
|
||||||
|
stream.write_all(b"ping").await?;
|
||||||
|
info!("> ({}) ping", self.cfg.hostname);
|
||||||
|
while stream.read(&mut buf).await? > 0 {
|
||||||
|
let response = decode(&buf)?;
|
||||||
|
info!("< ({}) {}", self.cfg.hostname, response);
|
||||||
|
if response == "You win!" {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
stream.write_all(b"ping").await?;
|
||||||
|
info!("> ({}) ping", self.cfg.hostname);
|
||||||
|
// we should wait, so that we don't spam the client
|
||||||
|
std::thread::sleep(self.cfg.delay);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use libpt::log::{Level, Logger};
|
use libpt::log::{Level, Logger};
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use clap_verbosity_flag::{InfoLevel, Verbosity};
|
use clap_verbosity_flag::{InfoLevel, Verbosity};
|
||||||
|
|
||||||
use crate::common::conf::Mode;
|
|
||||||
|
|
||||||
/// short about section displayed in help
|
/// short about section displayed in help
|
||||||
const ABOUT_ROOT: &'static str = r##"
|
const ABOUT_ROOT: &'static str = r##"
|
||||||
Let your hosts play ping pong over the network
|
Let your hosts play ping pong over the network
|
||||||
|
@ -46,16 +46,14 @@ pub(crate) struct Cli {
|
||||||
#[arg(short, long, default_value_t = false)]
|
#[arg(short, long, default_value_t = false)]
|
||||||
pub(crate) server: bool,
|
pub(crate) server: bool,
|
||||||
|
|
||||||
// how much threads the server should use
|
|
||||||
#[cfg(feature = "server")]
|
|
||||||
#[arg(short, long, default_value_t = 4)]
|
|
||||||
pub(crate) threads: usize,
|
|
||||||
|
|
||||||
#[arg(short, long, default_value_t = Mode::Tcp, ignore_case = true)]
|
|
||||||
pub(crate) mode: Mode,
|
|
||||||
|
|
||||||
/// Address of the server
|
/// Address of the server
|
||||||
pub(crate) addr: std::net::SocketAddr,
|
pub(crate) host: String,
|
||||||
|
|
||||||
|
#[cfg(feature = "server")]
|
||||||
|
#[arg(short, long)]
|
||||||
|
pub key: Option<PathBuf>,
|
||||||
|
#[arg(short, long)]
|
||||||
|
pub certs: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cli {
|
impl Cli {
|
||||||
|
@ -72,7 +70,7 @@ impl Cli {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if cli.meta {
|
if cli.meta {
|
||||||
Logger::init(None, Some(ll)).expect("could not initialize Logger");
|
Logger::init(None, Some(ll), true).expect("could not initialize Logger");
|
||||||
} else {
|
} else {
|
||||||
// less verbose version
|
// less verbose version
|
||||||
Logger::init_mini(Some(ll)).expect("could not initialize Logger");
|
Logger::init_mini(Some(ll)).expect("could not initialize Logger");
|
||||||
|
|
|
@ -1,65 +1,61 @@
|
||||||
use crate::common::args::Cli;
|
use crate::common::args::Cli;
|
||||||
use clap::ValueEnum;
|
|
||||||
use std::{fmt::Display, time::Duration};
|
use std::{
|
||||||
|
net::{SocketAddr, ToSocketAddrs},
|
||||||
|
path::PathBuf,
|
||||||
|
time::Duration,
|
||||||
|
};
|
||||||
|
|
||||||
|
use anyhow::{anyhow, Result};
|
||||||
|
use libpt::log::{error, trace};
|
||||||
|
|
||||||
const DEFAULT_TIMEOUT_LEN: u64 = 5000; // ms
|
const DEFAULT_TIMEOUT_LEN: u64 = 5000; // ms
|
||||||
const DEFAULT_DELAY_LEN: u64 = 500; // ms
|
const DEFAULT_DELAY_LEN: u64 = 500; // ms
|
||||||
const DEFAULT_WIN_AFTER: usize = 20;
|
const DEFAULT_WIN_AFTER: usize = 20;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Clone)]
|
||||||
pub enum Mode {
|
|
||||||
Tcp,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ValueEnum for Mode {
|
|
||||||
fn to_possible_value(&self) -> Option<clap::builder::PossibleValue> {
|
|
||||||
Some(match self {
|
|
||||||
Self::Tcp => clap::builder::PossibleValue::new("tcp"),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
fn value_variants<'a>() -> &'a [Self] {
|
|
||||||
&[Self::Tcp]
|
|
||||||
}
|
|
||||||
fn from_str(input: &str, ignore_case: bool) -> Result<Self, String> {
|
|
||||||
let comp: String = if ignore_case {
|
|
||||||
input.to_lowercase()
|
|
||||||
} else {
|
|
||||||
input.to_string()
|
|
||||||
};
|
|
||||||
match comp.as_str() {
|
|
||||||
"tcp" => return Ok(Self::Tcp),
|
|
||||||
_ => return Err(format!("\"{input}\" is not a valid mode")),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for Mode {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
let repr: String = match self {
|
|
||||||
Self::Tcp => format!("tcp"),
|
|
||||||
};
|
|
||||||
write!(f, "{}", repr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub addr: std::net::SocketAddr,
|
pub addr: std::net::SocketAddr,
|
||||||
pub mode: Mode,
|
pub hostname: String,
|
||||||
pub threads: usize,
|
|
||||||
pub timeout: Duration,
|
pub timeout: Duration,
|
||||||
pub delay: Duration,
|
pub delay: Duration,
|
||||||
|
#[cfg(feature = "server")]
|
||||||
pub win_after: usize,
|
pub win_after: usize,
|
||||||
|
#[cfg(feature = "server")]
|
||||||
|
pub key: Option<PathBuf>,
|
||||||
|
pub certs: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
pub fn new(cli: &Cli) -> Self {
|
pub fn build(cli: &Cli) -> Result<Self> {
|
||||||
Config {
|
let addr: SocketAddr = match cli.host.to_socket_addrs() {
|
||||||
addr: cli.addr.clone(),
|
Ok(mut addr) => addr.next().unwrap(),
|
||||||
mode: cli.mode.clone(),
|
Err(err) => {
|
||||||
threads: cli.threads,
|
error!(
|
||||||
|
"could not resolve host {:?} to a socket address: {err:?}",
|
||||||
|
cli.host.clone()
|
||||||
|
);
|
||||||
|
return Err(anyhow!(
|
||||||
|
"could not resolve host {:?} to a socket address: {err:?}",
|
||||||
|
cli.host
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let hostname = match cli.host.split_once(':') {
|
||||||
|
Some(hostname) => hostname.0.to_string(),
|
||||||
|
None => return Err(anyhow!("malformatted host (no port specified)")),
|
||||||
|
};
|
||||||
|
trace!("config has resolved the given hostname to: {addr:?}");
|
||||||
|
Ok(Config {
|
||||||
|
addr,
|
||||||
|
hostname,
|
||||||
timeout: Duration::from_millis(DEFAULT_TIMEOUT_LEN),
|
timeout: Duration::from_millis(DEFAULT_TIMEOUT_LEN),
|
||||||
delay: Duration::from_millis(DEFAULT_DELAY_LEN),
|
delay: Duration::from_millis(DEFAULT_DELAY_LEN),
|
||||||
|
#[cfg(feature = "server")]
|
||||||
win_after: DEFAULT_WIN_AFTER,
|
win_after: DEFAULT_WIN_AFTER,
|
||||||
}
|
#[cfg(feature = "server")]
|
||||||
|
key: cli.key.clone(),
|
||||||
|
certs: cli.certs.clone(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1,14 @@
|
||||||
|
use std::str::Utf8Error;
|
||||||
|
|
||||||
pub mod args;
|
pub mod args;
|
||||||
pub mod conf;
|
pub mod conf;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn decode(buf: &[u8]) -> Result<String, Utf8Error> {
|
||||||
|
Ok(match std::str::from_utf8(buf) {
|
||||||
|
Ok(s) => s.to_string(),
|
||||||
|
Err(err) => return Err(err.into()),
|
||||||
|
}
|
||||||
|
.trim_matches(char::from(0))
|
||||||
|
.to_string())
|
||||||
|
}
|
||||||
|
|
|
@ -13,14 +13,14 @@ mod server;
|
||||||
|
|
||||||
use common::{args::Cli, conf::*};
|
use common::{args::Cli, conf::*};
|
||||||
|
|
||||||
use crate::server::Server;
|
use crate::{client::Client, server::Server};
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
let cli = Cli::cli_parse();
|
let cli = Cli::cli_parse();
|
||||||
debug!("dumping cli args:\n{:#?}", cli);
|
debug!("dumping cli args:\n{:#?}", cli);
|
||||||
|
|
||||||
let cfg = Config::new(&cli);
|
let cfg = Config::build(&cli)?;
|
||||||
|
|
||||||
#[cfg(feature = "server")]
|
#[cfg(feature = "server")]
|
||||||
if cli.server {
|
if cli.server {
|
||||||
|
@ -29,5 +29,5 @@ async fn main() -> Result<()> {
|
||||||
}
|
}
|
||||||
// implicit else, so we can work without the server feature
|
// implicit else, so we can work without the server feature
|
||||||
info!("starting client");
|
info!("starting client");
|
||||||
Ok(())
|
return Client::build(cfg).await?.run().await;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{fmt::Display, string::FromUtf8Error};
|
use std::{fmt::Display, str::Utf8Error};
|
||||||
|
|
||||||
use anyhow;
|
use anyhow;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
@ -11,7 +11,7 @@ pub enum ServerError {
|
||||||
Timeout(Elapsed),
|
Timeout(Elapsed),
|
||||||
Anyhow(anyhow::Error),
|
Anyhow(anyhow::Error),
|
||||||
IO(std::io::Error),
|
IO(std::io::Error),
|
||||||
Format(FromUtf8Error),
|
Format(Utf8Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<anyhow::Error> for ServerError {
|
impl From<anyhow::Error> for ServerError {
|
||||||
|
@ -26,8 +26,8 @@ impl From<std::io::Error> for ServerError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<FromUtf8Error> for ServerError {
|
impl From<Utf8Error> for ServerError {
|
||||||
fn from(value: FromUtf8Error) -> Self {
|
fn from(value: Utf8Error) -> Self {
|
||||||
Self::Format(value)
|
Self::Format(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,125 +1,189 @@
|
||||||
#![cfg(feature = "server")]
|
#![cfg(feature = "server")]
|
||||||
use std::time::Duration;
|
use std::{
|
||||||
|
fs::File,
|
||||||
use libpt::log::{debug, info, trace, warn};
|
net::SocketAddr,
|
||||||
use tokio::{
|
sync::{atomic::AtomicUsize, Arc},
|
||||||
io::{AsyncBufReadExt, AsyncWriteExt, BufReader},
|
time::Duration,
|
||||||
net::{TcpListener, TcpStream},
|
|
||||||
time::timeout,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::common::conf::Config;
|
use libpt::log::{debug, error, info, trace, warn};
|
||||||
|
use rustls::pki_types::{CertificateDer, PrivateKeyDer};
|
||||||
|
use rustls_pemfile::{certs, private_key};
|
||||||
|
use tokio::{
|
||||||
|
io::{AsyncReadExt, AsyncWriteExt},
|
||||||
|
net::{TcpListener, TcpStream},
|
||||||
|
time::{self},
|
||||||
|
};
|
||||||
|
use tokio_rustls::{rustls, TlsAcceptor};
|
||||||
|
|
||||||
|
use crate::common::{conf::Config, decode};
|
||||||
|
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
use errors::*;
|
use errors::*;
|
||||||
|
|
||||||
|
const BUF_SIZE: usize = 512;
|
||||||
|
|
||||||
pub struct Server {
|
pub struct Server {
|
||||||
cfg: Config,
|
cfg: Config,
|
||||||
pub timeout: Option<Duration>,
|
|
||||||
server: TcpListener,
|
server: TcpListener,
|
||||||
|
num_peers: AtomicUsize,
|
||||||
|
acceptor: TlsAcceptor,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Server {
|
impl Server {
|
||||||
pub async fn build(cfg: Config) -> anyhow::Result<Self> {
|
pub async fn build(cfg: Config) -> anyhow::Result<Self> {
|
||||||
|
let certs = Self::load_certs(cfg.clone())?;
|
||||||
|
trace!("loaded certs: {:?}", certs);
|
||||||
|
let key = Self::load_key(cfg.clone())?.expect("bad key?");
|
||||||
|
trace!("loaded key: {:?}", key);
|
||||||
|
let tls_config = rustls::ServerConfig::builder()
|
||||||
|
.with_no_client_auth()
|
||||||
|
.with_single_cert(certs, key)?;
|
||||||
|
let acceptor = TlsAcceptor::from(Arc::new(tls_config));
|
||||||
let server = TcpListener::bind(cfg.addr).await?;
|
let server = TcpListener::bind(cfg.addr).await?;
|
||||||
let timeout = Some(Duration::from_secs(5));
|
|
||||||
Ok(Server {
|
Ok(Server {
|
||||||
cfg,
|
cfg,
|
||||||
timeout,
|
|
||||||
server,
|
server,
|
||||||
|
num_peers: AtomicUsize::new(0),
|
||||||
|
acceptor,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run(self) -> anyhow::Result<()> {
|
pub async fn run(self) -> anyhow::Result<()> {
|
||||||
|
let rc_self = Arc::new(self);
|
||||||
|
let ref_self = rc_self.clone();
|
||||||
|
tokio::spawn(async move {
|
||||||
|
let mut interval = time::interval(Duration::from_millis(5000));
|
||||||
|
loop {
|
||||||
|
interval.tick().await;
|
||||||
|
info!(
|
||||||
|
"status: {} peers",
|
||||||
|
ref_self
|
||||||
|
.num_peers
|
||||||
|
.load(std::sync::atomic::Ordering::Relaxed)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
loop {
|
loop {
|
||||||
let (stream, addr) = match self.server.accept().await {
|
let (stream, addr) = match rc_self.server.accept().await {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!("could not accept stream: {err:?}");
|
warn!("could not accept tcp stream: {err:?}");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
match self.handle_stream(stream).await {
|
let ref_self = rc_self.clone();
|
||||||
Ok(_) => (),
|
// NOTE: we can only start the task now. If we start it before accepting connections
|
||||||
Err(err) => {
|
// (so that the task theoretically accepts the connection), we would create endless
|
||||||
match err {
|
// tasks in a loop.
|
||||||
|
tokio::spawn(async move {
|
||||||
|
let stream: tokio_rustls::server::TlsStream<_> =
|
||||||
|
match ref_self.acceptor.accept(stream).await {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(err) => {
|
||||||
|
warn!("could not accept tls stream: {err}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ref_self.peer_add(1);
|
||||||
|
match ref_self.handle_stream(stream, addr).await {
|
||||||
|
Ok(_) => (),
|
||||||
|
Err(err) => match err {
|
||||||
ServerError::Timeout(_) => {
|
ServerError::Timeout(_) => {
|
||||||
info!("stream {:?} timed out", addr)
|
debug!("stream {:?} timed out", addr)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
warn!("error while handling stream: {:?}", err)
|
warn!("error while handling stream: {:?}", err)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
continue;
|
};
|
||||||
}
|
ref_self.peer_sub(1);
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_stream(&self, stream: TcpStream) -> Result<()> {
|
fn load_key(cfg: Config) -> std::io::Result<Option<PrivateKeyDer<'static>>> {
|
||||||
let mut pings: usize = 0;
|
if cfg.key.is_none() {
|
||||||
let addr = match stream.peer_addr() {
|
error!("the server needs a key!");
|
||||||
Ok(a) => a,
|
return Err(std::io::ErrorKind::InvalidInput.into());
|
||||||
Err(err) => {
|
}
|
||||||
debug!("could not get peer address: {:?}", err);
|
let key = private_key(&mut std::io::BufReader::new(File::open(
|
||||||
return Err(err.into());
|
cfg.key.clone().unwrap(),
|
||||||
}
|
)?));
|
||||||
};
|
return key;
|
||||||
info!("new peer: {:?}", addr);
|
}
|
||||||
let mut buf = Vec::new();
|
|
||||||
let mut reader = BufReader::new(stream);
|
|
||||||
let mut len;
|
|
||||||
loop {
|
|
||||||
len = match self.read(&mut reader, &mut buf).await {
|
|
||||||
Ok(len) => len,
|
|
||||||
Err(err) => {
|
|
||||||
match err {
|
|
||||||
ServerError::Timeout(_) => {
|
|
||||||
info!("peer {:?} timed out", addr)
|
|
||||||
}
|
|
||||||
_ => return Err(err),
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
trace!("received message: {:X?}", buf);
|
|
||||||
if len == 0 {
|
|
||||||
trace!("len is apperently 0: {len:?}");
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
let msg = self.decode(&buf)?;
|
|
||||||
info!("< {:?} : {}", addr, msg);
|
|
||||||
if msg.contains("ping") {
|
|
||||||
pings += 1;
|
|
||||||
}
|
|
||||||
if pings < self.cfg.win_after {
|
|
||||||
reader.write_all(b"pong\0").await?;
|
|
||||||
info!("> {:?} : pong", addr,);
|
|
||||||
} else {
|
|
||||||
reader.write_all(b"you win!\0").await?;
|
|
||||||
info!("> {:?} : you win!", addr,);
|
|
||||||
reader.shutdown().await?;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
buf.clear();
|
|
||||||
|
|
||||||
// we should wait, so that we don't spam the client
|
fn load_certs(cfg: Config) -> std::io::Result<Vec<CertificateDer<'static>>> {
|
||||||
std::thread::sleep(self.cfg.delay);
|
if cfg.certs.is_none() {
|
||||||
|
error!("the server needs at least one certificate!");
|
||||||
|
return Err(std::io::ErrorKind::InvalidInput.into());
|
||||||
|
}
|
||||||
|
match certs(&mut std::io::BufReader::new(File::open(
|
||||||
|
&cfg.certs.clone().unwrap(),
|
||||||
|
)?))
|
||||||
|
.collect::<std::io::Result<Vec<CertificateDer<'static>>>>()
|
||||||
|
{
|
||||||
|
Ok(v) if !v.is_empty() => Ok(v),
|
||||||
|
Ok(_) => {
|
||||||
|
error!("no certs found in provided file {:?}", cfg.certs);
|
||||||
|
return Err(std::io::ErrorKind::InvalidInput.into());
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
error!("could not load certs: {err:?}");
|
||||||
|
return Err(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
info!("disconnected peer: {:?}", addr);
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn peer_add(&self, v: usize) {
|
||||||
|
self.num_peers.store(
|
||||||
|
self.num_peers.load(std::sync::atomic::Ordering::Relaxed) + v,
|
||||||
|
std::sync::atomic::Ordering::Relaxed,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn peer_sub(&self, v: usize) {
|
||||||
|
self.num_peers.store(
|
||||||
|
self.num_peers.load(std::sync::atomic::Ordering::Relaxed) - v,
|
||||||
|
std::sync::atomic::Ordering::Relaxed,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle_stream(
|
||||||
|
&self,
|
||||||
|
mut stream: tokio_rustls::server::TlsStream<TcpStream>,
|
||||||
|
addr: SocketAddr,
|
||||||
|
) -> Result<()> {
|
||||||
|
let mut buf = [0; BUF_SIZE];
|
||||||
|
let mut pings = 0;
|
||||||
|
debug!("new peer: {:?}", addr);
|
||||||
|
while stream.read(&mut buf).await? > 0 {
|
||||||
|
let request = decode(&buf)?;
|
||||||
|
debug!(pings, "< ({})\n\"{}\"", addr, request);
|
||||||
|
if request == format!("ping") {
|
||||||
|
pings += 1;
|
||||||
|
if pings > self.cfg.win_after {
|
||||||
|
stream.write_all(b"You win!").await?;
|
||||||
|
debug!(pings, "> ({})\n\"{}\"", addr, "You win!");
|
||||||
|
info!("{} won!", addr);
|
||||||
|
stream.flush().await?;
|
||||||
|
stream.shutdown().await?;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
stream.write_all(b"pong").await?;
|
||||||
|
debug!(pings, "> ({})\n\"{}\"", addr, "pong");
|
||||||
|
} else {
|
||||||
|
stream.write_all(b"what is the magic word?").await?;
|
||||||
|
debug!(pings, "> ({})\n\"{}\"", addr, "what is the magic word?");
|
||||||
|
stream.flush().await?;
|
||||||
|
}
|
||||||
|
// we should wait, so that we don't spam the client
|
||||||
|
std::thread::sleep(self.cfg.delay);
|
||||||
|
}
|
||||||
|
debug!("disconnected peer: {:?}", addr);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn decode(&self, buf: &Vec<u8>) -> Result<String> {
|
|
||||||
Ok(String::from_utf8(buf.clone())?.replace('\n', "\\n"))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
async fn read(&self, reader: &mut BufReader<TcpStream>, buf: &mut Vec<u8>) -> Result<usize> {
|
|
||||||
match timeout(self.cfg.timeout, reader.read_until(0x00, buf)).await? {
|
|
||||||
Ok(len) => Ok(len),
|
|
||||||
Err(err) => Err(err.into()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue