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

759 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",
760 conf->id, pkt->typ (), pkt->src (), pkt->dst ()); 760 conf->id, pkt->typ (), pkt->src (), pkt->dst ());
761 761
762 switch (pkt->typ ()) 762 switch (pkt->typ ())
763 { 763 {
764 case vpn_packet::PT_PING: 764 case vpn_packet::PT_PING:
765 // we send pings instead of auth packets after some retries, 765 // we send pings instead of auth packets after some retries,
766 // so reset the retry counter and establish a connection 766 // so reset the retry counter and establish a connection
767 // when we receive a ping. 767 // when we receive a ping.
768 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:
769 { 782 {
770 if (auth_rate_limiter.can (rsi)) 783 reset_connection ();
771 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 ();
772 } 795 }
773 else
774 send_ping (rsi, 1); // pong
775
776 break; 796 break;
777 797
778 case vpn_packet::PT_PONG:
779 break;
780
781 case vpn_packet::PT_RESET: 798 case vpn_packet::PT_AUTH_REQ:
782 { 799 if (auth_rate_limiter.can (rsi))
783 reset_connection ();
784
785 config_packet *p = (config_packet *) pkt;
786
787 if (!p->chk_config ())
788 { 800 {
789 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"),
790 conf->nodename, (const char *)rsi); 821 conf->nodename, (const char *)rsi);
791 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);
792 } 845 }
793 else if (connectmode == conf_node::C_ALWAYS) 846
794 establish_connection ();
795 }
796 break; 847 break;
797 848
798 case vpn_packet::PT_AUTH_REQ: 849 case vpn_packet::PT_AUTH_RES:
799 if (auth_rate_limiter.can (rsi))
800 { 850 {
801 auth_req_packet *p = (auth_req_packet *) pkt; 851 auth_res_packet *p = (auth_res_packet *) pkt;
802 852
803 slog (L_TRACE, "<<%d PT_AUTH_REQ(%d)", conf->id, p->initiate); 853 slog (L_TRACE, "<<%d PT_AUTH_RES", conf->id);
804 854
805 if (p->chk_config () && !strncmp (p->magic, MAGIC, 8)) 855 if (p->chk_config ())
806 { 856 {
807 if (p->prot_minor != PROTOCOL_MINOR) 857 if (p->prot_minor != PROTOCOL_MINOR)
808 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."),
809 conf->nodename, (const char *)rsi, 859 conf->nodename, (const char *)rsi,
810 PROTOCOL_MINOR, conf->nodename, p->prot_minor); 860 PROTOCOL_MINOR, conf->nodename, p->prot_minor);
811 861
812 if (p->initiate)
813 send_auth_request (rsi, false);
814
815 rsachallenge k; 862 rsachallenge chg;
816 863
817 if (0 > RSA_private_decrypt (sizeof (p->encr), 864 if (!rsa_cache.find (p->id, chg))
818 (unsigned char *)&p->encr, (unsigned char *)&k, 865 slog (L_ERR, _("%s(%s): unrequested auth response"),
819 ::conf.rsa_key, RSA_PKCS1_OAEP_PADDING))
820 slog (L_ERR, _("%s(%s): challenge illegal or corrupted"),
821 conf->nodename, (const char *)rsi); 866 conf->nodename, (const char *)rsi);
822 else 867 else
823 { 868 {
824 retry_cnt = 0; 869 crypto_ctx *cctx = new crypto_ctx (chg, 0);
825 establish_connection.set (NOW + 8); //? ;) 870
826 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);
827 rekey.reset (); 875 else
876 {
877 rsaresponse h;
828 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
829 delete ictx; 918 delete cctx;
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 } 919 }
842 } 920 }
843
844 send_reset (rsi);
845 } 921 }
846 922
923 send_reset (rsi);
847 break; 924 break;
848 925
849 case vpn_packet::PT_AUTH_RES: 926 case vpn_packet::PT_DATA_COMPRESSED:
850 { 927#if !ENABLE_COMPRESSION
851 auth_res_packet *p = (auth_res_packet *) pkt; 928 send_reset (rsi);
929 break;
930#endif
852 931
853 slog (L_TRACE, "<<%d PT_AUTH_RES", conf->id); 932 case vpn_packet::PT_DATA_UNCOMPRESSED:
854 933
855 if (p->chk_config ()) 934 if (ictx && octx)
856 { 935 {
857 if (p->prot_minor != PROTOCOL_MINOR) 936 vpndata_packet *p = (vpndata_packet *)pkt;
858 slog (L_INFO, _("%s(%s): protocol minor version mismatch: ours is %d, %s's is %d."),
859 conf->nodename, (const char *)rsi,
860 PROTOCOL_MINOR, conf->nodename, p->prot_minor);
861 937
862 rsachallenge chg; 938 if (rsi == si)
863
864 if (!rsa_cache.find (p->id, chg))
865 slog (L_ERR, _("%s(%s): unrequested auth response"),
866 conf->nodename, (const char *)rsi);
867 else
868 { 939 {
869 crypto_ctx *cctx = new crypto_ctx (chg, 0);
870
871 if (!p->hmac_chk (cctx)) 940 if (!p->hmac_chk (ictx))
872 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"
873 "could be an attack, or just corruption or an synchronization error"), 942 "could be an attack, or just corruption or an synchronization error"),
874 conf->nodename, (const char *)rsi); 943 conf->nodename, (const char *)rsi);
875 else 944 else
876 { 945 {
877 rsaresponse h; 946 u32 seqno;
947 tap_packet *d = p->unpack (this, seqno);
878 948
879 rsa_hash (p->id, chg, h); 949 if (iseqno.recv_ok (seqno))
880
881 if (!memcmp ((u8 *)&h, (u8 *)p->response, sizeof h))
882 { 950 {
883 prot_minor = p->prot_minor; 951 vpn->tap->send (d);
884 952
885 delete ictx; ictx = cctx; 953 if (p->dst () == 0) // re-broadcast
886 954 for (vpn::conns_vector::iterator i = vpn->conns.begin (); i != vpn->conns.end (); ++i)
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 { 955 {
956 connection *c = *i;
957
958 if (c->conf != THISNODE && c->conf != conf)
897 send_data_packet (p); 959 c->inject_data_packet (d);
898 delete p;
899 } 960 }
900 961
901 connectmode = conf->connectmode; 962 delete d;
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 963
911 break; 964 break;
912 } 965 }
913 else
914 slog (L_ERR, _("%s(%s): sent and received challenge do not match"),
915 conf->nodename, (const char *)rsi);
916 } 966 }
967 }
968 else
969 slog (L_ERR, _("received data packet from unknown source %s"), (const char *)rsi);
970 }
917 971
918 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);
919 } 993 }
920 } 994 }
921 }
922 995
923 send_reset (rsi);
924 break; 996 break;
925 997
926 case vpn_packet::PT_DATA_COMPRESSED:
927#if !ENABLE_COMPRESSION
928 send_reset (rsi);
929 break;
930#endif
931
932 case vpn_packet::PT_DATA_UNCOMPRESSED:
933
934 if (ictx && octx)
935 {
936 vpndata_packet *p = (vpndata_packet *)pkt;
937
938 if (rsi == si)
939 {
940 if (!p->hmac_chk (ictx))
941 slog (L_ERR, _("%s(%s): hmac authentication error, received invalid packet\n"
942 "could be an attack, or just corruption or an synchronization error"),
943 conf->nodename, (const char *)rsi);
944 else
945 {
946 u32 seqno;
947 tap_packet *d = p->unpack (this, seqno);
948
949 if (iseqno.recv_ok (seqno))
950 {
951 vpn->tap->send (d);
952
953 if (p->dst () == 0) // re-broadcast
954 for (vpn::conns_vector::iterator i = vpn->conns.begin (); i != vpn->conns.end (); ++i)
955 {
956 connection *c = *i;
957
958 if (c->conf != THISNODE && c->conf != conf)
959 c->inject_data_packet (d);
960 }
961
962 delete d;
963
964 break;
965 }
966 }
967 }
968 else
969 slog (L_ERR, _("received data packet from unknown source %s"), (const char *)rsi);
970 }
971
972 send_reset (rsi);
973 break;
974
975 case vpn_packet::PT_CONNECT_REQ: 998 case vpn_packet::PT_CONNECT_INFO:
976 if (ictx && octx && rsi == si && pkt->hmac_chk (ictx)) 999 if (ictx && octx && rsi == si && pkt->hmac_chk (ictx))
977 { 1000 {
978 connect_req_packet *p = (connect_req_packet *) pkt; 1001 connect_info_packet *p = (connect_info_packet *) pkt;
979 1002
980 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
981 conf->protocols = p->protocols; 1004 conf->protocols = p->protocols;
982 connection *c = vpn->conns[p->id - 1]; 1005 connection *c = vpn->conns[p->id - 1];
983 1006
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);
993 }
994 }
995
996 break;
997
998 case vpn_packet::PT_CONNECT_INFO:
999 if (ictx && octx && rsi == si && pkt->hmac_chk (ictx))
1000 {
1001 connect_info_packet *p = (connect_info_packet *) pkt;
1002
1003 assert (p->id > 0 && p->id <= vpn->conns.size ()); // hmac-auth does not mean we accept anything
1004 conf->protocols = p->protocols;
1005 connection *c = vpn->conns[p->id - 1];
1006
1007 slog (L_TRACE, "<<%d PT_CONNECT_INFO(%d,%s) (%d)", 1007 slog (L_TRACE, "<<%d PT_CONNECT_INFO(%d,%s) (%d)",
1008 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);
1009 1009
1010 c->send_auth_request (p->si, true); 1010 c->send_auth_request (p->si, true);
1011 } 1011 }
1012 1012
1013 break; 1013 break;
1014 1014
1015 default: 1015 default:
1016 send_reset (rsi); 1016 send_reset (rsi);
1017 break; 1017 break;
1018
1019 } 1018 }
1020} 1019}
1021 1020
1022void connection::keepalive_cb (tstamp &ts) 1021void connection::keepalive_cb (tstamp &ts)
1023{ 1022{
1049 delete p; 1048 delete p;
1050} 1049}
1051 1050
1052void connection::script_node () 1051void connection::script_node ()
1053{ 1052{
1054 vpn->script_if_up (0); 1053 vpn->script_if_up ();
1055 1054
1056 char *env; 1055 char *env;
1057 asprintf (&env, "DESTID=%d", conf->id); putenv (env); 1056 asprintf (&env, "DESTID=%d", conf->id); putenv (env);
1058 asprintf (&env, "DESTNODE=%s", conf->nodename); putenv (env); 1057 asprintf (&env, "DESTNODE=%s", conf->nodename); putenv (env);
1059 asprintf (&env, "DESTIP=%s", si.ntoa ()); putenv (env); 1058 asprintf (&env, "DESTIP=%s", si.ntoa ()); putenv (env);
1060 asprintf (&env, "DESTPORT=%d", ntohs (si.port)); putenv (env); 1059 asprintf (&env, "DESTPORT=%d", ntohs (si.port)); putenv (env);
1061} 1060}
1062 1061
1063const char *connection::script_node_up (int) 1062const char *connection::script_node_up ()
1064{ 1063{
1065 script_node (); 1064 script_node ();
1066 1065
1067 putenv ("STATE=up"); 1066 putenv ("STATE=up");
1068 1067
1069 return ::conf.script_node_up ? ::conf.script_node_up : "node-up"; 1068 return ::conf.script_node_up ? ::conf.script_node_up : "node-up";
1070} 1069}
1071 1070
1072const char *connection::script_node_down (int) 1071const char *connection::script_node_down ()
1073{ 1072{
1074 script_node (); 1073 script_node ();
1075 1074
1076 putenv ("STATE=down"); 1075 putenv ("STATE=down");
1077 1076
1080 1079
1081// send a vpn packet out to other hosts 1080// send a vpn packet out to other hosts
1082void 1081void
1083connection::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos) 1082connection::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos)
1084{ 1083{
1085 if (protocol & PROT_IPv4) 1084 switch (protocol)
1085 {
1086 case PROT_IPv4:
1086 vpn->send_ipv4_packet (pkt, si, tos); 1087 vpn->send_ipv4_packet (pkt, si, tos);
1087 else 1088 break;
1089
1090 case PROT_UDPv4:
1088 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 }
1089} 1098}
1090 1099
1091connection::connection(struct vpn *vpn_) 1100connection::connection(struct vpn *vpn_)
1092: vpn(vpn_) 1101: vpn(vpn_)
1093, rekey (this, &connection::rekey_cb) 1102, rekey (this, &connection::rekey_cb)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines