e->to->via = indirect ? n->via : e->to;
e->to->options = e->options;
- if(sockaddrcmp(&e->to->address, &e->address)) {
- node = avl_unlink(node_udp_tree, e->to);
- sockaddrfree(&e->to->address);
- sockaddrcpy(&e->to->address, &e->address);
-
- if(e->to->hostname)
- free(e->to->hostname);
-
- e->to->hostname = sockaddr2hostname(&e->to->address);
-
- if(node)
- avl_insert_node(node_udp_tree, node);
-
- if(e->to->options & OPTION_PMTU_DISCOVERY) {
- e->to->mtuprobes = 0;
- e->to->minmtu = 0;
- e->to->maxmtu = MTU;
- if(e->to->status.validkey)
- send_mtu_probe(e->to);
- }
- }
+ if(e->to->address.sa.sa_family == AF_UNSPEC && e->address.sa.sa_family != AF_UNKNOWN)
+ update_node_udp(e->to, &e->address);
list_insert_tail(todo_list, e->to);
}
if(n->status.reachable) {
ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Node %s (%s) became reachable"),
n->name, n->hostname);
- avl_insert(node_udp_tree, n);
} else {
ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Node %s (%s) became unreachable"),
n->name, n->hostname);
- avl_delete(node_udp_tree, n);
}
+ /* TODO: only clear status.validkey if node is unreachable? */
+
n->status.validkey = false;
n->status.waitingforkey = false;
/* Should we regenerate our key? */
if(keyexpires < now) {
- ifdebug(STATUS) logger(LOG_INFO, _("Regenerating symmetric key"));
+ avl_node_t *node;
+ node_t *n;
+
+ ifdebug(STATUS) logger(LOG_INFO, _("Expiring symmetric keys"));
+
+ for(node = node_tree->head; node; node = node->next) {
+ n = node->data;
+ if(n->inkey) {
+ free(n->inkey);
+ n->inkey = NULL;
+ }
+ }
- RAND_pseudo_bytes((unsigned char *)myself->key, myself->keylength);
- if(myself->cipher)
- EVP_DecryptInit_ex(&packet_ctx, myself->cipher, NULL, (unsigned char *)myself->key, (unsigned char *)myself->key + myself->cipher->key_len);
send_key_changed(broadcast, myself);
keyexpires = now + keylifetime;
}
route(n, packet);
}
+static bool try_mac(const node_t *n, const vpn_packet_t *inpkt)
+{
+ unsigned char hmac[EVP_MAX_MD_SIZE];
+
+ if(!n->indigest || !n->inmaclength || !n->inkey || inpkt->len < sizeof inpkt->seqno + n->inmaclength)
+ return false;
+
+ HMAC(n->indigest, n->inkey, n->inkeylength, (unsigned char *) &inpkt->seqno, inpkt->len - n->inmaclength, (unsigned char *)hmac, NULL);
+
+ return !memcmp(hmac, (char *) &inpkt->seqno + inpkt->len - n->inmaclength, n->inmaclength);
+}
+
static void receive_udppacket(node_t *n, vpn_packet_t *inpkt)
{
vpn_packet_t pkt1, pkt2;
cp();
+ if(!n->inkey) {
+ ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Got packet from %s (%s) but he hasn't got our key yet"),
+ n->name, n->hostname);
+ return;
+ }
+
/* Check packet length */
- if(inpkt->len < sizeof(inpkt->seqno) + myself->maclength) {
+ if(inpkt->len < sizeof(inpkt->seqno) + n->inmaclength) {
ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Got too short packet from %s (%s)"),
n->name, n->hostname);
return;
/* Check the message authentication code */
- if(myself->digest && myself->maclength) {
- inpkt->len -= myself->maclength;
- HMAC(myself->digest, myself->key, myself->keylength,
+ if(n->indigest && n->inmaclength) {
+ inpkt->len -= n->inmaclength;
+ HMAC(n->indigest, n->inkey, n->inkeylength,
(unsigned char *) &inpkt->seqno, inpkt->len, (unsigned char *)hmac, NULL);
- if(memcmp(hmac, (char *) &inpkt->seqno + inpkt->len, myself->maclength)) {
+ if(memcmp(hmac, (char *) &inpkt->seqno + inpkt->len, n->inmaclength)) {
ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Got unauthenticated packet from %s (%s)"),
n->name, n->hostname);
return;
/* Decrypt the packet */
- if(myself->cipher) {
+ if(n->incipher) {
outpkt = pkt[nextpkt++];
- if(!EVP_DecryptInit_ex(&packet_ctx, NULL, NULL, NULL, NULL)
- || !EVP_DecryptUpdate(&packet_ctx, (unsigned char *) &outpkt->seqno, &outlen,
+ if(!EVP_DecryptInit_ex(&n->inctx, NULL, NULL, NULL, NULL)
+ || !EVP_DecryptUpdate(&n->inctx, (unsigned char *) &outpkt->seqno, &outlen,
(unsigned char *) &inpkt->seqno, inpkt->len)
- || !EVP_DecryptFinal_ex(&packet_ctx, (unsigned char *) &outpkt->seqno + outlen, &outpad)) {
+ || !EVP_DecryptFinal_ex(&n->inctx, (unsigned char *) &outpkt->seqno + outlen, &outpad)) {
ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Error decrypting packet from %s (%s): %s"),
n->name, n->hostname, ERR_error_string(ERR_get_error(), NULL));
return;
/* Decompress the packet */
- if(myself->compression) {
+ if(n->incompression) {
outpkt = pkt[nextpkt++];
- if((outpkt->len = uncompress_packet(outpkt->data, inpkt->data, inpkt->len, myself->compression)) < 0) {
+ if((outpkt->len = uncompress_packet(outpkt->data, inpkt->data, inpkt->len, n->incompression)) < 0) {
ifdebug(TRAFFIC) logger(LOG_ERR, _("Error while uncompressing packet from %s (%s)"),
n->name, n->hostname);
return;
n->name, n->hostname);
if(!n->status.waitingforkey)
- send_req_key(n->nexthop->connection, myself, n);
+ send_req_key(n);
n->status.waitingforkey = true;
n->name, n->hostname);
send_tcppacket(n->nexthop->connection, origpkt);
+
+ return;
}
origlen = inpkt->len;
/* Compress the packet */
- if(n->compression) {
+ if(n->outcompression) {
outpkt = pkt[nextpkt++];
- if((outpkt->len = compress_packet(outpkt->data, inpkt->data, inpkt->len, n->compression)) < 0) {
+ if((outpkt->len = compress_packet(outpkt->data, inpkt->data, inpkt->len, n->outcompression)) < 0) {
ifdebug(TRAFFIC) logger(LOG_ERR, _("Error while compressing packet to %s (%s)"),
n->name, n->hostname);
return;
/* Encrypt the packet */
- if(n->cipher) {
+ if(n->outcipher) {
outpkt = pkt[nextpkt++];
- if(!EVP_EncryptInit_ex(&n->packet_ctx, NULL, NULL, NULL, NULL)
- || !EVP_EncryptUpdate(&n->packet_ctx, (unsigned char *) &outpkt->seqno, &outlen,
+ if(!EVP_EncryptInit_ex(&n->outctx, NULL, NULL, NULL, NULL)
+ || !EVP_EncryptUpdate(&n->outctx, (unsigned char *) &outpkt->seqno, &outlen,
(unsigned char *) &inpkt->seqno, inpkt->len)
- || !EVP_EncryptFinal_ex(&n->packet_ctx, (unsigned char *) &outpkt->seqno + outlen, &outpad)) {
+ || !EVP_EncryptFinal_ex(&n->outctx, (unsigned char *) &outpkt->seqno + outlen, &outpad)) {
ifdebug(TRAFFIC) logger(LOG_ERR, _("Error while encrypting packet to %s (%s): %s"),
n->name, n->hostname, ERR_error_string(ERR_get_error(), NULL));
goto end;
/* Add the message authentication code */
- if(n->digest && n->maclength) {
- HMAC(n->digest, n->key, n->keylength, (unsigned char *) &inpkt->seqno,
+ if(n->outdigest && n->outmaclength) {
+ HMAC(n->outdigest, n->outkey, n->outkeylength, (unsigned char *) &inpkt->seqno,
inpkt->len, (unsigned char *) &inpkt->seqno + inpkt->len, NULL);
- inpkt->len += n->maclength;
+ inpkt->len += n->outmaclength;
}
/* Determine which socket we have to use */
}
}
+static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) {
+ avl_node_t *node;
+ edge_t *e;
+ node_t *n = NULL;
+
+ for(node = edge_weight_tree->head; node; node = node->next) {
+ e = node->data;
+
+ if(sockaddrcmp_noport(from, &e->address))
+ continue;
+
+ if(!n)
+ n = e->to;
+
+ if(!try_mac(e->to, pkt))
+ continue;
+
+ n = e->to;
+ break;
+ }
+
+ return n;
+}
+
void handle_incoming_vpn_data(int sock)
{
vpn_packet_t pkt;
n = lookup_node_udp(&from);
if(!n) {
- hostname = sockaddr2hostname(&from);
- logger(LOG_WARNING, _("Received UDP packet from unknown source %s"),
- hostname);
- free(hostname);
- return;
+ n = try_harder(&from, &pkt);
+ if(n)
+ update_node_udp(n, &from);
+ else {
+ hostname = sockaddr2hostname(&from);
+ logger(LOG_WARNING, _("Received UDP packet from unknown source %s"), hostname);
+ free(hostname);
+ return;
+ }
}
receive_udppacket(n, &pkt);
if(get_config_string
(lookup_config(myself->connection->config_tree, "Cipher"), &cipher)) {
if(!strcasecmp(cipher, "none")) {
- myself->cipher = NULL;
+ myself->incipher = NULL;
} else {
- myself->cipher = EVP_get_cipherbyname(cipher);
+ myself->incipher = EVP_get_cipherbyname(cipher);
- if(!myself->cipher) {
+ if(!myself->incipher) {
logger(LOG_ERR, _("Unrecognized cipher type!"));
return false;
}
}
} else
- myself->cipher = EVP_bf_cbc();
+ myself->incipher = EVP_bf_cbc();
- if(myself->cipher)
- myself->keylength = myself->cipher->key_len + myself->cipher->iv_len;
+ if(myself->incipher)
+ myself->inkeylength = myself->incipher->key_len + myself->incipher->iv_len;
else
- myself->keylength = 1;
+ myself->inkeylength = 1;
myself->connection->outcipher = EVP_bf_ofb();
- myself->key = xmalloc(myself->keylength);
- RAND_pseudo_bytes((unsigned char *)myself->key, myself->keylength);
-
if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime))
keylifetime = 3600;
keyexpires = now + keylifetime;
- if(myself->cipher) {
- EVP_CIPHER_CTX_init(&packet_ctx);
- if(!EVP_DecryptInit_ex(&packet_ctx, myself->cipher, NULL, (unsigned char *)myself->key, (unsigned char *)myself->key + myself->cipher->key_len)) {
- logger(LOG_ERR, _("Error during initialisation of cipher for %s (%s): %s"),
- myself->name, myself->hostname, ERR_error_string(ERR_get_error(), NULL));
- return false;
- }
-
- }
-
/* Check if we want to use message authentication codes... */
- if(get_config_string
- (lookup_config(myself->connection->config_tree, "Digest"), &digest)) {
+ if(get_config_string(lookup_config(myself->connection->config_tree, "Digest"), &digest)) {
if(!strcasecmp(digest, "none")) {
- myself->digest = NULL;
+ myself->indigest = NULL;
} else {
- myself->digest = EVP_get_digestbyname(digest);
+ myself->indigest = EVP_get_digestbyname(digest);
- if(!myself->digest) {
+ if(!myself->indigest) {
logger(LOG_ERR, _("Unrecognized digest type!"));
return false;
}
}
} else
- myself->digest = EVP_sha1();
+ myself->indigest = EVP_sha1();
myself->connection->outdigest = EVP_sha1();
- if(get_config_int(lookup_config(myself->connection->config_tree, "MACLength"),
- &myself->maclength)) {
- if(myself->digest) {
- if(myself->maclength > myself->digest->md_size) {
+ if(get_config_int(lookup_config(myself->connection->config_tree, "MACLength"), &myself->inmaclength)) {
+ if(myself->indigest) {
+ if(myself->inmaclength > myself->indigest->md_size) {
logger(LOG_ERR, _("MAC length exceeds size of digest!"));
return false;
- } else if(myself->maclength < 0) {
+ } else if(myself->inmaclength < 0) {
logger(LOG_ERR, _("Bogus MAC length!"));
return false;
}
}
} else
- myself->maclength = 4;
+ myself->inmaclength = 4;
myself->connection->outmaclength = 0;
/* Compression */
- if(get_config_int(lookup_config(myself->connection->config_tree, "Compression"),
- &myself->compression)) {
- if(myself->compression < 0 || myself->compression > 11) {
+ if(get_config_int(lookup_config(myself->connection->config_tree, "Compression"), &myself->incompression)) {
+ if(myself->incompression < 0 || myself->incompression > 11) {
logger(LOG_ERR, _("Bogus compression level!"));
return false;
}
} else
- myself->compression = 0;
+ myself->incompression = 0;
myself->connection->outcompression = 0;
return str;
}
+int sockaddrcmp_noport(const sockaddr_t *a, const sockaddr_t *b)
+{
+ int result;
+
+ cp();
+
+ result = a->sa.sa_family - b->sa.sa_family;
+
+ if(result)
+ return result;
+
+ switch (a->sa.sa_family) {
+ case AF_UNSPEC:
+ return 0;
+
+ case AF_UNKNOWN:
+ return strcmp(a->unknown.address, b->unknown.address);
+
+ case AF_INET:
+ return memcmp(&a->in.sin_addr, &b->in.sin_addr, sizeof(a->in.sin_addr));
+
+ case AF_INET6:
+ return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr));
+
+ default:
+ logger(LOG_ERR, _("sockaddrcmp() was called with unknown address family %d, exitting!"),
+ a->sa.sa_family);
+ cp_trace();
+ raise(SIGFPE);
+ exit(0);
+ }
+}
+
int sockaddrcmp(const sockaddr_t *a, const sockaddr_t *b)
{
int result;
static int node_udp_compare(const node_t *a, const node_t *b)
{
- int result;
-
- cp();
-
- result = sockaddrcmp(&a->address, &b->address);
-
- if(result)
- return result;
-
- return (a->name && b->name) ? strcmp(a->name, b->name) : 0;
+ return sockaddrcmp(&a->address, &b->address);
}
void init_nodes(void)
n->subnet_tree = new_subnet_tree();
n->edge_tree = new_edge_tree();
- EVP_CIPHER_CTX_init(&n->packet_ctx);
+ EVP_CIPHER_CTX_init(&n->inctx);
+ EVP_CIPHER_CTX_init(&n->outctx);
n->mtu = MTU;
n->maxmtu = MTU;
{
cp();
- if(n->key)
- free(n->key);
+ if(n->inkey)
+ free(n->inkey);
+
+ if(n->outkey)
+ free(n->outkey);
if(n->subnet_tree)
free_subnet_tree(n->subnet_tree);
sockaddrfree(&n->address);
- EVP_CIPHER_CTX_cleanup(&n->packet_ctx);
+ EVP_CIPHER_CTX_cleanup(&n->inctx);
+ EVP_CIPHER_CTX_cleanup(&n->outctx);
if(n->mtuevent)
event_del(n->mtuevent);
}
avl_delete(node_tree, n);
+ avl_delete(node_udp_tree, n);
}
node_t *lookup_node(char *name)
return avl_search(node_udp_tree, &n);
}
+void update_node_udp(node_t *n, const sockaddr_t *sa)
+{
+ avl_delete(node_udp_tree, n);
+
+ if(n->hostname)
+ free(n->hostname);
+
+ if(sa) {
+ n->address = *sa;
+ n->hostname = sockaddr2hostname(&n->address);
+ avl_delete(node_udp_tree, n);
+ avl_insert(node_udp_tree, n);
+ logger(LOG_DEBUG, "UDP address of %s set to %s", n->name, n->hostname);
+ } else {
+ memset(&n->address, 0, sizeof n->address);
+ logger(LOG_DEBUG, "UDP address of %s cleared", n->name);
+ }
+}
+
void dump_nodes(void)
{
avl_node_t *node;
for(node = node_tree->head; node; node = node->next) {
n = node->data;
logger(LOG_DEBUG, _(" %s at %s cipher %d digest %d maclength %d compression %d options %lx status %04x nexthop %s via %s pmtu %d (min %d max %d)"),
- n->name, n->hostname, n->cipher ? n->cipher->nid : 0,
- n->digest ? n->digest->type : 0, n->maclength, n->compression,
+ n->name, n->hostname, n->outcipher ? n->outcipher->nid : 0,
+ n->outdigest ? n->outdigest->type : 0, n->outmaclength, n->outcompression,
n->options, *(uint32_t *)&n->status, n->nexthop ? n->nexthop->name : "-",
n->via ? n->via->name : "-", n->mtu, n->minmtu, n->maxmtu);
}
node_status_t status;
- const EVP_CIPHER *cipher; /* Cipher type for UDP packets */
- char *key; /* Cipher key and iv */
- int keylength; /* Cipher key and iv length */
- EVP_CIPHER_CTX packet_ctx; /* Cipher context */
+ const EVP_CIPHER *incipher; /* Cipher type for UDP packets received from him */
+ char *inkey; /* Cipher key and iv */
+ int inkeylength; /* Cipher key and iv length */
+ EVP_CIPHER_CTX inctx; /* Cipher context */
- const EVP_MD *digest; /* Digest type for MAC */
- int maclength; /* Length of MAC */
+ const EVP_CIPHER *outcipher; /* Cipher type for UDP packets sent to him*/
+ char *outkey; /* Cipher key and iv */
+ int outkeylength; /* Cipher key and iv length */
+ EVP_CIPHER_CTX outctx; /* Cipher context */
+
+ const EVP_MD *indigest; /* Digest type for MAC of packets received from him */
+ int inmaclength; /* Length of MAC */
+
+ const EVP_MD *outdigest; /* Digest type for MAC of packets sent to him*/
+ int outmaclength; /* Length of MAC */
- int compression; /* Compressionlevel, 0 = no compression */
+ int incompression; /* Compressionlevel, 0 = no compression */
+ int outcompression; /* Compressionlevel, 0 = no compression */
struct node_t *nexthop; /* nearest node from us to him */
struct node_t *via; /* next hop for UDP packets */
extern void node_del(node_t *);
extern node_t *lookup_node(char *);
extern node_t *lookup_node_udp(const sockaddr_t *);
+extern void update_node_udp(node_t *, const sockaddr_t *);
extern void dump_nodes(void);
#endif /* __TINC_NODE_H__ */
extern bool send_del_subnet(struct connection_t *, const struct subnet_t *);
extern bool send_add_edge(struct connection_t *, const struct edge_t *);
extern bool send_del_edge(struct connection_t *, const struct edge_t *);
-extern bool send_key_changed(struct connection_t *, const struct node_t *);
-extern bool send_req_key(struct connection_t *, const struct node_t *, const struct node_t *);
-extern bool send_ans_key(struct connection_t *, const struct node_t *, const struct node_t *);
+extern bool send_key_changed();
+extern bool send_req_key(struct node_t *);
+extern bool send_ans_key(struct node_t *);
extern bool send_tcppacket(struct connection_t *, struct vpn_packet_t *);
/* Request handlers */
#include <openssl/evp.h>
#include <openssl/err.h>
+#include <openssl/rand.h>
#include "avl_tree.h"
#include "connection.h"
bool mykeyused = false;
-bool send_key_changed(connection_t *c, const node_t *n)
+bool send_key_changed()
{
cp();
This reduces unnecessary key_changed broadcasts.
*/
- if(n == myself && !mykeyused)
+ if(!mykeyused)
return true;
- return send_request(c, "%d %lx %s", KEY_CHANGED, random(), n->name);
+ return send_request(broadcast, "%d %lx %s", KEY_CHANGED, random(), myself->name);
}
bool key_changed_h(connection_t *c)
return true;
}
-bool send_req_key(connection_t *c, const node_t *from, const node_t *to)
+bool send_req_key(node_t *to)
{
cp();
- return send_request(c, "%d %s %s", REQ_KEY, from->name, to->name);
+ return send_request(to->nexthop->connection, "%d %s %s", REQ_KEY, myself->name, to->name);
}
bool req_key_h(connection_t *c)
mykeyused = true;
from->received_seqno = 0;
memset(from->late, 0, sizeof(from->late));
- send_ans_key(c, myself, from);
+ send_ans_key(from);
} else {
if(tunnelserver)
return false;
return true;
}
- send_req_key(to->nexthop->connection, from, to);
+ send_request(to->nexthop->connection, "%s", c->buffer);
}
return true;
}
-bool send_ans_key(connection_t *c, const node_t *from, const node_t *to)
+bool send_ans_key(node_t *to)
{
char *key;
cp();
- key = alloca(2 * from->keylength + 1);
- bin2hex(from->key, key, from->keylength);
- key[from->keylength * 2] = '\0';
+ if(!to->inkey) {
+ to->incipher = myself->incipher;
+ to->inkeylength = myself->inkeylength;
+ to->indigest = myself->indigest;
+ to->incompression = myself->incompression;
+ to->inkey = xmalloc(to->inkeylength);
- return send_request(c, "%d %s %s %s %d %d %d %d", ANS_KEY,
- from->name, to->name, key,
- from->cipher ? from->cipher->nid : 0,
- from->digest ? from->digest->type : 0, from->maclength,
- from->compression);
+ RAND_pseudo_bytes((unsigned char *)to->inkey, to->inkeylength);
+ if(to->incipher)
+ EVP_DecryptInit_ex(&packet_ctx, to->incipher, NULL, (unsigned char *)to->inkey, (unsigned char *)to->inkey + to->incipher->key_len);
+ }
+
+ key = alloca(2 * to->inkeylength + 1);
+ bin2hex(to->inkey, key, to->inkeylength);
+ key[to->outkeylength * 2] = '\0';
+
+ return send_request(to->nexthop->connection, "%d %s %s %s %d %d %d %d", ANS_KEY,
+ myself->name, to->name, key,
+ to->incipher ? to->incipher->nid : 0,
+ to->indigest ? to->indigest->type : 0, to->inmaclength,
+ to->incompression);
}
bool ans_key_h(connection_t *c)
/* Update our copy of the origin's packet key */
- if(from->key)
- free(from->key);
+ if(from->outkey)
+ free(from->outkey);
- from->key = xstrdup(key);
- from->keylength = strlen(key) / 2;
- hex2bin(from->key, from->key, from->keylength);
- from->key[from->keylength] = '\0';
+ from->outkey = xstrdup(key);
+ from->outkeylength = strlen(key) / 2;
+ hex2bin(from->outkey, from->outkey, from->outkeylength);
+ from->outkey[from->outkeylength] = '\0';
from->status.validkey = true;
from->status.waitingforkey = false;
/* Check and lookup cipher and digest algorithms */
if(cipher) {
- from->cipher = EVP_get_cipherbynid(cipher);
+ from->outcipher = EVP_get_cipherbynid(cipher);
- if(!from->cipher) {
+ if(!from->outcipher) {
logger(LOG_ERR, _("Node %s (%s) uses unknown cipher!"), from->name,
from->hostname);
return false;
}
- if(from->keylength != from->cipher->key_len + from->cipher->iv_len) {
+ if(from->outkeylength != from->outcipher->key_len + from->outcipher->iv_len) {
logger(LOG_ERR, _("Node %s (%s) uses wrong keylength!"), from->name,
from->hostname);
return false;
}
} else {
- from->cipher = NULL;
+ from->outcipher = NULL;
}
- from->maclength = maclength;
+ from->outmaclength = maclength;
if(digest) {
- from->digest = EVP_get_digestbynid(digest);
+ from->outdigest = EVP_get_digestbynid(digest);
- if(!from->digest) {
+ if(!from->outdigest) {
logger(LOG_ERR, _("Node %s (%s) uses unknown digest!"), from->name,
from->hostname);
return false;
}
- if(from->maclength > from->digest->md_size || from->maclength < 0) {
+ if(from->outmaclength > from->outdigest->md_size || from->outmaclength < 0) {
logger(LOG_ERR, _("Node %s (%s) uses bogus MAC length!"),
from->name, from->hostname);
return false;
}
} else {
- from->digest = NULL;
+ from->outdigest = NULL;
}
if(compression < 0 || compression > 11) {
return false;
}
- from->compression = compression;
+ from->outcompression = compression;
- if(from->cipher)
- if(!EVP_EncryptInit_ex(&from->packet_ctx, from->cipher, NULL, (unsigned char *)from->key, (unsigned char *)from->key + from->cipher->key_len)) {
+ if(from->outcipher)
+ if(!EVP_EncryptInit_ex(&from->outctx, from->outcipher, NULL, (unsigned char *)from->outkey, (unsigned char *)from->outkey + from->outcipher->key_len)) {
logger(LOG_ERR, _("Error during initialisation of key from %s (%s): %s"),
from->name, from->hostname, ERR_error_string(ERR_get_error(), NULL));
return false;