File "sekura.php"

Path: /sekura/sekura.php
File size: 14.11 KB
MIME-type: text/x-php
Charset: utf-8

<?PHP
//  CHANGE ME --->
$db = mysql_connect('sql.domain.com', 'user', 'password');  // Connect to main database
mysql_select_db('table', $db);     // and main table
//  <--- CHANGE ME

$sql = "CREATE TABLE IF NOT EXISTS 'sekura' ('data' TEXT NOT NULL)";
mysql_query($sql);

if (isset($_POST["wn"])) {  // User added a new website via form + submit
    $data = $_POST["wn"]; // encrypted triplet: website name + ">" + url + "<" + password
    $sql = "INSERT INTO sekura VALUES ('".$data."')";
    $req = mysql_query($sql) or die(mysql_error());
}

// Connect to database to retrieve all values of website + password (still encrypted)
$sql = "SELECT data FROM sekura";
$req = mysql_query($sql) or die (mysql_error());
$tot = mysql_num_rows($req);
if ($tot) {    // protect against empty table
    for($i=0; $i < $tot-1; ++$i) { $data.='"'.mysql_result($req, $i, "data").'", '; }
    $data.='"'.mysql_result($req, $tot-1, "data").'"';
}
mysql_close();
?>

<html>

<head>
    <title>My sekura locker</title>
    <meta http-equiv=Content-Type content="text/html; charset=windows-1252">
    <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1">

    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" />
    <script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
    <script src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
    <script>function htc(){$('.ui-table-columntoggle-btn').hide()}</script>

    <style>
        // table customization:
        th{border-bottom:1px solid #d6d6d6;}
        tr:nth-child(even){background:rgba(233,233,233,0.75);}
        tr:nth-child(odd){background:rgba(255,255,255,0.75);}
        // to put input control and button on same line:
        .inline-form {}
        .inline-form .wrapper {float:left; width:100%;}
        .inline-form .wrapper .content {margin:0 100px 0 2px;  /* 0 RC 0 LC */ }
        .inline-form .right {float:left; width: 100px; /* RC */ margin-left:-100px; /* -RC */ margin-top:-3px;}
        .inline-form .footer{clear:left;}
        // restrict desktop page-width to 600px max:
        html {}
        @media only screen and (min-width:600px){
            .ui-page {
                background-image:url(seamless_sakura.jpg) !important;
                background-attachment:fixed;
                background-repeat:repeat;
                width:600px !important;
                margin:0 auto !important;
                position:relative !important;
                border-right:5px #666 outset !important;
                border-left:5px #666 outset !important;
            }
        }
        .ui-popup {
            background-image:url(seamless_sakura.jpg) !important;
            background-attachment:fixed;
            background-repeat:repeat;
            max-width: 500px !important;
        }
        .ui-header .ui-title { margin-right:10%; margin-left:10%; }
        .ui-page {
            background-image:url(seamless_sakura.jpg) !important;
            background-attachment:fixed;
            background-repeat:repeat;
        }
    </style>

    <script>
        var specials = "!@'#$%^&*()_+{}:|[];,./~";
        var lowercase = "abcdefghijklmnopqrstuvwxyz";
        var uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        var numbers = "0123456789";
        var BasilePwd;
        var data = [<?PHP echo $data ?>];

        function SetBasilePwd() {
            BasilePwd = document.getElementById("password").value;
            if (BasilePwd == "") { BasilePwd = String.fromCharCode(0); }
        }

        function BasileEncode(txt) {
            var res="";
            var ind=0;
            var tmp=0;
            for (var i=0; i < txt.length; i++) {
                tmp = (256 + txt.charCodeAt(i) + BasilePwd.charCodeAt(ind)) % 256;
                res += tmp.toString(16);
                ind = (ind + 1) % BasilePwd.length;
            }
            return res;
        }

        function BasileDecode(txt) {
            if (BasilePwd == String.fromCharCode(0)) return "&nbsp;";
            var res="";
            var ind=0;
            var tmp=0;
            for (var i=0; i < txt.length; i+=2) {
                tmp = (256 + parseInt(txt.substr(i,2), 16) - BasilePwd.charCodeAt(ind)) % 256;
                res += String.fromCharCode(tmp);
                ind = (ind + 1) % BasilePwd.length;
            }
            return res;
        }

        function Decode() {
            SetBasilePwd();
            var lbl="";
            var url="";
            var pwd="";
            var idx1=0;
            var idx2=0;
            for (var i=0; i < data.length; i++) {
                lbl = BasileDecode(data[i]);
                idx1 = lbl.indexOf(">");
                idx2 = lbl.indexOf("<");
                pwd = lbl.substring(idx2+1);
                url = lbl.substr(idx1+1,idx2-idx1-1);
                lbl = lbl.substr(0,idx1);
                document.getElementById("web"+i).innerHTML = "<a target='_blank' href='" + url + "'>" + lbl + "</a>";
                document.getElementById("pwd"+i).innerHTML = pwd;
            }
        }

        String.prototype.pick = function(min, max) {
            var n, chars = '';
            if (typeof max === 'undefined') { n = min; } else { n = min + Math.floor(Math.random() * (max - min)); }
            for (var i = 0; i < n; i++) { chars += this.charAt(Math.floor(Math.random() * this.length)); }
            return chars;
        }

        String.prototype.shuffle = function() {
            var array = this.split('');
            var tmp, current, top = array.length;
            if (top) while (--top) {
                current = Math.floor(Math.random() * (top + 1));
                tmp = array[current];
                array[current] = array[top];
                array[top] = tmp;
            }
            return array.join('');
        }

        function GenNewPass() {
            var strength = parseInt(document.getElementById("ps").value);
            var a = document.getElementById("cba").checked;
            var z = document.getElementById("cbz").checked;
            var n = document.getElementById("cbn").checked;
            var s = document.getElementById("cbs").checked;
            var all = "";
            if (s) all+=specials;
            if (a) all+=lowercase;
            if (z) all+=uppercase;
            if (n) all+=numbers;
            if (all == "") {
                alert("You must choose at least one category of characters");
            } else {
                var pwd = all.pick(strength, strength);
                pwd = pwd.shuffle();
                document.getElementById("gp").innerHTML = pwd;
            }
        }

        function validateForm() {
            var pwd1 = document.getElementById("password").value;
            var pwd2 = document.forms["formNew"]["pw"].value;
            // Do not accept empty or different pass phrases
            if (pwd1 == "" || pwd1 != pwd2) {
                alert("Pass phrases do not match, or are empty !");
                return false;
            }
            // Else, all is good --> encrypt value with Basile algo before returning 'true' to validate the submitting
            SetBasilePwd();
            var web = document.getElementById("wn").value;
            var url = document.getElementById("wu").value;
            var pwd = document.getElementById("gp").innerHTML;
            if (url.substr(0,4) != "http") url="http://"+url;
            document.getElementById("wn").value = BasileEncode(web + ">" + url + "<" + pwd);
            document.getElementById("pw").value = ""; // to prevent transmitting
            document.getElementById("ps").value = ""; // clear data to the server
            document.getElementById("wu").value = ""; // ...
            return true;
        }
    </script>

</head>

<body onload="htc(); GenNewPass();">

    <div data-role="page" id="sekura">

        <div data-role="popup" id="popupAbout" data-overlay-theme="a" class="ui-corner-all">
            <a href="#" data-rel="back" data-role="button" data-theme="a"
               data-icon="delete" data-iconpos="notext" class="ui-btn-right">Close
            </a>
            <div data-role="header" data-theme="a" class="ui-corner-top">
                <h3>About...</h3>
            </div><!-- /header -->
            <div data-role="content" data-theme="d" class="ui-corner-bottom ui-content">
                <p>The word "sekura" means <b>a safe</b> in Esperanto.</p>
                <p>The <b>sekura</b> software allows you to generate and store strong passwords for 
                your websites (amazon, eBay, etc.) very safely.<br>
                All the encryption/decryption is done on client side (on your PC) with 
                JavaScript. No deciphered data is ever stored on server side, all the data 
                in clear remains at all time on your PC, furthermore no clear data is <u>ever</u> 
                transmitted via the network. Any "man in the middle" attack is useless.</p>
                <p>Also, in opposition to all the big commercial websites, your master password is 
                <u>never</u> stored on any server, nor even locally! With <b>sekura</b> algorithm, 
                there is no way to test the validity of your password against the original one, 
                in other words the decrypted data is never tested for correctness. A hacker 
                can't use brute force to decrypt your data, since <u>all</u> and <u>any</u> 
                password will produce a "valid" result (no error will be thrown, just the data 
                will not be readable by a human... but a machine has no way to know).</p>
                <p>Finally, <b>sekura</b> is open source software and can be audited by anyone.</p>
            </div><!-- /content -->
        </div>

        <div data-role="popup" id="popupNew" data-overlay-theme="a" class="ui-corner-all">
            <a href="#" data-rel="back" data-role="button" data-theme="a"
               data-icon="delete" data-iconpos="notext" class="ui-btn-right">Close
            </a>
            <div data-role="header" data-theme="a" class="ui-corner-top">
                <h3>Add a new website</h3>
            </div><!-- /header -->
            <div data-role="content" data-theme="d" class="ui-corner-bottom ui-content">
                <form name="formNew" action="sekura.php" onsubmit="return validateForm()" method="post" data-ajax="false">
                    <label for="pw" class="ui-hidden-accessible">Confirm passphrase:</label>
                    <input type="password" name="pw" id="pw" value="" data-theme="b"
                       placeholder="First, confirm passphrase" data-clear-btn="true">
                    <p>Then, enter website name and URL:</p>
                    <label for="wn" class="ui-hidden-accessible">Website name:</label>
                    <input type="text" name="wn" id="wn" value="" placeholder="Website name" data-clear-btn="true">
                    <label for="wu" class="ui-hidden-accessible">Website URL:</label>
                    <input type="url" name="wu" id="wu" value="" placeholder="Website URL" data-clear-btn="true">
                    <label for="ps">Random password length:</label>
                    <input type="range" name="ps" id="ps" value="12" min="6" max="16" step="1" data-highlight="true">
                    <div data-role="controlgroup" data-type="horizontal" data-mini="true">
                        <input type="checkbox" id="cba" checked=""><label for="cba">a</label>
                        <input type="checkbox" id="cbz" checked=""><label for="cbz">A</label>
                        <input type="checkbox" id="cbn" checked=""><label for="cbn">1</label>
                        <input type="checkbox" id="cbs" checked=""><label for="cbs">$</label>
                        <input type="button" value="Generate" onclick="GenNewPass();">
                    </div>
                    <div name="gp" id="gp" class="ui-body ui-body-a ui-corner-all"
                      style="font-family:'Lucida Console',Monaco,monospace; font-size:15px;">
                    </div>
                    <input type="submit" data-theme="b" value="Save this new website">
                </form>
            </div><!-- /content -->
        </div>

        <div data-role="header" data-position="inline">
            <a href="#popupAbout" data-role="button" data-transition="slidedown"
               data-rel="popup" data-icon="info" data-position-to="window">About</a>
            <h1>My sekura locker</h1>
        </div>

        <div data-role="content">

            <!-- Passphrase and Decode button, on 1 line -->
            <div class="inline-form">
                <div class="wrapper">
                    <div class="content">
                        <input id="password" data-mini="true" type="password" placeholder="Enter your passphrase" data-clear-btn="true">
                    </div><!-- /content -->
                </div><!-- /wrapper -->
                <div class="right">
                    <button onclick="Decode()" data-icon="lock" data-inline="true" data-mini="true">Decode</button>
                </div><!-- /right -->
            </div><!-- /inline-form -->

            <!-- Add website button -->
            <div style="height:10px; margin-top:50px;"></div>
            <a href="#popupNew" data-role="button" data-rel="popup" data-position-to="window" data-transition="flow"
               data-icon="plus" data-inline="true" data-mini="true">Add a website + password</a>

            <!-- Table of websites + passwords -->
            <h4>Existing websites + passwords:</h4>
            <table data-role="table" class="ui-responsive ui-shadow" data-mode="columntoggle">
                <tbody>
                    <?PHP
                    for($i = 0; $i < $tot ; ++$i) {
                        echo "<tr>";
                        echo "<td id='web".($tot-$i-1)."'>&nbsp;</td>";
                        echo "<td id='pwd".($tot-$i-1)."' style='font-family:\"Lucida Console\", Monaco, monospace; font-size: 15px;'>&nbsp;</td>";
                        echo "</tr>";
                    }
                    echo "\n";
                    ?>
                </tbody>
            </table>

        </div><!-- /content -->
    </div><!-- /page -->

</body>

</html>