Compare commits
13 Commits
959e8a5bfb
...
c1ba6a8e8a
Author | SHA1 | Date | |
---|---|---|---|
|
c1ba6a8e8a | ||
|
400b0d66de | ||
|
e643cd4944 | ||
|
8f3b313776 | ||
|
d49f135370 | ||
|
5f054bdded | ||
|
76c9ee11de | ||
|
b810ba0f77 | ||
|
d19099eb3c | ||
|
99a1244e46 | ||
|
edd460a8fa | ||
|
4cd5bdb381 | ||
c6a872ed61 |
@ -3,7 +3,7 @@ if COND_WANT_TESTS
|
|||||||
endif
|
endif
|
||||||
SUBDIRS = src . $(MAYBE_TESTS)
|
SUBDIRS = src . $(MAYBE_TESTS)
|
||||||
|
|
||||||
dist_man_MANS = bip.1 bip.conf.5 bipmkpw.1
|
dist_man_MANS = bip.1 bip.conf.5 bipmkpw.1 bipgenconfig.1
|
||||||
|
|
||||||
examplesdir = $(prefix)/share/doc/bip/examples/
|
examplesdir = $(prefix)/share/doc/bip/examples/
|
||||||
dist_examples_DATA = samples/bip.conf samples/bip.vim
|
dist_examples_DATA = samples/bip.conf samples/bip.vim
|
||||||
|
@ -146,7 +146,7 @@ Defines the delay between each logfiles sync to the disk. Must be a non null
|
|||||||
positive integer.
|
positive integer.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fBreconn_timer\fP (default: \fB120\fP)
|
\fBreconn_timer\fP (default: \fB30\fP)
|
||||||
Defines the initial delay (in seconds) before a reconnection attempt.
|
Defines the initial delay (in seconds) before a reconnection attempt.
|
||||||
The delay increases with the number of attempts:
|
The delay increases with the number of attempts:
|
||||||
delay = reconn_timer * number of attempts
|
delay = reconn_timer * number of attempts
|
||||||
@ -227,7 +227,7 @@ This option should of course not be enabled if \fBbacklog_lines\fP is 0 !
|
|||||||
If you still want to do so, don't forget to \fB/BIP BLRESET\fP sometimes.
|
If you still want to do so, don't forget to \fB/BIP BLRESET\fP sometimes.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fBbacklog_lines\fP (default: \fB10\fP)
|
\fBbacklog_lines\fP (default: \fB0\fP)
|
||||||
If set to 0, BIP will replay all the logs since last client disconnect. Else,
|
If set to 0, BIP will replay all the logs since last client disconnect. Else,
|
||||||
it'll replay exactly \fBbacklog_lines\fP lines on each channel and privates.
|
it'll replay exactly \fBbacklog_lines\fP lines on each channel and privates.
|
||||||
Be aware that BIP will replay \fBbacklog_lines\fP lines of all privates, even
|
Be aware that BIP will replay \fBbacklog_lines\fP lines of all privates, even
|
||||||
|
68
configure.ac
68
configure.ac
@ -94,6 +94,74 @@ if test "$ap_cv_cc_pie" = "yes"; then
|
|||||||
enable_pie=yes
|
enable_pie=yes
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
AC_CACHE_CHECK([whether $CC accepts hardening flags], [ap_cv_cc_hardening], [
|
||||||
|
save_CFLAGS=$CFLAGS
|
||||||
|
save_LDFLAGS=$LDFLAGS
|
||||||
|
CFLAGS="$CFLAGS -O2 -D_FORTIFY_SOURCE=2 -fstack-protector-strong -fstack-clash-protection -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack -Wl,-z,separate-code"
|
||||||
|
AC_RUN_IFELSE([AC_LANG_SOURCE([[static int foo[30000]; int main () { return 0; }]])],
|
||||||
|
[ap_cv_cc_hardening=yes],
|
||||||
|
[ap_cv_cc_hardening=no],
|
||||||
|
[ap_cv_cc_hardening=yes]
|
||||||
|
)
|
||||||
|
CFLAGS=$save_CFLAGS
|
||||||
|
])
|
||||||
|
if test "$ap_cv_cc_hardening" = "yes"; then
|
||||||
|
CFLAGS="$CFLAGS -O2 -D_FORTIFY_SOURCE=2 -fstack-protector-strong -fstack-clash-protection -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack -Wl,-z,separate-code"
|
||||||
|
enable_cc_hardening=yes
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_CACHE_CHECK([whether $CC accepts some warning flags], [ap_cv_cc_warnings], [
|
||||||
|
save_CFLAGS=$CFLAGS
|
||||||
|
save_LDFLAGS=$LDFLAGS
|
||||||
|
CFLAGS="$CFLAGS -Wformat-overflow=2 -Wformat-truncation=2 -Wtrampolines -Warray-bounds=2 -Wimplicit-fallthrough=3 -Wtraditional-conversion -Wshift-overflow=2 -Wstringop-overflow=4 -Wlogical-op -Wduplicated-cond -Wduplicated-branches -Wformat-signedness -Wstack-usage=1000000 -Wcast-align=strict"
|
||||||
|
AC_RUN_IFELSE([AC_LANG_SOURCE([[static int foo[30000]; int main () { return 0; }]])],
|
||||||
|
[ap_cv_cc_warnings=yes],
|
||||||
|
[ap_cv_cc_warnings=no],
|
||||||
|
[ap_cv_cc_warnings=yes]
|
||||||
|
)
|
||||||
|
CFLAGS=$save_CFLAGS
|
||||||
|
])
|
||||||
|
if test "$ap_cv_cc_warnings" = "yes"; then
|
||||||
|
CFLAGS="$CFLAGS -Wformat-overflow=2 -Wformat-truncation=2 -Wtrampolines -Warray-bounds=2 -Wimplicit-fallthrough=3 -Wtraditional-conversion -Wshift-overflow=2 -Wstringop-overflow=4 -Wlogical-op -Wduplicated-cond -Wduplicated-branches -Wformat-signedness -Wstack-usage=1000000 -Wcast-align=strict"
|
||||||
|
enable_cc_warnings=yes
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_CACHE_CHECK([whether $CC accepts some supplementary warning flags], [ap_cv_cc_warnings2], [
|
||||||
|
save_CFLAGS=$CFLAGS
|
||||||
|
save_LDFLAGS=$LDFLAGS
|
||||||
|
CFLAGS="$CFLAGS -Wformat=2 -Wformat-security -Wnull-dereference -Wstack-protector -Walloca -Wvla -Wcast-qual -Wconversion -Wshadow -Wstrict-overflow=4 -Wstrict-prototypes -Wswitch-default -Wswitch-enum"
|
||||||
|
AC_RUN_IFELSE([AC_LANG_SOURCE([[static int foo[30000]; int main () { return 0; }]])],
|
||||||
|
[ap_cv_cc_warnings2=yes],
|
||||||
|
[ap_cv_cc_warnings2=no],
|
||||||
|
[ap_cv_cc_warnings2=yes]
|
||||||
|
)
|
||||||
|
CFLAGS=$save_CFLAGS
|
||||||
|
])
|
||||||
|
if test "$ap_cv_cc_warnings2" = "yes"; then
|
||||||
|
CFLAGS="$CFLAGS -Wformat=2 -Wformat-security -Wnull-dereference -Wstack-protector -Walloca -Wvla -Wcast-qual -Wconversion -Wshadow -Wstrict-overflow=4 -Wstrict-prototypes -Wswitch-default -Wswitch-enum"
|
||||||
|
enable_cc_warnings2=yes
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AC_CACHE_CHECK([whether $CC accepts -Warith-conversion flag], [ap_cv_cc_warith], [
|
||||||
|
save_CFLAGS=$CFLAGS
|
||||||
|
save_LDFLAGS=$LDFLAGS
|
||||||
|
CFLAGS="$CFLAGS -Warith-conversion"
|
||||||
|
AC_RUN_IFELSE([AC_LANG_SOURCE([[static int foo[30000]; int main () { return 0; }]])],
|
||||||
|
[ap_cv_cc_warith=yes],
|
||||||
|
[ap_cv_cc_warith=no],
|
||||||
|
[ap_cv_cc_warith=yes]
|
||||||
|
)
|
||||||
|
CFLAGS=$save_CFLAGS
|
||||||
|
])
|
||||||
|
if test "$ap_cv_cc_warith" = "yes"; then
|
||||||
|
CFLAGS="$CFLAGS -Warith-conversion"
|
||||||
|
enable_warith_conversion=yes
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
PKG_CHECK_MODULES([CHECK], [check >= 0.9.6], [enable_tests=yes], [enable_tests=no])
|
PKG_CHECK_MODULES([CHECK], [check >= 0.9.6], [enable_tests=yes], [enable_tests=no])
|
||||||
AM_CONDITIONAL([COND_WANT_TESTS], [test "$enable_tests" = yes])
|
AM_CONDITIONAL([COND_WANT_TESTS], [test "$enable_tests" = yes])
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@
|
|||||||
# Sets the initial delay (in seconds) before a reconnection attempt.
|
# Sets the initial delay (in seconds) before a reconnection attempt.
|
||||||
# The delay increases with the number of attempts:
|
# The delay increases with the number of attempts:
|
||||||
# delay = reconn_timer * number of attempts
|
# delay = reconn_timer * number of attempts
|
||||||
#reconn_timer = 120;
|
#reconn_timer = 30;
|
||||||
|
|
||||||
# Network definition, a name and server info
|
# Network definition, a name and server info
|
||||||
#network {
|
#network {
|
||||||
|
@ -119,7 +119,7 @@ my %optdesc = (
|
|||||||
'optional' => 1,
|
'optional' => 1,
|
||||||
'depends' => 'log', 'depval' => 'true',
|
'depends' => 'log', 'depval' => 'true',
|
||||||
'desc' => 'Do you want to activate backlog {play back logs} system ?' },
|
'desc' => 'Do you want to activate backlog {play back logs} system ?' },
|
||||||
'backlog_lines' => { 'type' => 'i', 'adv' => 0, 'default' => '10',
|
'backlog_lines' => { 'type' => 'i', 'adv' => 0, 'default' => '0',
|
||||||
'optional' => 1,
|
'optional' => 1,
|
||||||
'depends' => 'backlog', 'depval' => 'true',
|
'depends' => 'backlog', 'depval' => 'true',
|
||||||
'desc' => 'How much line do you want bip to play back upon client connect' .
|
'desc' => 'How much line do you want bip to play back upon client connect' .
|
||||||
|
@ -36,9 +36,4 @@ bipmkpw_LDADD = libbip.a libbiplex.a $(OPENSSL_LIBS)
|
|||||||
AM_YFLAGS= -d
|
AM_YFLAGS= -d
|
||||||
BUILT_SOURCES = conf.c conf.h lex.c
|
BUILT_SOURCES = conf.c conf.h lex.c
|
||||||
|
|
||||||
AM_CFLAGS=-Wall -Wextra -Werror \
|
AM_CFLAGS=-Wall -Wextra -Werror -Wundef -Wpedantic
|
||||||
-O2 \
|
|
||||||
-D_FORTIFY_SOURCE=2 \
|
|
||||||
-fstack-protector-strong -fstack-clash-protection \
|
|
||||||
-Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack -Wl,-z,separate-code \
|
|
||||||
-Wpedantic -Wformat=2 -Wformat-overflow=2 -Wformat-truncation=2 -Wformat-security -Wnull-dereference -Wstack-protector -Wtrampolines -Walloca -Wvla -Warray-bounds=2 -Wimplicit-fallthrough=3 -Wtraditional-conversion -Wshift-overflow=2 -Wcast-qual -Wstringop-overflow=4 -Wconversion -Warith-conversion -Wlogical-op -Wduplicated-cond -Wduplicated-branches -Wformat-signedness -Wshadow -Wstrict-overflow=4 -Wundef -Wstrict-prototypes -Wswitch-default -Wswitch-enum -Wstack-usage=1000000 -Wcast-align=strict
|
|
||||||
|
97
src/bip.c
97
src/bip.c
@ -67,6 +67,7 @@ void conf_die(bip_t *bip, char *fmt, ...);
|
|||||||
static char *get_tuple_pvalue(list_t *tuple_l, int lex);
|
static char *get_tuple_pvalue(list_t *tuple_l, int lex);
|
||||||
void bip_notify(struct link_client *ic, char *fmt, ...);
|
void bip_notify(struct link_client *ic, char *fmt, ...);
|
||||||
void adm_list_connections(struct link_client *ic, struct bipuser *bu);
|
void adm_list_connections(struct link_client *ic, struct bipuser *bu);
|
||||||
|
struct link *find_link(const char *link_name, struct bipuser *bu);
|
||||||
void free_conf(list_t *l);
|
void free_conf(list_t *l);
|
||||||
|
|
||||||
|
|
||||||
@ -373,6 +374,45 @@ static int add_network(bip_t *bip, list_t *data)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void adm_bip_jump(struct link_client *ic, const char *conn_name,
|
||||||
|
int reset_timer)
|
||||||
|
{
|
||||||
|
struct link *lnk;
|
||||||
|
if (conn_name) {
|
||||||
|
lnk = find_link(conn_name, LINK(ic)->user);
|
||||||
|
if (!lnk) {
|
||||||
|
bip_notify(ic, "-- Cannot find connection named %s",
|
||||||
|
conn_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
goto do_the_jump;
|
||||||
|
} else {
|
||||||
|
lnk = LINK(ic);
|
||||||
|
}
|
||||||
|
|
||||||
|
do_the_jump:
|
||||||
|
if (!lnk->l_server) {
|
||||||
|
if (reset_timer) {
|
||||||
|
lnk->recon_timer = 0;
|
||||||
|
bip_notify(ic,
|
||||||
|
"-- %s is not connected, "
|
||||||
|
"timer has been reset, please wait",
|
||||||
|
conn_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int timer = (lnk->recon_timer ? lnk->recon_timer : 0);
|
||||||
|
bip_notify(ic,
|
||||||
|
"-- %s is not connected, "
|
||||||
|
"please wait for reconnect (%ds)",
|
||||||
|
conn_name, timer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE_LINE1(CONN(lnk->l_server), NULL, "QUIT", "jumpin' jumpin'");
|
||||||
|
connection_close(CONN(lnk->l_server));
|
||||||
|
bip_notify(ic, "-- Jumping to next server on %s", conn_name);
|
||||||
|
}
|
||||||
|
|
||||||
void adm_bip_delconn(bip_t *bip, struct link_client *ic, const char *conn_name)
|
void adm_bip_delconn(bip_t *bip, struct link_client *ic, const char *conn_name)
|
||||||
{
|
{
|
||||||
struct bipuser *user = LINK(ic)->user;
|
struct bipuser *user = LINK(ic)->user;
|
||||||
@ -664,6 +704,31 @@ static int add_connection(bip_t *bip, struct bipuser *user, list_t *data)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct link *find_link(const char *link_name, struct bipuser *bu)
|
||||||
|
{
|
||||||
|
list_iterator_t it;
|
||||||
|
|
||||||
|
// Immediately return NULL when bip user (bu) is NULL
|
||||||
|
if (!bu) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (list_it_init(&_bip->link_list, &it); list_it_item(&it);
|
||||||
|
list_it_next(&it)) {
|
||||||
|
struct link *lnk = list_it_item(&it);
|
||||||
|
if (!lnk)
|
||||||
|
continue;
|
||||||
|
// Only lookup in optionally specified user links
|
||||||
|
if (bu != lnk->user)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (strcmp(link_name, lnk->name) == 0)
|
||||||
|
return lnk;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static char *get_tuple_pvalue(list_t *tuple_l, int lex)
|
static char *get_tuple_pvalue(list_t *tuple_l, int lex)
|
||||||
{
|
{
|
||||||
struct tuple *t;
|
struct tuple *t;
|
||||||
@ -1331,9 +1396,10 @@ void adm_print_connection(struct link_client *ic, struct link *lnk,
|
|||||||
bufpos = buf;
|
bufpos = buf;
|
||||||
|
|
||||||
list_iterator_t itocs;
|
list_iterator_t itocs;
|
||||||
|
int i = 0;
|
||||||
for (list_it_init(&lnk->on_connect_send, &itocs);
|
for (list_it_init(&lnk->on_connect_send, &itocs);
|
||||||
list_it_item(&itocs);) {
|
list_it_item(&itocs) && i < 10; i++) {
|
||||||
bufpos = bip_strcatf_fit(&remaining, bufpos, "%s",
|
bufpos = bip_strcatf_fit(&remaining, bufpos, " on_connect_send: %s",
|
||||||
(char *)list_it_item(&itocs));
|
(char *)list_it_item(&itocs));
|
||||||
if (!bufpos) {
|
if (!bufpos) {
|
||||||
// if oversized, print and reset
|
// if oversized, print and reset
|
||||||
@ -1341,6 +1407,7 @@ void adm_print_connection(struct link_client *ic, struct link *lnk,
|
|||||||
bip_notify(ic, "%s", buf);
|
bip_notify(ic, "%s", buf);
|
||||||
remaining = LINE_SIZE_LIM;
|
remaining = LINE_SIZE_LIM;
|
||||||
bufpos = buf;
|
bufpos = buf;
|
||||||
|
list_it_next(&itocs);
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
// if ok, go to next item
|
// if ok, go to next item
|
||||||
@ -1992,8 +2059,8 @@ void adm_bip_help(struct link_client *ic, int admin, const char *subhelp)
|
|||||||
bip_notify(ic, "/BIP LIST networks|connections");
|
bip_notify(ic, "/BIP LIST networks|connections");
|
||||||
}
|
}
|
||||||
bip_notify(ic,
|
bip_notify(ic,
|
||||||
"/BIP JUMP # jump to next server (in same "
|
"/BIP JUMP [-f] [conn_name] # jump to next "
|
||||||
"network)");
|
"server (defaults to current network)");
|
||||||
bip_notify(ic,
|
bip_notify(ic,
|
||||||
"/BIP BLRESET [channel|query]# reset backlog "
|
"/BIP BLRESET [channel|query]# reset backlog "
|
||||||
"(this connection only). Add -q flag and the "
|
"(this connection only). Add -q flag and the "
|
||||||
@ -2046,8 +2113,14 @@ void adm_bip_help(struct link_client *ic, int admin, const char *subhelp)
|
|||||||
" Removing a connection will cause "
|
" Removing a connection will cause "
|
||||||
"its disconnection.");
|
"its disconnection.");
|
||||||
} else if (strcasecmp(subhelp, "JUMP") == 0) {
|
} else if (strcasecmp(subhelp, "JUMP") == 0) {
|
||||||
bip_notify(ic, "/BIP JUMP :");
|
bip_notify(ic, "/BIP JUMP [-f] [conn_name]:");
|
||||||
bip_notify(ic, " Jump to next server in current network.");
|
bip_notify(ic, " Jump to next server in current network.");
|
||||||
|
bip_notify(ic,
|
||||||
|
" If [conn_name] is set, jump to next server in "
|
||||||
|
"[conn_name] network instead.");
|
||||||
|
bip_notify(ic,
|
||||||
|
" If [-f] flag is used, also resets reconnect "
|
||||||
|
"timer.");
|
||||||
} else if (strcasecmp(subhelp, "BLRESET") == 0) {
|
} else if (strcasecmp(subhelp, "BLRESET") == 0) {
|
||||||
bip_notify(ic, "/BIP BLRESET :");
|
bip_notify(ic, "/BIP BLRESET :");
|
||||||
bip_notify(ic, " Reset backlog on this network.");
|
bip_notify(ic, " Reset backlog on this network.");
|
||||||
@ -2227,12 +2300,16 @@ int adm_bip(bip_t *bip, struct link_client *ic, struct line *line, int privmsg)
|
|||||||
bip_notify(ic, "-- Invalid INFO request");
|
bip_notify(ic, "-- Invalid INFO request");
|
||||||
}
|
}
|
||||||
} else if (irc_line_elem_case_equals(line, privmsg + 1, "JUMP")) {
|
} else if (irc_line_elem_case_equals(line, privmsg + 1, "JUMP")) {
|
||||||
if (LINK(ic)->l_server) {
|
if (irc_line_count(line) == privmsg + 2) {
|
||||||
WRITE_LINE1(CONN(LINK(ic)->l_server), NULL, "QUIT",
|
adm_bip_jump(ic, NULL, 0);
|
||||||
"jumpin' jumpin'");
|
} else if (irc_line_count(line) == privmsg + 3) {
|
||||||
connection_close(CONN(LINK(ic)->l_server));
|
adm_bip_jump(ic, irc_line_elem(line, privmsg + 2), 0);
|
||||||
|
} else if (irc_line_count(line) == privmsg + 4
|
||||||
|
&& irc_line_elem_equals(line, privmsg + 2, "-f")) {
|
||||||
|
adm_bip_jump(ic, irc_line_elem(line, privmsg + 3), 1);
|
||||||
|
} else {
|
||||||
|
bip_notify(ic, "-- Invalid usage (/BIP HELP JUMP)");
|
||||||
}
|
}
|
||||||
bip_notify(ic, "-- Jumping to next server");
|
|
||||||
} else if (irc_line_elem_case_equals(line, privmsg + 1, "BLRESET")) {
|
} else if (irc_line_elem_case_equals(line, privmsg + 1, "BLRESET")) {
|
||||||
if (irc_line_includes(line, privmsg + 2)) {
|
if (irc_line_includes(line, privmsg + 2)) {
|
||||||
if (irc_line_elem_equals(line, privmsg + 2, "-q")) {
|
if (irc_line_elem_equals(line, privmsg + 2, "-q")) {
|
||||||
|
@ -68,6 +68,7 @@ void rlimit_cpu_reached(int i);
|
|||||||
void rlimit_bigfile_reached(int i);
|
void rlimit_bigfile_reached(int i);
|
||||||
void conf_die(bip_t *bip, char *fmt, ...);
|
void conf_die(bip_t *bip, char *fmt, ...);
|
||||||
int fireup(bip_t *bip, FILE *conf);
|
int fireup(bip_t *bip, FILE *conf);
|
||||||
|
int check_ssl_files(int failmode);
|
||||||
int do_pid_stuff(void);
|
int do_pid_stuff(void);
|
||||||
|
|
||||||
static void usage(char *name)
|
static void usage(char *name)
|
||||||
@ -143,6 +144,44 @@ static pid_t daemonize(void)
|
|||||||
return getpid();
|
return getpid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int check_ssl_files(int failmode)
|
||||||
|
{
|
||||||
|
int e;
|
||||||
|
struct stat fs;
|
||||||
|
|
||||||
|
if (!conf_ssl_certfile) {
|
||||||
|
conf_ssl_certfile = default_path(
|
||||||
|
conf_biphome, "bip.pem", "SSL certificate");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failmode == HARD_FAIL)
|
||||||
|
assert_path_exists(conf_ssl_certfile);
|
||||||
|
else if (!check_path_exists(conf_ssl_certfile))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
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) {
|
||||||
|
if (failmode == HARD_FAIL) {
|
||||||
|
assert_path_exists(conf_client_dh_file);
|
||||||
|
} else if (!check_path_exists(conf_client_dh_file)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* all is well */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
FILE *conf = NULL;
|
FILE *conf = NULL;
|
||||||
@ -264,30 +303,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
#ifdef HAVE_LIBSSL
|
#ifdef HAVE_LIBSSL
|
||||||
if (conf_css) {
|
if (conf_css) {
|
||||||
int e;
|
check_ssl_files(HARD_FAIL);
|
||||||
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
|
#endif
|
||||||
|
|
||||||
|
@ -23,9 +23,9 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "md5.h"
|
#include "md5.h"
|
||||||
|
|
||||||
int conf_log_level;
|
extern int conf_log_level;
|
||||||
FILE *conf_global_log_file;
|
extern FILE *conf_global_log_file;
|
||||||
int conf_log_system;
|
extern int conf_log_system;
|
||||||
|
|
||||||
void bipmkpw_fatal(char *msg, char *err)
|
void bipmkpw_fatal(char *msg, char *err)
|
||||||
{
|
{
|
||||||
|
@ -62,7 +62,7 @@ void connection_close(connection_t *cn)
|
|||||||
{
|
{
|
||||||
mylog(LOG_DEBUG, "Connection close asked. FD:%d (status: %d)",
|
mylog(LOG_DEBUG, "Connection close asked. FD:%d (status: %d)",
|
||||||
(long)cn->handle, cn->connected);
|
(long)cn->handle, cn->connected);
|
||||||
if (cn->connected != CONN_DISCONN && cn->connected != CONN_ERROR) {
|
if (cn->connected != CONN_DISCONN) {
|
||||||
cn->connected = CONN_DISCONN;
|
cn->connected = CONN_DISCONN;
|
||||||
if (close(cn->handle) == -1)
|
if (close(cn->handle) == -1)
|
||||||
mylog(LOG_WARN, "Error on socket close: %s",
|
mylog(LOG_WARN, "Error on socket close: %s",
|
||||||
@ -1171,6 +1171,7 @@ static connection_t *connection_init(int anti_flood, int ssl, time_t timeout,
|
|||||||
static int ctx_set_dh(SSL_CTX *ctx)
|
static int ctx_set_dh(SSL_CTX *ctx)
|
||||||
{
|
{
|
||||||
/* Return ephemeral DH parameters. */
|
/* Return ephemeral DH parameters. */
|
||||||
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L /* 3.0.0 */
|
||||||
DH *dh = NULL;
|
DH *dh = NULL;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
long ret;
|
long ret;
|
||||||
@ -1203,7 +1204,31 @@ static int ctx_set_dh(SSL_CTX *ctx)
|
|||||||
ERR_error_string(ERR_get_error(), NULL));
|
ERR_error_string(ERR_get_error(), NULL));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
BIO *pbio = BIO_new_file(conf_client_dh_file, "r");
|
||||||
|
if (!pbio) {
|
||||||
|
mylog(LOG_ERROR, "Unable to open DH parameters, BIO_new_file(%s): %s",
|
||||||
|
conf_client_dh_file, ERR_error_string(ERR_get_error(), NULL));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
EVP_PKEY *param = PEM_read_bio_Parameters(pbio, NULL);
|
||||||
|
BIO_free(pbio);
|
||||||
|
if (!param) {
|
||||||
|
mylog(LOG_ERROR, "TLS DH Error: PEM_read_bio_Parameters(%s): %s",
|
||||||
|
conf_client_dh_file, ERR_error_string(ERR_get_error(), NULL));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SSL_CTX_set0_tmp_dh_pkey(ctx, param) != 1) {
|
||||||
|
EVP_PKEY_free(param);
|
||||||
|
mylog(LOG_ERROR, "TLS DH Error: SSL_CTX_set0_tmp_dh_pkey(%s): %s",
|
||||||
|
conf_client_dh_file, ERR_error_string(ERR_get_error(), NULL));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
mylog(LOG_DEBUG, "TLS: succesfully set up DH params %s",
|
||||||
|
conf_client_dh_file);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#define DEFAULT_BACKLOG 1
|
#define DEFAULT_BACKLOG 1
|
||||||
#define DEFAULT_ALWAYS_BACKLOG 0
|
#define DEFAULT_ALWAYS_BACKLOG 0
|
||||||
#define DEFAULT_BL_MSG_ONLY 0
|
#define DEFAULT_BL_MSG_ONLY 0
|
||||||
#define DEFAULT_BACKLOG_LINES 10
|
#define DEFAULT_BACKLOG_LINES 0
|
||||||
#define DEFAULT_BACKLOG_TIMESTAMP BLTSTime
|
#define DEFAULT_BACKLOG_TIMESTAMP BLTSTime
|
||||||
#define DEFAULT_BLRESET_ON_TALK 0
|
#define DEFAULT_BLRESET_ON_TALK 0
|
||||||
#define DEFAULT_BLRESET_CONNECTION 0
|
#define DEFAULT_BLRESET_CONNECTION 0
|
||||||
@ -29,6 +29,6 @@
|
|||||||
#define DEFAULT_LOG_LEVEL LOG_INFO
|
#define DEFAULT_LOG_LEVEL LOG_INFO
|
||||||
#define DEFAULT_LOG_FORMAT "%u/%n/%Y-%m/%c.%d.log"
|
#define DEFAULT_LOG_FORMAT "%u/%n/%Y-%m/%c.%d.log"
|
||||||
#define DEFAULT_BIP_USE_NOTICE 0
|
#define DEFAULT_BIP_USE_NOTICE 0
|
||||||
#define DEFAULT_RECONN_TIMER 120
|
#define DEFAULT_RECONN_TIMER 30
|
||||||
|
|
||||||
#endif /* DEFAULTS_H */
|
#endif /* DEFAULTS_H */
|
||||||
|
43
src/irc.c
43
src/irc.c
@ -33,6 +33,7 @@
|
|||||||
extern int sighup;
|
extern int sighup;
|
||||||
extern bip_t *_bip;
|
extern bip_t *_bip;
|
||||||
|
|
||||||
|
static int irc_generic_error(struct link_server *server, struct line *line);
|
||||||
static int irc_join(struct link_server *server, struct line *line);
|
static int irc_join(struct link_server *server, struct line *line);
|
||||||
static int irc_part(struct link_server *server, struct line *line);
|
static int irc_part(struct link_server *server, struct line *line);
|
||||||
static int irc_mode(struct link_server *server, struct line *line);
|
static int irc_mode(struct link_server *server, struct line *line);
|
||||||
@ -625,6 +626,10 @@ int irc_dispatch_server(bip_t *bip, struct link_server *server,
|
|||||||
ret = irc_quit(server, line);
|
ret = irc_quit(server, line);
|
||||||
} else if (irc_line_elem_equals(line, 0, "NICK")) {
|
} else if (irc_line_elem_equals(line, 0, "NICK")) {
|
||||||
ret = irc_nick(server, line);
|
ret = irc_nick(server, line);
|
||||||
|
} else if (irc_line_is_error(line)) {
|
||||||
|
// IRC errors catchall (for unhandled ones)
|
||||||
|
// logs error to bip.log
|
||||||
|
ret = irc_generic_error(server, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == OK_COPY) {
|
if (ret == OK_COPY) {
|
||||||
@ -1025,6 +1030,31 @@ static int irc_cli_pass(bip_t *bip, struct link_client *ic, struct line *line)
|
|||||||
return OK_FORGET;
|
return OK_FORGET;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int irc_cli_cap(bip_t *bip, struct link_client *ic, struct line *line)
|
||||||
|
{
|
||||||
|
if (irc_line_count(line) < 2)
|
||||||
|
return ERR_PROTOCOL;
|
||||||
|
|
||||||
|
/* When we decide to enable actual capabilities, we'll have to handle CAP
|
||||||
|
* version, add a flag cap_started or similar, and handle CAP END.
|
||||||
|
*/
|
||||||
|
if (irc_line_elem_equals(line, 1, "LS")) {
|
||||||
|
WRITE_LINE2(CONN(ic), NULL, "CAP", "*", "LS");
|
||||||
|
} else if (irc_line_elem_equals(line, 1, "LIST")) {
|
||||||
|
WRITE_LINE3(CONN(ic), NULL, "CAP", "*", "LIST", "");
|
||||||
|
} else if (irc_line_elem_equals(line, 1, "REQ")) {
|
||||||
|
char *caps = irc_line_to_string_skip(line, 2);
|
||||||
|
if (caps) {
|
||||||
|
caps++;
|
||||||
|
WRITE_LINE3(CONN(ic), NULL, "CAP", "*", "NAK", caps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ic->state & IRCC_READY) == IRCC_READY)
|
||||||
|
return irc_cli_startup(bip, ic, line);
|
||||||
|
return OK_FORGET;
|
||||||
|
}
|
||||||
|
|
||||||
static int irc_cli_quit(struct link_client *ic, struct line *line)
|
static int irc_cli_quit(struct link_client *ic, struct line *line)
|
||||||
{
|
{
|
||||||
(void)ic;
|
(void)ic;
|
||||||
@ -1403,6 +1433,8 @@ static int irc_dispatch_logging_client(bip_t *bip, struct link_client *ic,
|
|||||||
return irc_cli_user(bip, ic, line);
|
return irc_cli_user(bip, ic, line);
|
||||||
} else if (irc_line_elem_equals(line, 0, "PASS")) {
|
} else if (irc_line_elem_equals(line, 0, "PASS")) {
|
||||||
return irc_cli_pass(bip, ic, line);
|
return irc_cli_pass(bip, ic, line);
|
||||||
|
} else if (irc_line_elem_equals(line, 0, "CAP")) {
|
||||||
|
return irc_cli_cap(bip, ic, line);
|
||||||
}
|
}
|
||||||
return OK_FORGET;
|
return OK_FORGET;
|
||||||
}
|
}
|
||||||
@ -1448,6 +1480,17 @@ static int origin_is_me(struct line *l, struct link_server *server)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int irc_generic_error(struct link_server *server, struct line *line)
|
||||||
|
{
|
||||||
|
if (irc_line_count(line) == 4)
|
||||||
|
mylog(LOG_INFO, "[%s] IRC error: %s", LINK(server)->name,
|
||||||
|
irc_line_elem(line, 3));
|
||||||
|
else
|
||||||
|
mylog(LOG_INFO, "[%s] IRC error: %s", LINK(server)->name,
|
||||||
|
irc_line_to_string(line));
|
||||||
|
return OK_COPY;
|
||||||
|
}
|
||||||
|
|
||||||
static int irc_join(struct link_server *server, struct line *line)
|
static int irc_join(struct link_server *server, struct line *line)
|
||||||
{
|
{
|
||||||
char *s_nick;
|
char *s_nick;
|
||||||
|
25
src/line.c
25
src/line.c
@ -16,6 +16,8 @@
|
|||||||
#include "line.h"
|
#include "line.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
char *_irc_line_to_string(struct line *l, int skip_first);
|
||||||
|
|
||||||
// TODO resolve assuming signed overflow does not occur when changing X +- C1
|
// TODO resolve assuming signed overflow does not occur when changing X +- C1
|
||||||
// cmp C2 to X cmp C2 -+ C1
|
// cmp C2 to X cmp C2 -+ C1
|
||||||
#pragma GCC diagnostic ignored "-Wstrict-overflow"
|
#pragma GCC diagnostic ignored "-Wstrict-overflow"
|
||||||
@ -76,6 +78,19 @@ void irc_line_append(struct line *l, const char *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
char *irc_line_to_string(struct line *l)
|
char *irc_line_to_string(struct line *l)
|
||||||
|
{
|
||||||
|
return _irc_line_to_string(l, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *irc_line_to_string_skip(struct line *l, int skip_first)
|
||||||
|
{
|
||||||
|
if (skip_first >= irc_line_count(l)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return _irc_line_to_string(l, skip_first);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *_irc_line_to_string(struct line *l, int skip_first)
|
||||||
{
|
{
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
int i;
|
int i;
|
||||||
@ -83,7 +98,7 @@ char *irc_line_to_string(struct line *l)
|
|||||||
|
|
||||||
if (l->origin)
|
if (l->origin)
|
||||||
len = strlen(l->origin) + 2;
|
len = strlen(l->origin) + 2;
|
||||||
for (i = 0; i < array_count(&l->words); i++)
|
for (i = skip_first; i < array_count(&l->words); i++)
|
||||||
len += strlen(array_get(&l->words, i)) + 1;
|
len += strlen(array_get(&l->words, i)) + 1;
|
||||||
len += 1; /* remove one trailing space and add \r\n */
|
len += 1; /* remove one trailing space and add \r\n */
|
||||||
len++; /* last args ":" */
|
len++; /* last args ":" */
|
||||||
@ -95,7 +110,7 @@ char *irc_line_to_string(struct line *l)
|
|||||||
strcat(ret, l->origin);
|
strcat(ret, l->origin);
|
||||||
strcat(ret, " ");
|
strcat(ret, " ");
|
||||||
}
|
}
|
||||||
for (i = 0; i < array_count(&l->words) - 1; i++) {
|
for (i = skip_first; i < array_count(&l->words) - 1; i++) {
|
||||||
strcat(ret, array_get(&l->words, i));
|
strcat(ret, array_get(&l->words, i));
|
||||||
strcat(ret, " ");
|
strcat(ret, " ");
|
||||||
}
|
}
|
||||||
@ -143,6 +158,12 @@ void irc_line_drop(struct line *line, int elem)
|
|||||||
bip_cfree(array_drop(&line->words, elem));
|
bip_cfree(array_drop(&line->words, elem));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int irc_line_is_error(struct line *line)
|
||||||
|
{
|
||||||
|
const char *irc_code = irc_line_elem(line, 0);
|
||||||
|
return (irc_code[0] == '4');
|
||||||
|
}
|
||||||
|
|
||||||
int irc_line_elem_equals(struct line *line, int elem, const char *cmp)
|
int irc_line_elem_equals(struct line *line, int elem, const char *cmp)
|
||||||
{
|
{
|
||||||
return !strcmp(irc_line_elem(line, elem), cmp);
|
return !strcmp(irc_line_elem(line, elem), cmp);
|
||||||
|
@ -90,6 +90,7 @@ void irc_line_write(struct line *l, connection_t *c);
|
|||||||
void irc_line_append(struct line *l, const char *s);
|
void irc_line_append(struct line *l, const char *s);
|
||||||
struct line *irc_line_new_from_string(char *str);
|
struct line *irc_line_new_from_string(char *str);
|
||||||
char *irc_line_to_string(struct line *l);
|
char *irc_line_to_string(struct line *l);
|
||||||
|
char *irc_line_to_string_skip(struct line *l, int skip_first);
|
||||||
char *irc_line_to_string_to(struct line *line, char *nick);
|
char *irc_line_to_string_to(struct line *line, char *nick);
|
||||||
void irc_line_free(struct line *l);
|
void irc_line_free(struct line *l);
|
||||||
struct line *irc_line_dup(struct line *line);
|
struct line *irc_line_dup(struct line *line);
|
||||||
@ -98,6 +99,7 @@ int irc_line_includes(struct line *line, int elem);
|
|||||||
const char *irc_line_elem(struct line *line, int elem);
|
const char *irc_line_elem(struct line *line, int elem);
|
||||||
int irc_line_count(struct line *line);
|
int irc_line_count(struct line *line);
|
||||||
char *irc_line_pop(struct line *l);
|
char *irc_line_pop(struct line *l);
|
||||||
|
int irc_line_is_error(struct line *line);
|
||||||
int irc_line_elem_equals(struct line *line, int elem, const char *cmp);
|
int irc_line_elem_equals(struct line *line, int elem, const char *cmp);
|
||||||
int irc_line_elem_case_equals(struct line *line, int elem, const char *cmp);
|
int irc_line_elem_case_equals(struct line *line, int elem, const char *cmp);
|
||||||
void irc_line_drop(struct line *line, int elem);
|
void irc_line_drop(struct line *line, int elem);
|
||||||
|
@ -35,3 +35,15 @@ void assert_path_exists(char *path)
|
|||||||
if (stat(path, &st_buf) != 0)
|
if (stat(path, &st_buf) != 0)
|
||||||
fatal("Path %s doesn't exist (%s)", path, strerror(errno));
|
fatal("Path %s doesn't exist (%s)", path, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int check_path_exists(char *path)
|
||||||
|
{
|
||||||
|
struct stat st_buf;
|
||||||
|
|
||||||
|
if (stat(path, &st_buf) != 0) {
|
||||||
|
mylog(LOG_WARN, "Path %s doesn't exist (%s)", path, strerror(errno));
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -18,5 +18,7 @@
|
|||||||
char *default_path(const char *biphome, const char *filename, const char *desc);
|
char *default_path(const char *biphome, const char *filename, const char *desc);
|
||||||
/* exit program if path doesn't exist */
|
/* exit program if path doesn't exist */
|
||||||
void assert_path_exists(char *path);
|
void assert_path_exists(char *path);
|
||||||
|
/* return 1 if path exists, 0 otherwise */
|
||||||
|
int check_path_exists(char *path);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user