… | |
… | |
58 | |
58 | |
59 | static time_t next_timecheck; |
59 | static time_t next_timecheck; |
60 | |
60 | |
61 | #define MAGIC "vped\xbd\xc6\xdb\x82" // 8 bytes of magic |
61 | #define MAGIC "vped\xbd\xc6\xdb\x82" // 8 bytes of magic |
62 | |
62 | |
63 | static u8 |
|
|
64 | best_protocol (u8 protset) |
|
|
65 | { |
|
|
66 | if (protset & PROT_IPv4) |
|
|
67 | return PROT_IPv4; |
|
|
68 | |
|
|
69 | return PROT_UDPv4; |
|
|
70 | } |
|
|
71 | |
|
|
72 | struct crypto_ctx |
63 | struct crypto_ctx |
73 | { |
64 | { |
74 | EVP_CIPHER_CTX cctx; |
65 | EVP_CIPHER_CTX cctx; |
75 | HMAC_CTX hctx; |
66 | HMAC_CTX hctx; |
76 | |
67 | |
… | |
… | |
581 | } |
572 | } |
582 | |
573 | |
583 | struct auth_req_packet : config_packet |
574 | struct auth_req_packet : config_packet |
584 | { |
575 | { |
585 | char magic[8]; |
576 | char magic[8]; |
586 | u8 initiate, can_recv; // false if this is just an automatic reply |
577 | u8 initiate; // false if this is just an automatic reply |
|
|
578 | u8 protocols; // supported protocols (will get patches on forward) |
587 | u8 pad2, pad3; |
579 | u8 pad2, pad3; |
588 | rsaid id; |
580 | rsaid id; |
589 | rsaencrdata encr; |
581 | rsaencrdata encr; |
590 | |
582 | |
591 | auth_req_packet (int dst, bool initiate_, u8 can_recv_) |
583 | auth_req_packet (int dst, bool initiate_, u8 protocols_) |
592 | { |
584 | { |
593 | config_packet::setup (PT_AUTH_REQ, dst); |
585 | config_packet::setup (PT_AUTH_REQ, dst); |
594 | strncpy (magic, MAGIC, 8); |
586 | strncpy (magic, MAGIC, 8); |
595 | initiate = !!initiate_; |
587 | initiate = !!initiate_; |
596 | can_recv = can_recv_; |
588 | protocols = protocols_; |
597 | |
589 | |
598 | len = sizeof (*this) - sizeof (net_packet); |
590 | len = sizeof (*this) - sizeof (net_packet); |
599 | } |
591 | } |
600 | }; |
592 | }; |
601 | |
593 | |
… | |
… | |
614 | } |
606 | } |
615 | }; |
607 | }; |
616 | |
608 | |
617 | struct connect_req_packet : vpn_packet |
609 | struct connect_req_packet : vpn_packet |
618 | { |
610 | { |
619 | u8 id; |
611 | u8 id, protocols; |
620 | u8 pad1, pad2, pad3; |
612 | u8 pad1, pad2; |
621 | |
613 | |
622 | connect_req_packet (int dst, int id_) |
614 | connect_req_packet (int dst, int id_, u8 protocols_) |
|
|
615 | : id(id_) |
|
|
616 | , protocols(protocols_) |
623 | { |
617 | { |
624 | id = id_; |
|
|
625 | set_hdr (PT_CONNECT_REQ, dst); |
618 | set_hdr (PT_CONNECT_REQ, dst); |
626 | len = sizeof (*this) - sizeof (net_packet); |
619 | len = sizeof (*this) - sizeof (net_packet); |
627 | } |
620 | } |
628 | }; |
621 | }; |
629 | |
622 | |
630 | struct connect_info_packet : vpn_packet |
623 | struct connect_info_packet : vpn_packet |
631 | { |
624 | { |
632 | u8 id, can_recv; |
625 | u8 id, protocols; |
633 | u8 pad1, pad2; |
626 | u8 pad1, pad2; |
634 | sockinfo si; |
627 | sockinfo si; |
635 | |
628 | |
636 | connect_info_packet (int dst, int id_, sockinfo &si_, u8 can_recv_) |
629 | connect_info_packet (int dst, int id_, const sockinfo &si_, u8 protocols_) |
|
|
630 | : id(id_) |
|
|
631 | , protocols(protocols_) |
|
|
632 | , si(si_) |
637 | { |
633 | { |
638 | id = id_; |
|
|
639 | can_recv = can_recv_; |
|
|
640 | si = si_; |
|
|
641 | set_hdr (PT_CONNECT_INFO, dst); |
634 | set_hdr (PT_CONNECT_INFO, dst); |
642 | |
635 | |
643 | len = sizeof (*this) - sizeof (net_packet); |
636 | len = sizeof (*this) - sizeof (net_packet); |
644 | } |
637 | } |
645 | }; |
638 | }; |
… | |
… | |
678 | } |
671 | } |
679 | |
672 | |
680 | void |
673 | void |
681 | connection::send_auth_request (const sockinfo &si, bool initiate) |
674 | connection::send_auth_request (const sockinfo &si, bool initiate) |
682 | { |
675 | { |
683 | auth_req_packet *pkt = new auth_req_packet (conf->id, initiate, THISNODE->can_recv); |
676 | auth_req_packet *pkt = new auth_req_packet (conf->id, initiate, THISNODE->protocols); |
684 | |
677 | |
685 | // the next line is very conservative |
678 | protocol = best_protocol (THISNODE->protocols & conf->protocols); |
686 | prot_send = best_protocol (THISNODE->can_send & THISNODE->can_recv & conf->can_recv); |
|
|
687 | |
679 | |
688 | rsachallenge chg; |
680 | rsachallenge chg; |
689 | |
681 | |
690 | rsa_cache.gen (pkt->id, chg); |
682 | rsa_cache.gen (pkt->id, chg); |
691 | |
683 | |
… | |
… | |
715 | slog (L_TRACE, ">>%d PT_AUTH_RES [%s]", conf->id, (const char *)si); |
707 | slog (L_TRACE, ">>%d PT_AUTH_RES [%s]", conf->id, (const char *)si); |
716 | |
708 | |
717 | send_vpn_packet (pkt, si, IPTOS_RELIABILITY); // rsa is very very costly |
709 | send_vpn_packet (pkt, si, IPTOS_RELIABILITY); // rsa is very very costly |
718 | |
710 | |
719 | delete pkt; |
711 | delete pkt; |
|
|
712 | } |
|
|
713 | |
|
|
714 | void |
|
|
715 | connection::send_connect_info (int rid, const sockinfo &rsi, u8 rprotocols) |
|
|
716 | { |
|
|
717 | slog (L_TRACE, ">>%d PT_CONNECT_INFO(%d,%s)\n", |
|
|
718 | conf->id, rid, (const char *)rsi); |
|
|
719 | |
|
|
720 | connect_info_packet *r = new connect_info_packet (conf->id, rid, rsi, rprotocols); |
|
|
721 | |
|
|
722 | r->hmac_set (octx); |
|
|
723 | send_vpn_packet (r, si); |
|
|
724 | |
|
|
725 | delete r; |
720 | } |
726 | } |
721 | |
727 | |
722 | void |
728 | void |
723 | connection::establish_connection_cb (tstamp &ts) |
729 | connection::establish_connection_cb (tstamp &ts) |
724 | { |
730 | { |
… | |
… | |
909 | delete octx; |
915 | delete octx; |
910 | |
916 | |
911 | octx = new crypto_ctx (k, 1); |
917 | octx = new crypto_ctx (k, 1); |
912 | oseqno = ntohl (*(u32 *)&k[CHG_SEQNO]) & 0x7fffffff; |
918 | oseqno = ntohl (*(u32 *)&k[CHG_SEQNO]) & 0x7fffffff; |
913 | |
919 | |
914 | conf->can_recv = p->can_recv; |
920 | conf->protocols = p->protocols; |
915 | send_auth_response (rsi, p->id, k); |
921 | send_auth_response (rsi, p->id, k); |
916 | |
922 | |
917 | break; |
923 | break; |
918 | } |
924 | } |
919 | } |
925 | } |
… | |
… | |
975 | delete p; |
981 | delete p; |
976 | } |
982 | } |
977 | |
983 | |
978 | connectmode = conf->connectmode; |
984 | connectmode = conf->connectmode; |
979 | |
985 | |
980 | slog (L_INFO, _("%s(%s): connection established, protocol version %d.%d"), |
986 | slog (L_INFO, _("%s(%s): %s connection established, protocol version %d.%d"), |
981 | conf->nodename, (const char *)rsi, |
987 | conf->nodename, (const char *)rsi, |
|
|
988 | strprotocol (protocol), |
982 | p->prot_major, p->prot_minor); |
989 | p->prot_major, p->prot_minor); |
983 | |
990 | |
984 | if (::conf.script_node_up) |
991 | if (::conf.script_node_up) |
985 | run_script (run_script_cb (this, &connection::script_node_up), false); |
992 | run_script (run_script_cb (this, &connection::script_node_up), false); |
986 | |
993 | |
… | |
… | |
1052 | if (ictx && octx && rsi == si && pkt->hmac_chk (ictx)) |
1059 | if (ictx && octx && rsi == si && pkt->hmac_chk (ictx)) |
1053 | { |
1060 | { |
1054 | connect_req_packet *p = (connect_req_packet *) pkt; |
1061 | connect_req_packet *p = (connect_req_packet *) pkt; |
1055 | |
1062 | |
1056 | assert (p->id > 0 && p->id <= vpn->conns.size ()); // hmac-auth does not mean we accept anything |
1063 | assert (p->id > 0 && p->id <= vpn->conns.size ()); // hmac-auth does not mean we accept anything |
1057 | |
1064 | conf->protocols = p->protocols; |
1058 | connection *c = vpn->conns[p->id - 1]; |
1065 | connection *c = vpn->conns[p->id - 1]; |
1059 | |
1066 | |
1060 | slog (L_TRACE, "<<%d PT_CONNECT_REQ(%d) [%d]\n", |
1067 | slog (L_TRACE, "<<%d PT_CONNECT_REQ(%d) [%d]\n", |
1061 | conf->id, p->id, c->ictx && c->octx); |
1068 | conf->id, p->id, c->ictx && c->octx); |
1062 | |
1069 | |
1063 | if (c->ictx && c->octx) |
1070 | if (c->ictx && c->octx) |
1064 | { |
1071 | { |
1065 | // send connect_info packets to both sides, in case one is |
1072 | // send connect_info packets to both sides, in case one is |
1066 | // behind a nat firewall (or both ;) |
1073 | // behind a nat firewall (or both ;) |
1067 | { |
1074 | c->send_connect_info (conf->id, si, conf->protocols); |
1068 | slog (L_TRACE, ">>%d PT_CONNECT_INFO(%d,%s)\n", |
1075 | send_connect_info (c->conf->id, c->si, c->conf->protocols); |
1069 | c->conf->id, conf->id, (const char *)si); |
|
|
1070 | |
|
|
1071 | connect_info_packet *r = new connect_info_packet (c->conf->id, conf->id, si, conf->can_recv); |
|
|
1072 | |
|
|
1073 | r->hmac_set (c->octx); |
|
|
1074 | send_vpn_packet (r, c->si); |
|
|
1075 | |
|
|
1076 | delete r; |
|
|
1077 | } |
|
|
1078 | |
|
|
1079 | { |
|
|
1080 | slog (L_TRACE, ">>%d PT_CONNECT_INFO(%d,%s)\n", |
|
|
1081 | conf->id, c->conf->id, (const char *)c->si); |
|
|
1082 | |
|
|
1083 | connect_info_packet *r = new connect_info_packet (conf->id, c->conf->id, c->si, c->conf->can_recv); |
|
|
1084 | |
|
|
1085 | r->hmac_set (octx); |
|
|
1086 | send_vpn_packet (r, si); |
|
|
1087 | |
|
|
1088 | delete r; |
|
|
1089 | } |
|
|
1090 | } |
1076 | } |
1091 | } |
1077 | } |
1092 | |
1078 | |
1093 | break; |
1079 | break; |
1094 | |
1080 | |
… | |
… | |
1096 | if (ictx && octx && rsi == si && pkt->hmac_chk (ictx)) |
1082 | if (ictx && octx && rsi == si && pkt->hmac_chk (ictx)) |
1097 | { |
1083 | { |
1098 | connect_info_packet *p = (connect_info_packet *) pkt; |
1084 | connect_info_packet *p = (connect_info_packet *) pkt; |
1099 | |
1085 | |
1100 | assert (p->id > 0 && p->id <= vpn->conns.size ()); // hmac-auth does not mean we accept anything |
1086 | assert (p->id > 0 && p->id <= vpn->conns.size ()); // hmac-auth does not mean we accept anything |
1101 | |
1087 | conf->protocols = p->protocols; |
1102 | connection *c = vpn->conns[p->id - 1]; |
1088 | connection *c = vpn->conns[p->id - 1]; |
1103 | |
1089 | |
1104 | slog (L_TRACE, "<<%d PT_CONNECT_INFO(%d,%s) (%d)", |
1090 | slog (L_TRACE, "<<%d PT_CONNECT_INFO(%d,%s) (%d)", |
1105 | conf->id, p->id, (const char *)p->si, !c->ictx && !c->octx); |
1091 | conf->id, p->id, (const char *)p->si, !c->ictx && !c->octx); |
1106 | |
1092 | |
1107 | c->conf->can_recv = p->can_recv; |
|
|
1108 | c->send_auth_request (p->si, true); |
1093 | c->send_auth_request (p->si, true); |
1109 | } |
1094 | } |
1110 | |
1095 | |
1111 | break; |
1096 | break; |
1112 | |
1097 | |
… | |
… | |
1125 | establish_connection (); |
1110 | establish_connection (); |
1126 | } |
1111 | } |
1127 | else if (NOW < last_activity + ::conf.keepalive) |
1112 | else if (NOW < last_activity + ::conf.keepalive) |
1128 | ts = last_activity + ::conf.keepalive; |
1113 | ts = last_activity + ::conf.keepalive; |
1129 | else if (conf->connectmode != conf_node::C_ONDEMAND |
1114 | else if (conf->connectmode != conf_node::C_ONDEMAND |
1130 | || THISNODE->connectmode != conf_node::C_ONDEMAND) |
1115 | || THISNODE->connectmode != conf_node::C_ONDEMAND) |
1131 | { |
1116 | { |
1132 | send_ping (si); |
1117 | send_ping (si); |
1133 | ts = NOW + 5; |
1118 | ts = NOW + 5; |
1134 | } |
1119 | } |
1135 | else |
1120 | else |
1136 | reset_connection (); |
1121 | reset_connection (); |
1137 | |
|
|
1138 | } |
1122 | } |
1139 | |
1123 | |
1140 | void connection::connect_request (int id) |
1124 | void connection::connect_request (int id) |
1141 | { |
1125 | { |
1142 | connect_req_packet *p = new connect_req_packet (conf->id, id); |
1126 | connect_req_packet *p = new connect_req_packet (conf->id, id, conf->protocols); |
1143 | |
1127 | |
1144 | slog (L_TRACE, ">>%d PT_CONNECT_REQ(%d)", id, conf->id); |
1128 | slog (L_TRACE, ">>%d PT_CONNECT_REQ(%d)", conf->id, id); |
1145 | p->hmac_set (octx); |
1129 | p->hmac_set (octx); |
1146 | send_vpn_packet (p, si); |
1130 | send_vpn_packet (p, si); |
1147 | |
1131 | |
1148 | delete p; |
1132 | delete p; |
1149 | } |
1133 | } |
… | |
… | |
1179 | |
1163 | |
1180 | // send a vpn packet out to other hosts |
1164 | // send a vpn packet out to other hosts |
1181 | void |
1165 | void |
1182 | connection::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos) |
1166 | connection::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos) |
1183 | { |
1167 | { |
1184 | if (prot_send & PROT_IPv4) |
1168 | if (protocol & PROT_IPv4) |
1185 | vpn->send_ipv4_packet (pkt, si, tos); |
1169 | vpn->send_ipv4_packet (pkt, si, tos); |
1186 | else |
1170 | else |
1187 | vpn->send_udpv4_packet (pkt, si, tos); |
1171 | vpn->send_udpv4_packet (pkt, si, tos); |
1188 | } |
1172 | } |
1189 | |
1173 | |
… | |
… | |
1236 | } |
1220 | } |
1237 | |
1221 | |
1238 | int |
1222 | int |
1239 | vpn::setup () |
1223 | vpn::setup () |
1240 | { |
1224 | { |
1241 | u8 prots = 0; |
|
|
1242 | |
|
|
1243 | for (configuration::node_vector::iterator i = conf.nodes.begin (); |
|
|
1244 | i != conf.nodes.end (); ++i) |
|
|
1245 | prots |= (*i)->can_send | (*i)->can_recv; |
|
|
1246 | |
|
|
1247 | sockinfo si; |
1225 | sockinfo si; |
1248 | |
1226 | |
1249 | si.set (THISNODE); |
1227 | si.set (THISNODE); |
1250 | |
1228 | |
1251 | udpv4_fd = -1; |
1229 | udpv4_fd = -1; |
1252 | |
1230 | |
1253 | if (prots & PROT_UDPv4) |
1231 | if (THISNODE->protocols & PROT_UDPv4) |
1254 | { |
1232 | { |
1255 | udpv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); |
1233 | udpv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); |
1256 | |
1234 | |
1257 | if (udpv4_fd < 0) |
1235 | if (udpv4_fd < 0) |
1258 | return -1; |
1236 | return -1; |
… | |
… | |
1281 | |
1259 | |
1282 | udpv4_ev_watcher.start (udpv4_fd, POLLIN); |
1260 | udpv4_ev_watcher.start (udpv4_fd, POLLIN); |
1283 | } |
1261 | } |
1284 | |
1262 | |
1285 | ipv4_fd = -1; |
1263 | ipv4_fd = -1; |
1286 | if (prots & PROT_IPv4) |
1264 | if (THISNODE->protocols & PROT_IPv4) |
1287 | { |
1265 | { |
1288 | ipv4_fd = socket (PF_INET, SOCK_RAW, ::conf.ip_proto); |
1266 | ipv4_fd = socket (PF_INET, SOCK_RAW, ::conf.ip_proto); |
1289 | |
1267 | |
1290 | if (ipv4_fd < 0) |
1268 | if (ipv4_fd < 0) |
1291 | return -1; |
1269 | return -1; |
… | |
… | |
1346 | unsigned int dst = pkt->dst (); |
1324 | unsigned int dst = pkt->dst (); |
1347 | |
1325 | |
1348 | slog (L_NOISE, _("<<?/%s received possible vpn packet type %d from %d to %d, length %d"), |
1326 | slog (L_NOISE, _("<<?/%s received possible vpn packet type %d from %d to %d, length %d"), |
1349 | (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len); |
1327 | (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len); |
1350 | |
1328 | |
1351 | if (dst > conns.size () || pkt->typ () >= vpn_packet::PT_MAX) |
|
|
1352 | slog (L_WARN, _("<<? received CORRUPTED packet type %d from %d to %d"), |
|
|
1353 | pkt->typ (), pkt->src (), pkt->dst ()); |
|
|
1354 | else if (dst == 0 && !THISNODE->routerprio) |
|
|
1355 | slog (L_WARN, _("<<%d received broadcast, but we are no router"), dst); |
|
|
1356 | else if (dst != 0 && dst != THISNODE->id) |
|
|
1357 | slog (L_WARN, |
|
|
1358 | _("received frame for node %d ('%s') from %s, but this is node %d ('%s')"), |
|
|
1359 | dst, conns[dst - 1]->conf->nodename, |
|
|
1360 | (const char *)rsi, |
|
|
1361 | THISNODE->id, THISNODE->nodename); |
|
|
1362 | else if (src == 0 || src > conns.size ()) |
1329 | if (src == 0 || src > conns.size () |
1363 | slog (L_WARN, _("received frame from unknown node %d (%s)"), |
1330 | || dst > conns.size () |
1364 | src, (const char *)rsi); |
1331 | || pkt->typ () >= vpn_packet::PT_MAX) |
|
|
1332 | slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)"), |
|
|
1333 | (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ()); |
1365 | else |
1334 | else |
|
|
1335 | { |
|
|
1336 | connection *c = conns[src - 1]; |
|
|
1337 | |
|
|
1338 | if (dst == 0 && !THISNODE->routerprio) |
|
|
1339 | slog (L_WARN, _("%s(%s): received broadcast, but we are no router"), |
|
|
1340 | c->conf->nodename, (const char *)rsi); |
|
|
1341 | else if (dst != 0 && dst != THISNODE->id) |
|
|
1342 | // FORWARDING NEEDED ;) |
|
|
1343 | slog (L_WARN, |
|
|
1344 | _("received frame for node %d ('%s') from %s, but this is node %d ('%s')"), |
|
|
1345 | dst, conns[dst - 1]->conf->nodename, |
|
|
1346 | (const char *)rsi, |
|
|
1347 | THISNODE->id, THISNODE->nodename); |
|
|
1348 | else |
1366 | conns[src - 1]->recv_vpn_packet (pkt, rsi); |
1349 | c->recv_vpn_packet (pkt, rsi); |
|
|
1350 | } |
1367 | } |
1351 | } |
1368 | |
1352 | |
1369 | void |
1353 | void |
1370 | vpn::udpv4_ev (short revents) |
1354 | vpn::udpv4_ev (short revents) |
1371 | { |
1355 | { |