X-Git-Url: https://scripts.mit.edu/gitweb/autoinstallsdev/mediawiki.git/blobdiff_plain/19e297c21b10b1b8a3acad5e73fc71dcb35db44a..6932310fd58ebef145fa01eb76edf7150284d8ea:/includes/session/Token.php diff --git a/includes/session/Token.php b/includes/session/Token.php new file mode 100644 index 00000000..14d239d5 --- /dev/null +++ b/includes/session/Token.php @@ -0,0 +1,125 @@ +secret = $secret; + $this->salt = $salt; + $this->new = $new; + } + + /** + * Decode the timestamp from a token string + * + * Does not validate the token beyond the syntactic checks necessary to + * be able to extract the timestamp. + * + * @param string $token + * @return int|null + */ + public static function getTimestamp( $token ) { + $suffixLen = strlen( self::SUFFIX ); + $len = strlen( $token ); + if ( $len <= 32 + $suffixLen || + substr( $token, -$suffixLen ) !== self::SUFFIX || + strspn( $token, '0123456789abcdef' ) + $suffixLen !== $len + ) { + return null; + } + + return hexdec( substr( $token, 32, -$suffixLen ) ); + } + + /** + * Get the string representation of the token at a timestamp + * @param int $timestamp + * @return string + */ + protected function toStringAtTimestamp( $timestamp ) { + return hash_hmac( 'md5', $timestamp . $this->salt, $this->secret, false ) . + dechex( $timestamp ) . + self::SUFFIX; + } + + /** + * Get the string representation of the token + * @return string + */ + public function toString() { + return $this->toStringAtTimestamp( wfTimestamp() ); + } + + public function __toString() { + return $this->toString(); + } + + /** + * Test if the token-string matches this token + * @param string $userToken + * @param int|null $maxAge Return false if $userToken is older than this many seconds + * @return bool + */ + public function match( $userToken, $maxAge = null ) { + $timestamp = self::getTimestamp( $userToken ); + if ( $timestamp === null ) { + return false; + } + if ( $maxAge !== null && $timestamp < wfTimestamp() - $maxAge ) { + // Expired token + return false; + } + + $sessionToken = $this->toStringAtTimestamp( $timestamp ); + return hash_equals( $sessionToken, $userToken ); + } + + /** + * Indicate whether this token was just created + * @return bool + */ + public function wasNew() { + return $this->new; + } + +}