meeting-room-booking-system / mrbs-code

MRBS application code
Other
127 stars 62 forks source link

Functions have been turned off on server CAS login problem/db problem ? #3426

Open jberanek opened 1 year ago

jberanek commented 1 year ago

Hello, wonderfull developers, i think i need some help here. I'm using this wonderful script for years now , but now i'm at the end of my IT knowledge.

The admins here decided, for security reasons, to turn off this functions:

exec, passthru, shell_exec, system, proc_open, popen,curl, exec,curl, multi_exec,show_source

Result CAS login was broken.

They fixed this by editing the CurlRequest file. (code on the bottom)

Recently the server has been updated to php 8.1. But now when i want to make a reservation i'm getting this error.

Uncaught exception 'Error' in /srv/vhosts/------/functions.inc at line 248
Call to undefined function MRBS\curl_exec()
...
E_WARNING in /srv/vhosts/------/mrbs/functions.inc at line 878
Cannot modify header information - headers already sent by (output started at /srv/vhosts/-------functions_error.inc:226)
.....
E_WARNING in /srv/vhosts/-------/functions.inc at line 865
Cannot modify header information - headers already sent by (output started at /srv/vhosts/------mrbs/functions_error.inc:226)
...

The strange thing is that one of the reservation pages (on the same website and the same db) still works, it only breaks when i change the link in the config file, to one of the other reservation tables. (I made a new set of tables and that worked also.)

I then see this error:

E_USER_NOTICE in /srv/vhosts/-----MRBS/DB_mysql.php at line 402 Unknown database type 'Percona Server (GPL), Release '44', Revision '27f408641db''

Someone has any clue what is going on here, this is going above my knowledge of php/mysql.

CurlRequest

<?php

/**
 * Licensed to Jasig under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for
 * additional information regarding copyright ownership.
 *
 * Jasig 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.
 *
 * PHP Version 5
 *
 * @file     CAS/Request/CurlRequest.php
 * @category Authentication
 * @package  PhpCAS
 * @author   Adam Franco <afranco@middlebury.edu>
 * @license  http://www.apache.org/licenses/LICENSE-2.0  Apache License 2.0
 * @link     https://wiki.jasig.org/display/CASC/phpCAS
 */

/**
 * Provides support for performing web-requests via curl
 *
 * @class    CAS_Request_CurlRequest
 * @category Authentication
 * @package  PhpCAS
 * @author   Adam Franco <afranco@middlebury.edu>
 * @license  http://www.apache.org/licenses/LICENSE-2.0  Apache License 2.0
 * @link     https://wiki.jasig.org/display/CASC/phpCAS
 */
