diff options
author | Andrew Cady <d@jerkface.net> | 2020-08-21 12:47:29 -0400 |
---|---|---|
committer | Andrew Cady <d@jerkface.net> | 2020-08-21 12:47:29 -0400 |
commit | f2153aebaacc67e59311738f74f5b6f3b76347cf (patch) | |
tree | 0db6d671bef6737e8271c86ba2084757ea6738bd | |
parent | 127d2c239bb4c8d156154c5fb87e082ef22ed5a4 (diff) |
represent program mode as a single enum
-rw-r--r-- | client.c | 87 | ||||
-rw-r--r-- | main.c | 163 | ||||
-rw-r--r-- | main.h | 20 |
3 files changed, 127 insertions, 143 deletions
@@ -35,7 +35,7 @@ int handle_pong_frame() | |||
35 | 35 | ||
36 | log_printf(L_INFO, "GOT PONG! Time = %.3fs\n", secs2-secs1); | 36 | log_printf(L_INFO, "GOT PONG! Time = %.3fs\n", secs2-secs1); |
37 | 37 | ||
38 | if(ping_mode) | 38 | if(program_mode == Mode_Client_Ping) |
39 | { | 39 | { |
40 | state = CLIENT_STATE_SHUTDOWN; | 40 | state = CLIENT_STATE_SHUTDOWN; |
41 | } | 41 | } |
@@ -116,12 +116,24 @@ int local_bind() | |||
116 | return 0; | 116 | return 0; |
117 | } | 117 | } |
118 | 118 | ||
119 | bool tunnel_client_mode() | ||
120 | { | ||
121 | switch (program_mode) { | ||
122 | case Mode_Client_Local_Port_Forward: | ||
123 | case Mode_Client_Pipe: | ||
124 | return true; | ||
125 | case Mode_Client_Ping: | ||
126 | default: | ||
127 | return false; | ||
128 | } | ||
129 | } | ||
130 | |||
119 | /* Bind the client.sockfd to a tunnel */ | 131 | /* Bind the client.sockfd to a tunnel */ |
120 | int handle_acktunnel_frame(protocol_frame *rcvd_frame) | 132 | int handle_acktunnel_frame(protocol_frame *rcvd_frame) |
121 | { | 133 | { |
122 | tunnel *tun; | 134 | tunnel *tun; |
123 | 135 | ||
124 | if(!client_mode) | 136 | if(!tunnel_client_mode()) |
125 | { | 137 | { |
126 | log_printf(L_WARNING, "Got ACK tunnel frame when not in client mode!?\n"); | 138 | log_printf(L_WARNING, "Got ACK tunnel frame when not in client mode!?\n"); |
127 | return -1; | 139 | return -1; |
@@ -136,23 +148,12 @@ int handle_acktunnel_frame(protocol_frame *rcvd_frame) | |||
136 | /* Mark that we can accept() another connection */ | 148 | /* Mark that we can accept() another connection */ |
137 | client_tunnel.sockfd = -1; | 149 | client_tunnel.sockfd = -1; |
138 | 150 | ||
139 | // printf("New tunnel ID: %d\n", tun->connid); | 151 | update_select_nfds(tun->sockfd); |
140 | 152 | FD_SET(tun->sockfd, &client_master_fdset); | |
141 | if(client_local_port_mode || client_pipe_mode) | 153 | if(program_mode == Mode_Client_Local_Port_Forward) |
142 | { | 154 | { |
143 | update_select_nfds(tun->sockfd); | 155 | log_printf(L_INFO, "Accepted a new connection on port %d\n", local_port); |
144 | FD_SET(tun->sockfd, &client_master_fdset); | ||
145 | if(client_local_port_mode) | ||
146 | { | ||
147 | log_printf(L_INFO, "Accepted a new connection on port %d\n", local_port); | ||
148 | } | ||
149 | } | 156 | } |
150 | else | ||
151 | { | ||
152 | log_printf(L_ERROR, "This tunnel mode is not supported yet\n"); | ||
153 | exit(1); | ||
154 | } | ||
155 | |||
156 | return 0; | 157 | return 0; |
157 | } | 158 | } |
158 | 159 | ||
@@ -175,25 +176,18 @@ int handle_server_tcp_frame(protocol_frame *rcvd_frame) | |||
175 | { | 176 | { |
176 | int sent_bytes; | 177 | int sent_bytes; |
177 | 178 | ||
178 | if(client_pipe_mode) | 179 | switch (program_mode) { |
179 | { | 180 | case Mode_Client_Pipe: |
180 | sent_bytes = write( | 181 | sent_bytes = write(1, rcvd_frame->data + offset, rcvd_frame->data_length - offset); |
181 | 1, /* STDOUT */ | 182 | break; |
182 | rcvd_frame->data + offset, | 183 | case Mode_Client_Local_Port_Forward: |
183 | rcvd_frame->data_length - offset | 184 | sent_bytes = send(tun->sockfd, rcvd_frame->data + offset, rcvd_frame->data_length - offset, MSG_NOSIGNAL); |
184 | ); | 185 | break; |
185 | } | 186 | default: |
186 | else | 187 | log_printf(L_ERROR, "BUG: Impossible client mode at %s:%s", __FILE__, __LINE__); |
187 | { | 188 | return -1; |
188 | sent_bytes = send( | ||
189 | tun->sockfd, | ||
190 | rcvd_frame->data + offset, | ||
191 | rcvd_frame->data_length - offset, | ||
192 | MSG_NOSIGNAL | ||
193 | ); | ||
194 | } | 189 | } |
195 | 190 | ||
196 | |||
197 | if(sent_bytes < 0) | 191 | if(sent_bytes < 0) |
198 | { | 192 | { |
199 | uint8_t data[PROTOCOL_BUFFER_OFFSET]; | 193 | uint8_t data[PROTOCOL_BUFFER_OFFSET]; |
@@ -296,7 +290,7 @@ int do_client_loop(uint8_t *tox_id_str) | |||
296 | exit(1); | 290 | exit(1); |
297 | } | 291 | } |
298 | 292 | ||
299 | if(!ping_mode && !client_pipe_mode) | 293 | if(program_mode == Mode_Client_Local_Port_Forward) |
300 | { | 294 | { |
301 | local_bind(); | 295 | local_bind(); |
302 | signal(SIGPIPE, SIG_IGN); | 296 | signal(SIGPIPE, SIG_IGN); |
@@ -400,17 +394,19 @@ int do_client_loop(uint8_t *tox_id_str) | |||
400 | break; | 394 | break; |
401 | } | 395 | } |
402 | case CLIENT_STATE_REQUEST_ACCEPTED: | 396 | case CLIENT_STATE_REQUEST_ACCEPTED: |
403 | if(ping_mode) | 397 | switch (program_mode) { |
404 | { | 398 | case Mode_Client_Ping: |
405 | state = CLIENT_STATE_SEND_PING; | 399 | state = CLIENT_STATE_SEND_PING; |
406 | } | 400 | break; |
407 | else if(client_pipe_mode) | 401 | case Mode_Client_Pipe: |
408 | { | ||
409 | state = CLIENT_STATE_SETUP_PIPE; | 402 | state = CLIENT_STATE_SETUP_PIPE; |
410 | } | 403 | break; |
411 | else | 404 | case Mode_Client_Local_Port_Forward: |
412 | { | ||
413 | state = CLIENT_STATE_BIND_PORT; | 405 | state = CLIENT_STATE_BIND_PORT; |
406 | break; | ||
407 | default: | ||
408 | log_printf(L_ERROR, "BUG: Impossible client mode at %s:%s", __FILE__, __LINE__); | ||
409 | exit(1); | ||
414 | } | 410 | } |
415 | break; | 411 | break; |
416 | case CLIENT_STATE_SEND_PING: | 412 | case CLIENT_STATE_SEND_PING: |
@@ -490,8 +486,7 @@ int do_client_loop(uint8_t *tox_id_str) | |||
490 | fds = client_master_fdset; | 486 | fds = client_master_fdset; |
491 | 487 | ||
492 | /* Handle accepting new connections */ | 488 | /* Handle accepting new connections */ |
493 | if(!client_pipe_mode && | 489 | if(program_mode != Mode_Client_Ping && client_tunnel.sockfd <= 0) /* Don't accept if we're already waiting to establish a tunnel */ |
494 | client_tunnel.sockfd <= 0) /* Don't accept if we're already waiting to establish a tunnel */ | ||
495 | { | 490 | { |
496 | accept_fd = accept(bind_sockfd, NULL, NULL); | 491 | accept_fd = accept(bind_sockfd, NULL, NULL); |
497 | if(accept_fd != -1) | 492 | if(accept_fd != -1) |
@@ -529,7 +524,7 @@ int do_client_loop(uint8_t *tox_id_str) | |||
529 | if(FD_ISSET(tun->sockfd, &fds)) | 524 | if(FD_ISSET(tun->sockfd, &fds)) |
530 | { | 525 | { |
531 | int nbytes; | 526 | int nbytes; |
532 | if(client_local_port_mode) | 527 | if(program_mode == Mode_Client_Local_Port_Forward) |
533 | { | 528 | { |
534 | nbytes = recv(tun->sockfd, | 529 | nbytes = recv(tun->sockfd, |
535 | tox_packet_buf + PROTOCOL_BUFFER_OFFSET, | 530 | tox_packet_buf + PROTOCOL_BUFFER_OFFSET, |
@@ -3,6 +3,8 @@ | |||
3 | #include "tox_bootstrap.h" | 3 | #include "tox_bootstrap.h" |
4 | #include "log.h" | 4 | #include "log.h" |
5 | 5 | ||
6 | #define LOG_IP_ADDRESS | ||
7 | |||
6 | #ifdef __MACH__ | 8 | #ifdef __MACH__ |
7 | #include "mach.h" | 9 | #include "mach.h" |
8 | #endif | 10 | #endif |
@@ -14,19 +16,12 @@ TOX_CONNECTION connection_status = TOX_CONNECTION_NONE; | |||
14 | TOX_CONNECTION friend_connection_status = TOX_CONNECTION_NONE; | 16 | TOX_CONNECTION friend_connection_status = TOX_CONNECTION_NONE; |
15 | /** CONFIGURATION OPTIONS **/ | 17 | /** CONFIGURATION OPTIONS **/ |
16 | /* Whether we're a client */ | 18 | /* Whether we're a client */ |
17 | int client_mode = 0; | 19 | |
18 | 20 | ||
19 | /* Don't bootstrap nodes */ | 21 | /* Don't bootstrap nodes */ |
20 | int skip_bootstrap = 1; | 22 | int skip_bootstrap = 1; |
21 | 23 | ||
22 | /* Just send a ping and exit */ | 24 | enum Mode program_mode = Mode_Unspecified; |
23 | int ping_mode = 0; | ||
24 | |||
25 | /* Open a local port and forward it */ | ||
26 | int client_local_port_mode = 0; | ||
27 | |||
28 | /* Forward stdin/stdout to remote machine - SSH ProxyCommand mode */ | ||
29 | int client_pipe_mode = 0; | ||
30 | 25 | ||
31 | /* Remote Tox ID in client mode */ | 26 | /* Remote Tox ID in client mode */ |
32 | uint8_t *remote_tox_id = NULL; | 27 | uint8_t *remote_tox_id = NULL; |
@@ -39,7 +34,7 @@ long int udp_start_port = 0; | |||
39 | long int udp_end_port = 0; | 34 | long int udp_end_port = 0; |
40 | 35 | ||
41 | /* Directory with config and tox save */ | 36 | /* Directory with config and tox save */ |
42 | char config_path[500] = "/etc/tuntox/"; | 37 | char *config_path = "/etc/tuntox/"; |
43 | 38 | ||
44 | /* Limit hostname and port in server */ | 39 | /* Limit hostname and port in server */ |
45 | int tunnel_target_whitelist_size = 0; | 40 | int tunnel_target_whitelist_size = 0; |
@@ -68,7 +63,7 @@ char shared_secret[TOX_MAX_FRIEND_REQUEST_LENGTH]; | |||
68 | int server_whitelist_mode = 0; | 63 | int server_whitelist_mode = 0; |
69 | allowed_toxid *allowed_toxids = NULL; | 64 | allowed_toxid *allowed_toxids = NULL; |
70 | 65 | ||
71 | int load_saved_toxid_in_client_mode = 0; | 66 | bool config_path_modified = false; |
72 | 67 | ||
73 | fd_set master_server_fds; | 68 | fd_set master_server_fds; |
74 | 69 | ||
@@ -452,9 +447,9 @@ int handle_request_tunnel_frame(protocol_frame *rcvd_frame) | |||
452 | int sockfd = 0; | 447 | int sockfd = 0; |
453 | uint16_t tunnel_id; | 448 | uint16_t tunnel_id; |
454 | 449 | ||
455 | if(client_mode) | 450 | if(program_mode != Mode_Server) |
456 | { | 451 | { |
457 | log_printf(L_WARNING, "Got tunnel request frame from friend #%d when in client mode\n", rcvd_frame->friendnumber); | 452 | log_printf(L_WARNING, "Got tunnel request frame from friend #%d but not in server mode\n", rcvd_frame->friendnumber); |
458 | return -1; | 453 | return -1; |
459 | } | 454 | } |
460 | 455 | ||
@@ -592,15 +587,9 @@ int handle_frame(protocol_frame *frame) | |||
592 | return handle_pong_frame(frame); | 587 | return handle_pong_frame(frame); |
593 | break; | 588 | break; |
594 | case PACKET_TYPE_TCP: | 589 | case PACKET_TYPE_TCP: |
595 | if(client_mode) | 590 | return program_mode != Mode_Server |
596 | { | 591 | ? handle_server_tcp_frame(frame) |
597 | return handle_server_tcp_frame(frame); | 592 | : handle_client_tcp_frame(frame); |
598 | } | ||
599 | else | ||
600 | { | ||
601 | return handle_client_tcp_frame(frame); | ||
602 | } | ||
603 | break; | ||
604 | case PACKET_TYPE_REQUESTTUNNEL: | 593 | case PACKET_TYPE_REQUESTTUNNEL: |
605 | handle_request_tunnel_frame(frame); | 594 | handle_request_tunnel_frame(frame); |
606 | break; | 595 | break; |
@@ -608,15 +597,9 @@ int handle_frame(protocol_frame *frame) | |||
608 | handle_acktunnel_frame(frame); | 597 | handle_acktunnel_frame(frame); |
609 | break; | 598 | break; |
610 | case PACKET_TYPE_TCP_FIN: | 599 | case PACKET_TYPE_TCP_FIN: |
611 | if(client_mode) | 600 | return program_mode != Mode_Server |
612 | { | 601 | ? handle_server_tcp_fin_frame(frame) |
613 | return handle_server_tcp_fin_frame(frame); | 602 | : handle_client_tcp_fin_frame(frame); |
614 | } | ||
615 | else | ||
616 | { | ||
617 | return handle_client_tcp_fin_frame(frame); | ||
618 | } | ||
619 | break; | ||
620 | default: | 603 | default: |
621 | log_printf(L_DEBUG, "Got unknown packet type 0x%x from friend %d\n", | 604 | log_printf(L_DEBUG, "Got unknown packet type 0x%x from friend %d\n", |
622 | frame->packet_type, | 605 | frame->packet_type, |
@@ -672,14 +655,16 @@ void parse_lossless_packet(Tox *tox, uint32_t friendnumber, const uint8_t *data, | |||
672 | 655 | ||
673 | if(len < (size_t)frame->data_length + PROTOCOL_BUFFER_OFFSET) | 656 | if(len < (size_t)frame->data_length + PROTOCOL_BUFFER_OFFSET) |
674 | { | 657 | { |
675 | log_printf(L_WARNING, "Received frame too small (attempted buffer overflow?): %d bytes, excepted at least %d bytes\n", len, frame->data_length + PROTOCOL_BUFFER_OFFSET); | 658 | log_printf(L_WARNING, "Received frame too small (attempted buffer overflow?): %d bytes, excepted at least %d bytes\n", |
659 | len, frame->data_length + PROTOCOL_BUFFER_OFFSET); | ||
676 | free(frame); | 660 | free(frame); |
677 | return; | 661 | return; |
678 | } | 662 | } |
679 | 663 | ||
680 | if(frame->data_length > (TOX_MAX_CUSTOM_PACKET_SIZE - PROTOCOL_BUFFER_OFFSET)) | 664 | if(frame->data_length > (TOX_MAX_CUSTOM_PACKET_SIZE - PROTOCOL_BUFFER_OFFSET)) |
681 | { | 665 | { |
682 | log_printf(L_WARNING, "Declared data length too big (attempted buffer overflow?): %d bytes, excepted at most %d bytes\n", frame->data_length, (TOX_MAX_CUSTOM_PACKET_SIZE - PROTOCOL_BUFFER_OFFSET)); | 666 | log_printf(L_WARNING, "Declared data length too big (attempted buffer overflow?): %d bytes, excepted at most %d bytes\n", |
667 | frame->data_length, (TOX_MAX_CUSTOM_PACKET_SIZE - PROTOCOL_BUFFER_OFFSET)); | ||
683 | free(frame); | 668 | free(frame); |
684 | return; | 669 | return; |
685 | } | 670 | } |
@@ -772,12 +757,13 @@ static size_t load_save(uint8_t **out_data) | |||
772 | { | 757 | { |
773 | void *data; | 758 | void *data; |
774 | uint32_t size; | 759 | uint32_t size; |
775 | uint8_t path_real[512], *p; | 760 | uint8_t path_real[PATH_MAX], *p; |
776 | 761 | ||
777 | strncpy((char *)path_real, config_path, sizeof(path_real)); | 762 | strncpy((char *)path_real, config_path, sizeof(path_real)); |
778 | 763 | ||
779 | p = path_real + strlen((char *)path_real); | 764 | p = path_real + strlen((char *)path_real); |
780 | memcpy(p, "tox_save", sizeof("tox_save")); | 765 | char basename[] = "/tox_save"; |
766 | memcpy(p, "/tox_save", sizeof(basename)); | ||
781 | 767 | ||
782 | data = file_raw((char *)path_real, &size); | 768 | data = file_raw((char *)path_real, &size); |
783 | 769 | ||
@@ -857,7 +843,7 @@ void tunnel_target_whitelist_load() | |||
857 | } | 843 | } |
858 | fclose(file); | 844 | fclose(file); |
859 | 845 | ||
860 | log_printf(L_INFO, "Loaded %d rules\n", tunnel_target_whitelist_size); | 846 | log_printf(L_INFO, "Loaded %d rule%s\n", tunnel_target_whitelist_size, tunnel_target_whitelist_size == 1 ? "" : "s"); |
861 | if (tunnel_target_whitelist_size == 0 && tunnel_target_whitelist_enforced){ | 847 | if (tunnel_target_whitelist_size == 0 && tunnel_target_whitelist_enforced){ |
862 | log_printf(L_WARNING, "No rules loaded! NO CONNECTIONS WILL BE ALLOWED!\n"); | 848 | log_printf(L_WARNING, "No rules loaded! NO CONNECTIONS WILL BE ALLOWED!\n"); |
863 | } | 849 | } |
@@ -969,7 +955,7 @@ void handle_friend_connection_status(Tox *tox, uint32_t friend_number, TOX_CONNE | |||
969 | if(connection_status == TOX_CONNECTION_UDP) | 955 | if(connection_status == TOX_CONNECTION_UDP) |
970 | log_friend_ip_address(tox, friend_number); | 956 | log_friend_ip_address(tox, friend_number); |
971 | #endif | 957 | #endif |
972 | if(client_mode) | 958 | if(program_mode != Mode_Server) |
973 | { | 959 | { |
974 | friend_connection_status = connection_status; | 960 | friend_connection_status = connection_status; |
975 | } | 961 | } |
@@ -1306,29 +1292,22 @@ int main(int argc, char *argv[]) | |||
1306 | 1292 | ||
1307 | log_init(); | 1293 | log_init(); |
1308 | 1294 | ||
1309 | while ((oc = getopt(argc, argv, "L:pi:C:s:f:W:dqhSF:DU:t:u:")) != -1) | 1295 | while ((oc = getopt(argc, argv, "L:pi:C:s:f:W:vdqhSF:DU:t:u:")) != -1) |
1310 | { | 1296 | { |
1311 | switch(oc) | 1297 | switch(oc) |
1312 | { | 1298 | { |
1313 | case 'L': | 1299 | case 'L': |
1314 | /* Local port forwarding */ | 1300 | /* Local port forwarding */ |
1315 | client_mode = 1; | 1301 | program_mode = Mode_Client_Local_Port_Forward; |
1316 | client_local_port_mode = 1; | ||
1317 | if(!parse_local_port_forward(optarg, &local_port, &remote_host, &remote_port)) | 1302 | if(!parse_local_port_forward(optarg, &local_port, &remote_host, &remote_port)) |
1318 | { | 1303 | { |
1319 | log_printf(L_ERROR, "Invalid value for -L option - use something like -L 22:127.0.0.1:22\n"); | 1304 | log_printf(L_ERROR, "Invalid value for -L option - use something like -L 22:127.0.0.1:22\n"); |
1320 | exit(1); | 1305 | exit(1); |
1321 | } | 1306 | } |
1322 | if(min_log_level == L_UNSET) | ||
1323 | { | ||
1324 | min_log_level = L_INFO; | ||
1325 | } | ||
1326 | log_printf(L_DEBUG, "Forwarding remote port %d to local port %d\n", remote_port, local_port); | ||
1327 | break; | 1307 | break; |
1328 | case 'W': | 1308 | case 'W': |
1329 | /* Pipe forwarding */ | 1309 | /* Pipe forwarding */ |
1330 | client_mode = 1; | 1310 | program_mode = Mode_Client_Pipe; |
1331 | client_pipe_mode = 1; | ||
1332 | if(!parse_pipe_port_forward(optarg, &remote_host, &remote_port) || remote_port == 0) | 1311 | if(!parse_pipe_port_forward(optarg, &remote_host, &remote_port) || remote_port == 0) |
1333 | { | 1312 | { |
1334 | log_printf(L_ERROR, "Invalid value for -W option - use something like -W 127.0.0.1:22\n"); | 1313 | log_printf(L_ERROR, "Invalid value for -W option - use something like -W 127.0.0.1:22\n"); |
@@ -1338,12 +1317,10 @@ int main(int argc, char *argv[]) | |||
1338 | { | 1317 | { |
1339 | min_log_level = L_ERROR; | 1318 | min_log_level = L_ERROR; |
1340 | } | 1319 | } |
1341 | log_printf(L_INFO, "Forwarding remote port %d to stdin/out\n", remote_port); | ||
1342 | break; | 1320 | break; |
1343 | case 'p': | 1321 | case 'p': |
1344 | /* Ping */ | 1322 | /* Ping */ |
1345 | client_mode = 1; | 1323 | program_mode = Mode_Client_Ping; |
1346 | ping_mode = 1; | ||
1347 | if(min_log_level == L_UNSET) | 1324 | if(min_log_level == L_UNSET) |
1348 | { | 1325 | { |
1349 | min_log_level = L_INFO; | 1326 | min_log_level = L_INFO; |
@@ -1368,20 +1345,12 @@ int main(int argc, char *argv[]) | |||
1368 | break; | 1345 | break; |
1369 | case 'C': | 1346 | case 'C': |
1370 | /* Config directory */ | 1347 | /* Config directory */ |
1371 | strncpy(config_path, optarg, sizeof(config_path) - 1); | 1348 | config_path = strdup(optarg); |
1372 | if(optarg[strlen(optarg) - 1] != '/') | 1349 | config_path_modified = 1; |
1373 | { | ||
1374 | int optarg_len = strlen(optarg); | ||
1375 | |||
1376 | config_path[optarg_len] = '/'; | ||
1377 | config_path[optarg_len + 1] = '\0'; | ||
1378 | } | ||
1379 | load_saved_toxid_in_client_mode = 1; | ||
1380 | break; | 1350 | break; |
1381 | case 'f': | 1351 | case 'f': |
1382 | tunnel_target_whitelist_file = strdup(optarg); | 1352 | tunnel_target_whitelist_file = strdup(optarg); |
1383 | tunnel_target_whitelist_enforced = true; | 1353 | tunnel_target_whitelist_enforced = true; |
1384 | log_printf(L_INFO, "Whitelist enforced on outgoing connections: only matched hosts/ports will be allowed.\n"); | ||
1385 | break; | 1354 | break; |
1386 | case 's': | 1355 | case 's': |
1387 | /* Shared secret */ | 1356 | /* Shared secret */ |
@@ -1389,6 +1358,7 @@ int main(int argc, char *argv[]) | |||
1389 | memset(shared_secret, 0, TOX_MAX_FRIEND_REQUEST_LENGTH); | 1358 | memset(shared_secret, 0, TOX_MAX_FRIEND_REQUEST_LENGTH); |
1390 | strncpy(shared_secret, optarg, TOX_MAX_FRIEND_REQUEST_LENGTH-1); | 1359 | strncpy(shared_secret, optarg, TOX_MAX_FRIEND_REQUEST_LENGTH-1); |
1391 | break; | 1360 | break; |
1361 | case 'v': | ||
1392 | case 'd': | 1362 | case 'd': |
1393 | switch(++verbosity) | 1363 | switch(++verbosity) |
1394 | { | 1364 | { |
@@ -1425,8 +1395,8 @@ int main(int argc, char *argv[]) | |||
1425 | tcp_relay_port = strtol(optarg, NULL, 10); | 1395 | tcp_relay_port = strtol(optarg, NULL, 10); |
1426 | if(errno != 0 || tcp_relay_port < 0 || tcp_relay_port > 65535) | 1396 | if(errno != 0 || tcp_relay_port < 0 || tcp_relay_port > 65535) |
1427 | { | 1397 | { |
1428 | tcp_relay_port = 1024 + (rand() % 64511); | 1398 | tcp_relay_port = 1024 + (rand() % 64511); |
1429 | log_printf(L_WARNING, "Ignored -t %s: TCP port number needs to be a number between 0 and 65535."); | 1399 | log_printf(L_WARNING, "Ignored -t %s: TCP port number needs to be a number between 0 and 65535."); |
1430 | } | 1400 | } |
1431 | break; | 1401 | break; |
1432 | case 'u': | 1402 | case 'u': |
@@ -1465,25 +1435,44 @@ int main(int argc, char *argv[]) | |||
1465 | } | 1435 | } |
1466 | } | 1436 | } |
1467 | 1437 | ||
1468 | if(!client_mode && min_log_level == L_UNSET) | 1438 | switch (program_mode) { |
1469 | { | 1439 | case Mode_Client_Local_Port_Forward: |
1470 | min_log_level = L_INFO; | 1440 | case Mode_Client_Pipe: |
1471 | } | 1441 | case Mode_Client_Ping: |
1472 | 1442 | if(!remote_tox_id) | |
1473 | if(client_mode && !remote_tox_id) | 1443 | { |
1474 | { | 1444 | log_printf(L_ERROR, "Tox id is required in client mode. Use -i 58435984ABCDEF475...\n"); |
1475 | log_printf(L_ERROR, "Tox id is required in client mode. Use -i 58435984ABCDEF475...\n"); | 1445 | exit(1); |
1476 | exit(1); | 1446 | } |
1477 | } | 1447 | break; |
1478 | 1448 | case Mode_Unspecified: | |
1479 | if(!client_mode && server_whitelist_mode) | 1449 | program_mode = Mode_Server; |
1480 | { | 1450 | case Mode_Server: |
1481 | log_printf(L_INFO, "Server in ToxID whitelisting mode - only clients listed with -i can connect"); | 1451 | break; |
1482 | } | 1452 | } |
1483 | 1453 | ||
1484 | if(!client_mode && tunnel_target_whitelist_enforced) | 1454 | switch (program_mode) { |
1485 | { | 1455 | case Mode_Client_Local_Port_Forward: |
1486 | tunnel_target_whitelist_load(); | 1456 | log_printf(L_DEBUG, "Forwarding remote port %d to local port %d\n", remote_port, local_port); |
1457 | break; | ||
1458 | case Mode_Client_Pipe: | ||
1459 | log_printf(L_INFO, "Forwarding remote port %d to stdin/out\n", remote_port); | ||
1460 | break; | ||
1461 | case Mode_Server: | ||
1462 | if(min_log_level == L_UNSET) | ||
1463 | { | ||
1464 | min_log_level = L_INFO; | ||
1465 | } | ||
1466 | if(tunnel_target_whitelist_enforced) | ||
1467 | { | ||
1468 | log_printf(L_INFO, "Whitelist enforced on outgoing connections: only matched hosts/ports will be allowed.\n"); | ||
1469 | tunnel_target_whitelist_load(); | ||
1470 | } | ||
1471 | if(server_whitelist_mode) | ||
1472 | { | ||
1473 | log_printf(L_INFO, "Server in ToxID whitelisting mode - only clients listed with -i can connect"); | ||
1474 | } | ||
1475 | default:; | ||
1487 | } | 1476 | } |
1488 | 1477 | ||
1489 | /* If shared secret has not been provided via -s, read from TUNTOX_SHARED_SECRET env variable */ | 1478 | /* If shared secret has not been provided via -s, read from TUNTOX_SHARED_SECRET env variable */ |
@@ -1525,7 +1514,7 @@ int main(int argc, char *argv[]) | |||
1525 | tox_options.end_port | 1514 | tox_options.end_port |
1526 | ); | 1515 | ); |
1527 | 1516 | ||
1528 | if((!client_mode) || load_saved_toxid_in_client_mode) | 1517 | if(program_mode == Mode_Server || config_path_modified) |
1529 | { | 1518 | { |
1530 | save_size = load_save(&save_data); | 1519 | save_size = load_save(&save_data); |
1531 | if(save_data && save_size) | 1520 | if(save_data && save_size) |
@@ -1564,10 +1553,10 @@ int main(int argc, char *argv[]) | |||
1564 | tox_callback_self_connection_status(tox, handle_connection_status_change); | 1553 | tox_callback_self_connection_status(tox, handle_connection_status_change); |
1565 | tox_callback_friend_connection_status(tox, handle_friend_connection_status); | 1554 | tox_callback_friend_connection_status(tox, handle_friend_connection_status); |
1566 | 1555 | ||
1567 | if (!skip_bootstrap) | 1556 | if(!skip_bootstrap) |
1568 | do_bootstrap(tox); | 1557 | do_bootstrap(tox); |
1569 | 1558 | ||
1570 | if((!client_mode) || load_saved_toxid_in_client_mode) | 1559 | if(program_mode == Mode_Server || config_path_modified) |
1571 | { | 1560 | { |
1572 | write_save(tox); | 1561 | write_save(tox); |
1573 | } | 1562 | } |
@@ -1591,16 +1580,14 @@ int main(int argc, char *argv[]) | |||
1591 | to_hex(readable_dht_key, dht_key, TOX_PUBLIC_KEY_SIZE); | 1580 | to_hex(readable_dht_key, dht_key, TOX_PUBLIC_KEY_SIZE); |
1592 | log_printf(L_DEBUG, "DHT key: %s\n", readable_dht_key); | 1581 | log_printf(L_DEBUG, "DHT key: %s\n", readable_dht_key); |
1593 | 1582 | ||
1594 | if (client_mode) | 1583 | if (program_mode == Mode_Server) |
1595 | { | 1584 | { |
1596 | do_client_loop(remote_tox_id); | 1585 | tox_callback_friend_request(tox, accept_friend_request); |
1586 | return do_server_loop(); | ||
1597 | } | 1587 | } |
1598 | else | 1588 | else |
1599 | { | 1589 | { |
1600 | tox_callback_friend_request(tox, accept_friend_request); | 1590 | return do_client_loop(remote_tox_id); |
1601 | do_server_loop(); | ||
1602 | } | 1591 | } |
1603 | } | 1592 | } |
1604 | |||
1605 | return 0; | ||
1606 | } | 1593 | } |
@@ -80,26 +80,28 @@ typedef struct protocol_frame_t { | |||
80 | } protocol_frame; | 80 | } protocol_frame; |
81 | 81 | ||
82 | /* Rules policy */ | 82 | /* Rules policy */ |
83 | enum rules_policy_enum { VALIDATE, NONE }; | ||
84 | typedef struct rule { | 83 | typedef struct rule { |
85 | uint16_t port; | 84 | uint16_t port; |
86 | char * host; | 85 | char * host; |
87 | struct rule *next; | 86 | struct rule *next; |
88 | } rule; | 87 | } rule; |
89 | 88 | ||
89 | enum Mode { | ||
90 | Mode_Unspecified, | ||
91 | Mode_Server, | ||
92 | Mode_Client_Local_Port_Forward, | ||
93 | Mode_Client_Pipe, | ||
94 | Mode_Client_Ping | ||
95 | }; | ||
96 | |||
90 | /**** GLOBAL VARIABLES ****/ | 97 | /**** GLOBAL VARIABLES ****/ |
91 | extern Tox *tox; | 98 | extern Tox *tox; |
92 | /* Whether we're a client */ | 99 | |
93 | extern int client_mode; | 100 | /* Whether we're a server, client, etc. */ |
94 | /* Just send a ping and exit */ | 101 | extern enum Mode program_mode; |
95 | extern int ping_mode; | ||
96 | /* TOX_CONNECTION global variable */ | 102 | /* TOX_CONNECTION global variable */ |
97 | extern TOX_CONNECTION connection_status; | 103 | extern TOX_CONNECTION connection_status; |
98 | /* Open a local port and forward it */ | 104 | /* Open a local port and forward it */ |
99 | extern int client_local_port_mode; | ||
100 | /* Forward stdin/stdout to remote machine - SSH ProxyCommand mode */ | ||
101 | extern int client_pipe_mode; | ||
102 | /* Remote Tox ID in client mode */ | ||
103 | extern uint8_t *remote_tox_id; | 105 | extern uint8_t *remote_tox_id; |
104 | /* Ports and hostname for port forwarding */ | 106 | /* Ports and hostname for port forwarding */ |
105 | extern int remote_port; | 107 | extern int remote_port; |