Error: Class "\Drupal\drd_agent\Crypt\Method\OpenSSL" not found

Created on 10 March 2025, 23 days ago

Problem/Motivation

After updating drd_agent from 4.1.2 to 4.1.3 and drd to 4.1.7, the agents can't connect with drd:

On the monitor instance (drd):
[WARNING] drd_action_info [drd_domain/45]: Remote instance does not support DRD. Exampleproject

In the error logs on the projects:
Error: Class "\Drupal\drd_agent\Crypt\Method\OpenSSL" not found in Drupal\drd_agent\Crypt\Base::getInstance() (Zeile 19 in /web/modules/contrib/drd_agent/src/Crypt/Base.php).

#0 /web/modules/contrib/drd_agent/src/Agent/Action/Base.php(449): Drupal\drd_agent\Crypt\Base::getInstance(Object(Drupal\Core\DependencyInjection\Container), 'OpenSSL', Array)
#1 /web/modules/contrib/drd_agent/src/Agent/Action/Base.php(289): Drupal\drd_agent\Agent\Action\Base->getCryptInstance('a7360e8a-05b2-4...')
#2 /web/modules/contrib/drd_agent/src/Controller/Agent.php(79): Drupal\drd_agent\Agent\Action\Base->run(false)
#3 [internal function]: Drupal\drd_agent\Controller\Agent->get()
#4 /web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array)
#5 /web/core/lib/Drupal/Core/Render/Renderer.php(638): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#6 /web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(121): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#7 /web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array)
#8 /vendor/symfony/http-kernel/HttpKernel.php(181): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#9 /vendor/symfony/http-kernel/HttpKernel.php(76): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#10 /web/core/lib/Drupal/Core/StackMiddleware/Session.php(53): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#11 /web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#12 /web/core/lib/Drupal/Core/StackMiddleware/ContentLength.php(28): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#13 /web/core/modules/page_cache/src/StackMiddleware/PageCache.php(116): Drupal\Core\StackMiddleware\ContentLength->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#14 /web/core/modules/page_cache/src/StackMiddleware/PageCache.php(90): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#15 /web/core/modules/ban/src/BanMiddleware.php(50): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#16 /web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\ban\BanMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#17 /web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#18 /web/core/lib/Drupal/Core/StackMiddleware/AjaxPageState.php(36): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#19 /web/core/lib/Drupal/Core/StackMiddleware/StackedHttpKernel.php(51): Drupal\Core\StackMiddleware\AjaxPageState->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#20 /web/core/lib/Drupal/Core/DrupalKernel.php(741): Drupal\Core\StackMiddleware\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#21 /web/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#22 {main}

Additional infos

- Drupal Core: 10.4.3
- PHP: 8.3
- Webserver: Apache

🐛 Bug report
Status

Active

Version

4.1

Component

Code

Created by

