Compare commits
3 Commits
master
...
#765_Add_c
Author | SHA1 | Date | |
---|---|---|---|
|
f1214dbfb5 | ||
|
662bc9baf1 | ||
8c3e51c559 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -58,6 +58,7 @@ src/lex.c
|
||||
|
||||
# Binaries
|
||||
src/*.o
|
||||
src/b64/*.o
|
||||
src/*.a
|
||||
src/bip
|
||||
src/bipmkpw
|
||||
|
4
AUTHORS
4
AUTHORS
@ -10,4 +10,6 @@ Thanks to our marketting and management team:
|
||||
ack|, ato, blackmore, lafouine, Gaston & gromit
|
||||
|
||||
Crypto shamelessly stolen from Christophe 'sexy' Devine.
|
||||
Credits to Jouni Malinen for base64 library (http://web.mit.edu/freebsd/head/contrib/wpa/src/utils/)
|
||||
|
||||
Credits to Jouni Malinen for base64 library:
|
||||
Source: http://w1.fi/cgit/hostap/commit/src/utils/base64.c
|
||||
|
68
configure.ac
68
configure.ac
@ -94,74 +94,6 @@ if test "$ap_cv_cc_pie" = "yes"; then
|
||||
enable_pie=yes
|
||||
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])
|
||||
AM_CONDITIONAL([COND_WANT_TESTS], [test "$enable_tests" = yes])
|
||||
|
||||
|
@ -19,7 +19,7 @@ libbip_a_SOURCES = \
|
||||
path_util.c path_util.h \
|
||||
tuple.h \
|
||||
util.c util.h \
|
||||
utils/base64.c utils/base64.h
|
||||
b64/base64.c b64/base64.h
|
||||
|
||||
libbip_a_CFLAGS = ${OPENSSL_CFLAGS} $(AM_CFLAGS)
|
||||
|
||||
@ -36,4 +36,9 @@ bipmkpw_LDADD = libbip.a libbiplex.a $(OPENSSL_LIBS)
|
||||
AM_YFLAGS= -d
|
||||
BUILT_SOURCES = conf.c conf.h lex.c
|
||||
|
||||
AM_CFLAGS=-Wall -Wextra -Werror -Wundef -Wpedantic
|
||||
AM_CFLAGS=-Wall -Wextra -Werror \
|
||||
-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
|
||||
|
102
src/b64/base64.c
Normal file
102
src/b64/base64.c
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Base64 encoding/decoding (RFC1341)
|
||||
* Copyright (c) 2005-2019, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "os.h"
|
||||
#include "base64.h"
|
||||
|
||||
static const char base64_table[65] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
|
||||
#define BASE64_PAD BIT(0)
|
||||
#define BASE64_LF BIT(1)
|
||||
|
||||
|
||||
static char * base64_gen_encode(const unsigned char *src, size_t len,
|
||||
size_t *out_len, const char *table, int add_pad)
|
||||
{
|
||||
char *out, *pos;
|
||||
const unsigned char *end, *in;
|
||||
size_t olen;
|
||||
int line_len;
|
||||
|
||||
if (len >= SIZE_MAX / 4)
|
||||
return NULL;
|
||||
olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */
|
||||
if (add_pad & BASE64_LF)
|
||||
olen += olen / 72; /* line feeds */
|
||||
olen++; /* nul termination */
|
||||
if (olen < len)
|
||||
return NULL; /* integer overflow */
|
||||
out = os_malloc(olen);
|
||||
if (out == NULL)
|
||||
return NULL;
|
||||
|
||||
end = src + len;
|
||||
in = src;
|
||||
pos = out;
|
||||
line_len = 0;
|
||||
while (end - in >= 3) {
|
||||
*pos++ = table[(in[0] >> 2) & 0x3f];
|
||||
*pos++ = table[(((in[0] & 0x03) << 4) | (in[1] >> 4)) & 0x3f];
|
||||
*pos++ = table[(((in[1] & 0x0f) << 2) | (in[2] >> 6)) & 0x3f];
|
||||
*pos++ = table[in[2] & 0x3f];
|
||||
in += 3;
|
||||
line_len += 4;
|
||||
if ((add_pad & BASE64_LF) && line_len >= 72) {
|
||||
*pos++ = '\n';
|
||||
line_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (end - in) {
|
||||
*pos++ = table[(in[0] >> 2) & 0x3f];
|
||||
if (end - in == 1) {
|
||||
*pos++ = table[((in[0] & 0x03) << 4) & 0x3f];
|
||||
if (add_pad & BASE64_PAD)
|
||||
*pos++ = '=';
|
||||
} else {
|
||||
*pos++ = table[(((in[0] & 0x03) << 4) |
|
||||
(in[1] >> 4)) & 0x3f];
|
||||
*pos++ = table[((in[1] & 0x0f) << 2) & 0x3f];
|
||||
}
|
||||
if (add_pad & BASE64_PAD)
|
||||
*pos++ = '=';
|
||||
line_len += 4;
|
||||
}
|
||||
|
||||
if ((add_pad & BASE64_LF) && line_len)
|
||||
*pos++ = '\n';
|
||||
|
||||
*pos = '\0';
|
||||
if (out_len)
|
||||
*out_len = (size_t)(pos - out);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* base64_encode - Base64 encode
|
||||
* @src: Data to be encoded
|
||||
* @len: Length of the data to be encoded
|
||||
* @out_len: Pointer to output length variable, or %NULL if not used
|
||||
* Returns: Allocated buffer of out_len bytes of encoded data,
|
||||
* or %NULL on failure
|
||||
*
|
||||
* Caller is responsible for freeing the returned buffer. Returned buffer is
|
||||
* nul terminated to make it easier to use as a C string. The nul terminator is
|
||||
* not included in out_len.
|
||||
*/
|
||||
char * base64_encode_no_lf(const void *src, size_t len, size_t *out_len)
|
||||
{
|
||||
return base64_gen_encode(src, len, out_len, base64_table, BASE64_PAD);
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
/*
|
||||
* Base64 encoding/decoding (RFC1341)
|
||||
* Copyright (c) 2005, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2022 Loïc Gomez
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
@ -10,7 +9,6 @@
|
||||
#ifndef BASE64_H
|
||||
#define BASE64_H
|
||||
|
||||
unsigned char *base64_encode(const unsigned char *src, size_t len,
|
||||
size_t *out_len);
|
||||
char * base64_encode_no_lf(const void *src, size_t len, size_t *out_len);
|
||||
|
||||
#endif /* BASE64_H */
|
7
src/b64/base64.lastsync
Normal file
7
src/b64/base64.lastsync
Normal file
@ -0,0 +1,7 @@
|
||||
Last sync for base64 lib:
|
||||
- by: Kyoshiro on 2024-02-19
|
||||
- url: http://w1.fi/cgit/hostap/commit/src/utils/base64.c
|
||||
- commit-id: c7e6dbdad8ee043a9d7f856502196dbeb65cb4ac
|
||||
- commit-date: Mon Jun 15 20:18:12 2020 +0300
|
||||
- base64.h: d545b2931ca2206a265226049d90882a527236f0
|
||||
- base64.c: 0d121c1989cac9349949b2cd3611f49a1ef2820f
|
3
src/b64/common.h
Normal file
3
src/b64/common.h
Normal file
@ -0,0 +1,3 @@
|
||||
#ifndef BIT
|
||||
#define BIT(x) (int)(1U << (x))
|
||||
#endif
|
4
src/b64/includes.h
Normal file
4
src/b64/includes.h
Normal file
@ -0,0 +1,4 @@
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
3
src/b64/os.h
Normal file
3
src/b64/os.h
Normal file
@ -0,0 +1,3 @@
|
||||
#ifndef os_malloc
|
||||
#define os_malloc(s) malloc((s))
|
||||
#endif
|
@ -1396,10 +1396,9 @@ void adm_print_connection(struct link_client *ic, struct link *lnk,
|
||||
bufpos = buf;
|
||||
|
||||
list_iterator_t itocs;
|
||||
int i = 0;
|
||||
for (list_it_init(&lnk->on_connect_send, &itocs);
|
||||
list_it_item(&itocs) && i < 10; i++) {
|
||||
bufpos = bip_strcatf_fit(&remaining, bufpos, " on_connect_send: %s",
|
||||
list_it_item(&itocs);) {
|
||||
bufpos = bip_strcatf_fit(&remaining, bufpos, "%s",
|
||||
(char *)list_it_item(&itocs));
|
||||
if (!bufpos) {
|
||||
// if oversized, print and reset
|
||||
@ -1407,7 +1406,6 @@ void adm_print_connection(struct link_client *ic, struct link *lnk,
|
||||
bip_notify(ic, "%s", buf);
|
||||
remaining = LINE_SIZE_LIM;
|
||||
bufpos = buf;
|
||||
list_it_next(&itocs);
|
||||
continue;
|
||||
} else {
|
||||
// if ok, go to next item
|
||||
|
@ -68,7 +68,6 @@ 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 check_ssl_files(int failmode);
|
||||
int do_pid_stuff(void);
|
||||
|
||||
static void usage(char *name)
|
||||
@ -144,44 +143,6 @@ static pid_t daemonize(void)
|
||||
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)
|
||||
{
|
||||
FILE *conf = NULL;
|
||||
@ -303,7 +264,30 @@ int main(int argc, char **argv)
|
||||
|
||||
#ifdef HAVE_LIBSSL
|
||||
if (conf_css) {
|
||||
check_ssl_files(HARD_FAIL);
|
||||
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
|
||||
|
||||
@ -340,24 +324,6 @@ int main(int argc, char **argv)
|
||||
|
||||
/* re-open to allow logfile rotate */
|
||||
log_file_setup();
|
||||
|
||||
#ifdef HAVE_LIBSSL
|
||||
/*
|
||||
* reload SSL context if server-side SSL is enabled and SSL files
|
||||
* seem accessible.
|
||||
*/
|
||||
if (conf_css) {
|
||||
if (check_ssl_files(SOFT_FAIL)) {
|
||||
if (set_ssl_context(SSLCTX_FORCE_UPDATE) == 1)
|
||||
mylog(LOG_DEBUG, "SSL context has been updated");
|
||||
else
|
||||
mylog(LOG_DEBUG, "SSL context has not been updated");
|
||||
} else {
|
||||
mylog(LOG_ERROR, "Unable to update SSL context, "
|
||||
"file checks failed");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -23,9 +23,9 @@
|
||||
#include "util.h"
|
||||
#include "md5.h"
|
||||
|
||||
extern int conf_log_level;
|
||||
extern FILE *conf_global_log_file;
|
||||
extern int conf_log_system;
|
||||
int conf_log_level;
|
||||
FILE *conf_global_log_file;
|
||||
int conf_log_system;
|
||||
|
||||
void bipmkpw_fatal(char *msg, char *err)
|
||||
{
|
||||
|
144
src/connection.c
144
src/connection.c
@ -34,7 +34,6 @@ extern char *conf_client_ciphers;
|
||||
extern char *conf_client_dh_file;
|
||||
static int SSLize(connection_t *cn, int *nc);
|
||||
static SSL_CTX *SSL_init_context(char *ciphers);
|
||||
SSL_CTX *get_ssl_context(void);
|
||||
/* SSH like trust management */
|
||||
int link_add_untrusted(void *ls, X509 *cert);
|
||||
#endif
|
||||
@ -63,7 +62,7 @@ void connection_close(connection_t *cn)
|
||||
{
|
||||
mylog(LOG_DEBUG, "Connection close asked. FD:%d (status: %d)",
|
||||
(long)cn->handle, cn->connected);
|
||||
if (cn->connected != CONN_DISCONN) {
|
||||
if (cn->connected != CONN_DISCONN && cn->connected != CONN_ERROR) {
|
||||
cn->connected = CONN_DISCONN;
|
||||
if (close(cn->handle) == -1)
|
||||
mylog(LOG_WARN, "Error on socket close: %s",
|
||||
@ -1172,7 +1171,6 @@ static connection_t *connection_init(int anti_flood, int ssl, time_t timeout,
|
||||
static int ctx_set_dh(SSL_CTX *ctx)
|
||||
{
|
||||
/* Return ephemeral DH parameters. */
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L /* 3.0.0 */
|
||||
DH *dh = NULL;
|
||||
FILE *f;
|
||||
long ret;
|
||||
@ -1205,104 +1203,9 @@ static int ctx_set_dh(SSL_CTX *ctx)
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
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;
|
||||
}
|
||||
|
||||
int set_ssl_context(int force)
|
||||
{
|
||||
SSL_CTX *newctx = NULL;
|
||||
if (sslctx) {
|
||||
if (force == SSLCTX_FORCE_UPDATE) {
|
||||
mylog(LOG_DEBUG, "SSL context already set, forcing update");
|
||||
} else {
|
||||
mylog(LOG_DEBUG, "SSL context is already set, not updating");
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
mylog(LOG_DEBUG, "Initializing SSL context for accepted connections");
|
||||
}
|
||||
|
||||
newctx = get_ssl_context();
|
||||
if (!newctx) {
|
||||
mylog(LOG_ERROR, "Failed to get new SSL context");
|
||||
if (sslctx)
|
||||
mylog(LOG_WARN, "Keeping old SSL context");
|
||||
return 0;
|
||||
}
|
||||
sslctx = newctx;
|
||||
return 1;
|
||||
}
|
||||
|
||||
SSL_CTX *get_ssl_context(void)
|
||||
{
|
||||
SSL_CTX *newctx = NULL;
|
||||
if (!(newctx = SSL_init_context(conf_client_ciphers))) {
|
||||
mylog(LOG_ERROR, "SSL context initialization failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!conf_client_dh_file) {
|
||||
// try with a default path but don't fail if it doesn't exist
|
||||
conf_client_dh_file = default_path(conf_biphome, "dh.pem",
|
||||
"DH parameters");
|
||||
|
||||
struct stat st_buf;
|
||||
if (stat(conf_client_dh_file, &st_buf) != 0) {
|
||||
free(conf_client_dh_file);
|
||||
conf_client_dh_file = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (conf_client_dh_file) {
|
||||
if (!ctx_set_dh(newctx)) {
|
||||
SSL_CTX_free(newctx);
|
||||
mylog(LOG_ERROR, "SSL Unable to load DH parameters");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
mylog(LOG_DEBUG, "Loading SSL cert from %s", conf_ssl_certfile);
|
||||
if (!SSL_CTX_use_certificate_chain_file(newctx, conf_ssl_certfile)) {
|
||||
mylog(LOG_WARN, "SSL: Unable to load certificate file");
|
||||
SSL_CTX_free(newctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mylog(LOG_DEBUG, "Loading SSL key from %s", conf_ssl_certfile);
|
||||
if (!SSL_CTX_use_PrivateKey_file(newctx, conf_ssl_certfile,
|
||||
SSL_FILETYPE_PEM)) {
|
||||
mylog(LOG_WARN, "SSL: Unable to load key file");
|
||||
SSL_CTX_free(newctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return newctx;
|
||||
}
|
||||
#endif
|
||||
|
||||
connection_t *accept_new(connection_t *cn)
|
||||
@ -1338,13 +1241,54 @@ connection_t *accept_new(connection_t *cn)
|
||||
conn->client = 1;
|
||||
#ifdef HAVE_LIBSSL
|
||||
if (cn->ssl) {
|
||||
if (!sslctx)
|
||||
set_ssl_context(SSLCTX_NO_REPLACE);
|
||||
if (!sslctx) {
|
||||
mylog(LOG_DEBUG,
|
||||
"No SSL context available for "
|
||||
"accepted connections. "
|
||||
"Initializing...");
|
||||
if (!(sslctx = SSL_init_context(conf_client_ciphers))) {
|
||||
mylog(LOG_ERROR,
|
||||
"SSL context initialization "
|
||||
"failed");
|
||||
connection_free(conn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!conf_client_dh_file) {
|
||||
// try with a default path but don't fail if it
|
||||
// doesn't exist
|
||||
conf_client_dh_file =
|
||||
default_path(conf_biphome, "dh.pem",
|
||||
"DH parameters");
|
||||
|
||||
struct stat st_buf;
|
||||
if (stat(conf_client_dh_file, &st_buf) != 0) {
|
||||
free(conf_client_dh_file);
|
||||
conf_client_dh_file = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (conf_client_dh_file) {
|
||||
if (!ctx_set_dh(sslctx)) {
|
||||
mylog(LOG_ERROR,
|
||||
"SSL Unable to load DH "
|
||||
"parameters");
|
||||
connection_free(conn);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!SSL_CTX_use_certificate_chain_file(
|
||||
sslctx, conf_ssl_certfile))
|
||||
mylog(LOG_WARN,
|
||||
"SSL: Unable to load "
|
||||
"certificate file");
|
||||
if (!SSL_CTX_use_PrivateKey_file(sslctx,
|
||||
conf_ssl_certfile,
|
||||
SSL_FILETYPE_PEM))
|
||||
mylog(LOG_WARN, "SSL: Unable to load key file");
|
||||
}
|
||||
|
||||
conn->ssl_h = SSL_new(sslctx);
|
||||
if (!conn->ssl_h) {
|
||||
connection_free(conn);
|
||||
|
@ -60,9 +60,6 @@
|
||||
#define SSL_CHECK_NONE (0)
|
||||
#define SSL_CHECK_BASIC (1)
|
||||
#define SSL_CHECK_CA (2)
|
||||
|
||||
#define SSLCTX_NO_REPLACE 0
|
||||
#define SSLCTX_FORCE_UPDATE 1
|
||||
#endif
|
||||
|
||||
struct connecting_data;
|
||||
@ -116,9 +113,4 @@ uint16_t connection_localport(connection_t *cn);
|
||||
uint16_t connection_remoteport(connection_t *cn);
|
||||
char *connection_localip(connection_t *cn);
|
||||
char *connection_remoteip(connection_t *cn);
|
||||
#ifdef HAVE_LIBSSL
|
||||
/* Set SSL context, force update if already set and force is 1
|
||||
* Return 1 if SSL context has been set */
|
||||
int set_ssl_context(int force);
|
||||
#endif
|
||||
#endif
|
||||
|
36
src/irc.c
36
src/irc.c
@ -22,7 +22,7 @@
|
||||
#include "log.h"
|
||||
#include "connection.h"
|
||||
#include "md5.h"
|
||||
#include "utils/base64.h"
|
||||
#include "b64/base64.h"
|
||||
|
||||
// TODO resolve assuming signed overflow does not occur when changing X +- C1
|
||||
// cmp C2 to X cmp C2 -+ C1
|
||||
@ -1030,31 +1030,6 @@ static int irc_cli_pass(bip_t *bip, struct link_client *ic, struct line *line)
|
||||
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)
|
||||
{
|
||||
(void)ic;
|
||||
@ -1433,8 +1408,6 @@ static int irc_dispatch_logging_client(bip_t *bip, struct link_client *ic,
|
||||
return irc_cli_user(bip, ic, line);
|
||||
} else if (irc_line_elem_equals(line, 0, "PASS")) {
|
||||
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;
|
||||
}
|
||||
@ -2209,15 +2182,16 @@ static int irc_server_sasl_authenticate(struct link_server *ircs)
|
||||
size_t p_len = strlen(sasl_password);
|
||||
size_t raw_len = u_len * 2 + p_len + 2;
|
||||
size_t enc_len;
|
||||
unsigned char *raw_str = bip_malloc(raw_len + 1);
|
||||
unsigned char *enc_str;
|
||||
char *raw_str = bip_malloc(raw_len + 1);
|
||||
char *enc_str;
|
||||
|
||||
memcpy(raw_str, sasl_username, u_len);
|
||||
raw_str[u_len] = '\0';
|
||||
memcpy(raw_str + u_len + 1, sasl_username, u_len);
|
||||
raw_str[u_len * 2 + 1] = '\0';
|
||||
memcpy(raw_str + u_len * 2 + 2, sasl_password, p_len);
|
||||
enc_str = base64_encode(raw_str, raw_len, &enc_len);
|
||||
enc_str = base64_encode_no_lf(raw_str, raw_len, &enc_len);
|
||||
free(raw_str);
|
||||
mylog(LOG_DEBUG, "[%s] Base64 encoded SASL auth token (len %d): %s",
|
||||
LINK(ircs)->name, enc_len, enc_str);
|
||||
|
||||
|
19
src/line.c
19
src/line.c
@ -16,8 +16,6 @@
|
||||
#include "line.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
|
||||
// cmp C2 to X cmp C2 -+ C1
|
||||
#pragma GCC diagnostic ignored "-Wstrict-overflow"
|
||||
@ -78,19 +76,6 @@ void irc_line_append(struct line *l, const char *s)
|
||||
}
|
||||
|
||||
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;
|
||||
int i;
|
||||
@ -98,7 +83,7 @@ char *_irc_line_to_string(struct line *l, int skip_first)
|
||||
|
||||
if (l->origin)
|
||||
len = strlen(l->origin) + 2;
|
||||
for (i = skip_first; i < array_count(&l->words); i++)
|
||||
for (i = 0; i < array_count(&l->words); i++)
|
||||
len += strlen(array_get(&l->words, i)) + 1;
|
||||
len += 1; /* remove one trailing space and add \r\n */
|
||||
len++; /* last args ":" */
|
||||
@ -110,7 +95,7 @@ char *_irc_line_to_string(struct line *l, int skip_first)
|
||||
strcat(ret, l->origin);
|
||||
strcat(ret, " ");
|
||||
}
|
||||
for (i = skip_first; i < array_count(&l->words) - 1; i++) {
|
||||
for (i = 0; i < array_count(&l->words) - 1; i++) {
|
||||
strcat(ret, array_get(&l->words, i));
|
||||
strcat(ret, " ");
|
||||
}
|
||||
|
@ -90,7 +90,6 @@ void irc_line_write(struct line *l, connection_t *c);
|
||||
void irc_line_append(struct line *l, const char *s);
|
||||
struct line *irc_line_new_from_string(char *str);
|
||||
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);
|
||||
void irc_line_free(struct line *l);
|
||||
struct line *irc_line_dup(struct line *line);
|
||||
|
@ -35,15 +35,3 @@ void assert_path_exists(char *path)
|
||||
if (stat(path, &st_buf) != 0)
|
||||
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,7 +18,5 @@
|
||||
char *default_path(const char *biphome, const char *filename, const char *desc);
|
||||
/* exit program if path doesn't exist */
|
||||
void assert_path_exists(char *path);
|
||||
/* return 1 if path exists, 0 otherwise */
|
||||
int check_path_exists(char *path);
|
||||
|
||||
#endif
|
||||
|
@ -31,9 +31,6 @@
|
||||
#define HASH_NOCASE 1
|
||||
#define HASH_DEFAULT 0
|
||||
|
||||
#define SOFT_FAIL 0
|
||||
#define HARD_FAIL 1
|
||||
|
||||
void mylog(int level, char *fmt, ...);
|
||||
void _mylog(int level, char *fmt, va_list ap);
|
||||
void fatal(char *fmt, ...);
|
||||
|
@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Base64 encoding/decoding (RFC1341)
|
||||
* Copyright (c) 2005-2011, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2022 Loïc Gomez
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "base64.h"
|
||||
|
||||
static const unsigned char base64_table[65] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
/**
|
||||
* base64_encode - Base64 encode
|
||||
* @src: Data to be encoded
|
||||
* @len: Length of the data to be encoded
|
||||
* @out_len: Pointer to output length variable, or %NULL if not used
|
||||
* Returns: Allocated buffer of out_len bytes of encoded data,
|
||||
* or %NULL on failure
|
||||
*
|
||||
* Caller is responsible for freeing the returned buffer. Returned buffer is
|
||||
* nul terminated to make it easier to use as a C string. The nul terminator is
|
||||
* not included in out_len.
|
||||
*
|
||||
* BIP change: remove line returns.
|
||||
*/
|
||||
unsigned char *base64_encode(const unsigned char *src, size_t len,
|
||||
size_t *out_len)
|
||||
{
|
||||
unsigned char *out, *pos;
|
||||
const unsigned char *end, *in;
|
||||
size_t olen;
|
||||
int line_len;
|
||||
|
||||
olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */
|
||||
olen += olen / 72; /* line feeds */
|
||||
olen++; /* nul termination */
|
||||
if (olen < len)
|
||||
return NULL; /* integer overflow */
|
||||
out = malloc(olen);
|
||||
if (out == NULL)
|
||||
return NULL;
|
||||
|
||||
end = src + len;
|
||||
in = src;
|
||||
pos = out;
|
||||
line_len = 0;
|
||||
while (end - in >= 3) {
|
||||
*pos++ = base64_table[in[0] >> 2];
|
||||
*pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
|
||||
*pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
|
||||
*pos++ = base64_table[in[2] & 0x3f];
|
||||
in += 3;
|
||||
line_len += 4;
|
||||
/*
|
||||
* BIP change: remove line returns.
|
||||
if (line_len >= 72) {
|
||||
*pos++ = '\n';
|
||||
line_len = 0;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
if (end - in) {
|
||||
*pos++ = base64_table[in[0] >> 2];
|
||||
if (end - in == 1) {
|
||||
*pos++ = base64_table[(in[0] & 0x03) << 4];
|
||||
*pos++ = '=';
|
||||
} else {
|
||||
*pos++ = base64_table[((in[0] & 0x03) << 4)
|
||||
| (in[1] >> 4)];
|
||||
*pos++ = base64_table[(in[1] & 0x0f) << 2];
|
||||
}
|
||||
*pos++ = '=';
|
||||
line_len += 4;
|
||||
}
|
||||
|
||||
/*
|
||||
* BIP change: remove line returns.
|
||||
if (line_len)
|
||||
*pos++ = '\n';
|
||||
*/
|
||||
|
||||
*pos = '\0';
|
||||
if (out_len)
|
||||
*out_len = (size_t)(pos - out);
|
||||
return out;
|
||||
}
|
Loading…
Reference in New Issue
Block a user