-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathwizard.html
479 lines (463 loc) · 69.1 KB
/
wizard.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
<!--
#
# EdgeMAX Wizard "WireGuard" created 11/2021 by CHiL.at
#
# Github repository: https://github.com/vchrizz/ER-wizard-WireGuard/
#
# Works on all EdgeRouter and EdgePoint devices (EdgeOS versions 1.9.0+ and 2.0+)
#
-->
<style>
/* add wireguard logo in background of configuration box */
div#wireguardlogo {
position:absolute;
top:0px;
left:130px;
width:560px;
height:99px;
z-index:0;
padding:0px;
background-image:url(data:image/jpeg;base64,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);
background-repeat:no-repeat;
opacity:0.3;
filter:alpha(opacity=5);
}
/* set courier font for local public key input field */
input#localpubkey {
font-family:courier;
}
/* position credits right on top */
legend#createdby {
position:absolute;
right:0px;
padding:5px;
}
/* style status-box */
div#status {
padding:15px;
border: 1px solid lightgray;
width:670px;
float:none;
clear:both;
}
/* align public key input field */
div#publickey {
left:40px;
}
/* hide QR elements and align qrcode for pubkey */
#qrcodepubkey {
display:none; left:300px;
}
#qrcodeclientconf {
/* display:none; */
width:384px;
height:384px;
padding:0px;
}
/* vertically align all td elements in the middle */
td {
vertical-align:middle;
}
/* vertically align allowed-ips input fields at the top */
td#allowedips {
vertical-align:top;
}
</style>
<legend id="createdby">
<center>EdgeMAX Wizard "WireGuard"<br>created 2021 by <a href="https://chil.at" target="_blank">CHiL.at</a></center>
</legend>
<div class="instructions">
<h3>WireGuard - FAST, MODERN, SECURE, VPN TUNNEL</h3>
<div><a href="https://www.wireguard.com/" target="_blank">WireGuard</a><sup>®</sup> is an extremely simple yet fast and modern VPN that utilizes state-of-the-art <a href="https://www.wireguard.com/protocol/" target="_blank">cryptography</a>.</div>
<div>It aims to be <a href="https://www.wireguard.com/performance/" target="_blank">faster</a>, <a href="https://www.wireguard.com/quickstart/" target="_blank">simpler</a>, leaner, and more useful than IPsec, while avoiding the massive headache.</div>
</div>
<div id="status">
<table border="0">
<tr><td>Package Status:</td><td><input disabled id="pkgstatus" name="pkgstatus" type="text" size="80" disabled /></td></tr>
<tr><td>Process Status:</td><td><input disabled id="procstatus" name="procstatus" type="text" size="80" disabled /></td></tr>
<tr><td>Wizard Status:</td><td><input disabled id="wizstatus" name="wizstatus" type="text" size="80" disabled /></td></tr>
<tr><td colspan="2"><div><span><input id="wgsetupscript" name="wgsetupscript" type="checkbox" /> </span></div><div><span class="text" data-infotip='When updating the Firmware, WireGuard package gets lost (only data from /config/ directory will be copied over to newly installed system). Enable this Setup-Script to install and setup WireGuard after a firmware upgrade. WARNING: DO NOT remove WireGuard Wizard if Setup-Script is enabled because it uses functions from this Wizard for setup.'>Setup Script</span></div></td></tr>
<tr><td colspan="2"><div><span><input id="updatefromgithub" name="updatefromgithub" type="checkbox" /> </span></div><div><span class="text" data-infotip='When checked, the wizard will download and install the current version from github. During this process, wireguard will update and restart as well - this will interrupt current connections for a couple of seconds. You need to refresh the EdgeRouter WebUI afterwards, as the browser session will need a restart.'>Upgrade Wizard and WireGuard on 'Apply'.</span></div></td></tr>
<tr><td colspan="2"><div><span><input id="autoupdatefromgithub" name="autoupdatefromgithub" type="checkbox" /> </span></div><div><span class="text" data-infotip='When checked, a daily cronjob will check for a new version on Github and install it automatically. WARNING: DO NOT remove WireGuard Wizard if Auto-Upgrade is enabled because it uses functions from this Wizard for upgrade.'>Upgrade Wizard and WireGuard from <a href="https://github.com/vchrizz/ER-wizard-WireGuard/" target="_blank">GitHub</a> <b>automatically</b></span></div></td></tr>
</table>
</div>
<fieldset id="wireguardconf" name="wireguardconf" class="primary expanded" style="width:700px;">
<div title="WireGuard - FAST, MODERN, SECURE, VPN TUNNEL" id="wireguardlogo"></div>
<legend>Configuration</legend>
<div><span><input name="wgenable" type="checkbox" /></span></div><div><span class="text" data-infotip="Configure interface wg0 and generate private key.">Enable</span></div><br><br>
<div><span class="text" data-infotip="WireGuard Server Port - enables listen-port if set. Only required if you want to connect clients to this device.">Server Port</span></div><br>
<span><input name="listen-port" size="5" placeholder="N/A" title="for example: 51820" /></span><br>
<div><span><input name="route-allowed-ips" type="checkbox" /></span></div><div><span class="text" data-infotip="Add the allowed IPs for all peers to the routing table. By default this is enabled.">Route allowed IPs</span></div><br><br>
<div><span class="text" data-infotip="Sets IP address on interface wg0 (optional).">IP: </span><br>
<div class="addable" data-min="0" data-max="20" data-object="ipaddress" data-objectify="0">
<div class="addable-container"></div>
<div class="addable-template" style="padding-top:0px">
<div class="multi">
<input name="ipaddress" size="13" placeholder="192.168.1.0/24" title="Allowed IP" />
<button type="button" class="addable-remove"></button>
</div>
</div>
<button type="button" class="addable-add">Add IP</button>
</div>
</div>
<div id="publickey">
<input type="hidden" id="privatekey" name="privatekey" />
<div>
<span>Public key: </span>
<span><input disabled id="localpubkey" name="localpubkey" placeholder="N/A" size="45" title="public wireguard key calculated from private key" /></span>
</div>
<div class="addable" data-min="0" data-max="1" data-object="qrcodepubkey" data-objectify="0">
<button type="button" class="addable-add" style="margin-top:0px;" onclick="toggleQRpubkey();">QRcode</button>
</div>
</div>
<div id="qrcodepubkey" style="display:none;"></div>
<div class="clear"><br></div>
<span><b><u>Peers common options:</u></b></span><br>
<table border=0 width="450px"><tr>
<td><div><span class="text" data-infotip="Allowed IPs from peers point of view, for QR code (optional).">Peers allowed ips: </span></td><td>
<div class="addable" data-min="0" data-max="20" data-object="peers-allowed-ips" data-objectify="0">
<div class="addable-container"></div>
<div class="addable-template" style="padding-top:0px">
<div class="multi">
<input name="peers-allowed-ips" size="13" placeholder="192.168.1.0/24" title="Peers allowed IPs" />
<button type="button" class="addable-remove"></button>
</div>
</div>
<button type="button" class="addable-add">Add IP</button>
</div>
</tr><tr><td> </td><td> </td></tr><tr>
<td><div><span class="text" data-infotip="DNS or domain search list from peers point of view, for QR code (optional).">Peers DNS: </span></td><td>
<div class="addable" data-min="0" data-max="20" data-object="peers-dns" data-objectify="0">
<div class="addable-container"></div>
<div class="addable-template" style="padding-top:0px">
<div class="multi">
<input name="peers-dns" size="13" placeholder="192.168.1.1" title="DNS or domain search list" />
<button type="button" class="addable-remove"></button>
</div>
</div>
<button type="button" class="addable-add">Add IP or domain</button>
</div>
</div></td>
</tr><tr><td> </td><td> </td></tr><tr>
<td><div><span class="text" data-infotip="Remote server address with port from peers point of view, for QR code (optional).">Peers remote endpoint: </span></td><td>
<input name="peers-endpoint" id="peers-endpoint" size="30" placeholder="server.example.org:51820" title="Remote server address with port" /></td>
</div></td>
</tr><tr>
<td><div class="clear"><br></div></td><td><div class="clear"><br></div></td>
</tr></table>
<span><b><u>Peers:</u></b></span><br>
<div class="addable" data-min="0" data-max="20" data-object="peerlist" data-objectify="1">
<div class="addable-container"></div>
<div class="addable-template">
<div class="multi">
<table border=0 width="650px" cellspacing=0 cellpadding=0><tr><td>
<table border=0 width="450px"><tr>
<td>Description: </td><td><input name="description" size="30" placeholder="N/A" title="Description of the remote peer" /></td>
</tr><tr>
<td>Remote endpoint: </td><td><input name="endpoint" size="30" placeholder="server.example.org:51820" title="Remote server address with port" /></td>
</tr><tr>
<td>Public key: </td><td><input name="public-key" size="45" placeholder="N/A" title="Remote public key (required)" /></td>
</tr><tr style="display: none;">
<td>Private key: </td><td><input disabled name="private-key" size="45" placeholder="N/A" title="Remote private key" /></td>
</tr><tr>
<td>Preshared key: </td><td><input name="preshared-key" size="45" placeholder="N/A" title="Preshared key (optional)" /></td>
</tr><tr>
<td><div><span class="text" data-infotip='Only useful when trying to maintain a connection from behind NAT, how often to send persistent keepalive packets'>Keepalive: </span></div></td><td><input name="persistent-keepalive" size="2" placeholder="N/A" title="Persistent keepalive, for example: 25" /></td>
</tr><tr>
<td><div><span class="text" data-infotip='The re-keying "handshake" occurs every 2-3 minutes when the connection is actively used (and only when used), so it gives you a good approximation of the last time the connection was active. This field will be omitted if the interface has not successfully connected to the peer since the interface was started.'>Latest handshake: </span></div></td>
<td><input disabled name="latesthandshake" size="30" placeholder="N/A" title="Status: Latest handshake" /></td>
</tr><tr id="foo">
<td><div><span class="text" data-infotip="Generate QR code with configuration to import on the client. Includes new (clientside-)generated client-key, server-public-key and peer pre-shared-key. ATTENTION: make sure you save the generated client-key, it is generated on the client, not saved on the router and can not be recovered if you do not save it!">Client config QR: </span></div></td>
<td>
<div class="addable" data-min="0" data-max="1" data-object="qrcodeclientconf" data-objectify="0">
<div class="addable-template">
<div class="multi">
<input disabled value="" type="image" src="" id="qrcodeclientconf" width="0" height="0" name="qrcodeclientconf" title="Client configuration QR code" ></input>
<!-- <button type="button" class="addable-remove"></button> -->
<br><button class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" type="button" role="button" aria-disabled="false" onclick="downloadConf(this)"><span class="ui-button-text">Download client configuration</span></button>
<button style="display:none" type="button" name="generate-config-remove" class="addable-remove">Remove config</button>
</div>
</div>
<div class="addable-container"></div>
<button type="button" class="addable-add" onclick="setTimeout(toggleQRclientconf,1,this)">Generate config</button>
</div>
</td>
</tr><tr>
<td><br><button type="button" class="addable-remove">Remove peer</button></td>
</tr></table>
</td><td width="250px" id="allowedips">
<span class="text">Allowed IPs: </span><br>
<div class="addable" data-min="0" data-max="20" data-object="allowed-ips" data-objectify="0">
<div class="addable-container"></div>
<div class="addable-template" style="padding-top:0px">
<div class="multi">
<input name="allowed-ips" size="13" placeholder="192.168.1.0/24" title="Allowed IP" />
<button type="button" class="addable-remove"></button>
</div>
</div>
<button type="button" class="addable-add">Add IP</button>
</div>
</td></tr></table>
<hr>
</div>
</div>
<button type="button" class="addable-add">Add peer</button>
</div>
</fieldset>
<script>
// qrcode.min.js from http://davidshimjs.github.io/qrcodejs/
var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this.parsedData=[];for(var b=[],d=0,e=this.data.length;e>d;d++){var f=this.data.charCodeAt(d);f>65536?(b[0]=240|(1835008&f)>>>18,b[1]=128|(258048&f)>>>12,b[2]=128|(4032&f)>>>6,b[3]=128|63&f):f>2048?(b[0]=224|(61440&f)>>>12,b[1]=128|(4032&f)>>>6,b[2]=128|63&f):f>128?(b[0]=192|(1984&f)>>>6,b[1]=128|63&f):b[0]=f,this.parsedData=this.parsedData.concat(b)}this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function b(a,b){this.typeNumber=a,this.errorCorrectLevel=b,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}function i(a,b){if(void 0==a.length)throw new Error(a.length+"/"+b);for(var c=0;c<a.length&&0==a[c];)c++;this.num=new Array(a.length-c+b);for(var d=0;d<a.length-c;d++)this.num[d]=a[d+c]}function j(a,b){this.totalCount=a,this.dataCount=b}function k(){this.buffer=[],this.length=0}function m(){return"undefined"!=typeof CanvasRenderingContext2D}function n(){var a=!1,b=navigator.userAgent;return/android/i.test(b)&&(a=!0,aMat=b.toString().match(/android ([0-9]\.[0-9])/i),aMat&&aMat[1]&&(a=parseFloat(aMat[1]))),a}function r(a,b){for(var c=1,e=s(a),f=0,g=l.length;g>=f;f++){var h=0;switch(b){case d.L:h=l[f][0];break;case d.M:h=l[f][1];break;case d.Q:h=l[f][2];break;case d.H:h=l[f][3]}if(h>=e)break;c++}if(c>l.length)throw new Error("Too long data");return c}function s(a){var b=encodeURI(a).toString().replace(/\%[0-9a-fA-F]{2}/g,"a");return b.length+(b.length!=a?3:0)}a.prototype={getLength:function(){return this.parsedData.length},write:function(a){for(var b=0,c=this.parsedData.length;c>b;b++)a.put(this.parsedData[b],8)}},b.prototype={addData:function(b){var c=new a(b);this.dataList.push(c),this.dataCache=null},isDark:function(a,b){if(0>a||this.moduleCount<=a||0>b||this.moduleCount<=b)throw new Error(a+","+b);return this.modules[a][b]},getModuleCount:function(){return this.moduleCount},make:function(){this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(a,c){this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount);for(var d=0;d<this.moduleCount;d++){this.modules[d]=new Array(this.moduleCount);for(var e=0;e<this.moduleCount;e++)this.modules[d][e]=null}this.setupPositionProbePattern(0,0),this.setupPositionProbePattern(this.moduleCount-7,0),this.setupPositionProbePattern(0,this.moduleCount-7),this.setupPositionAdjustPattern(),this.setupTimingPattern(),this.setupTypeInfo(a,c),this.typeNumber>=7&&this.setupTypeNumber(a),null==this.dataCache&&(this.dataCache=b.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,c)},setupPositionProbePattern:function(a,b){for(var c=-1;7>=c;c++)if(!(-1>=a+c||this.moduleCount<=a+c))for(var d=-1;7>=d;d++)-1>=b+d||this.moduleCount<=b+d||(this.modules[a+c][b+d]=c>=0&&6>=c&&(0==d||6==d)||d>=0&&6>=d&&(0==c||6==c)||c>=2&&4>=c&&d>=2&&4>=d?!0:!1)},getBestMaskPattern:function(){for(var a=0,b=0,c=0;8>c;c++){this.makeImpl(!0,c);var d=f.getLostPoint(this);(0==c||a>d)&&(a=d,b=c)}return b},createMovieClip:function(a,b,c){var d=a.createEmptyMovieClip(b,c),e=1;this.make();for(var f=0;f<this.modules.length;f++)for(var g=f*e,h=0;h<this.modules[f].length;h++){var i=h*e,j=this.modules[f][h];j&&(d.beginFill(0,100),d.moveTo(i,g),d.lineTo(i+e,g),d.lineTo(i+e,g+e),d.lineTo(i,g+e),d.endFill())}return d},setupTimingPattern:function(){for(var a=8;a<this.moduleCount-8;a++)null==this.modules[a][6]&&(this.modules[a][6]=0==a%2);for(var b=8;b<this.moduleCount-8;b++)null==this.modules[6][b]&&(this.modules[6][b]=0==b%2)},setupPositionAdjustPattern:function(){for(var a=f.getPatternPosition(this.typeNumber),b=0;b<a.length;b++)for(var c=0;c<a.length;c++){var d=a[b],e=a[c];if(null==this.modules[d][e])for(var g=-2;2>=g;g++)for(var h=-2;2>=h;h++)this.modules[d+g][e+h]=-2==g||2==g||-2==h||2==h||0==g&&0==h?!0:!1}},setupTypeNumber:function(a){for(var b=f.getBCHTypeNumber(this.typeNumber),c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[Math.floor(c/3)][c%3+this.moduleCount-8-3]=d}for(var c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[c%3+this.moduleCount-8-3][Math.floor(c/3)]=d}},setupTypeInfo:function(a,b){for(var c=this.errorCorrectLevel<<3|b,d=f.getBCHTypeInfo(c),e=0;15>e;e++){var g=!a&&1==(1&d>>e);6>e?this.modules[e][8]=g:8>e?this.modules[e+1][8]=g:this.modules[this.moduleCount-15+e][8]=g}for(var e=0;15>e;e++){var g=!a&&1==(1&d>>e);8>e?this.modules[8][this.moduleCount-e-1]=g:9>e?this.modules[8][15-e-1+1]=g:this.modules[8][15-e-1]=g}this.modules[this.moduleCount-8][8]=!a},mapData:function(a,b){for(var c=-1,d=this.moduleCount-1,e=7,g=0,h=this.moduleCount-1;h>0;h-=2)for(6==h&&h--;;){for(var i=0;2>i;i++)if(null==this.modules[d][h-i]){var j=!1;g<a.length&&(j=1==(1&a[g]>>>e));var k=f.getMask(b,d,h-i);k&&(j=!j),this.modules[d][h-i]=j,e--,-1==e&&(g++,e=7)}if(d+=c,0>d||this.moduleCount<=d){d-=c,c=-c;break}}}},b.PAD0=236,b.PAD1=17,b.createData=function(a,c,d){for(var e=j.getRSBlocks(a,c),g=new k,h=0;h<d.length;h++){var i=d[h];g.put(i.mode,4),g.put(i.getLength(),f.getLengthInBits(i.mode,a)),i.write(g)}for(var l=0,h=0;h<e.length;h++)l+=e[h].dataCount;if(g.getLengthInBits()>8*l)throw new Error("code length overflow. ("+g.getLengthInBits()+">"+8*l+")");for(g.getLengthInBits()+4<=8*l&&g.put(0,4);0!=g.getLengthInBits()%8;)g.putBit(!1);for(;;){if(g.getLengthInBits()>=8*l)break;if(g.put(b.PAD0,8),g.getLengthInBits()>=8*l)break;g.put(b.PAD1,8)}return b.createBytes(g,e)},b.createBytes=function(a,b){for(var c=0,d=0,e=0,g=new Array(b.length),h=new Array(b.length),j=0;j<b.length;j++){var k=b[j].dataCount,l=b[j].totalCount-k;d=Math.max(d,k),e=Math.max(e,l),g[j]=new Array(k);for(var m=0;m<g[j].length;m++)g[j][m]=255&a.buffer[m+c];c+=k;var n=f.getErrorCorrectPolynomial(l),o=new i(g[j],n.getLength()-1),p=o.mod(n);h[j]=new Array(n.getLength()-1);for(var m=0;m<h[j].length;m++){var q=m+p.getLength()-h[j].length;h[j][m]=q>=0?p.get(q):0}}for(var r=0,m=0;m<b.length;m++)r+=b[m].totalCount;for(var s=new Array(r),t=0,m=0;d>m;m++)for(var j=0;j<b.length;j++)m<g[j].length&&(s[t++]=g[j][m]);for(var m=0;e>m;m++)for(var j=0;j<b.length;j++)m<h[j].length&&(s[t++]=h[j][m]);return s};for(var c={MODE_NUMBER:1,MODE_ALPHA_NUM:2,MODE_8BIT_BYTE:4,MODE_KANJI:8},d={L:1,M:0,Q:3,H:2},e={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7},f={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:1335,G18:7973,G15_MASK:21522,getBCHTypeInfo:function(a){for(var b=a<<10;f.getBCHDigit(b)-f.getBCHDigit(f.G15)>=0;)b^=f.G15<<f.getBCHDigit(b)-f.getBCHDigit(f.G15);return(a<<10|b)^f.G15_MASK},getBCHTypeNumber:function(a){for(var b=a<<12;f.getBCHDigit(b)-f.getBCHDigit(f.G18)>=0;)b^=f.G18<<f.getBCHDigit(b)-f.getBCHDigit(f.G18);return a<<12|b},getBCHDigit:function(a){for(var b=0;0!=a;)b++,a>>>=1;return b},getPatternPosition:function(a){return f.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,b,c){switch(a){case e.PATTERN000:return 0==(b+c)%2;case e.PATTERN001:return 0==b%2;case e.PATTERN010:return 0==c%3;case e.PATTERN011:return 0==(b+c)%3;case e.PATTERN100:return 0==(Math.floor(b/2)+Math.floor(c/3))%2;case e.PATTERN101:return 0==b*c%2+b*c%3;case e.PATTERN110:return 0==(b*c%2+b*c%3)%2;case e.PATTERN111:return 0==(b*c%3+(b+c)%2)%2;default:throw new Error("bad maskPattern:"+a)}},getErrorCorrectPolynomial:function(a){for(var b=new i([1],0),c=0;a>c;c++)b=b.multiply(new i([1,g.gexp(c)],0));return b},getLengthInBits:function(a,b){if(b>=1&&10>b)switch(a){case c.MODE_NUMBER:return 10;case c.MODE_ALPHA_NUM:return 9;case c.MODE_8BIT_BYTE:return 8;case c.MODE_KANJI:return 8;default:throw new Error("mode:"+a)}else if(27>b)switch(a){case c.MODE_NUMBER:return 12;case c.MODE_ALPHA_NUM:return 11;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 10;default:throw new Error("mode:"+a)}else{if(!(41>b))throw new Error("type:"+b);switch(a){case c.MODE_NUMBER:return 14;case c.MODE_ALPHA_NUM:return 13;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 12;default:throw new Error("mode:"+a)}}},getLostPoint:function(a){for(var b=a.getModuleCount(),c=0,d=0;b>d;d++)for(var e=0;b>e;e++){for(var f=0,g=a.isDark(d,e),h=-1;1>=h;h++)if(!(0>d+h||d+h>=b))for(var i=-1;1>=i;i++)0>e+i||e+i>=b||(0!=h||0!=i)&&g==a.isDark(d+h,e+i)&&f++;f>5&&(c+=3+f-5)}for(var d=0;b-1>d;d++)for(var e=0;b-1>e;e++){var j=0;a.isDark(d,e)&&j++,a.isDark(d+1,e)&&j++,a.isDark(d,e+1)&&j++,a.isDark(d+1,e+1)&&j++,(0==j||4==j)&&(c+=3)}for(var d=0;b>d;d++)for(var e=0;b-6>e;e++)a.isDark(d,e)&&!a.isDark(d,e+1)&&a.isDark(d,e+2)&&a.isDark(d,e+3)&&a.isDark(d,e+4)&&!a.isDark(d,e+5)&&a.isDark(d,e+6)&&(c+=40);for(var e=0;b>e;e++)for(var d=0;b-6>d;d++)a.isDark(d,e)&&!a.isDark(d+1,e)&&a.isDark(d+2,e)&&a.isDark(d+3,e)&&a.isDark(d+4,e)&&!a.isDark(d+5,e)&&a.isDark(d+6,e)&&(c+=40);for(var k=0,e=0;b>e;e++)for(var d=0;b>d;d++)a.isDark(d,e)&&k++;var l=Math.abs(100*k/b/b-50)/5;return c+=10*l}},g={glog:function(a){if(1>a)throw new Error("glog("+a+")");return g.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;a>=256;)a-=255;return g.EXP_TABLE[a]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},h=0;8>h;h++)g.EXP_TABLE[h]=1<<h;for(var h=8;256>h;h++)g.EXP_TABLE[h]=g.EXP_TABLE[h-4]^g.EXP_TABLE[h-5]^g.EXP_TABLE[h-6]^g.EXP_TABLE[h-8];for(var h=0;255>h;h++)g.LOG_TABLE[g.EXP_TABLE[h]]=h;i.prototype={get:function(a){return this.num[a]},getLength:function(){return this.num.length},multiply:function(a){for(var b=new Array(this.getLength()+a.getLength()-1),c=0;c<this.getLength();c++)for(var d=0;d<a.getLength();d++)b[c+d]^=g.gexp(g.glog(this.get(c))+g.glog(a.get(d)));return new i(b,0)},mod:function(a){if(this.getLength()-a.getLength()<0)return this;for(var b=g.glog(this.get(0))-g.glog(a.get(0)),c=new Array(this.getLength()),d=0;d<this.getLength();d++)c[d]=this.get(d);for(var d=0;d<a.getLength();d++)c[d]^=g.gexp(g.glog(a.get(d))+b);return new i(c,0).mod(a)}},j.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]],j.getRSBlocks=function(a,b){var c=j.getRsBlockTable(a,b);if(void 0==c)throw new Error("bad rs block @ typeNumber:"+a+"/errorCorrectLevel:"+b);for(var d=c.length/3,e=[],f=0;d>f;f++)for(var g=c[3*f+0],h=c[3*f+1],i=c[3*f+2],k=0;g>k;k++)e.push(new j(h,i));return e},j.getRsBlockTable=function(a,b){switch(b){case d.L:return j.RS_BLOCK_TABLE[4*(a-1)+0];case d.M:return j.RS_BLOCK_TABLE[4*(a-1)+1];case d.Q:return j.RS_BLOCK_TABLE[4*(a-1)+2];case d.H:return j.RS_BLOCK_TABLE[4*(a-1)+3];default:return void 0}},k.prototype={get:function(a){var b=Math.floor(a/8);return 1==(1&this.buffer[b]>>>7-a%8)},put:function(a,b){for(var c=0;b>c;c++)this.putBit(1==(1&a>>>b-c-1))},getLengthInBits:function(){return this.length},putBit:function(a){var b=Math.floor(this.length/8);this.buffer.length<=b&&this.buffer.push(0),a&&(this.buffer[b]|=128>>>this.length%8),this.length++}};var l=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]],o=function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){function g(a,b){var c=document.createElementNS("http://www.w3.org/2000/svg",a);for(var d in b)b.hasOwnProperty(d)&&c.setAttribute(d,b[d]);return c}var b=this._htOption,c=this._el,d=a.getModuleCount();Math.floor(b.width/d),Math.floor(b.height/d),this.clear();var h=g("svg",{viewBox:"0 0 "+String(d)+" "+String(d),width:"100%",height:"100%",fill:b.colorLight});h.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink"),c.appendChild(h),h.appendChild(g("rect",{fill:b.colorDark,width:"1",height:"1",id:"template"}));for(var i=0;d>i;i++)for(var j=0;d>j;j++)if(a.isDark(i,j)){var k=g("use",{x:String(i),y:String(j)});k.setAttributeNS("http://www.w3.org/1999/xlink","href","#template"),h.appendChild(k)}},a.prototype.clear=function(){for(;this._el.hasChildNodes();)this._el.removeChild(this._el.lastChild)},a}(),p="svg"===document.documentElement.tagName.toLowerCase(),q=p?o:m()?function(){function a(){this._elImage.src=this._elCanvas.toDataURL("image/png"),this._elImage.style.display="block",this._elCanvas.style.display="none"}function d(a,b){var c=this;if(c._fFail=b,c._fSuccess=a,null===c._bSupportDataURI){var d=document.createElement("img"),e=function(){c._bSupportDataURI=!1,c._fFail&&_fFail.call(c)},f=function(){c._bSupportDataURI=!0,c._fSuccess&&c._fSuccess.call(c)};return d.onabort=e,d.onerror=e,d.onload=f,d.src="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",void 0}c._bSupportDataURI===!0&&c._fSuccess?c._fSuccess.call(c):c._bSupportDataURI===!1&&c._fFail&&c._fFail.call(c)}if(this._android&&this._android<=2.1){var b=1/window.devicePixelRatio,c=CanvasRenderingContext2D.prototype.drawImage;CanvasRenderingContext2D.prototype.drawImage=function(a,d,e,f,g,h,i,j){if("nodeName"in a&&/img/i.test(a.nodeName))for(var l=arguments.length-1;l>=1;l--)arguments[l]=arguments[l]*b;else"undefined"==typeof j&&(arguments[1]*=b,arguments[2]*=b,arguments[3]*=b,arguments[4]*=b);c.apply(this,arguments)}}var e=function(a,b){this._bIsPainted=!1,this._android=n(),this._htOption=b,this._elCanvas=document.createElement("canvas"),this._elCanvas.width=b.width,this._elCanvas.height=b.height,a.appendChild(this._elCanvas),this._el=a,this._oContext=this._elCanvas.getContext("2d"),this._bIsPainted=!1,this._elImage=document.createElement("img"),this._elImage.style.display="none",this._el.appendChild(this._elImage),this._bSupportDataURI=null};return e.prototype.draw=function(a){var b=this._elImage,c=this._oContext,d=this._htOption,e=a.getModuleCount(),f=d.width/e,g=d.height/e,h=Math.round(f),i=Math.round(g);b.style.display="none",this.clear();for(var j=0;e>j;j++)for(var k=0;e>k;k++){var l=a.isDark(j,k),m=k*f,n=j*g;c.strokeStyle=l?d.colorDark:d.colorLight,c.lineWidth=1,c.fillStyle=l?d.colorDark:d.colorLight,c.fillRect(m,n,f,g),c.strokeRect(Math.floor(m)+.5,Math.floor(n)+.5,h,i),c.strokeRect(Math.ceil(m)-.5,Math.ceil(n)-.5,h,i)}this._bIsPainted=!0},e.prototype.makeImage=function(){this._bIsPainted&&d.call(this,a)},e.prototype.isPainted=function(){return this._bIsPainted},e.prototype.clear=function(){this._oContext.clearRect(0,0,this._elCanvas.width,this._elCanvas.height),this._bIsPainted=!1},e.prototype.round=function(a){return a?Math.floor(1e3*a)/1e3:a},e}():function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){for(var b=this._htOption,c=this._el,d=a.getModuleCount(),e=Math.floor(b.width/d),f=Math.floor(b.height/d),g=['<table style="border:0;border-collapse:collapse;">'],h=0;d>h;h++){g.push("<tr>");for(var i=0;d>i;i++)g.push('<td style="border:0;border-collapse:collapse;padding:0;margin:0;width:'+e+"px;height:"+f+"px;background-color:"+(a.isDark(h,i)?b.colorDark:b.colorLight)+';"></td>');g.push("</tr>")}g.push("</table>"),c.innerHTML=g.join("");var j=c.childNodes[0],k=(b.width-j.offsetWidth)/2,l=(b.height-j.offsetHeight)/2;k>0&&l>0&&(j.style.margin=l+"px "+k+"px")},a.prototype.clear=function(){this._el.innerHTML=""},a}();QRCode=function(a,b){if(this._htOption={width:384,height:384,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:d.H},"string"==typeof b&&(b={text:b}),b)for(var c in b)this._htOption[c]=b[c];"string"==typeof a&&(a=document.getElementById(a)),this._android=n(),this._el=a,this._oQRCode=null,this._oDrawing=new q(this._el,this._htOption),this._htOption.text&&this.makeCode(this._htOption.text)},QRCode.prototype.makeCode=function(a){this._oQRCode=new b(r(a,this._htOption.correctLevel),this._htOption.correctLevel),this._oQRCode.addData(a),this._oQRCode.make(),this._el.title=a,this._oDrawing.draw(this._oQRCode),this.makeImage()},QRCode.prototype.makeImage=function(){"function"==typeof this._oDrawing.makeImage&&(!this._android||this._android>=3)&&this._oDrawing.makeImage()},QRCode.prototype.clear=function(){this._oDrawing.clear()},QRCode.CorrectLevel=d}();
// wireguard.js blob: 2349ca2e7e79691ecbaca2c06d6026dac656b378 from https://git.zx2c4.com/wireguard-tools/tree/contrib/keygen-html/wireguard.js
!function(){function w(r){var n=new Float64Array(16);if(r)for(var o=0;o<r.length;++o)n[o]=r[o];return n}function l(r){for(var n=0;n<16;++n)r[(n+1)%16]+=(n<15?1:38)*Math.floor(r[n]/65536),r[n]&=65535}function A(r,n,o){for(var a,f=~(o-1),t=0;t<16;++t)a=f&(r[t]^n[t]),r[t]^=a,n[t]^=a}function p(r,n,o){for(var a=0;a<16;++a)r[a]=n[a]+o[a]|0}function d(r,n,o){for(var a=0;a<16;++a)r[a]=n[a]-o[a]|0}function g(r,n,o){for(var a=new Float64Array(31),f=0;f<16;++f)for(var t=0;t<16;++t)a[f+t]+=n[f]*o[t];for(f=0;f<15;++f)a[f]+=38*a[f+16];for(f=0;f<16;++f)r[f]=a[f];l(r),l(r)}function U(r){r[31]=127&r[31]|64,r[0]&=248}function n(r){for(var n,o=new Uint8Array(32),a=w([1]),f=w([9]),t=w(),i=w([1]),u=w(),e=w(),c=w([56129,1]),v=w([9]),y=0;y<32;++y)o[y]=r[y];U(o);for(y=254;0<=y;--y)A(a,f,n=o[y>>>3]>>>(7&y)&1),A(t,i,n),p(u,a,t),d(a,a,t),p(t,f,i),d(f,f,i),g(i,u,u),g(e,a,a),g(a,t,a),g(t,f,u),p(u,a,t),d(a,a,t),g(f,a,a),d(t,i,e),g(a,t,c),p(a,a,i),g(t,t,a),g(a,i,e),g(i,f,v),g(f,u,u),A(a,f,n),A(t,i,n);return function(r,n){for(var o=w(),a=0;a<16;++a)o[a]=n[a];for(a=253;0<=a;--a)g(o,o,o),2!==a&&4!==a&&g(o,o,n);for(a=0;a<16;++a)r[a]=o[a]}(t,t),g(a,a,t),function(r,n){for(var o,a=w(),f=w(),t=0;t<16;++t)f[t]=n[t];l(f),l(f),l(f);for(var i=0;i<2;++i){a[0]=f[0]-65517;for(t=1;t<15;++t)a[t]=f[t]-65535-(a[t-1]>>16&1),a[t-1]&=65535;a[15]=f[15]-32767-(a[14]>>16&1),o=a[15]>>16&1,a[14]&=65535,A(f,a,1-o)}for(t=0;t<16;++t)r[2*t]=255&f[t],r[2*t+1]=f[t]>>8}(o,a),o}function o(){var r,r=(r=new Uint8Array(32),window.crypto.getRandomValues(r),r);return U(r),r}function a(r,n){for(var o=Uint8Array.from([n[0]>>2&63,63&(n[0]<<4|n[1]>>4),63&(n[1]<<2|n[2]>>6),63&n[2]]),a=0;a<4;++a)r[a]=o[a]+65+(25-o[a]>>8&6)-(51-o[a]>>8&75)-(61-o[a]>>8&15)+(62-o[a]>>8&3)}function f(r){for(var n=new Uint8Array(44),o=0;o<32/3;++o)a(n.subarray(4*o),r.subarray(3*o));return a(n.subarray(4*o),Uint8Array.from([r[3*o+0],r[3*o+1],0])),n[43]=61,String.fromCharCode.apply(null,n)}window.wireguard={generateKeypair:function(){var r=o();return{publicKey:f(n(r)),privateKey:f(r)}}}}();
var qrcodegeneratedpubkey = "false";
function toggleQRpubkey() {
var qrcodebox = document.getElementById('qrcodepubkey');
if (qrcodebox.style.display === "none") {
if (qrcodegeneratedpubkey == "false") {
var localpubkey = document.getElementById('localpubkey').value
new QRCode(qrcodebox, localpubkey);
qrcodegeneratedpubkey = "true";
}
qrcodebox.style.display = "block";
} else {
qrcodebox.style.display = "none";
}
}
/*
// listen for click events
$(document).click(function(event) {
startelement = $(event.target).context;
if (startelement.parentElement) {
// get element where to write qr image
if ((startelement.parentElement.parentElement.children[0].children[0] !== undefined) && (startelement.parentElement.parentElement.children[0].children[0].hasChildNodes())) {
input = startelement.parentElement.parentElement.children[0].children[0].children[0].children[0];
if ((input) && (input.localName == "input")) {
//peernumber = input.name.replace('qrcodeclientconf','')
writeqrbox = input
}
}
// get peernumber where to write keys
if (($(event.target).context.parentElement.parentElement.hasChildNodes()) && ($(event.target).context.parentElement.parentElement.parentElement.parentElement.parentElement.children[0].children[1] !== undefined)) {
myelement = $(event.target).context.parentElement.parentElement.parentElement.parentElement.parentElement.children[0].children[1];
if (myelement) {
if ((myelement.nodeName == "TD") && (myelement.childNodes[0].name)) {
text = myelement.childNodes[0].name;
peernumber = text.replace(/[a-z]/g,'')
} else {
myelement = $(event.target).context.parentElement.parentElement.parentElement.parentElement.parentElement.children[0].children[1];
}
}
}
}
});
function getNearestTableAncestor(htmlElementNode) {
while (htmlElementNode) {
htmlElementNode = htmlElementNode.parentNode;
if (htmlElementNode.tagName.toLowerCase() === 'table') {
return htmlElementNode;
}
}
return undefined;
}
*/
function getPeer(element, level) {
var myfield = element;
var currentlevel = 0;
while (myfield) {
myfield = myfield.parentNode;
if (myfield.tagName.toLowerCase() === 'div' && myfield.className.toLowerCase() === 'multi') {
currentlevel++;
}
if (currentlevel >= level) {
node = myfield.querySelector('[name^="description"]');
peernumber = node.name.replace(/[^0-9]/g, '');
writeqrbox = myfield.querySelector('[name^="qrcodeclientconf"]');
//console.log("peernumber " + peernumber);
return [peernumber, writeqrbox];
}
}
}
function setConfig(peernumber) {
var clientprivkey = document.getElementsByName("private-key" + peernumber)[0].value;
var clientpubkey = document.getElementsByName("public-key" + peernumber)[0].value;
var serverpubkey = document.getElementById('localpubkey').value;
//var peersallowedips = document.getElementById('peers-allowed-ips').value;
var peersallowedips = "";
const pamatches = document.querySelectorAll('[name^="peers-allowed-ips"]');
for (const node of pamatches.values()) {
if (peersallowedips) {
peersallowedips += ',';
}
peersallowedips += node.value;
}
//var peersdns = document.getElementById('peers-dns').value;
var peersdns = "";
const pdmatches = document.querySelectorAll('[name^="peers-dns"]');
for (const node of pdmatches.values()) {
if (peersdns) {
peersdns += ',';
}
peersdns += node.value;
}
var endpoint = document.getElementById('peers-endpoint').value;
var myfield2 = document.getElementsByName("preshared-key" + peernumber);
var presharedkey = myfield2[0].value;
var persistentkeepalive = document.getElementsByName('persistent-keepalive' + peernumber)[0].value;
var address = "";
if (myfield2 && myfield2[0]) {
myfield2 = myfield2[0];
while (myfield2) {
myfield2 = myfield2.parentNode;
if (myfield2.tagName.toLowerCase() === 'div' && myfield2.className.toLowerCase() === 'multi') {
const matches = myfield2.querySelectorAll('[name^="allowed-ips"]');
for (const node of matches.values()) {
if (address) {
address += ',';
}
address += node.value;
}
break;
}
}
}
config = "[Interface]\nPrivateKey = " + clientprivkey;
if (address) {
config += "\nAddress = " + address;
}
if (peersdns) {
config += "\nDNS = " + peersdns;
}
config += "\n[Peer]\nPublicKey = " + serverpubkey + "\nPresharedKey = " + presharedkey;
if (endpoint) {
config += "\nEndpoint = " + endpoint;
}
if (persistentkeepalive) {
config += "\nPersistentKeepalive = " + persistentkeepalive;
}
if (peersallowedips) {
config += "\nAllowedIPs = " + peersallowedips;
}
console.log("Client privateKey: " + clientprivkey);
console.log("Client address: " + address);
console.log("Client DNS: " + peersdns);
console.log("Client publicKey: " + clientpubkey);
console.log("Server publicKey: " + serverpubkey);
console.log("Peer presharedkey: " + presharedkey);
console.log("Peer Endpoint: " + endpoint);
console.log("Peer PersistentKeepalive: " + persistentkeepalive);
console.log("Peer AllowedIPs: " + peersallowedips);
console.log("Generated configuration for client:\n" + config);
return config;
}
function downloadConf(buttonElement) {
const [peernumber, writeqrbox] = getPeer(buttonElement,2);
var element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(setConfig(peernumber)));
element.setAttribute('download', 'wireguard-client-config.conf');
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
async function toggleQRclientconf(buttonElement) {
const [peernumber, writeqrbox] = getPeer(buttonElement,1);
var keypair = window.wireguard.generateKeypair();
var clientprivkey = keypair["privateKey"];
var clientpubkey = keypair["publicKey"];
var presharedkey = window.wireguard.generateKeypair()["privateKey"];
var myfield1 = document.getElementsByName("public-key" + peernumber);
var myfield2;
if (myfield1 && myfield1[0]) {
myfield1 = myfield1[0];
// set generated keys on empty fields
if (myfield1.value == "") {
myfield1.value = clientpubkey;
myfield2 = document.getElementsByName("private-key" + peernumber)[0];
myfield2.value = clientprivkey;
myfield2.parentNode.parentNode.style.display = 'table-row';
} else {
// clientpubkey already set, ask user to overwrite
if (confirm('Are you sure you want to OVERWRITE and generate NEW keys?')) {
var msgconfirm = "ok"
myfield1.value = clientpubkey;
myfield2 = document.getElementsByName("private-key" + peernumber)[0];
myfield2.value = clientprivkey;
myfield2.parentNode.parentNode.style.display = 'table-row';
} else {
writeqrbox.parentElement.parentElement.style.display = "none"
// restore generage config button
buttonElement.parentNode.querySelector('[name^="generate-config-remove"]').click();
buttonElement.disabled = false;
buttonElement.classList.remove("ui-state-disabled");
return;
}
}
}
myfield2 = document.getElementsByName("preshared-key" + peernumber);
if (myfield2 && myfield2[0]) {
myfield2 = myfield2[0];
// set generated keys on empty fields - else overwrite if user confirmed or keep existing values
if (myfield2.value == "") {
myfield2.value = presharedkey;
} else {
if (msgconfirm == "ok") {
myfield2.value = presharedkey
}
}
}
// if correctLevel:QRCode.CorrectLevel.H (=default) is set, then Error: code length overflow. (1564>1056)
config = setConfig(peernumber);
new QRCode(writeqrbox, {text:config,correctLevel:QRCode.CorrectLevel.M});
// short wait for generating code
await new Promise(r => setTimeout(r, 1));
// set generated image as src for input field
box = document.getElementsByName(writeqrbox.name)[0];
generatedimg = box.getElementsByTagName("img")[0].src;
writeqrbox.src = generatedimg;
}
document.onchange=function() {
// set colored text on package and wizard status
var pkgstatus = document.getElementById('pkgstatus')
var wizstatus = document.getElementById('wizstatus')
if(pkgstatus.value.match(/^error/)) {
pkgstatus.style.color = "red"
} else if (pkgstatus.value.match(/^success/)) {
pkgstatus.style.color = "green"
} else if (pkgstatus.value.match(/^info/)) {
pkgstatus.style.color = "orange"
}
if(wizstatus.value.match(/^error/)) {
wizstatus.style.color = "red"
} else if (wizstatus.value.match(/^success/)) {
wizstatus.style.color = "green"
} else if (wizstatus.value.match(/^info/)) {
wizstatus.style.color = "orange"
}
// enable manual update checkbox if package or wizard status shows 'new version found'
if (pkgstatus.value.match(/new version found/) || wizstatus.value.match(/new version found/)) {
document.getElementById('updatefromgithub').disabled = false
} else {
document.getElementById('updatefromgithub').disabled = true
}
}
document.onsubmit=function() {
// disable inputfields not meant to be edited
document.getElementById('pkgstatus').disabled = true
document.getElementById('procstatus').disabled = true
document.getElementById('wizstatus').disabled = true
document.getElementById('localpubkey').disabled = true
latesthandshakefields = document.getElementsByName("latesthandshake")
for(var i=0; i<latesthandshakefields.length; i++) {
document.getElementsByName("latesthandshake")[i].disabled = true
}
}
$(function () {
EDGE.Views.Global.WizardBase.prototype.addLabel = function() {
switch (arguments.callee.caller.caller.caller.caller.caller.caller.caller.caller.caller.arguments[1].parentElement.dataset.object) {
case 'qrcodeclientconf': return 'Generate config';
case 'allowed-ips': return 'Add IP';
default: return null;
}
};
});
</script>