summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGDR! <gdr@gdr.name>2016-10-12 13:45:51 +0200
committerGitHub <noreply@github.com>2016-10-12 13:45:51 +0200
commit91d3cf917678517623eee42acbb948cbe13e15ce (patch)
tree8bd1fc4fa46af4035c0254cd0ce7dfae1f2ef3f2
parentd194df598555e6ba31d53f5b1ec74f370b869c8c (diff)
parent315ee76599c2ebf92c9fed9b13ffad5ef50b849b (diff)
Merge pull request #26 from bonfus/master
Limit allowed hostnames and ports
-rw-r--r--main.c124
-rw-r--r--main.h7
2 files changed, 130 insertions, 1 deletions
diff --git a/main.c b/main.c
index 2acafa6..942c395 100644
--- a/main.c
+++ b/main.c
@@ -31,6 +31,12 @@ char *remote_tox_id = NULL;
31/* Directory with config and tox save */ 31/* Directory with config and tox save */
32char config_path[500] = "/etc/tuntox/"; 32char config_path[500] = "/etc/tuntox/";
33 33
34/* Limit hostname and port in server */
35int nrules = 0;
36char rules_file[500] = "/etc/tuntox/rules";
37enum rules_policy_enum rules_policy = NONE;
38rule *rules = NULL;
39
34/* Ports and hostname for port forwarding */ 40/* Ports and hostname for port forwarding */
35int remote_port = 0; 41int remote_port = 0;
36char *remote_host = NULL; 42char *remote_host = NULL;
@@ -88,6 +94,16 @@ int allowed_toxid_cmp(allowed_toxid *a, allowed_toxid *b)
88 return memcmp(a->toxid, b->toxid, TOX_PUBLIC_KEY_SIZE); 94 return memcmp(a->toxid, b->toxid, TOX_PUBLIC_KEY_SIZE);
89} 95}
90 96
97/* Comparison function for rule objects */
98int rule_cmp(rule *a, rule *b)
99{
100 //log_printf(L_INFO, "Comparison result: %d %d\n", strcmp(a->host, b->host), (a->port == b->port));
101 if ((strcmp(a->host, b->host)==0) && (a->port == b->port))
102 return 0;
103 else
104 return -1;
105}
106
91void update_select_nfds(int fd) 107void update_select_nfds(int fd)
92{ 108{
93 /* TODO maybe replace with a scan every time to make select() more efficient in the long run? */ 109 /* TODO maybe replace with a scan every time to make select() more efficient in the long run? */
@@ -389,6 +405,26 @@ int handle_request_tunnel_frame(protocol_frame *rcvd_frame)
389 hostname[rcvd_frame->data_length] = '\0'; 405 hostname[rcvd_frame->data_length] = '\0';
390 406
391 log_printf(L_INFO, "Got a request to forward data from %s:%d\n", hostname, port); 407 log_printf(L_INFO, "Got a request to forward data from %s:%d\n", hostname, port);
408
409 // check rules
410 if (rules_policy == VALIDATE && nrules > 0 ) {
411
412 rule rtmp, *found = NULL;
413 rtmp.host = hostname;
414 rtmp.port = port;
415
416 LL_SEARCH(rules, found, &rtmp, rule_cmp);
417 if(!found)
418 {
419 log_printf(L_WARNING, "Rejected, request not in rules\n");
420 return -1;
421 }
422 } else if (rules_policy != NONE) {
423 log_printf(L_WARNING, "Filter option active but no allowed host/port. All requests will be dropped.\n");
424 return -1;
425 }
426
427
392 428
393 tunnel_id = get_random_tunnel_id(); 429 tunnel_id = get_random_tunnel_id();
394 log_printf(L_DEBUG, "Tunnel ID: %d\n", tunnel_id); 430 log_printf(L_DEBUG, "Tunnel ID: %d\n", tunnel_id);
@@ -707,6 +743,80 @@ static size_t load_save(uint8_t **out_data)
707 } 743 }
708} 744}
709 745
746/* Loads a list of allowed hostnames and ports from file. Format is hostname:port*/
747void load_rules()
748{
749 char * ahost=NULL;
750 int aport=0;
751 char line[100 + 1] = "";
752 FILE *file = NULL;
753 rule *rule_obj = NULL;
754 int valid_rules = 0;
755
756 file = fopen(rules_file, "r");
757
758 if (file == NULL) {
759 log_printf(L_WARNING, "Could not open rules file (%s)\n", rules_file);
760 return;
761 }
762
763 while (fgets(line, sizeof(line), file)) {
764 if(line)
765 {
766 /* allow comments & white lines */
767 if (line[0]=='#'||line[0]=='\n') {
768 continue;
769 }
770 if (parse_pipe_port_forward(line, &ahost, &aport) >= 0) {
771 if (aport > 0 && aport < 65535) {
772
773 rule_obj = (rule *)calloc(sizeof(rule), 1);
774 if(!rule_obj)
775 {
776 log_printf(L_ERROR, "Could not allocate memory for rule");
777 exit(1);
778 }
779
780 rule_obj->port = aport;
781 rule_obj->host = strdup(ahost);
782
783 LL_APPEND(rules, rule_obj);
784 valid_rules++;
785 } else {
786 log_printf(L_WARNING, "Invalid port in line: %s\n", line);
787 }
788 } else {
789 log_printf(L_WARNING, "Could not parse line: %s\n", line);
790 }
791 } else {
792 /* reached end of file*/
793 break;
794 }
795 }
796 fclose(file);
797
798 /* save valid rules in global variable */
799 nrules = valid_rules;
800
801 log_printf(L_INFO, "Loaded %d rules\n", nrules);
802 if (nrules==0 && rules_policy != NONE){
803 log_printf(L_WARNING, "No rules loaded! NO CONNECTIONS WILL BE ALLOWED!\n");
804 }
805}
806
807/* Clear rules loaded into memory */
808void clear_rules()
809{
810 int i;
811 rule * elt, *tmp;
812 /* delete each elemen using the safe iterator */
813 LL_FOREACH_SAFE(rules,elt,tmp) {
814 LL_DELETE(rules,elt);
815 free(elt->host);
816 free(elt);
817 }
818}
819
710void accept_friend_request(Tox *tox, const uint8_t *public_key, const uint8_t *message, size_t length, void *userdata) 820void accept_friend_request(Tox *tox, const uint8_t *public_key, const uint8_t *message, size_t length, void *userdata)
711{ 821{
712 unsigned char tox_printable_id[TOX_ADDRESS_SIZE * 2 + 1]; 822 unsigned char tox_printable_id[TOX_ADDRESS_SIZE * 2 + 1];
@@ -1060,6 +1170,7 @@ void help()
1060 fprintf(stderr, "-p - ping the server from -i and exit\n"); 1170 fprintf(stderr, "-p - ping the server from -i and exit\n");
1061 fprintf(stderr, "-C <dir> - save private key in <dir> instead of /etc/tuntox in server mode\n"); 1171 fprintf(stderr, "-C <dir> - save private key in <dir> instead of /etc/tuntox in server mode\n");
1062 fprintf(stderr, "-s <secret> - shared secret used for connection authentication (max %u characters)\n", TOX_MAX_FRIEND_REQUEST_LENGTH-1); 1172 fprintf(stderr, "-s <secret> - shared secret used for connection authentication (max %u characters)\n", TOX_MAX_FRIEND_REQUEST_LENGTH-1);
1173 fprintf(stderr, "-f <file> - only allow connections to hostname/port combinations contained in <file>. Rules must by entered one per line with the <hostname>:<port> format\n");
1063 fprintf(stderr, "-d - debug mode\n"); 1174 fprintf(stderr, "-d - debug mode\n");
1064 fprintf(stderr, "-q - quiet mode\n"); 1175 fprintf(stderr, "-q - quiet mode\n");
1065 fprintf(stderr, "-S - send output to syslog instead of stderr\n"); 1176 fprintf(stderr, "-S - send output to syslog instead of stderr\n");
@@ -1081,7 +1192,7 @@ int main(int argc, char *argv[])
1081 1192
1082 log_init(); 1193 log_init();
1083 1194
1084 while ((oc = getopt(argc, argv, "L:pi:C:s:P:dqhSF:DU:")) != -1) 1195 while ((oc = getopt(argc, argv, "L:pi:C:s:f:P:dqhSF:DU:")) != -1)
1085 { 1196 {
1086 switch(oc) 1197 switch(oc)
1087 { 1198 {
@@ -1154,6 +1265,11 @@ int main(int argc, char *argv[])
1154 } 1265 }
1155 load_saved_toxid_in_client_mode = 1; 1266 load_saved_toxid_in_client_mode = 1;
1156 break; 1267 break;
1268 case 'f':
1269 strncpy(rules_file, optarg, sizeof(rules_file) - 1);
1270 rules_policy = VALIDATE;
1271 log_printf(L_INFO, "Filter policy set to VALIDATE\n");
1272 break;
1157 case 's': 1273 case 's':
1158 /* Shared secret */ 1274 /* Shared secret */
1159 use_shared_secret = 1; 1275 use_shared_secret = 1;
@@ -1197,6 +1313,11 @@ int main(int argc, char *argv[])
1197 { 1313 {
1198 log_printf(L_INFO, "Server in ToxID whitelisting mode - only clients listed with -i can connect"); 1314 log_printf(L_INFO, "Server in ToxID whitelisting mode - only clients listed with -i can connect");
1199 } 1315 }
1316
1317 if((!client_mode) && (rules_policy != NONE))
1318 {
1319 load_rules();
1320 }
1200 1321
1201 if(daemonize) 1322 if(daemonize)
1202 { 1323 {
@@ -1281,6 +1402,7 @@ int main(int argc, char *argv[])
1281 1402
1282 tox_callback_friend_request(tox, accept_friend_request, NULL); 1403 tox_callback_friend_request(tox, accept_friend_request, NULL);
1283 do_server_loop(); 1404 do_server_loop();
1405 clear_rules();
1284 } 1406 }
1285 1407
1286 return 0; 1408 return 0;
diff --git a/main.h b/main.h
index 65494ef..329135f 100644
--- a/main.h
+++ b/main.h
@@ -73,6 +73,13 @@ typedef struct protocol_frame_t {
73 uint8_t *data; 73 uint8_t *data;
74} protocol_frame; 74} protocol_frame;
75 75
76/* Rules policy */
77enum rules_policy_enum { VALIDATE, NONE };
78typedef struct rule {
79 uint16_t port;
80 char * host;
81 struct rule *next;
82} rule;
76 83
77/**** GLOBAL VARIABLES ****/ 84/**** GLOBAL VARIABLES ****/
78extern Tox *tox; 85extern Tox *tox;