From: Guus Sliepen Date: Mon, 1 May 2000 18:07:12 +0000 (+0000) Subject: Meta protocol overhaul. Tinc is now incompatible with previous versions, X-Git-Tag: release-1.0pre1~22 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=ca6abd41ea0cdf2ca6491c3945fb3c62fd40ab98;p=oweals%2Ftinc.git Meta protocol overhaul. Tinc is now incompatible with previous versions, furthermore this version does NOT work yet because of a problem with sending keys (these should be converted to base36 or something like that). It is possible to telnet to the tinc daemon now and type some commands by hand though :). --- diff --git a/src/encr.c b/src/encr.c index 75793b2..31e0b94 100644 --- a/src/encr.c +++ b/src/encr.c @@ -252,13 +252,13 @@ int verify_passphrase(conn_list_t *cl, unsigned char *his_pubkey) char which[sizeof("123.123.123.123")+1]; char *meuk; cp - mpz_init_set_str(pk, his_pubkey, 36); + mpz_init_set_str(pk, his_pubkey, 16); mpz_get_str(tmp, 16, pk); len = str_hex_to_bin(key, tmp); - out = xmalloc(cl->pp->len+3); + out = xmalloc(strlen(cl->pp) + 3); cipher_set_key(&bf_key, len, key); - low_crypt_key(cl->pp->phrase, out, &bf_key, cl->pp->len, BF_DECRYPT); + low_crypt_key(cl->pp, out, &bf_key, strlen(cl->pp), BF_DECRYPT); if(key_inited) cipher_set_key(&encryption_key, encryption_keylen, text_key); diff --git a/src/net.c b/src/net.c index 246d62c..7ee41b8 100644 --- a/src/net.c +++ b/src/net.c @@ -704,7 +704,8 @@ cp p->real_ip = ntohl(ci.sin_addr.s_addr); p->meta_socket = sfd; p->status.meta = 1; - + p->buflen = 0; + syslog(LOG_NOTICE, "Connection from %s:%d", p->hostname, htons(ci.sin_port)); if(send_basic_info(p) < 0) @@ -922,8 +923,7 @@ cp int handle_incoming_meta_data(conn_list_t *cl) { int x, l = sizeof(x); - unsigned char tmp[1600]; - int request; + int request, oldlen, p, i; int lenin = 0; cp if(getsockopt(cl->meta_socket, SOL_SOCKET, SO_ERROR, &x, &l) < 0) @@ -937,22 +937,66 @@ cp return -1; } - if(read(cl->meta_socket, &tmp, 1) <= 0) + if(cl->buflen >= MAXBUFSIZE) + { + syslog(LOG_ERR, "Metadata read buffer full! Discarding contents."); + cl->buflen = 0; + } + + lenin = read(cl->meta_socket, cl->buffer, MAXBUFSIZE-cl->buflen); + + if(lenin<=0) { - syslog(LOG_ERR, "Receive failed: %m"); + syslog(LOG_ERR, "Metadata socket read error: %m"); return -1; } - request = (int)(tmp[0]); + oldlen = cl->buflen; + cl->buflen += lenin; - if(debug_lvl > 3) - syslog(LOG_DEBUG, "got request %d", request); + for(;;) + { + p=0; - if(request_handlers[request] == NULL) - syslog(LOG_ERR, "Unknown request %d.", request); - else - if(request_handlers[request](cl) < 0) - return -1; + for(i = oldlen; i < cl->buflen; i++) + { + if(cl->buffer[i] == '\n') + { + cl->buffer[i] = 0; /* turn end-of-line into end-of-string */ + p = i + 1; + break; + } + } + + if(p) + { + if(sscanf(cl->buffer, "%d", &request) == 1) + { + if(request_handlers[request] == NULL) + { + syslog(LOG_ERR, "Unknown request: %s", cl->buffer); + return 0; + } + + if(debug_lvl > 3) + syslog(LOG_DEBUG, "Got request: %s", cl->buffer); + + request_handlers[request](cl); + } + else + { + syslog(LOG_ERR, "Bogus data received: %s", cl->buffer); + } + + cl->buflen -= p; + memmove(cl->buffer, cl->buffer + p, cl->buflen); + oldlen = 0; + } + else + { + break; + } + } cp return 0; } diff --git a/src/net.h b/src/net.h index 93b8c31..7dae419 100644 --- a/src/net.h +++ b/src/net.h @@ -46,6 +46,8 @@ ((unsigned char*)&(x))[1],((unsigned char*)&(x))[0] #endif +#define MAXBUFSIZE 2048 /* Probably way too much, but it must fit every possible request. */ + typedef unsigned long ip_t; typedef short length_t; @@ -61,8 +63,6 @@ typedef struct real_packet_t { } real_packet_t; typedef struct passphrase_t { - unsigned char type; - char unused1; unsigned short len; unsigned char phrase[MAX_PASSPHRASE_SIZE]; } passphrase_t; @@ -104,17 +104,19 @@ typedef struct conn_list_t { ip_t vpn_mask; /* his vpn network address */ ip_t real_ip; /* his real (internet) ip */ char *hostname; /* the hostname of its real ip */ - short int port; /* his portnumber */ + short unsigned int port; /* his portnumber */ int socket; /* our udp vpn socket */ int meta_socket; /* our tcp meta socket */ - unsigned char protocol_version; /* used protocol */ + int protocol_version; /* used protocol */ status_bits_t status; /* status info */ - passphrase_t *pp; /* encoded passphrase */ + unsigned char *pp; /* encoded passphrase */ packet_queue_t *sq; /* pending outgoing packets */ packet_queue_t *rq; /* pending incoming packets (they have no valid key to be decrypted with) */ enc_key_t *public_key; /* the other party's public key */ enc_key_t *key; /* encrypt with this key */ + char buffer[MAXBUFSIZE]; /* metadata input buffer */ + int buflen; /* bytes read into buffer */ struct conn_list_t *nexthop; /* nearest meta-hop in this direction */ struct conn_list_t *next; /* after all, it's a list of connections */ } conn_list_t; diff --git a/src/netutl.c b/src/netutl.c index fc53aae..df6401f 100644 --- a/src/netutl.c +++ b/src/netutl.c @@ -81,8 +81,6 @@ void free_conn_element(conn_list_t *p) cp if(p->hostname) free(p->hostname); - if(p->pp) - free(p->pp); if(p->sq) destroy_queue(p->sq); if(p->rq) diff --git a/src/protocol.c b/src/protocol.c index 13a5793..21dba5b 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -34,36 +35,38 @@ #include "netutl.h" #include "protocol.h" +char buffer[MAXBUFSIZE]; +int buflen; + int send_ack(conn_list_t *cl) { - unsigned char tmp = ACK; cp if(debug_lvl > 2) syslog(LOG_DEBUG, "Send ACK to %s", cl->hostname); - syslog(LOG_NOTICE, "Connection with %s activated.", cl->hostname); - if((write(cl->meta_socket, &tmp, sizeof(tmp))) < 0) + buflen = sprintf(buffer, "%d\n", ACK); + + if((write(cl->meta_socket, buffer, buflen)) < 0) { syslog(LOG_ERR, "send failed: %d:%d: %m", __FILE__, __LINE__); return -1; } + + syslog(LOG_NOTICE, "Connection with %s activated.", cl->hostname); cp return 0; } int send_termreq(conn_list_t *cl) { - termreq_t tmp; cp - memset(&tmp, 0, sizeof(tmp)); - tmp.type = TERMREQ; - tmp.vpn_ip = myself->vpn_ip; - if(debug_lvl > 2) - syslog(LOG_DEBUG, "Send TERMREQ(" IP_ADDR_S ") to " IP_ADDR_S, IP_ADDR_V(tmp.vpn_ip), + syslog(LOG_DEBUG, "Send TERMREQ to " IP_ADDR_S, IP_ADDR_V(cl->vpn_ip)); - if((write(cl->meta_socket, &tmp, sizeof(tmp))) < 0) + buflen = sprintf(buffer, "%d %lx\n", TERMREQ, myself->vpn_ip); + + if((write(cl->meta_socket, buffer, buflen)) < 0) { syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__); return -1; @@ -74,17 +77,14 @@ cp int send_timeout(conn_list_t *cl) { - termreq_t tmp; cp - memset(&tmp, 0, sizeof(tmp)); - tmp.type = PINGTIMEOUT; - tmp.vpn_ip = myself->vpn_ip; - if(debug_lvl > 2) - syslog(LOG_DEBUG, "Send TIMEOUT(" IP_ADDR_S ") to " IP_ADDR_S, IP_ADDR_V(tmp.vpn_ip), + syslog(LOG_DEBUG, "Send TIMEOUT to " IP_ADDR_S, IP_ADDR_V(cl->vpn_ip)); - if((write(cl->meta_socket, &tmp, sizeof(tmp))) < 0) + buflen = sprintf(buffer, "%d %lx\n", PINGTIMEOUT, myself->vpn_ip); + + if((write(cl->meta_socket, buffer, buflen)) < 0) { syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__); return -1; @@ -95,17 +95,14 @@ cp int send_del_host(conn_list_t *cl, conn_list_t *new_host) { - del_host_t tmp; cp - memset(&tmp, 0, sizeof(tmp)); - tmp.type = DEL_HOST; - tmp.vpn_ip = new_host->vpn_ip; - if(debug_lvl > 2) - syslog(LOG_DEBUG, "Sending delete host %lx to " IP_ADDR_S, - tmp.vpn_ip, IP_ADDR_V(cl->vpn_ip)); + syslog(LOG_DEBUG, "Sending delete host " IP_ADDR_S " to " IP_ADDR_S, + IP_ADDR_V(new_host->vpn_ip), IP_ADDR_V(cl->vpn_ip)); + + buflen = sprintf(buffer, "%d %lx\n", DEL_HOST, new_host->vpn_ip); - if((write(cl->meta_socket, &tmp, sizeof(tmp))) < 0) + if((write(cl->meta_socket, buffer, buflen)) < 0) { syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__); return -1; @@ -116,12 +113,13 @@ cp int send_ping(conn_list_t *cl) { - unsigned char tmp = PING; cp if(debug_lvl > 3) syslog(LOG_DEBUG, "pinging " IP_ADDR_S, IP_ADDR_V(cl->vpn_ip)); - if((write(cl->meta_socket, &tmp, sizeof(tmp))) < 0) + buflen = sprintf(buffer, "%d\n", PING); + + if((write(cl->meta_socket, buffer, buflen)) < 0) { syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__); return -1; @@ -132,9 +130,10 @@ cp int send_pong(conn_list_t *cl) { - unsigned char tmp = PONG; cp - if((write(cl->meta_socket, &tmp, sizeof(tmp))) < 0) + buflen = sprintf(buffer, "%d\n", PONG); + + if((write(cl->meta_socket, buffer, buflen)) < 0) { syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__); return -1; @@ -145,21 +144,14 @@ cp int send_add_host(conn_list_t *cl, conn_list_t *new_host) { - add_host_t tmp; cp - memset(&tmp, 0, sizeof(tmp)); - tmp.type = ADD_HOST; - tmp.real_ip = new_host->real_ip; - tmp.vpn_ip = new_host->vpn_ip; - tmp.vpn_mask = new_host->vpn_mask; - tmp.portnr = new_host->port; - if(debug_lvl > 2) - syslog(LOG_DEBUG, "Sending add host (%lx/%lx %lx:%hd) to " IP_ADDR_S, - tmp.vpn_ip, tmp.vpn_mask, tmp.real_ip, tmp.portnr, + syslog(LOG_DEBUG, "Sending add host to " IP_ADDR_S, IP_ADDR_V(cl->vpn_ip)); - if((write(cl->meta_socket, &tmp, sizeof(tmp))) < 0) + buflen = sprintf(buffer, "%d %lx %lx/%lx:%x\n", ADD_HOST, new_host->real_ip, new_host->vpn_ip, new_host->vpn_mask, new_host->port); + + if((write(cl->meta_socket, buffer, buflen)) < 0) { syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__); return -1; @@ -170,17 +162,14 @@ cp int send_key_changed(conn_list_t *cl, conn_list_t *src) { - key_changed_t tmp; cp - memset(&tmp, 0, sizeof(tmp)); - tmp.type = KEY_CHANGED; - tmp.from = src->vpn_ip; - if(debug_lvl > 2) - syslog(LOG_DEBUG, "Sending KEY_CHANGED (%lx) to " IP_ADDR_S, - tmp.from, IP_ADDR_V(cl->vpn_ip)); + syslog(LOG_DEBUG, "Sending KEY_CHANGED to " IP_ADDR_S, + IP_ADDR_V(cl->vpn_ip)); - if((write(cl->meta_socket, &tmp, sizeof(tmp))) < 0) + buflen = sprintf(buffer, "%d %lx\n", KEY_CHANGED, src->vpn_ip); + + if((write(cl->meta_socket, buffer, buflen)) < 0) { syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__); return -1; @@ -201,22 +190,14 @@ cp int send_basic_info(conn_list_t *cl) { - basic_info_t tmp; cp - memset(&tmp, 0, sizeof(tmp)); - tmp.type = BASIC_INFO; - tmp.protocol = PROT_CURRENT; - - tmp.portnr = myself->port; - tmp.vpn_ip = myself->vpn_ip; - tmp.vpn_mask = myself->vpn_mask; - if(debug_lvl > 2) - syslog(LOG_DEBUG, "Send BASIC_INFO(%d,%hd," IP_ADDR_S "," IP_ADDR_S ") to " IP_ADDR_S, - tmp.protocol, tmp.portnr, IP_ADDR_V(tmp.vpn_ip), IP_ADDR_V(tmp.vpn_mask), + syslog(LOG_DEBUG, "Send BASIC_INFO to " IP_ADDR_S, IP_ADDR_V(cl->real_ip)); - if((write(cl->meta_socket, &tmp, sizeof(tmp))) < 0) + buflen = sprintf(buffer, "%d %d %lx/%lx:%x\n", BASIC_INFO, PROT_CURRENT, myself->vpn_ip, myself->vpn_mask, myself->port); + + if((write(cl->meta_socket, buffer, buflen)) < 0) { syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__); return -1; @@ -229,15 +210,15 @@ int send_passphrase(conn_list_t *cl) { passphrase_t tmp; cp - memset(&tmp, 0, sizeof(tmp)); - tmp.type = PASSPHRASE; encrypt_passphrase(&tmp); if(debug_lvl > 2) - syslog(LOG_DEBUG, "Send PASSPHRASE(%hd,...) to " IP_ADDR_S, tmp.len, + syslog(LOG_DEBUG, "Send PASSPHRASE to " IP_ADDR_S, IP_ADDR_V(cl->vpn_ip)); - if((write(cl->meta_socket, &tmp, tmp.len+3)) < 0) + buflen = sprintf(buffer, "%d %s\n", PASSPHRASE, tmp.phrase); + + if((write(cl->meta_socket, buffer, buflen)) < 0) { syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__); return -1; @@ -248,19 +229,14 @@ cp int send_public_key(conn_list_t *cl) { - public_key_t *tmp; cp - tmp = (public_key_t*)xmalloc(strlen(my_public_key_base36)+sizeof(*tmp)); - memset(tmp, 0, sizeof(*tmp)); - tmp->type = PUBLIC_KEY; - tmp->len = strlen(my_public_key_base36); - strcpy(&tmp->key, my_public_key_base36); - if(debug_lvl > 2) - syslog(LOG_DEBUG, "Send PUBLIC_KEY(%hd,%s) to " IP_ADDR_S, tmp->len, &tmp->key, + syslog(LOG_DEBUG, "Send PUBLIC_KEY to " IP_ADDR_S, IP_ADDR_V(cl->vpn_ip)); - if((write(cl->meta_socket, tmp, tmp->len+sizeof(*tmp))) < 0) + buflen = sprintf(buffer, "%d %s\n", PUBLIC_KEY, my_public_key_base36); + + if((write(cl->meta_socket, buffer, buflen)) < 0) { syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__); return -1; @@ -271,15 +247,10 @@ cp int send_calculate(conn_list_t *cl, char *k) { - calculate_t *tmp; cp - tmp = xmalloc(strlen(k)+sizeof(*tmp)); - memset(tmp, 0, sizeof(*tmp)); - tmp->type = CALCULATE; - tmp->len = strlen(k); - strcpy(&tmp->key, k); + buflen = sprintf(buffer, "%d %s\n", CALCULATE, k); - if((write(cl->meta_socket, tmp, tmp->len+sizeof(*tmp))) < 0) + if((write(cl->meta_socket, buffer, buflen)) < 0) { syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__); return -1; @@ -290,16 +261,8 @@ cp int send_key_request(ip_t to) { - key_req_t *tmp; conn_list_t *fw; cp - tmp = xmalloc(sizeof(*tmp)); - memset(tmp, 0, sizeof(*tmp)); - tmp->type = REQ_KEY; - tmp->to = to; - tmp->from = myself->vpn_ip; - tmp->len = 0; - fw = lookup_conn(to); if(!fw) { @@ -311,7 +274,10 @@ cp if(debug_lvl > 2) syslog(LOG_DEBUG, "Sending out request for public key to " IP_ADDR_S, IP_ADDR_V(fw->nexthop->vpn_ip)); - if(write(fw->nexthop->meta_socket, tmp, sizeof(*tmp)) < 0) + + buflen = sprintf(buffer, "%d %lx %lx\n", REQ_KEY, to, myself->vpn_ip); + + if((write(fw->nexthop->meta_socket, buffer, buflen)) < 0) { syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__); return -1; @@ -323,17 +289,8 @@ cp int send_key_answer(conn_list_t *cl, ip_t to) { - key_req_t *tmp; conn_list_t *fw; cp - tmp = xmalloc(sizeof(*tmp)+strlen(my_public_key_base36)); - memset(tmp, 0, sizeof(*tmp)); - tmp->type = ANS_KEY; - tmp->to = to; - tmp->from = myself->vpn_ip; - tmp->expiry = my_key_expiry; - tmp->len = strlen(my_public_key_base36); - strcpy(&(tmp->key), my_public_key_base36); fw = lookup_conn(to); @@ -344,12 +301,13 @@ cp return -1; } -cp if(debug_lvl > 2) syslog(LOG_DEBUG, "Sending public key to " IP_ADDR_S, IP_ADDR_V(fw->nexthop->vpn_ip)); -cp - if(write(fw->nexthop->meta_socket, tmp, sizeof(*tmp)+tmp->len) < 0) + + buflen = sprintf(buffer, "%d %lx %lx %d %s\n", ANS_KEY, to, myself->vpn_ip, my_key_expiry, my_public_key_base36); + + if((write(fw->nexthop->meta_socket, buffer, buflen)) < 0) { syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__); return -1; @@ -369,7 +327,7 @@ int notify_others(conn_list_t *new, conn_list_t *source, conn_list_t *p; cp for(p = conn_list; p != NULL; p = p->next) - if(p != new && p != source && p->status.meta && p->protocol_version > PROT_3) + if(p != new && p != source && p->status.meta) function(p, new); cp return 0; @@ -396,22 +354,16 @@ cp int basic_info_h(conn_list_t *cl) { - basic_info_t tmp; cp - if(read(cl->meta_socket, &((char*)(&tmp))[1], sizeof(tmp)-1) <= 0) + if(sscanf(cl->buffer, "%*d %d %lx/%lx:%hx", &cl->protocol_version, &cl->vpn_ip, &cl->vpn_mask, &cl->port) != 4) { - syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__); - return -1; - } + syslog(LOG_ERR, "got bad BASIC_INFO request: %s", cl->buffer); + return -1; + } - cl->protocol_version = tmp.protocol; - cl->port = tmp.portnr; - cl->vpn_ip = tmp.vpn_ip; - cl->vpn_mask = tmp.vpn_mask; - - if(cl->protocol_version < PROT_CURRENT) + if(cl->protocol_version != PROT_CURRENT) { - syslog(LOG_ERR, "Peer uses protocol version %d which is too old.", + syslog(LOG_ERR, "Peer uses incompatible protocol version %d.", cl->protocol_version); return -1; } @@ -443,32 +395,15 @@ cp int passphrase_h(conn_list_t *cl) { - char unused; - unsigned short int len; cp - if(read(cl->meta_socket, &unused, sizeof(unused)) <= 0) - { - syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__); - return -1; - } - - if(read(cl->meta_socket, &len, sizeof(len)) <= 0) - { - syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__); - return -1; - } - - cl->pp = xmalloc(len+4); - - cl->pp->len = len; - if(read(cl->meta_socket, &(cl->pp->phrase), len) <= 0) + if(sscanf(cl->buffer, "%*d %s", cl->pp) != 1) { - syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__); - return -1; - } - + syslog(LOG_ERR, "got bad PASSPHRASE request: %s", cl->buffer); + return -1; + } + if(debug_lvl > 2) - syslog(LOG_DEBUG, "got PASSPHRASE(%hd,...)", len); + syslog(LOG_DEBUG, "got PASSPHRASE"); if(cl->status.outgoing) send_passphrase(cl); @@ -481,30 +416,15 @@ cp int public_key_h(conn_list_t *cl) { char *g_n; - unsigned short int len; - char unused; cp - if(read(cl->meta_socket, &unused, sizeof(unused)) <= 0) - { - syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__); - return -1; - } - if(read(cl->meta_socket, &len, sizeof(len)) <= 0) + if(sscanf(cl->buffer, "%*d %as", &g_n) != 1) { - syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__); - return -1; - } - - g_n = xmalloc(len+2); - - if(read(cl->meta_socket, g_n, len+2) <= 0) - { - syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__); - return -1; - } + syslog(LOG_ERR, "got bad PUBLIC_KEY request: %s", cl->buffer); + return -1; + } if(debug_lvl > 2) - syslog(LOG_DEBUG, "got PUBLIC_KEY(%hd,%s)", len, g_n); + syslog(LOG_DEBUG, "got PUBLIC_KEY"); if(verify_passphrase(cl, g_n)) { @@ -564,23 +484,23 @@ cp int del_host_h(conn_list_t *cl) { - del_host_t tmp; + ip_t vpn_ip; conn_list_t *fw; cp - if(read(cl->meta_socket, &((char*)(&tmp))[1], sizeof(tmp)-1) <= 0) + if(sscanf(cl->buffer, "%*d %lx", &vpn_ip) != 1) { - syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__); - return -1; - } + syslog(LOG_ERR, "got bad DEL_HOST request: %s", cl->buffer); + return -1; + } if(debug_lvl > 2) syslog(LOG_DEBUG, "got DEL_HOST for " IP_ADDR_S, - IP_ADDR_V(tmp.vpn_ip)); + IP_ADDR_V(vpn_ip)); - if(!(fw = lookup_conn(tmp.vpn_ip))) + if(!(fw = lookup_conn(vpn_ip))) { syslog(LOG_ERR, "Somebody wanted to delete " IP_ADDR_S " which does not exist?", - IP_ADDR_V(tmp.vpn_ip)); + IP_ADDR_V(vpn_ip)); return 0; } @@ -617,36 +537,39 @@ cp int add_host_h(conn_list_t *cl) { - add_host_t tmp; + ip_t real_ip; + ip_t vpn_ip; + ip_t vpn_mask; + unsigned short port; conn_list_t *ncn, *fw; cp - if(read(cl->meta_socket, &((char*)(&tmp))[1], sizeof(tmp)-1) <= 0) + if(sscanf(cl->buffer, "%*d %lx %lx/%lx:%hx", &real_ip, &vpn_ip, &vpn_mask, &port) != 4) { - syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__); - return -1; - } + syslog(LOG_ERR, "got bad ADD_HOST request: %s", cl->buffer); + return -1; + } if(debug_lvl > 2) syslog(LOG_DEBUG, "Add host request from " IP_ADDR_S, IP_ADDR_V(cl->vpn_ip)); if(debug_lvl > 3) syslog(LOG_DEBUG, "got ADD_HOST(" IP_ADDR_S "," IP_ADDR_S ",%hd)", - IP_ADDR_V(tmp.vpn_ip), IP_ADDR_V(tmp.vpn_mask), tmp.portnr); + IP_ADDR_V(vpn_ip), IP_ADDR_V(vpn_mask), port); /* Suggestion of Hans Bayle */ - if((fw = lookup_conn(tmp.vpn_ip))) + if((fw = lookup_conn(vpn_ip))) { notify_others(fw, cl, send_add_host); return 0; } ncn = new_conn_list(); - ncn->real_ip = tmp.real_ip; - ncn->vpn_ip = tmp.vpn_ip; - ncn->vpn_mask = tmp.vpn_mask; - ncn->port = tmp.portnr; - ncn->hostname = hostlookup(tmp.real_ip); + ncn->real_ip = real_ip; + ncn->vpn_ip = vpn_ip; + ncn->vpn_mask = vpn_mask; + ncn->port = port; + ncn->hostname = hostlookup(real_ip); ncn->nexthop = cl; ncn->next = conn_list; conn_list = ncn; @@ -658,31 +581,32 @@ cp int req_key_h(conn_list_t *cl) { - key_req_t tmp; + ip_t to; + ip_t from; conn_list_t *fw; cp - if(read(cl->meta_socket, &((char*)(&tmp))[1], sizeof(tmp)-1) <= 0) + if(sscanf(cl->buffer, "%*d %lx %lx", &to, &from) != 2) { - syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__); - return -1; - } + syslog(LOG_ERR, "got bad request: %s", cl->buffer); + return -1; + } if(debug_lvl > 2) syslog(LOG_DEBUG, "got REQ_KEY from " IP_ADDR_S " for " IP_ADDR_S, - IP_ADDR_V(tmp.from), IP_ADDR_V(tmp.to)); + IP_ADDR_V(from), IP_ADDR_V(to)); - if((tmp.to & myself->vpn_mask) == (myself->vpn_ip & myself->vpn_mask)) + if((to & myself->vpn_mask) == (myself->vpn_ip & myself->vpn_mask)) { /* hey! they want something from ME! :) */ - send_key_answer(cl, tmp.from); + send_key_answer(cl, from); return 0; } - fw = lookup_conn(tmp.to); + fw = lookup_conn(to); if(!fw) { syslog(LOG_ERR, "Attempting to forward key request to " IP_ADDR_S ", which does not exist?", - IP_ADDR_V(tmp.to)); + IP_ADDR_V(to)); return -1; } @@ -690,9 +614,7 @@ cp syslog(LOG_DEBUG, "Forwarding request for public key to " IP_ADDR_S, IP_ADDR_V(fw->nexthop->vpn_ip)); - tmp.type = REQ_KEY; - tmp.key = 0; - if(write(fw->nexthop->meta_socket, &tmp, sizeof(tmp)) < 0) + if(write(fw->nexthop->meta_socket, cl->buffer, strlen(cl->buffer)) < 0) { syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__); return -1; @@ -701,7 +623,7 @@ cp return 0; } -void set_keys(conn_list_t *cl, key_req_t *k, char *key) +void set_keys(conn_list_t *cl, int expiry, char *key) { char *ek; cp @@ -710,92 +632,84 @@ cp cl->public_key = xmalloc(sizeof(*cl->key)); cl->public_key->key = NULL; } + if(cl->public_key->key) free(cl->public_key->key); - cl->public_key->length = k->len; - cl->public_key->expiry = k->expiry; - cl->public_key->key = xmalloc(k->len + 1); + cl->public_key->length = strlen(key); + cl->public_key->expiry = expiry; + cl->public_key->key = xmalloc(cl->public_key->length + 1); strcpy(cl->public_key->key, key); ek = make_shared_key(key); + if(!cl->key) { cl->key = xmalloc(sizeof(*cl->key)); cl->key->key = NULL; } + if(cl->key->key) free(cl->key->key); + cl->key->length = strlen(ek); - cl->key->expiry = k->expiry; - cl->key->key = xmalloc(strlen(ek) + 1); + cl->key->expiry = expiry; + cl->key->key = xmalloc(cl->key->length + 1); strcpy(cl->key->key, ek); cp } int ans_key_h(conn_list_t *cl) { - key_req_t tmp; - conn_list_t *fw, *gk; + ip_t to; + ip_t from; + int expiry; char *key; + conn_list_t *fw, *gk; cp - if(read(cl->meta_socket, &((char*)(&tmp))[1], sizeof(tmp) - 3) <= 0) + if(sscanf(cl->buffer, "%*d %lx %lx %d %as", &to, &from, &expiry, &key) != 4) { - syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__); - return -1; - } - - key = xmalloc(tmp.len); - - if(read(cl->meta_socket, key, tmp.len + 2) <= 0) - { - syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__); - return -1; - } - syslog(LOG_DEBUG, "%s", key); + syslog(LOG_ERR, "got bad ANS_KEY request: %s", cl->buffer); + return -1; + } if(debug_lvl > 3) syslog(LOG_DEBUG, "got ANS_KEY from " IP_ADDR_S " for " IP_ADDR_S, - IP_ADDR_V(tmp.from), IP_ADDR_V(tmp.to)); + IP_ADDR_V(from), IP_ADDR_V(to)); - if(tmp.to == myself->vpn_ip) + if(to == myself->vpn_ip) { /* hey! that key's for ME! :) */ if(debug_lvl > 2) syslog(LOG_DEBUG, "Yeah! key arrived. Now do something with it."); - gk = lookup_conn(tmp.from); + gk = lookup_conn(from); if(!gk) { syslog(LOG_ERR, "Receiving key from " IP_ADDR_S ", which does not exist?", - IP_ADDR_V(tmp.from)); + IP_ADDR_V(from)); return -1; } - set_keys(gk, &tmp, key); + set_keys(gk, expiry, key); gk->status.validkey = 1; gk->status.waitingforkey = 0; flush_queues(gk); return 0; } - fw = lookup_conn(tmp.to); + fw = lookup_conn(to); if(!fw) { syslog(LOG_ERR, "Attempting to forward key to " IP_ADDR_S ", which does not exist?", - IP_ADDR_V(tmp.to)); + IP_ADDR_V(to)); return -1; } if(debug_lvl > 2) syslog(LOG_DEBUG, "Forwarding public key to " IP_ADDR_S, IP_ADDR_V(fw->nexthop->vpn_ip)); - tmp.type = ANS_KEY; - if(write(fw->nexthop->meta_socket, &tmp, sizeof(tmp) - 2) < 0) - { - syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__); - return -1; - } - if(write(fw->nexthop->meta_socket, key, tmp.len + 2) < 0) + + if((write(fw->nexthop->meta_socket, cl->buffer, strlen(cl->buffer))) < 0) { syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__); return -1; @@ -806,25 +720,25 @@ cp int key_changed_h(conn_list_t *cl) { - key_changed_t tmp; + ip_t from; conn_list_t *ik; cp - if(read(cl->meta_socket, &((char*)(&tmp))[1], sizeof(tmp)-1) <= 0) + if(sscanf(cl->buffer, "%*d %lx", &from) != 1) { - syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__); - return -1; - } + syslog(LOG_ERR, "got bad ANS_KEY request: %s", cl->buffer); + return -1; + } if(debug_lvl > 2) syslog(LOG_DEBUG, "got KEY_CHANGED from " IP_ADDR_S, - IP_ADDR_V(tmp.from)); + IP_ADDR_V(from)); - ik = lookup_conn(tmp.from); + ik = lookup_conn(from); if(!ik) { syslog(LOG_ERR, "Got changed key from " IP_ADDR_S ", which does not exist?", - IP_ADDR_V(tmp.from)); + IP_ADDR_V(from)); return -1; } diff --git a/src/protocol.h b/src/protocol.h index 2713df9..b092681 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -27,6 +27,8 @@ enum { PROT_NOT_IN_USE, PROT_TOO_OLD = 2, PROT_3, + PROT_4, + PROT_ECHELON, PROT_CURRENT, /* protocol currently in use */ }; @@ -59,65 +61,6 @@ enum { KEY_CHANGED, /* public key has changed */ }; -typedef struct add_host_t { - unsigned char type; - char unused1; - ip_t real_ip; - ip_t vpn_ip; - ip_t vpn_mask; - unsigned short portnr; -} add_host_t; - -typedef struct termreq_t { - unsigned char type; - char unused1; - ip_t vpn_ip; -} termreq_t; - -typedef struct basic_info_t { - unsigned char type; - unsigned char protocol; - unsigned short portnr; - ip_t vpn_ip; - ip_t vpn_mask; -} basic_info_t; - -typedef struct calculate_t { - unsigned char type; - char unused1; - unsigned short len; - char key; -} calculate_t; - -typedef struct public_key_t { - unsigned char type; - char unused1; - unsigned short len; - char key; -} public_key_t; - -typedef struct key_req_t { - unsigned char type; - char unused1; - ip_t from; - ip_t to; - time_t expiry; - short int len; /* 0 if requesting */ - char key; -} key_req_t; - -typedef struct key_changed_t { - unsigned char type; - char unused1; - ip_t from; -} key_changed_t; - -typedef struct del_host_t { - unsigned char type; - char unused1; - ip_t vpn_ip; -} del_host_t; - extern int (*request_handlers[256])(conn_list_t*); extern int send_ping(conn_list_t*);