From ba3b4c0014a52ca33c6623a9817f4f31ee025859 Mon Sep 17 00:00:00 2001 From: Andrew Pamment Date: Thu, 18 Jan 2018 21:27:10 +1000 Subject: [PATCH 1/5] Dual Stack Support (two sockets per service) --- .gitignore | 11 +++ src/bbs.h | 1 + src/main.c | 215 +++++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 170 insertions(+), 57 deletions(-) diff --git a/.gitignore b/.gitignore index 6bb8047..442798f 100644 --- a/.gitignore +++ b/.gitignore @@ -64,3 +64,14 @@ utils/magimail/bin/magimail utils/magimail/bin/magimaint utils/magimail/bin/magistats utils/magimail/bin/magiwrite +keys/ssh_host_dsa_key +magicka.strings +www +keys/ssh_host_dsa_key.pub +keys/ssh_host_rsa_key +keys/ssh_host_rsa_key.pub +menus/doors.mnu +menus/file.mnu +menus/logoff.mnu +menus/mail.mnu +menus/main.mnu diff --git a/src/bbs.h b/src/bbs.h index 5e1daa6..4b3f502 100644 --- a/src/bbs.h +++ b/src/bbs.h @@ -115,6 +115,7 @@ struct ip_address_guard { struct bbs_config { int codepage; + int ipv6; char *bbs_name; char *bwave_name; char *sysop_name; diff --git a/src/main.c b/src/main.c index 108fced..19a6cc2 100644 --- a/src/main.c +++ b/src/main.c @@ -410,6 +410,12 @@ static int handler(void* user, const char* section, const char* name, conf->ssh_server = 1; } else { conf->ssh_server = 0; + } + } else if (strcasecmp(name, "enable ipv6") == 0) { + if (strcasecmp(value, "true") == 0) { + conf->ipv6 = 1; + } else { + conf->ipv6 = 0; } } else if (strcasecmp(name, "enable www") == 0) { if (strcasecmp(value, "true") == 0) { @@ -680,7 +686,7 @@ struct ssh_channel_callbacks_struct ssh_cb = { .userdata = NULL }; -void serverssh(int port) { +void serverssh(int port, int ipv6) { ssh_session p_ssh_session; ssh_bind p_ssh_bind; int err; @@ -698,6 +704,8 @@ void serverssh(int port) { char buffer[1024]; FILE *fptr; struct sockaddr_in6 server, client; + struct sockaddr_in server4, client4; + void *server_p, *client_p; int ssh_sock, csock, c; int on = 1; char str[INET6_ADDRSTRLEN]; @@ -722,8 +730,11 @@ void serverssh(int port) { ssh_bind_options_set(p_ssh_bind, SSH_BIND_OPTIONS_RSAKEY, conf.ssh_rsa_key); //ssh_bind_listen(p_ssh_bind); - - ssh_sock = socket(AF_INET6, SOCK_STREAM, 0); + if (ipv6) { + ssh_sock = socket(AF_INET6, SOCK_STREAM, 0); + } else { + ssh_sock = socket(AF_INET, SOCK_STREAM, 0); + } if (ssh_sock == -1) { fprintf(stderr, "Error starting SSH server.\n"); exit(-1); @@ -735,20 +746,43 @@ void serverssh(int port) { exit(-1); } - memset(&server, 0, sizeof(server)); + if (ipv6) { + if (setsockopt(ssh_sock, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&on, sizeof(on)) < 0) { + fprintf(stderr, "setsockopt(IPV6_V6ONLY) failed"); + } + + memset(&server, 0, sizeof(server)); + server.sin6_family = AF_INET6; + server.sin6_addr = in6addr_any; + server.sin6_port = htons(port); - server.sin6_family = AF_INET6; - server.sin6_addr = in6addr_any; - server.sin6_port = htons(port); + server_p = &server; + client_p = &client; - if (bind(ssh_sock, (struct sockaddr *)&server, sizeof(server)) < 0) { - perror("Bind Failed, Error\n"); - exit(1); + if (bind(ssh_sock, (struct sockaddr *)server_p, sizeof(struct sockaddr_in6)) < 0) { + perror("Bind Failed, Error\n"); + exit(1); + } + c = sizeof(struct sockaddr_in6); + } else { + memset(&server4, 0, sizeof(server4)); + server4.sin_family = AF_INET; + server4.sin_addr.s_addr = INADDR_ANY; + server4.sin_port = htons(port); + + server_p = &server4; + client_p = &client4; + + if (bind(ssh_sock, (struct sockaddr *)server_p, sizeof(struct sockaddr_in)) < 0) { + perror("Bind Failed, Error\n"); + exit(1); + } + c = sizeof(struct sockaddr_in); } listen(ssh_sock, 3); - c = sizeof(struct sockaddr_in6); - while ((csock = accept(ssh_sock, (struct sockaddr *)&client, (socklen_t *)&c))) { + + while ((csock = accept(ssh_sock, (struct sockaddr *)client_p, (socklen_t *)&c))) { p_ssh_session = ssh_new(); if (p_ssh_session == NULL) { fprintf(stderr, "Error starting SSH session.\n"); @@ -756,8 +790,11 @@ void serverssh(int port) { continue; } if (ssh_bind_accept_fd(p_ssh_bind, p_ssh_session, csock) == SSH_OK) { - ip = strdup(inet_ntop(AF_INET6, &client.sin6_addr, str, sizeof(str))); - + if (ipv6) { + ip = strdup(inet_ntop(AF_INET6, &((struct sockaddr_in6 *)client_p)->sin6_addr, str, sizeof(str))); + } else { + ip = strdup(inet_ntop(AF_INET, &((struct sockaddr_in *)client_p)->sin_addr, str, sizeof(str))); + } if (conf.ipguard_enable) { i = hashmap_get(ip_guard_map, ip, (void **)(&ip_guard)); @@ -778,7 +815,7 @@ void serverssh(int port) { ip_guard->connection_count++; if (ip_guard->connection_count == conf.ipguard_tries) { ip_guard->status = IP_STATUS_BLACKLISTED; - snprintf(buffer, 1024, "%s/blacklist.ip", conf.bbs_path); + snprintf(buffer, 1024, "%s/blacklist.ip%d", conf.bbs_path, (ipv6 ? 6 : 4)); fptr = fopen(buffer, "a"); fprintf(fptr, "%s\n", ip); fclose(fptr); @@ -910,7 +947,7 @@ void serverssh(int port) { } } -void server(int port) { +void server(int port, int ipv6) { struct sigaction sa; struct sigaction st; struct sigaction sq; @@ -918,6 +955,8 @@ void server(int port) { int pid; char *ip; struct sockaddr_in6 server, client; + struct sockaddr_in server4, client4; + void *client_p, *server_p; FILE *fptr; char buffer[1024]; struct ip_address_guard *ip_guard; @@ -929,25 +968,11 @@ void server(int port) { www_daemon = NULL; #endif - if (!conf.fork) { - printf("Magicka BBS Server Starting....\n"); - } - - for (i=1;i<=conf.nodes;i++) { - snprintf(buffer, 1024, "%s/nodeinuse.%d", conf.bbs_path, i); - if (stat(buffer, &s) == 0) { - if (!conf.fork) { - printf(" - Removing stale file: nodeinuse.%d\n", i); - } - unlink(buffer); - } - } - if (conf.ipguard_enable) { ip_guard_map = hashmap_new(); - snprintf(buffer, 1024, "%s/whitelist.ip", conf.bbs_path); + snprintf(buffer, 1024, "%s/whitelist.ip%d", conf.bbs_path, (ipv6 ? 6 : 4)); fptr = fopen(buffer, "r"); if (fptr) { @@ -970,7 +995,7 @@ void server(int port) { } fclose(fptr); } - snprintf(buffer, 1024, "%s/blacklist.ip", conf.bbs_path); + snprintf(buffer, 1024, "%s/blacklist.ip%d", conf.bbs_path, (ipv6 ? 6 : 4)); fptr = fopen(buffer, "r"); if (fptr) { @@ -1023,7 +1048,7 @@ void server(int port) { if (conf.ssh_server) { if (!conf.fork) { - printf(" - SSH Starting on Port %d\n", conf.ssh_port); + printf(" - SSH Starting on Port %d (IPv%d)\n", conf.ssh_port, (ipv6 ? 6 : 4)); } // fork ssh server @@ -1031,7 +1056,7 @@ void server(int port) { if (ssh_pid == 0) { ssh_pid = -1; - serverssh(conf.ssh_port); + serverssh(conf.ssh_port, ipv6); exit(0); } if (ssh_pid < 0) { @@ -1042,20 +1067,29 @@ void server(int port) { #if defined(ENABLE_WWW) if (conf.www_server && conf.www_path != NULL) { if (!conf.fork) { - printf(" - HTTP Starting on Port %d\n", conf.www_port); + printf(" - HTTP Starting on Port %d (IPv%d)\n", conf.www_port, (ipv6 ? 6 : 4)); } www_init(); - www_daemon = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION|MHD_USE_DUAL_STACK, conf.www_port, NULL, NULL, &www_handler, NULL, MHD_OPTION_NOTIFY_COMPLETED, &www_request_completed, NULL, MHD_OPTION_URI_LOG_CALLBACK, &www_logger, NULL, MHD_OPTION_END); + if (ipv6) { + www_daemon = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION|MHD_USE_IPv6, conf.www_port, NULL, NULL, &www_handler, NULL, MHD_OPTION_NOTIFY_COMPLETED, &www_request_completed, NULL, MHD_OPTION_URI_LOG_CALLBACK, &www_logger, NULL, MHD_OPTION_END); + } else { + www_daemon = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION, conf.www_port, NULL, NULL, &www_handler, NULL, MHD_OPTION_NOTIFY_COMPLETED, &www_request_completed, NULL, MHD_OPTION_URI_LOG_CALLBACK, &www_logger, NULL, MHD_OPTION_END); + } } #endif - server_socket = socket(AF_INET6, SOCK_STREAM, 0); + if (ipv6) { + server_socket = socket(AF_INET6, SOCK_STREAM, 0); + } else { + server_socket = socket(AF_INET, SOCK_STREAM, 0); + } + if (server_socket == -1) { remove(conf.pid_file); fprintf(stderr, "Couldn't create socket..\n"); exit(1); } - + if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) { remove(conf.pid_file); @@ -1063,28 +1097,55 @@ void server(int port) { exit(1); } - memset(&server, 0, sizeof(server)); - - server.sin6_family = AF_INET6; - server.sin6_addr = in6addr_any; - server.sin6_port = htons(port); - if (!conf.fork) { - printf(" - Telnet Starting on Port %d\n", port); + printf(" - Telnet Starting on Port %d (IPv%d)\n", port, (ipv6 ? 6 : 4)); } - if (bind(server_socket, (struct sockaddr *)&server, sizeof(server)) < 0) { - perror("Bind Failed, Error\n"); - remove(conf.pid_file); - exit(1); + + if (ipv6) { + if (setsockopt(server_socket, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&on, sizeof(on)) < 0) { + fprintf(stderr, "setsockopt(IPV6_V6ONLY) failed"); + } + memset(&server, 0, sizeof(server)); + + server.sin6_family = AF_INET6; + server.sin6_addr = in6addr_any; + server.sin6_port = htons(port); + + if (bind(server_socket, (struct sockaddr *)&server, sizeof(server)) < 0) { + perror("Bind Failed, Error\n"); + remove(conf.pid_file); + exit(1); + } + c = sizeof(struct sockaddr_in6); + server_p = &server; + client_p = &client; + } else { + memset(&server4, 0, sizeof(server4)); + + server4.sin_family = AF_INET; + server4.sin_addr.s_addr = INADDR_ANY; + server4.sin_port = htons(port); + + if (bind(server_socket, (struct sockaddr *)&server4, sizeof(server4)) < 0) { + perror("Bind Failed, Error\n"); + remove(conf.pid_file); + exit(1); + } + c = sizeof(struct sockaddr_in); + server_p = &server4; + client_p = &client4; } listen(server_socket, 3); - c = sizeof(struct sockaddr_in6); - while ((client_sock = accept(server_socket, (struct sockaddr *)&client, (socklen_t *)&c))) { - ip = strdup(inet_ntop(AF_INET6, &client.sin6_addr, str, sizeof(str))); + while ((client_sock = accept(server_socket, (struct sockaddr *)client_p, (socklen_t *)&c))) { + if (ipv6) { + ip = strdup(inet_ntop(AF_INET6, &((struct sockaddr_in6 *)client_p)->sin6_addr, str, sizeof(str))); + } else { + ip = strdup(inet_ntop(AF_INET, &((struct sockaddr_in *)client_p)->sin_addr, str, sizeof(str))); + } if (client_sock == -1) { if (errno == EINTR) { continue; @@ -1114,7 +1175,7 @@ void server(int port) { ip_guard->connection_count++; if (ip_guard->connection_count == conf.ipguard_tries) { ip_guard->status = IP_STATUS_BLACKLISTED; - snprintf(buffer, 1024, "%s/blacklist.ip", conf.bbs_path); + snprintf(buffer, 1024, "%s/blacklist.ip%d", conf.bbs_path, (ipv6 ? 6 : 4)); fptr = fopen(buffer, "a"); fprintf(fptr, "%s\n", ip); fclose(fptr); @@ -1153,7 +1214,7 @@ void server(int port) { int main(int argc, char **argv) { int i; - int main_pid; + int main_pid, ipv6_pid; FILE *fptr; struct stat s; char buffer[1024]; @@ -1191,7 +1252,8 @@ int main(int argc, char **argv) { conf.protocol_count = 0; conf.codepage = 0; conf.date_style = 0; - + conf.ipv6 = 0; + // Load BBS data if (ini_parse(argv[1], handler, &conf) <0) { fprintf(stderr, "Unable to load configuration ini (%s)!\n", argv[1]); @@ -1266,9 +1328,48 @@ int main(int argc, char **argv) { fclose(fptr); } } else { - server(conf.telnet_port); + for (i=1;i<=conf.nodes;i++) { + snprintf(buffer, 1024, "%s/nodeinuse.%d", conf.bbs_path, i); + if (stat(buffer, &s) == 0) { + unlink(buffer); + } + } + if (conf.ipv6) { + ipv6_pid = fork(); + if (ipv6_pid < 0) { + fprintf(stderr, "Error forking.\n"); + exit(-1); + } else if (ipv6_pid > 0) { + server(conf.telnet_port, 0); + } else { + server(conf.telnet_port, 1); + } + } else { + server(conf.telnet_port, 0); + } } } else { - server(conf.telnet_port); + printf("Magicka BBS Server Starting....\n"); + + for (i=1;i<=conf.nodes;i++) { + snprintf(buffer, 1024, "%s/nodeinuse.%d", conf.bbs_path, i); + if (stat(buffer, &s) == 0) { + printf(" - Removing stale file: nodeinuse.%d\n", i); + unlink(buffer); + } + } + if (conf.ipv6) { + ipv6_pid = fork(); + if (ipv6_pid < 0) { + fprintf(stderr, "Error forking.\n"); + exit(-1); + } else if (ipv6_pid > 0) { + server(conf.telnet_port, 0); + } else { + server(conf.telnet_port, 1); + } + } else { + server(conf.telnet_port, 0); + } } } From 71d442898ae5403146cb9c5f380ab14ec79fb0d2 Mon Sep 17 00:00:00 2001 From: Andrew Pamment Date: Thu, 18 Jan 2018 21:31:08 +1000 Subject: [PATCH 2/5] Add enable ipv6 to config --- dist/config/bbs.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/dist/config/bbs.ini b/dist/config/bbs.ini index af7cae8..3a2736a 100644 --- a/dist/config/bbs.ini +++ b/dist/config/bbs.ini @@ -31,6 +31,7 @@ IP Guard Timeout = 120 IP Guard Tries = 4 Root Menu = main Date Style = EU +Enable IPv6 = true [paths] Config Path = /home/andrew/MagickaBBS/config From e56ba91b5b9bd3ed5b7b6d703368d482ca57fec2 Mon Sep 17 00:00:00 2001 From: Andrew Pamment Date: Fri, 19 Jan 2018 10:37:08 +1000 Subject: [PATCH 3/5] Updates to script and version bump --- dist/ansis/bulletin1.ans | Bin 5766 -> 5744 bytes setup.sh | 32 ++++++++++++++++++++------------ src/bbs.h | 2 +- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/dist/ansis/bulletin1.ans b/dist/ansis/bulletin1.ans index 69e752f907182b69c9c1ef039def3b204250ab67..12ccc0126faeb3eb3e3ed25416028bae5b1bf659 100644 GIT binary patch delta 70 zcmZqE{h+hq8$auv`}glCO#aPZ%qbmhXl-ngd;iYla)Cx}DDSp{!tKe-g2h}4_Z9Bn WSCEc2$lW|m@DvNvd(p{BVk!U|og0k+ delta 92 zcmeyM)26%O8$avq`}gnPnf#l-m{UPPI@-|M*d%vyxj-W~jB{H-VKTE|F_3GJ3lqDK V%u#^wHa7^KVqszxo9rW|0stQE9q9l7 diff --git a/setup.sh b/setup.sh index 6ffcd8d..c9f20dd 100755 --- a/setup.sh +++ b/setup.sh @@ -61,15 +61,23 @@ printstuff "Please enter the name of your BBS:" read -e bbsname -sed -i "s@/home/andrew/MagickaBBS@${PWD}@g" config/bbs.ini -sed -i "s/BBS Name = Magicka BBS/BBS Name = ${bbsname}/g" config/bbs.ini -sed -i "s/Sysop Name = sysop/Sysop Name = ${handle}/g" config/bbs.ini -sed -i "s@/home/andrew/MagickaBBS@${PWD}@g" config/localmail.ini -sed -i "s@/home/andrew/MagickaBBS@${PWD}@g" config/filesgen.ini -sed -i "s@/home/andrew/MagickaBBS@${PWD}@g" config/illusionnet.ini -sed -i "s@/home/andrew/MagickaBBS@${PWD}@g" utils/magiedit/magiedit.sh -sed -i "s@/home/andrew/MagickaBBS@${PWD}@g" scripts/login_stanza.lua -sed -i "s/MagiChat Server = localhost/; MagiChat Server = localhost/g" config/bbs.ini -sed -i "s/Default Tagline = Brought to you by Another Magicka BBS!/Default Tagline = ${bbsname}/g" config/bbs.ini -sed -i "s/echomail.out/mail.out/g" config/bbs.ini -sed -i "s/netmail.out/mail.out/g" config/bbs.ini +PLATFORM=`uname` + +if [[ "$PLATFORM" == 'FreeBSD' ]] || [[ "$PLATFORM" == 'Darwin' ]]; then + SED = gsed +else + SED = sed +fi + +$SED -i "s@/home/andrew/MagickaBBS@${PWD}@g" config/bbs.ini +$SED -i "s/BBS Name = Magicka BBS/BBS Name = ${bbsname}/g" config/bbs.ini +$SED -i "s/Sysop Name = sysop/Sysop Name = ${handle}/g" config/bbs.ini +$SED -i "s@/home/andrew/MagickaBBS@${PWD}@g" config/localmail.ini +$SED -i "s@/home/andrew/MagickaBBS@${PWD}@g" config/filesgen.ini +$SED -i "s@/home/andrew/MagickaBBS@${PWD}@g" config/illusionnet.ini +$SED -i "s@/home/andrew/MagickaBBS@${PWD}@g" utils/magiedit/magiedit.sh +$SED -i "s@/home/andrew/MagickaBBS@${PWD}@g" scripts/login_stanza.lua +$SED -i "s/MagiChat Server = localhost/; MagiChat Server = localhost/g" config/bbs.ini +$SED -i "s/Default Tagline = Brought to you by Another Magicka BBS!/Default Tagline = ${bbsname}/g" config/bbs.ini +$SED -i "s/echomail.out/mail.out/g" config/bbs.ini +$SED -i "s/netmail.out/mail.out/g" config/bbs.ini diff --git a/src/bbs.h b/src/bbs.h index 4b3f502..efe4e7a 100644 --- a/src/bbs.h +++ b/src/bbs.h @@ -12,7 +12,7 @@ #include "jamlib/jam.h" #define VERSION_MAJOR 0 -#define VERSION_MINOR 7 +#define VERSION_MINOR 8 #define VERSION_STR "alpha" #define NETWORK_FIDO 1 From 583709835e49fe4e7541a5a66ef38e5b3f7d98ce Mon Sep 17 00:00:00 2001 From: Andrew Pamment Date: Fri, 19 Jan 2018 10:41:38 +1000 Subject: [PATCH 4/5] Fix erronous spaces in script --- setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.sh b/setup.sh index c9f20dd..7649260 100755 --- a/setup.sh +++ b/setup.sh @@ -64,9 +64,9 @@ read -e bbsname PLATFORM=`uname` if [[ "$PLATFORM" == 'FreeBSD' ]] || [[ "$PLATFORM" == 'Darwin' ]]; then - SED = gsed + SED=gsed else - SED = sed + SED=sed fi $SED -i "s@/home/andrew/MagickaBBS@${PWD}@g" config/bbs.ini From ea84cbd73227720e5a4862199cbed1689b38b659 Mon Sep 17 00:00:00 2001 From: Andrew Pamment Date: Fri, 19 Jan 2018 11:09:07 +1000 Subject: [PATCH 5/5] Support for DragonFlyBSD --- setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.sh b/setup.sh index 7649260..127d315 100755 --- a/setup.sh +++ b/setup.sh @@ -63,7 +63,7 @@ read -e bbsname PLATFORM=`uname` -if [[ "$PLATFORM" == 'FreeBSD' ]] || [[ "$PLATFORM" == 'Darwin' ]]; then +if [[ "$PLATFORM" == 'FreeBSD' ]] || [[ "$PLATFORM" == 'Darwin' ]] || [[ "$PLATFORM" == 'DragonFly' ]]; then SED=gsed else SED=sed