4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
19 * Copyright 2012-2014 Rob van Son
20 * email: R.J.J.H.vanSon@gmail.com
23 // Global variables, set by the server as CGI parameter values
24 var CGIscriptorSessionType="<SCRIPT TYPE="text/ssperl" CGI='$SESSIONTYPE=""'>
25 $SESSIONTYPE;</SCRIPT>";
26 var CGIscriptorChallengeTicket="<SCRIPT TYPE="text/ssperl" CGI='$CHALLENGETICKET=""'>
27 $CHALLENGETICKET;</SCRIPT>";
29 var CGIscriptorLoginticket="<SCRIPT TYPE='text/ssperl' CGI='$LOGINTICKET=""'>
30 $LOGINTICKET</SCRIPT>";
31 var CGIscriptorServerSalt="<SCRIPT TYPE='text/ssperl' CGI='$SERVERSALT=""'>
32 $SERVERSALT</SCRIPT>";
33 var CGIscriptorRandomSalt="<SCRIPT TYPE='text/ssperl' CGI='$RANDOMSALT=""'>
34 $RANDOMSALT</SCRIPT>";
37 function LoginSubmit () {
38 var success=check_username_password();
39 // Set the LOGINTICKET value in FORM
40 var formID = document.getElementById("LOGINTICKET");
41 var ipaddress = document.getElementById("CLIENTIPADDRESS").value;
43 formID.value = CGIscriptorLoginticket;
47 HashPassword(ipaddress+CGIscriptorRandomSalt);
52 function ChangePasswordSubmit () {
53 if(! check_password_fields())return false;
54 // Set the LOGINTICKET value in FORM
55 var formID = document.getElementById("LOGINTICKET");
57 formID.value = CGIscriptorLoginticket;
60 EncryptNewPassword("CGIUSERNAME");
61 HashPassword(CGIscriptorRandomSalt);
66 function CreateUserSubmit () {
67 if(! check_password_fields())return false;
68 // Set the LOGINTICKET value in FORM
69 var formID = document.getElementById("LOGINTICKET");
71 formID.value = CGIscriptorLoginticket;
74 EncryptNewPassword("NEWUSERNAME");
75 HashPassword(CGIscriptorRandomSalt);
80 // Function definitions
81 function hex_sha1 (plaintext) {
82 var shaObj = new jsSHA(plaintext, "ASCII");
83 return shaObj.getHash("SHA-1", "HEX");
85 function hex_sha256 (plaintext) {
86 var shaObj = new jsSHA(plaintext, "ASCII");
87 return shaObj.getHash("SHA-256", "HEX");
89 function hex_sha512 (plaintext) {
90 var shaObj = new jsSHA(plaintext, "ASCII");
91 return shaObj.getHash("SHA-256", "HEX");
93 function chained_sha (plaintext) {
94 return hex_sha256( hex_sha256( hex_sha512(plaintext) ) );
97 function loadSessionData (SessionType, ChallengeTicket) {
98 if(SessionType == 'CHALLENGE')
99 setChallengeParameters(ChallengeTicket);
100 else if(SessionType == 'SESSION')
101 setSessionParameters();
105 function createCookie(name,value,days,path) {
107 var date = new Date();
108 date.setTime(date.getTime()+(days*24*60*60*1000));
109 var expires = "; expires="+date.toGMTString();
111 else var expires = "";
112 var match = document.cookie.match('/('+name+'\=[^\;]*\);/');
115 document.cookie = document.cookie.replace(match[1], name+"="+value);
116 match = document.cookie.match('/('+name+'\=[^\;]*\);/');
119 document.cookie = name+"=-";
120 document.cookie = name+"="+value+expires+"; path=/"+path;
125 function readCookie(name) {
126 var nameEQ = name + "=";
127 var ca = document.cookie.split(';');
128 for(var i=0;i < ca.length;i++) {
130 while (c.charAt(0)==' ') c = c.substring(1,c.length);
131 if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
136 function eraseCookie(name) {
137 createCookie(name,"",-1);
140 // Combine the PASSWORD with the site SERVERSALT and hash it
141 // Combine this Hash with the extra SERVERSALT, and hash them
142 function HashPassword(extsalt) {
143 var hash = HashSessionSeed(extsalt);
144 var password = document.getElementById('PASSWORD');
146 password.value = hash;
148 alert("NO PASSWORD IN FORM");
154 // REMEMBER: Set the session cookie BEFORE you hash the password!!!
155 function SetSessionCookie() {
156 var loginticket = CGIscriptorLoginticket;
157 var randomsalt = CGIscriptorRandomSalt;
158 var hash = HashSessionSeed(loginticket);
159 // Dom.storage.enabled must be set!
160 if (!sessionStorage || typeof(sessionStorage) == 'undefined' ) {
161 alert('Your browser does not support HTML5 sessionStorage. Set Dom.storage.enabled or try upgrading.');
164 else sessionStorage.setItem("CGIscriptorPRIVATE", hash);
166 // Store a secret key, if one is given
172 function SetSecretKey() {
173 var loginticket = CGIscriptorLoginticket;
174 var randomsalt = CGIscriptorRandomSalt;
176 if (!sessionStorage || typeof(sessionStorage) == 'undefined' ) {
177 alert('Your browser does not support HTML5 sessionStorage. Set Dom.storage.enabled or try upgrading.');
180 else if (loginticket && randomsalt) {
181 secretkey = HashSessionSeed(loginticket+randomsalt);
182 sessionStorage.setItem("CGIscriptorSECRET", secretkey);
188 // Hash(hash(password+username.toLowerCase()+salt) + sessionseed)
189 function HashSessionSeed(sessionseed) {
192 var passwordvalue = document.getElementById('PASSWORD');
193 var saltvalue = CGIscriptorServerSalt;
194 var username = document.getElementById('CGIUSERNAME');
195 hash1 = hex_sha256(passwordvalue.value+username.value.toLowerCase()+saltvalue);
196 if(sessionseed != "")
197 hash2 = hex_sha256(hash1+sessionseed);
203 // Remember to hash the repeat too! Or else it will be send in the clear
204 function HashNewPassword(userid) {
206 var newpassword = document.getElementById('NEWPASSWORD');
207 var newpasswordrep = document.getElementById('NEWPASSWORDREP');
208 var username = document.getElementById(userid);
209 if(newpassword.value == "" ) {
210 newpassword.value = "";
213 if(newpasswordrep && (newpasswordrep.value == ""|| newpassword.value != newpasswordrep.value)) {
214 newpassword.value = "";
215 newpasswordrep.value = "";
218 var saltvalue = CGIscriptorServerSalt;
219 hash1 = hex_sha256(newpassword.value+username.value.toLowerCase()+saltvalue);
220 newpassword.value = hash1;
221 newpasswordrep.value = hash1;
225 function XOR_hex_strings(hex1, hex2) {
227 var maxlength = Math.max(hex1.length, hex2.length);
229 for(var i=0; i < maxlength; ++i) {
230 var h1 = hex1.charAt(i);
232 var h2 = hex2.charAt(i);
234 var d1 = parseInt(h1,16);
235 var d2 = parseInt(h2,16);
237 resultHex = resultHex+resultD.toString(16);
242 function EncryptNewPassword(userid) {
243 var newpassword = document.getElementById('NEWPASSWORD');
244 var newpasswordrep = document.getElementById('NEWPASSWORDREP');
245 var secretkey = SetSecretKey();
247 // This hashes the newpassword field!
248 HashNewPassword(userid);
249 var encrypted = XOR_hex_strings(secretkey, newpassword.value);
250 newpassword.value = encrypted;
251 newpasswordrep.value = encrypted;
255 function DecryptNewPassword(key, encrypted) {
256 decrypted = XOR_hex_strings(key, encrypted);
261 function add_cgiparam(elem, attr, param) {
262 var elems = document.getElementsByTagName(elem);
263 for (var i = 0; i < elems.length; i++)
265 var n=elems[i][attr].indexOf("?");
267 elems[i][attr] = elems[i][attr] + "?" + param;
269 elems[i][attr] = elems[i][attr] + "&" + param;
273 function setSessionParameters() {
274 var cgiScriptorPRIVATE = sessionStorage.getItem("CGIscriptorPRIVATE");
275 // Use existing cookie
276 if(! cgiScriptorPRIVATE) return true;
278 var sessionset = readCookie("CGIscriptorSESSION");
279 if(!(sessionset && sessionset.match(/[\S]/)))return false;
281 var sessionticket = "";
282 sessionticket = hex_sha256(cgiScriptorPRIVATE);
283 sessionticket = hex_sha256(sessionticket+cgiScriptorPRIVATE);
284 if(!sessionticket) return false;
285 createCookie("CGIscriptorSESSION",sessionticket, 0, "");
287 // Without cookies, use this
288 // var sessionparm = document.getElementById('SESSIONTICKET');
289 // if(sessionparm) sessionparm.value = sessionticket;
290 // add_cgiparam('a', 'href', "SESSIONTICKET="+sessionticket);
291 // add_cgiparam('form', 'action', "SESSIONTICKET="+sessionticket);
293 // UNCOMMENT for use in a local version of the Private/Login.html web page.
294 // add_cgiparam('form', 'action', "SETCGISESSIONCOOKIE="+sessionticket);
298 function setChallengeParameters(sessionset) {
299 if(!(sessionset && sessionset.match(/[\S]/)))return false;
301 var sessionticket = "";
302 var sessionkey = sessionStorage.getItem("CGIscriptorPRIVATE");
303 if(!sessionkey) return false;
304 sessionticket = hex_sha256(sessionkey+sessionset);
305 createCookie("CGIscriptorCHALLENGE",sessionticket, 0, "");
307 // Without cookies, use this
308 // var sessionparm = document.getElementById('CHALLENGETICKET');
309 // if(sessionparm) sessionparm.value = sessionticket;
311 // add_cgiparam('a', 'href', "CHALLENGETICKET="+sessionticket);
312 // add_cgiparam('form', 'action', "CHALLENGETICKET="+sessionticket);
316 function clear_persistent_data () {
317 createCookie("CGIscriptorSESSION","", 0, "");
318 createCookie("CGIscriptorCHALLENGE","", 0, "");
319 sessionStorage.setItem("CGIscriptorPRIVATE", "");
323 function check_password_fields ( ) {
324 var newpassword = document.getElementById('NEWPASSWORD');
325 var newpasswordrep = document.getElementById('NEWPASSWORDREP');
326 if(newpassword.value == "" || newpasswordrep.value == "") {
327 alert("No passwords");
330 if(newpassword.value == newpasswordrep.value) {
331 var submitbutton = document.getElementById('SUBMIT');
332 submitbutton.style.color = "Black";
335 alert("Passwords differ");
339 function check_username_password ( ) {
340 var username = document.getElementById('CGIUSERNAME');
341 var password = document.getElementById('PASSWORD');
342 if(username.value.match(/[a-zA-Z0-9]/) && password.value.match(/[a-zA-Z0-9]/))
344 alert("Please enter a user name and password");
348 function revealPasswords () {
349 var inputs = document.getElementsByTagName("input");
350 for (i=(inputs.length-1); i>=0; i--) {
351 var curr = inputs[i];
352 if (curr.type.toLowerCase()=="password") {
359 function hidePasswords () {
360 var inputs = document.getElementsByTagName("input");
361 for (i=(inputs.length-1); i>=0; i--) {
362 var curr = inputs[i];
363 if (curr.type.toLowerCase()=="text") {
364 curr.type = "PASSWORD";
370 function togglePasswords (hide, show, value) {
371 if(value.match(hide)) {
373 return value.replace(hide, show);
376 return value.replace(show, hide);
380 // Get a loginticket, salt, and random salt from a hidden loginFrame
381 // For use in a local version of the Private/Login.html web page.
382 // UNFINISHED WORK only useful with IPADDRESS sessions
383 // Put the following line in your local version of the HTML page to activate
384 // Replace http://localhost:8080/Private/index.html with the correct URL of the login page
385 // <iFrame id="loginFrame" src="http://localhost:8080/Private/index.html" hidden>Login frame</iFrame>
387 function getLoginData(){
388 var frameID = document.getElementById("loginFrame");
391 if ( frameID.contentDocument )
393 iFrameHeader = frameID.contentDocument.getElementsByTagName('head')[0];
394 iFrameBody = frameID.contentDocument.getElementsByTagName('body')[0];
395 iFrameHTML = frameID.contentDocument.getElementsByTagName('html')[0];
397 else if ( frameID.contentWindow )
399 iFrameHeader = frameID.contentWindow.document.getElementsByTagName('head')[0];
400 iFrameBody = frameID.contentWindow.document.getElementsByTagName('body')[0];
401 iFrameHTML = frameID.contentWindow.document.getElementsByTagName('html')[0];
405 var myLoginexp = /CGIscriptorLoginticket="([a-f0-9]{64})"/;
406 var myLogin = iFrameHeader.innerHTML.match(myLoginexp);
408 CGIscriptorLoginticket = myLogin[1];
410 alert("Login not possible: Are you already logged in?\nLogin ticket missing");
414 var mySaltexp = /CGIscriptorServerSalt="([a-f0-9]{64})"/;
415 var mySalt = iFrameHeader.innerHTML.match(mySaltexp);
417 CGIscriptorServerSalt = mySalt[1];
419 alert("Login not possible: Are you already logged in?\nServer salt missing");
423 var myRandomexp = /CGIscriptorRandomSalt="([a-f0-9]{64})"/;
424 var myRandom = iFrameHeader.innerHTML.match(myRandomexp);
426 CGIscriptorRandomSalt = myRandom[1];
427 } else if(myLogin && mySalt) {
428 alert("Login not possible: Are you already logged in?\nRandom salt missing");
431 // REMOTE_HOST IP ADDRESS
432 var myRemoteHostExp = /id=['"]*CLIENTIPADDRESS['"]* value=['"]([a-f0-9\.\:]+)['"]/;
433 var myRemoteHost = iFrameBody.innerHTML.match(myRemoteHostExp);
435 var ipaddress = document.getElementById("CLIENTIPADDRESS");
436 ipaddress.value = myRemoteHost[1];
440 iFrameHTML.innerHTML = "<html><head><title>EMPTY</title></head><body><h1>EMPTY</h1></body></html>";