#include "./wgcpp.hpp" #include "wireguard/wireguard.h" #include #include #include #include #include std::map> Users::acl_aggr() { std::map> acl_list; for (const User &usr : this->users) { for (const std::string_view member : usr.acl_member) { auto x = acl_list.find(member); if (x != acl_list.end()) { acl_list.at(member).push_back(usr); } else { std::vector acl_members; acl_members.push_back(usr); acl_list[member] = acl_members; } } } return acl_list; } void Users::sort_with_ip() { std::sort(this->users.begin(), this->users.end(), [](User &a, User &b) { return a.ipv4 < b.ipv4; }); } WG::WG(Users &wg_users, const char name[16], std::uint16_t port, uint32_t network, uint8_t cidr) : users(wg_users), network_ipv4(network), cidr(cidr) { wg_generate_private_key(this->wg_dev.private_key); wg_key_to_base64(this->b64_private_key, this->wg_dev.private_key); wg_generate_public_key(this->wg_dev.public_key, this->wg_dev.private_key); wg_key_to_base64(this->b64_public_key, this->wg_dev.public_key); this->wg_dev.first_peer = nullptr; this->wg_dev.last_peer = nullptr; std::strncpy(this->wg_dev.name, name, 16); this->wg_dev.listen_port = port; this->wg_dev.flags = (enum wg_device_flags)(WGDEVICE_HAS_LISTEN_PORT | WGDEVICE_HAS_PRIVATE_KEY | WGDEVICE_HAS_PUBLIC_KEY); uint32_t wildcard = 0xffffffff; if (this->cidr < 32) { wildcard = ((1 << (32 - this->cidr)) - 1); } for (uint32_t i = 2; i < wildcard; i++) { if ((i ^ 255) != 0) { this->ipv4_pool.insert(this->network_ipv4 + i); } } for (const auto &user : wg_users.users) { this->ipv4_pool.erase(user.ipv4); } } WG::WG(Users &wg_users, const char name[16], std::uint16_t port, uint32_t network, uint8_t cidr, std::string_view srv_priv_key, std::string_view srv_pub_key) : users(wg_users), network_ipv4(network), cidr(cidr) { std::strncpy(this->b64_private_key, srv_priv_key.data(), 45); std::strncpy(this->b64_public_key, srv_pub_key.data(), 45); wg_key_from_base64(this->wg_dev.private_key, this->b64_private_key); wg_key_from_base64(this->wg_dev.public_key, this->b64_public_key); this->wg_dev.first_peer = nullptr; this->wg_dev.last_peer = nullptr; std::strncpy(this->wg_dev.name, name, 16); this->wg_dev.listen_port = port; this->wg_dev.flags = (enum wg_device_flags)(WGDEVICE_HAS_LISTEN_PORT | WGDEVICE_HAS_PRIVATE_KEY | WGDEVICE_HAS_PUBLIC_KEY); uint32_t wildcard = 0xffffffff; if (this->cidr < 32) { wildcard = ((1 << (32 - this->cidr)) - 1); } for (uint32_t i = 2; i < wildcard; i++) { if ((i ^ 255) != 0) { this->ipv4_pool.insert(this->network_ipv4 + i); } } for (const auto &user : wg_users.users) { this->ipv4_pool.erase(user.ipv4); } } void WG::merge() { User *previous = nullptr; for (User &user : this->users.users) { if (previous) { previous->node.next_peer = &user.node; } else { previous = &user; } } } User &WG::add_cfg(strv name) { uint32_t ipv4 = this->ipv4_alloc(); return this->add_cfg(name, ipv4); } User &WG::add_cfg(strv name, uint32_t ipv4) { wg_key pub, priv; wg_generate_private_key(priv); wg_generate_public_key(pub, priv); User new_user(name, ipv4, pub, priv); this->users.users.push_back(new_user); return this->users.users.back(); } std::vector *WG::peer_state() { std::vector *x = new std::vector(); for (User &user : this->users.users) { WGPeerStat stat; stat.active = !(user.node.flags & WGPEER_REMOVE_ME); stat.ipv4 = user.node.first_allowedip->ip4.s_addr; wg_key_to_base64(stat.pubkey, user.node.public_key); x->push_back(stat); } return x; } User::User(strv name, uint32_t ipv4, wg_key pubkey, wg_key privkey) : username(name), ipv4(ipv4) { memset(&this->node, 0, sizeof(wg_peer)); this->node.flags = (enum wg_peer_flags)(WGPEER_HAS_PUBLIC_KEY | WGPEER_REPLACE_ALLOWEDIPS); wg_allowedip *allowed_ip = new wg_allowedip; allowed_ip->cidr = 32; allowed_ip->family = AF_INET; allowed_ip->ip4.s_addr = htonl(ipv4); this->node.first_allowedip = allowed_ip; this->node.last_allowedip = allowed_ip; memcpy(this->node.public_key, pubkey, sizeof(uint8_t) * 32); memcpy(this->privkey, privkey, sizeof(uint8_t) * 32); }