… | |
… | |
581 | } |
581 | } |
582 | |
582 | |
583 | struct auth_req_packet : config_packet |
583 | struct auth_req_packet : config_packet |
584 | { |
584 | { |
585 | char magic[8]; |
585 | char magic[8]; |
586 | u8 initiate, can_recv; // false if this is just an automatic reply |
586 | u8 initiate; // false if this is just an automatic reply |
|
|
587 | u8 protocols; // supported protocols (will get patches on forward) |
587 | u8 pad2, pad3; |
588 | u8 pad2, pad3; |
588 | rsaid id; |
589 | rsaid id; |
589 | rsaencrdata encr; |
590 | rsaencrdata encr; |
590 | |
591 | |
591 | auth_req_packet (int dst, bool initiate_, u8 can_recv_) |
592 | auth_req_packet (int dst, bool initiate_, u8 protocols_) |
592 | { |
593 | { |
593 | config_packet::setup (PT_AUTH_REQ, dst); |
594 | config_packet::setup (PT_AUTH_REQ, dst); |
594 | strncpy (magic, MAGIC, 8); |
595 | strncpy (magic, MAGIC, 8); |
595 | initiate = !!initiate_; |
596 | initiate = !!initiate_; |
596 | can_recv = can_recv_; |
597 | protocols = protocols_; |
597 | |
598 | |
598 | len = sizeof (*this) - sizeof (net_packet); |
599 | len = sizeof (*this) - sizeof (net_packet); |
599 | } |
600 | } |
600 | }; |
601 | }; |
601 | |
602 | |
… | |
… | |
614 | } |
615 | } |
615 | }; |
616 | }; |
616 | |
617 | |
617 | struct connect_req_packet : vpn_packet |
618 | struct connect_req_packet : vpn_packet |
618 | { |
619 | { |
619 | u8 id; |
620 | u8 id, protocols; |
620 | u8 pad1, pad2, pad3; |
621 | u8 pad1, pad2; |
621 | |
622 | |
622 | connect_req_packet (int dst, int id_) |
623 | connect_req_packet (int dst, int id_, u8 protocols_) |
|
|
624 | : id(id_) |
|
|
625 | , protocols(protocols_) |
623 | { |
626 | { |
624 | id = id_; |
|
|
625 | set_hdr (PT_CONNECT_REQ, dst); |
627 | set_hdr (PT_CONNECT_REQ, dst); |
626 | len = sizeof (*this) - sizeof (net_packet); |
628 | len = sizeof (*this) - sizeof (net_packet); |
627 | } |
629 | } |
628 | }; |
630 | }; |
629 | |
631 | |
630 | struct connect_info_packet : vpn_packet |
632 | struct connect_info_packet : vpn_packet |
631 | { |
633 | { |
632 | u8 id, can_recv; |
634 | u8 id, protocols; |
633 | u8 pad1, pad2; |
635 | u8 pad1, pad2; |
634 | sockinfo si; |
636 | sockinfo si; |
635 | |
637 | |
636 | connect_info_packet (int dst, int id_, sockinfo &si_, u8 can_recv_) |
638 | connect_info_packet (int dst, int id_, const sockinfo &si_, u8 protocols_) |
|
|
639 | : id(id_) |
|
|
640 | , protocols(protocols_) |
|
|
641 | , si(si_) |
637 | { |
642 | { |
638 | id = id_; |
|
|
639 | can_recv = can_recv_; |
|
|
640 | si = si_; |
|
|
641 | set_hdr (PT_CONNECT_INFO, dst); |
643 | set_hdr (PT_CONNECT_INFO, dst); |
642 | |
644 | |
643 | len = sizeof (*this) - sizeof (net_packet); |
645 | len = sizeof (*this) - sizeof (net_packet); |
644 | } |
646 | } |
645 | }; |
647 | }; |
… | |
… | |
678 | } |
680 | } |
679 | |
681 | |
680 | void |
682 | void |
681 | connection::send_auth_request (const sockinfo &si, bool initiate) |
683 | connection::send_auth_request (const sockinfo &si, bool initiate) |
682 | { |
684 | { |
683 | auth_req_packet *pkt = new auth_req_packet (conf->id, initiate, THISNODE->can_recv); |
685 | auth_req_packet *pkt = new auth_req_packet (conf->id, initiate, THISNODE->protocols); |
684 | |
686 | |
685 | // the next line is very conservative |
687 | prot_send = best_protocol (THISNODE->protocols & conf->protocols); |
686 | prot_send = best_protocol (THISNODE->can_send & THISNODE->can_recv & conf->can_recv); |
|
|
687 | |
688 | |
688 | rsachallenge chg; |
689 | rsachallenge chg; |
689 | |
690 | |
690 | rsa_cache.gen (pkt->id, chg); |
691 | rsa_cache.gen (pkt->id, chg); |
691 | |
692 | |
… | |
… | |
715 | slog (L_TRACE, ">>%d PT_AUTH_RES [%s]", conf->id, (const char *)si); |
716 | slog (L_TRACE, ">>%d PT_AUTH_RES [%s]", conf->id, (const char *)si); |
716 | |
717 | |
717 | send_vpn_packet (pkt, si, IPTOS_RELIABILITY); // rsa is very very costly |
718 | send_vpn_packet (pkt, si, IPTOS_RELIABILITY); // rsa is very very costly |
718 | |
719 | |
719 | delete pkt; |
720 | delete pkt; |
|
|
721 | } |
|
|
722 | |
|
|
723 | void |
|
|
724 | connection::send_connect_info (int rid, const sockinfo &rsi, u8 rprotocols) |
|
|
725 | { |
|
|
726 | slog (L_TRACE, ">>%d PT_CONNECT_INFO(%d,%s)\n", |
|
|
727 | conf->id, rid, (const char *)rsi); |
|
|
728 | |
|
|
729 | connect_info_packet *r = new connect_info_packet (conf->id, rid, rsi, rprotocols); |
|
|
730 | |
|
|
731 | r->hmac_set (octx); |
|
|
732 | send_vpn_packet (r, si); |
|
|
733 | |
|
|
734 | delete r; |
720 | } |
735 | } |
721 | |
736 | |
722 | void |
737 | void |
723 | connection::establish_connection_cb (tstamp &ts) |
738 | connection::establish_connection_cb (tstamp &ts) |
724 | { |
739 | { |
… | |
… | |
909 | delete octx; |
924 | delete octx; |
910 | |
925 | |
911 | octx = new crypto_ctx (k, 1); |
926 | octx = new crypto_ctx (k, 1); |
912 | oseqno = ntohl (*(u32 *)&k[CHG_SEQNO]) & 0x7fffffff; |
927 | oseqno = ntohl (*(u32 *)&k[CHG_SEQNO]) & 0x7fffffff; |
913 | |
928 | |
914 | conf->can_recv = p->can_recv; |
929 | conf->protocols = p->protocols; |
915 | send_auth_response (rsi, p->id, k); |
930 | send_auth_response (rsi, p->id, k); |
916 | |
931 | |
917 | break; |
932 | break; |
918 | } |
933 | } |
919 | } |
934 | } |
… | |
… | |
1052 | if (ictx && octx && rsi == si && pkt->hmac_chk (ictx)) |
1067 | if (ictx && octx && rsi == si && pkt->hmac_chk (ictx)) |
1053 | { |
1068 | { |
1054 | connect_req_packet *p = (connect_req_packet *) pkt; |
1069 | connect_req_packet *p = (connect_req_packet *) pkt; |
1055 | |
1070 | |
1056 | assert (p->id > 0 && p->id <= vpn->conns.size ()); // hmac-auth does not mean we accept anything |
1071 | assert (p->id > 0 && p->id <= vpn->conns.size ()); // hmac-auth does not mean we accept anything |
1057 | |
1072 | conf->protocols = p->protocols; |
1058 | connection *c = vpn->conns[p->id - 1]; |
1073 | connection *c = vpn->conns[p->id - 1]; |
1059 | |
1074 | |
1060 | slog (L_TRACE, "<<%d PT_CONNECT_REQ(%d) [%d]\n", |
1075 | slog (L_TRACE, "<<%d PT_CONNECT_REQ(%d) [%d]\n", |
1061 | conf->id, p->id, c->ictx && c->octx); |
1076 | conf->id, p->id, c->ictx && c->octx); |
1062 | |
1077 | |
1063 | if (c->ictx && c->octx) |
1078 | if (c->ictx && c->octx) |
1064 | { |
1079 | { |
1065 | // send connect_info packets to both sides, in case one is |
1080 | // send connect_info packets to both sides, in case one is |
1066 | // behind a nat firewall (or both ;) |
1081 | // behind a nat firewall (or both ;) |
1067 | { |
1082 | c->send_connect_info (conf->id, si, conf->protocols); |
1068 | slog (L_TRACE, ">>%d PT_CONNECT_INFO(%d,%s)\n", |
1083 | 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 | } |
1084 | } |
1091 | } |
1085 | } |
1092 | |
1086 | |
1093 | break; |
1087 | break; |
1094 | |
1088 | |
… | |
… | |
1096 | if (ictx && octx && rsi == si && pkt->hmac_chk (ictx)) |
1090 | if (ictx && octx && rsi == si && pkt->hmac_chk (ictx)) |
1097 | { |
1091 | { |
1098 | connect_info_packet *p = (connect_info_packet *) pkt; |
1092 | connect_info_packet *p = (connect_info_packet *) pkt; |
1099 | |
1093 | |
1100 | assert (p->id > 0 && p->id <= vpn->conns.size ()); // hmac-auth does not mean we accept anything |
1094 | assert (p->id > 0 && p->id <= vpn->conns.size ()); // hmac-auth does not mean we accept anything |
1101 | |
1095 | conf->protocols = p->protocols; |
1102 | connection *c = vpn->conns[p->id - 1]; |
1096 | connection *c = vpn->conns[p->id - 1]; |
1103 | |
1097 | |
1104 | slog (L_TRACE, "<<%d PT_CONNECT_INFO(%d,%s) (%d)", |
1098 | slog (L_TRACE, "<<%d PT_CONNECT_INFO(%d,%s) (%d)", |
1105 | conf->id, p->id, (const char *)p->si, !c->ictx && !c->octx); |
1099 | conf->id, p->id, (const char *)p->si, !c->ictx && !c->octx); |
1106 | |
1100 | |
1107 | c->conf->can_recv = p->can_recv; |
|
|
1108 | c->send_auth_request (p->si, true); |
1101 | c->send_auth_request (p->si, true); |
1109 | } |
1102 | } |
1110 | |
1103 | |
1111 | break; |
1104 | break; |
1112 | |
1105 | |
… | |
… | |
1136 | reset_connection (); |
1129 | reset_connection (); |
1137 | } |
1130 | } |
1138 | |
1131 | |
1139 | void connection::connect_request (int id) |
1132 | void connection::connect_request (int id) |
1140 | { |
1133 | { |
1141 | connect_req_packet *p = new connect_req_packet (conf->id, id); |
1134 | connect_req_packet *p = new connect_req_packet (conf->id, id, conf->protocols); |
1142 | |
1135 | |
1143 | slog (L_TRACE, ">>%d PT_CONNECT_REQ(%d)", id, conf->id); |
1136 | slog (L_TRACE, ">>%d PT_CONNECT_REQ(%d)", conf->id, id); |
1144 | p->hmac_set (octx); |
1137 | p->hmac_set (octx); |
1145 | send_vpn_packet (p, si); |
1138 | send_vpn_packet (p, si); |
1146 | |
1139 | |
1147 | delete p; |
1140 | delete p; |
1148 | } |
1141 | } |
… | |
… | |
1235 | } |
1228 | } |
1236 | |
1229 | |
1237 | int |
1230 | int |
1238 | vpn::setup () |
1231 | vpn::setup () |
1239 | { |
1232 | { |
1240 | u8 prots = 0; |
|
|
1241 | |
|
|
1242 | for (configuration::node_vector::iterator i = conf.nodes.begin (); |
|
|
1243 | i != conf.nodes.end (); ++i) |
|
|
1244 | prots |= (*i)->can_send | (*i)->can_recv; |
|
|
1245 | |
|
|
1246 | sockinfo si; |
1233 | sockinfo si; |
1247 | |
1234 | |
1248 | si.set (THISNODE); |
1235 | si.set (THISNODE); |
1249 | |
1236 | |
1250 | udpv4_fd = -1; |
1237 | udpv4_fd = -1; |
1251 | |
1238 | |
1252 | if (prots & PROT_UDPv4) |
1239 | if (THISNODE->protocols & PROT_UDPv4) |
1253 | { |
1240 | { |
1254 | udpv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); |
1241 | udpv4_fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); |
1255 | |
1242 | |
1256 | if (udpv4_fd < 0) |
1243 | if (udpv4_fd < 0) |
1257 | return -1; |
1244 | return -1; |
… | |
… | |
1280 | |
1267 | |
1281 | udpv4_ev_watcher.start (udpv4_fd, POLLIN); |
1268 | udpv4_ev_watcher.start (udpv4_fd, POLLIN); |
1282 | } |
1269 | } |
1283 | |
1270 | |
1284 | ipv4_fd = -1; |
1271 | ipv4_fd = -1; |
1285 | if (prots & PROT_IPv4) |
1272 | if (THISNODE->protocols & PROT_IPv4) |
1286 | { |
1273 | { |
1287 | ipv4_fd = socket (PF_INET, SOCK_RAW, ::conf.ip_proto); |
1274 | ipv4_fd = socket (PF_INET, SOCK_RAW, ::conf.ip_proto); |
1288 | |
1275 | |
1289 | if (ipv4_fd < 0) |
1276 | if (ipv4_fd < 0) |
1290 | return -1; |
1277 | return -1; |
… | |
… | |
1345 | unsigned int dst = pkt->dst (); |
1332 | unsigned int dst = pkt->dst (); |
1346 | |
1333 | |
1347 | slog (L_NOISE, _("<<?/%s received possible vpn packet type %d from %d to %d, length %d"), |
1334 | slog (L_NOISE, _("<<?/%s received possible vpn packet type %d from %d to %d, length %d"), |
1348 | (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len); |
1335 | (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len); |
1349 | |
1336 | |
1350 | if (dst > conns.size () || pkt->typ () >= vpn_packet::PT_MAX) |
|
|
1351 | slog (L_WARN, _("<<? received CORRUPTED packet type %d from %d to %d"), |
|
|
1352 | pkt->typ (), pkt->src (), pkt->dst ()); |
|
|
1353 | else if (dst == 0 && !THISNODE->routerprio) |
|
|
1354 | slog (L_WARN, _("<<%d received broadcast, but we are no router"), dst); |
|
|
1355 | else if (dst != 0 && dst != THISNODE->id) |
|
|
1356 | slog (L_WARN, |
|
|
1357 | _("received frame for node %d ('%s') from %s, but this is node %d ('%s')"), |
|
|
1358 | dst, conns[dst - 1]->conf->nodename, |
|
|
1359 | (const char *)rsi, |
|
|
1360 | THISNODE->id, THISNODE->nodename); |
|
|
1361 | else if (src == 0 || src > conns.size ()) |
1337 | if (src == 0 || src > conns.size () |
1362 | slog (L_WARN, _("received frame from unknown node %d (%s)"), |
1338 | || dst > conns.size () |
1363 | src, (const char *)rsi); |
1339 | || pkt->typ () >= vpn_packet::PT_MAX) |
|
|
1340 | slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)"), |
|
|
1341 | (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ()); |
1364 | else |
1342 | else |
|
|
1343 | { |
|
|
1344 | connection *c = conns[src - 1]; |
|
|
1345 | |
|
|
1346 | if (dst == 0 && !THISNODE->routerprio) |
|
|
1347 | slog (L_WARN, _("%s(%s): received broadcast, but we are no router"), |
|
|
1348 | c->conf->nodename, (const char *)rsi); |
|
|
1349 | else if (dst != 0 && dst != THISNODE->id) |
|
|
1350 | // FORWARDING NEEDED ;) |
|
|
1351 | slog (L_WARN, |
|
|
1352 | _("received frame for node %d ('%s') from %s, but this is node %d ('%s')"), |
|
|
1353 | dst, conns[dst - 1]->conf->nodename, |
|
|
1354 | (const char *)rsi, |
|
|
1355 | THISNODE->id, THISNODE->nodename); |
|
|
1356 | else |
1365 | conns[src - 1]->recv_vpn_packet (pkt, rsi); |
1357 | c->recv_vpn_packet (pkt, rsi); |
|
|
1358 | } |
1366 | } |
1359 | } |
1367 | |
1360 | |
1368 | void |
1361 | void |
1369 | vpn::udpv4_ev (short revents) |
1362 | vpn::udpv4_ev (short revents) |
1370 | { |
1363 | { |