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.1 by pcg, Wed Apr 2 03:06:22 2003 UTC vs.
Revision 1.3 by pcg, Wed Apr 2 05:15:00 2003 UTC

22# include "lzf/lzf.h" 22# include "lzf/lzf.h"
23} 23}
24 24
25#include <list> 25#include <list>
26 26
27#include <openssl/rand.h>
28#include <openssl/evp.h>
29#include <openssl/rsa.h>
30#include <openssl/err.h>
31
27#include "gettext.h" 32#include "gettext.h"
28 33
29#include "conf.h" 34#include "conf.h"
30#include "slog.h" 35#include "slog.h"
31#include "device.h" 36#include "device.h"
32#include "protocol.h" 37#include "vpn.h"
33#include "connection.h" 38#include "connection.h"
34 39
35#if !HAVE_RAND_PSEUDO_BYTES 40#if !HAVE_RAND_PSEUDO_BYTES
36# define RAND_pseudo_bytes RAND_bytes 41# define RAND_pseudo_bytes RAND_bytes
37#endif 42#endif
578{ 583{
579 auth_req_packet *pkt = new auth_req_packet (conf->id, initiate, THISNODE->protocols); 584 auth_req_packet *pkt = new auth_req_packet (conf->id, initiate, THISNODE->protocols);
580 585
581 protocol = best_protocol (THISNODE->protocols & conf->protocols); 586 protocol = best_protocol (THISNODE->protocols & conf->protocols);
582 587
588 // mask out protocols we cannot establish
589 if (!conf->udp_port) protocol &= ~PROT_UDPv4;
590 if (!conf->tcp_port) protocol &= ~PROT_TCPv4;
591
592 if (protocol)
593 {
583 rsachallenge chg; 594 rsachallenge chg;
584 595
585 rsa_cache.gen (pkt->id, chg); 596 rsa_cache.gen (pkt->id, chg);
586 597
587 if (0 > RSA_public_encrypt (sizeof chg, 598 if (0 > RSA_public_encrypt (sizeof chg,
588 (unsigned char *)&chg, (unsigned char *)&pkt->encr, 599 (unsigned char *)&chg, (unsigned char *)&pkt->encr,
589 conf->rsa_key, RSA_PKCS1_OAEP_PADDING)) 600 conf->rsa_key, RSA_PKCS1_OAEP_PADDING))
590 fatal ("RSA_public_encrypt error"); 601 fatal ("RSA_public_encrypt error");
591 602
592 slog (L_TRACE, ">>%d PT_AUTH_REQ [%s]", conf->id, (const char *)si); 603 slog (L_TRACE, ">>%d PT_AUTH_REQ [%s]", conf->id, (const char *)si);
593 604
594 send_vpn_packet (pkt, si, IPTOS_RELIABILITY); // rsa is very very costly 605 send_vpn_packet (pkt, si, IPTOS_RELIABILITY); // rsa is very very costly
595 606
596 delete pkt; 607 delete pkt;
608 }
609 else
610 ; // silently fail
597} 611}
598 612
599void 613void
600connection::send_auth_response (const sockinfo &si, const rsaid &id, const rsachallenge &chg) 614connection::send_auth_response (const sockinfo &si, const rsaid &id, const rsachallenge &chg)
601{ 615{
745 slog (L_NOISE, "<<%d received packet type %d from %d to %d", 759 slog (L_NOISE, "<<%d received packet type %d from %d to %d",
746 conf->id, pkt->typ (), pkt->src (), pkt->dst ()); 760 conf->id, pkt->typ (), pkt->src (), pkt->dst ());
747 761
748 switch (pkt->typ ()) 762 switch (pkt->typ ())
749 { 763 {
750 case vpn_packet::PT_PING: 764 case vpn_packet::PT_PING:
751 // we send pings instead of auth packets after some retries, 765 // we send pings instead of auth packets after some retries,
752 // so reset the retry counter and establish a connection 766 // so reset the retry counter and establish a connection
753 // when we receive a ping. 767 // when we receive a ping.
754 if (!ictx) 768 if (!ictx)
769 {
770 if (auth_rate_limiter.can (rsi))
771 send_auth_request (rsi, true);
772 }
773 else
774 send_ping (rsi, 1); // pong
775
776 break;
777
778 case vpn_packet::PT_PONG:
779 break;
780
781 case vpn_packet::PT_RESET:
755 { 782 {
756 if (auth_rate_limiter.can (rsi)) 783 reset_connection ();
757 send_auth_request (rsi, true); 784
785 config_packet *p = (config_packet *) pkt;
786
787 if (!p->chk_config ())
788 {
789 slog (L_WARN, _("%s(%s): protocol mismatch, disabling node"),
790 conf->nodename, (const char *)rsi);
791 connectmode = conf_node::C_DISABLED;
792 }
793 else if (connectmode == conf_node::C_ALWAYS)
794 establish_connection ();
758 } 795 }
759 else
760 send_ping (rsi, 1); // pong
761
762 break; 796 break;
763 797
764 case vpn_packet::PT_PONG:
765 break;
766
767 case vpn_packet::PT_RESET: 798 case vpn_packet::PT_AUTH_REQ:
768 { 799 if (auth_rate_limiter.can (rsi))
769 reset_connection ();
770
771 config_packet *p = (config_packet *) pkt;
772
773 if (!p->chk_config ())
774 { 800 {
775 slog (L_WARN, _("%s(%s): protocol mismatch, disabling node"), 801 auth_req_packet *p = (auth_req_packet *) pkt;
802
803 slog (L_TRACE, "<<%d PT_AUTH_REQ(%d)", conf->id, p->initiate);
804
805 if (p->chk_config () && !strncmp (p->magic, MAGIC, 8))
806 {
807 if (p->prot_minor != PROTOCOL_MINOR)
808 slog (L_INFO, _("%s(%s): protocol minor version mismatch: ours is %d, %s's is %d."),
809 conf->nodename, (const char *)rsi,
810 PROTOCOL_MINOR, conf->nodename, p->prot_minor);
811
812 if (p->initiate)
813 send_auth_request (rsi, false);
814
815 rsachallenge k;
816
817 if (0 > RSA_private_decrypt (sizeof (p->encr),
818 (unsigned char *)&p->encr, (unsigned char *)&k,
819 ::conf.rsa_key, RSA_PKCS1_OAEP_PADDING))
820 slog (L_ERR, _("%s(%s): challenge illegal or corrupted"),
776 conf->nodename, (const char *)rsi); 821 conf->nodename, (const char *)rsi);
777 connectmode = conf_node::C_DISABLED; 822 else
823 {
824 retry_cnt = 0;
825 establish_connection.set (NOW + 8); //? ;)
826 keepalive.reset ();
827 rekey.reset ();
828
829 delete ictx;
830 ictx = 0;
831
832 delete octx;
833
834 octx = new crypto_ctx (k, 1);
835 oseqno = ntohl (*(u32 *)&k[CHG_SEQNO]) & 0x7fffffff;
836
837 conf->protocols = p->protocols;
838 send_auth_response (rsi, p->id, k);
839
840 break;
841 }
842 }
843
844 send_reset (rsi);
778 } 845 }
779 else if (connectmode == conf_node::C_ALWAYS) 846
780 establish_connection ();
781 }
782 break; 847 break;
783 848
784 case vpn_packet::PT_AUTH_REQ: 849 case vpn_packet::PT_AUTH_RES:
785 if (auth_rate_limiter.can (rsi))
786 { 850 {
787 auth_req_packet *p = (auth_req_packet *) pkt; 851 auth_res_packet *p = (auth_res_packet *) pkt;
788 852
789 slog (L_TRACE, "<<%d PT_AUTH_REQ(%d)", conf->id, p->initiate); 853 slog (L_TRACE, "<<%d PT_AUTH_RES", conf->id);
790 854
791 if (p->chk_config () && !strncmp (p->magic, MAGIC, 8)) 855 if (p->chk_config ())
792 { 856 {
793 if (p->prot_minor != PROTOCOL_MINOR) 857 if (p->prot_minor != PROTOCOL_MINOR)
794 slog (L_INFO, _("%s(%s): protocol minor version mismatch: ours is %d, %s's is %d."), 858 slog (L_INFO, _("%s(%s): protocol minor version mismatch: ours is %d, %s's is %d."),
795 conf->nodename, (const char *)rsi, 859 conf->nodename, (const char *)rsi,
796 PROTOCOL_MINOR, conf->nodename, p->prot_minor); 860 PROTOCOL_MINOR, conf->nodename, p->prot_minor);
797 861
798 if (p->initiate)
799 send_auth_request (rsi, false);
800
801 rsachallenge k; 862 rsachallenge chg;
802 863
803 if (0 > RSA_private_decrypt (sizeof (p->encr), 864 if (!rsa_cache.find (p->id, chg))
804 (unsigned char *)&p->encr, (unsigned char *)&k, 865 slog (L_ERR, _("%s(%s): unrequested auth response"),
805 ::conf.rsa_key, RSA_PKCS1_OAEP_PADDING))
806 slog (L_ERR, _("%s(%s): challenge illegal or corrupted"),
807 conf->nodename, (const char *)rsi); 866 conf->nodename, (const char *)rsi);
808 else 867 else
809 { 868 {
810 retry_cnt = 0; 869 crypto_ctx *cctx = new crypto_ctx (chg, 0);
811 establish_connection.set (NOW + 8); //? ;) 870
812 keepalive.reset (); 871 if (!p->hmac_chk (cctx))
872 slog (L_ERR, _("%s(%s): hmac authentication error on auth response, received invalid packet\n"
873 "could be an attack, or just corruption or an synchronization error"),
874 conf->nodename, (const char *)rsi);
813 rekey.reset (); 875 else
876 {
877 rsaresponse h;
814 878
879 rsa_hash (p->id, chg, h);
880
881 if (!memcmp ((u8 *)&h, (u8 *)p->response, sizeof h))
882 {
883 prot_minor = p->prot_minor;
884
885 delete ictx; ictx = cctx;
886
887 iseqno.reset (ntohl (*(u32 *)&chg[CHG_SEQNO]) & 0x7fffffff); // at least 2**31 sequence numbers are valid
888
889 si = rsi;
890
891 rekey.set (NOW + ::conf.rekey);
892 keepalive.set (NOW + ::conf.keepalive);
893
894 // send queued packets
895 while (tap_packet *p = queue.get ())
896 {
897 send_data_packet (p);
898 delete p;
899 }
900
901 connectmode = conf->connectmode;
902
903 slog (L_INFO, _("%s(%s): %s connection established, protocol version %d.%d"),
904 conf->nodename, (const char *)rsi,
905 strprotocol (protocol),
906 p->prot_major, p->prot_minor);
907
908 if (::conf.script_node_up)
909 run_script (run_script_cb (this, &connection::script_node_up), false);
910
911 break;
912 }
913 else
914 slog (L_ERR, _("%s(%s): sent and received challenge do not match"),
915 conf->nodename, (const char *)rsi);
916 }
917
815 delete ictx; 918 delete cctx;
816 ictx = 0;
817
818 delete octx;
819
820 octx = new crypto_ctx (k, 1);
821 oseqno = ntohl (*(u32 *)&k[CHG_SEQNO]) & 0x7fffffff;
822
823 conf->protocols = p->protocols;
824 send_auth_response (rsi, p->id, k);
825
826 break;
827 } 919 }
828 } 920 }
829
830 send_reset (rsi);
831 } 921 }
832 922
923 send_reset (rsi);
833 break; 924 break;
834 925
835 case vpn_packet::PT_AUTH_RES: 926 case vpn_packet::PT_DATA_COMPRESSED:
836 { 927#if !ENABLE_COMPRESSION
837 auth_res_packet *p = (auth_res_packet *) pkt; 928 send_reset (rsi);
929 break;
930#endif
838 931
839 slog (L_TRACE, "<<%d PT_AUTH_RES", conf->id); 932 case vpn_packet::PT_DATA_UNCOMPRESSED:
840 933
841 if (p->chk_config ()) 934 if (ictx && octx)
842 { 935 {
843 if (p->prot_minor != PROTOCOL_MINOR) 936 vpndata_packet *p = (vpndata_packet *)pkt;
844 slog (L_INFO, _("%s(%s): protocol minor version mismatch: ours is %d, %s's is %d."),
845 conf->nodename, (const char *)rsi,
846 PROTOCOL_MINOR, conf->nodename, p->prot_minor);
847 937
848 rsachallenge chg; 938 if (rsi == si)
849
850 if (!rsa_cache.find (p->id, chg))
851 slog (L_ERR, _("%s(%s): unrequested auth response"),
852 conf->nodename, (const char *)rsi);
853 else
854 { 939 {
855 crypto_ctx *cctx = new crypto_ctx (chg, 0);
856
857 if (!p->hmac_chk (cctx)) 940 if (!p->hmac_chk (ictx))
858 slog (L_ERR, _("%s(%s): hmac authentication error on auth response, received invalid packet\n" 941 slog (L_ERR, _("%s(%s): hmac authentication error, received invalid packet\n"
859 "could be an attack, or just corruption or an synchronization error"), 942 "could be an attack, or just corruption or an synchronization error"),
860 conf->nodename, (const char *)rsi); 943 conf->nodename, (const char *)rsi);
861 else 944 else
862 { 945 {
863 rsaresponse h; 946 u32 seqno;
947 tap_packet *d = p->unpack (this, seqno);
864 948
865 rsa_hash (p->id, chg, h); 949 if (iseqno.recv_ok (seqno))
866
867 if (!memcmp ((u8 *)&h, (u8 *)p->response, sizeof h))
868 { 950 {
869 prot_minor = p->prot_minor; 951 vpn->tap->send (d);
870 952
871 delete ictx; ictx = cctx; 953 if (p->dst () == 0) // re-broadcast
872 954 for (vpn::conns_vector::iterator i = vpn->conns.begin (); i != vpn->conns.end (); ++i)
873 iseqno.reset (ntohl (*(u32 *)&chg[CHG_SEQNO]) & 0x7fffffff); // at least 2**31 sequence numbers are valid
874
875 si = rsi;
876
877 rekey.set (NOW + ::conf.rekey);
878 keepalive.set (NOW + ::conf.keepalive);
879
880 // send queued packets
881 while (tap_packet *p = queue.get ())
882 { 955 {
956 connection *c = *i;
957
958 if (c->conf != THISNODE && c->conf != conf)
883 send_data_packet (p); 959 c->inject_data_packet (d);
884 delete p;
885 } 960 }
886 961
887 connectmode = conf->connectmode; 962 delete d;
888
889 slog (L_INFO, _("%s(%s): %s connection established, protocol version %d.%d"),
890 conf->nodename, (const char *)rsi,
891 strprotocol (protocol),
892 p->prot_major, p->prot_minor);
893
894 if (::conf.script_node_up)
895 run_script (run_script_cb (this, &connection::script_node_up), false);
896 963
897 break; 964 break;
898 } 965 }
899 else
900 slog (L_ERR, _("%s(%s): sent and received challenge do not match"),
901 conf->nodename, (const char *)rsi);
902 } 966 }
967 }
968 else
969 slog (L_ERR, _("received data packet from unknown source %s"), (const char *)rsi);
970 }
903 971
904 delete cctx; 972 send_reset (rsi);
973 break;
974
975 case vpn_packet::PT_CONNECT_REQ:
976 if (ictx && octx && rsi == si && pkt->hmac_chk (ictx))
977 {
978 connect_req_packet *p = (connect_req_packet *) pkt;
979
980 assert (p->id > 0 && p->id <= vpn->conns.size ()); // hmac-auth does not mean we accept anything
981 conf->protocols = p->protocols;
982 connection *c = vpn->conns[p->id - 1];
983
984 slog (L_TRACE, "<<%d PT_CONNECT_REQ(%d) [%d]\n",
985 conf->id, p->id, c->ictx && c->octx);
986
987 if (c->ictx && c->octx)
988 {
989 // send connect_info packets to both sides, in case one is
990 // behind a nat firewall (or both ;)
991 c->send_connect_info (conf->id, si, conf->protocols);
992 send_connect_info (c->conf->id, c->si, c->conf->protocols);
905 } 993 }
906 } 994 }
907 }
908 995
909 send_reset (rsi);
910 break; 996 break;
911 997
912 case vpn_packet::PT_DATA_COMPRESSED:
913#if !ENABLE_COMPRESSION
914 send_reset (rsi);
915 break;
916#endif
917
918 case vpn_packet::PT_DATA_UNCOMPRESSED:
919
920 if (ictx && octx)
921 {
922 vpndata_packet *p = (vpndata_packet *)pkt;
923
924 if (rsi == si)
925 {
926 if (!p->hmac_chk (ictx))
927 slog (L_ERR, _("%s(%s): hmac authentication error, received invalid packet\n"
928 "could be an attack, or just corruption or an synchronization error"),
929 conf->nodename, (const char *)rsi);
930 else
931 {
932 u32 seqno;
933 tap_packet *d = p->unpack (this, seqno);
934
935 if (iseqno.recv_ok (seqno))
936 {
937 vpn->tap->send (d);
938
939 if (p->dst () == 0) // re-broadcast
940 for (vpn::conns_vector::iterator i = vpn->conns.begin (); i != vpn->conns.end (); ++i)
941 {
942 connection *c = *i;
943
944 if (c->conf != THISNODE && c->conf != conf)
945 c->inject_data_packet (d);
946 }
947
948 delete d;
949
950 break;
951 }
952 }
953 }
954 else
955 slog (L_ERR, _("received data packet from unknown source %s"), (const char *)rsi);
956 }
957
958 send_reset (rsi);
959 break;
960
961 case vpn_packet::PT_CONNECT_REQ: 998 case vpn_packet::PT_CONNECT_INFO:
962 if (ictx && octx && rsi == si && pkt->hmac_chk (ictx)) 999 if (ictx && octx && rsi == si && pkt->hmac_chk (ictx))
963 { 1000 {
964 connect_req_packet *p = (connect_req_packet *) pkt; 1001 connect_info_packet *p = (connect_info_packet *) pkt;
965 1002
966 assert (p->id > 0 && p->id <= vpn->conns.size ()); // hmac-auth does not mean we accept anything 1003 assert (p->id > 0 && p->id <= vpn->conns.size ()); // hmac-auth does not mean we accept anything
967 conf->protocols = p->protocols; 1004 conf->protocols = p->protocols;
968 connection *c = vpn->conns[p->id - 1]; 1005 connection *c = vpn->conns[p->id - 1];
969 1006
970 slog (L_TRACE, "<<%d PT_CONNECT_REQ(%d) [%d]\n",
971 conf->id, p->id, c->ictx && c->octx);
972
973 if (c->ictx && c->octx)
974 {
975 // send connect_info packets to both sides, in case one is
976 // behind a nat firewall (or both ;)
977 c->send_connect_info (conf->id, si, conf->protocols);
978 send_connect_info (c->conf->id, c->si, c->conf->protocols);
979 }
980 }
981
982 break;
983
984 case vpn_packet::PT_CONNECT_INFO:
985 if (ictx && octx && rsi == si && pkt->hmac_chk (ictx))
986 {
987 connect_info_packet *p = (connect_info_packet *) pkt;
988
989 assert (p->id > 0 && p->id <= vpn->conns.size ()); // hmac-auth does not mean we accept anything
990 conf->protocols = p->protocols;
991 connection *c = vpn->conns[p->id - 1];
992
993 slog (L_TRACE, "<<%d PT_CONNECT_INFO(%d,%s) (%d)", 1007 slog (L_TRACE, "<<%d PT_CONNECT_INFO(%d,%s) (%d)",
994 conf->id, p->id, (const char *)p->si, !c->ictx && !c->octx); 1008 conf->id, p->id, (const char *)p->si, !c->ictx && !c->octx);
995 1009
996 c->send_auth_request (p->si, true); 1010 c->send_auth_request (p->si, true);
997 } 1011 }
998 1012
999 break; 1013 break;
1000 1014
1001 default: 1015 default:
1002 send_reset (rsi); 1016 send_reset (rsi);
1003 break; 1017 break;
1004
1005 } 1018 }
1006} 1019}
1007 1020
1008void connection::keepalive_cb (tstamp &ts) 1021void connection::keepalive_cb (tstamp &ts)
1009{ 1022{
1035 delete p; 1048 delete p;
1036} 1049}
1037 1050
1038void connection::script_node () 1051void connection::script_node ()
1039{ 1052{
1040 vpn->script_if_up (0); 1053 vpn->script_if_up ();
1041 1054
1042 char *env; 1055 char *env;
1043 asprintf (&env, "DESTID=%d", conf->id); putenv (env); 1056 asprintf (&env, "DESTID=%d", conf->id); putenv (env);
1044 asprintf (&env, "DESTNODE=%s", conf->nodename); putenv (env); 1057 asprintf (&env, "DESTNODE=%s", conf->nodename); putenv (env);
1045 asprintf (&env, "DESTIP=%s", si.ntoa ()); putenv (env); 1058 asprintf (&env, "DESTIP=%s", si.ntoa ()); putenv (env);
1046 asprintf (&env, "DESTPORT=%d", ntohs (si.port)); putenv (env); 1059 asprintf (&env, "DESTPORT=%d", ntohs (si.port)); putenv (env);
1047} 1060}
1048 1061
1049const char *connection::script_node_up (int) 1062const char *connection::script_node_up ()
1050{ 1063{
1051 script_node (); 1064 script_node ();
1052 1065
1053 putenv ("STATE=up"); 1066 putenv ("STATE=up");
1054 1067
1055 return ::conf.script_node_up ? ::conf.script_node_up : "node-up"; 1068 return ::conf.script_node_up ? ::conf.script_node_up : "node-up";
1056} 1069}
1057 1070
1058const char *connection::script_node_down (int) 1071const char *connection::script_node_down ()
1059{ 1072{
1060 script_node (); 1073 script_node ();
1061 1074
1062 putenv ("STATE=down"); 1075 putenv ("STATE=down");
1063 1076
1066 1079
1067// send a vpn packet out to other hosts 1080// send a vpn packet out to other hosts
1068void 1081void
1069connection::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos) 1082connection::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos)
1070{ 1083{
1071 if (protocol & PROT_IPv4) 1084 switch (protocol)
1085 {
1086 case PROT_IPv4:
1072 vpn->send_ipv4_packet (pkt, si, tos); 1087 vpn->send_ipv4_packet (pkt, si, tos);
1073 else 1088 break;
1089
1090 case PROT_UDPv4:
1074 vpn->send_udpv4_packet (pkt, si, tos); 1091 vpn->send_udpv4_packet (pkt, si, tos);
1092 break;
1093
1094 case PROT_TCPv4:
1095 vpn->send_tcpv4_packet (pkt, si, tos);
1096 break;
1097 }
1075} 1098}
1076 1099
1077connection::connection(struct vpn *vpn_) 1100connection::connection(struct vpn *vpn_)
1078: vpn(vpn_) 1101: vpn(vpn_)
1079, rekey (this, &connection::rekey_cb) 1102, rekey (this, &connection::rekey_cb)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines