php with Suhosin patch

Hello everyone.

My application began to work not correctly after I transferred it to the server where php has suhosin patch (Apache/2.2.9 (Debian) PHP/5.2.6-1+lenny9 with Suhosin-Patch mod_ssl/2.2.9 OpenSSL/0.9.8g). Can this patch cause the preblems? And are there any recommendations for application configurations when using this patch?

Thanks.

On my development machine (OpenSuse) I have apache 2.2 with Suhosin Extension 0.9.32.1 and all works fine.

Can you explain more the "My application began to work not correctly"… do you get any error?

No, I don’t get any errors. I just can’t login. I enter my username and pass but get redirected to my index page.

Could be something with the code… you will need to check the suhosin logs to see if something is reported there…

You can try to create a new Yii webapp and check if there the login works just to be sure it’s something in your code and not Yii…

How can I check the suhosin logs?

Here is the suhosin configuration documentation with the logging options - http://www.hardened-php.net/suhosin/configuration.html#logging_configuration

It looks like my user logins but instantly gets logged out.

I don’t understand why this very application with this very code works Ok on one server but does not work on another.

Can you explain a bit more…

Did you try with a new Yii webapp like I suggested before?

Have you found something in the logs?

I just can’t find where suhosin logs are.

Can you look at my code to see if something is wrong?

My controller:


public function actionLogin()

	{

		$model=new LoginForm;


		// if it is ajax validation request

		if(isset($_POST['ajax']) && $_POST['ajax']==='login-form')

		{

			echo CActiveForm::validate($model);

			Yii::app()->end();

		}


		// collect user input data

		if(isset($_POST['LoginForm']))

		{

			$model->attributes=$_POST['LoginForm'];

			// validate user input and redirect to the previous page if valid

			if($model->validate() && $model->login())

			{

				if(Yii::app()->user->getType() != 'admin')

				{

					$this->redirect('index.php?r=site/vvid');

				}

				else

				{

					$this->redirect(Yii::app()->user->returnUrl);

				}

			}

		}

		// display the login form

		$this->layout='l_login';

		$this->render('login',array('model'=>$model));

	}

My LoginForm model


class LoginForm extends CFormModel

{

	public $username;

	public $password;

	public $rememberMe;


	private $_identity;


	/**

	 * Declares the validation rules.

	 * The rules state that username and password are required,

	 * and password needs to be authenticated.

	 */

	public function rules()

	{

		return array(

			// username and password are required

			array('username', 'required', 'message'=>'Треба вказати ім\'я!'),

			array('password', 'required', 'message'=>'Треба вказати пароль!'),

			array('password', 'authenticate'),

			array('username','ifvalid'),

			// rememberMe needs to be a boolean

			array('rememberMe', 'boolean'),

			// password needs to be authenticated

			

		);

	}

	

	public function ifvalid($attribute,$params)

	{

		if(!preg_match("/^[a-zA-Z0-9]+$/",$this->username))

		{

			$this->addError('username', "Логін має складатися тільки з латинських букв та цифр!");

		}

	}


	/**

	 * Declares attribute labels.

	 */

	public function attributeLabels()

	{

		return array(

			'username'=>"Логін:",

			'password'=>"Пароль:",

		);

	}


	/**

	 * Authenticates the password.

	 * This is the 'authenticate' validator as declared in rules().

	 */

	public function authenticate($attribute,$params)

	{

		if(!$this->hasErrors())  // we only want to authenticate when no input errors

		{

			$this->_identity=new UserIdentity($this->username,$this->password);

			$this->_identity->authenticate();

			switch($this->_identity->errorCode)

			{

				case UserIdentity::ERROR_USERNAME_INVALID:

					$this->addError('username',"Ім'я користувача не вірне.");

					break;

				case UserIdentity::ERROR_PASSWORD_INVALID:

					$this->addError('password','Пароль не вірний.');

					break;

				default:

					break;

			}

		}

	}


	/**

	 * Logs in the user using the given username and password in the model.

	 * @return boolean whether login is successful

	 */

	public function login()

	{

		if($this->_identity===null)

		{

			$this->_identity=new UserIdentity($this->username,$this->password);

			$this->_identity->authenticate();

		}

		if($this->_identity->errorCode===UserIdentity::ERROR_NONE)

		{

			

			Yii::app()->user->login($this->_identity);

			return true;

		}

		else

			return false;

	}

}



UserIdentity component


class UserIdentity extends CUserIdentity

{

    private $_id;

 

    public function authenticate()

