@@ -73,9 +73,9 @@ int tcp_rpcc_default_execute (struct connection *c, int op, raw_message_t *raw)
7373 tvkprintf (net_connections, 3 , " rpcc_execute: fd=%d, op=%d, len=%d\n " , c->fd , op, raw->total_bytes );
7474 if (op == TL_RPC_PING && raw->total_bytes == 12 ) {
7575 c->last_response_time = precise_now;
76- static int Q[12 ];
76+ int Q[12 ];
7777 assert (rwm_fetch_data (raw, Q, 12 ) == 12 );
78- static int P[12 ];
78+ int P[12 ];
7979 P[0 ] = TL_RPC_PONG;
8080 P[1 ] = Q[1 ];
8181 P[2 ] = Q[2 ];
@@ -90,18 +90,24 @@ int tcp_rpcc_default_execute (struct connection *c, int op, raw_message_t *raw)
9090
9191static int tcp_rpcc_process_nonce_packet (struct connection *c, raw_message_t *msg) {
9292 struct tcp_rpc_data *D = TCP_RPC_DATA (c);
93- static struct tcp_rpc_nonce_packet P;
93+ struct tcp_rpc_nonce_packet P{} ;
9494 int res;
9595
9696 if (D->packet_num != -2 || D->packet_type != RPC_NONCE) {
9797 return -2 ;
9898 }
99- if (D->packet_len != sizeof (struct tcp_rpc_nonce_packet ) ) {
99+ if (D->packet_len < sizeof (P) || D-> packet_len >= 1024 ) {
100100 return -3 ;
101101 }
102+ int excess_data_size = D->packet_len - sizeof (P); // fields from newer protocol version
102103
103- assert (rwm_fetch_data (msg, &P, D->packet_len ) == D->packet_len );
104- tvkprintf (net_connections, 4 , " Processing nonce packet, crypto schema: %d, key select: %d\n " , P.crypto_schema , P.key_select );
104+ assert (rwm_fetch_data (msg, &P, sizeof (P)) == sizeof (P));
105+ assert (rwm_fetch_data (msg, 0 , excess_data_size) == excess_data_size);
106+ tvkprintf (net_connections, 4 , " Processing nonce packet, crypto schema: %d, version: %d, excess_data: %d, key select: %d\n " , P.crypto_schema , P.protocol_version , excess_data_size, P.key_select );
107+
108+ if (P.protocol_version > 1 ) { // server must not reply with version > client
109+ return -3 ;
110+ }
105111
106112 switch (P.crypto_schema ) {
107113 case RPC_CRYPTO_NONE:
@@ -127,7 +133,7 @@ static int tcp_rpcc_process_nonce_packet (struct connection *c, raw_message_t *m
127133 if (abs (P.crypto_ts - D->nonce_time ) > 30 ) {
128134 return -6 ; // less'om
129135 }
130- res = TCP_RPCC_FUNC (c)->rpc_start_crypto (c, P. crypto_nonce , P. key_select );
136+ res = TCP_RPCC_FUNC (c)->rpc_start_crypto (c, &P );
131137 if (res < 0 ) {
132138 return -6 ;
133139 }
@@ -142,14 +148,13 @@ static int tcp_rpcc_process_nonce_packet (struct connection *c, raw_message_t *m
142148static int tcp_rpcc_send_handshake_packet (struct connection *c) {
143149 tvkprintf (net_connections, 4 , " tcp_rpcc_send_handshake_packet\n " );
144150 struct tcp_rpc_data *D = TCP_RPC_DATA (c);
145- static struct tcp_rpc_handshake_packet P;
151+ struct tcp_rpc_handshake_packet P{} ;
146152 if (!PID.ip ) {
147153 init_client_PID (c->local_endpoint .ss_family == AF_INET ? inet_sockaddr_address (&c->local_endpoint ): 0 );
148154 if (!PID.ip ) {
149155 PID.ip = get_my_ipv4 ();
150156 }
151157 }
152- memset (&P, 0 , sizeof (P));
153158 P.type = RPC_HANDSHAKE;
154159 P.flags = default_rpc_flags & RPC_CRYPTO_USE_CRC32C;
155160 if (!D->remote_pid .port ) {
@@ -167,11 +172,10 @@ static int tcp_rpcc_send_handshake_packet (struct connection *c) {
167172}
168173
169174static int tcp_rpcc_send_handshake_error_packet (struct connection *c, int error_code) {
170- static struct tcp_rpc_handshake_error_packet P;
175+ struct tcp_rpc_handshake_error_packet P{} ;
171176 if (!PID.pid ) {
172177 init_client_PID (inet_sockaddr_address (&c->local_endpoint ));
173178 }
174- memset (&P, 0 , sizeof (P));
175179 P.type = RPC_HANDSHAKE_ERROR;
176180 P.error_code = error_code;
177181 memcpy (&P.sender_pid , &PID, sizeof (PID));
@@ -185,11 +189,11 @@ static int tcp_rpcc_process_handshake_packet (struct connection *c, raw_message_
185189 tvkprintf (net_connections, 4 , " tcp_rpcc_process_handshake_packet\n " );
186190
187191 struct tcp_rpc_data *D = TCP_RPC_DATA (c);
188- static struct tcp_rpc_handshake_packet P;
192+ struct tcp_rpc_handshake_packet P{} ;
189193 if (D->packet_num != -1 || D->packet_type != RPC_HANDSHAKE) {
190194 return -2 ;
191195 }
192- if (D->packet_len != sizeof (struct tcp_rpc_handshake_packet )) {
196+ if (D->packet_len != sizeof (P )) {
193197 tcp_rpcc_send_handshake_error_packet (c, -3 );
194198 return -3 ;
195199 }
@@ -227,17 +231,23 @@ int tcp_rpcc_parse_execute (struct connection *c) {
227231 int len;
228232
229233 while (true ) {
230- len = c->in .total_bytes ;
234+ len = c->in .total_bytes ;
231235 if (len <= 0 ) {
232236 break ;
233237 }
234238 if (!D->packet_len ) {
235- if (len < 4 ) {
239+ if (len < D-> packet_v1_padding + 4 ) {
236240 c->status = conn_reading_answer;
237- return 4 - len;
241+ return D->packet_v1_padding + 4 - len;
242+ }
243+ if (D->packet_v1_padding ) {
244+ assert (D->packet_v1_padding < 4 );
245+ assert (rwm_fetch_data (&c->in , 0 , D->packet_v1_padding ) == D->packet_v1_padding );
246+ D->packet_v1_padding = 0 ;
238247 }
239248 assert (rwm_fetch_lookup (&c->in , &D->packet_len , 4 ) == 4 );
240- if (D->packet_len <= 0 || (D->packet_len & 3 ) || (D->packet_len > TCP_RPCC_FUNC (c)->max_packet_len && TCP_RPCC_FUNC (c)->max_packet_len > 0 )) {
249+ // We skip checks for len&3 == 0 for protocol version 0, because there is little value in it.
250+ if (D->packet_len > TCP_RPCC_FUNC (c)->max_packet_len && TCP_RPCC_FUNC (c)->max_packet_len > 0 ) {
241251 tvkprintf (net_connections, 1 , " error while parsing packet: bad packet length %d\n " , D->packet_len );
242252 c->status = conn_error;
243253 c->error = -1 ;
@@ -259,7 +269,6 @@ int tcp_rpcc_parse_execute (struct connection *c) {
259269 c->status = conn_reading_answer;
260270 return D->packet_len - len;
261271 }
262-
263272
264273 raw_message_t msg;
265274 if (c->in .total_bytes == D->packet_len ) {
@@ -339,6 +348,9 @@ int tcp_rpcc_parse_execute (struct connection *c) {
339348 }
340349
341350 D->in_packet_num ++;
351+ if (c->crypto ) {
352+ D->packet_v1_padding = (-D->packet_len ) & 3 ;
353+ }
342354 D->packet_len = 0 ;
343355 if (c->status == conn_running) {
344356 c->status = conn_wait_answer;
@@ -421,10 +433,10 @@ int tcp_rpcc_init_fake_crypto (struct connection *c) {
421433 return -1 ;
422434 }
423435
424- static struct tcp_rpc_nonce_packet buf;
425- memset (&buf, 0 , sizeof (buf));
436+ struct tcp_rpc_nonce_packet buf{};
426437 buf.type = RPC_NONCE;
427438 buf.crypto_schema = RPC_CRYPTO_NONE;
439+ buf.protocol_version = 1 ; // ask for latest version we support
428440
429441 tcp_rpc_conn_send_data (c, sizeof (buf), &buf);
430442
@@ -477,13 +489,13 @@ int tcp_rpcc_init_crypto (struct connection *c) {
477489
478490 aes_generate_nonce (TCP_RPC_DATA (c)->nonce );
479491
480- static struct tcp_rpc_nonce_packet buf;
481- memset (&buf, 0 , sizeof (buf));
492+ struct tcp_rpc_nonce_packet buf{};
482493 memcpy (buf.crypto_nonce , TCP_RPC_DATA (c)->nonce , 16 );
483494 buf.crypto_ts = TCP_RPC_DATA (c)->nonce_time ;
484495 buf.type = RPC_NONCE;
485496 buf.key_select = get_crypto_key_id (default_aes_key);
486497 buf.crypto_schema = (TCP_RPC_DATA (c)->crypto_flags & RPC_CRYPTO_ALLOW_UNENCRYPTED) ? RPC_CRYPTO_NONE_OR_AES : RPC_CRYPTO_AES;
498+ buf.protocol_version = 1 ; // ask for latest version we support
487499
488500 tcp_rpc_conn_send_data (c, sizeof (buf), &buf);
489501
@@ -494,9 +506,9 @@ int tcp_rpcc_init_crypto (struct connection *c) {
494506 return 1 ;
495507}
496508
497- int tcp_rpcc_start_crypto (struct connection *c, char *nonce, int key_select ) {
509+ int tcp_rpcc_start_crypto (struct connection *c, struct tcp_rpc_nonce_packet *P ) {
498510 struct tcp_rpc_data *D = TCP_RPC_DATA (c);
499- tvkprintf (net_connections, 4 , " rpcc_start_crypto: key_select = %d\n " , key_select);
511+ tvkprintf (net_connections, 4 , " rpcc_start_crypto: key_select = %d\n " , P-> key_select );
500512
501513 if (c->crypto ) {
502514 return -1 ;
@@ -506,13 +518,13 @@ int tcp_rpcc_start_crypto (struct connection *c, char *nonce, int key_select) {
506518 return -1 ;
507519 }
508520
509- if (!key_select || key_select != get_crypto_key_id (default_aes_key)) {
521+ if (!P-> key_select || P-> key_select != get_crypto_key_id (default_aes_key)) {
510522 return -1 ;
511523 }
512524
513525 struct aes_session_key aes_keys;
514526
515- if (aes_create_connection_keys (default_aes_key, &aes_keys, 1 , nonce , D->nonce , D->nonce_time , c) < 0 ) {
527+ if (aes_create_connection_keys (P-> protocol_version , default_aes_key, &aes_keys, 1 , P-> crypto_nonce , D->nonce , P-> crypto_ts , D->nonce_time , c) < 0 ) {
516528 return -1 ;
517529 }
518530
@@ -529,7 +541,7 @@ void tcp_rpcc_flush_crypto (struct connection *c) {
529541 tvkprintf (net_connections, 4 , " rpcc_flush_packet: padding with %d bytes\n " , pad_bytes);
530542 if (pad_bytes > 0 ) {
531543 assert (!(pad_bytes & 3 ));
532- static int pad_str[3 ] = {4 , 4 , 4 };
544+ int pad_str[3 ] = {4 , 4 , 4 };
533545 assert (pad_bytes <= 12 );
534546 assert (rwm_push_data (&c->out , pad_str, pad_bytes) == pad_bytes);
535547 }
@@ -552,7 +564,7 @@ int tcp_rpcc_flush (struct connection *c) {
552564 tvkprintf (net_connections, 4 , " rpcs_flush: padding with %d bytes\n " , pad_bytes);
553565 if (pad_bytes > 0 ) {
554566 assert (!(pad_bytes & 3 ));
555- static int pad_str[3 ] = {4 , 4 , 4 };
567+ int pad_str[3 ] = {4 , 4 , 4 };
556568 assert (pad_bytes <= 12 );
557569 assert (rwm_push_data (&c->out , pad_str, pad_bytes) == pad_bytes);
558570 }
0 commit comments