Import Upstream version 1.0.21

This commit is contained in:
Guus Sliepen 2019-08-26 13:44:43 +02:00
parent d131e9a06f
commit 37abcfc1ea
38 changed files with 2387 additions and 11248 deletions

View file

@ -1,4 +1,4 @@
# Makefile.in generated by automake 1.11.5 from Makefile.am.
# Makefile.in generated by automake 1.11.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,

View file

@ -29,17 +29,22 @@
#include "utils.h"
#include "xalloc.h"
#ifdef HAVE_TUNEMU
#ifdef ENABLE_TUNEMU
#include "bsd/tunemu.h"
#endif
#define DEFAULT_DEVICE "/dev/tun0"
#define DEFAULT_TUN_DEVICE "/dev/tun0"
#if defined(HAVE_FREEBSD) || defined(HAVE_NETBSD)
#define DEFAULT_TAP_DEVICE "/dev/tap0"
#else
#define DEFAULT_TAP_DEVICE "/dev/tun0"
#endif
typedef enum device_type {
DEVICE_TYPE_TUN,
DEVICE_TYPE_TUNIFHEAD,
DEVICE_TYPE_TAP,
#ifdef HAVE_TUNEMU
#ifdef ENABLE_TUNEMU
DEVICE_TYPE_TUNEMU,
#endif
} device_type_t;
@ -50,7 +55,7 @@ char *iface = NULL;
static char *device_info = NULL;
static uint64_t device_total_in = 0;
static uint64_t device_total_out = 0;
#if defined(TUNEMU)
#if defined(ENABLE_TUNEMU)
static device_type_t device_type = DEVICE_TYPE_TUNEMU;
#elif defined(HAVE_OPENBSD) || defined(HAVE_FREEBSD) || defined(HAVE_DRAGONFLY)
static device_type_t device_type = DEVICE_TYPE_TUNIFHEAD;
@ -61,8 +66,12 @@ static device_type_t device_type = DEVICE_TYPE_TUN;
static bool setup_device(void) {
char *type;
if(!get_config_string(lookup_config(config_tree, "Device"), &device))
device = xstrdup(DEFAULT_DEVICE);
if(!get_config_string(lookup_config(config_tree, "Device"), &device)) {
if(routing_mode == RMODE_ROUTER)
device = xstrdup(DEFAULT_TUN_DEVICE);
else
device = xstrdup(DEFAULT_TAP_DEVICE);
}
if(!get_config_string(lookup_config(config_tree, "Interface"), &iface))
iface = xstrdup(strrchr(device, '/') ? strrchr(device, '/') + 1 : device);
@ -70,7 +79,7 @@ static bool setup_device(void) {
if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) {
if(!strcasecmp(type, "tun"))
/* use default */;
#ifdef HAVE_TUNEMU
#ifdef ENABLE_TUNEMU
else if(!strcasecmp(type, "tunemu"))
device_type = DEVICE_TYPE_TUNEMU;
#endif
@ -90,7 +99,7 @@ static bool setup_device(void) {
}
switch(device_type) {
#ifdef HAVE_TUNEMU
#ifdef ENABLE_TUNEMU
case DEVICE_TYPE_TUNEMU: {
char dynamic_name[256] = "";
device_fd = tunemu_open(dynamic_name);
@ -167,7 +176,7 @@ static bool setup_device(void) {
#endif
break;
#ifdef HAVE_TUNEMU
#ifdef ENABLE_TUNEMU
case DEVICE_TYPE_TUNEMU:
device_info = "BSD tunemu device";
break;
@ -181,7 +190,7 @@ static bool setup_device(void) {
static void close_device(void) {
switch(device_type) {
#ifdef HAVE_TUNEMU
#ifdef ENABLE_TUNEMU
case DEVICE_TYPE_TUNEMU:
tunemu_close(device_fd);
break;
@ -199,7 +208,7 @@ static bool read_packet(vpn_packet_t *packet) {
switch(device_type) {
case DEVICE_TYPE_TUN:
#ifdef HAVE_TUNEMU
#ifdef ENABLE_TUNEMU
case DEVICE_TYPE_TUNEMU:
if(device_type == DEVICE_TYPE_TUNEMU)
lenin = tunemu_read(device_fd, packet->data + 14, MTU - 14);
@ -229,6 +238,7 @@ static bool read_packet(vpn_packet_t *packet) {
return false;
}
memset(packet->data, 0, 12);
packet->len = lenin + 14;
break;
@ -260,6 +270,7 @@ static bool read_packet(vpn_packet_t *packet) {
return false;
}
memset(packet->data, 0, 12);
packet->len = lenin + 10;
break;
}
@ -336,7 +347,7 @@ static bool write_packet(vpn_packet_t *packet) {
}
break;
#ifdef HAVE_TUNEMU
#ifdef ENABLE_TUNEMU
case DEVICE_TYPE_TUNEMU:
if(tunemu_write(device_fd, packet->data + 14, packet->len - 14) < 0) {
logger(LOG_ERR, "Error while writing to %s %s: %s", device_info,

View file

@ -73,6 +73,15 @@ void free_connection_partially(connection_t *c) {
c->hischallenge = NULL;
c->outbuf = NULL;
c->status.pinged = false;
c->status.active = false;
c->status.connecting = false;
c->status.timeout = false;
c->status.encryptout = false;
c->status.decryptin = false;
c->status.mst = false;
c->options = 0;
c->buflen = 0;
c->reqlen = 0;
c->tcplen = 0;
@ -80,6 +89,8 @@ void free_connection_partially(connection_t *c) {
c->outbuflen = 0;
c->outbufsize = 0;
c->outbufstart = 0;
c->last_ping_time = 0;
c->last_flushed_time = 0;
if(c->inctx) {
EVP_CIPHER_CTX_cleanup(c->inctx);

View file

@ -35,7 +35,7 @@ typedef struct connection_status_t {
unsigned int pinged:1; /* sent ping */
unsigned int active:1; /* 1 if active.. */
unsigned int connecting:1; /* 1 if we are waiting for a non-blocking connect() to finish */
unsigned int termreq:1; /* the termination of this connection was requested */
unsigned int unused_termreq:1; /* the termination of this connection was requested */
unsigned int remove:1; /* Set to 1 if you want this connection removed */
unsigned int timeout:1; /* 1 if gotten timeout */
unsigned int encryptout:1; /* 1 if we can encrypt outgoing traffic */

View file

@ -1,6 +1,6 @@
/*
graph.c -- graph algorithms
Copyright (C) 2001-2012 Guus Sliepen <guus@tinc-vpn.org>,
Copyright (C) 2001-2013 Guus Sliepen <guus@tinc-vpn.org>,
2001-2005 Ivo Timmermans
This program is free software; you can redistribute it and/or modify
@ -287,10 +287,13 @@ static void sssp_bfs(void) {
subnet_update(n, NULL, n->status.reachable);
if(!n->status.reachable)
if(!n->status.reachable) {
update_node_udp(n, NULL);
else if(n->connection)
memset(&n->status, 0, sizeof n->status);
n->options = 0;
} else if(n->connection) {
send_ans_key(n);
}
}
}
}
@ -315,7 +318,7 @@ void dump_graph(void) {
node_t *n;
edge_t *e;
char *filename = NULL, *tmpname = NULL;
FILE *file;
FILE *file, *pipe = NULL;
if(!graph_changed || !get_config_string(lookup_config(config_tree, "GraphDumpFile"), &filename))
return;
@ -325,7 +328,7 @@ void dump_graph(void) {
ifdebug(PROTOCOL) logger(LOG_NOTICE, "Dumping graph");
if(filename[0] == '|') {
file = popen(filename + 1, "w");
file = pipe = popen(filename + 1, "w");
} else {
xasprintf(&tmpname, "%s.new", filename);
file = fopen(tmpname, "w");
@ -353,8 +356,8 @@ void dump_graph(void) {
fprintf(file, "}\n");
if(filename[0] == '|') {
pclose(file);
if(pipe) {
pclose(pipe);
} else {
fclose(file);
#ifdef HAVE_MINGW

View file

@ -155,6 +155,7 @@ static bool read_packet(vpn_packet_t *packet) {
return false;
}
memset(packet->data, 0, 12);
packet->len = lenin + 10;
break;
case DEVICE_TYPE_TAP:

View file

@ -1,6 +1,6 @@
/*
meta.c -- handle the meta communication
Copyright (C) 2000-2009 Guus Sliepen <guus@tinc-vpn.org>,
Copyright (C) 2000-2013 Guus Sliepen <guus@tinc-vpn.org>,
2000-2005 Ivo Timmermans
2006 Scott Lamb <slamb@slamb.org>
@ -177,15 +177,45 @@ bool receive_meta(connection_t *c) {
if(c->tcplen) {
if(c->tcplen <= c->buflen) {
if(proxytype == PROXY_SOCKS4 && c->allow_request == ID) {
if(c->buffer[0] == 0 && c->buffer[1] == 0x5a) {
logger(LOG_DEBUG, "Proxy request granted");
if(!c->node) {
if(c->outgoing && proxytype == PROXY_SOCKS4 && c->allow_request == ID) {
if(c->buffer[0] == 0 && c->buffer[1] == 0x5a) {
logger(LOG_DEBUG, "Proxy request granted");
} else {
logger(LOG_ERR, "Proxy request rejected");
return false;
}
} else if(c->outgoing && proxytype == PROXY_SOCKS5 && c->allow_request == ID) {
if(c->buffer[0] != 5) {
logger(LOG_ERR, "Invalid response from proxy server");
return false;
}
if(c->buffer[1] == (char)0xff) {
logger(LOG_ERR, "Proxy request rejected: unsuitable authentication method");
return false;
}
if(c->buffer[2] != 5) {
logger(LOG_ERR, "Invalid response from proxy server");
return false;
}
if(c->buffer[3] == 0) {
logger(LOG_DEBUG, "Proxy request granted");
} else {
logger(LOG_DEBUG, "Proxy request rejected");
return false;
}
} else {
logger(LOG_ERR, "Proxy request rejected");
logger(LOG_ERR, "c->tcplen set but c->node is NULL!");
abort();
}
} else {
if(c->allow_request == ALL) {
receive_tcppacket(c, c->buffer, c->tcplen);
} else {
logger(LOG_ERR, "Got unauthorized TCP packet from %s (%s)", c->name, c->hostname);
return false;
}
} else
receive_tcppacket(c, c->buffer, c->tcplen);
}
c->buflen -= c->tcplen;
lenin -= c->tcplen - oldlen;

View file

@ -1,7 +1,7 @@
/*
device.c -- Interaction with Windows tap driver in a MinGW environment
Copyright (C) 2002-2005 Ivo Timmermans,
2002-2011 Guus Sliepen <guus@tinc-vpn.org>
2002-2013 Guus Sliepen <guus@tinc-vpn.org>
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
@ -46,7 +46,7 @@ extern char *myport;
static DWORD WINAPI tapreader(void *bla) {
int status;
long len;
DWORD len;
OVERLAPPED overlapped;
vpn_packet_t packet;
@ -91,7 +91,7 @@ static bool setup_device(void) {
char adapterid[1024];
char adaptername[1024];
char tapname[1024];
long len;
DWORD len;
unsigned long status;
bool found = false;
@ -122,7 +122,7 @@ static bool setup_device(void) {
continue;
len = sizeof(adaptername);
err = RegQueryValueEx(key2, "Name", 0, 0, adaptername, &len);
err = RegQueryValueEx(key2, "Name", 0, 0, (LPBYTE)adaptername, &len);
RegCloseKey(key2);
@ -222,7 +222,7 @@ static bool read_packet(vpn_packet_t *packet) {
}
static bool write_packet(vpn_packet_t *packet) {
long lenout;
DWORD lenout;
OVERLAPPED overlapped = {0};
ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s",

View file

@ -1,7 +1,7 @@
/*
device.c -- multicast socket
Copyright (C) 2002-2005 Ivo Timmermans,
2002-2012 Guus Sliepen <guus@tinc-vpn.org>
2002-2013 Guus Sliepen <guus@tinc-vpn.org>
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
@ -158,7 +158,7 @@ static void close_device(void) {
static bool read_packet(vpn_packet_t *packet) {
int lenin;
if((lenin = recv(device_fd, packet->data, MTU, 0)) <= 0) {
if((lenin = recv(device_fd, (void *)packet->data, MTU, 0)) <= 0) {
logger(LOG_ERR, "Error while reading from %s %s: %s", device_info,
device, strerror(errno));
return false;
@ -184,7 +184,7 @@ static bool write_packet(vpn_packet_t *packet) {
ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s",
packet->len, device_info);
if(sendto(device_fd, packet->data, packet->len, 0, ai->ai_addr, ai->ai_addrlen) < 0) {
if(sendto(device_fd, (void *)packet->data, packet->len, 0, ai->ai_addr, ai->ai_addrlen) < 0) {
logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device,
strerror(errno));
return false;

View file

@ -1,7 +1,7 @@
/*
net_packet.c -- Handles in- and outgoing VPN packets
Copyright (C) 1998-2005 Ivo Timmermans,
2000-2012 Guus Sliepen <guus@tinc-vpn.org>
2000-2013 Guus Sliepen <guus@tinc-vpn.org>
2010 Timothy Redaelli <timothy@redaelli.eu>
2010 Brandon Black <blblack@gmail.com>
@ -70,11 +70,15 @@ bool localdiscovery = false;
mtuprobes == 32: send 1 burst, sleep pingtimeout second
mtuprobes == 33: no response from other side, restart PMTU discovery process
Probes are sent in batches of three, with random sizes between the lower and
upper boundaries for the MTU thus far discovered.
Probes are sent in batches of at least three, with random sizes between the
lower and upper boundaries for the MTU thus far discovered.
In case local discovery is enabled, a fourth packet is added to each batch,
After the initial discovery, a fourth packet is added to each batch with a
size larger than the currently known PMTU, to test if the PMTU has increased.
In case local discovery is enabled, another packet is added to each batch,
which will be broadcast to the local network.
*/
void send_mtu_probe(node_t *n) {
@ -126,11 +130,16 @@ void send_mtu_probe(node_t *n) {
timeout = pingtimeout;
}
for(i = 0; i < 3 + localdiscovery; i++) {
if(n->maxmtu <= n->minmtu)
for(i = 0; i < 4 + localdiscovery; i++) {
if(i == 0) {
if(n->mtuprobes < 30 || n->maxmtu + 8 >= MTU)
continue;
len = n->maxmtu + 8;
} else if(n->maxmtu <= n->minmtu) {
len = n->maxmtu;
else
} else {
len = n->minmtu + 1 + rand() % (n->maxmtu - n->minmtu);
}
if(len < 64)
len = 64;
@ -138,7 +147,7 @@ void send_mtu_probe(node_t *n) {
memset(packet.data, 0, 14);
RAND_pseudo_bytes(packet.data + 14, len - 14);
packet.len = len;
if(i >= 3 && n->mtuprobes <= 10)
if(i >= 4 && n->mtuprobes <= 10)
packet.priority = -1;
else
packet.priority = 0;
@ -164,6 +173,13 @@ void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) {
send_udppacket(n, packet);
} else {
if(n->mtuprobes > 30) {
if (len == n->maxmtu + 8) {
ifdebug(TRAFFIC) logger(LOG_INFO, "Increase in PMTU to %s (%s) detected, restarting PMTU discovery", n->name, n->hostname);
n->maxmtu = MTU;
n->mtuprobes = 10;
return;
}
if(n->minmtu)
n->mtuprobes = 30;
else
@ -378,6 +394,9 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) {
void receive_tcppacket(connection_t *c, const char *buffer, int len) {
vpn_packet_t outpkt;
if(len > sizeof outpkt.data)
return;
outpkt.len = len;
if(c->options & OPTION_TCPONLY)
outpkt.priority = 0;
@ -500,17 +519,27 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
struct sockaddr *sa;
socklen_t sl;
int sock;
sockaddr_t broadcast;
/* Overloaded use of priority field: -1 means local broadcast */
if(origpriority == -1 && n->prevedge) {
struct sockaddr_in in;
in.sin_family = AF_INET;
in.sin_addr.s_addr = -1;
in.sin_port = n->prevedge->address.in.sin_port;
sa = (struct sockaddr *)&in;
sl = sizeof in;
sock = 0;
sock = rand() % listen_sockets;
memset(&broadcast, 0, sizeof broadcast);
if(listen_socket[sock].sa.sa.sa_family == AF_INET6) {
broadcast.in6.sin6_family = AF_INET6;
broadcast.in6.sin6_addr.s6_addr[0x0] = 0xff;
broadcast.in6.sin6_addr.s6_addr[0x1] = 0x02;
broadcast.in6.sin6_addr.s6_addr[0xf] = 0x01;
broadcast.in6.sin6_port = n->prevedge->address.in.sin_port;
broadcast.in6.sin6_scope_id = listen_socket[sock].sa.in6.sin6_scope_id;
} else {
broadcast.in.sin_family = AF_INET;
broadcast.in.sin_addr.s_addr = -1;
broadcast.in.sin_port = n->prevedge->address.in.sin_port;
}
sa = &broadcast.sa;
sl = SALEN(broadcast.sa);
} else {
if(origpriority == -1)
origpriority = 0;

View file

@ -1,7 +1,7 @@
/*
net_setup.c -- Setup.
Copyright (C) 1998-2005 Ivo Timmermans,
2000-2012 Guus Sliepen <guus@tinc-vpn.org>
2000-2013 Guus Sliepen <guus@tinc-vpn.org>
2006 Scott Lamb <slamb@slamb.org>
2010 Brandon Black <blblack@gmail.com>
@ -55,7 +55,8 @@ proxytype_t proxytype;
bool read_rsa_public_key(connection_t *c) {
FILE *fp;
char *fname;
char *pubname;
char *hcfname;
char *key;
if(!c->rsa_key) {
@ -66,7 +67,10 @@ bool read_rsa_public_key(connection_t *c) {
/* First, check for simple PublicKey statement */
if(get_config_string(lookup_config(c->config_tree, "PublicKey"), &key)) {
BN_hex2bn(&c->rsa_key->n, key);
if(BN_hex2bn(&c->rsa_key->n, key) != strlen(key)) {
logger(LOG_ERR, "Invalid PublicKey for %s!", c->name);
return false;
}
BN_hex2bn(&c->rsa_key->e, "FFFF");
free(key);
return true;
@ -74,80 +78,79 @@ bool read_rsa_public_key(connection_t *c) {
/* Else, check for PublicKeyFile statement and read it */
if(get_config_string(lookup_config(c->config_tree, "PublicKeyFile"), &fname)) {
fp = fopen(fname, "r");
if(get_config_string(lookup_config(c->config_tree, "PublicKeyFile"), &pubname)) {
fp = fopen(pubname, "r");
if(!fp) {
logger(LOG_ERR, "Error reading RSA public key file `%s': %s",
fname, strerror(errno));
free(fname);
logger(LOG_ERR, "Error reading RSA public key file `%s': %s", pubname, strerror(errno));
free(pubname);
return false;
}
free(fname);
c->rsa_key = PEM_read_RSAPublicKey(fp, &c->rsa_key, NULL, NULL);
fclose(fp);
if(c->rsa_key)
if(c->rsa_key) {
free(pubname);
return true; /* Woohoo. */
}
/* If it fails, try PEM_read_RSA_PUBKEY. */
fp = fopen(fname, "r");
fp = fopen(pubname, "r");
if(!fp) {
logger(LOG_ERR, "Error reading RSA public key file `%s': %s",
fname, strerror(errno));
free(fname);
logger(LOG_ERR, "Error reading RSA public key file `%s': %s", pubname, strerror(errno));
free(pubname);
return false;
}
free(fname);
c->rsa_key = PEM_read_RSA_PUBKEY(fp, &c->rsa_key, NULL, NULL);
fclose(fp);
if(c->rsa_key) {
// RSA_blinding_on(c->rsa_key, NULL);
free(pubname);
return true;
}
logger(LOG_ERR, "Reading RSA public key file `%s' failed: %s",
fname, strerror(errno));
logger(LOG_ERR, "Reading RSA public key file `%s' failed: %s", pubname, strerror(errno));
free(pubname);
return false;
}
/* Else, check if a harnessed public key is in the config file */
xasprintf(&fname, "%s/hosts/%s", confbase, c->name);
fp = fopen(fname, "r");
xasprintf(&hcfname, "%s/hosts/%s", confbase, c->name);
fp = fopen(hcfname, "r");
if(!fp) {
logger(LOG_ERR, "Error reading RSA public key file `%s': %s", fname, strerror(errno));
free(fname);
logger(LOG_ERR, "Error reading RSA public key file `%s': %s", hcfname, strerror(errno));
free(hcfname);
return false;
}
c->rsa_key = PEM_read_RSAPublicKey(fp, &c->rsa_key, NULL, NULL);
fclose(fp);
free(fname);
if(c->rsa_key)
if(c->rsa_key) {
free(hcfname);
return true;
}
/* Try again with PEM_read_RSA_PUBKEY. */
xasprintf(&fname, "%s/hosts/%s", confbase, c->name);
fp = fopen(fname, "r");
fp = fopen(hcfname, "r");
if(!fp) {
logger(LOG_ERR, "Error reading RSA public key file `%s': %s", fname, strerror(errno));
free(fname);
logger(LOG_ERR, "Error reading RSA public key file `%s': %s", hcfname, strerror(errno));
free(hcfname);
return false;
}
free(hcfname);
c->rsa_key = PEM_read_RSA_PUBKEY(fp, &c->rsa_key, NULL, NULL);
// RSA_blinding_on(c->rsa_key, NULL);
fclose(fp);
free(fname);
if(c->rsa_key)
return true;
@ -160,7 +163,6 @@ bool read_rsa_public_key(connection_t *c) {
static bool read_rsa_private_key(void) {
FILE *fp;
char *fname, *key, *pubkey;
struct stat s;
if(get_config_string(lookup_config(config_tree, "PrivateKey"), &key)) {
if(!get_config_string(lookup_config(config_tree, "PublicKey"), &pubkey)) {
@ -169,8 +171,14 @@ static bool read_rsa_private_key(void) {
}
myself->connection->rsa_key = RSA_new();
// RSA_blinding_on(myself->connection->rsa_key, NULL);
BN_hex2bn(&myself->connection->rsa_key->d, key);
BN_hex2bn(&myself->connection->rsa_key->n, pubkey);
if(BN_hex2bn(&myself->connection->rsa_key->d, key) != strlen(key)) {
logger(LOG_ERR, "Invalid PrivateKey for myself!");
return false;
}
if(BN_hex2bn(&myself->connection->rsa_key->n, pubkey) != strlen(pubkey)) {
logger(LOG_ERR, "Invalid PublicKey for myself!");
return false;
}
BN_hex2bn(&myself->connection->rsa_key->e, "FFFF");
free(key);
free(pubkey);
@ -190,6 +198,8 @@ static bool read_rsa_private_key(void) {
}
#if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN)
struct stat s;
if(fstat(fileno(fp), &s)) {
logger(LOG_ERR, "Could not stat RSA private key file `%s': %s'",
fname, strerror(errno));
@ -290,7 +300,7 @@ char *get_name(void) {
fprintf(stderr, "Invalid Name: environment variable %s does not exist\n", name + 1);
return false;
}
envname = alloca(32);
char envname[32];
if(gethostname(envname, 32)) {
fprintf(stderr, "Could not get hostname: %s\n", strerror(errno));
return false;

View file

@ -1,7 +1,7 @@
/*
net_socket.c -- Handle various kinds of sockets.
Copyright (C) 1998-2005 Ivo Timmermans,
2000-2012 Guus Sliepen <guus@tinc-vpn.org>
2000-2013 Guus Sliepen <guus@tinc-vpn.org>
2006 Scott Lamb <slamb@slamb.org>
2009 Florian Forster <octo@verplant.org>
@ -64,7 +64,7 @@ static void configure_tcp(connection_t *c) {
unsigned long arg = 1;
if(ioctlsocket(c->socket, FIONBIO, &arg) != 0) {
logger(LOG_ERR, "ioctlsocket for %s: %d", c->hostname, sockstrerror(sockerrno));
logger(LOG_ERR, "ioctlsocket for %s: %s", c->hostname, sockstrerror(sockerrno));
}
#endif
@ -294,9 +294,6 @@ void retry_outgoing(outgoing_t *outgoing) {
void finish_connecting(connection_t *c) {
ifdebug(CONNECTIONS) logger(LOG_INFO, "Connected to %s (%s)", c->name, c->hostname);
if(proxytype != PROXY_EXEC)
configure_tcp(c);
c->last_ping_time = now;
send_id(c);
@ -419,6 +416,7 @@ begin:
goto begin;
ifdebug(CONNECTIONS) logger(LOG_INFO, "Using proxy at %s port %s", proxyhost, proxyport);
c->socket = socket(proxyai->ai_family, SOCK_STREAM, IPPROTO_TCP);
configure_tcp(c);
}
if(c->socket == -1) {

View file

@ -1,7 +1,7 @@
/*
process.c -- process management functions
Copyright (C) 1999-2005 Ivo Timmermans,
2000-2011 Guus Sliepen <guus@tinc-vpn.org>
2000-2013 Guus Sliepen <guus@tinc-vpn.org>
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
@ -47,8 +47,6 @@ extern bool use_logfile;
static sigset_t emptysigset;
#endif
static int saved_debug_level = -1;
static void memory_full(int size) {
logger(LOG_ERR, "Memory exhausted (couldn't allocate %d bytes), exitting.", size);
exit(1);
@ -167,7 +165,7 @@ DWORD WINAPI controlhandler(DWORD request, DWORD type, LPVOID boe, LPVOID bah) {
logger(LOG_NOTICE, "Got %s request", "SERVICE_CONTROL_SHUTDOWN");
break;
default:
logger(LOG_WARNING, "Got unexpected request %d", request);
logger(LOG_WARNING, "Got unexpected request %d", (int)request);
return ERROR_CALL_NOT_IMPLEMENTED;
}
@ -187,10 +185,8 @@ DWORD WINAPI controlhandler(DWORD request, DWORD type, LPVOID boe, LPVOID bah) {
}
VOID WINAPI run_service(DWORD argc, LPTSTR* argv) {
int err = 1;
extern int main2(int argc, char **argv);
status.dwServiceType = SERVICE_WIN32;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
status.dwWin32ExitCode = 0;
@ -201,7 +197,6 @@ VOID WINAPI run_service(DWORD argc, LPTSTR* argv) {
if (!statushandle) {
logger(LOG_ERR, "System call `%s' failed: %s", "RegisterServiceCtrlHandlerEx", winerror(GetLastError()));
err = 1;
} else {
status.dwWaitHint = 30000;
status.dwCurrentState = SERVICE_START_PENDING;
@ -211,11 +206,10 @@ VOID WINAPI run_service(DWORD argc, LPTSTR* argv) {
status.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(statushandle, &status);
err = main2(argc, argv);
main2(argc, argv);
status.dwWaitHint = 0;
status.dwCurrentState = SERVICE_STOPPED;
//status.dwWin32ExitCode = err;
SetServiceStatus(statushandle, &status);
}
@ -358,6 +352,7 @@ bool execute_script(const char *name, char **envp) {
int status, len;
char *scriptname;
int i;
char *interpreter = NULL;
#ifndef HAVE_MINGW
len = xasprintf(&scriptname, "\"%s/%s\"", confbase, name);
@ -369,14 +364,22 @@ bool execute_script(const char *name, char **envp) {
scriptname[len - 1] = '\0';
#ifndef HAVE_TUNEMU
/* First check if there is a script */
if(access(scriptname + 1, F_OK)) {
free(scriptname);
return true;
}
#endif
// Custom scripts interpreter
if(get_config_string(lookup_config(config_tree, "ScriptsInterpreter"), &interpreter)) {
// Force custom scripts interpreter allowing execution of scripts on android without execution flag (such as on /sdcard)
free(scriptname);
len = xasprintf(&scriptname, "%s \"%s/%s\"", interpreter, confbase, name);
free(interpreter);
if(len < 0)
return false;
}
ifdebug(STATUS) logger(LOG_INFO, "Executing script %s", name);
@ -404,8 +407,8 @@ bool execute_script(const char *name, char **envp) {
}
}
#ifdef WEXITSTATUS
if(status != -1) {
#ifdef WEXITSTATUS
if(WIFEXITED(status)) { /* Child exited by itself */
if(WEXITSTATUS(status)) {
logger(LOG_ERR, "Script %s exited with non-zero status %d",
@ -420,11 +423,11 @@ bool execute_script(const char *name, char **envp) {
logger(LOG_ERR, "Script %s terminated abnormally", name);
return false;
}
#endif
} else {
logger(LOG_ERR, "System call `%s' failed: %s", "system", strerror(errno));
return false;
}
#endif
#endif
return true;
}
@ -485,6 +488,8 @@ static RETSIGTYPE sighup_handler(int a) {
}
static RETSIGTYPE sigint_handler(int a) {
static int saved_debug_level = -1;
logger(LOG_NOTICE, "Got %s signal", "INT");
if(saved_debug_level != -1) {

View file

@ -1,7 +1,7 @@
/*
protocol.c -- handle the meta-protocol, basic functions
Copyright (C) 1999-2005 Ivo Timmermans,
2000-2012 Guus Sliepen <guus@tinc-vpn.org>
2000-2013 Guus Sliepen <guus@tinc-vpn.org>
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
@ -125,7 +125,7 @@ void forward_request(connection_t *from) {
bool receive_request(connection_t *c) {
int request;
if(proxytype == PROXY_HTTP && c->allow_request == ID) {
if(c->outgoing && proxytype == PROXY_HTTP && c->allow_request == ID) {
if(!c->buffer[0] || c->buffer[0] == '\r')
return true;
if(!strncasecmp(c->buffer, "HTTP/1.1 ", 9)) {

View file

@ -1,7 +1,7 @@
/*
protocol_auth.c -- handle the meta-protocol, authentication
Copyright (C) 1999-2005 Ivo Timmermans,
2000-2012 Guus Sliepen <guus@tinc-vpn.org>
2000-2013 Guus Sliepen <guus@tinc-vpn.org>
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
@ -126,7 +126,7 @@ static bool send_proxyrequest(connection_t *c) {
}
bool send_id(connection_t *c) {
if(proxytype)
if(proxytype && c->outgoing)
if(!send_proxyrequest(c))
return false;
@ -244,8 +244,8 @@ bool send_metakey(connection_t *c) {
*/
if(RSA_public_encrypt(len, (unsigned char *)c->outkey, (unsigned char *)buffer, c->rsa_key, RSA_NO_PADDING) != len) {
logger(LOG_ERR, "Error during encryption of meta key for %s (%s)",
c->name, c->hostname);
logger(LOG_ERR, "Error during encryption of meta key for %s (%s): %s",
c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
return false;
}
@ -308,13 +308,16 @@ bool metakey_h(connection_t *c) {
/* Convert the challenge from hexadecimal back to binary */
hex2bin(buffer, buffer, len);
if(!hex2bin(buffer, buffer, len)) {
logger(LOG_ERR, "Got bad %s from %s(%s): %s", "METAKEY", c->name, c->hostname, "invalid key");
return false;
}
/* Decrypt the meta key */
if(RSA_private_decrypt(len, (unsigned char *)buffer, (unsigned char *)c->inkey, myself->connection->rsa_key, RSA_NO_PADDING) != len) { /* See challenge() */
logger(LOG_ERR, "Error during decryption of meta key for %s (%s)",
c->name, c->hostname);
logger(LOG_ERR, "Error during decryption of meta key for %s (%s): %s",
c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
return false;
}
@ -426,7 +429,10 @@ bool challenge_h(connection_t *c) {
/* Convert the challenge from hexadecimal back to binary */
hex2bin(buffer, c->mychallenge, len);
if(!hex2bin(buffer, c->mychallenge, len)) {
logger(LOG_ERR, "Got bad %s from %s(%s): %s", "CHALLENGE", c->name, c->hostname, "invalid challenge");
return false;
}
c->allow_request = CHAL_REPLY;
@ -480,7 +486,10 @@ bool chal_reply_h(connection_t *c) {
/* Convert the hash to binary format */
hex2bin(hishash, hishash, c->outdigest->md_size);
if(!hex2bin(hishash, hishash, c->outdigest->md_size)) {
logger(LOG_ERR, "Got bad %s from %s(%s): %s", "CHAL_REPLY", c->name, c->hostname, "invalid hash");
return false;
}
/* Calculate the hash from the challenge we sent */

View file

@ -240,10 +240,16 @@ bool ans_key_h(connection_t *c) {
return send_request(to->nexthop->connection, "%s", c->buffer);
}
/* Don't use key material until every check has passed. */
from->status.validkey = false;
/* Update our copy of the origin's packet key */
from->outkey = xrealloc(from->outkey, strlen(key) / 2);
from->outkeylength = strlen(key) / 2;
hex2bin(key, from->outkey, from->outkeylength);
if(!hex2bin(key, from->outkey, from->outkeylength)) {
logger(LOG_ERR, "Got bad %s from %s(%s): %s", "ANS_KEY", from->name, from->hostname, "invalid key");
return true;
}
/* Check and lookup cipher and digest algorithms */

View file

@ -1,7 +1,7 @@
/*
route.c -- routing
Copyright (C) 2000-2005 Ivo Timmermans,
2000-2012 Guus Sliepen <guus@tinc-vpn.org>
2000-2013 Guus Sliepen <guus@tinc-vpn.org>
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
@ -110,15 +110,22 @@ static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *pac
mtu = via->mtu;
/* Find TCP header */
int start = 0;
int start = ether_size;
uint16_t type = packet->data[12] << 8 | packet->data[13];
if(type == ETH_P_IP && packet->data[23] == 6)
start = 14 + (packet->data[14] & 0xf) * 4;
else if(type == ETH_P_IPV6 && packet->data[20] == 6)
start = 14 + 40;
if(type == ETH_P_8021Q) {
start += 4;
type = packet->data[16] << 8 | packet->data[17];
}
if(!start || packet->len <= start + 20)
if(type == ETH_P_IP && packet->data[start + 9] == 6)
start += (packet->data[start] & 0xf) * 4;
else if(type == ETH_P_IPV6 && packet->data[start + 6] == 6)
start += 40;
else
return;
if(packet->len <= start + 20)
return;
/* Use data offset field to calculate length of options field */
@ -244,7 +251,7 @@ void age_subnets(void) {
/* RFC 792 */
static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, uint8_t type, uint8_t code) {
static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_t ether_size, uint8_t type, uint8_t code) {
struct ip ip = {0};
struct icmp icmp = {0};
@ -317,7 +324,7 @@ static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, uint8_t
/* RFC 791 */
static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet) {
static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t ether_size) {
struct ip ip;
vpn_packet_t fragment;
int len, maxlen, todo;
@ -333,7 +340,7 @@ static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet) {
todo = ntohs(ip.ip_len) - ip_size;
if(ether_size + ip_size + todo != packet->len) {
ifdebug(TRAFFIC) logger(LOG_WARNING, "Length of packet (%d) doesn't match length in IPv4 header (%zd)", packet->len, ether_size + ip_size + todo);
ifdebug(TRAFFIC) logger(LOG_WARNING, "Length of packet (%d) doesn't match length in IPv4 header (%d)", packet->len, (int)(ether_size + ip_size + todo));
return;
}
@ -381,7 +388,7 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) {
dest.x[2],
dest.x[3]);
route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_UNKNOWN);
route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_UNKNOWN);
return;
}
@ -391,10 +398,10 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) {
}
if(!subnet->owner->status.reachable)
return route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_UNREACH);
return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_UNREACH);
if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself)
return route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_ANO);
return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO);
if(priorityinheritance)
packet->priority = packet->data[15];
@ -407,15 +414,15 @@ static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) {
}
if(directonly && subnet->owner != via)
return route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_ANO);
return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO);
if(via && packet->len > MAX(via->mtu, 590) && via != myself) {
ifdebug(TRAFFIC) logger(LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu);
if(packet->data[20] & 0x40) {
packet->len = MAX(via->mtu, 590);
route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED);
route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED);
} else {
fragment_ipv4_packet(via, packet);
fragment_ipv4_packet(via, packet, ether_size);
}
return;
@ -442,7 +449,7 @@ static void route_ipv4(node_t *source, vpn_packet_t *packet) {
/* RFC 2463 */
static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, uint8_t type, uint8_t code) {
static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, length_t ether_size, uint8_t type, uint8_t code) {
struct ip6_hdr ip6;
struct icmp6_hdr icmp6 = {0};
uint16_t checksum;
@ -540,7 +547,7 @@ static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) {
ntohs(dest.x[6]),
ntohs(dest.x[7]));
route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR);
route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR);
return;
}
@ -550,10 +557,10 @@ static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) {
}
if(!subnet->owner->status.reachable)
return route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE);
return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE);
if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself)
return route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN);
return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN);
via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via;
@ -563,12 +570,12 @@ static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) {
}
if(directonly && subnet->owner != via)
return route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN);
return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN);
if(via && packet->len > MAX(via->mtu, 1294) && via != myself) {
ifdebug(TRAFFIC) logger(LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu);
packet->len = MAX(via->mtu, 1294);
route_ipv6_unreachable(source, packet, ICMP6_PACKET_TOO_BIG, 0);
route_ipv6_unreachable(source, packet, ether_size, ICMP6_PACKET_TOO_BIG, 0);
return;
}
@ -829,6 +836,11 @@ static void route_mac(node_t *source, vpn_packet_t *packet) {
if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself)
return;
uint16_t type = packet->data[12] << 8 | packet->data[13];
if(priorityinheritance && type == ETH_P_IP && packet->len >= ether_size + ip_size)
packet->priority = packet->data[15];
// Handle packets larger than PMTU
node_t *via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via;
@ -838,18 +850,24 @@ static void route_mac(node_t *source, vpn_packet_t *packet) {
if(via && packet->len > via->mtu && via != myself) {
ifdebug(TRAFFIC) logger(LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu);
uint16_t type = packet->data[12] << 8 | packet->data[13];
if(type == ETH_P_IP && packet->len > 590) {
if(packet->data[20] & 0x40) {
length_t ethlen = 14;
if(type == ETH_P_8021Q) {
type = packet->data[16] << 8 | packet->data[17];
ethlen += 4;
}
if(type == ETH_P_IP && packet->len > 576 + ethlen) {
if(packet->data[6 + ethlen] & 0x40) {
packet->len = via->mtu;
route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED);
route_ipv4_unreachable(source, packet, ethlen, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED);
} else {
fragment_ipv4_packet(via, packet);
fragment_ipv4_packet(via, packet, ethlen);
}
return;
} else if(type == ETH_P_IPV6 && packet->len > 1294) {
} else if(type == ETH_P_IPV6 && packet->len > 1280 + ethlen) {
packet->len = via->mtu;
route_ipv6_unreachable(source, packet, ICMP6_PACKET_TOO_BIG, 0);
route_ipv6_unreachable(source, packet, ethlen, ICMP6_PACKET_TOO_BIG, 0);
return;
}
}
@ -861,42 +879,48 @@ static void route_mac(node_t *source, vpn_packet_t *packet) {
static bool do_decrement_ttl(node_t *source, vpn_packet_t *packet) {
uint16_t type = packet->data[12] << 8 | packet->data[13];
length_t ethlen = ether_size;
if(type == ETH_P_8021Q) {
type = packet->data[16] << 8 | packet->data[17];
ethlen += 4;
}
switch (type) {
case ETH_P_IP:
if(!checklength(source, packet, 14 + 32))
if(!checklength(source, packet, ethlen + ip_size))
return false;
if(packet->data[22] < 1) {
if(packet->data[25] != IPPROTO_ICMP || packet->data[46] != ICMP_TIME_EXCEEDED)
route_ipv4_unreachable(source, packet, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL);
if(packet->data[ethlen + 8] < 1) {
if(packet->data[ethlen + 11] != IPPROTO_ICMP || packet->data[ethlen + 32] != ICMP_TIME_EXCEEDED)
route_ipv4_unreachable(source, packet, ethlen, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL);
return false;
}
uint16_t old = packet->data[22] << 8 | packet->data[23];
packet->data[22]--;
uint16_t new = packet->data[22] << 8 | packet->data[23];
uint16_t old = packet->data[ethlen + 8] << 8 | packet->data[ethlen + 9];
packet->data[ethlen + 8]--;
uint16_t new = packet->data[ethlen + 8] << 8 | packet->data[ethlen + 9];
uint32_t checksum = packet->data[24] << 8 | packet->data[25];
uint32_t checksum = packet->data[ethlen + 10] << 8 | packet->data[ethlen + 11];
checksum += old + (~new & 0xFFFF);
while(checksum >> 16)
checksum = (checksum & 0xFFFF) + (checksum >> 16);
packet->data[24] = checksum >> 8;
packet->data[25] = checksum & 0xff;
packet->data[ethlen + 10] = checksum >> 8;
packet->data[ethlen + 11] = checksum & 0xff;
return true;
case ETH_P_IPV6:
if(!checklength(source, packet, 14 + 40))
if(!checklength(source, packet, ethlen + ip6_size))
return false;
if(packet->data[21] < 1) {
if(packet->data[20] != IPPROTO_ICMPV6 || packet->data[54] != ICMP6_TIME_EXCEEDED)
route_ipv6_unreachable(source, packet, ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT);
if(packet->data[ethlen + 7] < 1) {
if(packet->data[ethlen + 6] != IPPROTO_ICMPV6 || packet->data[ethlen + 40] != ICMP6_TIME_EXCEEDED)
route_ipv6_unreachable(source, packet, ethlen, ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT);
return false;
}
packet->data[21]--;
packet->data[ethlen + 7]--;
return true;

View file

@ -151,6 +151,7 @@ static bool read_packet(vpn_packet_t *packet) {
return false;
}
memset(packet->data, 0, 12);
packet->len = lenin + 14;
device_total_in += packet->len;

View file

@ -1,7 +1,7 @@
/*
tincd.c -- the main file for tincd
Copyright (C) 1998-2005 Ivo Timmermans
2000-2012 Guus Sliepen <guus@tinc-vpn.org>
2000-2013 Guus Sliepen <guus@tinc-vpn.org>
2008 Max Rijevski <maksuf@gmail.com>
2009 Michael Tokarev <mjt@tls.msk.ru>
2010 Julien Muchembled <jm@jmuchemb.eu>
@ -338,7 +338,7 @@ static bool keygen(int bits) {
RSA *rsa_key;
FILE *f;
char *name = get_name();
char *filename;
char *pubname, *privname;
fprintf(stderr, "Generating %d bits keys:\n", bits);
rsa_key = RSA_generate_key(bits, 0x10001, indicator, NULL);
@ -349,8 +349,9 @@ static bool keygen(int bits) {
} else
fprintf(stderr, "Done.\n");
xasprintf(&filename, "%s/rsa_key.priv", confbase);
f = ask_and_open(filename, "private RSA key");
xasprintf(&privname, "%s/rsa_key.priv", confbase);
f = ask_and_open(privname, "private RSA key");
free(privname);
if(!f)
return false;
@ -363,14 +364,14 @@ static bool keygen(int bits) {
fputc('\n', f);
PEM_write_RSAPrivateKey(f, rsa_key, NULL, NULL, 0, NULL, NULL);
fclose(f);
free(filename);
if(name)
xasprintf(&filename, "%s/hosts/%s", confbase, name);
xasprintf(&pubname, "%s/hosts/%s", confbase, name);
else
xasprintf(&filename, "%s/rsa_key.pub", confbase);
xasprintf(&pubname, "%s/rsa_key.pub", confbase);
f = ask_and_open(filename, "public RSA key");
f = ask_and_open(pubname, "public RSA key");
free(pubname);
if(!f)
return false;
@ -378,7 +379,6 @@ static bool keygen(int bits) {
fputc('\n', f);
PEM_write_RSAPublicKey(f, rsa_key);
fclose(f);
free(filename);
free(name);
return true;
@ -391,7 +391,7 @@ static void make_names(void) {
#ifdef HAVE_MINGW
HKEY key;
char installdir[1024] = "";
long len = sizeof(installdir);
DWORD len = sizeof(installdir);
#endif
if(netname)
@ -401,7 +401,7 @@ static void make_names(void) {
#ifdef HAVE_MINGW
if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\tinc", 0, KEY_READ, &key)) {
if(!RegQueryValueEx(key, NULL, 0, 0, installdir, &len)) {
if(!RegQueryValueEx(key, NULL, 0, 0, (LPBYTE)installdir, &len)) {
if(!logfilename)
xasprintf(&logfilename, "%s/log/%s.log", identname);
if(!confbase) {
@ -467,8 +467,11 @@ static bool drop_privs() {
"initgroups", strerror(errno));
return false;
}
#ifndef __ANDROID__
// Not supported in android NDK
endgrent();
endpwent();
#endif
}
if (do_chroot) {
tzset(); /* for proper timestamps in logs */
@ -510,7 +513,7 @@ int main(int argc, char **argv) {
if(show_version) {
printf("%s version %s (built %s %s, protocol %d)\n", PACKAGE,
VERSION, __DATE__, __TIME__, PROT_CURRENT);
printf("Copyright (C) 1998-2012 Ivo Timmermans, Guus Sliepen and others.\n"
printf("Copyright (C) 1998-2013 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"