diff options
-rw-r--r-- | pttbbs/common/bbs/Makefile | 2 | ||||
-rw-r--r-- | pttbbs/common/bbs/banip.c | 129 | ||||
-rw-r--r-- | pttbbs/daemon/logind/logind.c | 178 | ||||
-rw-r--r-- | pttbbs/include/cmbbs.h | 8 | ||||
-rw-r--r-- | pttbbs/include/common.h | 1 |
5 files changed, 230 insertions, 88 deletions
diff --git a/pttbbs/common/bbs/Makefile b/pttbbs/common/bbs/Makefile index a6c85f65..2c461fdd 100644 --- a/pttbbs/common/bbs/Makefile +++ b/pttbbs/common/bbs/Makefile @@ -4,7 +4,7 @@ SRCROOT:= ../.. .include "$(SRCROOT)/pttbbs.mk" SRCS:= log.c money.c names.c path.c time.c string.c fhdr_stamp.c cache.c \ - passwd.c filehdr.c + passwd.c filehdr.c banip.c LIB:= cmbbs install: diff --git a/pttbbs/common/bbs/banip.c b/pttbbs/common/bbs/banip.c new file mode 100644 index 00000000..8256536c --- /dev/null +++ b/pttbbs/common/bbs/banip.c @@ -0,0 +1,129 @@ +// Ban IP Table Reader (~bbs/etc/banip.conf) +// +// Copyright (C) 2012, Hung-Te Lin <piaip@csie.ntu.edu.tw> +// All rights reserved. +// Distributed under BSD license (GPL compatible). + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <assert.h> +#include <arpa/inet.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include "cmbbs.h" +#define BANIP_ALLOC (128) + +typedef struct { + // table allocation + size_t sz, alloc; + IPv4 *ar; +} IPv4List; + +static int +compare_ipv4(const void *pa, const void *pb) { + const IPv4 *a = (const IPv4*)pa, *b = (const IPv4*)pb; + // Since IPv4 are all random number, we can't do simple a-b due to + // underflow. + return (*a > *b) ? 1 : (*a == *b) ? 0 : -1; +} + +static void +add_banip_list(IPv4List *list, IPv4 addr) { + if (list->sz >= list->alloc) { + list->alloc += BANIP_ALLOC; + list->ar = (IPv4*)realloc(list->ar, sizeof(IPv4) * list->alloc); + assert(list->ar); + } + list->ar[list->sz++] = addr; +} + +static void +reset_banip_list(IPv4List *list) { + list->sz = 0; +} + +static void +sort_banip_list(IPv4List *list) { + if (!list->ar) + return; + qsort(list->ar, list->sz, sizeof(IPv4), compare_ipv4); +} + +int +in_banip_list_addr(const BanIpList *blist, IPv4 addr) { + const IPv4List *list = (const IPv4List*)blist; + if (!list || !list->ar) + return 0; + return bsearch(&addr, list->ar, list->sz, + sizeof(IPv4), compare_ipv4) != NULL; +} + +int +in_banip_list(const BanIpList *blist, const char *ip) { + struct in_addr addr; + if (blist && inet_pton(AF_INET, ip, &addr) == 1) + return in_banip_list_addr(blist, addr.s_addr); + return 0; +} + +BanIpList * +free_banip_list(BanIpList *blist) { + IPv4List *list = (IPv4List*) blist; + if (!list) + return NULL; + free(list->ar); + free(list); + return NULL; +} + +BanIpList * +load_banip_list(const char *filename, FILE* err) { + // Loads banip.conf (shared by daemon/banipd). + IPv4List *list = NULL; + FILE *fp; + char *p; + char buf[PATHLEN]; + struct in_addr addr; + + fp = fopen(filename, "rt"); + if (!fp) + return (BanIpList*)list; + + list = (IPv4List*)malloc(sizeof(IPv4List)); + memset(list, 0, sizeof(*list)); + + reset_banip_list(list); + while (fgets(buf, sizeof(buf), fp)) { + // only process lines starting with digits, + // and ignore all comments. + p = strchr(buf, '#'); + if (p) *p = 0; + p = buf; + while (*p && isascii(*p) && isspace(*p)) + p++; + if (!(*p && isascii(*p) && isdigit(*p))) + continue; + for (p = strtok(p, " \t\r\n"); p; p = strtok(NULL, " \t\r\n")) { + if (!(*p && isascii(*p) && isdigit(*p))) + continue; + if (inet_pton(AF_INET, p, &addr) != 1) { + if (err) + fprintf(err, "(banip) Invalid IP: %s\n", p); + continue; + } +#ifdef DEBUG + if (err) + fprintf(err, "(banip) Added IP: %s %lu\n", p, addr.s_addr); +#endif + add_banip_list(list, addr.s_addr); + } + } + fclose(fp); + sort_banip_list(list); + if (err) + fprintf(err, "(banip) Loaded %lu IPs\n", list->sz); + return (BanIpList*)list; +} diff --git a/pttbbs/daemon/logind/logind.c b/pttbbs/daemon/logind/logind.c index d627c4ee..2875c75c 100644 --- a/pttbbs/daemon/logind/logind.c +++ b/pttbbs/daemon/logind/logind.c @@ -49,7 +49,6 @@ #define _BBS_UTIL_C_ #include "bbs.h" -#include "banip.h" #include "daemons.h" #ifndef LOGIND_REGULAR_CHECK_DURATION @@ -150,6 +149,10 @@ time4_t g_welcome_mtime; int g_guest_usernum = 0; // numeric uid of guest account int g_guest_too_many = 0; // 1 if exceed MAX_GUEST +// banned ip +BanIpList g_banip; +time4_t g_banip_mtime = -1; + enum { VERBOSE_ERROR, VERBOSE_INFO, @@ -432,7 +435,7 @@ ackq_add(login_conn_ctx *ctx) if (g_ack_queue.capacity < ACK_QUEUE_DEFAULT_CAPACITY) g_ack_queue.capacity = ACK_QUEUE_DEFAULT_CAPACITY; - fprintf(stderr, LOG_PREFIX "%s: resize ack queue to: %u (%u in use)\r\n", + fprintf(stderr, LOG_PREFIX "%s: resize ack queue to: %u (%u in use)\n", Cdate(&tnow), (unsigned int)g_ack_queue.capacity, (unsigned int)g_ack_queue.size); @@ -652,7 +655,7 @@ _set_tunnel_opt(int sock) setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &szsend, sizeof(szsend)) < 0) { fprintf(stderr, LOG_PREFIX "WARNING: " - "set_tunnel_opt: failed to increase buffer to (%u,%u)\r\n", + "set_tunnel_opt: failed to increase buffer to (%u,%u)\n", szsend, szrecv); } @@ -700,7 +703,7 @@ DEBUG_IO(int fd, const char *msg) { return; #endif now = time(NULL); - fprintf(stderr, LOG_PREFIX "%s: %s fd(%d): FION READ:%d/%d WRITE:%d/%d\r\n", + fprintf(stderr, LOG_PREFIX "%s: %s fd(%d): FION READ:%d/%d WRITE:%d/%d\n", Cdate(&now), msg, fd, nread, rcvbuf, nwrite, sndbuf); } #else @@ -839,13 +842,21 @@ reload_data() if (!g_reload_data) return; - fprintf(stderr, LOG_PREFIX "start reloading data.\r\n"); + fprintf(stderr, LOG_PREFIX "start reloading data.\n"); g_reload_data = 0; g_welcome_mtime = dasht(FN_WELCOME); load_text_screen_file(FN_WELCOME, &welcome_screen); load_text_screen_file(FN_GOODBYE, &goodbye_screen); load_text_screen_file(FN_BANIP, &banip_screen); load_text_screen_file(FN_BAN, &ban_screen); + + // Loading banip table is slow - only reload if the file is really modified. + if (dasht(FN_CONF_BANIP) != g_banip_mtime) { + fprintf(stderr, LOG_PREFIX "reload banip table: %s.\n", FN_CONF_BANIP); + g_banip_mtime = dasht(FN_CONF_BANIP); + g_banip = free_banip_list(g_banip); + g_banip = load_banip_list(FN_CONF_BANIP, stderr); + } } static void @@ -1081,13 +1092,13 @@ regular_check() // check welcome screen if (g_verbose > VERBOSE_INFO) - fprintf(stderr, LOG_PREFIX "check welcome screen.\r\n"); + fprintf(stderr, LOG_PREFIX "check welcome screen.\n"); if (dasht(FN_WELCOME) != g_welcome_mtime) { g_reload_data = 1; if (g_verbose > VERBOSE_INFO) fprintf(stderr, LOG_PREFIX - "modified. must update welcome screen ...\r\n"); + "modified. must update welcome screen ...\n"); } } @@ -1119,13 +1130,6 @@ is_tunnel_available() { return 1; } -static int -check_banip(char *host) -{ - uint32_t thisip = ipstr2int(host); - return uintbsearch(thisip, &banip[1], banip[0]) ? 1 : 0; -} - static const char * auth_is_free_userid(const char *userid) { @@ -1170,7 +1174,7 @@ auth_check_free_userid_allowance(const char *userid) if (!g_guest_usernum) { if (g_verbose > VERBOSE_INFO) - fprintf(stderr, LOG_PREFIX " reload guest information\r\n"); + fprintf(stderr, LOG_PREFIX " reload guest information\n"); // reload guest information g_guest_usernum = searchuser(STR_GUEST, NULL); @@ -1187,7 +1191,7 @@ auth_check_free_userid_allowance(const char *userid) (!g_guest_usernum || (search_ulistn(g_guest_usernum, MAX_GUEST) != NULL)); if (g_verbose > VERBOSE_INFO) fprintf(stderr, LOG_PREFIX - " guests are %s\r\n", g_guest_too_many ? "TOO MANY" : "ok."); + " guests are %s\n", g_guest_too_many ? "TOO MANY" : "ok."); # endif // MAX_GUEST return g_guest_too_many ? 0 : 1; @@ -1246,13 +1250,13 @@ retry_service() if (g_retry_times >= LOGIND_MAX_RETRY_SERVICE) { fprintf(stderr, LOG_PREFIX - "retry too many times (>%d), stop and wait manually maintainance.\r\n", + "retry too many times (>%d), stop and wait manually maintainance.\n", LOGIND_MAX_RETRY_SERVICE); return; } g_retry_times++; - fprintf(stderr, LOG_PREFIX "#%d retry to start service: %s\r\n", + fprintf(stderr, LOG_PREFIX "#%d retry to start service: %s\n", g_retry_times, g_retry_cmd); system(g_retry_cmd); } @@ -1289,7 +1293,7 @@ start_service(int fd, login_conn_ctx *conn) ld.t_cols = ctx->t_cols; if (g_verbose > VERBOSE_INFO) - fprintf(stderr, LOG_PREFIX "start new service: %s@%s:%s #%d\r\n", + fprintf(stderr, LOG_PREFIX "start new service: %s@%s:%s #%d\n", ld.userid, ld.hostip, ld.port, fd); // XXX simulate the cache re-construction in mbbsd/login_query. @@ -1302,7 +1306,7 @@ start_service(int fd, login_conn_ctx *conn) if (send_remote_fd(g_tunnel, fd) < 0) { if (g_verbose > VERBOSE_ERROR) fprintf(stderr, LOG_PREFIX - "failed in send_remote_fd\r\n"); + "failed in send_remote_fd\n"); return ack; } @@ -1311,7 +1315,7 @@ start_service(int fd, login_conn_ctx *conn) if (towrite(g_tunnel, &ld, sizeof(ld)) < (int)sizeof(ld)) { if (g_verbose > VERBOSE_ERROR) fprintf(stderr, LOG_PREFIX - "failed in towrite(login_data)\r\n"); + "failed in towrite(login_data)\n"); return ack; } DEBUG_IO(g_tunnel, "after start_service:towrite(g_tunnel)"); @@ -1325,7 +1329,7 @@ start_service(int fd, login_conn_ctx *conn) if (!login_conn_end_ack(conn, ld.ack, fd)) { if (g_verbose > VERBOSE_ERROR) fprintf(stderr, LOG_PREFIX - "failed in logind_conn_end_ack\r\n"); + "failed in logind_conn_end_ack\n"); return ack; } return 1; @@ -1351,7 +1355,7 @@ logattempt2(const char *userid, char c, time4_t logtime, const char *hostip) // failed ... back to internal. fprintf(stderr, LOG_PREFIX - "error: cannot use logattempt daemon, change to internal.\r\n"); + "error: cannot use logattempt daemon, change to internal.\n"); close(g_logattempt_pipe); g_async_logattempt= 0; g_logattempt_pipe = 0; @@ -1455,7 +1459,7 @@ static void sighup_cb(int signal GCC_UNUSED, short event GCC_UNUSED, void *arg GCC_UNUSED) { fprintf(stderr, LOG_PREFIX - "caught sighup (request to reload) with %u opening fd...\r\n", + "caught sighup (request to reload) with %u opening fd...\n", g_opened_fd); g_reload_data = 1; } @@ -1502,7 +1506,7 @@ endconn_cb(int fd, short event GCC_UNUSED, void *arg) close(fd); g_opened_fd--; free(conn); - if (g_verbose > VERBOSE_INFO) fprintf(stderr, " done.\r\n"); + if (g_verbose > VERBOSE_INFO) fprintf(stderr, " done.\n"); } static void @@ -1527,9 +1531,10 @@ login_conn_remove(login_conn_ctx *conn, int fd, int sleep_sec) event_del(&conn->ev); event_set(&conn->ev, fd, 0, endconn_cb, conn); event_add(&conn->ev, &tv); - if (g_verbose > VERBOSE_INFO) fprintf(stderr, LOG_PREFIX - "login_conn_remove: stop conn #%d in %d seconds later.\r\n", - fd, sleep_sec); + if (g_verbose > VERBOSE_INFO) + fprintf(stderr, LOG_PREFIX + "login_conn_remove: stop conn #%d in %d seconds later.\n", + fd, sleep_sec); } } @@ -1539,12 +1544,12 @@ get_tunnel_ack(int tunnel) void *arg = NULL; #ifdef VERIFY_BLOCKING_TUNNEL - // fprintf(stderr, LOG_PREFIX "get_tunnel_ack: tunnel %s .\r\n", + // fprintf(stderr, LOG_PREFIX "get_tunnel_ack: tunnel %s .\n", // ( fcntl(tunnel, F_GETFL) & O_NONBLOCK ) ? "nonblock" : "blocking"); if (fcntl(tunnel, F_GETFL) & (O_NONBLOCK)) { fprintf(stderr, LOG_PREFIX - "get_tunnel_ack: warning: tunnel is nonblocking.\r\n"); + "get_tunnel_ack: warning: tunnel is nonblocking.\n"); stop_tunnel(tunnel); return NULL; } @@ -1557,7 +1562,7 @@ get_tunnel_ack(int tunnel) // sorry... broken, let's shutdown the tunnel. if (g_verbose > VERBOSE_ERROR) fprintf(stderr, LOG_PREFIX - "get_tunnel_ack: tunnel (%d) is broken with arg %p.\r\n", + "get_tunnel_ack: tunnel (%d) is broken with arg %p.\n", tunnel, arg); stop_tunnel(tunnel); @@ -1579,7 +1584,7 @@ ack_cb(int tunnel, short event, void *arg) { // not read event (closed? timeout?) if (g_verbose > VERBOSE_ERROR) fprintf(stderr, LOG_PREFIX - "warning: invalid ack event at tunnel %d.\r\n", tunnel); + "warning: invalid ack event at tunnel %d.\n", tunnel); stop_tunnel(tunnel); return; } @@ -1589,7 +1594,7 @@ ack_cb(int tunnel, short event, void *arg) if (!conn) { if (g_verbose > VERBOSE_ERROR) fprintf(stderr, LOG_PREFIX - "warning: invalid ack at tunnel %d.\r\n", tunnel); + "warning: invalid ack at tunnel %d.\n", tunnel); return; } @@ -1599,7 +1604,7 @@ ack_cb(int tunnel, short event, void *arg) if (!ackq_del(conn)) { if (g_verbose > VERBOSE_ERROR) fprintf(stderr, LOG_PREFIX - "drop abandoned ack connection: %p.\r\n", conn); + "drop abandoned ack connection: %p.\n", conn); return; } @@ -1607,7 +1612,7 @@ ack_cb(int tunnel, short event, void *arg) if (conn->cb != sizeof(login_conn_ctx)) { fprintf(stderr, LOG_PREFIX - "warning: received invalid ack from tunnel. abort/reset tunnel?\r\n"); + "warning: received invalid ack from tunnel. abort/reset tunnel?\n"); // assert(conn && conn->cb == sizeof(login_conn_ctx)); return; } @@ -1622,12 +1627,12 @@ ack_cb(int tunnel, short event, void *arg) static int login_conn_end_ack(login_conn_ctx *conn, void *ack, int fd) { - // fprintf(stderr, LOG_PREFIX "login_conn_end_ack: enter.\r\n"); + // fprintf(stderr, LOG_PREFIX "login_conn_end_ack: enter.\n"); if (g_async_ack) { // simply wait for ack_cb to complete - // fprintf(stderr, LOG_PREFIX "login_conn_end_ack: async mode.\r\n"); + // fprintf(stderr, LOG_PREFIX "login_conn_end_ack: async mode.\n"); // mark as queued for waiting ack conn->ctx.state = LOGIN_STATE_WAITACK; @@ -1640,7 +1645,7 @@ login_conn_end_ack(login_conn_ctx *conn, void *ack, int fd) // wait service to complete void *rack = NULL; - // fprintf(stderr, LOG_PREFIX "login_conn_end_ack: sync mode.\r\n"); + // fprintf(stderr, LOG_PREFIX "login_conn_end_ack: sync mode.\n"); if (!g_tunnel) return 0; @@ -1652,7 +1657,7 @@ login_conn_end_ack(login_conn_ctx *conn, void *ack, int fd) { // critical error! fprintf(stderr, LOG_PREFIX - "login_conn_end_ack: failed in ack value (%p != %p).\r\n", + "login_conn_end_ack: failed in ack value (%p != %p).\n", rack, ack); stop_g_tunnel(); @@ -1683,7 +1688,7 @@ client_cb(int fd, short event, void *arg) strlcpy((char*)buf, Cdate(&tnow), sizeof(buf)); fprintf(stderr, LOG_PREFIX - "timeout: %-16s [%s -> %s : %-4ds] %08X %s%s\r\n", + "timeout: %-16s [%s -> %s : %-4ds] %08X %s%s\n", conn->ctx.hostip, Cdate(&conn->enter), buf, @@ -1753,7 +1758,7 @@ client_cb(int fd, short event, void *arg) case LOGIN_HANDLE_REDRAW_USERID: if (g_verbose > VERBOSE_DEBUG) fprintf(stderr, LOG_PREFIX - "redraw userid: id=[%s], icurr=%d\r\n", + "redraw userid: id=[%s], icurr=%d\n", conn->ctx.userid, conn->ctx.icurr); draw_userid_prompt(conn, conn->ctx.userid, conn->ctx.icurr); break; @@ -1876,7 +1881,7 @@ listen_cb(int lfd, short event GCC_UNUSED, void *arg) snprintf(conn->ctx.port, sizeof(conn->ctx.port), "%u", pbindev->port); // ntohs(xsin.sin_port)); if (g_verbose > VERBOSE_INFO) fprintf(stderr, LOG_PREFIX - "new connection: fd=#%d %s:%s (opened fd: %d)\r\n", + "new connection: fd=#%d %s:%s (opened fd: %d)\n", fd, conn->ctx.hostip, conn->ctx.port, g_opened_fd); // set events @@ -1889,8 +1894,7 @@ listen_cb(int lfd, short event GCC_UNUSED, void *arg) return; } - // TODO can we directly use xsin.sin_addr instead of ASCII form? - if (check_banip(conn->ctx.hostip)) + if (in_banip_list_addr(g_banip, xsin.sin_addr.s_addr)) { draw_text_screen (conn, banip_screen); login_conn_remove(conn, fd, BAN_SLEEP_SEC); @@ -1923,7 +1927,7 @@ tunnel_cb(int fd, short event GCC_UNUSED, void *arg GCC_UNUSED) return; // got new tunnel - fprintf(stderr, LOG_PREFIX "new tunnel established.\r\n"); + fprintf(stderr, LOG_PREFIX "new tunnel established.\n"); _set_connection_opt(cfd); _set_tunnel_opt(cfd); @@ -1947,7 +1951,7 @@ logattempt_daemon() int pid; logattempt_ctx ctx = {0}; - fprintf(stderr, LOG_PREFIX "forking logattempt daemon...\r\n"); + fprintf(stderr, LOG_PREFIX "forking logattempt daemon...\n"); if (pipe(pipe_fds) < 0) { perror("pipe"); @@ -1982,7 +1986,7 @@ logattempt_daemon() "after logattempt_daemon:toread(g_logattempt_pipe)"); if (ctx.cb != sizeof(ctx)) { - fprintf(stderr, LOG_PREFIX "broken pipe. abort.\r\n"); + fprintf(stderr, LOG_PREFIX "broken pipe. abort.\n"); break; } @@ -2003,7 +2007,7 @@ bind_port(int port) fprintf(stderr, LOG_PREFIX "binding to port: %d...", port); if ( (sfd = tobindex(buf, LOGIND_SOCKET_QLEN, _set_bind_opt, 1)) < 0 ) { - fprintf(stderr, LOG_PREFIX "cannot bind to port: %d. abort.\r\n", port); + fprintf(stderr, LOG_PREFIX "cannot bind to port: %d. abort.\n", port); return -1; } @@ -2018,7 +2022,7 @@ bind_port(int port) pev->port = port; event_set(&pev->ev, sfd, EV_READ | EV_PERSIST, listen_cb, pev); event_add(&pev->ev, NULL); - fprintf(stderr,"ok. \r\n"); + fprintf(stderr,"ok. \n"); return 0; } @@ -2046,16 +2050,16 @@ parse_bindports_conf(FILE *fp, if (*tclient_cmd) { fprintf(stderr, LOG_PREFIX - "warning: ignored configuration file due to specified client command: %s\r\n", + "warning: ignored configuration file due to specified client command: %s\n", tclient_cmd); continue; } if (sscanf(buf, "%*s%*s%[^\n]", vtunnel) != 1 || !*vtunnel) { - fprintf(stderr, LOG_PREFIX "incorrect tunnel client configuration. abort.\r\n"); + fprintf(stderr, LOG_PREFIX "incorrect tunnel client configuration. abort.\n"); exit(1); } - if (g_verbose) fprintf(stderr, "client: %s\r\n", vtunnel); + if (g_verbose) fprintf(stderr, "client: %s\n", vtunnel); strlcpy(tclient_cmd, vtunnel, sz_tclient_cmd); continue; } @@ -2065,16 +2069,16 @@ parse_bindports_conf(FILE *fp, if (*g_retry_cmd) { fprintf(stderr, LOG_PREFIX - "warning: ignored configuration file due to specified retry command: %s\r\n", + "warning: ignored configuration file due to specified retry command: %s\n", g_retry_cmd); continue; } if (sscanf(buf, "%*s%*s%[^\n]", vtunnel) != 1 || !*vtunnel) { - fprintf(stderr, LOG_PREFIX "incorrect retry client configuration. abort.\r\n"); + fprintf(stderr, LOG_PREFIX "incorrect retry client configuration. abort.\n"); exit(1); } - if (g_verbose) fprintf(stderr, "client_retry: %s\r\n", vtunnel); + if (g_verbose) fprintf(stderr, "client_retry: %s\n", vtunnel); strlcpy(g_retry_cmd, vtunnel, sizeof(g_retry_cmd)); continue; } @@ -2084,16 +2088,16 @@ parse_bindports_conf(FILE *fp, if (*g_logfile_path) { fprintf(stderr, LOG_PREFIX - "warning: ignored configuration file due to specified log: %s\r\n", + "warning: ignored configuration file due to specified log: %s\n", g_logfile_path); continue; } if (sscanf(buf, "%*s%*s%s", vtunnel) != 1 || !*vtunnel) { - fprintf(stderr, LOG_PREFIX "incorrect tunnel configuration. abort.\r\n"); + fprintf(stderr, LOG_PREFIX "incorrect tunnel configuration. abort.\n"); exit(1); } - if (g_verbose) fprintf(stderr, "log_file: %s\r\n", vtunnel); + if (g_verbose) fprintf(stderr, "log_file: %s\n", vtunnel); strlcpy(g_logfile_path, vtunnel, sizeof(g_logfile_path)); continue; } @@ -2102,16 +2106,16 @@ parse_bindports_conf(FILE *fp, if (*tunnel_path) { fprintf(stderr, LOG_PREFIX - "warning: ignored configuration file due to specified tunnel: %s\r\n", + "warning: ignored configuration file due to specified tunnel: %s\n", tunnel_path); continue; } if (sscanf(buf, "%*s%*s%s", vtunnel) != 1 || !*vtunnel) { - fprintf(stderr, LOG_PREFIX "incorrect tunnel configuration. abort.\r\n"); + fprintf(stderr, LOG_PREFIX "incorrect tunnel configuration. abort.\n"); exit(1); } - if (g_verbose) fprintf(stderr, "tunnel: %s\r\n", vtunnel); + if (g_verbose) fprintf(stderr, "tunnel: %s\n", vtunnel); strlcpy(tunnel_path, vtunnel, sz_tunnel_path); continue; } @@ -2119,13 +2123,13 @@ parse_bindports_conf(FILE *fp, iport = atoi(vport); if (!iport) { - fprintf(stderr, LOG_PREFIX "warning: unknown settings: %s\r\n", buf); + fprintf(stderr, LOG_PREFIX "warning: unknown settings: %s\n", buf); continue; } if (bind_port(iport) < 0) { - fprintf(stderr, LOG_PREFIX "cannot bind to port: %d. abort.\r\n", iport); + fprintf(stderr, LOG_PREFIX "cannot bind to port: %d. abort.\n", iport); exit(3); } bound_ports++; @@ -2212,26 +2216,26 @@ main(int argc, char *argv[], char *envp[]) case 'h': default: fprintf(stderr, - "usage: %s [-vTmMaAbBdD] [-l log_file] [-f conf] [-p port] [-t tunnel] [-c client_command]\r\n", argv[0]); + "usage: %s [-vTmMaAbBdD] [-l log_file] [-f conf] [-p port] [-t tunnel] [-c client_command]\n", argv[0]); fprintf(stderr, - "\t-v: provide verbose messages\r\n" - "\t-T: provide timeout connection info\r\n" - "\t-d/-D: do/not enter daemon mode (default: %s)\r\n" - "\t-a/-A: do/not use asynchronous service ack (deafult: %s)\r\n" - "\t-b/-B: do/not use non-blocking socket mode (default: %s)\r\n" - "\t-m/-M: do/not use asynchronous logattempts (default: %s)\r\n" - "\t-f: read configuration from file (default: %s)\r\n", + "\t-v: provide verbose messages\n" + "\t-T: provide timeout connection info\n" + "\t-d/-D: do/not enter daemon mode (default: %s)\n" + "\t-a/-A: do/not use asynchronous service ack (deafult: %s)\n" + "\t-b/-B: do/not use non-blocking socket mode (default: %s)\n" + "\t-m/-M: do/not use asynchronous logattempts (default: %s)\n" + "\t-f: read configuration from file (default: %s)\n", as_daemon ? "true" : "false", g_async_ack ? "true" : "false", g_nonblock ? "true" : "false", g_async_logattempt ? "true" : "false", BBSHOME "/" FN_CONF_BINDPORTS); fprintf(stderr, - "\t-l: log meesages into log_file\r\n" - "\t-p: bind (listen) to specific port\r\n" - "\t-t: create tunnel in given path\r\n" - "\t-c: spawn a (tunnel) client after initialization\r\n" - "\t-r: the command to retry spawning clients\r\n" + "\t-l: log meesages into log_file\n" + "\t-p: bind (listen) to specific port\n" + "\t-t: create tunnel in given path\n" + "\t-c: spawn a (tunnel) client after initialization\n" + "\t-r: the command to retry spawning clients\n" ); return 1; } @@ -2239,7 +2243,7 @@ main(int argc, char *argv[], char *envp[]) if (setrlimit(RLIMIT_NOFILE, &r) < 0) { - fprintf(stderr, LOG_PREFIX "warning: cannot increase max fd to %u...\r\n", LOGIND_MAX_FDS); + fprintf(stderr, LOG_PREFIX "warning: cannot increase max fd to %u...\n", LOGIND_MAX_FDS); } chdir(BBSHOME); @@ -2247,7 +2251,7 @@ main(int argc, char *argv[], char *envp[]) if (g_async_logattempt && logattempt_daemon() < 0) { - fprintf(stderr, LOG_PREFIX "error: cannot fork to handle logattempts.\r\n"); + fprintf(stderr, LOG_PREFIX "error: cannot fork to handle logattempts.\n"); return 5; } @@ -2258,7 +2262,7 @@ main(int argc, char *argv[], char *envp[]) // bind ports if (port && bind_port(port) < 0) { - fprintf(stderr, LOG_PREFIX "cannot bind to port: %d. abort.\r\n", port); + fprintf(stderr, LOG_PREFIX "cannot bind to port: %d. abort.\n", port); return 3; } if (port) @@ -2275,12 +2279,12 @@ main(int argc, char *argv[], char *envp[]) if (!bound_ports) { - fprintf(stderr, LOG_PREFIX "error: no ports to bind. abort.\r\n"); + fprintf(stderr, LOG_PREFIX "error: no ports to bind. abort.\n"); return 4; } if (!*tunnel_path) { - fprintf(stderr, LOG_PREFIX "error: must assign one tunnel path. abort.\r\n"); + fprintf(stderr, LOG_PREFIX "error: must assign one tunnel path. abort.\n"); return 4; } @@ -2292,10 +2296,10 @@ main(int argc, char *argv[], char *envp[]) fprintf(stderr, LOG_PREFIX "creating tunnel: %s...", tunnel_path); if ( (tfd = tobindex(tunnel_path, 1, _set_bind_opt, 1)) < 0) { - fprintf(stderr, LOG_PREFIX "cannot create tunnel. abort.\r\n"); + fprintf(stderr, LOG_PREFIX "cannot create tunnel. abort.\n"); return 2; } - fprintf(stderr, "ok.\r\n"); + fprintf(stderr, "ok.\n"); event_set(&ev_tunnel, tfd, EV_READ | EV_PERSIST, tunnel_cb, &ev_tunnel); event_add(&ev_tunnel, NULL); @@ -2304,7 +2308,7 @@ main(int argc, char *argv[], char *envp[]) { char *logfile_path = NULL; if (g_logfile_path[0]) logfile_path = g_logfile_path; - fprintf(stderr, LOG_PREFIX "start daemonize\r\n"); + fprintf(stderr, LOG_PREFIX "start daemonize\n"); daemonize(BBSHOME "/run/logind.pid", logfile_path); // because many of the libraries used in this daemon (for example, @@ -2324,17 +2328,17 @@ main(int argc, char *argv[], char *envp[]) if (*tclient_cmd) { int r; - fprintf(stderr, LOG_PREFIX "invoking client...\r\n"); + fprintf(stderr, LOG_PREFIX "invoking client...\n"); // XXX this should NOT be a blocking call. r = system(tclient_cmd); if (g_verbose) - fprintf(stderr, LOG_PREFIX "client return value = %d\r\n", r); + fprintf(stderr, LOG_PREFIX "client return value = %d\n", r); } // warning: after daemonize, the directory was changed to root (/)... { time4_t tnow = time(0); - fprintf(stderr, LOG_PREFIX "%s: start event dispatch.\r\n", + fprintf(stderr, LOG_PREFIX "%s: start event dispatch.\n", Cdate(&tnow)); } event_dispatch(); diff --git a/pttbbs/include/cmbbs.h b/pttbbs/include/cmbbs.h index 3173022c..d4f6c356 100644 --- a/pttbbs/include/cmbbs.h +++ b/pttbbs/include/cmbbs.h @@ -42,6 +42,14 @@ int stampfile_u(char *fpath, fileheader_t *fh); // does not zero existing data i int log_payment(const char *filename, int money, int oldm, int newm, const char *reason, time4_t now); +/* banip.c */ +typedef unsigned long IPv4; // derived from in_addr.s_addr +typedef void *BanIpList; +int in_banip_list(const BanIpList *list, const char *ip); +int in_banip_list_addr(const BanIpList *list, IPv4 addr); +BanIpList *load_banip_list(const char *filename, FILE *err); +BanIpList *free_banip_list(BanIpList *list); + /* cache.c */ #define search_ulist(uid) search_ulistn(uid, 1) #define getbcache(bid) (bcache + bid - 1) diff --git a/pttbbs/include/common.h b/pttbbs/include/common.h index 8787f20a..6eb0e22f 100644 --- a/pttbbs/include/common.h +++ b/pttbbs/include/common.h @@ -11,6 +11,7 @@ #define FN_CONF_EDITABLE "etc/editable" // 站務可編輯的系統檔案列表 #define FN_CONF_RESERVED_ID "etc/reserved.id" // 保留系統用無法註冊的 ID #define FN_CONF_BINDPORTS "etc/bindports.conf" // 預設要提供連線服務的 port 列表 +#define FN_CONF_BANIP BBSHOME "/etc/banip.conf" // 禁止連線的 IP 列表 // BBS Data File Names #define FN_PASSWD BBSHOME "/.PASSWDS" /* User records */ |