libresign icon indicating copy to clipboard operation
libresign copied to clipboard

Error with enable_previews = false at config.php

Open D592VN5 opened this issue 9 months ago • 18 comments

Hi there,

Fresh installation on Ubuntu 22.04, php 8.3 in FastCGI mode, latest Nextcloud 31.02, LibreSign 11.0.4. (no upgrade history)

All dependencies installed, all green-success in NextCloud LibreSign Configuration check window.

OpenSSL engine case: entire workflow works, except when pdf is signed, 'explode(): Argument #2 ($string) must be of type string, null given' message is returned in the upper right corner.

Nevertheless, pdf is created, stamp, qr and certificate are all attached to it. However - signature validation functionality does not work (same 'explode(): Argument #2 ($string) must be of type string, null given' is returned).

Tried 'I will not use root certificate' and 'CFSSL' even with less success - 'Failure on generate certificate' is returned when attempt to sign.

Re-installed LibreSign multiple times from NextCloud UI. Re-installed LibreSign with occ: occ libresign:uninstall --all occ files:scan-app-data libresign occ libresign:install --all

Re-issued certificate with different parameters multiple times. Log file does not give any additional hints (same as above).

Would be good to have at least OpenSSL method working.

Looks like this error was mentioned (on the web) at least twice previously, but outcome is unclear.

Thank you.

D592VN5 avatar Mar 26 '25 23:03 D592VN5

Could you provide the log with more details?

You can get the entire row log at nextcloud.log file or using the interface at Administration Settings > logs and getting the entire log text. Follow a random example from my environment:

{
	"reqId": "X4YysvO6GK8dL08Po9dE",
	"level": 0,
	"time": "2025-03-27T00:05:29+00:00",
	"remoteAddr": "192.168.240.1",
	"user": "admin",
	"app": "no app in context",
	"method": "GET",
	"url": "/ocs/v2.php/apps/notifications/api/v2/notifications",
	"message": "OCA\\QuotaWarning\\Notification\\Notifier::prepare() threw \\InvalidArgumentException which is deprecated. Throw \\OCP\\Notification\\UnknownNotificationException when the notification is not known to your notifier and otherwise handle all \\InvalidArgumentException yourself.",
	"userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
	"version": "32.0.0.0",
	"data": []
}

vitormattos avatar Mar 27 '25 00:03 vitormattos

Could you provide the log with more details?

Hi! Thank you for responding. Here it is, I cleared the log before starting sequence again.

{"reqId":"Z4l3KybDjS7oaXsVizht","level":3,"time":"2025-03-27T00:27:18+00:00","remoteAddr":"","user":"U48","app":"index","method":"GET","url":"/index.php/ocsapp/apps/libresign/api/v1/signature/elements/preview/1076&_t=1743035236274","message":"Previews disabled","userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36","version":"31.0.2.1","exception":{"Exception":"OCP\Files\NotFoundException","Message":"Previews disabled","Code":0,"Trace":[{"file":"/var/www/u_usr/data/www/test.com/cloud/lib/private/PreviewManager.php","line":163,"function":"throwIfPreviewsDisabled","class":"OC\PreviewManager","type":"->","args":[]},{"file":"/var/www/u_usr/data/www/test.com/cloud/apps/libresign/lib/Controller/SignatureElementsController.php","line":163,"function":"getPreview","class":"OC\PreviewManager","type":"->","args":[{"class":"OC\Files\Node\File"},350,100]},{"file":"/var/www/u_usr/data/www/test.com/cloud/lib/private/AppFramework/Http/Dispatcher.php","line":200,"function":"getSignatureElementPreview","class":"OCA\Libresign\Controller\SignatureElementsController","type":"->","args":[1076]},{"file":"/var/www/u_usr/data/www/test.com/cloud/lib/private/AppFramework/Http/Dispatcher.php","line":114,"function":"executeController","class":"OC\AppFramework\Http\Dispatcher","type":"->","args":[{"class":"OCA\Libresign\Controller\SignatureElementsController"},"getSignatureElementPreview"]},{"file":"/var/www/u_usr/data/www/test.com/cloud/lib/private/AppFramework/App.php","line":161,"function":"dispatch","class":"OC\AppFramework\Http\Dispatcher","type":"->","args":[{"class":"OCA\Libresign\Controller\SignatureElementsController"},"getSignatureElementPreview"]},{"file":"/var/www/u_usr/data/www/test.com/cloud/lib/private/Route/Router.php","line":307,"function":"main","class":"OC\AppFramework\App","type":"::","args":["OCA\Libresign\Controller\SignatureElementsController","getSignatureElementPreview",{"class":"OC\AppFramework\DependencyInjection\DIContainer"},{"apiVersion":"v1","nodeId":"1076&_t=1743035236274","_route":"ocs.libresign.signatureelements.getsignatureelementpreview"}]},{"file":"/var/www/u_usr/data/www/test.com/cloud/lib/base.php","line":1025,"function":"match","class":"OC\Route\Router","type":"->","args":["/ocsapp/apps/libresign/api/v1/signature/elements/preview/1076&_t=1743035236274"]},{"file":"/var/www/_usr/data/www/test.com/cloud/index.php","line":24,"function":"handleRequest","class":"OC","type":"::","args":[]}],"File":"/var/www/u_usr/data/www/test.com/cloud/lib/private/PreviewManager.php","Line":466,"message":"Previews disabled","exception":{},"CustomMessage":"Previews disabled"}} {"reqId":"GVl5GwCsP3cHiQiME6H2","level":3,"time":"2025-03-27T00:27:37+00:00","remoteAddr":"","user":"U48","app":"libresign","method":"GET","url":"/ocs/v2.php/apps/libresign/api/v1/file/validate/uuid/18aaca5a-f985-4d72-912d-27b7f380b2e1","message":"explode(): Argument https://github.com/LibreSign/libresign/issues/2 ($string) must be of type string, null given","userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36","version":"31.0.2.1","data":{"app":"libresign"}}

Previews are indeed disabled, on purpose, for security.

D592VN5 avatar Mar 27 '25 13:03 D592VN5

Thanks!

The system setting enable_previews is new for me.

I will create a PR disabling the previews at LibreSign side when enable_previews is false.

vitormattos avatar Apr 09 '25 15:04 vitormattos

Thanks!

The system setting enable_previews is new for me.

I will create a PR disabling the previews at LibreSign side when enable_previews is false.

Hi.

I enabled previews, but unfortunately that message keeps appearing when document and signed and document validation does not work

Also, at some point NextCloud log indicated more details on this error, I think this is interesting to you

Exception explode(): Argument #2 ($string) must be of type string, null given in file '/var/www/abc/data/www/test.com/cloud/apps/libresign/lib/Handler/Pkcs12Handler.php' line 205

D592VN5 avatar Apr 09 '25 16:04 D592VN5

Could you provide the entire log of this exception?

vitormattos avatar Apr 09 '25 16:04 vitormattos

Looking the code at this point, I think that could be a problem related with permission.

Sounds that you have the command pdfsig at your environment and that this command didn't returned nothing with the signed pdf file as argument.

https://github.com/LibreSign/libresign/blob/18043b6418ee43957bf141b44ddfdab3c2cdb7b7/lib/Handler/Pkcs12Handler.php#L190-L205

  • Did you really have the command pdfsig at your environment? This is part of poppler-utils
  • Could you check the output of command pdfsig with a signed document or any other document?
  • Also would be good to check if pdfsig have access to files at the tempfolder that Nextcloud are using, normally is /tmp

This error isn't related to this issue and is because sounds that the output of pdfsig command at your environments is empty and because this, the parse of output throws this error.

vitormattos avatar Apr 09 '25 16:04 vitormattos

