Started work on using a local copy of the Login.html page, unfinished
[CGIscriptor.git] / JavaScript / CGIscriptorSession.js
blob7678f0002f4abb250f517025b07a84bc6b5ff034
1 // Global variables, set by the server as CGI parameter values
2 var CGIscriptorSessionType="<SCRIPT TYPE="text/ssperl" CGI='$SESSIONTYPE=""'>
3         $SESSIONTYPE;</SCRIPT>";
4 var CGIscriptorChallengeTicket="<SCRIPT TYPE="text/ssperl" CGI='$CHALLENGETICKET=""'>
5         $CHALLENGETICKET;</SCRIPT>";
7 var CGIscriptorLoginticket="<SCRIPT TYPE='text/ssperl' CGI='$LOGINTICKET=""'>
8         $LOGINTICKET</SCRIPT>";
9 var CGIscriptorServerSalt="<SCRIPT TYPE='text/ssperl' CGI='$SERVERSALT=""'>
10         $SERVERSALT</SCRIPT>";
11 var CGIscriptorRandomSalt="<SCRIPT TYPE='text/ssperl' CGI='$RANDOMSALT=""'>
12         $RANDOMSALT</SCRIPT>";
14 // OnSubmit functions
15 function LoginSubmit () {
16         var success=check_username_password();
17         SetSessionCookie();
18         HashPassword(CGIscriptorRandomSalt);
19         hidePasswords();
20         return success;
23 function ChangePasswordSubmit () {
24         if(! check_password_fields())return false;
25         
26         EncryptNewPassword("CGIUSERNAME");
27         HashPassword(CGIscriptorRandomSalt);
28         hidePasswords();
29         return true;
32 function CreateUserSubmit () {
33         if(! check_password_fields())return false;
34         
35         EncryptNewPassword("NEWUSERNAME");
36         HashPassword(CGIscriptorRandomSalt);
37         hidePasswords();
38         return true;
41 // Function definitions
42 function hex_sha1 (plaintext) {
43         var shaObj = new jsSHA(plaintext, "ASCII");
44         return shaObj.getHash("SHA-1", "HEX");
46 function hex_sha256 (plaintext) {
47         var shaObj = new jsSHA(plaintext, "ASCII");
48         return shaObj.getHash("SHA-256", "HEX");
50 function hex_sha512 (plaintext) {
51         var shaObj = new jsSHA(plaintext, "ASCII");
52         return shaObj.getHash("SHA-256", "HEX");
54 function chained_sha (plaintext) {
55         return hex_sha256( hex_sha256( hex_sha512(plaintext) ) );
58 function loadSessionData (SessionType, ChallengeTicket) {
59         if(SessionType == 'CHALLENGE') 
60                 setChallengeParameters(ChallengeTicket);
61         else if(SessionType == 'SESSION')
62                 setSessionParameters();
63         return SessionType;
66 function createCookie(name,value,days,path) {
67         if (days) {
68                 var date = new Date();
69                 date.setTime(date.getTime()+(days*24*60*60*1000));
70                 var expires = "; expires="+date.toGMTString();
71         }
72         else var expires = "";
73         var match = document.cookie.match('/('+name+'\=[^\;]*\);/');
74         if(match){
75                 while(match) {
76                         document.cookie = document.cookie.replace(match[1], name+"="+value);
77                         match = document.cookie.match('/('+name+'\=[^\;]*\);/');
78                 };
79         } else {
80                 document.cookie = name+"=-";
81                 document.cookie = name+"="+value+expires+"; path=/"+path;
82         };
86 function readCookie(name) {
87         var nameEQ = name + "=";
88         var ca = document.cookie.split(';');
89         for(var i=0;i < ca.length;i++) {
90                 var c = ca[i];
91                 while (c.charAt(0)==' ') c = c.substring(1,c.length);
92                 if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
93         }
94         return null;
97 function eraseCookie(name) {
98         createCookie(name,"",-1);
101 // Combine the PASSWORD with the site SERVERSALT and hash it
102 // Combine this Hash iwth the extra SERVERSALT, and hash them
103 function HashPassword(extsalt) {
104         var hash = HashSessionSeed(extsalt);
105         var password = document.getElementById('PASSWORD');
106         if(password){
107                 password.value = hash;
108         } else {
109                 alert("NO PASSWORD IN FORM");
110                 return 0;
111         };
112         return hash;
115 // REMEMBER: Set the session cookie BEFORE you hash the password!!!
116 function SetSessionCookie() {
117         var loginticket = CGIscriptorLoginticket;
118         var randomsalt = CGIscriptorRandomSalt;
119         var hash = HashSessionSeed(loginticket);
120         // Dom.storage.enabled must be set!
121         if (!sessionStorage || typeof(sessionStorage) == 'undefined' ) {
122                 alert('Your browser does not support HTML5 sessionStorage. Set Dom.storage.enabled or try upgrading.');
123                 return 0;
124         } 
125         else sessionStorage.setItem("CGIscriptorPRIVATE", hash);
126         
127         // Store a secret key, if one is given
128         SetSecretKey();
129         
130         return hash;
133 function SetSecretKey() {
134         var loginticket = CGIscriptorLoginticket;
135         var randomsalt = CGIscriptorRandomSalt;
136         var secretkey = ""; 
137         if (!sessionStorage || typeof(sessionStorage) == 'undefined' ) {
138                 alert('Your browser does not support HTML5 sessionStorage. Set Dom.storage.enabled or try upgrading.');
139                 return "";
140         } 
141         else if (loginticket && randomsalt) {
142                 secretkey = HashSessionSeed(loginticket+randomsalt);
143                 sessionStorage.setItem("CGIscriptorSECRET", secretkey);
144         };
145         
146         return secretkey;
149 // Hash(sessionseed+hash(password+username+salt.toLowerCase()))
150 function HashSessionSeed(sessionseed) {
151         var hash1 = "";
152         var hash2 = "";
153         var passwordvalue = document.getElementById('PASSWORD');
154         var saltvalue = CGIscriptorServerSalt;
155         var username = document.getElementById('CGIUSERNAME');
156         hash1 = hex_sha256(passwordvalue.value+username.value.toLowerCase()+saltvalue);
157         if(sessionseed != "")
158                 hash2 = hex_sha256(hash1+sessionseed);
159         else
160                 hash2 = hash1;
161         return hash2;
164 // Remember to hash the repeat too! Or else it will be send in the clear
165 function HashNewPassword(userid) {
166         var hash1 = "";
167         var newpassword = document.getElementById('NEWPASSWORD');
168         var newpasswordrep = document.getElementById('NEWPASSWORDREP');
169         var username = document.getElementById(userid);
170         if(newpassword.value == "" ) {
171                 newpassword.value = "";
172                 return 0;
173         };
174         if(newpasswordrep && (newpasswordrep.value == ""|| newpassword.value != newpasswordrep.value)) {
175                 newpassword.value = "";
176                 newpasswordrep.value = "";
177                 return 0;
178         };
179         var saltvalue = CGIscriptorServerSalt;
180         hash1 = hex_sha256(newpassword.value+username.value.toLowerCase()+saltvalue);
181         newpassword.value = hash1;
182         newpasswordrep.value = hash1;
183         return hash1;
186 function XOR_hex_strings(hex1, hex2) {
187         var resultHex = "";
188         var maxlength = Math.max(hex1.length, hex2.length);
190         for(var i=0; i < maxlength; ++i) {
191                 var h1 = hex1.charAt(i);
192                 if(! h1) h1='0';
193                 var h2 = hex2.charAt(i);
194                 if(! h2) h2 ='0';
195                 var d1 = parseInt(h1,16);
196                 var d2 = parseInt(h2,16);
197                 var resultD = d1^d2;
198                 resultHex = resultHex+resultD.toString(16);
199         };
200         return resultHex;
203 function EncryptNewPassword(userid) {
204         var newpassword = document.getElementById('NEWPASSWORD');
205         var newpasswordrep = document.getElementById('NEWPASSWORDREP');
206         var secretkey = SetSecretKey();
207         
208         // This hashes the newpassword field!
209         HashNewPassword(userid);
210         var encrypted = XOR_hex_strings(secretkey, newpassword.value);
211         newpassword.value = encrypted;
212         newpasswordrep.value = encrypted;
213         return encrypted;
216 function DecryptNewPassword(key, encrypted) {
217         decrypted = XOR_hex_strings(key, encrypted);
218         
219         return decrypted;
222 function add_cgiparam(elem, attr, param) {
223     var elems = document.getElementsByTagName(elem);
224     for (var i = 0; i < elems.length; i++)
225     {
226                 var n=elems[i][attr].indexOf("?");
227                 if(n<0)
228                         elems[i][attr] = elems[i][attr] + "?" + param;
229                 else
230                         elems[i][attr] = elems[i][attr] + "&" + param;
231     };
234 function setSessionParameters() {
235         var sessionset = readCookie("CGIscriptorSESSION");
236         if(!(sessionset &&sessionset.match(/[\S]/)))return false;
238         var sessionticket = "";
239         sessionticket = sessionStorage.getItem("CGIscriptorPRIVATE");
240         if(!sessionticket) return false;
241         createCookie("CGIscriptorSESSION",sessionticket, 0, "");
242         
243         // Without cookies, use this
244         // var sessionparm = document.getElementById('SESSIONTICKET');
245         // if(sessionparm) sessionparm.value = sessionticket;
246     // add_cgiparam('a', 'href', "SESSIONTICKET="+sessionticket);
247     // add_cgiparam('form', 'action', "SESSIONTICKET="+sessionticket);
248         return true;
250 function setChallengeParameters(sessionset) {
251         if(!(sessionset && sessionset.match(/[\S]/)))return false;
252         
253         var sessionticket = "";
254         var sessionkey = sessionStorage.getItem("CGIscriptorPRIVATE");
255         if(!sessionkey) return false;
256         sessionticket = hex_sha256(sessionkey+sessionset);
257         createCookie("CGIscriptorCHALLENGE",sessionticket, 0, "");
259         // Without cookies, use this
260         // var sessionparm = document.getElementById('CHALLENGETICKET');
261         // if(sessionparm) sessionparm.value = sessionticket;
262         
263         // add_cgiparam('a', 'href', "CHALLENGETICKET="+sessionticket);
264         // add_cgiparam('form', 'action', "CHALLENGETICKET="+sessionticket);
265         return true;
268 function clear_persistent_data () {
269         createCookie("CGIscriptorSESSION","", 0, "");
270         createCookie("CGIscriptorCHALLENGE","", 0, "");
271         sessionStorage.setItem("CGIscriptorPRIVATE", "");
272         return true;
275 function check_password_fields ( ) {
276         var newpassword = document.getElementById('NEWPASSWORD');
277         var newpasswordrep = document.getElementById('NEWPASSWORDREP');
278         if(newpassword.value == "" || newpasswordrep.value == "") {
279                 alert("No passwords");
280                 return false;
281         };
282         if(newpassword.value == newpasswordrep.value) {
283                 var submitbutton = document.getElementById('SUBMIT');
284                 submitbutton.style.color = "Black";
285                 return true;
286         };
287         alert("Passwords differ");
288         return false;
291 function check_username_password ( ) {
292         var username = document.getElementById('CGIUSERNAME');
293         var password = document.getElementById('PASSWORD');
294         if(username.value.match(/[a-zA-Z0-9]/) && password.value.match(/[a-zA-Z0-9]/))
295                 return true;
296         alert("Please enter a user name and password");
297         return false;
300 function revealPasswords () {
301         var inputs = document.getElementsByTagName("input");
302         for (i=(inputs.length-1); i>=0; i--) {
303                 var curr = inputs[i];
304                 if (curr.type.toLowerCase()=="password") {
305                         curr.type = "TEXT";
306                 };
307         };
308         
311 function hidePasswords () {
312         var inputs = document.getElementsByTagName("input");
313         for (i=(inputs.length-1); i>=0; i--) {
314                 var curr = inputs[i];
315                 if (curr.type.toLowerCase()=="text") {
316                         curr.type = "PASSWORD";
317                 };
318         };
319         
322 function togglePasswords (hide, show, value) {
323         if(value.match(hide)) {
324                 hidePasswords ();
325                 return value.replace(hide, show);
326         } else {
327                 revealPasswords ();
328                 return value.replace(show, hide);
329         };
332 // Get a loginticket, salt, and random salt from a hidden loginFrame
333 // UNCOMMENT for use in a local version of the Private/Login.html web page.
334 // UNFINISHED WORK
335 // Put the following line in your local version to activate
336 // <iFrame id="loginFrame" src="http://localhost:8080/Private/index.html" hidden>Login frame</iFrame>
338 function getLoginData(){
339         var frameID = document.getElementById("loginFrame");
340         var iFrameHeader;
341         if ( frameID.contentDocument ) 
342         { // FF
343           iFrameHeader = frameID.contentDocument.getElementsByTagName('head')[0];
344         }
345         else if ( frameID.contentWindow ) 
346         { // IE
347           iFrameHeader = frameID.contentWindow.document.getElementsByTagName('head')[0];
348         }
349         
350         // Login ticket
351         var myLoginexp = /CGIscriptorLoginticket="([a-f0-9]{64})"/;
352         var myLogin = iFrameHeader.innerHTML.match(myLoginexp);
353         CGIscriptorLoginticket = myLogin[1];
354         var formID = document.getElementById("LOGINTICKET");
355         // Set correct LOGINTICKET value in Form
356         formID.value = CGIscriptorLoginticket;
357         
358         // Server Salt
359         var mySaltexp = /CGIscriptorServerSalt="([a-f0-9]{64})"/;
360         var mySalt = iFrameHeader.innerHTML.match(mySaltexp);
361         CGIscriptorServerSalt = mySalt[1];
363         // Random Salt
364         var myRandomexp = /CGIscriptorRandomSalt="([a-f0-9]{64})"/;
365         var myRandom = iFrameHeader.innerHTML.match(myRandomexp);
366         CGIscriptorRandomSalt = myRandom[1];