[BlueOnyx:25667] Re: BlueOnyx 5211R development - progress report

Michael Stauber mstauber at blueonyx.it
Sun Oct 23 22:26:05 -05 2022


Hi all,

Last week (15th of October) I had posted another progress report on the 
BlueOnyx 5211R development. Here is another follow up:

Since the last progress report I've been porting GUI pages from the old 
5210R coding style to the new 5211R coding style. Often spending 12-16 
hours or more a day hard at it.

By now around 70% of all GUI pages have been ported. This also includes 
some real bastards of pages where I was cleaning out old spaghetti code 
or cutting out chaff and redundancies.

So far there have been a few pages that made me pull the rest of my 
hairs out. Like this stupid examples I'd like to share.

In a few GUI pages we used MySQL calls directly from within PHP. Via the 
"mysqli()" command. Now it turns out that in CodeIgniter 4 you HAVE to 
use their built in MySQL connector, as they simply high-jacked and 
invalidated the PHP mysql() and mysqli() commands.

The problem? That CodeIgniter MySQL connector throws a code exception if 
the MySQL credentials aren't correct. And this can easily happen during 
server management, like the server admin trying to reconfigure MySQL or 
changing the MySQL password.

So I had to write our own wrapper around that procedure. First we use a 
CODB handler to check if the servers MySQL configuration works. If yes? 
Then we allow usage of the CodeIgniter MySQL stuff. If not? Then we 
don't use it, avoid that CodeIgniter throws an exception and return our 
own less obnoxious error message instead.

So as a side effect we now have a reliable built in GUI function that 
GUI pages can use to run their own MySQL queries:

-------------------------------------------------------------------------
     //--- BX_MySQL_Query():
     //
     // Helper function to connect to MySQL and to execute a query
     // against a database.
     //
     // $database:   The DB we want to run the query against
     // $query:      The SQL statement we want to run
     // returns:     CodeIgniter Object of the result.
     // Errors:      Can be fetched via $CI->getBX_MySQL_Error() and
     //              the optional parameters 'code' and 'message'
     public function BX_MySQL_Query($database = '', $query='') {

	    [... Lots of code ....]

             // Return result:
             return $query_result;
         }
         else {
             // Set error as we couldn't establish a connection to MySQL:
             $this->setBX_MySQL_Error(array(
                'code' => '500',
                'message' => '[[base-mysql.mysql_status_incorrect]]')
               );
             return FALSE;
         }
     }
-------------------------------------------------------------------------

That function turned out to be quite useful already and we use it in 
several places in the base-mysql module. The AV-SPAM will also heavily 
rely on this once I port it over.

One module that was driving me bat shit crazy and took WAY more time to 
port than I'd like to admit? base-phpmyadmin of all places!

It only has one GUI page that we use in three different places in the 
menu to perform an auto-login into phpMyadmin with the correct 
credentials. How hard can that be to port? Maybe an hour or two of 
effort? Right? Bwahahaha! Nope!

It took me two days. Which is almost a whole work week for a salaried 
nine to five office employee. :p

The problem? We use the "SignOn" method that phpMyAdmin provides for 
auto-logins. POST requests to the index page of phpMyadmin are 
prohibited from external apps for security reasons. The CSRF method they 
use won't allow it. Login via GET URL parameters also has long been 
deprecated for security reasons and even if it wasn't: We wouldn't use 
it anyway. So if you want to use auto-login from another app? Their 
"SignOn" method is what it has to be.

Which uses PHP Session data. The new BlueOnyx GUI does now use PHP 
sessions as well. But you can only have one active session.

So the BlueOnyx GUI and phpMyAdmin would have to share the same session.

Which sadly isn't as easy as giving the session the same name. The 
cookie parameters also need to coincide and there I could never get the 
two to cooperate, as CodeIgniter uses a different general cookie 
configuration than phpMyadmin. On top of that phpMyAdmin uses encrypted 
session data and we don't, as we don't expose critical data anyway.

Long story short: Eventually I had to switch the auto-login into 
phpMyAdmin to "SignOn" with external SignOn-Script. Which is hardly 
documented at all, so I had to poke around in phpMyAdmin's code to 
figure out the details.

Via that alternate SignOn method a custom SignOn-Script performs the 
authentication into phpMyAdmin, which then uses its own encrypted 
cookies to keep the session alive. So our GUI now passes an 
authenticator to phpMyAdmin, which then uses that for the login via the 
custom signon-script-blueonyx.php in the phpMyAdmin directory. Yikes.


Lastly: For weeks I had observed some odd behavior of the new GUI. 
Whenever you logged in the first time around you were kicked back to 
/login after submitting valid login data. You then entered the login 
details AGAIN and finally it would let you in.

This only happened in completely new browser sessions (like open new 
browser or open the same browser in incognito mode) or if the session 
data (CCE and PHP) had fully expired. Or at the end of the expiry of the 
last valid CSRF token.

Over the last few weeks I threw lots of logging at it, trying to find 
out what part of the GUI caused it. There were a few suspects:

- BaseController.php
- ServerScriptHelper.php
- CceClient.php
- Login.php
- BxPage.php
- The CodeIgniter Filter pages

Today I finally had enough of it and started hunting the issue in 
earnest. It was a good excuse NOT to start working on base-sitestats, 
which contains some of the most complex code we have.

And after spending the whole Sunday afternoon on it I finally found the 
issue why the initial login always failed:

CodeIgniter's CSRF protection! /facepalm

When /login first loads it DOES set the CSRF name and Hash into a hidden 
input field. Like it MUST do for this to work. Sadly: First time around 
it ALWAYS used the wrong hash due to a mistake that I had made.

So that's now working as well. \o/

Positive side effect: If GUI debugging is enabled (via "touch 
/etc/DEBUG"), then /var/log/gui-debug.log now provides a *REALLY* 
detailed view of what's going on in the background on every GUI page 
access.

If I can keep up the pace (absence of other work permitting), then I 
might be able to wrap up the GUI conversion work in the next 8-10 days.

After that the next step is packaging and RPM building to push out new 
RPMs with the updated GUI pages.


-- 
With best regards

Michael Stauber



More information about the Blueonyx mailing list