/Authentication/src/filters/htpasswd/htpasswd_filter.php
PHP | 250 lines | 99 code | 14 blank | 137 comment | 11 complexity | 8385d02b4459bf9823da97cc72b939f7 MD5 | raw file
- <?php
- /**
- * File containing the ezcAuthenticationHtpasswdFilter class.
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
- * @filesource
- * @package Authentication
- * @version //autogen//
- */
- /**
- * Filter to authenticate against an Unix htpasswd file.
- *
- * It supports files created with the htpasswd command options
- * -m (MD5 encryption - different than the PHP md5() function)
- * -d (CRYPT encryption)
- * -s (SHA encryption)
- * -p (plain text)
- *
- * The encryption used for the password field in the file will be detected
- * automatically.
- *
- * The password property can be specified as plain text or in encrypted form,
- * depending on the option 'plain' in the ezcAuthenticationHtpasswdOptions object
- * used as options.
- *
- * Example:
- * <code>
- * $credentials = new ezcAuthenticationPasswordCredentials( 'jan.modaal', 'b1b3773a05c0ed0176787a4f1574ff0075f7521e' );
- * $authentication = new ezcAuthentication( $credentials );
- * $authentication->session = new ezcAuthenticationSession();
- * $authentication->addFilter( new ezcAuthenticationHtpasswdFilter( '/etc/htpasswd' ) );
- * // add other filters if needed
- * if ( !$authentication->run() )
- * {
- * // authentication did not succeed, so inform the user
- * $status = $authentication->getStatus();
- * $err = array(
- * 'ezcAuthenticationHtpasswdFilter' => array(
- * ezcAuthenticationHtpasswdFilter::STATUS_USERNAME_INCORRECT => 'Incorrect username',
- * ezcAuthenticationHtpasswdFilter::STATUS_PASSWORD_INCORRECT => 'Incorrect password'
- * )
- * );
- * foreach ( $status as $line )
- * {
- * list( $key, $value ) = each( $line );
- * echo $err[$key][$value] . "\n";
- * }
- * }
- * else
- * {
- * // authentication succeeded, so allow the user to see his content
- * }
- * </code>
- *
- * @property string $file
- * The path and file name of the htpasswd file to use.
- *
- * @package Authentication
- * @version //autogen//
- * @mainclass
- */
- class ezcAuthenticationHtpasswdFilter extends ezcAuthenticationFilter
- {
- /**
- * Username is not found in the htpasswd file.
- */
- const STATUS_USERNAME_INCORRECT = 1;
- /**
- * Password is incorrect.
- */
- const STATUS_PASSWORD_INCORRECT = 2;
- /**
- * Holds the properties of this class.
- *
- * @var array(string=>mixed)
- */
- private $properties = array();
- /**
- * Creates a new object of this class.
- *
- * @throws ezcBaseValueException
- * if the value provided is not correct for the property $file
- * @throws ezcBaseFileNotFoundException
- * if $file does not exist
- * @throws ezcBaseFilePermissionException
- * if $file cannot be opened for reading
- * @param string $file The path and file name of the htpasswd file to use
- * @param ezcAuthenticationHtpasswdOptions $options Options for this class
- */
- public function __construct( $file, ezcAuthenticationHtpasswdOptions $options = null )
- {
- $this->file = $file;
- $this->options = ( $options === null ) ? new ezcAuthenticationHtpasswdOptions() : $options;
- }
- /**
- * Sets the property $name to $value.
- *
- * @throws ezcBasePropertyNotFoundException
- * if the property $name does not exist
- * @throws ezcBaseValueException
- * if $value is not correct for the property $name
- * @throws ezcBaseFileNotFoundException
- * if the $value file does not exist
- * @throws ezcBaseFilePermissionException
- * if the $value file cannot be opened for reading
- * @param string $name The name of the property to set
- * @param mixed $value The new value of the property
- * @ignore
- */
- public function __set( $name, $value )
- {
- switch ( $name )
- {
- case 'file':
- if ( !is_string( $value ) )
- {
- throw new ezcBaseValueException( $name, $value, 'string' );
- }
- if ( !file_exists( $value ) )
- {
- throw new ezcBaseFileNotFoundException( $value );
- }
- if ( !is_readable( $value ) )
- {
- throw new ezcBaseFilePermissionException( $value, ezcBaseFileException::READ );
- }
- $this->properties[$name] = $value;
- break;
- default:
- throw new ezcBasePropertyNotFoundException( $name );
- }
- }
- /**
- * Returns the value of the property $name.
- *
- * @throws ezcBasePropertyNotFoundException
- * if the property $name does not exist
- * @param string $name The name of the property for which to return the value
- * @return mixed
- * @ignore
- */
- public function __get( $name )
- {
- switch ( $name )
- {
- case 'file':
- return $this->properties[$name];
- default:
- throw new ezcBasePropertyNotFoundException( $name );
- }
- }
- /**
- * Returns true if the property $name is set, otherwise false.
- *
- * @param string $name The name of the property to test if it is set
- * @return bool
- * @ignore
- */
- public function __isset( $name )
- {
- switch ( $name )
- {
- case 'file':
- return isset( $this->properties[$name] );
- default:
- return false;
- }
- }
- /**
- * Runs the filter and returns a status code when finished.
- *
- * @param ezcAuthenticationPasswordCredentials $credentials Authentication credentials
- * @return int
- */
- public function run( $credentials )
- {
- $fh = fopen( $this->file, 'r' );
- $found = false;
- while ( $line = fgets( $fh ) )
- {
- if ( substr( $line, 0, strlen( $credentials->id ) + 1 ) === $credentials->id . ':' )
- {
- $found = true;
- break;
- }
- }
- fclose( $fh );
- if ( $found )
- {
- $parts = explode( ':', $line );
- $hashFromFile = trim( $parts[1] );
- if ( substr( $hashFromFile, 0, 6 ) === '$apr1$' )
- {
- $password = ( $this->options->plain ) ? ezcAuthenticationMath::apr1( $credentials->password, $hashFromFile ) :
- '$apr1$' . $credentials->password;
- }
- elseif ( substr( $hashFromFile, 0, 5 ) === '{SHA}' )
- {
- $password = ( $this->options->plain ) ? '{SHA}' . base64_encode( pack( 'H40', sha1( $credentials->password ) ) ) :
- '{SHA}' . $credentials->password;
- }
- else
- {
- $password = ( $this->options->plain ) ? crypt( $credentials->password, $hashFromFile ) :
- $credentials->password;
- }
- if ( $password === $hashFromFile )
- {
- return self::STATUS_OK;
- }
- else
- {
- return self::STATUS_PASSWORD_INCORRECT;
- }
- }
- return self::STATUS_USERNAME_INCORRECT;
- }
- }
- ?>