| 1 | <!DOCTYPE html> |
| 2 | <html lang="en"> |
| 3 | <head> |
| 4 | <meta charset="utf-8"> |
| 5 | <meta http-equiv="X-UA-Compatible" content="IE=edge"> |
| 6 | <meta name="viewport" content="width=device-width, initial-scale=1"> |
| 7 | <meta name="robots" content="noindex,nofollow"> |
| 8 | <link rel="icon" href="/favicon.ico"> |
| 9 | <link rel="apple-touch-icon" href="/favicon-303x303.png" /> |
| 10 | {{{customCSSTags}}} |
| 11 | <title>RDP</title> |
| 12 | <script type="text/javascript" src="mstsc/mstsc.js"></script> |
| 13 | <script type="text/javascript" src="mstsc/keyboard.js"></script> |
| 14 | <script type="text/javascript" src="mstsc/rle.js"></script> |
| 15 | <script type="text/javascript" src="mstsc/client.js"></script> |
| 16 | <script type="text/javascript" src="mstsc/canvas.js"></script> |
| 17 | {{{customJSTags}}} |
| 18 | <style> |
| 19 | :focus { |
| 20 | outline: 0; |
| 21 | } |
| 22 | |
| 23 | body { |
| 24 | font-family:sans-serif; |
| 25 | margin: 0; |
| 26 | background-color: black; |
| 27 | } |
| 28 | |
| 29 | .container { |
| 30 | background-color:cadetblue; |
| 31 | background: linear-gradient(to bottom right, #003366, #0055AA); |
| 32 | } |
| 33 | |
| 34 | .middleContainer { |
| 35 | color: lightgray; |
| 36 | position: absolute; |
| 37 | top: 50%; |
| 38 | left: 50%; |
| 39 | -moz-transform: translateX(-50%) translateY(-50%); |
| 40 | -webkit-transform: translateX(-50%) translateY(-50%); |
| 41 | transform: translateX(-50%) translateY(-50%); |
| 42 | } |
| 43 | |
| 44 | .signinform { |
| 45 | width: 380px; |
| 46 | margin: 0 auto; |
| 47 | } |
| 48 | |
| 49 | .formDropdown { |
| 50 | font-size: 17px; |
| 51 | } |
| 52 | |
| 53 | .formLabel { } |
| 54 | |
| 55 | .formControl { |
| 56 | width:calc(100% - 16px); |
| 57 | font-size: 17px; |
| 58 | border-radius: 5px; |
| 59 | } |
| 60 | |
| 61 | .connectButton { |
| 62 | margin-top: 6px; |
| 63 | width: 100%; |
| 64 | padding: 6px; |
| 65 | font-size: 16px; |
| 66 | border-radius: 5px; |
| 67 | cursor:pointer; |
| 68 | } |
| 69 | |
| 70 | .mainCanvas { |
| 71 | position: absolute; |
| 72 | top: 50%; |
| 73 | left: 50%; |
| 74 | -moz-transform: translateX(-50%) translateY(-50%); |
| 75 | -webkit-transform: translateX(-50%) translateY(-50%); |
| 76 | transform: translateX(-50%) translateY(-50%); |
| 77 | } |
| 78 | </style> |
| 79 | <script language="javascript"> |
| 80 | var random = '{{{randomlength}}}' // Random length string for BREACH mitigation |
| 81 | var client = null; |
| 82 | var canvas = null; |
| 83 | var urlargs = parseUriArgs(); |
| 84 | if (urlargs.key && (isAlphaNumeric(urlargs.key) == false)) { delete urlargs.key; } |
| 85 | var cookie = '{{{cookie}}}'; |
| 86 | var serverCredentials = parseInt('{{{serverCredentials}}}'); |
| 87 | var name = decodeURIComponent('{{{name}}}'); |
| 88 | if (name != '') { document.title = name + ' - ' + document.title; } |
| 89 | var features = parseInt('{{{features}}}'); |
| 90 | |
| 91 | function load() { |
| 92 | if (name != '') { QH('computerName', EscapeHtml(name)); } |
| 93 | client = MstscClient.create(Q('myCanvas')); |
| 94 | Q('inputDomain').focus(); |
| 95 | canvas = Q('myCanvas'); |
| 96 | if (cookie == '') { |
| 97 | QE('inputDomain', false); |
| 98 | QE('inputUsername', false); |
| 99 | QE('inputPassword', false); |
| 100 | QE('connectButton', false); |
| 101 | } |
| 102 | |
| 103 | if (serverCredentials == 1) { |
| 104 | QV('dropdowndomain', true); |
| 105 | Q('d3coreMode').value = 1; |
| 106 | } else { |
| 107 | QV('dropdowndomain', false); |
| 108 | Q('d3coreMode').value = 2; |
| 109 | } |
| 110 | dropDownChange(); |
| 111 | } |
| 112 | |
| 113 | function connect(domain, username, password) { |
| 114 | if (cookie == '') return; |
| 115 | var domain = Q('inputDomain').value; |
| 116 | var username = Q('inputUsername').value; |
| 117 | var password = Q('inputPassword').value; |
| 118 | var savepass = Q('inputSaveCredentials').checked; |
| 119 | var options = { savepass: savepass, useServerCreds: (Q('d3coreMode').value == 1) }; |
| 120 | QV('myCanvas', true); |
| 121 | QV('main', false); |
| 122 | canvas.width = window.innerWidth; |
| 123 | canvas.height = window.innerHeight; |
| 124 | client.connect(cookie, domain, username, password, options, function (err) { QV('myCanvas', false); QV('main', true); }); |
| 125 | return false; |
| 126 | } |
| 127 | |
| 128 | function Q(x) { return document.getElementById(x); } // "Q" |
| 129 | function QS(x) { try { return Q(x).style; } catch (x) { } } // "Q" style |
| 130 | function QE(x, y) { try { Q(x).disabled = !y; } catch (x) { } } // "Q" enable |
| 131 | function QV(x, y) { try { QS(x).display = (y ? '' : 'none'); } catch (x) { } } // "Q" visible |
| 132 | function QA(x, y) { Q(x).innerHTML += y; } // "Q" append |
| 133 | function QH(x, y) { Q(x).innerHTML = y; } // "Q" html |
| 134 | function QC(x) { try { return Q(x).classList; } catch (x) { } } // "Q" class |
| 135 | function EscapeHtml(x) { if (typeof x == 'string') return x.replace(/&/g, '&').replace(/>/g, '>').replace(/</g, '<').replace(/"/g, '"').replace(/'/g, '''); if (typeof x == 'boolean') return x; if (typeof x == 'number') return x; } |
| 136 | function EscapeHtmlBreaks(x) { if (typeof x == 'string') return x.replace(/&/g, '&').replace(/>/g, '>').replace(/</g, '<').replace(/"/g, '"').replace(/'/g, ''').replace(/\r/g, '<br />').replace(/\n/g, '').replace(/\t/g, ' '); if (typeof x == 'boolean') return x; if (typeof x == 'number') return x; } |
| 137 | |
| 138 | // String validation |
| 139 | function isAlphaNumeric(str) { return (str.match(/^[A-Za-z0-9]+$/) != null); }; |
| 140 | function isSafeString(str) { return ((typeof str == 'string') && (str.indexOf('<') == -1) && (str.indexOf('>') == -1) && (str.indexOf('&') == -1) && (str.indexOf('"') == -1) && (str.indexOf('\'') == -1) && (str.indexOf('+') == -1) && (str.indexOf('(') == -1) && (str.indexOf(')') == -1) && (str.indexOf('#') == -1) && (str.indexOf('%') == -1) && (str.indexOf(':') == -1)) }; |
| 141 | |
| 142 | // Parse URL arguments, only keep safe values |
| 143 | function parseUriArgs() { |
| 144 | var href = window.document.location.href; |
| 145 | if (href.endsWith('#')) { href = href.substring(0, href.length - 1); } |
| 146 | var name, r = {}, parsedUri = href.split(/[\?&|\=]/); |
| 147 | parsedUri.splice(0, 1); |
| 148 | for (x in parsedUri) { |
| 149 | switch (x % 2) { |
| 150 | case 0: { name = decodeURIComponent(parsedUri[x]); break; } |
| 151 | case 1: { |
| 152 | r[name] = decodeURIComponent(parsedUri[x]); |
| 153 | if (!isSafeString(r[name])) { delete r[name]; } else { var x = parseInt(r[name]); if (x == r[name]) { r[name] = x; } } |
| 154 | break; |
| 155 | } default: { break; } |
| 156 | } |
| 157 | } |
| 158 | return r; |
| 159 | } |
| 160 | |
| 161 | function dropDownChange() { |
| 162 | var newCreds = (Q('d3coreMode').value == 2); |
| 163 | QV('rowdomain', newCreds); |
| 164 | QV('rowusername', newCreds); |
| 165 | QV('rowpassword', newCreds); |
| 166 | QV('rowremember', newCreds && ((features & 1) == 0)); |
| 167 | if (newCreds) Q('inputUsername').focus(); |
| 168 | } |
| 169 | |
| 170 | </script> |
| 171 | </head> |
| 172 | <body onload='load()' style="position:absolute;top:0px;right:0;left:0;bottom:0px"> |
| 173 | <div id="main" class="container" style="position:absolute;top:0px;right:0;left:0;bottom:0px"> |
| 174 | <div class="middleContainer"> |
| 175 | <div id="computerName" style="width:100%;text-align:center;font-size:24px"></div> |
| 176 | <table class="signinform"> |
| 177 | <tr> |
| 178 | <td colspan="2"><hr style="color:gray;border:1px solid;" /></td> |
| 179 | </tr> |
| 180 | <tr id="dropdowndomain" style="display:none"> |
| 181 | <td colspan="2"> |
| 182 | <select id=d3coreMode style=width:100%;margin-bottom:5px class="formDropdown" onchange="dropDownChange()"><option value=1>Use server credentials</option><option value=2>Use new credentials</option></select> |
| 183 | </td> |
| 184 | </tr> |
| 185 | <tr id="rowdomain" style="display:none"> |
| 186 | <td><label for="inputDomain" class="formLabel">Domain</label></td> |
| 187 | <td style="text-align:right"><input type="text" id="inputDomain" class="formControl" placeholder="Domain"></td> |
| 188 | </tr> |
| 189 | <tr id="rowusername" style="display:none"> |
| 190 | <td><label for="inputUsername" class="formLabel">Username</label></td> |
| 191 | <td style="text-align:right"><input type="text" id="inputUsername" class="formControl" placeholder="Username"></td> |
| 192 | </tr> |
| 193 | <tr id="rowpassword" style="display:none"> |
| 194 | <td><label for="inputPassword" class="formLabel">Password</label></td> |
| 195 | <td style="text-align:right"><input type="password" id="inputPassword" class="formControl" placeholder="Password"></td> |
| 196 | </tr> |
| 197 | <tr id="rowremember" style="display:none"> |
| 198 | <td></td> |
| 199 | <td><label><input type="checkbox" id="inputSaveCredentials" style="margin-left:8px;margin-right:5px">Remember credentials</label></td> |
| 200 | </tr> |
| 201 | <tr> |
| 202 | <td colspan="2"><button class="connectButton" onclick="return connect()">Connect</button></td> |
| 203 | </tr> |
| 204 | </table> |
| 205 | </div> |
| 206 | </div> |
| 207 | <canvas id="myCanvas" class="mainCanvas" style="display:none" /> |
| 208 | </body> |
| 209 | </html> |