#include "models/wg2nd.hpp" #include #include #include void print_config(std::ostream & ss, wg2nd::SystemdFilespec const & filespec, bool privileged) { if(privileged) { ss << "touch " << filespec.name << "\n\n"; ss << "chown root:systemd-network " << filespec.name << "\n\n"; ss << "chmod 0640 " << filespec.name << "\n\n"; } ss << "cat >" << filespec.name << " <<_EOF\n" << filespec.contents << "_EOF\n"; ss << "\n"; } std::string wg2nd_cmdseq(std::string const & interface_name, std::string const & wg_config) { std::istringstream wg_stream { wg_config }; std::ostringstream bash_config_cmds; wg2nd::SystemdConfig cfg; try { cfg = wg2nd::wg2nd(interface_name, wg_stream, "/etc/systemd/network/", {}); } catch(wg2nd::ParsingException const & e) { bash_config_cmds << "parsing error: "; if(e.line_no().has_value()) { bash_config_cmds << "line " << e.line_no().value() << ": "; } bash_config_cmds << e.what() << "\n"; return bash_config_cmds.str(); } catch(wg2nd::ConfigurationException const & e) { bash_config_cmds << "configuration error: " << e.what() << "\n"; return bash_config_cmds.str(); } bash_config_cmds << "# Disable history to prevent private key leakage\n"; bash_config_cmds << "set +o history\n"; bash_config_cmds << "\n"; bash_config_cmds << "cd /etc/systemd/network\n\n"; bash_config_cmds << "# Create network device\n"; print_config(bash_config_cmds, cfg.netdev, false); bash_config_cmds << "\n"; bash_config_cmds << "# Configure network\n"; print_config(bash_config_cmds, cfg.network, false); bash_config_cmds << "\n"; bash_config_cmds << "# Create and protect private keyfile\n"; print_config(bash_config_cmds, cfg.private_keyfile, true); bash_config_cmds << "\n"; if(cfg.symmetric_keyfiles.size() > 0) { bash_config_cmds << "# Create and protect private preshared keyfile\n"; } for(wg2nd::SystemdFilespec const & spec : cfg.symmetric_keyfiles) { print_config(bash_config_cmds, spec, true); bash_config_cmds << "\n"; } bash_config_cmds << "# Re-enable history tracking\n"; bash_config_cmds << "set -o history\n"; bash_config_cmds << "\n"; if(cfg.warnings.size() > 0) { bash_config_cmds << "# NOTE: the conversion tool emitted warnings.\n"; for(std::string const & warning : cfg.warnings) { bash_config_cmds << "# warning:" << warning << "\n"; } } return bash_config_cmds.str(); } EMSCRIPTEN_BINDINGS(wg2nd) { emscripten::function("wg2nd_cmdseq", &wg2nd_cmdseq); }