--- gvpe/src/connection.C 2013/07/18 13:35:16 1.102 +++ gvpe/src/connection.C 2013/07/18 17:35:10 1.103 @@ -554,12 +554,13 @@ struct config_packet : vpn_packet { + u8 serial[SERIAL_SIZE]; u8 prot_major, prot_minor, randsize; u8 flags, features, pad6, pad7, pad8; u32 cipher_nid, mac_nid, auth_nid; void setup (ptype type, int dst); - bool chk_config () const; + bool chk_config (const conf_node *conf, const sockinfo &rsi) const; static u8 get_features () { @@ -586,6 +587,8 @@ flags = 0; features = get_features (); + strncpy ((char *)serial, conf.serial, sizeof (serial)); + cipher_nid = htonl (EVP_CIPHER_nid (CIPHER ())); mac_nid = htonl (EVP_MD_type (MAC_DIGEST ())); auth_nid = htonl (EVP_MD_type (AUTH_DIGEST ())); @@ -595,20 +598,33 @@ } bool -config_packet::chk_config () const +config_packet::chk_config (const conf_node *conf, const sockinfo &rsi) const { if (prot_major != PROTOCOL_MAJOR) - slog (L_WARN, _("major version mismatch (remote %d <=> local %d)"), prot_major, PROTOCOL_MAJOR); + slog (L_WARN, _("%s(%s): major version mismatch (remote %d <=> local %d)"), + conf->nodename, (const char *)rsi, prot_major, PROTOCOL_MAJOR); else if (randsize != RAND_SIZE) - slog (L_WARN, _("rand size mismatch (remote %d <=> local %d)"), randsize, RAND_SIZE); + slog (L_WARN, _("%s(%s): rand size mismatch (remote %d <=> local %d)"), + conf->nodename, (const char *)rsi, randsize, RAND_SIZE); else if (cipher_nid != htonl (EVP_CIPHER_nid (CIPHER ()))) - slog (L_WARN, _("cipher algo mismatch (remote %x <=> local %x)"), ntohl (cipher_nid), EVP_CIPHER_nid (CIPHER ())); + slog (L_WARN, _("%s(%s): cipher algo mismatch (remote %x <=> local %x)"), + conf->nodename, (const char *)rsi, ntohl (cipher_nid), EVP_CIPHER_nid (CIPHER ())); else if (mac_nid != htonl (EVP_MD_type (MAC_DIGEST ()))) - slog (L_WARN, _("mac algo mismatch (remote %x <=> local %x)"), ntohl (mac_nid), EVP_MD_type (MAC_DIGEST ())); + slog (L_WARN, _("%s(%s): mac algo mismatch (remote %x <=> local %x)"), + conf->nodename, (const char *)rsi, ntohl (mac_nid), EVP_MD_type (MAC_DIGEST ())); else if (auth_nid != htonl (EVP_MD_type (AUTH_DIGEST ()))) - slog (L_WARN, _("auth algo mismatch (remote %x <=> local %x)"), ntohl (auth_nid), EVP_MD_type (AUTH_DIGEST ())); + slog (L_WARN, _("%s(%s): auth algo mismatch (remote %x <=> local %x)"), + conf->nodename, (const char *)rsi, ntohl (auth_nid), EVP_MD_type (AUTH_DIGEST ())); else - return true; + { + int cmp = memcmp (serial, ::conf.serial, sizeof (serial)); + + if (cmp > 0) + slog (L_WARN, _("%s(%s): remote serial newer than local serial - outdated config?"), + conf->nodename, (const char *)rsi); + else if (cmp == 0) + return true; + } return false; } @@ -632,13 +648,13 @@ } }; -struct auth_res_packet : config_packet // UNPROTECTED +struct auth_res_packet : vpn_packet // UNPROTECTED { auth_response response; auth_res_packet (int dst) { - config_packet::setup (PT_AUTH_RES, dst); + set_hdr (PT_AUTH_RES, dst); len = sizeof (*this) - sizeof (net_packet); } @@ -1058,13 +1074,7 @@ config_packet *p = (config_packet *) pkt; - if (!p->chk_config ()) - { - slog (L_WARN, _("%s(%s): protocol mismatch, disabling node."), - conf->nodename, (const char *)rsi); - connectmode = conf_node::C_DISABLED; - } - else if (connectmode == conf_node::C_ALWAYS) + if (p->chk_config (conf, rsi) && connectmode == conf_node::C_ALWAYS) establish_connection (); } break; @@ -1078,7 +1088,12 @@ conf->nodename, p->initiate ? "initiate" : "reply", p->protocols, p->features); - if (p->chk_config () && !memcmp (p->magic, MAGIC, 8)) + if (memcmp (p->magic, MAGIC, 8)) + { + slog (L_WARN, _("%s(%s): protocol magic mismatch - stray packet?"), + conf->nodename, (const char *)rsi); + } + else if (p->chk_config (conf, rsi)) { if (p->prot_minor != PROTOCOL_MINOR) slog (L_INFO, _("%s(%s): protocol minor version mismatch: ours is %d, %s's is %d."), @@ -1115,9 +1130,6 @@ break; } - else - slog (L_WARN, _("%s(%s): protocol mismatch."), - conf->nodename, (const char *)rsi); send_reset (rsi); } @@ -1130,29 +1142,20 @@ slog (L_TRACE, "%s >> PT_AUTH_RES", conf->nodename); - if (p->chk_config ()) + if (memcmp (&p->response.mac, snd_auth_mac, sizeof (snd_auth_mac))) { - if (memcmp (&p->response.mac, snd_auth_mac, sizeof (snd_auth_mac))) - { - slog (L_ERR, _("%s(%s): unrequested or outdated auth response, ignoring."), - conf->nodename, (const char *)rsi); - } - else if (!have_snd_auth) - { - if (p->prot_minor != PROTOCOL_MINOR) - slog (L_INFO, _("%s(%s): protocol minor version mismatch: ours is %d, %s's is %d."), - conf->nodename, (const char *)rsi, - PROTOCOL_MINOR, conf->nodename, p->prot_minor); - - prot_minor = p->prot_minor; - memcpy (snd_ecdh_b, p->response.ecdh, sizeof (snd_ecdh_b)); - - have_snd_auth = true; - connection_established (rsi); - } + slog (L_ERR, _("%s(%s): unrequested or outdated auth response, ignoring."), + conf->nodename, (const char *)rsi); + } + else if (!have_snd_auth) + { + memcpy (snd_ecdh_b, p->response.ecdh, sizeof (snd_ecdh_b)); - break; + have_snd_auth = true; + connection_established (rsi); } + + break; } send_reset (rsi);