🇨🇭Switzerland handkerchief

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @handkerchief
  • 🇩🇪Germany jurgenhaas Gottmadingen

    If you run your database update on the main site with DRD it will update all connection settings from OpenSSL to OpenSsl which is what's required.

  • 🇨🇭Switzerland handkerchief

    Thanks for the fast response. The database update has already been carried out immediately after the update, on the main instance as well as on the projects. All updates were successful, so this must be a bug, right?

  • 🇩🇪Germany jurgenhaas Gottmadingen

    I can't think of anything anymore, because nothing is calling \Drupal\drd_agent\Crypt\Method\OpenSSL any longer, the class is now called \Drupal\drd_agent\Crypt\Method\OpenSsl. Only if the database update didn't succeed would there be a reference left to the old spelling. You can check that by looking into your database with the SQL query select domain,crypt from drd_domain;. Let's see what the crypt column tells you.

  • 🇨🇭Switzerland handkerchief

    Thank you, I've checked the database from the main instance already:
    SELECT crypt FROM `drd_domain`;
    result OpenSsl

    I've run cron multiple times, also run "drush cr", nothing helped... strange.

  • 🇨🇭Switzerland handkerchief

    It gets even stranger, in \Drupal\drd\Crypt\Base::getInstance() I've logged the variable $method, and what does the log say?
    'OpenSsl'

    So at this point, the correct string is used.

  • 🇩🇪Germany jurgenhaas Gottmadingen

    Hmm, I'm running out of ideas then. I've had that same issue as I only updated my agents but not DRD on the main instance. When I realized that this was going wrong, I released DRD 4.1.7 and that fixed it. Maybe any legacy records in a queue somewhere?

    If not, then only debugging may help to find out what exact request is being sent from DRD to the remote DRD Agent.

  • 🇩🇪Germany jurgenhaas Gottmadingen

    It gets even stranger, in \Drupal\drd\Crypt\Base::getInstance() I've logged the variable $method

    So, that's on the DRD side. Maybe you can do something similar on the DRD Agent side?

  • 🇨🇭Switzerland handkerchief

    So I have switched on the debug mode in the drd_agent project, I get this message:
    "Input is incomplete"

    The variable "$input" at line 270 in \Drupal\drd_agent\Agent\Action\Base::run() in /drd_agent/src/Agent/Action/Base.php:

    Array
    (
        [uuid] => string 36 characters
        [args] => 
        [iv] => string 24 characters
    )

    So no $args variable is available, which causes the message "Input is incomplete"

    The request from the module drd on the main instance:

    Array
    (
        [0] => post
        [1] => https://example.com/drd-agent
        [2] => Array
            (
                [body] => string 120 charaters
                [headers] => Array
                    (
                        [X-Drd-Version] => 1.7.0
                    )
    
                [cookies] => GuzzleHttp\Cookie\CookieJar Object
                    (
                        [cookies:GuzzleHttp\Cookie\CookieJar:private] => Array
                            (
                            )
    
                        [strictMode:GuzzleHttp\Cookie\CookieJar:private] => 
                    )
    
            )
    )

    @jurgenhaas does that give you a clue as to what might be wrong? I have only updated the modules and updated the database.

  • 🇨🇭Switzerland handkerchief

    I deleted the core of the project on the main instance, and reconnected it again with the agent. After that, I checked the variable "$method" at \Drupal\drd_agent\Crypt\Base::getInstance():
    OpenSSL

    So in the method \Drupal\drd_agent\Agent\Action\Base::getCryptInstance() the value $authorised[$uuid]['crypt'] is indeed "OpenSSL". I guess something went wrong with all the instances with the update of drd_agent including “drush updb” which was shown as successful.

    To avoid investing even more time, it is probably best to uninstall the agent everywhere, reinstall it and then link all the projects again.

  • 🇨🇭Switzerland handkerchief

    #10 helped not. Same issue.

    In \Drupal\drd_agent\Agent\Action\Base::getCryptInstance(), the value of $authorised[$uuid]['crypt'] is always "OpenSSL". I have reinstalled everything several times, deleted and relinked core, with one exception, I have not uninstalled and reinstalled the drd module on the main instance.

    @jurgenhaas Do you have any idea what's going on?

  • 🇨🇭Switzerland handkerchief

    Ok so the problem is, the drd module core add form is not correct, I don't know why. I run composer remove drupal/drd and after that composer require 'drupal/drd:^4.1', so I'm sure it's the current version 4.1.7.

    New added cores are saved wrong in the database (table drd_domain):

    name = NULL
    crypt = OpenSSL

    First of all, as a first crypt settings on loading the add-core-page is this (but MCrypt is greyed out if i click on the select list)

    After changing to OpenSSL:

  • 🇩🇪Germany jurgenhaas Gottmadingen

    Sounds like a great finding. I'm not back in the office before Thursday, so if you wanted to provide an MR I'd be happy to review and merge that first thing when I'm back.

  • 🇨🇭Switzerland handkerchief

    So the final problem is the function \Drupal\drd\Crypt\Method\OpenSsl::getLabel():

      /**
       * {@inheritdoc}
       */
      public function getLabel(): string {
        return 'OpenSSL';
      }
    

    Which is called in \Drupal\drd\Crypt\Base::getMethods():

      /**
       * {@inheritdoc}
       */
      public static function getMethods($instances = FALSE): array {
        $dir = __DIR__ . '/Method';
        $methods = [];
        foreach (['Mcrypt', 'OpenSsl', 'Tls'] as $item) {
          /* @noinspection PhpIncludeInspection */
          include_once $dir . '/' . $item . '.php';
          $classname = "\\Drupal\\drd\\Crypt\\Method\\$item";
          /** @var BaseMethodInterface $method */
          $method = new $classname(\Drupal::getContainer());
          if ($method instanceof BaseMethodInterface && $method->isAvailable()) {
            if ($instances) {
              $methods[$method->getLabel()] = $method;
            }
            else {
              $methods[$method->getLabel()] = [
                'classname' => $classname,
                'cipher' => $method->getCipherMethods(),
              ];
            }
          }
        }
        return $methods;
      }
    

    Strictly speaking the part $methods[$method->getLabel()]

    Solution: Change the getLabel() method of OpenSsl.php, Tls.php and Mcrypt.php or use the $item value.

  • 🇨🇭Switzerland handkerchief

    I don't know with more recommended, but in a hurry I can only do it for patches. The adjustment must also be done on the agent side.

    This is how it works for me again. But I have to link the projects again.

    • jurgenhaas committed d6232f77 on 4.1.x
      Issue #3512046 by handkerchief, jurgenhaas: Error: Class "\Drupal\...
  • 🇩🇪Germany jurgenhaas Gottmadingen

    This is now pushed to DRD and DRD Agent, both in their latest dev release. Looking for another test.

  • 🇩🇪Germany jurgenhaas Gottmadingen

    @handkerchief there is an additional fix in 🐛 OpenSSL" not found Active that will help with this issue on remote sites so that you don't have to re-register remote sites with DRD.

  • 🇨🇭Switzerland handkerchief

    @jurgenhaas I tested the new dev version of drd and drd_agent. Commit #16 of this issue is working, no more problems to add cores.

    BUT your suggestion in #18 is not working. 🐛 OpenSSL" not found Active
    The drd_agent update 8002 was successful, but a "drush drd-ping" from the main instance results in "Input is incomplete" (with drd_agent debug mode on). Reason: The $input variable at line 270 in /drd_agent/src/Agent/Action/Base.php has an empty $input['args'] parameter. I don't know why. So the only workaround right now is to re-register all remote sites so you get a new token with the correct values/parameters.

  • 🇳🇴Norway jfauske

    Looks like, somewhat similar to what is done in the drd_agent state and in drd_update_8008(), we need to update the relevant keys in the cryptsetting-field in the drd_domain table.
    Some iteration on stored domains to update OpenSSL => OpenSsl.
    I can have a closer look in the morning.

  • Pipeline finished with Success
    16 days ago
    Total: 165s
    #450710
  • 🇳🇴Norway jfauske

    I've given the MR here a round of testing in top of the 4.1.x branch in combination with the drd_agent 4.1x branch

    Gathering patches for dependencies. This might take a minute.
      - Upgrading drupal/drd_agent (4.1.2 => dev-4.1.x ab72fef): Checking out ab72fefab1 from cache
      - Upgrading drupal/drd (4.1.6 => dev-4.1.x d6232f7): Checking out d6232f774f from cache
    

    After applying the relevant db updates the connection between drd and drd_agent appear to be maintained as expected:

    $ drush updb
     ----------- ----------- --------------- --------------------------------------------------------------------------- 
      Module      Update ID   Type            Description                                                                
     ----------- ----------- --------------- --------------------------------------------------------------------------- 
      drd         8008        hook_update_n   8008 - Update crypt class names.                                           
      drd         8009        hook_update_n   8009 - Update crypt class names stored as keys in the cryptsetting field.  
      drd_agent   8002        hook_update_n   8002 - Update stored crypt methods after 4.1.3 update.                     
     ----------- ----------- --------------- --------------------------------------------------------------------------- 
    
    $ drush drd:ping
    Executing Ping
    ==============
    - on id 1: Drush Site-Install
    -----------------------------
     ! [NOTE] drd_action_ping [drd_domain/1]: Success with response Drush Site-Install {"data":"pong"}                                                                                          
     [OK]   ok!                                                                                                             
      pong
     [OK] Completed!                                                                                                        
    
  • Pipeline finished with Skipped
    2 days ago
    #461520
  • 🇩🇪Germany jurgenhaas Gottmadingen

    This looks great, thanks @jfauske for your help on this one.

Production build 0.71.5 2024