From c78a204f06182f50b0812c8e4fef6163e82097bf Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Tue, 26 Sep 2000 14:06:11 +0000 Subject: [PATCH] - Added meta.c which contains functions to send, receive and broadcast metadata. It will also handle encryption and decryption, and possibly compression and checksumming. - Moved request dispatcher to protocol.c. --- src/meta.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++++ src/meta.h | 32 ++++++++++ src/net.c | 124 +----------------------------------- src/protocol.c | 56 +++++++++-------- src/protocol.h | 23 +++---- 5 files changed, 239 insertions(+), 162 deletions(-) create mode 100644 src/meta.c create mode 100644 src/meta.h diff --git a/src/meta.c b/src/meta.c new file mode 100644 index 0000000..21cbe96 --- /dev/null +++ b/src/meta.c @@ -0,0 +1,166 @@ +/* + meta.c -- handle the meta communication + Copyright (C) 2000 Guus Sliepen , + 2000 Ivo Timmermans + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id: meta.c,v 1.1.2.1 2000/09/26 14:06:03 guus Exp $ +*/ + +#include "config.h" + +int send_meta(conn_list_t *cl, const char *buffer, int length) +{ + char outbuf[MAXBUFSIZE]; + char *bufp; +cp + if(debug_lvl >= DEBUG_META) + syslog(LOG_DEBUG, _("Sending %d bytes of metadata to %s (%s): %s"), int length, + cl->name, cl->hostname, buffer); + + if(cl->status.encryptout) + { + if(EVP_EncryptUpdate(cl->cipher_outctx, cl->buffer + cl->buflen, NULL, inbuf, length) != 1) + { + syslog(LOG_ERR, _("Error during encryption of outgoing metadata to %s (%s)"), cl->name, cl->hostname); + return -1; + } + bufp = outbuf; + } + else + bufp = buffer; + + if(write(cl->meta_socket, bufp, length) < 0) + { + syslog(LOG_ERR, _("Sending meta data to %s (%s) failed: %m"), cl->name, cl->hostname); + return -1; + } +cp + return 0; +} + +int broadcast_meta(conn_list_t *cl, const char *buffer, int length) +{ + conn_list_t *p; +cp + for(p = conn_list; p != NULL; p = p->next) + if(p != cl && p->status.meta && p->status.active) + send_meta(p, buffer, length); +cp + return 0; +} + +int receive_meta(conn_list_t *cl) +{ + int x, l = sizeof(x); + int oldlen, i; + int lenin = 0; + char inbuf[MAXBUFSIZE]; + char *bufp; +cp + if(getsockopt(cl->meta_socket, SOL_SOCKET, SO_ERROR, &x, &l) < 0) + { + syslog(LOG_ERR, _("This is a bug: %s:%d: %d:%m %s (%s)"), __FILE__, __LINE__, cl->meta_socket, + cl->name, cl->hostname); + return -1; + } + if(x) + { + syslog(LOG_ERR, _("Metadata socket error for %s (%s): %s"), + cl->name, cl->hostname, strerror(x)); + return -1; + } + + if(cl->status.encryptin) + bufp = inbuf; + else + bufp = cl->buffer + cl->buflen; + + lenin = read(cl->meta_socket, bufp, MAXBUFSIZE - cl->buflen); + + if(lenin<=0) + { + if(errno==EINTR) + return 0; + if(errno==0) + { + if(debug_lvl>DEBUG_CONNECTIONS) + syslog(LOG_NOTICE, _("Connection closed by %s (%s)"), + cl->name, cl->hostname); + } + else + syslog(LOG_ERR, _("Metadata socket read error for %s (%s): %m"), + cl->name, cl->hostname); + return -1; + } + + if(cl->status.decryptin) + { + if(EVP_DecryptUpdate(cl->cipher_inctx, cl->buffer + cl->buflen, NULL, inbuf, lenin) != 1) + { + syslog(LOG_ERR, _("Error during decryption of incoming metadata from %s (%s)"), cl->name, cl->hostname); + return -1; + } + } + + oldlen = cl->buflen; + cl->buflen += lenin; + + for(;;) + { + cl->reqlen = 0; + + for(i = oldlen; i < cl->buflen; i++) + { + if(cl->buffer[i] == '\n') + { + cl->buffer[i] = 0; /* replace end-of-line by end-of-string so we can use sscanf */ + cl->reqlen = i + 1; + break; + } + } + + if(cl->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)) + return -1; + + cl->buflen -= cl->reqlen; + memmove(cl->buffer, cl->buffer + cl->reqlen, cl->buflen); + oldlen = 0; + } + else + { + break; + } + } + + if(cl->buflen >= MAXBUFSIZE) + { + syslog(LOG_ERR, _("Metadata read buffer overflow for %s (%s)"), + cl->name, cl->hostname); + return -1; + } + + cl->last_ping_time = time(NULL); + cl->want_ping = 0; +cp + return 0; +} diff --git a/src/meta.h b/src/meta.h new file mode 100644 index 0000000..263131b --- /dev/null +++ b/src/meta.h @@ -0,0 +1,32 @@ +/* + protocol.h -- header for protocol.c + Copyright (C) 1999,2000 Ivo Timmermans , + 2000 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., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id: meta.h,v 1.1.2.1 2000/09/26 14:06:04 guus Exp $ +*/ + +#ifndef __TINC_META_H__ +#define __TINC_META_H__ + +#include net.h + +extern int send_meta(conn_list_t *, const char *, int) +extern int broadcast_meta(conn_list_t *, const char *, int) +extern int receive_meta(conn_list_t *) + +#endif /* __TINC_META_H__ */ diff --git a/src/net.c b/src/net.c index f5f1b2f..94c0e44 100644 --- a/src/net.c +++ b/src/net.c @@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id: net.c,v 1.35.4.31 2000/09/22 16:20:07 guus Exp $ + $Id: net.c,v 1.35.4.32 2000/09/26 14:06:04 guus Exp $ */ #include "config.h" @@ -46,6 +46,7 @@ #include "net.h" #include "netutl.h" #include "protocol.h" +#include "meta.h" #include "system.h" @@ -1062,125 +1063,6 @@ cp return 0; } -/* - dispatch any incoming meta requests -*/ -int handle_incoming_meta_data(conn_list_t *cl) -{ - int x, l = sizeof(x); - int request, oldlen, i; - int lenin = 0; -cp - if(getsockopt(cl->meta_socket, SOL_SOCKET, SO_ERROR, &x, &l) < 0) - { - syslog(LOG_ERR, _("This is a bug: %s:%d: %d:%m %s (%s)"), __FILE__, __LINE__, cl->meta_socket, - cl->name, cl->hostname); - return -1; - } - if(x) - { - syslog(LOG_ERR, _("Metadata socket error for %s (%s): %s"), - cl->name, cl->hostname, strerror(x)); - return -1; - } - - lenin = read(cl->meta_socket, cl->buffer+cl->buflen, MAXBUFSIZE - cl->buflen); - - if(lenin<=0) - { - if(errno==EINTR) - return 0; - if(errno==0) - { - if(debug_lvl>DEBUG_CONNECTIONS) - syslog(LOG_NOTICE, _("Connection closed by %s (%s)"), - cl->name, cl->hostname); - } - else - syslog(LOG_ERR, _("Metadata socket read error for %s (%s): %m"), - cl->name, cl->hostname); - return -1; - } - - if(cl->status.encryptin) - { - /* FIXME: do decryption. */ - } - - oldlen = cl->buflen; - cl->buflen += lenin; - - for(;;) - { - cl->reqlen = 0; - - for(i = oldlen; i < cl->buflen; i++) - { - if(cl->buffer[i] == '\n') - { - cl->buffer[i] = 0; /* replace end-of-line by end-of-string so we can use sscanf */ - cl->reqlen = i + 1; - break; - } - } - - if(cl->reqlen) - { - if(debug_lvl > DEBUG_PROTOCOL) - syslog(LOG_DEBUG, _("Got request from %s (%s): %s"), - cl->name, cl->hostname, cl->buffer); - if(sscanf(cl->buffer, "%d", &request) == 1) - { - if((request < 0) || (request > 255) || (request_handlers[request] == NULL)) - { - syslog(LOG_ERR, _("Unknown request from %s (%s)"), - cl->name, cl->hostname); - return -1; - } - else - { - if(debug_lvl > DEBUG_PROTOCOL) - syslog(LOG_DEBUG, _("Got %s from %s (%s)"), - request_name[request], cl->name, cl->hostname); - } - if(request_handlers[request](cl)) - /* Something went wrong. Probably scriptkiddies. Terminate. */ - { - syslog(LOG_ERR, _("Error while processing %s from %s (%s)"), - request_name[request], cl->name, cl->hostname); - return -1; - } - } - else - { - syslog(LOG_ERR, _("Bogus data received from %s (%s)"), - cl->name, cl->hostname); - return -1; - } - - cl->buflen -= cl->reqlen; - memmove(cl->buffer, cl->buffer + cl->reqlen, cl->buflen); - oldlen = 0; - } - else - { - break; - } - } - - if(cl->buflen >= MAXBUFSIZE) - { - syslog(LOG_ERR, _("Metadata read buffer overflow for %s (%s)"), - cl->name, cl->hostname); - return -1; - } - - cl->last_ping_time = time(NULL); - cl->want_ping = 0; -cp - return 0; -} - /* check all connections to see if anything happened on their sockets @@ -1213,7 +1095,7 @@ cp if(p->status.meta) if(FD_ISSET(p->meta_socket, f)) - if(handle_incoming_meta_data(p) < 0) + if(receive_meta(p) < 0) { terminate_connection(p); return; diff --git a/src/protocol.c b/src/protocol.c index d52fd54..20a2fc3 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id: protocol.c,v 1.28.4.35 2000/09/22 16:20:07 guus Exp $ + $Id: protocol.c,v 1.28.4.36 2000/09/26 14:06:06 guus Exp $ */ #include "config.h" @@ -43,6 +43,7 @@ #include "net.h" #include "netutl.h" #include "protocol.h" +#include "meta.h" #include "system.h" @@ -61,7 +62,7 @@ int check_id(char *id) return 1; } -/* Generic outgoing request routine - takes care of logging and error detection as well */ +/* Generic request routines - takes care of logging and error detection as well */ int send_request(conn_list_t *cl, const char *format, int request, /*args*/ ...) { @@ -89,37 +90,38 @@ cp return send_meta(cl, buffer, length); } - -int send_meta(conn_list_t *cl, const char *buffer, int length) +int receive_request(conn_list_t *cl) { -cp - if(debug_lvl >= DEBUG_META) - syslog(LOG_DEBUG, _("Sending %d bytes of metadata to %s (%s): %s"), int length, - cl->name, cl->hostname, buffer); - - if(cl->status.encryptin) + int request; +cp + if(sscanf(cl->buffer, "%d", &request) == 1) { - /* FIXME: Do encryption */ + if((request < 0) || (request > 255) || (request_handlers[request] == NULL)) + { + syslog(LOG_ERR, _("Unknown request from %s (%s)"), + cl->name, cl->hostname); + return -1; + } + else + { + if(debug_lvl > DEBUG_PROTOCOL) + syslog(LOG_DEBUG, _("Got %s from %s (%s)"), + request_name[request], cl->name, cl->hostname); + } + if(request_handlers[request](cl)) + /* Something went wrong. Probably scriptkiddies. Terminate. */ + { + syslog(LOG_ERR, _("Error while processing %s from %s (%s)"), + request_name[request], cl->name, cl->hostname); + return -1; + } } - - if(write(cl->meta_socket, buffer, length) < 0) + else { - syslog(LOG_ERR, _("Sending meta data to %s (%s) failed: %m"), cl->name, cl->hostname); + syslog(LOG_ERR, _("Bogus data received from %s (%s)"), + cl->name, cl->hostname); return -1; } -cp - return 0; -} - -int broadcast_meta(conn_list_t *cl, const char *buffer, int length) -{ - conn_list_t *p; -cp - for(p = conn_list; p != NULL; p = p->next) - if(p != cl && p->status.meta && p->status.active) - send_meta(p, buffer, length); -cp - return 0; } /* Connection protocol: diff --git a/src/protocol.h b/src/protocol.h index f3119aa..d77c045 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id: protocol.h,v 1.5.4.7 2000/09/11 10:05:35 guus Exp $ + $Id: protocol.h,v 1.5.4.8 2000/09/26 14:06:11 guus Exp $ */ #ifndef __TINC_PROTOCOL_H__ @@ -29,17 +29,14 @@ incompatible version have different protocols. */ -enum { - PROT_RESERVED = 0, /* reserved: do not use. */ - PROT_NOT_IN_USE, - PROT_TOO_OLD = 2, - PROT_3, - PROT_4, - PROT_ECHELON, - PROT_6, - PROT_7, - PROT_CURRENT, /* protocol currently in use */ -}; +#define PROT_CURRENT 8 + +/* Length of the challenge. Since the challenge will also + contain the key for the symmetric cipher, it must be + quite large. + */ + +#define CHAL_LENGTH 2048 /* Request numbers */ @@ -79,5 +76,3 @@ extern int send_tcppacket(conn_list_t *, void *, int); extern int notify_others(conn_list_t *, conn_list_t *, int (*function)(conn_list_t*, conn_list_t*)); #endif /* __TINC_PROTOCOL_H__ */ - - -- 2.25.1