summaryrefslogtreecommitdiffstats
path: root/src/bin/server/tls.rs
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-08-24 14:48:12 +0200
committersalmonik <salmonik@tuta.io>2026-08-24 14:48:12 +0200
commit5d6b5049c2a34a3f8abe725d4a871ba84a0dd714 (patch)
tree57cb03bf59b3358a96742f455d38c21f4f645396 /src/bin/server/tls.rs
parentstable and working, both platforms (diff)
downloadzagan-bet-5d6b5049c2a34a3f8abe725d4a871ba84a0dd714.tar.gz
zagan-bet-5d6b5049c2a34a3f8abe725d4a871ba84a0dd714.zip
TLS transport and games framework on client and server
Diffstat (limited to '')
-rw-r--r--src/bin/server/tls.rs96
1 files changed, 96 insertions, 0 deletions
diff --git a/src/bin/server/tls.rs b/src/bin/server/tls.rs
new file mode 100644
index 0000000..acf3315
--- /dev/null
+++ b/src/bin/server/tls.rs
@@ -0,0 +1,96 @@
1use std::io::{Read, Write};
2use std::net::TcpStream;
3
4#[derive(Clone)]
5pub struct TlsServer {
6 acceptor: native_tls::TlsAcceptor,
7}
8
9impl TlsServer {
10 pub fn new(
11 cert_path: &str,
12 _key_path: &str,
13 unsafe_mode: bool,
14 ) -> Result<Self, Box<dyn std::error::Error>> {
15 let cert_data = if unsafe_mode {
16 if std::path::Path::new(cert_path).exists() {
17 std::fs::read(cert_path)?
18 } else {
19 return Err(format!(
20 "Certificate file '{}' not found. In --unsafe mode, you must provide a valid PKCS12 certificate file.\n\
21 You can generate one with:\n\
22 openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes\n\
23 openssl pkcs12 -export -out identity.p12 -inkey key.pem -in cert.pem",
24 cert_path
25 ).into());
26 }
27 } else {
28 std::fs::read(cert_path)?
29 };
30
31 let identity = native_tls::Identity::from_pkcs12(&cert_data, "")?;
32 let acceptor = native_tls::TlsAcceptor::new(identity)?;
33
34 Ok(Self { acceptor })
35 }
36
37 pub fn accept(&self, stream: TcpStream) -> Result<TlsStream, Box<dyn std::error::Error>> {
38 let stream = self.acceptor.accept(stream)?;
39 Ok(TlsStream::new(stream))
40 }
41}
42
43pub struct TlsStream {
44 stream: native_tls::TlsStream<TcpStream>,
45}
46
47impl TlsStream {
48 pub fn new(stream: native_tls::TlsStream<TcpStream>) -> Self {
49 Self { stream }
50 }
51
52 pub fn read_line(&mut self, s: &mut String) -> std::io::Result<usize> {
53 let mut buf = [0u8; 1024];
54 loop {
55 match self.stream.read(&mut buf) {
56 Ok(0) => return Ok(0),
57 Ok(n) => {
58 let chunk = std::str::from_utf8(&buf[..n]).unwrap_or("");
59 s.push_str(chunk);
60 if s.contains('\n') {
61 return Ok(n);
62 }
63 }
64 Err(e) => return Err(e),
65 }
66 }
67 }
68
69 pub fn write_line(&mut self, msg: &str) -> std::io::Result<()> {
70 use std::io::Write;
71 self.stream.write_all(msg.as_bytes())?;
72 self.stream.write_all(b"\n")?;
73 self.stream.flush()?;
74 Ok(())
75 }
76
77 pub fn peer_addr(&self) -> std::io::Result<std::net::SocketAddr> {
78 self.stream.get_ref().peer_addr()
79 }
80}
81
82impl Read for TlsStream {
83 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
84 self.stream.read(buf)
85 }
86}
87
88impl Write for TlsStream {
89 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
90 self.stream.write(buf)
91 }
92
93 fn flush(&mut self) -> std::io::Result<()> {
94 self.stream.flush()
95 }
96}