diff --git a/authorizer.php b/authorizer.php index 0b623b38..cbd5c319 100644 --- a/authorizer.php +++ b/authorizer.php @@ -36,6 +36,8 @@ require_once __DIR__ . '/src/authorizer/class-authentication.php'; require_once __DIR__ . '/src/authorizer/class-authorization.php'; require_once __DIR__ . '/src/authorizer/class-login-form.php'; +require_once __DIR__ . '/src/authorizer/class-save-secure.php'; + require_once __DIR__ . '/src/authorizer/class-dashboard-widget.php'; require_once __DIR__ . '/src/authorizer/class-ajax-endpoints.php'; require_once __DIR__ . '/src/authorizer/class-sync-userdata.php'; diff --git a/src/authorizer/class-authentication.php b/src/authorizer/class-authentication.php index d6ae401e..f39f4871 100644 --- a/src/authorizer/class-authentication.php +++ b/src/authorizer/class-authentication.php @@ -12,6 +12,7 @@ use Authorizer\Helper; use Authorizer\Options; use Authorizer\Authorization; +use Authorizer\Save_Secure; /** * Implements the authentication (is user who they say they are?) features of @@ -137,6 +138,7 @@ public function custom_authenticate( $user, $username, $password ) { $externally_authenticated_emails = array(); $authenticated_by = ''; $result = null; + $encrypted_token = ''; // Try OAuth2 authentication if it's enabled and we don't have a // successful login yet. @@ -153,6 +155,10 @@ public function custom_authenticate( $user, $username, $password ) { $externally_authenticated_emails[] = $result['email']; } $authenticated_by = $result['authenticated_by']; + + if (isset($result['encrypted_token'])){ + $encrypted_token = $result['encrypted_token']; + } } } @@ -294,6 +300,11 @@ public function custom_authenticate( $user, $username, $password ) { $user = $result; } + if ($encrypted_token != ''){ + //Save the Access Token in user_meta for later use, f.e in other Plugins + update_user_meta( $user->ID, 'encrypted_token', $encrypted_token ); + } + // If we haven't exited yet, we have a valid/approved user, so authenticate them. return $user; } @@ -309,6 +320,9 @@ public function custom_authenticate( $user, $username, $password ) { * or null if not attempting an oauth2 login. */ protected function custom_authenticate_oauth2( $auth_settings ) { + $encrypted_token = ''; //Maybe the access token from oauth2 service, encrypted + + // Move on if oauth2 hasn't been requested here. // phpcs:ignore WordPress.Security.NonceVerification if ( empty( $_GET['external'] ) || 'oauth2' !== $_GET['external'] ) { @@ -585,6 +599,14 @@ function ( $entry ) { $token = $provider->getAccessToken( 'authorization_code', array( 'code' => $_REQUEST['code'], ) ); + + $token_json_prepared = $token->jsonSerialize(); + $token_json = json_encode($token_json_prepared); + + $save_secure = new Save_Secure; + $encrypted_token = $save_secure->encrypt($token_json); + + } catch ( \Exception $e ) { // Failed to get token; try again from the beginning. $auth_url = $provider->getAuthorizationUrl( @@ -726,6 +748,7 @@ function ( $entry ) { 'authenticated_by' => 'oauth2', 'oauth2_provider' => $auth_settings['oauth2_provider'], 'oauth2_attributes' => $attributes, + 'encrypted_token' => $encrypted_token, ); } @@ -1496,6 +1519,11 @@ public function pre_logout() { if ( empty( self::$authenticated_by ) && ! empty( $_REQUEST['external'] ) ) { self::$authenticated_by = $_REQUEST['external']; } + + $user_id = get_current_user_id(); + //Delete token from usermeta + delete_user_meta( $user_id, 'encrypted_token'); + } /** diff --git a/src/authorizer/class-save-secure.php b/src/authorizer/class-save-secure.php new file mode 100644 index 00000000..2d04a0b9 --- /dev/null +++ b/src/authorizer/class-save-secure.php @@ -0,0 +1,99 @@ +key = $this->get_default_key(); + $this->salt = $this->get_default_salt(); + } + + // encrypt and decrypt methods omitted for readability. + + private function get_default_key() + { + + if (defined('LOGGED_IN_KEY') && '' !== LOGGED_IN_KEY) { + return LOGGED_IN_KEY; + } + + // If this is reached, you're either not on a live site or have a serious security issue. + return 'no-secret-key'; + } + + private function get_default_salt() + { + + if (defined('LOGGED_IN_SALT') && '' !== LOGGED_IN_SALT) { + return LOGGED_IN_SALT; + } + + // If this is reached, you're either not on a live site or have a serious security issue. + return 'no-secret-salt'; + } + + + /** + * Encypts a value for storing in database + */ + public function encrypt($value) + { + if (!extension_loaded('openssl')) { + return $value; + } + + $method = 'aes-256-ctr'; + $ivlen = openssl_cipher_iv_length($method); + $iv = openssl_random_pseudo_bytes($ivlen); + + $raw_value = openssl_encrypt($value . $this->salt, $method, $this->key, 0, $iv); + if (!$raw_value) { + return false; + } + + return base64_encode($iv . $raw_value); + } + + + /** + * Decrypts a value + */ + public function decrypt($raw_value) + { + if (!extension_loaded('openssl')) { + return $raw_value; + } + + $raw_value = base64_decode($raw_value, true); + + $method = 'aes-256-ctr'; + $ivlen = openssl_cipher_iv_length($method); + $iv = substr($raw_value, 0, $ivlen); + + $raw_value = substr($raw_value, $ivlen); + + $value = openssl_decrypt($raw_value, $method, $this->key, 0, $iv); + if (!$value || substr($value, -strlen($this->salt)) !== $this->salt) { + return false; + } + + return substr($value, 0, -strlen($this->salt)); + } +}