commit b1af29b

shrub  ·  2026-08-16 09:34:53 +0000 UTC
parent ac731f2
make crypto conditional
5 files changed,  +77, -19
+1, -0
1@@ -50,6 +50,7 @@ typedef enum {
2 	MC_EC_CONNECTION_CLOSED,
3 	MC_EC_LOGIN_START,
4 	MC_EC_INVALID_ACCOUNT,
5+	MC_EC_CRYPTO_DISABLED,
6 
7 	MC_EC_LAST
8 } MCErrorCode;
+28, -7
 1@@ -1,6 +1,7 @@
 2 project(
 3     'Magnolia',
 4     'c',
 5+    meson_version: '>=1.1',
 6     default_options: [
 7         'c_std=c89',
 8         'warning_level=3',
 9@@ -10,9 +11,16 @@ project(
10 cc = meson.get_compiler('c')
11 math_dep = cc.find_library('m', required: false)
12 zlib_dep = dependency('zlib')
13-libtls_sp = subproject('libtls-bearssl', default_options: ['default_library=static'])
14-tls_dep = libtls_sp.get_variable('libtls_dep')
15-bearssl_dep = cc.find_library('bearssl')
16+crypto_enabled = get_option('crypto')
17+
18+if crypto_enabled
19+    libtls_sp = subproject('libtls-bearssl', default_options: ['default_library=static'])
20+    tls_dep = libtls_sp.get_variable('libtls_dep')
21+    bearssl_dep = cc.find_library('bearssl')
22+else
23+    tls_dep = declare_dependency()
24+    bearssl_dep = declare_dependency()
25+endif
26 
27 requested_renderer = get_option('renderer')
28 requested_window = get_option('windowing')
29@@ -64,7 +72,6 @@ message('Selected windowing: ' + window_backend)
30 
31 sources = [
32     'source/main.c',
33-    'source/mgrandom.c',
34     'source/config.c',
35     'source/util.c',
36     'source/world/block.c',
37@@ -72,16 +79,22 @@ sources = [
38     'source/client/camera.c',
39     'source/client/player.c',
40     'source/client/world.c',
41-    'source/net/mc_auth.c',
42     'source/net/mc_chunk.c',
43     'source/net/mc_buffer.c',
44     'source/net/mc_client.c',
45-    'source/net/mc_crypto.c',
46     'source/net/packet.c',
47     'vendor/stb_image_c89.c',
48     'vendor/json.c',
49 ]
50 
51+if crypto_enabled
52+    sources += [
53+        'source/mgrandom.c',
54+        'source/net/mc_auth.c',
55+        'source/net/mc_crypto.c',
56+    ]
57+endif
58+
59 include_dirs = [
60     include_directories('include', '/usr/local/include'),
61 ]
62@@ -172,6 +185,14 @@ renderer_dep = declare_dependency(
63 
64 deps = [platform_dep, zlib_dep, tls_dep, bearssl_dep, mgmath_dep, renderer_dep]
65 
66+crypto_c_args = []
67+if crypto_enabled
68+    crypto_c_args += ['-DMG_ENABLE_CRYPTO']
69+    message('crypto: on')
70+else
71+    message('crypto: off')
72+endif
73+
74 # illumos needs extra libraries before it links
75 if host_machine.system() == 'sunos'
76     extra_libs = ['-lsocket', '-lnsl']
77@@ -184,7 +205,7 @@ executable(
78     sources,
79     include_directories: include_dirs + vendor_inc,
80     dependencies: deps,
81-    c_args: platform_c_args + renderer_c_args,
82+    c_args: platform_c_args + renderer_c_args + crypto_c_args,
83     link_args: extra_libs,
84     override_options: ['c_std=c99'],
85 )
+7, -0
 1@@ -13,3 +13,10 @@ option(
 2     value: 'auto',
 3     description: 'Windowing backend',
 4 )
 5+
 6+option(
 7+    'crypto',
 8+    type: 'boolean',
 9+    value: false,
10+    description: 'Encryption and TLS for online-mode servers',
11+)
+27, -6
  1@@ -12,14 +12,19 @@
  2 #include <zlib.h>
  3 
  4 #include "mc_internal.h"
  5+
  6+#ifdef MG_ENABLE_CRYPTO
  7 #include "mgrandom.h"
  8+#endif
  9 
 10 #ifndef MSG_NOSIGNAL
 11 	#define MSG_NOSIGNAL 0
 12 #endif
 13 
 14+#ifdef MG_ENABLE_CRYPTO
 15 static i8 handle_encryption(MCClient* client, const MCAccount* account, MCPacket* packet, char* error,
 16                             size_t error_size);
 17+#endif
 18 static i8 login_loop(MCClient* client, const MCAccount* account, char* error, size_t error_size);
 19 static i8 send_handshake(MCClient* client);
 20 static i8 send_login_start(MCClient* client);
 21@@ -31,6 +36,7 @@ static i8 tcp_connect(MCClient* client, char* error, size_t error_size);
 22 
 23 /* handle server encryption request
 24    returns 1 on success, 0 on failure */
 25+#ifdef MG_ENABLE_CRYPTO
 26 static i8 handle_encryption(MCClient* client, const MCAccount* account, MCPacket* packet, char* error,
 27                             size_t error_size)
 28 {
 29@@ -91,11 +97,15 @@ cleanup:
 30 	free(encrypted_token);
 31 	return ok;
 32 }
 33+#endif
 34 
 35 /* process login packets until play state
 36    returns 1 on success, 0 on failure */
 37 static i8 login_loop(MCClient* client, const MCAccount* account, char* error, size_t error_size)
 38 {
 39+#ifndef MG_ENABLE_CRYPTO
 40+	(void)account;
 41+#endif
 42 	/* login state packet ids for protocol 47:
 43 	   0x00 disconnect
 44 	   0x01 encryption request
 45@@ -122,11 +132,18 @@ static i8 login_loop(MCClient* client, const MCAccount* account, char* error, si
 46 			return 0;
 47 		}
 48 		if (packet.id == 0x01) {
 49+#ifdef MG_ENABLE_CRYPTO
 50 			i8 ok = handle_encryption(client, account, &packet, error, error_size);
 51 			mc_packet_free(&packet);
 52 			if (!ok)
 53 				return 0;
 54 			continue;
 55+#else
 56+			mc_set_error(MC_EC_CRYPTO_DISABLED, error, error_size,
 57+			             "server is online-mode, i can't do that");
 58+			mc_packet_free(&packet);
 59+			return 0;
 60+#endif
 61 		}
 62 		if (packet.id == 0x02) {
 63 			char username[64];
 64@@ -205,8 +222,10 @@ static i8 socket_read(MCClient* client, u8* data, size_t size)
 65 			return 0;
 66 		}
 67 	}
 68+#ifdef MG_ENABLE_CRYPTO
 69 	if (client->encrypted)
 70 		mc_cipher_decrypt(&client->read_cipher, data, size);
 71+#endif
 72 	return 1;
 73 }
 74 
 75@@ -233,19 +252,21 @@ static i8 socket_read_varint(MCClient* client, i32* value)
 76    returns 1 on success, 0 on failure */
 77 static i8 socket_write(MCClient* client, const u8* data, size_t size)
 78 {
 79-	u8     encrypted[4096];
 80+	u8     output[4096];
 81 	size_t offset = 0;
 82 
 83 	while (offset < size) {
 84 		size_t chunk = size - offset;
 85 		size_t sent = 0;
 86-		if (chunk > sizeof(encrypted))
 87-			chunk = sizeof(encrypted);
 88-		memcpy(encrypted, data + offset, chunk);
 89+		if (chunk > sizeof(output))
 90+			chunk = sizeof(output);
 91+		memcpy(output, data + offset, chunk);
 92+#ifdef MG_ENABLE_CRYPTO
 93 		if (client->encrypted)
 94-			mc_cipher_encrypt(&client->write_cipher, encrypted, chunk);
 95+			mc_cipher_encrypt(&client->write_cipher, output, chunk);
 96+#endif
 97 		while (sent < chunk) {
 98-			ssize_t count = send(client->socket_fd, encrypted + sent, chunk - sent, MSG_NOSIGNAL);
 99+			ssize_t count = send(client->socket_fd, output + sent, chunk - sent, MSG_NOSIGNAL);
100 			if (count > 0) {
101 				sent += (size_t)count;
102 			}
+14, -6
 1@@ -3,7 +3,9 @@
 2 
 3 #include <stddef.h>
 4 
 5+#ifdef MG_ENABLE_CRYPTO
 6 #include <bearssl.h>
 7+#endif
 8 
 9 #include "net/mc_proto.h"
10 
11@@ -18,10 +20,12 @@ typedef struct {
12 	size_t cursor;
13 } MCBuffer;
14 
15+#ifdef MG_ENABLE_CRYPTO
16 typedef struct {
17 	br_aes_ct_cbcenc_keys key;
18 	u8                    state[16];
19 } MCCipher;
20+#endif
21 
22 struct MCClient {
23 	int      socket_fd;
24@@ -30,9 +34,11 @@ struct MCClient {
25 	char     username[17];
26 	char     uuid[37];
27 	i32      compression_threshold;
28+#ifdef MG_ENABLE_CRYPTO
29 	i8       encrypted;
30 	MCCipher read_cipher;
31 	MCCipher write_cipher;
32+#endif
33 };
34 
35 void mc_set_error(MCErrorCode code, char* error, size_t error_size, const char* fmt, ...);
36@@ -61,14 +67,16 @@ i8 bufread_varint(MCBuffer* buffer, i32* value);
37 i8 bufread_string(MCBuffer* buffer, char* value, size_t value_size);
38 i8 bufread_bytes(MCBuffer* buffer, const u8** value, size_t* size);
39 
40+#ifdef MG_ENABLE_CRYPTO
41 void mc_cipher_init(MCCipher* cipher, const u8 key[16]);
42 void mc_cipher_encrypt(MCCipher* cipher, u8* data, size_t size);
43 void mc_cipher_decrypt(MCCipher* cipher, u8* data, size_t size);
44-i8 mc_rsa_encrypt(const u8* public_key, size_t public_key_size, const u8* message, size_t message_size, u8** encrypted,
45-                  size_t* encrypted_size, char* error, size_t error_size);
46-void mc_server_hash(const char* server_id, const u8 shared_secret[16], const u8* public_key, size_t public_key_size,
47-                    char output[42]);
48-i8   mc_join_server(const MCAccount* account, const char* server_id, const u8 shared_secret[16], const u8* public_key,
49-                    size_t public_key_size, char* error, size_t error_size);
50+i8 mc_rsa_encrypt(const u8* public_key, size_t public_key_size, const u8* message, size_t message_size,
51+                  u8** encrypted, size_t* encrypted_size, char* error, size_t error_size);
52+void mc_server_hash(const char* server_id, const u8 shared_secret[16], const u8* public_key,
53+                    size_t public_key_size, char output[42]);
54+i8 mc_join_server(const MCAccount* account, const char* server_id, const u8 shared_secret[16],
55+                  const u8* public_key, size_t public_key_size, char* error, size_t error_size);
56+#endif
57 
58 #endif /* MC_PROTO_INTERNAL_H */