TCPonly now works (in a relatively clean way too).
This commit is contained in:
parent
a5e2ae6b2b
commit
fcf869cd42
6 changed files with 104 additions and 97 deletions
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
$Id: connection.h,v 1.1.2.8 2001/03/04 13:59:25 guus Exp $
|
$Id: connection.h,v 1.1.2.9 2001/05/25 11:54:28 guus Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TINC_CONNECTION_H__
|
#ifndef __TINC_CONNECTION_H__
|
||||||
|
@ -85,7 +85,7 @@ typedef struct connection_t {
|
||||||
|
|
||||||
char *buffer; /* metadata input buffer */
|
char *buffer; /* metadata input buffer */
|
||||||
int buflen; /* bytes read into buffer */
|
int buflen; /* bytes read into buffer */
|
||||||
int reqlen; /* length of first request in buffer */
|
int tcplen; /* length of incoming TCPpacket */
|
||||||
int allow_request; /* defined if there's only one request possible */
|
int allow_request; /* defined if there's only one request possible */
|
||||||
|
|
||||||
time_t last_ping_time; /* last time we saw some activity from the other end */
|
time_t last_ping_time; /* last time we saw some activity from the other end */
|
||||||
|
|
67
src/meta.c
67
src/meta.c
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
$Id: meta.c,v 1.1.2.17 2001/05/25 08:36:11 guus Exp $
|
$Id: meta.c,v 1.1.2.18 2001/05/25 11:54:28 guus Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -45,15 +45,13 @@
|
||||||
|
|
||||||
int send_meta(connection_t *cl, char *buffer, int length)
|
int send_meta(connection_t *cl, char *buffer, int length)
|
||||||
{
|
{
|
||||||
char outbuf[MAXBUFSIZE];
|
|
||||||
char *bufp;
|
char *bufp;
|
||||||
int outlen;
|
int outlen;
|
||||||
|
char outbuf[MAXBUFSIZE];
|
||||||
cp
|
cp
|
||||||
if(debug_lvl >= DEBUG_META)
|
if(debug_lvl >= DEBUG_META)
|
||||||
syslog(LOG_DEBUG, _("Sending %d bytes of metadata to %s (%s): %s"), length,
|
syslog(LOG_DEBUG, _("Sending %d bytes of metadata to %s (%s)"), length,
|
||||||
cl->name, cl->hostname, buffer);
|
cl->name, cl->hostname);
|
||||||
|
|
||||||
buffer[length-1]='\n';
|
|
||||||
|
|
||||||
if(cl->status.encryptout)
|
if(cl->status.encryptout)
|
||||||
{
|
{
|
||||||
|
@ -91,9 +89,9 @@ int receive_meta(connection_t *cl)
|
||||||
{
|
{
|
||||||
int x, l = sizeof(x);
|
int x, l = sizeof(x);
|
||||||
int oldlen, i;
|
int oldlen, i;
|
||||||
int lenin = 0;
|
int lenin, reqlen;
|
||||||
char inbuf[MAXBUFSIZE];
|
|
||||||
int decrypted = 0;
|
int decrypted = 0;
|
||||||
|
char inbuf[MAXBUFSIZE];
|
||||||
cp
|
cp
|
||||||
if(getsockopt(cl->meta_socket, SOL_SOCKET, SO_ERROR, &x, &l) < 0)
|
if(getsockopt(cl->meta_socket, SOL_SOCKET, SO_ERROR, &x, &l) < 0)
|
||||||
{
|
{
|
||||||
|
@ -108,6 +106,15 @@ cp
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Strategy:
|
||||||
|
- Read as much as possible from the TCP socket in one go.
|
||||||
|
- Decrypt it.
|
||||||
|
- Check if a full request is in the input buffer.
|
||||||
|
- If yes, process request and remove it from the buffer,
|
||||||
|
then check again.
|
||||||
|
- If not, keep stuff in buffer and exit.
|
||||||
|
*/
|
||||||
|
|
||||||
lenin = read(cl->meta_socket, cl->buffer + cl->buflen, MAXBUFSIZE - cl->buflen);
|
lenin = read(cl->meta_socket, cl->buffer + cl->buflen, MAXBUFSIZE - cl->buflen);
|
||||||
|
|
||||||
if(lenin<=0)
|
if(lenin<=0)
|
||||||
|
@ -133,6 +140,8 @@ cp
|
||||||
|
|
||||||
while(lenin)
|
while(lenin)
|
||||||
{
|
{
|
||||||
|
/* Decrypt */
|
||||||
|
|
||||||
if(cl->status.decryptin && !decrypted)
|
if(cl->status.decryptin && !decrypted)
|
||||||
{
|
{
|
||||||
EVP_DecryptUpdate(cl->cipher_inctx, inbuf, &lenin, cl->buffer + oldlen, lenin);
|
EVP_DecryptUpdate(cl->cipher_inctx, inbuf, &lenin, cl->buffer + oldlen, lenin);
|
||||||
|
@ -140,31 +149,51 @@ cp
|
||||||
decrypted = 1;
|
decrypted = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cl->reqlen = 0;
|
/* Are we receiving a TCPpacket? */
|
||||||
|
|
||||||
|
if(cl->tcplen)
|
||||||
|
{
|
||||||
|
if(cl->tcplen <= cl->buflen)
|
||||||
|
{
|
||||||
|
receive_tcppacket(cl, cl->buffer, cl->tcplen);
|
||||||
|
|
||||||
|
cl->buflen -= cl->tcplen;
|
||||||
|
lenin -= cl->tcplen;
|
||||||
|
memmove(cl->buffer, cl->buffer + cl->tcplen, cl->buflen);
|
||||||
|
oldlen = 0;
|
||||||
|
cl->tcplen = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise we are waiting for a request */
|
||||||
|
|
||||||
|
reqlen = 0;
|
||||||
|
|
||||||
for(i = oldlen; i < cl->buflen; i++)
|
for(i = oldlen; i < cl->buflen; i++)
|
||||||
{
|
{
|
||||||
if(cl->buffer[i] == '\n')
|
if(cl->buffer[i] == '\n')
|
||||||
{
|
{
|
||||||
cl->buffer[i] = 0; /* replace end-of-line by end-of-string so we can use sscanf */
|
cl->buffer[i] = '\0'; /* replace end-of-line by end-of-string so we can use sscanf */
|
||||||
cl->reqlen = i + 1;
|
reqlen = i + 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cl->reqlen)
|
if(reqlen)
|
||||||
{
|
{
|
||||||
if(debug_lvl >= DEBUG_META)
|
|
||||||
syslog(LOG_DEBUG, _("Got request from %s (%s): %s"),
|
|
||||||
cl->name, cl->hostname, cl->buffer);
|
|
||||||
|
|
||||||
if(receive_request(cl))
|
if(receive_request(cl))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
cl->buflen -= cl->reqlen;
|
cl->buflen -= reqlen;
|
||||||
lenin -= cl->reqlen;
|
lenin -= reqlen;
|
||||||
memmove(cl->buffer, cl->buffer + cl->reqlen, cl->buflen);
|
memmove(cl->buffer, cl->buffer + reqlen, cl->buflen);
|
||||||
oldlen = 0;
|
oldlen = 0;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
17
src/net.c
17
src/net.c
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
$Id: net.c,v 1.35.4.107 2001/05/25 10:08:11 guus Exp $
|
$Id: net.c,v 1.35.4.108 2001/05/25 11:54:28 guus Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -184,6 +184,17 @@ cp
|
||||||
cp
|
cp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void receive_tcppacket(connection_t *cl, char *buffer, int len)
|
||||||
|
{
|
||||||
|
vpn_packet_t outpkt;
|
||||||
|
cp
|
||||||
|
outpkt.len = len;
|
||||||
|
memcpy(outpkt.data, buffer, len);
|
||||||
|
|
||||||
|
receive_packet(cl, &outpkt);
|
||||||
|
cp
|
||||||
|
}
|
||||||
|
|
||||||
void accept_packet(vpn_packet_t *packet)
|
void accept_packet(vpn_packet_t *packet)
|
||||||
{
|
{
|
||||||
cp
|
cp
|
||||||
|
@ -203,7 +214,7 @@ cp
|
||||||
if(write(tap_fd, packet->data - 2, packet->len + 2) < 0)
|
if(write(tap_fd, packet->data - 2, packet->len + 2) < 0)
|
||||||
syslog(LOG_ERR, _("Can't write to ethertap device: %m"));
|
syslog(LOG_ERR, _("Can't write to ethertap device: %m"));
|
||||||
else
|
else
|
||||||
total_tap_out += packet->len + 2;
|
total_tap_out += packet->len;
|
||||||
}
|
}
|
||||||
cp
|
cp
|
||||||
}
|
}
|
||||||
|
@ -1290,7 +1301,7 @@ cp
|
||||||
vp.len = lenin - 2;
|
vp.len = lenin - 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
total_tap_in += lenin;
|
total_tap_in += vp.len;
|
||||||
|
|
||||||
if(lenin < 32)
|
if(lenin < 32)
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
$Id: net.h,v 1.9.4.30 2001/05/07 19:08:46 guus Exp $
|
$Id: net.h,v 1.9.4.31 2001/05/25 11:54:28 guus Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TINC_NET_H__
|
#ifndef __TINC_NET_H__
|
||||||
|
@ -109,6 +109,7 @@ extern int str2opt(const char *);
|
||||||
extern char *opt2str(int);
|
extern char *opt2str(int);
|
||||||
extern void send_packet(connection_t *, vpn_packet_t *);
|
extern void send_packet(connection_t *, vpn_packet_t *);
|
||||||
extern void receive_packet(connection_t *, vpn_packet_t *);
|
extern void receive_packet(connection_t *, vpn_packet_t *);
|
||||||
|
extern void receive_tcppacket(connection_t *, char *, int);
|
||||||
extern void accept_packet(vpn_packet_t *);
|
extern void accept_packet(vpn_packet_t *);
|
||||||
extern int setup_network_connections(void);
|
extern int setup_network_connections(void);
|
||||||
extern void close_network_connections(void);
|
extern void close_network_connections(void);
|
||||||
|
|
103
src/protocol.c
103
src/protocol.c
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
$Id: protocol.c,v 1.28.4.90 2001/05/25 08:36:11 guus Exp $
|
$Id: protocol.c,v 1.28.4.91 2001/05/25 11:54:28 guus Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -106,11 +106,15 @@ cp
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
len++;
|
|
||||||
|
|
||||||
if(debug_lvl >= DEBUG_PROTOCOL)
|
if(debug_lvl >= DEBUG_PROTOCOL)
|
||||||
syslog(LOG_DEBUG, _("Sending %s to %s (%s)"), request_name[request], cl->name, cl->hostname);
|
{
|
||||||
|
if(debug_lvl >= DEBUG_META)
|
||||||
|
syslog(LOG_DEBUG, _("Sending %s to %s (%s): %s"), request_name[request], cl->name, cl->hostname, buffer);
|
||||||
|
else
|
||||||
|
syslog(LOG_DEBUG, _("Sending %s to %s (%s)"), request_name[request], cl->name, cl->hostname);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[len++] = '\n';
|
||||||
cp
|
cp
|
||||||
return send_meta(cl, buffer, len);
|
return send_meta(cl, buffer, len);
|
||||||
}
|
}
|
||||||
|
@ -118,20 +122,31 @@ cp
|
||||||
int receive_request(connection_t *cl)
|
int receive_request(connection_t *cl)
|
||||||
{
|
{
|
||||||
int request;
|
int request;
|
||||||
cp
|
cp
|
||||||
if(sscanf(cl->buffer, "%d", &request) == 1)
|
if(sscanf(cl->buffer, "%d", &request) == 1)
|
||||||
{
|
{
|
||||||
if((request < 0) || (request >= LAST) || (request_handlers[request] == NULL))
|
if((request < 0) || (request >= LAST) || (request_handlers[request] == NULL))
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, _("Unknown request from %s (%s)"),
|
if(debug_lvl >= DEBUG_META)
|
||||||
cl->name, cl->hostname);
|
syslog(LOG_DEBUG, _("Unknown request from %s (%s): %s"),
|
||||||
|
cl->name, cl->hostname, cl->buffer);
|
||||||
|
else
|
||||||
|
syslog(LOG_ERR, _("Unknown request from %s (%s)"),
|
||||||
|
cl->name, cl->hostname);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(debug_lvl >= DEBUG_PROTOCOL)
|
if(debug_lvl >= DEBUG_PROTOCOL)
|
||||||
syslog(LOG_DEBUG, _("Got %s from %s (%s)"),
|
{
|
||||||
request_name[request], cl->name, cl->hostname);
|
if(debug_lvl >= DEBUG_META)
|
||||||
|
syslog(LOG_DEBUG, _("Got %s from %s (%s): %s"),
|
||||||
|
request_name[request], cl->name, cl->hostname, cl->buffer);
|
||||||
|
else
|
||||||
|
syslog(LOG_DEBUG, _("Got %s from %s (%s)"),
|
||||||
|
request_name[request], cl->name, cl->hostname);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((cl->allow_request != ALL) && (cl->allow_request != request))
|
if((cl->allow_request != ALL) && (cl->allow_request != request))
|
||||||
|
@ -158,34 +173,8 @@ cp
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Connection protocol:
|
/* The authentication protocol is described in detail in doc/SECURITY2,
|
||||||
|
the rest will be described in doc/PROTOCOL. */
|
||||||
Client Server
|
|
||||||
send_id(u)
|
|
||||||
send_challenge(R)
|
|
||||||
send_chal_reply(H)
|
|
||||||
send_id(u)
|
|
||||||
send_challenge(R)
|
|
||||||
send_chal_reply(H)
|
|
||||||
---------------------------------------
|
|
||||||
send_metakey(R)
|
|
||||||
send_metakey(R)
|
|
||||||
---------------------------------------
|
|
||||||
send_ack(u)
|
|
||||||
send_ack(u)
|
|
||||||
---------------------------------------
|
|
||||||
Other requests(E)...
|
|
||||||
|
|
||||||
(u) Unencrypted,
|
|
||||||
(R) RSA,
|
|
||||||
(H) SHA1,
|
|
||||||
(E) Encrypted with symmetric cipher.
|
|
||||||
|
|
||||||
Part of the challenge is directly used to set the symmetric cipher
|
|
||||||
key and the initial vector. Since a man-in-the-middle cannot
|
|
||||||
decrypt the RSA challenges, this means that he cannot get or forge
|
|
||||||
the key for the symmetric cipher.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int send_id(connection_t *cl)
|
int send_id(connection_t *cl)
|
||||||
{
|
{
|
||||||
|
@ -1287,53 +1276,29 @@ int send_tcppacket(connection_t *cl, vpn_packet_t *packet)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
cp
|
cp
|
||||||
|
/* Evil hack. */
|
||||||
|
|
||||||
x = send_request(cl->nexthop, "%d %hd", PACKET, packet->len);
|
x = send_request(cl->nexthop, "%d %hd", PACKET, packet->len);
|
||||||
|
|
||||||
if(x)
|
if(x)
|
||||||
return x;
|
return x;
|
||||||
|
cp
|
||||||
return send_meta(cl->nexthop, packet->data, packet->len);
|
return send_meta(cl, packet->data, packet->len);
|
||||||
}
|
}
|
||||||
|
|
||||||
int tcppacket_h(connection_t *cl)
|
int tcppacket_h(connection_t *cl)
|
||||||
{
|
{
|
||||||
vpn_packet_t packet;
|
short int len;
|
||||||
char *p;
|
|
||||||
int todo, x;
|
|
||||||
cp
|
cp
|
||||||
if(sscanf(cl->buffer, "%*d %hd", &packet.len) != 1)
|
if(sscanf(cl->buffer, "%*d %hd", &len) != 1)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, _("Got bad PACKET from %s (%s)"), cl->name, cl->hostname);
|
syslog(LOG_ERR, _("Got bad PACKET from %s (%s)"), cl->name, cl->hostname);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Evil hack. */
|
/* Set reqlen to len, this will tell receive_meta() that a tcppacket is coming. */
|
||||||
|
|
||||||
p = packet.data;
|
cl->tcplen = len;
|
||||||
todo = packet.len;
|
|
||||||
|
|
||||||
while(todo)
|
|
||||||
{
|
|
||||||
x = read(cl->meta_socket, p, todo);
|
|
||||||
|
|
||||||
if(x<=0)
|
|
||||||
{
|
|
||||||
if(x==0)
|
|
||||||
syslog(LOG_NOTICE, _("Connection closed by %s (%s)"), cl->name, cl->hostname);
|
|
||||||
else
|
|
||||||
if(errno==EINTR || errno==EAGAIN) /* FIXME: select() or poll() or reimplement this evil hack */
|
|
||||||
continue;
|
|
||||||
else
|
|
||||||
syslog(LOG_ERR, _("Error during reception of PACKET from %s (%s): %m"), cl->name, cl->hostname);
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
todo -= x;
|
|
||||||
p += x;
|
|
||||||
}
|
|
||||||
|
|
||||||
receive_packet(cl, &packet);
|
|
||||||
cp
|
cp
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
$Id: route.c,v 1.1.2.7 2001/03/04 13:59:32 guus Exp $
|
$Id: route.c,v 1.1.2.8 2001/05/25 11:54:28 guus Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -181,11 +181,12 @@ void route_incoming(connection_t *source, vpn_packet_t *packet)
|
||||||
{
|
{
|
||||||
switch(routing_mode)
|
switch(routing_mode)
|
||||||
{
|
{
|
||||||
|
case RMODE_ROUTER:
|
||||||
|
memcpy(packet->data, mymac.net.mac.address.x, 6);
|
||||||
|
break;
|
||||||
case RMODE_SWITCH:
|
case RMODE_SWITCH:
|
||||||
learn_mac(source, (mac_t *)(&packet->data[0]));
|
learn_mac(source, (mac_t *)(&packet->data[0]));
|
||||||
break;
|
break;
|
||||||
case RMODE_ROUTER:
|
|
||||||
memcpy(packet->data, mymac.net.mac.address.x, 6);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
accept_packet(packet);
|
accept_packet(packet);
|
||||||
|
|
Loading…
Reference in a new issue