cc_flags = [cc_defs]
ld_flags = []
+if cc_name != 'msvc'
+ cc_flags += [
+ '-Qunused-arguments',
+ '-Wbad-function-cast',
+ '-Wduplicated-branches',
+ '-Wduplicated-cond',
+ '-Wformat-overflow=2',
+ '-Wformat-truncation=1', # 2 prints too much noise
+ '-Wformat=2',
+ '-Wlogical-op',
+ '-Wmissing-declarations',
+ '-Wmissing-noreturn',
+ '-Wmissing-prototypes',
+ '-Wno-embedded-directive',
+ '-Wold-style-definition',
+ '-Wredundant-decls',
+ '-Wreturn-type',
+ '-Wstrict-prototypes',
+ '-Wswitch-enum',
+ '-Wtrampolines', # may require executable stack which is disabled
+ '-Wvla', # VLAs are not supported by MSVC
+ '-Wwrite-strings',
+ '-fdiagnostics-show-option',
+ '-fno-strict-overflow',
+ '-fstrict-aliasing',
+ ]
+endif
+
if opt_static.auto()
static = os_name == 'windows'
else
else
cc_flags += [
'-D_FORTIFY_SOURCE=2',
- '-fwrapv',
- '-fno-strict-overflow',
- '-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',
+ '-fcf-protection=full',
+ '-fstack-protector-strong',
]
- if cc_name == 'clang'
- cc_flags += '-Qunused-arguments'
- endif
- ld_flags += ['-Wl,-z,relro', '-Wl,-z,now']
+ ld_flags += ['-Wl,-z,relro', '-Wl,-z,now', '-Wl,-z,noexecstack']
if os_name == 'windows'
ld_flags += ['-Wl,--dynamicbase', '-Wl,--nxcompat']
+ else
+ # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90458
+ cc_flags += '-fstack-clash-protection'
endif
endif
endif
COMPRESS_LZO_HI = 11,
COMPRESS_LZ4 = 12,
-
- COMPRESS_GUARD = INT_MAX, /* ensure that sizeof(compression_level_t) == sizeof(int) */
} compression_level_t;
STATIC_ASSERT(sizeof(compression_level_t) == sizeof(int), "compression_level_t has invalid size");
goto again;
}
+static void print_tinc_cmd(const char *format, ...) ATTR_FORMAT(printf, 1, 2);
static void print_tinc_cmd(const char *format, ...) {
if(confbasegiven) {
fprintf(stderr, "%s -c %s ", exe_name, confbase);
bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) {
gcry_error_t err;
- uint8_t pad[cipher->blklen];
+ uint8_t *pad = alloca(cipher->blklen);
if(cipher->padding) {
if(!oneshot) {
memcpy(outdata, tmpdata, digest->maclength);
} else {
- char tmpdata[len];
+ char *tmpdata = alloca(len);
gcry_md_hash_buffer(digest->algo, tmpdata, indata, inlen);
memcpy(outdata, tmpdata, digest->maclength);
}
bool digest_verify(digest_t *digest, const void *indata, size_t inlen, const void *cmpdata) {
size_t len = digest->maclength;
- uint8_t outdata[len];
+ uint8_t *outdata = alloca(len);
return digest_create(digest, indata, inlen, outdata) && !memcmp(cmpdata, outdata, len);
}
return false;
}
- char b64[B64_SIZE(size)];
+ char *b64 = alloca(B64_SIZE(size));
const size_t b64len = b64encode(b64, buf, size);
for(size_t i = 0; i < b64len; i += 64) {
static const size_t blklen = 128;
static bool hmac_sha512(const uint8_t *key, size_t keylen, const uint8_t *msg, size_t msglen, uint8_t *out) {
- uint8_t tmp[blklen + mdlen];
+ const size_t tmplen = blklen + mdlen;
+ uint8_t *tmp = alloca(tmplen);
+
sha512_context md;
if(keylen <= blklen) {
// opad
memxor(tmp, 0x36 ^ 0x5c, blklen);
- if(sha512(tmp, sizeof(tmp), out) != 0) {
+ if(sha512(tmp, tmplen, out) != 0) {
return false;
}
It consists of the previous HMAC result plus the seed.
*/
- uint8_t data[mdlen + seedlen];
+ const size_t datalen = mdlen + seedlen;
+ uint8_t *data = alloca(datalen);
+
memset(data, 0, mdlen);
memcpy(data + mdlen, seed, seedlen);
- uint8_t hash[mdlen];
+ uint8_t *hash = alloca(mdlen);
while(outlen > 0) {
/* Inner HMAC */
- if(!hmac_sha512(secret, secretlen, data, sizeof(data), data)) {
+ if(!hmac_sha512(secret, secretlen, data, datalen, data)) {
return false;
}
/* Outer HMAC */
if(outlen >= mdlen) {
- if(!hmac_sha512(secret, secretlen, data, sizeof(data), out)) {
+ if(!hmac_sha512(secret, secretlen, data, datalen, out)) {
return false;
}
out += mdlen;
outlen -= mdlen;
} else {
- if(!hmac_sha512(secret, secretlen, data, sizeof(data), hash)) {
+ if(!hmac_sha512(secret, secretlen, data, datalen, hash)) {
return false;
}
return mpi ? !err : true;
}
+rsa_t *rsa_new(void) {
+ return xzalloc(sizeof(rsa_t));
+}
+
rsa_t *rsa_set_hex_public_key(const char *n, const char *e) {
- rsa_t *rsa = xzalloc(sizeof(rsa_t));
+ rsa_t *rsa = rsa_new();
gcry_error_t err = gcry_mpi_scan(&rsa->n, GCRYMPI_FMT_HEX, n, 0, NULL);
}
rsa_t *rsa_set_hex_private_key(const char *n, const char *e, const char *d) {
- rsa_t *rsa = xzalloc(sizeof(rsa_t));
+ rsa_t *rsa = rsa_new();
gcry_error_t err = gcry_mpi_scan(&rsa->n, GCRYMPI_FMT_HEX, n, 0, NULL);
return NULL;
}
- rsa_t *rsa = xzalloc(sizeof(rsa_t));
+ rsa_t *rsa = rsa_new();
if(!ber_skip_sequence(&derp, &derlen)
|| !ber_read_mpi(&derp, &derlen, &rsa->n)
return NULL;
}
- rsa_t *rsa = xzalloc(sizeof(rsa_t));
+ rsa_t *rsa = rsa_new();
if(!ber_skip_sequence(&derp, &derlen)
|| !ber_read_mpi(&derp, &derlen, NULL)
#include <gcrypt.h>
+#include "../rsa.h"
+#include "../xalloc.h"
+
#define TINC_RSA_INTERNAL
typedef struct rsa {
gcry_mpi_t n;
gcry_mpi_t d;
} rsa_t;
+extern rsa_t *rsa_new(void) ATTR_MALLOC ATTR_DEALLOCATOR(rsa_free);
+
#endif
return NULL;
}
- rsa_t *rsa = xzalloc(sizeof(*rsa));
+ rsa_t *rsa = rsa_new();
rsa->n = find_mpi(s_rsa, "n");
rsa->e = find_mpi(s_rsa, "e");
ipv6 = address;
break;
+ case SUBNET_MAC:
default:
return;
}
fprintf(out, "ip route add %s via %s dev \"$INTERFACE\" onlink\n", subnet_str, gateway_str);
break;
+ case SUBNET_MAC:
default:
return;
}
fprintf(out, "ip route add %s dev \"$INTERFACE\"\n", subnet_str);
break;
+ case SUBNET_MAC:
default:
return;
}
fprintf(out, "netsh interface ipv6 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str);
break;
+ case SUBNET_MAC:
default:
return;
}
fprintf(out, "netsh interface ipv6 add route %s \"%%INTERFACE%%\"\n", subnet_str);
break;
+ case SUBNET_MAC:
default:
return;
}
net2str(gateway_str, sizeof(gateway_str), &ipv6);
break;
+ case SUBNET_MAC:
default:
return;
}
fprintf(out, "route add -inet6 %s %s\n", subnet_str, gateway_str);
break;
+ case SUBNET_MAC:
default:
return;
}
real_logger(level, priority, message);
}
+static void sptps_logger(sptps_t *s, int s_errno, const char *format, va_list ap) ATTR_FORMAT(printf, 3, 0);
static void sptps_logger(sptps_t *s, int s_errno, const char *format, va_list ap) {
(void)s_errno;
char message[1024];
break;
+ case BMODE_NONE:
default:
break;
}
case PROXY_EXEC:
return true;
+ case PROXY_NONE:
default:
logger(DEBUG_ALWAYS, LOG_ERR, "Unknown proxy type");
return false;
char **entries;
} environment_t;
-extern int environment_add(environment_t *env, const char *format, ...);
-extern void environment_update(environment_t *env, int pos, const char *format, ...);
+extern int environment_add(environment_t *env, const char *format, ...) ATTR_FORMAT(printf, 2, 3);
+extern void environment_update(environment_t *env, int pos, const char *format, ...) ATTR_FORMAT(printf, 3, 4);
extern void environment_init(environment_t *env);
extern void environment_exit(environment_t *env);
void (*sptps_log)(sptps_t *s, int s_errno, const char *format, va_list ap) = sptps_log_stderr;
// Log an error message.
+static bool error(sptps_t *s, int s_errno, const char *format, ...) ATTR_FORMAT(printf, 3, 4);
static bool error(sptps_t *s, int s_errno, const char *format, ...) {
(void)s;
(void)s_errno;
return false;
}
+static void warning(sptps_t *s, const char *format, ...) ATTR_FORMAT(printf, 2, 3);
static void warning(sptps_t *s, const char *format, ...) {
va_list ap;
va_start(ap, format);
s->inbuf = realloc(s->inbuf, s->reclen + 19UL);
if(!s->inbuf) {
- return error(s, errno, strerror(errno));
+ return error(s, errno, "%s", strerror(errno));
}
// Exit early if we have no more data to process.
s->late = malloc(s->replaywin);
if(!s->late) {
- return error(s, errno, strerror(errno));
+ return error(s, errno, "%s", strerror(errno));
}
memset(s->late, 0, s->replaywin);
s->label = malloc(labellen);
if(!s->label) {
- return error(s, errno, strerror(errno));
+ return error(s, errno, "%s", strerror(errno));
}
if(!datagram) {
s->inbuf = malloc(7);
if(!s->inbuf) {
- return error(s, errno, strerror(errno));
+ return error(s, errno, "%s", strerror(errno));
}
s->buflen = 0;
} sptps_t;
extern unsigned int sptps_replaywin;
-extern void sptps_log_quiet(sptps_t *s, int s_errno, const char *format, va_list ap);
-extern void sptps_log_stderr(sptps_t *s, int s_errno, const char *format, va_list ap);
-extern void (*sptps_log)(sptps_t *s, int s_errno, const char *format, va_list ap);
+extern void sptps_log_quiet(sptps_t *s, int s_errno, const char *format, va_list ap) ATTR_FORMAT(printf, 3, 0);
+extern void sptps_log_stderr(sptps_t *s, int s_errno, const char *format, va_list ap) ATTR_FORMAT(printf, 3, 0);
+extern void (*sptps_log)(sptps_t *s, int s_errno, const char *format, va_list ap) ATTR_FORMAT(printf, 3, 0);
extern bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_t *mykey, ecdsa_t *hiskey, const void *label, size_t labellen, send_data_t send_data, receive_record_t receive_record);
extern bool sptps_stop(sptps_t *s);
extern bool sptps_send_record(sptps_t *s, uint8_t type, const void *data, uint16_t len);
};
static void usage(void) {
- static const char *message =
+ fprintf(stderr,
"Usage: %s [options] my_ed25519_key_file his_ed25519_key_file [host] port\n"
"\n"
"Valid options are:\n"
" -4 Use IPv4.\n"
" -6 Use IPv6.\n"
"\n"
- "Report bugs to tinc@tinc-vpn.org.\n";
-
- fprintf(stderr, message, program_name);
+ "Report bugs to tinc@tinc-vpn.org.\n",
+ program_name);
}
#ifdef HAVE_WINDOWS
};
static void version(void) {
- static const char *message =
+ fprintf(stdout,
"%s version %s (built %s %s, protocol %d.%d)\n"
"Features:"
#ifdef HAVE_READLINE
"\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);
+ "see the file COPYING for details.\n",
+ 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 {
- static const char *message =
+ fprintf(stdout,
"Usage: %s [options] command\n"
"\n"
"Valid options are:\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);
+ "Report bugs to tinc@tinc-vpn.org.\n",
+ program_name);
}
}
extern size_t rstrip(char *value);
extern char *get_my_name(bool verbose) ATTR_MALLOC;
extern bool connect_tincd(bool verbose);
-extern bool sendline(int fd, const char *format, ...);
+extern bool sendline(int fd, const char *format, ...) ATTR_FORMAT(printf, 2, 3);
extern bool recvline(int fd, char *line, size_t len);
extern int check_port(const char *name);
fprintf(stderr, "Try `%s --help\' for more information.\n",
program_name);
else {
- static const char *message =
+ fprintf(stdout,
"Usage: %s [option]...\n"
"\n"
" -c, --config=DIR Read configuration options from DIR.\n"
" --help Display this help and exit.\n"
" --version Output version information and exit.\n"
"\n"
- "Report bugs to tinc@tinc-vpn.org.\n";
-
- printf(message, program_name);
+ "Report bugs to tinc@tinc-vpn.org.\n",
+ program_name);
}
}
}
if(show_version) {
- static const char *message =
+ fprintf(stdout,
"%s version %s (built %s %s, protocol %d.%d)\n"
"Features:"
#ifdef HAVE_OPENSSL
"\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);
+ "see the file COPYING for details.\n",
+ PACKAGE, BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR);
return 0;
}
return p;
}
+static inline int xvasprintf(char **strp, const char *fmt, va_list ap) ATTR_FORMAT(printf, 2, 0);
static inline int xvasprintf(char **strp, const char *fmt, va_list ap) {
#ifdef HAVE_WINDOWS
char buf[1024];