I also created another PR to prevent this error considering that poppler-utils isn't mandatory to LibreSign works fine. Without poppler-utils only will return less information about signature when extract data from PDF file.

  • https://github.com/LibreSign/libresign/pull/4812

vitormattos avatar Apr 09 '25 16:04 vitormattos

Could you provide the entire log of this exception?

Here is the log

{ "reqId": "9Xi1OJnaBss64uAgjZzQ", "level": 3, "time": "2025-04-09T15:52:45+00:00", "remoteAddr": "xxx", "user": "yyy", "app": "no app in context", "method": "POST", "url": "/ocs/v2.php/apps/libresign/api/v1/file/validate", "message": "explode(): Argument #2 ($string) must be of type string, null given in file '/var/www/abc/data/www/test.com/cloud/apps/libresign/lib/Handler/Pkcs12Handler.php' line 205", "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36", "version": "31.0.2.1", "exception": { "Exception": "Exception", "Message": "explode(): Argument #2 ($string) must be of type string, null given in file '/var/www/abc/data/www/test.com/cloud/apps/libresign/lib/Handler/Pkcs12Handler.php' line 205", "Code": 0, "Trace": [ { "file": "/var/www/abc/data/www/test.com/cloud/lib/private/AppFramework/App.php", "line": 161, "function": "dispatch", "class": "OC\AppFramework\Http\Dispatcher", "type": "->", "args": [ { "class": "OCA\Libresign\Controller\FileController" }, "validateBinary" ] }, { "file": "/var/www/abc/data/www/test.com/cloud/lib/private/Route/Router.php", "line": 307, "function": "main", "class": "OC\AppFramework\App", "type": "::", "args": [ "OCA\Libresign\Controller\FileController", "validateBinary", { "class": "OC\AppFramework\DependencyInjection\DIContainer" }, { "apiVersion": "v1", "_route": "ocs.libresign.file.validatebinary" } ] }, { "file": "/var/www/abc/data/www/test.com/cloud/ocs/v1.php", "line": 49, "function": "match", "class": "OC\Route\Router", "type": "->", "args": [ "/ocsapp/apps/libresign/api/v1/file/validate" ] }, { "file": "/var/www/abc/data/www/test.com/cloud/ocs/v2.php", "line": 7, "args": [ "/var/www/abc/data/www/test.com/cloud/ocs/v1.php" ], "function": "require_once" } ], "File": "/var/www/abc/data/www/test.com/cloud/lib/private/AppFramework/Http/Dispatcher.php", "Line": 146, "Previous": { "Exception": "TypeError", "Message": "explode(): Argument #2 ($string) must be of type string, null given", "Code": 0, "Trace": [ { "file": "/var/www/abc/data/www/test.com/cloud/apps/libresign/lib/Handler/Pkcs12Handler.php", "line": 205, "function": "explode", "args": [ "\n", null ] }, { "file": "/var/www/abc/data/www/test.com/cloud/apps/libresign/lib/Handler/Pkcs12Handler.php", "line": 138, "function": "popplerUtilsPdfSignFallback", "class": "OCA\Libresign\Handler\Pkcs12Handler", "type": "->", "args": [ null, 0 ] }, { "file": "/var/www/abc/data/www/test.com/cloud/apps/libresign/lib/Service/FileService.php", "line": 221, "function": "getCertificateChain", "class": "OCA\Libresign\Handler\Pkcs12Handler", "type": "->", "args": [ null ] }, { "file": "/var/www/abc/data/www/test.com/cloud/apps/libresign/lib/Controller/FileController.php", "line": 141, "function": "setFileFromRequest", "class": "OCA\Libresign\Service\FileService", "type": "->", "args": [ { "0": "And 1 more entries, set log level to debug to see all entries", "name": "lorem2.signed.pdf", "full_path": "lorem2.signed.pdf", "type": "application/pdf", "tmp_name": "/var/www/abc/data/tmp/phpZsrgoN", "error": 0 } ] }, { "file": "/var/www/abc/data/www/test.com/cloud/lib/private/AppFramework/Http/Dispatcher.php", "line": 200, "function": "validateBinary", "class": "OCA\Libresign\Controller\FileController", "type": "->", "args": [] }, { "file": "/var/www/abc/data/www/test.com/cloud/lib/private/AppFramework/Http/Dispatcher.php", "line": 114, "function": "executeController", "class": "OC\AppFramework\Http\Dispatcher", "type": "->", "args": [ { "class": "OCA\Libresign\Controller\FileController" }, "validateBinary" ] }, { "file": "/var/www/abc/data/www/test.com/cloud/lib/private/AppFramework/App.php", "line": 161, "function": "dispatch", "class": "OC\AppFramework\Http\Dispatcher", "type": "->", "args": [ { "class": "OCA\Libresign\Controller\FileController" }, "validateBinary" ] }, { "file": "/var/www/abc/data/www/test.com/cloud/lib/private/Route/Router.php", "line": 307, "function": "main", "class": "OC\AppFramework\App", "type": "::", "args": [ "OCA\Libresign\Controller\FileController", "validateBinary", { "class": "OC\AppFramework\DependencyInjection\DIContainer" }, { "apiVersion": "v1", "_route": "ocs.libresign.file.validatebinary" } ] }, { "file": "/var/www/abc/data/www/test.com/cloud/ocs/v1.php", "line": 49, "function": "match", "class": "OC\Route\Router", "type": "->", "args": [ "/ocsapp/apps/libresign/api/v1/file/validate" ] }, { "file": "/var/www/abc/data/www/test.com/cloud/ocs/v2.php", "line": 7, "args": [ "/var/www/abc/data/www/test.com/cloud/ocs/v1.php" ], "function": "require_once" } ], "File": "/var/www/abc/data/www/test.com/cloud/apps/libresign/lib/Handler/Pkcs12Handler.php", "Line": 205 }, "message": "explode(): Argument #2 ($string) must be of type string, null given in file '/var/www/abc/data/www/test.com/cloud/apps/libresign/lib/Handler/Pkcs12Handler.php' line 205", "exception": [], "CustomMessage": "explode(): Argument #2 ($string) must be of type string, null given in file '/var/www/abc/data/www/test.com/cloud/apps/libresign/lib/Handler/Pkcs12Handler.php' line 205" }, "id": "67f63a7b98da4" }

