From: Guus Sliepen Date: Sun, 16 Jan 2022 22:02:09 +0000 (+0100) Subject: Enable and fix many extra warnings supported by GCC and Clang. X-Git-Url: https://git.tinc-vpn.org/git/browse?a=commitdiff_plain;h=28b7a53b6;p=tinc Enable and fix many extra warnings supported by GCC and Clang. This enables many extra warning options when hardening is enabled, and fixes the definition of _FORTITY_SOURCE. -Wshadow is not (yet) enabled, as this generates quite some warnings that are less trivial to fix. --- diff --git a/configure.ac b/configure.ac index e5bd2883..0ed205d7 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script. origcflags="$CFLAGS" -AC_PREREQ(2.69) +AC_PREREQ([2.69]) AC_INIT([tinc], m4_esyscmd_s((git describe || echo UNKNOWN) | sed 's/release-//')) AC_CONFIG_SRCDIR([src/tincd.c]) AM_INIT_AUTOMAKE([std-options subdir-objects nostdinc silent-rules -Wall]) @@ -14,9 +14,10 @@ AC_USE_SYSTEM_EXTENSIONS dnl Checks for programs. AC_PROG_CC -AC_PROG_CC_STDC +AC_PROG_CC_C99 AC_PROG_CPP AC_PROG_INSTALL +AC_PROG_LN_S AM_PROG_CC_C_O dnl Check whether to enable code coverage testing, and if so, clear the default CFLAGS. @@ -67,7 +68,7 @@ case $host_os in *mingw*) mingw=true AC_DEFINE(HAVE_MINGW, 1, [MinGW]) - LIBS="$LIBS -lws2_32 -lgdi32 -lcrypt32 -liphlpapi" + LIBS="$LIBS -lws2_32 -lgdi32 -lcrypt32 -liphlpapi -lwinpthread" LDFLAGS="$LDFLAGS -static" CPPFLAGS="$CPPFLAGS -DMINIUPNP_STATICLIB" ;; @@ -149,13 +150,14 @@ AX_CFLAGS_WARN_ALL(CFLAGS) AC_ARG_ENABLE([hardening], AS_HELP_STRING([--disable-hardening], [disable compiler and linker hardening flags])) AS_IF([test "x$enable_hardening" != "xno"], - [AX_CHECK_COMPILE_FLAG([-DFORTIFY_SOURCE=2], [CPPFLAGS="$CPPFLAGS -DFORTIFY_SOURCE=2"]) + [AX_CHECK_COMPILE_FLAG([-D_FORTIFY_SOURCE=2], [CPPFLAGS="$CPPFLAGS -D_FORTIFY_SOURCE=2"]) AX_CHECK_COMPILE_FLAG([-fwrapv], [CPPFLAGS="$CPPFLAGS -fwrapv"], AX_CHECK_COMPILE_FLAG([-fno-strict-overflow], [CPPFLAGS="$CPPFLAGS -fno-strict-overflow"])) case $host_os in *mingw*) AX_CHECK_LINK_FLAG([-Wl,--dynamicbase], [LDFLAGS="$LDFLAGS -Wl,--dynamicbase"]) AX_CHECK_LINK_FLAG([-Wl,--nxcompat], [LDFLAGS="$LDFLAGS -Wl,--nxcompat"]) + AX_CHECK_LINK_FLAG([-lssp], [LDFLAGS="$LDFLAGS -lssp"]) ;; *) AX_CHECK_COMPILE_FLAG([-fPIE], [CPPFLAGS="$CPPFLAGS -fPIE"]) @@ -164,6 +166,8 @@ AS_IF([test "x$enable_hardening" != "xno"], esac AX_CHECK_LINK_FLAG([-Wl,-z,relro], [LDFLAGS="$LDFLAGS -Wl,-z,relro"]) AX_CHECK_LINK_FLAG([-Wl,-z,now], [LDFLAGS="$LDFLAGS -Wl,-z,now"]) + AX_CHECK_COMPILE_FLAG([-W -Wextra -pedantic -Wreturn-type -Wold-style-definition -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls -Wbad-function-cast -Wwrite-strings -fdiagnostics-show-option -fstrict-aliasing -Wmissing-noreturn], + [CPPFLAGS="$CPPFLAGS -W -Wextra -pedantic -Wreturn-type -Wold-style-definition -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls -Wbad-function-cast -Wwrite-strings -fdiagnostics-show-option -fstrict-aliasing -Wmissing-noreturn"]) ] ); @@ -233,8 +237,8 @@ AC_ARG_ENABLE(legacy-protocol, dnl These are defined in files in m4/ -dnl AC_ARG_WITH(libgcrypt, AC_HELP_STRING([--with-libgcrypt], [enable use of libgcrypt instead of OpenSSL])], []) -dnl AC_ARG_WITH(openssl, AC_HELP_STRING([--without-openssl], [disable support for OpenSSL])], []) +dnl AC_ARG_WITH(libgcrypt, AS_HELP_STRING([--with-libgcrypt], [enable use of libgcrypt instead of OpenSSL])], []) +dnl AC_ARG_WITH(openssl, AS_HELP_STRING([--without-openssl], [disable support for OpenSSL])], []) tinc_CURSES tinc_READLINE diff --git a/src/autoconnect.c b/src/autoconnect.c index 9f4abece..d771078a 100644 --- a/src/autoconnect.c +++ b/src/autoconnect.c @@ -1,6 +1,6 @@ /* autoconnect.c -- automatic connection establishment - Copyright (C) 2017 Guus Sliepen + Copyright (C) 2017-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,13 +19,14 @@ #include "system.h" +#include "autoconnect.h" #include "connection.h" #include "crypto.h" #include "logger.h" #include "node.h" #include "xalloc.h" -static void make_new_connection() { +static void make_new_connection(void) { /* Select a random node we haven't connected to yet. */ uint32_t count = 0; @@ -74,7 +75,7 @@ static void make_new_connection() { } } -static void connect_to_unreachable() { +static void connect_to_unreachable(void) { /* Select a random known node. The rationale is that if there are many * reachable nodes, and only a few unreachable nodes, we don't want all * reachable nodes to try to connect to the unreachable ones at the @@ -111,7 +112,7 @@ static void connect_to_unreachable() { } } -static void drop_superfluous_outgoing_connection() { +static void drop_superfluous_outgoing_connection(void) { /* Choose a random outgoing connection to a node that has at least one other connection. */ uint32_t count = 0; @@ -146,7 +147,7 @@ static void drop_superfluous_outgoing_connection() { } } -static void drop_superfluous_pending_connections() { +static void drop_superfluous_pending_connections(void) { for list_each(outgoing_t, o, &outgoing_list) { /* Only look for connections that are waiting to be retried later. */ bool found = false; @@ -167,7 +168,7 @@ static void drop_superfluous_pending_connections() { } } -void do_autoconnect() { +void do_autoconnect(void) { /* Count number of active connections. */ uint32_t nc = 0; diff --git a/src/bsd/device.c b/src/bsd/device.c index fe2d6c52..0c1a62f4 100644 --- a/src/bsd/device.c +++ b/src/bsd/device.c @@ -1,7 +1,7 @@ /* device.c -- Interaction BSD tun/tap device Copyright (C) 2001-2005 Ivo Timmermans, - 2001-2021 Guus Sliepen + 2001-2022 Guus Sliepen 2009 Grzegorz Dymarek This program is free software; you can redistribute it and/or modify @@ -76,7 +76,9 @@ static bool setup_utun(void) { return false; } - struct ctl_info info = {}; + struct ctl_info info; + + memset(&info, 0, sizeof(info)); strlcpy(info.ctl_name, UTUN_CONTROL_NAME, sizeof(info.ctl_name)); diff --git a/src/bsd/tunemu.h b/src/bsd/tunemu.h index c67cfae3..7dcd2d59 100644 --- a/src/bsd/tunemu.h +++ b/src/bsd/tunemu.h @@ -20,7 +20,7 @@ #ifndef TUNEMU_H #define TUNEMU_H -#include "system.h" +#include "../system.h" typedef char tunemu_device[7]; diff --git a/src/cipher.c b/src/cipher.c index 0bab3bd9..5ac790a1 100644 --- a/src/cipher.c +++ b/src/cipher.c @@ -1,9 +1,30 @@ +/* + crypto.c -- stub cipher handling functions + Copyright (C) 2007-2022 Guus Sliepen + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + #include "cipher.h" #include "xalloc.h" #ifndef DISABLE_LEGACY -cipher_t *cipher_alloc() { +cipher_t *cipher_alloc(void) { return xzalloc(sizeof(cipher_t)); } diff --git a/src/cipher.h b/src/cipher.h index 1224210c..966a8640 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -3,7 +3,7 @@ /* cipher.h -- header file cipher.c - Copyright (C) 2007-2016 Guus Sliepen + Copyright (C) 2007-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -38,7 +38,7 @@ typedef struct cipher cipher_t; -extern cipher_t *cipher_alloc() __attribute__((__malloc__)); +extern cipher_t *cipher_alloc(void) __attribute__((__malloc__)); extern void cipher_free(cipher_t **cipher); extern bool cipher_open_by_name(cipher_t *cipher, const char *name); extern bool cipher_open_by_nid(cipher_t *cipher, int nid); diff --git a/src/conf.c b/src/conf.c index 4dd8fe7a..a40fdfa8 100644 --- a/src/conf.c +++ b/src/conf.c @@ -4,7 +4,7 @@ 1998-2005 Ivo Timmermans 2000 Cris van Pelt 2010-2011 Julien Muchembled - 2000-2021 Guus Sliepen + 2000-2022 Guus Sliepen 2013 Florent Clairambault This program is free software; you can redistribute it and/or modify @@ -75,7 +75,7 @@ splay_tree_t config_tree = { .delete = (splay_action_t) free_config, }; -splay_tree_t *create_configuration() { +splay_tree_t *create_configuration(void) { splay_tree_t *tree = splay_alloc_tree(NULL, NULL); init_configuration(tree); return tree; @@ -107,14 +107,14 @@ void config_add(splay_tree_t *config_tree, config_t *cfg) { splay_insert(config_tree, cfg); } -config_t *lookup_config(splay_tree_t *config_tree, char *variable) { - config_t cfg, *found; +config_t *lookup_config(splay_tree_t *config_tree, const char *variable) { + const config_t cfg = { + .variable = (char *)variable, + .file = NULL, + .line = 0, + }; - cfg.variable = variable; - cfg.file = NULL; - cfg.line = 0; - - found = splay_search_closest_greater(config_tree, &cfg); + config_t *found = splay_search_closest_greater(config_tree, &cfg); if(!found) { return NULL; diff --git a/src/conf.h b/src/conf.h index 8672ad79..2d55edde 100644 --- a/src/conf.h +++ b/src/conf.h @@ -4,7 +4,7 @@ /* conf.h -- header for conf.c Copyright (C) 1998-2005 Ivo Timmermans - 2000-2013 Guus Sliepen + 2000-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -40,13 +40,13 @@ extern int maxtimeout; extern bool bypass_security; extern list_t cmdline_conf; -extern splay_tree_t *create_configuration(); +extern splay_tree_t *create_configuration(void); extern void init_configuration(splay_tree_t *); extern void exit_configuration(splay_tree_t **config_tree); extern config_t *new_config(void) __attribute__((__malloc__)); extern void free_config(config_t *config); extern void config_add(splay_tree_t *config_tree, config_t *config); -extern config_t *lookup_config(splay_tree_t *config_tree, char *variable); +extern config_t *lookup_config(splay_tree_t *config_tree, const char *variable); extern config_t *lookup_config_next(splay_tree_t *config_tree, const config_t *config); extern bool get_config_bool(const config_t *config, bool *result); extern bool get_config_int(const config_t *config, int *result); diff --git a/src/connection.h b/src/connection.h index d9340fdb..60ec60a7 100644 --- a/src/connection.h +++ b/src/connection.h @@ -35,22 +35,21 @@ #define OPTION_VERSION(x) ((x) >> 24) /* Top 8 bits are for protocol minor version */ typedef struct connection_status_t { - bool pinged: 1; /* sent ping */ - bool unused_active: 1; - bool connecting: 1; /* 1 if we are waiting for a non-blocking connect() to finish */ - bool unused_termreq: 1; /* the termination of this connection was requested */ - bool remove_unused: 1; /* Set to 1 if you want this connection removed */ - bool timeout_unused: 1; /* 1 if gotten timeout */ - bool encryptout: 1; /* 1 if we can encrypt outgoing traffic */ - bool decryptin: 1; /* 1 if we have to decrypt incoming traffic */ - bool mst: 1; /* 1 if this connection is part of a minimum spanning tree */ - bool control: 1; /* 1 if this is a control connection */ - bool pcap: 1; /* 1 if this is a control connection requesting packet capture */ - bool log: 1; /* 1 if this is a control connection requesting log dump */ - bool invitation: 1; /* 1 if this is an invitation */ - bool invitation_used: 1; /* 1 if the invitation has been consumed */ - bool tarpit: 1; /* 1 if the connection should be added to the tarpit */ - uint32_t unused: 17; + uint32_t pinged: 1; /* sent ping */ + uint32_t unused_active: 1; + uint32_t connecting: 1; /* 1 if we are waiting for a non-blocking connect() to finish */ + uint32_t unused_termreq: 1; /* the termination of this connection was requested */ + uint32_t remove_unused: 1; /* Set to 1 if you want this connection removed */ + uint32_t timeout_unused: 1; /* 1 if gotten timeout */ + uint32_t encryptout: 1; /* 1 if we can encrypt outgoing traffic */ + uint32_t decryptin: 1; /* 1 if we have to decrypt incoming traffic */ + uint32_t mst: 1; /* 1 if this connection is part of a minimum spanning tree */ + uint32_t control: 1; /* 1 if this is a control connection */ + uint32_t pcap: 1; /* 1 if this is a control connection requesting packet capture */ + uint32_t log: 1; /* 1 if this is a control connection requesting log dump */ + uint32_t invitation: 1; /* 1 if this is an invitation */ + uint32_t invitation_used: 1; /* 1 if the invitation has been consumed */ + uint32_t tarpit: 1; /* 1 if the connection should be added to the tarpit */ } connection_status_t; #include "ecdsa.h" diff --git a/src/digest.c b/src/digest.c index 85bea7d5..4ef98cd8 100644 --- a/src/digest.c +++ b/src/digest.c @@ -1,9 +1,30 @@ +/* + digest.c -- stub digest handling functions + Copyright (C) 2007-2022 Guus Sliepen + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "system.h" + #include "digest.h" #include "xalloc.h" #ifndef DISABLE_LEGACY -digest_t *digest_alloc() { +digest_t *digest_alloc(void) { return xzalloc(sizeof(digest_t)); } diff --git a/src/digest.h b/src/digest.h index 9fb12483..dba6ee44 100644 --- a/src/digest.h +++ b/src/digest.h @@ -3,7 +3,7 @@ /* digest.h -- header file digest.c - Copyright (C) 2007-2016 Guus Sliepen + Copyright (C) 2007-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -39,7 +39,7 @@ typedef struct digest digest_t; extern bool digest_open_by_name(digest_t *digest, const char *name, size_t maclength); extern bool digest_open_by_nid(digest_t *digest, int nid, size_t maclength); -extern digest_t *digest_alloc() __attribute__((__malloc__)); +extern digest_t *digest_alloc(void) __attribute__((__malloc__)); extern void digest_free(digest_t **digest); extern void digest_close(digest_t *digest); extern bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *outdata) __attribute__((__warn_unused_result__)); diff --git a/src/dropin.c b/src/dropin.c index 3c950ada..e732fa09 100644 --- a/src/dropin.c +++ b/src/dropin.c @@ -1,7 +1,7 @@ /* dropin.c -- a set of drop-in replacements for libc functions Copyright (C) 2000-2005 Ivo Timmermans, - 2000-2018 Guus Sliepen + 2000-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -145,11 +145,3 @@ int gettimeofday(struct timeval *tv, void *tz) { return 0; } #endif - -#ifndef HAVE_NANOSLEEP -int nanosleep(const struct timespec *req, struct timespec *rem) { - (void)rem; - struct timeval tv = {req->tv_sec, req->tv_nsec / 1000}; - return select(0, NULL, NULL, NULL, &tv); -} -#endif diff --git a/src/dropin.h b/src/dropin.h index d1919e1c..14783ffb 100644 --- a/src/dropin.h +++ b/src/dropin.h @@ -4,7 +4,7 @@ /* dropin.h -- header file for dropin.c Copyright (C) 2000-2005 Ivo Timmermans, - 2000-2016 Guus Sliepen + 2000-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -36,10 +36,6 @@ extern int vasprintf(char **, const char *, va_list ap); extern int gettimeofday(struct timeval *, void *); #endif -#ifndef HAVE_NANOSLEEP -extern int nanosleep(const struct timespec *req, struct timespec *rem); -#endif - #ifndef timeradd #define timeradd(a, b, r) do {\ (r)->tv_sec = (a)->tv_sec + (b)->tv_sec;\ diff --git a/src/ed25519/ecdsa.c b/src/ed25519/ecdsa.c index 0e80d910..f0ce2c16 100644 --- a/src/ed25519/ecdsa.c +++ b/src/ed25519/ecdsa.c @@ -38,7 +38,7 @@ ecdsa_t *ecdsa_set_base64_public_key(const char *p) { size_t len = strlen(p); if(len != 43) { - logger(DEBUG_ALWAYS, LOG_ERR, "Invalid size %zu for public key!", len); + logger(DEBUG_ALWAYS, LOG_ERR, "Invalid size %lu for public key!", (unsigned long)len); return 0; } @@ -46,7 +46,7 @@ ecdsa_t *ecdsa_set_base64_public_key(const char *p) { len = b64decode_tinc(p, ecdsa->public, len); if(len != 32) { - logger(DEBUG_ALWAYS, LOG_ERR, "Invalid format of public key! len = %zu", len); + logger(DEBUG_ALWAYS, LOG_ERR, "Invalid format of public key! len = %lu", (unsigned long)len); free(ecdsa); return 0; } diff --git a/src/event.c b/src/event.c index c547c46d..899b62a0 100644 --- a/src/event.c +++ b/src/event.c @@ -1,6 +1,6 @@ /* event.c -- I/O, timeout and signal event handling - Copyright (C) 2012-2021 Guus Sliepen + Copyright (C) 2012-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,12 +18,14 @@ */ #include "system.h" -#include "dropin.h" + +#include #ifdef HAVE_SYS_EPOLL_H #include #endif +#include "dropin.h" #include "event.h" #include "utils.h" #include "net.h" @@ -46,7 +48,7 @@ static DWORD event_count = 0; static bool running; #ifdef HAVE_SYS_EPOLL_H -static inline int event_epoll_init() { +static inline int event_epoll_init(void) { /* NOTE: 1024 limit is only used on ancient (pre 2.6.27) kernels. Decent kernels will ignore this value making it unlimited. epoll_create1 might be better, but these kernels would not be supported @@ -290,11 +292,14 @@ void timeout_del(timeout_t *timeout) { static io_t signalio; static int pipefd[2] = {-1, -1}; -static signal_t *signal_handle[NSIG + 1] = {}; +static signal_t *signal_handle[NSIG + 1] = {NULL}; static void signal_handler(int signum) { unsigned char num = signum; - write(pipefd[1], &num, 1); + + if(write(pipefd[1], &num, 1) != 1) { + // Pipe full or broken, nothing we can do about it. + } } static void signalio_handler(void *data, int flags) { @@ -480,6 +485,7 @@ bool event_loop(void) { } #else + assert(WSA_WAIT_EVENT_0 == 0); while(running) { struct timeval diff; @@ -541,12 +547,12 @@ bool event_loop(void) { break; } - if(result < WSA_WAIT_EVENT_0 || result >= WSA_WAIT_EVENT_0 + event_count - event_offset) { + if(result >= event_count - event_offset) { return false; } /* Look up io in the map by index. */ - event_index = result - WSA_WAIT_EVENT_0 + event_offset; + event_index = result + event_offset; io_t *io = io_map[event_index]; if(io->fd == -1) { diff --git a/src/fd_device.c b/src/fd_device.c index f21e475c..6e85be0d 100644 --- a/src/fd_device.c +++ b/src/fd_device.c @@ -1,7 +1,7 @@ /* fd_device.c -- Interaction with Android tun fd Copyright (C) 2001-2005 Ivo Timmermans, - 2001-2021 Guus Sliepen + 2001-2022 Guus Sliepen 2009 Grzegorz Dymarek 2016-2020 Pacien TRAN-GIRARD @@ -53,7 +53,7 @@ static int read_fd(int socket) { msg.msg_controllen = sizeof(cmsgbuf); if((ret = recvmsg(socket, &msg, 0)) < 1) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not read from unix socket (error %zd)!", ret); + logger(DEBUG_ALWAYS, LOG_ERR, "Could not read from unix socket (error %ld)!", (long)ret); return -1; } @@ -83,8 +83,8 @@ static int read_fd(int socket) { } if(cmsgptr->cmsg_len != CMSG_LEN(sizeof(device_fd))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Wrong CMSG data length: %zu, expected %zu!", - cmsgptr->cmsg_len, CMSG_LEN(sizeof(device_fd))); + logger(DEBUG_ALWAYS, LOG_ERR, "Wrong CMSG data length: %lu, expected %lu!", + (unsigned long)cmsgptr->cmsg_len, (unsigned long)CMSG_LEN(sizeof(device_fd))); return -1; } diff --git a/src/fsck.c b/src/fsck.c index 5c7762a8..3a64959d 100644 --- a/src/fsck.c +++ b/src/fsck.c @@ -1,6 +1,6 @@ /* fsck.c -- Check the configuration files for problems - Copyright (C) 2014-2021 Guus Sliepen + Copyright (C) 2014-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -187,7 +187,7 @@ static void check_conffile(const char *nodename, bool server) { #ifdef HAVE_MINGW typedef int uid_t; -static uid_t getuid() { +static uid_t getuid(void) { return 0; } @@ -220,7 +220,7 @@ static void check_key_file_mode(const char *fname) { } #endif // HAVE_MINGW -static char *read_node_name() { +static char *read_node_name(void) { if(access(tinc_conf, R_OK) == 0) { return get_my_name(true); } @@ -438,7 +438,7 @@ static bool check_config_mode(const char *fname) { return true; } -static bool check_script_confdir() { +static bool check_script_confdir(void) { char fname[PATH_MAX]; DIR *dir = opendir(confbase); @@ -616,7 +616,7 @@ static void check_config_variables(const char *host_dir) { } } -static bool check_scripts_and_configs() { +static bool check_scripts_and_configs(void) { // Check whether scripts are executable. if(!check_script_confdir()) { return false; diff --git a/src/gcrypt/cipher.c b/src/gcrypt/cipher.c index 0f7b008d..c1ecf50a 100644 --- a/src/gcrypt/cipher.c +++ b/src/gcrypt/cipher.c @@ -1,6 +1,6 @@ /* cipher.c -- Symmetric block cipher handling - Copyright (C) 2007-2012 Guus Sliepen + Copyright (C) 2007-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,11 +17,12 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" #include "cipher.h" -#include "logger.h" -#include "xalloc.h" +#include "../cipher.h" +#include "../logger.h" +#include "../xalloc.h" static struct { const char *name; @@ -53,9 +54,7 @@ static struct { }; static bool nametocipher(const char *name, int *algo, int *mode) { - size_t i; - - for(i = 0; i < sizeof(ciphertable) / sizeof(*ciphertable); i++) { + for(size_t i = 0; i < sizeof(ciphertable) / sizeof(*ciphertable); i++) { if(ciphertable[i].name && !strcasecmp(name, ciphertable[i].name)) { *algo = ciphertable[i].algo; *mode = ciphertable[i].mode; @@ -67,9 +66,7 @@ static bool nametocipher(const char *name, int *algo, int *mode) { } static bool nidtocipher(int nid, int *algo, int *mode) { - size_t i; - - for(i = 0; i < sizeof(ciphertable) / sizeof(*ciphertable); i++) { + for(size_t i = 0; i < sizeof(ciphertable) / sizeof(*ciphertable); i++) { if(nid == ciphertable[i].nid) { *algo = ciphertable[i].algo; *mode = ciphertable[i].mode; @@ -81,9 +78,7 @@ static bool nidtocipher(int nid, int *algo, int *mode) { } static bool ciphertonid(int algo, int mode, int *nid) { - size_t i; - - for(i = 0; i < sizeof(ciphertable) / sizeof(*ciphertable); i++) { + for(size_t i = 0; i < sizeof(ciphertable) / sizeof(*ciphertable); i++) { if(algo == ciphertable[i].algo && mode == ciphertable[i].mode) { *nid = ciphertable[i].nid; return true; @@ -136,10 +131,6 @@ bool cipher_open_by_nid(cipher_t *cipher, int nid) { return cipher_open(cipher, algo, mode); } -bool cipher_open_blowfish_ofb(cipher_t *cipher) { - return cipher_open(cipher, GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_OFB); -} - void cipher_close(cipher_t *cipher) { if(cipher->handle) { gcry_cipher_close(cipher->handle); @@ -185,11 +176,9 @@ size_t cipher_blocksize(const cipher_t *cipher) { return cipher->blklen; } -void cipher_get_key(const cipher_t *cipher, void *key) { - memcpy(key, cipher->key, cipher->keylen + cipher->blklen); -} - bool cipher_set_key(cipher_t *cipher, void *key, bool encrypt) { + (void)encrypt; + memcpy(cipher->key, key, cipher->keylen + cipher->blklen); gcry_cipher_setkey(cipher->handle, cipher->key, cipher->keylen); @@ -199,23 +188,12 @@ bool cipher_set_key(cipher_t *cipher, void *key, bool encrypt) { } bool cipher_set_key_from_rsa(cipher_t *cipher, void *key, size_t len, bool encrypt) { - memcpy(cipher->key, - key + len - cipher->keylen, - cipher->keylen); - gcry_cipher_setkey(cipher->handle, cipher->key, cipher->keylen); - - memcpy(cipher->key + cipher->keylen, - key + len - cipher->blklen - cipher->keylen, - cipher->blklen); - gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen); - - return true; -} - -bool cipher_regenerate_key(cipher_t *cipher, bool encrypt) { - gcry_create_nonce(cipher->key, cipher->keylen + cipher->blklen); + (void)encrypt; + memcpy(cipher->key, (char *)key + len - cipher->keylen, cipher->keylen); gcry_cipher_setkey(cipher->handle, cipher->key, cipher->keylen); + + memcpy((char *)cipher->key + cipher->keylen, (char *)key + len - cipher->blklen - cipher->keylen, cipher->blklen); gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen); return true; @@ -258,7 +236,7 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou } if(cipher->padding) { - if((err = gcry_cipher_encrypt(cipher->handle, outdata + inlen, cipher->blklen, pad, cipher->blklen))) { + if((err = gcry_cipher_encrypt(cipher->handle, (char *)outdata + inlen, cipher->blklen, pad, cipher->blklen))) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", gcry_strerror(err)); return false; } diff --git a/src/gcrypt/cipher.h b/src/gcrypt/cipher.h index 41450c41..2067db68 100644 --- a/src/gcrypt/cipher.h +++ b/src/gcrypt/cipher.h @@ -3,7 +3,7 @@ /* cipher.h -- header file cipher.c - Copyright (C) 2007-2009 Guus Sliepen + Copyright (C) 2007-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,35 +20,17 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" #include -#define CIPHER_MAX_BLOCK_SIZE 32 -#define CIPHER_MAX_IV_SIZE 16 -#define CIPHER_MAX_KEY_SIZE 32 - -typedef struct cipher { +struct cipher { gcry_cipher_hd_t handle; uint8_t *key; int nid; uint16_t keylen; uint16_t blklen; bool padding; -} cipher_t; - -extern bool cipher_open_by_name(struct cipher *, const char *); -extern bool cipher_open_by_nid(struct cipher *, int); -extern bool cipher_open_blowfish_ofb(struct cipher *); -extern void cipher_close(struct cipher *); -extern size_t cipher_keylength(const struct cipher *); -extern void cipher_get_key(const struct cipher *, void *); -extern bool cipher_set_key(struct cipher *, void *, bool); -extern bool cipher_set_key_from_rsa(struct cipher *, void *, size_t, bool); -extern bool cipher_regenerate_key(struct cipher *, bool); -extern bool cipher_encrypt(struct cipher *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot); -extern bool cipher_decrypt(struct cipher *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot); -extern int cipher_get_nid(const struct cipher *); -extern bool cipher_active(const struct cipher *); +}; #endif diff --git a/src/gcrypt/crypto.c b/src/gcrypt/crypto.c index dc92b3e0..cf5d0e64 100644 --- a/src/gcrypt/crypto.c +++ b/src/gcrypt/crypto.c @@ -1,6 +1,6 @@ /* crypto.c -- Cryptographic miscellaneous functions and initialisation - Copyright (C) 2007 Guus Sliepen + Copyright (C) 2007-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,16 +17,16 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" #include -#include "crypto.h" +#include "../crypto.h" -void crypto_init() { +void crypto_init(void) { } -void crypto_exit() { +void crypto_exit(void) { } void randomize(void *out, size_t outlen) { diff --git a/src/gcrypt/crypto.h b/src/gcrypt/crypto.h deleted file mode 100644 index c77d4f46..00000000 --- a/src/gcrypt/crypto.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef TINC_GCRYPT_CRYPTO_H -#define TINC_GCRYPT_CRYPTO_H - -/* - crypto.h -- header for crypto.c - Copyright (C) 2007-2009 Guus Sliepen - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -extern void crypto_init(); -extern void crypto_exit(); -extern void randomize(void *, size_t); - -#endif diff --git a/src/gcrypt/digest.c b/src/gcrypt/digest.c index c8d4b314..1795277e 100644 --- a/src/gcrypt/digest.c +++ b/src/gcrypt/digest.c @@ -1,6 +1,6 @@ /* digest.c -- Digest handling - Copyright (C) 2007-2012 Guus Sliepen + Copyright (C) 2007-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,10 +17,11 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" #include "digest.h" -#include "logger.h" +#include "../digest.h" +#include "../logger.h" static struct { const char *name; @@ -35,9 +36,7 @@ static struct { }; static bool nametodigest(const char *name, enum gcry_md_algos *algo) { - int i; - - for(i = 0; i < sizeof(digesttable) / sizeof(*digesttable); i++) { + for(size_t i = 0; i < sizeof(digesttable) / sizeof(*digesttable); i++) { if(digesttable[i].name && !strcasecmp(name, digesttable[i].name)) { *algo = digesttable[i].algo; return true; @@ -48,7 +47,7 @@ static bool nametodigest(const char *name, enum gcry_md_algos *algo) { } static bool nidtodigest(int nid, enum gcry_md_algos *algo) { - for(int i = 0; i < sizeof(digesttable) / sizeof(*digesttable); i++) { + for(size_t i = 0; i < sizeof(digesttable) / sizeof(*digesttable); i++) { if(nid == digesttable[i].nid) { *algo = digesttable[i].algo; return true; @@ -59,7 +58,7 @@ static bool nidtodigest(int nid, enum gcry_md_algos *algo) { } static bool digesttonid(enum gcry_md_algos algo, int *nid) { - for(int i = 0; i < sizeof(digesttable) / sizeof(*digesttable); i++) { + for(size_t i = 0; i < sizeof(digesttable) / sizeof(*digesttable); i++) { if(algo == digesttable[i].algo) { *nid = digesttable[i].nid; return true; @@ -77,7 +76,7 @@ static bool digest_open(digest_t *digest, enum gcry_md_algos algo, size_t maclen unsigned int len = gcry_md_get_algo_dlen(algo); - if(maclength > len || maclength < 0) { + if(maclength > len) { digest->maclength = len; } else { digest->maclength = maclength; @@ -111,10 +110,6 @@ bool digest_open_by_nid(digest_t *digest, int nid, size_t maclength) { return digest_open(digest, algo, maclength); } -bool digest_open_sha1(digest_t *digest, size_t maclength) { - return digest_open(digest, GCRY_MD_SHA1, maclength); -} - void digest_close(digest_t *digest) { if(digest->hmac) { gcry_md_close(digest->hmac); diff --git a/src/gcrypt/digest.h b/src/gcrypt/digest.h index 9a9c611e..a83535d3 100644 --- a/src/gcrypt/digest.h +++ b/src/gcrypt/digest.h @@ -3,7 +3,7 @@ /* digest.h -- header file digest.c - Copyright (C) 2007-2009 Guus Sliepen + Copyright (C) 2007-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,8 +22,6 @@ #include -#define DIGEST_MAX_SIZE 64 - typedef struct digest { enum gcry_md_algos algo; int nid; @@ -31,15 +29,4 @@ typedef struct digest { gcry_md_hd_t hmac; } digest_t; -extern bool digest_open_by_name(struct digest *, const char *name, size_t maclength); -extern bool digest_open_by_nid(struct digest *, int nid, size_t maclength); -extern bool digest_open_sha1(struct digest *, size_t maclength); -extern void digest_close(struct digest *); -extern bool digest_create(struct digest *, const void *indata, size_t inlen, void *outdata); -extern bool digest_verify(struct digest *, const void *indata, size_t inlen, const void *digestdata); -extern bool digest_set_key(struct digest *, const void *key, size_t len); -extern int digest_get_nid(const struct digest *); -extern size_t digest_length(const struct digest *); -extern bool digest_active(const struct digest *); - #endif diff --git a/src/gcrypt/pem.c b/src/gcrypt/pem.c index b22d0e40..b2eca3d4 100644 --- a/src/gcrypt/pem.c +++ b/src/gcrypt/pem.c @@ -1,5 +1,26 @@ +/* + pem.c -- PEM encoding and decoding + Copyright (C) 2007-2022 Guus Sliepen + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "../system.h" + #include "pem.h" -#include "utils.h" +#include "../utils.h" // Base64 decoding table @@ -35,7 +56,7 @@ static const char b64enc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" // Heavily based on code by Jouni Malinen // https://web.mit.edu/freebsd/head/contrib/wpa/src/utils/base64.c static size_t b64encode(char *dst, const void *src, const size_t length) { - const uint8_t *end = src + length; + const uint8_t *end = (const uint8_t *)src + length; const uint8_t *in = src; char *pos = dst; diff --git a/src/gcrypt/pem.h b/src/gcrypt/pem.h index 119c114b..f7d1d6ec 100644 --- a/src/gcrypt/pem.h +++ b/src/gcrypt/pem.h @@ -1,6 +1,25 @@ #ifndef TINC_GCRYPT_PEM_H #define TINC_GCRYPT_PEM_H +/* + pem.h -- PEM encoding and decoding + Copyright (C) 2007-2022 Guus Sliepen + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + #include "../system.h" bool pem_decode(FILE *fp, const char *header, uint8_t *buf, size_t size, size_t *outsize); diff --git a/src/gcrypt/rsa.c b/src/gcrypt/rsa.c index 5d12985d..1b151648 100644 --- a/src/gcrypt/rsa.c +++ b/src/gcrypt/rsa.c @@ -1,6 +1,6 @@ /* rsa.c -- RSA key handling - Copyright (C) 2007-2012 Guus Sliepen + Copyright (C) 2007-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,14 +17,16 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" #include -#include "logger.h" -#include "rsa.h" #include "pem.h" -#include "xalloc.h" + +#include "rsa.h" +#include "../logger.h" +#include "../rsa.h" +#include "../xalloc.h" // BER decoding functions @@ -62,7 +64,7 @@ static size_t ber_read_len(unsigned char **p, size_t *buflen) { if(**p & 0x80) { size_t result = 0; - int len = *(*p)++ & 0x7f; + size_t len = *(*p)++ & 0x7f; (*buflen)--; if(len > *buflen) { @@ -117,11 +119,14 @@ static bool ber_read_mpi(unsigned char **p, size_t *buflen, gcry_mpi_t *mpi) { return mpi ? !err : true; } -rsa_t *rsa_set_hex_public_key(char *n, char *e) { +rsa_t *rsa_set_hex_public_key(const char *n, const char *e) { rsa_t *rsa = xzalloc(sizeof(rsa_t)); - gcry_error_t err = gcry_mpi_scan(&rsa->n, GCRYMPI_FMT_HEX, n, 0, NULL) - ? : gcry_mpi_scan(&rsa->e, GCRYMPI_FMT_HEX, e, 0, NULL); + gcry_error_t err = gcry_mpi_scan(&rsa->n, GCRYMPI_FMT_HEX, n, 0, NULL); + + if(!err) { + err = gcry_mpi_scan(&rsa->e, GCRYMPI_FMT_HEX, e, 0, NULL); + } if(err) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading RSA public key: %s", gcry_strerror(errno)); @@ -132,12 +137,18 @@ rsa_t *rsa_set_hex_public_key(char *n, char *e) { return rsa; } -rsa_t *rsa_set_hex_private_key(char *n, char *e, char *d) { +rsa_t *rsa_set_hex_private_key(const char *n, const char *e, const char *d) { rsa_t *rsa = xzalloc(sizeof(rsa_t)); - gcry_error_t err = gcry_mpi_scan(&rsa->n, GCRYMPI_FMT_HEX, n, 0, NULL) - ? : gcry_mpi_scan(&rsa->e, GCRYMPI_FMT_HEX, e, 0, NULL) - ? : gcry_mpi_scan(&rsa->d, GCRYMPI_FMT_HEX, d, 0, NULL); + gcry_error_t err = gcry_mpi_scan(&rsa->n, GCRYMPI_FMT_HEX, n, 0, NULL); + + if(!err) { + err = gcry_mpi_scan(&rsa->e, GCRYMPI_FMT_HEX, e, 0, NULL); + } + + if(!err) { + err = gcry_mpi_scan(&rsa->d, GCRYMPI_FMT_HEX, d, 0, NULL); + } if(err) { logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading RSA public key: %s", gcry_strerror(errno)); @@ -203,7 +214,7 @@ rsa_t *rsa_read_pem_private_key(FILE *fp) { return rsa; } -size_t rsa_size(rsa_t *rsa) { +size_t rsa_size(const rsa_t *rsa) { return (gcry_mpi_get_nbits(rsa->n) + 7) / 8; } @@ -214,7 +225,7 @@ size_t rsa_size(rsa_t *rsa) { // TODO: get rid of this macro, properly clean up gcry_ structures after use #define check(foo) { gcry_error_t err = (foo); if(err) {logger(DEBUG_ALWAYS, LOG_ERR, "gcrypt error %s/%s at %s:%d", gcry_strsource(err), gcry_strerror(err), __FILE__, __LINE__); return false; }} -bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) { +bool rsa_public_encrypt(rsa_t *rsa, const void *in, size_t len, void *out) { gcry_mpi_t inmpi; check(gcry_mpi_scan(&inmpi, GCRYMPI_FMT_USG, in, len, NULL)); @@ -223,17 +234,18 @@ bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) { size_t out_bytes = (gcry_mpi_get_nbits(outmpi) + 7) / 8; size_t pad = len - MIN(out_bytes, len); + unsigned char *pout = out; for(; pad; --pad) { - *(char *)out++ = 0; + *pout++ = 0; } - check(gcry_mpi_print(GCRYMPI_FMT_USG, out, len, NULL, outmpi)); + check(gcry_mpi_print(GCRYMPI_FMT_USG, pout, len, NULL, outmpi)); return true; } -bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) { +bool rsa_private_decrypt(rsa_t *rsa, const void *in, size_t len, void *out) { gcry_mpi_t inmpi; check(gcry_mpi_scan(&inmpi, GCRYMPI_FMT_USG, in, len, NULL)); @@ -241,12 +253,13 @@ bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) { gcry_mpi_powm(outmpi, inmpi, rsa->d, rsa->n); size_t pad = len - (gcry_mpi_get_nbits(outmpi) + 7) / 8; + unsigned char *pout = out; for(; pad; --pad) { - *(char *)out++ = 0; + *pout++ = 0; } - check(gcry_mpi_print(GCRYMPI_FMT_USG, out, len, NULL, outmpi)); + check(gcry_mpi_print(GCRYMPI_FMT_USG, pout, len, NULL, outmpi)); return true; } diff --git a/src/gcrypt/rsa.h b/src/gcrypt/rsa.h index c27f1967..e6bb5ec9 100644 --- a/src/gcrypt/rsa.h +++ b/src/gcrypt/rsa.h @@ -3,7 +3,7 @@ /* rsa.h -- RSA key handling - Copyright (C) 2007 Guus Sliepen + Copyright (C) 2007-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,6 +22,7 @@ #include +#define TINC_RSA_INTERNAL typedef struct rsa { gcry_mpi_t n; gcry_mpi_t e; diff --git a/src/gcrypt/rsagen.c b/src/gcrypt/rsagen.c index acf96acf..01bb1378 100644 --- a/src/gcrypt/rsagen.c +++ b/src/gcrypt/rsagen.c @@ -1,6 +1,6 @@ /* rsagen.c -- RSA key generation and export - Copyright (C) 2008-2012 Guus Sliepen + Copyright (C) 2008-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,15 +17,15 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" #include #include -#include "../rsagen.h" -#include "xalloc.h" #include "rsa.h" #include "pem.h" +#include "../rsagen.h" +#include "../xalloc.h" // ASN.1 tags. typedef enum { @@ -106,7 +106,7 @@ static size_t der_fill(uint8_t *derbuf, bool is_private, const gcry_mpi_t mpi[], der += len; } - assert(der - derbuf == derlen); + assert((size_t)(der - derbuf) == derlen); return derlen; } diff --git a/src/hash.h b/src/hash.h index 11d132a4..531c6639 100644 --- a/src/hash.h +++ b/src/hash.h @@ -3,7 +3,7 @@ /* hash.h -- header file for hash.c - Copyright (C) 2012 Guus Sliepen + Copyright (C) 2012-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -37,10 +37,10 @@ uint32_t modulo(uint32_t hash, size_t n); t keys[n]; \ const void *values[n]; \ } hash_ ## t; \ - static uint32_t inline hash_modulo_ ## t(uint32_t hash) { \ + static inline uint32_t hash_modulo_ ## t(uint32_t hash) { \ return hash & (n - 1); \ } \ - void hash_insert_ ## t (hash_ ##t *hash, const t *key, const void *value) { \ + static inline void hash_insert_ ## t (hash_ ##t *hash, const t *key, const void *value) { \ uint32_t i = hash_modulo_ ## t(hash_function_ ## t(key)); \ for(uint8_t f=0; f< (HASH_SEARCH_ITERATIONS - 1); f++){ \ if(hash->values[i] == NULL || !memcmp(key, &hash->keys[i], sizeof(t))) { \ @@ -54,7 +54,7 @@ uint32_t modulo(uint32_t hash, size_t n); memcpy(&hash->keys[i], key, sizeof(t)); \ hash->values[i] = value; \ } \ - void *hash_search_ ## t (const hash_ ##t *hash, const t *key) { \ + static inline void *hash_search_ ## t (const hash_ ##t *hash, const t *key) { \ uint32_t i = hash_modulo_ ## t(hash_function_ ## t(key)); \ for(uint8_t f=0; fkeys[i], sizeof(t))) { \ @@ -64,7 +64,7 @@ uint32_t modulo(uint32_t hash, size_t n); } \ return NULL; \ } \ - void hash_delete_ ## t (hash_ ##t *hash, const t *key) { \ + static inline void hash_delete_ ## t (hash_ ##t *hash, const t *key) { \ uint32_t i = hash_modulo_ ## t(hash_function_ ## t(key)); \ for(uint8_t f=0; fkeys[i], sizeof(t))) { \ @@ -74,7 +74,7 @@ uint32_t modulo(uint32_t hash, size_t n); if(++i == n) i = 0; \ } \ } \ - void hash_clear_ ## t(hash_ ##t *hash) { \ + static inline void hash_clear_ ## t(hash_ ##t *hash) { \ memset(hash->values, 0, n * sizeof(*hash->values)); \ memset(hash->keys, 0, n * sizeof(*hash->keys)); \ } diff --git a/src/have.h b/src/have.h index bb236622..96e35fd7 100644 --- a/src/have.h +++ b/src/have.h @@ -22,7 +22,8 @@ */ #ifdef HAVE_MINGW -#define WINVER WindowsXP +#define WINVER 0x0600 +#define _WIN32_WINNT 0x0600 #define WIN32_LEAN_AND_MEAN #endif diff --git a/src/info.c b/src/info.c index c324df94..25e6b60c 100644 --- a/src/info.c +++ b/src/info.c @@ -1,6 +1,6 @@ /* info.c -- Show information about a node, subnet or address - Copyright (C) 2012-2017 Guus Sliepen + Copyright (C) 2012-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,9 +20,10 @@ #include "system.h" #include "control_common.h" +#include "info.h" +#include "logger.h" #include "subnet.h" #include "tincctl.h" -#include "info.h" #include "utils.h" void logger(int level, int priority, const char *format, ...) { diff --git a/src/invitation.c b/src/invitation.c index f2f4d76c..e71a4889 100644 --- a/src/invitation.c +++ b/src/invitation.c @@ -1,6 +1,6 @@ /* invitation.c -- Create and accept invitations - Copyright (C) 2013-2017 Guus Sliepen + Copyright (C) 2013-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -97,7 +97,7 @@ static void scan_for_hostname(const char *filename, char **hostname, char **port fclose(f); } -char *get_my_hostname() { +static char *get_my_hostname(void) { char *hostname = NULL; char *port = NULL; char *hostport = NULL; @@ -545,14 +545,12 @@ int cmd_invite(int argc, char *argv[]) { } static int sock; -static char cookie[18]; +static char cookie[18], hash[18]; static sptps_t sptps; static char *data; static size_t datalen; static bool success = false; -static char cookie[18], hash[18]; - static char *get_line(const char **data) { if(!data || !*data) { return NULL; @@ -1087,7 +1085,7 @@ ask_netname: static bool invitation_send(void *handle, uint8_t type, const void *vdata, size_t len) { (void)handle; (void)type; - const uint8_t *data = vdata; + const char *data = vdata; while(len) { ssize_t result = send(sock, data, len, 0); @@ -1227,7 +1225,8 @@ int cmd_join(int argc, char *argv[]) { } if(!port || !*port) { - port = "655"; + static char default_port[] = "655"; + port = default_port; } if(!b64decode_tinc(slash, hash, 24) || !b64decode_tinc(slash + 24, cookie, 24)) { diff --git a/src/invitation.h b/src/invitation.h index 6517fe84..e176c4da 100644 --- a/src/invitation.h +++ b/src/invitation.h @@ -3,7 +3,7 @@ /* invitation.h -- header for invitation.c. - Copyright (C) 2013 Guus Sliepen + Copyright (C) 2013-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/logger.c b/src/logger.c index 1a2e95ff..caaf038d 100644 --- a/src/logger.c +++ b/src/logger.c @@ -1,6 +1,6 @@ /* logger.c -- logging code - Copyright (C) 2004-2017 Guus Sliepen + Copyright (C) 2004-2022 Guus Sliepen 2004-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -91,8 +91,11 @@ static void real_logger(debug_t level, int priority, const char *message) { } if(umbilical && do_detach) { - write(umbilical, message, strlen(message)); - write(umbilical, "\n", 1); + size_t len = strlen(message); + + if(write(umbilical, message, len) != (ssize_t)len || write(umbilical, "\n", 1) != 1) { + // Other end broken, nothing we can do about it. + } } } @@ -113,7 +116,7 @@ static void real_logger(debug_t level, int priority, const char *message) { size_t len = strlen(message); - if(send_request(c, "%d %d %zu", CONTROL, REQ_LOG, len)) { + if(send_request(c, "%d %d %lu", CONTROL, REQ_LOG, (unsigned long)len)) { send_meta(c, message, len); } } @@ -220,7 +223,7 @@ void openlogger(const char *ident, logmode_t mode) { } } -void reopenlogger() { +void reopenlogger(void) { if(logmode != LOGMODE_FILE) { return; } diff --git a/src/meta.c b/src/meta.c index f6a9ba18..6a217d61 100644 --- a/src/meta.c +++ b/src/meta.c @@ -56,8 +56,8 @@ bool send_meta(connection_t *c, const void *buffer, size_t length) { abort(); } - logger(DEBUG_META, LOG_DEBUG, "Sending %zu bytes of metadata to %s (%s)", - length, c->name, c->hostname); + logger(DEBUG_META, LOG_DEBUG, "Sending %lu bytes of metadata to %s (%s)", + (unsigned long)length, c->name, c->hostname); if(c->protocol_minor >= 2) { return sptps_send_record(&c->sptps, 0, buffer, length); @@ -100,8 +100,8 @@ void send_meta_raw(connection_t *c, const void *buffer, size_t length) { abort(); } - logger(DEBUG_META, LOG_DEBUG, "Sending %zu bytes of raw metadata to %s (%s)", - length, c->name, c->hostname); + logger(DEBUG_META, LOG_DEBUG, "Sending %lu bytes of raw metadata to %s (%s)", + (unsigned long)length, c->name, c->hostname); buffer_add(&c->outbuf, buffer, length); diff --git a/src/mingw/device.c b/src/mingw/device.c index b7a191f4..03a1d48c 100644 --- a/src/mingw/device.c +++ b/src/mingw/device.c @@ -1,7 +1,7 @@ /* device.c -- Interaction with Windows tap driver in a MinGW environment Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2018 Guus Sliepen + 2002-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -45,9 +45,7 @@ char *device = NULL; char *iface = NULL; static const char *device_info = "Windows tap device"; -extern char *myport; - -static void device_issue_read() { +static void device_issue_read(void) { int status; for(;;) { diff --git a/src/multicast_device.c b/src/multicast_device.c index 907eb100..79239a19 100644 --- a/src/multicast_device.c +++ b/src/multicast_device.c @@ -188,7 +188,7 @@ static bool read_packet(vpn_packet_t *packet) { } if(!memcmp(&ignore_src, DATA(packet) + 6, sizeof(ignore_src))) { - logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Ignoring loopback packet of %zd bytes from %s", lenin, device_info); + logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Ignoring loopback packet of %ld bytes from %s", (long)lenin, device_info); return false; } diff --git a/src/net_packet.c b/src/net_packet.c index 89172670..459b2413 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -1,7 +1,7 @@ /* net_packet.c -- Handles in- and outgoing VPN packets Copyright (C) 1998-2005 Ivo Timmermans, - 2000-2021 Guus Sliepen + 2000-2022 Guus Sliepen 2010 Timothy Redaelli 2010 Brandon Black @@ -992,8 +992,8 @@ bool send_sptps_data(node_t *to, node_t *from, int type, const void *data, size_ overhead += sizeof(to->id) + sizeof(from->id); } - uint8_t buf[len + overhead]; - uint8_t *buf_ptr = buf; + char buf[len + overhead]; + char *buf_ptr = buf; if(relay_supported) { if(direct) { @@ -1165,7 +1165,7 @@ static void send_udp_probe_packet(node_t *n, size_t len) { vpn_packet_t packet; if(len > sizeof(packet.data)) { - logger(DEBUG_TRAFFIC, LOG_INFO, "Truncating probe length %zu to %s (%s)", len, n->name, n->hostname); + logger(DEBUG_TRAFFIC, LOG_INFO, "Truncating probe length %lu to %s (%s)", (unsigned long)len, n->name, n->hostname); len = sizeof(packet.data); } @@ -1175,7 +1175,7 @@ static void send_udp_probe_packet(node_t *n, size_t len) { packet.len = len; packet.priority = 0; - logger(DEBUG_TRAFFIC, LOG_INFO, "Sending UDP probe length %zu to %s (%s)", len, n->name, n->hostname); + logger(DEBUG_TRAFFIC, LOG_INFO, "Sending UDP probe length %lu to %s (%s)", (unsigned long)len, n->name, n->hostname); send_udppacket(n, &packet); } @@ -1261,7 +1261,7 @@ static length_t choose_initial_maxmtu(node_t *n) { int ip_mtu; socklen_t ip_mtu_len = sizeof(ip_mtu); - if(getsockopt(sock, IPPROTO_IP, IP_MTU, &ip_mtu, &ip_mtu_len)) { + if(getsockopt(sock, IPPROTO_IP, IP_MTU, (void *)&ip_mtu, &ip_mtu_len)) { logger(DEBUG_TRAFFIC, LOG_ERR, "getsockopt(IP_MTU) on %s (%s) failed: %s", n->name, n->hostname, sockstrerror(sockerrno)); close(sock); return MTU; @@ -1424,7 +1424,7 @@ static void try_mtu(node_t *n) { on the precise MTU as we are approaching it. The last probe of the cycle is always 1 byte in size - this is to make sure we'll get at least one reply per cycle so that we can make progress. */ - offset = (length_t) powf(interval, multiplier * cycle_position / ((float) probes_per_cycle - 1.0f)); + offset = lrintf(powf(interval, multiplier * cycle_position / (float)(probes_per_cycle - 1))); } length_t maxmtu = n->maxmtu; diff --git a/src/node.c b/src/node.c index 7655cae9..fce1217e 100644 --- a/src/node.c +++ b/src/node.c @@ -202,12 +202,12 @@ bool dump_nodes(connection_t *c) { } id[sizeof(id) - 1] = 0; - send_request(c, "%d %d %s %s %s %d %d %zu %d %x %x %s %s %d %d %d %d %ld %d %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, CONTROL, REQ_DUMP_NODES, + send_request(c, "%d %d %s %s %s %d %d %lu %d %x %x %s %s %d %d %d %d %ld %d %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, CONTROL, REQ_DUMP_NODES, n->name, id, n->hostname ? n->hostname : "unknown port unknown", #ifdef DISABLE_LEGACY 0, 0, 0UL, #else - cipher_get_nid(n->outcipher), digest_get_nid(n->outdigest), digest_length(n->outdigest), + cipher_get_nid(n->outcipher), digest_get_nid(n->outdigest), (unsigned long)digest_length(n->outdigest), #endif n->outcompression, n->options, bitfield_to_int(&n->status, sizeof(n->status)), n->nexthop ? n->nexthop->name : "-", n->via && n->via->name ? n->via->name : "-", n->distance, diff --git a/src/node.h b/src/node.h index f312043d..d0700825 100644 --- a/src/node.h +++ b/src/node.h @@ -29,20 +29,19 @@ #include "subnet.h" typedef struct node_status_t { - bool unused_active: 1; /* 1 if active (not used for nodes) */ - bool validkey: 1; /* 1 if we currently have a valid key for him */ - bool waitingforkey: 1; /* 1 if we already sent out a request */ - bool visited: 1; /* 1 if this node has been visited by one of the graph algorithms */ - bool reachable: 1; /* 1 if this node is reachable in the graph */ - bool indirect: 1; /* 1 if this node is not directly reachable by us */ - bool sptps: 1; /* 1 if this node supports SPTPS */ - bool udp_confirmed: 1; /* 1 if the address is one that we received UDP traffic on */ - bool send_locally: 1; /* 1 if the next UDP packet should be sent on the local network */ - bool udppacket: 1; /* 1 if the most recently received packet was UDP */ - bool validkey_in: 1; /* 1 if we have sent a valid key to him */ - bool has_address: 1; /* 1 if we know an external address for this node */ - bool ping_sent: 1; /* 1 if we sent a UDP probe but haven't received the reply yet */ - uint32_t unused: 19; + uint32_t unused_active: 1; /* 1 if active (not used for nodes) */ + uint32_t validkey: 1; /* 1 if we currently have a valid key for him */ + uint32_t waitingforkey: 1; /* 1 if we already sent out a request */ + uint32_t visited: 1; /* 1 if this node has been visited by one of the graph algorithms */ + uint32_t reachable: 1; /* 1 if this node is reachable in the graph */ + uint32_t indirect: 1; /* 1 if this node is not directly reachable by us */ + uint32_t sptps: 1; /* 1 if this node supports SPTPS */ + uint32_t udp_confirmed: 1; /* 1 if the address is one that we received UDP traffic on */ + uint32_t send_locally: 1; /* 1 if the next UDP packet should be sent on the local network */ + uint32_t udppacket: 1; /* 1 if the most recently received packet was UDP */ + uint32_t validkey_in: 1; /* 1 if we have sent a valid key to him */ + uint32_t has_address: 1; /* 1 if we know an external address for this node */ + uint32_t ping_sent: 1; /* 1 if we sent a UDP probe but haven't received the reply yet */ } node_status_t; typedef struct node_t { diff --git a/src/nolegacy/crypto.c b/src/nolegacy/crypto.c index 424fac27..d9df8288 100644 --- a/src/nolegacy/crypto.c +++ b/src/nolegacy/crypto.c @@ -67,14 +67,14 @@ void randomize(void *vout, size_t outlen) { #include HCRYPTPROV prov; -void random_init(void) { +static void random_init(void) { if(!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { fprintf(stderr, "CryptAcquireContext() failed!\n"); abort(); } } -void random_exit(void) { +static void random_exit(void) { CryptReleaseContext(prov, 0); } diff --git a/src/openssl/cipher.c b/src/openssl/cipher.c index 08b81de7..6b2affc0 100644 --- a/src/openssl/cipher.c +++ b/src/openssl/cipher.c @@ -1,6 +1,6 @@ /* cipher.c -- Symmetric block cipher handling - Copyright (C) 2007-2017 Guus Sliepen + Copyright (C) 2007-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,6 +23,7 @@ #include #include +#include "cipher.h" #include "../cipher.h" #include "../logger.h" diff --git a/src/openssl/cipher.h b/src/openssl/cipher.h index 6f3e6b7b..360596c6 100644 --- a/src/openssl/cipher.h +++ b/src/openssl/cipher.h @@ -1,6 +1,25 @@ #ifndef TINC_OPENSSL_CIPHER_H #define TINC_OPENSSL_CIPHER_H +/* + cipher.h -- header file cipher.c + Copyright (C) 2007-2022 Guus Sliepen + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + #include struct cipher { diff --git a/src/openssl/crypto.c b/src/openssl/crypto.c index 7cfdbbaf..34009d69 100644 --- a/src/openssl/crypto.c +++ b/src/openssl/crypto.c @@ -70,14 +70,14 @@ void randomize(void *vout, size_t outlen) { #include HCRYPTPROV prov; -void random_init(void) { +static void random_init(void) { if(!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { fprintf(stderr, "CryptAcquireContext() failed!\n"); abort(); } } -void random_exit(void) { +static void random_exit(void) { CryptReleaseContext(prov, 0); } diff --git a/src/openssl/digest.h b/src/openssl/digest.h index 35153532..66d54164 100644 --- a/src/openssl/digest.h +++ b/src/openssl/digest.h @@ -3,7 +3,7 @@ /* digest.h -- header file digest.c - Copyright (C) 2013 Guus Sliepen + Copyright (C) 2013-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/openssl/rsa.c b/src/openssl/rsa.c index e7428add..d50ba1d7 100644 --- a/src/openssl/rsa.c +++ b/src/openssl/rsa.c @@ -1,6 +1,6 @@ /* rsa.c -- RSA key handling - Copyright (C) 2007-2021 Guus Sliepen + Copyright (C) 2007-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -31,7 +31,7 @@ typedef RSA rsa_t; // Set RSA keys -rsa_t *rsa_set_hex_public_key(char *n, char *e) { +rsa_t *rsa_set_hex_public_key(const char *n, const char *e) { BIGNUM *bn_n = NULL; BIGNUM *bn_e = NULL; @@ -52,7 +52,7 @@ rsa_t *rsa_set_hex_public_key(char *n, char *e) { return rsa; } -rsa_t *rsa_set_hex_private_key(char *n, char *e, char *d) { +rsa_t *rsa_set_hex_private_key(const char *n, const char *e, const char *d) { BIGNUM *bn_n = NULL; BIGNUM *bn_e = NULL; BIGNUM *bn_d = NULL; @@ -106,7 +106,7 @@ size_t rsa_size(const rsa_t *rsa) { return RSA_size(rsa); } -bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) { +bool rsa_public_encrypt(rsa_t *rsa, const void *in, size_t len, void *out) { if((size_t)RSA_public_encrypt((int) len, in, out, rsa, RSA_NO_PADDING) == len) { return true; } @@ -115,7 +115,7 @@ bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) { return false; } -bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) { +bool rsa_private_decrypt(rsa_t *rsa, const void *in, size_t len, void *out) { if((size_t)RSA_private_decrypt((int) len, in, out, rsa, RSA_NO_PADDING) == len) { return true; } diff --git a/src/openssl/rsagen.c b/src/openssl/rsagen.c index 277df231..ce0bd0bf 100644 --- a/src/openssl/rsagen.c +++ b/src/openssl/rsagen.c @@ -1,6 +1,6 @@ /* rsagen.c -- RSA key generation and export - Copyright (C) 2008-2013 Guus Sliepen + Copyright (C) 2008-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,6 +17,8 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include "system.h" + #include #include diff --git a/src/process.c b/src/process.c index f3e190c2..7d528f7e 100644 --- a/src/process.c +++ b/src/process.c @@ -46,7 +46,8 @@ static SERVICE_STATUS_HANDLE statushandle = 0; static bool install_service(void) { char command[4096] = "\""; - SERVICE_DESCRIPTION description = {"Virtual Private Network daemon"}; + char description_buffer[] = "Virtual Private Network daemon"; + SERVICE_DESCRIPTION description = {description_buffer}; manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); @@ -107,7 +108,7 @@ static bool install_service(void) { io_t stop_io; -DWORD WINAPI controlhandler(DWORD request, DWORD type, LPVOID data, LPVOID context) { +static DWORD WINAPI controlhandler(DWORD request, DWORD type, LPVOID data, LPVOID context) { (void)type; (void)data; (void)context; @@ -141,7 +142,7 @@ DWORD WINAPI controlhandler(DWORD request, DWORD type, LPVOID data, LPVOID conte return NO_ERROR; } -VOID WINAPI run_service(DWORD argc, LPTSTR *argv) { +static VOID WINAPI run_service(DWORD argc, LPTSTR *argv) { extern int main2(int argc, char **argv); status.dwServiceType = SERVICE_WIN32; diff --git a/src/protocol.c b/src/protocol.c index 8f0efb2a..3539ca7c 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -1,7 +1,7 @@ /* protocol.c -- handle the meta-protocol, basic functions Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2013 Guus Sliepen + 2000-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -49,7 +49,7 @@ static bool (*request_handlers[])(connection_t *, const char *) = { /* Request names */ -static char (*request_name[]) = { +static const char (*request_name[]) = { "ID", "METAKEY", "CHALLENGE", "CHAL_REPLY", "ACK", "STATUS", "ERROR", "TERMREQ", "PING", "PONG", diff --git a/src/protocol_auth.c b/src/protocol_auth.c index 12dc144a..02b7399c 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -1,7 +1,7 @@ /* protocol_auth.c -- handle the meta-protocol, authentication Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2017 Guus Sliepen + 2000-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -287,7 +287,12 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat // Read the new node's Name from the file char buf[1024] = ""; - fgets(buf, sizeof(buf), f); + + if(!fgets(buf, sizeof(buf), f)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not read invitation file %s\n", cookie); + return false; + } + size_t buflen = strlen(buf); // Strip whitespace at the end diff --git a/src/protocol_key.c b/src/protocol_key.c index c14dfcac..1d1bee15 100644 --- a/src/protocol_key.c +++ b/src/protocol_key.c @@ -383,11 +383,11 @@ bool send_ans_key(node_t *to) { to->status.validkey_in = true; - return send_request(to->nexthop->connection, "%d %s %s %s %d %d %zu %d", ANS_KEY, + return send_request(to->nexthop->connection, "%d %s %s %s %d %d %lu %d", ANS_KEY, myself->name, to->name, key, cipher_get_nid(to->incipher), digest_get_nid(to->indigest), - digest_length(to->indigest), + (unsigned long)digest_length(to->indigest), to->incompression); #endif } @@ -399,11 +399,11 @@ bool ans_key_h(connection_t *c, const char *request) { char address[MAX_STRING_SIZE] = ""; char port[MAX_STRING_SIZE] = ""; int cipher, digest; - size_t maclength; + unsigned long maclength; int compression; node_t *from, *to; - if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %zu %d "MAX_STRING" "MAX_STRING, + if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %lu %d "MAX_STRING" "MAX_STRING, from_name, to_name, key, &cipher, &digest, &maclength, &compression, address, port) < 7) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ANS_KEY", c->name, diff --git a/src/protocol_misc.c b/src/protocol_misc.c index 088a5242..cef7e3d0 100644 --- a/src/protocol_misc.c +++ b/src/protocol_misc.c @@ -1,7 +1,7 @@ /* protocol_misc.c -- handle the meta-protocol, miscellaneous functions Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2013 Guus Sliepen + 2000-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -75,8 +75,8 @@ bool pong_h(connection_t *c, const char *request) { } static bool random_early_drop(connection_t *c) { - if(c->outbuf.len > maxoutbufsize / 2) { - if((c->outbuf.len - maxoutbufsize / 2) > prng((maxoutbufsize) / 2)) { + if(c->outbuf.len > (size_t)maxoutbufsize / 2) { + if((c->outbuf.len - (size_t)maxoutbufsize / 2) > prng((size_t)maxoutbufsize / 2)) { return true; } } @@ -125,7 +125,7 @@ bool send_sptps_tcppacket(connection_t *c, const void *packet, size_t len) { return true; } - if(!send_request(c, "%d %zu", SPTPS_PACKET, len)) { + if(!send_request(c, "%d %lu", SPTPS_PACKET, (unsigned long)len)) { return false; } diff --git a/src/route.c b/src/route.c index 166b8b24..25f2be5e 100644 --- a/src/route.c +++ b/src/route.c @@ -585,7 +585,7 @@ static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t et todo = ntohs(ip.ip_len) - ip_size; if(ether_size + ip_size + todo != packet->len) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Length of packet (%d) doesn't match length in IPv4 header (%zu)", packet->len, ether_size + ip_size + todo); + logger(DEBUG_TRAFFIC, LOG_WARNING, "Length of packet (%d) doesn't match length in IPv4 header (%lu)", packet->len, (unsigned long)(ether_size + ip_size + todo)); return; } diff --git a/src/rsa.h b/src/rsa.h index 4410d5c2..f7e9dbfa 100644 --- a/src/rsa.h +++ b/src/rsa.h @@ -3,7 +3,7 @@ /* rsa.h -- RSA key handling - Copyright (C) 2007-2013 Guus Sliepen + Copyright (C) 2007-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -27,12 +27,12 @@ typedef struct rsa rsa_t; #endif extern void rsa_free(rsa_t *rsa); -extern rsa_t *rsa_set_hex_public_key(char *n, char *e) __attribute__((__malloc__)); -extern rsa_t *rsa_set_hex_private_key(char *n, char *e, char *d) __attribute__((__malloc__)); +extern rsa_t *rsa_set_hex_public_key(const char *n, const char *e) __attribute__((__malloc__)); +extern rsa_t *rsa_set_hex_private_key(const char *n, const char *e, const char *d) __attribute__((__malloc__)); extern rsa_t *rsa_read_pem_public_key(FILE *fp) __attribute__((__malloc__)); extern rsa_t *rsa_read_pem_private_key(FILE *fp) __attribute__((__malloc__)); extern size_t rsa_size(const rsa_t *rsa); -extern bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) __attribute__((__warn_unused_result__)); -extern bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) __attribute__((__warn_unused_result__)); +extern bool rsa_public_encrypt(rsa_t *rsa, const void *in, size_t len, void *out) __attribute__((__warn_unused_result__)); +extern bool rsa_private_decrypt(rsa_t *rsa, const void *in, size_t len, void *out) __attribute__((__warn_unused_result__)); #endif diff --git a/src/script.c b/src/script.c index 1336ff37..cb3d2934 100644 --- a/src/script.c +++ b/src/script.c @@ -1,7 +1,7 @@ /* script.c -- call an external script Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2018 Guus Sliepen + 2000-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -80,7 +80,12 @@ int environment_add(environment_t *env, const char *format, ...) { if(format) { va_list ap; va_start(ap, format); - vasprintf(&env->entries[env->n], format, ap); + + if(vasprintf(&env->entries[env->n], format, ap) == -1) { + // Assume we are out of memory. + abort(); + } + va_end(ap); } else { env->entries[env->n] = NULL; @@ -93,7 +98,11 @@ void environment_update(environment_t *env, int pos, const char *format, ...) { free(env->entries[pos]); va_list ap; va_start(ap, format); - vasprintf(&env->entries[pos], format, ap); + + if(vasprintf(&env->entries[pos], format, ap) == -1) { + abort(); + } + va_end(ap); } diff --git a/src/solaris/device.c b/src/solaris/device.c index a8ddd04f..98c63167 100644 --- a/src/solaris/device.c +++ b/src/solaris/device.c @@ -2,7 +2,7 @@ device.c -- Interaction with Solaris tun device Copyright (C) 2001-2005 Ivo Timmermans, 2002-2010 OpenVPN Technologies, Inc. - 2001-2014 Guus Sliepen + 2001-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -160,7 +160,8 @@ static bool setup_device(void) { { /* Remove muxes just in case they are left over from a crashed tincd */ - struct lifreq ifr = {}; + struct lifreq ifr; + memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.lifr_name, iface, sizeof(ifr.lifr_name)); if(ioctl(ip_fd, SIOCGLIFMUXID, &ifr) >= 0) { @@ -182,7 +183,8 @@ static bool setup_device(void) { int arp_fd = -1; if(device_type == DEVICE_TYPE_TAP) { - struct lifreq ifr = {}; + struct lifreq ifr; + memset(&ifr, 0, sizeof(ifr)); if(ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0) { logger(DEBUG_ALWAYS, LOG_ERR, "Could not set flags on %s %s!", device_info, device); @@ -263,7 +265,9 @@ static bool setup_device(void) { close(arp_fd); } - struct lifreq ifr = {}; + struct lifreq ifr; + + memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.lifr_name, iface, sizeof(ifr.lifr_name)); @@ -297,7 +301,8 @@ static bool setup_device(void) { static void close_device(void) { if(iface) { - struct lifreq ifr = {}; + struct lifreq ifr; + memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.lifr_name, iface, sizeof(ifr.lifr_name)); if(ioctl(ip_fd, SIOCGLIFMUXID, &ifr) >= 0) { diff --git a/src/sptps_keypair.c b/src/sptps_keypair.c index bf7de125..22433b93 100644 --- a/src/sptps_keypair.c +++ b/src/sptps_keypair.c @@ -1,6 +1,6 @@ /* sptps_test.c -- Simple Peer-to-Peer Security test program - Copyright (C) 2011-2013 Guus Sliepen , + Copyright (C) 2011-2022 Guus Sliepen , This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -39,7 +39,7 @@ void logger(debug_t level, int priority, const char *format, ...) { fputc('\n', stderr); } -static void usage() { +static void usage(void) { fprintf(stderr, "Usage: %s [options] private_key_file public_key_file\n\n", program_name); fprintf(stderr, "Valid options are:\n" " --help Display this help and exit.\n" diff --git a/src/sptps_speed.c b/src/sptps_speed.c index 8e6f5bed..cc05b865 100644 --- a/src/sptps_speed.c +++ b/src/sptps_speed.c @@ -1,6 +1,6 @@ /* sptps_speed.c -- SPTPS benchmark - Copyright (C) 2013-2014 Guus Sliepen + Copyright (C) 2013-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -26,14 +26,23 @@ #include "ecdh.h" #include "ecdsa.h" #include "ecdsagen.h" +#include "meta.h" +#include "protocol.h" #include "sptps.h" // Symbols necessary to link with logger.o -bool send_request(void *c, const char *msg, ...) { +bool send_request(struct connection_t *c, const char *msg, ...) { + (void)c; + (void)msg; return false; } -struct list_t *connection_list = NULL; -bool send_meta(void *c, const char *msg, int len) { + +list_t connection_list; + +bool send_meta(struct connection_t *c, const void *msg, size_t len) { + (void)c; + (void)msg; + (void)len; return false; } char *logfilename = NULL; @@ -41,12 +50,17 @@ bool do_detach = false; struct timeval now; static bool send_data(void *handle, uint8_t type, const void *data, size_t len) { + (void)type; int fd = *(int *)handle; send(fd, data, len, 0); return true; } static bool receive_record(void *handle, uint8_t type, const void *data, uint16_t len) { + (void)handle; + (void)type; + (void)data; + (void)len; return true; } @@ -73,7 +87,7 @@ double elapsed; double rate; unsigned int count; -static void clock_start() { +static void clock_start(void) { count = 0; clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); } @@ -165,7 +179,7 @@ int main(int argc, char *argv[]) { return 1; } - struct pollfd pfd[2] = {{fd[0], POLLIN}, {fd[1], POLLIN}}; + struct pollfd pfd[2] = {{fd[0], POLLIN, 0}, {fd[1], POLLIN, 0}}; fprintf(stderr, "SPTPS/TCP authenticate for %lg seconds: ", duration); diff --git a/src/sptps_test.c b/src/sptps_test.c index 2c013223..0f62af01 100644 --- a/src/sptps_test.c +++ b/src/sptps_test.c @@ -1,6 +1,6 @@ /* sptps_test.c -- Simple Peer-to-Peer Security test program - Copyright (C) 2011-2014 Guus Sliepen + Copyright (C) 2011-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -31,6 +31,8 @@ #include "crypto.h" #include "ecdsa.h" +#include "meta.h" +#include "protocol.h" #include "sptps.h" #include "utils.h" @@ -39,15 +41,15 @@ #endif // Symbols necessary to link with logger.o -bool send_request(void *c, const char *msg, ...) { +bool send_request(struct connection_t *c, const char *msg, ...) { (void)c; (void)msg; return false; } -struct list_t *connection_list = NULL; +list_t connection_list; -bool send_meta(void *c, const char *msg, int len) { +bool send_meta(struct connection_t *c, const void *msg, size_t len) { (void)c; (void)msg; (void)len; @@ -64,7 +66,7 @@ static bool readonly; static bool writeonly; static int in = 0; static int out = 1; -static int addressfamily = AF_UNSPEC; +int addressfamily = AF_UNSPEC; static bool send_data(void *handle, uint8_t type, const void *data, size_t len) { (void)type; @@ -72,13 +74,22 @@ static bool send_data(void *handle, uint8_t type, const void *data, size_t len) bin2hex(data, hex, len); if(verbose) { - fprintf(stderr, "Sending %zu bytes of data:\n%s\n", len, hex); + fprintf(stderr, "Sending %lu bytes of data:\n%s\n", (unsigned long)len, hex); } const int *sock = handle; + const char *p = data; - if((size_t)send(*sock, data, len, 0) != len) { - return false; + while(len) { + ssize_t sent = send(*sock, p, len, 0); + + if(sent <= 0) { + fprintf(stderr, "Error sending data: %s\n", strerror(errno)); + return false; + } + + p += sent; + len -= sent; } return true; @@ -91,8 +102,22 @@ static bool receive_record(void *handle, uint8_t type, const void *data, uint16_ fprintf(stderr, "Received type %d record of %u bytes:\n", type, len); } - if(!writeonly) { - write(out, data, len); + if(writeonly) { + return true; + } + + const char *p = data; + + while(len) { + ssize_t written = write(out, p, len); + + if(written <= 0) { + fprintf(stderr, "Error writing received data: %s\n", strerror(errno)); + return false; + } + + p += written; + len -= written; } return true; @@ -113,9 +138,11 @@ static struct option const long_options[] = { const char *program_name; -static void usage() { - fprintf(stderr, "Usage: %s [options] my_ed25519_key_file his_ed25519_key_file [host] port\n\n", program_name); - fprintf(stderr, "Valid options are:\n" +static void usage(void) { + static const char *message = + "Usage: %s [options] my_ed25519_key_file his_ed25519_key_file [host] port\n" + "\n" + "Valid options are:\n" " -d, --datagram Enable datagram mode.\n" " -q, --quit Quit when EOF occurs on stdin.\n" " -r, --readonly Only send data from the socket to stdout.\n" @@ -129,8 +156,10 @@ static void usage() { " -v, --verbose Display debug messages.\n" " -4 Use IPv4.\n" " -6 Use IPv6.\n" - "\n"); - fprintf(stderr, "Report bugs to tinc@tinc-vpn.org.\n"); + "\n" + "Report bugs to tinc@tinc-vpn.org.\n"; + + fprintf(stderr, message, program_name); } #ifdef HAVE_MINGW @@ -142,7 +171,7 @@ int stdin_sock_fd = -1; // separate thread between the stdin and the sptps loop way below. This thread // reads stdin and sends its content to the main thread through a TCP socket, // which can be properly select()'ed. -void *stdin_reader_thread(void *arg) { +static void *stdin_reader_thread(void *arg) { struct sockaddr_in sa; socklen_t sa_size = sizeof(sa); @@ -158,7 +187,7 @@ void *stdin_reader_thread(void *arg) { fprintf(stderr, "New connection received from :%d\n", ntohs(sa.sin_port)); } - uint8_t buf[1024]; + char buf[1024]; ssize_t nread; while((nread = read(STDIN_FILENO, buf, sizeof(buf))) > 0) { @@ -166,7 +195,7 @@ void *stdin_reader_thread(void *arg) { fprintf(stderr, "Read %lld bytes from input\n", nread); } - uint8_t *start = buf; + char *start = buf; ssize_t nleft = nread; while(nleft) { @@ -199,9 +228,10 @@ void *stdin_reader_thread(void *arg) { closesocket(stdin_sock_fd); stdin_sock_fd = -1; + return NULL; } -int start_input_reader() { +static int start_input_reader(void) { if(stdin_sock_fd != -1) { fprintf(stderr, "stdin thread can only be started once.\n"); return -1; @@ -473,7 +503,7 @@ int main(int argc, char *argv[]) { } else { fprintf(stderr, "Listening...\n"); - uint8_t buf[65536]; + char buf[65536]; struct sockaddr addr; socklen_t addrlen = sizeof(addr); @@ -643,10 +673,10 @@ int main(int argc, char *argv[]) { if(verbose) { char hex[len * 2 + 1]; bin2hex(buf, hex, len); - fprintf(stderr, "Received %zd bytes of data:\n%s\n", len, hex); + fprintf(stderr, "Received %ld bytes of data:\n%s\n", (long)len, hex); } - if(packetloss && prng(100) < packetloss) { + if(packetloss && (int)prng(100) < packetloss) { if(verbose) { fprintf(stderr, "Dropped.\n"); } diff --git a/src/subnet.c b/src/subnet.c index fe7d23ef..1ddf11e5 100644 --- a/src/subnet.c +++ b/src/subnet.c @@ -1,6 +1,6 @@ /* subnet.c -- handle subnet lookups and lists - Copyright (C) 2000-2017 Guus Sliepen , + Copyright (C) 2000-2022 Guus Sliepen , 2000-2005 Ivo Timmermans This program is free software; you can redistribute it and/or modify @@ -162,7 +162,7 @@ void subnet_cache_flush_tables(void) { hash_clear(mac_t, &mac_cache); } -void subnet_cache_flush(subnet_t *subnet) { +static void subnet_cache_flush(subnet_t *subnet) { switch(subnet->type) { case SUBNET_IPV4: if(subnet->net.ipv4.prefixlength == 32) { @@ -322,7 +322,7 @@ subnet_t *lookup_subnet_ipv6(const ipv6_t *address) { void subnet_update(node_t *owner, subnet_t *subnet, bool up) { char netstr[MAXNETSTR]; - char *name, *address, *port; + char *address, *port; char empty[] = ""; // Prepare environment variables to be passed to the script @@ -342,7 +342,7 @@ void subnet_update(node_t *owner, subnet_t *subnet, bool up) { int env_subnet = environment_add(&env, NULL); int env_weight = environment_add(&env, NULL); - name = up ? "subnet-up" : "subnet-down"; + const char *name = up ? "subnet-up" : "subnet-down"; if(!subnet) { for splay_each(subnet_t, subnet, &owner->subnet_tree) { diff --git a/src/tincctl.c b/src/tincctl.c index b6c4fc89..215d757c 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -1,6 +1,6 @@ /* tincctl.c -- Controlling a running tincd - Copyright (C) 2007-2021 Guus Sliepen + Copyright (C) 2007-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -72,7 +72,8 @@ bool force = false; bool tty = true; bool confbasegiven = false; char *scriptinterpreter = NULL; -char *scriptextension = ""; +static char defaultextension[] = ""; +char *scriptextension = defaultextension; static char *prompt; char *device = NULL; char *iface = NULL; @@ -90,88 +91,95 @@ static struct option const long_options[] = { }; static void version(void) { - printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE, - BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR); - printf("Features:" + static const char *message = + "%s version %s (built %s %s, protocol %d.%d)\n" + "Features:" #ifdef HAVE_READLINE - " readline" + " readline" #endif #ifdef HAVE_CURSES - " curses" + " curses" #endif #ifndef DISABLE_LEGACY - " legacy_protocol" + " legacy_protocol" #endif - "\n\n"); - printf("Copyright (C) 1998-2018 Ivo Timmermans, Guus Sliepen and others.\n" - "See the AUTHORS file for a complete list.\n\n" - "tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n" - "and you are welcome to redistribute it under certain conditions;\n" - "see the file COPYING for details.\n"); + "\n\n" + "Copyright (C) 1998-2018 Ivo Timmermans, Guus Sliepen and others.\n" + "See the AUTHORS file for a complete list.\n" + "\n" + "tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n" + "and you are welcome to redistribute it under certain conditions;\n" + "see the file COPYING for details.\n"; + + printf(message, PACKAGE, BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR); } static void usage(bool status) { if(status) { fprintf(stderr, "Try `%s --help\' for more information.\n", program_name); } else { - printf("Usage: %s [options] command\n\n", program_name); - printf("Valid options are:\n" - " -b, --batch Don't ask for anything (non-interactive mode).\n" - " -c, --config=DIR Read configuration options from DIR.\n" - " -n, --net=NETNAME Connect to net NETNAME.\n" - " --pidfile=FILENAME Read control cookie from FILENAME.\n" - " --force Force some commands to work despite warnings.\n" - " --help Display this help and exit.\n" - " --version Output version information and exit.\n" - "\n" - "Valid commands are:\n" - " init [name] Create initial configuration files.\n" - " get VARIABLE Print current value of VARIABLE\n" - " set VARIABLE VALUE Set VARIABLE to VALUE\n" - " add VARIABLE VALUE Add VARIABLE with the given VALUE\n" - " del VARIABLE [VALUE] Remove VARIABLE [only ones with watching VALUE]\n" - " start [tincd options] Start tincd.\n" - " stop Stop tincd.\n" - " restart [tincd options] Restart tincd.\n" - " reload Partially reload configuration of running tincd.\n" - " pid Show PID of currently running tincd.\n" + static const char *message = + "Usage: %s [options] command\n" + "\n" + "Valid options are:\n" + " -b, --batch Don't ask for anything (non-interactive mode).\n" + " -c, --config=DIR Read configuration options from DIR.\n" + " -n, --net=NETNAME Connect to net NETNAME.\n" + " --pidfile=FILENAME Read control cookie from FILENAME.\n" + " --force Force some commands to work despite warnings.\n" + " --help Display this help and exit.\n" + " --version Output version information and exit.\n" + "\n" + "Valid commands are:\n" + " init [name] Create initial configuration files.\n" + " get VARIABLE Print current value of VARIABLE\n" + " set VARIABLE VALUE Set VARIABLE to VALUE\n" + " add VARIABLE VALUE Add VARIABLE with the given VALUE\n" + " del VARIABLE [VALUE] Remove VARIABLE [only ones with watching VALUE]\n" + " start [tincd options] Start tincd.\n" + " stop Stop tincd.\n" + " restart [tincd options] Restart tincd.\n" + " reload Partially reload configuration of running tincd.\n" + " pid Show PID of currently running tincd.\n" #ifdef DISABLE_LEGACY - " generate-keys Generate a new Ed25519 public/private key pair.\n" + " generate-keys Generate a new Ed25519 public/private key pair.\n" #else - " generate-keys [bits] Generate new RSA and Ed25519 public/private key pairs.\n" - " generate-rsa-keys [bits] Generate a new RSA public/private key pair.\n" + " generate-keys [bits] Generate new RSA and Ed25519 public/private key pairs.\n" + " generate-rsa-keys [bits] Generate a new RSA public/private key pair.\n" #endif - " generate-ed25519-keys Generate a new Ed25519 public/private key pair.\n" - " dump Dump a list of one of the following things:\n" - " [reachable] nodes - all known nodes in the VPN\n" - " edges - all known connections in the VPN\n" - " subnets - all known subnets in the VPN\n" - " connections - all meta connections with ourself\n" - " [di]graph - graph of the VPN in dotty format\n" - " invitations - outstanding invitations\n" - " info NODE|SUBNET|ADDRESS Give information about a particular NODE, SUBNET or ADDRESS.\n" - " purge Purge unreachable nodes\n" - " debug N Set debug level\n" - " retry Retry all outgoing connections\n" - " disconnect NODE Close meta connection with NODE\n" + " generate-ed25519-keys Generate a new Ed25519 public/private key pair.\n" + " dump Dump a list of one of the following things:\n" + " [reachable] nodes - all known nodes in the VPN\n" + " edges - all known connections in the VPN\n" + " subnets - all known subnets in the VPN\n" + " connections - all meta connections with ourself\n" + " [di]graph - graph of the VPN in dotty format\n" + " invitations - outstanding invitations\n" + " info NODE|SUBNET|ADDRESS Give information about a particular NODE, SUBNET or ADDRESS.\n" + " purge Purge unreachable nodes\n" + " debug N Set debug level\n" + " retry Retry all outgoing connections\n" + " disconnect NODE Close meta connection with NODE\n" #ifdef HAVE_CURSES - " top Show real-time statistics\n" + " top Show real-time statistics\n" #endif - " pcap [snaplen] Dump traffic in pcap format [up to snaplen bytes per packet]\n" - " log [level] Dump log output [up to the specified level]\n" - " export Export host configuration of local node to standard output\n" - " export-all Export all host configuration files to standard output\n" - " import Import host configuration file(s) from standard input\n" - " exchange Same as export followed by import\n" - " exchange-all Same as export-all followed by import\n" - " invite NODE [...] Generate an invitation for NODE\n" - " join INVITATION Join a VPN using an INVITATION\n" - " network [NETNAME] List all known networks, or switch to the one named NETNAME.\n" - " fsck Check the configuration files for problems.\n" - " sign [FILE] Generate a signed version of a file.\n" - " verify NODE [FILE] Verify that a file was signed by the given NODE.\n" - "\n"); - printf("Report bugs to tinc@tinc-vpn.org.\n"); + " pcap [snaplen] Dump traffic in pcap format [up to snaplen bytes per packet]\n" + " log [level] Dump log output [up to the specified level]\n" + " export Export host configuration of local node to standard output\n" + " export-all Export all host configuration files to standard output\n" + " import Import host configuration file(s) from standard input\n" + " exchange Same as export followed by import\n" + " exchange-all Same as export-all followed by import\n" + " invite NODE [...] Generate an invitation for NODE\n" + " join INVITATION Join a VPN using an INVITATION\n" + " network [NETNAME] List all known networks, or switch to the one named NETNAME.\n" + " fsck Check the configuration files for problems.\n" + " sign [FILE] Generate a signed version of a file.\n" + " verify NODE [FILE] Verify that a file was signed by the given NODE.\n" + "\n" + "Report bugs to tinc@tinc-vpn.org.\n"; + + printf(message, program_name); } } @@ -282,8 +290,12 @@ ask_filename: if(filename[0] != '/') { #endif + /* The directory is a relative path or a filename. */ - getcwd(directory, sizeof(directory)); + if(!getcwd(directory, sizeof(directory))) { + fprintf(stderr, "Could not get current directory: %s\n", strerror(errno)); + return NULL; + } if((size_t)snprintf(buf2, sizeof(buf2), "%s" SLASH "%s", directory, filename) >= sizeof(buf2)) { fprintf(stderr, "Filename too long: %s" SLASH "%s\n", directory, filename); @@ -508,7 +520,7 @@ static bool recvdata(int fd, char *data, size_t len) { return true; } -bool sendline(int fd, char *format, ...) { +bool sendline(int fd, const char *format, ...) { static char buffer[4096]; char *p = buffer; ssize_t blen; @@ -578,8 +590,8 @@ static void pcap(int fd, FILE *out, uint32_t snaplen) { while(recvline(fd, line, sizeof(line))) { int code, req; - size_t len; - int n = sscanf(line, "%d %d %zd", &code, &req, &len); + unsigned long len; + int n = sscanf(line, "%d %d %lu", &code, &req, &len); gettimeofday(&tv, NULL); if(n != 3 || code != CONTROL || req != REQ_PCAP || len > sizeof(data)) { @@ -884,12 +896,10 @@ static int cmd_start(int argc, char *argv[]) { #endif - char *default_c = "tincd"; - if(slash++) { xasprintf(&c, "%.*stincd", (int)(slash - program_name), program_name); } else { - c = default_c; + c = xstrdup("tincd"); } int nargc = 0; @@ -921,10 +931,7 @@ static int cmd_start(int argc, char *argv[]) { int status = spawnvp(_P_WAIT, c, nargv); free(nargv); - - if(c != default_c) { - free(c); - } + free(c); if(status == -1) { fprintf(stderr, "Error starting %s: %s\n", c, strerror(errno)); @@ -938,11 +945,7 @@ static int cmd_start(int argc, char *argv[]) { if(socketpair(AF_UNIX, SOCK_STREAM, 0, pfd)) { fprintf(stderr, "Could not create umbilical socket: %s\n", strerror(errno)); free(nargv); - - if(c != default_c) { - free(c); - } - + free(c); return 1; } @@ -951,11 +954,7 @@ static int cmd_start(int argc, char *argv[]) { if(pid == -1) { fprintf(stderr, "Could not fork: %s\n", strerror(errno)); free(nargv); - - if(c != default_c) { - free(c); - } - + free(c); return 1; } @@ -988,7 +987,9 @@ static int cmd_start(int argc, char *argv[]) { len--; } - write(2, buf, len); + if(write(2, buf, len) != len) { + // Nothing we can do about it. + } } if(len) { @@ -1011,9 +1012,7 @@ static int cmd_start(int argc, char *argv[]) { fprintf(stderr, "Error starting %s\n", c); } - if(c != default_c) { - free(c); - } + free(c); return failed ? EXIT_FAILURE : EXIT_SUCCESS; #endif @@ -1244,7 +1243,8 @@ static int cmd_dump(int argc, char *argv[]) { char nexthop[4096]; int cipher, digest, maclength, compression, distance, socket, weight; short int pmtu, minmtu, maxmtu; - unsigned int options, status_int; + unsigned int options; + uint32_t status_int; node_status_t status; long int last_state_change; int udp_ping_rtt; @@ -1252,7 +1252,7 @@ static int cmd_dump(int argc, char *argv[]) { switch(req) { case REQ_DUMP_NODES: { - int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %d %d %d %d %x %x %4095s %4095s %d %hd %hd %hd %ld %d %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_int, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change, &udp_ping_rtt, &in_packets, &in_bytes, &out_packets, &out_bytes); + int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %d %d %d %d %x %"PRIx32" %4095s %4095s %d %hd %hd %hd %ld %d %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_int, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change, &udp_ping_rtt, &in_packets, &in_bytes, &out_packets, &out_bytes); if(n != 22) { fprintf(stderr, "Unable to parse node dump from tincd: %s\n", line); @@ -3158,6 +3158,7 @@ static int cmd_shell(int argc, char *argv[]) { #ifdef HAVE_READLINE rl_readline_name = "tinc"; + rl_basic_word_break_characters = "\t\n "; rl_completion_entry_function = complete_nothing; rl_attempted_completion_function = completion; rl_filename_completion_desired = 0; @@ -3170,7 +3171,6 @@ static int cmd_shell(int argc, char *argv[]) { if(tty) { free(copy); free(line); - rl_basic_word_break_characters = "\t\n "; line = readline(prompt); copy = line ? xstrdup(line) : NULL; } else { @@ -3261,7 +3261,7 @@ static int cmd_shell(int argc, char *argv[]) { return result; } -static void cleanup() { +static void cleanup(void) { free(tinc_conf); free(hosts_dir); free_names(); diff --git a/src/tincctl.h b/src/tincctl.h index d09013d8..4018bb32 100644 --- a/src/tincctl.h +++ b/src/tincctl.h @@ -3,7 +3,7 @@ /* tincctl.h -- header for tincctl.c. - Copyright (C) 2011-2016 Guus Sliepen + Copyright (C) 2011-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -49,10 +49,9 @@ extern const var_t variables[]; extern size_t rstrip(char *value); extern char *get_my_name(bool verbose); extern bool connect_tincd(bool verbose); -extern bool sendline(int fd, char *format, ...); +extern bool sendline(int fd, const char *format, ...); extern bool recvline(int fd, char *line, size_t len); extern int check_port(const char *name); -extern FILE *fopenmask(const char *filename, const char *mode, mode_t perms); extern ecdsa_t *get_pubkey(FILE *f); #endif diff --git a/src/tincd.c b/src/tincd.c index f9e31c19..022fb536 100644 --- a/src/tincd.c +++ b/src/tincd.c @@ -1,7 +1,7 @@ /* tincd.c -- the main file for tincd Copyright (C) 1998-2005 Ivo Timmermans - 2000-2021 Guus Sliepen + 2000-2022 Guus Sliepen 2008 Max Rijevski 2009 Michael Tokarev 2010 Julien Muchembled @@ -119,26 +119,31 @@ static void usage(bool status) { fprintf(stderr, "Try `%s --help\' for more information.\n", program_name); else { - printf("Usage: %s [option]...\n\n", program_name); - printf(" -c, --config=DIR Read configuration options from DIR.\n" - " -D, --no-detach Don't fork and detach.\n" - " -d, --debug[=LEVEL] Increase debug level or set it to LEVEL.\n" - " -n, --net=NETNAME Connect to net NETNAME.\n" + static const char *message = + "Usage: %s [option]...\n" + "\n" + " -c, --config=DIR Read configuration options from DIR.\n" + " -D, --no-detach Don't fork and detach.\n" + " -d, --debug[=LEVEL] Increase debug level or set it to LEVEL.\n" + " -n, --net=NETNAME Connect to net NETNAME.\n" #ifdef HAVE_MLOCKALL - " -L, --mlock Lock tinc into main memory.\n" + " -L, --mlock Lock tinc into main memory.\n" #endif - " --logfile[=FILENAME] Write log entries to a logfile.\n" - " -s --syslog Use syslog instead of stderr with --no-detach.\n" - " --pidfile=FILENAME Write PID and control socket cookie to FILENAME.\n" - " --bypass-security Disables meta protocol security, for debugging.\n" - " -o, --option[HOST.]KEY=VALUE Set global/host configuration value.\n" + " --logfile[=FILENAME] Write log entries to a logfile.\n" + " -s --syslog Use syslog instead of stderr with --no-detach.\n" + " --pidfile=FILENAME Write PID and control socket cookie to FILENAME.\n" + " --bypass-security Disables meta protocol security, for debugging.\n" + " -o, --option[HOST.]KEY=VALUE Set global/host configuration value.\n" #ifndef HAVE_MINGW - " -R, --chroot chroot to NET dir at startup.\n" - " -U, --user=USER setuid to given USER at startup.\n" + " -R, --chroot chroot to NET dir at startup.\n" + " -U, --user=USER setuid to given USER at startup.\n" #endif - " --help Display this help and exit.\n" - " --version Output version information and exit.\n\n"); - printf("Report bugs to tinc@tinc-vpn.org.\n"); + " --help Display this help and exit.\n" + " --version Output version information and exit.\n" + "\n" + "Report bugs to tinc@tinc-vpn.org.\n"; + + fprintf(stderr, message, program_name); } } @@ -378,7 +383,7 @@ static BOOL WINAPI console_ctrl_handler(DWORD type) { # define setpriority(level) (setpriority(PRIO_PROCESS, 0, (level))) #endif -static void cleanup() { +static void cleanup(void) { splay_empty_tree(&config_tree); list_empty_list(&cmdline_conf); free_names(); @@ -392,49 +397,51 @@ int main(int argc, char **argv) { } if(show_version) { - printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE, - BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR); - printf("Features:" + static const char *message = + "%s version %s (built %s %s, protocol %d.%d)\n" + "Features:" #ifdef HAVE_OPENSSL - " openssl" + " openssl" #endif #ifdef HAVE_LIBGCRYPT - " libgcrypt" + " libgcrypt" #endif #ifdef HAVE_LZO - " comp_lzo" + " comp_lzo" #endif #ifdef HAVE_ZLIB - " comp_zlib" + " comp_zlib" #endif #ifdef HAVE_LZ4 - " comp_lz4" + " comp_lz4" #endif #ifndef DISABLE_LEGACY - " legacy_protocol" + " legacy_protocol" #endif #ifdef ENABLE_JUMBOGRAMS - " jumbograms" + " jumbograms" #endif #ifdef ENABLE_TUNEMU - " tunemu" + " tunemu" #endif #ifdef HAVE_MINIUPNPC - " miniupnpc" + " miniupnpc" #endif #ifdef ENABLE_UML - " uml" + " uml" #endif #ifdef ENABLE_VDE - " vde" + " vde" #endif - "\n\n"); - printf("Copyright (C) 1998-2021 Ivo Timmermans, Guus Sliepen and others.\n" - "See the AUTHORS file for a complete list.\n\n" - "tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n" - "and you are welcome to redistribute it under certain conditions;\n" - "see the file COPYING for details.\n"); + "\n\n" + "Copyright (C) 1998-2021 Ivo Timmermans, Guus Sliepen and others.\n" + "See the AUTHORS file for a complete list.\n" + "\n" + "tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n" + "and you are welcome to redistribute it under certain conditions;\n" + "see the file COPYING for details.\n"; + printf(message, PACKAGE, BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR); return 0; } @@ -446,7 +453,10 @@ int main(int argc, char **argv) { make_names(true); atexit(cleanup); - chdir(confbase); + if(chdir(confbase) == -1) { + logger(DEBUG_ALWAYS, LOG_ERR, "Could not change to configuration directory: %s", strerror(errno)); + return 1; + } #ifdef HAVE_MINGW @@ -601,7 +611,10 @@ int main2(int argc, char **argv) { logger(DEBUG_ALWAYS, LOG_NOTICE, "Ready"); if(umbilical) { // snip! - write(umbilical, "", 1); + if(write(umbilical, "", 1) != 1) { + // Pipe full or broken, nothing we can do about it. + } + close(umbilical); umbilical = 0; } diff --git a/src/uml_device.c b/src/uml_device.c index 970e462a..f35ae0d2 100644 --- a/src/uml_device.c +++ b/src/uml_device.c @@ -1,7 +1,7 @@ /* device.c -- UML network socket Copyright (C) 2002-2005 Ivo Timmermans, - 2002-2017 Guus Sliepen + 2002-2022 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -163,7 +163,7 @@ static bool setup_device(void) { return true; } -void close_device(void) { +static void close_device(void) { if(listen_fd >= 0) { close(listen_fd); listen_fd = -1; @@ -249,7 +249,12 @@ static bool read_packet(vpn_packet_t *packet) { return false; } - write(request_fd, &data_sun, sizeof(data_sun)); + if(write(request_fd, &data_sun, sizeof(data_sun)) != sizeof(data_sun)) { + logger(DEBUG_ALWAYS, LOG_ERR, "Error while responding to request from %s %s: %s", device_info, device, strerror(errno)); + event_exit(); + return false; + } + device_fd = data_fd; logger(DEBUG_ALWAYS, LOG_INFO, "Connection with UML established"); diff --git a/src/upnp.c b/src/upnp.c index 93c207fa..eb68998b 100644 --- a/src/upnp.c +++ b/src/upnp.c @@ -1,6 +1,6 @@ /* upnp.c -- UPnP-IGD client - Copyright (C) 2015-2018 Guus Sliepen , + Copyright (C) 2015-2022 Guus Sliepen , This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,22 +17,20 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "upnp.h" +#include "system.h" -#ifndef HAVE_MINGW #include -#endif #include "miniupnpc/miniupnpc.h" #include "miniupnpc/upnpcommands.h" #include "miniupnpc/upnperrors.h" -#include "system.h" #include "logger.h" #include "names.h" #include "net.h" #include "netutl.h" #include "utils.h" +#include "upnp.h" static bool upnp_tcp; static bool upnp_udp; @@ -107,7 +105,7 @@ static void upnp_add_mapping(struct UPNPUrls *urls, struct IGDdatas *data, const free(port); } -static void upnp_refresh() { +static void upnp_refresh(void) { logger(DEBUG_PROTOCOL, LOG_INFO, "[upnp] Discovering IGD devices"); int error; @@ -180,20 +178,10 @@ void upnp_init(bool tcp, bool udp) { get_config_int(lookup_config(&config_tree, "UPnPDiscoverWait"), &upnp_discover_wait); get_config_int(lookup_config(&config_tree, "UPnPRefreshPeriod"), &upnp_refresh_period); -#ifdef HAVE_MINGW - HANDLE handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)upnp_thread, NULL, 0, NULL); - - if(!handle) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to start UPnP-IGD client thread"); - } - -#else pthread_t thread; int error = pthread_create(&thread, NULL, upnp_thread, NULL); if(error) { logger(DEBUG_ALWAYS, LOG_ERR, "Unable to start UPnP-IGD client thread: [%d] %s", error, strerror(error)); } - -#endif } diff --git a/src/xoshiro.c b/src/xoshiro.c index 469c74ab..481c2d52 100644 --- a/src/xoshiro.c +++ b/src/xoshiro.c @@ -6,7 +6,7 @@ worldwide. This software is distributed without any warranty. See . */ -#include +#include "system.h" #include "crypto.h"