diff --git a/Makefile.am b/Makefile.am index 3965c88..6356b46 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,20 +1,4 @@ -bin_PROGRAMS = src/bip src/bipmkpw -src_bip_SOURCES = src/conf.y src/lex.l \ - src/bip.c src/bip.h \ - src/connection.c src/connection.h \ - src/defaults.h \ - src/irc.c src/irc.h \ - src/line.c src/line.h \ - src/log.c src/log.h \ - src/md5.c src/md5.h \ - src/path_util.c src/path_util.h \ - src/tuple.h \ - src/util.c src/util.h -src_bipmkpw_SOURCES = src/bipmkpw.c src/md5.c src/util.c -AM_YFLAGS= -d -BUILT_SOURCES = src/conf.c src/conf.h src/lex.c - -AM_CFLAGS=-Wall -Wextra -Werror +SUBDIRS = src dist_man_MANS = bip.1 bip.conf.5 bipmkpw.1 diff --git a/configure.ac b/configure.ac index c0630c7..b1a48a0 100644 --- a/configure.ac +++ b/configure.ac @@ -10,6 +10,7 @@ AC_CONFIG_HEADERS([src/config.h]) # Checks for programs AC_PROG_CC +AC_PROG_RANLIB AM_PROG_CC_C_O AC_PROG_INSTALL AM_PROG_LEX @@ -121,7 +122,7 @@ AS_IF([test "x$enable_pie" != "xno"], [ fi ]) -AC_CONFIG_FILES([Makefile]) +AC_CONFIG_FILES([Makefile src/Makefile]) AC_OUTPUT AS_IF([test "x$with_openssl" != "xno"], [ diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..cd2ea2b --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,24 @@ +noinst_LIBRARIES = libbip.a + +libbip_a_SOURCES = conf.y lex.l \ + bip.c bip.h \ + connection.c connection.h \ + defaults.h \ + irc.c irc.h \ + line.c line.h \ + log.c log.h \ + md5.c md5.h \ + path_util.c path_util.h \ + tuple.h \ + util.c util.h + +bin_PROGRAMS = bip bipmkpw + +bip_SOURCES = bip_main.c +bip_LDADD = libbip.a + +bipmkpw_SOURCES = bipmkpw.c md5.c util.c +AM_YFLAGS= -d +BUILT_SOURCES = conf.c conf.h lex.c + +#AM_CFLAGS=-Wall -Wextra -Werror diff --git a/src/bip.c b/src/bip.c index abb5afb..8552fdf 100644 --- a/src/bip.c +++ b/src/bip.c @@ -32,6 +32,8 @@ #include "line.h" #include "defaults.h" +#define S_CONF "bip.conf" + int sighup = 0; char *conf_log_root; @@ -56,6 +58,9 @@ int conf_log = DEFAULT_LOG; int conf_log_system = DEFAULT_LOG_SYSTEM; int conf_log_sync_interval = DEFAULT_LOG_SYNC_INTERVAL; +bip_t *_bip; +FILE *conf_global_log_file; + list_t *parse_conf(FILE *file, int *err); void conf_die(bip_t *bip, char *fmt, ...); static char *get_tuple_pvalue(list_t *tuple_l, int lex); @@ -63,6 +68,7 @@ void bip_notify(struct link_client *ic, char *fmt, ...); void adm_list_connections(struct link_client *ic, struct bipuser *bu); void free_conf(list_t *l); + #ifdef HAVE_OIDENTD #define OIDENTD_FILENAME ".oidentd.conf" #endif @@ -156,40 +162,6 @@ void conf_die(bip_t *bip, char *fmt, ...) va_end(ap); } -FILE *conf_global_log_file; - -static pid_t daemonize(void) -{ - switch (fork()) { - case -1: - fatal("Fork failed"); - break; - case 0: - break; - default: - _exit(0); - } - - if (setsid() < 0) - fatal("setsid() failed"); - - switch (fork()) { - case -1: - fatal("Fork failed"); - break; - case 0: - break; - default: - _exit(0); - } - - close(0); - close(1); - close(2); - /* This better be the very last action since fatal makes use of - * conf_global_log_file */ - return getpid(); -} /* RACE CONDITION! */ int do_pid_stuff(void) @@ -265,32 +237,6 @@ pid_is_there: return 0; } -#define S_CONF "bip.conf" - -static void usage(char *name) -{ - printf( -"Usage: %s [-f config_file] [-h] [-n]\n" -" -f config_file: Use config_file as the configuration file\n" -" If no config file is given %s will try to open ~/.bip/" S_CONF "\n" -" -n: Don't daemonize, log in stderr\n" -" -s: Bip HOME, default parent directory for client certificate,\n" -" configuration, logs, pid, oidentd\n" -" -v: Print version and exit\n" -" -h: This help\n", name, name); - exit(1); -} - -static void version() -{ - printf( -"Bip IRC Proxy - " PACKAGE_VERSION "\n" -"Copyright © Arnaud Cornet and Loïc Gomez (2004 - 2008)\n" -"Distributed under the GNU Public License Version 2\n"); -} - -bip_t *_bip; - void reload_config(int i) { (void)i; @@ -1100,23 +1046,6 @@ out_conf_error: return 0; } -static void log_file_setup(void) -{ - char buf[4096]; - - if (conf_log_system && conf_daemonize) { - if (conf_global_log_file && conf_global_log_file != stderr) - fclose(conf_global_log_file); - snprintf(buf, 4095, "%s/bip.log", conf_log_root); - FILE *f = fopen(buf, "a"); - if (!f) - fatal("Can't open %s: %s", buf, strerror(errno)); - conf_global_log_file = f; - } else { - conf_global_log_file = stderr; - } -} - void check_rlimits() { int r, cklim; @@ -1192,186 +1121,6 @@ void check_rlimits() mylog(LOG_WARN, "You can check your limits with `ulimit -a'"); } -int main(int argc, char **argv) -{ - FILE *conf = NULL; - char *confpath = NULL; - int ch; - int r, fd; - char buf[30]; - bip_t bip; - - bip_init(&bip); - _bip = &bip; - - conf_ip = bip_strdup("0.0.0.0"); - conf_port = 7778; - conf_css = 0; - - signal(SIGPIPE, SIG_IGN); - signal(SIGHUP, reload_config); - signal(SIGINT, bad_quit); - signal(SIGQUIT, bad_quit); - signal(SIGTERM, bad_quit); - signal(SIGXFSZ, rlimit_bigfile_reached); - signal(SIGXCPU, rlimit_cpu_reached); - - conf_log_root = NULL; - conf_log_format = bip_strdup(DEFAULT_LOG_FORMAT); - conf_log_level = DEFAULT_LOG_LEVEL; - conf_reconn_timer = DEFAULT_RECONN_TIMER; - conf_daemonize = 1; - conf_global_log_file = stderr; - conf_pid_file = NULL; -#ifdef HAVE_LIBSSL - conf_ssl_certfile = NULL; - conf_client_ciphers = NULL; - conf_server_default_ciphers = NULL; - conf_client_dh_file = NULL; -#endif - - while ((ch = getopt(argc, argv, "hvnf:s:")) != -1) { - switch (ch) { - case 'f': - confpath = bip_strdup(optarg); - break; - case 'n': - conf_daemonize = 0; - break; - case 's': - conf_biphome = bip_strdup(optarg); - break; - case 'v': - version(); - exit(0); - break; - default: - version(); - usage(argv[0]); - } - } - - umask(0027); - - check_rlimits(); - - char *home = NULL; /* oidentd path searching ignores conf_biphome */ - home = getenv("HOME"); - if (!home && !conf_biphome) { - conf_die(&bip, "no value for environment variable $HOME," - "use '-s' parameter"); - return 0; - } - - if (!conf_biphome) { - conf_biphome = bip_malloc(strlen(home) + strlen("/.bip") + 1); - strcpy(conf_biphome, home); - strcat(conf_biphome, "/.bip"); - } - -#ifdef HAVE_OIDENTD - if (!bip.oidentdpath) { - bip.oidentdpath = bip_malloc(strlen(conf_biphome) + 1 + - strlen(OIDENTD_FILENAME) + 1); - strcpy(bip.oidentdpath, conf_biphome); - strcat(bip.oidentdpath, "/"); - strcat(bip.oidentdpath, OIDENTD_FILENAME); - } -#endif - - if (!confpath) { - confpath = bip_malloc(strlen(conf_biphome) + 1 + - strlen(S_CONF) + 1); - strcpy(confpath, conf_biphome); - strcat(confpath, "/"); - strcat(confpath, S_CONF); - } - conf = fopen(confpath, "r"); - if (!conf) - fatal("config file not found"); - - r = fireup(&bip, conf); - fclose(conf); - if (!r) - fatal("Not starting: error in config file."); - - if (!conf_log_root) { - char *ap = "/logs"; - conf_log_root = bip_malloc(strlen(conf_biphome) + - strlen(ap) + 1); - strcpy(conf_log_root, conf_biphome); - strcat(conf_log_root, ap); - mylog(LOG_INFO, "Default log root: %s", conf_log_root); - } - if (!conf_pid_file) { - char *pid = "/bip.pid"; - conf_pid_file = bip_malloc(strlen(conf_biphome) + - strlen(pid) + 1); - strcpy(conf_pid_file, conf_biphome); - strcat(conf_pid_file, pid); - mylog(LOG_INFO, "Default pid file: %s", conf_pid_file); - } - -#ifdef HAVE_LIBSSL - if (conf_css) { - int e; - struct stat fs; - - if (!conf_ssl_certfile) { - conf_ssl_certfile = default_path(conf_biphome, "bip.pem", - "SSL certificate"); - } - assert_path_exists(conf_ssl_certfile); - - e = stat(conf_ssl_certfile, &fs); - if (e) - mylog(LOG_WARN, "Unable to check PEM file, stat(%s): " - "%s", conf_ssl_certfile, strerror(errno)); - else if ((fs.st_mode & S_IROTH) | (fs.st_mode & S_IWOTH)) - mylog(LOG_ERROR, "PEM file %s should not be world " - "readable / writable. Please fix the modes.", - conf_ssl_certfile); - - if (conf_client_dh_file) { - assert_path_exists(conf_client_dh_file); - } - } -#endif - - check_dir(conf_log_root, 1); - fd = do_pid_stuff(); - pid_t pid = 0; - - log_file_setup(); - if (conf_daemonize) - pid = daemonize(); - else - pid = getpid(); - snprintf(buf, 29, "%ld\n", (long unsigned int)pid); - write(fd, buf, strlen(buf)); - close(fd); - - bip.listener = listen_new(conf_ip, conf_port, conf_css); - if (!bip.listener || bip.listener->connected == CONN_ERROR) - fatal("Could not create listening socket"); - - for (;;) { - irc_main(&bip); - - sighup = 0; - - conf = fopen(confpath, "r"); - if (!conf) - fatal("%s config file not found", confpath); - fireup(&bip, conf); - fclose(conf); - - /* re-open to allow logfile rotate */ - log_file_setup(); - } - return 1; -} - #define RET_STR_LEN 256 #define LINE_SIZE_LIM 70 void adm_print_connection(struct link_client *ic, struct link *lnk, diff --git a/src/bip_main.c b/src/bip_main.c new file mode 100644 index 0000000..5c7fa1f --- /dev/null +++ b/src/bip_main.c @@ -0,0 +1,321 @@ +/* + * $Id: bip.c,v 1.39 2005/04/21 06:58:50 nohar Exp $ + * + * This file is part of the bip project + * Copyright (C) 2004 2005 Arnaud Cornet and Loïc Gomez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * See the file "COPYING" for the exact licensing terms. + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "irc.h" +#include "conf.h" +#include "path_util.h" +#include "tuple.h" +#include "log.h" +#include "bip.h" +#include "line.h" +#include "defaults.h" + +#define S_CONF "bip.conf" + +extern int sighup; +extern char *conf_log_root; +extern char *conf_log_format; +extern int conf_log_level; +extern char *conf_ip; +extern unsigned short conf_port; +extern int conf_css; +#ifdef HAVE_LIBSSL +extern char *conf_ssl_certfile; +extern char *conf_client_ciphers; +extern char *conf_client_dh_file; +extern char *conf_server_default_ciphers; +#endif +extern int conf_daemonize; +extern char *conf_pid_file; +extern char *conf_biphome; +extern int conf_reconn_timer; + +/* log options, for sure the trickiest :) */ +extern int conf_log; +extern int conf_log_system; +extern int conf_log_sync_interval; +extern bip_t *_bip; +extern FILE *conf_global_log_file; + +void reload_config(int i); +void bad_quit(int i); +void check_rlimits(); +void rlimit_cpu_reached(int i); +void rlimit_bigfile_reached(int i); +void conf_die(bip_t *bip, char *fmt, ...); +int fireup(bip_t *bip, FILE *conf); +int do_pid_stuff(void); + +static void usage(char *name) +{ + printf( +"Usage: %s [-f config_file] [-h] [-n]\n" +" -f config_file: Use config_file as the configuration file\n" +" If no config file is given %s will try to open ~/.bip/" S_CONF "\n" +" -n: Don't daemonize, log in stderr\n" +" -s: Bip HOME, default parent directory for client certificate,\n" +" configuration, logs, pid, oidentd\n" +" -v: Print version and exit\n" +" -h: This help\n", name, name); + exit(1); +} + +static void version() +{ + printf( +"Bip IRC Proxy - " PACKAGE_VERSION "\n" +"Copyright © Arnaud Cornet and Loïc Gomez (2004 - 2008)\n" +"Distributed under the GNU Public License Version 2\n"); +} + +static void log_file_setup(void) +{ + char buf[4096]; + + if (conf_log_system && conf_daemonize) { + if (conf_global_log_file && conf_global_log_file != stderr) + fclose(conf_global_log_file); + snprintf(buf, 4095, "%s/bip.log", conf_log_root); + FILE *f = fopen(buf, "a"); + if (!f) + fatal("Can't open %s: %s", buf, strerror(errno)); + conf_global_log_file = f; + } else { + conf_global_log_file = stderr; + } +} + +static pid_t daemonize(void) +{ + switch (fork()) { + case -1: + fatal("Fork failed"); + break; + case 0: + break; + default: + _exit(0); + } + + if (setsid() < 0) + fatal("setsid() failed"); + + switch (fork()) { + case -1: + fatal("Fork failed"); + break; + case 0: + break; + default: + _exit(0); + } + + close(0); + close(1); + close(2); + /* This better be the very last action since fatal makes use of + * conf_global_log_file */ + return getpid(); +} + +int main(int argc, char **argv) +{ + FILE *conf = NULL; + char *confpath = NULL; + int ch; + int r, fd; + char buf[30]; + bip_t bip; + + bip_init(&bip); + _bip = &bip; + + conf_ip = bip_strdup("0.0.0.0"); + conf_port = 7778; + conf_css = 0; + + signal(SIGPIPE, SIG_IGN); + signal(SIGHUP, reload_config); + signal(SIGINT, bad_quit); + signal(SIGQUIT, bad_quit); + signal(SIGTERM, bad_quit); + signal(SIGXFSZ, rlimit_bigfile_reached); + signal(SIGXCPU, rlimit_cpu_reached); + + conf_log_root = NULL; + conf_log_format = bip_strdup(DEFAULT_LOG_FORMAT); + conf_log_level = DEFAULT_LOG_LEVEL; + conf_reconn_timer = DEFAULT_RECONN_TIMER; + conf_daemonize = 1; + conf_global_log_file = stderr; + conf_pid_file = NULL; +#ifdef HAVE_LIBSSL + conf_ssl_certfile = NULL; + conf_client_ciphers = NULL; + conf_server_default_ciphers = NULL; + conf_client_dh_file = NULL; +#endif + + while ((ch = getopt(argc, argv, "hvnf:s:")) != -1) { + switch (ch) { + case 'f': + confpath = bip_strdup(optarg); + break; + case 'n': + conf_daemonize = 0; + break; + case 's': + conf_biphome = bip_strdup(optarg); + break; + case 'v': + version(); + exit(0); + break; + default: + version(); + usage(argv[0]); + } + } + + umask(0027); + + check_rlimits(); + + char *home = NULL; /* oidentd path searching ignores conf_biphome */ + home = getenv("HOME"); + if (!home && !conf_biphome) { + conf_die(&bip, "no value for environment variable $HOME," + "use '-s' parameter"); + return 0; + } + + if (!conf_biphome) { + conf_biphome = bip_malloc(strlen(home) + strlen("/.bip") + 1); + strcpy(conf_biphome, home); + strcat(conf_biphome, "/.bip"); + } + +#ifdef HAVE_OIDENTD + if (!bip.oidentdpath) { + bip.oidentdpath = bip_malloc(strlen(conf_biphome) + 1 + + strlen(OIDENTD_FILENAME) + 1); + strcpy(bip.oidentdpath, conf_biphome); + strcat(bip.oidentdpath, "/"); + strcat(bip.oidentdpath, OIDENTD_FILENAME); + } +#endif + + if (!confpath) { + confpath = bip_malloc(strlen(conf_biphome) + 1 + + strlen(S_CONF) + 1); + strcpy(confpath, conf_biphome); + strcat(confpath, "/"); + strcat(confpath, S_CONF); + } + conf = fopen(confpath, "r"); + if (!conf) + fatal("config file not found"); + + r = fireup(&bip, conf); + fclose(conf); + if (!r) + fatal("Not starting: error in config file."); + + if (!conf_log_root) { + char *ap = "/logs"; + conf_log_root = bip_malloc(strlen(conf_biphome) + + strlen(ap) + 1); + strcpy(conf_log_root, conf_biphome); + strcat(conf_log_root, ap); + mylog(LOG_INFO, "Default log root: %s", conf_log_root); + } + if (!conf_pid_file) { + char *pid = "/bip.pid"; + conf_pid_file = bip_malloc(strlen(conf_biphome) + + strlen(pid) + 1); + strcpy(conf_pid_file, conf_biphome); + strcat(conf_pid_file, pid); + mylog(LOG_INFO, "Default pid file: %s", conf_pid_file); + } + +#ifdef HAVE_LIBSSL + if (conf_css) { + int e; + struct stat fs; + + if (!conf_ssl_certfile) { + conf_ssl_certfile = default_path(conf_biphome, "bip.pem", + "SSL certificate"); + } + assert_path_exists(conf_ssl_certfile); + + e = stat(conf_ssl_certfile, &fs); + if (e) + mylog(LOG_WARN, "Unable to check PEM file, stat(%s): " + "%s", conf_ssl_certfile, strerror(errno)); + else if ((fs.st_mode & S_IROTH) | (fs.st_mode & S_IWOTH)) + mylog(LOG_ERROR, "PEM file %s should not be world " + "readable / writable. Please fix the modes.", + conf_ssl_certfile); + + if (conf_client_dh_file) { + assert_path_exists(conf_client_dh_file); + } + } +#endif + + check_dir(conf_log_root, 1); + fd = do_pid_stuff(); + pid_t pid = 0; + + log_file_setup(); + if (conf_daemonize) + pid = daemonize(); + else + pid = getpid(); + snprintf(buf, 29, "%ld\n", (long unsigned int)pid); + write(fd, buf, strlen(buf)); + close(fd); + + bip.listener = listen_new(conf_ip, conf_port, conf_css); + if (!bip.listener || bip.listener->connected == CONN_ERROR) + fatal("Could not create listening socket"); + + for (;;) { + irc_main(&bip); + + sighup = 0; + + conf = fopen(confpath, "r"); + if (!conf) + fatal("%s config file not found", confpath); + fireup(&bip, conf); + fclose(conf); + + /* re-open to allow logfile rotate */ + log_file_setup(); + } + return 1; +}