diff --git a/server/functions.php b/server/functions.php
index fd5d7b9..df844d4 100755
--- a/server/functions.php
+++ b/server/functions.php
@@ -171,28 +171,28 @@ function load_database($user)
return $db;
}
-function add_entry($user, $mkey, $url, $login, $password)
+function add_entry($user, $login, $password)
{
$db = load_database($user);
- if ($db == null) return false;
-
- $password = encrypt($mkey, trim($password), true);
- $login = encrypt($mkey, "@@" . trim($url) . ";" . trim($login), false);
-
- if ($password == null || $login == null)
+ if ($db == null)
+ {
+ echo "Unknown user";
return false;
+ }
$count = $db->querySingle("SELECT COUNT(*) FROM gpass WHERE login='" . $login . "'");
if ($count != 0)
{
- echo "
-
-
-" . (count($entries) - $nb_ciphered) . " unciphered password(s)
\n";
- foreach($entries as $entry)
- {
- if ($entry['ciphered'] == 1) continue;
- echo '
' . "\n";
- }
-
- echo "
\n";
- echo "
$nb_ciphered ciphered password(s)\n";
- if ($VIEW_CIPHERED_PASSWORDS)
- {
- foreach($entries as $entry)
- {
- if ($entry['ciphered'] == 0) continue;
- echo '
' . "\n";
- }
- }
+ if (!isset($_SERVER['HTTPS']))
+ echo "
Current addon address is : http://" . $_SERVER['SERVER_NAME'] . "/" . $user . "
\n";
+ else
+ echo "
Current addon address is : https://" . $_SERVER['SERVER_NAME'] . "/" . $user . "
\n";
}
?>
+
Add a new password
\n";
- echo '' . "\n";
+ echo "";
}
?>
-
\ No newline at end of file
+
diff --git a/server/ressources/gpass.css b/server/ressources/gpass.css
index 68f95f8..709ab5e 100755
--- a/server/ressources/gpass.css
+++ b/server/ressources/gpass.css
@@ -31,9 +31,11 @@ body {
border-color:green;
padding : 15px;
margin : 15px;
+ text-align:center;
}
#user input {
+ margin-left : 15px;
margin-right : 30px;
margin-top : 10px;
margin-bottom : 10px;
diff --git a/server/ressources/gpass.js b/server/ressources/gpass.js
index 61bf4ff..2823770 100755
--- a/server/ressources/gpass.js
+++ b/server/ressources/gpass.js
@@ -31,6 +31,26 @@ parseUri.options = {
}
};
+if (!String.prototype.trim) {
+ String.prototype.trim = function() {
+ return this.replace(/^\s+|\s+$/g, "");
+ };
+}
+
+// Array Remove - By John Resig (MIT Licensed)
+// http://stackoverflow.com/questions/500606/javascript-array-delete-elements
+Array.prototype.remove = function(from, to) {
+ var rest = this.slice((to || from) + 1 || this.length);
+ this.length = from < 0 ? this.length + from : from;
+ return this.push.apply(this, rest);
+};
+
+Element.prototype.removeAllChilds = function() {
+ while (this.hasChildNodes())
+ this.removeChild(this.childNodes[0]);
+};
+
+
function generate_password()
{
// symbols 32 - 47 / 58 - 64 / 91 - 96 / 123 - 126
@@ -72,20 +92,543 @@ function a2hex(str) {
return hex;
}
-function derive_mkey(user, mkey_target)
+function derive_mkey(user, mkey)
{
- mkey_target = document.getElementById(mkey_target) ;
- mkey = mkey_target.value;
-
- if (mkey.length == 0)
- {
- alert('Empty master key');
- return false;
- }
-
url = url_domain(document.URL) + "/" + user;
mkey = a2hex(pkdbf2(mkey, url, 1000, 256/8));
- mkey_target.value = mkey;
+
+ return mkey;
+}
+
+var passwords;
+var current_user = "";
+var current_mkey = "";
+
+function PasswordEntry (ciphered_login="", ciphered_password="") {
+ this.ciphered_login = ciphered_login;
+ this.ciphered_password = ciphered_password;
+ this.unciphered = false;
+ this.clear_url = "";
+ this.clear_login = "";
+ this.clear_password = "";
+ this.masterkey = "";
+
+ this.decrypt = function(masterkey)
+ {
+ if (masterkey == this.masterkey && this.unciphered == true)
+ return true;
+
+ if (masterkey == "" || this.unciphered == true)
+ return false;
+
+ aes = new AES();
+ a_masterkey = aes.init(hex2a(masterkey));
+ login = aes.decryptLongString(hex2a(this.ciphered_login), a_masterkey);
+ login = login.replace(/\0*$/, "");
+ if (login.indexOf("@@") != 0)
+ {
+ aes.finish();
+ return false;
+ }
+ // Remove @@
+ login = login.substring(2);
+ infos = login.split(";");
+ this.clear_url = infos[0];
+ this.clear_login = infos[1];
+ this.clear_password = aes.decryptLongString(hex2a(this.ciphered_password), a_masterkey);
+ this.unciphered = true;
+ this.masterkey = masterkey;
+ aes.finish();
+
+ // Remove salt
+ this.clear_password = this.clear_password.replace(/\0*$/, "");
+ this.clear_password = this.clear_password.substr(0, this.clear_password.length-3);
+
+ return true;
+ }
+
+ this.isUnciphered = function(masterkey)
+ {
+ return (this.unciphered == true && masterkey == this.masterkey && masterkey != "")
+ }
+
+ this.isCiphered = function(masterkey)
+ {
+ return !(this.isUnciphered(masterkey));
+ }
+}
+
+function list_all_entries(user)
+{
+ passwords = new Array();
+
+ req = new XMLHttpRequest();
+ req.addEventListener("load", function(evt) {
+ entries = this.responseText.split("\n");
+ if (entries[0] == "entries")
+ {
+ for(i=1; i
= 256)
+ Rcon ^= 0x11b;
+ }
+ else if ((kl > 24) && (i % kl == 16))
+ temp = new Array(AES_Sbox[temp[0]], AES_Sbox[temp[1]],
+ AES_Sbox[temp[2]], AES_Sbox[temp[3]]);
+ for(var j = 0; j < 4; j++)
+ key[i + j] = key[i + j - kl] ^ temp[j];
+ }
+}
+
+/*
+ AES_Encrypt: encrypt the 16 byte array 'block' with the previously
+ expanded key 'key'.
+*/
+
+function AES_Encrypt(block, key) {
+ var l = key.length;
+ AES_AddRoundKey(block, key.slice(0, 16));
+ for(var i = 16; i < l - 16; i += 16) {
+ AES_SubBytes(block, AES_Sbox);
+ AES_ShiftRows(block, AES_ShiftRowTab);
+ AES_MixColumns(block);
+ AES_AddRoundKey(block, key.slice(i, i + 16));
+ }
+ AES_SubBytes(block, AES_Sbox);
+ AES_ShiftRows(block, AES_ShiftRowTab);
+ AES_AddRoundKey(block, key.slice(i, l));
+}
+
+/*
+ AES_Decrypt: decrypt the 16 byte array 'block' with the previously
+ expanded key 'key'.
+*/
+
+function AES_Decrypt(block, key) {
+ var l = key.length;
+ AES_AddRoundKey(block, key.slice(l - 16, l));
+ AES_ShiftRows(block, AES_ShiftRowTab_Inv);
+ AES_SubBytes(block, AES_Sbox_Inv);
+ for(var i = l - 32; i >= 16; i -= 16) {
+ AES_AddRoundKey(block, key.slice(i, i + 16));
+ AES_MixColumns_Inv(block);
+ AES_ShiftRows(block, AES_ShiftRowTab_Inv);
+ AES_SubBytes(block, AES_Sbox_Inv);
+ }
+ AES_AddRoundKey(block, key.slice(0, 16));
+}
+
+/******************************************************************************/
+
+/* The following lookup tables and functions are for internal use only! */
+
+AES_Sbox = new Array(99,124,119,123,242,107,111,197,48,1,103,43,254,215,171,
+ 118,202,130,201,125,250,89,71,240,173,212,162,175,156,164,114,192,183,253,
+ 147,38,54,63,247,204,52,165,229,241,113,216,49,21,4,199,35,195,24,150,5,154,
+ 7,18,128,226,235,39,178,117,9,131,44,26,27,110,90,160,82,59,214,179,41,227,
+ 47,132,83,209,0,237,32,252,177,91,106,203,190,57,74,76,88,207,208,239,170,
+ 251,67,77,51,133,69,249,2,127,80,60,159,168,81,163,64,143,146,157,56,245,
+ 188,182,218,33,16,255,243,210,205,12,19,236,95,151,68,23,196,167,126,61,
+ 100,93,25,115,96,129,79,220,34,42,144,136,70,238,184,20,222,94,11,219,224,
+ 50,58,10,73,6,36,92,194,211,172,98,145,149,228,121,231,200,55,109,141,213,
+ 78,169,108,86,244,234,101,122,174,8,186,120,37,46,28,166,180,198,232,221,
+ 116,31,75,189,139,138,112,62,181,102,72,3,246,14,97,53,87,185,134,193,29,
+ 158,225,248,152,17,105,217,142,148,155,30,135,233,206,85,40,223,140,161,
+ 137,13,191,230,66,104,65,153,45,15,176,84,187,22);
+
+AES_ShiftRowTab = new Array(0,5,10,15,4,9,14,3,8,13,2,7,12,1,6,11);
+
+function AES_SubBytes(state, sbox) {
+ for(var i = 0; i < 16; i++)
+ state[i] = sbox[state[i]];
+}
+
+function AES_AddRoundKey(state, rkey) {
+ for(var i = 0; i < 16; i++)
+ state[i] ^= rkey[i];
+}
+
+function AES_ShiftRows(state, shifttab) {
+ var h = new Array().concat(state);
+ for(var i = 0; i < 16; i++)
+ state[i] = h[shifttab[i]];
+}
+
+function AES_MixColumns(state) {
+ for(var i = 0; i < 16; i += 4) {
+ var s0 = state[i + 0], s1 = state[i + 1];
+ var s2 = state[i + 2], s3 = state[i + 3];
+ var h = s0 ^ s1 ^ s2 ^ s3;
+ state[i + 0] ^= h ^ AES_xtime[s0 ^ s1];
+ state[i + 1] ^= h ^ AES_xtime[s1 ^ s2];
+ state[i + 2] ^= h ^ AES_xtime[s2 ^ s3];
+ state[i + 3] ^= h ^ AES_xtime[s3 ^ s0];
+ }
+}
+
+function AES_MixColumns_Inv(state) {
+ for(var i = 0; i < 16; i += 4) {
+ var s0 = state[i + 0], s1 = state[i + 1];
+ var s2 = state[i + 2], s3 = state[i + 3];
+ var h = s0 ^ s1 ^ s2 ^ s3;
+ var xh = AES_xtime[h];
+ var h1 = AES_xtime[AES_xtime[xh ^ s0 ^ s2]] ^ h;
+ var h2 = AES_xtime[AES_xtime[xh ^ s1 ^ s3]] ^ h;
+ state[i + 0] ^= h1 ^ AES_xtime[s0 ^ s1];
+ state[i + 1] ^= h2 ^ AES_xtime[s1 ^ s2];
+ state[i + 2] ^= h1 ^ AES_xtime[s2 ^ s3];
+ state[i + 3] ^= h2 ^ AES_xtime[s3 ^ s0];
+ }
+}
+
+function bin2String (array) {
+ var result = "";
+ for (var i = 0; i < array.length; i++) {
+ result += String.fromCharCode(parseInt(array[i], 2));
+ }
+ return result;
+}
+
+function string2Bin (str) {
+ var result = [];
+ for (var i = 0; i < str.length; i++) {
+ result.push(str.charCodeAt(i));
+ }
+ while ((result.length % 16))
+ result.push(0);
+ return result;
+}
+
+function bin2String (array) {
+ return String.fromCharCode.apply(String, array);
+}
+
+// http://osama-oransa.blogspot.fr/2012/03/using-aes-encrypting-in-java-script.html
+function AES(a) {
+ this.init = function (myKey){
+ AES_Init();
+ var key = string2Bin(myKey);
+ AES_ExpandKey(key);
+ return key;
+ }
+
+ this.encrypt = function ( inputStr,key ) {
+ var block = string2Bin(inputStr);
+ AES_Encrypt(block, key);
+ var data=bin2String(block);
+ return data;
+ }
+
+ this.decrypt = function ( inputStr,key ) {
+ block = string2Bin(inputStr);
+ AES_Decrypt(block, key);
+ var data=bin2String(block);
+ return data;
+ }
+
+ this.encryptLongString = function( myString,key ) {
+ if(myString.length>16){
+ var data='';
+ for(var i=0;i16){
+ var data='';
+ for(var i=0;i