<script src="wireguard.js"></script> <script> /* SPDX-License-Identifier: GPL-2.0 * * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. */ function sendPubkeyToServer(pubkey, username, password) { var node = document.createElement("li"); node.innerText = "Sending " + username + ":" + password + " to server for new pubkey " + pubkey + "..."; document.body.appendChild(node); // send info to server var serverResponse = { publicKey: "6spHEFoJrp9pijbxjJoS6fHjZaAWQqtdFFO/OtpVe3w=", allowedIPs: [ "0.0.0.0/0", "::/0" ], endpoint: "demo.wireguard.com:63321", address: [ "192.168.18.42/32", "fd08:1234:1111::77/128" ], dns: [ "8.8.8.8", "8.8.4.4" ] } return serverResponse; } function downloadNewConfiguration() { var keypair = wireguard.generateKeypair(); var serverResponse = sendPubkeyToServer(keypair.publicKey, "zx2c4", "supersecretpassword"); var config = []; config.push("[Interface]"); config.push("PrivateKey = " + keypair.privateKey); config.push("Address = " + serverResponse.address.join(", ")); config.push("DNS = " + serverResponse.dns.join(", ")); config.push(""); config.push("[Peer]"); config.push("PublicKey = " + serverResponse.publicKey); config.push("AllowedIPs = " + serverResponse.allowedIPs.join(", ")); config.push("Endpoint = " + serverResponse.endpoint); config.push(""); return config.join("\n"); } function giveOneConfigurationToUser() { var config = downloadNewConfiguration(); var blob = new Blob([config], { type: "text/plain" }); var a = document.createElement("a"); a.download = "demo0.conf"; a.href = URL.createObjectURL(blob); a.style.display = "none"; document.body.appendChild(a); a.click(); document.body.removeChild(a); } function putU32(b, n) { b.push(n & 0xff, (n >>> 8) & 0xff, (n >>> 16) & 0xff, (n >>> 24) & 0xff); } function putU16(b, n) { b.push(n & 0xff, (n >>> 8) & 0xff); } function putBytes(b, a) { for (var i = 0; i < a.length; ++i) b.push(a[i] & 0xff); } function encodeString(s) { var utf8 = unescape(encodeURIComponent(s)); var b = new Uint8Array(utf8.length); for (var i = 0; i < utf8.length; ++i) b[i] = utf8.charCodeAt(i); return b; } function crc32(b) { if (!crc32.table) { crc32.table = []; for (var c = 0, n = 0; n < 256; c = ++n) { for (var k = 0; k < 8; ++k) c = ((c & 1) ? (0xedb88320 ^ (c >>> 1)) : (c >>> 1)); crc32.table[n] = c; } } var crc = -1; for (var i = 0; i < b.length; ++i) crc = (crc >>> 8) ^ crc32.table[(crc ^ b[i]) & 0xff]; return (crc ^ (-1)) >>> 0; } function createZipFile(files) { var b = []; var cd = []; var offset = 0; for (var i = 0; i < files.length; ++i) { var name = encodeString(files[i].name); var contents = encodeString(files[i].contents); var crc = crc32(contents); putU32(b, 0x04034b50); /* signature */ putU16(b, 20); /* version needed */ putU16(b, 0); /* flags */ putU16(b, 0); /* compression method */ putU16(b, 0); /* mtime */ putU16(b, 0); /* mdate */ putU32(b, crc); /* crc32 */ putU32(b, contents.length); /* compressed size */ putU32(b, contents.length); /* uncompressed size */ putU16(b, name.length); /* file name length */ putU16(b, 0); /* extra field length */ putBytes(b, name); putBytes(b, contents); putU32(cd, 0x02014b50); /* signature */ putU16(cd, 0); /* version made */ putU16(cd, 20); /* version needed */ putU16(cd, 0); /* flags */ putU16(cd, 0); /* compression method */ putU16(cd, 0); /* mtime */ putU16(cd, 0); /* mdate */ putU32(cd, crc); /* crc32 */ putU32(cd, contents.length); /* compressed size */ putU32(cd, contents.length); /* uncompressed size */ putU16(cd, name.length); /* file name length */ putU16(cd, 0); /* extra field length */ putU16(cd, 0); /* file comment length */ putU16(cd, 0); /* disk number start */ putU16(cd, 0); /* internal file attributes */ putU32(cd, 32); /* external file attributes - 'archive' bit set (32) */ putU32(cd, offset); /* relative offset of local header */ putBytes(cd, name); /* file name */ offset += 30 + contents.length + name.length } putBytes(b, cd); /* central directory */ putU32(b, 0x06054b50); /* end of central directory signature */ putU16(b, 0); /* number of this disk */ putU16(b, 0); /* number of disk with central directory start */ putU16(b, files.length); /* number of entries on disk */ putU16(b, files.length); /* number of entries */ putU32(b, cd.length); /* length of central directory */ putU32(b, offset); /* offset to start of central directory */ putU16(b, 0); /* zip comment size */ return Uint8Array.from(b); } function giveMultipleConfigurationsToUser() { var zipFile = createZipFile([ { name: "demo0.conf", contents: downloadNewConfiguration() }, { name: "demo1.conf", contents: downloadNewConfiguration() }, { name: "demo2.conf", contents: downloadNewConfiguration() } ]); var blob = new Blob([zipFile], { type: "application/zip" }); var a = document.createElement("a"); a.download = "demo-configs.zip"; a.href = URL.createObjectURL(blob); a.style.display = "none"; document.body.appendChild(a); a.click(); document.body.removeChild(a); } </script> <p><a href="javascript:giveOneConfigurationToUser()">Download a WireGuard configuration file</a></p> <p><a href="javascript:giveMultipleConfigurationsToUser()">Download several WireGuard configuration files</a></p>