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-2013 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");
42 formID.value = CGIscriptorLoginticket;
46 HashPassword(CGIscriptorRandomSalt);
51 function ChangePasswordSubmit () {
52 if(! check_password_fields())return false;
53 // Set the LOGINTICKET value in FORM
54 var formID = document.getElementById("LOGINTICKET");
56 formID.value = CGIscriptorLoginticket;
59 EncryptNewPassword("CGIUSERNAME");
60 HashPassword(CGIscriptorRandomSalt);
65 function CreateUserSubmit () {
66 if(! check_password_fields())return false;
67 // Set the LOGINTICKET value in FORM
68 var formID = document.getElementById("LOGINTICKET");
70 formID.value = CGIscriptorLoginticket;
73 EncryptNewPassword("NEWUSERNAME");
74 HashPassword(CGIscriptorRandomSalt);
79 // Function definitions
80 function hex_sha1 (plaintext) {
81 var shaObj = new jsSHA(plaintext, "ASCII");
82 return shaObj.getHash("SHA-1", "HEX");
84 function hex_sha256 (plaintext) {
85 var shaObj = new jsSHA(plaintext, "ASCII");
86 return shaObj.getHash("SHA-256", "HEX");
88 function hex_sha512 (plaintext) {
89 var shaObj = new jsSHA(plaintext, "ASCII");
90 return shaObj.getHash("SHA-256", "HEX");
92 function chained_sha (plaintext) {
93 return hex_sha256( hex_sha256( hex_sha512(plaintext) ) );
96 function loadSessionData (SessionType, ChallengeTicket) {
97 if(SessionType == 'CHALLENGE')
98 setChallengeParameters(ChallengeTicket);
99 else if(SessionType == 'SESSION')
100 setSessionParameters();
104 function createCookie(name,value,days,path) {
106 var date = new Date();
107 date.setTime(date.getTime()+(days*24*60*60*1000));
108 var expires = "; expires="+date.toGMTString();
110 else var expires = "";
111 var match = document.cookie.match('/('+name+'\=[^\;]*\);/');
114 document.cookie = document.cookie.replace(match[1], name+"="+value);
115 match = document.cookie.match('/('+name+'\=[^\;]*\);/');
118 document.cookie = name+"=-";
119 document.cookie = name+"="+value+expires+"; path=/"+path;
124 function readCookie(name) {
125 var nameEQ = name + "=";
126 var ca = document.cookie.split(';');
127 for(var i=0;i < ca.length;i++) {
129 while (c.charAt(0)==' ') c = c.substring(1,c.length);
130 if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
135 function eraseCookie(name) {
136 createCookie(name,"",-1);
139 // Combine the PASSWORD with the site SERVERSALT and hash it
140 // Combine this Hash iwth the extra SERVERSALT, and hash them
141 function HashPassword(extsalt) {
142 var hash = HashSessionSeed(extsalt);
143 var password = document.getElementById('PASSWORD');
145 password.value = hash;
147 alert("NO PASSWORD IN FORM");
153 // REMEMBER: Set the session cookie BEFORE you hash the password!!!
154 function SetSessionCookie() {
155 var loginticket = CGIscriptorLoginticket;
156 var randomsalt = CGIscriptorRandomSalt;
157 var hash = HashSessionSeed(loginticket);
158 // Dom.storage.enabled must be set!
159 if (!sessionStorage || typeof(sessionStorage) == 'undefined' ) {
160 alert('Your browser does not support HTML5 sessionStorage. Set Dom.storage.enabled or try upgrading.');
163 else sessionStorage.setItem("CGIscriptorPRIVATE", hash);
165 // Store a secret key, if one is given
171 function SetSecretKey() {
172 var loginticket = CGIscriptorLoginticket;
173 var randomsalt = CGIscriptorRandomSalt;
175 if (!sessionStorage || typeof(sessionStorage) == 'undefined' ) {
176 alert('Your browser does not support HTML5 sessionStorage. Set Dom.storage.enabled or try upgrading.');
179 else if (loginticket && randomsalt) {
180 secretkey = HashSessionSeed(loginticket+randomsalt);
181 sessionStorage.setItem("CGIscriptorSECRET", secretkey);
187 // Hash(sessionseed+hash(password+username+salt.toLowerCase()))
188 function HashSessionSeed(sessionseed) {
191 var passwordvalue = document.getElementById('PASSWORD');
192 var saltvalue = CGIscriptorServerSalt;
193 var username = document.getElementById('CGIUSERNAME');
194 hash1 = hex_sha256(passwordvalue.value+username.value.toLowerCase()+saltvalue);
195 if(sessionseed != "")
196 hash2 = hex_sha256(hash1+sessionseed);
202 // Remember to hash the repeat too! Or else it will be send in the clear
203 function HashNewPassword(userid) {
205 var newpassword = document.getElementById('NEWPASSWORD');
206 var newpasswordrep = document.getElementById('NEWPASSWORDREP');
207 var username = document.getElementById(userid);
208 if(newpassword.value == "" ) {
209 newpassword.value = "";
212 if(newpasswordrep && (newpasswordrep.value == ""|| newpassword.value != newpasswordrep.value)) {
213 newpassword.value = "";
214 newpasswordrep.value = "";
217 var saltvalue = CGIscriptorServerSalt;
218 hash1 = hex_sha256(newpassword.value+username.value.toLowerCase()+saltvalue);
219 newpassword.value = hash1;
220 newpasswordrep.value = hash1;
224 function XOR_hex_strings(hex1, hex2) {
226 var maxlength = Math.max(hex1.length, hex2.length);
228 for(var i=0; i < maxlength; ++i) {
229 var h1 = hex1.charAt(i);
231 var h2 = hex2.charAt(i);
233 var d1 = parseInt(h1,16);
234 var d2 = parseInt(h2,16);
236 resultHex = resultHex+resultD.toString(16);
241 function EncryptNewPassword(userid) {
242 var newpassword = document.getElementById('NEWPASSWORD');
243 var newpasswordrep = document.getElementById('NEWPASSWORDREP');
244 var secretkey = SetSecretKey();
246 // This hashes the newpassword field!
247 HashNewPassword(userid);
248 var encrypted = XOR_hex_strings(secretkey, newpassword.value);
249 newpassword.value = encrypted;
250 newpasswordrep.value = encrypted;
254 function DecryptNewPassword(key, encrypted) {
255 decrypted = XOR_hex_strings(key, encrypted);
260 function add_cgiparam(elem, attr, param) {
261 var elems = document.getElementsByTagName(elem);
262 for (var i = 0; i < elems.length; i++)
264 var n=elems[i][attr].indexOf("?");
266 elems[i][attr] = elems[i][attr] + "?" + param;
268 elems[i][attr] = elems[i][attr] + "&" + param;
272 function setSessionParameters() {
273 var sessionset = readCookie("CGIscriptorSESSION");
274 if(!(sessionset &&sessionset.match(/[\S]/)))return false;
276 var sessionticket = "";
277 sessionticket = sessionStorage.getItem("CGIscriptorPRIVATE");
278 if(!sessionticket) return false;
279 createCookie("CGIscriptorSESSION",sessionticket, 0, "");
281 // Without cookies, use this
282 // var sessionparm = document.getElementById('SESSIONTICKET');
283 // if(sessionparm) sessionparm.value = sessionticket;
284 // add_cgiparam('a', 'href', "SESSIONTICKET="+sessionticket);
285 // add_cgiparam('form', 'action', "SESSIONTICKET="+sessionticket);
288 function setChallengeParameters(sessionset) {
289 if(!(sessionset && sessionset.match(/[\S]/)))return false;
291 var sessionticket = "";
292 var sessionkey = sessionStorage.getItem("CGIscriptorPRIVATE");
293 if(!sessionkey) return false;
294 sessionticket = hex_sha256(sessionkey+sessionset);
295 createCookie("CGIscriptorCHALLENGE",sessionticket, 0, "");
297 // Without cookies, use this
298 // var sessionparm = document.getElementById('CHALLENGETICKET');
299 // if(sessionparm) sessionparm.value = sessionticket;
301 // add_cgiparam('a', 'href', "CHALLENGETICKET="+sessionticket);
302 // add_cgiparam('form', 'action', "CHALLENGETICKET="+sessionticket);
306 function clear_persistent_data () {
307 createCookie("CGIscriptorSESSION","", 0, "");
308 createCookie("CGIscriptorCHALLENGE","", 0, "");
309 sessionStorage.setItem("CGIscriptorPRIVATE", "");
313 function check_password_fields ( ) {
314 var newpassword = document.getElementById('NEWPASSWORD');
315 var newpasswordrep = document.getElementById('NEWPASSWORDREP');
316 if(newpassword.value == "" || newpasswordrep.value == "") {
317 alert("No passwords");
320 if(newpassword.value == newpasswordrep.value) {
321 var submitbutton = document.getElementById('SUBMIT');
322 submitbutton.style.color = "Black";
325 alert("Passwords differ");
329 function check_username_password ( ) {
330 var username = document.getElementById('CGIUSERNAME');
331 var password = document.getElementById('PASSWORD');
332 if(username.value.match(/[a-zA-Z0-9]/) && password.value.match(/[a-zA-Z0-9]/))
334 alert("Please enter a user name and password");
338 function revealPasswords () {
339 var inputs = document.getElementsByTagName("input");
340 for (i=(inputs.length-1); i>=0; i--) {
341 var curr = inputs[i];
342 if (curr.type.toLowerCase()=="password") {
349 function hidePasswords () {
350 var inputs = document.getElementsByTagName("input");
351 for (i=(inputs.length-1); i>=0; i--) {
352 var curr = inputs[i];
353 if (curr.type.toLowerCase()=="text") {
354 curr.type = "PASSWORD";
360 function togglePasswords (hide, show, value) {
361 if(value.match(hide)) {
363 return value.replace(hide, show);
366 return value.replace(show, hide);
370 // Get a loginticket, salt, and random salt from a hidden loginFrame
371 // For use in a local version of the Private/Login.html web page.
372 // UNFINISHED WORK only useful with IPADDRESS sessions
373 // Put the following line in your local version of the HTML page to activate
374 // Replace http://localhost:8080/Private/index.html with the correct URL of the login page
375 // <iFrame id="loginFrame" src="http://localhost:8080/Private/index.html" hidden>Login frame</iFrame>
377 function getLoginData(){
378 var frameID = document.getElementById("loginFrame");
380 if ( frameID.contentDocument )
382 iFrameHeader = frameID.contentDocument.getElementsByTagName('head')[0];
384 else if ( frameID.contentWindow )
386 iFrameHeader = frameID.contentWindow.document.getElementsByTagName('head')[0];
390 var myLoginexp = /CGIscriptorLoginticket="([a-f0-9]{64})"/;
391 var myLogin = iFrameHeader.innerHTML.match(myLoginexp);
392 CGIscriptorLoginticket = myLogin[1];
395 var mySaltexp = /CGIscriptorServerSalt="([a-f0-9]{64})"/;
396 var mySalt = iFrameHeader.innerHTML.match(mySaltexp);
397 CGIscriptorServerSalt = mySalt[1];
400 var myRandomexp = /CGIscriptorRandomSalt="([a-f0-9]{64})"/;
401 var myRandom = iFrameHeader.innerHTML.match(myRandomexp);
402 CGIscriptorRandomSalt = myRandom[1];