1
0
Fork 0
mirror of https://github.com/seiichiro0185/sailotp.git synced 2024-11-22 07:39:42 +00:00

Merge branch 'feat-cleanup' into develop

This commit is contained in:
seiichiro 2014-01-06 20:10:16 +01:00
commit 12cf6106a5
10 changed files with 386 additions and 301 deletions

26
COPYING Normal file
View file

@ -0,0 +1,26 @@
Copyright (c) 2013, Stefan Brand <seiichiro@seiichiro0185.org>
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
3. The names of the contributors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

36
README.md Normal file
View file

@ -0,0 +1,36 @@
# SailOTP
SailOTP is a Sailfish Implementation of the Google-Authenticator algorithm,
also known as Timebased One Time Pad (TOPT) as described in RFC 6238. A growing
number of sites uses this algorithm for two-factor-authentication, including
Github, Linode and several Google services.
At the moment the App is quite basic. One can add new OTP-entries using the
pulley-menu. The main view of the app will show a List off all entries and
their current One-Time-Tokens. The entries will be regenerated every 30 seconds, the remaining time for the current tokens is shown through a progress bar at the top of the app. An entry can be deleted by long-pressing on it.
## Known Limitations
At the moment the only way to insert new entries into the app is to insert the
title and secret key by hand. It's not possible to use the QR-Codes some sites
provide directly.
## Contact and Issues
If you find any bugs or want to suggest a feature, feel free to use Githubs
Issues feature.
## License
SailOTP is licensed under a 3-Clause BSD-License. See COPYING for details.
## Accnowledgements
SailOTP uses the SHA-1 and HMAC-Implementation from
<a href="https://github.com/Caligatio/jsSHA" target="_blank">https://github.com/Caligatio/jsSHA</a>
The implementation of the TOTP-algorithm was inspired by:
<a href="http://blog.tinisles.com/2011/10/google-authenticator-one-time-password-algorithm-in-javascript/" target="_blank">http://blog.tinisles.com/2011/10/google-authenticator-one-time-password-algorithm-in-javascript/</a>

View file

@ -30,8 +30,10 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
// Define the Layout of the Active Cover
CoverBackground {
// Show the SailOTP Logo
Image {
id: logo
source: "../sailotp.png"
@ -40,6 +42,7 @@ CoverBackground {
anchors.topMargin: 48
}
// Show the Application Name
Label {
id: label
anchors.centerIn: parent

View file

@ -29,12 +29,15 @@
.import "./sha.js" as SHA
// Helper Functions
// *** Helper Functions *** //
// Decimal to HEX
function dec2hex(s) { return (s < 15.5 ? '0' : '') + Math.round(s).toString(16); }
// HEX to Decimal
function hex2dec(s) { return parseInt(s, 16); }
// Convert Base32-secret to HEX Value
function base32tohex(base32) {
var base32chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
var bits = "";
@ -50,9 +53,9 @@ function base32tohex(base32) {
hex = hex + parseInt(chunk, 2).toString(16) ;
}
return hex;
}
// Pad Strings to given length
function leftpad(str, len, pad) {
if (len + 1 >= str.length) {
str = Array(len + 1 - str.length).join(pad) + str;
@ -60,18 +63,28 @@ function leftpad(str, len, pad) {
return str;
}
// *** Main Function *** //
// Calculate an OTP-Value from the given secret
// Parameter is the secret key in Base32-notation
function calcOTP(secret) {
// Convert the key to HEX
var key = base32tohex(secret);
// Get current Time in UNIX Timestamp format (Seconds since 01.01.1970 00:00 UTC)
var epoch = Math.round(new Date().getTime() / 1000.0);
// Get last full 30 / 60 Seconds and convert to HEX
var time = leftpad(dec2hex(Math.floor(epoch / 30)), 16, '0');
// Calculate the SHA-1 HMAC Value from time and key
var hmacObj = new SHA.jsSHA(time, 'HEX');
var hmac = hmacObj.getHMAC(key, 'HEX', 'SHA-1', "HEX");
// Finally convert the HMAC-Value to the corresponding 6-digit token
var offset = hex2dec(hmac.substring(hmac.length - 1));
var otp = (hex2dec(hmac.substr(offset * 2, 8)) & hex2dec('7fffffff')) + '';
otp = (otp).substr(otp.length - 6, 6);
// return the calculated token
return otp;
}

View file

@ -30,16 +30,15 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
// Define the Layout of the About Page
Page {
id: aboutPage
Image {
id: logo
source: "../sailotp.png"
anchors.horizontalCenter: parent.horizontalCenter
y: 200
}
Label {
id: name
anchors.horizontalCenter: parent.horizontalCenter
@ -81,5 +80,4 @@ Page {
text: "SailOTP uses the SHA-1 Implementation<br />from http://caligatio.github.io/jsSHA/"
color: "white"
}
}

View file

@ -30,11 +30,13 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
import "../lib/storage.js" as DB
import "../lib/storage.js" as DB // Import the storage library for Config-Access
// Define Layout of the Add OTP Dialog
Dialog {
id: addOTP
// We get the Object of the parent page on call to refresh it after adding a new Entry
property QtObject parentPage: null
SilicaFlickable {
@ -48,7 +50,6 @@ Dialog {
DialogHeader {
acceptText: "Add"
}
TextField {
id: otpLabel
width: parent.width
@ -57,7 +58,6 @@ Dialog {
focus: true
horizontalAlignment: TextInput.AlignLeft
}
TextField {
id: otpSecret
width: parent.width
@ -69,13 +69,16 @@ Dialog {
}
}
// Save if page is Left with Add
onDone: {
// Some basic Input Check, we need both Values to work
if (otpLabel.text != "" && otpSecret.text != "") {
// Save the entry to the Config DB
DB.addOTP(otpLabel.text, otpSecret.text);
// Refresh the main Page
parentPage.refreshOTPList();
}
}
}

View file

@ -40,6 +40,7 @@ Page {
id: otpListModel
}
// This holds the time of the last update of the page as Unix Timestamp (in Milliseconds)
property double lastUpdated: null
// Add an entry to the list
@ -56,10 +57,13 @@ Page {
// Calculate new OTPs for every entry
function refreshOTPValues() {
// get seconds from current Date
var curDate = new Date();
var seconds = curDate.getSeconds();
// Iterate over all List entries
for (var i=0; i<otpListModel.count; i++) {
// Only update on full 30 / 60 Seconds or if last run of the Functions is more than 2s in the past (e.g. app was in background)
if (otpListModel.get(i).otp == "" || seconds == 30 || seconds == 0 || (curDate.getTime() - lastUpdated > 2000)) {
var curOTP = OTP.calcOTP(otpListModel.get(i).secret)
otpListModel.setProperty(i, "otp", curOTP);
@ -67,15 +71,16 @@ Page {
}
}
// Update the Progressbar
updateProgress.value = 29 - (seconds % 30)
// Set lastUpdate property
lastUpdated = curDate.getTime();
}
Timer {
interval: 1000
running: Qt.application.active
running: Qt.application.active // Timer only runs when App is active
repeat: true
onTriggered: refreshOTPValues();
}
@ -125,6 +130,7 @@ Page {
contentHeight: Theme.itemSizeMedium
function remove() {
// Show 5s countdown, then delete from DB and List
remorseAction("Deleting", function() { DB.removeOTP(title, secret); otpListModel.remove(index) })
}
@ -162,7 +168,9 @@ Page {
VerticalScrollDecorator{}
Component.onCompleted: {
// Initialize DB (create tables etc..)
DB.initialize();
// Load list of OTP-Entries
refreshOTPList();
}
}

View file

@ -1,32 +1,31 @@
/*
Copyright (C) 2013 Jolla Ltd.
Contact: Thomas Perl <thomas.perl@jollamobile.com>
All rights reserved.
You may use this file under the terms of BSD license as follows:
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Jolla Ltd nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
* Copyright (c) 2013, Stefan Brand <seiichiro@seiichiro0185.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. The names of the contributors may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef QT_QML_DEBUG
#include <QtQuick>
@ -34,7 +33,6 @@
#include <sailfishapp.h>
int main(int argc, char *argv[])
{
return SailfishApp::main(argc, argv);