mirror of
https://github.com/itflow-org/itflow
synced 2026-03-04 21:04:50 +00:00
Combine base32static.php and rfc6238.php into 1 file called totp.php and place it into the functions folder
This commit is contained in:
2
ajax.php
2
ajax.php
@@ -9,7 +9,7 @@
|
|||||||
require_once "config.php";
|
require_once "config.php";
|
||||||
require_once "functions.php";
|
require_once "functions.php";
|
||||||
require_once "check_login.php";
|
require_once "check_login.php";
|
||||||
require_once "includes/rfc6238.php";
|
require_once "includes/totp.php";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fetches SSL certificates from remote hosts & returns the relevant info (issuer, expiry, public key)
|
* Fetches SSL certificates from remote hosts & returns the relevant info (issuer, expiry, public key)
|
||||||
|
|||||||
@@ -1,6 +1,106 @@
|
|||||||
<?php
|
<?php
|
||||||
// http://www.faqs.org/rfcs/rfc6238.html
|
|
||||||
require_once(dirname(__FILE__).'/base32static.php');
|
//TOTP
|
||||||
|
//simple PHP implementation of a Time-based One-Time Password (TOTP) authentication mechanism (as described in RFC 6238). It uses HMAC-SHA1 with a time-based counter (stepping in 30-second intervals by default) to generate and verify 6-digit codes, much like Google Authenticator or other 2FA apps.
|
||||||
|
|
||||||
|
//base32static
|
||||||
|
/**
|
||||||
|
* Encode in Base32 based on RFC 4648.
|
||||||
|
* Requires 20% more space than base64
|
||||||
|
* Great for case-insensitive filesystems like Windows and URL's (except for = char which can be excluded using the pad option for urls)
|
||||||
|
*
|
||||||
|
* @package default
|
||||||
|
* @author Bryan Ruiz
|
||||||
|
**/
|
||||||
|
class Base32Static {
|
||||||
|
private static $map = array(
|
||||||
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 7
|
||||||
|
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 15
|
||||||
|
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 23
|
||||||
|
'Y', 'Z', '2', '3', '4', '5', '6', '7', // 31
|
||||||
|
'=' // padding character
|
||||||
|
);
|
||||||
|
|
||||||
|
private static $flippedMap = array(
|
||||||
|
'A'=>'0', 'B'=>'1', 'C'=>'2', 'D'=>'3', 'E'=>'4', 'F'=>'5', 'G'=>'6', 'H'=>'7',
|
||||||
|
'I'=>'8', 'J'=>'9', 'K'=>'10', 'L'=>'11', 'M'=>'12', 'N'=>'13', 'O'=>'14', 'P'=>'15',
|
||||||
|
'Q'=>'16', 'R'=>'17', 'S'=>'18', 'T'=>'19', 'U'=>'20', 'V'=>'21', 'W'=>'22', 'X'=>'23',
|
||||||
|
'Y'=>'24', 'Z'=>'25', '2'=>'26', '3'=>'27', '4'=>'28', '5'=>'29', '6'=>'30', '7'=>'31'
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use padding false when encoding for urls
|
||||||
|
*
|
||||||
|
* @return base32 encoded string
|
||||||
|
* @author Bryan Ruiz
|
||||||
|
**/
|
||||||
|
public static function encode($input, $padding = true) {
|
||||||
|
if (empty($input)) return "";
|
||||||
|
|
||||||
|
$input = str_split($input);
|
||||||
|
$binaryString = "";
|
||||||
|
|
||||||
|
for ($i = 0; $i < count($input); $i++) {
|
||||||
|
$binaryString .= str_pad(base_convert(ord($input[$i]), 10, 2), 8, '0', STR_PAD_LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
$fiveBitBinaryArray = str_split($binaryString, 5);
|
||||||
|
$base32 = "";
|
||||||
|
$i=0;
|
||||||
|
|
||||||
|
while($i < count($fiveBitBinaryArray)) {
|
||||||
|
$base32 .= self::$map[base_convert(str_pad($fiveBitBinaryArray[$i], 5, '0'), 2, 10)];
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($padding && ($x = strlen($binaryString) % 40) != 0) {
|
||||||
|
if ($x == 8) $base32 .= str_repeat(self::$map[32], 6);
|
||||||
|
else if ($x == 16) $base32 .= str_repeat(self::$map[32], 4);
|
||||||
|
else if ($x == 24) $base32 .= str_repeat(self::$map[32], 3);
|
||||||
|
else if ($x == 32) $base32 .= self::$map[32];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $base32;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function decode($input) {
|
||||||
|
if (empty($input)) return;
|
||||||
|
|
||||||
|
$paddingCharCount = substr_count($input, self::$map[32]);
|
||||||
|
$allowedValues = array(6,4,3,1,0);
|
||||||
|
|
||||||
|
if (!in_array($paddingCharCount, $allowedValues)) return false;
|
||||||
|
|
||||||
|
for ($i=0; $i<4; $i++){
|
||||||
|
if ($paddingCharCount == $allowedValues[$i] &&
|
||||||
|
substr($input, -($allowedValues[$i])) != str_repeat(self::$map[32], $allowedValues[$i])) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$input = str_replace('=', '', $input);
|
||||||
|
$input = str_split($input);
|
||||||
|
$binaryString = "";
|
||||||
|
|
||||||
|
for ($i=0; $i < count($input); $i = $i+8) {
|
||||||
|
$x = "";
|
||||||
|
|
||||||
|
if (!in_array($input[$i], self::$map)) return false;
|
||||||
|
|
||||||
|
for ($j=0; $j < 8; $j++) {
|
||||||
|
$x .= str_pad(base_convert(@self::$flippedMap[@$input[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
$eightBits = str_split($x, 8);
|
||||||
|
|
||||||
|
for ($z = 0; $z < count($eightBits); $z++) {
|
||||||
|
$binaryString .= (($y = chr(base_convert($eightBits[$z], 2, 10))) || ord($y) == 48) ? $y:"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $binaryString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//http://www.faqs.org/rfcs/rfc6238.html
|
||||||
class TokenAuth6238 {
|
class TokenAuth6238 {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
172
global.css
172
global.css
@@ -1,172 +0,0 @@
|
|||||||
/* Variables */
|
|
||||||
* {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
|
|
||||||
font-size: 16px;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-content: center;
|
|
||||||
height: 100vh;
|
|
||||||
width: 100vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
form {
|
|
||||||
width: 30vw;
|
|
||||||
min-width: 500px;
|
|
||||||
align-self: center;
|
|
||||||
box-shadow: 0px 0px 0px 0.5px rgba(50, 50, 93, 0.1),
|
|
||||||
0px 2px 5px 0px rgba(50, 50, 93, 0.1), 0px 1px 1.5px 0px rgba(0, 0, 0, 0.07);
|
|
||||||
border-radius: 7px;
|
|
||||||
padding: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
border-radius: 6px;
|
|
||||||
margin-bottom: 6px;
|
|
||||||
padding: 12px;
|
|
||||||
border: 1px solid rgba(50, 50, 93, 0.1);
|
|
||||||
height: 44px;
|
|
||||||
font-size: 16px;
|
|
||||||
width: 100%;
|
|
||||||
background: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-message {
|
|
||||||
line-height: 22px;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-message a {
|
|
||||||
color: rgb(89, 111, 214);
|
|
||||||
font-weight: 600;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#card-error {
|
|
||||||
color: rgb(105, 115, 134);
|
|
||||||
text-align: left;
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 17px;
|
|
||||||
margin-top: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#card-element {
|
|
||||||
border-radius: 4px 4px 0 0 ;
|
|
||||||
padding: 12px;
|
|
||||||
border: 1px solid rgba(50, 50, 93, 0.1);
|
|
||||||
height: 44px;
|
|
||||||
width: 100%;
|
|
||||||
background: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
#payment-request-button {
|
|
||||||
margin-bottom: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Buttons and links */
|
|
||||||
button {
|
|
||||||
background: #5469d4;
|
|
||||||
color: #ffffff;
|
|
||||||
font-family: Courier, monospace;
|
|
||||||
border-radius: 0 0 4px 4px;
|
|
||||||
border: 0;
|
|
||||||
padding: 12px 16px;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 600;
|
|
||||||
cursor: pointer;
|
|
||||||
display: block;
|
|
||||||
transition: all 0.2s ease;
|
|
||||||
box-shadow: 0px 4px 5.5px 0px rgba(0, 0, 0, 0.07);
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
button:hover {
|
|
||||||
filter: contrast(115%);
|
|
||||||
}
|
|
||||||
button:disabled {
|
|
||||||
opacity: 0.5;
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* spinner/processing state, errors */
|
|
||||||
.spinner,
|
|
||||||
.spinner:before,
|
|
||||||
.spinner:after {
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
.spinner {
|
|
||||||
color: #ffffff;
|
|
||||||
font-size: 22px;
|
|
||||||
text-indent: -99999px;
|
|
||||||
margin: 0px auto;
|
|
||||||
position: relative;
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
box-shadow: inset 0 0 0 2px;
|
|
||||||
-webkit-transform: translateZ(0);
|
|
||||||
-ms-transform: translateZ(0);
|
|
||||||
transform: translateZ(0);
|
|
||||||
}
|
|
||||||
.spinner:before,
|
|
||||||
.spinner:after {
|
|
||||||
position: absolute;
|
|
||||||
content: "";
|
|
||||||
}
|
|
||||||
.spinner:before {
|
|
||||||
width: 10.4px;
|
|
||||||
height: 20.4px;
|
|
||||||
background: #5469d4;
|
|
||||||
border-radius: 20.4px 0 0 20.4px;
|
|
||||||
top: -0.2px;
|
|
||||||
left: -0.2px;
|
|
||||||
-webkit-transform-origin: 10.4px 10.2px;
|
|
||||||
transform-origin: 10.4px 10.2px;
|
|
||||||
-webkit-animation: loading 2s infinite ease 1.5s;
|
|
||||||
animation: loading 2s infinite ease 1.5s;
|
|
||||||
}
|
|
||||||
.spinner:after {
|
|
||||||
width: 10.4px;
|
|
||||||
height: 10.2px;
|
|
||||||
background: #5469d4;
|
|
||||||
border-radius: 0 10.2px 10.2px 0;
|
|
||||||
top: -0.1px;
|
|
||||||
left: 10.2px;
|
|
||||||
-webkit-transform-origin: 0px 10.2px;
|
|
||||||
transform-origin: 0px 10.2px;
|
|
||||||
-webkit-animation: loading 2s infinite ease;
|
|
||||||
animation: loading 2s infinite ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
@-webkit-keyframes loading {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(360deg);
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@keyframes loading {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(360deg);
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 600px) {
|
|
||||||
form {
|
|
||||||
width: 80vw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -11,7 +11,7 @@ require_once "../config.php";
|
|||||||
// Set Timezone
|
// Set Timezone
|
||||||
require_once "../inc_set_timezone.php";
|
require_once "../inc_set_timezone.php";
|
||||||
require_once "../functions.php";
|
require_once "../functions.php";
|
||||||
require_once "../includes/rfc6238.php";
|
require_once "../functions/totp.php";
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -1,96 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Encode in Base32 based on RFC 4648.
|
|
||||||
* Requires 20% more space than base64
|
|
||||||
* Great for case-insensitive filesystems like Windows and URL's (except for = char which can be excluded using the pad option for urls)
|
|
||||||
*
|
|
||||||
* @package default
|
|
||||||
* @author Bryan Ruiz
|
|
||||||
**/
|
|
||||||
class Base32Static {
|
|
||||||
private static $map = array(
|
|
||||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 7
|
|
||||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 15
|
|
||||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 23
|
|
||||||
'Y', 'Z', '2', '3', '4', '5', '6', '7', // 31
|
|
||||||
'=' // padding character
|
|
||||||
);
|
|
||||||
|
|
||||||
private static $flippedMap = array(
|
|
||||||
'A'=>'0', 'B'=>'1', 'C'=>'2', 'D'=>'3', 'E'=>'4', 'F'=>'5', 'G'=>'6', 'H'=>'7',
|
|
||||||
'I'=>'8', 'J'=>'9', 'K'=>'10', 'L'=>'11', 'M'=>'12', 'N'=>'13', 'O'=>'14', 'P'=>'15',
|
|
||||||
'Q'=>'16', 'R'=>'17', 'S'=>'18', 'T'=>'19', 'U'=>'20', 'V'=>'21', 'W'=>'22', 'X'=>'23',
|
|
||||||
'Y'=>'24', 'Z'=>'25', '2'=>'26', '3'=>'27', '4'=>'28', '5'=>'29', '6'=>'30', '7'=>'31'
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use padding false when encoding for urls
|
|
||||||
*
|
|
||||||
* @return base32 encoded string
|
|
||||||
* @author Bryan Ruiz
|
|
||||||
**/
|
|
||||||
public static function encode($input, $padding = true) {
|
|
||||||
if (empty($input)) return "";
|
|
||||||
|
|
||||||
$input = str_split($input);
|
|
||||||
$binaryString = "";
|
|
||||||
|
|
||||||
for ($i = 0; $i < count($input); $i++) {
|
|
||||||
$binaryString .= str_pad(base_convert(ord($input[$i]), 10, 2), 8, '0', STR_PAD_LEFT);
|
|
||||||
}
|
|
||||||
|
|
||||||
$fiveBitBinaryArray = str_split($binaryString, 5);
|
|
||||||
$base32 = "";
|
|
||||||
$i=0;
|
|
||||||
|
|
||||||
while($i < count($fiveBitBinaryArray)) {
|
|
||||||
$base32 .= self::$map[base_convert(str_pad($fiveBitBinaryArray[$i], 5, '0'), 2, 10)];
|
|
||||||
$i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($padding && ($x = strlen($binaryString) % 40) != 0) {
|
|
||||||
if ($x == 8) $base32 .= str_repeat(self::$map[32], 6);
|
|
||||||
else if ($x == 16) $base32 .= str_repeat(self::$map[32], 4);
|
|
||||||
else if ($x == 24) $base32 .= str_repeat(self::$map[32], 3);
|
|
||||||
else if ($x == 32) $base32 .= self::$map[32];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $base32;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function decode($input) {
|
|
||||||
if (empty($input)) return;
|
|
||||||
|
|
||||||
$paddingCharCount = substr_count($input, self::$map[32]);
|
|
||||||
$allowedValues = array(6,4,3,1,0);
|
|
||||||
|
|
||||||
if (!in_array($paddingCharCount, $allowedValues)) return false;
|
|
||||||
|
|
||||||
for ($i=0; $i<4; $i++){
|
|
||||||
if ($paddingCharCount == $allowedValues[$i] &&
|
|
||||||
substr($input, -($allowedValues[$i])) != str_repeat(self::$map[32], $allowedValues[$i])) return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$input = str_replace('=', '', $input);
|
|
||||||
$input = str_split($input);
|
|
||||||
$binaryString = "";
|
|
||||||
|
|
||||||
for ($i=0; $i < count($input); $i = $i+8) {
|
|
||||||
$x = "";
|
|
||||||
|
|
||||||
if (!in_array($input[$i], self::$map)) return false;
|
|
||||||
|
|
||||||
for ($j=0; $j < 8; $j++) {
|
|
||||||
$x .= str_pad(base_convert(@self::$flippedMap[@$input[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT);
|
|
||||||
}
|
|
||||||
|
|
||||||
$eightBits = str_split($x, 8);
|
|
||||||
|
|
||||||
for ($z = 0; $z < count($eightBits); $z++) {
|
|
||||||
$binaryString .= (($y = chr(base_convert($eightBits[$z], 2, 10))) || ord($y) == 48) ? $y:"";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $binaryString;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -21,7 +21,7 @@ if ($config_https_only && (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] !== 'o
|
|||||||
|
|
||||||
require_once "functions.php";
|
require_once "functions.php";
|
||||||
|
|
||||||
require_once "includes/rfc6238.php";
|
require_once "functions/totp.php";
|
||||||
|
|
||||||
|
|
||||||
// IP & User Agent for logging
|
// IP & User Agent for logging
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ if (isset($_POST['edit_your_user_preferences'])) {
|
|||||||
|
|
||||||
if (isset($_POST['verify'])) {
|
if (isset($_POST['verify'])) {
|
||||||
|
|
||||||
require_once "includes/rfc6238.php";
|
require_once "functions/totp.php";
|
||||||
|
|
||||||
$currentcode = intval($_POST['code']); //code to validate, for example received from device
|
$currentcode = intval($_POST['code']); //code to validate, for example received from device
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ $remember_token_count = mysqli_num_rows($sql_remember_tokens);
|
|||||||
<center>
|
<center>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once 'includes/rfc6238.php';
|
require_once 'includes/totp.php';
|
||||||
|
|
||||||
//Generate a base32 Key
|
//Generate a base32 Key
|
||||||
$secretkey = key32gen();
|
$secretkey = key32gen();
|
||||||
|
|||||||
Reference in New Issue
Block a user