-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathindex.html
464 lines (396 loc) · 19.2 KB
/
index.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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/simple-keyboard@latest/build/css/index.css"></link>
<link rel="stylesheet" type="text/css" href="/css/interface.css"></link>
<link rel="stylesheet" href="node_modules/xterm/css/xterm.css"></link>
<script src="/siofu/client.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script src="node_modules/xterm/lib/xterm.js"></script>
<script src="https://kit.fontawesome.com/6873aa3c17.js" crossorigin="anonymous"></script>
<script>
function askPassword() {
var password = prompt("Please enter your password", "Password");
while (password != 'pass') {var password = prompt("Please enter your password", "Password")}
}
function initFunctions() {
askPassword();
}
window.addEventListener("load", initFunctions, true)
</script>
</head>
<body class='light-background'
oncontextmenu="return false;">
<!-- Keyboard -->
<div id='keyboard' class='keyboard'>
<input class="input"
size=120
placeholder="Tap on the virtual keyboard to start" />
<div class="keyboardContainer">
<div class="simple-keyboard-main"></div>
<div class="controlArrows">
<div class="simple-keyboard-control"></div>
<div class="simple-keyboard-arrows"></div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/simple-keyboard@latest/build/index.min.js"></script>
</div>
<!-- Keyboard -->
<button class="toggleButton" id="keyboardToggle" title="Toggle Virtual Keyboard"><i class="fas fa-eye-slash"></i></button>
<script>
toggle = document.getElementById('keyboardToggle');
keyBoard = document.getElementById('keyboard');
toggle.onclick = function toggleFullScreen() {
keyBoard.classList.toggle('hide');
}
</script>
<ul>
<li class="dropdown">
<a href="javascript:void(0)" class="dropbtn" title="HID Keyboard"><i class="far fa-keyboard fa-5x"></i></a>
<div class="dropdown-content">
<button class="button" id="keyboardReset" title="Reset Keyboard"><i class="fas fa-sync fa-3x"></i></button>
<br><br>
<button class="button" id="">Send Alt+Shift</button>
<button class="button" id="">Send Crtl+Shift</button>
<button class="button" id="">Send Shift+Shift</button>
<button class="button" id="">Send Meta(Win)+Space</button>
<button class="button" id="">Send Crtl+W</button>
<button class="button" id="">Send Alt+Tab</button>
<button class="button" id="">Send Alt+Enter</button>
<button class="button" id="">Send Alt+F4</button>
<button class="button" id="">Send Crtl+Alt+Del</button>
<input type="text" value="" placeholder="Paste Text Here">
<button class="button" id="">Send (ASCII) Keys</button>
<script src="/js/keyboard-capture.js"></script>
</div>
</li>
<li class="dropdown">
<a href="javascript:void(0)" class="dropbtn" title="HID Mouse"><i class="fas fa-mouse fa-5x"></i></a>
<div class="dropdown-content">
<button class="button" id="mouseReset" title="Reset Mouse"><i class="fas fa-sync fa-3x"></i></button>
</div>
</li>
<li class="dropdown">
<a href="javascript:void(0)" class="dropbtn" title="Write Method"><i class="fas fa-pencil-alt fa-5x"></i></a>
<div class="dropdown-content">
<a>(Future)</a>
<button class="button" id="" title="bluetooth"><i class="fab fa-bluetooth-b fa-3x"></i></button>
<button class="button" id="" title="arduino"><i class="fas fa-infinity fa-3x"></i></button>
</div>
</li>
<li class="dropdown">
<a href="javascript:void(0)" class="dropbtn" title="Media"><i class="fas fa-hdd fa-5x"></i></a>
<div class="dropdown-content">
<br>
<button type="button" onclick="alert('Mass Storage Reset')" title="Reset Mass Storage"><i class="fas fa-sync fa-3x"></i></button>
<div class="dropdown-content">
<br>
<!-- https://android.googlesource.com/kernel/common/+/android-3.18/Documentation/usb/mass-storage.txt -->
<!-- https://www.w3schools.com/howto/howto_css_custom_checkbox.asp -->
<label class="container" title="Specifies whether the gadget is allowed to halt bulk endpoints. The default is determined according to the type of USB device controller, but usually true."
>Stall
<input id='stall' type="checkbox">
<span class="checkmark"></span>
</label>
<label class="container" title="This parameter specifies whether each logical unit should simulate CD-ROM. The default is false."
>CD-ROM
<input id='cdrom' type="checkbox">
<span class="checkmark"></span>
</label>
<label class="container" title="This parameter specifies whether each logical unit should be removable. “b” here is either “y”, “Y” or “1” for true or “n”, “N” or “0” for false. If this option is set for a logical unit, gadget will accept an “eject” SCSI request (Start/Stop Unit). When it is sent, the backing file will be closed to simulate ejection and the logical unit will not be mountable by the host until a new backing file is specified by userspace on the device (see “sysfs entries” section). If a logical unit is not removable (the default), a backing file must be specified for it with the “file” parameter as the module is loaded. The same applies if the module is built in, no exceptions. The default value of the flag is false, *HOWEVER* it used to be true. This has been changed to better match File Storage Gadget and because it seems like a saner default after all. Thus to maintain compatibility with older kernels, it's best to specify the default values. Also, if one relied on old default, explicit “n” needs to be specified now. Note that “removable” means the logical unit's media can be ejected or removed (as is true for a CD-ROM drive or a card reader). It does *not* mean that the entire gadget can be unplugged from the host; the proper term for that is “hot-unpluggable”."
>Removable
<input id='removable' type="checkbox"
checked="checked">
<span class="checkmark"></span>
</label>
<label class="container" title="This parameter specifies whether each logical unit should be reported as read only. This will prevent host from modifying the backing files. Note that if this flag for given logical unit is false but the backing file could not be opened in read/write mode, the gadget will fall back to read only mode anyway. The default value for non-CD-ROM logical units is false; for logical units simulating CD-ROM it is forced to true.">Read-Only
<input id='read-only' type="checkbox">
<span class="checkmark"></span>
</label>
<label class="container" title="This parameter specifies whether FUA flag should be ignored in SCSI Write10 and Write12 commands sent to given logical units. MS Windows mounts removable storage in “Removal optimised mode” by default. All the writes to the media are synchronous, which is achieved by setting the FUA (Force Unit Access) bit in SCSI Write(10,12) commands. This forces each write to wait until the data has actually been written out and prevents I/O requests aggregation in block layer dramatically decreasing performance. Note that this may mean that if the device is powered from USB and the user unplugs the device without unmounting it first (which at least some Windows users do), the data may be lost. The default value is false."
>Don't Force Unit Access
<input id='nofua' type="checkbox">
<span class="checkmark"></span>
</label>
<script type="text/javascript" src="/js/file-capture.js"></script>
<p><label class="custom-file-upload">Choose File<input type="file" id="upload_input"/></label></p>
<label for="file">File progress:</label>
<progress style="width:100%" id="fileProgress" max="100" value="0"></progress>
<br> <br>
<table id="file-table" style="width:100%">
<thead>
<tr>
<th>Lun</th>
<th>File</th>
<th>CD</th>
<th>Removable</th>
<th>ReadOnly</th>
<th>NoFUA</th>
</tr>
</thead>
</table>
<select id="fileDropdown"></select>
<button type="button" onclick="attachFile()">Attach File</button>
<button type="button" onclick="detachFile()">Detach File</button>
<script>
function attachFile() {
var file = document.getElementById('fileDropdown').value;
var cdrom = document.getElementById('cdrom').checked;
var removable = document.getElementById('removable').checked;
var readonly = document.getElementById('read-only').checked;
var stall = document.getElementById('stall').checked;
var fua = document.getElementById('nofua').checked;
var socketTx = io();
var socketRx = io.connect();
var message = {Command: "Attach",
File: file,
CDRom: +cdrom,
Removable: +removable,
ReadOnly: +readonly,
FUA: +fua};
socketTx.emit('fileChannel', message);
// Receive attached files or > 8 message
socketRx.on('fileChannel', function(data){
console.log(data);
alert('File Attached as Lun');
// alert(data);
var tbdy = document.createElement('tbody');
for (var lun in data) {
console.log(lun);
var tr = document.createElement('tr');
tr.appendChild(document.createElement('td').appendChild(document.createTextNode(lun)));
for (var info in data[lun]) {
var td = document.createElement('td');
td.appendChild(document.createTextNode(data[lun][info]))
tr.appendChild(td)
}
tbdy.appendChild(tr);
}
var table = document.getElementById('file-table')
var old_tbdy = table.getElementsByTagName('tbody')[0];
if (!old_tbdy) {
table.appendChild(tbdy);
} else {
table.replaceChild(tbdy, old_tbdy)
}
});
};
function detachFile() {
alert('Detaching File');
var file = document.getElementById('fileDropdown').value;
var socketTx = io();
var message = {Command: "Detach", Argument: file};
socketTx.emit('fileChannel', message);
};
</script>
<a>Samba Server (future)</a>
<a>PXE Server (future)</a>
</div>
</div>
</li>
<li class="dropdown">
<a href="javascript:void(0)" class="dropbtn" title="Targets"><i class="fas fa-bullseye fa-5x"></i></a>
<div class="dropdown-content">
<!-- Sources -->
<label>Audio Source</label>
<select id="audioSource">
<option value="no-input" id="noAudio"> No Input </option>
</select>
<br>
<label>Video Source</label>
<select id="videoSource">
<option value="no-input" id="noVideo"> No Input </option>
</select>
<script>
var socket = io.connect();
videoSource = document.getElementById('videoSource');
socket.on('sourceChannel', function(data){
console.log(data);
const option = document.createElement('option');
option.value = data; // file.path
option.text = data; // file.name
videoSource.appendChild(option);
});
</script>
<br>
<button onclick='refreshSources()'>Refresh Sources</button>
<script>
function refreshSources() {
var socketTx = io();
//videoSource = document.getElementById('videoSource');
console.log("Requesting sources under <path>");
socketTx.emit('sourceChannel', "RefreshVideo");
};
</script>
<button onclick='resetStream()'>Reset Stream</button>
<script>
function resetStream() {
var socketTx = io();
streamSource = document.getElementById('videoSource');
console.log("Sending Reset command for Stream");
socketTx.emit('streamChannel', streamSource.value);
alert('Stream Reset');
};
</script>
<!-- Sources -->
</div>
</li>
<li class="dropdown">
<a href="javascript:void(0)" class="dropbtn" title="Power Management"><i class="fas fa-power-off fa-5x"></i></a>
<div class="dropdown-content">
<label>Select Target to Reset</label>
<input type="number" id="gpioTargets">
<button onclick='resetTarget()'>Reset Specified Target</button>
<br>
<table id="mac-table" style="width:100%">
<thead>
<tr>
<th>IP Address</th>
<th>Mac Address</th>
</tr>
</thead>
</table>
<label>Enter Mac Address</label>
<input id="WOLmacAddress" type="text">
<br>
<button onclick='detectMACs()' id="detectMACs">Detect MAC Addresses (future)</button>
<button onclick='submitWOL()' id="submitWOL">Wake via LAN</button>
</div>
<script>
function resetTarget() {
var socketTx = io();
gpioTargets = document.getElementById('gpioTargets');
console.log("Sending Reset command for GPIO " + gpioTargets.value);
var message = {Method: "GPIO", Pin: gpioTargets.value};
socketTx.emit('powerChannel', message);
};
</script>
<script>
function detectMACs() {
var socketTx = io();
var socketRx = io.connect();
console.log("Requesting MAC Addresses");
var message = "requestMACs";
socketTx.emit('networkChannel', message);
socketRx.on('networkChannel', function(data) {
console.log(data);
var tbdy = document.createElement('tbody');
for (var device in data) {
console.log(data[device]);
var tr = document.createElement('tr');
//tr.appendChild(document.createElement('td').appendChild(document.createTextNode(device['name'])));
var td = document.createElement('td');
td.appendChild(document.createTextNode(data[device].ip));
td.appendChild(document.createTextNode(data[device].mac));
tr.appendChild(td);
tbdy.appendChild(tr);
}
var table = document.getElementById('mac-table')
var old_tbdy = table.getElementsByTagName('tbody')[0];
if (!old_tbdy) {
table.appendChild(tbdy);
} else {
table.replaceChild(tbdy, old_tbdy)
}
});
};
</script>
<script>
function submitWOL() {
var socketTx = io();
macAddress = document.getElementById('WOLmacAddress').value;
console.log("Requesting WOL for" + macAddress);
var message = {Method: "WOL", MAC: macAddress};
socketTx.emit('powerChannel', message);
};
</script>
</li>
<li class="dropdown">
<a href="javascript:void(0)" class="dropbtn" title="Debugging"><i class="fas fa-bug fa-5x"></i></a>
<div class="dropdown-content">
<button class="button" id="terminalToggle" title="Toggle Terminal"><i class="fas fa-terminal fa-3x"></i></button>
<input type="text" style="display: none" value="" id="command">
<button class="button" id="copyCommand" onclick="copyCommand()" title="Copy command to paste into butterfly terminal for standard output of server process">
<i class="far fa-clipboard fa-3x"></i></button>
</div>
<script>
function copyCommand() {
var copyText = document.getElementById("command");
var socketTx = io();
console.log("Requesting PID");
socketTx.emit('debugChannel', "PID");
var socket = io.connect();
socket.on('debugChannel', function(data){
copyText.value = "tail -f /proc/" + data + "/fd/1"
copyText.select();
// copyText.setSelectionRange(0, 99999);
document.execCommand("copy");
alert("Copied Command: " + copyText.value);
});
}
</script>
</li>
<li class="dropdown">
<a href="javascript:void(0)" class="dropbtn" title="Remote Capability"><i class="fas fa-network-wired fa-5x"></i></a>
<div class="dropdown-content">
</div>
</li>
<li class="dropdown">
<a href="javascript:void(0)" class="dropbtn" title="Miscellaneous"><i class="fas fa-desktop fa-5x"></i></a>
<div class="dropdown-content">
<a>VNC (future)</a>
</div>
</li>
</ul>
<!-- Video -->
<canvas id="video" class="regular-video"></canvas>
<script type="text/javascript" src="/js/jsmpeg.min.js"></script>
<script type="text/javascript">
var canvas = document.getElementById('video');
var url = 'ws://'+document.location.hostname+':8082/';
var player = new JSMpeg.Player(url, {canvas: canvas});
</script>
<div id="signal-screen" class="regular-video black-box hide">
<a class="loading-prompt">No video loaded...</a>
</div>
<script src="/js/cursor-capture.js"></script>
<!-- Video -->
<div class="regular-video" id="terminal"></div>
<script>
var socketTx = io();
var socketRx = io.connect();
var options = {'cols': 250};
var term = new Terminal(options);
term.welcome = function() {
term.write('Hello from \x1B[1;3;31mR(p)ipMI\x1B[0m\r\n');
};
term.open(document.getElementById('terminal'));
term.welcome();
//Initialize Terminal
socketTx.emit('data', 'su pi\r');
term.onKey(function(e) {
console.log(e);
socketTx.emit('data', e.key);
});
// Capture Pasting
term.onData(function (e) {
if (e.length > 1) {
socketTx.emit('data', e);
}
})
socketRx.on('data', function(data){
term.write(data);
});
</script>
<script>
var toggle = document.getElementById('terminalToggle');
var terminal = document.getElementById('terminal');
var signalScreen = document.getElementById('signal-screen');
toggle.onclick = function toggleTerminal() {
terminal.classList.toggle('hide');
signalScreen.classList.toggle('hide');
}
</script>
</body>
</html>