ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/connection.C
(Generate patch)

Comparing gvpe/src/connection.C (file contents):
Revision 1.17 by pcg, Mon Sep 1 21:23:35 2003 UTC vs.
Revision 1.24 by pcg, Wed Oct 22 01:05:23 2003 UTC

1/* 1/*
2 connection.C -- manage a single connection 2 connection.C -- manage a single connection
3 Copyright (C) 2003 Marc Lehmann <pcg@goof.com>
3 4
4 This program is free software; you can redistribute it and/or modify 5 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by 6 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or 7 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version. 8 (at your option) any later version.
35#include "slog.h" 36#include "slog.h"
36#include "device.h" 37#include "device.h"
37#include "vpn.h" 38#include "vpn.h"
38#include "connection.h" 39#include "connection.h"
39 40
41#include "netcompat.h"
42
40#if !HAVE_RAND_PSEUDO_BYTES 43#if !HAVE_RAND_PSEUDO_BYTES
41# define RAND_pseudo_bytes RAND_bytes 44# define RAND_pseudo_bytes RAND_bytes
42#endif 45#endif
43 46
44#define MAGIC "vped\xbd\xc6\xdb\x82" // 8 bytes of magic 47#define MAGIC "vped\xbd\xc6\xdb\x82" // 8 bytes of magic
476} 479}
477 480
478bool config_packet::chk_config () const 481bool config_packet::chk_config () const
479{ 482{
480 if (prot_major != PROTOCOL_MAJOR) 483 if (prot_major != PROTOCOL_MAJOR)
481 slog (L_WARN, _("major version mismatch (%d <=> %d)"), prot_major, PROTOCOL_MAJOR); 484 slog (L_WARN, _("major version mismatch (remote %d <=> local %d)"), prot_major, PROTOCOL_MAJOR);
482 else if (randsize != RAND_SIZE) 485 else if (randsize != RAND_SIZE)
483 slog (L_WARN, _("rand size mismatch (%d <=> %d)"), randsize, RAND_SIZE); 486 slog (L_WARN, _("rand size mismatch (remote %d <=> local %d)"), randsize, RAND_SIZE);
484 else if (hmaclen != HMACLENGTH) 487 else if (hmaclen != HMACLENGTH)
485 slog (L_WARN, _("hmac length mismatch (%d <=> %d)"), hmaclen, HMACLENGTH); 488 slog (L_WARN, _("hmac length mismatch (remote %d <=> local %d)"), hmaclen, HMACLENGTH);
486 else if (flags != curflags ()) 489 else if (flags != curflags ())
487 slog (L_WARN, _("flag mismatch (%x <=> %x)"), flags, curflags ()); 490 slog (L_WARN, _("flag mismatch (remote %x <=> local %x)"), flags, curflags ());
488 else if (challengelen != sizeof (rsachallenge)) 491 else if (challengelen != sizeof (rsachallenge))
489 slog (L_WARN, _("challenge length mismatch (%d <=> %d)"), challengelen, sizeof (rsachallenge)); 492 slog (L_WARN, _("challenge length mismatch (remote %d <=> local %d)"), challengelen, sizeof (rsachallenge));
490 else if (cipher_nid != htonl (EVP_CIPHER_nid (CIPHER))) 493 else if (cipher_nid != htonl (EVP_CIPHER_nid (CIPHER)))
491 slog (L_WARN, _("cipher mismatch (%x <=> %x)"), ntohl (cipher_nid), EVP_CIPHER_nid (CIPHER)); 494 slog (L_WARN, _("cipher mismatch (remote %x <=> local %x)"), ntohl (cipher_nid), EVP_CIPHER_nid (CIPHER));
492 else if (digest_nid != htonl (EVP_MD_type (RSA_HASH))) 495 else if (digest_nid != htonl (EVP_MD_type (RSA_HASH)))
493 slog (L_WARN, _("digest mismatch (%x <=> %x)"), ntohl (digest_nid), EVP_MD_type (RSA_HASH)); 496 slog (L_WARN, _("digest mismatch (remote %x <=> local %x)"), ntohl (digest_nid), EVP_MD_type (RSA_HASH));
494 else if (hmac_nid != htonl (EVP_MD_type (DIGEST))) 497 else if (hmac_nid != htonl (EVP_MD_type (DIGEST)))
495 slog (L_WARN, _("hmac mismatch (%x <=> %x)"), ntohl (hmac_nid), EVP_MD_type (DIGEST)); 498 slog (L_WARN, _("hmac mismatch (remote %x <=> local %x)"), ntohl (hmac_nid), EVP_MD_type (DIGEST));
496 else 499 else
497 return true; 500 return true;
498 501
499 return false; 502 return false;
500} 503}
672connection::send_auth_request (const sockinfo &si, bool initiate) 675connection::send_auth_request (const sockinfo &si, bool initiate)
673{ 676{
674 auth_req_packet *pkt = new auth_req_packet (conf->id, initiate, THISNODE->protocols); 677 auth_req_packet *pkt = new auth_req_packet (conf->id, initiate, THISNODE->protocols);
675 678
676 rsachallenge chg; 679 rsachallenge chg;
677
678 rsa_cache.gen (pkt->id, chg); 680 rsa_cache.gen (pkt->id, chg);
679 681 rsa_encrypt (conf->rsa_key, chg, pkt->encr);
680 if (0 > RSA_public_encrypt (sizeof chg,
681 (unsigned char *)&chg, (unsigned char *)&pkt->encr,
682 conf->rsa_key, RSA_PKCS1_OAEP_PADDING))
683 fatal ("RSA_public_encrypt error");
684 682
685 slog (L_TRACE, ">>%d PT_AUTH_REQ [%s]", conf->id, (const char *)si); 683 slog (L_TRACE, ">>%d PT_AUTH_REQ [%s]", conf->id, (const char *)si);
686 684
687 send_vpn_packet (pkt, si, IPTOS_RELIABILITY | IPTOS_LOWDELAY); // rsa is very very costly 685 send_vpn_packet (pkt, si, IPTOS_RELIABILITY | IPTOS_LOWDELAY); // rsa is very very costly
688 686
798 reset_connection (); 796 reset_connection ();
799 establish_connection (); 797 establish_connection ();
800} 798}
801 799
802void 800void
803connection::send_data_packet (tap_packet *pkt, bool broadcast) 801connection::send_data_packet (tap_packet *pkt)
804{ 802{
805 vpndata_packet *p = new vpndata_packet; 803 vpndata_packet *p = new vpndata_packet;
806 int tos = 0; 804 int tos = 0;
807 805
808 // I am not hilarious about peeking into packets, but so be it. 806 // I am not hilarious about peeking into packets, but so be it.
809 if (conf->inherit_tos 807 if (conf->inherit_tos && pkt->is_ipv4 ())
810 && (*pkt)[12] == 0x08 && (*pkt)[13] == 0x00 // IP
811 && ((*pkt)[14] & 0xf0) == 0x40) // IPv4
812 tos = (*pkt)[15] & IPTOS_TOS_MASK; 808 tos = (*pkt)[15] & IPTOS_TOS_MASK;
813 809
814 p->setup (this, broadcast ? 0 : conf->id, &((*pkt)[6 + 6]), pkt->len - 6 - 6, ++oseqno); // skip 2 macs 810 p->setup (this, conf->id, &((*pkt)[6 + 6]), pkt->len - 6 - 6, ++oseqno); // skip 2 macs
815 send_vpn_packet (p, si, tos); 811 send_vpn_packet (p, si, tos);
816 812
817 delete p; 813 delete p;
818 814
819 if (oseqno > MAX_SEQNO) 815 if (oseqno > MAX_SEQNO)
820 rekey (); 816 rekey ();
821} 817}
822 818
823void 819void
824connection::inject_data_packet (tap_packet *pkt, bool broadcast) 820connection::inject_data_packet (tap_packet *pkt, bool broadcast/*TODO DDD*/)
825{ 821{
826 if (ictx && octx) 822 if (ictx && octx)
827 send_data_packet (pkt, broadcast); 823 send_data_packet (pkt);
828 else 824 else
829 { 825 {
830 if (!broadcast)//DDDD 826 if (!broadcast)//DDDD
831 data_queue.put (new tap_packet (*pkt)); 827 data_queue.put (new tap_packet (*pkt));
832 828
907 if (p->initiate) 903 if (p->initiate)
908 send_auth_request (rsi, false); 904 send_auth_request (rsi, false);
909 905
910 rsachallenge k; 906 rsachallenge k;
911 907
912 if (0 > RSA_private_decrypt (sizeof (p->encr), 908 if (!rsa_decrypt (::conf.rsa_key, p->encr, k))
913 (unsigned char *)&p->encr, (unsigned char *)&k, 909 {
914 ::conf.rsa_key, RSA_PKCS1_OAEP_PADDING))
915 slog (L_ERR, _("%s(%s): challenge illegal or corrupted (%s). mismatched key or config file?"), 910 slog (L_ERR, _("%s(%s): challenge illegal or corrupted (%s). mismatched key or config file?"),
916 conf->nodename, (const char *)rsi, ERR_error_string (ERR_get_error (), 0)); 911 conf->nodename, (const char *)rsi, ERR_error_string (ERR_get_error (), 0));
912 break;
913 }
917 else 914 else
918 { 915 {
919 delete octx; 916 delete octx;
920 917
921 octx = new crypto_ctx (k, 1); 918 octx = new crypto_ctx (k, 1);
954 951
955 rsachallenge chg; 952 rsachallenge chg;
956 953
957 if (!rsa_cache.find (p->id, chg)) 954 if (!rsa_cache.find (p->id, chg))
958 { 955 {
959 slog (L_ERR, _("%s(%s): unrequested auth response"), 956 slog (L_ERR, _("%s(%s): unrequested auth response ignored"),
960 conf->nodename, (const char *)rsi); 957 conf->nodename, (const char *)rsi);
961 break; 958 break;
962 } 959 }
963 else 960 else
964 { 961 {
965 crypto_ctx *cctx = new crypto_ctx (chg, 0); 962 crypto_ctx *cctx = new crypto_ctx (chg, 0);
966 963
967 if (!p->hmac_chk (cctx)) 964 if (!p->hmac_chk (cctx))
965 {
968 slog (L_ERR, _("%s(%s): hmac authentication error on auth response, received invalid packet\n" 966 slog (L_ERR, _("%s(%s): hmac authentication error on auth response, received invalid packet\n"
969 "could be an attack, or just corruption or an synchronization error"), 967 "could be an attack, or just corruption or an synchronization error"),
970 conf->nodename, (const char *)rsi); 968 conf->nodename, (const char *)rsi);
969 break;
970 }
971 else 971 else
972 { 972 {
973 rsaresponse h; 973 rsaresponse h;
974 974
975 rsa_hash (p->id, chg, h); 975 rsa_hash (p->id, chg, h);
1031 tap_packet *d = p->unpack (this, seqno); 1031 tap_packet *d = p->unpack (this, seqno);
1032 1032
1033 if (iseqno.recv_ok (seqno)) 1033 if (iseqno.recv_ok (seqno))
1034 { 1034 {
1035 vpn->tap->send (d); 1035 vpn->tap->send (d);
1036
1037 if (p->dst () == 0) // re-broadcast
1038 for (vpn::conns_vector::iterator i = vpn->conns.begin (); i != vpn->conns.end (); ++i)
1039 {
1040 connection *c = *i;
1041
1042 if (c->conf != THISNODE && c->conf != conf)
1043 c->inject_data_packet (d);
1044 }
1045 1036
1046 if (si != rsi) 1037 if (si != rsi)
1047 { 1038 {
1048 // fast re-sync on connection changes, useful especially for tcp/ip 1039 // fast re-sync on connection changes, useful especially for tcp/ip
1049 si = rsi; 1040 si = rsi;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines