maas login --cacerts can't handle non-ascii

Bug #2067503 reported by Andrew
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
MAAS
Fix Committed
Medium
Anton Troyanov
3.5
Fix Released
Medium
Anton Troyanov

Bug Description

I'm logging into the maas API using the CLI with our private certs. We've added the cert chain to our system certificate authority stuff. (I'm not sure on my terminology here.)

This fails:

$ maas login --cacerts /etc/pki/tls/cert.pem $USER https://$MAAS_HOST:5443/MAAS `cat maas-api-key`
[...snip usage message...]
'ascii' codec can't encode character '\u0151' in position 137865: ordinal not in range(128)

If I remove the offending characters from the comments of the system cert file:

$ diff /etc/pki/tls/cert.pem /etc/pki/tls/cert-asciionly.pem
2401c2401
< # NetLock Arany (Class Gold) Főtanúsítvány
---
> # NetLock Arany (Class Gold)

...it works:

$ maas login --cacerts /etc/pki/tls/cert-asciionly.pem $USER https://$MAAS_HOST:5443/MAAS `cat maas-api-key`
You are now logged in to the MAAS server at
[...etc...]

Is there a way to get maas to ignore non-ascii characters in the comments on a cacerts file?

System details:

Rocky Linux release 9.4
snapd-2.62-0.el9.x86_64
maas 3.4.2-14353-g.5a5221d57 35359 3.4/stable canonical✓ -

Related branches

Revision history for this message
Anton Troyanov (troyanov) wrote :

Hi Andrew,

Can you please try to apply the following change in src/maascli/cli.py?

         parser.add_argument(
             "--cacerts",
             help="Certificate CA file in PEM format",
- type=argparse.FileType(),
+ type=argparse.FileType('r', encoding='UTF-8'),
         )

The easiest way to test it would be:

> cd /tmp
> cp /snap/maas/current/lib/python3.10/site-packages/maascli/cli.py .
> sudo mount -o bind,ro /tmp/cli.py /snap/maas/current/lib/python3.10/site-packages/maascli/cli.py
> sudo snap restart maas

Revision history for this message
Andrew (andrew-boatrocker) wrote :

Hi Anton,

Looks like I don't have a /snap directory:

$ ls /snap
ls: cannot access '/snap': No such file or directory

I tried it with the cli.py that I was able to find:

$ cd /tmp/
$ cp /var/lib/snapd/snap/maas/35359/lib/python3.10/site-packages/maascli/cli.py .
$ vi cli.py
$ sudo mount -o bind,ro /tmp/cli.py /var/lib/snapd/snap/maas/35359/lib/python3.10/site-packages/maascli/cli.py
$ sudo snap restart maas

When I look at /var/lib/snapd/snap/maas/35359/lib/python3.10/site-packages/maascli/cli.py it does have the change (type=argparse.FileType('r', encoding='UTF-8')), but unfortunately I'm still getting the same "ascii codec can't encode" error as before.

Revision history for this message
Anton Troyanov (troyanov) wrote :

Hmm, thats interesting.

And can you please share the whole Traceback where this error happens?
Maybe thats coming from somewhere else?

> 'ascii' codec can't encode character '\u0151' in position 137865: ordinal not in range(128)

In order to reproduce it I need a bit more information. Where exactly do you have non-ascii symbols? Is it in the CN of the certificate (Főtanúsítvány)?

Revision history for this message
Andrew (andrew-boatrocker) wrote :

Hi Anton,

The non-ascii symbols are in a comment line in the .pem file. Their ultimate source is the Mozilla root CA list, in the NetLock Arany entry:

https://wiki.mozilla.org/CA/Included_Certificates
https://ccadb.my.salesforce-sites.com/mozilla/IncludedCACertificateReport

Redhat puts them into the /etc/pki/tls/cert.pem file by default. When we add our private cert chain to that file with "update-ca-certs", the NetLock Arany entry remains (along with all of the other Mozilla root certs). So it's a very long file, and in the middle of it is this:

5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oGI/hGoiLtk/bdmuYqh7GYVPEi92tF4+KO
dh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmgkpzNNIaRkPpkUZ3+/uul
9XXeifdy
-----END CERTIFICATE-----

# NetLock Arany (Class Gold) Főtanúsítvány
-----BEGIN CERTIFICATE-----
MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG
EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3
MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl

I don't get a proper traceback. All that I get other than the error is a usage message. Here's the full output:

$ maas login --cacerts /etc/pki/tls/cert.pem $USER https://$MAAS_HOST:5443/MAAS `cat ~/maas-api-key`
usage: maas [-h] COMMAND ...

options:
  -h, --help show this help message and exit

drill down:
  COMMAND
    login Log in to a remote API, and remember its description and credentials.
    logout Log out of a remote API, purging any stored credentials.
    list List remote APIs that have been logged-in to.
    refresh Refresh the API descriptions of all profiles.
    init Initialise MAAS in the specified run mode.
    config View or change controller configuration.
    status Status of controller services.
    migrate Perform migrations on connected database.
    apikey Used to manage a user's API keys. Shows existing keys unless --generate or --delete is passed.
    configauth Configure external authentication.
    config-tls Configure MAAS Region TLS.
    config-vault Configure MAAS Region Vault integration.
    createadmin Create a MAAS administrator account.
    changepassword
                  Change a MAAS user's password.
    <user>
                  Interact with https://$MAAS_HOST:5443/MAAS/api/2.0/

https://maas.io/

'ascii' codec can't encode character '\u0151' in position 137865: ordinal not in range(128)

Revision history for this message
Anton Troyanov (troyanov) wrote :

Hi Andrew,

Thanks for the very detailed explanation. I was able to reproduce it.
May I ask you to try this patch?

diff --git a/src/maascli/cli.py b/src/maascli/cli.py
index 47a62c82f..dfe921018 100644
--- a/src/maascli/cli.py
+++ b/src/maascli/cli.py
@@ -98,7 +98,7 @@ class cmd_login(Command):
         if options.cacerts is not None:
             cacerts = options.cacerts.read()
             try:
- crypto.load_certificate(crypto.FILETYPE_PEM, cacerts)
+ crypto.load_certificate(crypto.FILETYPE_PEM, cacerts.encode('utf-8'))
             except crypto.Error:
                 raise CommandError("Invalid PEM material")

Changed in maas:
status: New → Triaged
milestone: none → 3.6.0
importance: Undecided → Medium
assignee: nobody → Anton Troyanov (troyanov)
Revision history for this message
Andrew (andrew-boatrocker) wrote :

Hi Anton,

That patch fixes the problem, thanks.

Is there a straightforward way for us to roll that out to production?

Revision history for this message
Anton Troyanov (troyanov) wrote :

Hi Andrew,

Thats a good question and I don't think I have an answer :(

You can always repack the snap but that will require providing --dangerous flag during installation and I would not recommend this for production as you will lose automatic updates.

root@maas:/var/lib/snapd/snaps$ snap install maas
root@maas:/var/lib/snapd/snaps$ unsquashfs maas_xxx.snap
# do the changes and pack it back
root@maas:/var/lib/snapd/snaps$ snap pack ./squashfs-root
root@maas:/var/lib/snapd/snaps$ sudo snap install --dangerous maas_xxx.snap
root@maas:/var/lib/snapd/snaps$ snap connections maas | awk '$1 != "content" && $3 == "-" {print $2}' | xargs -r -n1 sudo snap connect
root@maas:/var/lib/snapd/snaps$ sudo maas init region+rack

Meanwhile maybe adding a bash-script wrapper will help you? Just sanitise CA file to remove non-ascii characters and call maas CLI?

Changed in maas:
status: Triaged → In Progress
Revision history for this message
Andrew (andrew-boatrocker) wrote :

Hi Anton,

Agreed, I think we'll have to go with the sanitizing option for now.

Thanks again.

Changed in maas:
status: In Progress → Fix Committed
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.