class CAS_Request_CurlRequest
extends CAS_Request_AbstractRequest
implements CAS_Request_RequestInterface
{

    /**
     * Set additional curl options
     *
     * @param array $options option to set
     *
     * @return void
     */
    public function setCurlOptions (array $options)
    {
        $this->_curlOptions = $options;
    }
    private $_curlOptions = array();

    /**
     * Send the request and store the results.
     *
     * @return bool true on success, false on failure.
     */
    protected function sendRequest ()
    {
        phpCAS::traceBegin();

        /*********************************************************
         * initialize the CURL session
        *********************************************************/
        /*
        $ch = $this->_initAndConfigure();
        */
        /*********************************************************
         * Perform the query
        *********************************************************/
        if ($this->isPost) {
          $data = $this->postBody;
          $options = array(
            'http' => array(
              'method'  => 'POST',
              'header'  => "Content-type: application/x-www-form-urlencoded\r\n".
                 "Content-Length: ".strlen($data)."\r\n",
              'content' => $data
            )
          );
        } else {
          $options = array(
            'http' => array(
              'method'  => 'GET',
              'ignore_errors' => true
            )
          );
        }
        $ch  = stream_context_create($options);
        $buf = file_get_contents($this->url, false, $ch);
        if (!$buf) {
            phpCAS::trace('curl_exec() failed');
            $this->storeErrorMessage(
                'CURL error :'.error_get_last()['message']
            );
        } else {
            $this->storeResponseBody($buf);
            phpCAS::trace("Response Body: \n".$buf."\n");
            $res = true;
        }
        /*
        $buf = curl_exec($ch);
        if ( $buf === false ) {
            phpCAS::trace('curl_exec() failed');
            $this->storeErrorMessage(
                'CURL error #'.curl_errno($ch).': '.curl_error($ch)
            );
            $res = false;
        } else {
            $this->storeResponseBody($buf);
            phpCAS::trace("Response Body: \n".$buf."\n");
            $res = true;

        }
        // close the CURL session
        curl_close($ch);
        */
        phpCAS::traceEnd($res);
        return $res;
    }

    /**
     * Internal method to initialize our cURL handle and configure the request.
     * This method should NOT be used outside of the CurlRequest or the
     * CurlMultiRequest.
     *
     * @return resource The cURL handle on success, false on failure
     */
    private function _initAndConfigure()
    {
        /*********************************************************
         * initialize the CURL session
        *********************************************************/
        $ch = curl_init($this->url);

        if (version_compare(PHP_VERSION, '5.1.3', '>=')) {
            //only avaible in php5
            curl_setopt_array($ch, $this->_curlOptions);
        } else {
            foreach ($this->_curlOptions as $key => $value) {
                curl_setopt($ch, $key, $value);
            }
        }

        /*********************************************************
         * Set SSL configuration
        *********************************************************/
        if ($this->caCertPath) {
            if ($this->validateCN) {
                curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
            } else {
                curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
            }
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
            curl_setopt($ch, CURLOPT_CAINFO, $this->caCertPath);
            phpCAS::trace('CURL: Set CURLOPT_CAINFO ' . $this->caCertPath);
        } else {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        }

        /*********************************************************
         * Configure curl to capture our output.
        *********************************************************/
        // return the CURL output into a variable
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        // get the HTTP header with a callback
        curl_setopt($ch, CURLOPT_HEADERFUNCTION, array($this, '_curlReadHeaders'));

        /*********************************************************
         * Add cookie headers to our request.
        *********************************************************/
        if (count($this->cookies)) {
            $cookieStrings = array();
            foreach ($this->cookies as $name => $val) {
                $cookieStrings[] = $name.'='.$val;
            }
            curl_setopt($ch, CURLOPT_COOKIE, implode(';', $cookieStrings));
        }

        /*********************************************************
         * Add any additional headers
        *********************************************************/
        if (count($this->headers)) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $this->headers);
        }

        /*********************************************************
         * Flag and Body for POST requests
        *********************************************************/
        if ($this->isPost) {
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $this->postBody);
        }

        return $ch;
    }

    /**
     * Store the response body.
     * This method should NOT be used outside of the CurlRequest or the
     * CurlMultiRequest.
     *
     * @param string $body body to stor
     *
     * @return void
     */
    private function _storeResponseBody ($body)
    {
        $this->storeResponseBody($body);
    }

    /**
     * Internal method for capturing the headers from a curl request.
     *
     * @param handle $ch     handle of curl
     * @param string $header header
     *
     * @return void
     */
    private function _curlReadHeaders ($ch, $header)
    {
        $this->storeResponseHeader($header);
        return strlen($header);
    }
}

Reported by: hebus4

Original Ticket: mrbs/support-requests/2744

jberanek commented 1 year ago

The strange thing is that one of the reservation pages (on the same website and the same db) still works, it only breaks when i change the link in the config file, to one of the other reservation tables. (I made a new set of tables and that worked also.)

You are probably seeing this on some systems but not others because curl_exec is only called very occasionally. It's used to get new timezone definitions which are cached for 28 days.

The problem happens in the first place because MRBS is just checking for the existence of curl_init() before using curl. In your case it will exist, but curl_exec() has been disabled so will appear as though it doesn't exist (in PHP 8). I will modify the code.

