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 cgiScriptorPRIVATE
= sessionStorage
.getItem("CGIscriptorPRIVATE");
274 // Use existing cookie
275 if(! cgiScriptorPRIVATE
) return true;
277 var sessionset
= readCookie("CGIscriptorSESSION");
278 if(!(sessionset
&& sessionset
.match(/[\S]/)))return false;
280 var sessionticket
= "";
281 sessionticket
= hex_sha256(cgiScriptorPRIVATE
);
282 if(!sessionticket
) return false;
283 createCookie("CGIscriptorSESSION",sessionticket
, 0, "");
285 // Without cookies, use this
286 // var sessionparm = document.getElementById('SESSIONTICKET');
287 // if(sessionparm) sessionparm.value = sessionticket;
288 // add_cgiparam('a', 'href', "SESSIONTICKET="+sessionticket);
289 // add_cgiparam('form', 'action', "SESSIONTICKET="+sessionticket);
291 // UNCOMMENT for use in a local version of the Private/Login.html web page.
292 // add_cgiparam('form', 'action', "SETCGISESSIONCOOKIE="+sessionticket);
296 function setChallengeParameters(sessionset
) {
297 if(!(sessionset
&& sessionset
.match(/[\S]/)))return false;
299 var sessionticket
= "";
300 var sessionkey
= sessionStorage
.getItem("CGIscriptorPRIVATE");
301 if(!sessionkey
) return false;
302 sessionticket
= hex_sha256(sessionkey
+sessionset
);
303 createCookie("CGIscriptorCHALLENGE",sessionticket
, 0, "");
305 // Without cookies, use this
306 // var sessionparm = document.getElementById('CHALLENGETICKET');
307 // if(sessionparm) sessionparm.value = sessionticket;
309 // add_cgiparam('a', 'href', "CHALLENGETICKET="+sessionticket);
310 // add_cgiparam('form', 'action', "CHALLENGETICKET="+sessionticket);
314 function clear_persistent_data () {
315 createCookie("CGIscriptorSESSION","", 0, "");
316 createCookie("CGIscriptorCHALLENGE","", 0, "");
317 sessionStorage
.setItem("CGIscriptorPRIVATE", "");
321 function check_password_fields ( ) {
322 var newpassword
= document
.getElementById('NEWPASSWORD');
323 var newpasswordrep
= document
.getElementById('NEWPASSWORDREP');
324 if(newpassword
.value
== "" || newpasswordrep
.value
== "") {
325 alert("No passwords");
328 if(newpassword
.value
== newpasswordrep
.value
) {
329 var submitbutton
= document
.getElementById('SUBMIT');
330 submitbutton
.style
.color
= "Black";
333 alert("Passwords differ");
337 function check_username_password ( ) {
338 var username
= document
.getElementById('CGIUSERNAME');
339 var password
= document
.getElementById('PASSWORD');
340 if(username
.value
.match(/[a-zA-Z0-9]/) && password
.value
.match(/[a-zA-Z0-9]/))
342 alert("Please enter a user name and password");
346 function revealPasswords () {
347 var inputs
= document
.getElementsByTagName("input");
348 for (i
=(inputs
.length
-1); i
>=0; i
--) {
349 var curr
= inputs
[i
];
350 if (curr
.type
.toLowerCase()=="password") {
357 function hidePasswords () {
358 var inputs
= document
.getElementsByTagName("input");
359 for (i
=(inputs
.length
-1); i
>=0; i
--) {
360 var curr
= inputs
[i
];
361 if (curr
.type
.toLowerCase()=="text") {
362 curr
.type
= "PASSWORD";
368 function togglePasswords (hide
, show
, value
) {
369 if(value
.match(hide
)) {
371 return value
.replace(hide
, show
);
374 return value
.replace(show
, hide
);
378 // Get a loginticket, salt, and random salt from a hidden loginFrame
379 // For use in a local version of the Private/Login.html web page.
380 // UNFINISHED WORK only useful with IPADDRESS sessions
381 // Put the following line in your local version of the HTML page to activate
382 // Replace http://localhost:8080/Private/index.html with the correct URL of the login page
383 // <iFrame id="loginFrame" src="http://localhost:8080/Private/index.html" hidden>Login frame</iFrame>
385 function getLoginData(){
386 var frameID
= document
.getElementById("loginFrame");
388 if ( frameID
.contentDocument
)
390 iFrameHeader
= frameID
.contentDocument
.getElementsByTagName('head')[0];
391 iFrameHTML
= frameID
.contentDocument
.getElementsByTagName('html')[0];
393 else if ( frameID
.contentWindow
)
395 iFrameHeader
= frameID
.contentWindow
.document
.getElementsByTagName('head')[0];
396 iFrameHTML
= frameID
.contentWindow
.document
.getElementsByTagName('html')[0];
400 var myLoginexp
= /CGIscriptorLoginticket="([a-f0-9]{64})"/;
401 var myLogin
= iFrameHeader
.innerHTML
.match(myLoginexp
);
403 CGIscriptorLoginticket
= myLogin
[1];
405 alert("Login not possible: Are you already logged in?\nLogin ticket missing");
409 var mySaltexp
= /CGIscriptorServerSalt="([a-f0-9]{64})"/;
410 var mySalt
= iFrameHeader
.innerHTML
.match(mySaltexp
);
412 CGIscriptorServerSalt
= mySalt
[1];
414 alert("Login not possible: Are you already logged in?\nServer salt missing");
418 var myRandomexp
= /CGIscriptorRandomSalt="([a-f0-9]{64})"/;
419 var myRandom
= iFrameHeader
.innerHTML
.match(myRandomexp
);
421 CGIscriptorRandomSalt
= myRandom
[1];
422 } else if(myLogin
&& mySalt
) {
423 alert("Login not possible: Are you already logged in?\nRandom salt missing");
427 iFrameHTML
.innerHTML
= "<html><head><title>EMPTY</title></head><body><h1>EMPTY</h1></body></html>";