Closed RGarrido03 closed 1 year ago
This is where the g_file_get_contents()
function is called:
https://github.com/nm-l2tp/NetworkManager-l2tp/blob/6c89042b1a17610efb759fa307e0e72eae6802b9/src/nm-l2tp-service.c#L235
For some reason it appears that the ipsec_secrets_file
filename that is passed to the g_file_get_contents()
function is NULL
.
The filename is typically /etc/ipsec.secrets
(although on Fedora when strongswan is used, it falls back to /etc/strongswan/ipsec.secrets
).
Did you build NetworkManager-l2tp from source code? If so, did you override the default /etc/ipsec.secrets
filename --with-nm-ipsec-secrets=
and the /etc/ipsec.d
secrets dir with --with-nm-ipsec-secrets-dir=
?
I've seen bug reports from 2017 that the g_file_get_contents()
function in glib was producing a false positive, but wouldn't think and current linux distro would have that bug.
Actually, it doesn't make sense that the filename is NULL as it checks earlier in the code that the ipsec_secrets_file
file exists with the g_file_test()
function before it calls the has_include_ipsec_secrets()
which calls the problematic g_file_get_contents()
:
I guess SELinux or AppArmor could be interfering with opening the contents of /etc/ipsec.secret
and it is producing a misleading error.
Are you able open the contents of /etc/ipsec.secrets
without error from the command-line, e.g,:
sudo cat /etc/ipsec.secrets
Otherwise, I think you might have a buggy glib library which has the g_file_get_contents()
function.
You can try manually adding the following line to the end of /etc/ipsec.secrets
and see if it makes a difference:
include ipsec.d/ipsec.nm-l2tp.secrets
As the code you are having issues with is basically checking if that include line is there and adds it if it isn't.
If it's able to get past that section of code, the certificate details for strongswan will then be written to the /etc/ipsec.d/ipsec.nm-l2tp.secrets
file.
Thank you for the quick reply, and I'm sorry for the delay, yesterday was a pretty busy day.
This is where the
g_file_get_contents()
function is called:For some reason it appears that the
ipsec_secrets_file
filename that is passed to theg_file_get_contents()
function isNULL
. The filename is typically/etc/ipsec.secrets
(although on Fedora when strongswan is used, it falls back to/etc/strongswan/ipsec.secrets
).Did you build NetworkManager-l2tp from source code? If so, did you override the default
/etc/ipsec.secrets
filename--with-nm-ipsec-secrets=
and the/etc/ipsec.d
secrets dir with--with-nm-ipsec-secrets-dir=
?I've seen bug reports from 2017 that the
g_file_get_contents()
function in glib was producing a false positive, but wouldn't think and current linux distro would have that bug.
I didn't build NetworkManager-l2tp
from the source code, because I got it from the Arch repos. And no, I didn't override any default, because I'm connecting through either the GNOME Shell's quick panel or the GNOME Control Center.
Actually, it doesn't make sense that the filename is NULL as it checks earlier in the code that the
ipsec_secrets_file
file exists with theg_file_test()
function before it calls thehas_include_ipsec_secrets()
which calls the problematicg_file_get_contents()
:I guess SELinux or AppArmor could be interfering with opening the contents of
/etc/ipsec.secret
and it is producing a misleading error.Are you able open the contents of
/etc/ipsec.secrets
without error from the command-line, e.g,:sudo cat /etc/ipsec.secrets
Otherwise, I think you might have a buggy glib library which has the
g_file_get_contents()
function.
I don't have SELinux or AppArmor, and yes, I'm able to cat
that file successfully. I really think I have a buggy glib
library.
You can try manually adding the following line to the end of
/etc/ipsec.secrets
and see if it makes a difference:include ipsec.d/ipsec.nm-l2tp.secrets
As the code you are having issues with is basically checking if that include line is there and adds it if it isn't.
If it's able to get past that section of code, the certificate details for strongswan will then be written to the
/etc/ipsec.d/ipsec.nm-l2tp.secrets
file.
Unfortunately, this doesn't change anything. But I'm not using strongswan
, I'm using libreswan
instead:
sudo pacman -Q | grep "swan"
libreswan 4.10-1
networkmanager-libreswan 1.2.16-1
I think I was mistaken in the reading the journalctl output for the g_file_get_contents()
function. Here are all the location in the source code where that function is called:
The first location in src/nm-l2tp-service.c
was where I previously thought the issue was, but it is not possible as you can only get there if you are using strongswan. So please undo the changes I suggested to make to /etc/ipsec.secrets
file, that include line is not needed for libreswan.
shared/nm-l2tp-crypto-nss.c
or shared/nm-l2tp-crypto-openssl.c
at first seem unlikely as there are checks for NULL
elsewhere in the code, but they are the prime suspects as they are related to processing of the TLS certificate code.
shared/nm-utils/nm-shared-utils.c
can be eliminated as the corresponding function that it is located in, isn't used.
I'll have to get back to you after I've done some testing. I did remove some deprecated code that OpenSSL 3.1 was complaining about with the last release of NetworkManager-l2tp, I may have gone too far and removed something I shouldn't have.
shared/nm-l2tp-crypto-openssl.c
is probably the trouble maker, there are code paths were a NULL
value can be set for the filename that is passed to the g_file_get_contents()
function. I won't get a chance to work on the code till the weekend.
Thank you for your findings. Take your time, no worries :)
Can you provide a screenshot of the IPsec Properties dialog box that shows the TLS certificate machine authentication fields? I want to see what fields have been filled in and what type of certificates and keys are being used to make it easier to reproduce the issue.
I've committed something in the code to no longer cause a core dump if the filename is NULL
, it prevents the assertion, but doesn't fix the actual issue. I suspect something the the Gtk4 pull request from last year may have broken something with the certificate handling in the GUI.
I haven't been able to reproduce the issue, but suspect it is one of the following filenames that is empty (i.e. (None)
or NULL
) in the IPsec settings :
If you are using a PKCS#12 or .p12 certificate file, then all 3 of the above should automatically get filled out to the same filename.
If you are use a PEM or DER certificate file along with a private key, then only the CA certificate filename can optionally be empty.
The NMACertChooser code introduced with commit https://github.com/nm-l2tp/NetworkManager-l2tp/commit/22e06721c4c06fdb841b6f45bb83e304fd8da8fd for Gtk4 support isn't as user friendly as the previous GtkFileChooserButton for handling certificates, unfortunately the GtkFileChooserButton no longer exists with Gtk4
I'm sorry for the delay; I must confess that I got the email yesterday, but I completely forgot to reply 👀
Can you provide a screenshot of the IPsec Properties dialog box that shows the TLS certificate machine authentication fields? I want to see what fields have been filled in and what type of certificates and keys are being used to make it easier to reproduce the issue.
I've committed something in the code to no longer cause a core dump if the filename is
NULL
, it prevents the assertion, but doesn't fix the actual issue. I suspect something the the Gtk4 pull request from last year may have broken something with the certificate handling in the GUI.
Here it is! Do you want me to build this from source, so that I can test the commit?
I haven't been able to reproduce the issue, but suspect it is one of the following filenames that is empty (i.e.
(None)
orNULL
) in the IPsec settings :
- CA certificate filename
- Machine certificate filename
- Machine private key filename
If you are using a PKCS#12 or .p12 certificate file, then all 3 of the above should automatically get filled out to the same filename.
If you are use a PEM or DER certificate file along with a private key, then only the CA certificate filename can optionally be empty.
The NMACertChooser code introduced with commit 22e0672 for Gtk4 support isn't as user friendly as the previous GtkFileChooserButton for handling certificates, unfortunately the GtkFileChooserButton no longer exists with Gtk4
I'm only using .crt
files, not .p12
ones. The machine private key input is disabled in the GUI, so I think it's not needed, right?
No worries.
The machine private key field is definitely needed and that's what is causing the 'filename != NULL'
assertion to fail.
If the GUI recognises what sort of certificate it is, it makes the machine private key field editable. But looks like it doesn't know what sort of certificate it is.
Could you try the file
and openssl x509
commands (only need a little of the output from the latter) on the CShell_Certificate.crt certificate file to see what sort of certificate it is.
$ file rsa_2048.crt
rsa_2048.crt: Certificate, Version=3
$ openssl x509 -in rsa_2048.crt -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
3c:2b:eb:04:86:9b:e2:a8:c7:bc:1e:fa:24:ca:0b:f2:a9:cc:45:e6
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = AU, ST = Queensland, L = Brisbane, OU = Test, CN = TestCN
Validity
Not Before: Apr 23 08:35:42 2023 GMT
Not After : Sep 7 08:35:42 2050 GMT
...
The output is as follows:
file CShell_Certificate.crt
CShell_Certificate.crt: PEM certificate
openssl x509 -in CShell_Certificate.crt -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
27:d3:e3:77:54:8b:00:84:05:c0:e9:98:bc:d2:24:4a:77:10:93:aa
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = IL, O = Check Point, OU = Mobile Access, CN = Check Point Mobile
Validity
Not Before: Apr 19 21:44:01 2023 GMT
Not After : Apr 16 21:44:01 2033 GMT
Subject: C = IL, O = Check Point, OU = Mobile Access, CN = Check Point Mobile
I got it through the vpn.sh
script in this repo, after connecting to the Check Point VPN using that. Truth is, though, I need a private machine key, but I don't know where exactly I can get it lmao.
.crt certificates are generally DER certificates, but in this case it is PEM, that shouldn't matter.
I think there is a bug with the NMACertChooser from the libnma package you are using. I'm not able to reproduce the private key not enabled issue with a PEM .crt certificate. You could try renaming CShell_Certificate.crt to CShell_Certificate.pem and adding the renamed certificate back and see if it makes a difference.
Just tested; as soon as I added the renamed certificate to the NM GUI, it unlocked the private key field!
I didn't input any certificate there because, as I said, I don't know where to get it. Because of that, it still fails with that assertation error. Should I input the same CShell_Certificate.pem
in the Machine private key field? I'll test it.
Well, when I try that it fails with the following warning: <warn> [1682360308.0184] vpn[0x55f5bf51c410,04d21ba0-ecfe-452f-9a2b-16e78d5ba28b,"UA"]: failed to connect: 'Error decrypting private key file '/home/ruben/Downloads/CShell_Certificate.pem'
, so I guess I can't just use the same certificate for both public and private keys. I'll try to grab it somewhere in the system, idk.
I just found out that there is also a .p12
certificate in the same folder (that repo's config) as the .crt
one. I tried it, and it automatically filled the 3 fields as you said. However, once I try to connect to the VPN, it now asks for a Machine Certificate Password. What the heck is this?
A PKCS#12 (or .p12) file stores a private key and its corresponding certificate, optionally it may also contain the corresponding CA certificate. That's why all 3 machine auth fields show the same .p12 file when a .p12 file is used.
A private key is definitely required for the L2TP/IPsec client machine authentication, be it in a standalone key file or in a .p12 file. I suspect the standalone key file is there somewhere, but not sure what the file extension would be. A private key is just a text file which begins and ends with the following:
-----BEGIN PRIVATE KEY-----
-----END PRIVATE KEY-----
or if the private key is encrypted with a password (aka passphrase), it begins and ends with:
-----BEGIN ENCRYPTED PRIVATE KEY-----
-----END ENCRYPTED PRIVATE KEY----
So you could grep "PRIVATE KEY" *
in the folder(s) to see if there is a private key file somewhere, hopefully an unencrypted one especially if you don't know the corresponding password or passphrase.
A PKCS#12 (or .p12) file often needs a passphrase (aka password) to unlock it, similarly to private key that is encrypted with a password or passphrase.
NetworkManager-l2tp will only prompt you for the Machine Certificate Password if it was determined the .p12 file needs a passphrase (aka password). The IPsec settings also has a password field where the password can be stored in the machine authentication fields if you don't want to be prompted for the Machine Certificate Password.
The following openssl command will most likely prompt for the passphrase before it will show the info for the .p12 file :
openssl pkcs12 -info -in CShell_Certificate.p12
I don't understand how the vpn.sh
script in that repo works. It seems to fetch the TLS server certificate from a localhost website. I don't understand how you'll then be able use that for TLS client machine's certificate. I'm not sure where the .p12
file came from, but you normally specify the passphrase (aka password) at certificate creation time.
On the following Check Point page for L2TP/IPsec, they talk about client machine's certificate : https://sc1.checkpoint.com/documents/R81/WebAdminGuides/EN/CP_R81_RemoteAccessVPN_AdminGuide/Topics-VPNRG/L2TP-Clients.htm
The L2TP VPN server validates the client machine's certificate and the L2TP client does a validation of the VPN server certificate.
Unfortunately, I can't find the private key, i.e., any file containing
-----BEGIN ENCRYPTED PRIVATE KEY-----
-----END ENCRYPTED PRIVATE KEY----
It is indeed very strange on how the Check Point VPN works. The .p12
file is in the cshell
folder, I also don't know how that file came from. I mean, the vpn.sh
script doesn't even mention this type of file...
But yeah, (un)fortunately the problem is not related to NetworkManager-l2tp. I have to make some deeper research; it would be awesome to connect to the VPN through the GNOME Shell. Thank you so much for the time you spent on this issue!!
When I added support for certificates in NetworkManager-l2tp back in 2019, I used Windows Server 2019 in a VM as the L2TP test server. I hadn't used TLS certificates in a while, so it was all fuzzy in memory.
I just noticed I still had the script I used to generate the machine certificates. Turns out I used the ipsec pki
command from strongswan to generate machine certificates as it was easier than using openssl. But still had to use openssl for generating the PKCS#12 container file.
The following has good info on what is required for a machine certificate and also how to make them compatible with Windows, macOS, iOS and Android clients:
The simple PSK is way easier.
I'll close this issue and wish you luck.
Hi! My university uses a Check Point VPN, whose CLI (
snx
) is deprecated. I'm trying to use this to adopt a modern & native solution in my pc, however I'm facing an assertation error and a segmentation fault.All parameters are okay and comply with the values in the Check Point forum, and I'm using the correct certificates (my university's VPN uses TLS certificates for machine authentication, instead of a Pre-Shared Key).
I'm running the VPN through the Network Manager GUI in the GNOME Control Center.
journalctl
output is like this: