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 */