1
0
forked from bip/bip

Format the whole code using clang-format

This commit is contained in:
Pierre-Louis Bonicoli 2022-03-10 13:52:03 +01:00
parent 8d9658ca43
commit f2fd1824ca
Signed by untrusted user: pilou
GPG Key ID: 06914C4A5EDAA6DD
17 changed files with 1683 additions and 1467 deletions

484
src/bip.c

File diff suppressed because it is too large Load Diff

View File

@ -72,24 +72,25 @@ int do_pid_stuff(void);
static void usage(char *name) static void usage(char *name)
{ {
printf( printf("Usage: %s [-f config_file] [-h] [-n]\n"
"Usage: %s [-f config_file] [-h] [-n]\n" " -f config_file: Use config_file as the configuration file\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
" If no config file is given %s will try to open ~/.bip/" S_CONF "\n" "\n"
" -n: Don't daemonize, log in stderr\n" " -n: Don't daemonize, log in stderr\n"
" -s: Bip HOME, default parent directory for client certificate,\n" " -s: Bip HOME, default parent directory for client certificate,\n"
" configuration, logs, pid, oidentd\n" " configuration, logs, pid, oidentd\n"
" -v: Print version and exit\n" " -v: Print version and exit\n"
" -h: This help\n", name, name); " -h: This help\n",
name, name);
exit(1); exit(1);
} }
static void version(void) static void version(void)
{ {
printf( printf("Bip IRC Proxy - " PACKAGE_VERSION
"Bip IRC Proxy - " PACKAGE_VERSION "\n" "\n"
"Copyright © Arnaud Cornet and Loïc Gomez (2004 - 2008)\n" "Copyright © Arnaud Cornet and Loïc Gomez (2004 - 2008)\n"
"Distributed under the GNU General Public License Version 2\n"); "Distributed under the GNU General Public License Version 2\n");
} }
static void log_file_setup(void) static void log_file_setup(void)
@ -99,7 +100,7 @@ static void log_file_setup(void)
if (conf_log_system && conf_daemonize) { if (conf_log_system && conf_daemonize) {
if (conf_global_log_file && conf_global_log_file != stderr) if (conf_global_log_file && conf_global_log_file != stderr)
fclose(conf_global_log_file); fclose(conf_global_log_file);
snprintf(buf, (size_t) 4095, "%s/bip.log", conf_log_root); snprintf(buf, (size_t)4095, "%s/bip.log", conf_log_root);
FILE *f = fopen(buf, "a"); FILE *f = fopen(buf, "a");
if (!f) if (!f)
fatal("Can't open %s: %s", buf, strerror(errno)); fatal("Can't open %s: %s", buf, strerror(errno));
@ -208,7 +209,8 @@ int main(int argc, char **argv)
char *home = NULL; /* oidentd path searching ignores conf_biphome */ char *home = NULL; /* oidentd path searching ignores conf_biphome */
home = getenv("HOME"); home = getenv("HOME");
if (!home && !conf_biphome) { if (!home && !conf_biphome) {
conf_die(&bip, "no value for environment variable $HOME," conf_die(&bip,
"no value for environment variable $HOME,"
"use '-s' parameter"); "use '-s' parameter");
return 0; return 0;
} }
@ -220,16 +222,16 @@ int main(int argc, char **argv)
} }
if (!bip.oidentdpath) { if (!bip.oidentdpath) {
bip.oidentdpath = bip_malloc(strlen(conf_biphome) + 1 + bip.oidentdpath = bip_malloc(strlen(conf_biphome) + 1
strlen(OIDENTD_FILENAME) + 1); + strlen(OIDENTD_FILENAME) + 1);
strcpy(bip.oidentdpath, conf_biphome); strcpy(bip.oidentdpath, conf_biphome);
strcat(bip.oidentdpath, "/"); strcat(bip.oidentdpath, "/");
strcat(bip.oidentdpath, OIDENTD_FILENAME); strcat(bip.oidentdpath, OIDENTD_FILENAME);
} }
if (!confpath) { if (!confpath) {
confpath = bip_malloc(strlen(conf_biphome) + 1 + confpath = bip_malloc(strlen(conf_biphome) + 1 + strlen(S_CONF)
strlen(S_CONF) + 1); + 1);
strcpy(confpath, conf_biphome); strcpy(confpath, conf_biphome);
strcat(confpath, "/"); strcat(confpath, "/");
strcat(confpath, S_CONF); strcat(confpath, S_CONF);
@ -245,16 +247,16 @@ int main(int argc, char **argv)
if (!conf_log_root) { if (!conf_log_root) {
char *ap = "/logs"; char *ap = "/logs";
conf_log_root = bip_malloc(strlen(conf_biphome) + conf_log_root =
strlen(ap) + 1); bip_malloc(strlen(conf_biphome) + strlen(ap) + 1);
strcpy(conf_log_root, conf_biphome); strcpy(conf_log_root, conf_biphome);
strcat(conf_log_root, ap); strcat(conf_log_root, ap);
mylog(LOG_INFO, "Default log root: %s", conf_log_root); mylog(LOG_INFO, "Default log root: %s", conf_log_root);
} }
if (!conf_pid_file) { if (!conf_pid_file) {
char *pid = "/bip.pid"; char *pid = "/bip.pid";
conf_pid_file = bip_malloc(strlen(conf_biphome) + conf_pid_file =
strlen(pid) + 1); bip_malloc(strlen(conf_biphome) + strlen(pid) + 1);
strcpy(conf_pid_file, conf_biphome); strcpy(conf_pid_file, conf_biphome);
strcat(conf_pid_file, pid); strcat(conf_pid_file, pid);
mylog(LOG_INFO, "Default pid file: %s", conf_pid_file); mylog(LOG_INFO, "Default pid file: %s", conf_pid_file);
@ -266,17 +268,20 @@ int main(int argc, char **argv)
struct stat fs; struct stat fs;
if (!conf_ssl_certfile) { if (!conf_ssl_certfile) {
conf_ssl_certfile = default_path(conf_biphome, "bip.pem", conf_ssl_certfile = default_path(
"SSL certificate"); conf_biphome, "bip.pem", "SSL certificate");
} }
assert_path_exists(conf_ssl_certfile); assert_path_exists(conf_ssl_certfile);
e = stat(conf_ssl_certfile, &fs); e = stat(conf_ssl_certfile, &fs);
if (e) if (e)
mylog(LOG_WARN, "Unable to check PEM file, stat(%s): " mylog(LOG_WARN,
"%s", conf_ssl_certfile, strerror(errno)); "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)) else if ((fs.st_mode & S_IROTH) | (fs.st_mode & S_IWOTH))
mylog(LOG_ERROR, "PEM file %s should not be world " mylog(LOG_ERROR,
"PEM file %s should not be world "
"readable / writable. Please fix the modes.", "readable / writable. Please fix the modes.",
conf_ssl_certfile); conf_ssl_certfile);
@ -295,7 +300,7 @@ int main(int argc, char **argv)
pid = daemonize(); pid = daemonize();
else else
pid = getpid(); pid = getpid();
snprintf(buf, (size_t) 29, "%lu\n", (unsigned long int)pid); snprintf(buf, (size_t)29, "%lu\n", (unsigned long int)pid);
ssize_t written; ssize_t written;
written = write(fd, buf, strlen(buf)); written = write(fd, buf, strlen(buf));
if (written <= 0) if (written <= 0)

View File

@ -45,10 +45,11 @@ void readpass(char *buffer, int buflen)
bipmkpw_fatal("tcgetattr failed", strerror(errno)); bipmkpw_fatal("tcgetattr failed", strerror(errno));
memcpy(&tt, &ttback, sizeof(ttback)); memcpy(&tt, &ttback, sizeof(ttback));
// unsigned conversion from int to tcflag_t {aka unsigned int} changes value from -11 to 4294967285 // unsigned conversion from int to tcflag_t {aka unsigned int} changes
// value from -11 to 4294967285
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-conversion" #pragma GCC diagnostic ignored "-Wsign-conversion"
tt.c_lflag &= ~(ICANON|ECHO); tt.c_lflag &= ~(ICANON | ECHO);
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
if (tcsetattr(ttyfd, TCSANOW, &tt) < 0) if (tcsetattr(ttyfd, TCSANOW, &tt) < 0)
bipmkpw_fatal("tcsetattr failed", strerror(errno)); bipmkpw_fatal("tcsetattr failed", strerror(errno));
@ -59,7 +60,7 @@ void readpass(char *buffer, int buflen)
int idx = 0; int idx = 0;
int valid = 1; int valid = 1;
while (idx < buflen) { while (idx < buflen) {
ssize_t rbytes = read(ttyfd, buffer+idx, (size_t)1); ssize_t rbytes = read(ttyfd, buffer + idx, (size_t)1);
if (rbytes <= 0) { if (rbytes <= 0) {
break; break;
} }
@ -94,9 +95,9 @@ int main(void)
readpass(str, 256); readpass(str, 256);
str[255] = 0; str[255] = 0;
// passing argument 1 of srand with different width due to prototype [-Werror=traditional-conversion] // passing argument 1 of srand with different width due to prototype
// conversion from time_t {aka long int} to unsigned int may change value [-Werror=conversion] // [-Werror=traditional-conversion] conversion from time_t {aka long int} to
// We don't care. // unsigned int may change value [-Werror=conversion] We don't care.
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wtraditional-conversion" #pragma GCC diagnostic ignored "-Wtraditional-conversion"
#pragma GCC diagnostic ignored "-Wconversion" #pragma GCC diagnostic ignored "-Wconversion"

View File

@ -43,8 +43,7 @@ static int connection_timedout(connection_t *cn);
static int socket_set_nonblock(int s); static int socket_set_nonblock(int s);
static void connection_connected(connection_t *c); static void connection_connected(connection_t *c);
struct connecting_data struct connecting_data {
{
struct addrinfo *dst; struct addrinfo *dst;
struct addrinfo *src; struct addrinfo *src;
struct addrinfo *cur; struct addrinfo *cur;
@ -127,9 +126,10 @@ static void connect_trynext(connection_t *cn)
cur = cn->connecting_data->cur; cur = cn->connecting_data->cur;
for (cur = cn->connecting_data->cur ; cur ; cur = cur->ai_next) { for (cur = cn->connecting_data->cur; cur; cur = cur->ai_next) {
if ((cn->handle = socket(cur->ai_family, cur->ai_socktype, if ((cn->handle = socket(cur->ai_family, cur->ai_socktype,
cur->ai_protocol)) < 0) { cur->ai_protocol))
< 0) {
mylog(LOG_WARN, "socket() : %s", strerror(errno)); mylog(LOG_WARN, "socket() : %s", strerror(errno));
continue; continue;
} }
@ -203,17 +203,18 @@ static X509 *mySSL_get_cert(SSL *ssl)
} }
cert = SSL_get_peer_certificate(ssl); cert = SSL_get_peer_certificate(ssl);
if (cert == NULL) if (cert == NULL)
mylog(LOG_WARN, "mySSL_get_cert() SSL server supplied no " mylog(LOG_WARN,
"mySSL_get_cert() SSL server supplied no "
"certificate !"); "certificate !");
return cert; return cert;
} }
static int _write_socket_SSL(connection_t *cn, char* message) static int _write_socket_SSL(connection_t *cn, char *message)
{ {
int count; int count;
size_t size; size_t size;
size = sizeof(char)*strlen(message); size = sizeof(char) * strlen(message);
// let's not ERR (SSL_write doesn't allow 0 len writes) // let's not ERR (SSL_write doesn't allow 0 len writes)
if (size == 0) if (size == 0)
@ -241,8 +242,7 @@ static int _write_socket_SSL(connection_t *cn, char* message)
|| err == SSL_ERROR_WANT_ACCEPT) || err == SSL_ERROR_WANT_ACCEPT)
return WRITE_KEEP; return WRITE_KEEP;
if (cn_is_connected(cn)) { if (cn_is_connected(cn)) {
mylog(LOG_ERROR, "fd %d: Connection error", mylog(LOG_ERROR, "fd %d: Connection error", cn->handle);
cn->handle);
cn->connected = CONN_ERROR; cn->connected = CONN_ERROR;
} }
return WRITE_ERROR; return WRITE_ERROR;
@ -250,8 +250,9 @@ static int _write_socket_SSL(connection_t *cn, char* message)
if (count != (int)size) { if (count != (int)size) {
/* abnormal : openssl keeps writing until message is not fully /* abnormal : openssl keeps writing until message is not fully
* sent */ * sent */
mylog(LOG_ERROR, "SSL_write wrote only %d while message length is %d", mylog(LOG_ERROR,
count,size); "SSL_write wrote only %d while message length is %d",
count, size);
} }
mylog(LOG_DEBUGVERB, "%d/%d bytes sent", count, size); mylog(LOG_DEBUGVERB, "%d/%d bytes sent", count, size);
@ -260,7 +261,8 @@ static int _write_socket_SSL(connection_t *cn, char* message)
#if OPENSSL_VERSION_NUMBER < 0x10100000L #if OPENSSL_VERSION_NUMBER < 0x10100000L
#define X509_OBJECT_get0_X509(o) ((o)->data.x509) #define X509_OBJECT_get0_X509(o) ((o)->data.x509)
#define X509_STORE_CTX_get_by_subject(vs, type, name, ret) X509_STORE_get_by_subject(vs, type, name, ret) #define X509_STORE_CTX_get_by_subject(vs, type, name, ret) \
X509_STORE_get_by_subject(vs, type, name, ret)
int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
{ {
@ -362,7 +364,6 @@ static int write_socket(connection_t *cn, char *line)
else else
#endif #endif
return _write_socket(cn, line); return _write_socket(cn, line);
} }
/* returns 1 if connection must be notified */ /* returns 1 if connection must be notified */
@ -498,7 +499,7 @@ static int read_socket_SSL(connection_t *cn)
return -1; return -1;
} }
max = sizeof(char)*(CONN_BUFFER_SIZE - cn->incoming_end); max = sizeof(char) * (CONN_BUFFER_SIZE - cn->incoming_end);
if (max > INT_MAX) { if (max > INT_MAX) {
mylog(LOG_ERROR, "read_socket_SSL: cannot read that much data"); mylog(LOG_ERROR, "read_socket_SSL: cannot read that much data");
return -1; return -1;
@ -521,20 +522,19 @@ static int read_socket_SSL(connection_t *cn)
|| err == SSL_ERROR_WANT_ACCEPT) || err == SSL_ERROR_WANT_ACCEPT)
return 0; return 0;
if (cn_is_connected(cn)) { if (cn_is_connected(cn)) {
mylog(LOG_ERROR, "fd %d: Connection error", mylog(LOG_ERROR, "fd %d: Connection error", cn->handle);
cn->handle);
cn->connected = CONN_ERROR; cn->connected = CONN_ERROR;
} }
return 1; return 1;
} else if (count == 0) { } else if (count == 0) {
/* int err = SSL_get_error(cn->ssl_h,count); /* int err = SSL_get_error(cn->ssl_h,count);
if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE if (err == SSL_ERROR_WANT_READ || err ==
SSL_ERROR_WANT_WRITE
|| err == SSL_ERROR_WANT_CONNECT || err == SSL_ERROR_WANT_CONNECT
|| err == SSL_ERROR_WANT_ACCEPT) || err == SSL_ERROR_WANT_ACCEPT)
return 0;*/ return 0;*/
if (cn_is_connected(cn)) { if (cn_is_connected(cn)) {
mylog(LOG_ERROR, "fd %d: Connection lost", mylog(LOG_ERROR, "fd %d: Connection lost", cn->handle);
cn->handle);
connection_close(cn); connection_close(cn);
} }
return 1; return 1;
@ -559,8 +559,8 @@ static int read_socket(connection_t *cn)
return -1; return -1;
} }
max = sizeof(char)*(CONN_BUFFER_SIZE - cn->incoming_end); max = sizeof(char) * (CONN_BUFFER_SIZE - cn->incoming_end);
count = read(cn->handle, cn->incoming+cn->incoming_end, max); count = read(cn->handle, cn->incoming + cn->incoming_end, max);
if (count < 0) { if (count < 0) {
if (errno == EAGAIN || errno == EINTR || errno == EINPROGRESS) if (errno == EAGAIN || errno == EINTR || errno == EINPROGRESS)
return 0; return 0;
@ -678,7 +678,7 @@ static int check_event_except(fd_set *fds, connection_t *cn)
if (!FD_ISSET(cn->handle, fds)) if (!FD_ISSET(cn->handle, fds))
return 0; return 0;
mylog(LOG_DEBUGTOOMUCH,"fd %d is in exceptions list", cn->handle); mylog(LOG_DEBUGTOOMUCH, "fd %d is in exceptions list", cn->handle);
cn->connected = CONN_EXCEPT; cn->connected = CONN_EXCEPT;
return 1; return 1;
} }
@ -688,8 +688,8 @@ static int check_event_read(fd_set *fds, connection_t *cn)
int ret; int ret;
if (cn_is_in_error(cn)) { if (cn_is_in_error(cn)) {
mylog(LOG_ERROR, "Error on fd %d (read, state %d)", mylog(LOG_ERROR, "Error on fd %d (read, state %d)", cn->handle,
cn->handle, cn->connected); cn->connected);
return 1; return 1;
} }
@ -711,8 +711,7 @@ static int check_event_read(fd_set *fds, connection_t *cn)
ret = read_socket(cn); ret = read_socket(cn);
if (ret) { if (ret) {
mylog(LOG_ERROR, "Error while reading on fd %d", mylog(LOG_ERROR, "Error while reading on fd %d", cn->handle);
cn->handle);
return 1; return 1;
} }
@ -742,8 +741,8 @@ static void connection_connected(connection_t *c)
static int check_event_write(fd_set *fds, connection_t *cn, int *nc) static int check_event_write(fd_set *fds, connection_t *cn, int *nc)
{ {
if (cn_is_in_error(cn)) { if (cn_is_in_error(cn)) {
mylog(LOG_ERROR, "Error on fd %d (write, state %d)", mylog(LOG_ERROR, "Error on fd %d (write, state %d)", cn->handle,
cn->handle, cn->connected); cn->connected);
return 1; return 1;
} }
@ -775,8 +774,10 @@ static int check_event_write(fd_set *fds, connection_t *cn, int *nc)
cn->handle = -1; cn->handle = -1;
connect_trynext(cn); connect_trynext(cn);
} }
return (cn_is_new(cn) || cn->connected == return (cn_is_new(cn)
CONN_NEED_SSLIZE) ? 0 : 1; || cn->connected == CONN_NEED_SSLIZE)
? 0
: 1;
} else if (err == EINPROGRESS || err == EALREADY) { } else if (err == EINPROGRESS || err == EALREADY) {
mylog(LOG_DEBUG, "fd:%d Connection in progress...", mylog(LOG_DEBUG, "fd:%d Connection in progress...",
@ -803,8 +804,10 @@ static int check_event_write(fd_set *fds, connection_t *cn, int *nc)
cn->handle = -1; cn->handle = -1;
connect_trynext(cn); connect_trynext(cn);
} }
return (cn_is_new(cn) || cn->connected == return (cn_is_new(cn)
CONN_NEED_SSLIZE) ? 0 : 1; || cn->connected == CONN_NEED_SSLIZE)
? 0
: 1;
} }
} }
@ -842,7 +845,8 @@ static int cn_want_write(connection_t *cn)
if (!clock_gettime(CLOCK_MONOTONIC, &tv)) { if (!clock_gettime(CLOCK_MONOTONIC, &tv)) {
if (tv.tv_sec < 0 || tv.tv_nsec < 0) if (tv.tv_sec < 0 || tv.tv_nsec < 0)
fatal("clock_gettime returned negative time"); fatal("clock_gettime returned negative time");
now = (unsigned long)(tv.tv_sec * 1000 + tv.tv_nsec / 1000000); now = (unsigned long)(tv.tv_sec * 1000
+ tv.tv_nsec / 1000000);
/* round now to TOKEN_INTERVAL multiple */ /* round now to TOKEN_INTERVAL multiple */
now -= now % TOKEN_INTERVAL; now -= now % TOKEN_INTERVAL;
if (now < cn->lasttoken) { if (now < cn->lasttoken) {
@ -850,8 +854,8 @@ static int cn_want_write(connection_t *cn)
cn->token = 1; cn->token = 1;
cn->lasttoken = now; cn->lasttoken = now;
} else if (now > cn->lasttoken + TOKEN_INTERVAL) { } else if (now > cn->lasttoken + TOKEN_INTERVAL) {
cn->token += (unsigned)((now - cn->lasttoken) / cn->token += (unsigned)((now - cn->lasttoken)
TOKEN_INTERVAL); / TOKEN_INTERVAL);
if (cn->token > TOKEN_MAX) if (cn->token > TOKEN_MAX)
cn->token = TOKEN_MAX; cn->token = TOKEN_MAX;
if (!cn->token) if (!cn->token)
@ -917,8 +921,7 @@ list_t *wait_event(list_t *cn_list, time_t *msec, int *nc)
if (cn_is_connected(cn)) { if (cn_is_connected(cn)) {
FD_SET(cn->handle, &fds_read); FD_SET(cn->handle, &fds_read);
mylog(LOG_DEBUGTOOMUCH, "Test read on fd %d %d:%d", mylog(LOG_DEBUGTOOMUCH, "Test read on fd %d %d:%d",
cn->handle, cn->connected, cn->handle, cn->connected, cn_is_connected(cn));
cn_is_connected(cn));
} }
/* we NEVER want to check write on a listening socket */ /* we NEVER want to check write on a listening socket */
@ -928,8 +931,7 @@ list_t *wait_event(list_t *cn_list, time_t *msec, int *nc)
if (!cn_is_connected(cn) || cn_want_write(cn)) { if (!cn_is_connected(cn) || cn_want_write(cn)) {
FD_SET(cn->handle, &fds_write); FD_SET(cn->handle, &fds_write);
mylog(LOG_DEBUGTOOMUCH, "Test write on fd %d %d:%d", mylog(LOG_DEBUGTOOMUCH, "Test write on fd %d %d:%d",
cn->handle, cn->connected, cn->handle, cn->connected, cn_is_connected(cn));
cn_is_connected(cn));
} }
} }
@ -1018,8 +1020,8 @@ static void create_socket(char *dsthostname, char *dstport, char *srchostname,
hint.ai_protocol = 0; hint.ai_protocol = 0;
cn->connected = CONN_ERROR; cn->connected = CONN_ERROR;
cdata = (struct connecting_data *) cdata = (struct connecting_data *)bip_malloc(
bip_malloc(sizeof(struct connecting_data)); sizeof(struct connecting_data));
cdata->dst = cdata->src = cdata->cur = NULL; cdata->dst = cdata->src = cdata->cur = NULL;
err = getaddrinfo(dsthostname, dstport, &hint, &cdata->dst); err = getaddrinfo(dsthostname, dstport, &hint, &cdata->dst);
@ -1054,8 +1056,7 @@ static void create_listening_socket(char *hostname, char *port,
int multi_client = 1; int multi_client = 1;
int err; int err;
struct addrinfo *res, *cur; struct addrinfo *res, *cur;
struct addrinfo hint = { struct addrinfo hint = {.ai_flags = AI_PASSIVE,
.ai_flags = AI_PASSIVE,
.ai_family = AF_UNSPEC, .ai_family = AF_UNSPEC,
.ai_socktype = SOCK_STREAM, .ai_socktype = SOCK_STREAM,
.ai_protocol = 0, .ai_protocol = 0,
@ -1063,8 +1064,7 @@ static void create_listening_socket(char *hostname, char *port,
.ai_addrlen = 0, .ai_addrlen = 0,
.ai_addr = 0, .ai_addr = 0,
.ai_canonname = 0, .ai_canonname = 0,
.ai_next = 0 .ai_next = 0};
};
cn->connected = CONN_ERROR; cn->connected = CONN_ERROR;
@ -1074,15 +1074,17 @@ static void create_listening_socket(char *hostname, char *port,
return; return;
} }
for (cur = res ; cur ; cur = cur->ai_next) { for (cur = res; cur; cur = cur->ai_next) {
if ((cn->handle = socket(cur->ai_family, cur->ai_socktype, if ((cn->handle = socket(cur->ai_family, cur->ai_socktype,
cur->ai_protocol)) < 0) { cur->ai_protocol))
< 0) {
mylog(LOG_WARN, "socket : %s", strerror(errno)); mylog(LOG_WARN, "socket : %s", strerror(errno));
continue; continue;
} }
if (cn->handle >= FD_SETSIZE) { if (cn->handle >= FD_SETSIZE) {
mylog(LOG_WARN, "too many fd used, close listening socket %d", mylog(LOG_WARN,
"too many fd used, close listening socket %d",
cn->handle); cn->handle);
if (close(cn->handle) == -1) if (close(cn->handle) == -1)
@ -1095,7 +1097,8 @@ static void create_listening_socket(char *hostname, char *port,
if (setsockopt(cn->handle, SOL_SOCKET, SO_REUSEADDR, if (setsockopt(cn->handle, SOL_SOCKET, SO_REUSEADDR,
(char *)&multi_client, (char *)&multi_client,
(socklen_t)sizeof(multi_client)) < 0) { (socklen_t)sizeof(multi_client))
< 0) {
mylog(LOG_WARN, "setsockopt() : %s", strerror(errno)); mylog(LOG_WARN, "setsockopt() : %s", strerror(errno));
close(cn->handle); close(cn->handle);
cn->handle = -1; cn->handle = -1;
@ -1187,7 +1190,8 @@ static int ctx_set_dh(SSL_CTX *ctx)
return 0; return 0;
} }
// SSL crap: passing argument 3 of SSL_CTX_ctrl with different width due to prototype // SSL crap: passing argument 3 of SSL_CTX_ctrl with different width due to
// prototype
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wtraditional-conversion" #pragma GCC diagnostic ignored "-Wtraditional-conversion"
ret = SSL_CTX_set_tmp_dh(ctx, dh); ret = SSL_CTX_set_tmp_dh(ctx, dh);
@ -1208,7 +1212,7 @@ connection_t *accept_new(connection_t *cn)
{ {
connection_t *conn; connection_t *conn;
int err; int err;
socklen_t sa_len = sizeof (struct sockaddr); socklen_t sa_len = sizeof(struct sockaddr);
struct sockaddr sa; struct sockaddr sa;
mylog(LOG_DEBUG, "Trying to accept new client on %d", cn->handle); mylog(LOG_DEBUG, "Trying to accept new client on %d", cn->handle);
@ -1238,19 +1242,23 @@ connection_t *accept_new(connection_t *cn)
#ifdef HAVE_LIBSSL #ifdef HAVE_LIBSSL
if (cn->ssl) { if (cn->ssl) {
if (!sslctx) { if (!sslctx) {
mylog(LOG_DEBUG, "No SSL context available for " mylog(LOG_DEBUG,
"No SSL context available for "
"accepted connections. " "accepted connections. "
"Initializing..."); "Initializing...");
if (!(sslctx = SSL_init_context(conf_client_ciphers))) { if (!(sslctx = SSL_init_context(conf_client_ciphers))) {
mylog(LOG_ERROR, "SSL context initialization " mylog(LOG_ERROR,
"SSL context initialization "
"failed"); "failed");
connection_free(conn); connection_free(conn);
return NULL; return NULL;
} }
if (!conf_client_dh_file) { if (!conf_client_dh_file) {
// try with a default path but don't fail if it doesn't exist // try with a default path but don't fail if it
conf_client_dh_file = default_path(conf_biphome, "dh.pem", // doesn't exist
conf_client_dh_file =
default_path(conf_biphome, "dh.pem",
"DH parameters"); "DH parameters");
struct stat st_buf; struct stat st_buf;
@ -1262,16 +1270,18 @@ connection_t *accept_new(connection_t *cn)
if (conf_client_dh_file) { if (conf_client_dh_file) {
if (!ctx_set_dh(sslctx)) { if (!ctx_set_dh(sslctx)) {
mylog(LOG_ERROR, "SSL Unable to load DH " mylog(LOG_ERROR,
"SSL Unable to load DH "
"parameters"); "parameters");
connection_free(conn); connection_free(conn);
return NULL; return NULL;
} }
} }
if (!SSL_CTX_use_certificate_chain_file(sslctx, if (!SSL_CTX_use_certificate_chain_file(
conf_ssl_certfile)) sslctx, conf_ssl_certfile))
mylog(LOG_WARN, "SSL: Unable to load " mylog(LOG_WARN,
"SSL: Unable to load "
"certificate file"); "certificate file");
if (!SSL_CTX_use_PrivateKey_file(sslctx, if (!SSL_CTX_use_PrivateKey_file(sslctx,
conf_ssl_certfile, conf_ssl_certfile,
@ -1288,7 +1298,7 @@ connection_t *accept_new(connection_t *cn)
SSL_set_accept_state(conn->ssl_h); SSL_set_accept_state(conn->ssl_h);
} }
#endif #endif
mylog(LOG_DEBUG, "New client on socket %d !",conn->handle); mylog(LOG_DEBUG, "New client on socket %d !", conn->handle);
return conn; return conn;
} }
@ -1312,7 +1322,8 @@ connection_t *listen_new(char *hostname, int port, int ssl)
} }
static connection_t *_connection_new(char *dsthostname, char *dstport, static connection_t *_connection_new(char *dsthostname, char *dstport,
char *srchostname, char *srcport, time_t timeout) char *srchostname, char *srcport,
time_t timeout)
{ {
connection_t *conn; connection_t *conn;
@ -1331,7 +1342,8 @@ static SSL_CTX *SSL_init_context(char *ciphers)
SSL_CTX *ctx; SSL_CTX *ctx;
if (!ssl_initialized) { if (!ssl_initialized) {
// SSL crap: passing argument 1 of OPENSSL_init_ssl with different width due to prototype // SSL crap: passing argument 1 of OPENSSL_init_ssl with different width due
// to prototype
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wtraditional-conversion" #pragma GCC diagnostic ignored "-Wtraditional-conversion"
SSL_library_init(); SSL_library_init();
@ -1340,13 +1352,14 @@ static SSL_CTX *SSL_init_context(char *ciphers)
errbio = BIO_new_fp(conf_global_log_file, BIO_NOCLOSE); errbio = BIO_new_fp(conf_global_log_file, BIO_NOCLOSE);
ssl_cx_idx = SSL_get_ex_new_index((size_t)0, "bip connection_t", ssl_cx_idx = SSL_get_ex_new_index((size_t)0, "bip connection_t",
NULL, NULL,NULL); NULL, NULL, NULL);
flags = O_RDONLY; flags = O_RDONLY;
flags |= O_NONBLOCK; flags |= O_NONBLOCK;
fd = open("/dev/random", flags); fd = open("/dev/random", flags);
if (fd < 0) { if (fd < 0) {
mylog(LOG_WARN, "SSL: /dev/random not ready, unable " mylog(LOG_WARN,
"SSL: /dev/random not ready, unable "
"to manually seed PRNG."); "to manually seed PRNG.");
goto prng_end; goto prng_end;
} }
@ -1354,16 +1367,18 @@ static SSL_CTX *SSL_init_context(char *ciphers)
do { do {
ret = read(fd, buf, (size_t)1024); ret = read(fd, buf, (size_t)1024);
if (ret <= 0) { if (ret <= 0) {
mylog(LOG_ERROR,"/dev/random: %s", mylog(LOG_ERROR, "/dev/random: %s",
strerror(errno)); strerror(errno));
goto prng_end; goto prng_end;
} }
mylog(LOG_DEBUG, "PRNG seeded with %d /dev/random " mylog(LOG_DEBUG,
"bytes", ret); "PRNG seeded with %d /dev/random "
"bytes",
ret);
RAND_seed(buf, (int)ret); RAND_seed(buf, (int)ret);
} while (!(rng = RAND_status())); } while (!(rng = RAND_status()));
prng_end: prng_end:
do { do {
ret = close(fd); ret = close(fd);
} while (ret != 0 && errno == EINTR); } while (ret != 0 && errno == EINTR);
@ -1371,7 +1386,8 @@ prng_end:
mylog(LOG_DEBUG, "SSL: PRNG is seeded !"); mylog(LOG_DEBUG, "SSL: PRNG is seeded !");
} else { } else {
mylog(LOG_WARN, "SSL: PRNG is not seeded enough"); mylog(LOG_WARN, "SSL: PRNG is not seeded enough");
mylog(LOG_WARN, " OpenSSL will use /dev/urandom if " mylog(LOG_WARN,
" OpenSSL will use /dev/urandom if "
"available."); "available.");
} }
@ -1385,10 +1401,12 @@ prng_end:
} }
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wtraditional-conversion" #pragma GCC diagnostic ignored "-Wtraditional-conversion"
// SSL crap: passing argument 3 of SSL_CTX_ctrl with different width due to prototype // SSL crap: passing argument 3 of SSL_CTX_ctrl with different width
// due to prototype
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_BOTH); SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_BOTH);
SSL_CTX_set_timeout(ctx, (long)60); SSL_CTX_set_timeout(ctx, (long)60);
// SSL crap: passing argument 2 of SSL_CTX_set_options with different width due to prototype // SSL crap: passing argument 2 of SSL_CTX_set_options with different
// width due to prototype
SSL_CTX_set_options(ctx, SSL_OP_ALL); SSL_CTX_set_options(ctx, SSL_OP_ALL);
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
if (ciphers && !SSL_CTX_set_cipher_list(ctx, ciphers)) { if (ciphers && !SSL_CTX_set_cipher_list(ctx, ciphers)) {
@ -1429,38 +1447,45 @@ static int bip_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
/* in basic mode (mode 1), accept a leaf certificate if we can find it /* in basic mode (mode 1), accept a leaf certificate if we can find it
* in the store */ * in the store */
if (c->ssl_check_mode == SSL_CHECK_BASIC && result == 0 && if (c->ssl_check_mode == SSL_CHECK_BASIC && result == 0
(err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY || && (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
err == X509_V_ERR_CERT_UNTRUSTED || || err == X509_V_ERR_CERT_UNTRUSTED
err == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE || || err == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE
err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT || || err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
err == X509_V_ERR_CERT_HAS_EXPIRED || || err == X509_V_ERR_CERT_HAS_EXPIRED
err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN)) { || err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN)) {
if (!(xobj = X509_OBJECT_new())) { if (!(xobj = X509_OBJECT_new())) {
result = 0; result = 0;
} else { } else {
if (X509_STORE_CTX_get_by_subject(ctx, X509_LU_X509, if (X509_STORE_CTX_get_by_subject(
X509_get_subject_name(err_cert), xobj) > 0 && ctx, X509_LU_X509,
!X509_cmp(X509_OBJECT_get0_X509(xobj), err_cert)) { X509_get_subject_name(err_cert), xobj)
> 0
&& !X509_cmp(X509_OBJECT_get0_X509(xobj),
err_cert)) {
if (err == X509_V_ERR_CERT_HAS_EXPIRED) if (err == X509_V_ERR_CERT_HAS_EXPIRED)
mylog(LOG_INFO, "Basic mode; Accepting " mylog(LOG_INFO,
"Basic mode; Accepting "
"*expired* peer certificate " "*expired* peer certificate "
"found in store."); "found in store.");
else else
mylog(LOG_INFO, "Basic mode; Accepting peer " mylog(LOG_INFO,
"Basic mode; Accepting peer "
"certificate found in store."); "certificate found in store.");
result = 1; result = 1;
err = X509_V_OK; err = X509_V_OK;
X509_STORE_CTX_set_error(ctx, err); X509_STORE_CTX_set_error(ctx, err);
} else { } else {
mylog(LOG_INFO, "Basic mode; peer certificate NOT " mylog(LOG_INFO,
"Basic mode; peer certificate NOT "
"in store, rejecting it!"); "in store, rejecting it!");
err = X509_V_ERR_CERT_REJECTED; err = X509_V_ERR_CERT_REJECTED;
X509_STORE_CTX_set_error(ctx, err); X509_STORE_CTX_set_error(ctx, err);
link_add_untrusted(c->user_data, X509_dup(err_cert)); link_add_untrusted(c->user_data,
X509_dup(err_cert));
} }
X509_OBJECT_free(xobj); X509_OBJECT_free(xobj);
} }
@ -1524,7 +1549,7 @@ static int SSLize(connection_t *cn, int *nc)
case SSL_CHECK_NONE: case SSL_CHECK_NONE:
break; break;
case SSL_CHECK_BASIC: case SSL_CHECK_BASIC:
if((errl = SSL_get_verify_result(cn->ssl_h)) != X509_V_OK) { if ((errl = SSL_get_verify_result(cn->ssl_h)) != X509_V_OK) {
mylog(LOG_ERROR, "Certificate check failed: %s (%ld)!", mylog(LOG_ERROR, "Certificate check failed: %s (%ld)!",
X509_verify_cert_error_string(errl), errl); X509_verify_cert_error_string(errl), errl);
cn->connected = CONN_UNTRUSTED; cn->connected = CONN_UNTRUSTED;
@ -1532,7 +1557,7 @@ static int SSLize(connection_t *cn, int *nc)
} }
break; break;
case SSL_CHECK_CA: case SSL_CHECK_CA:
if((errl = SSL_get_verify_result(cn->ssl_h)) != X509_V_OK) { if ((errl = SSL_get_verify_result(cn->ssl_h)) != X509_V_OK) {
mylog(LOG_ERROR, "Certificate check failed: %s (%ld)!", mylog(LOG_ERROR, "Certificate check failed: %s (%ld)!",
X509_verify_cert_error_string(errl), errl); X509_verify_cert_error_string(errl), errl);
cn->connected = CONN_UNTRUSTED; cn->connected = CONN_UNTRUSTED;
@ -1540,7 +1565,8 @@ static int SSLize(connection_t *cn, int *nc)
} }
break; break;
default: default:
mylog(LOG_ERROR, "Unknown ssl_check_mode (%d)!", cn->ssl_check_mode); mylog(LOG_ERROR, "Unknown ssl_check_mode (%d)!",
cn->ssl_check_mode);
return 1; return 1;
} }
@ -1563,8 +1589,11 @@ static int SSLize(connection_t *cn, int *nc)
} }
static connection_t *_connection_new_SSL(char *dsthostname, char *dstport, static connection_t *_connection_new_SSL(char *dsthostname, char *dstport,
char *srchostname, char *srcport, char *ciphers, int check_mode, char *srchostname, char *srcport,
char *check_store, char *ssl_client_certfile, time_t timeout) char *ciphers, int check_mode,
char *check_store,
char *ssl_client_certfile,
time_t timeout)
{ {
connection_t *conn; connection_t *conn;
@ -1584,18 +1613,21 @@ static connection_t *_connection_new_SSL(char *dsthostname, char *dstport,
case SSL_CHECK_BASIC: case SSL_CHECK_BASIC:
if (!SSL_CTX_load_verify_locations(conn->ssl_ctx_h, check_store, if (!SSL_CTX_load_verify_locations(conn->ssl_ctx_h, check_store,
NULL)) { NULL)) {
mylog(LOG_ERROR, "Can't assign check store to " mylog(LOG_ERROR,
"Can't assign check store to "
"SSL connection! Proceeding without!"); "SSL connection! Proceeding without!");
} }
break; break;
case SSL_CHECK_CA: case SSL_CHECK_CA:
if (!check_store) { if (!check_store) {
if (SSL_CTX_set_default_verify_paths(conn->ssl_ctx_h)) { if (SSL_CTX_set_default_verify_paths(conn->ssl_ctx_h)) {
mylog(LOG_INFO, "No SSL certificate check store configured. " mylog(LOG_INFO,
"No SSL certificate check store configured. "
"Default store will be used."); "Default store will be used.");
break; break;
} else { } else {
mylog(LOG_ERROR, "No SSL certificate check store configured " mylog(LOG_ERROR,
"No SSL certificate check store configured "
"and cannot use default store!"); "and cannot use default store!");
return conn; return conn;
} }
@ -1603,28 +1635,34 @@ static connection_t *_connection_new_SSL(char *dsthostname, char *dstport,
// Check if check_store is a file or directory // Check if check_store is a file or directory
if (stat(check_store, &st_buf) == 0) { if (stat(check_store, &st_buf) == 0) {
if (st_buf.st_mode & S_IFDIR) { if (st_buf.st_mode & S_IFDIR) {
if (!SSL_CTX_load_verify_locations(conn->ssl_ctx_h, NULL, if (!SSL_CTX_load_verify_locations(
conn->ssl_ctx_h, NULL,
check_store)) { check_store)) {
mylog(LOG_ERROR, "Can't assign check store to " mylog(LOG_ERROR,
"Can't assign check store to "
"SSL connection!"); "SSL connection!");
return conn; return conn;
} }
break; break;
} }
if (st_buf.st_mode & S_IFREG) { if (st_buf.st_mode & S_IFREG) {
if (!SSL_CTX_load_verify_locations(conn->ssl_ctx_h, check_store, if (!SSL_CTX_load_verify_locations(
conn->ssl_ctx_h, check_store,
NULL)) { NULL)) {
mylog(LOG_ERROR, "Can't assign check store to " mylog(LOG_ERROR,
"Can't assign check store to "
"SSL connection!"); "SSL connection!");
return conn; return conn;
} }
break; break;
} }
mylog(LOG_ERROR, "Specified SSL certificate check store is neither " mylog(LOG_ERROR,
"Specified SSL certificate check store is neither "
"a file nor a directory."); "a file nor a directory.");
return conn; return conn;
} }
mylog(LOG_ERROR, "Can't open SSL certificate check store! Check path " mylog(LOG_ERROR,
"Can't open SSL certificate check store! Check path "
"and permissions."); "and permissions.");
return conn; return conn;
default: default:
@ -1653,11 +1691,14 @@ static connection_t *_connection_new_SSL(char *dsthostname, char *dstport,
ssl_client_certfile)) ssl_client_certfile))
mylog(LOG_WARN, "SSL: Unable to load certificate file"); mylog(LOG_WARN, "SSL: Unable to load certificate file");
else if (!SSL_CTX_use_PrivateKey_file(conn->ssl_ctx_h, else if (!SSL_CTX_use_PrivateKey_file(conn->ssl_ctx_h,
ssl_client_certfile, SSL_FILETYPE_PEM)) ssl_client_certfile,
SSL_FILETYPE_PEM))
mylog(LOG_WARN, "SSL: Unable to load key file"); mylog(LOG_WARN, "SSL: Unable to load key file");
else else
mylog(LOG_INFO, "SSL: using %s pem file as client SSL " mylog(LOG_INFO,
"certificate", ssl_client_certfile); "SSL: using %s pem file as client SSL "
"certificate",
ssl_client_certfile);
} }
conn->ssl_h = SSL_new(conn->ssl_ctx_h); conn->ssl_h = SSL_new(conn->ssl_ctx_h);
@ -1683,8 +1724,9 @@ static connection_t *_connection_new_SSL(char *dsthostname, char *dstport,
#endif #endif
connection_t *connection_new(char *dsthostname, int dstport, char *srchostname, connection_t *connection_new(char *dsthostname, int dstport, char *srchostname,
int srcport, int ssl, char *ssl_ciphers, int ssl_check_mode, int srcport, int ssl, char *ssl_ciphers,
char *ssl_check_store, char *ssl_client_certfile, time_t timeout) int ssl_check_mode, char *ssl_check_store,
char *ssl_client_certfile, time_t timeout)
{ {
char dstportbuf[20], srcportbuf[20], *tmp; char dstportbuf[20], srcportbuf[20], *tmp;
#ifndef HAVE_LIBSSL #ifndef HAVE_LIBSSL
@ -1706,8 +1748,9 @@ connection_t *connection_new(char *dsthostname, int dstport, char *srchostname,
#ifdef HAVE_LIBSSL #ifdef HAVE_LIBSSL
if (ssl) if (ssl)
return _connection_new_SSL(dsthostname, dstportbuf, srchostname, return _connection_new_SSL(dsthostname, dstportbuf, srchostname,
tmp, ssl_ciphers, ssl_check_mode, ssl_check_store, tmp, ssl_ciphers, ssl_check_mode,
ssl_client_certfile, timeout); ssl_check_store, ssl_client_certfile,
timeout);
else else
#endif #endif
return _connection_new(dsthostname, dstportbuf, srchostname, return _connection_new(dsthostname, dstportbuf, srchostname,
@ -1747,37 +1790,37 @@ static int socket_set_nonblock(int s)
int flags; int flags;
if ((flags = fcntl(s, F_GETFL, 0)) < 0) { if ((flags = fcntl(s, F_GETFL, 0)) < 0) {
mylog(LOG_ERROR, "Cannot set socket %d to non blocking : %s", mylog(LOG_ERROR, "Cannot set socket %d to non blocking : %s", s,
s, strerror(errno)); strerror(errno));
return 0; return 0;
} }
if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) { if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) {
mylog(LOG_ERROR, "Cannot set socket %d to non blocking : %s", mylog(LOG_ERROR, "Cannot set socket %d to non blocking : %s", s,
s, strerror(errno)); strerror(errno));
return 0; return 0;
} }
return 1; return 1;
} }
#ifdef TEST #ifdef TEST
int main(int argc,char* argv[]) int main(int argc, char *argv[])
{ {
connection_t *conn, *conn2; connection_t *conn, *conn2;
int s, cont = 1; int s, cont = 1;
if (argc != 3) { if (argc != 3) {
fprintf(stderr,"Usage: %s host port\n",argv[0]); fprintf(stderr, "Usage: %s host port\n", argv[0]);
exit(1); exit(1);
} }
conn = connection_init(0, 0, (time_t)0, 1); conn = connection_init(0, 0, (time_t)0, 1);
conn->connect_time = time(NULL); conn->connect_time = time(NULL);
create_listening_socket(argv[1],argv[2],&conn); create_listening_socket(argv[1], argv[2], &conn);
if (s == -1) { if (s == -1) {
mylog(LOG_ERROR, "socket() : %s", strerror(errno)); mylog(LOG_ERROR, "socket() : %s", strerror(errno));
exit(1); exit(1);
} }
mylog(LOG_DEBUG, "Socket number %d",s); mylog(LOG_DEBUG, "Socket number %d", s);
while (cont) { while (cont) {
conn2 = accept_new(conn); conn2 = accept_new(conn);
@ -1789,7 +1832,7 @@ int main(int argc,char* argv[])
} }
while (1) { while (1) {
int ret = read_socket(conn2); int ret = read_socket(conn2);
mylog(LOG_DEBUGTOOMUCH, "READ: %d %*s",ret, conn2->incoming, mylog(LOG_DEBUGTOOMUCH, "READ: %d %*s", ret, conn2->incoming,
conn2->incoming_end); conn2->incoming_end);
conn2->incoming_end = 0; conn2->incoming_end = 0;
sleep(1); sleep(1);
@ -1866,8 +1909,7 @@ static char *socket_ip(int fd, int remote)
/* getsockname every time to get IP version */ /* getsockname every time to get IP version */
err = getsockname(fd, (struct sockaddr *)&addr, &addrlen); err = getsockname(fd, (struct sockaddr *)&addr, &addrlen);
if (err != 0) { if (err != 0) {
mylog(LOG_ERROR, "in getsockname(%d): %s", fd, mylog(LOG_ERROR, "in getsockname(%d): %s", fd, strerror(errno));
strerror(errno));
return NULL; return NULL;
} }

View File

@ -92,8 +92,9 @@ typedef struct connection {
} connection_t; } connection_t;
connection_t *connection_new(char *dsthostname, int dstport, char *srchostname, connection_t *connection_new(char *dsthostname, int dstport, char *srchostname,
int srcport, int ssl, char *ssl_ciphers, int ssl_check_mode, int srcport, int ssl, char *ssl_ciphers,
char *ssl_check_store, char *ssl_client_certfile, time_t timeout); int ssl_check_mode, char *ssl_check_store,
char *ssl_client_certfile, time_t timeout);
connection_t *listen_new(char *hostname, int port, int ssl); connection_t *listen_new(char *hostname, int port, int ssl);
connection_t *accept_new(connection_t *cn); connection_t *accept_new(connection_t *cn);
void connection_free(connection_t *cn); void connection_free(connection_t *cn);

411
src/irc.c
View File

@ -24,7 +24,8 @@
#include "md5.h" #include "md5.h"
#include "utils/base64.h" #include "utils/base64.h"
// TODO resolve assuming signed overflow does not occur when changing X +- C1 cmp C2 to X cmp C2 -+ C1 // 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" #pragma GCC diagnostic ignored "-Wstrict-overflow"
#define S_CONN_DELAY (10) #define S_CONN_DELAY (10)
@ -36,7 +37,8 @@ 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);
static int irc_mode_channel(struct link_server *s, struct channel *channel, static int irc_mode_channel(struct link_server *s, struct channel *channel,
struct line *line, const char* mode, int add, int cur_arg); struct line *line, const char *mode, int add,
int cur_arg);
static int irc_kick(struct link_server *server, struct line *line); static int irc_kick(struct link_server *server, struct line *line);
static int irc_privmsg(struct link_server *server, struct line *line); static int irc_privmsg(struct link_server *server, struct line *line);
static int irc_notice(struct link_server *server, struct line *line); static int irc_notice(struct link_server *server, struct line *line);
@ -56,7 +58,7 @@ static void ls_set_nick(struct link_server *ircs, char *nick);
static void server_set_chanmodes(struct link_server *l, const char *chanmodes); static void server_set_chanmodes(struct link_server *l, const char *chanmodes);
static void server_set_prefix(struct link_server *l, const char *prefix); static void server_set_prefix(struct link_server *l, const char *prefix);
static void server_init_modes(struct link_server *s); static void server_init_modes(struct link_server *s);
static int bip_get_index(const char* str, char car); static int bip_get_index(const char *str, char car);
static int bip_fls(long v); static int bip_fls(long v);
void oidentd_dump(bip_t *bip); void oidentd_dump(bip_t *bip);
@ -123,7 +125,7 @@ list_t *channel_name_list(struct link_server *server, struct channel *c)
ret = list_new(NULL); ret = list_new(NULL);
*str = 0; *str = 0;
for (hash_it_init(&c->ovmasks, &hi); hash_it_key(&hi); for (hash_it_init(&c->ovmasks, &hi); hash_it_key(&hi);
hash_it_next(&hi)){ hash_it_next(&hi)) {
const char *nick = hash_it_key(&hi); const char *nick = hash_it_key(&hi);
long int ovmask = (long int)hash_it_item(&hi); long int ovmask = (long int)hash_it_item(&hi);
@ -195,8 +197,8 @@ void irc_compute_lag(struct link_server *is)
time_t lag; time_t lag;
assert(is->laginit_ts != -1); assert(is->laginit_ts != -1);
lag = time(NULL) - is->laginit_ts; lag = time(NULL) - is->laginit_ts;
if (lag > LAGOUT_TIME*2) if (lag > LAGOUT_TIME * 2)
is->lag = LAGOUT_TIME*2; is->lag = LAGOUT_TIME * 2;
else else
is->lag = (unsigned)lag; is->lag = (unsigned)lag;
} }
@ -238,8 +240,8 @@ static void irc_server_connected(struct link_server *server)
LINK(server)->s_state = IRCS_CONNECTED; LINK(server)->s_state = IRCS_CONNECTED;
LINK(server)->s_conn_attempt = 0; LINK(server)->s_conn_attempt = 0;
mylog(LOG_INFO, "[%s] Connected for user %s", mylog(LOG_INFO, "[%s] Connected for user %s", LINK(server)->name,
LINK(server)->name, LINK(server)->user->name); LINK(server)->user->name);
irc_server_join(server); irc_server_join(server);
log_connected(LINK(server)->log); log_connected(LINK(server)->log);
@ -401,54 +403,74 @@ int irc_dispatch_server(bip_t *bip, struct link_server *server,
} }
} else if (irc_line_elem_equals(line, 0, "CAP")) { } else if (irc_line_elem_equals(line, 0, "CAP")) {
if (LINK(server)->sasl_mechanism) { if (LINK(server)->sasl_mechanism) {
if (irc_line_elem_equals(line, 2, "ACK") && irc_line_elem_equals(line, 3, "sasl")) { if (irc_line_elem_equals(line, 2, "ACK")
// Server is answering our CAP REQ :sasl and is SASL capable && irc_line_elem_equals(line, 3, "sasl")) {
char *sasl_mech = sasl_mechanism_to_text(LINK(server)->sasl_mechanism); // Server is answering our CAP REQ :sasl and is
mylog(LOG_INFO, "[%s] Server is SASL capable, starting %s authentication.", // SASL capable
char *sasl_mech = sasl_mechanism_to_text(
LINK(server)->sasl_mechanism);
mylog(LOG_INFO,
"[%s] Server is SASL capable, starting %s authentication.",
LINK(server)->name, sasl_mech); LINK(server)->name, sasl_mech);
WRITE_LINE1(CONN(server), NULL, "AUTHENTICATE", sasl_mech); WRITE_LINE1(CONN(server), NULL, "AUTHENTICATE",
sasl_mech);
ret = OK_FORGET; ret = OK_FORGET;
} else if (irc_line_elem_equals(line, 2, "NAK") && irc_line_elem_equals(line, 3, "sasl")) { } else if (irc_line_elem_equals(line, 2, "NAK")
// Server is answering our CAP REQ :sasl and isn't SASL capable && irc_line_elem_equals(line, 3, "sasl")) {
mylog(LOG_INFO, "[%s] Server is not SASL capable.", LINK(server)->name); // Server is answering our CAP REQ :sasl and
// isn't SASL capable
mylog(LOG_INFO,
"[%s] Server is not SASL capable.",
LINK(server)->name);
ret = ERR_PROTOCOL; ret = ERR_PROTOCOL;
} else {
// Unhandled CAP message
mylog(LOG_ERROR,
"[%s] Unhandled CAP message: %s",
LINK(server)->name,
irc_line_to_string(line));
ret = OK_FORGET;
}
} else { } else {
// Unhandled CAP message // Unhandled CAP message
mylog(LOG_ERROR, "[%s] Unhandled CAP message: %s", mylog(LOG_ERROR, "[%s] Unhandled CAP message: %s",
LINK(server)->name, irc_line_to_string(line)); LINK(server)->name, irc_line_to_string(line));
ret = OK_FORGET; ret = OK_FORGET;
} }
} else {
// Unhandled CAP message
mylog(LOG_ERROR, "[%s] Unhandled CAP message: %s", LINK(server)->name,
irc_line_to_string(line));
ret = OK_FORGET;
}
} else if (irc_line_elem_equals(line, 0, "AUTHENTICATE")) { } else if (irc_line_elem_equals(line, 0, "AUTHENTICATE")) {
if (LINK(server)->sasl_mechanism) { if (LINK(server)->sasl_mechanism) {
if (irc_line_count(line) == 2 && irc_line_elem_equals(line, 1, "+")) { if (irc_line_count(line) == 2
// Server is waiting for us to authenticate, let's do it && irc_line_elem_equals(line, 1, "+")) {
mylog(LOG_INFO, "[%s] Server accepted our authentication mechanism.", // Server is waiting for us to authenticate,
// let's do it
mylog(LOG_INFO,
"[%s] Server accepted our authentication mechanism.",
LINK(server)->name); LINK(server)->name);
ret = irc_server_sasl_authenticate(server); ret = irc_server_sasl_authenticate(server);
} else { } else {
// Anything else than "AUTHENTICATE +" is unknown to us // Anything else than "AUTHENTICATE +" is
mylog(LOG_ERROR, "[%s] Server sent gibberish: %s", // unknown to us
LINK(server)->name, irc_line_to_string(line)); mylog(LOG_ERROR,
"[%s] Server sent gibberish: %s",
LINK(server)->name,
irc_line_to_string(line));
ret = ERR_PROTOCOL; ret = ERR_PROTOCOL;
} }
} else { } else {
// Unhandled AUTHENTICATE message // Unhandled AUTHENTICATE message
mylog(LOG_ERROR, "[%s] Unhandled AUTHENTICATE message: %s", mylog(LOG_ERROR,
"[%s] Unhandled AUTHENTICATE message: %s",
LINK(server)->name, irc_line_to_string(line)); LINK(server)->name, irc_line_to_string(line));
ret = OK_FORGET; ret = OK_FORGET;
} }
} else if (irc_line_elem_equals(line, 0, "900")) { } else if (irc_line_elem_equals(line, 0, "900")) {
if (irc_line_count(line) >= 5) { if (irc_line_count(line) >= 5) {
mylog(LOG_INFO, "[%s] Logged in as %s(%s): %s", LINK(server)->name, mylog(LOG_INFO, "[%s] Logged in as %s(%s): %s",
irc_line_elem(line, 3), irc_line_elem(line, 2), irc_line_elem(line, 4)); LINK(server)->name, irc_line_elem(line, 3),
irc_line_elem(line, 2), irc_line_elem(line, 4));
} else { } else {
mylog(LOG_INFO, "[%s] Logged in: %s", LINK(server)->name, irc_line_to_string(line)); mylog(LOG_INFO, "[%s] Logged in: %s",
LINK(server)->name, irc_line_to_string(line));
} }
ret = OK_FORGET; ret = OK_FORGET;
} else if (irc_line_elem_equals(line, 0, "901")) { } else if (irc_line_elem_equals(line, 0, "901")) {
@ -456,7 +478,8 @@ int irc_dispatch_server(bip_t *bip, struct link_server *server,
mylog(LOG_INFO, "[%s] Logged out: %s", mylog(LOG_INFO, "[%s] Logged out: %s",
LINK(server)->name, irc_line_elem(line, 3)); LINK(server)->name, irc_line_elem(line, 3));
} else { } else {
mylog(LOG_INFO, "[%s] Logged out: %s", LINK(server)->name, irc_line_to_string(line)); mylog(LOG_INFO, "[%s] Logged out: %s",
LINK(server)->name, irc_line_to_string(line));
} }
ret = OK_FORGET; ret = OK_FORGET;
} else if (irc_line_elem_equals(line, 0, "902")) { } else if (irc_line_elem_equals(line, 0, "902")) {
@ -464,25 +487,30 @@ int irc_dispatch_server(bip_t *bip, struct link_server *server,
LINK(server)->name, irc_line_to_string(line)); LINK(server)->name, irc_line_to_string(line));
ret = OK_FORGET; ret = OK_FORGET;
} else if (irc_line_elem_equals(line, 0, "903")) { } else if (irc_line_elem_equals(line, 0, "903")) {
mylog(LOG_INFO, "[%s] SASL authentication successful", LINK(server)->name); mylog(LOG_INFO, "[%s] SASL authentication successful",
LINK(server)->name);
WRITE_LINE1(CONN(server), NULL, "CAP", "END"); WRITE_LINE1(CONN(server), NULL, "CAP", "END");
ret = OK_FORGET; ret = OK_FORGET;
} else if (irc_line_elem_equals(line, 0, "904")) { } else if (irc_line_elem_equals(line, 0, "904")) {
mylog(LOG_ERROR, "[%s] SASL authentication failed", LINK(server)->name); mylog(LOG_ERROR, "[%s] SASL authentication failed",
LINK(server)->name);
ret = ERR_AUTH; ret = ERR_AUTH;
} else if (irc_line_elem_equals(line, 0, "905")) { } else if (irc_line_elem_equals(line, 0, "905")) {
mylog(LOG_ERROR, "[%s] SASL message too long", LINK(server)->name); mylog(LOG_ERROR, "[%s] SASL message too long",
LINK(server)->name);
ret = ERR_AUTH; ret = ERR_AUTH;
} else if (irc_line_elem_equals(line, 0, "906")) { } else if (irc_line_elem_equals(line, 0, "906")) {
mylog(LOG_ERROR, "[%s] SASL authentication aborted by client", mylog(LOG_ERROR, "[%s] SASL authentication aborted by client",
LINK(server)->name); LINK(server)->name);
ret = ERR_AUTH; ret = ERR_AUTH;
} else if (irc_line_elem_equals(line, 0, "907")) { } else if (irc_line_elem_equals(line, 0, "907")) {
mylog(LOG_ERROR, "[%s] SASL authentication has already been completed", mylog(LOG_ERROR,
"[%s] SASL authentication has already been completed",
LINK(server)->name); LINK(server)->name);
ret = OK_FORGET; ret = OK_FORGET;
} else if (irc_line_elem_equals(line, 0, "908")) { } else if (irc_line_elem_equals(line, 0, "908")) {
mylog(LOG_ERROR, "[%s] Server only accepts following authentication mechanisms: %s", mylog(LOG_ERROR,
"[%s] Server only accepts following authentication mechanisms: %s",
LINK(server)->name, irc_line_elem(line, 2)); LINK(server)->name, irc_line_elem(line, 2));
ret = ERR_AUTH; ret = ERR_AUTH;
} else if (irc_line_elem_equals(line, 0, "433")) { } else if (irc_line_elem_equals(line, 0, "433")) {
@ -501,8 +529,10 @@ int irc_dispatch_server(bip_t *bip, struct link_server *server,
newnick[7] = '`'; newnick[7] = '`';
} }
} else { } else {
newnick[8] = (char)('a' + ('z' - 'a') * newnick[8] =
rand() / RAND_MAX); (char)('a'
+ ('z' - 'a') * rand()
/ RAND_MAX);
} }
newnick[9] = 0; newnick[9] = 0;
} }
@ -523,13 +553,19 @@ int irc_dispatch_server(bip_t *bip, struct link_server *server,
if (irc_line_elem_equals(line, 0, "005")) { if (irc_line_elem_equals(line, 0, "005")) {
int i; int i;
for (i = irc_line_count(line) - 1; i > 0; i--) { for (i = irc_line_count(line) - 1; i > 0; i--) {
if (LINK(server)->ignore_server_capab && if (LINK(server)->ignore_server_capab
irc_line_elem_equals(line, i, "CAPAB")) && irc_line_elem_equals(line, i, "CAPAB"))
irc_line_drop(line, i); irc_line_drop(line, i);
else if (!strncmp(irc_line_elem(line, i), "CHANMODES=", (size_t)10)) else if (!strncmp(irc_line_elem(line, i),
server_set_chanmodes(server, irc_line_elem(line, i) + 10); "CHANMODES=", (size_t)10))
else if (!strncmp(irc_line_elem(line, i), "PREFIX=(", (size_t)8)) server_set_chanmodes(
server_set_prefix(server, irc_line_elem(line, i) + 7); server,
irc_line_elem(line, i) + 10);
else if (!strncmp(irc_line_elem(line, i),
"PREFIX=(", (size_t)8))
server_set_prefix(server,
irc_line_elem(line, i)
+ 7);
} }
} }
if (irc_line_elem_equals(line, 0, "NOTICE")) { if (irc_line_elem_equals(line, 0, "NOTICE")) {
@ -594,8 +630,8 @@ int irc_dispatch_server(bip_t *bip, struct link_server *server,
if (ret == OK_COPY) { if (ret == OK_COPY) {
unsigned int i; unsigned int i;
for (i = 0; i < LINK(server)->l_clientc; i++) { for (i = 0; i < LINK(server)->l_clientc; i++) {
if (TYPE(LINK(server)->l_clientv[i]) == if (TYPE(LINK(server)->l_clientv[i])
IRC_TYPE_CLIENT) { == IRC_TYPE_CLIENT) {
char *s = irc_line_to_string(line); char *s = irc_line_to_string(line);
write_line(CONN(LINK(server)->l_clientv[i]), s); write_line(CONN(LINK(server)->l_clientv[i]), s);
free(s); free(s);
@ -609,8 +645,8 @@ int irc_dispatch_server(bip_t *bip, struct link_server *server,
write_line(CONN(LINK(server)->who_client), s); write_line(CONN(LINK(server)->who_client), s);
free(s); free(s);
} }
if (LINK(server)->who_client && if (LINK(server)->who_client
LINK(server)->who_client->who_count == 0) { && LINK(server)->who_client->who_count == 0) {
mylog(LOG_DEBUG, "OK_COPY_WHO: who_count for %p is nul", mylog(LOG_DEBUG, "OK_COPY_WHO: who_count for %p is nul",
LINK(server)->who_client); LINK(server)->who_client);
rotate_who_client(LINK(server)); rotate_who_client(LINK(server));
@ -628,8 +664,8 @@ static void irc_send_join(struct link_client *ic, struct channel *chan)
assert(user); assert(user);
/* user ircmask here for rbot */ /* user ircmask here for rbot */
ircmask = bip_malloc(strlen(LINK(ic)->l_server->nick) + ircmask = bip_malloc(strlen(LINK(ic)->l_server->nick)
strlen(BIP_FAKEMASK) + 1); + strlen(BIP_FAKEMASK) + 1);
strcpy(ircmask, LINK(ic)->l_server->nick); strcpy(ircmask, LINK(ic)->l_server->nick);
strcat(ircmask, BIP_FAKEMASK); strcat(ircmask, BIP_FAKEMASK);
WRITE_LINE1(CONN(ic), ircmask, "JOIN", chan->name); WRITE_LINE1(CONN(ic), ircmask, "JOIN", chan->name);
@ -673,8 +709,8 @@ static void bind_to_link(struct link *l, struct link_client *ic)
LINK(ic) = l; LINK(ic) = l;
l->l_clientc++; l->l_clientc++;
l->l_clientv = bip_realloc(l->l_clientv, l->l_clientc * l->l_clientv = bip_realloc(l->l_clientv,
sizeof(struct link_client *)); l->l_clientc * sizeof(struct link_client *));
l->l_clientv[i] = ic; l->l_clientv[i] = ic;
} }
@ -701,8 +737,8 @@ void unbind_from_link(struct link_client *ic)
if (l->l_clientc == 0) if (l->l_clientc == 0)
fatal("unbind_from_link: negative client count"); fatal("unbind_from_link: negative client count");
l->l_clientc--; l->l_clientc--;
l->l_clientv = bip_realloc(l->l_clientv, l->l_clientc * l->l_clientv = bip_realloc(l->l_clientv,
sizeof(struct link_client *)); l->l_clientc * sizeof(struct link_client *));
if (l->l_clientc == 0) { /* bip_realloc was equiv to free() */ if (l->l_clientc == 0) { /* bip_realloc was equiv to free() */
l->l_clientv = NULL; l->l_clientv = NULL;
return; return;
@ -759,8 +795,8 @@ static void irc_cli_make_join(struct link_client *ic)
list_iterator_t li; list_iterator_t li;
for (list_it_init(&LINK(ic)->chan_infos_order, &li); for (list_it_init(&LINK(ic)->chan_infos_order, &li);
list_it_item(&li); list_it_next(&li)) { list_it_item(&li); list_it_next(&li)) {
struct chan_info *ci = (struct chan_info *) struct chan_info *ci =
list_it_item(&li); (struct chan_info *)list_it_item(&li);
struct channel *chan; struct channel *chan;
if ((chan = hash_get(&LINK(ic)->l_server->channels, if ((chan = hash_get(&LINK(ic)->l_server->channels,
ci->name))) ci->name)))
@ -771,8 +807,8 @@ static void irc_cli_make_join(struct link_client *ic)
hash_iterator_t hi; hash_iterator_t hi;
for (hash_it_init(&LINK(ic)->l_server->channels, &hi); for (hash_it_init(&LINK(ic)->l_server->channels, &hi);
hash_it_item(&hi); hash_it_next(&hi)) { hash_it_item(&hi); hash_it_next(&hi)) {
struct channel *chan = (struct channel *) struct channel *chan =
hash_it_item(&hi); (struct channel *)hash_it_item(&hi);
if (!hash_get(&LINK(ic)->chan_infos, chan->name)) if (!hash_get(&LINK(ic)->chan_infos, chan->name))
irc_send_join(ic, chan); irc_send_join(ic, chan);
} }
@ -848,10 +884,10 @@ static int irc_cli_startup(bip_t *bip, struct link_client *ic,
for (list_it_init(&bip->link_list, &it); list_it_item(&it); for (list_it_init(&bip->link_list, &it); list_it_item(&it);
list_it_next(&it)) { list_it_next(&it)) {
struct link *l = list_it_item(&it); struct link *l = list_it_item(&it);
if (strcmp(user, l->user->name) == 0 && if (strcmp(user, l->user->name) == 0
strcmp(connname, l->name) == 0) { && strcmp(connname, l->name) == 0) {
if (chash_cmp(pass, l->user->password, if (chash_cmp(pass, l->user->password, l->user->seed)
l->user->seed) == 0) { == 0) {
bind_to_link(l, ic); bind_to_link(l, ic);
break; break;
} }
@ -887,7 +923,8 @@ static int irc_cli_startup(bip_t *bip, struct link_client *ic,
if (LINK(ic)->s_state == IRCS_NONE) { if (LINK(ic)->s_state == IRCS_NONE) {
/* drop it if corresponding server hasn't connected at all. */ /* drop it if corresponding server hasn't connected at all. */
write_line_fast(CONN(ic), ":irc.bip.net NOTICE pouet " write_line_fast(CONN(ic),
":irc.bip.net NOTICE pouet "
":ERROR Proxy not yet connected, try again " ":ERROR Proxy not yet connected, try again "
"later\r\n"); "later\r\n");
unbind_from_link(ic); unbind_from_link(ic);
@ -898,8 +935,8 @@ static int irc_cli_startup(bip_t *bip, struct link_client *ic,
list_remove(&bip->connecting_client_list, ic); list_remove(&bip->connecting_client_list, ic);
TYPE(ic) = IRC_TYPE_CLIENT; TYPE(ic) = IRC_TYPE_CLIENT;
for (list_it_init(&LINK(ic)->init_strings, &it); for (list_it_init(&LINK(ic)->init_strings, &it); list_it_item(&it);
list_it_item(&it); list_it_next(&it)) list_it_next(&it))
write_init_string(CONN(ic), list_it_item(&it), init_nick); write_init_string(CONN(ic), list_it_item(&it), init_nick);
/* we change nick on server */ /* we change nick on server */
@ -909,8 +946,8 @@ static int irc_cli_startup(bip_t *bip, struct link_client *ic,
if (!LINK(ic)->ignore_first_nick) if (!LINK(ic)->ignore_first_nick)
WRITE_LINE1(CONN(server), NULL, "NICK", init_nick); WRITE_LINE1(CONN(server), NULL, "NICK", init_nick);
else if (LINK(ic)->away_nick && else if (LINK(ic)->away_nick
strcmp(LINK(ic)->away_nick, server->nick) == 0) && strcmp(LINK(ic)->away_nick, server->nick) == 0)
WRITE_LINE1(CONN(server), NULL, "NICK", WRITE_LINE1(CONN(server), NULL, "NICK",
LINK(server)->connect_nick); LINK(server)->connect_nick);
@ -1038,8 +1075,8 @@ static int irc_cli_who(struct link_client *ic, struct line *line)
++ic->who_count; ++ic->who_count;
if (ic->who_count == 1) if (ic->who_count == 1)
ic->whoc_tstamp = time(NULL); ic->whoc_tstamp = time(NULL);
mylog(LOG_DEBUG, "cli_who: Incrementing who count for %p: %d", mylog(LOG_DEBUG, "cli_who: Incrementing who count for %p: %d", ic,
ic, ic->who_count); ic->who_count);
if (l->who_client && l->who_client != ic) { if (l->who_client && l->who_client != ic) {
list_add_first(&ic->who_queue, irc_line_to_string(line)); list_add_first(&ic->who_queue, irc_line_to_string(line));
@ -1060,8 +1097,8 @@ static int irc_cli_mode(struct link_client *ic, struct line *line)
return OK_COPY; return OK_COPY;
/* This is a wild guess and that sucks. */ /* This is a wild guess and that sucks. */
if (!irc_line_elem_equals(line, 0, "MODE") || if (!irc_line_elem_equals(line, 0, "MODE")
strchr(irc_line_elem(line, 2), 'b') == NULL) || strchr(irc_line_elem(line, 2), 'b') == NULL)
return OK_COPY; return OK_COPY;
++ic->who_count; ++ic->who_count;
@ -1093,8 +1130,8 @@ static void irc_notify_disconnection(struct link_server *is)
for (hash_it_init(&is->channels, &hi); hash_it_item(&hi); for (hash_it_init(&is->channels, &hi); hash_it_item(&hi);
hash_it_next(&hi)) { hash_it_next(&hi)) {
struct channel *c = (struct channel *)hash_it_item(&hi); struct channel *c = (struct channel *)hash_it_item(&hi);
WRITE_LINE3(CONN(ic), P_IRCMASK, "KICK", WRITE_LINE3(CONN(ic), P_IRCMASK, "KICK", c->name,
c->name, is->nick, is->nick,
"Server disconnected, reconnecting"); "Server disconnected, reconnecting");
} }
bip_notify(ic, "Server disconnected, reconnecting"); bip_notify(ic, "Server disconnected, reconnecting");
@ -1191,8 +1228,8 @@ static int irc_cli_part(struct link_client *irc, struct line *line)
cname = irc_line_elem(line, 1); cname = irc_line_elem(line, 1);
if ((ci = hash_remove_if_exists(&LINK(irc)->chan_infos, if ((ci = hash_remove_if_exists(&LINK(irc)->chan_infos, cname))
cname)) != NULL) { != NULL) {
list_remove(&LINK(irc)->chan_infos_order, ci); list_remove(&LINK(irc)->chan_infos_order, ci);
free(ci->name); free(ci->name);
if (ci->key) if (ci->key)
@ -1209,8 +1246,8 @@ static int irc_dispatch_trust_client(struct link_client *ic, struct line *line)
if (!irc_line_includes(line, 1)) if (!irc_line_includes(line, 1))
return ERR_PROTOCOL; return ERR_PROTOCOL;
if (strcasecmp(irc_line_elem(line, 0), "BIP") == 0 && if (strcasecmp(irc_line_elem(line, 0), "BIP") == 0
strcasecmp(irc_line_elem(line, 1), "TRUST") == 0) && strcasecmp(irc_line_elem(line, 1), "TRUST") == 0)
r = adm_trust(ic, line); r = adm_trust(ic, line);
return r; return r;
@ -1231,7 +1268,8 @@ static int irc_dispatch_client(bip_t *bip, struct link_client *ic,
irc_line_elem(line, 1)); irc_line_elem(line, 1));
r = OK_FORGET; r = OK_FORGET;
} else if (LINK(ic)->s_state != IRCS_CONNECTED) { } else if (LINK(ic)->s_state != IRCS_CONNECTED) {
write_line_fast(CONN(ic), ":irc.bip.net NOTICE pouet " write_line_fast(CONN(ic),
":irc.bip.net NOTICE pouet "
":ERROR Proxy not connected, please wait " ":ERROR Proxy not connected, please wait "
"before sending commands\r\n"); "before sending commands\r\n");
r = OK_FORGET; r = OK_FORGET;
@ -1257,13 +1295,14 @@ static int irc_dispatch_client(bip_t *bip, struct link_client *ic,
if (r == OK_COPY || r == OK_COPY_CLI) { if (r == OK_COPY || r == OK_COPY_CLI) {
char *str = irc_line_to_string(line); char *str = irc_line_to_string(line);
if (LINK(ic)->s_state == IRCS_CONNECTED && if (LINK(ic)->s_state == IRCS_CONNECTED
LINK(ic)->l_server->nick) && LINK(ic)->l_server->nick)
write_line(CONN(LINK(ic)->l_server), str); write_line(CONN(LINK(ic)->l_server), str);
else if (LINK(ic)->l_server->nick) else if (LINK(ic)->l_server->nick)
WRITE_LINE2(CONN(ic), P_IRCMASK, WRITE_LINE2(CONN(ic), P_IRCMASK,
(LINK(ic)->user->bip_use_notice ? (LINK(ic)->user->bip_use_notice
"NOTICE" : "PRIVMSG"), ? "NOTICE"
: "PRIVMSG"),
LINK(ic)->l_server->nick, LINK(ic)->l_server->nick,
":Not connected please try again " ":Not connected please try again "
"later...\r\n"); "later...\r\n");
@ -1288,8 +1327,8 @@ static void irc_copy_cli(struct link_client *src, struct link_client *dest,
if (src == dest) if (src == dest)
return; return;
if (!irc_line_includes(line, 1) || if (!irc_line_includes(line, 1)
!irc_line_elem_equals(line, 0, "PRIVMSG")) { || !irc_line_elem_equals(line, 0, "PRIVMSG")) {
str = irc_line_to_string(line); str = irc_line_to_string(line);
write_line(CONN(dest), str); write_line(CONN(dest), str);
free(str); free(str);
@ -1314,7 +1353,8 @@ static void irc_copy_cli(struct link_client *src, struct link_client *dest,
/* LINK(src) == LINK(dest) */ /* LINK(src) == LINK(dest) */
size_t len = strlen(irc_line_elem(line, 2)) + 6; size_t len = strlen(irc_line_elem(line, 2)) + 6;
// snprintf fix ^ // snprintf fix ^
// __builtin___snprintf_chk output may be truncated before the last format character // __builtin___snprintf_chk output may be truncated before the last
// format character
char *tmp; char *tmp;
if (len == 0) if (len == 0)
@ -1371,18 +1411,18 @@ int irc_dispatch(bip_t *bip, struct link_any *l, struct line *line)
{ {
switch (TYPE(l)) { switch (TYPE(l)) {
case IRC_TYPE_SERVER: case IRC_TYPE_SERVER:
return irc_dispatch_server(bip, (struct link_server*)l, line); return irc_dispatch_server(bip, (struct link_server *)l, line);
break; break;
case IRC_TYPE_CLIENT: case IRC_TYPE_CLIENT:
return irc_dispatch_client(bip, (struct link_client*)l, line); return irc_dispatch_client(bip, (struct link_client *)l, line);
break; break;
case IRC_TYPE_LOGGING_CLIENT: case IRC_TYPE_LOGGING_CLIENT:
return irc_dispatch_logging_client(bip, (struct link_client*)l, return irc_dispatch_logging_client(bip, (struct link_client *)l,
line); line);
break; break;
#ifdef HAVE_LIBSSL #ifdef HAVE_LIBSSL
case IRC_TYPE_TRUST_CLIENT: case IRC_TYPE_TRUST_CLIENT:
return irc_dispatch_trust_client((struct link_client*)l, line); return irc_dispatch_trust_client((struct link_client *)l, line);
break; break;
#endif #endif
default: default:
@ -1630,8 +1670,8 @@ static int irc_part(struct link_server *server, struct line *line)
if (origin_is_me(line, server)) { if (origin_is_me(line, server)) {
log_part(LINK(server)->log, line->origin, s_chan, log_part(LINK(server)->log, line->origin, s_chan,
irc_line_count(line) == 3 ? irc_line_elem(line, 2) : irc_line_count(line) == 3 ? irc_line_elem(line, 2)
NULL); : NULL);
log_reset_store(LINK(server)->log, s_chan); log_reset_store(LINK(server)->log, s_chan);
log_drop(LINK(server)->log, s_chan); log_drop(LINK(server)->log, s_chan);
@ -1654,8 +1694,7 @@ static int irc_part(struct link_server *server, struct line *line)
free(s_nick); free(s_nick);
log_part(LINK(server)->log, line->origin, s_chan, log_part(LINK(server)->log, line->origin, s_chan,
irc_line_count(line) == 3 ? irc_line_count(line) == 3 ? irc_line_elem(line, 2) : NULL);
irc_line_elem(line, 2) : NULL);
return OK_COPY; return OK_COPY;
} }
@ -1679,8 +1718,8 @@ static void mode_remove_letter(struct link_server *s, char c)
for (; i < s->user_mode_len - 1; i++) for (; i < s->user_mode_len - 1; i++)
s->user_mode[i] = s->user_mode[i + 1]; s->user_mode[i] = s->user_mode[i + 1];
s->user_mode_len--; s->user_mode_len--;
s->user_mode = bip_realloc(s->user_mode, s->user_mode =
s->user_mode_len); bip_realloc(s->user_mode, s->user_mode_len);
return; return;
} }
} }
@ -1775,25 +1814,30 @@ static int irc_mode(struct link_server *server, struct line *line)
// Check if mode is known: first user modes then // Check if mode is known: first user modes then
// server modes // server modes
if (!(str = strchr(server->usermodes, *mode))) { if (!(str = strchr(server->usermodes, *mode))) {
array_each(&server->chanmodes, i, str) { array_each(&server->chanmodes, i, str)
{
if ((str = strchr(str, *mode))) if ((str = strchr(str, *mode)))
break; break;
} }
} }
if (str) { if (str) {
// Usermodes, types A & B always take a parameter // Usermodes, types A & B always take a
// Type C take a parameter only when set // parameter Type C take a parameter only when
// set
if (i <= 1 || (i == 2 && add)) { if (i <= 1 || (i == 2 && add)) {
if (!irc_line_includes(line, cur_arg + 3)) { if (!irc_line_includes(line,
cur_arg + 3)) {
return ERR_PROTOCOL; return ERR_PROTOCOL;
} else { } else {
ret = irc_mode_channel(server, channel, line, mode, ret = irc_mode_channel(
add, cur_arg); server, channel, line,
mode, add, cur_arg);
cur_arg++; cur_arg++;
} }
} else { } else {
ret = irc_mode_channel(server, channel, line, mode, add, ret = irc_mode_channel(server, channel,
line, mode, add,
cur_arg); cur_arg);
} }
} }
@ -1805,7 +1849,8 @@ static int irc_mode(struct link_server *server, struct line *line)
} }
static int irc_mode_channel(struct link_server *s, struct channel *channel, static int irc_mode_channel(struct link_server *s, struct channel *channel,
struct line *line, const char* mode, int add, int cur_arg) struct line *line, const char *mode, int add,
int cur_arg)
{ {
const char *nick; const char *nick;
long int ovmask; long int ovmask;
@ -1817,8 +1862,8 @@ static int irc_mode_channel(struct link_server *s, struct channel *channel,
#pragma GCC diagnostic ignored "-Wtraditional-conversion" #pragma GCC diagnostic ignored "-Wtraditional-conversion"
if (*mode == 'k') { if (*mode == 'k') {
if (add) { if (add) {
channel->key = bip_strdup( channel->key =
irc_line_elem(line, cur_arg + 3)); bip_strdup(irc_line_elem(line, cur_arg + 3));
} else { } else {
if (channel->key) { if (channel->key) {
free(channel->key); free(channel->key);
@ -1905,8 +1950,8 @@ static int irc_kick(struct link_server *server, struct line *line)
/* we get kicked !! */ /* we get kicked !! */
log_kick(LINK(server)->log, line->origin, channel->name, log_kick(LINK(server)->log, line->origin, channel->name,
irc_line_elem(line, 2), irc_line_elem(line, 2),
irc_line_count(line) == 4 ? irc_line_count(line) == 4 ? irc_line_elem(line, 3)
irc_line_elem(line, 3) : NULL); : NULL);
log_reset_store(LINK(server)->log, channel->name); log_reset_store(LINK(server)->log, channel->name);
log_drop(LINK(server)->log, channel->name); log_drop(LINK(server)->log, channel->name);
@ -2011,9 +2056,9 @@ static int irc_nick(struct link_server *server, struct line *line)
if (origin_is_me(line, server)) { if (origin_is_me(line, server)) {
free(server->nick); free(server->nick);
server->nick = bip_strdup(dst_nick); server->nick = bip_strdup(dst_nick);
if (LINK(server)->follow_nick && if (LINK(server)->follow_nick
(LINK(server)->away_nick == NULL || && (LINK(server)->away_nick == NULL
strcmp(server->nick, LINK(server)->away_nick)) || strcmp(server->nick, LINK(server)->away_nick))
!= 0) { != 0) {
free(LINK(server)->connect_nick); free(LINK(server)->connect_nick);
LINK(server)->connect_nick = bip_strdup(server->nick); LINK(server)->connect_nick = bip_strdup(server->nick);
@ -2046,8 +2091,8 @@ static int irc_generic_quit(struct link_server *server, struct line *line)
continue; continue;
hash_remove(&channel->ovmasks, s_nick); hash_remove(&channel->ovmasks, s_nick);
log_quit(LINK(server)->log, line->origin, channel->name, log_quit(LINK(server)->log, line->origin, channel->name,
irc_line_includes(line, 1) ? irc_line_includes(line, 1) ? irc_line_elem(line, 1)
irc_line_elem(line, 1) : NULL); : NULL);
} }
free(s_nick); free(s_nick);
return OK_COPY; return OK_COPY;
@ -2106,7 +2151,8 @@ static int irc_server_sasl_authenticate(struct link_server *ircs)
// Should not happen, but we never know right ? // Should not happen, but we never know right ?
if (!sasl_username || !sasl_password) { if (!sasl_username || !sasl_password) {
mylog(LOG_ERROR, "[%s] Missing SASL username or password.", LINK(ircs)->name); mylog(LOG_ERROR, "[%s] Missing SASL username or password.",
LINK(ircs)->name);
return ERR_AUTH; return ERR_AUTH;
} }
@ -2118,7 +2164,7 @@ static int irc_server_sasl_authenticate(struct link_server *ircs)
char chunk[SASL_AUTH_CHUNK_SZ + 1]; char chunk[SASL_AUTH_CHUNK_SZ + 1];
size_t u_len = strlen(sasl_username); size_t u_len = strlen(sasl_username);
size_t p_len = strlen(sasl_password); size_t p_len = strlen(sasl_password);
size_t raw_len = u_len*2 + p_len + 2; size_t raw_len = u_len * 2 + p_len + 2;
size_t enc_len; size_t enc_len;
unsigned char *raw_str = bip_malloc(raw_len + 1); unsigned char *raw_str = bip_malloc(raw_len + 1);
unsigned char *enc_str; unsigned char *enc_str;
@ -2126,27 +2172,30 @@ static int irc_server_sasl_authenticate(struct link_server *ircs)
memcpy(raw_str, sasl_username, u_len); memcpy(raw_str, sasl_username, u_len);
raw_str[u_len] = '\0'; raw_str[u_len] = '\0';
memcpy(raw_str + u_len + 1, sasl_username, u_len); memcpy(raw_str + u_len + 1, sasl_username, u_len);
raw_str[u_len*2 + 1] = '\0'; raw_str[u_len * 2 + 1] = '\0';
memcpy(raw_str + u_len*2 + 2, sasl_password, p_len); 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(raw_str, raw_len, &enc_len);
mylog(LOG_DEBUG, "[%s] Base64 encoded SASL auth token (len %d): %s", LINK(ircs)->name, enc_len, enc_str); mylog(LOG_DEBUG, "[%s] Base64 encoded SASL auth token (len %d): %s",
LINK(ircs)->name, enc_len, enc_str);
for (size_t i = 0; i < enc_len; i += chunk_chars) { for (size_t i = 0; i < enc_len; i += chunk_chars) {
size_t remaining = enc_len - i; size_t remaining = enc_len - i;
if (remaining < chunk_chars) { if (remaining < chunk_chars) {
memcpy(chunk, &enc_str[i], remaining); memcpy(chunk, &enc_str[i], remaining);
chunk[remaining]= '\0'; chunk[remaining] = '\0';
} else { } else {
memcpy(chunk, &enc_str[i], chunk_chars); memcpy(chunk, &enc_str[i], chunk_chars);
chunk[chunk_chars]= '\0'; chunk[chunk_chars] = '\0';
} }
mylog(LOG_DEBUG, "[%s] SASL AUTHENTICATE chunk %d, len %d: %s", mylog(LOG_DEBUG, "[%s] SASL AUTHENTICATE chunk %d, len %d: %s",
LINK(ircs)->name, i/chunk_chars, strlen(chunk), chunk); LINK(ircs)->name, i / chunk_chars, strlen(chunk), chunk);
WRITE_LINE1(CONN(ircs), NULL, "AUTHENTICATE", chunk); WRITE_LINE1(CONN(ircs), NULL, "AUTHENTICATE", chunk);
// Send a closing AUTHENTICATE line if last chunk size was exactly 400 // Send a closing AUTHENTICATE line if last chunk size was
// exactly 400
if (remaining == chunk_chars) { if (remaining == chunk_chars) {
mylog(LOG_DEBUG, "[%s] Last SASL chunk was exactly 400, sending +", mylog(LOG_DEBUG,
"[%s] Last SASL chunk was exactly 400, sending +",
LINK(ircs)->name); LINK(ircs)->name);
WRITE_LINE1(CONN(ircs), NULL, "AUTHENTICATE", "+"); WRITE_LINE1(CONN(ircs), NULL, "AUTHENTICATE", "+");
break; break;
@ -2275,15 +2324,13 @@ static void server_setup_reconnect_timer(struct link *link)
{ {
int timer = 0; int timer = 0;
if (link->last_connection_attempt && if (link->last_connection_attempt
time(NULL) - link->last_connection_attempt && time(NULL) - link->last_connection_attempt < CONN_INTERVAL) {
< CONN_INTERVAL) {
timer = conf_reconn_timer * (link->s_conn_attempt); timer = conf_reconn_timer * (link->s_conn_attempt);
if (timer > RECONN_TIMER_MAX) if (timer > RECONN_TIMER_MAX)
timer = RECONN_TIMER_MAX; timer = RECONN_TIMER_MAX;
} }
mylog(LOG_ERROR, "[%s] reconnecting in %d seconds", link->name, mylog(LOG_ERROR, "[%s] reconnecting in %d seconds", link->name, timer);
timer);
link->recon_timer = timer; link->recon_timer = timer;
} }
@ -2371,8 +2418,7 @@ void irc_server_free(struct link_server *s)
int i; int i;
char *ptr; char *ptr;
array_each(&s->chanmodes, i, ptr) array_each(&s->chanmodes, i, ptr) free(ptr);
free(ptr);
MAYFREE(s->prefixes); MAYFREE(s->prefixes);
MAYFREE(s->usermodes); MAYFREE(s->usermodes);
@ -2395,18 +2441,18 @@ connection_t *irc_server_connect(struct link *link)
link->s_conn_attempt++; link->s_conn_attempt++;
mylog(LOG_INFO, "[%s] Connecting user '%s' using server " mylog(LOG_INFO,
"%s:%d", link->name, link->user->name, "[%s] Connecting user '%s' using server "
"%s:%d",
link->name, link->user->name,
link->network->serverv[link->cur_server].host, link->network->serverv[link->cur_server].host,
link->network->serverv[link->cur_server].port); link->network->serverv[link->cur_server].port);
conn = connection_new(link->network->serverv[link->cur_server].host, conn = connection_new(link->network->serverv[link->cur_server].host,
link->network->serverv[link->cur_server].port, link->network->serverv[link->cur_server].port,
link->vhost, link->bind_port, link->vhost, link->bind_port,
#ifdef HAVE_LIBSSL #ifdef HAVE_LIBSSL
link->network->ssl, link->network->ssl, link->network->ciphers,
link->network->ciphers, link->ssl_check_mode, link->user->ssl_check_store,
link->ssl_check_mode,
link->user->ssl_check_store,
link->user->ssl_client_certfile, link->user->ssl_client_certfile,
#else #else
0, NULL, 0, NULL, NULL, 0, NULL, 0, NULL, NULL,
@ -2458,8 +2504,7 @@ void irc_server_shutdown(struct link_server *s)
{ {
int i; int i;
char *cur; char *cur;
array_each(&s->chanmodes, i, cur) array_each(&s->chanmodes, i, cur) free(cur);
free(cur);
array_deinit(&s->chanmodes); array_deinit(&s->chanmodes);
server_init_modes(s); server_init_modes(s);
@ -2510,9 +2555,10 @@ void oidentd_dump(bip_t *bip)
content = (char *)bip_malloc((size_t)(stats.st_size + 1)); content = (char *)bip_malloc((size_t)(stats.st_size + 1));
// validate that content is of stats.st_size size // validate that content is of stats.st_size size
if (fread(content, (size_t)1, (size_t)stats.st_size, f) != if (fread(content, (size_t)1, (size_t)stats.st_size, f)
(size_t)stats.st_size) { != (size_t)stats.st_size) {
mylog(LOG_WARN, "Can't read %s fully", bip->oidentdpath); mylog(LOG_WARN, "Can't read %s fully",
bip->oidentdpath);
free(content); free(content);
goto clean_oidentd; goto clean_oidentd;
} }
@ -2532,32 +2578,37 @@ void oidentd_dump(bip_t *bip)
} }
// data preceeding the tag, bipstart >= content (strstr) // data preceeding the tag, bipstart >= content (strstr)
fwrite(content, (size_t)1, (size_t)(bipstart - content), f); fwrite(content, (size_t)1, (size_t)(bipstart - content),
f);
bipend = strstr(bipstart, BIP_OIDENTD_END); bipend = strstr(bipstart, BIP_OIDENTD_END);
if (bipend == NULL) { if (bipend == NULL) {
mylog(LOG_WARN, "No %s mark found in %s", mylog(LOG_WARN, "No %s mark found in %s",
BIP_OIDENTD_END, BIP_OIDENTD_END, bip->oidentdpath);
bip->oidentdpath);
} else { } else {
/* data following the tag /* data following the tag
* ...........BIP_OIDENTD_START...BIP_OIDENTD_END.............. * ...........BIP_OIDENTD_START...BIP_OIDENTD_END..............
* ^content...^bipstart...........^bipend........^remaining data * ^content...^bipstart...........^bipend........^remaining
* data
*/ */
char *remaining = bipend + BIP_OIDENTD_END_LENGTH; char *remaining =
off_t remaining_len = stats.st_size - bipend + BIP_OIDENTD_END_LENGTH;
(bipend - content) - (off_t)BIP_OIDENTD_END_LENGTH; off_t remaining_len =
stats.st_size - (bipend - content)
- (off_t)BIP_OIDENTD_END_LENGTH;
if (remaining_len < 0) { if (remaining_len < 0) {
mylog(LOG_ERROR, "oidentd_dump: error parsing %s", mylog(LOG_ERROR,
"oidentd_dump: error parsing %s",
bip->oidentdpath); bip->oidentdpath);
goto clean_oidentd; goto clean_oidentd;
} }
fwrite(remaining, (size_t)1, (size_t)remaining_len, f); fwrite(remaining, (size_t)1,
(size_t)remaining_len, f);
} }
} else { } else {
/* No previous conf */ /* No previous conf */
if (stats.st_size != 0 && if (stats.st_size != 0
content[stats.st_size - 1] != '\n') && content[stats.st_size - 1] != '\n')
fprintf(f, "\n"); fprintf(f, "\n");
} }
free(content); free(content);
@ -2567,10 +2618,10 @@ void oidentd_dump(bip_t *bip)
list_it_next(&it)) { list_it_next(&it)) {
connection_t *c = list_it_item(&it); connection_t *c = list_it_item(&it);
struct link_any *la = c->user_data; struct link_any *la = c->user_data;
if (la && TYPE(la) == IRC_TYPE_SERVER && ( if (la && TYPE(la) == IRC_TYPE_SERVER
c->connected == CONN_OK || && (c->connected == CONN_OK
c->connected == CONN_NEED_SSLIZE || || c->connected == CONN_NEED_SSLIZE
c->connected == CONN_UNTRUSTED)) { || c->connected == CONN_UNTRUSTED)) {
struct link_server *ls; struct link_server *ls;
struct link *l; struct link *l;
@ -2579,7 +2630,7 @@ void oidentd_dump(bip_t *bip)
tag_written = 1; tag_written = 1;
} }
ls = (struct link_server*)la; ls = (struct link_server *)la;
l = LINK(ls); l = LINK(ls);
fprintf(f, "to %s fport %d from %s lport %d {\n", fprintf(f, "to %s fport %d from %s lport %d {\n",
@ -2607,7 +2658,8 @@ void timeout_clean_who_counts(list_t *conns)
time_t now; time_t now;
now = time(NULL); now = time(NULL);
if (now - client->whoc_tstamp > 10) { if (now - client->whoc_tstamp > 10) {
mylog(LOG_DEBUG, "Yawn, " mylog(LOG_DEBUG,
"Yawn, "
"forgetting one who reply"); "forgetting one who reply");
if (client->who_count > 0) if (client->who_count > 0)
--client->who_count; --client->who_count;
@ -2651,7 +2703,7 @@ void bip_tick(bip_t *bip)
log_ping_timeout(link->log); log_ping_timeout(link->log);
list_remove(&bip->conn_list, list_remove(&bip->conn_list,
CONN(link->l_server)); CONN(link->l_server));
irc_close((struct link_any *) link->l_server); irc_close((struct link_any *)link->l_server);
} }
} else { } else {
if (link->recon_timer == 0) { if (link->recon_timer == 0) {
@ -2725,8 +2777,10 @@ void bip_on_event(bip_t *bip, connection_t *conn)
line = irc_line_new_from_string(line_s); line = irc_line_new_from_string(line_s);
if (!line) { if (!line) {
mylog(LOG_ERROR, "[%s] Can not parse line. Link type: %d. " mylog(LOG_ERROR,
"closing...", link_name(lc), TYPE(lc)); "[%s] Can not parse line. Link type: %d. "
"closing...",
link_name(lc), TYPE(lc));
free(line_s); free(line_s);
goto prot_err_lines; goto prot_err_lines;
} }
@ -2735,7 +2789,8 @@ void bip_on_event(bip_t *bip, connection_t *conn)
irc_line_free(line); irc_line_free(line);
free(line_s); free(line_s);
if (r == ERR_PROTOCOL) { if (r == ERR_PROTOCOL) {
mylog(LOG_ERROR, "[%s] Error in protocol. Link type: %d closing...", mylog(LOG_ERROR,
"[%s] Error in protocol. Link type: %d closing...",
link_name(lc), TYPE(lc)); link_name(lc), TYPE(lc));
goto prot_err_lines; goto prot_err_lines;
} }
@ -2744,7 +2799,6 @@ void bip_on_event(bip_t *bip, connection_t *conn)
/* XXX: not real error */ /* XXX: not real error */
if (r == OK_CLOSE) if (r == OK_CLOSE)
goto prot_err_lines; goto prot_err_lines;
} }
list_free(linel); list_free(linel);
return; return;
@ -2756,8 +2810,8 @@ prot_err:
if (linel) if (linel)
list_free(linel); list_free(linel);
if (lc) { if (lc) {
if (TYPE(lc) == IRC_TYPE_LOGGING_CLIENT || TYPE(lc) == if (TYPE(lc) == IRC_TYPE_LOGGING_CLIENT
IRC_TYPE_TRUST_CLIENT) || TYPE(lc) == IRC_TYPE_TRUST_CLIENT)
list_remove(&bip->connecting_client_list, lc); list_remove(&bip->connecting_client_list, lc);
irc_close(lc); irc_close(lc);
} }
@ -2897,8 +2951,7 @@ static void server_set_chanmodes(struct link_server *l, const char *modes)
mylog(LOG_DEBUG, "[%s] Set chanmodes", LINK(l)->name); mylog(LOG_DEBUG, "[%s] Set chanmodes", LINK(l)->name);
array_each(&l->chanmodes, i, cur) array_each(&l->chanmodes, i, cur) free(cur);
free(cur);
array_deinit(&l->chanmodes); array_deinit(&l->chanmodes);
// handle four categories, ignore all others // handle four categories, ignore all others
@ -2927,7 +2980,7 @@ static void server_set_chanmodes(struct link_server *l, const char *modes)
static void server_set_prefix(struct link_server *s, const char *modes) static void server_set_prefix(struct link_server *s, const char *modes)
{ {
char * end_mode; char *end_mode;
size_t len; size_t len;
mylog(LOG_DEBUG, "[%s] Set user modes", LINK(s)->name); mylog(LOG_DEBUG, "[%s] Set user modes", LINK(s)->name);
@ -2936,31 +2989,37 @@ static void server_set_prefix(struct link_server *s, const char *modes)
end_mode = strchr(modes + 1, ')'); // skip '(' end_mode = strchr(modes + 1, ')'); // skip '('
if (*modes != '(' || !end_mode) { if (*modes != '(' || !end_mode) {
mylog(LOG_WARN, "[%s] Unable to parse PREFIX parameter", LINK(s)->name); mylog(LOG_WARN, "[%s] Unable to parse PREFIX parameter",
LINK(s)->name);
return; return;
} }
// end_mode can't be lower than (modes + 1) // end_mode can't be lower than (modes + 1)
len = (size_t)(end_mode - modes - 1); // len of mode without '(' len = (size_t)(end_mode - modes - 1); // len of mode without '('
if (len * 2 + 2 != strlen(modes)) { if (len * 2 + 2 != strlen(modes)) {
mylog(LOG_WARN, "[%s] Unable to parse PREFIX parameter", LINK(s)->name); mylog(LOG_WARN, "[%s] Unable to parse PREFIX parameter",
LINK(s)->name);
return; return;
} }
s->prefixes = bip_realloc(s->prefixes, sizeof(*s->prefixes) * (len + 1)); s->prefixes =
s->usermodes = bip_realloc(s->usermodes, sizeof(s->usermodes) * (len + 1)); bip_realloc(s->prefixes, sizeof(*s->prefixes) * (len + 1));
s->usermodes =
bip_realloc(s->usermodes, sizeof(s->usermodes) * (len + 1));
memcpy(s->usermodes, modes + 1, len); memcpy(s->usermodes, modes + 1, len);
s->usermodes[len] = 0; s->usermodes[len] = 0;
memcpy(s->prefixes, end_mode + 1, len); memcpy(s->prefixes, end_mode + 1, len);
s->prefixes[len] = 0; s->prefixes[len] = 0;
mylog(LOG_DEBUGVERB, "[%s] user prefix: '%s'", LINK(s)->name, s->prefixes); mylog(LOG_DEBUGVERB, "[%s] user prefix: '%s'", LINK(s)->name,
mylog(LOG_DEBUGVERB, "[%s] user modes: '%s'", LINK(s)->name, s->usermodes); s->prefixes);
mylog(LOG_DEBUGVERB, "[%s] user modes: '%s'", LINK(s)->name,
s->usermodes);
} }
// Return the position (*1 based*) of car in str, else -1 // Return the position (*1 based*) of car in str, else -1
static int bip_get_index(const char* str, char car) static int bip_get_index(const char *str, char car)
{ {
char *cur; char *cur;
long diff; long diff;

View File

@ -96,8 +96,7 @@ struct bipuser {
char in_use; /* for mark and sweep on reload */ char in_use; /* for mark and sweep on reload */
}; };
struct network struct network {
{
char *name; char *name;
#ifdef HAVE_LIBSSL #ifdef HAVE_LIBSSL
int ssl; int ssl;
@ -168,7 +167,7 @@ struct link {
#ifdef HAVE_LIBSSL #ifdef HAVE_LIBSSL
int ssl_check_mode; int ssl_check_mode;
STACK_OF(X509) *untrusted_certs; STACK_OF(X509) * untrusted_certs;
#endif #endif
int in_use; /* for mark and sweep on reload */ int in_use; /* for mark and sweep on reload */
}; };
@ -189,9 +188,9 @@ struct link_any {
#define IRCC_NONE (0) #define IRCC_NONE (0)
#define IRCC_NICK (1) #define IRCC_NICK (1)
#define IRCC_USER (1<<1) #define IRCC_USER (1 << 1)
#define IRCC_PASS (1<<2) #define IRCC_PASS (1 << 2)
#define IRCC_READY (IRCC_NICK|IRCC_PASS|IRCC_USER) #define IRCC_READY (IRCC_NICK | IRCC_PASS | IRCC_USER)
struct link_client { struct link_client {
struct link_connection _link_c; struct link_connection _link_c;
@ -284,4 +283,3 @@ void irc_cli_backlog(struct link_client *ic, int hours);
#define BIP_FAKEMASK "!bip@bip.bip.bip" #define BIP_FAKEMASK "!bip@bip.bip.bip"
#endif #endif

View File

@ -16,7 +16,8 @@
#include "line.h" #include "line.h"
#include "util.h" #include "util.h"
// TODO resolve assuming signed overflow does not occur when changing X +- C1 cmp C2 to X cmp C2 -+ C1 // 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" #pragma GCC diagnostic ignored "-Wstrict-overflow"
void irc_line_init(struct line *l) void irc_line_init(struct line *l)

View File

@ -25,7 +25,7 @@
_irc_line_append(&l, com); \ _irc_line_append(&l, com); \
irc_line_write(&l, con); \ irc_line_write(&l, con); \
_irc_line_deinit(&l); \ _irc_line_deinit(&l); \
} while(0) } while (0)
#define WRITE_LINE1(con, org, com, a) \ #define WRITE_LINE1(con, org, com, a) \
do { \ do { \
@ -36,7 +36,7 @@
_irc_line_append(&l, a); \ _irc_line_append(&l, a); \
irc_line_write(&l, con); \ irc_line_write(&l, con); \
_irc_line_deinit(&l); \ _irc_line_deinit(&l); \
} while(0) } while (0)
#define WRITE_LINE2(con, org, com, a1, a2) \ #define WRITE_LINE2(con, org, com, a1, a2) \
do { \ do { \
@ -48,7 +48,7 @@
_irc_line_append(&l, a2); \ _irc_line_append(&l, a2); \
irc_line_write(&l, con); \ irc_line_write(&l, con); \
_irc_line_deinit(&l); \ _irc_line_deinit(&l); \
} while(0) } while (0)
#define WRITE_LINE3(con, org, com, a1, a2, a3) \ #define WRITE_LINE3(con, org, com, a1, a2, a3) \
do { \ do { \
@ -61,7 +61,7 @@
_irc_line_append(&l, a3); \ _irc_line_append(&l, a3); \
irc_line_write(&l, con); \ irc_line_write(&l, con); \
_irc_line_deinit(&l); \ _irc_line_deinit(&l); \
} while(0) } while (0)
#define WRITE_LINE4(con, org, com, a1, a2, a3, a4) \ #define WRITE_LINE4(con, org, com, a1, a2, a3, a4) \
do { \ do { \
@ -75,7 +75,7 @@
_irc_line_append(&l, a4); \ _irc_line_append(&l, a4); \
irc_line_write(&l, con); \ irc_line_write(&l, con); \
_irc_line_deinit(&l); \ _irc_line_deinit(&l); \
} while(0) } while (0)
struct line { struct line {
char *origin; char *origin;

157
src/log.c
View File

@ -61,8 +61,7 @@ int check_dir(char *filename, int is_fatal)
} else if (err) { } else if (err) {
if (is_fatal) if (is_fatal)
fatal("stat(%s) %s", filename, strerror(errno)); fatal("stat(%s) %s", filename, strerror(errno));
mylog(LOG_ERROR, "stat(%s) %s", filename, mylog(LOG_ERROR, "stat(%s) %s", filename, strerror(errno));
strerror(errno));
return 1; return 1;
} else if (!(statbuf.st_mode & S_IFDIR)) { } else if (!(statbuf.st_mode & S_IFDIR)) {
if (is_fatal) if (is_fatal)
@ -99,7 +98,7 @@ int check_dir_r(char *dirname)
tmp += pos; tmp += pos;
count += pos; count += pos;
*(dir + count) = '\0'; *(dir + count) = '\0';
mylog(LOG_DEBUGVERB,"check_dir_r: %s", dir); mylog(LOG_DEBUGVERB, "check_dir_r: %s", dir);
if (check_dir(dir, 0)) { if (check_dir(dir, 0)) {
free(dir); free(dir);
return 1; return 1;
@ -114,7 +113,8 @@ void strtolower(char *str)
char *c; char *c;
for (c = str; *c != '\0'; c++) for (c = str; *c != '\0'; c++)
*c = (char)tolower(*c); // tolower()->int but should be safe to cast *c = (char)tolower(
*c); // tolower()->int but should be safe to cast
} }
/* /*
@ -128,7 +128,7 @@ void replace_var(char *str, char *var, char *value, unsigned int max)
size_t lenvar = strlen(var); size_t lenvar = strlen(var);
size_t lenval = strlen(value); size_t lenval = strlen(value);
while((pos = strstr(str, var))) { while ((pos = strstr(str, var))) {
/* Make room */ /* Make room */
if (strlen(str) + lenval - lenvar >= max) if (strlen(str) + lenval - lenvar >= max)
return; return;
@ -201,8 +201,8 @@ static void log_reset(logstore_t *store)
return; return;
} }
while ((olf = list_get_first(&store->file_group)) && while ((olf = list_get_first(&store->file_group))
olf != list_get_last(&store->file_group)) { && olf != list_get_last(&store->file_group)) {
logfile_free(olf); logfile_free(olf);
list_remove_first(&store->file_group); list_remove_first(&store->file_group);
} }
@ -413,8 +413,8 @@ logstore_t *log_find_file(log_t *logdata, const char *destination)
time(&t); time(&t);
ltime = localtime(&t); ltime = localtime(&t);
if (ltime->tm_year != lf->last_log.tm_year || if (ltime->tm_year != lf->last_log.tm_year
ltime->tm_yday != lf->last_log.tm_yday) { || ltime->tm_yday != lf->last_log.tm_yday) {
logfile_t *oldlf; logfile_t *oldlf;
/* day changed, we might want to rotate logfile */ /* day changed, we might want to rotate logfile */
@ -443,8 +443,8 @@ logstore_t *log_find_file(log_t *logdata, const char *destination)
/* remove oldlf from file_group */ /* remove oldlf from file_group */
assert(list_remove_first(&store->file_group) == oldlf); assert(list_remove_first(&store->file_group) == oldlf);
logfile_free(oldlf); logfile_free(oldlf);
assert(list_get_first(&store->file_group) == assert(list_get_first(&store->file_group)
list_get_last(&store->file_group)); == list_get_last(&store->file_group));
} else { } else {
fclose(oldlf->file); fclose(oldlf->file);
oldlf->file = NULL; oldlf->file = NULL;
@ -456,8 +456,7 @@ logstore_t *log_find_file(log_t *logdata, const char *destination)
void log_join(log_t *logdata, const char *ircmask, const char *channel) void log_join(log_t *logdata, const char *ircmask, const char *channel)
{ {
snprintf(logdata->buffer, (size_t)LOGLINE_MAXLEN, snprintf(logdata->buffer, (size_t)LOGLINE_MAXLEN,
"%s -!- %s has joined %s", timestamp(), ircmask, "%s -!- %s has joined %s", timestamp(), ircmask, channel);
channel);
log_write(logdata, channel, logdata->buffer); log_write(logdata, channel, logdata->buffer);
} }
@ -479,8 +478,8 @@ void log_kick(log_t *logdata, const char *ircmask, const char *channel,
const char *who, const char *message) const char *who, const char *message)
{ {
snprintf(logdata->buffer, (size_t)LOGLINE_MAXLEN, snprintf(logdata->buffer, (size_t)LOGLINE_MAXLEN,
"%s -!- %s has been kicked by %s [%s]", timestamp(), "%s -!- %s has been kicked by %s [%s]", timestamp(), who,
who, ircmask, message); ircmask, message);
log_write(logdata, channel, logdata->buffer); log_write(logdata, channel, logdata->buffer);
} }
@ -488,8 +487,7 @@ void log_quit(log_t *logdata, const char *ircmask, const char *channel,
const char *message) const char *message)
{ {
snprintf(logdata->buffer, (size_t)LOGLINE_MAXLEN, snprintf(logdata->buffer, (size_t)LOGLINE_MAXLEN,
"%s -!- %s has quit [%s]", timestamp(), ircmask, "%s -!- %s has quit [%s]", timestamp(), ircmask, message);
message);
log_write(logdata, channel, logdata->buffer); log_write(logdata, channel, logdata->buffer);
} }
@ -497,8 +495,8 @@ void log_nick(log_t *logdata, const char *ircmask, const char *channel,
const char *newnick) const char *newnick)
{ {
char *oldnick = nick_from_ircmask(ircmask); char *oldnick = nick_from_ircmask(ircmask);
logstore_t* oldstore; logstore_t *oldstore;
logstore_t* newstore; logstore_t *newstore;
if ((oldstore = hash_get(&logdata->logfgs, oldnick))) { if ((oldstore = hash_get(&logdata->logfgs, oldnick))) {
if ((newstore = hash_get(&logdata->logfgs, newnick)) if ((newstore = hash_get(&logdata->logfgs, newnick))
@ -510,8 +508,7 @@ void log_nick(log_t *logdata, const char *ircmask, const char *channel,
free(oldnick); free(oldnick);
snprintf(logdata->buffer, (size_t)LOGLINE_MAXLEN, snprintf(logdata->buffer, (size_t)LOGLINE_MAXLEN,
"%s -!- %s is now known as %s", "%s -!- %s is now known as %s", timestamp(), ircmask, newnick);
timestamp(), ircmask, newnick);
log_write(logdata, channel, logdata->buffer); log_write(logdata, channel, logdata->buffer);
} }
@ -525,10 +522,11 @@ static void do_log_privmsg(log_t *logdata, const char *storage, int src,
if (src) if (src)
dir = '>'; dir = '>';
if (strlen(message) > 8 && ((*message == '\001' || if (strlen(message) > 8
((*message == '+' || *message == '-') && && ((*message == '\001'
(*(message + 1) == '\001'))) && || ((*message == '+' || *message == '-')
(*(message + strlen(message) - 1) == '\001'))) { && (*(message + 1) == '\001')))
&& (*(message + strlen(message) - 1) == '\001'))) {
char *msg; char *msg;
/* hack for freenode and the like */ /* hack for freenode and the like */
const char *real_message = message; const char *real_message = message;
@ -541,13 +539,11 @@ static void do_log_privmsg(log_t *logdata, const char *storage, int src,
msg = bip_strdup(real_message); msg = bip_strdup(real_message);
*(msg + strlen(msg) - 1) = '\0'; *(msg + strlen(msg) - 1) = '\0';
snprintf(logdata->buffer, (size_t)LOGLINE_MAXLEN, snprintf(logdata->buffer, (size_t)LOGLINE_MAXLEN,
"%s %c * %s %s", timestamp(), dir, "%s %c * %s %s", timestamp(), dir, from, msg + 8);
from, msg + 8);
free(msg); free(msg);
} else { } else {
snprintf(logdata->buffer, (size_t)LOGLINE_MAXLEN, snprintf(logdata->buffer, (size_t)LOGLINE_MAXLEN,
"%s %c %s: %s", timestamp(), dir, "%s %c %s: %s", timestamp(), dir, from, message);
from, message);
} }
log_write(logdata, storage, logdata->buffer); log_write(logdata, storage, logdata->buffer);
} }
@ -604,16 +600,15 @@ void log_topic(log_t *logdata, const char *ircmask, const char *channel,
const char *message) const char *message)
{ {
snprintf(logdata->buffer, (size_t)LOGLINE_MAXLEN, snprintf(logdata->buffer, (size_t)LOGLINE_MAXLEN,
"%s -!- %s changed topic of %s to: %s", timestamp(), "%s -!- %s changed topic of %s to: %s", timestamp(), ircmask,
ircmask, channel, message); channel, message);
log_write(logdata, channel, logdata->buffer); log_write(logdata, channel, logdata->buffer);
} }
void log_init_topic(log_t *logdata, const char *channel, const char *message) void log_init_topic(log_t *logdata, const char *channel, const char *message)
{ {
snprintf(logdata->buffer, (size_t)LOGLINE_MAXLEN, snprintf(logdata->buffer, (size_t)LOGLINE_MAXLEN,
"%s -!- Topic for %s: %s", timestamp(), channel, "%s -!- Topic for %s: %s", timestamp(), channel, message);
message);
log_write(logdata, channel, logdata->buffer); log_write(logdata, channel, logdata->buffer);
} }
@ -633,8 +628,7 @@ void log_init_topic_time(log_t *logdata, const char *channel, const char *who,
timestr[50] = '\0'; timestr[50] = '\0';
snprintf(logdata->buffer, (size_t)LOGLINE_MAXLEN, snprintf(logdata->buffer, (size_t)LOGLINE_MAXLEN,
"%s -!- Topic set by %s [%s]", timestamp(), who, "%s -!- Topic set by %s [%s]", timestamp(), who, timestr);
timestr);
free(timestr); free(timestr);
log_write(logdata, channel, logdata->buffer); log_write(logdata, channel, logdata->buffer);
} }
@ -647,20 +641,20 @@ void log_mode(log_t *logdata, const char *ircmask, const char *channel,
char *tmpbuf2 = bip_malloc((size_t)LOGLINE_MAXLEN + 1); char *tmpbuf2 = bip_malloc((size_t)LOGLINE_MAXLEN + 1);
char *tmp; char *tmp;
snprintf(tmpbuf, (size_t)LOGLINE_MAXLEN, snprintf(tmpbuf, (size_t)LOGLINE_MAXLEN, "%s -!- mode/%s [%s",
"%s -!- mode/%s [%s", timestamp(), channel, modes); timestamp(), channel, modes);
if (mode_args) { if (mode_args) {
for (i = 0; i < array_count(mode_args); i++) { for (i = 0; i < array_count(mode_args); i++) {
snprintf(tmpbuf2, (size_t)LOGLINE_MAXLEN, "%s %s", tmpbuf, snprintf(tmpbuf2, (size_t)LOGLINE_MAXLEN, "%s %s",
(const char*)array_get(mode_args, i)); tmpbuf, (const char *)array_get(mode_args, i));
tmp = tmpbuf; tmp = tmpbuf;
tmpbuf = tmpbuf2; tmpbuf = tmpbuf2;
tmpbuf2 = tmp; tmpbuf2 = tmp;
} }
} }
snprintf(logdata->buffer, (size_t)LOGLINE_MAXLEN, "%s] by %s", snprintf(logdata->buffer, (size_t)LOGLINE_MAXLEN, "%s] by %s", tmpbuf,
tmpbuf, ircmask); ircmask);
log_write(logdata, channel, logdata->buffer); log_write(logdata, channel, logdata->buffer);
free(tmpbuf); free(tmpbuf);
@ -670,8 +664,10 @@ void log_mode(log_t *logdata, const char *ircmask, const char *channel,
void log_disconnected(log_t *logdata) void log_disconnected(log_t *logdata)
{ {
hash_iterator_t hi; hash_iterator_t hi;
snprintf(logdata->buffer, (size_t)LOGLINE_MAXLEN, "%s -!- Disconnected" snprintf(logdata->buffer, (size_t)LOGLINE_MAXLEN,
" from server...", timestamp()); "%s -!- Disconnected"
" from server...",
timestamp());
for (hash_it_init(&logdata->logfgs, &hi); hash_it_item(&hi); for (hash_it_init(&logdata->logfgs, &hi); hash_it_item(&hi);
hash_it_next(&hi)) hash_it_next(&hi))
log_write(logdata, hash_it_key(&hi), logdata->buffer); log_write(logdata, hash_it_key(&hi), logdata->buffer);
@ -696,8 +692,10 @@ void log_connected(log_t *logdata)
{ {
hash_iterator_t hi; hash_iterator_t hi;
snprintf(logdata->buffer, (size_t)LOGLINE_MAXLEN, "%s -!- Connected to" snprintf(logdata->buffer, (size_t)LOGLINE_MAXLEN,
" server...", timestamp()); "%s -!- Connected to"
" server...",
timestamp());
for (hash_it_init(&logdata->logfgs, &hi); hash_it_item(&hi); for (hash_it_init(&logdata->logfgs, &hi); hash_it_item(&hi);
hash_it_next(&hi)) { hash_it_next(&hi)) {
log_write(logdata, hash_it_key(&hi), logdata->buffer); log_write(logdata, hash_it_key(&hi), logdata->buffer);
@ -793,11 +791,11 @@ void log_client_connected(log_t *logdata)
logdata->connected = 1; logdata->connected = 1;
} }
void log_advance_backlogs(log_t* ld, logstore_t *store) void log_advance_backlogs(log_t *ld, logstore_t *store)
{ {
int c; int c;
//mylog(LOG_ERROR, "LOG: log_advance_backlogs %s", store->name); // mylog(LOG_ERROR, "LOG: log_advance_backlogs %s", store->name);
if (!store->track_backlog) if (!store->track_backlog)
return; return;
@ -811,7 +809,8 @@ void log_advance_backlogs(log_t* ld, logstore_t *store)
logfile_t *lf; logfile_t *lf;
while ((lf = list_it_item(&store->file_it))) { while ((lf = list_it_item(&store->file_it))) {
//mylog(LOG_ERROR, "LOG: %s %d", lf->filename, store->file_offset); // mylog(LOG_ERROR, "LOG: %s %d", lf->filename,
// store->file_offset);
if (!lf->file) { if (!lf->file) {
lf->file = fopen(lf->filename, "r"); lf->file = fopen(lf->filename, "r");
if (!lf->file) { if (!lf->file) {
@ -822,7 +821,8 @@ void log_advance_backlogs(log_t* ld, logstore_t *store)
} }
} }
if (fseek(lf->file, store->file_offset, SEEK_SET)) { if (fseek(lf->file, store->file_offset, SEEK_SET)) {
//mylog(LOG_ERROR, "LOG: fseek FAIL %s %d", lf->filename, store->file_offset); // mylog(LOG_ERROR, "LOG: fseek FAIL %s %d",
// lf->filename, store->file_offset);
log_reinit(store); log_reinit(store);
return; return;
} }
@ -830,16 +830,20 @@ void log_advance_backlogs(log_t* ld, logstore_t *store)
while ((c = fgetc(lf->file)) != EOF) { while ((c = fgetc(lf->file)) != EOF) {
store->file_offset++; store->file_offset++;
if (c == '\n') { if (c == '\n') {
//mylog(LOG_ERROR, "LOG: %s advanced at %d", lf->filename, store->file_offset); // mylog(LOG_ERROR, "LOG: %s advanced at %d",
// lf->filename, store->file_offset);
return; return;
} }
} }
//mylog(LOG_ERROR, "LOG: %s advanced at %d", lf->filename, store->file_offset); // mylog(LOG_ERROR, "LOG: %s advanced at %d", lf->filename,
// store->file_offset);
if (lf == list_get_last(&store->file_group)) { if (lf == list_get_last(&store->file_group)) {
//mylog(LOG_ERROR, "LOG: %s is last of file_group", lf->filename, store->file_offset); // mylog(LOG_ERROR, "LOG: %s is last of file_group",
// lf->filename, store->file_offset);
return; return;
} }
//mylog(LOG_ERROR, "LOG: next file %s %d", lf->filename, store->file_offset); // mylog(LOG_ERROR, "LOG: next file %s %d", lf->filename,
// store->file_offset);
fclose(lf->file); fclose(lf->file);
lf->file = NULL; lf->file = NULL;
list_it_next(&store->file_it); list_it_next(&store->file_it);
@ -962,10 +966,10 @@ char *log_beautify(log_t *logdata, const char *buf, const char *storename,
return _log_wrap(dest, buf); return _log_wrap(dest, buf);
// action and out are 0 or 1, safe to cast // action and out are 0 or 1, safe to cast
p = ret = (char *)bip_malloc( p = ret = (char *)bip_malloc(1 + lon + strlen(LAMESTRING) + strlen(dest)
1 + lon + strlen(LAMESTRING) + strlen(dest) + 2 + lots + 2 + + 2 + lots + 2 + lom + 3
lom + 3 + (size_t)action * (2 + strlen("ACTION ")) + + (size_t)action * (2 + strlen("ACTION "))
(size_t)out * strlen(PMSG_ARROW)); + (size_t)out * strlen(PMSG_ARROW));
*p++ = ':'; *p++ = ':';
@ -977,8 +981,8 @@ char *log_beautify(log_t *logdata, const char *buf, const char *storename,
memcpy(p, dest, strlen(dest)); memcpy(p, dest, strlen(dest));
p += strlen(dest); p += strlen(dest);
//memcpy(p, sod, lod); // memcpy(p, sod, lod);
//p += lod; // p += lod;
*p++ = ' '; *p++ = ' ';
*p++ = ':'; *p++ = ':';
@ -1037,7 +1041,7 @@ static int log_backread_file(log_t *log, logstore_t *store, logfile_t *lf,
char *buf, *logbr; char *buf, *logbr;
int close = 0; int close = 0;
//mylog(LOG_ERROR, "log_backread_file store:", store->name); // mylog(LOG_ERROR, "log_backread_file store:", store->name);
if (!lf->file) { if (!lf->file) {
lf->file = fopen(lf->filename, "r"); lf->file = fopen(lf->filename, "r");
@ -1059,26 +1063,29 @@ static int log_backread_file(log_t *log, logstore_t *store, logfile_t *lf,
*/ */
if (fseek(lf->file, store->file_offset, SEEK_SET)) { if (fseek(lf->file, store->file_offset, SEEK_SET)) {
mylog(LOG_ERROR, "Can't seek in %s", lf->filename); mylog(LOG_ERROR, "Can't seek in %s", lf->filename);
list_add_last(res, _log_wrap(store->name, list_add_last(res,
_log_wrap(store->name,
"Error seeking in logfile")); "Error seeking in logfile"));
return 0; return 0;
} }
} else { } else {
//mylog(LOG_ERROR, "bread Seeking %s to %d", lf->filename, 0); // mylog(LOG_ERROR, "bread Seeking %s to %d", lf->filename, 0);
if (fseek(lf->file, (long)0, SEEK_SET)) { if (fseek(lf->file, (long)0, SEEK_SET)) {
mylog(LOG_ERROR, "Can't seek in %s", lf->filename); mylog(LOG_ERROR, "Can't seek in %s", lf->filename);
list_add_last(res, _log_wrap(store->name, list_add_last(res,
_log_wrap(store->name,
"Error seeking in logfile")); "Error seeking in logfile"));
return 0; return 0;
} }
} }
buf = bip_malloc((size_t)LOGLINE_MAXLEN + 1); buf = bip_malloc((size_t)LOGLINE_MAXLEN + 1);
for(;;) { for (;;) {
if (!fgets(buf, LOGLINE_MAXLEN, lf->file)) { if (!fgets(buf, LOGLINE_MAXLEN, lf->file)) {
if (ferror(lf->file)) { if (ferror(lf->file)) {
list_add_last(res, _log_wrap("Error reading " list_add_last(res, _log_wrap("Error reading "
"logfile", store->name)); "logfile",
store->name));
} }
/* error or oef */ /* error or oef */
break; break;
@ -1109,14 +1116,13 @@ static int log_backread_file(log_t *log, logstore_t *store, logfile_t *lf,
logbr = log_beautify(log, buf, store->name, dest); logbr = log_beautify(log, buf, store->name, dest);
if (logbr) if (logbr)
list_add_last(res, logbr); list_add_last(res, logbr);
} }
if (close) { if (close) {
fclose(lf->file); fclose(lf->file);
lf->file = NULL; lf->file = NULL;
} }
free(buf); free(buf);
//mylog(LOG_ERROR, "end of log_backread_file store: %s", store->name); // mylog(LOG_ERROR, "end of log_backread_file store: %s", store->name);
return 1; return 1;
} }
@ -1153,8 +1159,7 @@ static list_t *log_backread(log_t *log, const char *storename, const char *dest)
logfile_t *logf; logfile_t *logf;
ret = list_new(NULL); ret = list_new(NULL);
for (file_it = store->file_it; for (file_it = store->file_it; (logf = list_it_item(&file_it));
(logf = list_it_item(&file_it));
list_it_next(&file_it)) { list_it_next(&file_it)) {
if (!log_backread_file(log, store, logf, ret, dest, if (!log_backread_file(log, store, logf, ret, dest,
(time_t)0)) { (time_t)0)) {
@ -1201,8 +1206,8 @@ static size_t _log_write(log_t *logdata, logstore_t *store,
tmpstr[LOGLINE_MAXLEN] = 0; tmpstr[LOGLINE_MAXLEN] = 0;
if (store->memlog) { if (store->memlog) {
char *r = log_beautify(logdata, tmpstr, store->name, char *r =
destination); log_beautify(logdata, tmpstr, store->name, destination);
if (r != NULL) { if (r != NULL) {
list_add_last(store->memlog, r); list_add_last(store->memlog, r);
if (store->memc == logdata->user->backlog_lines) if (store->memc == logdata->user->backlog_lines)
@ -1320,7 +1325,8 @@ array_t *str_split(const char *str, const char *splt)
const char *start = str; const char *start = str;
size_t len; size_t len;
char *extracted; char *extracted;
array_t *array = array_new();; array_t *array = array_new();
;
do { do {
if (!*p || strchr(splt, *p)) { if (!*p || strchr(splt, *p)) {
@ -1358,8 +1364,7 @@ int log_parse_date(char *strdate, int *year, int *month, int *mday, int *hour,
ret = 1; ret = 1;
} }
int i; int i;
array_each(fields, i, sptr) array_each(fields, i, sptr) free(sptr);
free(sptr);
array_free(fields); array_free(fields);
return ret; return ret;
@ -1397,8 +1402,7 @@ static list_t *log_backread_hours(log_t *log, const char *storename,
ret = list_new(NULL); ret = list_new(NULL);
for (logstore_get_file_at(store, blstarttime, &file_it); for (logstore_get_file_at(store, blstarttime, &file_it);
(logf = list_it_item(&file_it)); (logf = list_it_item(&file_it)); list_it_next(&file_it)) {
list_it_next(&file_it)) {
if (!log_backread_file(log, store, logf, ret, dest, if (!log_backread_file(log, store, logf, ret, dest,
blstarttime)) { blstarttime)) {
log_reinit(store); log_reinit(store);
@ -1454,4 +1458,3 @@ list_t *backlog_lines(log_t *log, const char *bl, const char *cli_nick,
} }
return ret; return ret;
} }

View File

@ -29,8 +29,7 @@
struct list; struct list;
typedef struct logfile typedef struct logfile {
{
FILE *file; FILE *file;
char *filename; char *filename;
char *canonical_filename; char *canonical_filename;
@ -38,8 +37,7 @@ typedef struct logfile
size_t len; size_t len;
} logfile_t; } logfile_t;
typedef struct logstore typedef struct logstore {
{
char *name; char *name;
list_t file_group; list_t file_group;
int skip_advance; int skip_advance;
@ -51,8 +49,7 @@ typedef struct logstore
long file_offset; long file_offset;
} logstore_t; } logstore_t;
typedef struct log typedef struct log {
{
hash_t logfgs; hash_t logfgs;
char *network; char *network;
char *buffer; char *buffer;

362
src/md5.c
View File

@ -25,23 +25,22 @@
#include "md5.h" #include "md5.h"
#include "util.h" #include "util.h"
#define GET_UINT32(n,b,i) \ #define GET_UINT32(n, b, i) \
{ \ { \
(n) = ( (uint32) (b)[(i) ] ) \ (n) = ((uint32)(b)[(i)]) | ((uint32)(b)[(i) + 1] << 8) \
| ( (uint32) (b)[(i) + 1] << 8 ) \ | ((uint32)(b)[(i) + 2] << 16) \
| ( (uint32) (b)[(i) + 2] << 16 ) \ | ((uint32)(b)[(i) + 3] << 24); \
| ( (uint32) (b)[(i) + 3] << 24 ); \ }
}
#define PUT_UINT32(n,b,i) \ #define PUT_UINT32(n, b, i) \
{ \ { \
(b)[(i) ] = (uint8) ( (n) ); \ (b)[(i)] = (uint8)((n)); \
(b)[(i) + 1] = (uint8) ( (n) >> 8 ); \ (b)[(i) + 1] = (uint8)((n) >> 8); \
(b)[(i) + 2] = (uint8) ( (n) >> 16 ); \ (b)[(i) + 2] = (uint8)((n) >> 16); \
(b)[(i) + 3] = (uint8) ( (n) >> 24 ); \ (b)[(i) + 3] = (uint8)((n) >> 24); \
} }
void md5_starts( md5_context *ctx ) void md5_starts(md5_context *ctx)
{ {
ctx->total[0] = 0; ctx->total[0] = 0;
ctx->total[1] = 0; ctx->total[1] = 0;
@ -52,120 +51,121 @@ void md5_starts( md5_context *ctx )
ctx->state[3] = 0x10325476; ctx->state[3] = 0x10325476;
} }
void md5_process( md5_context *ctx, uint8 data[64] ) void md5_process(md5_context *ctx, uint8 data[64])
{ {
uint32 X[16], A, B, C, D; uint32 X[16], A, B, C, D;
GET_UINT32( X[0], data, 0 ); GET_UINT32(X[0], data, 0);
GET_UINT32( X[1], data, 4 ); GET_UINT32(X[1], data, 4);
GET_UINT32( X[2], data, 8 ); GET_UINT32(X[2], data, 8);
GET_UINT32( X[3], data, 12 ); GET_UINT32(X[3], data, 12);
GET_UINT32( X[4], data, 16 ); GET_UINT32(X[4], data, 16);
GET_UINT32( X[5], data, 20 ); GET_UINT32(X[5], data, 20);
GET_UINT32( X[6], data, 24 ); GET_UINT32(X[6], data, 24);
GET_UINT32( X[7], data, 28 ); GET_UINT32(X[7], data, 28);
GET_UINT32( X[8], data, 32 ); GET_UINT32(X[8], data, 32);
GET_UINT32( X[9], data, 36 ); GET_UINT32(X[9], data, 36);
GET_UINT32( X[10], data, 40 ); GET_UINT32(X[10], data, 40);
GET_UINT32( X[11], data, 44 ); GET_UINT32(X[11], data, 44);
GET_UINT32( X[12], data, 48 ); GET_UINT32(X[12], data, 48);
GET_UINT32( X[13], data, 52 ); GET_UINT32(X[13], data, 52);
GET_UINT32( X[14], data, 56 ); GET_UINT32(X[14], data, 56);
GET_UINT32( X[15], data, 60 ); GET_UINT32(X[15], data, 60);
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) #define S(x, n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
#define P(a,b,c,d,k,s,t) \ #define P(a, b, c, d, k, s, t) \
{ \ { \
a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ a += F(b, c, d) + X[k] + t; \
} a = S(a, s) + b; \
}
A = ctx->state[0]; A = ctx->state[0];
B = ctx->state[1]; B = ctx->state[1];
C = ctx->state[2]; C = ctx->state[2];
D = ctx->state[3]; D = ctx->state[3];
#define F(x,y,z) (z ^ (x & (y ^ z))) #define F(x, y, z) (z ^ (x & (y ^ z)))
P( A, B, C, D, 0, 7, 0xD76AA478 ); P(A, B, C, D, 0, 7, 0xD76AA478);
P( D, A, B, C, 1, 12, 0xE8C7B756 ); P(D, A, B, C, 1, 12, 0xE8C7B756);
P( C, D, A, B, 2, 17, 0x242070DB ); P(C, D, A, B, 2, 17, 0x242070DB);
P( B, C, D, A, 3, 22, 0xC1BDCEEE ); P(B, C, D, A, 3, 22, 0xC1BDCEEE);
P( A, B, C, D, 4, 7, 0xF57C0FAF ); P(A, B, C, D, 4, 7, 0xF57C0FAF);
P( D, A, B, C, 5, 12, 0x4787C62A ); P(D, A, B, C, 5, 12, 0x4787C62A);
P( C, D, A, B, 6, 17, 0xA8304613 ); P(C, D, A, B, 6, 17, 0xA8304613);
P( B, C, D, A, 7, 22, 0xFD469501 ); P(B, C, D, A, 7, 22, 0xFD469501);
P( A, B, C, D, 8, 7, 0x698098D8 ); P(A, B, C, D, 8, 7, 0x698098D8);
P( D, A, B, C, 9, 12, 0x8B44F7AF ); P(D, A, B, C, 9, 12, 0x8B44F7AF);
P( C, D, A, B, 10, 17, 0xFFFF5BB1 ); P(C, D, A, B, 10, 17, 0xFFFF5BB1);
P( B, C, D, A, 11, 22, 0x895CD7BE ); P(B, C, D, A, 11, 22, 0x895CD7BE);
P( A, B, C, D, 12, 7, 0x6B901122 ); P(A, B, C, D, 12, 7, 0x6B901122);
P( D, A, B, C, 13, 12, 0xFD987193 ); P(D, A, B, C, 13, 12, 0xFD987193);
P( C, D, A, B, 14, 17, 0xA679438E ); P(C, D, A, B, 14, 17, 0xA679438E);
P( B, C, D, A, 15, 22, 0x49B40821 ); P(B, C, D, A, 15, 22, 0x49B40821);
#undef F #undef F
#define F(x,y,z) (y ^ (z & (x ^ y))) #define F(x, y, z) (y ^ (z & (x ^ y)))
P( A, B, C, D, 1, 5, 0xF61E2562 ); P(A, B, C, D, 1, 5, 0xF61E2562);
P( D, A, B, C, 6, 9, 0xC040B340 ); P(D, A, B, C, 6, 9, 0xC040B340);
P( C, D, A, B, 11, 14, 0x265E5A51 ); P(C, D, A, B, 11, 14, 0x265E5A51);
P( B, C, D, A, 0, 20, 0xE9B6C7AA ); P(B, C, D, A, 0, 20, 0xE9B6C7AA);
P( A, B, C, D, 5, 5, 0xD62F105D ); P(A, B, C, D, 5, 5, 0xD62F105D);
P( D, A, B, C, 10, 9, 0x02441453 ); P(D, A, B, C, 10, 9, 0x02441453);
P( C, D, A, B, 15, 14, 0xD8A1E681 ); P(C, D, A, B, 15, 14, 0xD8A1E681);
P( B, C, D, A, 4, 20, 0xE7D3FBC8 ); P(B, C, D, A, 4, 20, 0xE7D3FBC8);
P( A, B, C, D, 9, 5, 0x21E1CDE6 ); P(A, B, C, D, 9, 5, 0x21E1CDE6);
P( D, A, B, C, 14, 9, 0xC33707D6 ); P(D, A, B, C, 14, 9, 0xC33707D6);
P( C, D, A, B, 3, 14, 0xF4D50D87 ); P(C, D, A, B, 3, 14, 0xF4D50D87);
P( B, C, D, A, 8, 20, 0x455A14ED ); P(B, C, D, A, 8, 20, 0x455A14ED);
P( A, B, C, D, 13, 5, 0xA9E3E905 ); P(A, B, C, D, 13, 5, 0xA9E3E905);
P( D, A, B, C, 2, 9, 0xFCEFA3F8 ); P(D, A, B, C, 2, 9, 0xFCEFA3F8);
P( C, D, A, B, 7, 14, 0x676F02D9 ); P(C, D, A, B, 7, 14, 0x676F02D9);
P( B, C, D, A, 12, 20, 0x8D2A4C8A ); P(B, C, D, A, 12, 20, 0x8D2A4C8A);
#undef F #undef F
#define F(x,y,z) (x ^ y ^ z) #define F(x, y, z) (x ^ y ^ z)
P( A, B, C, D, 5, 4, 0xFFFA3942 ); P(A, B, C, D, 5, 4, 0xFFFA3942);
P( D, A, B, C, 8, 11, 0x8771F681 ); P(D, A, B, C, 8, 11, 0x8771F681);
P( C, D, A, B, 11, 16, 0x6D9D6122 ); P(C, D, A, B, 11, 16, 0x6D9D6122);
P( B, C, D, A, 14, 23, 0xFDE5380C ); P(B, C, D, A, 14, 23, 0xFDE5380C);
P( A, B, C, D, 1, 4, 0xA4BEEA44 ); P(A, B, C, D, 1, 4, 0xA4BEEA44);
P( D, A, B, C, 4, 11, 0x4BDECFA9 ); P(D, A, B, C, 4, 11, 0x4BDECFA9);
P( C, D, A, B, 7, 16, 0xF6BB4B60 ); P(C, D, A, B, 7, 16, 0xF6BB4B60);
P( B, C, D, A, 10, 23, 0xBEBFBC70 ); P(B, C, D, A, 10, 23, 0xBEBFBC70);
P( A, B, C, D, 13, 4, 0x289B7EC6 ); P(A, B, C, D, 13, 4, 0x289B7EC6);
P( D, A, B, C, 0, 11, 0xEAA127FA ); P(D, A, B, C, 0, 11, 0xEAA127FA);
P( C, D, A, B, 3, 16, 0xD4EF3085 ); P(C, D, A, B, 3, 16, 0xD4EF3085);
P( B, C, D, A, 6, 23, 0x04881D05 ); P(B, C, D, A, 6, 23, 0x04881D05);
P( A, B, C, D, 9, 4, 0xD9D4D039 ); P(A, B, C, D, 9, 4, 0xD9D4D039);
P( D, A, B, C, 12, 11, 0xE6DB99E5 ); P(D, A, B, C, 12, 11, 0xE6DB99E5);
P( C, D, A, B, 15, 16, 0x1FA27CF8 ); P(C, D, A, B, 15, 16, 0x1FA27CF8);
P( B, C, D, A, 2, 23, 0xC4AC5665 ); P(B, C, D, A, 2, 23, 0xC4AC5665);
#undef F #undef F
#define F(x,y,z) (y ^ (x | ~z)) #define F(x, y, z) (y ^ (x | ~z))
P( A, B, C, D, 0, 6, 0xF4292244 ); P(A, B, C, D, 0, 6, 0xF4292244);
P( D, A, B, C, 7, 10, 0x432AFF97 ); P(D, A, B, C, 7, 10, 0x432AFF97);
P( C, D, A, B, 14, 15, 0xAB9423A7 ); P(C, D, A, B, 14, 15, 0xAB9423A7);
P( B, C, D, A, 5, 21, 0xFC93A039 ); P(B, C, D, A, 5, 21, 0xFC93A039);
P( A, B, C, D, 12, 6, 0x655B59C3 ); P(A, B, C, D, 12, 6, 0x655B59C3);
P( D, A, B, C, 3, 10, 0x8F0CCC92 ); P(D, A, B, C, 3, 10, 0x8F0CCC92);
P( C, D, A, B, 10, 15, 0xFFEFF47D ); P(C, D, A, B, 10, 15, 0xFFEFF47D);
P( B, C, D, A, 1, 21, 0x85845DD1 ); P(B, C, D, A, 1, 21, 0x85845DD1);
P( A, B, C, D, 8, 6, 0x6FA87E4F ); P(A, B, C, D, 8, 6, 0x6FA87E4F);
P( D, A, B, C, 15, 10, 0xFE2CE6E0 ); P(D, A, B, C, 15, 10, 0xFE2CE6E0);
P( C, D, A, B, 6, 15, 0xA3014314 ); P(C, D, A, B, 6, 15, 0xA3014314);
P( B, C, D, A, 13, 21, 0x4E0811A1 ); P(B, C, D, A, 13, 21, 0x4E0811A1);
P( A, B, C, D, 4, 6, 0xF7537E82 ); P(A, B, C, D, 4, 6, 0xF7537E82);
P( D, A, B, C, 11, 10, 0xBD3AF235 ); P(D, A, B, C, 11, 10, 0xBD3AF235);
P( C, D, A, B, 2, 15, 0x2AD7D2BB ); P(C, D, A, B, 2, 15, 0x2AD7D2BB);
P( B, C, D, A, 9, 21, 0xEB86D391 ); P(B, C, D, A, 9, 21, 0xEB86D391);
#undef F #undef F
@ -175,11 +175,12 @@ void md5_process( md5_context *ctx, uint8 data[64] )
ctx->state[3] += D; ctx->state[3] += D;
} }
void md5_update( md5_context *ctx, uint8 *input, uint32 length ) void md5_update(md5_context *ctx, uint8 *input, uint32 length)
{ {
uint32 left, fill; uint32 left, fill;
if( ! length ) return; if (!length)
return;
left = ctx->total[0] & 0x3F; left = ctx->total[0] & 0x3F;
fill = 64 - left; fill = 64 - left;
@ -187,64 +188,55 @@ void md5_update( md5_context *ctx, uint8 *input, uint32 length )
ctx->total[0] += length; ctx->total[0] += length;
ctx->total[0] &= 0xFFFFFFFF; ctx->total[0] &= 0xFFFFFFFF;
if( ctx->total[0] < length ) if (ctx->total[0] < length)
ctx->total[1]++; ctx->total[1]++;
if( left && length >= fill ) if (left && length >= fill) {
{ memcpy((void *)(ctx->buffer + left), (void *)input, fill);
memcpy( (void *) (ctx->buffer + left), md5_process(ctx, ctx->buffer);
(void *) input, fill );
md5_process( ctx, ctx->buffer );
length -= fill; length -= fill;
input += fill; input += fill;
left = 0; left = 0;
} }
while( length >= 64 ) while (length >= 64) {
{ md5_process(ctx, input);
md5_process( ctx, input );
length -= 64; length -= 64;
input += 64; input += 64;
} }
if( length ) if (length) {
{ memcpy((void *)(ctx->buffer + left), (void *)input, length);
memcpy( (void *) (ctx->buffer + left),
(void *) input, length );
} }
} }
static uint8 md5_padding[64] = static uint8 md5_padding[64] = {
{ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
void md5_finish( md5_context *ctx, uint8 digest[16] ) void md5_finish(md5_context *ctx, uint8 digest[16])
{ {
uint32 last, padn; uint32 last, padn;
uint32 high, low; uint32 high, low;
uint8 msglen[8]; uint8 msglen[8];
high = ( ctx->total[0] >> 29 ) high = (ctx->total[0] >> 29) | (ctx->total[1] << 3);
| ( ctx->total[1] << 3 ); low = (ctx->total[0] << 3);
low = ( ctx->total[0] << 3 );
PUT_UINT32( low, msglen, 0 ); PUT_UINT32(low, msglen, 0);
PUT_UINT32( high, msglen, 4 ); PUT_UINT32(high, msglen, 4);
last = ctx->total[0] & 0x3F; last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); padn = (last < 56) ? (56 - last) : (120 - last);
md5_update( ctx, md5_padding, padn ); md5_update(ctx, md5_padding, padn);
md5_update( ctx, msglen, (unsigned long)8 ); md5_update(ctx, msglen, (unsigned long)8);
PUT_UINT32( ctx->state[0], digest, 0 ); PUT_UINT32(ctx->state[0], digest, 0);
PUT_UINT32( ctx->state[1], digest, 4 ); PUT_UINT32(ctx->state[1], digest, 4);
PUT_UINT32( ctx->state[2], digest, 8 ); PUT_UINT32(ctx->state[2], digest, 8);
PUT_UINT32( ctx->state[3], digest, 12 ); PUT_UINT32(ctx->state[3], digest, 12);
} }
#ifdef TEST #ifdef TEST
@ -256,30 +248,23 @@ void md5_finish( md5_context *ctx, uint8 digest[16] )
* those are the standard RFC 1321 test vectors * those are the standard RFC 1321 test vectors
*/ */
static char *msg[] = static char *msg[] = {
{
"", "",
"a", "a",
"abc", "abc",
"message digest", "message digest",
"abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
"12345678901234567890123456789012345678901234567890123456789012" \ "12345678901234567890123456789012345678901234567890123456789012"
"345678901234567890" "345678901234567890"};
};
static char *val[] = static char *val[] = {
{ "d41d8cd98f00b204e9800998ecf8427e", "0cc175b9c0f1b6a831c399e269772661",
"d41d8cd98f00b204e9800998ecf8427e", "900150983cd24fb0d6963f7d28e17f72", "f96b697d7cb7938d525a2f31aaf161d0",
"0cc175b9c0f1b6a831c399e269772661", "c3fcd3d76192e4007dfb496cca67e13b", "d174ab98d277d9f5a5611c2c9f419d9f",
"900150983cd24fb0d6963f7d28e17f72", "57edf4a22be3c955ac49da2e2107b67a"};
"f96b697d7cb7938d525a2f31aaf161d0",
"c3fcd3d76192e4007dfb496cca67e13b",
"d174ab98d277d9f5a5611c2c9f419d9f",
"57edf4a22be3c955ac49da2e2107b67a"
};
int main( int argc, char *argv[] ) int main(int argc, char *argv[])
{ {
FILE *f; FILE *f;
int i, j; int i, j;
@ -288,60 +273,51 @@ int main( int argc, char *argv[] )
unsigned char buf[1000]; unsigned char buf[1000];
unsigned char md5sum[16]; unsigned char md5sum[16];
if( argc < 2 ) if (argc < 2) {
{ printf("\n MD5 Validation Tests:\n\n");
printf( "\n MD5 Validation Tests:\n\n" );
for( i = 0; i < 7; i++ ) for (i = 0; i < 7; i++) {
{ printf(" Test %d ", i + 1);
printf( " Test %d ", i + 1 );
md5_starts( &ctx ); md5_starts(&ctx);
md5_update( &ctx, (uint8 *) msg[i], strlen( msg[i] ) ); md5_update(&ctx, (uint8 *)msg[i], strlen(msg[i]));
md5_finish( &ctx, md5sum ); md5_finish(&ctx, md5sum);
for( j = 0; j < 16; j++ ) for (j = 0; j < 16; j++) {
{ sprintf(output + j * 2, "%02x", md5sum[j]);
sprintf( output + j * 2, "%02x", md5sum[j] );
} }
if( memcmp( output, val[i], 32 ) ) if (memcmp(output, val[i], 32)) {
{ printf("failed!\n");
printf( "failed!\n" ); return (1);
return( 1 );
} }
printf( "passed.\n" ); printf("passed.\n");
} }
printf( "\n" ); printf("\n");
} } else {
else if (!(f = fopen(argv[1], "rb"))) {
{ perror("fopen");
if( ! ( f = fopen( argv[1], "rb" ) ) ) return (1);
{
perror( "fopen" );
return( 1 );
} }
md5_starts( &ctx ); md5_starts(&ctx);
while( ( i = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) while ((i = fread(buf, 1, sizeof(buf), f)) > 0) {
{ md5_update(&ctx, buf, i);
md5_update( &ctx, buf, i );
} }
md5_finish( &ctx, md5sum ); md5_finish(&ctx, md5sum);
for( j = 0; j < 16; j++ ) for (j = 0; j < 16; j++) {
{ printf("%02x", md5sum[j]);
printf( "%02x", md5sum[j] );
} }
printf( " %s\n", argv[1] ); printf(" %s\n", argv[1]);
} }
return( 0 ); return (0);
} }
#endif #endif
@ -360,7 +336,8 @@ unsigned char *chash_double(char *str, unsigned int seed)
length = strlen(str); length = strlen(str);
length += 4; length += 4;
ptr = bip_malloc(length); ptr = bip_malloc(length);
// conversion from unsigned int to unsigned char may change value [-Werror=conversion] // conversion from unsigned int to unsigned char may change value
// [-Werror=conversion]
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion" #pragma GCC diagnostic ignored "-Wconversion"
ptr[0] = seed >> 24 & 0xff; ptr[0] = seed >> 24 & 0xff;
@ -399,4 +376,3 @@ int chash_cmp(char *try, unsigned char *pass, unsigned int seed)
free(try_hash); free(try_hash);
return 0; return 0;
} }

View File

@ -9,15 +9,12 @@
#define uint32 unsigned long int #define uint32 unsigned long int
#endif #endif
typedef struct typedef struct {
{
uint32 total[2]; uint32 total[2];
uint32 state[4]; uint32 state[4];
uint8 buffer[64]; uint8 buffer[64];
} } md5_context;
md5_context;
int chash_cmp(char *try, unsigned char *pass, int chash_cmp(char *try, unsigned char *pass, unsigned int seed);
unsigned int seed);
unsigned char *chash_double(char *str, unsigned int seed); unsigned char *chash_double(char *str, unsigned int seed);
#endif /* md5.h */ #endif /* md5.h */

View File

@ -107,7 +107,8 @@ char *bip_strcat_fit(size_t *remaining, char *str, const char *str2)
res = memccpy(str, str2, '\0', *remaining); res = memccpy(str, str2, '\0', *remaining);
if (!res) { if (!res) {
mylog(LOG_DEBUGTOOMUCH, "bip_strcat_fit: memccpy() failed, remaining %lu", mylog(LOG_DEBUGTOOMUCH,
"bip_strcat_fit: memccpy() failed, remaining %lu",
*remaining); *remaining);
return NULL; return NULL;
} }
@ -135,7 +136,8 @@ char *bip_strcatf_fit(size_t *remaining, char *str, const char *fmt, ...)
} }
if (*remaining > STRCATF_BUF_MAXLEN) { if (*remaining > STRCATF_BUF_MAXLEN) {
mylog(LOG_ERROR, "bip_strcatf_fit: remaining " mylog(LOG_ERROR,
"bip_strcatf_fit: remaining "
"is over STRCATF_BUF_MAXLEN"); "is over STRCATF_BUF_MAXLEN");
} }
@ -149,14 +151,17 @@ char *bip_strcatf_fit(size_t *remaining, char *str, const char *fmt, ...)
} }
if ((unsigned)written >= *remaining) { if ((unsigned)written >= *remaining) {
mylog(LOG_DEBUGVERB, "bip_strcatf_fit,vsnprintf: no space left"); mylog(LOG_DEBUGVERB,
"bip_strcatf_fit,vsnprintf: no space left");
goto end; goto end;
} }
res = memccpy(str, str2, '\0', *remaining); res = memccpy(str, str2, '\0', *remaining);
if (!res) { if (!res) {
mylog(LOG_DEBUGTOOMUCH, "bip_strcatf_fit: memccpy() failed, " mylog(LOG_DEBUGTOOMUCH,
"remaining %lu", *remaining); "bip_strcatf_fit: memccpy() failed, "
"remaining %lu",
*remaining);
goto end; goto end;
} }
@ -194,10 +199,10 @@ int is_valid_nick(char *str)
return 0; return 0;
tmp = str; tmp = str;
while (*tmp != '\0' && (isalnum(*tmp) || *tmp == '-' || *tmp == '[' || while (*tmp != '\0'
*tmp == ']' || *tmp == '\\' || *tmp == '`' || && (isalnum(*tmp) || *tmp == '-' || *tmp == '[' || *tmp == ']'
*tmp == '^' || *tmp == '{' || *tmp == '}' || || *tmp == '\\' || *tmp == '`' || *tmp == '^' || *tmp == '{'
*tmp == '|' || *tmp == '_' )) || *tmp == '}' || *tmp == '|' || *tmp == '_'))
tmp++; tmp++;
return (*tmp == '\0'); return (*tmp == '\0');
} }
@ -209,8 +214,8 @@ int is_valid_username(char *str)
return 0; return 0;
tmp = str; tmp = str;
while (*tmp != '\0' && *tmp != ' ' && *tmp != '\0' && *tmp != '\r' && while (*tmp != '\0' && *tmp != ' ' && *tmp != '\0' && *tmp != '\r'
*tmp != '\n') && *tmp != '\n')
tmp++; tmp++;
return (*tmp == '\0'); return (*tmp == '\0');
} }
@ -606,13 +611,13 @@ void hash_init(hash_t *h, int options)
switch (options) { switch (options) {
case HASH_NOCASE: case HASH_NOCASE:
list_init(&h->lists[i], list_init(&h->lists[i],
(int (*)(const void*, const void*)) (int (*)(const void *,
hash_item_nocase_cmp); const void *))hash_item_nocase_cmp);
break; break;
case HASH_DEFAULT: case HASH_DEFAULT:
list_init(&h->lists[i], list_init(&h->lists[i],
(int (*)(const void*,const void*)) (int (*)(const void *,
hash_item_cmp); const void *))hash_item_cmp);
break; break;
default: default:
fatal("wrong hash option %d", options); fatal("wrong hash option %d", options);
@ -800,7 +805,7 @@ void hash_dump(hash_t *h)
{ {
hash_iterator_t it; hash_iterator_t it;
assert(h); assert(h);
for (hash_it_init(h, &it); hash_it_key(&it) ;hash_it_next(&it)) for (hash_it_init(h, &it); hash_it_key(&it); hash_it_next(&it))
printf("%s => %p\n", hash_it_key(&it), hash_it_item(&it)); printf("%s => %p\n", hash_it_key(&it), hash_it_item(&it));
} }

View File

@ -74,37 +74,42 @@ typedef struct array {
const void **elemv; const void **elemv;
} array_t; } array_t;
#define MOVE_STRING(dest, src) do {\ #define MOVE_STRING(dest, src) \
if (dest)\ do { \
free(dest);\ if (dest) \
(dest) = (src);\ free(dest); \
(src) = NULL;\ (dest) = (src); \
} while(0) (src) = NULL; \
} while (0)
#define FREE(a) free(a); (a) = NULL; #define FREE(a) \
free(a); \
(a) = NULL;
#define MAYFREE(a) do { \ #define MAYFREE(a) \
do { \
if (a) { \ if (a) { \
free(a); \ free(a); \
(a) = NULL; \ (a) = NULL; \
} \ } \
} while(0); } while (0);
#define assert(condition) \ #define assert(condition) \
do { \ do { \
if (!(condition)) \ if (!(condition)) \
fatal("Failed assertion in " __FILE__ "(%d): " \ fatal("Failed assertion in " __FILE__ \
#condition, __LINE__); \ "(%d): " #condition, \
} while(0) __LINE__); \
} while (0)
#define assert_msg(condition, msg) \ #define assert_msg(condition, msg) \
do { \ do { \
if (!(condition)) \ if (!(condition)) \
fatal("%s in " __FILE__ "(%d): " \ fatal("%s in " __FILE__ "(%d): " #condition, (msg), \
#condition, (msg), __LINE__); \ __LINE__); \
} while(0) } while (0)
void list_init(list_t *list, int (*cmp)(const void*, const void*)); void list_init(list_t *list, int (*cmp)(const void *, const void *));
int list_ptr_cmp(const void *a, const void *b); int list_ptr_cmp(const void *a, const void *b);
list_t *list_new(int (*cmp)(const void *, const void *)); list_t *list_new(int (*cmp)(const void *, const void *));
void *list_remove(list_t *list, const void *ptr); void *list_remove(list_t *list, const void *ptr);
@ -183,8 +188,9 @@ char *bip_strdup(const char *str);
char *bip_strcat_fit(size_t *remaining, char *str, const char *str2); char *bip_strcat_fit(size_t *remaining, char *str, const char *str2);
char *bip_strcatf_fit(size_t *remaining, char *str, const char *str2, ...); char *bip_strcatf_fit(size_t *remaining, char *str, const char *str2, ...);
void bip_clock_gettime(clockid_t clockid, struct timespec *tp); void bip_clock_gettime(clockid_t clockid, struct timespec *tp);
#define array_each(a, idx, ptr) for ((idx) = 0; \ #define array_each(a, idx, ptr) \
(idx) < (a)->elemc && (((ptr) = bip_strdup(array_get((a), (idx)))) || 1); \ for ((idx) = 0; (idx) < (a)->elemc \
&& (((ptr) = bip_strdup(array_get((a), (idx)))) || 1); \
(idx)++) (idx)++)
void array_init(array_t *a); void array_init(array_t *a);

View File

@ -29,7 +29,7 @@ static const unsigned char base64_table[65] =
* *
* BIP change: remove line returns. * BIP change: remove line returns.
*/ */
unsigned char * base64_encode(const unsigned char *src, size_t len, unsigned char *base64_encode(const unsigned char *src, size_t len,
size_t *out_len) size_t *out_len)
{ {
unsigned char *out, *pos; unsigned char *out, *pos;
@ -72,8 +72,8 @@ unsigned char * base64_encode(const unsigned char *src, size_t len,
*pos++ = base64_table[(in[0] & 0x03) << 4]; *pos++ = base64_table[(in[0] & 0x03) << 4];
*pos++ = '='; *pos++ = '=';
} else { } else {
*pos++ = base64_table[((in[0] & 0x03) << 4) | *pos++ = base64_table[((in[0] & 0x03) << 4)
(in[1] >> 4)]; | (in[1] >> 4)];
*pos++ = base64_table[(in[1] & 0x0f) << 2]; *pos++ = base64_table[(in[1] & 0x0f) << 2];
} }
*pos++ = '='; *pos++ = '=';
@ -91,4 +91,3 @@ unsigned char * base64_encode(const unsigned char *src, size_t len,
*out_len = (size_t)(pos - out); *out_len = (size_t)(pos - out);
return out; return out;
} }

View File

@ -10,7 +10,7 @@
#ifndef BASE64_H #ifndef BASE64_H
#define BASE64_H #define BASE64_H
unsigned char * base64_encode(const unsigned char *src, size_t len, unsigned char *base64_encode(const unsigned char *src, size_t len,
size_t *out_len); size_t *out_len);
#endif /* BASE64_H */ #endif /* BASE64_H */