Changeset View
Changeset View
Standalone View
Standalone View
src/include/Kolab2FA/Driver/TOTP.php
Show First 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | public function init($config) | ||||
'type' => 'text', | 'type' => 'text', | ||||
'private' => true, | 'private' => true, | ||||
'label' => 'secret', | 'label' => 'secret', | ||||
'generator' => 'generate_secret', | 'generator' => 'generate_secret', | ||||
), | ), | ||||
); | ); | ||||
// copy config options | // copy config options | ||||
$this->backend = new \Kolab2FA\OTP\TOTP(); | $this->backend = \OTPHP\TOTP::create( | ||||
$this->backend | null, | ||||
->setDigits($this->config['digits']) | $this->config['interval'], | ||||
->setInterval($this->config['interval']) | $this->config['digest'], | ||||
->setDigest($this->config['digest']) | $this->config['digits'] | ||||
->setIssuer($this->config['issuer']) | ); | ||||
->setIssuerIncludedAsParameter(true); | |||||
$this->backend->setIssuer($this->config['issuer']); | |||||
$this->backend->setIssuerIncludedAsParameter(true); | |||||
} | } | ||||
/** | /** | ||||
* | * | ||||
*/ | */ | ||||
public function verify($code, $timestamp = null) | public function verify($code, $timestamp = null) | ||||
{ | { | ||||
// get my secret from the user storage | // get my secret from the user storage | ||||
$secret = $this->get('secret'); | $secret = $this->get('secret'); | ||||
if (!strlen($secret)) { | if (!strlen($secret)) { | ||||
// LOG: "no secret set for user $this->username" | // LOG: "no secret set for user $this->username" | ||||
// rcube::console("VERIFY TOTP: no secret set for user $this->username"); | // rcube::console("VERIFY TOTP: no secret set for user $this->username"); | ||||
return false; | return false; | ||||
} | } | ||||
$this->backend->setLabel($this->username)->setSecret($secret); | $this->backend->setLabel($this->username); | ||||
$this->backend->setParameter('secret', $secret); | |||||
// PHP gets a string, but we're comparing integers. | // Pass a window to indicate the maximum timeslip between client (device) and server. | ||||
$code = (int)$code; | $pass = $this->backend->verify((string) $code, $timestamp, 150); | ||||
//$code = (string) $code; | |||||
// Pass a window to indicate the maximum timeslip between client (mobile | |||||
// device) and server. | |||||
$pass = $this->backend->verify($code, $timestamp, 150); | |||||
// try all codes from $timestamp till now | // try all codes from $timestamp till now | ||||
if (!$pass && $timestamp) { | if (!$pass && $timestamp) { | ||||
$now = time(); | $now = time(); | ||||
while (!$pass && $timestamp < $now) { | while (!$pass && $timestamp < $now) { | ||||
$pass = $code === $this->backend->at($timestamp); | $pass = $code === $this->backend->at($timestamp); | ||||
$timestamp += $this->config['interval']; | $timestamp += $this->config['interval']; | ||||
} | } | ||||
Show All 10 Lines | class TOTP extends Base | ||||
{ | { | ||||
// get my secret from the user storage | // get my secret from the user storage | ||||
$secret = $this->get('secret'); | $secret = $this->get('secret'); | ||||
if (!strlen($secret)) { | if (!strlen($secret)) { | ||||
return; | return; | ||||
} | } | ||||
$this->backend->setLabel($this->username)->setSecret($secret); | $this->backend->setLabel($this->username); | ||||
$this->backend->setParameter('secret', $secret); | |||||
return $this->backend->at(time()); | return $this->backend->at(time()); | ||||
} | } | ||||
/** | /** | ||||
* | * | ||||
*/ | */ | ||||
public function get_provisioning_uri() | public function get_provisioning_uri() | ||||
{ | { | ||||
// rcube::console('PROV', $this->secret); | // rcube::console('PROV', $this->secret); | ||||
if (!$this->secret) { | if (!$this->secret) { | ||||
// generate new secret and store it | // generate new secret and store it | ||||
$this->set('secret', $this->get('secret', true)); | $this->set('secret', $this->get('secret', true)); | ||||
$this->set('created', $this->get('created', true)); | $this->set('created', $this->get('created', true)); | ||||
// rcube::console('PROV2', $this->secret); | // rcube::console('PROV2', $this->secret); | ||||
$this->commit(); | $this->commit(); | ||||
} | } | ||||
// TODO: deny call if already active? | // TODO: deny call if already active? | ||||
$this->backend->setLabel($this->username)->setSecret($this->secret); | $this->backend->setLabel($this->username); | ||||
$this->backend->setParameter('secret', $secret); | |||||
return $this->backend->getProvisioningUri(); | return $this->backend->getProvisioningUri(); | ||||
} | } | ||||
} | } |