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");
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 iwth 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(sessionseed+hash(password+username.toLowerCase()+salt))
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>";