Unknown database type 'Percona Server (GPL), Release '44', Revision '27f408641db''

This is just a Notice error which you can ignore, but I will modify the code.

Original comment by: campbell-m

jberanek commented 1 year ago

Ah, ok that explains the strange behaviour then. I have finally got an answer from the admins here, curl should be replaced by https://www.php.net/manual/en/function.stream-context-create.php

example they give me: (sadly again above my understanding)

curl_exec_without_curl.php <==
    1  <?php
    2  $opts = array(
    3    'http'=>array(
    4      'method'=>"GET",
    5      'header'=>"Accept-language: en\r\n" .
    6                "Cookie: foo=bar\r\n"
    7    )
    8  );

    9  $context = stream_context_create($opts);

   10  /* Sends an http request to the site
   11     with additional headers shown above */

   12  $url = "https://---------/mip.php";

   13  $fp = fopen($url, 'r', false, $context);
   14  fpassthru($fp);
   15  fclose($fp);
   16  ?>

Original comment by: hebus4

jberanek commented 1 year ago

Yes, that's exactly what MRBS does if it thinks that curl is not available. The problem is that it thought curl was available on your system. Fix coming up.

Original comment by: campbell-m

jberanek commented 1 year ago

Now fixed in 83ff02f.

Original comment by: campbell-m

jberanek commented 1 year ago

As I haven't got a Percona system to test against, could you run the attached test program please in the MRBS directory and let me know the output? It should look something like

MySQL Community Server - GPL
8.0.28

but obviously changed for Percona.

Original comment by: campbell-m

Attachments: https://sourceforge.net/p/mrbs/support-requests/_discuss/thread/ba7d438049/395d/attachment/test.php

jberanek commented 1 year ago

I have raised the dependence of phpCAS on curl as an issue with the phpCAS team.

Original comment by: campbell-m

jberanek commented 1 year ago

I've added another fix in f8b0619.

Original comment by: campbell-m

jberanek commented 1 year ago

Ty for the fast response Campbell, I replaced the functions.inc file using the f8b0619 fix. But when i open de page i'm getting this error now.

Uncaught exception 'Error' in /srv/vhosts/---------/functions.inc at line 2525 Call to undefined method MRBS\Session\SessionCas::isset()

Original comment by: *anonymous

jberanek commented 1 year ago

Yes, there have been a number of other changes to functions.inc which are incompatible with 1.11.0.

I think you'll need to download the complete latest code from this page (follow the green Code button) and treat it like an upgrade. You'll obviously need to reapply any modifications you have made yourself (eg the change to CurlRequest.php above).

If you don't want to do that you'll need to apply the changes in the fixes manually to your existing functions.inc.

Original comment by: campbell-m

jberanek commented 1 year ago

For the db test this is the result. Percona Server (GPL), Release '44', Revision '27f408641db' 5.7.41-44-log

Original comment by: *anonymous

jberanek commented 1 year ago

Thanks. I've now added in support for Percona version checking in b0dfff6. I think that in this case you should just be able to put the new DB_mysql.php into an MRBS 1.11.0 system.

Alternatively when you set $debug = false; the error message "Unknown database type 'Percona Server (GPL), Release '44', Revision '27f408641db'" will go away.

Original comment by: campbell-m

jberanek commented 1 year ago

After a few days of test running, it looks like the reservations are working again, incl. mailing etc. :). So thanks again for the fast fix.

The only error i still have in debugmode is :

E_USER_NOTICE in /srv/vhosts/...../functions_mail.inc at line 174
Invalid email address "usershortname <usershortname>".

But that will probably be an error in my config file i need to look into when i have more time.

Original comment by: hebus4

jberanek commented 1 year ago

Looks to be resolved.

campbell-m commented 1 year ago

I've reopened this issue to remind me to submit a PR to the PHP CAS team.