D592VN5 avatar Apr 09 '25 17:04 D592VN5

  • o

I confirmed pdfsig works correctly when run manually as the user (the same one that runs Nextcloud). It successfully returns signature data from the test PDF (NOTE - "Signature Validation: Signature is Invalid", but I think this is fine, isn't it?). So the issue does not seem to be related to pdfsig being unavailable or returning no output.

Image

D592VN5 avatar Apr 09 '25 17:04 D592VN5

Another possible hint: I have NextCloud encryption enabled (with default encryption module and 'encrypt the home storage' enabled). Is LibreSign tested with encryption?

D592VN5 avatar Apr 09 '25 19:04 D592VN5

We never had a customer that needed to use LibreSign with encryption enabled. Because this we never prioritize to check this scenario with encryption enabled.

Have an old issue related to encryption:

  • https://github.com/LibreSign/libresign/issues/895

About the log, could have relations with encryption. All points related to subject of this issue already was solved.

You got success with the command using a file that isn't the same of file that is used at the time to sign the document and considering that you are with encryption enabled, this can change the scenario, but would be good to check the file that is used by LibreSign.

After the follow row:

 file_put_contents($tempFile, $content);

You can add a new file_put contents to save this file into another place and test the pdfsig with the file that is really used by LibreSign:

 file_put_contents(__DIR__ . '/testFile.pdf', $content);

After this, you will have a file festFile.pdf, I think that, at your sever root folder. You also can use the find command to search by this file.

Then try to use the generated file with pdfsig.

But, again, the subject of this issue already was fixed.

vitormattos avatar Apr 10 '25 02:04 vitormattos

We never had a customer that needed to use LibreSign with encryption enabled. Because this we never prioritize to check this scenario with encryption enabled.

Have an old issue related to encryption:

About the log, could have relations with encryption. All points related to subject of this issue already was solved.

You got success with the command using a file that isn't the same of file that is used at the time to sign the document and considering that you are with encryption enabled, this can change the scenario, but would be good to check the file that is used by LibreSign.

After the follow row:

file_put_contents($tempFile, $content); You can add a new file_put contents to save this file into another place and test the pdfsig with the file that is really used by LibreSign:

file_put_contents(DIR . '/testFile.pdf', $content); After this, you will have a file festFile.pdf, I think that, at your sever root folder. You also can use the find command to search by this file.

Then try to use the generated file with pdfsig.

But, again, the subject of this issue already was fixed.

Hi vitormattos,

Apparently, the problem is with shell_exec('pdfsig ' . $tempFile);

I tested this with standalone script - even on external PDF signed with proper certificate (not self-signed/let's encrypt), this returns the same error as for PDF signed by LibreSign:

terminate called after throwing an instance of 'std::logic_error' what(): basic_string::_M_construct null not valid Aborted (core dumped)

But, when the same pdfsig command is executed from cli/console, it outputs valid data (as on the screenshot above)

I'm pretty certain it is not an issue with accessing PDF file (for testing above with custom script I didn't use /tmp/ folder)

Pdfsig is of version 22.02.0 php 8.3 in fastcgi mode shell_exec is not restricted

D592VN5 avatar Apr 10 '25 05:04 D592VN5

Other good test:

var_dump([
	'file_exists' => file_exists($tempFile),
	'is_readable' => is_readable($tempFile),
]);

Are you using SELinux, AppArmor or chroot? This could generate restrictions to your PHP process that could generate strange behavior when run pdfsig using PHP.

If you have SELinux, the command getenforce should exists and return a value. If you have AppArmor, the command aa-status should exists and return a value.

vitormattos avatar Apr 10 '25 13:04 vitormattos

Turned out I needed to put putenv('HOME=/root');

before $content = shell_exec('pdfsig ' . $tempFile);

Problem solved, no more error upon validation, LibreSign works for me!

D592VN5 avatar Apr 10 '25 17:04 D592VN5

Turned out I needed to put putenv('HOME=/root');

before $content = shell_exec('pdfsig ' . $tempFile);

Did you made any change at LibreSign code?

vitormattos avatar Apr 11 '25 12:04 vitormattos

Turned out I needed to put putenv('HOME=/root'); before $content = shell_exec('pdfsig ' . $tempFile);

Did you made any change at LibreSign code?

Yes,

in libresign/lib/Handler/Pkcs12Handler.php I put putenv('HOME=/root'); before $content = shell_exec('pdfsig ' . $tempFile);

However, I see that shell_exec is used by LibreSign in other files too, possibly I need to add putenv('HOME=/root'); there too.

But for now I did just this one change, since all use-cases that I use LibreSign with (OpenSSL mode), seem to work.

D592VN5 avatar Apr 11 '25 14:04 D592VN5

in libresign/lib/Handler/Pkcs12Handler.php
I put
putenv('HOME=/root');
before
$content = shell_exec('pdfsig ' . $tempFile);

Interesting! Where did you find this solution?

It seems like pdfsig requires access to or tries to write something in the folder defined by the HOME environment variable. If that's the case, setting it to /root might work on your system, but it could lead to permission issues or unexpected behavior on other environments.

Maybe a more portable and safer approach would be using something like:

putenv('HOME=' . sys_get_temp_dir());

Or pointing it to another writable directory instead of hardcoding /root.

But I'll need to confirm whether HOME environment is actually required by pdfsig and what exactly it tries to do in that directory.

vitormattos avatar Apr 18 '25 21:04 vitormattos

@D592VN5 Has this issue been resolved? Can we close this?

vitormattos avatar Jun 28 '25 17:06 vitormattos