    {

        $username=strtolower($this->username);

        $user=User::model()->find('LOWER(username)=?',array($username));

        if($user===null)

            $this->errorCode=self::ERROR_USERNAME_INVALID;

        else if(!$user->validatePassword($this->password))

            $this->errorCode=self::ERROR_PASSWORD_INVALID;

        else

        {

            $this->_id=$user->id;

            $this->username=$user->username;

            $this->errorCode=self::ERROR_NONE;

        }

        return $this->errorCode==self::ERROR_NONE;

    }

 

    public function getId()

    {

        return $this->_id;

    }

}

My WebUser component


class WebUser extends CWebUser {

 

  // Store model to not repeat query.

  private $_model;

 

  

  function getType(){

    if(Yii::app()->user->getIsGuest())

    {

      return "";

    }

    else

    {

      $user = $this->loadUser(Yii::app()->user->id);

      return $user->typ;

    }

  }

  

  function getKomId(){

    if(Yii::app()->user->getIsGuest())

    {

      return "";

    }

    else

    {

      $user = $this->loadUser(Yii::app()->user->id);

      return $user->komanda;

    }

  }

 

  // Load user model.

  protected function loadUser($id=null)

    {

        if($this->_model===null)

        {

            if($id!==null)

                $this->_model=User::model()->findByPk($id);

        }

        return $this->_model;

    }

}

And finally my User model


class User extends CActiveRecord

{

	/**

	 * The followings are the available columns in table 'tbl_user':

	 * @var integer $id

	 * @var string $username

	 * @var string $password

	 * @var string $salt

	 * @var string $email

	 * @var string $profile

	 */


	/**

	 * Returns the static model of the specified AR class.

	 * @return CActiveRecord the static model class

	 */

	public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}


	/**

	 * @return string the associated database table name

	 */

	public function tableName()

	{

		return '{{user}}';

	}


	/**

	 * @return array validation rules for model attributes.

	 */

	public function rules()

	{

		// NOTE: you should only define rules for those attributes that

		// will receive user inputs.

		return array(

			array('username','unique','message'=>'такий {attribute} вже є'),

			array('username, password', 'required'),

			array('username, komanda, password, salt, email', 'length', 'max'=>128),

		);

	}




	/**

	 * @return array customized attribute labels (name=>label)

	 */

	public function attributeLabels()

	{

		return array(

			'id' => 'Id',

			'username' => 'Логін',

			'password' => 'Пароль',

			'email' => 'Email',

			'komanda' => 'Команда',

			'typ' => 'адміністратор',

		);

	}


	/**

	 * Checks if the given password is correct.

	 * @param string the password to be validated

	 * @return boolean whether the password is valid

	 */

	public function validatePassword($password)

	{

		return $this->hashPassword($password,$this->salt)===$this->password;

	}


	/**

	 * Generates the password hash.

	 * @param string password

	 * @param string salt

	 * @return string hash

	 */

	public function hashPassword($password,$salt)

	{

		return sha1($salt.$password);

	}


	/**

	 * Generates a salt that can be used to generate a password hash.

	 * @return string the salt

	 */

	protected function generateSalt()

	{

		return uniqid('',true);

	}

	

	public function register($data)

	{

		$salt = $this->generateSalt();

		$pass = sha1($salt.$data['password']);

		$this->username = $data['username'];

		$this->email = $data['email'];

		$this->komanda = $data['komanda'];

		$this->password = $pass;

		$this->salt = $salt;

		$this->typ = $data['typ'];

		if(!$this->save())

		{

			return $this->getError('username');

		}

		else

		{

			return "ok";

		}

	}

	

	public function edit($data)

	{

		$this->findByPk($data['id']);

		$this->username = $data['username'];

		$this->email = $data['email'];

		$this->komanda = $data['komanda'];

		$this->typ = $data['typ'];

		$this->save();

	}

	

	public function change_pwd($data)

	{

		$salt = $this->generateSalt();

		$pass = sha1($salt.$data['password']);

		$this->password = $pass;

		$this->salt = $salt;

		$this->save();

	}

	

	public function getType()

	{

		return $this->typ;

	}

	

	public function getKomId()

	{

		return $this->komanda;

	}

}

Can you try with a new Yii app like I already mentioned above?

This way we will be sure if it’s something in your code… or something with that server configuration…

Should I create default yii application or add my code that I use for authintication?

Create a new Yii webapp… and try it on that server if you can login with "admin/admin" or "demo/demo"

So I created default yii application and I can’t login here either.

Must be something wrong with my server?

Can be something with the configuration…

before anything else… check the Yii requirements - http://www.yiiframework.com/doc/guide/1.1/en/quickstart.installation#requirements

Requirements are Ok.

I found the problem. In my virtual host configuration file there is this line


php_admin_value session.save_path /home/hoster/mydomain/tmp

But apache had no write access to /tmp folder and that’s why my session did not work.

I just set access rules 777 for this folder and everything is alright now.

Thank you mdomba for your help and sorry for taking your time.